diff options
33 files changed, 550 insertions, 628 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c index c57055d6df4c..1c274297b3e1 100644 --- a/drivers/media/video/tegra/nvavp/nvavp_dev.c +++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c @@ -1024,7 +1024,7 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp) filp->private_data = clientctx; - nvhost_module_busy(&nvavp->nvhost_dev->host->mod); + nvhost_module_busy(nvavp->nvhost_dev->host->dev); mutex_unlock(&nvavp->open_lock); return ret; @@ -1039,7 +1039,7 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp) dev_dbg(&nvavp->nvhost_dev->dev, "%s: ++\n", __func__); filp->private_data = NULL; - nvhost_module_idle(&nvavp->nvhost_dev->host->mod); + nvhost_module_idle(nvavp->nvhost_dev->host->dev); mutex_lock(&nvavp->open_lock); @@ -1359,7 +1359,7 @@ static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state) struct nvavp_info *nvavp = nvhost_get_drvdata(ndev); if (nvavp->refcount) - nvhost_module_idle(&ndev->host->mod); + nvhost_module_idle(ndev); return 0; } @@ -1368,7 +1368,7 @@ static int tegra_nvavp_resume(struct nvhost_device *ndev) struct nvavp_info *nvavp = nvhost_get_drvdata(ndev); if (nvavp->refcount) - nvhost_module_busy(&ndev->host->mod); + nvhost_module_busy(ndev); return 0; } #endif diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 87ef9c4395dc..98c518ad9b14 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -2110,7 +2110,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *ptr) unsigned long val; unsigned long underflow_mask; - if (!nvhost_module_powered(&dc->ndev->host->mod)) { + if (!nvhost_module_powered(dc->ndev->host->dev)) { WARN(1, "IRQ when DC not powered!\n"); tegra_dc_io_start(dc); status = tegra_dc_readl(dc, DC_CMD_INT_STATUS); diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h index 994edfe46d31..ca25265bfdb8 100644 --- a/drivers/video/tegra/dc/dc_priv.h +++ b/drivers/video/tegra/dc/dc_priv.h @@ -142,25 +142,25 @@ struct tegra_dc { static inline void tegra_dc_io_start(struct tegra_dc *dc) { - nvhost_module_busy(&dc->ndev->host->mod); + nvhost_module_busy(dc->ndev->host->dev); } static inline void tegra_dc_io_end(struct tegra_dc *dc) { - nvhost_module_idle(&dc->ndev->host->mod); + nvhost_module_idle(dc->ndev->host->dev); } static inline unsigned long tegra_dc_readl(struct tegra_dc *dc, unsigned long reg) { - BUG_ON(!nvhost_module_powered(&dc->ndev->host->mod)); + BUG_ON(!nvhost_module_powered(dc->ndev->host->dev)); return readl(dc->base + reg * 4); } static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val, unsigned long reg) { - BUG_ON(!nvhost_module_powered(&dc->ndev->host->mod)); + BUG_ON(!nvhost_module_powered(dc->ndev->host->dev)); writel(val, dc->base + reg * 4); } diff --git a/drivers/video/tegra/host/bus.c b/drivers/video/tegra/host/bus.c index 7e21bcbd7490..d93e44691847 100644 --- a/drivers/video/tegra/host/bus.c +++ b/drivers/video/tegra/host/bus.c @@ -23,9 +23,6 @@ #include "dev.h" struct nvhost_master *nvhost; -struct device nvhost_bus = { - .init_name = "nvhost", -}; struct resource *nvhost_get_resource(struct nvhost_device *dev, unsigned int type, unsigned int num) @@ -130,9 +127,12 @@ int nvhost_device_register(struct nvhost_device *dev) device_initialize(&dev->dev); - if (!dev->dev.parent) - dev->dev.parent = &nvhost_bus; + /* If the dev does not have a parent, assign host1x as parent */ + if (!dev->dev.parent && nvhost && nvhost->dev != dev) + dev->dev.parent = &nvhost->dev->dev; + /* Give pointer to host1x */ + dev->host = nvhost; dev->dev.bus = &nvhost_bus_type; if (dev->id != -1) @@ -198,7 +198,6 @@ void nvhost_device_unregister(struct nvhost_device *dev) } EXPORT_SYMBOL_GPL(nvhost_device_unregister); - static int nvhost_bus_match(struct device *_dev, struct device_driver *drv) { struct nvhost_device *dev = to_nvhost_device(_dev); @@ -540,10 +539,23 @@ struct bus_type nvhost_bus_type = { }; EXPORT_SYMBOL(nvhost_bus_type); -int nvhost_bus_register(struct nvhost_master *host) +static int set_parent(struct device *dev, void *data) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct nvhost_master *host = data; + if (!dev->parent && ndev != host->dev) + dev->parent = &host->dev->dev; + ndev->host = host; + return 0; +} + +int nvhost_bus_add_host(struct nvhost_master *host) { nvhost = host; + /* Assign host1x as parent to all devices in nvhost bus */ + bus_for_each_dev(&nvhost_bus_type, NULL, host, set_parent); + return 0; } @@ -553,13 +565,8 @@ int nvhost_bus_init(void) int err; pr_info("host1x bus init\n"); - err = device_register(&nvhost_bus); - if (err) - return err; err = bus_register(&nvhost_bus_type); - if (err) - device_unregister(&nvhost_bus); return err; } diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h index 3b8c4dc46b45..a8fedf241fbc 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -36,7 +36,6 @@ struct nvhost_intr; struct push_buffer; struct nvhost_syncpt; struct nvhost_cpuaccess; -struct nvhost_module; struct nvhost_master; struct dentry; struct nvhost_job; diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c index aa4b41d96574..75ce6f4147ea 100644 --- a/drivers/video/tegra/host/debug.c +++ b/drivers/video/tegra/host/debug.c @@ -89,13 +89,13 @@ static void show_syncpts(struct nvhost_master *m, struct output *o) static void show_all(struct nvhost_master *m, struct output *o) { - nvhost_module_busy(&m->mod); + nvhost_module_busy(m->dev); m->op.debug.show_mlocks(m, o); show_syncpts(m, o); show_channels(m, o); - nvhost_module_idle(&m->mod); + nvhost_module_idle(m->dev); } diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index bdbb21fe9e7c..6ea8cbabff13 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -99,7 +99,7 @@ static void trace_write_cmdbufs(struct nvhost_job *job) */ for (i = 0; i < gather->words; i += TRACE_MAX_LENGTH) { trace_nvhost_channel_write_cmdbuf_data( - job->ch->desc->name, + job->ch->dev->name, gather->mem_id, min(gather->words - i, TRACE_MAX_LENGTH), @@ -116,11 +116,11 @@ static int nvhost_channelrelease(struct inode *inode, struct file *filp) { struct nvhost_channel_userctx *priv = filp->private_data; - trace_nvhost_channel_release(priv->ch->desc->name); + trace_nvhost_channel_release(priv->ch->dev->name); filp->private_data = NULL; - nvhost_module_remove_client(priv->ch->dev, &priv->ch->mod, priv); + nvhost_module_remove_client(priv->ch->dev, priv); nvhost_putchannel(priv->ch, priv->hwctx); if (priv->hwctx) @@ -143,7 +143,7 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp) ch = nvhost_getchannel(ch); if (!ch) return -ENOMEM; - trace_nvhost_channel_open(ch->desc->name); + trace_nvhost_channel_open(ch->dev->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { @@ -152,7 +152,7 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp) } filp->private_data = priv; priv->ch = ch; - nvhost_module_add_client(ch->dev, &ch->mod, priv); + nvhost_module_add_client(ch->dev, priv); if (ch->ctxhandler.alloc) { priv->hwctx = ch->ctxhandler.alloc(ch); @@ -160,7 +160,7 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp) goto fail; } priv->priority = NVHOST_PRIORITY_MEDIUM; - priv->clientid = atomic_add_return(1, &ch->dev->clientid); + priv->clientid = atomic_add_return(1, &ch->dev->host->clientid); priv->job = nvhost_job_alloc(ch, priv->hwctx, &priv->hdr, NULL, priv->priority, priv->clientid); @@ -175,7 +175,7 @@ fail: static int set_submit(struct nvhost_channel_userctx *ctx) { - struct device *device = &ctx->ch->dev->pdev->dev; + struct device *device = &ctx->ch->dev->dev; /* submit should have at least 1 cmdbuf */ if (!ctx->hdr.num_cmdbufs) @@ -217,7 +217,7 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, int err = 0; struct nvhost_job *job = priv->job; struct nvhost_submit_hdr_ext *hdr = &priv->hdr; - const char *chname = priv->ch->desc->name; + const char *chname = priv->ch->dev->name; while (remaining) { size_t consumed; @@ -308,7 +308,7 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, } if (err < 0) { - dev_err(&priv->ch->dev->pdev->dev, "channel write error\n"); + dev_err(&priv->ch->dev->dev, "channel write error\n"); reset_submit(priv); return err; } @@ -321,10 +321,10 @@ static int nvhost_ioctl_channel_flush( struct nvhost_get_param_args *args, int null_kickoff) { - struct device *device = &ctx->ch->dev->pdev->dev; + struct device *device = &ctx->ch->dev->dev; int err; - trace_nvhost_ioctl_channel_flush(ctx->ch->desc->name); + trace_nvhost_ioctl_channel_flush(ctx->ch->dev->name); if (!ctx->job || ctx->hdr.num_relocs || @@ -405,7 +405,7 @@ static long nvhost_channelctl(struct file *filp, priv->hdr.num_cmdbufs || priv->hdr.num_waitchks) { reset_submit(priv); - dev_err(&priv->ch->dev->pdev->dev, + dev_err(&priv->ch->dev->dev, "channel submit out of sync\n"); err = -EIO; break; @@ -413,7 +413,7 @@ static long nvhost_channelctl(struct file *filp, hdr = (struct nvhost_submit_hdr_ext *)buf; if (hdr->submit_version > NVHOST_SUBMIT_VERSION_MAX_SUPPORTED) { - dev_err(&priv->ch->dev->pdev->dev, + dev_err(&priv->ch->dev->dev, "submit version %d > max supported %d\n", hdr->submit_version, NVHOST_SUBMIT_VERSION_MAX_SUPPORTED); @@ -422,7 +422,7 @@ static long nvhost_channelctl(struct file *filp, } memcpy(&priv->hdr, hdr, sizeof(struct nvhost_submit_hdr_ext)); err = set_submit(priv); - trace_nvhost_ioctl_channel_submit(priv->ch->desc->name, + trace_nvhost_ioctl_channel_submit(priv->ch->dev->name, priv->hdr.submit_version, priv->hdr.num_cmdbufs, priv->hdr.num_relocs, priv->hdr.num_waitchks, @@ -431,17 +431,17 @@ static long nvhost_channelctl(struct file *filp, } case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS: /* host syncpt ID is used by the RM (and never be given out) */ - BUG_ON(priv->ch->desc->syncpts & (1 << NVSYNCPT_GRAPHICS_HOST)); + BUG_ON(priv->ch->dev->syncpts & (1 << NVSYNCPT_GRAPHICS_HOST)); ((struct nvhost_get_param_args *)buf)->value = - priv->ch->desc->syncpts; + priv->ch->dev->syncpts; break; case NVHOST_IOCTL_CHANNEL_GET_WAITBASES: ((struct nvhost_get_param_args *)buf)->value = - priv->ch->desc->waitbases; + priv->ch->dev->waitbases; break; case NVHOST_IOCTL_CHANNEL_GET_MODMUTEXES: ((struct nvhost_get_param_args *)buf)->value = - priv->ch->desc->modulemutexes; + priv->ch->dev->modulemutexes; break; case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD: { @@ -468,8 +468,7 @@ static long nvhost_channelctl(struct file *filp, struct nvhost_clk_rate_args *arg = (struct nvhost_clk_rate_args *)buf; - err = nvhost_module_get_rate(priv->ch->dev, - &priv->ch->mod, &rate, 0); + err = nvhost_module_get_rate(priv->ch->dev, &rate, 0); if (err == 0) arg->rate = rate; break; @@ -480,14 +479,13 @@ static long nvhost_channelctl(struct file *filp, (struct nvhost_clk_rate_args *)buf; unsigned long rate = (unsigned long)arg->rate; - err = nvhost_module_set_rate(priv->ch->dev, - &priv->ch->mod, priv, rate, 0); + err = nvhost_module_set_rate(priv->ch->dev, priv, rate, 0); break; } case NVHOST_IOCTL_CHANNEL_SET_TIMEOUT: priv->timeout = (u32)((struct nvhost_set_timeout_args *)buf)->timeout; - dev_dbg(&priv->ch->dev->pdev->dev, + dev_dbg(&priv->ch->dev->dev, "%s: setting buffer timeout (%d ms) for userctx 0x%p\n", __func__, priv->timeout, priv); break; @@ -523,11 +521,11 @@ static int nvhost_ctrlrelease(struct inode *inode, struct file *filp) struct nvhost_ctrl_userctx *priv = filp->private_data; int i; - trace_nvhost_ctrlrelease(priv->dev->mod.name); + trace_nvhost_ctrlrelease(priv->dev->dev->name); filp->private_data = NULL; if (priv->mod_locks[0]) - nvhost_module_idle(&priv->dev->mod); + nvhost_module_idle(priv->dev->dev); for (i = 1; i < priv->dev->nb_mlocks; i++) if (priv->mod_locks[i]) nvhost_mutex_unlock(&priv->dev->cpuaccess, i); @@ -542,7 +540,7 @@ static int nvhost_ctrlopen(struct inode *inode, struct file *filp) struct nvhost_ctrl_userctx *priv; u32 *mod_locks; - trace_nvhost_ctrlopen(host->mod.name); + trace_nvhost_ctrlopen(host->dev->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); mod_locks = kzalloc(sizeof(u32)*host->nb_mlocks, GFP_KERNEL); @@ -611,14 +609,14 @@ static int nvhost_ioctl_ctrl_module_mutex( trace_nvhost_ioctl_ctrl_module_mutex(args->lock, args->id); if (args->lock && !ctx->mod_locks[args->id]) { if (args->id == 0) - nvhost_module_busy(&ctx->dev->mod); + nvhost_module_busy(ctx->dev->dev); else err = nvhost_mutex_try_lock(&ctx->dev->cpuaccess, args->id); if (!err) ctx->mod_locks[args->id] = 1; } else if (!args->lock && ctx->mod_locks[args->id]) { if (args->id == 0) - nvhost_module_idle(&ctx->dev->mod); + nvhost_module_idle(ctx->dev->dev); else nvhost_mutex_unlock(&ctx->dev->cpuaccess, args->id); ctx->mod_locks[args->id] = 0; @@ -736,22 +734,18 @@ static const struct file_operations nvhost_ctrlops = { .unlocked_ioctl = nvhost_ctrlctl }; -static void power_on_host(struct nvhost_module *mod) +static void power_on_host(struct nvhost_device *dev) { - struct nvhost_master *dev = - container_of(mod, struct nvhost_master, mod); - - nvhost_intr_start(&dev->intr, clk_get_rate(mod->clk[0])); - nvhost_syncpt_reset(&dev->syncpt); + struct nvhost_master *host = dev->host; + nvhost_intr_start(&host->intr, clk_get_rate(dev->clk[0])); + nvhost_syncpt_reset(&host->syncpt); } -static int power_off_host(struct nvhost_module *mod) +static int power_off_host(struct nvhost_device *dev) { - struct nvhost_master *dev = - container_of(mod, struct nvhost_master, mod); - - nvhost_syncpt_save(&dev->syncpt); - nvhost_intr_stop(&dev->intr); + struct nvhost_master *host = dev->host; + nvhost_syncpt_save(&host->syncpt); + nvhost_intr_stop(&host->intr); return 0; } @@ -766,15 +760,9 @@ static int __devinit nvhost_user_init(struct nvhost_master *host) goto fail; } - if (nvhost_major) { - devno = MKDEV(nvhost_major, nvhost_minor); - err = register_chrdev_region(devno, host->nb_channels + 1, - IFACE_NAME); - } else { - err = alloc_chrdev_region(&devno, nvhost_minor, - host->nb_channels + 1, IFACE_NAME); - nvhost_major = MAJOR(devno); - } + err = alloc_chrdev_region(&devno, nvhost_minor, + host->nb_channels + 1, IFACE_NAME); + nvhost_major = MAJOR(devno); if (err < 0) { dev_err(&host->pdev->dev, "failed to reserve chrdev region\n"); goto fail; @@ -793,7 +781,7 @@ static int __devinit nvhost_user_init(struct nvhost_master *host) goto fail; } ch->node = device_create(host->nvhost_class, NULL, devno, NULL, - IFACE_NAME "-%s", ch->desc->name); + IFACE_NAME "-%s", ch->dev->name); if (IS_ERR(ch->node)) { err = PTR_ERR(ch->node); dev_err(&host->pdev->dev, "failed to create chan %i device\n", i); @@ -902,11 +890,12 @@ static int __devinit nvhost_init_chip_support(struct nvhost_master *host) return 0; } -const struct nvhost_moduledesc hostdesc = { - .finalize_poweron = power_on_host, - .prepare_poweroff = power_off_host, - .clocks = {{"host1x", UINT_MAX}, {} }, - NVHOST_MODULE_NO_POWERGATE_IDS, +struct nvhost_device hostdev = { + .name = "host1x", + .finalize_poweron = power_on_host, + .prepare_poweroff = power_off_host, + .clocks = {{"host1x", UINT_MAX}, {} }, + NVHOST_MODULE_NO_POWERGATE_IDS, }; static int __devinit nvhost_probe(struct platform_device *pdev) @@ -957,6 +946,11 @@ static int __devinit nvhost_probe(struct platform_device *pdev) goto fail; } + /* Register host1x device as bus master */ + nvhost_device_register(&hostdev); + host->dev = &hostdev; + nvhost_bus_add_host(host); + for (i = 0; i < host->nb_channels; i++) { struct nvhost_channel *ch = &host->channels[i]; BUG_ON(!host_channel_op(host).init); @@ -965,6 +959,7 @@ static int __devinit nvhost_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to init channel %d\n", i); goto fail; } + ch->dev->channel = ch; } err = nvhost_cpuaccess_init(&host->cpuaccess, pdev); @@ -979,25 +974,20 @@ static int __devinit nvhost_probe(struct platform_device *pdev) if (err) goto fail; - err = nvhost_module_init(&host->mod, "host1x", - &hostdesc, NULL, &pdev->dev); - for (i = 0; i < host->nb_channels; i++) { - struct nvhost_channel *ch = &host->channels[i]; - nvhost_module_preinit(ch->desc->name, - &ch->desc->module); - } - + err = nvhost_module_init(&hostdev); if (err) goto fail; + for (i = 0; i < host->nb_channels; i++) { + struct nvhost_channel *ch = &host->channels[i]; + nvhost_module_preinit(ch->dev); + } platform_set_drvdata(pdev, host); - clk_enable(host->mod.clk[0]); + clk_enable(host->dev->clk[0]); nvhost_syncpt_reset(&host->syncpt); - clk_disable(host->mod.clk[0]); - - nvhost_bus_register(host); + clk_disable(host->dev->clk[0]); nvhost_debug_init(host); @@ -1031,7 +1021,7 @@ static int nvhost_suspend(struct platform_device *pdev, pm_message_t state) return ret; } - ret = nvhost_module_suspend(&host->mod, true); + ret = nvhost_module_suspend(host->dev, true); dev_info(&pdev->dev, "suspend status: %d\n", ret); return ret; } diff --git a/drivers/video/tegra/host/dev.h b/drivers/video/tegra/host/dev.h index 3d05da8c53e8..635b0c90ccf9 100644 --- a/drivers/video/tegra/host/dev.h +++ b/drivers/video/tegra/host/dev.h @@ -46,7 +46,7 @@ struct nvhost_master { struct nvhost_cpuaccess cpuaccess; u32 nb_mlocks; struct nvhost_intr intr; - struct nvhost_module mod; + struct nvhost_device *dev; struct nvhost_channel *channels; u32 nb_channels; u32 nb_modules; diff --git a/drivers/video/tegra/host/gr3d/gr3d.c b/drivers/video/tegra/host/gr3d/gr3d.c index f7f892b883a0..709d4ece9394 100644 --- a/drivers/video/tegra/host/gr3d/gr3d.c +++ b/drivers/video/tegra/host/gr3d/gr3d.c @@ -77,7 +77,7 @@ void nvhost_3dctx_restore_end(u32 *ptr) struct nvhost_hwctx *nvhost_3dctx_alloc_common(struct nvhost_channel *ch, bool map_restore) { - struct nvmap_client *nvmap = ch->dev->nvmap; + struct nvmap_client *nvmap = ch->dev->host->nvmap; struct nvhost_hwctx *ctx; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -130,7 +130,7 @@ void nvhost_3dctx_get(struct nvhost_hwctx *ctx) void nvhost_3dctx_free(struct kref *ref) { struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref); - struct nvmap_client *nvmap = ctx->channel->dev->nvmap; + struct nvmap_client *nvmap = ctx->channel->dev->host->nvmap; if (ctx->restore_virt) { nvmap_munmap(ctx->restore, ctx->restore_virt); @@ -148,7 +148,7 @@ void nvhost_3dctx_put(struct nvhost_hwctx *ctx) kref_put(&ctx->ref, nvhost_3dctx_free); } -int nvhost_gr3d_prepare_power_off(struct nvhost_module *mod) +int nvhost_gr3d_prepare_power_off(struct nvhost_device *dev) { - return host1x_save_context(mod, NVSYNCPT_3D); + return host1x_save_context(dev, NVSYNCPT_3D); } diff --git a/drivers/video/tegra/host/gr3d/gr3d.h b/drivers/video/tegra/host/gr3d/gr3d.h index cdaea188ebf2..1ea3c4c5bba4 100644 --- a/drivers/video/tegra/host/gr3d/gr3d.h +++ b/drivers/video/tegra/host/gr3d/gr3d.h @@ -57,6 +57,6 @@ struct nvhost_hwctx *nvhost_3dctx_alloc_common( void nvhost_3dctx_get(struct nvhost_hwctx *ctx); void nvhost_3dctx_free(struct kref *ref); void nvhost_3dctx_put(struct nvhost_hwctx *ctx); -int nvhost_gr3d_prepare_power_off(struct nvhost_module *mod); +int nvhost_gr3d_prepare_power_off(struct nvhost_device *dev); #endif diff --git a/drivers/video/tegra/host/gr3d/gr3d_t20.c b/drivers/video/tegra/host/gr3d/gr3d_t20.c index c1b25bd164c3..24d7e6d75503 100644 --- a/drivers/video/tegra/host/gr3d/gr3d_t20.c +++ b/drivers/video/tegra/host/gr3d/gr3d_t20.c @@ -340,7 +340,7 @@ static void ctx3d_save_service(struct nvhost_hwctx *ctx) ARRAY_SIZE(ctxsave_regs_3d_global)); wmb(); - nvhost_syncpt_cpu_incr(&ctx->channel->dev->syncpt, NVSYNCPT_3D); + nvhost_syncpt_cpu_incr(&ctx->channel->dev->host->syncpt, NVSYNCPT_3D); } int __init nvhost_gr3d_t20_ctxhandler_init(struct nvhost_hwctx_handler *h) @@ -350,7 +350,7 @@ int __init nvhost_gr3d_t20_ctxhandler_init(struct nvhost_hwctx_handler *h) u32 *save_ptr; ch = container_of(h, struct nvhost_channel, ctxhandler); - nvmap = ch->dev->nvmap; + nvmap = ch->dev->host->nvmap; setup_save(NULL); diff --git a/drivers/video/tegra/host/gr3d/gr3d_t30.c b/drivers/video/tegra/host/gr3d/gr3d_t30.c index 5f991a41db85..1fde326fc101 100644 --- a/drivers/video/tegra/host/gr3d/gr3d_t30.c +++ b/drivers/video/tegra/host/gr3d/gr3d_t30.c @@ -385,7 +385,7 @@ int __init nvhost_gr3d_t30_ctxhandler_init(struct nvhost_hwctx_handler *h) u32 *save_ptr; ch = container_of(h, struct nvhost_channel, ctxhandler); - nvmap = ch->dev->nvmap; + nvmap = ch->dev->host->nvmap; register_sets = tegra_gpu_register_sets(); BUG_ON(register_sets == 0 || register_sets > 2); diff --git a/drivers/video/tegra/host/gr3d/scale3d.c b/drivers/video/tegra/host/gr3d/scale3d.c index a8d7dec27f8c..e7ef19a840cc 100644 --- a/drivers/video/tegra/host/gr3d/scale3d.c +++ b/drivers/video/tegra/host/gr3d/scale3d.c @@ -153,7 +153,7 @@ static void scale3d_clocks_handler(struct work_struct *work) scale3d_clocks(scale); } -void nvhost_scale3d_suspend(struct nvhost_module *mod) +void nvhost_scale3d_suspend(struct nvhost_device *dev) { cancel_work_sync(&scale3d.work); cancel_delayed_work(&scale3d.idle_timer); @@ -370,7 +370,7 @@ static void scaling_state_check(ktime_t time) } } -void nvhost_scale3d_notify_idle(struct nvhost_module *mod) +void nvhost_scale3d_notify_idle(struct nvhost_device *dev) { ktime_t t; unsigned long dt; @@ -404,7 +404,7 @@ done: mutex_unlock(&scale3d.lock); } -void nvhost_scale3d_notify_busy(struct nvhost_module *mod) +void nvhost_scale3d_notify_busy(struct nvhost_device *dev) { unsigned long idle; unsigned long short_term_idle; @@ -523,7 +523,7 @@ static ssize_t enable_3d_scaling_store(struct device *dev, static DEVICE_ATTR(enable_3d_scaling, S_IRUGO | S_IWUGO, enable_3d_scaling_show, enable_3d_scaling_store); -void nvhost_scale3d_init(struct device *d, struct nvhost_module *mod) +void nvhost_scale3d_init(struct nvhost_device *d) { if (!scale3d.init) { int error; @@ -531,12 +531,12 @@ void nvhost_scale3d_init(struct device *d, struct nvhost_module *mod) long correction; mutex_init(&scale3d.lock); - scale3d.clk_3d = mod->clk[0]; + scale3d.clk_3d = d->clk[0]; if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) { - scale3d.clk_3d2 = mod->clk[1]; - scale3d.clk_3d_emc = mod->clk[2]; + scale3d.clk_3d2 = d->clk[1]; + scale3d.clk_3d_emc = d->clk[2]; } else - scale3d.clk_3d_emc = mod->clk[1]; + scale3d.clk_3d_emc = d->clk[1]; scale3d.max_rate_3d = clk_round_rate(scale3d.clk_3d, UINT_MAX); scale3d.min_rate_3d = clk_round_rate(scale3d.clk_3d, 0); @@ -634,9 +634,10 @@ void nvhost_scale3d_init(struct device *d, struct nvhost_module *mod) scale3d.p_verbosity = 0; scale3d.p_adjust = 1; - error = device_create_file(d, &dev_attr_enable_3d_scaling); + error = device_create_file(&d->dev, + &dev_attr_enable_3d_scaling); if (error) - dev_err(d, "failed to create sysfs attributes"); + dev_err(&d->dev, "failed to create sysfs attributes"); scale3d.init = 1; } @@ -644,8 +645,8 @@ void nvhost_scale3d_init(struct device *d, struct nvhost_module *mod) nvhost_scale3d_reset(); } -void nvhost_scale3d_deinit(struct device *dev, struct nvhost_module *mod) +void nvhost_scale3d_deinit(struct nvhost_device *dev) { - device_remove_file(dev, &dev_attr_enable_3d_scaling); + device_remove_file(&dev->dev, &dev_attr_enable_3d_scaling); scale3d.init = 0; } diff --git a/drivers/video/tegra/host/gr3d/scale3d.h b/drivers/video/tegra/host/gr3d/scale3d.h index e6d1a40f53e0..4e448154ec8d 100644 --- a/drivers/video/tegra/host/gr3d/scale3d.h +++ b/drivers/video/tegra/host/gr3d/scale3d.h @@ -23,16 +23,16 @@ #ifndef NVHOST_T30_SCALE3D_H #define NVHOST_T30_SCALE3D_H -struct nvhost_module; +struct nvhost_device; struct device; struct dentry; /* Initialization and de-initialization for module */ -void nvhost_scale3d_init(struct device *, struct nvhost_module *); -void nvhost_scale3d_deinit(struct device *, struct nvhost_module *); +void nvhost_scale3d_init(struct nvhost_device *); +void nvhost_scale3d_deinit(struct nvhost_device *); /* Suspend is called when powering down module */ -void nvhost_scale3d_suspend(struct nvhost_module *); +void nvhost_scale3d_suspend(struct nvhost_device *); /* reset 3d module load counters, called on resume */ void nvhost_scale3d_reset(void); @@ -41,8 +41,8 @@ void nvhost_scale3d_reset(void); * call when performing submit to notify scaling mechanism that 3d module is * in use */ -void nvhost_scale3d_notify_busy(struct nvhost_module *); -void nvhost_scale3d_notify_idle(struct nvhost_module *); +void nvhost_scale3d_notify_busy(struct nvhost_device *); +void nvhost_scale3d_notify_idle(struct nvhost_device *); void nvhost_scale3d_debug_init(struct dentry *de); diff --git a/drivers/video/tegra/host/host1x/host1x_cdma.c b/drivers/video/tegra/host/host1x/host1x_cdma.c index 008c8bfcde15..e5a72514c071 100644 --- a/drivers/video/tegra/host/host1x/host1x_cdma.c +++ b/drivers/video/tegra/host/host1x/host1x_cdma.c @@ -247,7 +247,7 @@ static int cdma_timeout_init(struct nvhost_cdma *cdma, sb->mapped[i++] = nvhost_class_host_incr_syncpt_base( NVWAITBASE_3D, 1); } - sb->mapped[i++] = nvhost_opcode_setclass(ch->desc->class, + sb->mapped[i++] = nvhost_opcode_setclass(ch->dev->class, 0, 0); } wmb(); @@ -546,7 +546,7 @@ void cdma_timeout_teardown_begin(struct nvhost_cdma *cdma) ch->aperture + HOST1X_CHANNEL_DMACTRL); writel(BIT(ch->chid), dev->sync_aperture + HOST1X_SYNC_CH_TEARDOWN); - nvhost_module_reset(&dev->pdev->dev, &ch->mod); + nvhost_module_reset(ch->dev); cdma->running = false; cdma->torndown = true; diff --git a/drivers/video/tegra/host/host1x/host1x_channel.c b/drivers/video/tegra/host/host1x/host1x_channel.c index f5f36ca6a001..18aa2da5151f 100644 --- a/drivers/video/tegra/host/host1x/host1x_channel.c +++ b/drivers/video/tegra/host/host1x/host1x_channel.c @@ -36,8 +36,8 @@ static void sync_waitbases(struct nvhost_channel *ch, u32 syncpt_val) { unsigned long waitbase; - unsigned long int waitbase_mask = ch->desc->waitbases; - if (ch->desc->waitbasesync) { + unsigned long int waitbase_mask = ch->dev->waitbases; + if (ch->dev->waitbasesync) { waitbase = find_first_bit(&waitbase_mask, BITS_PER_LONG); nvhost_cdma_push(&ch->cdma, nvhost_opcode_setclass(NV_HOST1X_CLASS_ID, @@ -52,7 +52,7 @@ int host1x_channel_submit(struct nvhost_job *job) { struct nvhost_hwctx *hwctx_to_save = NULL; struct nvhost_channel *channel = job->ch; - struct nvhost_syncpt *sp = &job->ch->dev->syncpt; + struct nvhost_syncpt *sp = &job->ch->dev->host->syncpt; u32 user_syncpt_incrs = job->syncpt_incrs; bool need_restore = false; u32 syncval; @@ -71,9 +71,9 @@ int host1x_channel_submit(struct nvhost_job *job) } /* keep module powered */ - nvhost_module_busy(&channel->mod); - if (channel->mod.desc->busy) - channel->mod.desc->busy(&channel->mod); + nvhost_module_busy(channel->dev); + if (channel->dev->busy) + channel->dev->busy(channel->dev); /* before error checks, return current max */ job->syncpt_end = nvhost_syncpt_read_max(sp, job->syncpt_id); @@ -81,7 +81,7 @@ int host1x_channel_submit(struct nvhost_job *job) /* get submit lock */ err = mutex_lock_interruptible(&channel->submitlock); if (err) { - nvhost_module_idle(&channel->mod); + nvhost_module_idle(channel->dev); goto done; } @@ -90,7 +90,7 @@ int host1x_channel_submit(struct nvhost_job *job) ctxrestore_waiter = nvhost_intr_alloc_waiter(); if (!ctxrestore_waiter) { mutex_unlock(&channel->submitlock); - nvhost_module_idle(&channel->mod); + nvhost_module_idle(channel->dev); err = -ENOMEM; goto done; } @@ -105,10 +105,10 @@ int host1x_channel_submit(struct nvhost_job *job) job->waitchk, job->num_waitchk); if (err) { - dev_warn(&channel->dev->pdev->dev, + dev_warn(&channel->dev->dev, "nvhost_syncpt_wait_check failed: %d\n", err); mutex_unlock(&channel->submitlock); - nvhost_module_idle(&channel->mod); + nvhost_module_idle(channel->dev); goto done; } } @@ -117,7 +117,7 @@ int host1x_channel_submit(struct nvhost_job *job) err = nvhost_cdma_begin(&channel->cdma, job); if (err) { mutex_unlock(&channel->submitlock); - nvhost_module_idle(&channel->mod); + nvhost_module_idle(channel->dev); goto done; } @@ -125,13 +125,13 @@ int host1x_channel_submit(struct nvhost_job *job) /* context switch */ if (channel->cur_ctx != job->hwctx) { - trace_nvhost_channel_context_switch(channel->desc->name, + trace_nvhost_channel_context_switch(channel->dev->name, channel->cur_ctx, job->hwctx); hwctx_to_save = channel->cur_ctx; if (hwctx_to_save && hwctx_to_save->has_timedout) { hwctx_to_save = NULL; - dev_dbg(&channel->dev->pdev->dev, + dev_dbg(&channel->dev->dev, "%s: skip save of timed out context (0x%p)\n", __func__, channel->cur_ctx); } @@ -162,7 +162,7 @@ int host1x_channel_submit(struct nvhost_job *job) /* gather restore buffer */ if (need_restore) { nvhost_cdma_push_gather(&channel->cdma, - channel->dev->nvmap, + channel->dev->host->nvmap, nvmap_ref_to_handle(channel->cur_ctx->restore), nvhost_opcode_gather(channel->cur_ctx->restore_size), channel->cur_ctx->restore_phys); @@ -170,9 +170,9 @@ int host1x_channel_submit(struct nvhost_job *job) } /* add a setclass for modules that require it (unless ctxsw added it) */ - if (!hwctx_to_save && !need_restore && channel->desc->class) + if (!hwctx_to_save && !need_restore && channel->dev->class) nvhost_cdma_push(&channel->cdma, - nvhost_opcode_setclass(channel->desc->class, 0, 0), + nvhost_opcode_setclass(channel->dev->class, 0, 0), NVHOST_OPCODE_NOOP); if (job->null_kickoff) { @@ -190,7 +190,7 @@ int host1x_channel_submit(struct nvhost_job *job) op_incr, NVHOST_OPCODE_NOOP); /* for 3d, waitbase needs to be incremented after each submit */ - if (channel->desc->class == NV_GRAPHICS_3D_CLASS_ID) + if (channel->dev->class == NV_GRAPHICS_3D_CLASS_ID) nvhost_cdma_push(&channel->cdma, nvhost_opcode_setclass( NV_HOST1X_CLASS_ID, @@ -214,7 +214,7 @@ int host1x_channel_submit(struct nvhost_job *job) /* end CDMA submit & stash pinned hMems into sync queue */ nvhost_cdma_end(&channel->cdma, job); - trace_nvhost_channel_submitted(channel->desc->name, + trace_nvhost_channel_submitted(channel->dev->name, syncval - job->syncpt_incrs, syncval); /* @@ -222,7 +222,7 @@ int host1x_channel_submit(struct nvhost_job *job) * if necessary, and to release the restore buffer) */ if (hwctx_to_save) { - err = nvhost_intr_add_action(&channel->dev->intr, + err = nvhost_intr_add_action(&channel->dev->host->intr, job->syncpt_id, syncval - job->syncpt_incrs + hwctx_to_save->save_thresh, @@ -235,7 +235,7 @@ int host1x_channel_submit(struct nvhost_job *job) if (need_restore) { BUG_ON(!ctxrestore_waiter); - err = nvhost_intr_add_action(&channel->dev->intr, + err = nvhost_intr_add_action(&channel->dev->host->intr, job->syncpt_id, syncval - user_syncpt_incrs, NVHOST_INTR_ACTION_CTXRESTORE, channel->cur_ctx, @@ -246,7 +246,7 @@ int host1x_channel_submit(struct nvhost_job *job) } /* schedule a submit complete interrupt */ - err = nvhost_intr_add_action(&channel->dev->intr, job->syncpt_id, + err = nvhost_intr_add_action(&channel->dev->host->intr, job->syncpt_id, syncval, NVHOST_INTR_ACTION_SUBMIT_COMPLETE, channel, completed_waiter, @@ -293,19 +293,19 @@ int host1x_channel_read_3d_reg( job = nvhost_job_alloc(channel, hwctx, NULL, - channel->dev->nvmap, 0, 0); + channel->dev->host->nvmap, 0, 0); if (!job) { err = -ENOMEM; goto done; } /* keep module powered */ - nvhost_module_busy(&channel->mod); + nvhost_module_busy(channel->dev); /* get submit lock */ err = mutex_lock_interruptible(&channel->submitlock); if (err) { - nvhost_module_idle(&channel->mod); + nvhost_module_idle(channel->dev); return err; } @@ -324,7 +324,7 @@ int host1x_channel_read_3d_reg( } } - syncval = nvhost_syncpt_incr_max(&channel->dev->syncpt, + syncval = nvhost_syncpt_incr_max(&channel->dev->host->syncpt, NVSYNCPT_3D, syncpt_incrs); job->syncpt_id = NVSYNCPT_3D; @@ -390,7 +390,8 @@ int host1x_channel_read_3d_reg( * if necessary, and to release the restore buffer) */ if (hwctx_to_save) { - err = nvhost_intr_add_action(&channel->dev->intr, NVSYNCPT_3D, + err = nvhost_intr_add_action(&channel->dev->host->intr, + NVSYNCPT_3D, syncval - syncpt_incrs + hwctx_to_save->save_incrs - 1, NVHOST_INTR_ACTION_CTXSAVE, hwctx_to_save, ctx_waiter, @@ -400,7 +401,7 @@ int host1x_channel_read_3d_reg( } /* Wait for FIFO to be ready */ - err = nvhost_intr_add_action(&channel->dev->intr, NVSYNCPT_3D, + err = nvhost_intr_add_action(&channel->dev->host->intr, NVSYNCPT_3D, syncval - 2, NVHOST_INTR_ACTION_WAKEUP, &wq, read_waiter, @@ -408,19 +409,20 @@ int host1x_channel_read_3d_reg( read_waiter = NULL; WARN(err, "Failed to set wakeup interrupt"); wait_event(wq, - nvhost_syncpt_min_cmp(&channel->dev->syncpt, + nvhost_syncpt_min_cmp(&channel->dev->host->syncpt, NVSYNCPT_3D, syncval - 2)); - nvhost_intr_put_ref(&channel->dev->intr, ref); + nvhost_intr_put_ref(&channel->dev->host->intr, ref); /* Read the register value from FIFO */ err = host1x_drain_read_fifo(channel->aperture, value, 1, &pending); /* Indicate we've read the value */ - nvhost_syncpt_cpu_incr(&channel->dev->syncpt, NVSYNCPT_3D); + nvhost_syncpt_cpu_incr(&channel->dev->host->syncpt, NVSYNCPT_3D); /* Schedule a submit complete interrupt */ - err = nvhost_intr_add_action(&channel->dev->intr, NVSYNCPT_3D, syncval, + err = nvhost_intr_add_action(&channel->dev->host->intr, + NVSYNCPT_3D, syncval, NVHOST_INTR_ACTION_SUBMIT_COMPLETE, channel, completed_waiter, NULL); completed_waiter = NULL; @@ -478,10 +480,9 @@ int host1x_drain_read_fifo(void __iomem *chan_regs, return 0; } -int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) +int host1x_save_context(struct nvhost_device *dev, u32 syncpt_id) { - struct nvhost_channel *ch = - container_of(mod, struct nvhost_channel, mod); + struct nvhost_channel *ch = dev->channel; struct nvhost_hwctx *hwctx_to_save; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); u32 syncpt_incrs, syncpt_val; @@ -497,8 +498,8 @@ int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) goto done; } - if (mod->desc->busy) - mod->desc->busy(mod); + if (dev->busy) + dev->busy(dev); mutex_lock(&ch->submitlock); hwctx_to_save = ch->cur_ctx; @@ -509,7 +510,7 @@ int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) job = nvhost_job_alloc(ch, hwctx_to_save, NULL, - ch->dev->nvmap, 0, 0); + ch->dev->host->nvmap, 0, 0); if (IS_ERR_OR_NULL(job)) { err = PTR_ERR(job); mutex_unlock(&ch->submitlock); @@ -521,7 +522,7 @@ int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) ch->cur_ctx = NULL; syncpt_incrs = hwctx_to_save->save_incrs; - syncpt_val = nvhost_syncpt_incr_max(&ch->dev->syncpt, + syncpt_val = nvhost_syncpt_incr_max(&ch->dev->host->syncpt, syncpt_id, syncpt_incrs); job->syncpt_id = syncpt_id; @@ -539,7 +540,7 @@ int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) nvhost_job_put(job); job = NULL; - err = nvhost_intr_add_action(&ch->dev->intr, syncpt_id, + err = nvhost_intr_add_action(&ch->dev->host->intr, syncpt_id, syncpt_val - syncpt_incrs + hwctx_to_save->save_thresh, NVHOST_INTR_ACTION_CTXSAVE, hwctx_to_save, ctx_waiter, @@ -547,17 +548,18 @@ int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id) ctx_waiter = NULL; WARN(err, "Failed to set context save interrupt"); - err = nvhost_intr_add_action(&ch->dev->intr, syncpt_id, syncpt_val, + err = nvhost_intr_add_action(&ch->dev->host->intr, + syncpt_id, syncpt_val, NVHOST_INTR_ACTION_WAKEUP, &wq, wakeup_waiter, &ref); wakeup_waiter = NULL; WARN(err, "Failed to set wakeup interrupt"); wait_event(wq, - nvhost_syncpt_min_cmp(&ch->dev->syncpt, + nvhost_syncpt_min_cmp(&ch->dev->host->syncpt, syncpt_id, syncpt_val)); - nvhost_intr_put_ref(&ch->dev->intr, ref); + nvhost_intr_put_ref(&ch->dev->host->intr, ref); nvhost_cdma_update(&ch->cdma); diff --git a/drivers/video/tegra/host/host1x/host1x_channel.h b/drivers/video/tegra/host/host1x/host1x_channel.h index 3c4cf4f9cbcd..68afc7233d17 100644 --- a/drivers/video/tegra/host/host1x/host1x_channel.h +++ b/drivers/video/tegra/host/host1x/host1x_channel.h @@ -26,6 +26,7 @@ struct nvhost_job; struct nvhost_channel; struct nvhost_hwctx; +struct nvhost_device; /* Submit job to a host1x client */ int host1x_channel_submit(struct nvhost_job *job); @@ -41,6 +42,6 @@ int host1x_channel_read_3d_reg( int host1x_drain_read_fifo(void __iomem *chan_regs, u32 *ptr, unsigned int count, unsigned int *pending); -int host1x_save_context(struct nvhost_module *mod, u32 syncpt_id); +int host1x_save_context(struct nvhost_device *dev, u32 syncpt_id); #endif diff --git a/drivers/video/tegra/host/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c index f47a2a5c275f..06b09d20c55b 100644 --- a/drivers/video/tegra/host/host1x/host1x_debug.c +++ b/drivers/video/tegra/host/host1x/host1x_debug.c @@ -275,8 +275,8 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m, cbstat = readl(m->sync_aperture + HOST1X_SYNC_CBSTAT_x(chid)); nvhost_debug_output(o, "%d-%s (%d): ", chid, - channel->mod.name, - channel->mod.refcount); + channel->dev->name, + channel->dev->refcount); if (HOST1X_VAL(CHANNEL_DMACTRL, DMASTOP, dmactrl) || !channel->cdma.push_buffer.mapped) { diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.c b/drivers/video/tegra/host/host1x/host1x_syncpt.c index ecfa08c31e94..21390fca7e9d 100644 --- a/drivers/video/tegra/host/host1x/host1x_syncpt.c +++ b/drivers/video/tegra/host/host1x/host1x_syncpt.c @@ -89,7 +89,7 @@ static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id) static void t20_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id) { struct nvhost_master *dev = syncpt_to_dev(sp); - BUG_ON(!nvhost_module_powered(&dev->mod)); + BUG_ON(!nvhost_module_powered(dev->dev)); if (!client_managed(id) && nvhost_syncpt_min_eq_max(sp, id)) { dev_err(&syncpt_to_dev(sp)->pdev->dev, "Syncpoint id %d\n", diff --git a/drivers/video/tegra/host/mpe/mpe.c b/drivers/video/tegra/host/mpe/mpe.c index 3e89e6989e44..5d497221a671 100644 --- a/drivers/video/tegra/host/mpe/mpe.c +++ b/drivers/video/tegra/host/mpe/mpe.c @@ -439,7 +439,7 @@ static u32 *save_ram(u32 *ptr, unsigned int *pending, static struct nvhost_hwctx *ctxmpe_alloc(struct nvhost_channel *ch) { - struct nvmap_client *nvmap = ch->dev->nvmap; + struct nvmap_client *nvmap = ch->dev->host->nvmap; struct nvhost_hwctx *ctx; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -482,7 +482,7 @@ static void ctxmpe_get(struct nvhost_hwctx *ctx) static void ctxmpe_free(struct kref *ref) { struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref); - struct nvmap_client *nvmap = ctx->channel->dev->nvmap; + struct nvmap_client *nvmap = ctx->channel->dev->host->nvmap; if (ctx->restore_virt) nvmap_munmap(ctx->restore, ctx->restore_virt); @@ -522,7 +522,7 @@ static void ctxmpe_save_service(struct nvhost_hwctx *ctx) IRFR_RAM_SIZE, IRFR_RAM_READ_CMD, IRFR_RAM_READ_DATA); wmb(); - nvhost_syncpt_cpu_incr(&ctx->channel->dev->syncpt, NVSYNCPT_MPE); + nvhost_syncpt_cpu_incr(&ctx->channel->dev->host->syncpt, NVSYNCPT_MPE); } int __init nvhost_mpe_ctxhandler_init(struct nvhost_hwctx_handler *h) @@ -532,7 +532,7 @@ int __init nvhost_mpe_ctxhandler_init(struct nvhost_hwctx_handler *h) u32 *save_ptr; ch = container_of(h, struct nvhost_channel, ctxhandler); - nvmap = ch->dev->nvmap; + nvmap = ch->dev->host->nvmap; setup_save(NULL); @@ -564,7 +564,7 @@ int __init nvhost_mpe_ctxhandler_init(struct nvhost_hwctx_handler *h) return 0; } -int nvhost_mpe_prepare_power_off(struct nvhost_module *mod) +int nvhost_mpe_prepare_power_off(struct nvhost_device *dev) { - return host1x_save_context(mod, NVSYNCPT_MPE); + return host1x_save_context(dev, NVSYNCPT_MPE); } diff --git a/drivers/video/tegra/host/mpe/mpe.h b/drivers/video/tegra/host/mpe/mpe.h index dfc7259f1c67..63f761b429d5 100644 --- a/drivers/video/tegra/host/mpe/mpe.h +++ b/drivers/video/tegra/host/mpe/mpe.h @@ -24,8 +24,9 @@ #define __NVHOST_MPE_MPE_H struct nvhost_hwctx_handler; +struct nvhost_device; int nvhost_mpe_ctxhandler_init(struct nvhost_hwctx_handler *h); -int nvhost_mpe_prepare_power_off(struct nvhost_module *mod); +int nvhost_mpe_prepare_power_off(struct nvhost_device *dev); #endif diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c index c3b4085df738..7a0108ab5f2f 100644 --- a/drivers/video/tegra/host/nvhost_acm.c +++ b/drivers/video/tegra/host/nvhost_acm.c @@ -56,250 +56,246 @@ static void do_unpowergate_locked(int id) tegra_unpowergate_partition(id); } -void nvhost_module_reset(struct device *dev, struct nvhost_module *mod) +void nvhost_module_reset(struct nvhost_device *dev) { - dev_dbg(dev, + dev_dbg(&dev->dev, "%s: asserting %s module reset (id %d, id2 %d)\n", - __func__, mod->name, - mod->desc->powergate_ids[0], mod->desc->powergate_ids[1]); + __func__, dev->name, + dev->powergate_ids[0], dev->powergate_ids[1]); - mutex_lock(&mod->lock); + mutex_lock(&dev->lock); /* assert module and mc client reset */ - if (mod->desc->powergate_ids[0] != -1) { - tegra_powergate_mc_disable(mod->desc->powergate_ids[0]); - tegra_periph_reset_assert(mod->clk[0]); - tegra_powergate_mc_flush(mod->desc->powergate_ids[0]); + if (dev->powergate_ids[0] != -1) { + tegra_powergate_mc_disable(dev->powergate_ids[0]); + tegra_periph_reset_assert(dev->clk[0]); + tegra_powergate_mc_flush(dev->powergate_ids[0]); } - if (mod->desc->powergate_ids[1] != -1) { - tegra_powergate_mc_disable(mod->desc->powergate_ids[1]); - tegra_periph_reset_assert(mod->clk[1]); - tegra_powergate_mc_flush(mod->desc->powergate_ids[1]); + if (dev->powergate_ids[1] != -1) { + tegra_powergate_mc_disable(dev->powergate_ids[1]); + tegra_periph_reset_assert(dev->clk[1]); + tegra_powergate_mc_flush(dev->powergate_ids[1]); } udelay(POWERGATE_DELAY); /* deassert reset */ - if (mod->desc->powergate_ids[0] != -1) { - tegra_powergate_mc_flush_done(mod->desc->powergate_ids[0]); - tegra_periph_reset_deassert(mod->clk[0]); - tegra_powergate_mc_enable(mod->desc->powergate_ids[0]); + if (dev->powergate_ids[0] != -1) { + tegra_powergate_mc_flush_done(dev->powergate_ids[0]); + tegra_periph_reset_deassert(dev->clk[0]); + tegra_powergate_mc_enable(dev->powergate_ids[0]); } - if (mod->desc->powergate_ids[1] != -1) { - tegra_powergate_mc_flush_done(mod->desc->powergate_ids[1]); - tegra_periph_reset_deassert(mod->clk[1]); - tegra_powergate_mc_enable(mod->desc->powergate_ids[1]); + if (dev->powergate_ids[1] != -1) { + tegra_powergate_mc_flush_done(dev->powergate_ids[1]); + tegra_periph_reset_deassert(dev->clk[1]); + tegra_powergate_mc_enable(dev->powergate_ids[1]); } - mutex_unlock(&mod->lock); + mutex_unlock(&dev->lock); - dev_dbg(dev, "%s: module %s out of reset\n", - __func__, mod->name); + dev_dbg(&dev->dev, "%s: module %s out of reset\n", + __func__, dev->name); } -static void to_state_clockgated_locked(struct nvhost_module *mod) +static void to_state_clockgated_locked(struct nvhost_device *dev) { - const struct nvhost_moduledesc *desc = mod->desc; - if (mod->powerstate == NVHOST_POWER_STATE_RUNNING) { + if (dev->powerstate == NVHOST_POWER_STATE_RUNNING) { int i; - for (i = 0; i < mod->num_clks; i++) - clk_disable(mod->clk[i]); - if (mod->parent) - nvhost_module_idle(mod->parent); - } else if (mod->powerstate == NVHOST_POWER_STATE_POWERGATED - && mod->desc->can_powergate) { - do_unpowergate_locked(desc->powergate_ids[0]); - do_unpowergate_locked(desc->powergate_ids[1]); + for (i = 0; i < dev->num_clks; i++) + clk_disable(dev->clk[i]); + if (dev->dev.parent) + nvhost_module_idle(to_nvhost_device(dev->dev.parent)); + } else if (dev->powerstate == NVHOST_POWER_STATE_POWERGATED + && dev->can_powergate) { + do_unpowergate_locked(dev->powergate_ids[0]); + do_unpowergate_locked(dev->powergate_ids[1]); } - mod->powerstate = NVHOST_POWER_STATE_CLOCKGATED; + dev->powerstate = NVHOST_POWER_STATE_CLOCKGATED; } -static void to_state_running_locked(struct nvhost_module *mod) +static void to_state_running_locked(struct nvhost_device *dev) { - int prev_state = mod->powerstate; - if (mod->powerstate == NVHOST_POWER_STATE_POWERGATED) - to_state_clockgated_locked(mod); - if (mod->powerstate == NVHOST_POWER_STATE_CLOCKGATED) { + int prev_state = dev->powerstate; + if (dev->powerstate == NVHOST_POWER_STATE_POWERGATED) + to_state_clockgated_locked(dev); + if (dev->powerstate == NVHOST_POWER_STATE_CLOCKGATED) { int i; - if (mod->parent) - nvhost_module_busy(mod->parent); + if (dev->dev.parent) + nvhost_module_busy(to_nvhost_device(dev->dev.parent)); - for (i = 0; i < mod->num_clks; i++) { - int err = clk_enable(mod->clk[i]); + for (i = 0; i < dev->num_clks; i++) { + int err = clk_enable(dev->clk[i]); BUG_ON(err); } if (prev_state == NVHOST_POWER_STATE_POWERGATED - && mod->desc->finalize_poweron) - mod->desc->finalize_poweron(mod); + && dev->finalize_poweron) + dev->finalize_poweron(dev); } - mod->powerstate = NVHOST_POWER_STATE_RUNNING; + dev->powerstate = NVHOST_POWER_STATE_RUNNING; } /* This gets called from powergate_handler() and from module suspend. * Module suspend is done for all modules, runtime power gating only * for modules with can_powergate set. */ -static int to_state_powergated_locked(struct nvhost_module *mod) +static int to_state_powergated_locked(struct nvhost_device *dev) { int err = 0; - if (mod->desc->prepare_poweroff - && mod->powerstate != NVHOST_POWER_STATE_POWERGATED) { + if (dev->prepare_poweroff + && dev->powerstate != NVHOST_POWER_STATE_POWERGATED) { /* Clock needs to be on in prepare_poweroff */ - to_state_running_locked(mod); - err = mod->desc->prepare_poweroff(mod); + to_state_running_locked(dev); + err = dev->prepare_poweroff(dev); if (err) return err; } - if (mod->powerstate == NVHOST_POWER_STATE_RUNNING) - to_state_clockgated_locked(mod); + if (dev->powerstate == NVHOST_POWER_STATE_RUNNING) + to_state_clockgated_locked(dev); - if (mod->desc->can_powergate) { - do_powergate_locked(mod->desc->powergate_ids[0]); - do_powergate_locked(mod->desc->powergate_ids[1]); + if (dev->can_powergate) { + do_powergate_locked(dev->powergate_ids[0]); + do_powergate_locked(dev->powergate_ids[1]); } - mod->powerstate = NVHOST_POWER_STATE_POWERGATED; + dev->powerstate = NVHOST_POWER_STATE_POWERGATED; return 0; } -static void schedule_powergating_locked(struct nvhost_module *mod) +static void schedule_powergating_locked(struct nvhost_device *dev) { - if (mod->desc->can_powergate) - schedule_delayed_work(&mod->powerstate_down, - msecs_to_jiffies(mod->desc->powergate_delay)); + if (dev->can_powergate) + schedule_delayed_work(&dev->powerstate_down, + msecs_to_jiffies(dev->powergate_delay)); } -static void schedule_clockgating_locked(struct nvhost_module *mod) +static void schedule_clockgating_locked(struct nvhost_device *dev) { - schedule_delayed_work(&mod->powerstate_down, - msecs_to_jiffies(mod->desc->clockgate_delay)); + schedule_delayed_work(&dev->powerstate_down, + msecs_to_jiffies(dev->clockgate_delay)); } -void nvhost_module_busy(struct nvhost_module *mod) +void nvhost_module_busy(struct nvhost_device *dev) { - if (mod->desc->busy) - mod->desc->busy(mod); + if (dev->busy) + dev->busy(dev); - mutex_lock(&mod->lock); - cancel_delayed_work(&mod->powerstate_down); + mutex_lock(&dev->lock); + cancel_delayed_work(&dev->powerstate_down); - mod->refcount++; - if (mod->refcount > 0 && !nvhost_module_powered(mod)) - to_state_running_locked(mod); - mutex_unlock(&mod->lock); + dev->refcount++; + if (dev->refcount > 0 && !nvhost_module_powered(dev)) + to_state_running_locked(dev); + mutex_unlock(&dev->lock); } static void powerstate_down_handler(struct work_struct *work) { - struct nvhost_module *mod; + struct nvhost_device *dev; - mod = container_of(to_delayed_work(work), - struct nvhost_module, + dev = container_of(to_delayed_work(work), + struct nvhost_device, powerstate_down); - mutex_lock(&mod->lock); - if (mod->refcount == 0) { - switch (mod->powerstate) { + mutex_lock(&dev->lock); + if (dev->refcount == 0) { + switch (dev->powerstate) { case NVHOST_POWER_STATE_RUNNING: - to_state_clockgated_locked(mod); - schedule_powergating_locked(mod); + to_state_clockgated_locked(dev); + schedule_powergating_locked(dev); break; case NVHOST_POWER_STATE_CLOCKGATED: - if (to_state_powergated_locked(mod)) - schedule_powergating_locked(mod); + if (to_state_powergated_locked(dev)) + schedule_powergating_locked(dev); break; default: break; } } - mutex_unlock(&mod->lock); + mutex_unlock(&dev->lock); } -void nvhost_module_idle_mult(struct nvhost_module *mod, int refs) +void nvhost_module_idle_mult(struct nvhost_device *dev, int refs) { bool kick = false; - mutex_lock(&mod->lock); - mod->refcount -= refs; - if (mod->refcount == 0) { - if (nvhost_module_powered(mod)) - schedule_clockgating_locked(mod); + mutex_lock(&dev->lock); + dev->refcount -= refs; + if (dev->refcount == 0) { + if (nvhost_module_powered(dev)) + schedule_clockgating_locked(dev); kick = true; } - mutex_unlock(&mod->lock); + mutex_unlock(&dev->lock); if (kick) { - wake_up(&mod->idle); + wake_up(&dev->idle_wq); - if (mod->desc->idle) - mod->desc->idle(mod); + if (dev->idle) + dev->idle(dev); } } -int nvhost_module_get_rate(struct nvhost_master *host, - struct nvhost_module *mod, unsigned long *rate, +int nvhost_module_get_rate(struct nvhost_device *dev, unsigned long *rate, int index) { struct clk *c; - c = mod->clk[index]; + c = dev->clk[index]; if (IS_ERR_OR_NULL(c)) return -EINVAL; /* Need to enable client to get correct rate */ - nvhost_module_busy(mod); + nvhost_module_busy(dev); *rate = clk_get_rate(c); - nvhost_module_idle(mod); + nvhost_module_idle(dev); return 0; } -static int nvhost_module_update_rate(struct nvhost_module *mod, int index) +static int nvhost_module_update_rate(struct nvhost_device *dev, int index) { unsigned long rate = 0; struct nvhost_module_client *m; - if (!mod->clk[index]) + if (!dev->clk[index]) return -EINVAL; - list_for_each_entry(m, &mod->client_list, node) { + list_for_each_entry(m, &dev->client_list, node) { rate = max(m->rate[index], rate); } if (!rate) - rate = clk_round_rate(mod->clk[index], - mod->desc->clocks[index].default_rate); + rate = clk_round_rate(dev->clk[index], + dev->clocks[index].default_rate); - return clk_set_rate(mod->clk[index], rate); + return clk_set_rate(dev->clk[index], rate); } -int nvhost_module_set_rate(struct nvhost_master *host, - struct nvhost_module *mod, void *priv, +int nvhost_module_set_rate(struct nvhost_device *dev, void *priv, unsigned long rate, int index) { struct nvhost_module_client *m; int ret; mutex_lock(&client_list_lock); - list_for_each_entry(m, &mod->client_list, node) { + list_for_each_entry(m, &dev->client_list, node) { if (m->priv == priv) { - rate = clk_round_rate(mod->clk[index], rate); + rate = clk_round_rate(dev->clk[index], rate); m->rate[index] = rate; break; } } - ret = nvhost_module_update_rate(mod, index); + ret = nvhost_module_update_rate(dev, index); mutex_unlock(&client_list_lock); return ret; } -int nvhost_module_add_client(struct nvhost_master *host, - struct nvhost_module *mod, void *priv) +int nvhost_module_add_client(struct nvhost_device *dev, void *priv) { int i; unsigned long rate; @@ -312,25 +308,24 @@ int nvhost_module_add_client(struct nvhost_master *host, INIT_LIST_HEAD(&client->node); client->priv = priv; - for (i = 0; i < mod->num_clks; i++) { - rate = clk_round_rate(mod->clk[i], - mod->desc->clocks[i].default_rate); + for (i = 0; i < dev->num_clks; i++) { + rate = clk_round_rate(dev->clk[i], + dev->clocks[i].default_rate); client->rate[i] = rate; } mutex_lock(&client_list_lock); - list_add_tail(&client->node, &mod->client_list); + list_add_tail(&client->node, &dev->client_list); mutex_unlock(&client_list_lock); return 0; } -void nvhost_module_remove_client(struct nvhost_master *host, - struct nvhost_module *mod, void *priv) +void nvhost_module_remove_client(struct nvhost_device *dev, void *priv) { int i; struct nvhost_module_client *m; mutex_lock(&client_list_lock); - list_for_each_entry(m, &mod->client_list, node) { + list_for_each_entry(m, &dev->client_list, node) { if (priv == m->priv) { list_del(&m->node); break; @@ -338,25 +333,24 @@ void nvhost_module_remove_client(struct nvhost_master *host, } if (m) { kfree(m); - for (i = 0; i < mod->num_clks; i++) - nvhost_module_update_rate(mod, i); + for (i = 0; i < dev->num_clks; i++) + nvhost_module_update_rate(dev, i); } mutex_unlock(&client_list_lock); } -void nvhost_module_preinit(const char *name, - const struct nvhost_moduledesc *desc) +void nvhost_module_preinit(struct nvhost_device *dev) { int i = 0; /* initialize clocks to known state */ - while (desc->clocks[i].name && i < NVHOST_MODULE_MAX_CLOCKS) { + while (dev->clocks[i].name && i < NVHOST_MODULE_MAX_CLOCKS) { char devname[MAX_DEVID_LENGTH]; - long rate = desc->clocks[i].default_rate; + long rate = dev->clocks[i].default_rate; struct clk *c; - snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s", name); - c = clk_get_sys(devname, desc->clocks[i].name); + snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s", dev->name); + c = clk_get_sys(devname, dev->clocks[i].name); BUG_ON(IS_ERR_OR_NULL(c)); rate = clk_round_rate(c, rate); @@ -366,145 +360,129 @@ void nvhost_module_preinit(const char *name, i++; } - if (desc->can_powergate) { - do_powergate_locked(desc->powergate_ids[0]); - do_powergate_locked(desc->powergate_ids[1]); + if (dev->can_powergate) { + do_powergate_locked(dev->powergate_ids[0]); + do_powergate_locked(dev->powergate_ids[1]); } else { - do_unpowergate_locked(desc->powergate_ids[0]); - do_unpowergate_locked(desc->powergate_ids[1]); + do_unpowergate_locked(dev->powergate_ids[0]); + do_unpowergate_locked(dev->powergate_ids[1]); } } -int nvhost_module_init(struct nvhost_module *mod, const char *name, - const struct nvhost_moduledesc *desc, - struct nvhost_module *parent, - struct device *dev) +int nvhost_module_init(struct nvhost_device *dev) { int i = 0; - int err; - /* register to kernel */ - mod->drv.driver.name = name; - mod->drv.driver.owner = THIS_MODULE; - err = nvhost_driver_register(&mod->drv); - if (err) - return err; + nvhost_module_preinit(dev); - nvhost_module_preinit(name, desc); - mod->name = name; - - INIT_LIST_HEAD(&mod->client_list); - while (desc->clocks[i].name && i < NVHOST_MODULE_MAX_CLOCKS) { + INIT_LIST_HEAD(&dev->client_list); + while (dev->clocks[i].name && i < NVHOST_MODULE_MAX_CLOCKS) { char devname[MAX_DEVID_LENGTH]; - snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s", name); - mod->clk[i] = clk_get_sys(devname, desc->clocks[i].name); - BUG_ON(IS_ERR_OR_NULL(mod->clk[i])); + snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s", dev->name); + dev->clk[i] = clk_get_sys(devname, dev->clocks[i].name); + BUG_ON(IS_ERR_OR_NULL(dev->clk[i])); i++; } - mod->num_clks = i; - mod->desc = desc; - mod->parent = parent; + dev->num_clks = i; - mutex_init(&mod->lock); - init_waitqueue_head(&mod->idle); - INIT_DELAYED_WORK(&mod->powerstate_down, powerstate_down_handler); + mutex_init(&dev->lock); + init_waitqueue_head(&dev->idle_wq); + INIT_DELAYED_WORK(&dev->powerstate_down, powerstate_down_handler); - if (desc->can_powergate) { - mod->powerstate = NVHOST_POWER_STATE_POWERGATED; - } else { - mod->powerstate = NVHOST_POWER_STATE_CLOCKGATED; - } + if (dev->can_powergate) + dev->powerstate = NVHOST_POWER_STATE_POWERGATED; + else + dev->powerstate = NVHOST_POWER_STATE_CLOCKGATED; - if (desc->init) - desc->init(dev, mod); + if (dev->init) + dev->init(dev); return 0; } -static int is_module_idle(struct nvhost_module *mod) +static int is_module_idle(struct nvhost_device *dev) { int count; - mutex_lock(&mod->lock); - count = mod->refcount; - mutex_unlock(&mod->lock); + mutex_lock(&dev->lock); + count = dev->refcount; + mutex_unlock(&dev->lock); return (count == 0); } -static void debug_not_idle(struct nvhost_master *dev) +static void debug_not_idle(struct nvhost_master *host) { int i; bool lock_released = true; - for (i = 0; i < dev->nb_channels; i++) { - struct nvhost_module *mod = &dev->channels[i].mod; - mutex_lock(&mod->lock); - if (mod->name) - dev_warn(&dev->pdev->dev, + for (i = 0; i < host->nb_channels; i++) { + struct nvhost_device *dev = host->channels[i].dev; + mutex_lock(&dev->lock); + if (dev->name) + dev_warn(&host->pdev->dev, "tegra_grhost: %s: refcnt %d\n", - mod->name, mod->refcount); - mutex_unlock(&mod->lock); + dev->name, dev->refcount); + mutex_unlock(&dev->lock); } - for (i = 0; i < dev->nb_mlocks; i++) { - int c = atomic_read(&dev->cpuaccess.lock_counts[i]); + for (i = 0; i < host->nb_mlocks; i++) { + int c = atomic_read(&host->cpuaccess.lock_counts[i]); if (c) { - dev_warn(&dev->pdev->dev, + dev_warn(&host->pdev->dev, "tegra_grhost: lock id %d: refcnt %d\n", i, c); lock_released = false; } } if (lock_released) - dev_dbg(&dev->pdev->dev, "tegra_grhost: all locks released\n"); + dev_dbg(&host->pdev->dev, "tegra_grhost: all locks released\n"); } -int nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend) +int nvhost_module_suspend(struct nvhost_device *dev, bool system_suspend) { int ret; - struct nvhost_master *dev; + struct nvhost_master *host; if (system_suspend) { - dev = container_of(mod, struct nvhost_master, mod); - if (!is_module_idle(mod)) - debug_not_idle(dev); + host = dev->host; + if (!is_module_idle(dev)) + debug_not_idle(host); } else { - dev = container_of(mod, struct nvhost_channel, mod)->dev; + host = dev->host; } - ret = wait_event_timeout(mod->idle, is_module_idle(mod), + ret = wait_event_timeout(dev->idle_wq, is_module_idle(dev), ACM_SUSPEND_WAIT_FOR_IDLE_TIMEOUT); if (ret == 0) { - dev_info(&dev->pdev->dev, "%s prevented suspend\n", mod->name); + dev_info(&dev->dev, "%s prevented suspend\n", + dev->name); return -EBUSY; } if (system_suspend) - dev_dbg(&dev->pdev->dev, "tegra_grhost: entered idle\n"); + dev_dbg(&dev->dev, "tegra_grhost: entered idle\n"); - mutex_lock(&mod->lock); - cancel_delayed_work(&mod->powerstate_down); - to_state_powergated_locked(mod); - mutex_unlock(&mod->lock); + mutex_lock(&dev->lock); + cancel_delayed_work(&dev->powerstate_down); + to_state_powergated_locked(dev); + mutex_unlock(&dev->lock); - if (mod->desc->suspend) - mod->desc->suspend(mod); + if (dev->suspend) + dev->suspend(dev); return 0; } -void nvhost_module_deinit(struct device *dev, struct nvhost_module *mod) +void nvhost_module_deinit(struct nvhost_device *dev) { int i; - nvhost_driver_unregister(&mod->drv); - - if (mod->desc->deinit) - mod->desc->deinit(dev, mod); + if (dev->deinit) + dev->deinit(dev); - nvhost_module_suspend(mod, false); - for (i = 0; i < mod->num_clks; i++) - clk_put(mod->clk[i]); - mod->powerstate = NVHOST_POWER_STATE_DEINIT; + nvhost_module_suspend(dev, false); + for (i = 0; i < dev->num_clks; i++) + clk_put(dev->clk[i]); + dev->powerstate = NVHOST_POWER_STATE_DEINIT; } diff --git a/drivers/video/tegra/host/nvhost_acm.h b/drivers/video/tegra/host/nvhost_acm.h index 548f3e6a5c25..3e1636f44176 100644 --- a/drivers/video/tegra/host/nvhost_acm.h +++ b/drivers/video/tegra/host/nvhost_acm.h @@ -29,92 +29,34 @@ #include <linux/clk.h> #include <linux/nvhost.h> -#define NVHOST_MODULE_MAX_CLOCKS 3 -#define NVHOST_MODULE_MAX_POWERGATE_IDS 2 -struct nvhost_module; -struct nvhost_master; - -struct nvhost_moduledesc_clock { - char *name; - long default_rate; -}; - -#define NVHOST_MODULE_NO_POWERGATE_IDS .powergate_ids = {-1, -1} -#define NVHOST_DEFAULT_CLOCKGATE_DELAY .clockgate_delay = 25 - -struct nvhost_moduledesc { - int (*prepare_poweroff)(struct nvhost_module *mod); - void (*finalize_poweron)(struct nvhost_module *mod); - void (*busy)(struct nvhost_module *); - void (*idle)(struct nvhost_module *); - void (*suspend)(struct nvhost_module *); - void (*init)(struct device *dev, struct nvhost_module *); - void (*deinit)(struct device *dev, struct nvhost_module *); - - int powergate_ids[NVHOST_MODULE_MAX_POWERGATE_IDS]; - bool can_powergate; - int clockgate_delay; - int powergate_delay; - struct nvhost_moduledesc_clock clocks[NVHOST_MODULE_MAX_CLOCKS]; -}; - -enum nvhost_module_powerstate_t { - NVHOST_POWER_STATE_DEINIT, - NVHOST_POWER_STATE_RUNNING, - NVHOST_POWER_STATE_CLOCKGATED, - NVHOST_POWER_STATE_POWERGATED -}; - -struct nvhost_module { - struct nvhost_driver drv; - const char *name; - struct delayed_work powerstate_down; - int num_clks; - struct clk *clk[NVHOST_MODULE_MAX_CLOCKS]; - struct mutex lock; - int powerstate; - int refcount; - wait_queue_head_t idle; - struct nvhost_module *parent; - const struct nvhost_moduledesc *desc; - struct list_head client_list; -}; - /* Sets clocks and powergating state for a module */ -void nvhost_module_preinit(const char *name, const struct nvhost_moduledesc *desc); -int nvhost_module_init(struct nvhost_module *mod, const char *name, - const struct nvhost_moduledesc *desc, - struct nvhost_module *parent, - struct device *dev); -void nvhost_module_deinit(struct device *dev, struct nvhost_module *mod); -int nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend); - -void nvhost_module_reset(struct device *dev, struct nvhost_module *mod); -void nvhost_module_busy(struct nvhost_module *mod); -void nvhost_module_idle_mult(struct nvhost_module *mod, int refs); -int nvhost_module_add_client(struct nvhost_master *host, - struct nvhost_module *mod, +void nvhost_module_preinit(struct nvhost_device *ndev); +int nvhost_module_init(struct nvhost_device *ndev); +void nvhost_module_deinit(struct nvhost_device *dev); +int nvhost_module_suspend(struct nvhost_device *dev, bool system_suspend); + +void nvhost_module_reset(struct nvhost_device *dev); +void nvhost_module_busy(struct nvhost_device *dev); +void nvhost_module_idle_mult(struct nvhost_device *dev, int refs); +int nvhost_module_add_client(struct nvhost_device *dev, void *priv); -void nvhost_module_remove_client(struct nvhost_master *host, - struct nvhost_module *mod, +void nvhost_module_remove_client(struct nvhost_device *dev, void *priv); -int nvhost_module_get_rate(struct nvhost_master *host, - struct nvhost_module *mod, +int nvhost_module_get_rate(struct nvhost_device *dev, unsigned long *rate, int index); -int nvhost_module_set_rate(struct nvhost_master *host, - struct nvhost_module *mod, void *priv, +int nvhost_module_set_rate(struct nvhost_device *dev, void *priv, unsigned long rate, int index); -static inline bool nvhost_module_powered(struct nvhost_module *mod) +static inline bool nvhost_module_powered(struct nvhost_device *dev) { - return mod->powerstate == NVHOST_POWER_STATE_RUNNING; + return dev->powerstate == NVHOST_POWER_STATE_RUNNING; } -static inline void nvhost_module_idle(struct nvhost_module *mod) +static inline void nvhost_module_idle(struct nvhost_device *dev) { - nvhost_module_idle_mult(mod, 1); + nvhost_module_idle_mult(dev, 1); } diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c index 63ce365e990e..bddb421aa7f2 100644 --- a/drivers/video/tegra/host/nvhost_cdma.c +++ b/drivers/video/tegra/host/nvhost_cdma.c @@ -120,7 +120,7 @@ unsigned int nvhost_cdma_wait_locked(struct nvhost_cdma *cdma, if (space) return space; - trace_nvhost_wait_cdma(cdma_to_channel(cdma)->desc->name, + trace_nvhost_wait_cdma(cdma_to_channel(cdma)->dev->name, event); BUG_ON(cdma->event != CDMA_EVENT_NONE); diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index 87b6a14d60e3..39142ca5cd83 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -108,7 +108,7 @@ struct nvhost_cdma { }; #define cdma_to_channel(cdma) container_of(cdma, struct nvhost_channel, cdma) -#define cdma_to_dev(cdma) ((cdma_to_channel(cdma))->dev) +#define cdma_to_dev(cdma) ((cdma_to_channel(cdma))->dev->host) #define cdma_op(cdma) (cdma_to_dev(cdma)->op.cdma) #define cdma_to_nvmap(cdma) ((cdma_to_dev(cdma))->nvmap) #define pb_to_cdma(pb) container_of(pb, struct nvhost_cdma, push_buffer) diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c index 85256016ad70..6d39eba643c4 100644 --- a/drivers/video/tegra/host/nvhost_channel.c +++ b/drivers/video/tegra/host/nvhost_channel.c @@ -49,17 +49,13 @@ struct nvhost_channel *nvhost_getchannel(struct nvhost_channel *ch) int err = 0; mutex_lock(&ch->reflock); if (ch->refcount == 0) { - err = nvhost_module_init(&ch->mod, ch->desc->name, - &ch->desc->module, - &ch->dev->mod, - &ch->dev->pdev->dev); + err = nvhost_module_init(ch->dev); if (!err) { err = nvhost_cdma_init(&ch->cdma); if (err) - nvhost_module_deinit(&ch->dev->pdev->dev, - &ch->mod); + nvhost_module_deinit(ch->dev); } - } else if (ch->desc->exclusive) { + } else if (ch->dev->exclusive) { err = -EBUSY; } if (!err) @@ -68,8 +64,8 @@ struct nvhost_channel *nvhost_getchannel(struct nvhost_channel *ch) mutex_unlock(&ch->reflock); /* Keep alive modules that needs to be when a channel is open */ - if (!err && ch->desc->keepalive) - nvhost_module_busy(&ch->mod); + if (!err && ch->dev->keepalive) + nvhost_module_busy(ch->dev); return err ? NULL : ch; } @@ -86,14 +82,14 @@ void nvhost_putchannel(struct nvhost_channel *ch, struct nvhost_hwctx *ctx) } /* Allow keep-alive'd module to be turned off */ - if (ch->desc->keepalive) - nvhost_module_idle(&ch->mod); + if (ch->dev->keepalive) + nvhost_module_idle(ch->dev); mutex_lock(&ch->reflock); if (ch->refcount == 1) { channel_cdma_op(ch).stop(&ch->cdma); nvhost_cdma_deinit(&ch->cdma); - nvhost_module_deinit(&ch->dev->pdev->dev, &ch->mod); + nvhost_module_deinit(ch->dev); } ch->refcount--; mutex_unlock(&ch->reflock); @@ -107,7 +103,7 @@ int nvhost_channel_suspend(struct nvhost_channel *ch) BUG_ON(!channel_cdma_op(ch).stop); if (ch->refcount) { - ret = nvhost_module_suspend(&ch->mod, false); + ret = nvhost_module_suspend(ch->dev, false); if (!ret) channel_cdma_op(ch).stop(&ch->cdma); } diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h index c6d60fbf1189..f6c22cac963d 100644 --- a/drivers/video/tegra/host/nvhost_channel.h +++ b/drivers/video/tegra/host/nvhost_channel.h @@ -38,18 +38,7 @@ struct nvhost_master; struct nvhost_waitchk; - -struct nvhost_channeldesc { - const char *name; - u32 syncpts; - u32 waitbases; - u32 modulemutexes; - u32 class; - bool exclusive; - bool keepalive; - bool waitbasesync; - struct nvhost_moduledesc module; -}; +struct nvhost_device; struct nvhost_channel_gather { u32 words; @@ -65,13 +54,11 @@ struct nvhost_channel { struct mutex reflock; struct mutex submitlock; void __iomem *aperture; - struct nvhost_master *dev; - const struct nvhost_channeldesc *desc; struct nvhost_hwctx *cur_ctx; struct device *node; + struct nvhost_device *dev; struct cdev cdev; struct nvhost_hwctx_handler ctxhandler; - struct nvhost_module mod; struct nvhost_cdma cdma; }; @@ -85,8 +72,8 @@ struct nvhost_channel *nvhost_getchannel(struct nvhost_channel *ch); void nvhost_putchannel(struct nvhost_channel *ch, struct nvhost_hwctx *ctx); int nvhost_channel_suspend(struct nvhost_channel *ch); -#define channel_cdma_op(ch) (ch->dev->op.cdma) -#define channel_op(ch) (ch->dev->op.channel) +#define channel_cdma_op(ch) (ch->dev->host->op.cdma) +#define channel_op(ch) (ch->dev->host->op.channel) #define host_channel_op(host) (host->op.channel) int nvhost_channel_drain_read_fifo(void __iomem *chan_regs, diff --git a/drivers/video/tegra/host/nvhost_cpuaccess.c b/drivers/video/tegra/host/nvhost_cpuaccess.c index 6c876b332001..0c7d0a4a98dc 100644 --- a/drivers/video/tegra/host/nvhost_cpuaccess.c +++ b/drivers/video/tegra/host/nvhost_cpuaccess.c @@ -65,10 +65,10 @@ int nvhost_mutex_try_lock(struct nvhost_cpuaccess *ctx, unsigned int idx) u32 reg; BUG_ON(!cpuaccess_op(ctx).mutex_try_lock); - nvhost_module_busy(&dev->mod); + nvhost_module_busy(dev->dev); reg = cpuaccess_op(ctx).mutex_try_lock(ctx, idx); if (reg) { - nvhost_module_idle(&dev->mod); + nvhost_module_idle(dev->dev); return -EBUSY; } atomic_inc(&ctx->lock_counts[idx]); @@ -81,7 +81,7 @@ void nvhost_mutex_unlock(struct nvhost_cpuaccess *ctx, unsigned int idx) BUG_ON(!cpuaccess_op(ctx).mutex_unlock); cpuaccess_op(ctx).mutex_unlock(ctx, idx); - nvhost_module_idle(&dev->mod); + nvhost_module_idle(dev->dev); atomic_dec(&ctx->lock_counts[idx]); } @@ -93,13 +93,13 @@ void nvhost_read_module_regs(struct nvhost_cpuaccess *ctx, u32 module, u32 *out = (u32 *)values; BUG_ON(size & 3); size >>= 2; - nvhost_module_busy(&dev->mod); + nvhost_module_busy(dev->dev); while (size--) { *(out++) = readl(p); p += 4; } rmb(); - nvhost_module_idle(&dev->mod); + nvhost_module_idle(dev->dev); } void nvhost_write_module_regs(struct nvhost_cpuaccess *ctx, u32 module, @@ -110,11 +110,11 @@ void nvhost_write_module_regs(struct nvhost_cpuaccess *ctx, u32 module, const u32 *in = (const u32 *)values; BUG_ON(size & 3); size >>= 2; - nvhost_module_busy(&dev->mod); + nvhost_module_busy(dev->dev); while (size--) { writel(*(in++), p); p += 4; } wmb(); - nvhost_module_idle(&dev->mod); + nvhost_module_idle(dev->dev); } diff --git a/drivers/video/tegra/host/nvhost_intr.c b/drivers/video/tegra/host/nvhost_intr.c index 1a1a9b3fa4c3..7fdf5e9f2e35 100644 --- a/drivers/video/tegra/host/nvhost_intr.c +++ b/drivers/video/tegra/host/nvhost_intr.c @@ -132,11 +132,11 @@ static void action_submit_complete(struct nvhost_waitlist *waiter) int nr_completed = waiter->count; /* Add nr_completed to trace */ - trace_nvhost_channel_submit_complete(channel->desc->name, + trace_nvhost_channel_submit_complete(channel->dev->name, nr_completed); nvhost_cdma_update(&channel->cdma); - nvhost_module_idle_mult(&channel->mod, nr_completed); + nvhost_module_idle_mult(channel->dev, nr_completed); } static void action_ctxsave(struct nvhost_waitlist *waiter) diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c index 0fa6d3e1ce20..f212e618f950 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.c +++ b/drivers/video/tegra/host/nvhost_syncpt.c @@ -77,9 +77,9 @@ u32 nvhost_syncpt_read(struct nvhost_syncpt *sp, u32 id) { u32 val; BUG_ON(!syncpt_op(sp).update_min); - nvhost_module_busy(&syncpt_to_dev(sp)->mod); + nvhost_module_busy(syncpt_to_dev(sp)->dev); val = syncpt_op(sp).update_min(sp, id); - nvhost_module_idle(&syncpt_to_dev(sp)->mod); + nvhost_module_idle(syncpt_to_dev(sp)->dev); return val; } @@ -90,10 +90,10 @@ u32 nvhost_syncpt_read_wait_base(struct nvhost_syncpt *sp, u32 id) { u32 val; BUG_ON(!syncpt_op(sp).read_wait_base); - nvhost_module_busy(&syncpt_to_dev(sp)->mod); + nvhost_module_busy(syncpt_to_dev(sp)->dev); syncpt_op(sp).read_wait_base(sp, id); val = sp->base_val[id]; - nvhost_module_idle(&syncpt_to_dev(sp)->mod); + nvhost_module_idle(syncpt_to_dev(sp)->dev); return val; } @@ -113,9 +113,9 @@ void nvhost_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id) void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id) { nvhost_syncpt_incr_max(sp, id, 1); - nvhost_module_busy(&syncpt_to_dev(sp)->mod); + nvhost_module_busy(syncpt_to_dev(sp)->dev); nvhost_syncpt_cpu_incr(sp, id); - nvhost_module_idle(&syncpt_to_dev(sp)->mod); + nvhost_module_idle(syncpt_to_dev(sp)->dev); } /** @@ -150,7 +150,7 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, } /* keep host alive */ - nvhost_module_busy(&syncpt_to_dev(sp)->mod); + nvhost_module_busy(syncpt_to_dev(sp)->dev); if (client_managed(id) || !nvhost_syncpt_min_eq_max(sp, id)) { /* try to read from register */ @@ -226,7 +226,7 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, nvhost_intr_put_ref(&(syncpt_to_dev(sp)->intr), ref); done: - nvhost_module_idle(&syncpt_to_dev(sp)->mod); + nvhost_module_idle(syncpt_to_dev(sp)->dev); return err; } diff --git a/drivers/video/tegra/host/t20/t20.c b/drivers/video/tegra/host/t20/t20.c index 510e0eb5f2df..6983f1cc3fbd 100644 --- a/drivers/video/tegra/host/t20/t20.c +++ b/drivers/video/tegra/host/t20/t20.c @@ -44,106 +44,90 @@ #define NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1) -static struct nvhost_device devices[] = { - {.name = "gr3d", .id = -1 }, - {.name = "gr2d", .id = -1 }, - {.name = "isp", .id = -1 }, - {.name = "vi", .id = -1 }, - {.name = "mpe", .id = -1 }, - {.name = "dsi", .id = -1 } -}; - -const struct nvhost_channeldesc nvhost_t20_channelmap[] = { +struct nvhost_device devices[] = { { /* channel 0 */ .name = "display", + .id = -1, .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) | BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) | BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) | BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1), .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB), - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 1 */ .name = "gr3d", + .id = -1, .syncpts = BIT(NVSYNCPT_3D), .waitbases = BIT(NVWAITBASE_3D), .modulemutexes = BIT(NVMODMUTEX_3D), .class = NV_GRAPHICS_3D_CLASS_ID, - .module = { - .prepare_poweroff = nvhost_gr3d_prepare_power_off, - .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} }, - .powergate_ids = {TEGRA_POWERGATE_3D, -1}, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + .prepare_poweroff = nvhost_gr3d_prepare_power_off, + .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} }, + .powergate_ids = {TEGRA_POWERGATE_3D, -1}, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 2 */ .name = "gr2d", + .id = -1, .syncpts = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1), .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1), .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) | BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B), - .module = { - .clocks = {{"gr2d", UINT_MAX} , - {"epp", UINT_MAX} , - {"emc", UINT_MAX} }, - NVHOST_MODULE_NO_POWERGATE_IDS, - .clockgate_delay = 0, - } + .clocks = {{"gr2d", UINT_MAX} , + {"epp", UINT_MAX} , + {"emc", UINT_MAX} }, + NVHOST_MODULE_NO_POWERGATE_IDS, + .clockgate_delay = 0, }, { /* channel 3 */ .name = "isp", + .id = -1, .syncpts = 0, - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 4 */ .name = "vi", + .id = -1, .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) | BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) | BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) | BIT(NVSYNCPT_VI_ISP_4), .modulemutexes = BIT(NVMODMUTEX_VI), .exclusive = true, - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - } + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 5 */ .name = "mpe", + .id = -1, .syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) | BIT(NVSYNCPT_MPE_WR_SAFE), .waitbases = BIT(NVWAITBASE_MPE), .class = NV_VIDEO_ENCODE_MPEG_CLASS_ID, .waitbasesync = true, .keepalive = true, - .module = { - .prepare_poweroff = nvhost_mpe_prepare_power_off, - .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} }, - .powergate_ids = {TEGRA_POWERGATE_MPE, -1}, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + .prepare_poweroff = nvhost_mpe_prepare_power_off, + .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} }, + .powergate_ids = {TEGRA_POWERGATE_MPE, -1}, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 6 */ .name = "dsi", + .id = -1, .syncpts = BIT(NVSYNCPT_DSI), .modulemutexes = BIT(NVMODMUTEX_DSI), - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, } }; static inline void __iomem *t20_channel_aperture(void __iomem *p, int ndx) @@ -167,15 +151,15 @@ static inline int t20_nvhost_hwctx_handler_init( static int t20_channel_init(struct nvhost_channel *ch, struct nvhost_master *dev, int index) { - ch->dev = dev; ch->chid = index; - ch->desc = nvhost_t20_channelmap + index; + ch->dev = &devices[index]; mutex_init(&ch->reflock); mutex_init(&ch->submitlock); + nvhost_device_register(ch->dev); ch->aperture = t20_channel_aperture(dev->aperture, index); - return t20_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->desc->name); + return t20_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->dev->name); } int nvhost_init_t20_channel_support(struct nvhost_master *host) @@ -193,10 +177,6 @@ int nvhost_init_t20_channel_support(struct nvhost_master *host) int nvhost_init_t20_support(struct nvhost_master *host) { int err; - int i; - - for (i = 0; i < ARRAY_SIZE(devices); i++) - nvhost_device_register(&devices[i]); /* don't worry about cleaning up on failure... "remove" does it. */ err = nvhost_init_t20_channel_support(host); diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c index 425b352a66a8..9347689812ba 100644 --- a/drivers/video/tegra/host/t30/t30.c +++ b/drivers/video/tegra/host/t30/t30.c @@ -34,15 +34,6 @@ #include "gr3d/scale3d.h" #include "../chip_support.h" -static struct nvhost_device devices[] = { - {.name = "gr3d", .id = -1 }, - {.name = "gr2d", .id = -1 }, - {.name = "isp", .id = -1 }, - {.name = "vi", .id = -1 }, - {.name = "mpe", .id = -1 }, - {.name = "dsi", .id = -1 }, -}; - #define NVMODMUTEX_2D_FULL (1) #define NVMODMUTEX_2D_SIMPLE (2) #define NVMODMUTEX_2D_SB_A (3) @@ -57,109 +48,102 @@ static struct nvhost_device devices[] = { #define TEGRA_POWERGATE_3D1 -1 #endif -const struct nvhost_channeldesc nvhost_t30_channelmap[] = { +static struct nvhost_device devices[] = { { /* channel 0 */ .name = "display", + .id = -1, .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) | BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) | BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) | BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1), .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB), - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 1 */ .name = "gr3d", + .id = -1, .syncpts = BIT(NVSYNCPT_3D), .waitbases = BIT(NVWAITBASE_3D), .modulemutexes = BIT(NVMODMUTEX_3D), .class = NV_GRAPHICS_3D_CLASS_ID, - .module = { - .prepare_poweroff = nvhost_gr3d_prepare_power_off, - .busy = nvhost_scale3d_notify_busy, - .idle = nvhost_scale3d_notify_idle, - .init = nvhost_scale3d_init, - .deinit = nvhost_scale3d_deinit, - .suspend = nvhost_scale3d_suspend, - .clocks = {{"gr3d", UINT_MAX}, - {"gr3d2", UINT_MAX}, - {"emc", UINT_MAX} }, - .powergate_ids = {TEGRA_POWERGATE_3D, - TEGRA_POWERGATE_3D1}, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - .can_powergate = true, - .powergate_delay = 100, - }, + .prepare_poweroff = nvhost_gr3d_prepare_power_off, + .busy = nvhost_scale3d_notify_busy, + .idle = nvhost_scale3d_notify_idle, + .init = nvhost_scale3d_init, + .deinit = nvhost_scale3d_deinit, + .suspend = nvhost_scale3d_suspend, + .clocks = {{"gr3d", UINT_MAX}, + {"gr3d2", UINT_MAX}, + {"emc", UINT_MAX} }, + .powergate_ids = {TEGRA_POWERGATE_3D, + TEGRA_POWERGATE_3D1}, + NVHOST_DEFAULT_CLOCKGATE_DELAY, + .can_powergate = true, + .powergate_delay = 100, }, { /* channel 2 */ .name = "gr2d", + .id = -1, .syncpts = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1), .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1), .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) | BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B), - .module = { - .clocks = {{"gr2d", 0}, - {"epp", 0}, - {"emc", 300000000} }, - NVHOST_MODULE_NO_POWERGATE_IDS, - .clockgate_delay = 0, - }, + .clocks = {{"gr2d", 0}, + {"epp", 0}, + {"emc", 300000000} }, + NVHOST_MODULE_NO_POWERGATE_IDS, + .clockgate_delay = 0, }, { /* channel 3 */ - .name = "isp", - .syncpts = 0, - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + .name = "isp", + .id = -1, + .syncpts = 0, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 4 */ .name = "vi", + .id = -1, .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) | BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) | BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) | BIT(NVSYNCPT_VI_ISP_4), .modulemutexes = BIT(NVMODMUTEX_VI), .exclusive = true, - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, }, { /* channel 5 */ .name = "mpe", + .id = -1, .syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) | BIT(NVSYNCPT_MPE_WR_SAFE), .waitbases = BIT(NVWAITBASE_MPE), .class = NV_VIDEO_ENCODE_MPEG_CLASS_ID, .waitbasesync = true, .keepalive = true, - .module = { - .prepare_poweroff = nvhost_mpe_prepare_power_off, - .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} }, - .powergate_ids = {TEGRA_POWERGATE_MPE, -1}, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - .can_powergate = true, - .powergate_delay = 100, - }, + .prepare_poweroff = nvhost_mpe_prepare_power_off, + .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} }, + .powergate_ids = {TEGRA_POWERGATE_MPE, -1}, + NVHOST_DEFAULT_CLOCKGATE_DELAY, + .can_powergate = true, + .powergate_delay = 100, }, { /* channel 6 */ .name = "dsi", + .id = -1, .syncpts = BIT(NVSYNCPT_DSI), .modulemutexes = BIT(NVMODMUTEX_DSI), - .module = { - NVHOST_MODULE_NO_POWERGATE_IDS, - NVHOST_DEFAULT_CLOCKGATE_DELAY, - }, + NVHOST_MODULE_NO_POWERGATE_IDS, + NVHOST_DEFAULT_CLOCKGATE_DELAY, } }; #define NVHOST_CHANNEL_BASE 0 @@ -187,15 +171,15 @@ static inline void __iomem *t30_channel_aperture(void __iomem *p, int ndx) static int t30_channel_init(struct nvhost_channel *ch, struct nvhost_master *dev, int index) { - ch->dev = dev; ch->chid = index; - ch->desc = nvhost_t30_channelmap + index; + ch->dev = &devices[index]; mutex_init(&ch->reflock); mutex_init(&ch->submitlock); + nvhost_device_register(ch->dev); ch->aperture = t30_channel_aperture(dev->aperture, index); - return t30_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->desc->name); + return t30_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->dev->name); } int nvhost_init_t30_channel_support(struct nvhost_master *host) @@ -216,10 +200,6 @@ int nvhost_init_t30_debug_support(struct nvhost_master *host) int nvhost_init_t30_support(struct nvhost_master *host) { int err; - int i; - - for (i = 0; i < ARRAY_SIZE(devices); i++) - nvhost_device_register(&devices[i]); /* don't worry about cleaning up on failure... "remove" does it. */ err = nvhost_init_t30_channel_support(host); diff --git a/include/linux/nvhost.h b/include/linux/nvhost.h index a1d211de1ef1..6b3c9e366f30 100644 --- a/include/linux/nvhost.h +++ b/include/linux/nvhost.h @@ -28,17 +28,75 @@ struct nvhost_master; +#define NVHOST_MODULE_MAX_CLOCKS 3 +#define NVHOST_MODULE_MAX_POWERGATE_IDS 2 +#define NVHOST_MODULE_NO_POWERGATE_IDS .powergate_ids = {-1, -1} +#define NVHOST_DEFAULT_CLOCKGATE_DELAY .clockgate_delay = 25 + +struct nvhost_clock { + char *name; + long default_rate; +}; + +enum nvhost_device_powerstate_t { + NVHOST_POWER_STATE_DEINIT, + NVHOST_POWER_STATE_RUNNING, + NVHOST_POWER_STATE_CLOCKGATED, + NVHOST_POWER_STATE_POWERGATED +}; + struct nvhost_device { - const char *name; - struct device dev; - int id; - u32 num_resources; - struct resource *resource; + const char *name; /* Device name */ + struct device dev; /* Linux device struct */ + int id; /* Separates clients of same hw */ + u32 num_resources; /* Number of resources following */ + struct resource *resource; /* Resources (IOMEM in particular) */ + + struct nvhost_master *host; /* Access to host1x resources */ + u32 syncpts; /* Bitfield of sync points used */ + u32 waitbases; /* Bit field of wait bases */ + u32 modulemutexes; /* Bit field of module mutexes */ + u32 class; /* Device class */ + bool exclusive; /* True if only one user at a time */ + bool keepalive; /* Do not power gate when opened */ + bool waitbasesync; /* Force sync of wait bases */ + + int powergate_ids[NVHOST_MODULE_MAX_POWERGATE_IDS]; + bool can_powergate; /* True if module can be power gated */ + int clockgate_delay;/* Delay before clock gated */ + int powergate_delay;/* Delay before power gated */ + struct nvhost_clock clocks[NVHOST_MODULE_MAX_CLOCKS];/* Clock names */ + + struct delayed_work powerstate_down;/* Power state management */ + int num_clks; /* Number of clocks opened for dev */ + struct clk *clk[NVHOST_MODULE_MAX_CLOCKS]; + struct mutex lock; /* Power management lock */ + int powerstate; /* Current power state */ + int refcount; /* Number of tasks active */ + wait_queue_head_t idle_wq; /* Work queue for idle */ + struct list_head client_list; /* List of clients and rate requests */ + + struct nvhost_channel *channel; /* Channel assigned for the module */ - struct nvhost_master *host; + /* Preparing for power off. Used for context save. */ + int (*prepare_poweroff)(struct nvhost_device *dev); + /* Finalize power on. Can be used for context restore. */ + void (*finalize_poweron)(struct nvhost_device *dev); + /* Device is busy. */ + void (*busy)(struct nvhost_device *); + /* Device is idle. */ + void (*idle)(struct nvhost_device *); + /* Device is going to be suspended */ + void (*suspend)(struct nvhost_device *); + /* Device is initialized */ + void (*init)(struct nvhost_device *dev); + /* Device is de-initialized. */ + void (*deinit)(struct nvhost_device *dev); }; +/* Register device to nvhost bus */ extern int nvhost_device_register(struct nvhost_device *); +/* Deregister device from nvhost bus */ extern void nvhost_device_unregister(struct nvhost_device *); extern struct bus_type nvhost_bus_type; @@ -68,6 +126,6 @@ extern int nvhost_get_irq_byname(struct nvhost_device *, const char *); #define nvhost_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) #define nvhost_set_drvdata(_dev, data) dev_set_drvdata(&(_dev)->dev, (data)) -int nvhost_bus_register(struct nvhost_master *host); +int nvhost_bus_add_host(struct nvhost_master *host); #endif |