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 0f05a75be34e..442eca5fc6a4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -897,6 +897,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 * @@ -918,6 +946,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) u16 cmd; int r; bool nospc = false; + bool override_bar_sizes = amdgpu_override_bar_sizes; /* Bypass for VF */ if (amdgpu_sriov_vf(adev)) @@ -954,10 +983,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 @@ -999,7 +1034,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) rbar_size >= 0; rbar_size = fls(available_sizes & ~(-1 << rbar_size)) - 1 ) { - 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 == 0) { break; } else if (r == -ENOTSUPP) { -- 2.20.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx