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
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to