mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
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>
This commit is contained in:
committed by
Dan Willemsen
parent
cc30ac4395
commit
d0ce4807d0
@@ -1604,16 +1604,30 @@ int gk20a_busy(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct gk20a *g = get_gk20a(pdev);
|
struct gk20a *g = get_gk20a(pdev);
|
||||||
|
struct gk20a_platform *platform = gk20a_get_platform(pdev);
|
||||||
|
|
||||||
down_read(&g->busy_lock);
|
down_read(&g->busy_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_RUNTIME
|
#ifdef CONFIG_PM_RUNTIME
|
||||||
|
if (platform->busy) {
|
||||||
|
ret = platform->busy(pdev);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "%s: failed to poweron platform dependency\n",
|
||||||
|
__func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = pm_runtime_get_sync(&pdev->dev);
|
ret = pm_runtime_get_sync(&pdev->dev);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
pm_runtime_put_noidle(&pdev->dev);
|
pm_runtime_put_noidle(&pdev->dev);
|
||||||
|
if (platform->idle)
|
||||||
|
platform->idle(pdev);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
gk20a_scale_notify_busy(pdev);
|
gk20a_scale_notify_busy(pdev);
|
||||||
|
|
||||||
|
fail:
|
||||||
up_read(&g->busy_lock);
|
up_read(&g->busy_lock);
|
||||||
|
|
||||||
return ret < 0 ? ret : 0;
|
return ret < 0 ? ret : 0;
|
||||||
@@ -1621,11 +1635,15 @@ int gk20a_busy(struct platform_device *pdev)
|
|||||||
|
|
||||||
void gk20a_idle(struct platform_device *pdev)
|
void gk20a_idle(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct gk20a_platform *platform = gk20a_get_platform(pdev);
|
||||||
#ifdef CONFIG_PM_RUNTIME
|
#ifdef CONFIG_PM_RUNTIME
|
||||||
if (atomic_read(&pdev->dev.power.usage_count) == 1)
|
if (atomic_read(&pdev->dev.power.usage_count) == 1)
|
||||||
gk20a_scale_notify_idle(pdev);
|
gk20a_scale_notify_idle(pdev);
|
||||||
pm_runtime_mark_last_busy(&pdev->dev);
|
pm_runtime_mark_last_busy(&pdev->dev);
|
||||||
pm_runtime_put_sync_autosuspend(&pdev->dev);
|
pm_runtime_put_sync_autosuspend(&pdev->dev);
|
||||||
|
|
||||||
|
if (platform->idle)
|
||||||
|
platform->idle(pdev);
|
||||||
#else
|
#else
|
||||||
gk20a_scale_notify_idle(pdev);
|
gk20a_scale_notify_idle(pdev);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -94,6 +94,12 @@ struct gk20a_platform {
|
|||||||
*/
|
*/
|
||||||
int (*late_probe)(struct platform_device *dev);
|
int (*late_probe)(struct platform_device *dev);
|
||||||
|
|
||||||
|
/* Poweron platform dependencies */
|
||||||
|
int (*busy)(struct platform_device *dev);
|
||||||
|
|
||||||
|
/* Powerdown platform dependencies */
|
||||||
|
void (*idle)(struct platform_device *dev);
|
||||||
|
|
||||||
/* This function is called to allocate secure memory (memory that the
|
/* This function is called to allocate secure memory (memory that the
|
||||||
* CPU cannot see). The function should fill the context buffer
|
* CPU cannot see). The function should fill the context buffer
|
||||||
* descriptor (especially fields destroy, sgt, size).
|
* descriptor (especially fields destroy, sgt, size).
|
||||||
|
|||||||
@@ -449,6 +449,25 @@ static void gk20a_tegra_debug_dump(struct platform_device *pdev)
|
|||||||
nvhost_debug_dump_device(g->host1x_dev);
|
nvhost_debug_dump_device(g->host1x_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gk20a_tegra_busy(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||||
|
struct gk20a *g = platform->g;
|
||||||
|
|
||||||
|
if (g->host1x_dev)
|
||||||
|
return nvhost_module_busy_ext(g->host1x_dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gk20a_tegra_idle(struct platform_device *dev)
|
||||||
|
{
|
||||||
|
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||||
|
struct gk20a *g = platform->g;
|
||||||
|
|
||||||
|
if (g->host1x_dev)
|
||||||
|
nvhost_module_idle_ext(g->host1x_dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int gk20a_tegra_probe(struct platform_device *dev)
|
static int gk20a_tegra_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||||
@@ -554,6 +573,9 @@ struct gk20a_platform t132_gk20a_tegra_platform = {
|
|||||||
.unrailgate = gk20a_tegra_unrailgate,
|
.unrailgate = gk20a_tegra_unrailgate,
|
||||||
.is_railgated = gk20a_tegra_is_railgated,
|
.is_railgated = gk20a_tegra_is_railgated,
|
||||||
|
|
||||||
|
.busy = gk20a_tegra_busy,
|
||||||
|
.idle = gk20a_tegra_idle,
|
||||||
|
|
||||||
/* frequency scaling configuration */
|
/* frequency scaling configuration */
|
||||||
.prescale = gk20a_tegra_prescale,
|
.prescale = gk20a_tegra_prescale,
|
||||||
.postscale = gk20a_tegra_postscale,
|
.postscale = gk20a_tegra_postscale,
|
||||||
@@ -587,6 +609,9 @@ struct gk20a_platform gk20a_tegra_platform = {
|
|||||||
.unrailgate = gk20a_tegra_unrailgate,
|
.unrailgate = gk20a_tegra_unrailgate,
|
||||||
.is_railgated = gk20a_tegra_is_railgated,
|
.is_railgated = gk20a_tegra_is_railgated,
|
||||||
|
|
||||||
|
.busy = gk20a_tegra_busy,
|
||||||
|
.idle = gk20a_tegra_idle,
|
||||||
|
|
||||||
/* frequency scaling configuration */
|
/* frequency scaling configuration */
|
||||||
.prescale = gk20a_tegra_prescale,
|
.prescale = gk20a_tegra_prescale,
|
||||||
.postscale = gk20a_tegra_postscale,
|
.postscale = gk20a_tegra_postscale,
|
||||||
@@ -618,6 +643,9 @@ struct gk20a_platform gm20b_tegra_platform = {
|
|||||||
/* power management callbacks */
|
/* power management callbacks */
|
||||||
.suspend = gk20a_tegra_suspend,
|
.suspend = gk20a_tegra_suspend,
|
||||||
|
|
||||||
|
.busy = gk20a_tegra_busy,
|
||||||
|
.idle = gk20a_tegra_idle,
|
||||||
|
|
||||||
/* frequency scaling configuration */
|
/* frequency scaling configuration */
|
||||||
.prescale = gk20a_tegra_prescale,
|
.prescale = gk20a_tegra_prescale,
|
||||||
.postscale = gk20a_tegra_postscale,
|
.postscale = gk20a_tegra_postscale,
|
||||||
|
|||||||
Reference in New Issue
Block a user