diff options
-rw-r--r-- | arch/arm/mach-tegra/include/mach/tegra_dc_ext.h | 58 | ||||
-rw-r--r-- | drivers/video/tegra/Kconfig | 9 | ||||
-rw-r--r-- | drivers/video/tegra/dc/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 12 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/dev.c | 141 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 33 |
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 */ |