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