mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: force idle if railgate not supported
Add a way to force idle and reset the GPU in case where GPU rail gating is not supported (i.e. platform->can_railgate = false) In this case, we follow below sequence : - once GPU is idle, get runtime reference which enables the clocks - call prepare_poweroff() to save the state explicitly - perform explicit reset assert/deassert - call finalize_poweron() to restore the state - drop the runtime reference taken earlier Bug 1525284 Change-Id: Id5f3ec152093acd585631dfbf785d8e0561f9048 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/435620 GVS: Gerrit_Virtual_Submit Reviewed-by: Arto Merilainen <amerilainen@nvidia.com> Tested-by: Arto Merilainen <amerilainen@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
597083eaba
commit
fec60b6e6e
@@ -1743,9 +1743,6 @@ int gk20a_do_idle(void)
|
||||
int ref_cnt;
|
||||
bool is_railgated;
|
||||
|
||||
if (!platform->can_railgate)
|
||||
return -ENOSYS;
|
||||
|
||||
/* acquire busy lock to block other busy() calls */
|
||||
down_write(&g->busy_lock);
|
||||
|
||||
@@ -1772,10 +1769,14 @@ int gk20a_do_idle(void)
|
||||
|
||||
/*
|
||||
* if GPU is now idle, we will have only one ref count
|
||||
* drop this ref which will rail gate the GPU
|
||||
* drop this ref which will rail gate the GPU (if GPU
|
||||
* railgate is supported)
|
||||
* if GPU railgate is not supported then we need to
|
||||
* explicitly reset it
|
||||
*/
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
if (platform->can_railgate) {
|
||||
/* add sufficient delay to allow GPU to rail gate */
|
||||
msleep(platform->railgate_delay);
|
||||
|
||||
@@ -1791,6 +1792,16 @@ int gk20a_do_idle(void)
|
||||
return 0;
|
||||
else
|
||||
goto fail_timeout;
|
||||
} else {
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
gk20a_pm_prepare_poweroff(&pdev->dev);
|
||||
|
||||
tegra_periph_reset_assert(platform->clk[0]);
|
||||
udelay(10);
|
||||
|
||||
g->forced_reset = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fail:
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
@@ -1811,6 +1822,15 @@ int gk20a_do_unidle(void)
|
||||
struct gk20a *g = get_gk20a(pdev);
|
||||
struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
if (g->forced_reset) {
|
||||
tegra_periph_reset_deassert(platform->clk[0]);
|
||||
|
||||
gk20a_pm_finalize_poweron(&pdev->dev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
g->forced_reset = false;
|
||||
}
|
||||
|
||||
/* release the lock and open up all other busy() calls */
|
||||
mutex_unlock(&platform->railgate_lock);
|
||||
up_write(&g->busy_lock);
|
||||
|
||||
@@ -271,6 +271,7 @@ struct gk20a {
|
||||
bool elpg_enabled;
|
||||
bool aelpg_enabled;
|
||||
bool forced_idle;
|
||||
bool forced_reset;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
spinlock_t debugfs_lock;
|
||||
|
||||
Reference in New Issue
Block a user