summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorRobert Morell <rmorell@nvidia.com>2011-03-03 13:04:00 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:11 -0800
commit4d785e53437e27a0bbf57f26c66dcad3bacd35f0 (patch)
tree59ec45c90e9462c8298ec504107588880a9a198f /drivers/video/tegra
parent6964bbc3358ef35caf426fc06490a9359a91ab6b (diff)
video: tegra: Add skeleton support for extensions
This adds the infrasturcture for an enhanced driver interface to program extended capabilities of the Tegra display controller. It exposes a new set of device nodes for userspace clients distinct from the traditional fbdev device nodes. This is necessary due to limitations in the fbdev infrastructure that don't allow drivers to store file-private data. bug 818525 Original-Change-Id: I06cecf894792b9904c73f9ebcdeb746ff7455f6e Signed-off-by: Robert Morell <rmorell@nvidia.com> Reviewed-on: http://git-master/r/40512 Reviewed-by: Jonathan Mayo <jmayo@nvidia.com> Rebase-Id: Rfa3969804d7f52c841be1ff96305c9463077e1c5
Diffstat (limited to 'drivers/video/tegra')
-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
7 files changed, 200 insertions, 1 deletions
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 */