aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch255
1 files changed, 255 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch
new file mode 100644
index 00000000..4806189b
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2935-drm-amdgpu-resize-VRAM-BAR-for-CPU-access-v6.patch
@@ -0,0 +1,255 @@
+From c679bc8114646cdafe6a8d71eb611b0cb43a90b9 Mon Sep 17 00:00:00 2001
+From: Christian Koenig <christian.koenig@amd.com>
+Date: Tue, 28 Feb 2017 10:36:43 +0100
+Subject: [PATCH 2935/4131] drm/amdgpu: resize VRAM BAR for CPU access v6
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Try to resize BAR0 to let CPU access all of VRAM.
+
+v2: rebased, style cleanups, disable mem decode before resize,
+ handle gmc_v9 as well, round size up to power of two.
+v3: handle gmc_v6 as well, release and reassign all BARs in the driver.
+v4: rename new function to amdgpu_device_resize_fb_bar,
+ reenable mem decoding only if all resources are assigned.
+v5: reorder resource release, return -ENODEV instead of BUG_ON().
+v6: squash in rebase fix
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 50 ++++++++++++++++++++++++++++++
+ drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 12 +++++--
+ drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 13 ++++++--
+ drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 13 ++++++--
+ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 14 ++++++---
+ 6 files changed, 90 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 2bfd570..6bb2277 100755
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1963,6 +1963,7 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
+ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
+ void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
+ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
++int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev);
+ void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
+ int amdgpu_ttm_init(struct amdgpu_device *adev);
+ void amdgpu_ttm_fini(struct amdgpu_device *adev);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index f2af411..dc7c6e5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -408,6 +408,9 @@ static int amdgpu_doorbell_init(struct amdgpu_device *adev)
+ adev->doorbell.ptr = NULL;
+ 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);
+@@ -723,6 +726,53 @@ int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
+ 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.
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+index daf46e4..468281f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+@@ -278,6 +278,7 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
+
+ u32 tmp;
+ int chansize, numchan;
++ int r;
+
+ tmp = RREG32(mmMC_ARB_RAMCFG);
+ if (tmp & (1 << 11)) {
+@@ -319,12 +320,17 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
+ break;
+ }
+ adev->mc.vram_width = numchan * chansize;
+- /* Could aper size report 0 ? */
+- adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
+- adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+ /* size in MB on si */
+ adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+ adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
++
++ if (!(adev->flags & AMD_IS_APU)) {
++ r = amdgpu_device_resize_fb_bar(adev);
++ if (r)
++ return r;
++ }
++ adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
++ adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+ adev->mc.visible_vram_size = adev->mc.aper_size;
+
+ /* set the gart size */
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+index 3c78948..ce7d9dd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+@@ -317,6 +317,8 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
+ */
+ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
+ {
++ int r;
++
+ adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
+ if (!adev->mc.vram_width) {
+ u32 tmp;
+@@ -362,13 +364,18 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
+ }
+ adev->mc.vram_width = numchan * chansize;
+ }
+- /* Could aper size report 0 ? */
+- adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
+- adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+ /* size in MB on si */
+ adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+ adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+
++ if (!(adev->flags & AMD_IS_APU)) {
++ r = amdgpu_device_resize_fb_bar(adev);
++ if (r)
++ return r;
++ }
++ adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
++ adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
++
+ #ifdef CONFIG_X86_64
+ if (adev->flags & AMD_IS_APU) {
+ adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+index 5e8a796..e9242ce 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+@@ -493,6 +493,8 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
+ */
+ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
+ {
++ int r;
++
+ adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
+ if (!adev->mc.vram_width) {
+ u32 tmp;
+@@ -542,13 +544,18 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
+ if (adev->mc.vram_type == AMDGPU_VRAM_TYPE_HBM)
+ adev->mc.vram_width = AMDGPU_VRAM_TYPE_HBM_WIDTH;
+ }
+- /* Could aper size report 0 ? */
+- adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
+- adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+ /* size in MB on si */
+ adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+ adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+
++ if (!(adev->flags & AMD_IS_APU)) {
++ r = amdgpu_device_resize_fb_bar(adev);
++ if (r)
++ return r;
++ }
++ adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
++ adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
++
+ #ifdef CONFIG_X86_64
+ if (adev->flags & AMD_IS_APU) {
+ adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+index 7412523..96a81dc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+@@ -655,6 +655,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
+ {
+ u32 tmp;
+ int chansize, numchan;
++ int r;
+
+ adev->mc.vram_width = amdgpu_atomfirmware_get_vram_width(adev);
+ if (!adev->mc.vram_width) {
+@@ -700,17 +701,22 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
+ adev->mc.vram_width = numchan * chansize;
+ }
+
+- /* Could aper size report 0 ? */
+- adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
+- adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+ /* size in MB on si */
+ adev->mc.mc_vram_size =
+ ((adev->flags & AMD_IS_APU) ? nbio_v7_0_get_memsize(adev) :
+ nbio_v6_1_get_memsize(adev)) * 1024ULL * 1024ULL;
+ adev->mc.real_vram_size = adev->mc.mc_vram_size;
+- adev->mc.visible_vram_size = adev->mc.aper_size;
++
++ if (!(adev->flags & AMD_IS_APU)) {
++ r = amdgpu_device_resize_fb_bar(adev);
++ if (r)
++ return r;
++ }
++ adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
++ adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+
+ /* In case the PCI BAR is larger than the actual amount of vram */
++ adev->mc.visible_vram_size = adev->mc.aper_size;
+ if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
+ adev->mc.visible_vram_size = adev->mc.real_vram_size;
+
+--
+2.7.4
+