4343#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616
4444#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617
4545#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618
46+ #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
4647
4748#define VCE_V3_0_FW_SIZE (384 * 1024)
4849#define VCE_V3_0_STACK_SIZE (64 * 1024)
5152static void vce_v3_0_mc_resume (struct amdgpu_device * adev , int idx );
5253static void vce_v3_0_set_ring_funcs (struct amdgpu_device * adev );
5354static void vce_v3_0_set_irq_funcs (struct amdgpu_device * adev );
55+ static int vce_v3_0_wait_for_idle (void * handle );
5456
5557/**
5658 * vce_v3_0_ring_get_rptr - get read pointer
@@ -205,6 +207,32 @@ static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
205207 vce_v3_0_override_vce_clock_gating (adev , false);
206208}
207209
210+ static int vce_v3_0_firmware_loaded (struct amdgpu_device * adev )
211+ {
212+ int i , j ;
213+ uint32_t status = 0 ;
214+
215+ for (i = 0 ; i < 10 ; ++ i ) {
216+ for (j = 0 ; j < 100 ; ++ j ) {
217+ status = RREG32 (mmVCE_STATUS );
218+ if (status & VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK )
219+ return 0 ;
220+ mdelay (10 );
221+ }
222+
223+ DRM_ERROR ("VCE not responding, trying to reset the ECPU!!!\n" );
224+ WREG32_P (mmVCE_SOFT_RESET ,
225+ VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK ,
226+ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
227+ mdelay (10 );
228+ WREG32_P (mmVCE_SOFT_RESET , 0 ,
229+ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
230+ mdelay (10 );
231+ }
232+
233+ return - ETIMEDOUT ;
234+ }
235+
208236/**
209237 * vce_v3_0_start - start VCE block
210238 *
@@ -215,11 +243,24 @@ static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
215243static int vce_v3_0_start (struct amdgpu_device * adev )
216244{
217245 struct amdgpu_ring * ring ;
218- int idx , i , j , r ;
246+ int idx , r ;
247+
248+ ring = & adev -> vce .ring [0 ];
249+ WREG32 (mmVCE_RB_RPTR , ring -> wptr );
250+ WREG32 (mmVCE_RB_WPTR , ring -> wptr );
251+ WREG32 (mmVCE_RB_BASE_LO , ring -> gpu_addr );
252+ WREG32 (mmVCE_RB_BASE_HI , upper_32_bits (ring -> gpu_addr ));
253+ WREG32 (mmVCE_RB_SIZE , ring -> ring_size / 4 );
254+
255+ ring = & adev -> vce .ring [1 ];
256+ WREG32 (mmVCE_RB_RPTR2 , ring -> wptr );
257+ WREG32 (mmVCE_RB_WPTR2 , ring -> wptr );
258+ WREG32 (mmVCE_RB_BASE_LO2 , ring -> gpu_addr );
259+ WREG32 (mmVCE_RB_BASE_HI2 , upper_32_bits (ring -> gpu_addr ));
260+ WREG32 (mmVCE_RB_SIZE2 , ring -> ring_size / 4 );
219261
220262 mutex_lock (& adev -> grbm_idx_mutex );
221263 for (idx = 0 ; idx < 2 ; ++ idx ) {
222-
223264 if (adev -> vce .harvest_config & (1 << idx ))
224265 continue ;
225266
@@ -233,48 +274,24 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
233274
234275 vce_v3_0_mc_resume (adev , idx );
235276
236- /* set BUSY flag */
237- WREG32_P (mmVCE_STATUS , 1 , ~1 );
277+ WREG32_P (mmVCE_STATUS , VCE_STATUS__JOB_BUSY_MASK ,
278+ ~VCE_STATUS__JOB_BUSY_MASK );
279+
238280 if (adev -> asic_type >= CHIP_STONEY )
239281 WREG32_P (mmVCE_VCPU_CNTL , 1 , ~0x200001 );
240282 else
241283 WREG32_P (mmVCE_VCPU_CNTL , VCE_VCPU_CNTL__CLK_EN_MASK ,
242284 ~VCE_VCPU_CNTL__CLK_EN_MASK );
243285
244- WREG32_P (mmVCE_SOFT_RESET ,
245- VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK ,
246- ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
247-
248- mdelay (100 );
249-
250286 WREG32_P (mmVCE_SOFT_RESET , 0 ,
251287 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
252288
253- for (i = 0 ; i < 10 ; ++ i ) {
254- uint32_t status ;
255- for (j = 0 ; j < 100 ; ++ j ) {
256- status = RREG32 (mmVCE_STATUS );
257- if (status & 2 )
258- break ;
259- mdelay (10 );
260- }
261- r = 0 ;
262- if (status & 2 )
263- break ;
264-
265- DRM_ERROR ("VCE not responding, trying to reset the ECPU!!!\n" );
266- WREG32_P (mmVCE_SOFT_RESET ,
267- VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK ,
268- ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
269- mdelay (10 );
270- WREG32_P (mmVCE_SOFT_RESET , 0 ,
271- ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
272- mdelay (10 );
273- r = -1 ;
274- }
289+ mdelay (100 );
290+
291+ r = vce_v3_0_firmware_loaded (adev );
275292
276293 /* clear BUSY flag */
277- WREG32_P (mmVCE_STATUS , 0 , ~1 );
294+ WREG32_P (mmVCE_STATUS , 0 , ~VCE_STATUS__JOB_BUSY_MASK );
278295
279296 /* Set Clock-Gating off */
280297 if (adev -> cg_flags & AMD_CG_SUPPORT_VCE_MGCG )
@@ -290,19 +307,46 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
290307 WREG32_P (mmGRBM_GFX_INDEX , 0 , ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK );
291308 mutex_unlock (& adev -> grbm_idx_mutex );
292309
293- ring = & adev -> vce .ring [0 ];
294- WREG32 (mmVCE_RB_RPTR , ring -> wptr );
295- WREG32 (mmVCE_RB_WPTR , ring -> wptr );
296- WREG32 (mmVCE_RB_BASE_LO , ring -> gpu_addr );
297- WREG32 (mmVCE_RB_BASE_HI , upper_32_bits (ring -> gpu_addr ));
298- WREG32 (mmVCE_RB_SIZE , ring -> ring_size / 4 );
310+ return 0 ;
311+ }
299312
300- ring = & adev -> vce .ring [1 ];
301- WREG32 (mmVCE_RB_RPTR2 , ring -> wptr );
302- WREG32 (mmVCE_RB_WPTR2 , ring -> wptr );
303- WREG32 (mmVCE_RB_BASE_LO2 , ring -> gpu_addr );
304- WREG32 (mmVCE_RB_BASE_HI2 , upper_32_bits (ring -> gpu_addr ));
305- WREG32 (mmVCE_RB_SIZE2 , ring -> ring_size / 4 );
313+ static int vce_v3_0_stop (struct amdgpu_device * adev )
314+ {
315+ int idx ;
316+
317+ mutex_lock (& adev -> grbm_idx_mutex );
318+ for (idx = 0 ; idx < 2 ; ++ idx ) {
319+ if (adev -> vce .harvest_config & (1 << idx ))
320+ continue ;
321+
322+ if (idx == 0 )
323+ WREG32_P (mmGRBM_GFX_INDEX , 0 ,
324+ ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK );
325+ else
326+ WREG32_P (mmGRBM_GFX_INDEX ,
327+ GRBM_GFX_INDEX__VCE_INSTANCE_MASK ,
328+ ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK );
329+
330+ if (adev -> asic_type >= CHIP_STONEY )
331+ WREG32_P (mmVCE_VCPU_CNTL , 0 , ~0x200001 );
332+ else
333+ WREG32_P (mmVCE_VCPU_CNTL , 0 ,
334+ ~VCE_VCPU_CNTL__CLK_EN_MASK );
335+ /* hold on ECPU */
336+ WREG32_P (mmVCE_SOFT_RESET ,
337+ VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK ,
338+ ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK );
339+
340+ /* clear BUSY flag */
341+ WREG32_P (mmVCE_STATUS , 0 , ~VCE_STATUS__JOB_BUSY_MASK );
342+
343+ /* Set Clock-Gating off */
344+ if (adev -> cg_flags & AMD_CG_SUPPORT_VCE_MGCG )
345+ vce_v3_0_set_vce_sw_clock_gating (adev , false);
346+ }
347+
348+ WREG32_P (mmGRBM_GFX_INDEX , 0 , ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK );
349+ mutex_unlock (& adev -> grbm_idx_mutex );
306350
307351 return 0 ;
308352}
@@ -441,7 +485,14 @@ static int vce_v3_0_hw_init(void *handle)
441485
442486static int vce_v3_0_hw_fini (void * handle )
443487{
444- return 0 ;
488+ int r ;
489+ struct amdgpu_device * adev = (struct amdgpu_device * )handle ;
490+
491+ r = vce_v3_0_wait_for_idle (handle );
492+ if (r )
493+ return r ;
494+
495+ return vce_v3_0_stop (adev );
445496}
446497
447498static int vce_v3_0_suspend (void * handle )
0 commit comments