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