aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3919-drm-amdgpu-atomfirmware-use-proper-index-for-queryin.patch
diff options
context:
space:
mode:
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.patch240
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
+