26
26
#include "soc15.h"
27
27
#include "soc15d.h"
28
28
#include "jpeg_v4_0_3.h"
29
+ #include "mmsch_v4_0_3.h"
29
30
30
31
#include "vcn/vcn_4_0_3_offset.h"
31
32
#include "vcn/vcn_4_0_3_sh_mask.h"
@@ -41,6 +42,7 @@ static void jpeg_v4_0_3_set_irq_funcs(struct amdgpu_device *adev);
41
42
static int jpeg_v4_0_3_set_powergating_state (void * handle ,
42
43
enum amd_powergating_state state );
43
44
static void jpeg_v4_0_3_set_ras_funcs (struct amdgpu_device * adev );
45
+ static void jpeg_v4_0_3_dec_ring_set_wptr (struct amdgpu_ring * ring );
44
46
45
47
static int amdgpu_ih_srcid_jpeg [] = {
46
48
VCN_4_0__SRCID__JPEG_DECODE ,
@@ -171,6 +173,119 @@ static int jpeg_v4_0_3_sw_fini(void *handle)
171
173
return r ;
172
174
}
173
175
176
+ static int jpeg_v4_0_3_start_sriov (struct amdgpu_device * adev )
177
+ {
178
+ struct amdgpu_ring * ring ;
179
+ uint64_t ctx_addr ;
180
+ uint32_t param , resp , expected ;
181
+ uint32_t tmp , timeout ;
182
+
183
+ struct amdgpu_mm_table * table = & adev -> virt .mm_table ;
184
+ uint32_t * table_loc ;
185
+ uint32_t table_size ;
186
+ uint32_t size , size_dw , item_offset ;
187
+ uint32_t init_status ;
188
+ int i , j , jpeg_inst ;
189
+
190
+ struct mmsch_v4_0_cmd_direct_write
191
+ direct_wt = { {0 } };
192
+ struct mmsch_v4_0_cmd_end end = { {0 } };
193
+ struct mmsch_v4_0_3_init_header header ;
194
+
195
+ direct_wt .cmd_header .command_type =
196
+ MMSCH_COMMAND__DIRECT_REG_WRITE ;
197
+ end .cmd_header .command_type =
198
+ MMSCH_COMMAND__END ;
199
+
200
+ for (i = 0 ; i < adev -> jpeg .num_jpeg_inst ; i ++ ) {
201
+ jpeg_inst = GET_INST (JPEG , i );
202
+
203
+ memset (& header , 0 , sizeof (struct mmsch_v4_0_3_init_header ));
204
+ header .version = MMSCH_VERSION ;
205
+ header .total_size = sizeof (struct mmsch_v4_0_3_init_header ) >> 2 ;
206
+
207
+ table_loc = (uint32_t * )table -> cpu_addr ;
208
+ table_loc += header .total_size ;
209
+
210
+ item_offset = header .total_size ;
211
+
212
+ for (j = 0 ; j < adev -> jpeg .num_jpeg_rings ; j ++ ) {
213
+ ring = & adev -> jpeg .inst [i ].ring_dec [j ];
214
+ table_size = 0 ;
215
+
216
+ tmp = SOC15_REG_OFFSET (JPEG , 0 , regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_LOW );
217
+ MMSCH_V4_0_INSERT_DIRECT_WT (tmp , lower_32_bits (ring -> gpu_addr ));
218
+ tmp = SOC15_REG_OFFSET (JPEG , 0 , regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_HIGH );
219
+ MMSCH_V4_0_INSERT_DIRECT_WT (tmp , upper_32_bits (ring -> gpu_addr ));
220
+ tmp = SOC15_REG_OFFSET (JPEG , 0 , regUVD_JRBC0_UVD_JRBC_RB_SIZE );
221
+ MMSCH_V4_0_INSERT_DIRECT_WT (tmp , ring -> ring_size / 4 );
222
+
223
+ if (j <= 3 ) {
224
+ header .mjpegdec0 [j ].table_offset = item_offset ;
225
+ header .mjpegdec0 [j ].init_status = 0 ;
226
+ header .mjpegdec0 [j ].table_size = table_size ;
227
+ } else {
228
+ header .mjpegdec1 [j - 4 ].table_offset = item_offset ;
229
+ header .mjpegdec1 [j - 4 ].init_status = 0 ;
230
+ header .mjpegdec1 [j - 4 ].table_size = table_size ;
231
+ }
232
+ header .total_size += table_size ;
233
+ item_offset += table_size ;
234
+ }
235
+
236
+ MMSCH_V4_0_INSERT_END ();
237
+
238
+ /* send init table to MMSCH */
239
+ size = sizeof (struct mmsch_v4_0_3_init_header );
240
+ table_loc = (uint32_t * )table -> cpu_addr ;
241
+ memcpy ((void * )table_loc , & header , size );
242
+
243
+ ctx_addr = table -> gpu_addr ;
244
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_CTX_ADDR_LO , lower_32_bits (ctx_addr ));
245
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_CTX_ADDR_HI , upper_32_bits (ctx_addr ));
246
+
247
+ tmp = RREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_VMID );
248
+ tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK ;
249
+ tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT );
250
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_VMID , tmp );
251
+
252
+ size = header .total_size ;
253
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_CTX_SIZE , size );
254
+
255
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_MAILBOX_RESP , 0 );
256
+
257
+ param = 0x00000001 ;
258
+ WREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_MAILBOX_HOST , param );
259
+ tmp = 0 ;
260
+ timeout = 1000 ;
261
+ resp = 0 ;
262
+ expected = MMSCH_VF_MAILBOX_RESP__OK ;
263
+ init_status =
264
+ ((struct mmsch_v4_0_3_init_header * )(table_loc ))-> mjpegdec0 [i ].init_status ;
265
+ while (resp != expected ) {
266
+ resp = RREG32_SOC15 (VCN , jpeg_inst , regMMSCH_VF_MAILBOX_RESP );
267
+
268
+ if (resp != 0 )
269
+ break ;
270
+ udelay (10 );
271
+ tmp = tmp + 10 ;
272
+ if (tmp >= timeout ) {
273
+ DRM_ERROR ("failed to init MMSCH. TIME-OUT after %d usec" \
274
+ " waiting for regMMSCH_VF_MAILBOX_RESP " \
275
+ "(expected=0x%08x, readback=0x%08x)\n" ,
276
+ tmp , expected , resp );
277
+ return - EBUSY ;
278
+ }
279
+ }
280
+ if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE &&
281
+ init_status != MMSCH_VF_ENGINE_STATUS__PASS )
282
+ DRM_ERROR ("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n" ,
283
+ resp , init_status );
284
+
285
+ }
286
+ return 0 ;
287
+ }
288
+
174
289
/**
175
290
* jpeg_v4_0_3_hw_init - start and test JPEG block
176
291
*
@@ -183,31 +298,47 @@ static int jpeg_v4_0_3_hw_init(void *handle)
183
298
struct amdgpu_ring * ring ;
184
299
int i , j , r , jpeg_inst ;
185
300
186
- for (i = 0 ; i < adev -> jpeg .num_jpeg_inst ; ++ i ) {
187
- jpeg_inst = GET_INST (JPEG , i );
301
+ if (amdgpu_sriov_vf (adev )) {
302
+ r = jpeg_v4_0_3_start_sriov (adev );
303
+ if (r )
304
+ return r ;
188
305
189
- ring = adev -> jpeg .inst [i ].ring_dec ;
306
+ for (i = 0 ; i < adev -> vcn .num_vcn_inst ; ++ i ) {
307
+ for (j = 0 ; j < adev -> jpeg .num_jpeg_rings ; ++ j ) {
308
+ ring = & adev -> jpeg .inst [i ].ring_dec [j ];
309
+ ring -> wptr = 0 ;
310
+ ring -> wptr_old = 0 ;
311
+ jpeg_v4_0_3_dec_ring_set_wptr (ring );
312
+ ring -> sched .ready = true;
313
+ }
314
+ }
315
+ } else {
316
+ for (i = 0 ; i < adev -> jpeg .num_jpeg_inst ; ++ i ) {
317
+ jpeg_inst = GET_INST (JPEG , i );
190
318
191
- if (ring -> use_doorbell )
192
- adev -> nbio .funcs -> vcn_doorbell_range (
193
- adev , ring -> use_doorbell ,
194
- (adev -> doorbell_index .vcn .vcn_ring0_1 << 1 ) +
195
- 9 * jpeg_inst ,
196
- adev -> jpeg .inst [i ].aid_id );
319
+ ring = adev -> jpeg .inst [i ].ring_dec ;
197
320
198
- for (j = 0 ; j < adev -> jpeg .num_jpeg_rings ; ++ j ) {
199
- ring = & adev -> jpeg .inst [i ].ring_dec [j ];
200
321
if (ring -> use_doorbell )
201
- WREG32_SOC15_OFFSET (
202
- VCN , GET_INST (VCN , i ),
203
- regVCN_JPEG_DB_CTRL ,
204
- (ring -> pipe ? (ring -> pipe - 0x15 ) : 0 ),
205
- ring -> doorbell_index
322
+ adev -> nbio .funcs -> vcn_doorbell_range (
323
+ adev , ring -> use_doorbell ,
324
+ (adev -> doorbell_index .vcn .vcn_ring0_1 << 1 ) +
325
+ 9 * jpeg_inst ,
326
+ adev -> jpeg .inst [i ].aid_id );
327
+
328
+ for (j = 0 ; j < adev -> jpeg .num_jpeg_rings ; ++ j ) {
329
+ ring = & adev -> jpeg .inst [i ].ring_dec [j ];
330
+ if (ring -> use_doorbell )
331
+ WREG32_SOC15_OFFSET (
332
+ VCN , GET_INST (VCN , i ),
333
+ regVCN_JPEG_DB_CTRL ,
334
+ (ring -> pipe ? (ring -> pipe - 0x15 ) : 0 ),
335
+ ring -> doorbell_index
206
336
<< VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
207
- VCN_JPEG_DB_CTRL__EN_MASK );
208
- r = amdgpu_ring_test_helper (ring );
209
- if (r )
210
- return r ;
337
+ VCN_JPEG_DB_CTRL__EN_MASK );
338
+ r = amdgpu_ring_test_helper (ring );
339
+ if (r )
340
+ return r ;
341
+ }
211
342
}
212
343
}
213
344
DRM_DEV_INFO (adev -> dev , "JPEG decode initialized successfully.\n" );
0 commit comments