.. | .. |
---|
289 | 289 | static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) |
---|
290 | 290 | { |
---|
291 | 291 | struct intel_uncore *uncore = gt->uncore; |
---|
| 292 | + int loops = 2; |
---|
292 | 293 | int err; |
---|
293 | 294 | |
---|
294 | 295 | /* |
---|
.. | .. |
---|
296 | 297 | * for fifo space for the write or forcewake the chip for |
---|
297 | 298 | * the read |
---|
298 | 299 | */ |
---|
299 | | - intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask); |
---|
| 300 | + do { |
---|
| 301 | + intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask); |
---|
300 | 302 | |
---|
301 | | - /* Wait for the device to ack the reset requests */ |
---|
302 | | - err = __intel_wait_for_register_fw(uncore, |
---|
303 | | - GEN6_GDRST, hw_domain_mask, 0, |
---|
304 | | - 500, 0, |
---|
305 | | - NULL); |
---|
| 303 | + /* |
---|
| 304 | + * Wait for the device to ack the reset requests. |
---|
| 305 | + * |
---|
| 306 | + * On some platforms, e.g. Jasperlake, we see that the |
---|
| 307 | + * engine register state is not cleared until shortly after |
---|
| 308 | + * GDRST reports completion, causing a failure as we try |
---|
| 309 | + * to immediately resume while the internal state is still |
---|
| 310 | + * in flux. If we immediately repeat the reset, the second |
---|
| 311 | + * reset appears to serialise with the first, and since |
---|
| 312 | + * it is a no-op, the registers should retain their reset |
---|
| 313 | + * value. However, there is still a concern that upon |
---|
| 314 | + * leaving the second reset, the internal engine state |
---|
| 315 | + * is still in flux and not ready for resuming. |
---|
| 316 | + */ |
---|
| 317 | + err = __intel_wait_for_register_fw(uncore, GEN6_GDRST, |
---|
| 318 | + hw_domain_mask, 0, |
---|
| 319 | + 2000, 0, |
---|
| 320 | + NULL); |
---|
| 321 | + } while (err == 0 && --loops); |
---|
306 | 322 | if (err) |
---|
307 | 323 | drm_dbg(>->i915->drm, |
---|
308 | 324 | "Wait for 0x%08x engines reset failed\n", |
---|
309 | 325 | hw_domain_mask); |
---|
310 | 326 | |
---|
| 327 | + /* |
---|
| 328 | + * As we have observed that the engine state is still volatile |
---|
| 329 | + * after GDRST is acked, impose a small delay to let everything settle. |
---|
| 330 | + */ |
---|
| 331 | + udelay(50); |
---|
| 332 | + |
---|
311 | 333 | return err; |
---|
312 | 334 | } |
---|
313 | 335 | |
---|