gpu: host1x: Use RESTART_W to skip timed out jobs on Tegra186+
authorMikko Perttunen <mperttunen@nvidia.com>
Mon, 27 Jun 2022 14:20:07 +0000 (17:20 +0300)
committerThierry Reding <treding@nvidia.com>
Fri, 8 Jul 2022 14:27:53 +0000 (16:27 +0200)
When MLOCK enforcement is enabled, the 0-word write currently done
is rejected by the hardware outside of an MLOCK region. As such,
on these chips, which also have the newer, more convenient RESTART_W
opcode, use that instead to skip over the timed out job.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/host1x/cdma.c

index 765e5aa64eb6886dab9400413c71452589f7f082..bb1f3c746be4714f4dbdeed48c54c5ce9273ae8a 100644 (file)
@@ -457,9 +457,24 @@ syncpt_incr:
                                 * to offset 0xbad. This does nothing but
                                 * has a easily detected signature in debug
                                 * traces.
+                                *
+                                * On systems with MLOCK enforcement enabled,
+                                * the above 0 word writes would fall foul of
+                                * the enforcement. As such, in the first slot
+                                * put a RESTART_W opcode to the beginning
+                                * of the next job. We don't use this for older
+                                * chips since those only support the RESTART
+                                * opcode with inconvenient alignment requirements.
                                 */
-                               mapped[2*slot+0] = 0x1bad0000;
-                               mapped[2*slot+1] = 0x1bad0000;
+                               if (i == 0 && host1x->info->has_wide_gather) {
+                                       unsigned int next_job = (job->first_get/8 + job->num_slots)
+                                               % HOST1X_PUSHBUFFER_SLOTS;
+                                       mapped[2*slot+0] = (0xd << 28) | (next_job * 2);
+                                       mapped[2*slot+1] = 0x0;
+                               } else {
+                                       mapped[2*slot+0] = 0x1bad0000;
+                                       mapped[2*slot+1] = 0x1bad0000;
+                               }
                        }
 
                        job->cancelled = true;