diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4445-drm-amdgpu-separate-JPEG1.0-code-out-from-VCN1.0.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4445-drm-amdgpu-separate-JPEG1.0-code-out-from-VCN1.0.patch | 1252 |
1 files changed, 1252 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4445-drm-amdgpu-separate-JPEG1.0-code-out-from-VCN1.0.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4445-drm-amdgpu-separate-JPEG1.0-code-out-from-VCN1.0.patch new file mode 100644 index 00000000..0cf4e9ae --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4445-drm-amdgpu-separate-JPEG1.0-code-out-from-VCN1.0.patch @@ -0,0 +1,1252 @@ +From 61fef67dd52e80e895970d745aff4fdec783ad80 Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Fri, 8 Nov 2019 10:17:06 -0500 +Subject: [PATCH 4445/4736] drm/amdgpu: separate JPEG1.0 code out from VCN1.0 + +For VCN1.0, the separation is just in code wise, JPEG1.0 HW is still +included in the VCN1.0 HW. + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/Makefile | 3 +- + drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c | 584 +++++++++++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h | 32 ++ + drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 481 +------------------- + 4 files changed, 630 insertions(+), 470 deletions(-) + create mode 100644 drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c + create mode 100644 drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h + +diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile +index e73f71bd99c2..62ef3d7955d9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/Makefile ++++ b/drivers/gpu/drm/amd/amdgpu/Makefile +@@ -154,7 +154,8 @@ amdgpu-y += \ + vcn_v1_0.o \ + vcn_v2_0.o \ + vcn_v2_5.o \ +- amdgpu_jpeg.o ++ amdgpu_jpeg.o \ ++ jpeg_v1_0.o + + # add ATHUB block + amdgpu-y += \ +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c +new file mode 100644 +index 000000000000..553506df077d +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c +@@ -0,0 +1,584 @@ ++/* ++ * Copyright 2019 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "amdgpu.h" ++#include "amdgpu_jpeg.h" ++#include "soc15.h" ++#include "soc15d.h" ++ ++#include "vcn/vcn_1_0_offset.h" ++#include "vcn/vcn_1_0_sh_mask.h" ++ ++static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); ++static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev); ++ ++static void jpeg_v1_0_decode_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(JPEG, 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 jpeg_v1_0_decode_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(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW); ++ reg_offset = (reg << 2); ++ val = lower_32_bits(ring->gpu_addr); ++ jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); ++ ++ // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH ++ reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH); ++ reg_offset = (reg << 2); ++ val = upper_32_bits(ring->gpu_addr); ++ jpeg_v1_0_decode_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(JPEG, 0, mmUVD_JRBC_RB_CNTL); ++ reg_offset = (reg << 2); ++ val = 0x13; ++ jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); ++ ++ // 7th: program mmUVD_JRBC_RB_REF_DATA ++ reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA); ++ reg_offset = (reg << 2); ++ val = 0x1; ++ jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); ++ ++ // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL ++ reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); ++ reg_offset = (reg << 2); ++ val = 0x1; ++ mask = 0x1; ++ ++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0); ++ ring->ring[ptr++] = 0x01400200; ++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0); ++ ring->ring[ptr++] = val; ++ ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 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(JPEG, 0, mmUVD_JRBC_RB_RPTR); ++ reg_offset = (reg << 2); ++ val = 0; ++ jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); ++ ++ //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch ++ reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); ++ reg_offset = (reg << 2); ++ val = 0x12; ++ jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_get_rptr - get read pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Returns the current hardware read pointer ++ */ ++static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_get_wptr - get write pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Returns the current hardware write pointer ++ */ ++static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_set_wptr - set write pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Commits the write pointer to the hardware ++ */ ++static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_insert_start - insert a start command ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Write a start command to the ring. ++ */ ++static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x68e04); ++ ++ amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x80010000); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_insert_end - insert a end command ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Write a end command to the ring. ++ */ ++static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x68e04); ++ ++ amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x00010000); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command ++ * ++ * @ring: amdgpu_ring pointer ++ * @fence: fence to emit ++ * ++ * Write a fence and a trap command to the ring. ++ */ ++static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, ++ unsigned flags) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, seq); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, seq); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, lower_32_bits(addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, upper_32_bits(addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x8); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); ++ amdgpu_ring_write(ring, 0); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x01400200); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, seq); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, lower_32_bits(addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, upper_32_bits(addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); ++ amdgpu_ring_write(ring, 0xffffffff); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x3fbc); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(0, 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x1); ++ ++ /* emit trap */ ++ amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); ++ amdgpu_ring_write(ring, 0); ++} ++ ++/** ++ * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer ++ * ++ * @ring: amdgpu_ring pointer ++ * @ib: indirect buffer to execute ++ * ++ * Write ring commands to execute the indirect buffer. ++ */ ++static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring, ++ struct amdgpu_job *job, ++ struct amdgpu_ib *ib, ++ uint32_t flags) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ unsigned vmid = AMDGPU_JOB_GET_VMID(job); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, (vmid | (vmid << 4))); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, (vmid | (vmid << 4))); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, ib->length_dw); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); ++ amdgpu_ring_write(ring, 0); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x01400200); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x2); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); ++ amdgpu_ring_write(ring, 0x2); ++} ++ ++static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring, ++ uint32_t reg, uint32_t val, ++ uint32_t mask) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ uint32_t reg_offset = (reg << 2); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, 0x01400200); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); ++ amdgpu_ring_write(ring, val); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); ++ if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || ++ ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { ++ amdgpu_ring_write(ring, 0); ++ amdgpu_ring_write(ring, ++ PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); ++ } else { ++ amdgpu_ring_write(ring, reg_offset); ++ amdgpu_ring_write(ring, ++ PACKETJ(0, 0, 0, PACKETJ_TYPE3)); ++ } ++ amdgpu_ring_write(ring, mask); ++} ++ ++static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring, ++ unsigned vmid, uint64_t pd_addr) ++{ ++ struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; ++ uint32_t data0, data1, mask; ++ ++ pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); ++ ++ /* wait for register write */ ++ data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; ++ data1 = lower_32_bits(pd_addr); ++ mask = 0xffffffff; ++ jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask); ++} ++ ++static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring, ++ uint32_t reg, uint32_t val) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ uint32_t reg_offset = (reg << 2); ++ ++ amdgpu_ring_write(ring, ++ PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); ++ if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || ++ ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { ++ amdgpu_ring_write(ring, 0); ++ amdgpu_ring_write(ring, ++ PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); ++ } else { ++ amdgpu_ring_write(ring, reg_offset); ++ amdgpu_ring_write(ring, ++ PACKETJ(0, 0, 0, PACKETJ_TYPE0)); ++ } ++ amdgpu_ring_write(ring, val); ++} ++ ++static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count) ++{ ++ int i; ++ ++ WARN_ON(ring->wptr % 2 || count % 2); ++ ++ for (i = 0; i < count / 2; i++) { ++ amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); ++ amdgpu_ring_write(ring, 0); ++ } ++} ++ ++static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev, ++ struct amdgpu_irq_src *source, ++ unsigned type, ++ enum amdgpu_interrupt_state state) ++{ ++ return 0; ++} ++ ++static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev, ++ struct amdgpu_irq_src *source, ++ struct amdgpu_iv_entry *entry) ++{ ++ DRM_DEBUG("IH: JPEG decode TRAP\n"); ++ ++ switch (entry->src_id) { ++ case 126: ++ amdgpu_fence_process(&adev->jpeg.inst->ring_dec); ++ break; ++ default: ++ DRM_ERROR("Unhandled interrupt: %d %d\n", ++ entry->src_id, entry->src_data[0]); ++ break; ++ } ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v1_0_early_init - set function pointers ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * Set ring and irq function pointers ++ */ ++int jpeg_v1_0_early_init(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ ++ adev->jpeg.num_jpeg_inst = 1; ++ ++ jpeg_v1_0_set_dec_ring_funcs(adev); ++ jpeg_v1_0_set_irq_funcs(adev); ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v1_0_sw_init - sw init for JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ */ ++int jpeg_v1_0_sw_init(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ struct amdgpu_ring *ring; ++ int r; ++ ++ /* JPEG TRAP */ ++ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq); ++ if (r) ++ return r; ++ ++ ring = &adev->jpeg.inst->ring_dec; ++ sprintf(ring->name, "jpeg_dec"); ++ r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0); ++ if (r) ++ return r; ++ ++ adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch = ++ SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH); ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v1_0_sw_fini - sw fini for JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * JPEG free up sw allocation ++ */ ++void jpeg_v1_0_sw_fini(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ ++ amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec); ++} ++ ++/** ++ * jpeg_v1_0_start - start JPEG block ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * Setup and start the JPEG block ++ */ ++void jpeg_v1_0_start(struct amdgpu_device *adev, int mode) ++{ ++ struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; ++ ++ if (mode == 0) { ++ WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0); ++ WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK | ++ UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); ++ WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0); ++ WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0); ++ } WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); ++ ++ /* initialize wptr */ ++ ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); ++ ++ /* copy patch commands to the jpeg ring */ ++ jpeg_v1_0_decode_ring_set_patch_ring(ring, ++ (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); ++} ++ ++static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = { ++ .type = AMDGPU_RING_TYPE_VCN_JPEG, ++ .align_mask = 0xf, ++ .nop = PACKET0(0x81ff, 0), ++ .support_64bit_ptrs = false, ++ .no_user_fence = true, ++ .vmhub = AMDGPU_MMHUB_0, ++ .extra_dw = 64, ++ .get_rptr = jpeg_v1_0_decode_ring_get_rptr, ++ .get_wptr = jpeg_v1_0_decode_ring_get_wptr, ++ .set_wptr = jpeg_v1_0_decode_ring_set_wptr, ++ .emit_frame_size = ++ 6 + 6 + /* hdp invalidate / flush */ ++ SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + ++ SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + ++ 8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */ ++ 26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */ ++ 6, ++ .emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */ ++ .emit_ib = jpeg_v1_0_decode_ring_emit_ib, ++ .emit_fence = jpeg_v1_0_decode_ring_emit_fence, ++ .emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush, ++ .test_ring = amdgpu_jpeg_dec_ring_test_ring, ++ .test_ib = amdgpu_jpeg_dec_ring_test_ib, ++ .insert_nop = jpeg_v1_0_decode_ring_nop, ++ .insert_start = jpeg_v1_0_decode_ring_insert_start, ++ .insert_end = jpeg_v1_0_decode_ring_insert_end, ++ .pad_ib = amdgpu_ring_generic_pad_ib, ++ .begin_use = amdgpu_vcn_ring_begin_use, ++ .end_use = amdgpu_vcn_ring_end_use, ++ .emit_wreg = jpeg_v1_0_decode_ring_emit_wreg, ++ .emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait, ++ .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, ++}; ++ ++static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) ++{ ++ adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs; ++ DRM_INFO("JPEG decode is enabled in VM mode\n"); ++} ++ ++static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = { ++ .set = jpeg_v1_0_set_interrupt_state, ++ .process = jpeg_v1_0_process_interrupt, ++}; ++ ++static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev) ++{ ++ adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs; ++} +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h +new file mode 100644 +index 000000000000..bbf33a6a3972 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright 2019 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __JPEG_V1_0_H__ ++#define __JPEG_V1_0_H__ ++ ++int jpeg_v1_0_early_init(void *handle); ++int jpeg_v1_0_sw_init(void *handle); ++void jpeg_v1_0_sw_fini(void *handle); ++void jpeg_v1_0_start(struct amdgpu_device *adev, int mode); ++ ++#endif /*__JPEG_V1_0_H__*/ +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +index b23362102e51..ef3cc37802ff 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +@@ -36,6 +36,7 @@ + #include "mmhub/mmhub_9_1_sh_mask.h" + + #include "ivsrcid/vcn/irqsrcs_vcn_1_0.h" ++#include "jpeg_v1_0.h" + + #define mmUVD_RBC_XX_IB_REG_CHECK 0x05ab + #define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1 +@@ -45,9 +46,7 @@ + static int vcn_v1_0_stop(struct amdgpu_device *adev); + 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); + static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state); + static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev, + struct dpg_pause_state *new_state); +@@ -68,9 +67,10 @@ static int vcn_v1_0_early_init(void *handle) + + vcn_v1_0_set_dec_ring_funcs(adev); + vcn_v1_0_set_enc_ring_funcs(adev); +- vcn_v1_0_set_jpeg_ring_funcs(adev); + vcn_v1_0_set_irq_funcs(adev); + ++ jpeg_v1_0_early_init(handle); ++ + return 0; + } + +@@ -101,11 +101,6 @@ static int vcn_v1_0_sw_init(void *handle) + return r; + } + +- /* VCN JPEG TRAP */ +- r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->vcn.inst->irq); +- if (r) +- return r; +- + r = amdgpu_vcn_sw_init(adev); + if (r) + return r; +@@ -149,17 +144,11 @@ static int vcn_v1_0_sw_init(void *handle) + return r; + } + +- ring = &adev->vcn.inst->ring_jpeg; +- sprintf(ring->name, "vcn_jpeg"); +- r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0); +- if (r) +- return r; +- + adev->vcn.pause_dpg_mode = vcn_v1_0_pause_dpg_mode; +- adev->vcn.internal.jpeg_pitch = adev->vcn.inst->external.jpeg_pitch = +- SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH); + +- return 0; ++ r = jpeg_v1_0_sw_init(handle); ++ ++ return r; + } + + /** +@@ -178,6 +167,8 @@ static int vcn_v1_0_sw_fini(void *handle) + if (r) + return r; + ++ jpeg_v1_0_sw_fini(handle); ++ + r = amdgpu_vcn_sw_fini(adev); + + return r; +@@ -207,7 +198,7 @@ static int vcn_v1_0_hw_init(void *handle) + goto done; + } + +- ring = &adev->vcn.inst->ring_jpeg; ++ ring = &adev->jpeg.inst->ring_dec; + r = amdgpu_ring_test_helper(ring); + if (r) + goto done; +@@ -947,22 +938,7 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev) + WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); + +- ring = &adev->vcn.inst->ring_jpeg; +- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0); +- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK | +- UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); +- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); +- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); +- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, 0); +- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, 0); +- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); +- +- /* initialize wptr */ +- ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); +- +- /* copy patch commands to the jpeg ring */ +- vcn_v1_0_jpeg_ring_set_patch_ring(ring, +- (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); ++ jpeg_v1_0_start(adev, 0); + + return 0; + } +@@ -1106,13 +1082,7 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) + WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, + ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); + +- /* initialize JPEG wptr */ +- ring = &adev->vcn.inst->ring_jpeg; +- ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); +- +- /* copy patch commands to the jpeg ring */ +- vcn_v1_0_jpeg_ring_set_patch_ring(ring, +- (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); ++ jpeg_v1_0_start(adev, 1); + + return 0; + } +@@ -1316,7 +1286,7 @@ static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev, + UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code); + + /* Restore */ +- ring = &adev->vcn.inst->ring_jpeg; ++ ring = &adev->jpeg.inst->ring_dec; + WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0); + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, + UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK | +@@ -1716,389 +1686,6 @@ static void vcn_v1_0_enc_ring_emit_wreg(struct amdgpu_ring *ring, + amdgpu_ring_write(ring, val); + } + +- +-/** +- * vcn_v1_0_jpeg_ring_get_rptr - get read pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Returns the current hardware read pointer +- */ +-static uint64_t vcn_v1_0_jpeg_ring_get_rptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_get_wptr - get write pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Returns the current hardware write pointer +- */ +-static uint64_t vcn_v1_0_jpeg_ring_get_wptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_set_wptr - set write pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Commits the write pointer to the hardware +- */ +-static void vcn_v1_0_jpeg_ring_set_wptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_insert_start - insert a start command +- * +- * @ring: amdgpu_ring pointer +- * +- * Write a start command to the ring. +- */ +-static void vcn_v1_0_jpeg_ring_insert_start(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x68e04); +- +- amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x80010000); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_insert_end - insert a end command +- * +- * @ring: amdgpu_ring pointer +- * +- * Write a end command to the ring. +- */ +-static void vcn_v1_0_jpeg_ring_insert_end(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x68e04); +- +- amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x00010000); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_emit_fence - emit an fence & trap command +- * +- * @ring: amdgpu_ring pointer +- * @fence: fence to emit +- * +- * Write a fence and a trap command to the ring. +- */ +-static void vcn_v1_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, +- unsigned flags) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, seq); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, seq); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x8); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); +- amdgpu_ring_write(ring, 0); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x01400200); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, seq); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); +- amdgpu_ring_write(ring, 0xffffffff); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x3fbc); +- +- amdgpu_ring_write(ring, +- PACKETJ(0, 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x1); +- +- /* emit trap */ +- amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); +- amdgpu_ring_write(ring, 0); +-} +- +-/** +- * vcn_v1_0_jpeg_ring_emit_ib - execute indirect buffer +- * +- * @ring: amdgpu_ring pointer +- * @ib: indirect buffer to execute +- * +- * Write ring commands to execute the indirect buffer. +- */ +-static void vcn_v1_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, +- struct amdgpu_job *job, +- struct amdgpu_ib *ib, +- uint32_t flags) +-{ +- struct amdgpu_device *adev = ring->adev; +- unsigned vmid = AMDGPU_JOB_GET_VMID(job); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, ib->length_dw); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); +- +- amdgpu_ring_write(ring, +- PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); +- amdgpu_ring_write(ring, 0); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x01400200); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x2); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); +- amdgpu_ring_write(ring, 0x2); +-} +- +-static void vcn_v1_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring, +- uint32_t reg, uint32_t val, +- uint32_t mask) +-{ +- struct amdgpu_device *adev = ring->adev; +- uint32_t reg_offset = (reg << 2); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x01400200); +- +- amdgpu_ring_write(ring, +- PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, val); +- +- amdgpu_ring_write(ring, +- 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))) { +- amdgpu_ring_write(ring, 0); +- amdgpu_ring_write(ring, +- PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); +- } else { +- amdgpu_ring_write(ring, reg_offset); +- amdgpu_ring_write(ring, +- PACKETJ(0, 0, 0, PACKETJ_TYPE3)); +- } +- amdgpu_ring_write(ring, mask); +-} +- +-static void vcn_v1_0_jpeg_ring_emit_vm_flush(struct amdgpu_ring *ring, +- unsigned vmid, uint64_t pd_addr) +-{ +- struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; +- uint32_t data0, data1, mask; +- +- pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); +- +- /* wait for register write */ +- data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; +- data1 = lower_32_bits(pd_addr); +- mask = 0xffffffff; +- vcn_v1_0_jpeg_ring_emit_reg_wait(ring, data0, data1, mask); +-} +- +-static void vcn_v1_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring, +- uint32_t reg, uint32_t val) +-{ +- struct amdgpu_device *adev = ring->adev; +- uint32_t reg_offset = (reg << 2); +- +- amdgpu_ring_write(ring, +- 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))) { +- amdgpu_ring_write(ring, 0); +- amdgpu_ring_write(ring, +- PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); +- } else { +- amdgpu_ring_write(ring, reg_offset); +- amdgpu_ring_write(ring, +- PACKETJ(0, 0, 0, PACKETJ_TYPE0)); +- } +- amdgpu_ring_write(ring, val); +-} +- +-static void vcn_v1_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count) +-{ +- int i; +- +- WARN_ON(ring->wptr % 2 || count % 2); +- +- for (i = 0; i < count / 2; i++) { +- amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); +- amdgpu_ring_write(ring, 0); +- } +-} +- +-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, +@@ -2123,9 +1710,6 @@ static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev, + case 120: + amdgpu_fence_process(&adev->vcn.inst->ring_enc[1]); + break; +- case 126: +- amdgpu_fence_process(&adev->vcn.inst->ring_jpeg); +- break; + default: + DRM_ERROR("Unhandled interrupt: %d %d\n", + entry->src_id, entry->src_data[0]); +@@ -2259,41 +1843,6 @@ static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = { + .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, + }; + +-static const struct amdgpu_ring_funcs vcn_v1_0_jpeg_ring_vm_funcs = { +- .type = AMDGPU_RING_TYPE_VCN_JPEG, +- .align_mask = 0xf, +- .nop = PACKET0(0x81ff, 0), +- .support_64bit_ptrs = false, +- .no_user_fence = true, +- .vmhub = AMDGPU_MMHUB_0, +- .extra_dw = 64, +- .get_rptr = vcn_v1_0_jpeg_ring_get_rptr, +- .get_wptr = vcn_v1_0_jpeg_ring_get_wptr, +- .set_wptr = vcn_v1_0_jpeg_ring_set_wptr, +- .emit_frame_size = +- 6 + 6 + /* hdp invalidate / flush */ +- SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + +- SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + +- 8 + /* vcn_v1_0_jpeg_ring_emit_vm_flush */ +- 26 + 26 + /* vcn_v1_0_jpeg_ring_emit_fence x2 vm fence */ +- 6, +- .emit_ib_size = 22, /* vcn_v1_0_jpeg_ring_emit_ib */ +- .emit_ib = vcn_v1_0_jpeg_ring_emit_ib, +- .emit_fence = vcn_v1_0_jpeg_ring_emit_fence, +- .emit_vm_flush = vcn_v1_0_jpeg_ring_emit_vm_flush, +- .test_ring = amdgpu_vcn_jpeg_ring_test_ring, +- .test_ib = amdgpu_vcn_jpeg_ring_test_ib, +- .insert_nop = vcn_v1_0_jpeg_ring_nop, +- .insert_start = vcn_v1_0_jpeg_ring_insert_start, +- .insert_end = vcn_v1_0_jpeg_ring_insert_end, +- .pad_ib = amdgpu_ring_generic_pad_ib, +- .begin_use = amdgpu_vcn_ring_begin_use, +- .end_use = amdgpu_vcn_ring_end_use, +- .emit_wreg = vcn_v1_0_jpeg_ring_emit_wreg, +- .emit_reg_wait = vcn_v1_0_jpeg_ring_emit_reg_wait, +- .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, +-}; +- + static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) + { + adev->vcn.inst->ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs; +@@ -2310,12 +1859,6 @@ static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev) + DRM_INFO("VCN encode is enabled in VM mode\n"); + } + +-static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev) +-{ +- adev->vcn.inst->ring_jpeg.funcs = &vcn_v1_0_jpeg_ring_vm_funcs; +- DRM_INFO("VCN jpeg decode is enabled in VM mode\n"); +-} +- + static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { + .set = vcn_v1_0_set_interrupt_state, + .process = vcn_v1_0_process_interrupt, +-- +2.17.1 + |