drm/amdgpu/gmc9: Adjust GART and AGP location with xgmi offset (v2)
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Jun 2018 21:11:56 +0000 (16:11 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 11 Sep 2018 03:47:34 +0000 (22:47 -0500)
On hives with xgmi enabled, the fb_location aperture is a size
which defines the total framebuffer size of all nodes in the
hive.  Each GPU in the hive has the same view via the fb_location
aperture.  GPU0 starts at offset (0 * segment size),
GPU1 starts at offset (1 * segment size), etc.

For access to local vram on each GPU, we need to take this offset into
account. This including on setting up GPUVM page table and GART table

v2: squash in "drm/amdgpu: Init correct fb region for none XGMI configuration"

Acked-by: Huang Rui <ray.huang@amd.com>
Acked-by: Slava Abramov <slava.abramov@amd.com>
Signed-off-by: Shaoyun Liu <Shaoyun.Liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Huang Rui <ray.huang@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c

index 6acdeebabfc08e10969a2393785532289153e986..ae4467113240684f7017d1bc4c59be059cad9b0d 100644 (file)
@@ -121,6 +121,11 @@ void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
        mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
        if (limit && limit < mc->real_vram_size)
                mc->real_vram_size = limit;
+
+       if (mc->xgmi.num_physical_nodes == 0) {
+               mc->fb_start = mc->vram_start;
+               mc->fb_end = mc->vram_end;
+       }
        dev_info(adev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
                        mc->mc_vram_size >> 20, mc->vram_start,
                        mc->vram_end, mc->real_vram_size >> 20);
@@ -147,8 +152,8 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
        /* VCE doesn't like it when BOs cross a 4GB segment, so align
         * the GART base on a 4GB boundary as well.
         */
-       size_bf = mc->vram_start;
-       size_af = adev->gmc.mc_mask + 1 - ALIGN(mc->vram_end + 1, four_gb);
+       size_bf = mc->fb_start;
+       size_af = adev->gmc.mc_mask + 1 - ALIGN(mc->fb_end + 1, four_gb);
 
        if (mc->gart_size > max(size_bf, size_af)) {
                dev_warn(adev->dev, "limiting GART\n");
@@ -184,23 +189,23 @@ void amdgpu_gmc_agp_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
        const uint64_t sixteen_gb_mask = ~(sixteen_gb - 1);
        u64 size_af, size_bf;
 
-       if (mc->vram_start > mc->gart_start) {
-               size_bf = (mc->vram_start & sixteen_gb_mask) -
+       if (mc->fb_start > mc->gart_start) {
+               size_bf = (mc->fb_start & sixteen_gb_mask) -
                        ALIGN(mc->gart_end + 1, sixteen_gb);
-               size_af = mc->mc_mask + 1 - ALIGN(mc->vram_end + 1, sixteen_gb);
+               size_af = mc->mc_mask + 1 - ALIGN(mc->fb_end + 1, sixteen_gb);
        } else {
-               size_bf = mc->vram_start & sixteen_gb_mask;
+               size_bf = mc->fb_start & sixteen_gb_mask;
                size_af = (mc->gart_start & sixteen_gb_mask) -
-                       ALIGN(mc->vram_end + 1, sixteen_gb);
+                       ALIGN(mc->fb_end + 1, sixteen_gb);
        }
 
        if (size_bf > size_af) {
-               mc->agp_start = mc->vram_start > mc->gart_start ?
+               mc->agp_start = mc->fb_start > mc->gart_start ?
                        mc->gart_end + 1 : 0;
                mc->agp_size = size_bf;
        } else {
-               mc->agp_start = (mc->vram_start > mc->gart_start ?
-                       mc->vram_end : mc->gart_end) + 1,
+               mc->agp_start = (mc->fb_start > mc->gart_start ?
+                       mc->fb_end : mc->gart_end) + 1,
                mc->agp_size = size_af;
        }
 
index a929a55b30c28144ccb8d671d1d42e94c5b63d5f..b00b5165969bd491826bc7b139bc0a618f209a93 100644 (file)
@@ -114,6 +114,14 @@ struct amdgpu_gmc {
        u64                     gart_end;
        u64                     vram_start;
        u64                     vram_end;
+       /* FB region , it's same as local vram region in single GPU, in XGMI
+        * configuration, this region covers all GPUs in the same hive ,
+        * each GPU in the hive has the same view of this FB region .
+        * GPU0's vram starts at offset (0 * segment size) ,
+        * GPU1 starts at offset (1 * segment size), etc.
+        */
+       u64                     fb_start;
+       u64                     fb_end;
        unsigned                vram_width;
        u64                     real_vram_size;
        int                     vram_mtrr;
index d4170cb4105516d5dc49c0c35754243fb9d1019e..5e9ab8eb214a023c2147bbb86dcaa9240e280942 100644 (file)
@@ -44,6 +44,9 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
                        REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_LFB_REGION);
                if (adev->gmc.xgmi.physical_node_id > 3)
                        return -EINVAL;
+               adev->gmc.xgmi.node_segment_size = REG_GET_FIELD(
+                       RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE),
+                       MC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24;
        }
 
        return 0;
index e9b5a13006575627e651f2fb3754f615c9607fdf..b1c848937e4241744b06d9416a2eb0523f59c7ce 100644 (file)
@@ -771,12 +771,18 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
        u64 base = 0;
        if (!amdgpu_sriov_vf(adev))
                base = mmhub_v1_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);
        if (!amdgpu_sriov_vf(adev))
                amdgpu_gmc_agp_location(adev, mc);
        /* base offset of vram pages */
        adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
+
+       /* XXX: 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;
 }
 
 /**
index 73d7c075dd33b7a16e0473229adebf8dbc53cf5c..0e09549d1db879211fc13dbf1de9138c5e1379b5 100644 (file)
 u64 mmhub_v1_0_get_fb_location(struct amdgpu_device *adev)
 {
        u64 base = RREG32_SOC15(MMHUB, 0, mmMC_VM_FB_LOCATION_BASE);
+       u64 top = RREG32_SOC15(MMHUB, 0, mmMC_VM_FB_LOCATION_TOP);
 
        base &= MC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
        base <<= 24;
 
+       top &= MC_VM_FB_LOCATION_TOP__FB_TOP_MASK;
+       top <<= 24;
+
+       adev->gmc.fb_start = base;
+       adev->gmc.fb_end = top;
+
        return base;
 }