[PATCH 7/8] amdgpu: implement a BAR size quirks list
Darren Salt
devspam at moreofthesa.me.uk
Sun Dec 13 22:53:22 UTC 2020
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
More information about the amd-gfx
mailing list