Allow early VRAM reads to fall back to a temporary BAR0 mapping when the normal aperture mapping has not been established yet.
Signed-off-by: chong li <[email protected]> Co-authored-by: Cursor <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 43 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5442a1fc1c37..610d82b79de3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -743,6 +743,44 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos, drm_dev_exit(idx); } +static int amdgpu_device_read_fb_via_bar0(struct amdgpu_device *adev, + u64 offset, void *buf, size_t size) +{ + resource_size_t bar_start, bar_size, map_base; + void __iomem *vram; + size_t map_offset, map_size; + unsigned long flags; + u64 end; + + if (!buf || !size) + return -EINVAL; + + flags = pci_resource_flags(adev->pdev, 0); + if ((flags & IORESOURCE_UNSET) || !(flags & IORESOURCE_MEM)) + return -EINVAL; + + bar_size = pci_resource_len(adev->pdev, 0); + if (!bar_size) + return -ENODEV; + + if (check_add_overflow(offset, size, &end) || end > bar_size) + return -EINVAL; + + bar_start = pci_resource_start(adev->pdev, 0); + map_offset = offset_in_page(offset); + map_base = bar_start + (offset & PAGE_MASK); + map_size = PAGE_ALIGN(map_offset + size); + + vram = ioremap_wc(map_base, map_size); + if (!vram) + return -ENOMEM; + + memcpy_fromio(buf, (u8 __iomem *)vram + map_offset, size); + iounmap(vram); + + return 0; +} + /** * amdgpu_device_aper_access - access vram by vram aperture * @@ -762,8 +800,11 @@ size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos, size_t count = 0; uint64_t last; - if (!adev->mman.aper_base_kaddr) + if (!adev->mman.aper_base_kaddr) { + if (!write && !amdgpu_device_read_fb_via_bar0(adev, pos, buf, size)) + return size; return 0; + } last = min(pos + size, adev->gmc.visible_vram_size); if (last > pos) { -- 2.48.1
