File Index
Files and directories
Sign in
FILE

jpeg_v4_0_5.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c C
  1/*
  2 * Copyright 2023 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 "amdgpu_pm.h"
 27#include "soc15.h"
 28#include "soc15d.h"
 29#include "jpeg_v2_0.h"
 30#include "jpeg_v4_0_5.h"
 31#include "mmsch_v4_0.h"
 32
 33#include "vcn/vcn_4_0_5_offset.h"
 34#include "vcn/vcn_4_0_5_sh_mask.h"
 35#include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
 36
 37#define mmUVD_DPG_LMA_CTL						regUVD_DPG_LMA_CTL
 38#define mmUVD_DPG_LMA_CTL_BASE_IDX					regUVD_DPG_LMA_CTL_BASE_IDX
 39#define mmUVD_DPG_LMA_DATA						regUVD_DPG_LMA_DATA
 40#define mmUVD_DPG_LMA_DATA_BASE_IDX					regUVD_DPG_LMA_DATA_BASE_IDX
 41
 42#define regUVD_JPEG_PITCH_INTERNAL_OFFSET		0x401f
 43#define regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET	0x4026
 44#define regJPEG_SYS_INT_EN_INTERNAL_OFFSET		0x4141
 45#define regJPEG_CGC_CTRL_INTERNAL_OFFSET		0x4161
 46#define regJPEG_CGC_GATE_INTERNAL_OFFSET		0x4160
 47#define regUVD_NO_OP_INTERNAL_OFFSET			0x0029
 48
 49static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0_5[] = {
 50	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
 51	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
 52	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
 53	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
 54	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
 55	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
 56	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
 57	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
 58	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
 59	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
 60	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
 61	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
 62	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
 63};
 64
 65static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev);
 66static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev);
 67static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
 68				enum amd_powergating_state state);
 69static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring);
 70
 71static int amdgpu_ih_clientid_jpeg[] = {
 72	SOC15_IH_CLIENTID_VCN,
 73	SOC15_IH_CLIENTID_VCN1
 74};
 75
 76
 77
 78/**
 79 * jpeg_v4_0_5_early_init - set function pointers
 80 *
 81 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 82 *
 83 * Set ring and irq function pointers
 84 */
 85static int jpeg_v4_0_5_early_init(struct amdgpu_ip_block *ip_block)
 86{
 87	struct amdgpu_device *adev = ip_block->adev;
 88
 89	switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
 90	case IP_VERSION(4, 0, 5):
 91		adev->jpeg.num_jpeg_inst = 1;
 92		break;
 93	case IP_VERSION(4, 0, 6):
 94		adev->jpeg.num_jpeg_inst = 2;
 95		break;
 96	default:
 97		DRM_DEV_ERROR(adev->dev,
 98			"Failed to init vcn ip block(UVD_HWIP:0x%x)\n",
 99			amdgpu_ip_version(adev, UVD_HWIP, 0));
100		return -EINVAL;
101	}
102
103	adev->jpeg.num_jpeg_rings = 1;
104
105	jpeg_v4_0_5_set_dec_ring_funcs(adev);
106	jpeg_v4_0_5_set_irq_funcs(adev);
107
108	return 0;
109}
110
111/**
112 * jpeg_v4_0_5_sw_init - sw init for JPEG block
113 *
114 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
115 *
116 * Load firmware and sw initialization
117 */
118static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
119{
120	struct amdgpu_device *adev = ip_block->adev;
121	struct amdgpu_ring *ring;
122	int r, i;
123
124	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
125		if (adev->jpeg.harvest_config & (1 << i))
126			continue;
127
128		/* JPEG TRAP */
129		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
130				VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
131		if (r)
132			return r;
133
134		/* JPEG DJPEG POISON EVENT */
135		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
136			VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].irq);
137		if (r)
138			return r;
139
140		/* JPEG EJPEG POISON EVENT */
141		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
142			VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].irq);
143		if (r)
144			return r;
145	}
146
147	r = amdgpu_jpeg_sw_init(adev);
148	if (r)
149		return r;
150
151	r = amdgpu_jpeg_resume(adev);
152	if (r)
153		return r;
154
155	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
156		if (adev->jpeg.harvest_config & (1 << i))
157			continue;
158
159		ring = adev->jpeg.inst[i].ring_dec;
160		ring->use_doorbell = true;
161		ring->vm_hub = AMDGPU_MMHUB0(0);
162		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
163		sprintf(ring->name, "jpeg_dec_%d", i);
164		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
165				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
166		if (r)
167			return r;
168
169		adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
170		adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, regUVD_JPEG_PITCH);
171	}
172
173	r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_5, ARRAY_SIZE(jpeg_reg_list_4_0_5));
174	if (r)
175		return r;
176
177	adev->jpeg.supported_reset =
178		amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
179	if (!amdgpu_sriov_vf(adev))
180		adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
181	r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
182	if (r)
183		return r;
184
185	return 0;
186}
187
188/**
189 * jpeg_v4_0_5_sw_fini - sw fini for JPEG block
190 *
191 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
192 *
193 * JPEG suspend and free up sw allocation
194 */
195static int jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block)
196{
197	struct amdgpu_device *adev = ip_block->adev;
198	int r;
199
200	r = amdgpu_jpeg_suspend(adev);
201	if (r)
202		return r;
203
204	amdgpu_jpeg_sysfs_reset_mask_fini(adev);
205	r = amdgpu_jpeg_sw_fini(adev);
206
207	return r;
208}
209
210/**
211 * jpeg_v4_0_5_hw_init - start and test JPEG block
212 *
213 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
214 *
215 */
216static int jpeg_v4_0_5_hw_init(struct amdgpu_ip_block *ip_block)
217{
218	struct amdgpu_device *adev = ip_block->adev;
219	struct amdgpu_ring *ring;
220	int i, r = 0;
221
222	// TODO: Enable ring test with DPG support
223	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
224		return 0;
225	}
226
227	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
228		if (adev->jpeg.harvest_config & (1 << i))
229			continue;
230
231		ring = adev->jpeg.inst[i].ring_dec;
232		r = amdgpu_ring_test_helper(ring);
233		if (r)
234			return r;
235	}
236
237	return 0;
238}
239
240/**
241 * jpeg_v4_0_5_hw_fini - stop the hardware block
242 *
243 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
244 *
245 * Stop the JPEG block, mark ring as not ready any more
246 */
247static int jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block)
248{
249	struct amdgpu_device *adev = ip_block->adev;
250	int i;
251
252	cancel_delayed_work_sync(&adev->jpeg.idle_work);
253
254	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
255		if (adev->jpeg.harvest_config & (1 << i))
256			continue;
257
258		if (!amdgpu_sriov_vf(adev)) {
259			if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
260			    RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS))
261				jpeg_v4_0_5_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
262		}
263	}
264	return 0;
265}
266
267/**
268 * jpeg_v4_0_5_suspend - suspend JPEG block
269 *
270 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
271 *
272 * HW fini and suspend JPEG block
273 */
274static int jpeg_v4_0_5_suspend(struct amdgpu_ip_block *ip_block)
275{
276	int r;
277
278	r = jpeg_v4_0_5_hw_fini(ip_block);
279	if (r)
280		return r;
281
282	r = amdgpu_jpeg_suspend(ip_block->adev);
283
284	return r;
285}
286
287/**
288 * jpeg_v4_0_5_resume - resume JPEG block
289 *
290 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
291 *
292 * Resume firmware and hw init JPEG block
293 */
294static int jpeg_v4_0_5_resume(struct amdgpu_ip_block *ip_block)
295{
296	int r;
297
298	r = amdgpu_jpeg_resume(ip_block->adev);
299	if (r)
300		return r;
301
302	r = jpeg_v4_0_5_hw_init(ip_block);
303
304	return r;
305}
306
307static void jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
308{
309	uint32_t data = 0;
310
311	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
312	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
313		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
314		data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
315	} else {
316		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
317	}
318
319	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
320	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
321	WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
322
323	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
324	data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
325		| JPEG_CGC_GATE__JPEG2_DEC_MASK
326		| JPEG_CGC_GATE__JMCIF_MASK
327		| JPEG_CGC_GATE__JRBBM_MASK);
328	WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
329}
330
331static void jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
332{
333	uint32_t data = 0;
334
335	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
336	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
337		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
338		data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
339	} else {
340		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
341	}
342
343	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
344	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
345	WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
346
347	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
348	data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
349		|JPEG_CGC_GATE__JPEG2_DEC_MASK
350		|JPEG_CGC_GATE__JMCIF_MASK
351		|JPEG_CGC_GATE__JRBBM_MASK);
352	WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
353}
354
355static void jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device *adev,
356			int inst_idx, uint8_t indirect)
357{
358	uint32_t data = 0;
359
360	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
361		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
362	else
363		data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
364
365	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
366	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
367	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_CTRL_INTERNAL_OFFSET, data, indirect);
368
369	data = 0;
370	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_GATE_INTERNAL_OFFSET,
371				data, indirect);
372}
373
374static int jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst)
375{
376	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
377		WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
378			1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
379		SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
380			0, UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
381	}
382
383	/* disable anti hang mechanism */
384	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
385		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
386
387	/* keep the JPEG in static PG mode */
388	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
389		~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
390
391	return 0;
392}
393
394static int jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst)
395{
396	/* enable anti hang mechanism */
397	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS),
398		UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
399		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
400
401	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
402		WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
403			2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
404		SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
405			1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
406			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
407	}
408
409	return 0;
410}
411
412/**
413 * jpeg_v4_0_5_start_dpg_mode - Jpeg start with dpg mode
414 *
415 * @adev: amdgpu_device pointer
416 * @inst_idx: instance number index
417 * @indirect: indirectly write sram
418 *
419 * Start JPEG block with dpg mode
420 */
421static void jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
422{
423	struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
424	uint32_t reg_data = 0;
425
426	/* enable anti hang mechanism */
427	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
428	reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
429	reg_data |=  0x1;
430	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
431
432	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
433		WREG32(SOC15_REG_OFFSET(JPEG, inst_idx, regUVD_IPX_DLDO_CONFIG),
434			2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
435		SOC15_WAIT_ON_RREG(JPEG, inst_idx, regUVD_IPX_DLDO_STATUS,
436			1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
437			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
438	}
439
440	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
441	reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
442	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
443
444	if (indirect)
445		adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
446					(uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
447
448	jpeg_engine_4_0_5_dpg_clock_gating_mode(adev, inst_idx, indirect);
449
450	/* MJPEG global tiling registers */
451	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET,
452	adev->gfx.config.gb_addr_config, indirect);
453	/* enable System Interrupt for JRBC */
454	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_SYS_INT_EN_INTERNAL_OFFSET,
455	JPEG_SYS_INT_EN__DJRBC_MASK, indirect);
456
457	/* add nop to workaround PSP size check */
458	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regUVD_NO_OP_INTERNAL_OFFSET, 0, indirect);
459
460	if (indirect)
461		amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
462
463	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
464	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
465	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
466		lower_32_bits(ring->gpu_addr));
467	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
468		upper_32_bits(ring->gpu_addr));
469	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0);
470	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0);
471	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L);
472	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
473	ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR);
474}
475
476/**
477 * jpeg_v4_0_5_stop_dpg_mode - Jpeg stop with dpg mode
478 *
479 * @adev: amdgpu_device pointer
480 * @inst_idx: instance number index
481 *
482 * Stop JPEG block with dpg mode
483 */
484static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
485{
486	uint32_t reg_data = 0;
487
488	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
489	reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
490	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
491
492}
493
494/**
495 * jpeg_v4_0_5_start - start JPEG block
496 *
497 * @adev: amdgpu_device pointer
498 *
499 * Setup and start the JPEG block
500 */
501static int jpeg_v4_0_5_start(struct amdgpu_device *adev)
502{
503	struct amdgpu_ring *ring;
504	int r, i;
505
506	if (adev->pm.dpm_enabled)
507		amdgpu_dpm_enable_jpeg(adev, true);
508
509	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
510		if (adev->jpeg.harvest_config & (1 << i))
511			continue;
512
513		ring = adev->jpeg.inst[i].ring_dec;
514		/* doorbell programming is done for every playback */
515		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
516				(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
517
518		WREG32_SOC15(VCN, i, regVCN_JPEG_DB_CTRL,
519			ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
520			VCN_JPEG_DB_CTRL__EN_MASK);
521
522		if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
523			jpeg_v4_0_5_start_dpg_mode(adev, i, adev->jpeg.indirect_sram);
524			continue;
525		}
526
527		/* disable power gating */
528		r = jpeg_v4_0_5_disable_static_power_gating(adev, i);
529		if (r)
530			return r;
531
532		/* JPEG disable CGC */
533		jpeg_v4_0_5_disable_clock_gating(adev, i);
534
535		/* MJPEG global tiling registers */
536		WREG32_SOC15(JPEG, i, regJPEG_DEC_GFX10_ADDR_CONFIG,
537			adev->gfx.config.gb_addr_config);
538
539		/* enable JMI channel */
540		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 0,
541			~UVD_JMI_CNTL__SOFT_RESET_MASK);
542
543		/* enable System Interrupt for JRBC */
544		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regJPEG_SYS_INT_EN),
545			JPEG_SYS_INT_EN__DJRBC_MASK,
546			~JPEG_SYS_INT_EN__DJRBC_MASK);
547
548		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_VMID, 0);
549		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
550		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
551			lower_32_bits(ring->gpu_addr));
552		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
553			upper_32_bits(ring->gpu_addr));
554		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_RPTR, 0);
555		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR, 0);
556		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, 0x00000002L);
557		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
558		ring->wptr = RREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR);
559	}
560
561	return 0;
562}
563
564/**
565 * jpeg_v4_0_5_stop - stop JPEG block
566 *
567 * @adev: amdgpu_device pointer
568 *
569 * stop the JPEG block
570 */
571static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
572{
573	int r, i;
574
575	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
576		if (adev->jpeg.harvest_config & (1 << i))
577			continue;
578
579		if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
580			jpeg_v4_0_5_stop_dpg_mode(adev, i);
581			continue;
582		}
583
584		/* reset JMI */
585		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL),
586			UVD_JMI_CNTL__SOFT_RESET_MASK,
587			~UVD_JMI_CNTL__SOFT_RESET_MASK);
588
589		jpeg_v4_0_5_enable_clock_gating(adev, i);
590
591		/* enable power gating */
592		r = jpeg_v4_0_5_enable_static_power_gating(adev, i);
593		if (r)
594			return r;
595	}
596	if (adev->pm.dpm_enabled)
597		amdgpu_dpm_enable_jpeg(adev, false);
598
599	return 0;
600}
601
602/**
603 * jpeg_v4_0_5_dec_ring_get_rptr - get read pointer
604 *
605 * @ring: amdgpu_ring pointer
606 *
607 * Returns the current hardware read pointer
608 */
609static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
610{
611	struct amdgpu_device *adev = ring->adev;
612
613	return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_RPTR);
614}
615
616/**
617 * jpeg_v4_0_5_dec_ring_get_wptr - get write pointer
618 *
619 * @ring: amdgpu_ring pointer
620 *
621 * Returns the current hardware write pointer
622 */
623static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
624{
625	struct amdgpu_device *adev = ring->adev;
626
627	if (ring->use_doorbell)
628		return *ring->wptr_cpu_addr;
629	else
630		return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR);
631}
632
633/**
634 * jpeg_v4_0_5_dec_ring_set_wptr - set write pointer
635 *
636 * @ring: amdgpu_ring pointer
637 *
638 * Commits the write pointer to the hardware
639 */
640static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
641{
642	struct amdgpu_device *adev = ring->adev;
643
644	if (ring->use_doorbell) {
645		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
646		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
647	} else {
648		WREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
649	}
650}
651
652static bool jpeg_v4_0_5_is_idle(struct amdgpu_ip_block *ip_block)
653{
654	struct amdgpu_device *adev = ip_block->adev;
655	int i, ret = 1;
656
657	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
658		if (adev->jpeg.harvest_config & (1 << i))
659			continue;
660
661		ret &= (((RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS) &
662			UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
663			UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
664	}
665	return ret;
666}
667
668static int jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
669{
670	struct amdgpu_device *adev = ip_block->adev;
671	int i;
672
673	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
674		if (adev->jpeg.harvest_config & (1 << i))
675			continue;
676
677		return SOC15_WAIT_ON_RREG(JPEG, i, regUVD_JRBC_STATUS,
678			UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
679			UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
680	}
681
682	return 0;
683}
684
685static int jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
686					  enum amd_clockgating_state state)
687{
688	struct amdgpu_device *adev = ip_block->adev;
689	bool enable = state == AMD_CG_STATE_GATE;
690	int i;
691
692	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
693		if (adev->jpeg.harvest_config & (1 << i))
694			continue;
695
696		if (enable) {
697			if (!jpeg_v4_0_5_is_idle(ip_block))
698				return -EBUSY;
699
700			jpeg_v4_0_5_enable_clock_gating(adev, i);
701		} else {
702			jpeg_v4_0_5_disable_clock_gating(adev, i);
703		}
704	}
705
706	return 0;
707}
708
709static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
710					  enum amd_powergating_state state)
711{
712	struct amdgpu_device *adev = ip_block->adev;
713	int ret;
714
715	if (amdgpu_sriov_vf(adev)) {
716		adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
717		return 0;
718	}
719
720	if (state == adev->jpeg.cur_state)
721		return 0;
722
723	if (state == AMD_PG_STATE_GATE)
724		ret = jpeg_v4_0_5_stop(adev);
725	else
726		ret = jpeg_v4_0_5_start(adev);
727
728	if (!ret)
729		adev->jpeg.cur_state = state;
730
731	return ret;
732}
733
734static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
735				      struct amdgpu_irq_src *source,
736				      struct amdgpu_iv_entry *entry)
737{
738	uint32_t ip_instance;
739
740	DRM_DEBUG("IH: JPEG TRAP\n");
741
742	switch (entry->client_id) {
743	case SOC15_IH_CLIENTID_VCN:
744		ip_instance = 0;
745		break;
746	case SOC15_IH_CLIENTID_VCN1:
747		ip_instance = 1;
748		break;
749	default:
750		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
751		return 0;
752	}
753
754	switch (entry->src_id) {
755	case VCN_4_0__SRCID__JPEG_DECODE:
756		amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
757		break;
758	case VCN_4_0__SRCID_DJPEG0_POISON:
759	case VCN_4_0__SRCID_EJPEG0_POISON:
760		amdgpu_jpeg_process_poison_irq(adev, source, entry);
761		break;
762	default:
763		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
764			  entry->src_id, entry->src_data[0]);
765		break;
766	}
767
768	return 0;
769}
770
771static int jpeg_v4_0_5_ring_reset(struct amdgpu_ring *ring,
772				  unsigned int vmid,
773				  struct amdgpu_fence *timedout_fence)
774{
775	int r;
776
777	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
778	r = jpeg_v4_0_5_stop(ring->adev);
779	if (r)
780		return r;
781	r = jpeg_v4_0_5_start(ring->adev);
782	if (r)
783		return r;
784	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
785}
786
787static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
788	.name = "jpeg_v4_0_5",
789	.early_init = jpeg_v4_0_5_early_init,
790	.sw_init = jpeg_v4_0_5_sw_init,
791	.sw_fini = jpeg_v4_0_5_sw_fini,
792	.hw_init = jpeg_v4_0_5_hw_init,
793	.hw_fini = jpeg_v4_0_5_hw_fini,
794	.suspend = jpeg_v4_0_5_suspend,
795	.resume = jpeg_v4_0_5_resume,
796	.is_idle = jpeg_v4_0_5_is_idle,
797	.wait_for_idle = jpeg_v4_0_5_wait_for_idle,
798	.set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
799	.set_powergating_state = jpeg_v4_0_5_set_powergating_state,
800	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
801	.print_ip_state = amdgpu_jpeg_print_ip_state,
802};
803
804static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
805	.type = AMDGPU_RING_TYPE_VCN_JPEG,
806	.align_mask = 0xf,
807	.get_rptr = jpeg_v4_0_5_dec_ring_get_rptr,
808	.get_wptr = jpeg_v4_0_5_dec_ring_get_wptr,
809	.set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
810	.parse_cs = amdgpu_jpeg_dec_parse_cs,
811	.emit_frame_size =
812		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
813		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
814		8 + /* jpeg_v4_0_5_dec_ring_emit_vm_flush */
815		18 + 18 + /* jpeg_v4_0_5_dec_ring_emit_fence x2 vm fence */
816		8 + 16,
817	.emit_ib_size = 22, /* jpeg_v4_0_5_dec_ring_emit_ib */
818	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,
819	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,
820	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
821	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
822	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
823	.insert_nop = jpeg_v2_0_dec_ring_nop,
824	.insert_start = jpeg_v2_0_dec_ring_insert_start,
825	.insert_end = jpeg_v2_0_dec_ring_insert_end,
826	.pad_ib = amdgpu_ring_generic_pad_ib,
827	.begin_use = amdgpu_jpeg_ring_begin_use,
828	.end_use = amdgpu_jpeg_ring_end_use,
829	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
830	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
831	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
832	.reset = jpeg_v4_0_5_ring_reset,
833};
834
835static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
836{
837	int i;
838
839	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
840		if (adev->jpeg.harvest_config & (1 << i))
841			continue;
842
843		adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs;
844		adev->jpeg.inst[i].ring_dec->me = i;
845	}
846}
847
848static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = {
849	.process = jpeg_v4_0_5_process_interrupt,
850};
851
852static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev)
853{
854	int i;
855
856	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
857		if (adev->jpeg.harvest_config & (1 << i))
858			continue;
859
860		adev->jpeg.inst[i].irq.num_types = 1;
861		adev->jpeg.inst[i].irq.funcs = &jpeg_v4_0_5_irq_funcs;
862	}
863}
864
865const struct amdgpu_ip_block_version jpeg_v4_0_5_ip_block = {
866	.type = AMD_IP_BLOCK_TYPE_JPEG,
867	.major = 4,
868	.minor = 0,
869	.rev = 5,
870	.funcs = &jpeg_v4_0_5_ip_funcs,
871};
872
~/ Read-only file preview.