video: tegra: Wait PMU finishes booting
sujeet baranwal [Fri, 29 Aug 2014 20:56:49 +0000 (13:56 -0700)]
GPU PMU booting is in a separate thread(workqueue) and currently
there is a race condition that PMU booting doesn't finish when
"nvhost_gk20a_finalize_power_on" is returning.
If the GPU starts to runtime powergate(nvhost_gk20a_prepare_poweroff)
at that time, we left a unfinished PMU booting workqueue task there.
So next time when this task starts running, GPU will be put into
a bad state which causes lots of GPU errors.
This patch adds a wait at the end of "nvhost_gk20a_finalize_power_on"
, so that the race condition can be avoided.

Bug 200055546

Change-Id: I4f2d0798fcadb4effc555a66f3c3e3061b18d246
Signed-off-by: Mark Zhang <markz@nvidia.com>
Signed-off-by: sujeet baranwal <sbaranwal@nvidia.com>
Reviewed-on: http://git-master/r/494065
(cherry picked from commit 3b9866a952ba0a1dea05d20bf32b6bcc9113f38b)
Reviewed-on: http://git-master/r/655952
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>

drivers/gpu/nvgpu/gk20a/gk20a.c
drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
drivers/gpu/nvgpu/gk20a/pmu_gk20a.h

index fdfc926..03d466e 100644 (file)
@@ -914,6 +914,8 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
                goto done;
        }
 
+       wait_event(g->pmu.boot_wq, g->pmu.pmu_state == PMU_STATE_STARTED);
+
        gk20a_channel_resume(g);
        set_user_nice(current, nice_value);
 
@@ -1469,6 +1471,7 @@ static int gk20a_probe(struct platform_device *dev)
                                        &gk20a->timeouts_enabled);
        gk20a_pmu_debugfs_init(dev);
 #endif
+       init_waitqueue_head(&gk20a->pmu.boot_wq);
 
        gk20a_init_gr(gk20a);
 
index 21e4d61..62b9a02 100644 (file)
@@ -1967,6 +1967,8 @@ static void pmu_setup_hw_enable_elpg(struct gk20a *g)
                gk20a_aelpg_init(g);
                gk20a_aelpg_init_and_enable(g, PMU_AP_CTRL_ID_GRAPHICS);
        }
+
+       wake_up(&g->pmu.boot_wq);
 }
 
 int gk20a_init_pmu_support(struct gk20a *g)
index c13bf9a..a577890 100644 (file)
@@ -1032,6 +1032,7 @@ struct pmu_gk20a {
        u32 elpg_stat;
 
        int pmu_state;
+       wait_queue_head_t boot_wq;
 
 #define PMU_ELPG_ENABLE_ALLOW_DELAY_MSEC       1 /* msec */
        struct work_struct pg_init;