|
@@ -410,6 +410,9 @@ static int amdgpu_doorbell_init(struct amdgpu_device *adev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
/* doorbell bar mapping */
|
|
|
adev->doorbell.base = pci_resource_start(adev->pdev, 2);
|
|
|
adev->doorbell.size = pci_resource_len(adev->pdev, 2);
|
|
@@ -749,6 +752,53 @@ error_create:
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * amdgpu_device_resize_fb_bar - try to resize FB BAR
|
|
|
+ *
|
|
|
+ * @adev: amdgpu_device pointer
|
|
|
+ *
|
|
|
+ * Try to resize FB BAR to make all VRAM CPU accessible. We try very hard not
|
|
|
+ * to fail, but if any of the BARs is not accessible after the size we abort
|
|
|
+ * driver loading by returning -ENODEV.
|
|
|
+ */
|
|
|
+int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
|
|
|
+{
|
|
|
+ u64 space_needed = roundup_pow_of_two(adev->mc.real_vram_size);
|
|
|
+ u32 rbar_size = order_base_2(((space_needed >> 20) | 1)) - 1;
|
|
|
+ u16 cmd;
|
|
|
+ int r;
|
|
|
+
|
|
|
+ /* Disable memory decoding while we change the BAR addresses and size */
|
|
|
+ pci_read_config_word(adev->pdev, PCI_COMMAND, &cmd);
|
|
|
+ pci_write_config_word(adev->pdev, PCI_COMMAND,
|
|
|
+ cmd & ~PCI_COMMAND_MEMORY);
|
|
|
+
|
|
|
+ /* Free the VRAM and doorbell BAR, we most likely need to move both. */
|
|
|
+ amdgpu_doorbell_fini(adev);
|
|
|
+ if (adev->asic_type >= CHIP_BONAIRE)
|
|
|
+ pci_release_resource(adev->pdev, 2);
|
|
|
+
|
|
|
+ pci_release_resource(adev->pdev, 0);
|
|
|
+
|
|
|
+ r = pci_resize_resource(adev->pdev, 0, rbar_size);
|
|
|
+ if (r == -ENOSPC)
|
|
|
+ DRM_INFO("Not enough PCI address space for a large BAR.");
|
|
|
+ else if (r && r != -ENOTSUPP)
|
|
|
+ DRM_ERROR("Problem resizing BAR0 (%d).", r);
|
|
|
+
|
|
|
+ pci_assign_unassigned_bus_resources(adev->pdev->bus);
|
|
|
+
|
|
|
+ /* When the doorbell or fb BAR isn't available we have no chance of
|
|
|
+ * using the device.
|
|
|
+ */
|
|
|
+ r = amdgpu_doorbell_init(adev);
|
|
|
+ if (r || (pci_resource_flags(adev->pdev, 0) & IORESOURCE_UNSET))
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ pci_write_config_word(adev->pdev, PCI_COMMAND, cmd);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* GPU helpers function.
|