summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_dc_ext.h58
-rw-r--r--drivers/video/tegra/Kconfig9
-rw-r--r--drivers/video/tegra/dc/Makefile1
-rw-r--r--drivers/video/tegra/dc/dc.c12
-rw-r--r--drivers/video/tegra/dc/dc_priv.h4
-rw-r--r--drivers/video/tegra/dc/ext/Makefile1
-rw-r--r--drivers/video/tegra/dc/ext/dev.c141
-rw-r--r--drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h33
8 files changed, 258 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h b/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
new file mode 100644
index 000000000000..54680a5b06ac
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-tegra/include/mach/tegra_dc_ext.h
+ *
+ * Copyright (C) 2011, NVIDIA Corporation
+ *
+ * Author: Robert Morell <rmorell@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#ifndef __MACH_TEGRA_DC_EXT_H
+#define __MACH_TEGRA_DC_EXT_H
+
+#include <mach/nvhost.h>
+
+struct tegra_dc_ext;
+
+#ifdef CONFIG_TEGRA_DC_EXTENSIONS
+int __init tegra_dc_ext_module_init(void);
+void __exit tegra_dc_ext_module_exit(void);
+
+struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev,
+ struct tegra_dc *dc);
+void tegra_dc_ext_unregister(struct tegra_dc_ext *dc_ext);
+
+#else /* CONFIG_TEGRA_DC_EXTENSIONS */
+
+static inline
+int tegra_dc_ext_module_init(void)
+{
+ return 0;
+}
+static inline
+void tegra_dc_ext_module_exit(void)
+{
+}
+
+static inline
+struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev,
+ struct tegra_dc *dc)
+{
+ return NULL;
+}
+static inline
+void tegra_dc_ext_unregister(struct tegra_dc_ext *dc_ext)
+{
+}
+#endif /* CONFIG_TEGRA_DC_EXTENSIONS */
+
+#endif /* __MACH_TEGRA_DC_EXT_H */
diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig
index b1da7f0e408f..a29e2488a386 100644
--- a/drivers/video/tegra/Kconfig
+++ b/drivers/video/tegra/Kconfig
@@ -19,7 +19,7 @@ config TEGRA_DC
config TEGRA_OVERLAY
tristate "Tegra Overlay Device Node"
- depends on TEGRA_DC
+ depends on TEGRA_DC && !TEGRA_DC_EXTENSIONS
default y
help
Device node for multi-client overlay support.
@@ -34,6 +34,13 @@ config FB_TEGRA
help
Framebuffer device support for the Tegra display controller.
+config TEGRA_DC_EXTENSIONS
+ bool "Tegra Display Controller Extensions"
+ depends on TEGRA_DC
+ help
+ This exposes support for extended capabilities of the Tegra display
+ controller to userspace drivers.
+
config TEGRA_NVMAP
bool "Tegra GPU memory management driver (nvmap)"
default y
diff --git a/drivers/video/tegra/dc/Makefile b/drivers/video/tegra/dc/Makefile
index 63044cafd638..90b03892673c 100644
--- a/drivers/video/tegra/dc/Makefile
+++ b/drivers/video/tegra/dc/Makefile
@@ -7,3 +7,4 @@ obj-y += nvsd.o
obj-y += dsi.o
obj-y += dc_sysfs.o
obj-$(CONFIG_TEGRA_OVERLAY) += overlay.o
+obj-$(CONFIG_TEGRA_DC_EXTENSIONS) += ext/
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index f6488ad7699e..a0e8c45098ef 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -2371,6 +2371,12 @@ static int tegra_dc_probe(struct nvhost_device *ndev)
if (dc->out && dc->out->hotplug_init)
dc->out->hotplug_init();
+ dc->ext = tegra_dc_ext_register(ndev, dc);
+ if (IS_ERR_OR_NULL(dc->ext)) {
+ dev_warn(&ndev->dev, "Failed to enable Tegra DC extensions.\n");
+ dc->ext = NULL;
+ }
+
if (dc->out_ops && dc->out_ops->detect)
dc->out_ops->detect(dc);
@@ -2413,6 +2419,8 @@ static int tegra_dc_remove(struct nvhost_device *ndev)
release_resource(dc->fb_mem);
}
+ if (dc->ext)
+ tegra_dc_ext_unregister(dc->ext);
if (dc->enabled)
_tegra_dc_disable(dc);
@@ -2522,12 +2530,16 @@ struct nvhost_driver tegra_dc_driver = {
static int __init tegra_dc_module_init(void)
{
+ int ret = tegra_dc_ext_module_init();
+ if (ret)
+ return ret;
return nvhost_driver_register(&tegra_dc_driver);
}
static void __exit tegra_dc_module_exit(void)
{
nvhost_driver_unregister(&tegra_dc_driver);
+ tegra_dc_ext_module_exit();
}
module_exit(tegra_dc_module_exit);
diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h
index ebd339c489c2..4bf429f7e68c 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -28,6 +28,8 @@
#include "../host/dev.h"
#include "../host/t20/syncpt_t20.h"
+#include <mach/tegra_dc_ext.h>
+
#define WIN_IS_TILED(win) ((win)->flags & TEGRA_WIN_FLAG_TILED)
#define WIN_IS_ENABLED(win) ((win)->flags & TEGRA_WIN_FLAG_ENABLED)
#define WIN_USE_V_FILTER(win) ((win)->flags & TEGRA_WIN_FLAG_V_FILTER)
@@ -121,6 +123,8 @@ struct tegra_dc {
unsigned underflows_c;
} stats;
+ struct tegra_dc_ext *ext;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *debugdir;
#endif
diff --git a/drivers/video/tegra/dc/ext/Makefile b/drivers/video/tegra/dc/ext/Makefile
new file mode 100644
index 000000000000..44c52311b4e3
--- /dev/null
+++ b/drivers/video/tegra/dc/ext/Makefile
@@ -0,0 +1 @@
+obj-y += dev.o
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
new file mode 100644
index 000000000000..6fe778896241
--- /dev/null
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -0,0 +1,141 @@
+/*
+ * drivers/video/tegra/dc/dev.c
+ *
+ * Copyright (C) 2011, NVIDIA Corporation
+ *
+ * Author: Robert Morell <rmorell@nvidia.com>
+ * Some code based on fbdev extensions written by:
+ * Erik Gilling <konkers@android.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+
+#include <mach/dc.h>
+#include <mach/tegra_dc_ext.h>
+
+#include "tegra_dc_ext_priv.h"
+
+static int tegra_dc_ext_devno;
+static struct class *tegra_dc_ext_class;
+
+static int tegra_dc_release(struct inode *inode, struct file *filp)
+{
+ struct tegra_dc_ext_user *user = filp->private_data;
+
+ kfree(user);
+
+ return 0;
+}
+
+static int tegra_dc_open(struct inode *inode, struct file *filp)
+{
+ struct tegra_dc_ext_user *user;
+
+ user = kzalloc(sizeof(*user), GFP_KERNEL);
+ if (!user)
+ return -ENOMEM;
+
+ filp->private_data = user;
+
+ return 0;
+}
+
+static long tegra_dc_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ return 0;
+}
+
+static const struct file_operations tegra_dc_devops = {
+ .owner = THIS_MODULE,
+ .open = tegra_dc_open,
+ .release = tegra_dc_release,
+ .unlocked_ioctl = tegra_dc_ioctl,
+};
+
+struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev,
+ struct tegra_dc *dc)
+{
+ int ret;
+ struct tegra_dc_ext *ext;
+
+ ext = kzalloc(sizeof(*ext), GFP_KERNEL);
+ if (!ext)
+ return ERR_PTR(-ENOMEM);
+
+ BUG_ON(!tegra_dc_ext_devno);
+ cdev_init(&ext->cdev, &tegra_dc_devops);
+ ext->cdev.owner = THIS_MODULE;
+ ret = cdev_add(&ext->cdev, tegra_dc_ext_devno, 1);
+ if (ret) {
+ dev_err(&ndev->dev, "Failed to create character device\n");
+ goto cleanup_alloc;
+ }
+
+ ext->dev = device_create(tegra_dc_ext_class,
+ &ndev->dev,
+ tegra_dc_ext_devno,
+ NULL,
+ "tegra_dc_%d",
+ ndev->id);
+
+ if (IS_ERR(ext->dev)) {
+ ret = PTR_ERR(ext->dev);
+ goto cleanup_cdev;
+ }
+
+ tegra_dc_ext_devno++;
+
+ return ext;
+
+cleanup_cdev:
+ cdev_del(&ext->cdev);
+
+cleanup_alloc:
+ kfree(ext);
+
+ return ERR_PTR(ret);
+}
+
+void tegra_dc_ext_unregister(struct tegra_dc_ext *ext)
+{
+ cdev_del(&ext->cdev);
+ kfree(ext);
+}
+
+int __init tegra_dc_ext_module_init(void)
+{
+ int ret;
+
+ tegra_dc_ext_class = class_create(THIS_MODULE, "tegra_dc_ext");
+ if (!tegra_dc_ext_class) {
+ printk(KERN_ERR "tegra_dc_ext: failed to create class\n");
+ return -ENOMEM;
+ }
+
+ ret = alloc_chrdev_region(&tegra_dc_ext_devno,
+ 0, TEGRA_MAX_DC,
+ "tegra_dc_ext");
+ if (ret)
+ class_destroy(tegra_dc_ext_class);
+
+ return ret;
+}
+
+void __exit tegra_dc_ext_module_exit(void)
+{
+ unregister_chrdev_region(tegra_dc_ext_devno, TEGRA_MAX_DC);
+ class_destroy(tegra_dc_ext_class);
+}
diff --git a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
new file mode 100644
index 000000000000..387af543c511
--- /dev/null
+++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
@@ -0,0 +1,33 @@
+/*
+ * drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
+ *
+ * Copyright (C) 2011, NVIDIA Corporation
+ *
+ * Author: Robert Morell <rmorell@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#ifndef __TEGRA_DC_EXT_PRIV_H
+#define __TEGRA_DC_EXT_PRIV_H
+
+#include <linux/cdev.h>
+
+struct tegra_dc_ext {
+ struct cdev cdev;
+ struct device *dev;
+};
+
+struct tegra_dc_ext_user {
+
+};
+
+#endif /* __TEGRA_DC_EXT_PRIV_H */