[PATCH] drm/amdgpu: fix getting vram info for gfx12

Min, Frank Frank.Min at amd.com
Mon May 13 14:55:09 UTC 2024


[AMD Official Use Only - AMD Internal Distribution Only]

From: Frank Min <Frank.Min at amd.com>

gfx12 query video mem channel/type/width from umc_info of atom list, so fix it accordingly.

Signed-off-by: Frank Min <Frank.Min at amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c  | 263 ++++++++++--------
 1 file changed, 148 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index a6d64bdbbb14..6fe84151332e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -289,7 +289,6 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
        return vram_type;
 }

-
 int
 amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
                                  int *vram_width, int *vram_type,
@@ -300,6 +299,7 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
        u16 data_offset, size;
        union igp_info *igp_info;
        union vram_info *vram_info;
+       union umc_info *umc_info;
        union vram_module *vram_module;
        u8 frev, crev;
        u8 mem_type;
@@ -311,10 +311,16 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
        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);
-
+       else {
+               switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
+               case IP_VERSION(12, 0, 0):
+               case IP_VERSION(12, 0, 1):
+                       index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, umc_info);
+                       break;
+               default:
+                       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)) {
@@ -368,123 +374,150 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
                                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;
-                       if (frev == 3) {
-                               switch (crev) {
-                               /* v30 */
-                               case 0:
-                                       vram_module = (union vram_module *)vram_info->v30.vram_module;
-                                       mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF;
-                                       if (vram_vendor)
-                                               *vram_vendor = mem_vendor;
-                                       mem_type = vram_info->v30.memory_type;
-                                       if (vram_type)
-                                               *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
-                                       mem_channel_number = vram_info->v30.channel_num;
-                                       mem_channel_width = vram_info->v30.channel_width;
-                                       if (vram_width)
-                                               *vram_width = mem_channel_number * (1 << mem_channel_width);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
-                       } else if (frev == 2) {
-                               switch (crev) {
-                               /* v23 */
-                               case 3:
-                                       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);
-                                       mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
-                                       if (vram_vendor)
-                                               *vram_vendor = mem_vendor;
-                                       break;
-                               /* v24 */
-                               case 4:
-                                       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++;
+                       switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
+                       case IP_VERSION(12, 0, 0):
+                       case IP_VERSION(12, 0, 1):
+                               umc_info = (union umc_info *)(mode_info->atom_context->bios +
+data_offset);
+
+                               if (frev == 4) {
+                                       switch (crev) {
+                                       case 0:
+                                               mem_channel_number = le32_to_cpu(umc_info->v40.channel_num);
+                                               mem_type = le32_to_cpu(umc_info->v40.vram_type);
+                                               mem_channel_width = le32_to_cpu(umc_info->v40.channel_width);
+                                               mem_vendor = RREG32(adev->bios_scratch_reg_offset + 4) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               if (vram_type)
+                                                       *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
+                                               if (vram_width)
+                                                       *vram_width = mem_channel_number * (1 << mem_channel_width);
+                                               break;
+                                       default:
+                                               return -EINVAL;
                                        }
-                                       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);
-                                       mem_vendor = (vram_module->v10.vender_rev_id) & 0xF;
-                                       if (vram_vendor)
-                                               *vram_vendor = mem_vendor;
-                                       break;
-                               /* v25 */
-                               case 5:
-                                       if (module_id > vram_info->v25.vram_module_num)
-                                               module_id = 0;
-                                       vram_module = (union vram_module *)vram_info->v25.vram_module;
-                                       while (i < module_id) {
-                                               vram_module = (union vram_module *)
-                                                       ((u8 *)vram_module + vram_module->v11.vram_module_size);
-                                               i++;
+                               } else
+                                       return -EINVAL;
+                               break;
+                       default:
+                               vram_info = (union vram_info *)
+                                       (mode_info->atom_context->bios + data_offset);
+
+                               module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16;
+                               if (frev == 3) {
+                                       switch (crev) {
+                                       /* v30 */
+                                       case 0:
+                                               vram_module = (union vram_module *)vram_info->v30.vram_module;
+                                               mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               mem_type = vram_info->v30.memory_type;
+                                               if (vram_type)
+                                                       *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
+                                               mem_channel_number = vram_info->v30.channel_num;
+                                               mem_channel_width = vram_info->v30.channel_width;
+                                               if (vram_width)
+                                                       *vram_width = mem_channel_number * (1 << mem_channel_width);
+                                               break;
+                                       default:
+                                               return -EINVAL;
                                        }
-                                       mem_type = vram_module->v11.memory_type;
-                                       if (vram_type)
-                                               *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
-                                       mem_channel_number = vram_module->v11.channel_num;
-                                       mem_channel_width = vram_module->v11.channel_width;
-                                       if (vram_width)
-                                               *vram_width = mem_channel_number * (1 << mem_channel_width);
-                                       mem_vendor = (vram_module->v11.vender_rev_id) & 0xF;
-                                       if (vram_vendor)
-                                               *vram_vendor = mem_vendor;
-                                       break;
-                               /* v26 */
-                               case 6:
-                                       if (module_id > vram_info->v26.vram_module_num)
-                                               module_id = 0;
-                                       vram_module = (union vram_module *)vram_info->v26.vram_module;
-                                       while (i < module_id) {
-                                               vram_module = (union vram_module *)
-                                                       ((u8 *)vram_module + vram_module->v9.vram_module_size);
-                                               i++;
+                               } else if (frev == 2) {
+                                       switch (crev) {
+                                       /* v23 */
+                                       case 3:
+                                               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);
+                                               mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               break;
+                                       /* v24 */
+                                       case 4:
+                                               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);
+                                               mem_vendor = (vram_module->v10.vender_rev_id) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               break;
+                                       /* v25 */
+                                       case 5:
+                                               if (module_id > vram_info->v25.vram_module_num)
+                                                       module_id = 0;
+                                               vram_module = (union vram_module *)vram_info->v25.vram_module;
+                                               while (i < module_id) {
+                                                       vram_module = (union vram_module *)
+                                                               ((u8 *)vram_module + vram_module->v11.vram_module_size);
+                                                       i++;
+                                               }
+                                               mem_type = vram_module->v11.memory_type;
+                                               if (vram_type)
+                                                       *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
+                                               mem_channel_number = vram_module->v11.channel_num;
+                                               mem_channel_width = vram_module->v11.channel_width;
+                                               if (vram_width)
+                                                       *vram_width = mem_channel_number * (1 << mem_channel_width);
+                                               mem_vendor = (vram_module->v11.vender_rev_id) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               break;
+                                       /* v26 */
+                                       case 6:
+                                               if (module_id > vram_info->v26.vram_module_num)
+                                                       module_id = 0;
+                                               vram_module = (union vram_module *)vram_info->v26.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);
+                                               mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
+                                               if (vram_vendor)
+                                                       *vram_vendor = mem_vendor;
+                                               break;
+                                       default:
+                                               return -EINVAL;
                                        }
-                                       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);
-                                       mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
-                                       if (vram_vendor)
-                                               *vram_vendor = mem_vendor;
-                                       break;
-                               default:
+                               } else {
+                                       /* invalid frev */
                                        return -EINVAL;
                                }
-                       } else {
-                               /* invalid frev */
-                               return -EINVAL;
                        }
                }
-
        }

        return 0;
--
2.34.1



More information about the amd-gfx mailing list