summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/board-aruba-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-harmony-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-kai-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-p1852-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-ventana-panel.c3
-rw-r--r--arch/arm/mach-tegra/board-whistler-panel.c3
-rw-r--r--arch/arm/mach-tegra/devices.h1
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-panel.c3
-rw-r--r--arch/arm/mach-tegra/tegra2_host1x_devices.h26
-rw-r--r--arch/arm/mach-tegra/tegra3_host1x_devices.h26
-rw-r--r--drivers/video/tegra/Makefile1
-rw-r--r--drivers/video/tegra/host/bus.c17
-rw-r--r--drivers/video/tegra/host/chip_support.h1
-rw-r--r--drivers/video/tegra/host/dev.c546
-rw-r--r--drivers/video/tegra/host/dev.h45
-rw-r--r--drivers/video/tegra/host/gr2d/gr2d.c12
-rw-r--r--drivers/video/tegra/host/gr3d/gr3d.c22
-rw-r--r--drivers/video/tegra/host/gr3d/gr3d_t20.c2
-rw-r--r--drivers/video/tegra/host/host1x/Makefile1
-rw-r--r--drivers/video/tegra/host/host1x/host1x.c563
-rw-r--r--drivers/video/tegra/host/host1x/host1x.h63
-rw-r--r--drivers/video/tegra/host/host1x/host1x_syncpt.c2
-rw-r--r--drivers/video/tegra/host/host1x/host1x_syncpt.h7
-rw-r--r--drivers/video/tegra/host/isp/isp.c25
-rw-r--r--drivers/video/tegra/host/mpe/mpe.c26
-rw-r--r--drivers/video/tegra/host/t20/t20.c112
-rw-r--r--drivers/video/tegra/host/t30/t30.c123
-rw-r--r--drivers/video/tegra/host/vi/vi.c25
-rw-r--r--include/linux/nvhost.h3
31 files changed, 879 insertions, 797 deletions
diff --git a/arch/arm/mach-tegra/board-aruba-panel.c b/arch/arm/mach-tegra/board-aruba-panel.c
index 0e24a4375c99..01ade01a0eb6 100644
--- a/arch/arm/mach-tegra/board-aruba-panel.c
+++ b/arch/arm/mach-tegra/board-aruba-panel.c
@@ -35,6 +35,7 @@
#include "board.h"
#include "devices.h"
#include "gpio-names.h"
+#include "tegra2_host1x_devices.h"
#define aruba_lvds_shutdown TEGRA_GPIO_PB2
#define aruba_bl_enb TEGRA_GPIO_PW1
@@ -228,7 +229,7 @@ int __init aruba_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra2_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c
index 4a5f8548f0dd..2a9e5201061a 100644
--- a/arch/arm/mach-tegra/board-cardhu-panel.c
+++ b/arch/arm/mach-tegra/board-cardhu-panel.c
@@ -41,6 +41,7 @@
#include "board-cardhu.h"
#include "devices.h"
#include "gpio-names.h"
+#include "tegra3_host1x_devices.h"
#define DC_CTRL_MODE TEGRA_DC_OUT_ONE_SHOT_MODE
@@ -1385,7 +1386,7 @@ skip_lvds:
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra3_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
index 8876c8ebf88e..7043916921d0 100644
--- a/arch/arm/mach-tegra/board-enterprise-panel.c
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -39,6 +39,7 @@
#include "board-enterprise.h"
#include "devices.h"
#include "gpio-names.h"
+#include "tegra3_host1x_devices.h"
#define DC_CTRL_MODE TEGRA_DC_OUT_ONE_SHOT_MODE
@@ -885,7 +886,7 @@ int __init enterprise_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra3_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c
index 9c3d296dd8d3..d4cd3f461b66 100644
--- a/arch/arm/mach-tegra/board-harmony-panel.c
+++ b/arch/arm/mach-tegra/board-harmony-panel.c
@@ -33,6 +33,7 @@
#include "devices.h"
#include "gpio-names.h"
#include "board.h"
+#include "tegra2_host1x_devices.h"
#define harmony_bl_enb TEGRA_GPIO_PB5
#define harmony_lvds_shutdown TEGRA_GPIO_PB2
@@ -356,7 +357,7 @@ int __init harmony_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra2_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-kai-panel.c b/arch/arm/mach-tegra/board-kai-panel.c
index 45333840ffb7..e6ac6dd82846 100644
--- a/arch/arm/mach-tegra/board-kai-panel.c
+++ b/arch/arm/mach-tegra/board-kai-panel.c
@@ -37,6 +37,7 @@
#include "board-kai.h"
#include "devices.h"
#include "gpio-names.h"
+#include "tegra3_host1x_devices.h"
/* kai default display board pins */
#define kai_lvds_avdd_en TEGRA_GPIO_PH6
@@ -681,7 +682,7 @@ int __init kai_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra3_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-p1852-panel.c b/arch/arm/mach-tegra/board-p1852-panel.c
index c104b913518e..4e86476cdd2c 100644
--- a/arch/arm/mach-tegra/board-p1852-panel.c
+++ b/arch/arm/mach-tegra/board-p1852-panel.c
@@ -28,6 +28,7 @@
#include "board.h"
#include "devices.h"
+#include "tegra3_host1x_devices.h"
static int p1852_panel_enable(void)
{
@@ -185,7 +186,7 @@ int __init p1852_panel_init(void)
res->end = tegra_fb_start + tegra_fb_size - 1;
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra3_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c
index 437969261b22..a9e7a67f2bb1 100644
--- a/arch/arm/mach-tegra/board-ventana-panel.c
+++ b/arch/arm/mach-tegra/board-ventana-panel.c
@@ -36,6 +36,7 @@
#include "devices.h"
#include "gpio-names.h"
#include "board.h"
+#include "tegra2_host1x_devices.h"
#define ventana_bl_enb TEGRA_GPIO_PD4
#define ventana_lvds_shutdown TEGRA_GPIO_PB2
@@ -411,7 +412,7 @@ int __init ventana_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra2_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/board-whistler-panel.c b/arch/arm/mach-tegra/board-whistler-panel.c
index d171cf008a77..3510f9468394 100644
--- a/arch/arm/mach-tegra/board-whistler-panel.c
+++ b/arch/arm/mach-tegra/board-whistler-panel.c
@@ -38,6 +38,7 @@
#include "devices.h"
#include "gpio-names.h"
#include "board.h"
+#include "tegra2_host1x_devices.h"
#define whistler_hdmi_hpd TEGRA_GPIO_PN7
@@ -361,7 +362,7 @@ int __init whistler_panel_init(void)
#endif
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra2_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 3d0734d1c688..1ee723534476 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -109,7 +109,6 @@ extern struct platform_device tegra_uartc_device;
extern struct platform_device tegra_uartd_device;
extern struct platform_device tegra_uarte_device;
extern struct platform_device tegra_avp_device;
-extern struct nvhost_device tegra_grhost_device;
extern struct nvhost_device nvavp_device;
extern struct platform_device tegra_aes_device;
#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
diff --git a/arch/arm/mach-tegra/p852/board-p852-panel.c b/arch/arm/mach-tegra/p852/board-p852-panel.c
index bcf9f4af76cf..8ed62f039dc8 100644
--- a/arch/arm/mach-tegra/p852/board-p852-panel.c
+++ b/arch/arm/mach-tegra/p852/board-p852-panel.c
@@ -32,6 +32,7 @@
#include <mach/fb.h>
#include "board-p852.h"
+#include "../tegra2_host1x_devices.h"
#define CARVEOUT_IRAM {\
.name = "iram",\
@@ -175,7 +176,7 @@ int __init p852_panel_init(void)
return err;
#ifdef CONFIG_TEGRA_GRHOST
- err = nvhost_device_register(&tegra_grhost_device);
+ err = tegra2_register_host1x_devices();
if (err)
return err;
#endif
diff --git a/arch/arm/mach-tegra/tegra2_host1x_devices.h b/arch/arm/mach-tegra/tegra2_host1x_devices.h
new file mode 100644
index 000000000000..974154a414dd
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_host1x_devices.h
@@ -0,0 +1,26 @@
+/*
+ * drivers/video/tegra/host/tegra2_host1x_devices.h
+ *
+ * Tegra2 Graphics Host Devices
+ *
+ * Copyright (c) 2012, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEGRA2_HOST1X_DEVICES_H
+#define TEGRA2_HOST1X_DEVICES_H
+
+int tegra2_register_host1x_devices(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra3_host1x_devices.h b/arch/arm/mach-tegra/tegra3_host1x_devices.h
new file mode 100644
index 000000000000..38a5eabf037f
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_host1x_devices.h
@@ -0,0 +1,26 @@
+/*
+ * drivers/video/tegra/host/tegra3_host1x_devices.h
+ *
+ * Tegra3 Graphics Host Devices
+ *
+ * Copyright (c) 2012, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEGRA3_HOST1X_DEVICES_H
+#define TEGRA3_HOST1X_DEVICES_H
+
+int tegra3_register_host1x_devices(void);
+
+#endif
diff --git a/drivers/video/tegra/Makefile b/drivers/video/tegra/Makefile
index 2299a3c5eaa3..104b161cc3db 100644
--- a/drivers/video/tegra/Makefile
+++ b/drivers/video/tegra/Makefile
@@ -1,4 +1,5 @@
GCOV_PROFILE := y
+EXTRA_CFLAGS += -Idrivers/video/tegra/host
obj-$(CONFIG_TEGRA_GRHOST) += host/
obj-$(CONFIG_TEGRA_DC) += dc/
obj-$(CONFIG_FB_TEGRA) += fb.o
diff --git a/drivers/video/tegra/host/bus.c b/drivers/video/tegra/host/bus.c
index e59dc4153b14..3b769f41170d 100644
--- a/drivers/video/tegra/host/bus.c
+++ b/drivers/video/tegra/host/bus.c
@@ -149,6 +149,23 @@ void nvhost_driver_unregister(struct nvhost_driver *drv)
}
EXPORT_SYMBOL_GPL(nvhost_driver_unregister);
+int nvhost_add_devices(struct nvhost_device **devs, int num)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < num; i++) {
+ ret = nvhost_device_register(devs[i]);
+ if (ret) {
+ while (--i >= 0)
+ nvhost_device_unregister(devs[i]);
+ break;
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(nvhost_add_devices);
+
int nvhost_device_register(struct nvhost_device *dev)
{
int i, ret = 0;
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index 33fd92eb31c8..6d378183e6e5 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -128,7 +128,6 @@ struct nvhost_chip_support {
} intr;
struct {
- struct nvhost_device *(*get_nvhost_device)(char *name);
struct nvhost_channel *(*alloc_nvhost_channel)(int chid);
void (*free_nvhost_channel)(struct nvhost_channel *ch);
} nvhost_dev;
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 5c1e39da72cf..b3afc6e4d1e4 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -18,561 +18,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include <linux/file.h>
-#include <linux/clk.h>
-#include <linux/hrtimer.h>
-
-#include "dev.h"
#define CREATE_TRACE_POINTS
#include <trace/events/nvhost.h>
-#include <linux/io.h>
-
#include <linux/nvhost.h>
-#include <linux/nvhost_ioctl.h>
#include <mach/gpufuse.h>
-#include <mach/hardware.h>
-#include <mach/iomap.h>
-
-#include "debug.h"
-#include "t20/t20.h"
-#include "t30/t30.h"
-#include "bus_client.h"
-#include "nvhost_acm.h"
-#include "nvhost_channel.h"
-#include "nvhost_job.h"
-#include "nvhost_memmgr.h"
-#include "chip_support.h"
-
-#define DRIVER_NAME "host1x"
static unsigned int register_sets;
-struct nvhost_ctrl_userctx {
- struct nvhost_master *dev;
- u32 *mod_locks;
-};
-
-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->dev->name);
-
- filp->private_data = NULL;
- if (priv->mod_locks[0])
- nvhost_module_idle(priv->dev->dev);
- for (i = 1; i < priv->dev->syncpt.nb_mlocks; i++)
- if (priv->mod_locks[i])
- nvhost_mutex_unlock(&priv->dev->syncpt, i);
- kfree(priv->mod_locks);
- kfree(priv);
- return 0;
-}
-
-static int nvhost_ctrlopen(struct inode *inode, struct file *filp)
-{
- struct nvhost_master *host =
- container_of(inode->i_cdev, struct nvhost_master, cdev);
- struct nvhost_ctrl_userctx *priv;
- u32 *mod_locks;
-
- trace_nvhost_ctrlopen(host->dev->name);
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- mod_locks = kzalloc(sizeof(u32) * host->syncpt.nb_mlocks, GFP_KERNEL);
-
- if (!(priv && mod_locks)) {
- kfree(priv);
- kfree(mod_locks);
- return -ENOMEM;
- }
-
- priv->dev = host;
- priv->mod_locks = mod_locks;
- filp->private_data = priv;
- return 0;
-}
-
-static int nvhost_ioctl_ctrl_syncpt_read(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_ctrl_syncpt_read_args *args)
-{
- if (args->id >= ctx->dev->syncpt.nb_pts)
- return -EINVAL;
- args->value = nvhost_syncpt_read(&ctx->dev->syncpt, args->id);
- trace_nvhost_ioctl_ctrl_syncpt_read(args->id, args->value);
- return 0;
-}
-
-static int nvhost_ioctl_ctrl_syncpt_incr(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_ctrl_syncpt_incr_args *args)
-{
- if (args->id >= ctx->dev->syncpt.nb_pts)
- return -EINVAL;
- trace_nvhost_ioctl_ctrl_syncpt_incr(args->id);
- nvhost_syncpt_incr(&ctx->dev->syncpt, args->id);
- return 0;
-}
-
-static int nvhost_ioctl_ctrl_syncpt_waitex(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_ctrl_syncpt_waitex_args *args)
-{
- u32 timeout;
- int err;
- if (args->id >= ctx->dev->syncpt.nb_pts)
- return -EINVAL;
- if (args->timeout == NVHOST_NO_TIMEOUT)
- timeout = MAX_SCHEDULE_TIMEOUT;
- else
- timeout = (u32)msecs_to_jiffies(args->timeout);
-
- err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
- args->thresh, timeout, &args->value);
- trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
- args->timeout, args->value, err);
-
- return err;
-}
-
-static int nvhost_ioctl_ctrl_module_mutex(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_ctrl_module_mutex_args *args)
-{
- int err = 0;
- if (args->id >= ctx->dev->syncpt.nb_mlocks ||
- args->lock > 1)
- return -EINVAL;
-
- 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->dev);
- else
- err = nvhost_mutex_try_lock(&ctx->dev->syncpt,
- 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->dev);
- else
- nvhost_mutex_unlock(&ctx->dev->syncpt, args->id);
- ctx->mod_locks[args->id] = 0;
- }
- return err;
-}
-
-static int match_by_moduleid(struct device *dev, void *data)
-{
- struct nvhost_device *ndev = to_nvhost_device(dev);
- u32 id = (u32)data;
-
- return id == ndev->moduleid;
-}
-
-static struct nvhost_device *get_ndev_by_moduleid(struct nvhost_master *host,
- u32 id)
-{
- struct device *dev = bus_find_device(&nvhost_bus_inst->nvhost_bus_type, NULL, (void *)id,
- match_by_moduleid);
-
- return dev ? to_nvhost_device(dev) : NULL;
-}
-
-static int nvhost_ioctl_ctrl_module_regrdwr(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_ctrl_module_regrdwr_args *args)
-{
- u32 num_offsets = args->num_offsets;
- u32 *offsets = args->offsets;
- u32 *values = args->values;
- u32 vals[64];
- struct nvhost_device *ndev;
-
- trace_nvhost_ioctl_ctrl_module_regrdwr(args->id,
- args->num_offsets, args->write);
- /* Check that there is something to read and that block size is
- * u32 aligned */
- if (num_offsets == 0 || args->block_size & 3)
- return -EINVAL;
-
- ndev = get_ndev_by_moduleid(ctx->dev, args->id);
- if (!ndev)
- return -EINVAL;
-
- while (num_offsets--) {
- int err;
- int remaining = args->block_size >> 2;
- u32 offs;
- if (get_user(offs, offsets))
- return -EFAULT;
- offsets++;
- while (remaining) {
- int batch = min(remaining, 64);
- if (args->write) {
- if (copy_from_user(vals, values,
- batch*sizeof(u32)))
- return -EFAULT;
- err = nvhost_write_module_regs(ndev,
- offs, batch, vals);
- if (err)
- return err;
- } else {
- err = nvhost_read_module_regs(ndev,
- offs, batch, vals);
- if (err)
- return err;
- if (copy_to_user(values, vals,
- batch*sizeof(u32)))
- return -EFAULT;
- }
- remaining -= batch;
- offs += batch*sizeof(u32);
- values += batch;
- }
- }
-
- return 0;
-}
-
-static int nvhost_ioctl_ctrl_get_version(struct nvhost_ctrl_userctx *ctx,
- struct nvhost_get_param_args *args)
-{
- args->value = NVHOST_SUBMIT_VERSION_MAX_SUPPORTED;
- return 0;
-}
-
-static long nvhost_ctrlctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct nvhost_ctrl_userctx *priv = filp->private_data;
- u8 buf[NVHOST_IOCTL_CTRL_MAX_ARG_SIZE];
- int err = 0;
-
- if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) ||
- (_IOC_NR(cmd) == 0) ||
- (_IOC_NR(cmd) > NVHOST_IOCTL_CTRL_LAST) ||
- (_IOC_SIZE(cmd) > NVHOST_IOCTL_CTRL_MAX_ARG_SIZE))
- return -EFAULT;
-
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd)))
- return -EFAULT;
- }
-
- switch (cmd) {
- case NVHOST_IOCTL_CTRL_SYNCPT_READ:
- err = nvhost_ioctl_ctrl_syncpt_read(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_SYNCPT_INCR:
- err = nvhost_ioctl_ctrl_syncpt_incr(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_SYNCPT_WAIT:
- err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_MODULE_MUTEX:
- err = nvhost_ioctl_ctrl_module_mutex(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_MODULE_REGRDWR:
- err = nvhost_ioctl_ctrl_module_regrdwr(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_SYNCPT_WAITEX:
- err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
- break;
- case NVHOST_IOCTL_CTRL_GET_VERSION:
- err = nvhost_ioctl_ctrl_get_version(priv, (void *)buf);
- break;
- default:
- err = -ENOTTY;
- break;
- }
-
- if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ))
- err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd));
-
- return err;
-}
-
-static const struct file_operations nvhost_ctrlops = {
- .owner = THIS_MODULE,
- .release = nvhost_ctrlrelease,
- .open = nvhost_ctrlopen,
- .unlocked_ioctl = nvhost_ctrlctl
-};
-
-static void power_on_host(struct nvhost_device *dev)
-{
- struct nvhost_master *host = nvhost_get_drvdata(dev);
- nvhost_syncpt_reset(&host->syncpt);
- nvhost_intr_start(&host->intr, clk_get_rate(dev->clk[0]));
-}
-
-static int power_off_host(struct nvhost_device *dev)
-{
- struct nvhost_master *host = nvhost_get_drvdata(dev);
- nvhost_syncpt_save(&host->syncpt);
- nvhost_intr_stop(&host->intr);
- return 0;
-}
-
-static int __devinit nvhost_user_init(struct nvhost_master *host)
+void nvhost_set_register_sets(unsigned int r)
{
- int err, devno;
-
- host->nvhost_class = class_create(THIS_MODULE, IFACE_NAME);
- if (IS_ERR(host->nvhost_class)) {
- err = PTR_ERR(host->nvhost_class);
- dev_err(&host->dev->dev, "failed to create class\n");
- goto fail;
- }
-
- err = alloc_chrdev_region(&devno, 0, 1, IFACE_NAME);
- if (err < 0) {
- dev_err(&host->dev->dev, "failed to reserve chrdev region\n");
- goto fail;
- }
-
- cdev_init(&host->cdev, &nvhost_ctrlops);
- host->cdev.owner = THIS_MODULE;
- err = cdev_add(&host->cdev, devno, 1);
- if (err < 0)
- goto fail;
- host->ctrl = device_create(host->nvhost_class, NULL, devno, NULL,
- IFACE_NAME "-ctrl");
- if (IS_ERR(host->ctrl)) {
- err = PTR_ERR(host->ctrl);
- dev_err(&host->dev->dev, "failed to create ctrl device\n");
- goto fail;
- }
-
- return 0;
-fail:
- return err;
+ register_sets = r;
}
-struct nvhost_device *nvhost_get_device(char *name)
-{
- BUG_ON(!host_device_op().get_nvhost_device);
- return host_device_op().get_nvhost_device(name);
-}
-
-struct nvhost_channel *nvhost_alloc_channel(int index)
-{
- BUG_ON(!host_device_op().alloc_nvhost_channel);
- return host_device_op().alloc_nvhost_channel(index);
-}
-
-void nvhost_free_channel(struct nvhost_channel *ch)
-{
- BUG_ON(!host_device_op().free_nvhost_channel);
- host_device_op().free_nvhost_channel(ch);
-}
-
-static void nvhost_free_resources(struct nvhost_master *host)
-{
- kfree(host->intr.syncpt);
- host->intr.syncpt = 0;
-}
-
-static int __devinit nvhost_alloc_resources(struct nvhost_master *host)
-{
- int err;
-
- err = nvhost_init_chip_support(host);
- if (err)
- return err;
-
- host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
- host->syncpt.nb_pts, GFP_KERNEL);
-
- if (!host->intr.syncpt) {
- /* frees happen in the support removal phase */
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static struct resource nvhost_resources[] = {
- {
- .start = TEGRA_HOST1X_BASE,
- .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_SYNCPT_THRESH_BASE,
- .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = INT_HOST1X_MPCORE_GENERAL,
- .end = INT_HOST1X_MPCORE_GENERAL,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct nvhost_device tegra_grhost_device = {
- .name = DRIVER_NAME,
- .id = -1,
- .resource = nvhost_resources,
- .num_resources = ARRAY_SIZE(nvhost_resources),
- .clocks = {{"host1x", UINT_MAX}, {} },
- NVHOST_MODULE_NO_POWERGATE_IDS,
-};
-
-static int __devinit nvhost_probe(struct nvhost_device *dev,
- struct nvhost_device_id *id_table)
-{
- struct nvhost_master *host;
- struct resource *regs, *intr0, *intr1;
- int i, err;
-
- regs = nvhost_get_resource(dev, IORESOURCE_MEM, 0);
- intr0 = nvhost_get_resource(dev, IORESOURCE_IRQ, 0);
- intr1 = nvhost_get_resource(dev, IORESOURCE_IRQ, 1);
-
- if (!regs || !intr0 || !intr1) {
- dev_err(&dev->dev, "missing required platform resources\n");
- return -ENXIO;
- }
-
- host = kzalloc(sizeof(*host), GFP_KERNEL);
- if (!host)
- return -ENOMEM;
-
- host->reg_mem = request_mem_region(regs->start,
- resource_size(regs), dev->name);
- if (!host->reg_mem) {
- dev_err(&dev->dev, "failed to get host register memory\n");
- err = -ENXIO;
- goto fail;
- }
-
- host->aperture = ioremap(regs->start, resource_size(regs));
- if (!host->aperture) {
- dev_err(&dev->dev, "failed to remap host registers\n");
- err = -ENXIO;
- goto fail;
- }
-
- err = nvhost_alloc_resources(host);
- if (err) {
- dev_err(&dev->dev, "failed to init chip support\n");
- goto fail;
- }
-
- host->memmgr = mem_op().alloc_mgr();
- if (!host->memmgr) {
- dev_err(&dev->dev, "unable to create nvmap client\n");
- err = -EIO;
- goto fail;
- }
-
- /* Register host1x device as bus master */
- host->dev = dev;
-
- /* Give pointer to host1x via driver */
- nvhost_set_drvdata(dev, host);
-
- nvhost_bus_add_host(host);
-
- err = nvhost_syncpt_init(&tegra_grhost_device, &host->syncpt);
- if (err)
- goto fail;
-
- err = nvhost_intr_init(&host->intr, intr1->start, intr0->start);
- if (err)
- goto fail;
-
- err = nvhost_user_init(host);
- if (err)
- goto fail;
-
- err = nvhost_module_init(&tegra_grhost_device);
- if (err)
- goto fail;
-
- for (i = 0; i < host->dev->num_clks; i++)
- clk_enable(host->dev->clk[i]);
- nvhost_syncpt_reset(&host->syncpt);
- for (i = 0; i < host->dev->num_clks; i++)
- clk_disable(host->dev->clk[0]);
-
- nvhost_debug_init(host);
-
- dev_info(&dev->dev, "initialized\n");
- return 0;
-
-fail:
- nvhost_free_resources(host);
- if (host->memmgr)
- mem_op().put_mgr(host->memmgr);
- kfree(host);
- return err;
-}
-
-static int __exit nvhost_remove(struct nvhost_device *dev)
-{
- struct nvhost_master *host = nvhost_get_drvdata(dev);
- nvhost_intr_deinit(&host->intr);
- nvhost_syncpt_deinit(&host->syncpt);
- nvhost_free_resources(host);
- return 0;
-}
-
-static int nvhost_suspend(struct nvhost_device *dev, pm_message_t state)
-{
- struct nvhost_master *host = nvhost_get_drvdata(dev);
- int ret = 0;
-
- ret = nvhost_module_suspend(host->dev);
- dev_info(&dev->dev, "suspend status: %d\n", ret);
-
- return ret;
-}
-
-static int nvhost_resume(struct nvhost_device *dev)
-{
- dev_info(&dev->dev, "resuming\n");
- return 0;
-}
-
-static struct nvhost_driver nvhost_driver = {
- .probe = nvhost_probe,
- .remove = __exit_p(nvhost_remove),
- .suspend = nvhost_suspend,
- .resume = nvhost_resume,
- .driver = {
- .owner = THIS_MODULE,
- .name = DRIVER_NAME
- },
- .finalize_poweron = power_on_host,
- .prepare_poweroff = power_off_host,
-};
-
-static int __init nvhost_mod_init(void)
-{
- register_sets = tegra_gpu_register_sets();
- return nvhost_driver_register(&nvhost_driver);
-}
-
-static void __exit nvhost_mod_exit(void)
-{
- nvhost_driver_unregister(&nvhost_driver);
-}
-
-/* host1x master device needs nvmap to be instantiated first.
- * nvmap is instantiated via fs_initcall.
- * Hence instantiate host1x master device using rootfs_initcall
- * which is one level after fs_initcall. */
-rootfs_initcall(nvhost_mod_init);
-module_exit(nvhost_mod_exit);
-
module_param_call(register_sets, NULL, param_get_uint, &register_sets, 0444);
MODULE_PARM_DESC(register_sets, "Number of register sets");
diff --git a/drivers/video/tegra/host/dev.h b/drivers/video/tegra/host/dev.h
index 332c99924b27..ce32ce498d4c 100644
--- a/drivers/video/tegra/host/dev.h
+++ b/drivers/video/tegra/host/dev.h
@@ -1,9 +1,7 @@
/*
* drivers/video/tegra/host/dev.h
*
- * Tegra Graphics Host Driver Entrypoint
- *
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -18,43 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __NVHOST_DEV_H
-#define __NVHOST_DEV_H
-
-#include <linux/cdev.h>
-#include "nvhost_syncpt.h"
-#include "nvhost_intr.h"
-
-#define TRACE_MAX_LENGTH 128U
-#define IFACE_NAME "nvhost"
-
-struct nvhost_hwctx;
-struct nvhost_channel;
-struct mem_mgr;
-
-struct nvhost_master {
- void __iomem *aperture;
- void __iomem *sync_aperture;
- struct resource *reg_mem;
- struct class *nvhost_class;
- struct cdev cdev;
- struct device *ctrl;
- struct nvhost_syncpt syncpt;
- struct mem_mgr *memmgr;
- struct nvhost_intr intr;
- struct nvhost_device *dev;
- atomic_t clientid;
-};
-
-extern struct nvhost_master *nvhost;
-
-void nvhost_debug_init(struct nvhost_master *master);
-void nvhost_debug_dump(struct nvhost_master *master);
-
-struct nvhost_device *nvhost_get_device(char *name);
-struct nvhost_channel *nvhost_alloc_channel(int index);
-void nvhost_free_channel(struct nvhost_channel *ch);
+#ifndef NVHOST_DEV_H
+#define NVHOST_DEV_H
-extern pid_t nvhost_debug_null_kickoff_pid;
+#include "host1x/host1x.h"
+void nvhost_set_register_sets(unsigned int r);
#endif
diff --git a/drivers/video/tegra/host/gr2d/gr2d.c b/drivers/video/tegra/host/gr2d/gr2d.c
index c91a3aa23714..1bbfcdd8b587 100644
--- a/drivers/video/tegra/host/gr2d/gr2d.c
+++ b/drivers/video/tegra/host/gr2d/gr2d.c
@@ -44,8 +44,6 @@ static int gr2d_resume(struct nvhost_device *dev)
return 0;
}
-struct nvhost_device *gr2d_device;
-
static struct nvhost_driver gr2d_driver = {
.probe = gr2d_probe,
.remove = __exit_p(gr2d_remove),
@@ -61,16 +59,6 @@ static struct nvhost_driver gr2d_driver = {
static int __init gr2d_init(void)
{
- int err;
-
- gr2d_device = nvhost_get_device("gr2d");
- if (!gr2d_device)
- return -ENXIO;
-
- err = nvhost_device_register(gr2d_device);
- if (err)
- return err;
-
return nvhost_driver_register(&gr2d_driver);
}
diff --git a/drivers/video/tegra/host/gr3d/gr3d.c b/drivers/video/tegra/host/gr3d/gr3d.c
index 3208ba452bff..d586e26f104d 100644
--- a/drivers/video/tegra/host/gr3d/gr3d.c
+++ b/drivers/video/tegra/host/gr3d/gr3d.c
@@ -19,6 +19,7 @@
*/
#include <linux/slab.h>
+#include <mach/gpufuse.h>
#include "t20/t20.h"
#include "host1x/host1x_channel.h"
@@ -35,12 +36,6 @@
#include "nvhost_memmgr.h"
#include "chip_support.h"
-#include <mach/hardware.h>
-
-#ifndef TEGRA_POWERGATE_3D1
-#define TEGRA_POWERGATE_3D1 -1
-#endif
-
void nvhost_3dctx_restore_begin(struct host1x_hwctx_handler *p, u32 *ptr)
{
/* set class to host */
@@ -224,6 +219,7 @@ static int __devinit gr3d_probe(struct nvhost_device *dev,
* found in clock tree */
dev->name = "gr3d";
+ nvhost_set_register_sets(tegra_gpu_register_sets());
return nvhost_client_device_init(dev);
}
@@ -244,8 +240,6 @@ static int gr3d_resume(struct nvhost_device *dev)
return 0;
}
-struct nvhost_device *gr3d_device;
-
static struct nvhost_driver gr3d_driver = {
.probe = gr3d_probe,
.remove = __exit_p(gr3d_remove),
@@ -262,18 +256,6 @@ static struct nvhost_driver gr3d_driver = {
static int __init gr3d_init(void)
{
- int err;
-
- gr3d_device = nvhost_get_device("gr3d");
- if (!gr3d_device)
- return -ENXIO;
-
- err = nvhost_device_register(gr3d_device);
- if (err) {
- pr_err("Could not register 3D device\n");
- return err;
- }
-
return nvhost_driver_register(&gr3d_driver);
}
diff --git a/drivers/video/tegra/host/gr3d/gr3d_t20.c b/drivers/video/tegra/host/gr3d/gr3d_t20.c
index baa27051c794..272c955d7e7f 100644
--- a/drivers/video/tegra/host/gr3d/gr3d_t20.c
+++ b/drivers/video/tegra/host/gr3d/gr3d_t20.c
@@ -20,7 +20,7 @@
#include "nvhost_hwctx.h"
#include "nvhost_channel.h"
-#include "dev.h"
+#include "host1x/host1x.h"
#include "host1x/host1x_channel.h"
#include "host1x/host1x_hardware.h"
#include "host1x/host1x_syncpt.h"
diff --git a/drivers/video/tegra/host/host1x/Makefile b/drivers/video/tegra/host/host1x/Makefile
index c3214ffe147b..55fcb375709a 100644
--- a/drivers/video/tegra/host/host1x/Makefile
+++ b/drivers/video/tegra/host/host1x/Makefile
@@ -3,6 +3,7 @@ GCOV_PROFILE := y
EXTRA_CFLAGS += -Idrivers/video/tegra/host
nvhost-host1x-objs = \
+ host1x.o \
host1x_syncpt.o \
host1x_channel.o \
host1x_intr.o \
diff --git a/drivers/video/tegra/host/host1x/host1x.c b/drivers/video/tegra/host/host1x/host1x.c
new file mode 100644
index 000000000000..d203bc73a67d
--- /dev/null
+++ b/drivers/video/tegra/host/host1x/host1x.c
@@ -0,0 +1,563 @@
+/*
+ * drivers/video/tegra/host/dev.c
+ *
+ * Tegra Graphics Host Driver Entrypoint
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/file.h>
+#include <linux/clk.h>
+#include <linux/hrtimer.h>
+
+#include "dev.h"
+#include "bus.h"
+#include <trace/events/nvhost.h>
+
+#include <linux/io.h>
+
+#include <linux/nvhost.h>
+#include <linux/nvhost_ioctl.h>
+#include <mach/hardware.h>
+#include <mach/iomap.h>
+
+#include "debug.h"
+#include "t20/t20.h"
+#include "t30/t30.h"
+#include "bus_client.h"
+#include "nvhost_acm.h"
+#include "nvhost_channel.h"
+#include "nvhost_job.h"
+
+#define DRIVER_NAME "host1x"
+
+static struct resource tegra_host1x01_resources[] = {
+ {
+ .start = TEGRA_HOST1X_BASE,
+ .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SYNCPT_THRESH_BASE,
+ .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_HOST1X_MPCORE_GENERAL,
+ .end = INT_HOST1X_MPCORE_GENERAL,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct nvhost_device tegra_host1x01_device = {
+ .name = "host1x",
+ .id = -1,
+ .resource = tegra_host1x01_resources,
+ .num_resources = ARRAY_SIZE(tegra_host1x01_resources),
+ .clocks = {{"host1x", UINT_MAX}, {} },
+ NVHOST_MODULE_NO_POWERGATE_IDS,
+};
+
+struct nvhost_ctrl_userctx {
+ struct nvhost_master *dev;
+ u32 *mod_locks;
+};
+
+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->dev->name);
+
+ filp->private_data = NULL;
+ if (priv->mod_locks[0])
+ nvhost_module_idle(priv->dev->dev);
+ for (i = 1; i < priv->dev->syncpt.nb_mlocks; i++)
+ if (priv->mod_locks[i])
+ nvhost_mutex_unlock(&priv->dev->syncpt, i);
+ kfree(priv->mod_locks);
+ kfree(priv);
+ return 0;
+}
+
+static int nvhost_ctrlopen(struct inode *inode, struct file *filp)
+{
+ struct nvhost_master *host =
+ container_of(inode->i_cdev, struct nvhost_master, cdev);
+ struct nvhost_ctrl_userctx *priv;
+ u32 *mod_locks;
+
+ trace_nvhost_ctrlopen(host->dev->name);
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ mod_locks = kzalloc(sizeof(u32) * host->syncpt.nb_mlocks, GFP_KERNEL);
+
+ if (!(priv && mod_locks)) {
+ kfree(priv);
+ kfree(mod_locks);
+ return -ENOMEM;
+ }
+
+ priv->dev = host;
+ priv->mod_locks = mod_locks;
+ filp->private_data = priv;
+ return 0;
+}
+
+static int nvhost_ioctl_ctrl_syncpt_read(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_ctrl_syncpt_read_args *args)
+{
+ if (args->id >= ctx->dev->syncpt.nb_pts)
+ return -EINVAL;
+ args->value = nvhost_syncpt_read(&ctx->dev->syncpt, args->id);
+ trace_nvhost_ioctl_ctrl_syncpt_read(args->id, args->value);
+ return 0;
+}
+
+static int nvhost_ioctl_ctrl_syncpt_incr(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_ctrl_syncpt_incr_args *args)
+{
+ if (args->id >= ctx->dev->syncpt.nb_pts)
+ return -EINVAL;
+ trace_nvhost_ioctl_ctrl_syncpt_incr(args->id);
+ nvhost_syncpt_incr(&ctx->dev->syncpt, args->id);
+ return 0;
+}
+
+static int nvhost_ioctl_ctrl_syncpt_waitex(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_ctrl_syncpt_waitex_args *args)
+{
+ u32 timeout;
+ int err;
+ if (args->id >= ctx->dev->syncpt.nb_pts)
+ return -EINVAL;
+ if (args->timeout == NVHOST_NO_TIMEOUT)
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ else
+ timeout = (u32)msecs_to_jiffies(args->timeout);
+
+ err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
+ args->thresh, timeout, &args->value);
+ trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
+ args->timeout, args->value, err);
+
+ return err;
+}
+
+static int nvhost_ioctl_ctrl_module_mutex(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_ctrl_module_mutex_args *args)
+{
+ int err = 0;
+ if (args->id >= ctx->dev->syncpt.nb_mlocks ||
+ args->lock > 1)
+ return -EINVAL;
+
+ 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->dev);
+ else
+ err = nvhost_mutex_try_lock(&ctx->dev->syncpt,
+ 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->dev);
+ else
+ nvhost_mutex_unlock(&ctx->dev->syncpt, args->id);
+ ctx->mod_locks[args->id] = 0;
+ }
+ return err;
+}
+
+static int match_by_moduleid(struct device *dev, void *data)
+{
+ struct nvhost_device *ndev = to_nvhost_device(dev);
+ u32 id = (u32)data;
+
+ return id == ndev->moduleid;
+}
+
+static struct nvhost_device *get_ndev_by_moduleid(struct nvhost_master *host,
+ u32 id)
+{
+ struct device *dev = bus_find_device(&nvhost_bus_inst->nvhost_bus_type,
+ NULL, (void *)id, match_by_moduleid);
+
+ return dev ? to_nvhost_device(dev) : NULL;
+}
+
+static int nvhost_ioctl_ctrl_module_regrdwr(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_ctrl_module_regrdwr_args *args)
+{
+ u32 num_offsets = args->num_offsets;
+ u32 *offsets = args->offsets;
+ u32 *values = args->values;
+ u32 vals[64];
+ struct nvhost_device *ndev;
+
+ trace_nvhost_ioctl_ctrl_module_regrdwr(args->id,
+ args->num_offsets, args->write);
+ /* Check that there is something to read and that block size is
+ * u32 aligned */
+ if (num_offsets == 0 || args->block_size & 3)
+ return -EINVAL;
+
+ ndev = get_ndev_by_moduleid(ctx->dev, args->id);
+ if (!ndev)
+ return -EINVAL;
+
+ while (num_offsets--) {
+ int err;
+ int remaining = args->block_size >> 2;
+ u32 offs;
+ if (get_user(offs, offsets))
+ return -EFAULT;
+ offsets++;
+ while (remaining) {
+ int batch = min(remaining, 64);
+ if (args->write) {
+ if (copy_from_user(vals, values,
+ batch*sizeof(u32)))
+ return -EFAULT;
+ err = nvhost_write_module_regs(ndev,
+ offs, batch, vals);
+ if (err)
+ return err;
+ } else {
+ err = nvhost_read_module_regs(ndev,
+ offs, batch, vals);
+ if (err)
+ return err;
+ if (copy_to_user(values, vals,
+ batch*sizeof(u32)))
+ return -EFAULT;
+ }
+ remaining -= batch;
+ offs += batch*sizeof(u32);
+ values += batch;
+ }
+ }
+
+ return 0;
+}
+
+static int nvhost_ioctl_ctrl_get_version(struct nvhost_ctrl_userctx *ctx,
+ struct nvhost_get_param_args *args)
+{
+ args->value = NVHOST_SUBMIT_VERSION_MAX_SUPPORTED;
+ return 0;
+}
+
+static long nvhost_ctrlctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct nvhost_ctrl_userctx *priv = filp->private_data;
+ u8 buf[NVHOST_IOCTL_CTRL_MAX_ARG_SIZE];
+ int err = 0;
+
+ if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) ||
+ (_IOC_NR(cmd) == 0) ||
+ (_IOC_NR(cmd) > NVHOST_IOCTL_CTRL_LAST) ||
+ (_IOC_SIZE(cmd) > NVHOST_IOCTL_CTRL_MAX_ARG_SIZE))
+ return -EFAULT;
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd)))
+ return -EFAULT;
+ }
+
+ switch (cmd) {
+ case NVHOST_IOCTL_CTRL_SYNCPT_READ:
+ err = nvhost_ioctl_ctrl_syncpt_read(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_SYNCPT_INCR:
+ err = nvhost_ioctl_ctrl_syncpt_incr(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_SYNCPT_WAIT:
+ err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_MODULE_MUTEX:
+ err = nvhost_ioctl_ctrl_module_mutex(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_MODULE_REGRDWR:
+ err = nvhost_ioctl_ctrl_module_regrdwr(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_SYNCPT_WAITEX:
+ err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf);
+ break;
+ case NVHOST_IOCTL_CTRL_GET_VERSION:
+ err = nvhost_ioctl_ctrl_get_version(priv, (void *)buf);
+ break;
+ default:
+ err = -ENOTTY;
+ break;
+ }
+
+ if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ))
+ err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd));
+
+ return err;
+}
+
+static const struct file_operations nvhost_ctrlops = {
+ .owner = THIS_MODULE,
+ .release = nvhost_ctrlrelease,
+ .open = nvhost_ctrlopen,
+ .unlocked_ioctl = nvhost_ctrlctl
+};
+
+static void power_on_host(struct nvhost_device *dev)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ nvhost_syncpt_reset(&host->syncpt);
+ nvhost_intr_start(&host->intr, clk_get_rate(dev->clk[0]));
+}
+
+static int power_off_host(struct nvhost_device *dev)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ nvhost_syncpt_save(&host->syncpt);
+ nvhost_intr_stop(&host->intr);
+ return 0;
+}
+
+static int __devinit nvhost_user_init(struct nvhost_master *host)
+{
+ int err, devno;
+
+ host->nvhost_class = class_create(THIS_MODULE, IFACE_NAME);
+ if (IS_ERR(host->nvhost_class)) {
+ err = PTR_ERR(host->nvhost_class);
+ dev_err(&host->dev->dev, "failed to create class\n");
+ goto fail;
+ }
+
+ err = alloc_chrdev_region(&devno, 0, 1, IFACE_NAME);
+ if (err < 0) {
+ dev_err(&host->dev->dev, "failed to reserve chrdev region\n");
+ goto fail;
+ }
+
+ cdev_init(&host->cdev, &nvhost_ctrlops);
+ host->cdev.owner = THIS_MODULE;
+ err = cdev_add(&host->cdev, devno, 1);
+ if (err < 0)
+ goto fail;
+ host->ctrl = device_create(host->nvhost_class, NULL, devno, NULL,
+ IFACE_NAME "-ctrl");
+ if (IS_ERR(host->ctrl)) {
+ err = PTR_ERR(host->ctrl);
+ dev_err(&host->dev->dev, "failed to create ctrl device\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ return err;
+}
+
+struct nvhost_channel *nvhost_alloc_channel(int index)
+{
+ BUG_ON(!host_device_op().alloc_nvhost_channel);
+ return host_device_op().alloc_nvhost_channel(index);
+}
+
+void nvhost_free_channel(struct nvhost_channel *ch)
+{
+ BUG_ON(!host_device_op().free_nvhost_channel);
+ host_device_op().free_nvhost_channel(ch);
+}
+
+static void nvhost_free_resources(struct nvhost_master *host)
+{
+ kfree(host->intr.syncpt);
+ host->intr.syncpt = 0;
+}
+
+static int __devinit nvhost_alloc_resources(struct nvhost_master *host)
+{
+ int err;
+
+ err = nvhost_init_chip_support(host);
+ if (err)
+ return err;
+
+ host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
+ host->syncpt.nb_pts, GFP_KERNEL);
+
+ if (!host->intr.syncpt) {
+ /* frees happen in the support removal phase */
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int __devinit nvhost_probe(struct nvhost_device *dev,
+ struct nvhost_device_id *id_table)
+{
+ struct nvhost_master *host;
+ struct resource *regs, *intr0, *intr1;
+ int i, err;
+
+ regs = nvhost_get_resource(dev, IORESOURCE_MEM, 0);
+ intr0 = nvhost_get_resource(dev, IORESOURCE_IRQ, 0);
+ intr1 = nvhost_get_resource(dev, IORESOURCE_IRQ, 1);
+
+ if (!regs || !intr0 || !intr1) {
+ dev_err(&dev->dev, "missing required platform resources\n");
+ return -ENXIO;
+ }
+
+ host = kzalloc(sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ host->reg_mem = request_mem_region(regs->start,
+ resource_size(regs), dev->name);
+ if (!host->reg_mem) {
+ dev_err(&dev->dev, "failed to get host register memory\n");
+ err = -ENXIO;
+ goto fail;
+ }
+
+ host->aperture = ioremap(regs->start, resource_size(regs));
+ if (!host->aperture) {
+ dev_err(&dev->dev, "failed to remap host registers\n");
+ err = -ENXIO;
+ goto fail;
+ }
+
+ err = nvhost_alloc_resources(host);
+ if (err) {
+ dev_err(&dev->dev, "failed to init chip support\n");
+ goto fail;
+ }
+
+ host->memmgr = mem_op().alloc_mgr();
+ if (!host->memmgr) {
+ dev_err(&dev->dev, "unable to create nvmap client\n");
+ err = -EIO;
+ goto fail;
+ }
+
+ /* Register host1x device as bus master */
+ host->dev = dev;
+
+ /* Give pointer to host1x via driver */
+ nvhost_set_drvdata(dev, host);
+
+ nvhost_bus_add_host(host);
+
+ err = nvhost_syncpt_init(dev, &host->syncpt);
+ if (err)
+ goto fail;
+
+ err = nvhost_intr_init(&host->intr, intr1->start, intr0->start);
+ if (err)
+ goto fail;
+
+ err = nvhost_user_init(host);
+ if (err)
+ goto fail;
+
+ err = nvhost_module_init(dev);
+ if (err)
+ goto fail;
+
+ for (i = 0; i < host->dev->num_clks; i++)
+ clk_enable(host->dev->clk[i]);
+ nvhost_syncpt_reset(&host->syncpt);
+ for (i = 0; i < host->dev->num_clks; i++)
+ clk_disable(host->dev->clk[0]);
+
+ nvhost_debug_init(host);
+
+ dev_info(&dev->dev, "initialized\n");
+ return 0;
+
+fail:
+ nvhost_free_resources(host);
+ if (host->memmgr)
+ mem_op().put_mgr(host->memmgr);
+ kfree(host);
+ return err;
+}
+
+static int __exit nvhost_remove(struct nvhost_device *dev)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ nvhost_intr_deinit(&host->intr);
+ nvhost_syncpt_deinit(&host->syncpt);
+ nvhost_free_resources(host);
+ return 0;
+}
+
+static int nvhost_suspend(struct nvhost_device *dev, pm_message_t state)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ int ret = 0;
+
+ ret = nvhost_module_suspend(host->dev);
+ dev_info(&dev->dev, "suspend status: %d\n", ret);
+
+ return ret;
+}
+
+static int nvhost_resume(struct nvhost_device *dev)
+{
+ dev_info(&dev->dev, "resuming\n");
+ return 0;
+}
+
+static struct nvhost_driver nvhost_driver = {
+ .probe = nvhost_probe,
+ .remove = __exit_p(nvhost_remove),
+ .suspend = nvhost_suspend,
+ .resume = nvhost_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME
+ },
+ .finalize_poweron = power_on_host,
+ .prepare_poweroff = power_off_host,
+};
+
+static int __init nvhost_mod_init(void)
+{
+ return nvhost_driver_register(&nvhost_driver);
+}
+
+static void __exit nvhost_mod_exit(void)
+{
+ nvhost_driver_unregister(&nvhost_driver);
+}
+
+/* host1x master device needs nvmap to be instantiated first.
+ * nvmap is instantiated via fs_initcall.
+ * Hence instantiate host1x master device using rootfs_initcall
+ * which is one level after fs_initcall. */
+rootfs_initcall(nvhost_mod_init);
+module_exit(nvhost_mod_exit);
+
diff --git a/drivers/video/tegra/host/host1x/host1x.h b/drivers/video/tegra/host/host1x/host1x.h
new file mode 100644
index 000000000000..295d3ff4c7f4
--- /dev/null
+++ b/drivers/video/tegra/host/host1x/host1x.h
@@ -0,0 +1,63 @@
+/*
+ * drivers/video/tegra/host/host1x/host1x.h
+ *
+ * Tegra Graphics Host Driver Entrypoint
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NVHOST_DEV_H
+#define __NVHOST_DEV_H
+
+#include <linux/cdev.h>
+#include "nvhost_syncpt.h"
+#include "nvhost_intr.h"
+
+#define TRACE_MAX_LENGTH 128U
+#define IFACE_NAME "nvhost"
+
+struct nvhost_hwctx;
+struct nvhost_channel;
+struct mem_mgr;
+
+struct nvhost_master {
+ void __iomem *aperture;
+ void __iomem *sync_aperture;
+ struct resource *reg_mem;
+ struct class *nvhost_class;
+ struct cdev cdev;
+ struct device *ctrl;
+ struct nvhost_syncpt syncpt;
+ struct mem_mgr *memmgr;
+ struct nvhost_intr intr;
+ struct nvhost_device *dev;
+ atomic_t clientid;
+};
+
+extern struct nvhost_master *nvhost;
+
+void nvhost_debug_init(struct nvhost_master *master);
+void nvhost_debug_dump(struct nvhost_master *master);
+
+struct nvhost_channel *nvhost_alloc_channel(int index);
+void nvhost_free_channel(struct nvhost_channel *ch);
+
+extern pid_t nvhost_debug_null_kickoff_pid;
+
+struct nvhost_device;
+
+extern struct nvhost_device tegra_host1x01_device;
+
+#endif
diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.c b/drivers/video/tegra/host/host1x/host1x_syncpt.c
index 4cc8e9e212fa..e67d2209c6ef 100644
--- a/drivers/video/tegra/host/host1x/host1x_syncpt.c
+++ b/drivers/video/tegra/host/host1x/host1x_syncpt.c
@@ -23,7 +23,7 @@
#include <trace/events/nvhost.h>
#include "nvhost_syncpt.h"
#include "nvhost_acm.h"
-#include "dev.h"
+#include "host1x.h"
#include "host1x_syncpt.h"
#include "host1x_hardware.h"
#include "chip_support.h"
diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.h b/drivers/video/tegra/host/host1x/host1x_syncpt.h
index 1e94a2b846eb..f624a755da9c 100644
--- a/drivers/video/tegra/host/host1x/host1x_syncpt.h
+++ b/drivers/video/tegra/host/host1x/host1x_syncpt.h
@@ -45,12 +45,6 @@
#define NVSYNCPT_MPE_WR_SAFE (29)
#define NVSYNCPT_DSI (31)
-
-/*#define NVSYNCPT_2D_CHANNEL2_0 (20) */
-/*#define NVSYNCPT_2D_CHANNEL2_1 (21) */
-/*#define NVSYNCPT_2D_TINYBLT_WAR (30)*/
-/*#define NVSYNCPT_2D_TINYBLT_RESTORE_CLASS_ID (30)*/
-
/* sync points that are wholly managed by the client */
#define NVSYNCPTS_CLIENT_MANAGED ( \
BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) | \
@@ -64,7 +58,6 @@
BIT(NVSYNCPT_MPE_EBM_EOF) | BIT(NVSYNCPT_MPE_WR_SAFE) | \
BIT(NVSYNCPT_2D_1) | BIT(NVSYNCPT_AVP_0))
-
#define NVWAITBASE_2D_0 (1)
#define NVWAITBASE_2D_1 (2)
#define NVWAITBASE_3D (3)
diff --git a/drivers/video/tegra/host/isp/isp.c b/drivers/video/tegra/host/isp/isp.c
index ae9d7eb09365..0a581f89e78d 100644
--- a/drivers/video/tegra/host/isp/isp.c
+++ b/drivers/video/tegra/host/isp/isp.c
@@ -18,10 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/resource.h>
-
-#include <mach/iomap.h>
-
#include "dev.h"
#include "bus_client.h"
@@ -54,15 +50,6 @@ static int isp_resume(struct nvhost_device *dev)
return 0;
}
-static struct resource isp_resources = {
- .name = "regs",
- .start = TEGRA_ISP_BASE,
- .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-struct nvhost_device *isp_device;
-
static struct nvhost_driver isp_driver = {
.probe = isp_probe,
.remove = __exit_p(isp_remove),
@@ -78,18 +65,6 @@ static struct nvhost_driver isp_driver = {
static int __init isp_init(void)
{
- int err;
-
- isp_device = nvhost_get_device("isp");
- if (!isp_device)
- return -ENXIO;
-
- isp_device->resource = &isp_resources;
- isp_device->num_resources = 1;
- err = nvhost_device_register(isp_device);
- if (err)
- return err;
-
return nvhost_driver_register(&isp_driver);
}
diff --git a/drivers/video/tegra/host/mpe/mpe.c b/drivers/video/tegra/host/mpe/mpe.c
index 7468d4b9d753..cee0714bf079 100644
--- a/drivers/video/tegra/host/mpe/mpe.c
+++ b/drivers/video/tegra/host/mpe/mpe.c
@@ -30,10 +30,6 @@
#include "nvhost_memmgr.h"
#include <linux/slab.h>
-#include <linux/resource.h>
-
-#include <mach/iomap.h>
-#include <mach/hardware.h>
#include "bus_client.h"
@@ -656,15 +652,6 @@ static int mpe_resume(struct nvhost_device *dev)
return 0;
}
-static struct resource mpe_resources = {
- .name = "regs",
- .start = TEGRA_MPE_BASE,
- .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-struct nvhost_device *mpe_device;
-
static struct nvhost_driver mpe_driver = {
.probe = mpe_probe,
.remove = __exit_p(mpe_remove),
@@ -681,19 +668,6 @@ static struct nvhost_driver mpe_driver = {
static int __init mpe_init(void)
{
- int err;
-
- mpe_device = nvhost_get_device("mpe");
- if (!mpe_device)
- return -ENXIO;
-
- /* use ARRAY_SIZE macro if resources are more than 1 */
- mpe_device->resource = &mpe_resources;
- mpe_device->num_resources = 1;
- err = nvhost_device_register(mpe_device);
- if (err)
- return err;
-
return nvhost_driver_register(&mpe_driver);
}
diff --git a/drivers/video/tegra/host/t20/t20.c b/drivers/video/tegra/host/t20/t20.c
index 50648bc98990..9c6e87a98f13 100644
--- a/drivers/video/tegra/host/t20/t20.c
+++ b/drivers/video/tegra/host/t20/t20.c
@@ -21,13 +21,14 @@
#include <linux/slab.h>
#include <linux/nvhost_ioctl.h>
#include <mach/powergate.h>
-#include "dev.h"
+#include <mach/iomap.h>
#include "t20.h"
#include "host1x/host1x_syncpt.h"
#include "host1x/host1x_hardware.h"
#include "gr3d/gr3d.h"
#include "gr3d/gr3d_t20.h"
#include "mpe/mpe.h"
+#include "host1x/host1x.h"
#include "nvhost_hwctx.h"
#include "nvhost_channel.h"
#include "host1x/host1x_channel.h"
@@ -50,13 +51,11 @@
static int t20_num_alloc_channels = 0;
-struct nvhost_device t20_devices[] = {
-{
- /* channel 0 */
+static struct nvhost_device tegra_display01_device = {
.name = "display",
.id = -1,
.index = 0,
- .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
+ .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),
@@ -64,9 +63,9 @@ struct nvhost_device t20_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 1 */
+};
+
+static struct nvhost_device tegra_gr3d01_device = {
.name = "gr3d01",
.id = -1,
.index = 1,
@@ -74,13 +73,13 @@ struct nvhost_device t20_devices[] = {
.waitbases = BIT(NVWAITBASE_3D),
.modulemutexes = BIT(NVMODMUTEX_3D),
.class = NV_GRAPHICS_3D_CLASS_ID,
- .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} },
+ .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} },
.powergate_ids = {TEGRA_POWERGATE_3D, -1},
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 2 */
+};
+
+static struct nvhost_device tegra_gr2d01_device = {
.name = "gr2d",
.id = -1,
.index = 2,
@@ -88,26 +87,48 @@ struct nvhost_device t20_devices[] = {
.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),
- .clocks = { {"gr2d", UINT_MAX},
+ .clocks = { {"gr2d", UINT_MAX},
{"epp", UINT_MAX},
{"emc", UINT_MAX} },
NVHOST_MODULE_NO_POWERGATE_IDS,
.clockgate_delay = 0,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 3 */
+};
+
+static struct resource isp_resources_t20[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_ISP_BASE,
+ .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct nvhost_device tegra_isp01_device = {
.name = "isp",
.id = -1,
+ .resource = isp_resources_t20,
+ .num_resources = ARRAY_SIZE(isp_resources_t20),
.index = 3,
.syncpts = 0,
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_ISP,
-},
-{
- /* channel 4 */
+};
+
+static struct resource vi_resources[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_VI_BASE,
+ .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct nvhost_device tegra_vi01_device = {
.name = "vi",
+ .resource = vi_resources,
+ .num_resources = ARRAY_SIZE(vi_resources),
.id = -1,
.index = 4,
.syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
@@ -119,11 +140,22 @@ struct nvhost_device t20_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_VI,
-},
-{
- /* channel 5 */
+};
+
+static struct resource tegra_mpe01_resources[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_MPE_BASE,
+ .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct nvhost_device tegra_mpe01_device = {
.name = "mpe01",
.id = -1,
+ .resource = tegra_mpe01_resources,
+ .num_resources = ARRAY_SIZE(tegra_mpe01_resources),
.index = 5,
.syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
BIT(NVSYNCPT_MPE_WR_SAFE),
@@ -136,9 +168,9 @@ struct nvhost_device t20_devices[] = {
.powergate_ids = {TEGRA_POWERGATE_MPE, -1},
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_MPE,
-},
-{
- /* channel 6 */
+};
+
+static struct nvhost_device tegra_dsi01_device = {
.name = "dsi",
.id = -1,
.index = 6,
@@ -147,8 +179,23 @@ struct nvhost_device t20_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_NONE,
-} };
+};
+static struct nvhost_device *t20_devices[] = {
+ &tegra_host1x01_device,
+ &tegra_display01_device,
+ &tegra_gr3d01_device,
+ &tegra_gr2d01_device,
+ &tegra_isp01_device,
+ &tegra_vi01_device,
+ &tegra_mpe01_device,
+ &tegra_dsi01_device,
+};
+
+int tegra2_register_host1x_devices(void)
+{
+ return nvhost_add_devices(t20_devices, ARRAY_SIZE(t20_devices));
+}
static inline void __iomem *t20_channel_aperture(void __iomem *p, int ndx)
{
@@ -209,18 +256,6 @@ static struct nvhost_channel *t20_alloc_nvhost_channel(int chindex)
T20_NVHOST_NUMCHANNELS, &t20_num_alloc_channels);
}
-struct nvhost_device *t20_get_nvhost_device(char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(t20_devices); i++) {
- if (strncmp(t20_devices[i].name, name, strlen(name)) == 0)
- return &t20_devices[i];
- }
-
- return NULL;
-}
-
int nvhost_init_t20_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
@@ -244,7 +279,6 @@ int nvhost_init_t20_support(struct nvhost_master *host,
return err;
err = nvhost_memmgr_init(op);
- op->nvhost_dev.get_nvhost_device = t20_get_nvhost_device;
op->nvhost_dev.alloc_nvhost_channel = t20_alloc_nvhost_channel;
op->nvhost_dev.free_nvhost_channel = t20_free_nvhost_channel;
diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c
index e6687fd2153b..acd5d928b1a1 100644
--- a/drivers/video/tegra/host/t30/t30.c
+++ b/drivers/video/tegra/host/t30/t30.c
@@ -22,13 +22,13 @@
#include <linux/nvhost_ioctl.h>
#include <mach/powergate.h>
#include <mach/iomap.h>
-#include "dev.h"
#include "t20/t20.h"
#include "t30.h"
#include "gr3d/gr3d.h"
#include "gr3d/gr3d_t30.h"
#include "gr3d/scale3d.h"
#include "mpe/mpe.h"
+#include "host1x/host1x.h"
#include "host1x/host1x_hardware.h"
#include "host1x/host1x_syncpt.h"
#include "chip_support.h"
@@ -47,19 +47,15 @@
#define NVMODMUTEX_VI (8)
#define NVMODMUTEX_DSI (9)
-#define NVHOST_CHANNEL_BASE 0
-
#define T30_NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1)
static int t30_num_alloc_channels = 0;
-struct nvhost_device t30_devices[] = {
-{
- /* channel 0 */
+static struct nvhost_device tegra_display01_device = {
.name = "display",
.id = -1,
.index = 0,
- .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
+ .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),
@@ -67,13 +63,13 @@ struct nvhost_device t30_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 1 */
+};
+
+static struct nvhost_device tegra_gr3d02_device = {
.name = "gr3d02",
.id = -1,
.index = 1,
- .syncpts = BIT(NVSYNCPT_3D),
+ .syncpts = BIT(NVSYNCPT_3D),
.waitbases = BIT(NVWAITBASE_3D),
.modulemutexes = BIT(NVMODMUTEX_3D),
.class = NV_GRAPHICS_3D_CLASS_ID,
@@ -87,9 +83,9 @@ struct nvhost_device t30_devices[] = {
.powerup_reset = true,
.powergate_delay = 250,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 2 */
+};
+
+static struct nvhost_device tegra_gr2d02_device = {
.name = "gr2d",
.id = -1,
.index = 2,
@@ -97,29 +93,51 @@ struct nvhost_device t30_devices[] = {
.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),
- .clocks = { {"gr2d", 0},
- {"epp", 0},
- {"emc", 300000000} },
+ .clocks = { {"gr2d", UINT_MAX},
+ {"epp", 0},
+ {"emc", 300000000} },
NVHOST_MODULE_NO_POWERGATE_IDS,
.clockgate_delay = 0,
.moduleid = NVHOST_MODULE_NONE,
-},
-{
- /* channel 3 */
+};
+
+static struct resource isp_resources_t20[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_ISP_BASE,
+ .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct nvhost_device tegra_isp01_device = {
.name = "isp",
.id = -1,
+ .resource = isp_resources_t20,
+ .num_resources = ARRAY_SIZE(isp_resources_t20),
.index = 3,
.syncpts = 0,
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_ISP,
-},
-{
- /* channel 4 */
+};
+
+static struct resource vi_resources[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_VI_BASE,
+ .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct nvhost_device tegra_vi01_device = {
.name = "vi",
+ .resource = vi_resources,
+ .num_resources = ARRAY_SIZE(vi_resources),
.id = -1,
.index = 4,
- .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_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),
@@ -128,11 +146,22 @@ struct nvhost_device t30_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_VI,
-},
-{
- /* channel 5 */
+};
+
+static struct resource tegra_mpe01_resources[] = {
+ {
+ .name = "regs",
+ .start = TEGRA_MPE_BASE,
+ .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct nvhost_device tegra_mpe02_device = {
.name = "mpe02",
.id = -1,
+ .resource = tegra_mpe01_resources,
+ .num_resources = ARRAY_SIZE(tegra_mpe01_resources),
.index = 5,
.syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
BIT(NVSYNCPT_MPE_WR_SAFE),
@@ -140,16 +169,16 @@ struct nvhost_device t30_devices[] = {
.class = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
.waitbasesync = true,
.keepalive = true,
- .clocks = { {"mpe", UINT_MAX},
+ .clocks = { {"mpe", UINT_MAX},
{"emc", UINT_MAX} },
.powergate_ids = {TEGRA_POWERGATE_MPE, -1},
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.can_powergate = true,
.powergate_delay = 100,
.moduleid = NVHOST_MODULE_MPE,
-},
-{
- /* channel 6 */
+};
+
+static struct nvhost_device tegra_dsi01_device = {
.name = "dsi",
.id = -1,
.index = 6,
@@ -158,7 +187,23 @@ struct nvhost_device t30_devices[] = {
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_NONE,
-} };
+};
+
+static struct nvhost_device *t30_devices[] = {
+ &tegra_host1x01_device,
+ &tegra_display01_device,
+ &tegra_gr3d02_device,
+ &tegra_gr2d02_device,
+ &tegra_isp01_device,
+ &tegra_vi01_device,
+ &tegra_mpe02_device,
+ &tegra_dsi01_device,
+};
+
+int tegra3_register_host1x_devices(void)
+{
+ return nvhost_add_devices(t30_devices, ARRAY_SIZE(t30_devices));
+}
static inline int t30_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
{
@@ -181,7 +226,6 @@ static inline int t30_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
static inline void __iomem *t30_channel_aperture(void __iomem *p, int ndx)
{
- ndx += NVHOST_CHANNEL_BASE;
p += NV_HOST1X_CHANNEL0_BASE;
p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
return p;
@@ -227,18 +271,6 @@ static struct nvhost_channel *t30_alloc_nvhost_channel(int chindex)
T30_NVHOST_NUMCHANNELS, &t30_num_alloc_channels);
}
-struct nvhost_device *t30_get_nvhost_device(char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(t30_devices); i++) {
- if (strncmp(t30_devices[i].name, name, strlen(name)) == 0)
- return &t30_devices[i];
- }
-
- return NULL;
-}
-
int nvhost_init_t30_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
@@ -264,7 +296,6 @@ int nvhost_init_t30_support(struct nvhost_master *host,
if (err)
return err;
- op->nvhost_dev.get_nvhost_device = t30_get_nvhost_device;
op->nvhost_dev.alloc_nvhost_channel = t30_alloc_nvhost_channel;
op->nvhost_dev.free_nvhost_channel = t30_free_nvhost_channel;
diff --git a/drivers/video/tegra/host/vi/vi.c b/drivers/video/tegra/host/vi/vi.c
index 3cfc7e32cbc1..3985ee029efa 100644
--- a/drivers/video/tegra/host/vi/vi.c
+++ b/drivers/video/tegra/host/vi/vi.c
@@ -18,10 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/resource.h>
-
-#include <mach/iomap.h>
-
#include "dev.h"
#include "bus_client.h"
@@ -54,15 +50,6 @@ static int vi_resume(struct nvhost_device *dev)
return 0;
}
-static struct resource vi_resources = {
- .name = "regs",
- .start = TEGRA_VI_BASE,
- .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-struct nvhost_device *vi_device;
-
static struct nvhost_driver vi_driver = {
.probe = vi_probe,
.remove = __exit_p(vi_remove),
@@ -78,18 +65,6 @@ static struct nvhost_driver vi_driver = {
static int __init vi_init(void)
{
- int err;
-
- vi_device = nvhost_get_device("vi");
- if (!vi_device)
- return -ENXIO;
-
- vi_device->resource = &vi_resources;
- vi_device->num_resources = 1;
- err = nvhost_device_register(vi_device);
- if (err)
- return err;
-
return nvhost_driver_register(&vi_driver);
}
diff --git a/include/linux/nvhost.h b/include/linux/nvhost.h
index 82bb884dfbbd..1293cec7cd75 100644
--- a/include/linux/nvhost.h
+++ b/include/linux/nvhost.h
@@ -94,6 +94,9 @@ struct nvhost_device {
struct nvhost_channel *channel; /* Channel assigned for the module */
};
+/* Register devices to nvhost bus */
+extern int nvhost_add_devices(struct nvhost_device **, int num);
+
/* Register device to nvhost bus */
extern int nvhost_device_register(struct nvhost_device *);