diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2010-12-20 14:33:10 +0530 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2010-12-21 03:52:08 -0800 |
commit | 2605df86defb61667131a6b42dc101ecefaf4138 (patch) | |
tree | 3b6bc783a23c766f41a0fabe72c07d95d908a649 | |
parent | ba2891ed491f531517e717274e1144bf442e13b9 (diff) |
video: tegra: host: add suspend instrumentation
cherry-picked and merged http://git-master.nvidia.com/r/6641 and
http://git-master.nvidia.com/r/7081 from tegra-2010-07 branch
Change-Id: I926062d2d949b4095ad1d5c88145c99a29cec122
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/13795
Reviewed-by: Andrew Howe <ahowe@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r-- | drivers/video/tegra/host/dev.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.c | 38 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.h | 2 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cpuaccess.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cpuaccess.h | 1 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_hardware.h | 2 |
6 files changed, 41 insertions, 6 deletions
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index 20a4eda0fb53..c9c88b0171a7 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -741,7 +741,7 @@ static int nvhost_suspend(struct platform_device *pdev, pm_message_t state) { struct nvhost_master *host = platform_get_drvdata(pdev); dev_info(&pdev->dev, "suspending\n"); - nvhost_module_suspend(&host->mod); + nvhost_module_suspend(&host->mod, true); clk_enable(host->mod.clk[0]); nvhost_syncpt_save(&host->syncpt); clk_disable(host->mod.clk[0]); diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c index c4ac035a26ec..9b56365bb44f 100644 --- a/drivers/video/tegra/host/nvhost_acm.c +++ b/drivers/video/tegra/host/nvhost_acm.c @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "nvhost_acm.h" +#include "dev.h" #include <linux/string.h> #include <linux/sched.h> #include <linux/err.h> @@ -155,17 +155,49 @@ static int is_module_idle(struct nvhost_module *mod) return (count == 0); } -void nvhost_module_suspend(struct nvhost_module *mod) +static void debug_not_idle(struct nvhost_module *mod) { + int i; + bool lock_released = true; + struct nvhost_master *dev = container_of(mod, struct nvhost_master, mod); + + for (i = 0; i < NVHOST_NUMCHANNELS; i++) { + struct nvhost_module *m = &dev->channels[i].mod; + if (m->name) + printk("tegra_grhost: %s: refcnt %d\n", + m->name, atomic_read(&m->refcount)); + } + + for (i = 0; i < NV_HOST1X_SYNC_MLOCK_NUM; i++) { + int c = atomic_read(&dev->cpuaccess.lock_counts[i]); + if (c) { + printk("tegra_grhost: lock id %d: refcnt %d\n", i, c); + lock_released = false; + } + } + if (lock_released) + printk("tegra_grhost: all locks released\n"); +} + +void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend) +{ + if (system_suspend && (!is_module_idle(mod))) + debug_not_idle(mod); + wait_event(mod->idle, is_module_idle(mod)); + if (system_suspend) + printk("tegra_grhost: entered idle\n"); + flush_delayed_work(&mod->powerdown); + if (system_suspend) + printk("tegra_grhost: flushed delayed work\n"); BUG_ON(mod->powered); } void nvhost_module_deinit(struct nvhost_module *mod) { int i; - nvhost_module_suspend(mod); + nvhost_module_suspend(mod, false); for (i = 0; i < mod->num_clks; i++) clk_put(mod->clk[i]); } diff --git a/drivers/video/tegra/host/nvhost_acm.h b/drivers/video/tegra/host/nvhost_acm.h index 57dcc2989113..c765d983afb4 100644 --- a/drivers/video/tegra/host/nvhost_acm.h +++ b/drivers/video/tegra/host/nvhost_acm.h @@ -57,7 +57,7 @@ int nvhost_module_init(struct nvhost_module *mod, const char *name, nvhost_modulef func, struct nvhost_module *parent, struct device *dev); void nvhost_module_deinit(struct nvhost_module *mod); -void nvhost_module_suspend(struct nvhost_module *mod); +void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend); void nvhost_module_busy(struct nvhost_module *mod); void nvhost_module_idle_mult(struct nvhost_module *mod, int refs); diff --git a/drivers/video/tegra/host/nvhost_cpuaccess.c b/drivers/video/tegra/host/nvhost_cpuaccess.c index 9114dad97783..4a5c34d593fc 100644 --- a/drivers/video/tegra/host/nvhost_cpuaccess.c +++ b/drivers/video/tegra/host/nvhost_cpuaccess.c @@ -71,6 +71,7 @@ int nvhost_mutex_try_lock(struct nvhost_cpuaccess *ctx, unsigned int idx) nvhost_module_idle(&dev->mod); return -ERESTARTSYS; } + atomic_inc(&ctx->lock_counts[idx]); return 0; } @@ -80,6 +81,7 @@ void nvhost_mutex_unlock(struct nvhost_cpuaccess *ctx, unsigned int idx) void __iomem *sync_regs = dev->sync_aperture; writel(0, sync_regs + (HOST1X_SYNC_MLOCK_0 + idx * 4)); nvhost_module_idle(&dev->mod); + atomic_dec(&ctx->lock_counts[idx]); } void nvhost_read_module_regs(struct nvhost_cpuaccess *ctx, u32 module, diff --git a/drivers/video/tegra/host/nvhost_cpuaccess.h b/drivers/video/tegra/host/nvhost_cpuaccess.h index d7d6c99cd416..98ea1e1e1f8f 100644 --- a/drivers/video/tegra/host/nvhost_cpuaccess.h +++ b/drivers/video/tegra/host/nvhost_cpuaccess.h @@ -45,6 +45,7 @@ enum nvhost_module_id { struct nvhost_cpuaccess { struct resource *reg_mem[NVHOST_MODULE_NUM]; void __iomem *regs[NVHOST_MODULE_NUM]; + atomic_t lock_counts[NV_HOST1X_SYNC_MLOCK_NUM]; }; int nvhost_cpuaccess_init(struct nvhost_cpuaccess *ctx, diff --git a/drivers/video/tegra/host/nvhost_hardware.h b/drivers/video/tegra/host/nvhost_hardware.h index f69f467dd64e..a7663489727e 100644 --- a/drivers/video/tegra/host/nvhost_hardware.h +++ b/drivers/video/tegra/host/nvhost_hardware.h @@ -38,7 +38,7 @@ enum { #define NV_HOST1X_CHANNELS 8 #define NV_HOST1X_CHANNEL0_BASE 0 #define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384 - +#define NV_HOST1X_SYNC_MLOCK_NUM 16 #define HOST1X_CHANNEL_FIFOSTAT 0x00 #define HOST1X_CHANNEL_INDDATA 0x0c |