diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 494b2e1717d5..18bd1b49ced6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1828,6 +1828,9 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) if (adev->is_atom_fw) { amdgpu_atomfirmware_scratch_regs_init(adev); amdgpu_atomfirmware_allocate_fb_scratch(adev); + /* cached firmware_flags for further usage */ + adev->mode_info.firmware_flags = + amdgpu_atomfirmware_query_firmware_capability(adev); } else { amdgpu_atombios_scratch_regs_init(adev); amdgpu_atombios_allocate_fb_scratch(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 60716b35444b..c6eb07f5235a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -29,6 +29,45 @@ #include "atombios.h" #include "soc15_hw_ip.h" +union firmware_info { + struct atom_firmware_info_v3_1 v31; + struct atom_firmware_info_v3_2 v32; + struct atom_firmware_info_v3_3 v33; + struct atom_firmware_info_v3_4 v34; +}; + +/* + * Helper function to query firmware capability + * + * @adev: amdgpu_device pointer + * + * Return firmware_capability in firmwareinfo table on success or 0 if not + */ +uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *adev) +{ + struct amdgpu_mode_info *mode_info = &adev->mode_info; + int index; + u16 data_offset, size; + union firmware_info *firmware_info; + u8 frev, crev; + u32 fw_cap = 0; + + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + firmwareinfo); + + if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, + index, &size, &frev, &crev, &data_offset)) { + /* support firmware_info 3.1 + */ + if ((frev == 3 && crev >=1) || (frev > 3)) { + firmware_info = (union firmware_info *) + (mode_info->atom_context->bios + data_offset); + fw_cap = le32_to_cpu(firmware_info->v31.firmware_capability); + } + } + + return fw_cap; +} + bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev) { int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, @@ -400,13 +439,6 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev) return ecc_default_enabled; } -union firmware_info { - struct atom_firmware_info_v3_1 v31; - struct atom_firmware_info_v3_2 v32; - struct atom_firmware_info_v3_3 v33; - struct atom_firmware_info_v3_4 v34; -}; - /* * Return true if vbios supports sram ecc or false if not */ @@ -466,10 +498,6 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) adev->pm.current_sclk = adev->clock.default_sclk; adev->pm.current_mclk = adev->clock.default_mclk; - /* not technically a clock, but... */ - adev->mode_info.firmware_flags = - le32_to_cpu(firmware_info->v31.firmware_capability); - ret = 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h index 9f0d4356e8df..77c5fb1f61cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h @@ -26,6 +26,7 @@ #define get_index_into_master_table(master_table, table_name) (offsetof(struct master_table, table_name) / sizeof(uint16_t)) +uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *adev); bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev); void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev); int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index cb0b581bbce7..89fb372ed49c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -344,7 +344,7 @@ struct amdgpu_mode_info { /* pointer to fbdev info structure */ struct amdgpu_fbdev *rfbdev; /* firmware flags */ - u16 firmware_flags; + u32 firmware_flags; /* pointer to backlight encoder */ struct amdgpu_encoder *bl_encoder; u8 bl_level; /* saved backlight level */