diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch new file mode 100644 index 00000000..f3cdca67 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch @@ -0,0 +1,240 @@ +From 8a506d87d40632dd9d40d4815f0388b28ac6614b Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 20 Sep 2019 14:43:44 -0500 +Subject: [PATCH 3919/4256] drm/amdgpu/atomfirmware: use proper index for + querying vram type (v3) + +The index is stored in scratch register 4 after asic init. Use +that index. No functional change since all asics in a family +use the same type of vram (G5, G6, HBM) and that is all we use +at the monent, but if we ever need to query other info, we will +now have the proper index. + +v2: module array is variable sized, handle that. +v3: fix off by one in array handling + +Reviewed-by: Xiaojie Yuan <xiaojie.yuan@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 158 ++++++++++-------- + 1 file changed, 88 insertions(+), 70 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +index 606ed819f355..e0e67a53fb3c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +@@ -120,65 +120,14 @@ union vram_info { + struct atom_vram_info_header_v2_3 v23; + struct atom_vram_info_header_v2_4 v24; + }; +-/* +- * Return vram width from integrated system info table, if available, +- * or 0 if not. +- */ +-int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev) +-{ +- struct amdgpu_mode_info *mode_info = &adev->mode_info; +- int index; +- u16 data_offset, size; +- union igp_info *igp_info; +- union vram_info *vram_info; +- u32 mem_channel_number; +- u32 mem_channel_width; +- u8 frev, crev; +- +- if (adev->flags & AMD_IS_APU) +- index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, +- integratedsysteminfo); +- else +- index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, +- vram_info); +- +- /* get any igp specific overrides */ +- if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size, +- &frev, &crev, &data_offset)) { +- if (adev->flags & AMD_IS_APU) { +- igp_info = (union igp_info *) +- (mode_info->atom_context->bios + data_offset); +- switch (crev) { +- case 11: +- mem_channel_number = igp_info->v11.umachannelnumber; +- /* channel width is 64 */ +- return mem_channel_number * 64; +- default: +- return 0; +- } +- } else { +- vram_info = (union vram_info *) +- (mode_info->atom_context->bios + data_offset); +- switch (crev) { +- case 3: +- mem_channel_number = vram_info->v23.vram_module[0].channel_num; +- mem_channel_width = vram_info->v23.vram_module[0].channel_width; +- return mem_channel_number * (1 << mem_channel_width); +- case 4: +- mem_channel_number = vram_info->v24.vram_module[0].channel_num; +- mem_channel_width = vram_info->v24.vram_module[0].channel_width; +- return mem_channel_number * (1 << mem_channel_width); +- default: +- return 0; +- } +- } +- } + +- return 0; +-} ++union vram_module { ++ struct atom_vram_module_v9 v9; ++ struct atom_vram_module_v10 v10; ++}; + +-static int convert_atom_mem_type_to_vram_type (struct amdgpu_device *adev, +- int atom_mem_type) ++static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev, ++ int atom_mem_type) + { + int vram_type; + +@@ -219,19 +168,23 @@ static int convert_atom_mem_type_to_vram_type (struct amdgpu_device *adev, + + return vram_type; + } +-/* +- * Return vram type from either integrated system info table +- * or umc info table, if available, or 0 (TYPE_UNKNOWN) if not +- */ +-int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev) ++ ++static int ++amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, ++ int *vram_width, int *vram_type) + { + struct amdgpu_mode_info *mode_info = &adev->mode_info; +- int index; ++ int index, i = 0; + u16 data_offset, size; + union igp_info *igp_info; + union vram_info *vram_info; ++ union vram_module *vram_module; + u8 frev, crev; + u8 mem_type; ++ u32 mem_channel_number; ++ u32 mem_channel_width; ++ u32 module_id; ++ + + if (adev->flags & AMD_IS_APU) + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, +@@ -239,6 +192,7 @@ int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev) + else + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + vram_info); ++ + if (amdgpu_atom_parse_data_header(mode_info->atom_context, + index, &size, + &frev, &crev, &data_offset)) { +@@ -247,30 +201,94 @@ int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev) + (mode_info->atom_context->bios + data_offset); + switch (crev) { + case 11: ++ mem_channel_number = igp_info->v11.umachannelnumber; ++ /* channel width is 64 */ ++ if (vram_width) ++ *vram_width = mem_channel_number * 64; + mem_type = igp_info->v11.memorytype; +- return convert_atom_mem_type_to_vram_type(adev, mem_type); ++ if (vram_type) ++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); ++ break; + default: +- return 0; ++ return -EINVAL; + } + } else { + vram_info = (union vram_info *) + (mode_info->atom_context->bios + data_offset); ++ module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16; + switch (crev) { + case 3: +- mem_type = vram_info->v23.vram_module[0].memory_type; +- return convert_atom_mem_type_to_vram_type(adev, mem_type); ++ if (module_id > vram_info->v23.vram_module_num) ++ module_id = 0; ++ vram_module = (union vram_module *)vram_info->v23.vram_module; ++ while (i < module_id) { ++ vram_module = (union vram_module *) ++ ((u8 *)vram_module + vram_module->v9.vram_module_size); ++ i++; ++ } ++ mem_type = vram_module->v9.memory_type; ++ if (vram_type) ++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); ++ mem_channel_number = vram_module->v9.channel_num; ++ mem_channel_width = vram_module->v9.channel_width; ++ if (vram_width) ++ *vram_width = mem_channel_number * (1 << mem_channel_width); ++ break; + case 4: +- mem_type = vram_info->v24.vram_module[0].memory_type; +- return convert_atom_mem_type_to_vram_type(adev, mem_type); ++ if (module_id > vram_info->v24.vram_module_num) ++ module_id = 0; ++ vram_module = (union vram_module *)vram_info->v24.vram_module; ++ while (i < module_id) { ++ vram_module = (union vram_module *) ++ ((u8 *)vram_module + vram_module->v10.vram_module_size); ++ i++; ++ } ++ mem_type = vram_module->v10.memory_type; ++ if (vram_type) ++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); ++ mem_channel_number = vram_module->v10.channel_num; ++ mem_channel_width = vram_module->v10.channel_width; ++ if (vram_width) ++ *vram_width = mem_channel_number * (1 << mem_channel_width); ++ break; + default: +- return 0; ++ return -EINVAL; + } + } ++ + } + + return 0; + } + ++/* ++ * Return vram width from integrated system info table, if available, ++ * or 0 if not. ++ */ ++int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev) ++{ ++ int vram_width = 0, vram_type = 0; ++ int r = amdgpu_atomfirmware_get_vram_info(adev, &vram_width, &vram_type); ++ if (r) ++ return 0; ++ ++ return vram_width; ++} ++ ++/* ++ * Return vram type from either integrated system info table ++ * or umc info table, if available, or 0 (TYPE_UNKNOWN) if not ++ */ ++int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev) ++{ ++ int vram_width = 0, vram_type = 0; ++ int r = amdgpu_atomfirmware_get_vram_info(adev, &vram_width, &vram_type); ++ if (r) ++ return 0; ++ ++ return vram_type; ++} ++ + /* + * Return true if vbios enabled ecc by default, if umc info table is available + * or false if ecc is not enabled or umc info table is not available +-- +2.17.1 + |