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
