On 7/1/26 07:53, chong li wrote: > Allow early VRAM reads to fall back to a temporary BAR0 mapping > when the normal aperture mapping has not been established yet.
Clear NAK. You are just trying to fix a symptom of incorrect initialization order here. Regards, Christian. > > 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) {
