cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

jpeg_v1_0.c (19400B)


      1/*
      2 * Copyright 2019 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 */
     23
     24#include "amdgpu.h"
     25#include "amdgpu_jpeg.h"
     26#include "soc15.h"
     27#include "soc15d.h"
     28#include "vcn_v1_0.h"
     29#include "jpeg_v1_0.h"
     30
     31#include "vcn/vcn_1_0_offset.h"
     32#include "vcn/vcn_1_0_sh_mask.h"
     33
     34static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
     35static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
     36static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
     37
     38static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
     39{
     40	struct amdgpu_device *adev = ring->adev;
     41	ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
     42	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
     43		((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
     44		ring->ring[(*ptr)++] = 0;
     45		ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0);
     46	} else {
     47		ring->ring[(*ptr)++] = reg_offset;
     48		ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0);
     49	}
     50	ring->ring[(*ptr)++] = val;
     51}
     52
     53static void jpeg_v1_0_decode_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr)
     54{
     55	struct amdgpu_device *adev = ring->adev;
     56
     57	uint32_t reg, reg_offset, val, mask, i;
     58
     59	// 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW
     60	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW);
     61	reg_offset = (reg << 2);
     62	val = lower_32_bits(ring->gpu_addr);
     63	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
     64
     65	// 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH
     66	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH);
     67	reg_offset = (reg << 2);
     68	val = upper_32_bits(ring->gpu_addr);
     69	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
     70
     71	// 3rd to 5th: issue MEM_READ commands
     72	for (i = 0; i <= 2; i++) {
     73		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2);
     74		ring->ring[ptr++] = 0;
     75	}
     76
     77	// 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability
     78	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
     79	reg_offset = (reg << 2);
     80	val = 0x13;
     81	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
     82
     83	// 7th: program mmUVD_JRBC_RB_REF_DATA
     84	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA);
     85	reg_offset = (reg << 2);
     86	val = 0x1;
     87	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
     88
     89	// 8th: issue conditional register read mmUVD_JRBC_RB_CNTL
     90	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
     91	reg_offset = (reg << 2);
     92	val = 0x1;
     93	mask = 0x1;
     94
     95	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0);
     96	ring->ring[ptr++] = 0x01400200;
     97	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0);
     98	ring->ring[ptr++] = val;
     99	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
    100	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
    101		((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
    102		ring->ring[ptr++] = 0;
    103		ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3);
    104	} else {
    105		ring->ring[ptr++] = reg_offset;
    106		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3);
    107	}
    108	ring->ring[ptr++] = mask;
    109
    110	//9th to 21st: insert no-op
    111	for (i = 0; i <= 12; i++) {
    112		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
    113		ring->ring[ptr++] = 0;
    114	}
    115
    116	//22nd: reset mmUVD_JRBC_RB_RPTR
    117	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_RPTR);
    118	reg_offset = (reg << 2);
    119	val = 0;
    120	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
    121
    122	//23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch
    123	reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
    124	reg_offset = (reg << 2);
    125	val = 0x12;
    126	jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
    127}
    128
    129/**
    130 * jpeg_v1_0_decode_ring_get_rptr - get read pointer
    131 *
    132 * @ring: amdgpu_ring pointer
    133 *
    134 * Returns the current hardware read pointer
    135 */
    136static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring)
    137{
    138	struct amdgpu_device *adev = ring->adev;
    139
    140	return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
    141}
    142
    143/**
    144 * jpeg_v1_0_decode_ring_get_wptr - get write pointer
    145 *
    146 * @ring: amdgpu_ring pointer
    147 *
    148 * Returns the current hardware write pointer
    149 */
    150static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring)
    151{
    152	struct amdgpu_device *adev = ring->adev;
    153
    154	return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
    155}
    156
    157/**
    158 * jpeg_v1_0_decode_ring_set_wptr - set write pointer
    159 *
    160 * @ring: amdgpu_ring pointer
    161 *
    162 * Commits the write pointer to the hardware
    163 */
    164static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring)
    165{
    166	struct amdgpu_device *adev = ring->adev;
    167
    168	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
    169}
    170
    171/**
    172 * jpeg_v1_0_decode_ring_insert_start - insert a start command
    173 *
    174 * @ring: amdgpu_ring pointer
    175 *
    176 * Write a start command to the ring.
    177 */
    178static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring)
    179{
    180	struct amdgpu_device *adev = ring->adev;
    181
    182	amdgpu_ring_write(ring,
    183		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
    184	amdgpu_ring_write(ring, 0x68e04);
    185
    186	amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
    187	amdgpu_ring_write(ring, 0x80010000);
    188}
    189
    190/**
    191 * jpeg_v1_0_decode_ring_insert_end - insert a end command
    192 *
    193 * @ring: amdgpu_ring pointer
    194 *
    195 * Write a end command to the ring.
    196 */
    197static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring)
    198{
    199	struct amdgpu_device *adev = ring->adev;
    200
    201	amdgpu_ring_write(ring,
    202		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
    203	amdgpu_ring_write(ring, 0x68e04);
    204
    205	amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
    206	amdgpu_ring_write(ring, 0x00010000);
    207}
    208
    209/**
    210 * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command
    211 *
    212 * @ring: amdgpu_ring pointer
    213 * @addr: address
    214 * @seq: sequence number
    215 * @flags: fence related flags
    216 *
    217 * Write a fence and a trap command to the ring.
    218 */
    219static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
    220				     unsigned flags)
    221{
    222	struct amdgpu_device *adev = ring->adev;
    223
    224	WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
    225
    226	amdgpu_ring_write(ring,
    227		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0));
    228	amdgpu_ring_write(ring, seq);
    229
    230	amdgpu_ring_write(ring,
    231		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0));
    232	amdgpu_ring_write(ring, seq);
    233
    234	amdgpu_ring_write(ring,
    235		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
    236	amdgpu_ring_write(ring, lower_32_bits(addr));
    237
    238	amdgpu_ring_write(ring,
    239		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
    240	amdgpu_ring_write(ring, upper_32_bits(addr));
    241
    242	amdgpu_ring_write(ring,
    243		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0));
    244	amdgpu_ring_write(ring, 0x8);
    245
    246	amdgpu_ring_write(ring,
    247		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
    248	amdgpu_ring_write(ring, 0);
    249
    250	amdgpu_ring_write(ring,
    251		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
    252	amdgpu_ring_write(ring, 0x01400200);
    253
    254	amdgpu_ring_write(ring,
    255		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
    256	amdgpu_ring_write(ring, seq);
    257
    258	amdgpu_ring_write(ring,
    259		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
    260	amdgpu_ring_write(ring, lower_32_bits(addr));
    261
    262	amdgpu_ring_write(ring,
    263		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
    264	amdgpu_ring_write(ring, upper_32_bits(addr));
    265
    266	amdgpu_ring_write(ring,
    267		PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2));
    268	amdgpu_ring_write(ring, 0xffffffff);
    269
    270	amdgpu_ring_write(ring,
    271		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
    272	amdgpu_ring_write(ring, 0x3fbc);
    273
    274	amdgpu_ring_write(ring,
    275		PACKETJ(0, 0, 0, PACKETJ_TYPE0));
    276	amdgpu_ring_write(ring, 0x1);
    277
    278	/* emit trap */
    279	amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
    280	amdgpu_ring_write(ring, 0);
    281}
    282
    283/**
    284 * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer
    285 *
    286 * @ring: amdgpu_ring pointer
    287 * @job: job to retrieve vmid from
    288 * @ib: indirect buffer to execute
    289 * @flags: unused
    290 *
    291 * Write ring commands to execute the indirect buffer.
    292 */
    293static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring,
    294					struct amdgpu_job *job,
    295					struct amdgpu_ib *ib,
    296					uint32_t flags)
    297{
    298	struct amdgpu_device *adev = ring->adev;
    299	unsigned vmid = AMDGPU_JOB_GET_VMID(job);
    300
    301	amdgpu_ring_write(ring,
    302		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0));
    303	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
    304
    305	amdgpu_ring_write(ring,
    306		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0));
    307	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
    308
    309	amdgpu_ring_write(ring,
    310		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
    311	amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
    312
    313	amdgpu_ring_write(ring,
    314		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
    315	amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
    316
    317	amdgpu_ring_write(ring,
    318		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0));
    319	amdgpu_ring_write(ring, ib->length_dw);
    320
    321	amdgpu_ring_write(ring,
    322		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
    323	amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
    324
    325	amdgpu_ring_write(ring,
    326		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
    327	amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
    328
    329	amdgpu_ring_write(ring,
    330		PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
    331	amdgpu_ring_write(ring, 0);
    332
    333	amdgpu_ring_write(ring,
    334		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
    335	amdgpu_ring_write(ring, 0x01400200);
    336
    337	amdgpu_ring_write(ring,
    338		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
    339	amdgpu_ring_write(ring, 0x2);
    340
    341	amdgpu_ring_write(ring,
    342		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
    343	amdgpu_ring_write(ring, 0x2);
    344}
    345
    346static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring,
    347					    uint32_t reg, uint32_t val,
    348					    uint32_t mask)
    349{
    350	struct amdgpu_device *adev = ring->adev;
    351	uint32_t reg_offset = (reg << 2);
    352
    353	amdgpu_ring_write(ring,
    354		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
    355	amdgpu_ring_write(ring, 0x01400200);
    356
    357	amdgpu_ring_write(ring,
    358		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
    359	amdgpu_ring_write(ring, val);
    360
    361	amdgpu_ring_write(ring,
    362		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
    363	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
    364		((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
    365		amdgpu_ring_write(ring, 0);
    366		amdgpu_ring_write(ring,
    367			PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
    368	} else {
    369		amdgpu_ring_write(ring, reg_offset);
    370		amdgpu_ring_write(ring,
    371			PACKETJ(0, 0, 0, PACKETJ_TYPE3));
    372	}
    373	amdgpu_ring_write(ring, mask);
    374}
    375
    376static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring,
    377		unsigned vmid, uint64_t pd_addr)
    378{
    379	struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
    380	uint32_t data0, data1, mask;
    381
    382	pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
    383
    384	/* wait for register write */
    385	data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;
    386	data1 = lower_32_bits(pd_addr);
    387	mask = 0xffffffff;
    388	jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask);
    389}
    390
    391static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring,
    392					uint32_t reg, uint32_t val)
    393{
    394	struct amdgpu_device *adev = ring->adev;
    395	uint32_t reg_offset = (reg << 2);
    396
    397	amdgpu_ring_write(ring,
    398		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
    399	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
    400			((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
    401		amdgpu_ring_write(ring, 0);
    402		amdgpu_ring_write(ring,
    403			PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
    404	} else {
    405		amdgpu_ring_write(ring, reg_offset);
    406		amdgpu_ring_write(ring,
    407			PACKETJ(0, 0, 0, PACKETJ_TYPE0));
    408	}
    409	amdgpu_ring_write(ring, val);
    410}
    411
    412static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count)
    413{
    414	int i;
    415
    416	WARN_ON(ring->wptr % 2 || count % 2);
    417
    418	for (i = 0; i < count / 2; i++) {
    419		amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
    420		amdgpu_ring_write(ring, 0);
    421	}
    422}
    423
    424static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev,
    425					struct amdgpu_irq_src *source,
    426					unsigned type,
    427					enum amdgpu_interrupt_state state)
    428{
    429	return 0;
    430}
    431
    432static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,
    433				      struct amdgpu_irq_src *source,
    434				      struct amdgpu_iv_entry *entry)
    435{
    436	DRM_DEBUG("IH: JPEG decode TRAP\n");
    437
    438	switch (entry->src_id) {
    439	case 126:
    440		amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
    441		break;
    442	default:
    443		DRM_ERROR("Unhandled interrupt: %d %d\n",
    444			  entry->src_id, entry->src_data[0]);
    445		break;
    446	}
    447
    448	return 0;
    449}
    450
    451/**
    452 * jpeg_v1_0_early_init - set function pointers
    453 *
    454 * @handle: amdgpu_device pointer
    455 *
    456 * Set ring and irq function pointers
    457 */
    458int jpeg_v1_0_early_init(void *handle)
    459{
    460	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    461
    462	adev->jpeg.num_jpeg_inst = 1;
    463
    464	jpeg_v1_0_set_dec_ring_funcs(adev);
    465	jpeg_v1_0_set_irq_funcs(adev);
    466
    467	return 0;
    468}
    469
    470/**
    471 * jpeg_v1_0_sw_init - sw init for JPEG block
    472 *
    473 * @handle: amdgpu_device pointer
    474 *
    475 */
    476int jpeg_v1_0_sw_init(void *handle)
    477{
    478	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    479	struct amdgpu_ring *ring;
    480	int r;
    481
    482	/* JPEG TRAP */
    483	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq);
    484	if (r)
    485		return r;
    486
    487	ring = &adev->jpeg.inst->ring_dec;
    488	sprintf(ring->name, "jpeg_dec");
    489	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
    490			     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
    491	if (r)
    492		return r;
    493
    494	adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch =
    495		SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
    496
    497	return 0;
    498}
    499
    500/**
    501 * jpeg_v1_0_sw_fini - sw fini for JPEG block
    502 *
    503 * @handle: amdgpu_device pointer
    504 *
    505 * JPEG free up sw allocation
    506 */
    507void jpeg_v1_0_sw_fini(void *handle)
    508{
    509	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    510
    511	amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec);
    512}
    513
    514/**
    515 * jpeg_v1_0_start - start JPEG block
    516 *
    517 * @adev: amdgpu_device pointer
    518 * @mode: SPG or DPG mode
    519 *
    520 * Setup and start the JPEG block
    521 */
    522void jpeg_v1_0_start(struct amdgpu_device *adev, int mode)
    523{
    524	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
    525
    526	if (mode == 0) {
    527		WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
    528		WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
    529				UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
    530		WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr));
    531		WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr));
    532		WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
    533		WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
    534		WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
    535	}
    536
    537	/* initialize wptr */
    538	ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
    539
    540	/* copy patch commands to the jpeg ring */
    541	jpeg_v1_0_decode_ring_set_patch_ring(ring,
    542		(ring->wptr + ring->max_dw * amdgpu_sched_hw_submission));
    543}
    544
    545static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {
    546	.type = AMDGPU_RING_TYPE_VCN_JPEG,
    547	.align_mask = 0xf,
    548	.nop = PACKET0(0x81ff, 0),
    549	.support_64bit_ptrs = false,
    550	.no_user_fence = true,
    551	.vmhub = AMDGPU_MMHUB_0,
    552	.extra_dw = 64,
    553	.get_rptr = jpeg_v1_0_decode_ring_get_rptr,
    554	.get_wptr = jpeg_v1_0_decode_ring_get_wptr,
    555	.set_wptr = jpeg_v1_0_decode_ring_set_wptr,
    556	.emit_frame_size =
    557		6 + 6 + /* hdp invalidate / flush */
    558		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
    559		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
    560		8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */
    561		26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */
    562		6,
    563	.emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */
    564	.emit_ib = jpeg_v1_0_decode_ring_emit_ib,
    565	.emit_fence = jpeg_v1_0_decode_ring_emit_fence,
    566	.emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush,
    567	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
    568	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
    569	.insert_nop = jpeg_v1_0_decode_ring_nop,
    570	.insert_start = jpeg_v1_0_decode_ring_insert_start,
    571	.insert_end = jpeg_v1_0_decode_ring_insert_end,
    572	.pad_ib = amdgpu_ring_generic_pad_ib,
    573	.begin_use = jpeg_v1_0_ring_begin_use,
    574	.end_use = vcn_v1_0_ring_end_use,
    575	.emit_wreg = jpeg_v1_0_decode_ring_emit_wreg,
    576	.emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait,
    577	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    578};
    579
    580static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
    581{
    582	adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs;
    583	DRM_INFO("JPEG decode is enabled in VM mode\n");
    584}
    585
    586static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = {
    587	.set = jpeg_v1_0_set_interrupt_state,
    588	.process = jpeg_v1_0_process_interrupt,
    589};
    590
    591static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev)
    592{
    593	adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs;
    594}
    595
    596static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
    597{
    598	struct	amdgpu_device *adev = ring->adev;
    599	bool	set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
    600	int		cnt = 0;
    601
    602	mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
    603
    604	if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_dec))
    605		DRM_ERROR("JPEG dec: vcn dec ring may not be empty\n");
    606
    607	for (cnt = 0; cnt < adev->vcn.num_enc_rings; cnt++) {
    608		if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_enc[cnt]))
    609			DRM_ERROR("JPEG dec: vcn enc ring[%d] may not be empty\n", cnt);
    610	}
    611
    612	vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
    613}