diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2014-07-28 06:51:10 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:10:37 -0400 |
commit | d0ce4807d0f190be8fd4221bb48d543bf20473f6 (patch) | |
tree | 410936871ebba93269bf15aa7b15638be780e6cc /drivers/gpu/nvgpu/gk20a/gk20a.c | |
parent | cc30ac4395809580d3d7ad9b3b6ac4aea099f9ec (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/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 20 |
1 files changed, 19 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 | ||
1630 | fail: | ||
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 | ||
1622 | void gk20a_idle(struct platform_device *pdev) | 1636 | void 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 |