summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsujeet baranwal <sbaranwal@nvidia.com>2014-08-29 13:56:49 -0700
committerWinnie Hsu <whsu@nvidia.com>2015-01-06 18:31:21 -0800
commitf69b7093accdacfa653b4bd45d78e04a2676dc2a (patch)
tree9fa4cc4389af4ebc886d5968fbaef35b9a928752
parent57d7c4ae3e86c2710eaad6f9812b982332ded940 (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>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h1
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;