Intended for devices which are misreporting available/supported BAR sizes. This may be insufficient to identify some devices. The inclusion of the reported BAR sizes bitmap is to assist with identification. --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 43 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 8490a96ee25e..fde1dfdacd04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1095,6 +1095,34 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) __clear_bit(wb, adev->wb.used); } +static const struct amdgpu_rebar_quirk { + u32 chip_vendor, chip_device; + u32 subsys_vendor, subsys_device; + int reported_sizes; /* 0, or as reported by pci_rebar_get_possible_sizes */ + int available_sizes; /* bitmap (-256 for anything >= 256MB, effectively automatic) */ +} amdgpu_rebar_quirk_list[] = { + { 0, 0, 0, 0, 0, 0 } +}; + +static int amdgpu_rebar_quirk_check(struct amdgpu_device *adev, int reported_sizes) +{ + const struct pci_dev *pdev = adev->pdev; + const struct amdgpu_rebar_quirk *p = amdgpu_rebar_quirk_list; + + while (p && p->chip_device != 0) { + if (pdev->vendor == p->chip_vendor && + pdev->device == p->chip_device && + pdev->subsystem_vendor == p->subsys_vendor && + pdev->subsystem_device == p->subsys_device && + (!reported_sizes || !p->available_sizes || reported_sizes == p->reported_sizes)) { + dev_info(adev->dev, "quirk: overriding BAR possible sizes list."); + return p->available_sizes; + } + ++p; + } + return 0; +} + /** * amdgpu_device_resize_fb_bar - try to resize FB BAR * @@ -1115,6 +1143,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) unsigned i; u16 cmd; int r; + bool override_bar_sizes = amdgpu_override_bar_sizes; /* Bypass for VF */ if (amdgpu_sriov_vf(adev)) @@ -1151,10 +1180,16 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) if (!res) return 0; - if (amdgpu_override_bar_sizes) + if (override_bar_sizes) available_sizes = ~(-1 << rbar_size) & ~0xFF; - else - available_sizes = pci_rebar_get_possible_sizes(adev->pdev, 0); + else { + int q = amdgpu_rebar_quirk_check(adev, available_sizes); + if (q) + override_bar_sizes = true; + else + q = pci_rebar_get_possible_sizes(adev->pdev, 0); + available_sizes = q; + } if (max_size >= 0) { /* Cause larger sizes to be ignored unless that would leave @@ -1192,7 +1227,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) pci_release_resource(adev->pdev, 0); - r = pci_resize_resource(adev->pdev, 0, rbar_size, amdgpu_override_bar_sizes); + r = pci_resize_resource(adev->pdev, 0, rbar_size, override_bar_sizes); if (r == -ENOTSUPP) { dev_info(adev->dev, "BAR resizing not supported."); } else if (r == -ENOSPC) { -- 2.20.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx