aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch134
1 files changed, 134 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch
new file mode 100644
index 00000000..90335bc9
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4606-drm-amdgpu-implement-patch-for-fixing-a-known-bug.patch
@@ -0,0 +1,134 @@
+From f9dbee6ad7ff29c4dfd78657fb238d1e8b8a05cd Mon Sep 17 00:00:00 2001
+From: Boyuan Zhang <boyuan.zhang@amd.com>
+Date: Wed, 30 May 2018 14:57:16 -0400
+Subject: [PATCH 4606/5725] drm/amdgpu: implement patch for fixing a known bug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Implement a patch to maunally reset read pointer
+
+v2: using ring assignment instead of amdgpu_ring_write. adding comments
+for each steps in the patch function.
+v3: fixing a typo bug.
+v4: fixing a bug in v3.
+
+Signed-off-by: Boyuan Zhang <boyuan.zhang@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 92 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 92 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+index 9ded8ef..5adb2d9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+@@ -40,6 +40,7 @@ static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
++static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr);
+
+ /**
+ * vcn_v1_0_early_init - set function pointers
+@@ -1479,6 +1480,97 @@ static void vcn_v1_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count)
+ }
+ }
+
++static void vcn_v1_0_jpeg_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
++{
++ struct amdgpu_device *adev = ring->adev;
++ ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
++ if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
++ ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
++ ring->ring[(*ptr)++] = 0;
++ ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0);
++ } else {
++ ring->ring[(*ptr)++] = reg_offset;
++ ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0);
++ }
++ ring->ring[(*ptr)++] = val;
++}
++
++static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr)
++{
++ struct amdgpu_device *adev = ring->adev;
++
++ uint32_t reg, reg_offset, val, mask, i;
++
++ // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW);
++ reg_offset = (reg << 2);
++ val = lower_32_bits(ring->gpu_addr);
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++
++ // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH);
++ reg_offset = (reg << 2);
++ val = upper_32_bits(ring->gpu_addr);
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++
++ // 3rd to 5th: issue MEM_READ commands
++ for (i = 0; i <= 2; i++) {
++ ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2);
++ ring->ring[ptr++] = 0;
++ }
++
++ // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
++ reg_offset = (reg << 2);
++ val = 0x13;
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++
++ // 7th: program mmUVD_JRBC_RB_REF_DATA
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA);
++ reg_offset = (reg << 2);
++ val = 0x1;
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++
++ // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
++ reg_offset = (reg << 2);
++ val = 0x1;
++ mask = 0x1;
++
++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0);
++ ring->ring[ptr++] = 0x01400200;
++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0);
++ ring->ring[ptr++] = val;
++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
++ if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
++ ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
++ ring->ring[ptr++] = 0;
++ ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3);
++ } else {
++ ring->ring[ptr++] = reg_offset;
++ ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3);
++ }
++ ring->ring[ptr++] = mask;
++
++ //9th to 21st: insert no-op
++ for (i = 0; i <= 12; i++) {
++ ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
++ ring->ring[ptr++] = 0;
++ }
++
++ //22nd: reset mmUVD_JRBC_RB_RPTR
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_RPTR);
++ reg_offset = (reg << 2);
++ val = 0;
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++
++ //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch
++ reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
++ reg_offset = (reg << 2);
++ val = 0x12;
++ vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
++}
++
+ static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,
+ struct amdgpu_irq_src *source,
+ unsigned type,
+--
+2.7.4
+