summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-07-08 08:30:18 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:26 -0400
commitfec60b6e6e299151d446f4bccc5fd64a23b704d2 (patch)
tree7ff144ac70c937e6a91e4f18afee64b35541d88a
parent597083eaba3abd3e48b3c6bfafac3ef94606c2ad (diff)
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>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c50
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
2 files changed, 36 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index cd104580..c69df460 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -1743,9 +1743,6 @@ int gk20a_do_idle(void)
1743 int ref_cnt; 1743 int ref_cnt;
1744 bool is_railgated; 1744 bool is_railgated;
1745 1745
1746 if (!platform->can_railgate)
1747 return -ENOSYS;
1748
1749 /* acquire busy lock to block other busy() calls */ 1746 /* acquire busy lock to block other busy() calls */
1750 down_write(&g->busy_lock); 1747 down_write(&g->busy_lock);
1751 1748
@@ -1772,25 +1769,39 @@ int gk20a_do_idle(void)
1772 1769
1773 /* 1770 /*
1774 * if GPU is now idle, we will have only one ref count 1771 * if GPU is now idle, we will have only one ref count
1775 * drop this ref which will rail gate the GPU 1772 * drop this ref which will rail gate the GPU (if GPU
1773 * railgate is supported)
1774 * if GPU railgate is not supported then we need to
1775 * explicitly reset it
1776 */ 1776 */
1777 pm_runtime_put_sync(&pdev->dev); 1777 pm_runtime_put_sync(&pdev->dev);
1778 1778
1779 /* add sufficient delay to allow GPU to rail gate */ 1779 if (platform->can_railgate) {
1780 msleep(platform->railgate_delay); 1780 /* add sufficient delay to allow GPU to rail gate */
1781 msleep(platform->railgate_delay);
1781 1782
1782 timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS); 1783 timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
1783 1784
1784 /* check in loop if GPU is railgated or not */ 1785 /* check in loop if GPU is railgated or not */
1785 do { 1786 do {
1786 msleep(1); 1787 msleep(1);
1787 is_railgated = platform->is_railgated(pdev); 1788 is_railgated = platform->is_railgated(pdev);
1788 } while (!is_railgated && time_before(jiffies, timeout)); 1789 } while (!is_railgated && time_before(jiffies, timeout));
1790
1791 if (is_railgated)
1792 return 0;
1793 else
1794 goto fail_timeout;
1795 } else {
1796 pm_runtime_get_sync(&pdev->dev);
1797 gk20a_pm_prepare_poweroff(&pdev->dev);
1798
1799 tegra_periph_reset_assert(platform->clk[0]);
1800 udelay(10);
1789 1801
1790 if (is_railgated) 1802 g->forced_reset = true;
1791 return 0; 1803 return 0;
1792 else 1804 }
1793 goto fail_timeout;
1794 1805
1795fail: 1806fail:
1796 pm_runtime_put_noidle(&pdev->dev); 1807 pm_runtime_put_noidle(&pdev->dev);
@@ -1811,6 +1822,15 @@ int gk20a_do_unidle(void)
1811 struct gk20a *g = get_gk20a(pdev); 1822 struct gk20a *g = get_gk20a(pdev);
1812 struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev); 1823 struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev);
1813 1824
1825 if (g->forced_reset) {
1826 tegra_periph_reset_deassert(platform->clk[0]);
1827
1828 gk20a_pm_finalize_poweron(&pdev->dev);
1829 pm_runtime_put_sync(&pdev->dev);
1830
1831 g->forced_reset = false;
1832 }
1833
1814 /* release the lock and open up all other busy() calls */ 1834 /* release the lock and open up all other busy() calls */
1815 mutex_unlock(&platform->railgate_lock); 1835 mutex_unlock(&platform->railgate_lock);
1816 up_write(&g->busy_lock); 1836 up_write(&g->busy_lock);
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 55bc6b20..774e4e85 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -271,6 +271,7 @@ struct gk20a {
271 bool elpg_enabled; 271 bool elpg_enabled;
272 bool aelpg_enabled; 272 bool aelpg_enabled;
273 bool forced_idle; 273 bool forced_idle;
274 bool forced_reset;
274 275
275#ifdef CONFIG_DEBUG_FS 276#ifdef CONFIG_DEBUG_FS
276 spinlock_t debugfs_lock; 277 spinlock_t debugfs_lock;