2626#include "soc15.h"
2727#include "soc15d.h"
2828#include "jpeg_v4_0_3.h"
29+ #include "mmsch_v4_0_3.h"
2930
3031#include "vcn/vcn_4_0_3_offset.h"
3132#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);
4142static int jpeg_v4_0_3_set_powergating_state (void * handle ,
4243 enum amd_powergating_state state );
4344static 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 );
4446
4547static int amdgpu_ih_srcid_jpeg [] = {
4648 VCN_4_0__SRCID__JPEG_DECODE ,
@@ -171,6 +173,119 @@ static int jpeg_v4_0_3_sw_fini(void *handle)
171173 return r ;
172174}
173175
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+
174289/**
175290 * jpeg_v4_0_3_hw_init - start and test JPEG block
176291 *
@@ -183,31 +298,47 @@ static int jpeg_v4_0_3_hw_init(void *handle)
183298 struct amdgpu_ring * ring ;
184299 int i , j , r , jpeg_inst ;
185300
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 ;
188305
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 );
190318
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 ;
197320
198- for (j = 0 ; j < adev -> jpeg .num_jpeg_rings ; ++ j ) {
199- ring = & adev -> jpeg .inst [i ].ring_dec [j ];
200321 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
206336 << 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+ }
211342 }
212343 }
213344 DRM_DEV_INFO (adev -> dev , "JPEG decode initialized successfully.\n" );
0 commit comments