diff options
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/imx-drm/Kconfig | 53 | ||||
-rw-r--r-- | drivers/staging/imx-drm/Makefile | 12 | ||||
-rw-r--r-- | drivers/staging/imx-drm/TODO | 17 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-drm-core.c | 703 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-drm.h | 56 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-hdmi.c | 1766 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-hdmi.h | 1032 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-ldb.c | 615 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-tve.c | 735 | ||||
-rw-r--r-- | drivers/staging/imx-drm/ipuv3-crtc.c | 518 | ||||
-rw-r--r-- | drivers/staging/imx-drm/ipuv3-plane.c | 363 | ||||
-rw-r--r-- | drivers/staging/imx-drm/ipuv3-plane.h | 55 | ||||
-rw-r--r-- | drivers/staging/imx-drm/parallel-display.c | 295 |
15 files changed, 0 insertions, 6223 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4690ae9a267f..9425728b7eb5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -86,8 +86,6 @@ source "drivers/staging/gdm72xx/Kconfig" source "drivers/staging/gdm724x/Kconfig" -source "drivers/staging/imx-drm/Kconfig" - source "drivers/staging/fwserial/Kconfig" source "drivers/staging/goldfish/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c780a0e70e15..bc233dd98a95 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_STAGING_BOARD) += board/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_LTE_GDM724X) += gdm724x/ -obj-$(CONFIG_DRM_IMX) += imx-drm/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_LUSTRE_FS) += lustre/ diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig deleted file mode 100644 index 82fb758a29bc..000000000000 --- a/drivers/staging/imx-drm/Kconfig +++ /dev/null @@ -1,53 +0,0 @@ -config DRM_IMX - tristate "DRM Support for Freescale i.MX" - select DRM_KMS_HELPER - select DRM_KMS_FB_HELPER - select VIDEOMODE_HELPERS - select DRM_GEM_CMA_HELPER - select DRM_KMS_CMA_HELPER - depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) - help - enable i.MX graphics support - -config DRM_IMX_FB_HELPER - tristate "provide legacy framebuffer /dev/fb0" - select DRM_KMS_CMA_HELPER - depends on DRM_IMX - help - The DRM framework can provide a legacy /dev/fb0 framebuffer - for your device. This is necessary to get a framebuffer console - and also for applications using the legacy framebuffer API - -config DRM_IMX_PARALLEL_DISPLAY - tristate "Support for parallel displays" - select DRM_PANEL - depends on DRM_IMX - select VIDEOMODE_HELPERS - -config DRM_IMX_TVE - tristate "Support for TV and VGA displays" - depends on DRM_IMX - select REGMAP_MMIO - help - Choose this to enable the internal Television Encoder (TVe) - found on i.MX53 processors. - -config DRM_IMX_LDB - tristate "Support for LVDS displays" - depends on DRM_IMX && MFD_SYSCON - help - Choose this to enable the internal LVDS Display Bridge (LDB) - found on i.MX53 and i.MX6 processors. - -config DRM_IMX_IPUV3 - tristate "DRM Support for i.MX IPUv3" - depends on DRM_IMX - depends on IMX_IPUV3_CORE - help - Choose this if you have a i.MX5 or i.MX6 processor. - -config DRM_IMX_HDMI - tristate "Freescale i.MX DRM HDMI" - depends on DRM_IMX - help - Choose this if you want to use HDMI on i.MX6. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile deleted file mode 100644 index 582c438d8cbd..000000000000 --- a/drivers/staging/imx-drm/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -imxdrm-objs := imx-drm-core.o - -obj-$(CONFIG_DRM_IMX) += imxdrm.o - -obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o -obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o -obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o - -imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o -obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o -obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO deleted file mode 100644 index 29636fb13959..000000000000 --- a/drivers/staging/imx-drm/TODO +++ /dev/null @@ -1,17 +0,0 @@ -TODO: -- get DRM Maintainer review for this code -- decide where to put the base driver. It is not specific to a subsystem - and would be used by DRM/KMS and media/V4L2 - -Missing features (not necessarily for moving out of staging): - -- Add support for IC (Image converter) -- Add support for CSI (CMOS Sensor interface) -- Add support for VDIC (Video Deinterlacer) - -Many work-in-progress patches for the above features exist. Contact -Sascha Hauer <kernel@pengutronix.de> if you are interested in working -on a specific feature. - -Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org> and -Sascha Hauer <kernel@pengutronix.de> diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c deleted file mode 100644 index ad6173500bfc..000000000000 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Freescale i.MX drm driver - * - * Copyright (C) 2011 Sascha Hauer, Pengutronix - * - * 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/component.h> -#include <linux/device.h> -#include <linux/fb.h> -#include <linux/module.h> -#include <linux/of_graph.h> -#include <linux/platform_device.h> -#include <drm/drmP.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_fb_cma_helper.h> - -#include "imx-drm.h" - -#define MAX_CRTC 4 - -struct imx_drm_crtc; - -struct imx_drm_component { - struct device_node *of_node; - struct list_head list; -}; - -struct imx_drm_device { - struct drm_device *drm; - struct imx_drm_crtc *crtc[MAX_CRTC]; - int pipes; - struct drm_fbdev_cma *fbhelper; -}; - -struct imx_drm_crtc { - struct drm_crtc *crtc; - int pipe; - struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs; - struct device_node *port; -}; - -static int legacyfb_depth = 16; -module_param(legacyfb_depth, int, 0444); - -int imx_drm_crtc_id(struct imx_drm_crtc *crtc) -{ - return crtc->pipe; -} -EXPORT_SYMBOL_GPL(imx_drm_crtc_id); - -static void imx_drm_driver_lastclose(struct drm_device *drm) -{ -#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) - struct imx_drm_device *imxdrm = drm->dev_private; - - if (imxdrm->fbhelper) - drm_fbdev_cma_restore_mode(imxdrm->fbhelper); -#endif -} - -static int imx_drm_driver_unload(struct drm_device *drm) -{ -#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) - struct imx_drm_device *imxdrm = drm->dev_private; -#endif - - drm_kms_helper_poll_fini(drm); - -#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) - if (imxdrm->fbhelper) - drm_fbdev_cma_fini(imxdrm->fbhelper); -#endif - - component_unbind_all(drm->dev, drm); - - drm_vblank_cleanup(drm); - drm_mode_config_cleanup(drm); - - platform_set_drvdata(drm->platformdev, NULL); - - return 0; -} - -static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) -{ - struct imx_drm_device *imxdrm = crtc->dev->dev_private; - unsigned i; - - for (i = 0; i < MAX_CRTC; i++) - if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc) - return imxdrm->crtc[i]; - - return NULL; -} - -int imx_drm_panel_format_pins(struct drm_encoder *encoder, - u32 interface_pix_fmt, int hsync_pin, int vsync_pin) -{ - struct imx_drm_crtc_helper_funcs *helper; - struct imx_drm_crtc *imx_crtc; - - imx_crtc = imx_drm_find_crtc(encoder->crtc); - if (!imx_crtc) - return -EINVAL; - - helper = &imx_crtc->imx_drm_helper_funcs; - if (helper->set_interface_pix_fmt) - return helper->set_interface_pix_fmt(encoder->crtc, - encoder->encoder_type, interface_pix_fmt, - hsync_pin, vsync_pin); - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins); - -int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt) -{ - return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3); -} -EXPORT_SYMBOL_GPL(imx_drm_panel_format); - -int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) -{ - return drm_vblank_get(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); -} -EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get); - -void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc) -{ - drm_vblank_put(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); -} -EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put); - -void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) -{ - drm_handle_vblank(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); -} -EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); - -static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) -{ - struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; - int ret; - - if (!imx_drm_crtc) - return -EINVAL; - - if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank) - return -ENOSYS; - - ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank( - imx_drm_crtc->crtc); - - return ret; -} - -static void imx_drm_disable_vblank(struct drm_device *drm, int crtc) -{ - struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; - - if (!imx_drm_crtc) - return; - - if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank) - return; - - imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc); -} - -static void imx_drm_driver_preclose(struct drm_device *drm, - struct drm_file *file) -{ - int i; - - if (!file->is_master) - return; - - for (i = 0; i < MAX_CRTC; i++) - imx_drm_disable_vblank(drm, i); -} - -static const struct file_operations imx_drm_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_gem_cma_mmap, - .poll = drm_poll, - .read = drm_read, - .llseek = noop_llseek, -}; - -void imx_drm_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} -EXPORT_SYMBOL_GPL(imx_drm_connector_destroy); - -void imx_drm_encoder_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} -EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy); - -static void imx_drm_output_poll_changed(struct drm_device *drm) -{ -#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) - struct imx_drm_device *imxdrm = drm->dev_private; - - drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); -#endif -} - -static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { - .fb_create = drm_fb_cma_create, - .output_poll_changed = imx_drm_output_poll_changed, -}; - -/* - * Main DRM initialisation. This binds, initialises and registers - * with DRM the subcomponents of the driver. - */ -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) -{ - struct imx_drm_device *imxdrm; - struct drm_connector *connector; - int ret; - - imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL); - if (!imxdrm) - return -ENOMEM; - - imxdrm->drm = drm; - - drm->dev_private = imxdrm; - - /* - * enable drm irq mode. - * - with irq_enabled = true, we can use the vblank feature. - * - * P.S. note that we wouldn't use drm irq handler but - * just specific driver own one instead because - * drm framework supports only one irq handler and - * drivers can well take care of their interrupts - */ - drm->irq_enabled = true; - - /* - * set max width and height as default value(4096x4096). - * this value would be used to check framebuffer size limitation - * at drm_mode_addfb(). - */ - drm->mode_config.min_width = 64; - drm->mode_config.min_height = 64; - drm->mode_config.max_width = 4096; - drm->mode_config.max_height = 4096; - drm->mode_config.funcs = &imx_drm_mode_config_funcs; - - drm_mode_config_init(drm); - - ret = drm_vblank_init(drm, MAX_CRTC); - if (ret) - goto err_kms; - - /* - * with vblank_disable_allowed = true, vblank interrupt will be - * disabled by drm timer once a current process gives up ownership - * of vblank event. (after drm_vblank_put function is called) - */ - drm->vblank_disable_allowed = true; - - platform_set_drvdata(drm->platformdev, drm); - - /* Now try and bind all our sub-components */ - ret = component_bind_all(drm->dev, drm); - if (ret) - goto err_vblank; - - /* - * All components are now added, we can publish the connector sysfs - * entries to userspace. This will generate hotplug events and so - * userspace will expect to be able to access DRM at this point. - */ - list_for_each_entry(connector, &drm->mode_config.connector_list, head) { - ret = drm_connector_register(connector); - if (ret) { - dev_err(drm->dev, - "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n", - connector->base.id, - connector->name, ret); - goto err_unbind; - } - } - - /* - * All components are now initialised, so setup the fb helper. - * The fb helper takes copies of key hardware information, so the - * crtcs/connectors/encoders must not change after this point. - */ -#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) - if (legacyfb_depth != 16 && legacyfb_depth != 32) { - dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); - legacyfb_depth = 16; - } - imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, - drm->mode_config.num_crtc, MAX_CRTC); - if (IS_ERR(imxdrm->fbhelper)) { - ret = PTR_ERR(imxdrm->fbhelper); - imxdrm->fbhelper = NULL; - goto err_unbind; - } -#endif - - drm_kms_helper_poll_init(drm); - - return 0; - -err_unbind: - component_unbind_all(drm->dev, drm); -err_vblank: - drm_vblank_cleanup(drm); -err_kms: - drm_mode_config_cleanup(drm); - - return ret; -} - -/* - * imx_drm_add_crtc - add a new crtc - */ -int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, - struct imx_drm_crtc **new_crtc, - const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, - struct device_node *port) -{ - struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc; - int ret; - - /* - * The vblank arrays are dimensioned by MAX_CRTC - we can't - * pass IDs greater than this to those functions. - */ - if (imxdrm->pipes >= MAX_CRTC) - return -EINVAL; - - if (imxdrm->drm->open_count) - return -EBUSY; - - imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL); - if (!imx_drm_crtc) - return -ENOMEM; - - imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; - imx_drm_crtc->pipe = imxdrm->pipes++; - imx_drm_crtc->port = port; - imx_drm_crtc->crtc = crtc; - - imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; - - *new_crtc = imx_drm_crtc; - - ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); - if (ret) - goto err_register; - - drm_crtc_helper_add(crtc, - imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); - - drm_crtc_init(drm, crtc, - imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); - - return 0; - -err_register: - imxdrm->crtc[imx_drm_crtc->pipe] = NULL; - kfree(imx_drm_crtc); - return ret; -} -EXPORT_SYMBOL_GPL(imx_drm_add_crtc); - -/* - * imx_drm_remove_crtc - remove a crtc - */ -int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) -{ - struct imx_drm_device *imxdrm = imx_drm_crtc->crtc->dev->dev_private; - - drm_crtc_cleanup(imx_drm_crtc->crtc); - - imxdrm->crtc[imx_drm_crtc->pipe] = NULL; - - kfree(imx_drm_crtc); - - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_remove_crtc); - -/* - * Find the DRM CRTC possible mask for the connected endpoint. - * - * The encoder possible masks are defined by their position in the - * mode_config crtc_list. This means that CRTCs must not be added - * or removed once the DRM device has been fully initialised. - */ -static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, - struct device_node *endpoint) -{ - struct device_node *port; - unsigned i; - - port = of_graph_get_remote_port(endpoint); - if (!port) - return 0; - of_node_put(port); - - for (i = 0; i < MAX_CRTC; i++) { - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; - - if (imx_drm_crtc && imx_drm_crtc->port == port) - return drm_crtc_mask(imx_drm_crtc->crtc); - } - - return 0; -} - -static struct device_node *imx_drm_of_get_next_endpoint( - const struct device_node *parent, struct device_node *prev) -{ - struct device_node *node = of_graph_get_next_endpoint(parent, prev); - - of_node_put(prev); - return node; -} - -int imx_drm_encoder_parse_of(struct drm_device *drm, - struct drm_encoder *encoder, struct device_node *np) -{ - struct imx_drm_device *imxdrm = drm->dev_private; - struct device_node *ep = NULL; - uint32_t crtc_mask = 0; - int i; - - for (i = 0; ; i++) { - u32 mask; - - ep = imx_drm_of_get_next_endpoint(np, ep); - if (!ep) - break; - - mask = imx_drm_find_crtc_mask(imxdrm, ep); - - /* - * If we failed to find the CRTC(s) which this encoder is - * supposed to be connected to, it's because the CRTC has - * not been registered yet. Defer probing, and hope that - * the required CRTC is added later. - */ - if (mask == 0) - return -EPROBE_DEFER; - - crtc_mask |= mask; - } - - of_node_put(ep); - if (i == 0) - return -ENOENT; - - encoder->possible_crtcs = crtc_mask; - - /* FIXME: this is the mask of outputs which can clone this output. */ - encoder->possible_clones = ~0; - - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of); - -/* - * @node: device tree node containing encoder input ports - * @encoder: drm_encoder - */ -int imx_drm_encoder_get_mux_id(struct device_node *node, - struct drm_encoder *encoder) -{ - struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc); - struct device_node *ep = NULL; - struct of_endpoint endpoint; - struct device_node *port; - int ret; - - if (!node || !imx_crtc) - return -EINVAL; - - do { - ep = imx_drm_of_get_next_endpoint(node, ep); - if (!ep) - break; - - port = of_graph_get_remote_port(ep); - of_node_put(port); - if (port == imx_crtc->port) { - ret = of_graph_parse_endpoint(ep, &endpoint); - return ret ? ret : endpoint.port; - } - } while (ep); - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id); - -static const struct drm_ioctl_desc imx_drm_ioctls[] = { - /* none so far */ -}; - -static struct drm_driver imx_drm_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, - .load = imx_drm_driver_load, - .unload = imx_drm_driver_unload, - .lastclose = imx_drm_driver_lastclose, - .preclose = imx_drm_driver_preclose, - .set_busid = drm_platform_set_busid, - .gem_free_object = drm_gem_cma_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - .dumb_create = drm_gem_cma_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, - - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_import = drm_gem_prime_import, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, - .gem_prime_vmap = drm_gem_cma_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, - .gem_prime_mmap = drm_gem_cma_prime_mmap, - .get_vblank_counter = drm_vblank_count, - .enable_vblank = imx_drm_enable_vblank, - .disable_vblank = imx_drm_disable_vblank, - .ioctls = imx_drm_ioctls, - .num_ioctls = ARRAY_SIZE(imx_drm_ioctls), - .fops = &imx_drm_driver_fops, - .name = "imx-drm", - .desc = "i.MX DRM graphics", - .date = "20120507", - .major = 1, - .minor = 0, - .patchlevel = 0, -}; - -static int compare_of(struct device *dev, void *data) -{ - struct device_node *np = data; - - /* Special case for LDB, one device for two channels */ - if (of_node_cmp(np->name, "lvds-channel") == 0) { - np = of_get_parent(np); - of_node_put(np); - } - - return dev->of_node == np; -} - -static int imx_drm_bind(struct device *dev) -{ - return drm_platform_init(&imx_drm_driver, to_platform_device(dev)); -} - -static void imx_drm_unbind(struct device *dev) -{ - drm_put_dev(dev_get_drvdata(dev)); -} - -static const struct component_master_ops imx_drm_ops = { - .bind = imx_drm_bind, - .unbind = imx_drm_unbind, -}; - -static int imx_drm_platform_probe(struct platform_device *pdev) -{ - struct device_node *ep, *port, *remote; - struct component_match *match = NULL; - int ret; - int i; - - /* - * Bind the IPU display interface ports first, so that - * imx_drm_encoder_parse_of called from encoder .bind callbacks - * works as expected. - */ - for (i = 0; ; i++) { - port = of_parse_phandle(pdev->dev.of_node, "ports", i); - if (!port) - break; - - component_match_add(&pdev->dev, &match, compare_of, port); - } - - if (i == 0) { - dev_err(&pdev->dev, "missing 'ports' property\n"); - return -ENODEV; - } - - /* Then bind all encoders */ - for (i = 0; ; i++) { - port = of_parse_phandle(pdev->dev.of_node, "ports", i); - if (!port) - break; - - for_each_child_of_node(port, ep) { - remote = of_graph_get_remote_port_parent(ep); - if (!remote || !of_device_is_available(remote)) { - of_node_put(remote); - continue; - } else if (!of_device_is_available(remote->parent)) { - dev_warn(&pdev->dev, "parent device of %s is not available\n", - remote->full_name); - of_node_put(remote); - continue; - } - - component_match_add(&pdev->dev, &match, compare_of, remote); - of_node_put(remote); - } - of_node_put(port); - } - - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - return component_master_add_with_match(&pdev->dev, &imx_drm_ops, match); -} - -static int imx_drm_platform_remove(struct platform_device *pdev) -{ - component_master_del(&pdev->dev, &imx_drm_ops); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int imx_drm_suspend(struct device *dev) -{ - struct drm_device *drm_dev = dev_get_drvdata(dev); - - /* The drm_dev is NULL before .load hook is called */ - if (drm_dev == NULL) - return 0; - - drm_kms_helper_poll_disable(drm_dev); - - return 0; -} - -static int imx_drm_resume(struct device *dev) -{ - struct drm_device *drm_dev = dev_get_drvdata(dev); - - if (drm_dev == NULL) - return 0; - - drm_helper_resume_force_mode(drm_dev); - drm_kms_helper_poll_enable(drm_dev); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(imx_drm_pm_ops, imx_drm_suspend, imx_drm_resume); - -static const struct of_device_id imx_drm_dt_ids[] = { - { .compatible = "fsl,imx-display-subsystem", }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, imx_drm_dt_ids); - -static struct platform_driver imx_drm_pdrv = { - .probe = imx_drm_platform_probe, - .remove = imx_drm_platform_remove, - .driver = { - .name = "imx-drm", - .pm = &imx_drm_pm_ops, - .of_match_table = imx_drm_dt_ids, - }, -}; -module_platform_driver(imx_drm_pdrv); - -MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); -MODULE_DESCRIPTION("i.MX drm driver core"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h deleted file mode 100644 index 7453ae00c412..000000000000 --- a/drivers/staging/imx-drm/imx-drm.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _IMX_DRM_H_ -#define _IMX_DRM_H_ - -struct device_node; -struct drm_crtc; -struct drm_connector; -struct drm_device; -struct drm_display_mode; -struct drm_encoder; -struct drm_fbdev_cma; -struct drm_framebuffer; -struct imx_drm_crtc; -struct platform_device; - -int imx_drm_crtc_id(struct imx_drm_crtc *crtc); - -struct imx_drm_crtc_helper_funcs { - int (*enable_vblank)(struct drm_crtc *crtc); - void (*disable_vblank)(struct drm_crtc *crtc); - int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type, - u32 pix_fmt, int hsync_pin, int vsync_pin); - const struct drm_crtc_helper_funcs *crtc_helper_funcs; - const struct drm_crtc_funcs *crtc_funcs; -}; - -int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, - struct imx_drm_crtc **new_crtc, - const struct imx_drm_crtc_helper_funcs *imx_helper_funcs, - struct device_node *port); -int imx_drm_remove_crtc(struct imx_drm_crtc *); -int imx_drm_init_drm(struct platform_device *pdev, - int preferred_bpp); -int imx_drm_exit_drm(void); - -int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc); -void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc); -void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc); - -void imx_drm_mode_config_init(struct drm_device *drm); - -struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); - -int imx_drm_panel_format_pins(struct drm_encoder *encoder, - u32 interface_pix_fmt, int hsync_pin, int vsync_pin); -int imx_drm_panel_format(struct drm_encoder *encoder, - u32 interface_pix_fmt); - -int imx_drm_encoder_get_mux_id(struct device_node *node, - struct drm_encoder *encoder); -int imx_drm_encoder_parse_of(struct drm_device *drm, - struct drm_encoder *encoder, struct device_node *np); - -void imx_drm_connector_destroy(struct drm_connector *connector); -void imx_drm_encoder_destroy(struct drm_encoder *encoder); - -#endif /* _IMX_DRM_H_ */ diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c deleted file mode 100644 index ddc53e039530..000000000000 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. - * - * 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. - * - * SH-Mobile High-Definition Multimedia Interface (HDMI) driver - * for SLISHDMI13T and SLIPHDMIT IP cores - * - * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> - */ - -#include <linux/component.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/hdmi.h> -#include <linux/regmap.h> -#include <linux/mfd/syscon.h> -#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> -#include <linux/of_device.h> - -#include <drm/drmP.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_edid.h> -#include <drm/drm_encoder_slave.h> -#include <video/imx-ipu-v3.h> - -#include "imx-hdmi.h" -#include "imx-drm.h" - -#define HDMI_EDID_LEN 512 - -#define RGB 0 -#define YCBCR444 1 -#define YCBCR422_16BITS 2 -#define YCBCR422_8BITS 3 -#define XVYCC444 4 - -enum hdmi_datamap { - RGB444_8B = 0x01, - RGB444_10B = 0x03, - RGB444_12B = 0x05, - RGB444_16B = 0x07, - YCbCr444_8B = 0x09, - YCbCr444_10B = 0x0B, - YCbCr444_12B = 0x0D, - YCbCr444_16B = 0x0F, - YCbCr422_8B = 0x16, - YCbCr422_10B = 0x14, - YCbCr422_12B = 0x12, -}; - -enum imx_hdmi_devtype { - IMX6Q_HDMI, - IMX6DL_HDMI, -}; - -static const u16 csc_coeff_default[3][4] = { - { 0x2000, 0x0000, 0x0000, 0x0000 }, - { 0x0000, 0x2000, 0x0000, 0x0000 }, - { 0x0000, 0x0000, 0x2000, 0x0000 } -}; - -static const u16 csc_coeff_rgb_out_eitu601[3][4] = { - { 0x2000, 0x6926, 0x74fd, 0x010e }, - { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, - { 0x2000, 0x0000, 0x38b4, 0x7e3b } -}; - -static const u16 csc_coeff_rgb_out_eitu709[3][4] = { - { 0x2000, 0x7106, 0x7a02, 0x00a7 }, - { 0x2000, 0x3264, 0x0000, 0x7e6d }, - { 0x2000, 0x0000, 0x3b61, 0x7e25 } -}; - -static const u16 csc_coeff_rgb_in_eitu601[3][4] = { - { 0x2591, 0x1322, 0x074b, 0x0000 }, - { 0x6535, 0x2000, 0x7acc, 0x0200 }, - { 0x6acd, 0x7534, 0x2000, 0x0200 } -}; - -static const u16 csc_coeff_rgb_in_eitu709[3][4] = { - { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, - { 0x62f0, 0x2000, 0x7d11, 0x0200 }, - { 0x6756, 0x78ab, 0x2000, 0x0200 } -}; - -struct hdmi_vmode { - bool mdvi; - bool mhsyncpolarity; - bool mvsyncpolarity; - bool minterlaced; - bool mdataenablepolarity; - - unsigned int mpixelclock; - unsigned int mpixelrepetitioninput; - unsigned int mpixelrepetitionoutput; -}; - -struct hdmi_data_info { - unsigned int enc_in_format; - unsigned int enc_out_format; - unsigned int enc_color_depth; - unsigned int colorimetry; - unsigned int pix_repet_factor; - unsigned int hdcp_enable; - struct hdmi_vmode video_mode; -}; - -struct imx_hdmi { - struct drm_connector connector; - struct drm_encoder encoder; - - enum imx_hdmi_devtype dev_type; - struct device *dev; - struct clk *isfr_clk; - struct clk *iahb_clk; - - struct hdmi_data_info hdmi_data; - int vic; - - u8 edid[HDMI_EDID_LEN]; - bool cable_plugin; - - bool phy_enabled; - struct drm_display_mode previous_mode; - - struct regmap *regmap; - struct i2c_adapter *ddc; - void __iomem *regs; - - unsigned int sample_rate; - int ratio; -}; - -static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di) -{ - regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, - IMX6Q_GPR3_HDMI_MUX_CTL_MASK, - ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); -} - -static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) -{ - writeb(val, hdmi->regs + offset); -} - -static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) -{ - return readb(hdmi->regs + offset); -} - -static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) -{ - u8 val = hdmi_readb(hdmi, reg) & ~mask; - - val |= data & mask; - hdmi_writeb(hdmi, val, reg); -} - -static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, - u8 shift, u8 mask) -{ - hdmi_modb(hdmi, data << shift, mask, reg); -} - -static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, - unsigned int value) -{ - hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); - hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2); - hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3); - - /* nshift factor = 0 */ - hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); -} - -static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) -{ - /* Must be set/cleared first */ - hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); - - hdmi_ |