drm/amdgpu: add XGMI support for sienna cichlid
authorJohn Clements <john.clements@amd.com>
Fri, 19 Jun 2020 07:01:13 +0000 (15:01 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jul 2020 05:59:24 +0000 (01:59 -0400)
support for setting up XGMI FB address regions

Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: John Clements <john.clements@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.h
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c

index 34c12c8..fcc4c19 100644 (file)
@@ -373,3 +373,39 @@ void gfxhub_v2_1_init(struct amdgpu_device *adev)
        hub->vm_l2_pro_fault_cntl =
                SOC15_REG_OFFSET(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
 }
+
+int gfxhub_v2_1_get_xgmi_info(struct amdgpu_device *adev)
+{
+       u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmGCMC_VM_XGMI_LFB_CNTL);
+       u32 max_region =
+               REG_GET_FIELD(xgmi_lfb_cntl, GCMC_VM_XGMI_LFB_CNTL, PF_MAX_REGION);
+       u32 max_num_physical_nodes   = 0;
+       u32 max_physical_node_id     = 0;
+
+       switch (adev->asic_type) {
+       case CHIP_SIENNA_CICHLID:
+               max_num_physical_nodes   = 4;
+               max_physical_node_id     = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* PF_MAX_REGION=0 means xgmi is disabled */
+       if (max_region) {
+               adev->gmc.xgmi.num_physical_nodes = max_region + 1;
+               if (adev->gmc.xgmi.num_physical_nodes > max_num_physical_nodes)
+                       return -EINVAL;
+
+               adev->gmc.xgmi.physical_node_id =
+                       REG_GET_FIELD(xgmi_lfb_cntl, GCMC_VM_XGMI_LFB_CNTL, PF_LFB_REGION);
+               if (adev->gmc.xgmi.physical_node_id > max_physical_node_id)
+                       return -EINVAL;
+
+               adev->gmc.xgmi.node_segment_size = REG_GET_FIELD(
+                       RREG32_SOC15(GC, 0, mmGCMC_VM_XGMI_LFB_SIZE),
+                       GCMC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24;
+       }
+
+       return 0;
+}
index e385ae0..3452a4e 100644 (file)
@@ -34,4 +34,6 @@ u64 gfxhub_v2_1_get_mc_fb_offset(struct amdgpu_device *adev);
 void gfxhub_v2_1_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
                                uint64_t page_table_base);
 
+int gfxhub_v2_1_get_xgmi_info(struct amdgpu_device *adev);
+
 #endif
index 061900e..f7e66bf 100644 (file)
@@ -691,6 +691,9 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev,
        else
                base = gfxhub_v2_0_get_fb_location(adev);
 
+       /* add the xgmi offset of the physical node */
+       base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
+
        amdgpu_gmc_vram_location(adev, &adev->gmc, base);
        amdgpu_gmc_gart_location(adev, mc);
 
@@ -699,6 +702,10 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev,
                adev->vm_manager.vram_base_offset = gfxhub_v2_1_get_mc_fb_offset(adev);
        else
                adev->vm_manager.vram_base_offset = gfxhub_v2_0_get_mc_fb_offset(adev);
+
+       /* add the xgmi offset of the physical node */
+       adev->vm_manager.vram_base_offset +=
+               adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
 }
 
 /**
@@ -871,6 +878,12 @@ static int gmc_v10_0_sw_init(void *handle)
                return r;
        }
 
+       if (adev->gmc.xgmi.supported) {
+               r = gfxhub_v2_1_get_xgmi_info(adev);
+               if (r)
+                       return r;
+       }
+
        r = gmc_v10_0_mc_init(adev);
        if (r)
                return r;