brintos

brintos / linux-shallow public Read only

0
0
Text · 21.8 KiB · eedb9a8 Raw
834 lines · c
1/*2 * Copyright 2019 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * 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 "jpeg_v2_0.h"29#include "jpeg_v2_5.h"30 31#include "vcn/vcn_2_5_offset.h"32#include "vcn/vcn_2_5_sh_mask.h"33#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"34 35#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET			0x401f36 37#define JPEG25_MAX_HW_INSTANCES_ARCTURUS			238 39static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);40static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev);41static int jpeg_v2_5_set_powergating_state(void *handle,42				enum amd_powergating_state state);43static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev);44 45static int amdgpu_ih_clientid_jpeg[] = {46	SOC15_IH_CLIENTID_VCN,47	SOC15_IH_CLIENTID_VCN148};49 50/**51 * jpeg_v2_5_early_init - set function pointers52 *53 * @handle: amdgpu_device pointer54 *55 * Set ring and irq function pointers56 */57static int jpeg_v2_5_early_init(void *handle)58{59	struct amdgpu_device *adev = (struct amdgpu_device *)handle;60	u32 harvest;61	int i;62 63	adev->jpeg.num_jpeg_rings = 1;64	adev->jpeg.num_jpeg_inst = JPEG25_MAX_HW_INSTANCES_ARCTURUS;65	for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {66		harvest = RREG32_SOC15(JPEG, i, mmCC_UVD_HARVESTING);67		if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)68			adev->jpeg.harvest_config |= 1 << i;69	}70	if (adev->jpeg.harvest_config == (AMDGPU_JPEG_HARVEST_JPEG0 |71					 AMDGPU_JPEG_HARVEST_JPEG1))72		return -ENOENT;73 74	jpeg_v2_5_set_dec_ring_funcs(adev);75	jpeg_v2_5_set_irq_funcs(adev);76	jpeg_v2_5_set_ras_funcs(adev);77 78	return 0;79}80 81/**82 * jpeg_v2_5_sw_init - sw init for JPEG block83 *84 * @handle: amdgpu_device pointer85 *86 * Load firmware and sw initialization87 */88static int jpeg_v2_5_sw_init(void *handle)89{90	struct amdgpu_ring *ring;91	int i, r;92	struct amdgpu_device *adev = (struct amdgpu_device *)handle;93 94	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {95		if (adev->jpeg.harvest_config & (1 << i))96			continue;97 98		/* JPEG TRAP */99		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],100				VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);101		if (r)102			return r;103 104		/* JPEG DJPEG POISON EVENT */105		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],106			VCN_2_6__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);107		if (r)108			return r;109 110		/* JPEG EJPEG POISON EVENT */111		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],112			VCN_2_6__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);113		if (r)114			return r;115	}116 117	r = amdgpu_jpeg_sw_init(adev);118	if (r)119		return r;120 121	r = amdgpu_jpeg_resume(adev);122	if (r)123		return r;124 125	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {126		if (adev->jpeg.harvest_config & (1 << i))127			continue;128 129		ring = adev->jpeg.inst[i].ring_dec;130		ring->use_doorbell = true;131		if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(2, 5, 0))132			ring->vm_hub = AMDGPU_MMHUB1(0);133		else134			ring->vm_hub = AMDGPU_MMHUB0(0);135		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;136		sprintf(ring->name, "jpeg_dec_%d", i);137		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,138				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);139		if (r)140			return r;141 142		adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;143		adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_PITCH);144	}145 146	r = amdgpu_jpeg_ras_sw_init(adev);147	if (r)148		return r;149 150	return 0;151}152 153/**154 * jpeg_v2_5_sw_fini - sw fini for JPEG block155 *156 * @handle: amdgpu_device pointer157 *158 * JPEG suspend and free up sw allocation159 */160static int jpeg_v2_5_sw_fini(void *handle)161{162	int r;163	struct amdgpu_device *adev = (struct amdgpu_device *)handle;164 165	r = amdgpu_jpeg_suspend(adev);166	if (r)167		return r;168 169	r = amdgpu_jpeg_sw_fini(adev);170 171	return r;172}173 174/**175 * jpeg_v2_5_hw_init - start and test JPEG block176 *177 * @handle: amdgpu_device pointer178 *179 */180static int jpeg_v2_5_hw_init(void *handle)181{182	struct amdgpu_device *adev = (struct amdgpu_device *)handle;183	struct amdgpu_ring *ring;184	int i, r;185 186	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {187		if (adev->jpeg.harvest_config & (1 << i))188			continue;189 190		ring = adev->jpeg.inst[i].ring_dec;191		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,192			(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);193 194		r = amdgpu_ring_test_helper(ring);195		if (r)196			return r;197	}198 199	return 0;200}201 202/**203 * jpeg_v2_5_hw_fini - stop the hardware block204 *205 * @handle: amdgpu_device pointer206 *207 * Stop the JPEG block, mark ring as not ready any more208 */209static int jpeg_v2_5_hw_fini(void *handle)210{211	struct amdgpu_device *adev = (struct amdgpu_device *)handle;212	int i;213 214	cancel_delayed_work_sync(&adev->vcn.idle_work);215 216	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {217		if (adev->jpeg.harvest_config & (1 << i))218			continue;219 220		if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&221		      RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS))222			jpeg_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);223 224		if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG))225			amdgpu_irq_put(adev, &adev->jpeg.inst[i].ras_poison_irq, 0);226	}227 228	return 0;229}230 231/**232 * jpeg_v2_5_suspend - suspend JPEG block233 *234 * @handle: amdgpu_device pointer235 *236 * HW fini and suspend JPEG block237 */238static int jpeg_v2_5_suspend(void *handle)239{240	struct amdgpu_device *adev = (struct amdgpu_device *)handle;241	int r;242 243	r = jpeg_v2_5_hw_fini(adev);244	if (r)245		return r;246 247	r = amdgpu_jpeg_suspend(adev);248 249	return r;250}251 252/**253 * jpeg_v2_5_resume - resume JPEG block254 *255 * @handle: amdgpu_device pointer256 *257 * Resume firmware and hw init JPEG block258 */259static int jpeg_v2_5_resume(void *handle)260{261	struct amdgpu_device *adev = (struct amdgpu_device *)handle;262	int r;263 264	r = amdgpu_jpeg_resume(adev);265	if (r)266		return r;267 268	r = jpeg_v2_5_hw_init(adev);269 270	return r;271}272 273static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device *adev, int inst)274{275	uint32_t data;276 277	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);278	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)279		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;280	else281		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;282 283	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;284	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;285	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);286 287	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);288	data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK289		| JPEG_CGC_GATE__JPEG2_DEC_MASK290		| JPEG_CGC_GATE__JMCIF_MASK291		| JPEG_CGC_GATE__JRBBM_MASK);292	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);293 294	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);295	data &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK296		| JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK297		| JPEG_CGC_CTRL__JMCIF_MODE_MASK298		| JPEG_CGC_CTRL__JRBBM_MODE_MASK);299	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);300}301 302static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)303{304	uint32_t data;305 306	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);307	data |= (JPEG_CGC_GATE__JPEG_DEC_MASK308		|JPEG_CGC_GATE__JPEG2_DEC_MASK309		|JPEG_CGC_GATE__JPEG_ENC_MASK310		|JPEG_CGC_GATE__JMCIF_MASK311		|JPEG_CGC_GATE__JRBBM_MASK);312	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);313}314 315/**316 * jpeg_v2_5_start - start JPEG block317 *318 * @adev: amdgpu_device pointer319 *320 * Setup and start the JPEG block321 */322static int jpeg_v2_5_start(struct amdgpu_device *adev)323{324	struct amdgpu_ring *ring;325	int i;326 327	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {328		if (adev->jpeg.harvest_config & (1 << i))329			continue;330 331		ring = adev->jpeg.inst[i].ring_dec;332		/* disable anti hang mechanism */333		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0,334			~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);335 336		/* JPEG disable CGC */337		jpeg_v2_5_disable_clock_gating(adev, i);338 339		/* MJPEG global tiling registers */340		WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,341			adev->gfx.config.gb_addr_config);342		WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,343			adev->gfx.config.gb_addr_config);344 345		/* enable JMI channel */346		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0,347			~UVD_JMI_CNTL__SOFT_RESET_MASK);348 349		/* enable System Interrupt for JRBC */350		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN),351			JPEG_SYS_INT_EN__DJRBC_MASK,352			~JPEG_SYS_INT_EN__DJRBC_MASK);353 354		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0);355		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));356		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,357			lower_32_bits(ring->gpu_addr));358		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,359			upper_32_bits(ring->gpu_addr));360		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0);361		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0);362		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);363		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);364		ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR);365	}366 367	return 0;368}369 370/**371 * jpeg_v2_5_stop - stop JPEG block372 *373 * @adev: amdgpu_device pointer374 *375 * stop the JPEG block376 */377static int jpeg_v2_5_stop(struct amdgpu_device *adev)378{379	int i;380 381	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {382		if (adev->jpeg.harvest_config & (1 << i))383			continue;384 385		/* reset JMI */386		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL),387			UVD_JMI_CNTL__SOFT_RESET_MASK,388			~UVD_JMI_CNTL__SOFT_RESET_MASK);389 390		jpeg_v2_5_enable_clock_gating(adev, i);391 392		/* enable anti hang mechanism */393		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS),394			UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,395			~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);396	}397 398	return 0;399}400 401/**402 * jpeg_v2_5_dec_ring_get_rptr - get read pointer403 *404 * @ring: amdgpu_ring pointer405 *406 * Returns the current hardware read pointer407 */408static uint64_t jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)409{410	struct amdgpu_device *adev = ring->adev;411 412	return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_RPTR);413}414 415/**416 * jpeg_v2_5_dec_ring_get_wptr - get write pointer417 *418 * @ring: amdgpu_ring pointer419 *420 * Returns the current hardware write pointer421 */422static uint64_t jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)423{424	struct amdgpu_device *adev = ring->adev;425 426	if (ring->use_doorbell)427		return *ring->wptr_cpu_addr;428	else429		return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR);430}431 432/**433 * jpeg_v2_5_dec_ring_set_wptr - set write pointer434 *435 * @ring: amdgpu_ring pointer436 *437 * Commits the write pointer to the hardware438 */439static void jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)440{441	struct amdgpu_device *adev = ring->adev;442 443	if (ring->use_doorbell) {444		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);445		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));446	} else {447		WREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));448	}449}450 451/**452 * jpeg_v2_6_dec_ring_insert_start - insert a start command453 *454 * @ring: amdgpu_ring pointer455 *456 * Write a start command to the ring.457 */458static void jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring *ring)459{460	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,461		0, 0, PACKETJ_TYPE0));462	amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */463 464	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,465		0, 0, PACKETJ_TYPE0));466	amdgpu_ring_write(ring, 0x80000000 | (1 << (ring->me * 2 + 14)));467}468 469/**470 * jpeg_v2_6_dec_ring_insert_end - insert a end command471 *472 * @ring: amdgpu_ring pointer473 *474 * Write a end command to the ring.475 */476static void jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring *ring)477{478	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,479		0, 0, PACKETJ_TYPE0));480	amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */481 482	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,483		0, 0, PACKETJ_TYPE0));484	amdgpu_ring_write(ring, (1 << (ring->me * 2 + 14)));485}486 487static bool jpeg_v2_5_is_idle(void *handle)488{489	struct amdgpu_device *adev = (struct amdgpu_device *)handle;490	int i, ret = 1;491 492	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {493		if (adev->jpeg.harvest_config & (1 << i))494			continue;495 496		ret &= (((RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS) &497			UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==498			UVD_JRBC_STATUS__RB_JOB_DONE_MASK));499	}500 501	return ret;502}503 504static int jpeg_v2_5_wait_for_idle(void *handle)505{506	struct amdgpu_device *adev = (struct amdgpu_device *)handle;507	int i, ret;508 509	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {510		if (adev->jpeg.harvest_config & (1 << i))511			continue;512 513		ret = SOC15_WAIT_ON_RREG(JPEG, i, mmUVD_JRBC_STATUS,514			UVD_JRBC_STATUS__RB_JOB_DONE_MASK,515			UVD_JRBC_STATUS__RB_JOB_DONE_MASK);516		if (ret)517			return ret;518	}519 520	return 0;521}522 523static int jpeg_v2_5_set_clockgating_state(void *handle,524					  enum amd_clockgating_state state)525{526	struct amdgpu_device *adev = (struct amdgpu_device *)handle;527	bool enable = (state == AMD_CG_STATE_GATE);528	int i;529 530	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {531		if (adev->jpeg.harvest_config & (1 << i))532			continue;533 534		if (enable) {535			if (!jpeg_v2_5_is_idle(handle))536				return -EBUSY;537			jpeg_v2_5_enable_clock_gating(adev, i);538		} else {539			jpeg_v2_5_disable_clock_gating(adev, i);540		}541	}542 543	return 0;544}545 546static int jpeg_v2_5_set_powergating_state(void *handle,547					  enum amd_powergating_state state)548{549	struct amdgpu_device *adev = (struct amdgpu_device *)handle;550	int ret;551 552	if (state == adev->jpeg.cur_state)553		return 0;554 555	if (state == AMD_PG_STATE_GATE)556		ret = jpeg_v2_5_stop(adev);557	else558		ret = jpeg_v2_5_start(adev);559 560	if (!ret)561		adev->jpeg.cur_state = state;562 563	return ret;564}565 566static int jpeg_v2_5_set_interrupt_state(struct amdgpu_device *adev,567					struct amdgpu_irq_src *source,568					unsigned type,569					enum amdgpu_interrupt_state state)570{571	return 0;572}573 574static int jpeg_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,575					struct amdgpu_irq_src *source,576					unsigned int type,577					enum amdgpu_interrupt_state state)578{579	return 0;580}581 582static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev,583				      struct amdgpu_irq_src *source,584				      struct amdgpu_iv_entry *entry)585{586	uint32_t ip_instance;587 588	switch (entry->client_id) {589	case SOC15_IH_CLIENTID_VCN:590		ip_instance = 0;591		break;592	case SOC15_IH_CLIENTID_VCN1:593		ip_instance = 1;594		break;595	default:596		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);597		return 0;598	}599 600	DRM_DEBUG("IH: JPEG TRAP\n");601 602	switch (entry->src_id) {603	case VCN_2_0__SRCID__JPEG_DECODE:604		amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);605		break;606	default:607		DRM_ERROR("Unhandled interrupt: %d %d\n",608			  entry->src_id, entry->src_data[0]);609		break;610	}611 612	return 0;613}614 615static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {616	.name = "jpeg_v2_5",617	.early_init = jpeg_v2_5_early_init,618	.late_init = NULL,619	.sw_init = jpeg_v2_5_sw_init,620	.sw_fini = jpeg_v2_5_sw_fini,621	.hw_init = jpeg_v2_5_hw_init,622	.hw_fini = jpeg_v2_5_hw_fini,623	.suspend = jpeg_v2_5_suspend,624	.resume = jpeg_v2_5_resume,625	.is_idle = jpeg_v2_5_is_idle,626	.wait_for_idle = jpeg_v2_5_wait_for_idle,627	.check_soft_reset = NULL,628	.pre_soft_reset = NULL,629	.soft_reset = NULL,630	.post_soft_reset = NULL,631	.set_clockgating_state = jpeg_v2_5_set_clockgating_state,632	.set_powergating_state = jpeg_v2_5_set_powergating_state,633	.dump_ip_state = NULL,634	.print_ip_state = NULL,635};636 637static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {638	.name = "jpeg_v2_6",639	.early_init = jpeg_v2_5_early_init,640	.late_init = NULL,641	.sw_init = jpeg_v2_5_sw_init,642	.sw_fini = jpeg_v2_5_sw_fini,643	.hw_init = jpeg_v2_5_hw_init,644	.hw_fini = jpeg_v2_5_hw_fini,645	.suspend = jpeg_v2_5_suspend,646	.resume = jpeg_v2_5_resume,647	.is_idle = jpeg_v2_5_is_idle,648	.wait_for_idle = jpeg_v2_5_wait_for_idle,649	.check_soft_reset = NULL,650	.pre_soft_reset = NULL,651	.soft_reset = NULL,652	.post_soft_reset = NULL,653	.set_clockgating_state = jpeg_v2_5_set_clockgating_state,654	.set_powergating_state = jpeg_v2_5_set_powergating_state,655	.dump_ip_state = NULL,656	.print_ip_state = NULL,657};658 659static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {660	.type = AMDGPU_RING_TYPE_VCN_JPEG,661	.align_mask = 0xf,662	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,663	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,664	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,665	.parse_cs = jpeg_v2_dec_ring_parse_cs,666	.emit_frame_size =667		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +668		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +669		8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */670		18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */671		8 + 16,672	.emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */673	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,674	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,675	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,676	.test_ring = amdgpu_jpeg_dec_ring_test_ring,677	.test_ib = amdgpu_jpeg_dec_ring_test_ib,678	.insert_nop = jpeg_v2_0_dec_ring_nop,679	.insert_start = jpeg_v2_0_dec_ring_insert_start,680	.insert_end = jpeg_v2_0_dec_ring_insert_end,681	.pad_ib = amdgpu_ring_generic_pad_ib,682	.begin_use = amdgpu_jpeg_ring_begin_use,683	.end_use = amdgpu_jpeg_ring_end_use,684	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,685	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,686	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,687};688 689static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = {690	.type = AMDGPU_RING_TYPE_VCN_JPEG,691	.align_mask = 0xf,692	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,693	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,694	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,695	.parse_cs = jpeg_v2_dec_ring_parse_cs,696	.emit_frame_size =697		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +698		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +699		8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */700		18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */701		8 + 16,702	.emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */703	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,704	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,705	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,706	.test_ring = amdgpu_jpeg_dec_ring_test_ring,707	.test_ib = amdgpu_jpeg_dec_ring_test_ib,708	.insert_nop = jpeg_v2_0_dec_ring_nop,709	.insert_start = jpeg_v2_6_dec_ring_insert_start,710	.insert_end = jpeg_v2_6_dec_ring_insert_end,711	.pad_ib = amdgpu_ring_generic_pad_ib,712	.begin_use = amdgpu_jpeg_ring_begin_use,713	.end_use = amdgpu_jpeg_ring_end_use,714	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,715	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,716	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,717};718 719static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)720{721	int i;722 723	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {724		if (adev->jpeg.harvest_config & (1 << i))725			continue;726		if (adev->asic_type == CHIP_ARCTURUS)727			adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_5_dec_ring_vm_funcs;728		else  /* CHIP_ALDEBARAN */729			adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_6_dec_ring_vm_funcs;730		adev->jpeg.inst[i].ring_dec->me = i;731	}732}733 734static const struct amdgpu_irq_src_funcs jpeg_v2_5_irq_funcs = {735	.set = jpeg_v2_5_set_interrupt_state,736	.process = jpeg_v2_5_process_interrupt,737};738 739static const struct amdgpu_irq_src_funcs jpeg_v2_6_ras_irq_funcs = {740	.set = jpeg_v2_6_set_ras_interrupt_state,741	.process = amdgpu_jpeg_process_poison_irq,742};743 744static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev)745{746	int i;747 748	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {749		if (adev->jpeg.harvest_config & (1 << i))750			continue;751 752		adev->jpeg.inst[i].irq.num_types = 1;753		adev->jpeg.inst[i].irq.funcs = &jpeg_v2_5_irq_funcs;754 755		adev->jpeg.inst[i].ras_poison_irq.num_types = 1;756		adev->jpeg.inst[i].ras_poison_irq.funcs = &jpeg_v2_6_ras_irq_funcs;757	}758}759 760const struct amdgpu_ip_block_version jpeg_v2_5_ip_block = {761		.type = AMD_IP_BLOCK_TYPE_JPEG,762		.major = 2,763		.minor = 5,764		.rev = 0,765		.funcs = &jpeg_v2_5_ip_funcs,766};767 768const struct amdgpu_ip_block_version jpeg_v2_6_ip_block = {769		.type = AMD_IP_BLOCK_TYPE_JPEG,770		.major = 2,771		.minor = 6,772		.rev = 0,773		.funcs = &jpeg_v2_6_ip_funcs,774};775 776static uint32_t jpeg_v2_6_query_poison_by_instance(struct amdgpu_device *adev,777		uint32_t instance, uint32_t sub_block)778{779	uint32_t poison_stat = 0, reg_value = 0;780 781	switch (sub_block) {782	case AMDGPU_JPEG_V2_6_JPEG0:783		reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG0_STATUS);784		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG0_STATUS, POISONED_PF);785		break;786	case AMDGPU_JPEG_V2_6_JPEG1:787		reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG1_STATUS);788		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG1_STATUS, POISONED_PF);789		break;790	default:791		break;792	}793 794	if (poison_stat)795		dev_info(adev->dev, "Poison detected in JPEG%d sub_block%d\n",796			instance, sub_block);797 798	return poison_stat;799}800 801static bool jpeg_v2_6_query_ras_poison_status(struct amdgpu_device *adev)802{803	uint32_t inst = 0, sub = 0, poison_stat = 0;804 805	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; inst++)806		for (sub = 0; sub < AMDGPU_JPEG_V2_6_MAX_SUB_BLOCK; sub++)807			poison_stat +=808			jpeg_v2_6_query_poison_by_instance(adev, inst, sub);809 810	return !!poison_stat;811}812 813const struct amdgpu_ras_block_hw_ops jpeg_v2_6_ras_hw_ops = {814	.query_poison_status = jpeg_v2_6_query_ras_poison_status,815};816 817static struct amdgpu_jpeg_ras jpeg_v2_6_ras = {818	.ras_block = {819		.hw_ops = &jpeg_v2_6_ras_hw_ops,820		.ras_late_init = amdgpu_jpeg_ras_late_init,821	},822};823 824static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev)825{826	switch (amdgpu_ip_version(adev, JPEG_HWIP, 0)) {827	case IP_VERSION(2, 6, 0):828		adev->jpeg.ras = &jpeg_v2_6_ras;829		break;830	default:831		break;832	}833}834