diff options
-rw-r--r-- | drivers/video/tegra/host/host1x/host1x.c | 15 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.c | 19 | ||||
-rw-r--r-- | include/linux/nvhost.h | 4 |
3 files changed, 37 insertions, 1 deletions
diff --git a/drivers/video/tegra/host/host1x/host1x.c b/drivers/video/tegra/host/host1x/host1x.c index 33ebc1ff5d22..31899c78065b 100644 --- a/drivers/video/tegra/host/host1x/host1x.c +++ b/drivers/video/tegra/host/host1x/host1x.c @@ -308,6 +308,19 @@ static int power_off_host(struct nvhost_device *dev) return 0; } +static void clock_on_host(struct nvhost_device *dev) +{ + struct nvhost_master *host = nvhost_get_drvdata(dev); + nvhost_intr_start(&host->intr, clk_get_rate(dev->clk[0])); +} + +static int clock_off_host(struct nvhost_device *dev) +{ + struct nvhost_master *host = nvhost_get_drvdata(dev); + nvhost_intr_stop(&host->intr); + return 0; +} + static int __devinit nvhost_user_init(struct nvhost_master *host) { int err, devno; @@ -516,6 +529,8 @@ static struct nvhost_driver nvhost_driver = { }, .finalize_poweron = power_on_host, .prepare_poweroff = power_off_host, + .finalize_clockon = clock_on_host, + .prepare_clockoff = clock_off_host, }; static int __init nvhost_mod_init(void) diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c index 76304d6e8fa6..5bde55ad2ff5 100644 --- a/drivers/video/tegra/host/nvhost_acm.c +++ b/drivers/video/tegra/host/nvhost_acm.c @@ -101,8 +101,17 @@ void nvhost_module_reset(struct nvhost_device *dev) static void to_state_clockgated_locked(struct nvhost_device *dev) { + struct nvhost_driver *drv = to_nvhost_driver(dev->dev.driver); + if (dev->powerstate == NVHOST_POWER_STATE_RUNNING) { - int i; + int i, err; + if (drv->prepare_clockoff) { + err = drv->prepare_clockoff(dev); + if (err) { + dev_err(&dev->dev, "error clock gating"); + return; + } + } for (i = 0; i < dev->num_clks; i++) clk_disable(dev->clk[i]); if (dev->dev.parent) @@ -141,6 +150,14 @@ static void to_state_running_locked(struct nvhost_device *dev) } } + /* Invoke callback after enabling clock. This is used for + * re-enabling host1x interrupts. */ + if (prev_state == NVHOST_POWER_STATE_CLOCKGATED + && drv->finalize_clockon) + drv->finalize_clockon(dev); + + /* Invoke callback after power un-gating. This is used for + * restoring context. */ if (prev_state == NVHOST_POWER_STATE_POWERGATED && drv->finalize_poweron) drv->finalize_poweron(dev); diff --git a/include/linux/nvhost.h b/include/linux/nvhost.h index c89d9b82af14..d7d8ad04653d 100644 --- a/include/linux/nvhost.h +++ b/include/linux/nvhost.h @@ -172,6 +172,10 @@ struct nvhost_driver { /* Allocates a context handler for the device */ struct nvhost_hwctx_handler *(*alloc_hwctx_handler)(u32 syncpt, u32 waitbase, struct nvhost_channel *ch); + + /* Clock gating callbacks */ + int (*prepare_clockoff)(struct nvhost_device *dev); + void (*finalize_clockon)(struct nvhost_device *dev); }; extern int nvhost_driver_register(struct nvhost_driver *); |