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@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to