drm/amdgpu: query vram type from atombios
authorHawking Zhang <Hawking.Zhang@amd.com>
Thu, 8 Mar 2018 10:01:24 +0000 (18:01 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 14 Mar 2018 19:38:26 +0000 (14:38 -0500)
The vram type for dGPU is stored in umc_info while sys mem type
for APU is stored in integratedsysteminfo

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
include/uapi/drm/amdgpu_drm.h

index ff8efd0f8fd54f7c3ef2db1e03cb4b0666d42002..a0f48cb9b8f06465c9a407e425c5881443ca804b 100644 (file)
@@ -114,6 +114,9 @@ union igp_info {
        struct atom_integrated_system_info_v1_11 v11;
 };
 
+union umc_info {
+       struct atom_umc_info_v3_1 v31;
+};
 /*
  * Return vram width from integrated system info table, if available,
  * or 0 if not.
@@ -143,6 +146,94 @@ int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev)
        return 0;
 }
 
+static int convert_atom_mem_type_to_vram_type (struct amdgpu_device *adev,
+                                              int atom_mem_type)
+{
+       int vram_type;
+
+       if (adev->flags & AMD_IS_APU) {
+               switch (atom_mem_type) {
+               case Ddr2MemType:
+               case LpDdr2MemType:
+                       vram_type = AMDGPU_VRAM_TYPE_DDR2;
+                       break;
+               case Ddr3MemType:
+               case LpDdr3MemType:
+                       vram_type = AMDGPU_VRAM_TYPE_DDR3;
+                       break;
+               case Ddr4MemType:
+               case LpDdr4MemType:
+                       vram_type = AMDGPU_VRAM_TYPE_DDR4;
+                       break;
+               default:
+                       vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+                       break;
+               }
+       } else {
+               switch (atom_mem_type) {
+               case ATOM_DGPU_VRAM_TYPE_GDDR5:
+                       vram_type = AMDGPU_VRAM_TYPE_GDDR5;
+                       break;
+               case ATOM_DGPU_VRAM_TYPE_HBM:
+                       vram_type = AMDGPU_VRAM_TYPE_HBM;
+                       break;
+               default:
+                       vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+                       break;
+               }
+       }
+
+       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)
+{
+       struct amdgpu_mode_info *mode_info = &adev->mode_info;
+       int index;
+       u16 data_offset, size;
+       union igp_info *igp_info;
+       union umc_info *umc_info;
+       u8 frev, crev;
+       u8 mem_type;
+
+       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,
+                                                   umc_info);
+       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_type = igp_info->v11.memorytype;
+                               return convert_atom_mem_type_to_vram_type(adev, mem_type);
+                       default:
+                               return 0;
+                       }
+               } else {
+                       umc_info = (union umc_info *)
+                               (mode_info->atom_context->bios + data_offset);
+                       switch (crev) {
+                       case 1:
+                               mem_type = umc_info->v31.vram_type;
+                               return convert_atom_mem_type_to_vram_type(adev, mem_type);
+                       default:
+                               return 0;
+                       }
+               }
+       }
+
+       return 0;
+}
+
 union firmware_info {
        struct atom_firmware_info_v3_1 v31;
 };
@@ -151,10 +242,6 @@ union smu_info {
        struct atom_smu_info_v3_1 v31;
 };
 
-union umc_info {
-       struct atom_umc_info_v3_1 v31;
-};
-
 int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
 {
        struct amdgpu_mode_info *mode_info = &adev->mode_info;
index 288b97e543478b48f2298cf3e442b03f99a91d69..7689c961c4ef62826dce6209ab653c1815e5c70c 100644 (file)
@@ -28,6 +28,7 @@ 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);
 int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev);
+int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev);
 int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
 
 #endif
index 67cd1fe176492a9fd0abd0f681eac1fd60a0dd1c..ceab14f16795f43db6f08a1aa6790aef9ce8df9c 100644 (file)
@@ -836,9 +836,9 @@ static int gmc_v9_0_sw_init(void *handle)
 
        spin_lock_init(&adev->gmc.invalidate_lock);
 
+       adev->gmc.vram_type = amdgpu_atomfirmware_get_vram_type(adev);
        switch (adev->asic_type) {
        case CHIP_RAVEN:
-               adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
                if (adev->rev_id == 0x0 || adev->rev_id == 0x1) {
                        amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
                } else {
@@ -849,8 +849,6 @@ static int gmc_v9_0_sw_init(void *handle)
                }
                break;
        case CHIP_VEGA10:
-               /* XXX Don't know how to get VRAM type yet. */
-               adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM;
                /*
                 * To fulfill 4-level page support,
                 * vm size is 256TB (48bit), maximum size of Vega10,
index 1816bd8200d1f3f2e23cfcc4f1e502c001c8fa35..528f6d041e906fd94a25031c0384445b820e7cfb 100644 (file)
@@ -806,6 +806,7 @@ struct drm_amdgpu_info_firmware {
 #define AMDGPU_VRAM_TYPE_GDDR5 5
 #define AMDGPU_VRAM_TYPE_HBM   6
 #define AMDGPU_VRAM_TYPE_DDR3  7
+#define AMDGPU_VRAM_TYPE_DDR4  8
 
 struct drm_amdgpu_info_device {
        /** PCI Device ID */