Home | History | Annotate | Line # | Download | only in amdgpu
      1 /*	$NetBSD: amdgpu_jpeg_v2_0.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2019 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  */
     25 
     26 #include <sys/cdefs.h>
     27 __KERNEL_RCSID(0, "$NetBSD: amdgpu_jpeg_v2_0.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $");
     28 
     29 #include "amdgpu.h"
     30 #include "amdgpu_jpeg.h"
     31 #include "amdgpu_pm.h"
     32 #include "soc15.h"
     33 #include "soc15d.h"
     34 
     35 #include "vcn/vcn_2_0_0_offset.h"
     36 #include "vcn/vcn_2_0_0_sh_mask.h"
     37 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
     38 
     39 #define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 			0x1bfff
     40 #define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET				0x4029
     41 #define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET				0x402a
     42 #define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET				0x402b
     43 #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET		0x40ea
     44 #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 	0x40eb
     45 #define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET				0x40cf
     46 #define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET				0x40d1
     47 #define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 		0x40e8
     48 #define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET		0x40e9
     49 #define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET				0x4082
     50 #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET		0x40ec
     51 #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 	0x40ed
     52 #define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET			0x4085
     53 #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET				0x4084
     54 #define mmUVD_JRBC_STATUS_INTERNAL_OFFSET				0x4089
     55 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET				0x401f
     56 
     57 #define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR				0x18000
     58 
     59 static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev);
     60 static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev);
     61 static int jpeg_v2_0_set_powergating_state(void *handle,
     62 				enum amd_powergating_state state);
     63 
     64 /**
     65  * jpeg_v2_0_early_init - set function pointers
     66  *
     67  * @handle: amdgpu_device pointer
     68  *
     69  * Set ring and irq function pointers
     70  */
     71 static int jpeg_v2_0_early_init(void *handle)
     72 {
     73 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     74 
     75 	adev->jpeg.num_jpeg_inst = 1;
     76 
     77 	jpeg_v2_0_set_dec_ring_funcs(adev);
     78 	jpeg_v2_0_set_irq_funcs(adev);
     79 
     80 	return 0;
     81 }
     82 
     83 /**
     84  * jpeg_v2_0_sw_init - sw init for JPEG block
     85  *
     86  * @handle: amdgpu_device pointer
     87  *
     88  * Load firmware and sw initialization
     89  */
     90 static int jpeg_v2_0_sw_init(void *handle)
     91 {
     92 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     93 	struct amdgpu_ring *ring;
     94 	int r;
     95 
     96 	/* JPEG TRAP */
     97 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
     98 		VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
     99 	if (r)
    100 		return r;
    101 
    102 	r = amdgpu_jpeg_sw_init(adev);
    103 	if (r)
    104 		return r;
    105 
    106 	r = amdgpu_jpeg_resume(adev);
    107 	if (r)
    108 		return r;
    109 
    110 	ring = &adev->jpeg.inst->ring_dec;
    111 	ring->use_doorbell = true;
    112 	ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
    113 	snprintf(ring->name, sizeof(ring->name), "jpeg_dec");
    114 	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0);
    115 	if (r)
    116 		return r;
    117 
    118 	adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
    119 	adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
    120 
    121 	return 0;
    122 }
    123 
    124 /**
    125  * jpeg_v2_0_sw_fini - sw fini for JPEG block
    126  *
    127  * @handle: amdgpu_device pointer
    128  *
    129  * JPEG suspend and free up sw allocation
    130  */
    131 static int jpeg_v2_0_sw_fini(void *handle)
    132 {
    133 	int r;
    134 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    135 
    136 	r = amdgpu_jpeg_suspend(adev);
    137 	if (r)
    138 		return r;
    139 
    140 	r = amdgpu_jpeg_sw_fini(adev);
    141 
    142 	return r;
    143 }
    144 
    145 /**
    146  * jpeg_v2_0_hw_init - start and test JPEG block
    147  *
    148  * @handle: amdgpu_device pointer
    149  *
    150  */
    151 static int jpeg_v2_0_hw_init(void *handle)
    152 {
    153 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    154 	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
    155 	int r;
    156 
    157 	adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
    158 		(adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
    159 
    160 	r = amdgpu_ring_test_helper(ring);
    161 	if (!r)
    162 		DRM_INFO("JPEG decode initialized successfully.\n");
    163 
    164 	return r;
    165 }
    166 
    167 /**
    168  * jpeg_v2_0_hw_fini - stop the hardware block
    169  *
    170  * @handle: amdgpu_device pointer
    171  *
    172  * Stop the JPEG block, mark ring as not ready any more
    173  */
    174 static int jpeg_v2_0_hw_fini(void *handle)
    175 {
    176 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    177 	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
    178 
    179 	if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
    180 	      RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
    181 		jpeg_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
    182 
    183 	ring->sched.ready = false;
    184 
    185 	return 0;
    186 }
    187 
    188 /**
    189  * jpeg_v2_0_suspend - suspend JPEG block
    190  *
    191  * @handle: amdgpu_device pointer
    192  *
    193  * HW fini and suspend JPEG block
    194  */
    195 static int jpeg_v2_0_suspend(void *handle)
    196 {
    197 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    198 	int r;
    199 
    200 	r = jpeg_v2_0_hw_fini(adev);
    201 	if (r)
    202 		return r;
    203 
    204 	r = amdgpu_jpeg_suspend(adev);
    205 
    206 	return r;
    207 }
    208 
    209 /**
    210  * jpeg_v2_0_resume - resume JPEG block
    211  *
    212  * @handle: amdgpu_device pointer
    213  *
    214  * Resume firmware and hw init JPEG block
    215  */
    216 static int jpeg_v2_0_resume(void *handle)
    217 {
    218 	int r;
    219 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    220 
    221 	r = amdgpu_jpeg_resume(adev);
    222 	if (r)
    223 		return r;
    224 
    225 	r = jpeg_v2_0_hw_init(adev);
    226 
    227 	return r;
    228 }
    229 
    230 static int jpeg_v2_0_disable_power_gating(struct amdgpu_device *adev)
    231 {
    232 	uint32_t data;
    233 	int r = 0;
    234 
    235 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
    236 		data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
    237 		WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
    238 
    239 		SOC15_WAIT_ON_RREG(JPEG, 0,
    240 			mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
    241 			UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r);
    242 
    243 		if (r) {
    244 			DRM_ERROR("amdgpu: JPEG disable power gating failed\n");
    245 			return r;
    246 		}
    247 	}
    248 
    249 	/* Removing the anti hang mechanism to indicate the UVDJ tile is ON */
    250 	data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS)) & ~0x1;
    251 	WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data);
    252 
    253 	return 0;
    254 }
    255 
    256 static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev)
    257 {
    258 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
    259 		uint32_t data;
    260 		int r = 0;
    261 
    262 		data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS));
    263 		data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
    264 		data |=  0x1; //UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_TILES_OFF;
    265 		WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data);
    266 
    267 		data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
    268 		WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
    269 
    270 		SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_PGFSM_STATUS,
    271 			(2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
    272 			UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r);
    273 
    274 		if (r) {
    275 			DRM_ERROR("amdgpu: JPEG enable power gating failed\n");
    276 			return r;
    277 		}
    278 	}
    279 
    280 	return 0;
    281 }
    282 
    283 static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev)
    284 {
    285 	uint32_t data;
    286 
    287 	data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
    288 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
    289 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
    290 	else
    291 		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
    292 
    293 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
    294 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
    295 	WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
    296 
    297 	data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
    298 	data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
    299 		| JPEG_CGC_GATE__JPEG2_DEC_MASK
    300 		| JPEG_CGC_GATE__JPEG_ENC_MASK
    301 		| JPEG_CGC_GATE__JMCIF_MASK
    302 		| JPEG_CGC_GATE__JRBBM_MASK);
    303 	WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
    304 }
    305 
    306 static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device* adev)
    307 {
    308 	uint32_t data;
    309 
    310 	data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
    311 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
    312 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
    313 	else
    314 		data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
    315 
    316 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
    317 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
    318 	WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
    319 
    320 	data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
    321 	data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
    322 		|JPEG_CGC_GATE__JPEG2_DEC_MASK
    323 		|JPEG_CGC_GATE__JPEG_ENC_MASK
    324 		|JPEG_CGC_GATE__JMCIF_MASK
    325 		|JPEG_CGC_GATE__JRBBM_MASK);
    326 	WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
    327 }
    328 
    329 /**
    330  * jpeg_v2_0_start - start JPEG block
    331  *
    332  * @adev: amdgpu_device pointer
    333  *
    334  * Setup and start the JPEG block
    335  */
    336 static int jpeg_v2_0_start(struct amdgpu_device *adev)
    337 {
    338 	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
    339 	int r;
    340 
    341 	if (adev->pm.dpm_enabled)
    342 		amdgpu_dpm_enable_jpeg(adev, true);
    343 
    344 	/* disable power gating */
    345 	r = jpeg_v2_0_disable_power_gating(adev);
    346 	if (r)
    347 		return r;
    348 
    349 	/* JPEG disable CGC */
    350 	jpeg_v2_0_disable_clock_gating(adev);
    351 
    352 	WREG32_SOC15(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
    353 
    354 	/* enable JMI channel */
    355 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 0,
    356 		~UVD_JMI_CNTL__SOFT_RESET_MASK);
    357 
    358 	/* enable System Interrupt for JRBC */
    359 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmJPEG_SYS_INT_EN),
    360 		JPEG_SYS_INT_EN__DJRBC_MASK,
    361 		~JPEG_SYS_INT_EN__DJRBC_MASK);
    362 
    363 	WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
    364 	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
    365 	WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
    366 		lower_32_bits(ring->gpu_addr));
    367 	WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
    368 		upper_32_bits(ring->gpu_addr));
    369 	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
    370 	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
    371 	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L);
    372 	WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
    373 	ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
    374 
    375 	return 0;
    376 }
    377 
    378 /**
    379  * jpeg_v2_0_stop - stop JPEG block
    380  *
    381  * @adev: amdgpu_device pointer
    382  *
    383  * stop the JPEG block
    384  */
    385 static int jpeg_v2_0_stop(struct amdgpu_device *adev)
    386 {
    387 	int r;
    388 
    389 	/* reset JMI */
    390 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL),
    391 		UVD_JMI_CNTL__SOFT_RESET_MASK,
    392 		~UVD_JMI_CNTL__SOFT_RESET_MASK);
    393 
    394 	/* enable JPEG CGC */
    395 	jpeg_v2_0_enable_clock_gating(adev);
    396 
    397 	/* enable power gating */
    398 	r = jpeg_v2_0_enable_power_gating(adev);
    399 	if (r)
    400 		return r;
    401 
    402 	if (adev->pm.dpm_enabled)
    403 		amdgpu_dpm_enable_jpeg(adev, false);
    404 
    405 	return 0;
    406 }
    407 
    408 /**
    409  * jpeg_v2_0_dec_ring_get_rptr - get read pointer
    410  *
    411  * @ring: amdgpu_ring pointer
    412  *
    413  * Returns the current hardware read pointer
    414  */
    415 static uint64_t jpeg_v2_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
    416 {
    417 	struct amdgpu_device *adev = ring->adev;
    418 
    419 	return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
    420 }
    421 
    422 /**
    423  * jpeg_v2_0_dec_ring_get_wptr - get write pointer
    424  *
    425  * @ring: amdgpu_ring pointer
    426  *
    427  * Returns the current hardware write pointer
    428  */
    429 static uint64_t jpeg_v2_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
    430 {
    431 	struct amdgpu_device *adev = ring->adev;
    432 
    433 	if (ring->use_doorbell)
    434 		return adev->wb.wb[ring->wptr_offs];
    435 	else
    436 		return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
    437 }
    438 
    439 /**
    440  * jpeg_v2_0_dec_ring_set_wptr - set write pointer
    441  *
    442  * @ring: amdgpu_ring pointer
    443  *
    444  * Commits the write pointer to the hardware
    445  */
    446 static void jpeg_v2_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
    447 {
    448 	struct amdgpu_device *adev = ring->adev;
    449 
    450 	if (ring->use_doorbell) {
    451 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
    452 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
    453 	} else {
    454 		WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
    455 	}
    456 }
    457 
    458 /**
    459  * jpeg_v2_0_dec_ring_insert_start - insert a start command
    460  *
    461  * @ring: amdgpu_ring pointer
    462  *
    463  * Write a start command to the ring.
    464  */
    465 void jpeg_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring)
    466 {
    467 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
    468 		0, 0, PACKETJ_TYPE0));
    469 	amdgpu_ring_write(ring, 0x68e04);
    470 
    471 	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
    472 		0, 0, PACKETJ_TYPE0));
    473 	amdgpu_ring_write(ring, 0x80010000);
    474 }
    475 
    476 /**
    477  * jpeg_v2_0_dec_ring_insert_end - insert a end command
    478  *
    479  * @ring: amdgpu_ring pointer
    480  *
    481  * Write a end command to the ring.
    482  */
    483 void jpeg_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring)
    484 {
    485 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
    486 		0, 0, PACKETJ_TYPE0));
    487 	amdgpu_ring_write(ring, 0x68e04);
    488 
    489 	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
    490 		0, 0, PACKETJ_TYPE0));
    491 	amdgpu_ring_write(ring, 0x00010000);
    492 }
    493 
    494 /**
    495  * jpeg_v2_0_dec_ring_emit_fence - emit an fence & trap command
    496  *
    497  * @ring: amdgpu_ring pointer
    498  * @fence: fence to emit
    499  *
    500  * Write a fence and a trap command to the ring.
    501  */
    502 void jpeg_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
    503 				unsigned flags)
    504 {
    505 	WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
    506 
    507 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET,
    508 		0, 0, PACKETJ_TYPE0));
    509 	amdgpu_ring_write(ring, seq);
    510 
    511 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET,
    512 		0, 0, PACKETJ_TYPE0));
    513 	amdgpu_ring_write(ring, seq);
    514 
    515 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET,
    516 		0, 0, PACKETJ_TYPE0));
    517 	amdgpu_ring_write(ring, lower_32_bits(addr));
    518 
    519 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET,
    520 		0, 0, PACKETJ_TYPE0));
    521 	amdgpu_ring_write(ring, upper_32_bits(addr));
    522 
    523 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
    524 		0, 0, PACKETJ_TYPE0));
    525 	amdgpu_ring_write(ring, 0x8);
    526 
    527 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
    528 		0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
    529 	amdgpu_ring_write(ring, 0);
    530 
    531 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
    532 		0, 0, PACKETJ_TYPE0));
    533 	amdgpu_ring_write(ring, 0x3fbc);
    534 
    535 	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
    536 		0, 0, PACKETJ_TYPE0));
    537 	amdgpu_ring_write(ring, 0x1);
    538 
    539 	amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
    540 	amdgpu_ring_write(ring, 0);
    541 }
    542 
    543 /**
    544  * jpeg_v2_0_dec_ring_emit_ib - execute indirect buffer
    545  *
    546  * @ring: amdgpu_ring pointer
    547  * @ib: indirect buffer to execute
    548  *
    549  * Write ring commands to execute the indirect buffer.
    550  */
    551 void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
    552 				struct amdgpu_job *job,
    553 				struct amdgpu_ib *ib,
    554 				uint32_t flags)
    555 {
    556 	unsigned vmid = AMDGPU_JOB_GET_VMID(job);
    557 
    558 	amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
    559 		0, 0, PACKETJ_TYPE0));
    560 	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
    561 
    562 	amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
    563 		0, 0, PACKETJ_TYPE0));
    564 	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
    565 
    566 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
    567 		0, 0, PACKETJ_TYPE0));
    568 	amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
    569 
    570 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET,
    571 		0, 0, PACKETJ_TYPE0));
    572 	amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
    573 
    574 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET,
    575 		0, 0, PACKETJ_TYPE0));
    576 	amdgpu_ring_write(ring, ib->length_dw);
    577 
    578 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET,
    579 		0, 0, PACKETJ_TYPE0));
    580 	amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
    581 
    582 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET,
    583 		0, 0, PACKETJ_TYPE0));
    584 	amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
    585 
    586 	amdgpu_ring_write(ring,	PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
    587 	amdgpu_ring_write(ring, 0);
    588 
    589 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
    590 		0, 0, PACKETJ_TYPE0));
    591 	amdgpu_ring_write(ring, 0x01400200);
    592 
    593 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
    594 		0, 0, PACKETJ_TYPE0));
    595 	amdgpu_ring_write(ring, 0x2);
    596 
    597 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_STATUS_INTERNAL_OFFSET,
    598 		0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
    599 	amdgpu_ring_write(ring, 0x2);
    600 }
    601 
    602 void jpeg_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
    603 				uint32_t val, uint32_t mask)
    604 {
    605 	uint32_t reg_offset = (reg << 2);
    606 
    607 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
    608 		0, 0, PACKETJ_TYPE0));
    609 	amdgpu_ring_write(ring, 0x01400200);
    610 
    611 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
    612 		0, 0, PACKETJ_TYPE0));
    613 	amdgpu_ring_write(ring, val);
    614 
    615 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
    616 		0, 0, PACKETJ_TYPE0));
    617 	if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
    618 		amdgpu_ring_write(ring, 0);
    619 		amdgpu_ring_write(ring,
    620 			PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
    621 	} else {
    622 		amdgpu_ring_write(ring, reg_offset);
    623 		amdgpu_ring_write(ring,	PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
    624 			0, 0, PACKETJ_TYPE3));
    625 	}
    626 	amdgpu_ring_write(ring, mask);
    627 }
    628 
    629 void jpeg_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
    630 				unsigned vmid, uint64_t pd_addr)
    631 {
    632 	struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
    633 	uint32_t data0, data1, mask;
    634 
    635 	pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
    636 
    637 	/* wait for register write */
    638 	data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2;
    639 	data1 = lower_32_bits(pd_addr);
    640 	mask = 0xffffffff;
    641 	jpeg_v2_0_dec_ring_emit_reg_wait(ring, data0, data1, mask);
    642 }
    643 
    644 void jpeg_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val)
    645 {
    646 	uint32_t reg_offset = (reg << 2);
    647 
    648 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
    649 		0, 0, PACKETJ_TYPE0));
    650 	if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
    651 		amdgpu_ring_write(ring, 0);
    652 		amdgpu_ring_write(ring,
    653 			PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
    654 	} else {
    655 		amdgpu_ring_write(ring, reg_offset);
    656 		amdgpu_ring_write(ring,	PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
    657 			0, 0, PACKETJ_TYPE0));
    658 	}
    659 	amdgpu_ring_write(ring, val);
    660 }
    661 
    662 void jpeg_v2_0_dec_ring_nop(struct amdgpu_ring *ring, uint32_t count)
    663 {
    664 	int i;
    665 
    666 	WARN_ON(ring->wptr % 2 || count % 2);
    667 
    668 	for (i = 0; i < count / 2; i++) {
    669 		amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
    670 		amdgpu_ring_write(ring, 0);
    671 	}
    672 }
    673 
    674 static bool jpeg_v2_0_is_idle(void *handle)
    675 {
    676 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    677 
    678 	return ((RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS) &
    679 		UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
    680 		UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
    681 }
    682 
    683 static int jpeg_v2_0_wait_for_idle(void *handle)
    684 {
    685 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    686 	int ret = 0;
    687 
    688 	SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS, UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
    689 		UVD_JRBC_STATUS__RB_JOB_DONE_MASK, ret);
    690 
    691 	return ret;
    692 }
    693 
    694 static int jpeg_v2_0_set_clockgating_state(void *handle,
    695 					  enum amd_clockgating_state state)
    696 {
    697 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    698 	bool enable = (state == AMD_CG_STATE_GATE);
    699 
    700 	if (enable) {
    701 		if (jpeg_v2_0_is_idle(handle))
    702 			return -EBUSY;
    703 		jpeg_v2_0_enable_clock_gating(adev);
    704 	} else {
    705 		jpeg_v2_0_disable_clock_gating(adev);
    706 	}
    707 
    708 	return 0;
    709 }
    710 
    711 static int jpeg_v2_0_set_powergating_state(void *handle,
    712 					enum amd_powergating_state state)
    713 {
    714 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    715 	int ret;
    716 
    717 	if (state == adev->jpeg.cur_state)
    718 		return 0;
    719 
    720 	if (state == AMD_PG_STATE_GATE)
    721 		ret = jpeg_v2_0_stop(adev);
    722 	else
    723 		ret = jpeg_v2_0_start(adev);
    724 
    725 	if (!ret)
    726 		adev->jpeg.cur_state = state;
    727 
    728 	return ret;
    729 }
    730 
    731 static int jpeg_v2_0_set_interrupt_state(struct amdgpu_device *adev,
    732 					struct amdgpu_irq_src *source,
    733 					unsigned type,
    734 					enum amdgpu_interrupt_state state)
    735 {
    736 	return 0;
    737 }
    738 
    739 static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev,
    740 				      struct amdgpu_irq_src *source,
    741 				      struct amdgpu_iv_entry *entry)
    742 {
    743 	DRM_DEBUG("IH: JPEG TRAP\n");
    744 
    745 	switch (entry->src_id) {
    746 	case VCN_2_0__SRCID__JPEG_DECODE:
    747 		amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
    748 		break;
    749 	default:
    750 		DRM_ERROR("Unhandled interrupt: %d %d\n",
    751 			  entry->src_id, entry->src_data[0]);
    752 		break;
    753 	}
    754 
    755 	return 0;
    756 }
    757 
    758 static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
    759 	.name = "jpeg_v2_0",
    760 	.early_init = jpeg_v2_0_early_init,
    761 	.late_init = NULL,
    762 	.sw_init = jpeg_v2_0_sw_init,
    763 	.sw_fini = jpeg_v2_0_sw_fini,
    764 	.hw_init = jpeg_v2_0_hw_init,
    765 	.hw_fini = jpeg_v2_0_hw_fini,
    766 	.suspend = jpeg_v2_0_suspend,
    767 	.resume = jpeg_v2_0_resume,
    768 	.is_idle = jpeg_v2_0_is_idle,
    769 	.wait_for_idle = jpeg_v2_0_wait_for_idle,
    770 	.check_soft_reset = NULL,
    771 	.pre_soft_reset = NULL,
    772 	.soft_reset = NULL,
    773 	.post_soft_reset = NULL,
    774 	.set_clockgating_state = jpeg_v2_0_set_clockgating_state,
    775 	.set_powergating_state = jpeg_v2_0_set_powergating_state,
    776 };
    777 
    778 static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
    779 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
    780 	.align_mask = 0xf,
    781 	.vmhub = AMDGPU_MMHUB_0,
    782 	.get_rptr = jpeg_v2_0_dec_ring_get_rptr,
    783 	.get_wptr = jpeg_v2_0_dec_ring_get_wptr,
    784 	.set_wptr = jpeg_v2_0_dec_ring_set_wptr,
    785 	.emit_frame_size =
    786 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
    787 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
    788 		8 + /* jpeg_v2_0_dec_ring_emit_vm_flush */
    789 		18 + 18 + /* jpeg_v2_0_dec_ring_emit_fence x2 vm fence */
    790 		8 + 16,
    791 	.emit_ib_size = 22, /* jpeg_v2_0_dec_ring_emit_ib */
    792 	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,
    793 	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,
    794 	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
    795 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
    796 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
    797 	.insert_nop = jpeg_v2_0_dec_ring_nop,
    798 	.insert_start = jpeg_v2_0_dec_ring_insert_start,
    799 	.insert_end = jpeg_v2_0_dec_ring_insert_end,
    800 	.pad_ib = amdgpu_ring_generic_pad_ib,
    801 	.begin_use = amdgpu_jpeg_ring_begin_use,
    802 	.end_use = amdgpu_jpeg_ring_end_use,
    803 	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
    804 	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
    805 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    806 };
    807 
    808 static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
    809 {
    810 	adev->jpeg.inst->ring_dec.funcs = &jpeg_v2_0_dec_ring_vm_funcs;
    811 	DRM_INFO("JPEG decode is enabled in VM mode\n");
    812 }
    813 
    814 static const struct amdgpu_irq_src_funcs jpeg_v2_0_irq_funcs = {
    815 	.set = jpeg_v2_0_set_interrupt_state,
    816 	.process = jpeg_v2_0_process_interrupt,
    817 };
    818 
    819 static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev)
    820 {
    821 	adev->jpeg.inst->irq.num_types = 1;
    822 	adev->jpeg.inst->irq.funcs = &jpeg_v2_0_irq_funcs;
    823 }
    824 
    825 const struct amdgpu_ip_block_version jpeg_v2_0_ip_block =
    826 {
    827 		.type = AMD_IP_BLOCK_TYPE_JPEG,
    828 		.major = 2,
    829 		.minor = 0,
    830 		.rev = 0,
    831 		.funcs = &jpeg_v2_0_ip_funcs,
    832 };
    833