summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-07-28 06:51:10 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:37 -0400
commitd0ce4807d0f190be8fd4221bb48d543bf20473f6 (patch)
tree410936871ebba93269bf15aa7b15638be780e6cc /drivers
parentcc30ac4395809580d3d7ad9b3b6ac4aea099f9ec (diff)
gpu: nvgpu: poweron host1x explicitly
Currently gk20a gets reference of host1x via phandle in Device Tree. But runtime PM does not seem to be handling power dependencies too well in this case and hence some times host1x is off when we need it. To fix this, exlicitly power on host1x while powering gpu up. Do this via "busy" and "idle" callbacks from gk20a_platform Bug 1534272 Bug 200022536 Change-Id: Ia562ee19722cfc8edc5626a5a058ab8edfe3d206 Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c20
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h6
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c28
3 files changed, 53 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 355b2039..fa6e0cce 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -1604,16 +1604,30 @@ int gk20a_busy(struct platform_device *pdev)
1604{ 1604{
1605 int ret = 0; 1605 int ret = 0;
1606 struct gk20a *g = get_gk20a(pdev); 1606 struct gk20a *g = get_gk20a(pdev);
1607 struct gk20a_platform *platform = gk20a_get_platform(pdev);
1607 1608
1608 down_read(&g->busy_lock); 1609 down_read(&g->busy_lock);
1609 1610
1610#ifdef CONFIG_PM_RUNTIME 1611#ifdef CONFIG_PM_RUNTIME
1612 if (platform->busy) {
1613 ret = platform->busy(pdev);
1614 if (ret < 0) {
1615 dev_err(&pdev->dev, "%s: failed to poweron platform dependency\n",
1616 __func__);
1617 goto fail;
1618 }
1619 }
1620
1611 ret = pm_runtime_get_sync(&pdev->dev); 1621 ret = pm_runtime_get_sync(&pdev->dev);
1612 if (ret < 0) 1622 if (ret < 0) {
1613 pm_runtime_put_noidle(&pdev->dev); 1623 pm_runtime_put_noidle(&pdev->dev);
1624 if (platform->idle)
1625 platform->idle(pdev);
1626 }
1614#endif 1627#endif
1615 gk20a_scale_notify_busy(pdev); 1628 gk20a_scale_notify_busy(pdev);
1616 1629
1630fail:
1617 up_read(&g->busy_lock); 1631 up_read(&g->busy_lock);
1618 1632
1619 return ret < 0 ? ret : 0; 1633 return ret < 0 ? ret : 0;
@@ -1621,11 +1635,15 @@ int gk20a_busy(struct platform_device *pdev)
1621 1635
1622void gk20a_idle(struct platform_device *pdev) 1636void gk20a_idle(struct platform_device *pdev)
1623{ 1637{
1638 struct gk20a_platform *platform = gk20a_get_platform(pdev);
1624#ifdef CONFIG_PM_RUNTIME 1639#ifdef CONFIG_PM_RUNTIME
1625 if (atomic_read(&pdev->dev.power.usage_count) == 1) 1640 if (atomic_read(&pdev->dev.power.usage_count) == 1)
1626 gk20a_scale_notify_idle(pdev); 1641 gk20a_scale_notify_idle(pdev);
1627 pm_runtime_mark_last_busy(&pdev->dev); 1642 pm_runtime_mark_last_busy(&pdev->dev);
1628 pm_runtime_put_sync_autosuspend(&pdev->dev); 1643 pm_runtime_put_sync_autosuspend(&pdev->dev);
1644
1645 if (platform->idle)
1646 platform->idle(pdev);
1629#else 1647#else
1630 gk20a_scale_notify_idle(pdev); 1648 gk20a_scale_notify_idle(pdev);
1631#endif 1649#endif
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index 76e9cf6c..6dd0c0db 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -94,6 +94,12 @@ struct gk20a_platform {
94 */ 94 */
95 int (*late_probe)(struct platform_device *dev); 95 int (*late_probe)(struct platform_device *dev);
96 96
97 /* Poweron platform dependencies */
98 int (*busy)(struct platform_device *dev);
99
100 /* Powerdown platform dependencies */
101 void (*idle)(struct platform_device *dev);
102
97 /* This function is called to allocate secure memory (memory that the 103 /* This function is called to allocate secure memory (memory that the
98 * CPU cannot see). The function should fill the context buffer 104 * CPU cannot see). The function should fill the context buffer
99 * descriptor (especially fields destroy, sgt, size). 105 * descriptor (especially fields destroy, sgt, size).
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
index 148496dd..f234fdec 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
@@ -449,6 +449,25 @@ static void gk20a_tegra_debug_dump(struct platform_device *pdev)
449 nvhost_debug_dump_device(g->host1x_dev); 449 nvhost_debug_dump_device(g->host1x_dev);
450} 450}
451 451
452static int gk20a_tegra_busy(struct platform_device *dev)
453{
454 struct gk20a_platform *platform = gk20a_get_platform(dev);
455 struct gk20a *g = platform->g;
456
457 if (g->host1x_dev)
458 return nvhost_module_busy_ext(g->host1x_dev);
459 return 0;
460}
461
462static void gk20a_tegra_idle(struct platform_device *dev)
463{
464 struct gk20a_platform *platform = gk20a_get_platform(dev);
465 struct gk20a *g = platform->g;
466
467 if (g->host1x_dev)
468 nvhost_module_idle_ext(g->host1x_dev);
469}
470
452static int gk20a_tegra_probe(struct platform_device *dev) 471static int gk20a_tegra_probe(struct platform_device *dev)
453{ 472{
454 struct gk20a_platform *platform = gk20a_get_platform(dev); 473 struct gk20a_platform *platform = gk20a_get_platform(dev);
@@ -554,6 +573,9 @@ struct gk20a_platform t132_gk20a_tegra_platform = {
554 .unrailgate = gk20a_tegra_unrailgate, 573 .unrailgate = gk20a_tegra_unrailgate,
555 .is_railgated = gk20a_tegra_is_railgated, 574 .is_railgated = gk20a_tegra_is_railgated,
556 575
576 .busy = gk20a_tegra_busy,
577 .idle = gk20a_tegra_idle,
578
557 /* frequency scaling configuration */ 579 /* frequency scaling configuration */
558 .prescale = gk20a_tegra_prescale, 580 .prescale = gk20a_tegra_prescale,
559 .postscale = gk20a_tegra_postscale, 581 .postscale = gk20a_tegra_postscale,
@@ -587,6 +609,9 @@ struct gk20a_platform gk20a_tegra_platform = {
587 .unrailgate = gk20a_tegra_unrailgate, 609 .unrailgate = gk20a_tegra_unrailgate,
588 .is_railgated = gk20a_tegra_is_railgated, 610 .is_railgated = gk20a_tegra_is_railgated,
589 611
612 .busy = gk20a_tegra_busy,
613 .idle = gk20a_tegra_idle,
614
590 /* frequency scaling configuration */ 615 /* frequency scaling configuration */
591 .prescale = gk20a_tegra_prescale, 616 .prescale = gk20a_tegra_prescale,
592 .postscale = gk20a_tegra_postscale, 617 .postscale = gk20a_tegra_postscale,
@@ -618,6 +643,9 @@ struct gk20a_platform gm20b_tegra_platform = {
618 /* power management callbacks */ 643 /* power management callbacks */
619 .suspend = gk20a_tegra_suspend, 644 .suspend = gk20a_tegra_suspend,
620 645
646 .busy = gk20a_tegra_busy,
647 .idle = gk20a_tegra_idle,
648
621 /* frequency scaling configuration */ 649 /* frequency scaling configuration */
622 .prescale = gk20a_tegra_prescale, 650 .prescale = gk20a_tegra_prescale,
623 .postscale = gk20a_tegra_postscale, 651 .postscale = gk20a_tegra_postscale,