diff options
author | sujeet baranwal <sbaranwal@nvidia.com> | 2014-08-29 13:56:49 -0700 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2015-01-06 18:31:21 -0800 |
commit | f69b7093accdacfa653b4bd45d78e04a2676dc2a (patch) | |
tree | 9fa4cc4389af4ebc886d5968fbaef35b9a928752 /drivers | |
parent | 57d7c4ae3e86c2710eaad6f9812b982332ded940 (diff) |
video: tegra: Wait PMU finishes booting
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 1 |
3 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index fdfc9260da99..03d466ef3dc8 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -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); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 21e4d611611c..62b9a022351c 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -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) diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index c13bf9a8ec17..a577890edd45 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h @@ -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; |