diff options
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.patch | 255 |
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 + |