The A+A VF FB BAR is not usable, so resolve its aperture from SRAT in
GMC early_init. Skip later aperture assignment for SPM-backed devices,
and restrict the existing mmhub-based override to native A+A and APU.

The GPU reaches its HBM at a system physical address, so
vram_base_offset becomes aper_base as well, which makes PDB0 map GPU
address 0 onto that address.

The XGMI node segment size comes from the same place: once early_init
has resolved the aperture, use its size rather than the value derived
from the register, which does not describe the VF partition.

v2:
- Use (sriov_vf || passthrough) and amdgpu_virt_vram_is_spm()
  instead of connected_to_cpu for the SRAT aperture and node segment
  size.

v3:
- Resolve the SRAT aperture in GMC early_init and skip later aperture
  assignment in mc_init for SPM-backed devices.
- Rely on amdgpu_virt_vram_is_spm() without redundant VF/passthrough
  checks.

Signed-off-by: Zhigang Luo <[email protected]>
Signed-off-by: Fangsheng Huang <[email protected]>
Signed-off-by: YuBiao Wang <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c    | 53 ++++++++++++++++++-----
 drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c |  5 ++-
 2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
index 0cc73982ed6f..c88ce5b94863 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
@@ -638,6 +638,7 @@ static void gmc_v12_0_set_gfxhub_funcs(struct amdgpu_device 
*adev)
 static int gmc_v12_0_early_init(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
+       int r;
 
        if (adev->smuio.funcs &&
            adev->smuio.funcs->is_host_gpu_xgmi_supported)
@@ -660,6 +661,14 @@ static int gmc_v12_0_early_init(struct amdgpu_ip_block 
*ip_block)
        gmc_v12_0_set_mmhub_funcs(adev);
        gmc_v12_0_set_umc_funcs(adev);
 
+       if (amdgpu_virt_vram_is_spm(adev)) {
+               r = amdgpu_acpi_find_gpu_memory_in_srat(adev,
+                                                       &adev->gmc.aper_base,
+                                                       &adev->gmc.aper_size);
+               if (r)
+                       return r;
+       }
+
        adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
        adev->gmc.shared_aperture_end =
                adev->gmc.shared_aperture_start + (4ULL << 30) - 1;
@@ -706,10 +715,19 @@ static void gmc_v12_0_vram_gtt_location(struct 
amdgpu_device *adev,
                        amdgpu_gmc_agp_location(adev, mc);
        }
        /* base offset of vram pages */
-       if (amdgpu_sriov_vf(adev))
+       if (amdgpu_virt_vram_is_spm(adev)) {
+               /*
+                * For SPM-backed VRAM, PDB0 entries use PTE_SYSTEM, so the
+                * address is a system physical address. vram_base_offset must
+                * be aper_base so PDB0 maps GPU address 0 onto the HBM system
+                * physical address.
+                */
+               adev->vm_manager.vram_base_offset = adev->gmc.aper_base;
+       } else if (amdgpu_sriov_vf(adev)) {
                adev->vm_manager.vram_base_offset = 0;
-       else
+       } else {
                adev->vm_manager.vram_base_offset = 
adev->mmhub.funcs->get_mc_fb_offset(adev);
+       }
 
        adev->vm_manager.vram_base_offset +=
                adev->gmc.xgmi.physical_node_id * 
adev->gmc.xgmi.node_segment_size;
@@ -746,17 +764,28 @@ static int gmc_v12_0_mc_init(struct amdgpu_device *adev)
                        return r;
        }
 
-       adev->gmc.aper_base = pci_resource_start(adev->pdev, 0);
-       adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
-
 #ifdef CONFIG_X86_64
-       if (((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) ||
-           (adev->gmc.xgmi.connected_to_cpu)) {
-               adev->gmc.aper_base =
-                       adev->mmhub.funcs->get_mc_fb_offset(adev) +
-                       adev->gmc.xgmi.physical_node_id *
-                       adev->gmc.xgmi.node_segment_size;
-               adev->gmc.aper_size = adev->gmc.real_vram_size;
+       /*
+        * SPM-backed devices resolve the aperture from SRAT during early_init.
+        * For native A+A (non-VF) or APU, override aper_base using mmhub
+        * offset. Otherwise derive the aperture from BAR 0.
+        */
+       if (!amdgpu_virt_vram_is_spm(adev)) {
+               if (!amdgpu_sriov_vf(adev) &&
+                   (((adev->flags & AMD_IS_APU) &&
+                     !amdgpu_passthrough(adev)) ||
+                    adev->gmc.xgmi.connected_to_cpu)) {
+                       adev->gmc.aper_base =
+                               adev->mmhub.funcs->get_mc_fb_offset(adev) +
+                               adev->gmc.xgmi.physical_node_id *
+                               adev->gmc.xgmi.node_segment_size;
+                       adev->gmc.aper_size = adev->gmc.real_vram_size;
+               } else {
+                       adev->gmc.aper_base =
+                               pci_resource_start(adev->pdev, 0);
+                       adev->gmc.aper_size =
+                               pci_resource_len(adev->pdev, 0);
+               }
        }
 #endif
        /* In case the PCI BAR is larger than the actual amount of vram */
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c 
b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c
index 4495d52b4b07..4c0a2d671cfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c
@@ -154,7 +154,10 @@ static int mmhub_v4_2_0_get_xgmi_info(struct amdgpu_device 
*adev)
        if (adev->gmc.xgmi.physical_node_id > max_physical_node_id)
                return -EINVAL;
 
-       adev->gmc.xgmi.node_segment_size = seg_size;
+       if (amdgpu_virt_vram_is_spm(adev) && adev->gmc.aper_size)
+               adev->gmc.xgmi.node_segment_size = adev->gmc.aper_size;
+       else
+               adev->gmc.xgmi.node_segment_size = seg_size;
 
        return 0;
 }
-- 
2.43.0

Reply via email to