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;
|
int ref_cnt;
|
||||||
bool is_railgated;
|
bool is_railgated;
|
||||||
|
|
||||||
if (!platform->can_railgate)
|
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
/* acquire busy lock to block other busy() calls */
|
/* acquire busy lock to block other busy() calls */
|
||||||
down_write(&g->busy_lock);
|
down_write(&g->busy_lock);
|
||||||
|
|
||||||
@@ -1772,25 +1769,39 @@ int gk20a_do_idle(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* if GPU is now idle, we will have only one ref count
|
* 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);
|
pm_runtime_put_sync(&pdev->dev);
|
||||||
|
|
||||||
/* add sufficient delay to allow GPU to rail gate */
|
if (platform->can_railgate) {
|
||||||
msleep(platform->railgate_delay);
|
/* add sufficient delay to allow GPU to rail gate */
|
||||||
|
msleep(platform->railgate_delay);
|
||||||
|
|
||||||
timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
|
timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
|
||||||
|
|
||||||
/* check in loop if GPU is railgated or not */
|
/* check in loop if GPU is railgated or not */
|
||||||
do {
|
do {
|
||||||
msleep(1);
|
msleep(1);
|
||||||
is_railgated = platform->is_railgated(pdev);
|
is_railgated = platform->is_railgated(pdev);
|
||||||
} while (!is_railgated && time_before(jiffies, timeout));
|
} while (!is_railgated && time_before(jiffies, timeout));
|
||||||
|
|
||||||
if (is_railgated)
|
if (is_railgated)
|
||||||
|
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;
|
return 0;
|
||||||
else
|
}
|
||||||
goto fail_timeout;
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pm_runtime_put_noidle(&pdev->dev);
|
pm_runtime_put_noidle(&pdev->dev);
|
||||||
@@ -1811,6 +1822,15 @@ int gk20a_do_unidle(void)
|
|||||||
struct gk20a *g = get_gk20a(pdev);
|
struct gk20a *g = get_gk20a(pdev);
|
||||||
struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev);
|
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 */
|
/* release the lock and open up all other busy() calls */
|
||||||
mutex_unlock(&platform->railgate_lock);
|
mutex_unlock(&platform->railgate_lock);
|
||||||
up_write(&g->busy_lock);
|
up_write(&g->busy_lock);
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ struct gk20a {
|
|||||||
bool elpg_enabled;
|
bool elpg_enabled;
|
||||||
bool aelpg_enabled;
|
bool aelpg_enabled;
|
||||||
bool forced_idle;
|
bool forced_idle;
|
||||||
|
bool forced_reset;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
spinlock_t debugfs_lock;
|
spinlock_t debugfs_lock;
|
||||||
|
|||||||
Reference in New Issue
Block a user