diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0221-drm-amdgpu-implement-VCE-two-instances-support.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0221-drm-amdgpu-implement-VCE-two-instances-support.patch | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0221-drm-amdgpu-implement-VCE-two-instances-support.patch b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0221-drm-amdgpu-implement-VCE-two-instances-support.patch new file mode 100644 index 00000000..91a563db --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0221-drm-amdgpu-implement-VCE-two-instances-support.patch @@ -0,0 +1,213 @@ +From 5bbc553a1acce5d1792ba778273ffbea5af1695d Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Wed, 6 May 2015 15:20:41 -0400 +Subject: [PATCH 0221/1050] drm/amdgpu: implement VCE two instances support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VCE 3.0 has two indentical instances in the engine, they share +the same registers name in differrent memory block distinguished +by the grbm_gfx_index, we set to master instance after init, it +will dispatch task to slave instance. These two instances will +share the same firmware, but have their own stacks and heaps. + +v2: add mutex for using grbm_gfx_index + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 141 +++++++++++++++++++++------------- + 1 file changed, 87 insertions(+), 54 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +index ee29436f..57e0e16 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +@@ -34,12 +34,16 @@ + #include "vce/vce_3_0_sh_mask.h" + #include "oss/oss_2_0_d.h" + #include "oss/oss_2_0_sh_mask.h" ++#include "gca/gfx_8_0_d.h" ++ ++#define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 ++#define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 + + #define VCE_V3_0_FW_SIZE (384 * 1024) + #define VCE_V3_0_STACK_SIZE (64 * 1024) + #define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) + +-static void vce_v3_0_mc_resume(struct amdgpu_device *adev); ++static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx); + static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); + static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); + +@@ -104,12 +108,70 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) + static int vce_v3_0_start(struct amdgpu_device *adev) + { + struct amdgpu_ring *ring; +- int i, j, r; ++ int idx, i, j, r; ++ ++ mutex_lock(&adev->grbm_idx_mutex); ++ for (idx = 0; idx < 2; ++idx) { ++ if(idx == 0) ++ WREG32_P(mmGRBM_GFX_INDEX, 0, ++ ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); ++ else ++ WREG32_P(mmGRBM_GFX_INDEX, ++ GRBM_GFX_INDEX__VCE_INSTANCE_MASK, ++ ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); ++ ++ vce_v3_0_mc_resume(adev, idx); ++ ++ /* set BUSY flag */ ++ WREG32_P(mmVCE_STATUS, 1, ~1); ++ ++ WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ++ ~VCE_VCPU_CNTL__CLK_EN_MASK); ++ ++ WREG32_P(mmVCE_SOFT_RESET, ++ VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, ++ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); ++ ++ mdelay(100); ++ ++ WREG32_P(mmVCE_SOFT_RESET, 0, ++ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); ++ ++ for (i = 0; i < 10; ++i) { ++ uint32_t status; ++ for (j = 0; j < 100; ++j) { ++ status = RREG32(mmVCE_STATUS); ++ if (status & 2) ++ break; ++ mdelay(10); ++ } ++ r = 0; ++ if (status & 2) ++ break; ++ ++ DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); ++ WREG32_P(mmVCE_SOFT_RESET, ++ VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, ++ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); ++ mdelay(10); ++ WREG32_P(mmVCE_SOFT_RESET, 0, ++ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); ++ mdelay(10); ++ r = -1; ++ } ++ ++ /* clear BUSY flag */ ++ WREG32_P(mmVCE_STATUS, 0, ~1); + +- vce_v3_0_mc_resume(adev); ++ if (r) { ++ DRM_ERROR("VCE not responding, giving up!!!\n"); ++ mutex_unlock(&adev->grbm_idx_mutex); ++ return r; ++ } ++ } + +- /* set BUSY flag */ +- WREG32_P(mmVCE_STATUS, 1, ~1); ++ WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); ++ mutex_unlock(&adev->grbm_idx_mutex); + + ring = &adev->vce.ring[0]; + WREG32(mmVCE_RB_RPTR, ring->wptr); +@@ -125,45 +187,6 @@ static int vce_v3_0_start(struct amdgpu_device *adev) + WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); + WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); + +- WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK); +- +- WREG32_P(mmVCE_SOFT_RESET, +- VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, +- ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); +- +- mdelay(100); +- +- WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); +- +- for (i = 0; i < 10; ++i) { +- uint32_t status; +- for (j = 0; j < 100; ++j) { +- status = RREG32(mmVCE_STATUS); +- if (status & 2) +- break; +- mdelay(10); +- } +- r = 0; +- if (status & 2) +- break; +- +- DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); +- WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, +- ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); +- mdelay(10); +- WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); +- mdelay(10); +- r = -1; +- } +- +- /* clear BUSY flag */ +- WREG32_P(mmVCE_STATUS, 0, ~1); +- +- if (r) { +- DRM_ERROR("VCE not responding, giving up!!!\n"); +- return r; +- } +- + return 0; + } + +@@ -292,7 +315,7 @@ static int vce_v3_0_resume(struct amdgpu_device *adev) + return r; + } + +-static void vce_v3_0_mc_resume(struct amdgpu_device *adev) ++static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) + { + uint32_t offset, size; + +@@ -313,15 +336,25 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev) + WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); + WREG32(mmVCE_VCPU_CACHE_SIZE0, size); + +- offset += size; +- size = VCE_V3_0_STACK_SIZE; +- WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); +- WREG32(mmVCE_VCPU_CACHE_SIZE1, size); +- +- offset += size; +- size = VCE_V3_0_DATA_SIZE; +- WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); +- WREG32(mmVCE_VCPU_CACHE_SIZE2, size); ++ if (idx == 0) { ++ offset += size; ++ size = VCE_V3_0_STACK_SIZE; ++ WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); ++ WREG32(mmVCE_VCPU_CACHE_SIZE1, size); ++ offset += size; ++ size = VCE_V3_0_DATA_SIZE; ++ WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); ++ WREG32(mmVCE_VCPU_CACHE_SIZE2, size); ++ } else { ++ offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE; ++ size = VCE_V3_0_STACK_SIZE; ++ WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff); ++ WREG32(mmVCE_VCPU_CACHE_SIZE1, size); ++ offset += size; ++ size = VCE_V3_0_DATA_SIZE; ++ WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff); ++ WREG32(mmVCE_VCPU_CACHE_SIZE2, size); ++ } + + WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); + +-- +1.9.1 + |