diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4461-drm-amdgpu-move-JPEG2.5-out-from-VCN2.5.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4461-drm-amdgpu-move-JPEG2.5-out-from-VCN2.5.patch | 1500 |
1 files changed, 1500 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4461-drm-amdgpu-move-JPEG2.5-out-from-VCN2.5.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4461-drm-amdgpu-move-JPEG2.5-out-from-VCN2.5.patch new file mode 100644 index 00000000..7ad116bf --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4461-drm-amdgpu-move-JPEG2.5-out-from-VCN2.5.patch @@ -0,0 +1,1500 @@ +From d078a2b7be1e7ff51af6940b0dac75ff90480c7b Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Mon, 11 Nov 2019 09:56:32 -0500 +Subject: [PATCH 4461/4736] drm/amdgpu: move JPEG2.5 out from VCN2.5 + +And clean up the duplicated stuff + +Change-Id: Ia5502c8d4a5e1431bdd04e2392efe41f81b5ef7a +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/amdgpu_jpeg.h | 3 + + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 105 ---- + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 5 - + drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 641 +++++++++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.h | 29 + + drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 236 --------- + drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h | 13 - + drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 246 +-------- + 9 files changed, 679 insertions(+), 602 deletions(-) + create mode 100644 drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c + create mode 100644 drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.h + +diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile +index 7cbe646d1ae1..bfcc29fdced7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/Makefile ++++ b/drivers/gpu/drm/amd/amdgpu/Makefile +@@ -156,7 +156,8 @@ amdgpu-y += \ + vcn_v2_5.o \ + amdgpu_jpeg.o \ + jpeg_v1_0.o \ +- jpeg_v2_0.o ++ jpeg_v2_0.o \ ++ jpeg_v2_5.o + + # add ATHUB block + amdgpu-y += \ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h +index 5e2e06ec13df..5131a0a1bc8a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h +@@ -26,6 +26,9 @@ + + #define AMDGPU_MAX_JPEG_INSTANCES 2 + ++#define AMDGPU_JPEG_HARVEST_JPEG0 (1 << 0) ++#define AMDGPU_JPEG_HARVEST_JPEG1 (1 << 1) ++ + struct amdgpu_jpeg_reg{ + unsigned jpeg_pitch; + }; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +index 9daa42f03886..2b9ae7725f42 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +@@ -705,108 +705,3 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) + amdgpu_bo_unref(&bo); + return r; + } +- +-int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- uint32_t tmp = 0; +- unsigned i; +- int r; +- +- WREG32(adev->vcn.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD); +- r = amdgpu_ring_alloc(ring, 3); +- if (r) +- return r; +- +- amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.jpeg_pitch, 0)); +- amdgpu_ring_write(ring, 0xDEADBEEF); +- amdgpu_ring_commit(ring); +- +- for (i = 0; i < adev->usec_timeout; i++) { +- tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch); +- if (tmp == 0xDEADBEEF) +- break; +- DRM_UDELAY(1); +- } +- +- if (i >= adev->usec_timeout) +- r = -ETIMEDOUT; +- +- return r; +-} +- +-static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, +- struct dma_fence **fence) +-{ +- struct amdgpu_device *adev = ring->adev; +- struct amdgpu_job *job; +- struct amdgpu_ib *ib; +- struct dma_fence *f = NULL; +- const unsigned ib_size_dw = 16; +- int i, r; +- +- r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); +- if (r) +- return r; +- +- ib = &job->ibs[0]; +- +- ib->ptr[0] = PACKETJ(adev->vcn.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0); +- ib->ptr[1] = 0xDEADBEEF; +- for (i = 2; i < 16; i += 2) { +- ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); +- ib->ptr[i+1] = 0; +- } +- ib->length_dw = 16; +- +- r = amdgpu_job_submit_direct(job, ring, &f); +- if (r) +- goto err; +- +- if (fence) +- *fence = dma_fence_get(f); +- dma_fence_put(f); +- +- return 0; +- +-err: +- amdgpu_job_free(job); +- return r; +-} +- +-int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) +-{ +- struct amdgpu_device *adev = ring->adev; +- uint32_t tmp = 0; +- unsigned i; +- struct dma_fence *fence = NULL; +- long r = 0; +- +- r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence); +- if (r) +- goto error; +- +- r = dma_fence_wait_timeout(fence, false, timeout); +- if (r == 0) { +- r = -ETIMEDOUT; +- goto error; +- } else if (r < 0) { +- goto error; +- } else { +- r = 0; +- } +- +- for (i = 0; i < adev->usec_timeout; i++) { +- tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch); +- if (tmp == 0xDEADBEEF) +- break; +- DRM_UDELAY(1); +- } +- +- if (i >= adev->usec_timeout) +- r = -ETIMEDOUT; +- +- dma_fence_put(fence); +-error: +- return r; +-} +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +index dface275c81a..402a5046b985 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +@@ -158,7 +158,6 @@ struct amdgpu_vcn_reg{ + unsigned ib_size; + unsigned gp_scratch8; + unsigned scratch9; +- unsigned jpeg_pitch; + }; + + struct amdgpu_vcn_inst { +@@ -168,7 +167,6 @@ struct amdgpu_vcn_inst { + void *saved_bo; + struct amdgpu_ring ring_dec; + struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS]; +- struct amdgpu_ring ring_jpeg; + struct amdgpu_irq_src irq; + struct amdgpu_vcn_reg external; + }; +@@ -209,7 +207,4 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout); + int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring); + int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout); + +-int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring); +-int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout); +- + #endif +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +new file mode 100644 +index 000000000000..2c58939e6ad0 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +@@ -0,0 +1,641 @@ ++/* ++ * 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 "jpeg_v2_0.h" ++ ++#include "vcn/vcn_2_5_offset.h" ++#include "vcn/vcn_2_5_sh_mask.h" ++#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" ++ ++#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f ++ ++#define JPEG25_MAX_HW_INSTANCES_ARCTURUS 2 ++ ++static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev); ++static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev); ++static int jpeg_v2_5_set_powergating_state(void *handle, ++ enum amd_powergating_state state); ++ ++static int amdgpu_ih_clientid_jpeg[] = { ++ SOC15_IH_CLIENTID_VCN, ++ SOC15_IH_CLIENTID_VCN1 ++}; ++ ++/** ++ * jpeg_v2_5_early_init - set function pointers ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * Set ring and irq function pointers ++ */ ++static int jpeg_v2_5_early_init(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ if (adev->asic_type == CHIP_ARCTURUS) { ++ u32 harvest; ++ int i; ++ ++ adev->jpeg.num_jpeg_inst = JPEG25_MAX_HW_INSTANCES_ARCTURUS; ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { ++ harvest = RREG32_SOC15(JPEG, i, mmCC_UVD_HARVESTING); ++ if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK) ++ adev->jpeg.harvest_config |= 1 << i; ++ } ++ ++ if (adev->jpeg.harvest_config == (AMDGPU_JPEG_HARVEST_JPEG0 | ++ AMDGPU_JPEG_HARVEST_JPEG1)) ++ return -ENOENT; ++ } else ++ adev->jpeg.num_jpeg_inst = 1; ++ ++ jpeg_v2_5_set_dec_ring_funcs(adev); ++ jpeg_v2_5_set_irq_funcs(adev); ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_sw_init - sw init for JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * Load firmware and sw initialization ++ */ ++static int jpeg_v2_5_sw_init(void *handle) ++{ ++ struct amdgpu_ring *ring; ++ int i, r; ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ /* JPEG TRAP */ ++ r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i], ++ VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq); ++ if (r) ++ return r; ++ } ++ ++ r = amdgpu_jpeg_sw_init(adev); ++ if (r) ++ return r; ++ ++ r = amdgpu_jpeg_resume(adev); ++ if (r) ++ return r; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ ring = &adev->jpeg.inst[i].ring_dec; ++ ring->use_doorbell = true; ++ ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i; ++ sprintf(ring->name, "jpeg_dec_%d", i); ++ r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq, 0); ++ if (r) ++ return r; ++ ++ adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET; ++ adev->jpeg.inst[i].external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_PITCH); ++ } ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_sw_fini - sw fini for JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * JPEG suspend and free up sw allocation ++ */ ++static int jpeg_v2_5_sw_fini(void *handle) ++{ ++ int r; ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ ++ r = amdgpu_jpeg_suspend(adev); ++ if (r) ++ return r; ++ ++ r = amdgpu_jpeg_sw_fini(adev); ++ ++ return r; ++} ++ ++/** ++ * jpeg_v2_5_hw_init - start and test JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ */ ++static int jpeg_v2_5_hw_init(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ struct amdgpu_ring *ring; ++ int i, r; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ ring = &adev->jpeg.inst[i].ring_dec; ++ adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, ++ (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i); ++ ++ r = amdgpu_ring_test_helper(ring); ++ if (r) ++ return r; ++ } ++ ++ DRM_INFO("JPEG decode initialized successfully.\n"); ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_hw_fini - stop the hardware block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * Stop the JPEG block, mark ring as not ready any more ++ */ ++static int jpeg_v2_5_hw_fini(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ struct amdgpu_ring *ring; ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ ring = &adev->jpeg.inst[i].ring_dec; ++ if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && ++ RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS)) ++ jpeg_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE); ++ ++ ring->sched.ready = false; ++ } ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_suspend - suspend JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * HW fini and suspend JPEG block ++ */ ++static int jpeg_v2_5_suspend(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int r; ++ ++ r = jpeg_v2_5_hw_fini(adev); ++ if (r) ++ return r; ++ ++ r = amdgpu_jpeg_suspend(adev); ++ ++ return r; ++} ++ ++/** ++ * jpeg_v2_5_resume - resume JPEG block ++ * ++ * @handle: amdgpu_device pointer ++ * ++ * Resume firmware and hw init JPEG block ++ */ ++static int jpeg_v2_5_resume(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int r; ++ ++ r = amdgpu_jpeg_resume(adev); ++ if (r) ++ return r; ++ ++ r = jpeg_v2_5_hw_init(adev); ++ ++ return r; ++} ++ ++static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device* adev, int inst) ++{ ++ uint32_t data; ++ ++ data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL); ++ if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) ++ data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; ++ else ++ data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; ++ ++ data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; ++ data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; ++ WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data); ++ ++ data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE); ++ data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK ++ | JPEG_CGC_GATE__JPEG2_DEC_MASK ++ | JPEG_CGC_GATE__JPEG_ENC_MASK ++ | JPEG_CGC_GATE__JMCIF_MASK ++ | JPEG_CGC_GATE__JRBBM_MASK); ++ WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data); ++ ++ data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL); ++ data &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK ++ | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK ++ | JPEG_CGC_CTRL__JMCIF_MODE_MASK ++ | JPEG_CGC_CTRL__JRBBM_MODE_MASK); ++ WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data); ++} ++ ++static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device* adev, int inst) ++{ ++ uint32_t data; ++ ++ data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE); ++ data |= (JPEG_CGC_GATE__JPEG_DEC_MASK ++ |JPEG_CGC_GATE__JPEG2_DEC_MASK ++ |JPEG_CGC_GATE__JPEG_ENC_MASK ++ |JPEG_CGC_GATE__JMCIF_MASK ++ |JPEG_CGC_GATE__JRBBM_MASK); ++ WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data); ++} ++ ++/** ++ * jpeg_v2_5_start - start JPEG block ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * Setup and start the JPEG block ++ */ ++static int jpeg_v2_5_start(struct amdgpu_device *adev) ++{ ++ struct amdgpu_ring *ring; ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ ring = &adev->jpeg.inst[i].ring_dec; ++ /* disable anti hang mechanism */ ++ WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0, ++ ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); ++ ++ /* JPEG disable CGC */ ++ jpeg_v2_5_disable_clock_gating(adev, i); ++ ++ /* MJPEG global tiling registers */ ++ WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG, ++ adev->gfx.config.gb_addr_config); ++ WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG, ++ adev->gfx.config.gb_addr_config); ++ ++ /* enable JMI channel */ ++ WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0, ++ ~UVD_JMI_CNTL__SOFT_RESET_MASK); ++ ++ /* enable System Interrupt for JRBC */ ++ WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN), ++ JPEG_SYS_INT_EN__DJRBC_MASK, ++ ~JPEG_SYS_INT_EN__DJRBC_MASK); ++ ++ WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0); ++ WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); ++ WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, ++ lower_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, ++ upper_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0); ++ WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0); ++ WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L); ++ WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4); ++ ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR); ++ } ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_stop - stop JPEG block ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * stop the JPEG block ++ */ ++static int jpeg_v2_5_stop(struct amdgpu_device *adev) ++{ ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ /* reset JMI */ ++ WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), ++ UVD_JMI_CNTL__SOFT_RESET_MASK, ++ ~UVD_JMI_CNTL__SOFT_RESET_MASK); ++ ++ jpeg_v2_5_enable_clock_gating(adev, i); ++ ++ /* enable anti hang mechanism */ ++ WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), ++ UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, ++ ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); ++ } ++ ++ return 0; ++} ++ ++/** ++ * jpeg_v2_5_dec_ring_get_rptr - get read pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Returns the current hardware read pointer ++ */ ++static uint64_t jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_RPTR); ++} ++ ++/** ++ * jpeg_v2_5_dec_ring_get_wptr - get write pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Returns the current hardware write pointer ++ */ ++static uint64_t jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ if (ring->use_doorbell) ++ return adev->wb.wb[ring->wptr_offs]; ++ else ++ return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR); ++} ++ ++/** ++ * jpeg_v2_5_dec_ring_set_wptr - set write pointer ++ * ++ * @ring: amdgpu_ring pointer ++ * ++ * Commits the write pointer to the hardware ++ */ ++static void jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring) ++{ ++ struct amdgpu_device *adev = ring->adev; ++ ++ if (ring->use_doorbell) { ++ adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); ++ WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); ++ } else { ++ WREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); ++ } ++} ++ ++static bool jpeg_v2_5_is_idle(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int i, ret = 1; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ ret &= (((RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS) & ++ UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == ++ UVD_JRBC_STATUS__RB_JOB_DONE_MASK)); ++ } ++ ++ return ret; ++} ++ ++static int jpeg_v2_5_wait_for_idle(void *handle) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int i, ret = 0; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ SOC15_WAIT_ON_RREG(JPEG, i, mmUVD_JRBC_STATUS, ++ UVD_JRBC_STATUS__RB_JOB_DONE_MASK, ++ UVD_JRBC_STATUS__RB_JOB_DONE_MASK, ret); ++ if (ret) ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int jpeg_v2_5_set_clockgating_state(void *handle, ++ enum amd_clockgating_state state) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ bool enable = (state == AMD_CG_STATE_GATE) ? true : false; ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ if (enable) { ++ if (jpeg_v2_5_is_idle(handle)) ++ return -EBUSY; ++ jpeg_v2_5_enable_clock_gating(adev, i); ++ } else { ++ jpeg_v2_5_disable_clock_gating(adev, i); ++ } ++ } ++ ++ return 0; ++} ++ ++static int jpeg_v2_5_set_powergating_state(void *handle, ++ enum amd_powergating_state state) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int ret; ++ ++ if(state == adev->jpeg.cur_state) ++ return 0; ++ ++ if (state == AMD_PG_STATE_GATE) ++ ret = jpeg_v2_5_stop(adev); ++ else ++ ret = jpeg_v2_5_start(adev); ++ ++ if(!ret) ++ adev->jpeg.cur_state = state; ++ ++ return ret; ++} ++ ++static int jpeg_v2_5_set_interrupt_state(struct amdgpu_device *adev, ++ struct amdgpu_irq_src *source, ++ unsigned type, ++ enum amdgpu_interrupt_state state) ++{ ++ return 0; ++} ++ ++static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev, ++ struct amdgpu_irq_src *source, ++ struct amdgpu_iv_entry *entry) ++{ ++ uint32_t ip_instance; ++ ++ switch (entry->client_id) { ++ case SOC15_IH_CLIENTID_VCN: ++ ip_instance = 0; ++ break; ++ case SOC15_IH_CLIENTID_VCN1: ++ ip_instance = 1; ++ break; ++ default: ++ DRM_ERROR("Unhandled client id: %d\n", entry->client_id); ++ return 0; ++ } ++ ++ DRM_DEBUG("IH: JPEG TRAP\n"); ++ ++ switch (entry->src_id) { ++ case VCN_2_0__SRCID__JPEG_DECODE: ++ amdgpu_fence_process(&adev->jpeg.inst[ip_instance].ring_dec); ++ break; ++ default: ++ DRM_ERROR("Unhandled interrupt: %d %d\n", ++ entry->src_id, entry->src_data[0]); ++ break; ++ } ++ ++ return 0; ++} ++ ++static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = { ++ .name = "jpeg_v2_5", ++ .early_init = jpeg_v2_5_early_init, ++ .late_init = NULL, ++ .sw_init = jpeg_v2_5_sw_init, ++ .sw_fini = jpeg_v2_5_sw_fini, ++ .hw_init = jpeg_v2_5_hw_init, ++ .hw_fini = jpeg_v2_5_hw_fini, ++ .suspend = jpeg_v2_5_suspend, ++ .resume = jpeg_v2_5_resume, ++ .is_idle = jpeg_v2_5_is_idle, ++ .wait_for_idle = jpeg_v2_5_wait_for_idle, ++ .check_soft_reset = NULL, ++ .pre_soft_reset = NULL, ++ .soft_reset = NULL, ++ .post_soft_reset = NULL, ++ .set_clockgating_state = jpeg_v2_5_set_clockgating_state, ++ .set_powergating_state = jpeg_v2_5_set_powergating_state, ++}; ++ ++static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = { ++ .type = AMDGPU_RING_TYPE_VCN_JPEG, ++ .align_mask = 0xf, ++ .vmhub = AMDGPU_MMHUB_1, ++ .get_rptr = jpeg_v2_5_dec_ring_get_rptr, ++ .get_wptr = jpeg_v2_5_dec_ring_get_wptr, ++ .set_wptr = jpeg_v2_5_dec_ring_set_wptr, ++ .emit_frame_size = ++ SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + ++ SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + ++ 8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */ ++ 18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */ ++ 8 + 16, ++ .emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */ ++ .emit_ib = jpeg_v2_0_dec_ring_emit_ib, ++ .emit_fence = jpeg_v2_0_dec_ring_emit_fence, ++ .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush, ++ .test_ring = amdgpu_jpeg_dec_ring_test_ring, ++ .test_ib = amdgpu_jpeg_dec_ring_test_ib, ++ .insert_nop = jpeg_v2_0_dec_ring_nop, ++ .insert_start = jpeg_v2_0_dec_ring_insert_start, ++ .insert_end = jpeg_v2_0_dec_ring_insert_end, ++ .pad_ib = amdgpu_ring_generic_pad_ib, ++ .begin_use = amdgpu_jpeg_ring_begin_use, ++ .end_use = amdgpu_jpeg_ring_end_use, ++ .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg, ++ .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait, ++ .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, ++}; ++ ++static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev) ++{ ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ adev->jpeg.inst[i].ring_dec.funcs = &jpeg_v2_5_dec_ring_vm_funcs; ++ adev->jpeg.inst[i].ring_dec.me = i; ++ DRM_INFO("JPEG(%d) JPEG decode is enabled in VM mode\n", i); ++ } ++} ++ ++static const struct amdgpu_irq_src_funcs jpeg_v2_5_irq_funcs = { ++ .set = jpeg_v2_5_set_interrupt_state, ++ .process = jpeg_v2_5_process_interrupt, ++}; ++ ++static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev) ++{ ++ int i; ++ ++ for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { ++ if (adev->jpeg.harvest_config & (1 << i)) ++ continue; ++ ++ adev->jpeg.inst[i].irq.num_types = 1; ++ adev->jpeg.inst[i].irq.funcs = &jpeg_v2_5_irq_funcs; ++ } ++} ++ ++const struct amdgpu_ip_block_version jpeg_v2_5_ip_block = ++{ ++ .type = AMD_IP_BLOCK_TYPE_JPEG, ++ .major = 2, ++ .minor = 5, ++ .rev = 0, ++ .funcs = &jpeg_v2_5_ip_funcs, ++}; +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.h +new file mode 100644 +index 000000000000..2b4087c02620 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.h +@@ -0,0 +1,29 @@ ++/* ++ * 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_V2_5_H__ ++#define __JPEG_V2_5_H__ ++ ++extern const struct amdgpu_ip_block_version jpeg_v2_5_ip_block; ++ ++#endif /* __JPEG_V2_5_H__ */ +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +index 4e0c3467deb2..7aba5a3ff3f7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +@@ -47,26 +47,6 @@ + #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7 + #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x1e2 + +-#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff +-#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 +-#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a +-#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b +-#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea +-#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb +-#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf +-#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 +-#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 +-#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 +-#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 +-#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec +-#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed +-#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 +-#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 +-#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 +-#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f +- +-#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000 +- + #define mmUVD_RBC_XX_IB_REG_CHECK 0x026b + #define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1 + #define mmUVD_REG_XX_MASK 0x026c +@@ -1616,222 +1596,6 @@ void vcn_v2_0_enc_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_ + amdgpu_ring_write(ring, val); + } + +-/** +- * vcn_v2_0_jpeg_ring_insert_start - insert a start command +- * +- * @ring: amdgpu_ring pointer +- * +- * Write a start command to the ring. +- */ +-void vcn_v2_0_jpeg_ring_insert_start(struct amdgpu_ring *ring) +-{ +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x68e04); +- +- amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x80010000); +-} +- +-/** +- * vcn_v2_0_jpeg_ring_insert_end - insert a end command +- * +- * @ring: amdgpu_ring pointer +- * +- * Write a end command to the ring. +- */ +-void vcn_v2_0_jpeg_ring_insert_end(struct amdgpu_ring *ring) +-{ +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x68e04); +- +- amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x00010000); +-} +- +-/** +- * vcn_v2_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. +- */ +-void vcn_v2_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, +- unsigned flags) +-{ +- WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, seq); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, seq); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(addr)); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(addr)); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x8); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET, +- 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); +- amdgpu_ring_write(ring, 0); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x3fbc); +- +- amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x1); +- +- amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); +- amdgpu_ring_write(ring, 0); +-} +- +-/** +- * vcn_v2_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. +- */ +-void vcn_v2_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, +- struct amdgpu_job *job, +- struct amdgpu_ib *ib, +- uint32_t flags) +-{ +- unsigned vmid = AMDGPU_JOB_GET_VMID(job); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, (vmid | (vmid << 4))); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, ib->length_dw); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET, +- 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(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x01400200); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x2); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_STATUS_INTERNAL_OFFSET, +- 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); +- amdgpu_ring_write(ring, 0x2); +-} +- +-void vcn_v2_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, +- uint32_t val, uint32_t mask) +-{ +- uint32_t reg_offset = (reg << 2); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, 0x01400200); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- amdgpu_ring_write(ring, val); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) { +- 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(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, +- 0, 0, PACKETJ_TYPE3)); +- } +- amdgpu_ring_write(ring, mask); +-} +- +-void vcn_v2_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_v2_0_jpeg_ring_emit_reg_wait(ring, data0, data1, mask); +-} +- +-void vcn_v2_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val) +-{ +- uint32_t reg_offset = (reg << 2); +- +- amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, +- 0, 0, PACKETJ_TYPE0)); +- if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) { +- 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(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, +- 0, 0, PACKETJ_TYPE0)); +- } +- amdgpu_ring_write(ring, val); +-} +- +-void vcn_v2_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 int vcn_v2_0_set_interrupt_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned type, +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h +index 8467292f32e5..ef749b02ded9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h +@@ -49,19 +49,6 @@ extern void vcn_v2_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring, + unsigned int vmid, uint64_t pd_addr); + extern void vcn_v2_0_enc_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); + +-extern void vcn_v2_0_jpeg_ring_insert_start(struct amdgpu_ring *ring); +-extern void vcn_v2_0_jpeg_ring_insert_end(struct amdgpu_ring *ring); +-extern void vcn_v2_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, +- unsigned flags); +-extern void vcn_v2_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job, +- struct amdgpu_ib *ib, uint32_t flags); +-extern void vcn_v2_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, +- uint32_t val, uint32_t mask); +-extern void vcn_v2_0_jpeg_ring_emit_vm_flush(struct amdgpu_ring *ring, +- unsigned vmid, uint64_t pd_addr); +-extern void vcn_v2_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); +-extern void vcn_v2_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count); +- + extern const struct amdgpu_ip_block_version vcn_v2_0_ip_block; + + #endif /* __VCN_V2_0_H__ */ +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +index ff6cc77ad0b0..98f423f30d2f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +@@ -47,13 +47,10 @@ + #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 + #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c + +-#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f +- +-#define VCN25_MAX_HW_INSTANCES_ARCTURUS 2 ++#define VCN25_MAX_HW_INSTANCES_ARCTURUS 2 + + static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev); + static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev); +-static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev); + static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev); + static int vcn_v2_5_set_powergating_state(void *handle, + enum amd_powergating_state state); +@@ -95,7 +92,6 @@ static int vcn_v2_5_early_init(void *handle) + + vcn_v2_5_set_dec_ring_funcs(adev); + vcn_v2_5_set_enc_ring_funcs(adev); +- vcn_v2_5_set_jpeg_ring_funcs(adev); + vcn_v2_5_set_irq_funcs(adev); + + return 0; +@@ -130,12 +126,6 @@ static int vcn_v2_5_sw_init(void *handle) + if (r) + return r; + } +- +- /* VCN JPEG TRAP */ +- r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j], +- VCN_2_0__SRCID__JPEG_DECODE, &adev->vcn.inst[j].irq); +- if (r) +- return r; + } + + r = amdgpu_vcn_sw_init(adev); +@@ -184,9 +174,6 @@ static int vcn_v2_5_sw_init(void *handle) + adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET; + adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(UVD, j, mmUVD_NO_OP); + +- adev->vcn.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET; +- adev->vcn.inst[j].external.jpeg_pitch = SOC15_REG_OFFSET(UVD, j, mmUVD_JPEG_PITCH); +- + ring = &adev->vcn.inst[j].ring_dec; + ring->use_doorbell = true; + ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8*j; +@@ -204,14 +191,6 @@ static int vcn_v2_5_sw_init(void *handle) + if (r) + return r; + } +- +- ring = &adev->vcn.inst[j].ring_jpeg; +- ring->use_doorbell = true; +- ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8*j; +- sprintf(ring->name, "vcn_jpeg_%d", j); +- r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0); +- if (r) +- return r; + } + + return 0; +@@ -269,12 +248,8 @@ static int vcn_v2_5_hw_init(void *handle) + if (r) + goto done; + } +- +- ring = &adev->vcn.inst[j].ring_jpeg; +- r = amdgpu_ring_test_helper(ring); +- if (r) +- goto done; + } ++ + done: + if (!r) + DRM_INFO("VCN decode and encode initialized successfully.\n"); +@@ -309,9 +284,6 @@ static int vcn_v2_5_hw_fini(void *handle) + ring = &adev->vcn.inst[i].ring_enc[i]; + ring->sched.ready = false; + } +- +- ring = &adev->vcn.inst[i].ring_jpeg; +- ring->sched.ready = false; + } + + return 0; +@@ -592,115 +564,6 @@ static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev) + } + } + +-/** +- * jpeg_v2_5_start - start JPEG block +- * +- * @adev: amdgpu_device pointer +- * +- * Setup and start the JPEG block +- */ +-static int jpeg_v2_5_start(struct amdgpu_device *adev) +-{ +- struct amdgpu_ring *ring; +- uint32_t tmp; +- int i; +- +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->vcn.harvest_config & (1 << i)) +- continue; +- ring = &adev->vcn.inst[i].ring_jpeg; +- /* disable anti hang mechanism */ +- WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS), 0, +- ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); +- +- /* JPEG disable CGC */ +- tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL); +- tmp |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; +- tmp |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; +- tmp |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; +- WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp); +- +- tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE); +- tmp &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK +- | JPEG_CGC_GATE__JPEG2_DEC_MASK +- | JPEG_CGC_GATE__JMCIF_MASK +- | JPEG_CGC_GATE__JRBBM_MASK); +- WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp); +- +- tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL); +- tmp &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK +- | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK +- | JPEG_CGC_CTRL__JMCIF_MODE_MASK +- | JPEG_CGC_CTRL__JRBBM_MODE_MASK); +- WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp); +- +- /* MJPEG global tiling registers */ +- WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX8_ADDR_CONFIG, +- adev->gfx.config.gb_addr_config); +- WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX10_ADDR_CONFIG, +- adev->gfx.config.gb_addr_config); +- +- /* enable JMI channel */ +- WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL), 0, +- ~UVD_JMI_CNTL__SOFT_RESET_MASK); +- +- /* enable System Interrupt for JRBC */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, mmJPEG_SYS_INT_EN), +- JPEG_SYS_INT_EN__DJRBC_MASK, +- ~JPEG_SYS_INT_EN__DJRBC_MASK); +- +- WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_VMID, 0); +- WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); +- WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, +- lower_32_bits(ring->gpu_addr)); +- WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, +- upper_32_bits(ring->gpu_addr)); +- WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_RPTR, 0); +- WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR, 0); +- WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, 0x00000002L); +- WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4); +- ring->wptr = RREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR); +- } +- +- return 0; +-} +- +-/** +- * jpeg_v2_5_stop - stop JPEG block +- * +- * @adev: amdgpu_device pointer +- * +- * stop the JPEG block +- */ +-static int jpeg_v2_5_stop(struct amdgpu_device *adev) +-{ +- uint32_t tmp; +- int i; +- +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->vcn.harvest_config & (1 << i)) +- continue; +- /* reset JMI */ +- WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL), +- UVD_JMI_CNTL__SOFT_RESET_MASK, +- ~UVD_JMI_CNTL__SOFT_RESET_MASK); +- +- tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE); +- tmp |= (JPEG_CGC_GATE__JPEG_DEC_MASK +- |JPEG_CGC_GATE__JPEG2_DEC_MASK +- |JPEG_CGC_GATE__JMCIF_MASK +- |JPEG_CGC_GATE__JRBBM_MASK); +- WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp); +- +- /* enable anti hang mechanism */ +- WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS), +- UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, +- ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); +- } +- +- return 0; +-} +- + static int vcn_v2_5_start(struct amdgpu_device *adev) + { + struct amdgpu_ring *ring; +@@ -874,19 +737,14 @@ static int vcn_v2_5_start(struct amdgpu_device *adev) + WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); + WREG32_SOC15(UVD, i, mmUVD_RB_SIZE2, ring->ring_size / 4); + } +- r = jpeg_v2_5_start(adev); + +- return r; ++ return 0; + } + + static int vcn_v2_5_stop(struct amdgpu_device *adev) + { + uint32_t tmp; +- int i, r; +- +- r = jpeg_v2_5_stop(adev); +- if (r) +- return r; ++ int i, r = 0; + + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) +@@ -1125,86 +983,6 @@ static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = { + .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, + }; + +-/** +- * vcn_v2_5_jpeg_ring_get_rptr - get read pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Returns the current hardware read pointer +- */ +-static uint64_t vcn_v2_5_jpeg_ring_get_rptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_RPTR); +-} +- +-/** +- * vcn_v2_5_jpeg_ring_get_wptr - get write pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Returns the current hardware write pointer +- */ +-static uint64_t vcn_v2_5_jpeg_ring_get_wptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- if (ring->use_doorbell) +- return adev->wb.wb[ring->wptr_offs]; +- else +- return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR); +-} +- +-/** +- * vcn_v2_5_jpeg_ring_set_wptr - set write pointer +- * +- * @ring: amdgpu_ring pointer +- * +- * Commits the write pointer to the hardware +- */ +-static void vcn_v2_5_jpeg_ring_set_wptr(struct amdgpu_ring *ring) +-{ +- struct amdgpu_device *adev = ring->adev; +- +- if (ring->use_doorbell) { +- adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); +- WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); +- } else { +- WREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); +- } +-} +- +-static const struct amdgpu_ring_funcs vcn_v2_5_jpeg_ring_vm_funcs = { +- .type = AMDGPU_RING_TYPE_VCN_JPEG, +- .align_mask = 0xf, +- .vmhub = AMDGPU_MMHUB_1, +- .get_rptr = vcn_v2_5_jpeg_ring_get_rptr, +- .get_wptr = vcn_v2_5_jpeg_ring_get_wptr, +- .set_wptr = vcn_v2_5_jpeg_ring_set_wptr, +- .emit_frame_size = +- SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + +- SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + +- 8 + /* vcn_v2_0_jpeg_ring_emit_vm_flush */ +- 18 + 18 + /* vcn_v2_0_jpeg_ring_emit_fence x2 vm fence */ +- 8 + 16, +- .emit_ib_size = 22, /* vcn_v2_0_jpeg_ring_emit_ib */ +- .emit_ib = vcn_v2_0_jpeg_ring_emit_ib, +- .emit_fence = vcn_v2_0_jpeg_ring_emit_fence, +- .emit_vm_flush = vcn_v2_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_v2_0_jpeg_ring_nop, +- .insert_start = vcn_v2_0_jpeg_ring_insert_start, +- .insert_end = vcn_v2_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_v2_0_jpeg_ring_emit_wreg, +- .emit_reg_wait = vcn_v2_0_jpeg_ring_emit_reg_wait, +- .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, +-}; +- + static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev) + { + int i; +@@ -1233,19 +1011,6 @@ static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev) + } + } + +-static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev) +-{ +- int i; +- +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->vcn.harvest_config & (1 << i)) +- continue; +- adev->vcn.inst[i].ring_jpeg.funcs = &vcn_v2_5_jpeg_ring_vm_funcs; +- adev->vcn.inst[i].ring_jpeg.me = i; +- DRM_INFO("VCN(%d) jpeg decode is enabled in VM mode\n", i); +- } +-} +- + static bool vcn_v2_5_is_idle(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +@@ -1352,9 +1117,6 @@ static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev, + case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY: + amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]); + break; +- case VCN_2_0__SRCID__JPEG_DECODE: +- amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_jpeg); +- break; + default: + DRM_ERROR("Unhandled interrupt: %d %d\n", + entry->src_id, entry->src_data[0]); +-- +2.17.1 + |