OSDN Git Service

drm/amdgpu: Placement of gart and vram in sysvm aperture
authorOak Zeng <Oak.Zeng@amd.com>
Wed, 16 Sep 2020 02:08:50 +0000 (21:08 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 24 Mar 2021 02:58:36 +0000 (22:58 -0400)
If use GART for FB translation, place both vram and gart to sysvm
aperture. AGP aperture is not set up in this case because it
is not used

Signed-off-by: Oak Zeng <Oak.Zeng@amd.com>
Reviewed-by: Christian Konig <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index 2a85887..2c34776 100644 (file)
@@ -158,6 +158,39 @@ void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
                        mc->vram_end, mc->real_vram_size >> 20);
 }
 
+/** amdgpu_gmc_sysvm_location - place vram and gart in sysvm aperture
+ *
+ * @adev: amdgpu device structure holding all necessary information
+ * @mc: memory controller structure holding memory information
+ *
+ * This function is only used if use GART for FB translation. In such
+ * case, we use sysvm aperture (vmid0 page tables) for both vram
+ * and gart (aka system memory) access.
+ *
+ * GPUVM (and our organization of vmid0 page tables) require sysvm
+ * aperture to be placed at a location aligned with 8 times of native
+ * page size. For example, if vm_context0_cntl.page_table_block_size
+ * is 12, then native page size is 8G (2M*2^12), sysvm should start
+ * with a 64G aligned address. For simplicity, we just put sysvm at
+ * address 0. So vram start at address 0 and gart is right after vram.
+ */
+void amdgpu_gmc_sysvm_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
+{
+       u64 hive_vram_start = 0;
+       u64 hive_vram_end = mc->xgmi.node_segment_size * mc->xgmi.num_physical_nodes - 1;
+       mc->vram_start = mc->xgmi.node_segment_size * mc->xgmi.physical_node_id;
+       mc->vram_end = mc->vram_start + mc->xgmi.node_segment_size - 1;
+       mc->gart_start = hive_vram_end + 1;
+       mc->gart_end = mc->gart_start + mc->gart_size - 1;
+       mc->fb_start = hive_vram_start;
+       mc->fb_end = hive_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);
+       dev_info(adev->dev, "GART: %lluM 0x%016llX - 0x%016llX\n",
+                       mc->gart_size >> 20, mc->gart_start, mc->gart_end);
+}
+
 /**
  * amdgpu_gmc_gart_location - try to find GART location
  *
@@ -165,7 +198,6 @@ void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
  * @mc: memory controller structure holding memory information
  *
  * Function will place try to place GART before or after VRAM.
- *
  * If GART size is bigger than space left then we ajust GART size.
  * Thus function will never fails.
  */
index f1a21e1..a061a56 100644 (file)
@@ -292,6 +292,7 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
                                uint64_t flags);
 uint64_t amdgpu_gmc_pd_addr(struct amdgpu_bo *bo);
 uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo);
+void amdgpu_gmc_sysvm_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc);
 void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
                              u64 base);
 void amdgpu_gmc_gart_location(struct amdgpu_device *adev,
index 563a8bc..0fce850 100644 (file)
@@ -1257,9 +1257,13 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *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, mc, base);
-       amdgpu_gmc_gart_location(adev, mc);
-       amdgpu_gmc_agp_location(adev, mc);
+       if (adev->gmc.xgmi.connected_to_cpu) {
+               amdgpu_gmc_sysvm_location(adev, mc);
+       } else {
+               amdgpu_gmc_vram_location(adev, mc, base);
+               amdgpu_gmc_gart_location(adev, mc);
+               amdgpu_gmc_agp_location(adev, mc);
+       }
        /* base offset of vram pages */
        adev->vm_manager.vram_base_offset = adev->gfxhub.funcs->get_mc_fb_offset(adev);