gpu: host1x: Fix hang on Tegra186+
authorDmitry Osipenko <digetx@gmail.com>
Thu, 23 Dec 2021 14:46:50 +0000 (17:46 +0300)
committerThierry Reding <treding@nvidia.com>
Thu, 27 Jan 2022 17:27:02 +0000 (18:27 +0100)
Tegra186+ hangs if host1x hardware is disabled at a kernel boot time
because we touch hardware before runtime PM is resumed. Move sync point
assignment initialization to the RPM-resume callback. Older SoCs were
unaffected because they skip that sync point initialization.

Tested-by: Jon Hunter <jonathanh@nvidia.com> # T186
Reported-by: Jon Hunter <jonathanh@nvidia.com> # T186
Fixes: 6b6776e2ab8a ("gpu: host1x: Add initial runtime PM and OPP support")
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/host1x/syncpt.c

index e08e331..83a16e4 100644 (file)
@@ -137,8 +137,15 @@ void host1x_syncpt_restore(struct host1x *host)
        struct host1x_syncpt *sp_base = host->syncpt;
        unsigned int i;
 
-       for (i = 0; i < host1x_syncpt_nb_pts(host); i++)
+       for (i = 0; i < host1x_syncpt_nb_pts(host); i++) {
+               /*
+                * Unassign syncpt from channels for purposes of Tegra186
+                * syncpoint protection. This prevents any channel from
+                * accessing it until it is reassigned.
+                */
+               host1x_hw_syncpt_assign_to_channel(host, sp_base + i, NULL);
                host1x_hw_syncpt_restore(host, sp_base + i);
+       }
 
        for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
                host1x_hw_syncpt_restore_wait_base(host, sp_base + i);
@@ -352,13 +359,6 @@ int host1x_syncpt_init(struct host1x *host)
        for (i = 0; i < host->info->nb_pts; i++) {
                syncpt[i].id = i;
                syncpt[i].host = host;
-
-               /*
-                * Unassign syncpt from channels for purposes of Tegra186
-                * syncpoint protection. This prevents any channel from
-                * accessing it until it is reassigned.
-                */
-               host1x_hw_syncpt_assign_to_channel(host, &syncpt[i], NULL);
        }
 
        for (i = 0; i < host->info->nb_bases; i++)