@@ -1282,10 +1282,10 @@ static int __intel_engine_stop_cs(struct intel_engine_cs *engine,
12821282 intel_uncore_write_fw (uncore , mode , _MASKED_BIT_ENABLE (STOP_RING ));
12831283
12841284 /*
1285- * Wa_22011802037 : gen12, Prior to doing a reset, ensure CS is
1285+ * Wa_22011802037 : gen11, gen12, Prior to doing a reset, ensure CS is
12861286 * stopped, set ring stop bit and prefetch disable bit to halt CS
12871287 */
1288- if (GRAPHICS_VER (engine -> i915 ) == 12 )
1288+ if (IS_GRAPHICS_VER (engine -> i915 , 11 , 12 ) )
12891289 intel_uncore_write_fw (uncore , RING_MODE_GEN7 (engine -> mmio_base ),
12901290 _MASKED_BIT_ENABLE (GEN12_GFX_PREFETCH_DISABLE ));
12911291
@@ -1308,6 +1308,18 @@ int intel_engine_stop_cs(struct intel_engine_cs *engine)
13081308 return - ENODEV ;
13091309
13101310 ENGINE_TRACE (engine , "\n" );
1311+ /*
1312+ * TODO: Find out why occasionally stopping the CS times out. Seen
1313+ * especially with gem_eio tests.
1314+ *
1315+ * Occasionally trying to stop the cs times out, but does not adversely
1316+ * affect functionality. The timeout is set as a config parameter that
1317+ * defaults to 100ms. In most cases the follow up operation is to wait
1318+ * for pending MI_FORCE_WAKES. The assumption is that this timeout is
1319+ * sufficient for any pending MI_FORCEWAKEs to complete. Once root
1320+ * caused, the caller must check and handle the return from this
1321+ * function.
1322+ */
13111323 if (__intel_engine_stop_cs (engine , 1000 , stop_timeout (engine ))) {
13121324 ENGINE_TRACE (engine ,
13131325 "timed out on STOP_RING -> IDLE; HEAD:%04x, TAIL:%04x\n" ,
@@ -1334,6 +1346,78 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs *engine)
13341346 ENGINE_WRITE_FW (engine , RING_MI_MODE , _MASKED_BIT_DISABLE (STOP_RING ));
13351347}
13361348
1349+ static u32 __cs_pending_mi_force_wakes (struct intel_engine_cs * engine )
1350+ {
1351+ static const i915_reg_t _reg [I915_NUM_ENGINES ] = {
1352+ [RCS0 ] = MSG_IDLE_CS ,
1353+ [BCS0 ] = MSG_IDLE_BCS ,
1354+ [VCS0 ] = MSG_IDLE_VCS0 ,
1355+ [VCS1 ] = MSG_IDLE_VCS1 ,
1356+ [VCS2 ] = MSG_IDLE_VCS2 ,
1357+ [VCS3 ] = MSG_IDLE_VCS3 ,
1358+ [VCS4 ] = MSG_IDLE_VCS4 ,
1359+ [VCS5 ] = MSG_IDLE_VCS5 ,
1360+ [VCS6 ] = MSG_IDLE_VCS6 ,
1361+ [VCS7 ] = MSG_IDLE_VCS7 ,
1362+ [VECS0 ] = MSG_IDLE_VECS0 ,
1363+ [VECS1 ] = MSG_IDLE_VECS1 ,
1364+ [VECS2 ] = MSG_IDLE_VECS2 ,
1365+ [VECS3 ] = MSG_IDLE_VECS3 ,
1366+ [CCS0 ] = MSG_IDLE_CS ,
1367+ [CCS1 ] = MSG_IDLE_CS ,
1368+ [CCS2 ] = MSG_IDLE_CS ,
1369+ [CCS3 ] = MSG_IDLE_CS ,
1370+ };
1371+ u32 val ;
1372+
1373+ if (!_reg [engine -> id ].reg ) {
1374+ drm_err (& engine -> i915 -> drm ,
1375+ "MSG IDLE undefined for engine id %u\n" , engine -> id );
1376+ return 0 ;
1377+ }
1378+
1379+ val = intel_uncore_read (engine -> uncore , _reg [engine -> id ]);
1380+
1381+ /* bits[29:25] & bits[13:9] >> shift */
1382+ return (val & (val >> 16 ) & MSG_IDLE_FW_MASK ) >> MSG_IDLE_FW_SHIFT ;
1383+ }
1384+
1385+ static void __gpm_wait_for_fw_complete (struct intel_gt * gt , u32 fw_mask )
1386+ {
1387+ int ret ;
1388+
1389+ /* Ensure GPM receives fw up/down after CS is stopped */
1390+ udelay (1 );
1391+
1392+ /* Wait for forcewake request to complete in GPM */
1393+ ret = __intel_wait_for_register_fw (gt -> uncore ,
1394+ GEN9_PWRGT_DOMAIN_STATUS ,
1395+ fw_mask , fw_mask , 5000 , 0 , NULL );
1396+
1397+ /* Ensure CS receives fw ack from GPM */
1398+ udelay (1 );
1399+
1400+ if (ret )
1401+ GT_TRACE (gt , "Failed to complete pending forcewake %d\n" , ret );
1402+ }
1403+
1404+ /*
1405+ * Wa_22011802037:gen12: In addition to stopping the cs, we need to wait for any
1406+ * pending MI_FORCE_WAKEUP requests that the CS has initiated to complete. The
1407+ * pending status is indicated by bits[13:9] (masked by bits[29:25]) in the
1408+ * MSG_IDLE register. There's one MSG_IDLE register per reset domain. Since we
1409+ * are concerned only with the gt reset here, we use a logical OR of pending
1410+ * forcewakeups from all reset domains and then wait for them to complete by
1411+ * querying PWRGT_DOMAIN_STATUS.
1412+ */
1413+ void intel_engine_wait_for_pending_mi_fw (struct intel_engine_cs * engine )
1414+ {
1415+ u32 fw_pending = __cs_pending_mi_force_wakes (engine );
1416+
1417+ if (fw_pending )
1418+ __gpm_wait_for_fw_complete (engine -> gt , fw_pending );
1419+ }
1420+
13371421static u32
13381422read_subslice_reg (const struct intel_engine_cs * engine ,
13391423 int slice , int subslice , i915_reg_t reg )
0 commit comments