| .. | .. |
|---|
| 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 | |
|---|