diff options
Diffstat (limited to 'drivers/gpu/drm/exynos_tmp')
43 files changed, 0 insertions, 15744 deletions
diff --git a/drivers/gpu/drm/exynos_tmp/Kconfig b/drivers/gpu/drm/exynos_tmp/Kconfig deleted file mode 100644 index 4466490..0000000 --- a/drivers/gpu/drm/exynos_tmp/Kconfig +++ /dev/null @@ -1,46 +0,0 @@ -config DRM_EXYNOS - tristate "DRM Support for Samsung SoC EXYNOS Series" - depends on DRM && PLAT_SAMSUNG - select DRM_KMS_HELPER - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE - -config DRM_EXYNOS_MEMSIZE - int "Memory size in kbytes for DRM" - depends on DRM_EXYNOS - default "32768" - -config DRM_EXYNOS_DMABUF - bool "GEM DMABUF Support" - depends on DRM_EXYNOS - -config DRM_EXYNOS_FIMD - bool "Samsung DRM FIMD" - depends on DRM_EXYNOS - -config DRM_EXYNOS_FIMD_WB - bool "Samsung DRM FIMD WB" - depends on DRM_EXYNOS_FIMD - help - This option enables writeback operations in FIMD for DRM. - It can support fimd streams data to fimc destinations ram. - writeback operations support final blended stream. - when enable this options. - -config DRM_EXYNOS_HDMI - bool "Samsung DRM HDMI" - depends on DRM_EXYNOS - -config DRM_EXYNOS_VIDI - bool "Samsung DRM Virtual Display" - depends on DRM_EXYNOS - -config DRM_EXYNOS_G2D - bool "Samsung DRM G2D" - depends on DRM_EXYNOS - -config DRM_EXYNOS_ROTATOR - bool "Samsung DRM Rotator" - depends on DRM_EXYNOS diff --git a/drivers/gpu/drm/exynos_tmp/Makefile b/drivers/gpu/drm/exynos_tmp/Makefile deleted file mode 100644 index f8a88f3..0000000 --- a/drivers/gpu/drm/exynos_tmp/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos \ - -Idrivers/media/video/samsung/ump/include -exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \ - exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \ - exynos_drm_buf.o exynos_drm_ump.o exynos_drm_gem.o \ - exynos_drm_core.o exynos_drm_plane.o exynos_drm_iommu.o - -exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o -exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o -exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o exynos_ddc.o \ - exynos_hdmiphy.o exynos_drm_hdmi.o -exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o -exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o -exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += exynos_drm_rotator.o - -obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o diff --git a/drivers/gpu/drm/exynos_tmp/exynos_ddc.c b/drivers/gpu/drm/exynos_tmp/exynos_ddc.c deleted file mode 100644 index 7e1051d..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_ddc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim <sw0312.kim@samsung.com> - * Inki Dae <inki.dae@samsung.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. - * - */ - -#include "drmP.h" - -#include <linux/kernel.h> -#include <linux/i2c.h> -#include <linux/module.h> - - -#include "exynos_drm_drv.h" -#include "exynos_hdmi.h" - -static int s5p_ddc_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - hdmi_attach_ddc_client(client); - - dev_info(&client->adapter->dev, "attached s5p_ddc " - "into i2c adapter successfully\n"); - - return 0; -} - -static int s5p_ddc_remove(struct i2c_client *client) -{ - dev_info(&client->adapter->dev, "detached s5p_ddc " - "from i2c adapter successfully\n"); - - return 0; -} - -static struct i2c_device_id ddc_idtable[] = { - {"s5p_ddc", 0}, - { }, -}; - -struct i2c_driver ddc_driver = { - .driver = { - .name = "s5p_ddc", - .owner = THIS_MODULE, - }, - .id_table = ddc_idtable, - .probe = s5p_ddc_probe, - .remove = __devexit_p(s5p_ddc_remove), - .command = NULL, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.c deleted file mode 100644 index f7bb7be..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.c +++ /dev/null @@ -1,241 +0,0 @@ -/* exynos_drm_buf.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "exynos_drm.h" - -#include <linux/cma.h> -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_buf.h" - -static int lowlevel_buffer_allocate(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buf) -{ - dma_addr_t start_addr; - unsigned int npages, i = 0; - struct scatterlist *sgl; - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (IS_NONCONTIG_BUFFER(flags)) { - DRM_DEBUG_KMS("not support allocation type.\n"); - return -EINVAL; - } - - if (buf->dma_addr) { - DRM_DEBUG_KMS("already allocated.\n"); - return 0; - } - - if (buf->size >= SZ_1M) { - npages = buf->size >> SECTION_SHIFT; - buf->page_size = SECTION_SIZE; - } else if (buf->size >= SZ_64K) { - npages = buf->size >> 16; - buf->page_size = SZ_64K; - } else { - npages = buf->size >> PAGE_SHIFT; - buf->page_size = PAGE_SIZE; - } - - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!buf->sgt) { - DRM_ERROR("failed to allocate sg table.\n"); - return -ENOMEM; - } - - ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); - if (ret < 0) { - DRM_ERROR("failed to initialize sg table.\n"); - kfree(buf->sgt); - buf->sgt = NULL; - return -ENOMEM; - } - -#ifdef CONFIG_CMA - buf->dma_addr = cma_alloc(dev->dev, "drm", buf->size, - buf->page_size); - if (IS_ERR((void *)buf->dma_addr)) { - DRM_DEBUG_KMS("cma_alloc of size %ld failed\n", - buf->size); - ret = -ENOMEM; - goto err1; - } - - buf->kvaddr = phys_to_virt(buf->dma_addr); -#else - /* align it as page size(page or section) TODO */ - - buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL); - if (!buf->kvaddr) { - DRM_ERROR("failed to allocate buffer.\n"); - ret = -ENOMEM; - goto err1; - } -#endif - buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); - if (!buf->pages) { - DRM_ERROR("failed to allocate pages.\n"); - ret = -ENOMEM; - goto err2; - } - - sgl = buf->sgt->sgl; - start_addr = buf->dma_addr; - - while (i < npages) { - buf->pages[i] = phys_to_page(start_addr); - sg_set_page(sgl, buf->pages[i], buf->page_size, 0); - sg_dma_address(sgl) = start_addr; - start_addr += buf->page_size; - sgl = sg_next(sgl); - i++; - } - - DRM_INFO("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", - (unsigned long)buf->kvaddr, - (unsigned long)buf->dma_addr, - buf->size); - - return ret; -err2: -#ifdef CONFIG_CMA - cma_free(buf->dma_addr); -#else - dma_free_writecombine(dev->dev, buf->size, buf->kvaddr, - (dma_addr_t)buf->dma_addr); -#endif - buf->dma_addr = (dma_addr_t)NULL; -err1: - sg_free_table(buf->sgt); - kfree(buf->sgt); - buf->sgt = NULL; - - return ret; -} - -static void lowlevel_buffer_deallocate(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buf) -{ - DRM_DEBUG_KMS("%s.\n", __FILE__); - - /* - * now buffer is being shared and it would be released - * by original owner so ignor free action. - */ - if (buf->shared || atomic_read(&buf->shared_refcount)) - return; - - /* - * release only physically continuous memory and - * non-continuous memory would be released by exynos - * gem framework. - */ - if (IS_NONCONTIG_BUFFER(flags)) { - DRM_DEBUG_KMS("not support allocation type.\n"); - return; - } - - if (!buf->dma_addr) { - DRM_DEBUG_KMS("dma_addr is invalid.\n"); - return; - } - - sg_free_table(buf->sgt); - - kfree(buf->sgt); - buf->sgt = NULL; - - kfree(buf->pages); - buf->pages = NULL; -#ifdef CONFIG_CMA - cma_free(buf->dma_addr); -#else - dma_free_writecombine(dev->dev, buf->size, buf->kvaddr, - (dma_addr_t)buf->dma_addr); -#endif - buf->dma_addr = (dma_addr_t)NULL; -} - -struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, - unsigned int size) -{ - struct exynos_drm_gem_buf *buffer; - - DRM_DEBUG_KMS("%s.\n", __FILE__); - DRM_DEBUG_KMS("desired size = 0x%x\n", size); - - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); - if (!buffer) { - DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); - return NULL; - } - - buffer->size = size; - return buffer; -} - -void exynos_drm_fini_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buffer) -{ - DRM_DEBUG_KMS("%s.\n", __FILE__); - - if (!buffer) { - DRM_DEBUG_KMS("buffer is null.\n"); - return; - } - - kfree(buffer); - buffer = NULL; -} - -int exynos_drm_alloc_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buf, unsigned int flags) -{ - - /* - * allocate memory region and set the memory information - * to vaddr and dma_addr of a buffer object. - */ - if (lowlevel_buffer_allocate(dev, flags, buf) < 0) - return -ENOMEM; - - return 0; -} - -void exynos_drm_free_buf(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buffer) -{ - - lowlevel_buffer_deallocate(dev, flags, buffer); -} - -MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DRM Buffer Management Module"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.h deleted file mode 100644 index 3388e4e..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_buf.h +++ /dev/null @@ -1,47 +0,0 @@ -/* exynos_drm_buf.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_BUF_H_ -#define _EXYNOS_DRM_BUF_H_ - -/* create and initialize buffer object. */ -struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, - unsigned int size); - -/* destroy buffer object. */ -void exynos_drm_fini_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buffer); - -/* allocate physical memory region and setup sgt and pages. */ -int exynos_drm_alloc_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buf, - unsigned int flags); - -/* release physical memory region, sgt and pages. */ -void exynos_drm_free_buf(struct drm_device *dev, - unsigned int flags, - struct exynos_drm_gem_buf *buffer); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.c deleted file mode 100644 index 0efb6df..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include <drm/exynos_drm.h> -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" - -#define MAX_EDID 256 -#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ - drm_connector) - -struct exynos_drm_connector { - struct drm_connector drm_connector; - uint32_t encoder_id; - struct exynos_drm_manager *manager; -}; - -/* convert exynos_video_timings to drm_display_mode */ -static inline void -convert_to_display_mode(struct drm_display_mode *mode, - struct exynos_drm_panel_info *panel) -{ - struct fb_videomode *timing = &panel->timing; - DRM_DEBUG_KMS("%s\n", __FILE__); - - mode->clock = timing->pixclock / 1000; - mode->vrefresh = timing->refresh; - - mode->hdisplay = timing->xres; - mode->hsync_start = mode->hdisplay + timing->right_margin; - mode->hsync_end = mode->hsync_start + timing->hsync_len; - mode->htotal = mode->hsync_end + timing->left_margin; - - mode->vdisplay = timing->yres; - mode->vsync_start = mode->vdisplay + timing->lower_margin; - mode->vsync_end = mode->vsync_start + timing->vsync_len; - mode->vtotal = mode->vsync_end + timing->upper_margin; - mode->width_mm = panel->width_mm; - mode->height_mm = panel->height_mm; - - if (timing->vmode & FB_VMODE_INTERLACED) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - - if (timing->vmode & FB_VMODE_DOUBLE) - mode->flags |= DRM_MODE_FLAG_DBLSCAN; -} - -/* convert drm_display_mode to exynos_video_timings */ -static inline void -convert_to_video_timing(struct fb_videomode *timing, - struct drm_display_mode *mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - memset(timing, 0, sizeof(*timing)); - - timing->pixclock = mode->clock * 1000; - timing->refresh = drm_mode_vrefresh(mode); - - timing->xres = mode->hdisplay; - timing->right_margin = mode->hsync_start - mode->hdisplay; - timing->hsync_len = mode->hsync_end - mode->hsync_start; - timing->left_margin = mode->htotal - mode->hsync_end; - - timing->yres = mode->vdisplay; - timing->lower_margin = mode->vsync_start - mode->vdisplay; - timing->vsync_len = mode->vsync_end - mode->vsync_start; - timing->upper_margin = mode->vtotal - mode->vsync_end; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - timing->vmode = FB_VMODE_INTERLACED; - else - timing->vmode = FB_VMODE_NONINTERLACED; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - timing->vmode |= FB_VMODE_DOUBLE; -} - -static int exynos_drm_connector_get_modes(struct drm_connector *connector) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = manager->display_ops; - unsigned int count; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!display_ops) { - DRM_DEBUG_KMS("display_ops is null.\n"); - return 0; - } - - /* - * if get_edid() exists then get_edid() callback of hdmi side - * is called to get edid data through i2c interface else - * get timing from the FIMD driver(display controller). - * - * P.S. in case of lcd panel, count is always 1 if success - * because lcd panel has only one mode. - */ - if (display_ops->get_edid) { - int ret; - void *edid; - - edid = kzalloc(MAX_EDID, GFP_KERNEL); - if (!edid) { - DRM_ERROR("failed to allocate edid\n"); - return 0; - } - - ret = display_ops->get_edid(manager->dev, connector, - edid, MAX_EDID); - if (ret < 0) { - DRM_ERROR("failed to get edid data.\n"); - kfree(edid); - edid = NULL; - return 0; - } - - drm_mode_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); - - kfree(connector->display_info.raw_edid); - connector->display_info.raw_edid = edid; - } else { - struct drm_display_mode *mode = drm_mode_create(connector->dev); - struct exynos_drm_panel_info *panel; - - if (display_ops->get_panel) - panel = display_ops->get_panel(manager->dev); - else { - drm_mode_destroy(connector->dev, mode); - return 0; - } - - convert_to_display_mode(mode, panel); - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); - - count = 1; - } - - return count; -} - -static int exynos_drm_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = manager->display_ops; - struct fb_videomode timing; - int ret = MODE_BAD; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - convert_to_video_timing(&timing, mode); - - if (display_ops && display_ops->check_timing) - if (!display_ops->check_timing(manager->dev, (void *)&timing)) - ret = MODE_OK; - - return ret; -} - -struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct drm_mode_object *obj; - struct drm_encoder *encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - obj = drm_mode_object_find(dev, exynos_connector->encoder_id, - DRM_MODE_OBJECT_ENCODER); - if (!obj) { - DRM_DEBUG_KMS("Unknown ENCODER ID %d\n", - exynos_connector->encoder_id); - return NULL; - } - - encoder = obj_to_encoder(obj); - - return encoder; -} - -static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { - .get_modes = exynos_drm_connector_get_modes, - .mode_valid = exynos_drm_connector_mode_valid, - .best_encoder = exynos_drm_best_encoder, -}; - -static int exynos_drm_connector_fill_modes(struct drm_connector *connector, - unsigned int max_width, unsigned int max_height) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_manager_ops *ops = manager->ops; - unsigned int width, height; - - width = max_width; - height = max_height; - - /* - * if specific driver want to find desired_mode using maxmum - * resolution then get max width and height from that driver. - */ - if (ops && ops->get_max_resol) - ops->get_max_resol(manager->dev, &width, &height); - - return drm_helper_probe_single_connector_modes(connector, width, - height); -} - -/* get detection status of display device. */ -static enum drm_connector_status -exynos_drm_connector_detect(struct drm_connector *connector, bool force) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = - manager->display_ops; - enum drm_connector_status status = connector_status_disconnected; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (display_ops && display_ops->is_connected) { - if (display_ops->is_connected(manager->dev)) - status = connector_status_connected; - else - status = connector_status_disconnected; - } - - return status; -} - -static void exynos_drm_connector_destroy(struct drm_connector *connector) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(exynos_connector); -} - -static struct drm_connector_funcs exynos_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .fill_modes = exynos_drm_connector_fill_modes, - .detect = exynos_drm_connector_detect, - .destroy = exynos_drm_connector_destroy, -}; - -struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, - struct drm_encoder *encoder) -{ - struct exynos_drm_connector *exynos_connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct drm_connector *connector; - int type; - int err; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL); - if (!exynos_connector) { - DRM_ERROR("failed to allocate connector\n"); - return NULL; - } - - connector = &exynos_connector->drm_connector; - - switch (manager->display_ops->type) { - case EXYNOS_DISPLAY_TYPE_HDMI: - type = DRM_MODE_CONNECTOR_HDMIA; - connector->interlace_allowed = true; - connector->polled = DRM_CONNECTOR_POLL_HPD; - break; - case EXYNOS_DISPLAY_TYPE_LCD: - type = DRM_MODE_CONNECTOR_LVDS; - break; - case EXYNOS_DISPLAY_TYPE_VIDI: - type = DRM_MODE_CONNECTOR_VIRTUAL; - connector->polled = DRM_CONNECTOR_POLL_HPD; - break; - default: - type = DRM_MODE_CONNECTOR_Unknown; - break; - } - - drm_connector_init(dev, connector, &exynos_connector_funcs, type); - drm_connector_helper_add(connector, &exynos_connector_helper_funcs); - - err = drm_sysfs_connector_add(connector); - if (err) - goto err_connector; - - exynos_connector->encoder_id = encoder->base.id; - exynos_connector->manager = manager; - connector->encoder = encoder; - - err = drm_mode_connector_attach_encoder(connector, encoder); - if (err) { - DRM_ERROR("failed to attach a connector to a encoder\n"); - goto err_sysfs; - } - - DRM_DEBUG_KMS("connector has been created\n"); - - return connector; - -err_sysfs: - drm_sysfs_connector_remove(connector); -err_connector: - drm_connector_cleanup(connector); - kfree(exynos_connector); - return NULL; -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.h deleted file mode 100644 index 1c7b2b5..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_connector.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_CONNECTOR_H_ -#define _EXYNOS_DRM_CONNECTOR_H_ - -struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, - struct drm_encoder *encoder); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_core.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_core.c deleted file mode 100644 index eaf630d..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_core.c +++ /dev/null @@ -1,217 +0,0 @@ -/* exynos_drm_core.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_connector.h" -#include "exynos_drm_fbdev.h" - -static LIST_HEAD(exynos_drm_subdrv_list); -static struct drm_device *drm_dev; - -static int exynos_drm_subdrv_probe(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - struct drm_encoder *encoder; - struct drm_connector *connector; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (subdrv->probe) { - int ret; - - /* - * this probe callback would be called by sub driver - * after setting of all resources to this sub driver, - * such as clock, irq and register map are done or by load() - * of exynos drm driver. - * - * P.S. note that this driver is considered for modularization. - */ - ret = subdrv->probe(dev, subdrv->dev); - if (ret) - return ret; - } - - if (!subdrv->manager) - return 0; - - subdrv->manager->dev = subdrv->dev; - - /* create and initialize a encoder for this sub driver. */ - encoder = exynos_drm_encoder_create(dev, subdrv->manager, - (1 << MAX_CRTC) - 1); - if (!encoder) { - DRM_ERROR("failed to create encoder\n"); - return -EFAULT; - } - - /* - * create and initialize a connector for this sub driver and - * attach the encoder created above to the connector. - */ - connector = exynos_drm_connector_create(dev, encoder); - if (!connector) { - DRM_ERROR("failed to create connector\n"); - encoder->funcs->destroy(encoder); - return -EFAULT; - } - - subdrv->encoder = encoder; - subdrv->connector = connector; - - return 0; -} - -static void exynos_drm_subdrv_remove(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (subdrv->remove) - subdrv->remove(dev); - - if (subdrv->encoder) { - struct drm_encoder *encoder = subdrv->encoder; - encoder->funcs->destroy(encoder); - subdrv->encoder = NULL; - } - - if (subdrv->connector) { - struct drm_connector *connector = subdrv->connector; - connector->funcs->destroy(connector); - subdrv->connector = NULL; - } -} - -int exynos_drm_device_register(struct drm_device *dev) -{ - struct exynos_drm_subdrv *subdrv, *n; - int err; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!dev) - return -EINVAL; - - drm_dev = dev; - - list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { - subdrv->drm_dev = dev; - err = exynos_drm_subdrv_probe(dev, subdrv); - if (err) { - DRM_DEBUG("exynos drm subdrv probe failed.\n"); - list_del(&subdrv->list); - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_device_register); - -int exynos_drm_device_unregister(struct drm_device *dev) -{ - struct exynos_drm_subdrv *subdrv; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!dev) { - WARN(1, "Unexpected drm device unregister!\n"); - return -EINVAL; - } - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) - exynos_drm_subdrv_remove(dev, subdrv); - - drm_dev = NULL; - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); - -int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!subdrv) - return -EINVAL; - - list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register); - -int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!subdrv) - return -EINVAL; - - list_del(&subdrv->list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); - -int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) -{ - struct exynos_drm_subdrv *subdrv; - int ret; - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { - if (subdrv->open) { - ret = subdrv->open(dev, subdrv->dev, file); - if (ret) - goto err; - } - } - - return 0; - -err: - list_for_each_entry_reverse(subdrv, &subdrv->list, list) { - if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); - } - return ret; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_open); - -void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) -{ - struct exynos_drm_subdrv *subdrv; - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { - if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); - } -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.c deleted file mode 100644 index 4afb625..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.c +++ /dev/null @@ -1,436 +0,0 @@ -/* exynos_drm_crtc.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_crtc.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_gem.h" - -#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\ - drm_crtc) - -/* - * Exynos specific crtc structure. - * - * @drm_crtc: crtc object. - * @overlay: contain information common to display controller and hdmi and - * contents of this overlay object would be copied to sub driver size. - * @pipe: a crtc index created at load() with a new crtc object creation - * and the crtc object would be set to private->crtc array - * to get a crtc object corresponding to this pipe from private->crtc - * array when irq interrupt occured. the reason of using this pipe is that - * drm framework doesn't support multiple irq yet. - * we can refer to the crtc to current hardware interrupt occured through - * this pipe value. - * @dpms: store the crtc dpms value - */ -struct exynos_drm_crtc { - struct drm_crtc drm_crtc; - struct exynos_drm_overlay overlay; - unsigned int pipe; - unsigned int dpms; -}; - -static void exynos_drm_crtc_apply(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_overlay *overlay = &exynos_crtc->overlay; - - exynos_drm_fn_encoder(crtc, overlay, - exynos_drm_encoder_crtc_mode_set); - exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, - exynos_drm_encoder_crtc_commit); -} - -int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, - struct drm_framebuffer *fb, - struct drm_display_mode *mode, - struct exynos_drm_crtc_pos *pos) -{ - struct exynos_drm_gem_buf *buffer; - unsigned int actual_w; - unsigned int actual_h; - int nr = exynos_drm_format_num_buffers(fb->pixel_format); - int i; - - for (i = 0; i < nr; i++) { - buffer = exynos_drm_fb_buffer(fb, i); - if (!buffer) { - DRM_LOG_KMS("buffer is null\n"); - return -EFAULT; - } - - overlay->dma_addr[i] = buffer->dma_addr; - overlay->vaddr[i] = buffer->kvaddr; - - DRM_DEBUG_KMS("buffer: %d, vaddr = 0x%lx, dma_addr = 0x%lx\n", - i, (unsigned long)overlay->vaddr[i], - (unsigned long)overlay->dma_addr[i]); - } - - actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w); - actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h); - - /* set drm framebuffer data. */ - overlay->fb_x = pos->fb_x; - overlay->fb_y = pos->fb_y; - overlay->fb_width = fb->width; - overlay->fb_height = fb->height; - overlay->src_width = pos->src_w; - overlay->src_height = pos->src_h; - overlay->bpp = fb->bits_per_pixel; - overlay->pitch = fb->pitches[0]; - overlay->pixel_format = fb->pixel_format; - - /* set overlay range to be displayed. */ - overlay->crtc_x = pos->crtc_x; - overlay->crtc_y = pos->crtc_y; - overlay->crtc_width = actual_w; - overlay->crtc_height = actual_h; - - /* set drm mode data. */ - overlay->mode_width = mode->hdisplay; - overlay->mode_height = mode->vdisplay; - overlay->refresh = mode->vrefresh; - overlay->scan_flag = mode->flags; - - DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)", - overlay->crtc_x, overlay->crtc_y, - overlay->crtc_width, overlay->crtc_height); - - return 0; -} - -static int exynos_drm_crtc_update(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc; - struct exynos_drm_overlay *overlay; - struct exynos_drm_crtc_pos pos; - struct drm_display_mode *mode = &crtc->mode; - struct drm_framebuffer *fb = crtc->fb; - - if (!mode || !fb) - return -EINVAL; - - exynos_crtc = to_exynos_crtc(crtc); - overlay = &exynos_crtc->overlay; - - memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos)); - - /* it means the offset of framebuffer to be displayed. */ - pos.fb_x = crtc->x; - pos.fb_y = crtc->y; - - /* OSD position to be displayed. */ - pos.crtc_x = 0; - pos.crtc_y = 0; - pos.crtc_w = fb->width - crtc->x; - pos.crtc_h = fb->height - crtc->y; - pos.src_w = pos.crtc_w; - pos.src_h = pos.crtc_h; - - return exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos); -} - -static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); - - if (exynos_crtc->dpms == mode) { - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); - return; - } - - mutex_lock(&dev->struct_mutex); - - switch (mode) { - case DRM_MODE_DPMS_ON: - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_crtc_dpms); - exynos_crtc->dpms = mode; - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_crtc_dpms); - exynos_crtc->dpms = mode; - break; - default: - DRM_ERROR("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&dev->struct_mutex); -} - -static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL. */ -} - -static void exynos_drm_crtc_commit(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * when set_crtc is requested from user or at booting time, - * crtc->commit would be called without dpms call so if dpms is - * no power on then crtc->dpms should be called - * with DRM_MODE_DPMS_ON for the hardware power to be on. - */ - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) { - int mode = DRM_MODE_DPMS_ON; - - /* - * enable hardware(power on) to all encoders hdmi connected - * to current crtc. - */ - exynos_drm_crtc_dpms(crtc, mode); - /* - * enable dma to all encoders connected to current crtc and - * lcd panel. - */ - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_dpms_from_crtc); - } - - exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, - exynos_drm_encoder_crtc_commit); -} - -static bool -exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL */ - return true; -} - -static int -exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * copy the mode data adjusted by mode_fixup() into crtc->mode - * so that hardware can be seet to proper mode. - */ - memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); - - return exynos_drm_crtc_update(crtc); -} - -static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = exynos_drm_crtc_update(crtc); - if (ret) - return ret; - - exynos_drm_crtc_apply(crtc); - - return ret; -} - -static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - /* drm framework doesn't check NULL */ -} - -static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { - .dpms = exynos_drm_crtc_dpms, - .prepare = exynos_drm_crtc_prepare, - .commit = exynos_drm_crtc_commit, - .mode_fixup = exynos_drm_crtc_mode_fixup, - .mode_set = exynos_drm_crtc_mode_set, - .mode_set_base = exynos_drm_crtc_mode_set_base, - .load_lut = exynos_drm_crtc_load_lut, -}; - -static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_private *dev_priv = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_framebuffer *old_fb = crtc->fb; - int ret = -EINVAL; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - if (event) { - /* - * the pipe from user always is 0 so we can set pipe number - * of current owner to event. - */ - event->pipe = exynos_crtc->pipe; - - ret = drm_vblank_get(dev, exynos_crtc->pipe); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter\n"); - list_del(&event->base.link); - - goto out; - } - - list_add_tail(&event->base.link, - &dev_priv->pageflip_event_list); - - crtc->fb = fb; - ret = exynos_drm_crtc_update(crtc); - if (ret) { - crtc->fb = old_fb; - drm_vblank_put(dev, exynos_crtc->pipe); - list_del(&event->base.link); - - goto out; - } - - /* - * the values related to a buffer of the drm framebuffer - * to be applied should be set at here. because these values - * first, are set to shadow registers and then to - * real registers at vsync front porch period. - */ - exynos_drm_crtc_apply(crtc); - } -out: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_private *private = crtc->dev->dev_private; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - private->crtc[exynos_crtc->pipe] = NULL; - - drm_crtc_cleanup(crtc); - kfree(exynos_crtc); -} - -static struct drm_crtc_funcs exynos_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, - .page_flip = exynos_drm_crtc_page_flip, - .destroy = exynos_drm_crtc_destroy, -}; - -struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - return &exynos_crtc->overlay; -} - -int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr) -{ - struct exynos_drm_crtc *exynos_crtc; - struct exynos_drm_private *private = dev->dev_private; - struct drm_crtc *crtc; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); - if (!exynos_crtc) { - DRM_ERROR("failed to allocate exynos crtc\n"); - return -ENOMEM; - } - - exynos_crtc->pipe = nr; - exynos_crtc->dpms = DRM_MODE_DPMS_OFF; - exynos_crtc->overlay.zpos = DEFAULT_ZPOS; - crtc = &exynos_crtc->drm_crtc; - - private->crtc[nr] = crtc; - - drm_crtc_init(dev, crtc, &exynos_crtc_funcs); - drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); - - return 0; -} - -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = - to_exynos_crtc(private->crtc[crtc]); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) - return -EPERM; - - exynos_drm_fn_encoder(private->crtc[crtc], &crtc, - exynos_drm_enable_vblank); - - return 0; -} - -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = - to_exynos_crtc(private->crtc[crtc]); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) - return; - - exynos_drm_fn_encoder(private->crtc[crtc], &crtc, - exynos_drm_disable_vblank); -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.h deleted file mode 100644 index 16b8e21..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_crtc.h +++ /dev/null @@ -1,67 +0,0 @@ -/* exynos_drm_crtc.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_CRTC_H_ -#define _EXYNOS_DRM_CRTC_H_ - -struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev, - struct drm_crtc *crtc); -int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr); -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); - -/* - * Exynos specific crtc postion structure. - * - * @fb_x: offset x on a framebuffer to be displyed - * - the unit is screen coordinates. - * @fb_y: offset y on a framebuffer to be displayed - * - the unit is screen coordinates. - * @src_w: width of source area to be displayed from a framebuffer. - * @src_h: height of source area to be displayed from a framebuffer. - * @crtc_x: offset x on hardware screen. - * @crtc_y: offset y on hardware screen. - * @crtc_w: width of hardware screen. - * @crtc_h: height of hardware screen. - */ -struct exynos_drm_crtc_pos { - unsigned int fb_x; - unsigned int fb_y; - unsigned int src_w; - unsigned int src_h; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_w; - unsigned int crtc_h; -}; - -int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, - struct drm_framebuffer *fb, - struct drm_display_mode *mode, - struct exynos_drm_crtc_pos *pos); -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.c deleted file mode 100644 index 9b97057..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.c +++ /dev/null @@ -1,288 +0,0 @@ -/* exynos_drm_dmabuf.c - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" - -#include <linux/dma-buf.h> - -static struct sg_table *exynos_pages_to_sg(struct page **pages, int nr_pages, - unsigned int page_size) -{ - struct sg_table *sgt = NULL; - struct scatterlist *sgl; - int i, ret; - - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); - if (!sgt) - goto out; - - ret = sg_alloc_table(sgt, nr_pages, GFP_KERNEL); - if (ret) - goto err_free_sgt; - - if (page_size < PAGE_SIZE) - page_size = PAGE_SIZE; - - for_each_sg(sgt->sgl, sgl, nr_pages, i) - sg_set_page(sgl, pages[i], page_size, 0); - - return sgt; - -err_free_sgt: - kfree(sgt); - sgt = NULL; -out: - return NULL; -} - -static struct sg_table *exynos_gem_map_dma_buf( - struct dma_buf_attachment *attach, - enum dma_data_direction dir) -{ - struct exynos_drm_gem_obj *gem_obj = attach->dmabuf->priv; - struct drm_device *dev = gem_obj->base.dev; - struct exynos_drm_gem_buf *buf; - struct sg_table *sgt = NULL; - unsigned int npages; - int nents; - - DRM_DEBUG_PRIME("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - buf = gem_obj->buffer; - - /* there should always be pages allocated. */ - if (!buf->pages) { - DRM_ERROR("pages is null.\n"); - goto err_unlock; - } - - npages = buf->size / buf->page_size; - - sgt = exynos_pages_to_sg(buf->pages, npages, buf->page_size); - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir); - - DRM_DEBUG_PRIME("npages = %d buffer size = 0x%lx page_size = 0x%lx\n", - npages, buf->size, buf->page_size); - -err_unlock: - mutex_unlock(&dev->struct_mutex); - return sgt; -} - -static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *sgt, - enum dma_data_direction dir) -{ - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); - sg_free_table(sgt); - kfree(sgt); - sgt = NULL; -} - -static void exynos_dmabuf_release(struct dma_buf *dmabuf) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv; - - DRM_DEBUG_PRIME("%s\n", __FILE__); - - /* - * exynos_dmabuf_release() call means that file object's - * f_count is 0 and it calls drm_gem_object_handle_unreference() - * to drop the references that these values had been increased - * at drm_prime_handle_to_fd() - */ - if (exynos_gem_obj->base.export_dma_buf == dmabuf) { - exynos_gem_obj->base.export_dma_buf = NULL; - - /* - * drop this gem object refcount to release allocated buffer - * and resources. - */ - drm_gem_object_unreference_unlocked(&exynos_gem_obj->base); - } -} - -static void *exynos_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num) -{ - return NULL; -} - -static void exynos_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num, - void *addr) -{ - -} - -static void *exynos_gem_dmabuf_kmap(struct dma_buf *dma_buf, - unsigned long page_num) -{ - return NULL; -} - -static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, - unsigned long page_num, void *addr) -{ - -} - -static struct dma_buf_ops exynos_dmabuf_ops = { - .map_dma_buf = exynos_gem_map_dma_buf, - .unmap_dma_buf = exynos_gem_unmap_dma_buf, - .kmap = exynos_gem_dmabuf_kmap, - .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, - .kunmap = exynos_gem_dmabuf_kunmap, - .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, - .release = exynos_dmabuf_release, -}; - -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, - struct drm_gem_object *obj, int flags) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - - return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops, - exynos_gem_obj->base.size, 0600); -} - -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, - struct dma_buf *dma_buf) -{ - struct dma_buf_attachment *attach; - struct sg_table *sgt; - struct scatterlist *sgl; - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buffer; - struct page *page; - int ret; - - DRM_DEBUG_PRIME("%s\n", __FILE__); - - /* is this one of own objects? */ - if (dma_buf->ops == &exynos_dmabuf_ops) { - struct drm_gem_object *obj; - - exynos_gem_obj = dma_buf->priv; - obj = &exynos_gem_obj->base; - - /* is it from our device? */ - if (obj->dev == drm_dev) { - drm_gem_object_reference(obj); - return obj; - } - } - - attach = dma_buf_attach(dma_buf, drm_dev->dev); - if (IS_ERR(attach)) - return ERR_PTR(-EINVAL); - - - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto err_buf_detach; - } - - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); - if (!buffer) { - DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); - ret = -ENOMEM; - goto err_unmap_attach; - } - - buffer->pages = kzalloc(sizeof(*page) * sgt->nents, GFP_KERNEL); - if (!buffer->pages) { - DRM_ERROR("failed to allocate pages.\n"); - ret = -ENOMEM; - goto err_free_buffer; - } - - exynos_gem_obj = exynos_drm_gem_init(drm_dev, dma_buf->size); - if (!exynos_gem_obj) { - ret = -ENOMEM; - goto err_free_pages; - } - - sgl = sgt->sgl; - - if (sgt->nents == 1) { - buffer->dma_addr = sg_dma_address(sgt->sgl); - buffer->size = sg_dma_len(sgt->sgl); - } else { - unsigned int i = 0; - - buffer->dma_addr = sg_dma_address(sgl); - while (i < sgt->nents) { - buffer->pages[i] = sg_page(sgl); - buffer->size += sg_dma_len(sgl); - sgl = sg_next(sgl); - i++; - } - } - - exynos_gem_obj->buffer = buffer; - buffer->sgt = sgt; - exynos_gem_obj->base.import_attach = attach; - - /* register buffer information to private buffer manager. */ - ret = register_buf_to_priv_mgr(exynos_gem_obj, - &exynos_gem_obj->priv_handle, - &exynos_gem_obj->priv_id); - if (ret < 0) - goto err_release_gem; - - DRM_DEBUG_PRIME("ump id = %d, dma_addr = 0x%x, size = 0x%lx\n", - exynos_gem_obj->priv_id, - buffer->dma_addr, - buffer->size); - - return &exynos_gem_obj->base; - -err_release_gem: - drm_gem_object_release(&exynos_gem_obj->base); - kfree(exynos_gem_obj); - exynos_gem_obj = NULL; -err_free_pages: - kfree(buffer->pages); - buffer->pages = NULL; -err_free_buffer: - kfree(buffer); - buffer = NULL; -err_unmap_attach: - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -err_buf_detach: - dma_buf_detach(dma_buf, attach); - return ERR_PTR(ret); -} - -MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DRM DMABUF Module"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.h deleted file mode 100644 index 662a8f9..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_dmabuf.h +++ /dev/null @@ -1,39 +0,0 @@ -/* exynos_drm_dmabuf.h - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_DMABUF_H_ -#define _EXYNOS_DRM_DMABUF_H_ - -#ifdef CONFIG_DRM_EXYNOS_DMABUF -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, - struct drm_gem_object *obj, int flags); - -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, - struct dma_buf *dma_buf); -#else -#define exynos_dmabuf_prime_export NULL -#define exynos_dmabuf_prime_import NULL -#endif -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.c deleted file mode 100644 index 340a8d6..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc_helper.h" - -#include <drm/exynos_drm.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_fbdev.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_g2d.h" -#include "exynos_drm_rotator.h" -#include "exynos_drm_plane.h" -#include "exynos_drm_vidi.h" -#include "exynos_drm_dmabuf.h" - -#define DRIVER_NAME "exynos-drm" -#define DRIVER_DESC "Samsung SoC DRM" -#define DRIVER_DATE "20110530" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 - -#define VBLANK_OFF_DELAY 50000 - -static int exynos_drm_list_gem_info(int id, void *ptr, void *data) -{ - struct drm_gem_object *obj = ptr; - struct drm_file *filp = data; - struct exynos_drm_gem_obj *gem = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = gem->buffer; - - DRM_INFO("%3d \t%3d \t%2d \t\t%2d \t0x%lx \t0x%x \t0x%lx "\ - "\t%2d \t\t%2d \t\t%2d\n", - filp->pid, - id, - atomic_read(&obj->refcount.refcount), - atomic_read(&obj->handle_count), - gem->size, - gem->flags, - buf->page_size, - buf->pfnmap, - obj->export_dma_buf ? 1 : 0, - obj->import_attach ? 1 : 0); - - return 0; -} - -static ssize_t exynos_drm_show_gem_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *drm_dev = dev_get_drvdata(dev); - struct drm_file *filp; - - DRM_INFO("pid \thandle \trefcount \thcount \tsize \t\tflags "\ - "\tpage_size \tpfnmap \texport_to_fd \timport_from_fd\n"); - - list_for_each_entry(filp, &drm_dev->filelist, lhead) - idr_for_each(&filp->object_idr, &exynos_drm_list_gem_info, - filp); - - return strlen(buf); -} - -static const struct device_attribute exynos_device_attrs[] = { - __ATTR(gem_info, S_IRUGO, exynos_drm_show_gem_info, NULL) -}; - -static int exynos_drm_load(struct drm_device *dev, unsigned long flags) -{ - struct exynos_drm_private *private; - int ret; - int nr; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); - if (!private) { - DRM_ERROR("failed to allocate private\n"); - return -ENOMEM; - } - - INIT_LIST_HEAD(&private->pageflip_event_list); - dev->dev_private = (void *)private; - - drm_mode_config_init(dev); - - /* init kms poll for handling hpd */ - drm_kms_helper_poll_init(dev); - - exynos_drm_mode_config_init(dev); - - /* - * EXYNOS4 is enough to have two CRTCs and each crtc would be used - * without dependency of hardware. - */ - for (nr = 0; nr < MAX_CRTC; nr++) { - ret = exynos_drm_crtc_create(dev, nr); - if (ret) - goto err_crtc; - } - - for (nr = 0; nr < MAX_PLANE; nr++) { - ret = exynos_plane_init(dev, nr); - if (ret) - goto err_crtc; - } - - ret = drm_vblank_init(dev, MAX_CRTC); - if (ret) - goto err_crtc; - - /* - * probe sub drivers such as display controller and hdmi driver, - * that were registered at probe() of platform driver - * to the sub driver and create encoder and connector for them. - */ - ret = exynos_drm_device_register(dev); - if (ret) - goto err_vblank; - - /* setup possible_clones. */ - exynos_drm_encoder_setup(dev); - - /* - * create and configure fb helper and also exynos specific - * fbdev object. - */ - ret = exynos_drm_fbdev_init(dev); - if (ret) { - DRM_ERROR("failed to initialize drm fbdev\n"); - goto err_drm_device; - } - - drm_vblank_offdelay = VBLANK_OFF_DELAY; - - ret = device_create_file(dev->dev, &exynos_device_attrs[0]); - if (ret < 0) - DRM_DEBUG_DRIVER("failed to create sysfs.\n"); - - return 0; - -err_drm_device: - exynos_drm_device_unregister(dev); -err_vblank: - drm_vblank_cleanup(dev); -err_crtc: - drm_mode_config_cleanup(dev); - kfree(private); - - return ret; -} - -static int exynos_drm_unload(struct drm_device *dev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_fbdev_fini(dev); - exynos_drm_device_unregister(dev); - drm_vblank_cleanup(dev); - drm_kms_helper_poll_fini(dev); - drm_mode_config_cleanup(dev); - kfree(dev->dev_private); - - dev->dev_private = NULL; - - return 0; -} - -static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); - if (!file_priv) - return -ENOMEM; - - drm_prime_init_file_private(&file->prime); - file->driver_priv = file_priv; - - return exynos_drm_subdrv_open(dev, file); -} - -static void exynos_drm_preclose(struct drm_device *dev, - struct drm_file *file) -{ - struct exynos_drm_private *private = dev->dev_private; - struct drm_pending_vblank_event *e, *t; - unsigned long flags; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - /* release events of current file */ - spin_lock_irqsave(&dev->event_lock, flags); - list_for_each_entry_safe(e, t, &private->pageflip_event_list, - base.link) { - if (e->base.file_priv == file) { - list_del(&e->base.link); - e->base.destroy(&e->base); - } - } - drm_prime_destroy_file_private(&file->prime); - spin_unlock_irqrestore(&dev->event_lock, flags); - - exynos_drm_subdrv_close(dev, file); -} - -static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!file->driver_priv) - return; - - kfree(file->driver_priv); - file->driver_priv = NULL; -} - -static void exynos_drm_lastclose(struct drm_device *dev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_fbdev_restore_mode(dev); -} - -static struct vm_operations_struct exynos_drm_gem_vm_ops = { - .fault = exynos_drm_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static struct drm_ioctl_desc exynos_ioctls[] = { - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, - DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET, - exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP, - exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_USERPTR, - exynos_drm_gem_userptr_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, - exynos_drm_gem_get_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_EXPORT_UMP, - exynos_drm_gem_export_ump_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CACHE_OP, - exynos_drm_gem_cache_op_ioctl, DRM_UNLOCKED), - /* temporary ioctl commands. */ - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET_PHY, - exynos_drm_gem_get_phy_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_PHY_IMP, - exynos_drm_gem_phy_imp_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, - exynos_plane_set_zpos_ioctl, DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, - vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH), - - DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER, - exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST, - exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, - exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH), - - DRM_IOCTL_DEF_DRV(EXYNOS_ROTATOR_EXEC, - exynos_drm_rotator_exec_ioctl, DRM_UNLOCKED | DRM_AUTH), -}; - -static const struct file_operations exynos_drm_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .mmap = exynos_drm_gem_mmap, - .poll = drm_poll, - .read = drm_read, - .unlocked_ioctl = drm_ioctl, - .release = drm_release, -}; - -static struct drm_driver exynos_drm_driver = { - .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM | - DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, - .load = exynos_drm_load, - .unload = exynos_drm_unload, - .open = exynos_drm_open, - .preclose = exynos_drm_preclose, - .lastclose = exynos_drm_lastclose, - .postclose = exynos_drm_postclose, - .get_vblank_counter = drm_vblank_count, - .enable_vblank = exynos_drm_crtc_enable_vblank, - .disable_vblank = exynos_drm_crtc_disable_vblank, - .gem_init_object = exynos_drm_gem_init_object, - .gem_free_object = exynos_drm_gem_free_object, - .gem_vm_ops = &exynos_drm_gem_vm_ops, - .gem_close_object = &exynos_drm_gem_close_object, - .dumb_create = exynos_drm_gem_dumb_create, - .dumb_map_offset = exynos_drm_gem_dumb_map_offset, - .dumb_destroy = exynos_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_export = exynos_dmabuf_prime_export, - .gem_prime_import = exynos_dmabuf_prime_import, - .ioctls = exynos_ioctls, - .fops = &exynos_drm_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, -}; - -static int exynos_drm_platform_probe(struct platform_device *pdev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); - - return drm_platform_init(&exynos_drm_driver, pdev); -} - -static int exynos_drm_platform_remove(struct platform_device *pdev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - drm_platform_exit(&exynos_drm_driver, pdev); - - return 0; -} - -static struct platform_driver exynos_drm_platform_driver = { - .probe = exynos_drm_platform_probe, - .remove = __devexit_p(exynos_drm_platform_remove), - .driver = { - .owner = THIS_MODULE, - .name = "exynos-drm", - }, -}; - -static int __init exynos_drm_init(void) -{ - int ret; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - -#ifdef CONFIG_DRM_EXYNOS_FIMD - ret = platform_driver_register(&fimd_driver); - if (ret < 0) - goto out_fimd; -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - ret = platform_driver_register(&hdmi_driver); - if (ret < 0) - goto out_hdmi; - ret = platform_driver_register(&mixer_driver); - if (ret < 0) - goto out_mixer; - ret = platform_driver_register(&exynos_drm_common_hdmi_driver); - if (ret < 0) - goto out_common_hdmi; -#endif - -#ifdef CONFIG_DRM_EXYNOS_VIDI - ret = platform_driver_register(&vidi_driver); - if (ret < 0) - goto out_vidi; -#endif - -#ifdef CONFIG_DRM_EXYNOS_G2D - ret = platform_driver_register(&g2d_driver); - if (ret < 0) - goto out_g2d; -#endif - -#ifdef CONFIG_DRM_EXYNOS_ROTATOR - ret = platform_driver_register(&rotator_driver); - if (ret < 0) - goto out_rotator; -#endif - - ret = platform_driver_register(&exynos_drm_platform_driver); - if (ret < 0) - goto out; - - return 0; - -out: -#ifdef CONFIG_DRM_EXYNOS_ROTATOR - platform_driver_unregister(&rotator_driver); -out_rotator: -#endif - -#ifdef CONFIG_DRM_EXYNOS_G2D - platform_driver_unregister(&g2d_driver); -out_g2d: -#endif - -#ifdef CONFIG_DRM_EXYNOS_VIDI - platform_driver_unregister(&vidi_driver); -out_vidi: -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&exynos_drm_common_hdmi_driver); -out_common_hdmi: - platform_driver_unregister(&mixer_driver); -out_mixer: - platform_driver_unregister(&hdmi_driver); -out_hdmi: -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -out_fimd: -#endif - return ret; -} - -static void __exit exynos_drm_exit(void) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - platform_driver_unregister(&exynos_drm_platform_driver); - -#ifdef CONFIG_DRM_EXYNOS_ROTATOR - platform_driver_unregister(&rotator_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_G2D - platform_driver_unregister(&g2d_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_VIDI - platform_driver_unregister(&vidi_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&exynos_drm_common_hdmi_driver); - platform_driver_unregister(&mixer_driver); - platform_driver_unregister(&hdmi_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -#endif -} - -module_init(exynos_drm_init); -module_exit(exynos_drm_exit); - -MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); -MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); -MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DRM Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.h deleted file mode 100644 index 463b086..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_drv.h +++ /dev/null @@ -1,335 +0,0 @@ -/* exynos_drm_drv.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_DRV_H_ -#define _EXYNOS_DRM_DRV_H_ - -#include <linux/module.h> -#include "drm.h" - -#define MAX_CRTC 3 -#define MAX_PLANE 5 -#define MAX_FB_BUFFER 4 -#define DEFAULT_ZPOS -1 - -struct drm_device; -struct exynos_drm_overlay; -struct drm_connector; - -extern unsigned int drm_vblank_offdelay; - -/* this enumerates display type. */ -enum exynos_drm_output_type { - EXYNOS_DISPLAY_TYPE_NONE, - /* RGB or CPU Interface. */ - EXYNOS_DISPLAY_TYPE_LCD, - /* HDMI Interface. */ - EXYNOS_DISPLAY_TYPE_HDMI, - /* Virtual Display Interface. */ - EXYNOS_DISPLAY_TYPE_VIDI, -}; - -/* - * Exynos drm overlay ops structure. - * - * @mode_set: copy drm overlay info to hw specific overlay info. - * @commit: apply hardware specific overlay data to registers. - * @disable: disable hardware specific overlay. - */ -struct exynos_drm_overlay_ops { - void (*mode_set)(struct device *subdrv_dev, - struct exynos_drm_overlay *overlay); - void (*commit)(struct device *subdrv_dev, int zpos); - void (*disable)(struct device *subdrv_dev, int zpos); -}; - -/* - * Exynos drm common overlay structure. - * - * @fb_x: offset x on a framebuffer to be displayed. - * - the unit is screen coordinates. - * @fb_y: offset y on a framebuffer to be displayed. - * - the unit is screen coordinates. - * @fb_width: width of a framebuffer. - * @fb_height: height of a framebuffer. - * @src_width: width of a partial image to be displayed from framebuffer. - * @src_height: height of a partial image to be displayed from framebuffer. - * @crtc_x: offset x on hardware screen. - * @crtc_y: offset y on hardware screen. - * @crtc_width: window width to be displayed (hardware screen). - * @crtc_height: window height to be displayed (hardware screen). - * @mode_width: width of screen mode. - * @mode_height: height of screen mode. - * @refresh: refresh rate. - * @scan_flag: interlace or progressive way. - * (it could be DRM_MODE_FLAG_*) - * @bpp: pixel size.(in bit) - * @pixel_format: fourcc pixel format of this overlay - * @dma_addr: array of bus(accessed by dma) address to the memory region - * allocated for a overlay. - * @vaddr: array of virtual memory addresss to this overlay. - * @zpos: order of overlay layer(z position). - * @default_win: a window to be enabled. - * @color_key: color key on or off. - * @index_color: if using color key feature then this value would be used - * as index color. - * @local_path: in case of lcd type, local path mode on or off. - * @transparency: transparency on or off. - * @activated: activated or not. - * - * this structure is common to exynos SoC and its contents would be copied - * to hardware specific overlay info. - */ -struct exynos_drm_overlay { - unsigned int fb_x; - unsigned int fb_y; - unsigned int fb_width; - unsigned int fb_height; - unsigned int src_width; - unsigned int src_height; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_width; - unsigned int crtc_height; - unsigned int mode_width; - unsigned int mode_height; - unsigned int refresh; - unsigned int scan_flag; - unsigned int bpp; - unsigned int pitch; - uint32_t pixel_format; - dma_addr_t dma_addr[MAX_FB_BUFFER]; - void __iomem *vaddr[MAX_FB_BUFFER]; - int zpos; - - bool default_win; - bool color_key; - unsigned int index_color; - bool local_path; - bool transparency; - bool activated; -}; - -/* - * Exynos DRM Display Structure. - * - this structure is common to analog tv, digital tv and lcd panel. - * - * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. - * @is_connected: check for that display is connected or not. - * @get_edid: get edid modes from display driver. - * @get_panel: get panel object from display driver. - * @check_timing: check if timing is valid or not. - * @power_on: display device on or off. - */ -struct exynos_drm_display_ops { - enum exynos_drm_output_type type; - bool (*is_connected)(struct device *dev); - int (*get_edid)(struct device *dev, struct drm_connector *connector, - u8 *edid, int len); - void *(*get_panel)(struct device *dev); - int (*check_timing)(struct device *dev, void *timing); - int (*power_on)(struct device *dev, int mode); -}; - -/* - * Exynos drm manager ops - * - * @dpms: control device power. - * @apply: set timing, vblank and overlay data to registers. - * @mode_fixup: fix mode data comparing to hw specific display mode. - * @mode_set: convert drm_display_mode to hw specific display mode and - * would be called by encoder->mode_set(). - * @get_max_resol: get maximum resolution to specific hardware. - * @commit: set current hw specific display mode to hw. - * @enable_vblank: specific driver callback for enabling vblank interrupt. - * @disable_vblank: specific driver callback for disabling vblank interrupt. - */ -struct exynos_drm_manager_ops { - void (*dpms)(struct device *subdrv_dev, int mode); - void (*apply)(struct device *subdrv_dev); - void (*mode_fixup)(struct device *subdrv_dev, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - void (*mode_set)(struct device *subdrv_dev, void *mode); - void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, - unsigned int *height); - void (*commit)(struct device *subdrv_dev); - int (*enable_vblank)(struct device *subdrv_dev); - void (*disable_vblank)(struct device *subdrv_dev); -}; - -/* - * Exynos drm common manager structure. - * - * @dev: pointer to device object for subdrv device driver. - * sub drivers such as display controller or hdmi driver, - * have their own device object. - * @ops: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control hardware global registers. - * @overlay_ops: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control hardware overlay reigsters. - * @display: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control display devices such as - * analog tv, digital tv and lcd panel and also get timing data for them. - */ -struct exynos_drm_manager { - struct device *dev; - int pipe; - struct exynos_drm_manager_ops *ops; - struct exynos_drm_overlay_ops *overlay_ops; - struct exynos_drm_display_ops *display_ops; -}; - -struct iommu_info_node { - struct list_head list; - dma_addr_t dma_addr; - void *gem_obj; - /* TODO */ -}; - -/* - * Exynos drm g2d private structure - * - * @dev: device object to device driver for using iommu. - * @iommu_map_list: list head to iommu map information. - * each device driver using iommu should have its own iommu_map_list - * because device drivers have their own device address space and - * the device address spaces could be duplicated echo other. - */ -struct exynos_drm_g2d_private { - struct device *dev; - struct list_head inuse_cmdlist; - struct list_head event_list; - struct list_head iommu_map_list; -}; - -/* - * Exynos drm rotator private structure - * - * @dev: device object to device driver for using driver data. - * @iommu_list: list head to iommu map information. - */ -struct exynos_drm_rot_private { - struct device *dev; - struct list_head iommu_list; -}; - -struct drm_exynos_file_private { - struct exynos_drm_g2d_private *g2d_priv; - struct exynos_drm_rot_private *rot_priv; -}; - -/* - * Exynos drm private structure. - */ -struct exynos_drm_private { - struct drm_fb_helper *fb_helper; - - /* list head for new event to be added. */ - struct list_head pageflip_event_list; - - /* - * created crtc object would be contained at this array and - * this array is used to be aware of which crtc did it request vblank. - */ - struct drm_crtc *crtc[MAX_CRTC]; -}; - -/* - * Exynos drm sub driver structure. - * - * @list: sub driver has its own list object to register to exynos drm driver. - * @dev: pointer to device object for subdrv device driver. - * @drm_dev: pointer to drm_device and this pointer would be set - * when sub driver calls exynos_drm_subdrv_register(). - * @manager: subdrv has its own manager to control a hardware appropriately - * and we can access a hardware drawing on this manager. - * @probe: this callback would be called by exynos drm driver after - * subdrv is registered to it. - * @remove: this callback is used to release resources created - * by probe callback. - * @open: this would be called with drm device file open. - * @close: this would be called with drm device file close. - * @encoder: encoder object owned by this sub driver. - * @connector: connector object owned by this sub driver. - */ -struct exynos_drm_subdrv { - struct list_head list; - struct device *dev; - struct drm_device *drm_dev; - struct exynos_drm_manager *manager; - - int (*probe)(struct drm_device *drm_dev, struct device *dev); - void (*remove)(struct drm_device *dev); - int (*open)(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file); - void (*close)(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file); - - struct drm_encoder *encoder; - struct drm_connector *connector; -}; - -/* - * this function calls a probe callback registered to sub driver list and - * create its own encoder and connector and then set drm_device object - * to global one. - */ -int exynos_drm_device_register(struct drm_device *dev); -/* - * this function calls a remove callback registered to sub driver list and - * destroy its own encoder and connetor. - */ -int exynos_drm_device_unregister(struct drm_device *dev); - -/* - * this function would be called by sub drivers such as display controller - * or hdmi driver to register this sub driver object to exynos drm driver - * and when a sub driver is registered to exynos drm driver a probe callback - * of the sub driver is called and creates its own encoder and connector. - */ -int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); - -/* this function removes subdrv list from exynos drm driver */ -int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); - -int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); -void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); - -extern struct platform_driver fimd_driver; -extern struct platform_driver hdmi_driver; -extern struct platform_driver mixer_driver; -extern struct platform_driver exynos_drm_common_hdmi_driver; -extern struct platform_driver vidi_driver; -extern struct platform_driver g2d_driver; -extern struct platform_driver rotator_driver; -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.c deleted file mode 100644 index 6e9ac7b..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.c +++ /dev/null @@ -1,445 +0,0 @@ -/* exynos_drm_encoder.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" - -#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\ - drm_encoder) - -/* - * exynos specific encoder structure. - * - * @drm_encoder: encoder object. - * @manager: specific encoder has its own manager to control a hardware - * appropriately and we can access a hardware drawing on this manager. - * @dpms: store the encoder dpms value. - */ -struct exynos_drm_encoder { - struct drm_encoder drm_encoder; - struct exynos_drm_manager *manager; - int dpms; -}; - -static void exynos_drm_display_power(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - struct exynos_drm_display_ops *display_ops = - manager->display_ops; - - DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", - connector->base.id, mode); - if (display_ops && display_ops->power_on) - display_ops->power_on(manager->dev, mode); - } - } -} - -static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - - DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); - - if (exynos_encoder->dpms == mode) { - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); - return; - } - - mutex_lock(&dev->struct_mutex); - - switch (mode) { - case DRM_MODE_DPMS_ON: - if (manager_ops && manager_ops->apply) - manager_ops->apply(manager->dev); - exynos_drm_display_power(encoder, mode); - exynos_encoder->dpms = mode; - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - exynos_drm_display_power(encoder, mode); - exynos_encoder->dpms = mode; - break; - default: - DRM_ERROR("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&dev->struct_mutex); -} - -static bool -exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) - if (manager_ops && manager_ops->mode_fixup) - manager_ops->mode_fixup(manager->dev, connector, - mode, adjusted_mode); - } - - return true; -} - -static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - struct exynos_drm_overlay *overlay = get_exynos_drm_overlay(dev, - encoder->crtc); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - if (manager_ops && manager_ops->mode_set) - manager_ops->mode_set(manager->dev, - adjusted_mode); - - if (overlay_ops && overlay_ops->mode_set) - overlay_ops->mode_set(manager->dev, overlay); - } - } -} - -static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL. */ -} - -static void exynos_drm_encoder_commit(struct drm_encoder *encoder) -{ - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (manager_ops && manager_ops->commit) - manager_ops->commit(manager->dev); -} - -static struct drm_crtc * -exynos_drm_encoder_get_crtc(struct drm_encoder *encoder) -{ - return encoder->crtc; -} - -static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { - .dpms = exynos_drm_encoder_dpms, - .mode_fixup = exynos_drm_encoder_mode_fixup, - .mode_set = exynos_drm_encoder_mode_set, - .prepare = exynos_drm_encoder_prepare, - .commit = exynos_drm_encoder_commit, - .get_crtc = exynos_drm_encoder_get_crtc, -}; - -static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) -{ - struct exynos_drm_encoder *exynos_encoder = - to_exynos_encoder(encoder); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_encoder->manager->pipe = -1; - - drm_encoder_cleanup(encoder); - kfree(exynos_encoder); -} - -static struct drm_encoder_funcs exynos_encoder_funcs = { - .destroy = exynos_drm_encoder_destroy, -}; - -static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder) -{ - struct drm_encoder *clone; - struct drm_device *dev = encoder->dev; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_display_ops *display_ops = - exynos_encoder->manager->display_ops; - unsigned int clone_mask = 0; - int cnt = 0; - - list_for_each_entry(clone, &dev->mode_config.encoder_list, head) { - switch (display_ops->type) { - case EXYNOS_DISPLAY_TYPE_LCD: - case EXYNOS_DISPLAY_TYPE_HDMI: - case EXYNOS_DISPLAY_TYPE_VIDI: - clone_mask |= (1 << (cnt++)); - break; - default: - continue; - } - } - - return clone_mask; -} - -void exynos_drm_encoder_setup(struct drm_device *dev) -{ - struct drm_encoder *encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - encoder->possible_clones = exynos_drm_encoder_clones(encoder); -} - -struct drm_encoder * -exynos_drm_encoder_create(struct drm_device *dev, - struct exynos_drm_manager *manager, - unsigned int possible_crtcs) -{ - struct drm_encoder *encoder; - struct exynos_drm_encoder *exynos_encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!manager || !possible_crtcs) - return NULL; - - if (!manager->dev) - return NULL; - - exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL); - if (!exynos_encoder) { - DRM_ERROR("failed to allocate encoder\n"); - return NULL; - } - - exynos_encoder->dpms = DRM_MODE_DPMS_OFF; - exynos_encoder->manager = manager; - encoder = &exynos_encoder->drm_encoder; - encoder->possible_crtcs = possible_crtcs; - - DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); - - drm_encoder_init(dev, encoder, &exynos_encoder_funcs, - DRM_MODE_ENCODER_TMDS); - - drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs); - - DRM_DEBUG_KMS("encoder has been created\n"); - - return encoder; -} - -struct exynos_drm_manager *exynos_drm_get_manager(struct drm_encoder *encoder) -{ - return to_exynos_encoder(encoder)->manager; -} - -void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, - void (*fn)(struct drm_encoder *, void *)) -{ - struct drm_device *dev = crtc->dev; - struct drm_encoder *encoder; - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_manager *manager; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - /* - * if crtc is detached from encoder, check pipe, - * otherwise check crtc attached to encoder - */ - if (!encoder->crtc) { - manager = to_exynos_encoder(encoder)->manager; - if (manager->pipe < 0 || - private->crtc[manager->pipe] != crtc) - continue; - } else { - if (encoder->crtc != crtc) - continue; - } - - fn(encoder, data); - } -} - -void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - int crtc = *(int *)data; - - if (manager->pipe == -1) - manager->pipe = crtc; - - if (manager_ops->enable_vblank) - manager_ops->enable_vblank(manager->dev); -} - -void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - int crtc = *(int *)data; - - if (manager->pipe == -1) - manager->pipe = crtc; - - if (manager_ops->disable_vblank) - manager_ops->disable_vblank(manager->dev); -} - -void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder, - void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - int zpos = DEFAULT_ZPOS; - - if (data) - zpos = *(int *)data; - - if (overlay_ops && overlay_ops->commit) - overlay_ops->commit(manager->dev, zpos); -} - -void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - int crtc = *(int *)data; - int zpos = DEFAULT_ZPOS; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * when crtc is detached from encoder, this pipe is used - * to select manager operation - */ - manager->pipe = crtc; - - exynos_drm_encoder_crtc_plane_commit(encoder, &zpos); -} - -void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - int mode = *(int *)data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_encoder_dpms(encoder, mode); - - exynos_encoder->dpms = mode; -} - -void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) -{ - struct drm_device *dev = encoder->dev; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_manager *manager = exynos_encoder->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct drm_connector *connector; - int mode = *(int *)data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (manager_ops && manager_ops->dpms) - manager_ops->dpms(manager->dev, mode); - - /* - * set current dpms mode to the connector connected to - * current encoder. connector->dpms would be checked - * at drm_helper_connector_dpms() - */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - connector->dpms = mode; - - /* - * if this condition is ok then it means that the crtc is already - * detached from encoder and last function for detaching is properly - * done, so clear pipe from manager to prevent repeated call. - */ - if (mode > DRM_MODE_DPMS_ON) { - if (!encoder->crtc) - manager->pipe = -1; - } -} - -void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - struct exynos_drm_overlay *overlay = data; - - if (overlay_ops && overlay_ops->mode_set) - overlay_ops->mode_set(manager->dev, overlay); -} - -void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - int zpos = DEFAULT_ZPOS; - - DRM_DEBUG_KMS("\n"); - - if (data) - zpos = *(int *)data; - - if (overlay_ops && overlay_ops->disable) - overlay_ops->disable(manager->dev, zpos); -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.h deleted file mode 100644 index eb7d231..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_encoder.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_ENCODER_H_ -#define _EXYNOS_DRM_ENCODER_H_ - -struct exynos_drm_manager; - -void exynos_drm_encoder_setup(struct drm_device *dev); -struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, - struct exynos_drm_manager *mgr, - unsigned int possible_crtcs); -struct exynos_drm_manager * -exynos_drm_get_manager(struct drm_encoder *encoder); -void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, - void (*fn)(struct drm_encoder *, void *)); -void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data); -void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder, - void *data); -void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, - void *data); -void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.c deleted file mode 100644 index 7b47330..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.c +++ /dev/null @@ -1,251 +0,0 @@ -/* exynos_drm_fb.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" - -#include "exynos_drm.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" - -#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) - -/* - * exynos specific framebuffer structure. - * - * @fb: drm framebuffer obejct. - * @exynos_gem_obj: array of exynos specific gem object containing a gem object. - */ -struct exynos_drm_fb { - struct drm_framebuffer fb; - struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; -}; - -static int check_fb_gem_memory_type(struct exynos_drm_gem_obj *exynos_gem_obj) -{ - unsigned int flags; - - flags = exynos_gem_obj->flags; - - /* not support physically non-continuous memory for fb yet. TODO */ - if (IS_NONCONTIG_BUFFER(flags)) { - DRM_ERROR("cannot use this gem memory type for fb.\n"); - return -EINVAL; - } - - return 0; -} - -static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_framebuffer_cleanup(fb); - - kfree(exynos_fb); - exynos_fb = NULL; -} - -static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return drm_gem_handle_create(file_priv, - &exynos_fb->exynos_gem_obj[0]->base, handle); -} - -static int exynos_drm_fb_dirty(struct drm_framebuffer *fb, - struct drm_file *file_priv, unsigned flags, - unsigned color, struct drm_clip_rect *clips, - unsigned num_clips) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - return 0; -} - -static struct drm_framebuffer_funcs exynos_drm_fb_funcs = { - .destroy = exynos_drm_fb_destroy, - .create_handle = exynos_drm_fb_create_handle, - .dirty = exynos_drm_fb_dirty, -}; - -struct drm_framebuffer * -exynos_drm_framebuffer_init(struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - struct exynos_drm_fb *exynos_fb; - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - exynos_gem_obj = to_exynos_gem_obj(obj); - - ret = check_fb_gem_memory_type(exynos_gem_obj); - if (ret < 0) { - DRM_ERROR("cannot use this gem memory type for fb.\n"); - return ERR_PTR(-EINVAL); - } - - exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); - if (!exynos_fb) { - DRM_ERROR("failed to allocate exynos drm framebuffer\n"); - return ERR_PTR(-ENOMEM); - } - - exynos_fb->exynos_gem_obj[0] = exynos_gem_obj; - - ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs); - if (ret) { - DRM_ERROR("failed to initialize framebuffer\n"); - return ERR_PTR(ret); - } - - drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); - - return &exynos_fb->fb; -} - -static struct drm_framebuffer * -exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct drm_framebuffer *fb; - struct exynos_drm_fb *exynos_fb; - int nr; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); - if (!obj) { - DRM_ERROR("failed to lookup gem object\n"); - return ERR_PTR(-ENOENT); - } - - drm_gem_object_unreference_unlocked(obj); - - fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); - if (IS_ERR(fb)) - return fb; - - exynos_fb = to_exynos_fb(fb); - nr = exynos_drm_format_num_buffers(fb->pixel_format); - - for (i = 1; i < nr; i++) { - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - obj = drm_gem_object_lookup(dev, file_priv, - mode_cmd->handles[i]); - if (!obj) { - DRM_ERROR("failed to lookup gem object\n"); - exynos_drm_fb_destroy(fb); - return ERR_PTR(-ENOENT); - } - - drm_gem_object_unreference_unlocked(obj); - - exynos_gem_obj = to_exynos_gem_obj(obj); - - ret = check_fb_gem_memory_type(exynos_gem_obj); - if (ret < 0) { - DRM_ERROR("cannot use this gem memory type for fb.\n"); - exynos_drm_fb_destroy(fb); - return ERR_PTR(ret); - } - - exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); - } - - return fb; -} - -struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, - int index) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - struct exynos_drm_gem_buf *buffer; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (index >= MAX_FB_BUFFER) - return NULL; - - buffer = exynos_fb->exynos_gem_obj[index]->buffer; - if (!buffer) - return NULL; - - DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", - (unsigned long)buffer->kvaddr, - (unsigned long)buffer->dma_addr); - - return buffer; -} - -static void exynos_drm_output_poll_changed(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - struct drm_fb_helper *fb_helper = private->fb_helper; - - if (fb_helper) - drm_fb_helper_hotplug_event(fb_helper); -} - -static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { - .fb_create = exynos_user_fb_create, - .output_poll_changed = exynos_drm_output_poll_changed, -}; - -void exynos_drm_mode_config_init(struct drm_device *dev) -{ - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - - /* - * set max width and height as default value(4096x4096). - * this value would be used to check framebuffer size limitation - * at drm_mode_addfb(). - */ - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; - - dev->mode_config.funcs = &exynos_drm_mode_config_funcs; -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.h deleted file mode 100644 index 3ecb30d..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_fb.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_FB_H_ -#define _EXYNOS_DRM_FB_H - -static inline int exynos_drm_format_num_buffers(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_NV12M: - case DRM_FORMAT_NV12MT: - return 2; - case DRM_FORMAT_YUV420M: - return 3; - default: - return 1; - } -} - -struct drm_framebuffer * -exynos_drm_framebuffer_init(struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); - -/* get memory information of a drm framebuffer */ -struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, - int index); - -void exynos_drm_mode_config_init(struct drm_device *dev); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.c deleted file mode 100644 index d5586cc..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.c +++ /dev/null @@ -1,318 +0,0 @@ -/* exynos_drm_fbdev.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_fb_helper.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" - -#define MAX_CONNECTOR 4 -#define PREFERRED_BPP 32 - -#define to_exynos_fbdev(x) container_of(x, struct exynos_drm_fbdev,\ - drm_fb_helper) - -struct exynos_drm_fbdev { - struct drm_fb_helper drm_fb_helper; - struct exynos_drm_gem_obj *exynos_gem_obj; -}; - -static struct fb_ops exynos_drm_fb_ops = { - .owner = THIS_MODULE, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_setcmap = drm_fb_helper_setcmap, -}; - -static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, - struct drm_framebuffer *fb) -{ - struct fb_info *fbi = helper->fbdev; - struct drm_device *dev = helper->dev; - struct exynos_drm_gem_buf *buffer; - unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3); - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); - drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); - - /* RGB formats use only one buffer */ - buffer = exynos_drm_fb_buffer(fb, 0); - if (!buffer) { - DRM_LOG_KMS("buffer is null.\n"); - return -EFAULT; - } - - offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); - offset += fbi->var.yoffset * fb->pitches[0]; - - dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; - fbi->screen_base = buffer->kvaddr + offset; - fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); - fbi->screen_size = size; - fbi->fix.smem_len = size; - - return 0; -} - -static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper); - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_device *dev = helper->dev; - struct fb_info *fbi; - struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct platform_device *pdev = dev->platformdev; - unsigned long size; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - mutex_lock(&dev->struct_mutex); - - fbi = framebuffer_alloc(0, &pdev->dev); - if (!fbi) { - DRM_ERROR("failed to allocate fb info.\n"); - ret = -ENOMEM; - goto out; - } - - size = mode_cmd.pitches[0] * mode_cmd.height; - - /* 0 means to allocate physically continuous memory */ - exynos_gem_obj = exynos_drm_gem_create(dev, 0, size); - if (IS_ERR(exynos_gem_obj)) { - ret = PTR_ERR(exynos_gem_obj); - goto out; - } - - exynos_fbdev->exynos_gem_obj = exynos_gem_obj; - - helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd, - &exynos_gem_obj->base); - if (IS_ERR_OR_NULL(helper->fb)) { - DRM_ERROR("failed to create drm framebuffer.\n"); - ret = PTR_ERR(helper->fb); - goto out; - } - - helper->fbdev = fbi; - - fbi->par = helper; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->fbops = &exynos_drm_fb_ops; - - ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - DRM_ERROR("failed to allocate cmap.\n"); - goto out; - } - - ret = exynos_drm_fbdev_update(helper, helper->fb); - if (ret < 0) { - fb_dealloc_cmap(&fbi->cmap); - goto out; - } - -/* - * if failed, all resources allocated above would be released by - * drm_mode_config_cleanup() when drm_load() had been called prior - * to any specific driver such as fimd or hdmi driver. - */ -out: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * with !helper->fb, it means that this funcion is called first time - * and after that, the helper->fb would be used as clone mode. - */ - if (!helper->fb) { - ret = exynos_drm_fbdev_create(helper, sizes); - if (ret < 0) { - DRM_ERROR("failed to create fbdev.\n"); - return ret; - } - - /* - * fb_helper expects a value more than 1 if succeed - * because register_framebuffer() should be called. - */ - ret = 1; - } - - return ret; -} - -static struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = { - .fb_probe = exynos_drm_fbdev_probe, -}; - -int exynos_drm_fbdev_init(struct drm_device *dev) -{ - struct exynos_drm_fbdev *fbdev; - struct exynos_drm_private *private = dev->dev_private; - struct drm_fb_helper *helper; - unsigned int num_crtc; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector) - return 0; - - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); - if (!fbdev) { - DRM_ERROR("failed to allocate drm fbdev.\n"); - return -ENOMEM; - } - - private->fb_helper = helper = &fbdev->drm_fb_helper; - helper->funcs = &exynos_drm_fb_helper_funcs; - - num_crtc = dev->mode_config.num_crtc; - - ret = drm_fb_helper_init(dev, helper, num_crtc, MAX_CONNECTOR); - if (ret < 0) { - DRM_ERROR("failed to initialize drm fb helper.\n"); - goto err_init; - } - - ret = drm_fb_helper_single_add_all_connectors(helper); - if (ret < 0) { - DRM_ERROR("failed to register drm_fb_helper_connector.\n"); - goto err_setup; - - } - - ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); - if (ret < 0) { - DRM_ERROR("failed to set up hw configuration.\n"); - goto err_setup; - } - - return 0; - -err_setup: - drm_fb_helper_fini(helper); - -err_init: - private->fb_helper = NULL; - kfree(fbdev); - - return ret; -} - -static void exynos_drm_fbdev_destroy(struct drm_device *dev, - struct drm_fb_helper *fb_helper) -{ - struct drm_framebuffer *fb; - - /* release drm framebuffer and real buffer */ - if (fb_helper->fb && fb_helper->fb->funcs) { - fb = fb_helper->fb; - if (fb && fb->funcs->destroy) - fb->funcs->destroy(fb); - } - - /* release linux framebuffer */ - if (fb_helper->fbdev) { - struct fb_info *info; - int ret; - - info = fb_helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } - - drm_fb_helper_fini(fb_helper); -} - -void exynos_drm_fbdev_fini(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_fbdev *fbdev; - - if (!private || !private->fb_helper) - return; - - fbdev = to_exynos_fbdev(private->fb_helper); - - if (fbdev->exynos_gem_obj) - exynos_drm_gem_destroy(fbdev->exynos_gem_obj); - - exynos_drm_fbdev_destroy(dev, private->fb_helper); - kfree(fbdev); - private->fb_helper = NULL; -} - -void exynos_drm_fbdev_restore_mode(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - - if (!private || !private->fb_helper) - return; - - drm_fb_helper_restore_fbdev_mode(private->fb_helper); -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.h deleted file mode 100644 index ccfce8a..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_fbdev.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_FBDEV_H_ -#define _EXYNOS_DRM_FBDEV_H_ - -int exynos_drm_fbdev_init(struct drm_device *dev); -int exynos_drm_fbdev_reinit(struct drm_device *dev); -void exynos_drm_fbdev_fini(struct drm_device *dev); -void exynos_drm_fbdev_restore_mode(struct drm_device *dev); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_fimd.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_fimd.c deleted file mode 100644 index 6ec2a61..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_fimd.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* exynos_drm_fimd.c - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Joonyoung Shim <jy0922.shim@samsung.com> - * Inki Dae <inki.dae@samsung.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. - * - */ -#include "drmP.h" -#include "drm_backlight.h" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/pm_runtime.h> -#include <linux/cma.h> - -#include <drm/exynos_drm.h> -#include <plat/regs-fb-v4.h> - -#include <plat/fimd_lite_ext.h> - -#include <mach/map.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_fbdev.h" -#include "exynos_drm_crtc.h" - -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ -#include <linux/devfreq/exynos4_display.h> -#endif - -#ifdef CONFIG_MACH_SLP_NAPLES -#define VIDCON0_DSI_DISABLE (0 << 30) -#define VIDCON0_DSI_ENABLE (1 << 30) - -/* I80/RGB Trigger control */ -#define TRIGCON (0x01A4) -/* I80 interface control 0 for main LDI */ -#define I80IFCONA0 (0x01B0) -#define I80IFCONA1 (0x01B4) -#define I80IFCONB0 (0x01B8) -#define I80IFCONB1 (0x01B8) - -/* I80IFCONA0 and I80IFCONA1 */ -#define LCD_CS_SETUP(x) (((x) & 0xf) << 16) -#define LCD_WR_SETUP(x) (((x) & 0xf) << 12) -#define LCD_WR_ACT(x) (((x) & 0xf) << 8) -#define LCD_WR_HOLD(x) (((x) & 0xf) << 4) -#define RSPOL_LOW (0 << 2) -#define RSPOL_HIGH (1 << 2) -#define I80IFEN_DISABLE (0 << 0) -#define I80IFEN_ENABLE (1 << 0) - -enum s3cfb_cpu_auto_cmd_rate { - DISABLE_AUTO_FRM, - PER_TWO_FRM, - PER_FOUR_FRM, - PER_SIX_FRM, - PER_EIGHT_FRM, - PER_TEN_FRM, - PER_TWELVE_FRM, - PER_FOURTEEN_FRM, - PER_SIXTEEN_FRM, - PER_EIGHTEEN_FRM, - PER_TWENTY_FRM, - PER_TWENTY_TWO_FRM, - PER_TWENTY_FOUR_FRM, - PER_TWENTY_SIX_FRM, - PER_TWENTY_EIGHT_FRM, - PER_THIRTY_FRM, -}; -#endif -#ifdef CONFIG_DRM_EXYNOS_FIMD_WB -#include <plat/fimc.h> -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ -#include <plat/pd.h> -#include <linux/pm_qos_params.h> -#endif -#define FIMD_GET_LCD_WIDTH _IOR('F', 302, int) -#define FIMD_GET_LCD_HEIGHT _IOR('F', 303, int) -#define FIMD_SET_WRITEBACK _IOW('F', 304, u32) -#endif - -/* - * FIMD is stand for Fully Interactive Mobile Display and - * as a display controller, it transfers contents drawn on memory - * to a LCD Panel through Display Interfaces such as RGB or - * CPU Interface. - */ - -/* position control register for hardware window 0, 2 ~ 4.*/ -#define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) -#define VIDOSD_B(win) (VIDOSD_BASE + 0x04 + (win) * 16) -/* size control register for hardware window 0. */ -#define VIDOSD_C_SIZE_W0 (VIDOSD_BASE + 0x08) -/* alpha control register for hardware window 1 ~ 4. */ -#define VIDOSD_C(win) (VIDOSD_BASE + 0x18 + (win) * 16) -/* size control register for hardware window 1 ~ 4. */ -#define VIDOSD_D(win) (VIDOSD_BASE + 0x0C + (win) * 16) - -#define VIDWx_BUF_START(win, buf) (VIDW_BUF_START(buf) + (win) * 8) -#define VIDWx_BUF_END(win, buf) (VIDW_BUF_END(buf) + (win) * 8) -#define VIDWx_BUF_SIZE(win, buf) (VIDW_BUF_SIZE(buf) + (win) * 4) - -/* color key control register for hardware window 1 ~ 4. */ -#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + (x * 8)) -/* color key value register for hardware window 1 ~ 4. */ -#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + (x * 8)) - -/* FIMD has totally five hardware windows. */ -#define WINDOWS_NR 5 - -#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev)) - -static struct s5p_fimd_ext_device *fimd_lite_dev, *mdnie; -static struct s5p_fimd_dynamic_refresh *fimd_refresh; - -struct fimd_notifier_block { - struct list_head list; - void *data; - int (*client_notifier)(unsigned int val, void *data); -}; - -static LIST_HEAD(fimd_notifier_list); -static DEFINE_MUTEX(fimd_notifier_lock); - -struct fimd_win_data { - unsigned int offset_x; - unsigned int offset_y; - unsigned int ovl_width; - unsigned int ovl_height; - unsigned int fb_width; - unsigned int fb_height; - unsigned int bpp; - dma_addr_t dma_addr; - void __iomem *vaddr; - unsigned int buf_offsize; - unsigned int line_size; /* bytes */ - bool enabled; -}; - -struct fimd_context { - struct exynos_drm_subdrv subdrv; - int irq; - struct drm_crtc *crtc; - struct clk *bus_clk; - struct clk *lcd_clk; - struct resource *regs_res; - void __iomem *regs; - struct fimd_win_data win_data[WINDOWS_NR]; - unsigned int clkdiv; - unsigned int default_win; - unsigned long irq_flags; - u32 vidcon0; - u32 vidcon1; - bool suspended; - struct mutex lock; - - struct exynos_drm_panel_info *panel; - unsigned int high_freq; - unsigned int dynamic_refresh; - struct notifier_block nb_exynos_display; - - struct work_struct work; - bool errata; -#ifdef CONFIG_DRM_EXYNOS_FIMD_WB - struct notifier_block nb_ctrl; -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - struct pm_qos_request_list pm_qos; -#endif -#endif -}; -#ifdef CONFIG_MACH_SLP_NAPLES -struct fimd_context *ctx_global; -#endif - -static bool fimd_display_is_connected(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return true; -} - -static void *fimd_get_panel(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return ctx->panel; -} - -static int fimd_check_timing(struct device *dev, void *timing) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return 0; -} - -static int fimd_display_power_on(struct device *dev, int mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - drm_bl_dpms(mode); - - return 0; -} - -static struct exynos_drm_display_ops fimd_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .is_connected = fimd_display_is_connected, - .get_panel = fimd_get_panel, - .check_timing = fimd_check_timing, - .power_on = fimd_display_power_on, -}; - -static void exynos_drm_mdnie_mode_stop(struct fimd_context *ctx) -{ - struct s5p_fimd_ext_driver *fimd_lite_drv; - u32 cfg; - - fimd_lite_drv = to_fimd_ext_driver(fimd_lite_dev->dev.driver); - - /* set dualrgb register to mDNIe mode. */ - cfg = readl(ctx->regs + DUALRGB); - cfg &= ~(0x3 << 0); - writel(cfg, ctx->regs + DUALRGB); - msleep(20); - - /* change display path. */ - cfg = readl(S3C_VA_SYS + 0x210); - cfg |= 1 << 1; - writel(cfg, S3C_VA_SYS + 0x210); - - if (fimd_lite_drv->stop) - fimd_lite_drv->stop(fimd_lite_dev); - - if (fimd_lite_drv->setup) - fimd_lite_drv->setup(fimd_lite_dev, 0); - - /* clock off */ - if (fimd_lite_drv->power_off) - fimd_lite_drv->power_off(fimd_lite_dev); - - fimd_lite_dev->enabled = false; -} - -static void exynos_drm_set_mdnie_mode(struct fimd_context *ctx) -{ - u32 cfg; - - /* change display path. */ - cfg = readl(S3C_VA_SYS + 0x210); - /* MIE_LBLK0 is mDNIe. */ - cfg |= 1 << 0; - /* FIMDBYPASS_LBLK0 is MIE/mDNIe. */ - cfg &= ~(1 << 1); - writel(cfg, S3C_VA_SYS + 0x210); - - /* all polarity values should be 0 for mDNIe. */ - cfg = readl(ctx->regs + VIDCON1); - cfg &= ~(VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC | - VIDCON1_INV_VSYNC | VIDCON1_INV_VDEN | - VIDCON1_VCLK_MASK); - - writel(cfg, ctx->regs + VIDCON1); - - /* set dualrgb register to mDNIe mode. */ - cfg = readl(ctx->regs + DUALRGB); - cfg &= ~(0x3 << 0); - cfg |= 0x3 << 0; - writel(cfg, ctx->regs + DUALRGB); -} - -static int exynos_drm_change_to_mdnie(struct fimd_context *ctx) -{ - u32 cfg; - struct s5p_fimd_ext_driver *mdnie_drv, *fimd_lite_drv; - - mdnie_drv = to_fimd_ext_driver(mdnie->dev.driver); - fimd_lite_drv = to_fimd_ext_driver(fimd_lite_dev->dev.driver); - - /** - * path change sequence for mDNIe. - * - * 1. FIMD-LITE DMA stop. - * 2. FIMD DMA stop. - * 3. change DISPLAY_CONTROL and DUALRGB registers to mDNIe mode. - * 4. change FIMD VCLKFREE to freerun mode. - * 5. initialize mDNIe module. - * 6. initialize FIMD-LITE module. - * 7. FIMD-LITE logic start. - * 8. FIMD-LITE DMA start. - * 9. FIMD DMA start. - * - * ps. FIMD polarity values should be 0. - * lcd polarity values should be set to FIMD-LITE. - * FIMD and FIMD-LITE DMA should be started at same time. - */ - /* set fimd to mDNIe mode.(WB/mDNIe) */ - exynos_drm_set_mdnie_mode(ctx); - - /* enable FIMD-LITE. clk */ - if (fimd_lite_drv && fimd_lite_drv->power_on) - fimd_lite_drv->power_on(fimd_lite_dev); - - /* setup mDNIe. */ - if (mdnie_drv) - mdnie_drv->setup(mdnie, 1); - - /* setup FIMD-LITE. */ - if (fimd_lite_drv) - fimd_lite_drv->setup(fimd_lite_dev, 1); - - cfg = readl(ctx->regs + VIDCON0); - cfg |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(cfg, ctx->regs + VIDCON0); - - if (fimd_lite_drv->start) - fimd_lite_drv->start(fimd_lite_dev); - return 0; -} - -static void fimd_dpms(struct device *subdrv_dev, int mode) -{ - struct fimd_context *ctx = get_fimd_context(subdrv_dev); - - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); - - mutex_lock(&ctx->lock); - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* - * enable fimd hardware only if suspended status. - * - * P.S. fimd_dpms function would be called at booting time so - * clk_enable could be called double time. - */ - if (ctx->suspended) - pm_runtime_get_sync(subdrv_dev); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (!ctx->suspended) - pm_runtime_put_sync(subdrv_dev); - break; - default: - DRM_DEBUG_KMS("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&ctx->lock); -} - -static void fimd_apply(struct device *subdrv_dev) -{ - struct fimd_context *ctx = get_fimd_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; - struct exynos_drm_manager_ops *mgr_ops = mgr->ops; - struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; - struct fimd_win_data *win_data; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - for (i = 0; i < WINDOWS_NR; i++) { - win_data = &ctx->win_data[i]; - if (win_data->enabled && (ovl_ops && ovl_ops->commit)) - ovl_ops->commit(subdrv_dev, i); - } - - if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); -} - -#ifdef CONFIG_MACH_SLP_NAPLES -void _fimd_set_auto_cmd_rate(struct fimd_context *ctx, unsigned char cmd_rate) -{ - unsigned int cmd_rate_val; - unsigned int i80_if_con_reg_val; - - cmd_rate_val = (cmd_rate == DISABLE_AUTO_FRM) ? (0x0 << 0) : - (cmd_rate == PER_TWO_FRM) ? (0x1 << 0) : - (cmd_rate == PER_FOUR_FRM) ? (0x2 << 0) : - (cmd_rate == PER_SIX_FRM) ? (0x3 << 0) : - (cmd_rate == PER_EIGHT_FRM) ? (0x4 << 0) : - (cmd_rate == PER_TEN_FRM) ? (0x5 << 0) : - (cmd_rate == PER_TWELVE_FRM) ? (0x6 << 0) : - (cmd_rate == PER_FOURTEEN_FRM) ? (0x7 << 0) : - (cmd_rate == PER_SIXTEEN_FRM) ? (0x8 << 0) : - (cmd_rate == PER_EIGHTEEN_FRM) ? (0x9 << 0) : - (cmd_rate == PER_TWENTY_FRM) ? (0xa << 0) : - (cmd_rate == PER_TWENTY_TWO_FRM) ? (0xb << 0) : - (cmd_rate == PER_TWENTY_FOUR_FRM) ? (0xc << 0) : - (cmd_rate == PER_TWENTY_SIX_FRM) ? (0xd << 0) : - (cmd_rate == PER_TWENTY_EIGHT_FRM) ? (0xe << 0) : (0xf << 0); - - i80_if_con_reg_val = readl(ctx->regs + I80IFCONB0); - i80_if_con_reg_val &= ~(0xf << 0); - i80_if_con_reg_val |= cmd_rate_val; - writel(i80_if_con_reg_val, ctx->regs + I80IFCONB0); -} -#endif -static void fimd_commit(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - u32 val; - - if (ctx->suspended) - return; - - DRM_DEBUG_KMS("%s\n", __FILE__); - -#ifdef CONFIG_MACH_SLP_NAPLES - /* setup horizontal and vertical display size. */ - val = VIDTCON2_LINEVAL(timing->yres - 1) | - VIDTCON2_HOZVAL(timing->xres - 1); - writel(val, ctx->regs + VIDTCON2); - - /* cpu_interface_timing */ - val = readl(ctx->regs + I80IFCONA0); - val = LCD_CS_SETUP(0) | - LCD_WR_SETUP(0) | - LCD_WR_ACT(1) | - LCD_WR_HOLD(0) | - RSPOL_LOW | /* in case of LCD MIPI module */ - I80IFEN_ENABLE; - writel(val, ctx->regs + I80IFCONA0); - - _fimd_set_auto_cmd_rate(ctx, DISABLE_AUTO_FRM); - - /* setup clock source, clock divider, enable dma. */ - val = ctx->vidcon0; - val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); - - if (ctx->clkdiv > 1) - val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) - | VIDCON0_CLKDIR; - else - val &= ~VIDCON0_CLKDIR; /* 1:1 clock */ - - /* - * fields of register with prefix '_F' would be updated - * at vsync(same as dma start) - */ - val |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(val, ctx->regs + VIDCON0); - - /* - * Workaround: After power domain is turned off - * then when it is turned on, this needs. - */ - val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F); - writel(val, ctx->regs + VIDCON0); - - val |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(val, ctx->regs + VIDCON0); -#else - /* setup polarity values from machine code. */ - writel(ctx->vidcon1, ctx->regs + VIDCON1); - - /* setup vertical timing values. */ - val = VIDTCON0_VBPD(timing->upper_margin - 1) | - VIDTCON0_VFPD(timing->lower_margin - 1) | - VIDTCON0_VSPW(timing->vsync_len - 1); - writel(val, ctx->regs + VIDTCON0); - - /* setup horizontal timing values. */ - val = VIDTCON1_HBPD(timing->left_margin - 1) | - VIDTCON1_HFPD(timing->right_margin - 1) | - VIDTCON1_HSPW(timing->hsync_len - 1); - writel(val, ctx->regs + VIDTCON1); - - /* setup horizontal and vertical display size. */ - val = VIDTCON2_LINEVAL(timing->yres - 1) | - VIDTCON2_HOZVAL(timing->xres - 1); - writel(val, ctx->regs + VIDTCON2); - - /* setup clock source, clock divider, enable dma. */ - val = ctx->vidcon0; - val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); - - if (ctx->clkdiv > 1) - val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR; - else - val &= ~VIDCON0_CLKDIR; /* 1:1 clock */ - - /* - * fields of register with prefix '_F' would be updated - * at vsync(same as dma start) - */ - val |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(val, ctx->regs + VIDCON0); - - /* - * fix fimd errata with mDNIe. - * - * this code fixes a issue that mDNIe unfunctions properly - * when fimd power off goes to on. this issue is because dma - * is enabled two times with setcrtc call once a process is - * ternimated(at this thime, fimd goes to on from off for back - * to console fb) so this condition would avoid the situation. - */ - if (!ctx->errata) { - /* - * Workaround: After power domain is turned off then - * when it is turned on, this needs. - */ - val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F); - writel(val, ctx->regs + VIDCON0); - - val |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(val, ctx->regs + VIDCON0); - - ctx->errata = true; - } -#endif -} - -static int fimd_enable_vblank(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return -EPERM; - - if (!test_and_set_bit(0, &ctx->irq_flags)) { - val = readl(ctx->regs + VIDINTCON0); - - val |= VIDINTCON0_INT_ENABLE; - val |= VIDINTCON0_INT_FRAME; - - val &= ~VIDINTCON0_FRAMESEL0_MASK; - val |= VIDINTCON0_FRAMESEL0_VSYNC; - val &= ~VIDINTCON0_FRAMESEL1_MASK; - val |= VIDINTCON0_FRAMESEL1_NONE; - - writel(val, ctx->regs + VIDINTCON0); - } - - return 0; -} - -static void fimd_disable_vblank(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (test_and_clear_bit(0, &ctx->irq_flags)) { - val = readl(ctx->regs + VIDINTCON0); - - val &= ~VIDINTCON0_INT_FRAME; - val &= ~VIDINTCON0_INT_ENABLE; - - writel(val, ctx->regs + VIDINTCON0); - } -} - -static struct exynos_drm_manager_ops fimd_manager_ops = { - .dpms = fimd_dpms, - .apply = fimd_apply, - .commit = fimd_commit, - .enable_vblank = fimd_enable_vblank, - .disable_vblank = fimd_disable_vblank, -}; - -static void fimd_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win; - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!overlay) { - dev_err(dev, "overlay is NULL\n"); - return; - } - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - offset = overlay->fb_x * (overlay->bpp >> 3); - offset += overlay->fb_y * overlay->pitch; - - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); - - win_data = &ctx->win_data[win]; - - win_data->offset_x = overlay->crtc_x; - win_data->offset_y = overlay->crtc_y; - win_data->ovl_width = overlay->crtc_width; - win_data->ovl_height = overlay->crtc_height; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - win_data->dma_addr = overlay->dma_addr[0] + offset; - win_data->vaddr = overlay->vaddr[0] + offset; - win_data->bpp = overlay->bpp; - win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * - (overlay->bpp >> 3); - win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); - - DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", - win_data->offset_x, win_data->offset_y); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", - (unsigned long)win_data->dma_addr, - (unsigned long)win_data->vaddr); - DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", - overlay->fb_width, overlay->crtc_width); -} - -static void fimd_win_set_pixfmt(struct device *dev, unsigned int win) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data = &ctx->win_data[win]; - unsigned long val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - val = WINCONx_ENWIN; - - switch (win_data->bpp) { - case 1: - val |= WINCON0_BPPMODE_1BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_4WORD; - break; - case 2: - val |= WINCON0_BPPMODE_2BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_8WORD; - break; - case 4: - val |= WINCON0_BPPMODE_4BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_8WORD; - break; - case 8: - val |= WINCON0_BPPMODE_8BPP_PALETTE; - val |= WINCONx_BURSTLEN_8WORD; - val |= WINCONx_BYTSWP; - break; - case 16: - val |= WINCON0_BPPMODE_16BPP_565; - val |= WINCONx_HAWSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - case 24: - val |= WINCON0_BPPMODE_24BPP_888; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - case 32: - val |= WINCON1_BPPMODE_28BPP_A4888 - | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - default: - DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n"); - - val |= WINCON0_BPPMODE_24BPP_888; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - } - - DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); - - writel(val, ctx->regs + WINCON(win)); -} - -static void fimd_win_set_colkey(struct device *dev, unsigned int win) -{ - struct fimd_context *ctx = get_fimd_context(dev); - unsigned int keycon0 = 0, keycon1 = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | - WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); - - keycon1 = WxKEYCON1_COLVAL(0xffffffff); - - writel(keycon0, ctx->regs + WKEYCON0_BASE(win)); - writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); -} - -static void fimd_win_commit(struct device *dev, int zpos) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win = zpos; - unsigned long val, alpha, size; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - /* - * SHADOWCON register is used for enabling timing. - * - * for example, once only width value of a register is set, - * if the dma is started then fimd hardware could malfunction so - * with protect window setting, the register fields with prefix '_F' - * wouldn't be updated at vsync also but updated once unprotect window - * is set. - */ - - /* protect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - /* buffer start address */ - val = (unsigned long)win_data->dma_addr; - writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); - - /* buffer end address */ - size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); - val = (unsigned long)(win_data->dma_addr + size); - writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); - - DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", - (unsigned long)win_data->dma_addr, val, size); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - - /* buffer size */ - val = VIDW_BUF_SIZE_OFFSET(win_data->buf_offsize) | - VIDW_BUF_SIZE_PAGEWIDTH(win_data->line_size); - writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); - - /* OSD position */ - val = VIDOSDxA_TOPLEFT_X(win_data->offset_x) | - VIDOSDxA_TOPLEFT_Y(win_data->offset_y); - writel(val, ctx->regs + VIDOSD_A(win)); - - val = VIDOSDxB_BOTRIGHT_X(win_data->offset_x + - win_data->ovl_width - 1) | - VIDOSDxB_BOTRIGHT_Y(win_data->offset_y + - win_data->ovl_height - 1); - writel(val, ctx->regs + VIDOSD_B(win)); - - DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", - win_data->offset_x, win_data->offset_y, - win_data->offset_x + win_data->ovl_width - 1, - win_data->offset_y + win_data->ovl_height - 1); - - /* hardware window 0 doesn't support alpha channel. */ - if (win != 0) { - /* OSD alpha */ - alpha = VIDISD14C_ALPHA1_R(0xf) | - VIDISD14C_ALPHA1_G(0xf) | - VIDISD14C_ALPHA1_B(0xf); - - writel(alpha, ctx->regs + VIDOSD_C(win)); - } - - /* OSD size */ - if (win != 3 && win != 4) { - u32 offset = VIDOSD_D(win); - if (win == 0) - offset = VIDOSD_C_SIZE_W0; - val = win_data->ovl_width * win_data->ovl_height; - writel(val, ctx->regs + offset); - - DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); - } - - fimd_win_set_pixfmt(dev, win); - - /* hardware window 0 doesn't support color key. */ - if (win != 0) - fimd_win_set_colkey(dev, win); - - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val |= WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); - - /* Enable DMA channel and unprotect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_CHx_ENABLE(win); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - win_data->enabled = true; -} - -static void fimd_win_disable(struct device *dev, int zpos) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win = zpos; - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - /* protect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val &= ~WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); - - /* unprotect windows */ - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_CHx_ENABLE(win); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - win_data->enabled = false; -} - -static struct exynos_drm_overlay_ops fimd_overlay_ops = { - .mode_set = fimd_win_mode_set, - .commit = fimd_win_commit, - .disable = fimd_win_disable, -}; - -static struct exynos_drm_manager fimd_manager = { - .pipe = -1, - .ops = &fimd_manager_ops, - .overlay_ops = &fimd_overlay_ops, - .display_ops = &fimd_display_ops, -}; - -static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) { - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - /* - * don't off vblank if vblank_disable_allowed is 1, - * because vblank would be off by timer handler. - */ - if (!drm_dev->vblank_disable_allowed) - drm_vblank_off(drm_dev, crtc); - } - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static void exynos_fimd_schedule_work(struct work_struct *work) -{ - struct fimd_context *ctx = container_of(work, struct fimd_context, - work); - u32 ret; - - /* Change mdnie mode after irq handler */ - if (mdnie && fimd_lite_dev) { - if (!fimd_lite_dev->enabled) { - while (1) { - ret = (__raw_readl(ctx->regs + VIDCON1)) & - VIDCON1_VSTATUS_MASK; - if (ret == VIDCON1_VSTATUS_BACKPORCH) { - exynos_drm_change_to_mdnie(ctx); - fimd_lite_dev->enabled = true; - break; - } - } - } - } - -} - -#ifdef CONFIG_MACH_SLP_NAPLES -void fimd_set_trigger(void) -{ - u32 reg = 0; - struct exynos_drm_subdrv *subdrv = &ctx_global->subdrv; - struct drm_device *drm_dev = subdrv->drm_dev; - struct exynos_drm_manager *manager = subdrv->manager; - u32 val; - - val = readl(ctx_global->regs + VIDINTCON1); - - if (val & VIDINTCON1_INT_FRAME) - /* VSYNC interrupt */ - writel(VIDINTCON1_INT_FRAME, ctx_global->regs + VIDINTCON1); - - /* check the crtc is detached already from encoder */ - if (manager->pipe < 0) - return; - - drm_handle_vblank(drm_dev, manager->pipe); - fimd_finish_pageflip(drm_dev, manager->pipe); - - schedule_work(&ctx_global->work); - - reg = readl(ctx_global->regs + TRIGCON); - - reg |= 1 << 0 | 1 << 1; - - writel(reg, ctx_global->regs + TRIGCON); -} -#endif -static irqreturn_t fimd_irq_handler(int irq, void *dev_id) -{ - struct fimd_context *ctx = (struct fimd_context *)dev_id; - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct drm_device *drm_dev = subdrv->drm_dev; - struct exynos_drm_manager *manager = subdrv->manager; - u32 val; - - val = readl(ctx->regs + VIDINTCON1); - - if (val & VIDINTCON1_INT_FRAME) - /* VSYNC interrupt */ - writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1); - - /* check the crtc is detached already from encoder */ - if (manager->pipe < 0) - goto out; - - drm_handle_vblank(drm_dev, manager->pipe); - fimd_finish_pageflip(drm_dev, manager->pipe); - - schedule_work(&ctx->work); - -out: - return IRQ_HANDLED; -} - -static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * enable drm irq mode. - * - with irq_enabled = 1, 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. - */ - drm_dev->irq_enabled = 1; - - /* - * with vblank_disable_allowed = 1, 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_dev->vblank_disable_allowed = 1; - - return 0; -} - -static void fimd_subdrv_remove(struct drm_device *drm_dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ -} - -static int fimd_calc_clkdiv(struct fimd_context *ctx, - struct fb_videomode *timing) -{ - unsigned long clk = clk_get_rate(ctx->lcd_clk); - u32 retrace; - u32 clkdiv; - u32 best_framerate = 0; - u32 framerate; - - DRM_DEBUG_KMS("%s\n", __FILE__); - -#ifdef CONFIG_MACH_SLP_NAPLES - retrace = timing->xres * timing->yres * 2; -#else - retrace = timing->left_margin + timing->hsync_len + - timing->right_margin + timing->xres; - retrace *= timing->upper_margin + timing->vsync_len + - timing->lower_margin + timing->yres; -#endif - - /* default framerate is 60Hz */ - if (!timing->refresh) - timing->refresh = 60; - - clk /= retrace; - - for (clkdiv = 1; clkdiv < 0x100; clkdiv++) { - int tmp; - - /* get best framerate */ - framerate = clk / clkdiv; - tmp = timing->refresh - framerate; - if (tmp < 0) { - best_framerate = framerate; - continue; - } else { - if (!best_framerate) - best_framerate = framerate; - else if (tmp < (best_framerate - framerate)) - best_framerate = framerate; - break; - } - } - - return clkdiv; -} - -static void fimd_clear_win(struct fimd_context *ctx, int win) -{ - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - writel(0, ctx->regs + WINCON(win)); - writel(0, ctx->regs + VIDOSD_A(win)); - writel(0, ctx->regs + VIDOSD_B(win)); - writel(0, ctx->regs + VIDOSD_C(win)); - - if (win == 1 || win == 2) - writel(0, ctx->regs + VIDOSD_D(win)); - - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); -} - -int fimd_register_client(int (*client_notifier)(unsigned int val, void *data), - void *data) -{ - struct fimd_notifier_block *fimd_block; - - fimd_block = kzalloc(sizeof(*fimd_block), GFP_KERNEL); - if (!fimd_block) { - printk(KERN_ERR "failed to allocate fimd_notifier_block\n"); - return -ENOMEM; - } - - fimd_block->client_notifier = client_notifier; - fimd_block->data = data; - - mutex_lock(&fimd_notifier_lock); - list_add_tail(&fimd_block->list, &fimd_notifier_list); - mutex_unlock(&fimd_notifier_lock); - - return 0; -} -EXPORT_SYMBOL(fimd_register_client); - -void fimd_unregister_client(int (*client_notifier)(unsigned int val, - void *data)) -{ - struct fimd_notifier_block *fimd_block; - - mutex_lock(&fimd_notifier_lock); - list_for_each_entry(fimd_block, &fimd_notifier_list, list) { - if (!fimd_block) - continue; - - if (fimd_block->client_notifier == client_notifier) { - list_del(&fimd_block->list); - kfree(fimd_block); - fimd_block = NULL; - break; - } - } - mutex_unlock(&fimd_notifier_lock); -} -EXPORT_SYMBOL(fimd_unregister_client); - -static int fimd_notifier_call_chain(void) -{ - struct fimd_notifier_block *fimd_block; - - mutex_lock(&fimd_notifier_lock); - list_for_each_entry(fimd_block, &fimd_notifier_list, list) { - if (fimd_block && fimd_block->client_notifier) - fimd_block->client_notifier(0, fimd_block->data); - } - mutex_unlock(&fimd_notifier_lock); - - return 0; -} - -static int fimd_power_on(struct fimd_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - int ret; - - /* fimd power should be off to clear mipi-dsi fifo. */ - fimd_notifier_call_chain(); - - ret = clk_enable(ctx->bus_clk); - if (ret < 0) - return ret; - - ret = clk_enable(ctx->lcd_clk); - if (ret < 0) { - clk_disable(ctx->bus_clk); - return ret; - } - - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - fimd_enable_vblank(dev); - - fimd_apply(dev); - } else { - if (fimd_lite_dev) - exynos_drm_mdnie_mode_stop(ctx); - - clk_disable(ctx->lcd_clk); - clk_disable(ctx->bus_clk); - - ctx->suspended = true; - ctx->errata = false; - } - - return 0; -} - -static void exynos_drm_change_clock(struct fimd_context *ctx) -{ - unsigned int cfg = 0; - struct s5p_fimd_ext_driver *fimd_lite_drv; - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - - fimd_lite_drv = to_fimd_ext_driver(fimd_lite_dev->dev.driver); - - if (!ctx->dynamic_refresh) { - timing->refresh = 60; - ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); -#ifdef CONFIG_LCD_S6E8AA0 - /* workaround: To apply dynamic refresh rate */ - s6e8aa0_panel_cond(1); -#endif - if (fimd_lite_dev && fimd_lite_dev->enabled) { - fimd_refresh->clkdiv = ctx->clkdiv; - fimd_lite_drv->change_clock(fimd_refresh, - fimd_lite_dev); - } else { - cfg = readl(ctx->regs + VIDCON0); - cfg &= ~VIDCON0_CLKVAL_F(0xFF); - cfg |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1); - writel(cfg, ctx->regs + VIDCON0); - } - } else { - ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); -#ifdef CONFIG_LCD_S6E8AA0 - /* workaround: To apply dynamic refresh rate */ - s6e8aa0_panel_cond(ctx->high_freq); -#endif - if (fimd_lite_dev && fimd_lite_dev->enabled) { - fimd_refresh->clkdiv = ctx->clkdiv; - fimd_lite_drv->change_clock(fimd_refresh, - fimd_lite_dev); - } else { - cfg = readl(ctx->regs + VIDCON0); - cfg &= ~VIDCON0_CLKVAL_F(0xFF); - cfg |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1); - writel(cfg, ctx->regs + VIDCON0); - } - } -} - -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ -static int exynos_display_notifier_callback(struct notifier_block *this, - unsigned long event, void *_data) -{ - struct fimd_context *ctx - = container_of(this, struct fimd_context, nb_exynos_display); - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - - if (ctx->suspended) - return NOTIFY_DONE; - - switch (event) { - case EXYNOS4_DISPLAY_LV_HF: - timing->refresh = EXYNOS4_DISPLAY_LV_HF; - ctx->high_freq = 1; - break; - case EXYNOS4_DISPLAY_LV_LF: - timing->refresh = EXYNOS4_DISPLAY_LV_LF; - ctx->high_freq = 0; - break; - default: - return NOTIFY_BAD; - } - - exynos_drm_change_clock(ctx); - - return NOTIFY_DONE; -} -#endif - -static ssize_t store_refresh(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - unsigned long refresh; - int ret; - - if (ctx->dynamic_refresh) { - ret = kstrtoul(buf, 0, &refresh); - timing->refresh = refresh; - if (refresh == 60) - ctx->high_freq = 1; - else - ctx->high_freq = 0; - - exynos_drm_change_clock(ctx); - } - - return count; -} - -static ssize_t show_refresh(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - - return snprintf(buf, PAGE_SIZE, "%d\n", timing->refresh); -} - -static struct device_attribute device_attrs[] = { - __ATTR(refresh, S_IRUGO|S_IWUSR, show_refresh, store_refresh), -}; - -#ifdef CONFIG_DRM_EXYNOS_FIMD_WB -static void fimd_set_writeback(struct fimd_context *ctx, int enable) -{ - u32 vidcon0 = readl(ctx->regs + VIDCON0); - u32 vidcon2 = readl(ctx->regs + VIDCON2); - - vidcon0 &= ~VIDCON0_VIDOUT_MASK; - vidcon2 &= ~(VIDCON2_WB_MASK | - VIDCON2_WB_SKIP_MASK | - VIDCON2_TVFORMATSEL_HW_SW_MASK | - VIDCON2_TVFORMATSEL_MASK); - - if (enable) { - vidcon0 |= VIDCON0_VIDOUT_WB; - vidcon2 |= (VIDCON2_WB_ENABLE | - VIDCON2_TVFORMATSEL_SW | - VIDCON2_TVFORMATSEL_YUV444); - } else { - vidcon0 |= VIDCON0_VIDOUT_RGB; - vidcon2 |= VIDCON2_WB_DISABLE; - } - - writel(vidcon0, ctx->regs + VIDCON0); - writel(vidcon2, ctx->regs + VIDCON2); -} - -static int fimd_notifier_ctrl(struct notifier_block *this, - unsigned long event, void *_data) -{ - struct fimd_context *ctx = container_of(this, - struct fimd_context, nb_ctrl); - - switch (event) { - case FIMD_GET_LCD_WIDTH: { - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - int *width = (int *)_data; - - *width = timing->xres; - } - break; - case FIMD_GET_LCD_HEIGHT: { - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - int *height = (int *)_data; - - *height = timing->yres; - } - break; - case FIMD_SET_WRITEBACK: { - unsigned int refresh; - int *enable = (int *)&_data; - -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - if (*enable) - refresh = EXYNOS4_DISPLAY_LV_HF; - else - refresh = EXYNOS4_DISPLAY_LV_LF; - pm_qos_update_request(&ctx->pm_qos, - refresh); -#endif - fimd_set_writeback(ctx, *enable); - } - break; - default: - /* ToDo : for checking use case */ - DRM_INFO("%s:event[0x%x]\n", __func__, (unsigned int)event); - break; - } - - return NOTIFY_DONE; -} -#endif - -static int __devinit fimd_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct fimd_context *ctx; - struct exynos_drm_subdrv *subdrv; - struct exynos_drm_fimd_pdata *pdata; - struct exynos_drm_panel_info *panel; - struct resource *res; - int win; - int i; - int ret = -EINVAL; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(dev, "no platform data specified\n"); - return -EINVAL; - } - - panel = &pdata->panel; - if (!panel) { - dev_err(dev, "panel is null.\n"); - return -EINVAL; - } - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->bus_clk = clk_get(dev, "lcd"); - if (IS_ERR(ctx->bus_clk)) { - dev_err(dev, "failed to get bus clock\n"); - ret = PTR_ERR(ctx->bus_clk); - goto err_clk_get; - } - - clk_enable(ctx->bus_clk); - - ctx->lcd_clk = clk_get(dev, "sclk_fimd"); - if (IS_ERR(ctx->lcd_clk)) { - dev_err(dev, "failed to get lcd clock\n"); - ret = PTR_ERR(ctx->lcd_clk); - goto err_bus_clk; - } - - clk_enable(ctx->lcd_clk); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to find registers\n"); - ret = -ENOENT; - goto err_clk; - } - - ctx->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!ctx->regs_res) { - dev_err(dev, "failed to claim register region\n"); - ret = -ENOENT; - goto err_clk; - } - - ctx->regs = ioremap(res->start, resource_size(res)); - if (!ctx->regs) { - dev_err(dev, "failed to map registers\n"); - ret = -ENXIO; - goto err_req_region_io; - } -#ifdef CONFIG_MACH_SLP_NAPLES - /* Temporary code for trigger*/ - ctx_global = ctx; -#endif - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "irq request failed.\n"); - goto err_get_resource; - } - - ctx->irq = res->start; - - ret = request_irq(ctx->irq, fimd_irq_handler, 0, "drm_fimd", ctx); - if (ret < 0) { - dev_err(dev, "irq request failed.\n"); - goto err_get_resource; - } - - ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); - ctx->vidcon0 = pdata->vidcon0; - ctx->vidcon1 = pdata->vidcon1; - ctx->default_win = pdata->default_win; - ctx->dynamic_refresh = pdata->dynamic_refresh; - ctx->panel = panel; - - INIT_WORK(&ctx->work, exynos_fimd_schedule_work); - - panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; - - DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", - panel->timing.pixclock, ctx->clkdiv); - - /* mdnie support. */ - mdnie = s5p_fimd_ext_find_device("mdnie"); - fimd_lite_dev = s5p_fimd_ext_find_device("fimd_lite"); - if (mdnie && fimd_lite_dev) { - fimd_refresh = kzalloc(sizeof(*fimd_refresh), GFP_KERNEL); - if (!fimd_refresh) { - dev_err(dev, "failed to allocate fimd_refresh.\n"); - ret = -ENOMEM; - goto err_alloc_fail; - } - - fimd_refresh->dynamic_refresh = pdata->dynamic_refresh; - fimd_refresh->regs = ctx->regs; - fimd_refresh->clkdiv = ctx->clkdiv; - } - - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - ret = device_create_file(&(pdev->dev), - &device_attrs[i]); - if (ret) - break; - } - - if (ret < 0) - dev_err(&pdev->dev, "failed to add sysfs entries\n"); - -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - ctx->nb_exynos_display.notifier_call = exynos_display_notifier_callback; - ret = exynos4_display_register_client(&ctx->nb_exynos_display); - if (ret < 0) - dev_warn(dev, "failed to register exynos-display notifier\n"); -#endif - - dev_info(&pdev->dev, "registered successfully\n"); - - subdrv = &ctx->subdrv; - - subdrv->dev = dev; - subdrv->manager = &fimd_manager; - subdrv->probe = fimd_subdrv_probe; - subdrv->remove = fimd_subdrv_remove; - -#ifdef CONFIG_DRM_EXYNOS_FIMD_WB - ctx->nb_ctrl.notifier_call = fimd_notifier_ctrl; - ret = fimc_register_client(&ctx->nb_ctrl); - if (ret) { - dev_err(dev, "could not register fimd notify callback\n"); - goto err_alloc_fail; - } -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - pm_qos_add_request(&ctx->pm_qos, - PM_QOS_DISPLAY_FREQUENCY, EXYNOS4_DISPLAY_LV_LF); -#endif -#endif - - mutex_init(&ctx->lock); - - platform_set_drvdata(pdev, ctx); - - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - - for (win = 0; win < WINDOWS_NR; win++) - if (win != ctx->default_win) - fimd_clear_win(ctx, win); - - exynos_drm_subdrv_register(subdrv); - - return 0; - -err_alloc_fail: - free_irq(ctx->irq, ctx); - -err_get_resource: - iounmap(ctx->regs); - -err_req_region_io: - release_resource(ctx->regs_res); - kfree(ctx->regs_res); - -err_clk: - clk_disable(ctx->lcd_clk); - clk_put(ctx->lcd_clk); - -err_bus_clk: - clk_disable(ctx->bus_clk); - clk_put(ctx->bus_clk); - -err_clk_get: - kfree(ctx); - return ret; -} - -static int __devexit fimd_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct fimd_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); -#ifdef CONFIG_DRM_EXYNOS_FIMD_WB - fimc_unregister_client(&ctx->nb_ctrl); -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - pm_qos_remove_request(&ctx->pm_qos); -#endif -#endif - - if (ctx->suspended) - goto out; - - pm_runtime_set_suspended(dev); - pm_runtime_put_sync(dev); - -out: - pm_runtime_disable(dev); - - clk_put(ctx->lcd_clk); - clk_put(ctx->bus_clk); - - -#ifdef CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ - exynos4_display_unregister_client(&ctx->nb_exynos_display); -#endif - - iounmap(ctx->regs); - release_resource(ctx->regs_res); - kfree(ctx->regs_res); - free_irq(ctx->irq, ctx); - - kfree(ctx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int fimd_suspend(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - if (pm_runtime_suspended(dev)) - return 0; - - /* - * do not use pm_runtime_suspend(). if pm_runtime_suspend() is - * called here, an error would be returned by that interface - * because the usage_count of pm runtime is more than 1. - */ - return fimd_power_on(ctx, false); -} - -static int fimd_resume(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - /* - * if entered to sleep when lcd panel was on, the usage_count - * of pm runtime would still be 1 so in this case, fimd driver - * should be on directly not drawing on pm runtime interface. - */ - if (!pm_runtime_suspended(dev)) - return fimd_power_on(ctx, true); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int fimd_runtime_suspend(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return fimd_power_on(ctx, false); -} - -static int fimd_runtime_resume(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return fimd_power_on(ctx, true); -} -#endif - -static const struct dev_pm_ops fimd_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) - SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) -}; - -struct platform_driver fimd_driver = { - .probe = fimd_probe, - .remove = __devexit_p(fimd_remove), - .driver = { - .name = "s3cfb", - .owner = THIS_MODULE, - .pm = &fimd_pm_ops, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.c deleted file mode 100644 index a8f201e..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/pm_qos_params.h> -#include <linux/pm_runtime.h> -#include <linux/slab.h> -#include <linux/workqueue.h> - -#include "drmP.h" -#include "exynos_drm.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_iommu.h" - -#define G2D_HW_MAJOR_VER 4 -#define G2D_HW_MINOR_VER 1 - -/* vaild register range set from user: 0x0104 ~ 0x0880 */ -#define G2D_VALID_START 0x0104 -#define G2D_VALID_END 0x0880 - -/* general registers */ -#define G2D_SOFT_RESET 0x0000 -#define G2D_INTEN 0x0004 -#define G2D_INTC_PEND 0x000C -#define G2D_DMA_SFR_BASE_ADDR 0x0080 -#define G2D_DMA_COMMAND 0x0084 -#define G2D_DMA_STATUS 0x008C -#define G2D_DMA_HOLD_CMD 0x0090 - -/* command registers */ -#define G2D_BITBLT_START 0x0100 - -/* registers for base address */ -#define G2D_SRC_BASE_ADDR 0x0304 -#define G2D_SRC_PLANE2_BASE_ADDR 0x0318 -#define G2D_DST_BASE_ADDR 0x0404 -#define G2D_DST_PLANE2_BASE_ADDR 0x0418 -#define G2D_PAT_BASE_ADDR 0x0500 -#define G2D_MSK_BASE_ADDR 0x0520 - -/* G2D_SOFT_RESET */ -#define G2D_SFRCLEAR (1 << 1) -#define G2D_R (1 << 0) - -/* G2D_INTEN */ -#define G2D_INTEN_ACF (1 << 3) -#define G2D_INTEN_UCF (1 << 2) -#define G2D_INTEN_GCF (1 << 1) -#define G2D_INTEN_SCF (1 << 0) - -/* G2D_INTC_PEND */ -#define G2D_INTP_ACMD_FIN (1 << 3) -#define G2D_INTP_UCMD_FIN (1 << 2) -#define G2D_INTP_GCMD_FIN (1 << 1) -#define G2D_INTP_SCMD_FIN (1 << 0) - -/* G2D_DMA_COMMAND */ -#define G2D_DMA_HALT (1 << 2) -#define G2D_DMA_CONTINUE (1 << 1) -#define G2D_DMA_START (1 << 0) - -/* G2D_DMA_STATUS */ -#define G2D_DMA_LIST_DONE_COUNT (0xFF << 17) -#define G2D_DMA_BITBLT_DONE_COUNT (0xFFFF << 1) -#define G2D_DMA_DONE (1 << 0) -#define G2D_DMA_LIST_DONE_COUNT_OFFSET 17 - -/* G2D_DMA_HOLD_CMD */ -#define G2D_USET_HOLD (1 << 2) -#define G2D_LIST_HOLD (1 << 1) -#define G2D_BITBLT_HOLD (1 << 0) - -/* G2D_BITBLT_START */ -#define G2D_START_CASESEL (1 << 2) -#define G2D_START_NHOLT (1 << 1) -#define G2D_START_BITBLT (1 << 0) - -#define G2D_CMDLIST_SIZE (PAGE_SIZE / 4) -#define G2D_CMDLIST_NUM 64 -#define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) -#define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2) - -#define MAX_BUF_ADDR_NR 6 - -/* cmdlist data structure */ -struct g2d_cmdlist { - u32 head; - u32 data[G2D_CMDLIST_DATA_NUM]; - u32 last; /* last data offset */ -}; - -struct drm_exynos_pending_g2d_event { - struct drm_pending_event base; - struct drm_exynos_g2d_event event; -}; - -struct g2d_cmdlist_node { - struct list_head list; - struct g2d_cmdlist *cmdlist; - unsigned int map_nr; - void *gem_obj[MAX_BUF_ADDR_NR]; - dma_addr_t dma_addr; - - struct drm_exynos_pending_g2d_event *event; -}; - -struct g2d_runqueue_node { - struct list_head list; - struct list_head run_cmdlist; - struct list_head event_list; - struct completion complete; - int async; -}; - -struct g2d_data { - struct device *dev; - struct clk *gate_clk; - struct resource *regs_res; - void __iomem *regs; - int irq; - struct workqueue_struct *g2d_workq; - struct work_struct runqueue_work; - struct exynos_drm_subdrv subdrv; - struct pm_qos_request_list pm_qos; - bool suspended; - - /* cmdlist */ - struct g2d_cmdlist_node *cmdlist_node; - struct list_head free_cmdlist; - struct mutex cmdlist_mutex; - dma_addr_t cmdlist_pool; - dma_addr_t cmdlist_pool_map; - void *cmdlist_pool_virt; - - /* runqueue*/ - struct g2d_runqueue_node *runqueue_node; - struct list_head runqueue; - struct mutex runqueue_mutex; - struct kmem_cache *runqueue_slab; -}; - -static int g2d_init_cmdlist(struct g2d_data *g2d) -{ - struct device *dev = g2d->dev; - struct g2d_cmdlist_node *node = g2d->cmdlist_node; - int nr; - int ret; - - g2d->cmdlist_pool_virt = dma_alloc_coherent(dev, G2D_CMDLIST_POOL_SIZE, - &g2d->cmdlist_pool, GFP_KERNEL); - if (!g2d->cmdlist_pool_virt) { - dev_err(dev, "failed to allocate dma memory\n"); - return -ENOMEM; - } - - /* - * Allocate device address space for command list pool and then map all - * pages contained in sg list to iommu table. Command list pool also is - * accessed by dma through device address with using iommu. - */ - g2d->cmdlist_pool_map = exynos_drm_iommu_map(dev, g2d->cmdlist_pool, - G2D_CMDLIST_POOL_SIZE); - if (!g2d->cmdlist_pool_map) { - dev_err(dev, "failed map to iommu\n"); - ret = -EFAULT; - goto err; - } - - node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node), - GFP_KERNEL); - if (!node) { - dev_err(dev, "failed to allocate memory\n"); - ret = -ENOMEM; - goto err_iommu_unmap; - } - - for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) { - node[nr].cmdlist = - g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; - node[nr].dma_addr = - g2d->cmdlist_pool_map + nr * G2D_CMDLIST_SIZE; - - list_add_tail(&node[nr].list, &g2d->free_cmdlist); - } - - return 0; - -err_iommu_unmap: - exynos_drm_iommu_unmap(dev, g2d->cmdlist_pool_map); -err: - dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt, - g2d->cmdlist_pool); - return ret; -} - -static void g2d_fini_cmdlist(struct g2d_data *g2d) -{ - struct device *dev = g2d->dev; - - exynos_drm_iommu_unmap(dev, g2d->cmdlist_pool_map); - - kfree(g2d->cmdlist_node); - dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt, - g2d->cmdlist_pool); -} - -static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) -{ - struct device *dev = g2d->dev; - struct g2d_cmdlist_node *node; - - mutex_lock(&g2d->cmdlist_mutex); - if (list_empty(&g2d->free_cmdlist)) { - dev_err(dev, "there is no free cmdlist\n"); - mutex_unlock(&g2d->cmdlist_mutex); - return NULL; - } - - node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node, - list); - list_del_init(&node->list); - mutex_unlock(&g2d->cmdlist_mutex); - - return node; -} - -static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node) -{ - mutex_lock(&g2d->cmdlist_mutex); - list_move_tail(&node->list, &g2d->free_cmdlist); - mutex_unlock(&g2d->cmdlist_mutex); -} - -static void g2d_add_cmdlist_to_inuse(struct exynos_drm_g2d_private *g2d_priv, - struct g2d_cmdlist_node *node) -{ - struct g2d_cmdlist_node *lnode; - - if (list_empty(&g2d_priv->inuse_cmdlist)) - goto add_to_list; - - /* this links to base address of new cmdlist */ - lnode = list_entry(g2d_priv->inuse_cmdlist.prev, - struct g2d_cmdlist_node, list); - lnode->cmdlist->data[lnode->cmdlist->last] = node->dma_addr; - -add_to_list: - list_add_tail(&node->list, &g2d_priv->inuse_cmdlist); - - if (node->event) - list_add_tail(&node->event->base.link, &g2d_priv->event_list); -} - -static int g2d_map_cmdlist_gem(struct g2d_data *g2d, - struct g2d_cmdlist_node *node, - struct drm_device *drm_dev, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; - struct g2d_cmdlist *cmdlist = node->cmdlist; - struct iommu_gem_map_params params; - unsigned int gem_handle; - dma_addr_t addr; - int offset; - int i; - - params.dev = g2d->dev; - params.drm_dev = drm_dev; - params.file = file; - - for (i = 0; i < node->map_nr; i++) { - offset = cmdlist->last - (i * 2 + 1); - gem_handle = cmdlist->data[offset]; - - addr = exynos_drm_iommu_map_gem(¶ms, - &g2d_priv->iommu_map_list, - gem_handle, - IOMMU_G2D); - if (!addr) { - node->map_nr = i; - return -EFAULT; - } - - cmdlist->data[offset] = addr; - node->gem_obj[i] = params.gem_obj; - } - - return 0; -} - -static void g2d_unmap_cmdlist_gem(struct drm_device *drm_dev, - struct g2d_cmdlist_node *node, - struct drm_file *file, int dec) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; - struct device *dev = g2d_priv->dev; - struct g2d_cmdlist *cmdlist = node->cmdlist; - struct iommu_gem_map_params params; - struct g2d_data *g2d; - dma_addr_t addr; - int offset; - int i; - - g2d = dev_get_drvdata(dev); - if (!g2d) - return; - - params.dev = dev; - params.drm_dev = drm_dev; - params.file = file; - - for (i = 0; i < node->map_nr; i++) { - offset = cmdlist->last - (i * 2 + 1) - dec; - addr = cmdlist->data[offset]; - - params.gem_obj = node->gem_obj[i]; - - exynos_drm_iommu_unmap_gem(¶ms, addr, - IOMMU_G2D); - } -} - -static void g2d_dma_start(struct g2d_data *g2d, - struct g2d_runqueue_node *runqueue_node) -{ - struct g2d_cmdlist_node *node = - list_first_entry(&runqueue_node->run_cmdlist, - struct g2d_cmdlist_node, list); - - pm_runtime_get_sync(g2d->dev); - clk_enable(g2d->gate_clk); - pm_qos_update_request(&g2d->pm_qos, 400000); - - /* interrupt enable */ - writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF, - g2d->regs + G2D_INTEN); - - writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); - writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); -} - -static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d) -{ - struct g2d_runqueue_node *runqueue_node; - - if (list_empty(&g2d->runqueue)) - return NULL; - - runqueue_node = list_first_entry(&g2d->runqueue, - struct g2d_runqueue_node, list); - list_del_init(&runqueue_node->list); - return runqueue_node; -} - -static void g2d_free_runqueue_node(struct g2d_data *g2d, - struct g2d_runqueue_node *runqueue_node) -{ - if (!runqueue_node) - return; - - mutex_lock(&g2d->cmdlist_mutex); - list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist); - mutex_unlock(&g2d->cmdlist_mutex); - - kmem_cache_free(g2d->runqueue_slab, runqueue_node); -} - -static void g2d_exec_runqueue(struct g2d_data *g2d) -{ - g2d->runqueue_node = g2d_get_runqueue_node(g2d); - if (g2d->runqueue_node) - g2d_dma_start(g2d, g2d->runqueue_node); -} - -static void g2d_runqueue_worker(struct work_struct *work) -{ - struct g2d_data *g2d = container_of(work, struct g2d_data, - runqueue_work); - - pm_qos_update_request(&g2d->pm_qos, 0); - - mutex_lock(&g2d->runqueue_mutex); - clk_disable(g2d->gate_clk); - pm_runtime_put_sync(g2d->dev); - - complete(&g2d->runqueue_node->complete); - if (g2d->runqueue_node->async) - g2d_free_runqueue_node(g2d, g2d->runqueue_node); - - if (g2d->suspended) - g2d->runqueue_node = NULL; - else - g2d_exec_runqueue(g2d); - mutex_unlock(&g2d->runqueue_mutex); -} - -static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) -{ - struct drm_device *drm_dev = g2d->subdrv.drm_dev; - struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; - struct drm_exynos_pending_g2d_event *e; - struct timeval now; - unsigned long flags; - - if (list_empty(&runqueue_node->event_list)) - return; - - e = list_first_entry(&runqueue_node->event_list, - struct drm_exynos_pending_g2d_event, base.link); - - do_gettimeofday(&now); - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - e->event.cmdlist_no = cmdlist_no; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static irqreturn_t g2d_irq_handler(int irq, void *dev_id) -{ - struct g2d_data *g2d = dev_id; - u32 pending; - - pending = readl_relaxed(g2d->regs + G2D_INTC_PEND); - if (pending) - writel_relaxed(pending, g2d->regs + G2D_INTC_PEND); - - if (pending & G2D_INTP_GCMD_FIN) { - u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS); - - cmdlist_no = (cmdlist_no & G2D_DMA_LIST_DONE_COUNT) >> - G2D_DMA_LIST_DONE_COUNT_OFFSET; - - g2d_finish_event(g2d, cmdlist_no); - - writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD); - if (!(pending & G2D_INTP_ACMD_FIN)) { - writel_relaxed(G2D_DMA_CONTINUE, - g2d->regs + G2D_DMA_COMMAND); - } - } - - if (pending & G2D_INTP_ACMD_FIN) - queue_work(g2d->g2d_workq, &g2d->runqueue_work); - - return IRQ_HANDLED; -} - -static int g2d_check_reg_offset(struct device *dev, struct g2d_cmdlist *cmdlist, - int nr, bool for_addr) -{ - int reg_offset; - int index; - int i; - - for (i = 0; i < nr; i++) { - index = cmdlist->last - 2 * (i + 1); - reg_offset = cmdlist->data[index] & ~0xfffff000; - - if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END) - goto err; - if (reg_offset % 4) - goto err; - - switch (reg_offset) { - case G2D_SRC_BASE_ADDR: - case G2D_SRC_PLANE2_BASE_ADDR: - case G2D_DST_BASE_ADDR: - case G2D_DST_PLANE2_BASE_ADDR: - case G2D_PAT_BASE_ADDR: - case G2D_MSK_BASE_ADDR: - if (!for_addr) - goto err; - break; - default: - if (for_addr) - goto err; - break; - } - } - - return 0; - -err: - dev_err(dev, "Bad register offset: 0x%x\n", cmdlist->data[index]); - return -EINVAL; -} - -/* ioctl functions */ -int exynos_g2d_get_ver_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file) -{ - struct drm_exynos_g2d_get_ver *ver = data; - - ver->major = G2D_HW_MAJOR_VER; - ver->minor = G2D_HW_MINOR_VER; - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_g2d_get_ver_ioctl); - -int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; - struct device *dev = g2d_priv->dev; - struct g2d_data *g2d; - struct drm_exynos_g2d_set_cmdlist *req = data; - struct drm_exynos_pending_g2d_event *e; - struct g2d_cmdlist_node *node; - struct g2d_cmdlist *cmdlist; - unsigned long flags; - int size; - int ret; - - if (!dev) - return -ENODEV; - - g2d = dev_get_drvdata(dev); - if (!g2d) - return -EFAULT; - - node = g2d_get_cmdlist(g2d); - if (!node) - return -ENOMEM; - - node->event = NULL; - - if (req->event_type != G2D_EVENT_NOT) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - if (file->event_space < sizeof(e->event)) { - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - ret = -ENOMEM; - goto err; - } - file->event_space -= sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - - e = kzalloc(sizeof(*node->event), GFP_KERNEL); - if (!e) { - dev_err(dev, "failed to allocate event\n"); - - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - - ret = -ENOMEM; - goto err; - } - - e->event.base.type = DRM_EXYNOS_G2D_EVENT; - e->event.base.length = sizeof(e->event); - e->event.user_data = req->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; - - node->event = e; - } - - cmdlist = node->cmdlist; - - cmdlist->last = 0; - - /* - * If don't clear SFR registers, the cmdlist is affected by register - * values of previous cmdlist. G2D hw executes SFR clear command and - * a next command at the same time then the next command is ignored and - * is executed rightly from next next command, so needs a dummy command - * to next command of SFR clear command. - */ - cmdlist->data[cmdlist->last++] = G2D_SOFT_RESET; - cmdlist->data[cmdlist->last++] = G2D_SFRCLEAR; - cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR; - cmdlist->data[cmdlist->last++] = 0; - - if (node->event) { - cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD; - cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD; - } - - /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ - size = cmdlist->last + req->cmd_nr * 2 + req->cmd_gem_nr * 2 + 2; - if (size > G2D_CMDLIST_DATA_NUM) { - dev_err(dev, "cmdlist size is too big\n"); - ret = -EINVAL; - goto err_free_event; - } - - if (copy_from_user(cmdlist->data + cmdlist->last, - (void __user *)req->cmd, - sizeof(*req->cmd) * req->cmd_nr)) { - ret = -EFAULT; - goto err_free_event; - } - cmdlist->last += req->cmd_nr * 2; - - ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_nr, false); - if (ret < 0) - goto err_free_event; - - node->map_nr = req->cmd_gem_nr; - if (req->cmd_gem_nr) { - struct drm_exynos_g2d_cmd *cmd_gem = req->cmd_gem; - - if (copy_from_user(cmdlist->data + cmdlist->last, - (void __user *)cmd_gem, - sizeof(*cmd_gem) * req->cmd_gem_nr)) { - ret = -EFAULT; - goto err_free_event; - } - cmdlist->last += req->cmd_gem_nr * 2; - - ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_gem_nr, true); - if (ret < 0) - goto err_free_event; - - ret = g2d_map_cmdlist_gem(g2d, node, drm_dev, file); - if (ret < 0) - goto err_unmap; - } - - cmdlist->data[cmdlist->last++] = G2D_BITBLT_START; - cmdlist->data[cmdlist->last++] = G2D_START_BITBLT; - - /* head */ - cmdlist->head = cmdlist->last / 2; - - /* tail */ - cmdlist->data[cmdlist->last] = 0; - - g2d_add_cmdlist_to_inuse(g2d_priv, node); - - return 0; - -err_unmap: - g2d_unmap_cmdlist_gem(drm_dev, node, file, 0); -err_free_event: - if (node->event) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - kfree(node->event); - } -err: - g2d_put_cmdlist(g2d, node); - return ret; -} -EXPORT_SYMBOL_GPL(exynos_g2d_set_cmdlist_ioctl); - -int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; - struct device *dev = g2d_priv->dev; - struct g2d_data *g2d; - struct drm_exynos_g2d_exec *req = data; - struct g2d_runqueue_node *runqueue_node; - struct list_head *run_cmdlist; - struct list_head *event_list; - - if (!dev) - return -ENODEV; - - g2d = dev_get_drvdata(dev); - if (!g2d) - return -EFAULT; - - runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL); - if (!runqueue_node) { - dev_err(dev, "failed to allocate memory\n"); - return -ENOMEM; - } - run_cmdlist = &runqueue_node->run_cmdlist; - event_list = &runqueue_node->event_list; - INIT_LIST_HEAD(run_cmdlist); - INIT_LIST_HEAD(event_list); - init_completion(&runqueue_node->complete); - runqueue_node->async = req->async; - - list_splice_init(&g2d_priv->inuse_cmdlist, run_cmdlist); - list_splice_init(&g2d_priv->event_list, event_list); - - if (list_empty(run_cmdlist)) { - dev_err(dev, "there is no inuse cmdlist\n"); - kmem_cache_free(g2d->runqueue_slab, runqueue_node); - return -EPERM; - } - - mutex_lock(&g2d->runqueue_mutex); - list_add_tail(&runqueue_node->list, &g2d->runqueue); - if (!g2d->runqueue_node) - g2d_exec_runqueue(g2d); - mutex_unlock(&g2d->runqueue_mutex); - - if (runqueue_node->async) - goto out; - - wait_for_completion(&runqueue_node->complete); - g2d_free_runqueue_node(g2d, runqueue_node); - -out: - return 0; -} -EXPORT_SYMBOL_GPL(exynos_g2d_exec_ioctl); - -static int g2d_open(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv; - - g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL); - if (!g2d_priv) { - dev_err(dev, "failed to allocate g2d private data\n"); - return -ENOMEM; - } - - g2d_priv->dev = dev; - file_priv->g2d_priv = g2d_priv; - - INIT_LIST_HEAD(&g2d_priv->inuse_cmdlist); - INIT_LIST_HEAD(&g2d_priv->event_list); - INIT_LIST_HEAD(&g2d_priv->iommu_map_list); - - return 0; -} - -static void g2d_close(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; - struct g2d_data *g2d; - struct g2d_cmdlist_node *node, *n; - struct iommu_info_node *im, *t_im; - struct iommu_gem_map_params params; - - if (!dev) - return; - - g2d = dev_get_drvdata(dev); - if (!g2d) - return; - - mutex_lock(&g2d->cmdlist_mutex); - list_for_each_entry_safe(node, n, &g2d_priv->inuse_cmdlist, list) - list_move_tail(&node->list, &g2d->free_cmdlist); - mutex_unlock(&g2d->cmdlist_mutex); - - params.dev = dev; - params.drm_dev = drm_dev; - params.file = file; - - /* - * unmap all device address spaces from iommu table and - * release all lists. - */ - list_for_each_entry_safe(im, t_im, &g2d_priv->iommu_map_list, list) { - params.gem_obj = im->gem_obj; - - exynos_drm_iommu_unmap_gem(¶ms, im->dma_addr, - IOMMU_G2D); - list_del(&im->list); - kfree(im); - im = NULL; - } - - kfree(file_priv->g2d_priv); -} - -static int __devinit g2d_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct resource *res; - struct g2d_data *g2d; - struct exynos_drm_subdrv *subdrv; - int ret; - - g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); - if (!g2d) { - dev_err(dev, "failed to allocate driver data\n"); - return -ENOMEM; - } - - g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", - sizeof(struct g2d_runqueue_node), 0, 0, NULL); - if (!g2d->runqueue_slab) { - ret = -ENOMEM; - goto err_free_mem; - } - - g2d->dev = dev; - - g2d->g2d_workq = create_singlethread_workqueue("g2d"); - if (!g2d->g2d_workq) { - dev_err(dev, "failed to create workqueue\n"); - ret = -EINVAL; - goto err_destroy_slab; - } - - INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker); - INIT_LIST_HEAD(&g2d->free_cmdlist); - INIT_LIST_HEAD(&g2d->runqueue); - - mutex_init(&g2d->cmdlist_mutex); - mutex_init(&g2d->runqueue_mutex); - - /* setup device address space for g2d iommu */ - ret = exynos_drm_iommu_setup(dev); - if (ret < 0) { - dev_err(dev, "failed to setup iommu\n"); - goto err_destroy_workqueue; - } - - /* enable iommu to g2d hardware */ - ret = exynos_drm_iommu_activate(dev); - if (ret < 0) { - dev_err(dev, "failed to activate iommu\n"); - goto err_iommu_cleanup; - } - - ret = g2d_init_cmdlist(g2d); - if (ret < 0) - goto err_iommu_deactivate; - - g2d->gate_clk = clk_get(dev, "fimg2d"); - if (IS_ERR(g2d->gate_clk)) { - dev_err(dev, "failed to get gate clock\n"); - ret = PTR_ERR(g2d->gate_clk); - goto err_fini_cmdlist; - } - - pm_runtime_enable(dev); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to get I/O memory\n"); - ret = -ENOENT; - goto err_put_clk; - } - - g2d->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!g2d->regs_res) { - dev_err(dev, "failed to request I/O memory\n"); - ret = -ENOENT; - goto err_put_clk; - } - - g2d->regs = ioremap(res->start, resource_size(res)); - if (!g2d->regs) { - dev_err(dev, "failed to remap I/O memory\n"); - ret = -ENXIO; - goto err_release_res; - } - - g2d->irq = platform_get_irq(pdev, 0); - if (g2d->irq < 0) { - dev_err(dev, "failed to get irq\n"); - ret = g2d->irq; - goto err_unmap_base; - } - - ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); - if (ret < 0) { - dev_err(dev, "irq request failed\n"); - goto err_unmap_base; - } - - platform_set_drvdata(pdev, g2d); - - subdrv = &g2d->subdrv; - subdrv->dev = dev; - subdrv->open = g2d_open; - subdrv->close = g2d_close; - - ret = exynos_drm_subdrv_register(subdrv); - if (ret < 0) { - dev_err(dev, "failed to register drm g2d device\n"); - goto err_free_irq; - } - - pm_qos_add_request(&g2d->pm_qos, PM_QOS_BUS_DMA_THROUGHPUT, 0); - - dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", - G2D_HW_MAJOR_VER, G2D_HW_MINOR_VER); - - return 0; - -err_free_irq: - free_irq(g2d->irq, g2d); -err_unmap_base: - iounmap(g2d->regs); -err_release_res: - release_resource(g2d->regs_res); - kfree(g2d->regs_res); -err_put_clk: - pm_runtime_disable(dev); - clk_put(g2d->gate_clk); -err_fini_cmdlist: - g2d_fini_cmdlist(g2d); -err_iommu_deactivate: - exynos_drm_iommu_deactivate(dev); -err_iommu_cleanup: - exynos_drm_iommu_cleanup(dev); -err_destroy_workqueue: - destroy_workqueue(g2d->g2d_workq); -err_destroy_slab: - kmem_cache_destroy(g2d->runqueue_slab); -err_free_mem: - kfree(g2d); - return ret; -} - -static int __devexit g2d_remove(struct platform_device *pdev) -{ - struct g2d_data *g2d = platform_get_drvdata(pdev); - - cancel_work_sync(&g2d->runqueue_work); - pm_qos_remove_request(&g2d->pm_qos); - exynos_drm_subdrv_unregister(&g2d->subdrv); - free_irq(g2d->irq, g2d); - - while (g2d->runqueue_node) { - g2d_free_runqueue_node(g2d, g2d->runqueue_node); - g2d->runqueue_node = g2d_get_runqueue_node(g2d); - } - - iounmap(g2d->regs); - release_resource(g2d->regs_res); - kfree(g2d->regs_res); - - pm_runtime_disable(&pdev->dev); - clk_put(g2d->gate_clk); - - g2d_fini_cmdlist(g2d); - exynos_drm_iommu_deactivate(&pdev->dev); - exynos_drm_iommu_cleanup(&pdev->dev); - destroy_workqueue(g2d->g2d_workq); - kmem_cache_destroy(g2d->runqueue_slab); - kfree(g2d); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int g2d_suspend(struct device *dev) -{ - struct g2d_data *g2d = dev_get_drvdata(dev); - - mutex_lock(&g2d->runqueue_mutex); - g2d->suspended = true; - mutex_unlock(&g2d->runqueue_mutex); - - while (g2d->runqueue_node) - /* FIXME: good range? */ - usleep_range(500, 1000); - - flush_work_sync(&g2d->runqueue_work); - - return 0; -} - -static int g2d_resume(struct device *dev) -{ - struct g2d_data *g2d = dev_get_drvdata(dev); - - g2d->suspended = false; - g2d_exec_runqueue(g2d); - - return 0; -} -#endif - -SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); - -struct platform_driver g2d_driver = { - .probe = g2d_probe, - .remove = __devexit_p(g2d_remove), - .driver = { - /* FIXME */ - .name = "s5p-fimg2d", - .owner = THIS_MODULE, - .pm = &g2d_pm_ops, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.h deleted file mode 100644 index 1a9c7ca..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_g2d.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#ifdef CONFIG_DRM_EXYNOS_G2D -extern int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -#else -static inline int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static inline int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev, - void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.c deleted file mode 100644 index 35d2cd9..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* exynos_drm_gem.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" - -#include <drm/exynos_drm.h> -#include <linux/shmem_fs.h> -#include <linux/dma-buf.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_buf.h" -#include "exynos_drm_iommu.h" - -static struct exynos_drm_private_cb *private_cb; - -void exynos_drm_priv_cb_register(struct exynos_drm_private_cb *cb) -{ - if (cb) - private_cb = cb; -} - -int register_buf_to_priv_mgr(struct exynos_drm_gem_obj *obj, - unsigned int *priv_handle, unsigned int *priv_id) -{ - if (private_cb && private_cb->add_buffer) - return private_cb->add_buffer(obj, priv_handle, priv_id); - - return 0; -} - -static unsigned int convert_to_vm_err_msg(int msg) -{ - unsigned int out_msg; - - switch (msg) { - case 0: - case -ERESTARTSYS: - case -EINTR: - out_msg = VM_FAULT_NOPAGE; - break; - - case -ENOMEM: - out_msg = VM_FAULT_OOM; - break; - - default: - out_msg = VM_FAULT_SIGBUS; - break; - } - - return out_msg; -} - -static int check_gem_flags(unsigned int flags) -{ - if (flags & ~(EXYNOS_BO_MASK)) { - DRM_ERROR("invalid flags.\n"); - return -EINVAL; - } - - return 0; -} - -static int check_cache_flags(unsigned int flags) -{ - if (flags & ~(EXYNOS_DRM_CACHE_SEL_MASK | EXYNOS_DRM_CACHE_OP_MASK)) { - DRM_ERROR("invalid flags.\n"); - return -EINVAL; - } - - return 0; -} - -static struct vm_area_struct *get_vma(struct vm_area_struct *vma) -{ - struct vm_area_struct *vma_copy; - - vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL); - if (!vma_copy) - return NULL; - - if (vma->vm_ops && vma->vm_ops->open) - vma->vm_ops->open(vma); - - if (vma->vm_file) - get_file(vma->vm_file); - - memcpy(vma_copy, vma, sizeof(*vma)); - - vma_copy->vm_mm = NULL; - vma_copy->vm_next = NULL; - vma_copy->vm_prev = NULL; - - return vma_copy; -} - -static void put_vma(struct vm_area_struct *vma) -{ - if (!vma) - return; - - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - - if (vma->vm_file) - fput(vma->vm_file); - - kfree(vma); -} - -static void update_vm_cache_attr(struct exynos_drm_gem_obj *obj, - struct vm_area_struct *vma) -{ - DRM_DEBUG_KMS("flags = 0x%x\n", obj->flags); - - /* non-cachable as default. */ - if (obj->flags & EXYNOS_BO_CACHABLE) - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - else if (obj->flags & EXYNOS_BO_WC) - vma->vm_page_prot = - pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); - else - vma->vm_page_prot = - pgprot_noncached(vm_get_page_prot(vma->vm_flags)); -} - -static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) -{ - if (!IS_NONCONTIG_BUFFER(flags)) { - if (size >= SZ_1M) - return roundup(size, SECTION_SIZE); - else if (size >= SZ_64K) - return roundup(size, SZ_64K); - else - goto out; - } -out: - return roundup(size, PAGE_SIZE); -} - -struct page **exynos_gem_get_pages(struct drm_gem_object *obj, - gfp_t gfpmask) -{ - struct inode *inode; - struct address_space *mapping; - struct page *p, **pages; - int i, npages; - - /* This is the shared memory object that backs the GEM resource */ - inode = obj->filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - - npages = obj->size >> PAGE_SHIFT; - - pages = drm_malloc_ab(npages, sizeof(struct page *)); - if (pages == NULL) - return ERR_PTR(-ENOMEM); - - gfpmask |= mapping_gfp_mask(mapping); - - for (i = 0; i < npages; i++) { - p = shmem_read_mapping_page_gfp(mapping, i, gfpmask); - if (IS_ERR(p)) - goto fail; - pages[i] = p; - } - - return pages; - -fail: - while (i--) - page_cache_release(pages[i]); - - drm_free_large(pages); - return ERR_PTR(PTR_ERR(p)); -} - -static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) -{ - int i, npages; - - npages = obj->size >> PAGE_SHIFT; - - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } - - drm_free_large(pages); -} - -static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, - struct vm_area_struct *vma, - unsigned long f_vaddr, - pgoff_t page_offset) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - unsigned long pfn; - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - if (!buf->pages) - return -EINTR; - - pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; - - return vm_insert_mixed(vma, f_vaddr, pfn); -} - -static int exynos_drm_gem_get_pages(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - struct scatterlist *sgl; - struct page **pages; - unsigned int npages, i = 0; - int ret; - - if (buf->pages) { - DRM_DEBUG_KMS("already allocated.\n"); - return -EINVAL; - } - - pages = exynos_gem_get_pages(obj, GFP_KERNEL); - if (IS_ERR(pages)) { - DRM_ERROR("failed to get pages.\n"); - return PTR_ERR(pages); - } - - npages = obj->size >> PAGE_SHIFT; - buf->page_size = PAGE_SIZE; - - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!buf->sgt) { - DRM_ERROR("failed to allocate sg table.\n"); - ret = -ENOMEM; - goto err; - } - - ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); - if (ret < 0) { - DRM_ERROR("failed to initialize sg table.\n"); - ret = -EFAULT; - goto err1; - } - - sgl = buf->sgt->sgl; - - /* set all pages to sg list. */ - while (i < npages) { - sg_set_page(sgl, pages[i], PAGE_SIZE, 0); - sg_dma_address(sgl) = page_to_phys(pages[i]); - i++; - sgl = sg_next(sgl); - } - - /* add some codes for UNCACHED type here. TODO */ - - buf->pages = pages; - return ret; -err1: - kfree(buf->sgt); - buf->sgt = NULL; -err: - exynos_gem_put_pages(obj, pages, true, false); - return ret; - -} - -static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - - /* - * if buffer typs is EXYNOS_BO_NONCONTIG then release all pages - * allocated at gem fault handler. - */ - sg_free_table(buf->sgt); - kfree(buf->sgt); - buf->sgt = NULL; - - exynos_gem_put_pages(obj, buf->pages, true, false); - buf->pages = NULL; - - /* add some codes for UNCACHED type here. TODO */ -} - -static void exynos_drm_put_userptr(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buf; - struct vm_area_struct *vma; - int npages; - - exynos_gem_obj = to_exynos_gem_obj(obj); - buf = exynos_gem_obj->buffer; - vma = exynos_gem_obj->vma; - - if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) { - put_vma(exynos_gem_obj->vma); - goto out; - } - - npages = buf->size >> PAGE_SHIFT; - - npages--; - while (npages >= 0) { - if (buf->write) - set_page_dirty_lock(buf->pages[npages]); - - put_page(buf->pages[npages]); - npages--; - } - -out: - kfree(buf->pages); - buf->pages = NULL; - - kfree(buf->sgt); - buf->sgt = NULL; -} - -static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, - struct drm_file *file_priv, - unsigned int *handle) -{ - int ret; - - /* - * allocate a id of idr table where the obj is registered - * and handle has the id what user can see. - */ - ret = drm_gem_handle_create(file_priv, obj, handle); - if (ret) - return ret; - - DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle); - - /* drop reference from allocate - handle holds it now. */ - drm_gem_object_unreference_unlocked(obj); - - return 0; -} - -void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj) -{ - struct drm_gem_object *obj; - struct exynos_drm_gem_buf *buf; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - obj = &exynos_gem_obj->base; - buf = exynos_gem_obj->buffer; - - DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count)); - - /* - * release a private buffer from its table. - * - * this callback will release a ump object only if user requested - * ump export otherwise just return. - */ - if (private_cb->release_buffer) - private_cb->release_buffer(exynos_gem_obj->priv_handle); - - if (!buf->pages) - return; - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) - exynos_drm_gem_put_pages(obj); - else if (exynos_gem_obj->flags & EXYNOS_BO_USERPTR) - exynos_drm_put_userptr(obj); - else - exynos_drm_free_buf(obj->dev, exynos_gem_obj->flags, buf); - - exynos_drm_fini_buf(obj->dev, buf); - exynos_gem_obj->buffer = NULL; - - if (obj->map_list.map) - drm_gem_free_mmap_offset(obj); - - /* release file pointer to gem object. */ - drm_gem_object_release(obj); - - kfree(exynos_gem_obj); - exynos_gem_obj = NULL; -} - -struct exynos_drm_gem_obj *exynos_drm_gem_get_obj(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return ERR_PTR(-EINVAL); - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - drm_gem_object_unreference_unlocked(obj); - - return exynos_gem_obj; -} - -struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, - unsigned long size) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - int ret; - - exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); - if (!exynos_gem_obj) { - DRM_ERROR("failed to allocate exynos gem object\n"); - return NULL; - } - - exynos_gem_obj->size = size; - obj = &exynos_gem_obj->base; - - ret = drm_gem_object_init(dev, obj, size); - if (ret < 0) { - DRM_ERROR("failed to initialize gem object\n"); - kfree(exynos_gem_obj); - return NULL; - } - - DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); - - return exynos_gem_obj; -} - -struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, - unsigned int flags, - unsigned long size) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buf; - int ret; - - if (!size) { - DRM_ERROR("invalid size.\n"); - return ERR_PTR(-EINVAL); - } - - size = roundup_gem_size(size, flags); - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = check_gem_flags(flags); - if (ret) - return ERR_PTR(ret); - - buf = exynos_drm_init_buf(dev, size); - if (!buf) - return ERR_PTR(-ENOMEM); - - exynos_gem_obj = exynos_drm_gem_init(dev, size); - if (!exynos_gem_obj) { - ret = -ENOMEM; - goto err_fini_buf; - } - - exynos_gem_obj->buffer = buf; - - /* set memory type and cache attribute from user side. */ - exynos_gem_obj->flags = flags; - - /* - * allocate all pages as desired size if user wants to allocate - * physically non-continuous memory. - */ - if (flags & EXYNOS_BO_NONCONTIG) { - ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); - if (ret < 0) { - drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; - } - } else { - ret = exynos_drm_alloc_buf(dev, buf, flags); - if (ret < 0) { - drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; - } - } - - return exynos_gem_obj; - -err_fini_buf: - exynos_drm_fini_buf(dev, buf); - return ERR_PTR(ret); -} - -int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_create *args = data; - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); - if (IS_ERR(exynos_gem_obj)) - return PTR_ERR(exynos_gem_obj); - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->handle); - if (ret) { - exynos_drm_gem_destroy(exynos_gem_obj); - return ret; - } - - return 0; -} - -void *exynos_drm_gem_get_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return ERR_PTR(-EINVAL); - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - DRM_DEBUG_KMS("not support NONCONTIG type.\n"); - drm_gem_object_unreference_unlocked(obj); - - /* TODO */ - return ERR_PTR(-EINVAL); - } - - return &exynos_gem_obj->buffer->dma_addr; -} - -void exynos_drm_gem_put_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - DRM_DEBUG_KMS("not support NONCONTIG type.\n"); - drm_gem_object_unreference_unlocked(obj); - - /* TODO */ - return; - } - - drm_gem_object_unreference_unlocked(obj); - - /* - * decrease obj->refcount one more time because we has already - * increased it at exynos_drm_gem_get_dma_addr(). - */ - drm_gem_object_unreference_unlocked(obj); -} - -int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_map_off *args = data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n", - args->handle, (unsigned long)args->offset); - - if (!(dev->driver->driver_features & DRIVER_GEM)) { - DRM_ERROR("does not support GEM.\n"); - return -ENODEV; - } - - return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle, - &args->offset); -} - -static int exynos_drm_gem_mmap_buffer(struct file *filp, - struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = filp->private_data; - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buffer; - unsigned long pfn, vm_size, usize, uaddr = vma->vm_start; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - vma->vm_flags |= (VM_IO | VM_RESERVED); - - update_vm_cache_attr(exynos_gem_obj, vma); - - vma->vm_file = filp; - - vm_size = usize = vma->vm_end - vma->vm_start; - - /* - * a buffer contains information to physically continuous memory - * allocated by user request or at framebuffer creation. - */ - buffer = exynos_gem_obj->buffer; - - /* check if user-requested size is valid. */ - if (vm_size > buffer->size) - return -EINVAL; - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - int i = 0; - - if (!buffer->pages) - return -EINVAL; - - vma->vm_flags |= VM_MIXEDMAP; - - do { - ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); - if (ret) { - DRM_ERROR("failed to remap user space.\n"); - return ret; - } - - uaddr += PAGE_SIZE; - usize -= PAGE_SIZE; - } while (usize > 0); - } else { - /* - * get page frame number to physical memory to be mapped - * to user space. - */ - pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> - PAGE_SHIFT; - - DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); - - if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size, - vma->vm_page_prot)) { - DRM_ERROR("failed to remap pfn range.\n"); - return -EAGAIN; - } - } - - return 0; -} - -static const struct file_operations exynos_drm_gem_fops = { - .mmap = exynos_drm_gem_mmap_buffer, -}; - -int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_mmap *args = data; - struct drm_gem_object *obj; - unsigned int addr; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!(dev->driver->driver_features & DRIVER_GEM)) { - DRM_ERROR("does not support GEM.\n"); - return -ENODEV; - } - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return -EINVAL; - } - - obj->filp->f_op = &exynos_drm_gem_fops; - obj->filp->private_data = obj; - - down_write(¤t->mm->mmap_sem); - addr = do_mmap(obj->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, 0); - up_write(¤t->mm->mmap_sem); - - drm_gem_object_unreference_unlocked(obj); - - if (IS_ERR((void *)addr)) - return PTR_ERR((void *)addr); - - args->mapped = addr; - - DRM_DEBUG_KMS("mapped = 0x%lx\n", (unsigned long)args->mapped); - - return 0; -} - -static int exynos_drm_get_userptr(struct drm_device *dev, - struct exynos_drm_gem_obj *obj, - unsigned long userptr, - unsigned int write) -{ - unsigned int get_npages; - unsigned long npages = 0; - struct vm_area_struct *vma; - struct exynos_drm_gem_buf *buf = obj->buffer; - - vma = find_vma(current->mm, userptr); - - /* the memory region mmaped with VM_PFNMAP. */ - if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) { - unsigned long this_pfn, prev_pfn, pa; - unsigned long start, end, offset; - struct scatterlist *sgl; - int ret; - - start = userptr; - offset = userptr & ~PAGE_MASK; - end = start + buf->size; - sgl = buf->sgt->sgl; - - for (prev_pfn = 0; start < end; start += PAGE_SIZE) { - ret = follow_pfn(vma, start, &this_pfn); - if (ret) - return ret; - - if (prev_pfn == 0) { - pa = this_pfn << PAGE_SHIFT; - buf->dma_addr = pa + offset; - } else if (this_pfn != prev_pfn + 1) { - ret = -EINVAL; - goto err; - } - - sg_dma_address(sgl) = (pa + offset); - sg_dma_len(sgl) = PAGE_SIZE; - prev_pfn = this_pfn; - pa += PAGE_SIZE; - npages++; - sgl = sg_next(sgl); - } - - obj->vma = get_vma(vma); - if (!obj->vma) { - ret = -ENOMEM; - goto err; - } - - buf->pfnmap = true; - - return npages; -err: - buf->dma_addr = 0; - return ret; - } - - buf->write = write; - npages = buf->size >> PAGE_SHIFT; - - down_read(¤t->mm->mmap_sem); - get_npages = get_user_pages(current, current->mm, userptr, - npages, write, 1, buf->pages, NULL); - up_read(¤t->mm->mmap_sem); - if (get_npages != npages) - DRM_ERROR("failed to get user_pages.\n"); - - buf->pfnmap = false; - - return get_npages; -} - -int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_exynos_gem_userptr *args = data; - struct exynos_drm_gem_buf *buf; - struct scatterlist *sgl; - unsigned long size, userptr; - unsigned int npages; - int ret, get_npages; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!args->size) { - DRM_ERROR("invalid size.\n"); - return -EINVAL; - } - - ret = check_gem_flags(args->flags); - if (ret) - return ret; - - size = roundup_gem_size(args->size, EXYNOS_BO_USERPTR); - userptr = args->userptr; - - buf = exynos_drm_init_buf(dev, size); - if (!buf) - return -ENOMEM; - - exynos_gem_obj = exynos_drm_gem_init(dev, size); - if (!exynos_gem_obj) { - ret = -ENOMEM; - goto err_free_buffer; - } - - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!buf->sgt) { - DRM_ERROR("failed to allocate buf->sgt.\n"); - ret = -ENOMEM; - goto err_release_gem; - } - - npages = size >> PAGE_SHIFT; - - ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); - if (ret < 0) { - DRM_ERROR("failed to initailize sg table.\n"); - goto err_free_sgt; - } - - buf->pages = kzalloc(npages * sizeof(struct page *), GFP_KERNEL); - if (!buf->pages) { - DRM_ERROR("failed to allocate buf->pages\n"); - ret = -ENOMEM; - goto err_free_table; - } - - exynos_gem_obj->buffer = buf; - - get_npages = exynos_drm_get_userptr(dev, exynos_gem_obj, userptr, 1); - if (get_npages != npages) { - DRM_ERROR("failed to get user_pages.\n"); - ret = get_npages; - goto err_release_userptr; - } - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->handle); - if (ret < 0) { - DRM_ERROR("failed to create gem handle.\n"); - goto err_release_userptr; - } - - sgl = buf->sgt->sgl; - - /* - * if buf->pfnmap is true then update sgl of sgt with pages but - * if buf->pfnmap is false then it means the sgl was updated already - * so it doesn't need to update the sgl. - */ - if (!buf->pfnmap) { - unsigned int i = 0; - - /* set all pages to sg list. */ - while (i < npages) { - sg_set_page(sgl, buf->pages[i], PAGE_SIZE, 0); - sg_dma_address(sgl) = page_to_phys(buf->pages[i]); - i++; - sgl = sg_next(sgl); - } - } - - /* always use EXYNOS_BO_USERPTR as memory type for userptr. */ - exynos_gem_obj->flags |= EXYNOS_BO_USERPTR; - - return 0; - -err_release_userptr: - get_npages--; - while (get_npages >= 0) - put_page(buf->pages[get_npages--]); - kfree(buf->pages); - buf->pages = NULL; -err_free_table: - sg_free_table(buf->sgt); -err_free_sgt: - kfree(buf->sgt); - buf->sgt = NULL; -err_release_gem: - drm_gem_object_release(&exynos_gem_obj->base); - kfree(exynos_gem_obj); - exynos_gem_obj = NULL; -err_free_buffer: - exynos_drm_free_buf(dev, 0, buf); - return ret; -} - -int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_exynos_gem_info *args = data; - struct drm_gem_object *obj; - - mutex_lock(&dev->struct_mutex); - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - args->flags = exynos_gem_obj->flags; - args->size = exynos_gem_obj->size; - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int exynos_drm_gem_export_ump_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - struct drm_exynos_gem_ump *ump = data; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - obj = drm_gem_object_lookup(dev, file, ump->gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - /* register gem buffer to private buffer. */ - ret = register_buf_to_priv_mgr(exynos_gem_obj, - (unsigned int *)&exynos_gem_obj->priv_handle, - (unsigned int *)&exynos_gem_obj->priv_id); - if (ret < 0) - goto err_unreference_gem; - - ump->secure_id = exynos_gem_obj->priv_id; - drm_gem_object_unreference(obj); - - mutex_unlock(&dev->struct_mutex); - - DRM_DEBUG_KMS("got secure id = %d\n", ump->secure_id); - - return 0; - -err_unreference_gem: - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - -} - -static int exynos_gem_l1_cache_ops(struct drm_device *drm_dev, - struct drm_exynos_gem_cache_op *op) { - if (op->flags & EXYNOS_DRM_CACHE_FSH_ALL) { - /* - * cortex-A9 core has individual l1 cache so flush l1 caches - * for all cores but other cores should be considered later. - * TODO - */ - if (op->flags & EXYNOS_DRM_ALL_CORES) - flush_all_cpu_caches(); - else - __cpuc_flush_user_all(); - - } else if (op->flags & EXYNOS_DRM_CACHE_FSH_RANGE) { - struct vm_area_struct *vma; - - down_read(¤t->mm->mmap_sem); - vma = find_vma(current->mm, op->usr_addr); - up_read(¤t->mm->mmap_sem); - - if (!vma) { - DRM_ERROR("failed to get vma.\n"); - return -EFAULT; - } - - __cpuc_flush_user_range(op->usr_addr, op->usr_addr + op->size, - vma->vm_flags); - } - - return 0; -} - -static int exynos_gem_l2_cache_ops(struct drm_device *drm_dev, - struct drm_exynos_gem_cache_op *op) { - phys_addr_t phy_start, phy_end; - - if (op->flags & EXYNOS_DRM_CACHE_FSH_RANGE || - op->flags & EXYNOS_DRM_CACHE_INV_RANGE || - op->flags & EXYNOS_DRM_CACHE_CLN_RANGE) { - struct vm_area_struct *vma; - - down_read(¤t->mm->mmap_sem); - vma = find_vma(current->mm, op->usr_addr); - up_read(¤t->mm->mmap_sem); - - if (!vma) { - DRM_ERROR("failed to get vma.\n"); - return -EFAULT; - } - - /* - * for range flush to l2 cache, mmaped memory region should - * be physically continuous because l2 cache uses PIPT. - */ - if (vma && (vma->vm_flags & VM_PFNMAP)) { - unsigned long virt_start = op->usr_addr, pfn; - int ret; - - ret = follow_pfn(vma, virt_start, &pfn); - if (ret < 0) { - DRM_ERROR("failed to get pfn from usr_addr.\n"); - return ret; - } - - phy_start = pfn << PAGE_SHIFT; - phy_end = phy_start + op->size; - } else { - DRM_ERROR("not mmaped memory region with PFNMAP.\n"); - return -EINVAL; - } - } - - if (op->flags & EXYNOS_DRM_CACHE_FSH_ALL) - outer_flush_all(); - else if (op->flags & EXYNOS_DRM_CACHE_FSH_RANGE) - outer_flush_range(phy_start, phy_end); - else if (op->flags & EXYNOS_DRM_CACHE_INV_ALL) - outer_inv_all(); - else if (op->flags & EXYNOS_DRM_CACHE_CLN_ALL) - outer_clean_all(); - else if (op->flags & EXYNOS_DRM_CACHE_INV_RANGE) - outer_inv_range(phy_start, phy_end); - else if (op->flags & EXYNOS_DRM_CACHE_CLN_RANGE) - outer_clean_range(phy_start, phy_end); - else { - DRM_ERROR("invalid l2 cache operation.\n"); - return -EINVAL; - } - - return 0; -} - -int exynos_drm_gem_cache_op_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_cache_op *op = data; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = check_cache_flags(op->flags); - if (ret) - return -EINVAL; - - if (op->flags & EXYNOS_DRM_L1_CACHE || - op->flags & EXYNOS_DRM_ALL_CACHES) { - ret = exynos_gem_l1_cache_ops(drm_dev, op); - if (ret < 0) - goto err; - } - - if (op->flags & EXYNOS_DRM_L2_CACHE || - op->flags & EXYNOS_DRM_ALL_CACHES) - ret = exynos_gem_l2_cache_ops(drm_dev, op); -err: - return ret; -} - -/* temporary functions. */ -int exynos_drm_gem_get_phy_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_get_phy *get_phy = data; - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&drm_dev->struct_mutex); - - obj = drm_gem_object_lookup(drm_dev, file_priv, get_phy->gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - mutex_unlock(&drm_dev->struct_mutex); - return -EINVAL; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - /* - * we can get physical address only for EXYNOS_DRM_GEM_PC memory type. - */ - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - DRM_DEBUG_KMS("not physically continuous memory type.\n"); - drm_gem_object_unreference(obj); - mutex_unlock(&drm_dev->struct_mutex); - return -EINVAL; - } - - get_phy->phy_addr = exynos_gem_obj->buffer->dma_addr; - get_phy->size = exynos_gem_obj->buffer->size; - - drm_gem_object_unreference(obj); - mutex_unlock(&drm_dev->struct_mutex); - - return 0; -} - -int exynos_drm_gem_phy_imp_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_phy_imp *args = data; - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buffer; - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_gem_obj = exynos_drm_gem_init(drm_dev, args->size); - if (!exynos_gem_obj) - return -ENOMEM; - - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); - if (!buffer) { - DRM_DEBUG_KMS("failed to allocate buffer\n"); - ret = -ENOMEM; - goto err; - } - - buffer->dma_addr = (dma_addr_t)args->phy_addr; - buffer->size = args->size; - - /* - * if shared is true, this bufer wouldn't be released. - * this buffer was allocated by other so don't release it. - */ - buffer->shared = true; - - exynos_gem_obj->buffer = buffer; - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->gem_handle); - if (ret) - goto err_kfree_buffer; - - DRM_DEBUG_KMS("got gem handle = 0x%x\n", args->gem_handle); - - return 0; - -err_kfree_buffer: - kfree(buffer); -err: - drm_gem_object_release(&exynos_gem_obj->base); - kfree(exynos_gem_obj); - return ret; -} - -int exynos_drm_gem_init_object(struct drm_gem_object *obj) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - return 0; -} - -void exynos_drm_gem_free_object(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buf; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_gem_obj = to_exynos_gem_obj(obj); - buf = exynos_gem_obj->buffer; - - if (obj->import_attach) - drm_prime_gem_destroy(obj, buf->sgt); - - exynos_drm_gem_destroy(to_exynos_gem_obj(obj)); -} - -int exynos_drm_gem_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * alocate memory to be used for framebuffer. - * - this callback would be called by user application - * with DRM_IOCTL_MODE_CREATE_DUMB command. - */ - - args->pitch = args->width * args->bpp >> 3; - args->size = PAGE_ALIGN(args->pitch * args->height); - - exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); - if (IS_ERR(exynos_gem_obj)) - return PTR_ERR(exynos_gem_obj); - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->handle); - if (ret) { - exynos_drm_gem_destroy(exynos_gem_obj); - return ret; - } - - return 0; -} - -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - /* - * get offset of memory allocated for drm framebuffer. - * - this callback would be called by user application - * with DRM_IOCTL_MODE_MAP_DUMB command. - */ - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - ret = -EINVAL; - goto unlock; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (!exynos_gem_obj->base.map_list.map) { - ret = drm_gem_create_mmap_offset(&exynos_gem_obj->base); - if (ret) - goto out; - } - - *offset = (u64)exynos_gem_obj->base.map_list.hash.key << PAGE_SHIFT; - DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); - -out: - drm_gem_object_unreference(obj); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - unsigned int handle) -{ - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * obj->refcount and obj->handle_count are decreased and - * if both them are 0 then exynos_drm_gem_free_object() - * would be called by callback to release resources. - */ - ret = drm_gem_handle_delete(file_priv, handle); - if (ret < 0) { - DRM_ERROR("failed to delete drm_gem_handle.\n"); - return ret; - } - - return 0; -} - -void exynos_drm_gem_close_object(struct drm_gem_object *obj, - struct drm_file *file) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct iommu_gem_map_params params; - unsigned int type = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* check this gem object was mapped to iommu at here. TODO */ - - exynos_gem_obj = to_exynos_gem_obj(obj); - - while (type < MAX_IOMMU_NR) { - /* - * unmap device address space already mapped to iommu. - * - this codes would be performed with user gem release - * request but in case of no request, when device driver - * using iommu is released, also same things should be - * performed by each driver. - */ - if (exynos_gem_obj->iommu_info.mapped & (1 << type)) { - dma_addr_t dma_addr; - struct list_head *list; - - params.dev = exynos_gem_obj->iommu_info.devs[type]; - params.drm_dev = obj->dev; - params.file = file; - params.gem_obj = exynos_gem_obj; - dma_addr = exynos_gem_obj->iommu_info.dma_addrs[type]; - - exynos_drm_iommu_unmap_gem(¶ms, - dma_addr, - type); - - exynos_gem_obj->iommu_info.mapped &= ~(1 << type); - exynos_gem_obj->iommu_info.dma_addrs[type] = 0; - - list = exynos_gem_obj->iommu_info.iommu_lists[type]; - - /* - * this gem has been unmapped from iommu so also - * remove a iommu node from current device's own - * iommu list. - */ - exynos_drm_remove_iommu_list(list, exynos_gem_obj); - } - - type++; - } -} - -int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; - unsigned long f_vaddr; - pgoff_t page_offset; - int ret; - - page_offset = ((unsigned long)vmf->virtual_address - - vma->vm_start) >> PAGE_SHIFT; - f_vaddr = (unsigned long)vmf->virtual_address; - - mutex_lock(&dev->struct_mutex); - - ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); - if (ret < 0) - DRM_ERROR("failed to map pages.\n"); - - mutex_unlock(&dev->struct_mutex); - - return convert_to_vm_err_msg(ret); -} - -int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* set vm_area_struct. */ - ret = drm_gem_mmap(filp, vma); - if (ret < 0) { - DRM_ERROR("failed to mmap.\n"); - return ret; - } - - obj = vma->vm_private_data; - exynos_gem_obj = to_exynos_gem_obj(obj); - - ret = check_gem_flags(exynos_gem_obj->flags); - if (ret) { - drm_gem_vm_close(vma); - drm_gem_free_mmap_offset(obj); - return ret; - } - - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_flags |= VM_MIXEDMAP; - - update_vm_cache_attr(exynos_gem_obj, vma); - - return ret; -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.h deleted file mode 100644 index 1227ae3..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_gem.h +++ /dev/null @@ -1,246 +0,0 @@ -/* exynos_drm_gem.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authoer: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_GEM_H_ -#define _EXYNOS_DRM_GEM_H_ - -#define to_exynos_gem_obj(x) container_of(x,\ - struct exynos_drm_gem_obj, base) - -/* FIMD/HDMI/G2D/FIMC/G3D */ -#define MAX_IOMMU_NR 5 - -#define IS_NONCONTIG_BUFFER(f) ((f & EXYNOS_BO_NONCONTIG) ||\ - (f & EXYNOS_BO_USERPTR)) - -struct exynos_drm_private_cb { - unsigned int (*get_handle)(unsigned int id); - int (*add_buffer)(void *obj, unsigned int *handle, unsigned int *id); - void (*release_buffer)(unsigned int handle); -}; - -/* - * exynos drm iommu information structure. - * - * @mapped: flag a bit of indicating whether any driver's device address - * is mapped to its own iommu or not. - * @dma_addrs: contain device address to each device driver using iommu. - * @devs: device objects that requested mapping to iommu. - */ -struct exynos_drm_iommu_info { - unsigned int mapped; - dma_addr_t dma_addrs[MAX_IOMMU_NR]; - struct device *devs[MAX_IOMMU_NR]; - struct list_head *iommu_lists[MAX_IOMMU_NR]; - /* TODO. */ -}; - -/* - * exynos drm gem buffer structure. - * - * @kvaddr: kernel virtual address to allocated memory region. - * @dma_addr: bus address(accessed by dma) to allocated memory region. - * - this address could be physical address without IOMMU and - * device address with IOMMU. - * @write: whether pages will be written to by the caller. - * @sgt: sg table to transfer page data. - * @pages: contain all pages to allocated memory region. - * @page_size: could be 4K, 64K or 1MB. - * @size: size of allocated memory region. - * @shared: indicate shared mfc memory region. - * (temporarily used and it should be removed later.) - * @shared_refcount: a reference count for this buffer being shared with others. - * @pfnmap: indicate whether memory region from userptr is mmaped with - * VM_PFNMAP or not. - */ -struct exynos_drm_gem_buf { - struct device *dev; - void __iomem *kvaddr; - dma_addr_t dma_addr; - unsigned int write; - struct sg_table *sgt; - struct page **pages; - unsigned long page_size; - unsigned long size; - bool shared; - atomic_t shared_refcount; - bool pfnmap; -}; - -/* - * exynos drm buffer structure. - * - * @base: a gem object. - * - a new handle to this gem object would be created - * by drm_gem_handle_create(). - * @buffer: a pointer to exynos_drm_gem_buffer object. - * - contain the information to memory region allocated - * by user request or at framebuffer creation. - * continuous memory region allocated by user request - * or at framebuffer creation. - * @iommu_info: contain iommu mapping information to each device driver - * using its own iommu. - * @size: total memory size to physically non-continuous memory region. - * @flags: indicate memory type to allocated buffer and cache attruibute. - * @priv_handle: handle to specific buffer object. - * @priv_id: unique id to specific buffer object. - * - * P.S. this object would be transfered to user as kms_bo.handle so - * user can access the buffer through kms_bo.handle. - */ -struct exynos_drm_gem_obj { - struct drm_gem_object base; - struct exynos_drm_gem_buf *buffer; - struct exynos_drm_iommu_info iommu_info; - unsigned long size; - struct vm_area_struct *vma; - unsigned int flags; - void *dma_buf_vmapping; - int vmapping_count; - unsigned int priv_handle; - unsigned int priv_id; -}; - -/* register private callback. */ -void exynos_drm_priv_cb_register(struct exynos_drm_private_cb *cb); - -/* register a buffer object to private buffer manager. */ -int register_buf_to_priv_mgr(struct exynos_drm_gem_obj *obj, - unsigned int *priv_handle, unsigned int *priv_id); - -struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); - -/* destroy a buffer with gem object */ -void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj); - -/* create a private gem object and initialize it. */ -struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, - unsigned long size); - -/* create a new buffer with gem object */ -struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, - unsigned int flags, - unsigned long size); - -/* - * request gem object creation and buffer allocation as the size - * that it is calculated with framebuffer information such as width, - * height and bpp. - */ -int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* - * get dma address from gem handle and this function could be used for - * other drivers such as 2d/3d acceleration drivers. - * with this function call, gem object reference count would be increased. - */ -void *exynos_drm_gem_get_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - -/* - * put dma address from gem handle and this function could be used for - * other drivers such as 2d/3d acceleration drivers. - * with this function call, gem object reference count would be decreased. - */ -void exynos_drm_gem_put_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - -/* get buffer offset to map to user space. */ -int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* - * mmap the physically continuous memory that a gem object contains - * to user space. - */ -int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* map user space allocated by malloc to pages. */ -int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* get buffer information to memory region allocated by gem. */ -int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* initialize gem object. */ -int exynos_drm_gem_init_object(struct drm_gem_object *obj); - -/* free gem object. */ -void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj); - -/* create memory region for drm framebuffer. */ -int exynos_drm_gem_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); - -/* map memory region for drm framebuffer to user space. */ -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset); - -/* - * destroy memory region allocated. - * - a gem handle and physical memory region pointed by a gem object - * would be released by drm_gem_handle_delete(). - */ -int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - unsigned int handle); - -/* page fault handler and mmap fault address(virtual) to physical memory. */ -int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); - -/* set vm_flags and we can change the vm attribute to other one at here. */ -int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); - -/* get ump sequre id for UMP. */ -int exynos_drm_gem_export_ump_ioctl(struct drm_device *dev, void *data, - struct drm_file *file); - -/* do user desired cache operation. */ -int exynos_drm_gem_cache_op_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); - -/* temporary functions. */ -/* get physical address from a gem. */ -int exynos_drm_gem_get_phy_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); -/* import physical memory to a gem. */ -int exynos_drm_gem_phy_imp_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); - -void exynos_drm_gem_close_object(struct drm_gem_object *obj, - struct drm_file *file); - -struct exynos_drm_gem_obj *exynos_drm_gem_get_obj(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.c deleted file mode 100644 index 5d9d2c2..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.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. - * - */ - -#include "drmP.h" - -#include <linux/kernel.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> - -#include <drm/exynos_drm.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#define to_context(dev) platform_get_drvdata(to_platform_device(dev)) -#define to_subdrv(dev) to_context(dev) -#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\ - struct drm_hdmi_context, subdrv); - -/* these callback points shoud be set by specific drivers. */ -static struct exynos_hdmi_ops *hdmi_ops; -static struct exynos_mixer_ops *mixer_ops; - -struct drm_hdmi_context { - struct exynos_drm_subdrv subdrv; - struct exynos_drm_hdmi_context *hdmi_ctx; - struct exynos_drm_hdmi_context *mixer_ctx; - - bool enabled[MIXER_WIN_NR]; -}; - -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ops) - hdmi_ops = ops; -} - -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ops) - mixer_ops = ops; -} - -static bool drm_hdmi_is_connected(struct device *dev) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->is_connected) - return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); - - return false; -} - -static int drm_hdmi_get_edid(struct device *dev, - struct drm_connector *connector, u8 *edid, int len) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->get_edid) - return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, - len); - - return 0; -} - -static int drm_hdmi_check_timing(struct device *dev, void *timing) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->check_timing) - return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); - - return 0; -} - -static int drm_hdmi_power_on(struct device *dev, int mode) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->power_on) - return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); - - return 0; -} - -static struct exynos_drm_display_ops drm_hdmi_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_HDMI, - .is_connected = drm_hdmi_is_connected, - .get_edid = drm_hdmi_get_edid, - .check_timing = drm_hdmi_check_timing, - .power_on = drm_hdmi_power_on, -}; - -static int drm_hdmi_enable_vblank(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->enable_vblank) - return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, - manager->pipe); - - return 0; -} - -static void drm_hdmi_disable_vblank(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->disable_vblank) - return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); -} - -static void drm_hdmi_mode_fixup(struct device *subdrv_dev, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->mode_fixup) - hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, - adjusted_mode); -} - -static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->mode_set) - hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); -} - -static void drm_hdmi_get_max_resol(struct device *subdrv_dev, - unsigned int *width, unsigned int *height) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->get_max_resol) - hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); -} - -static void drm_hdmi_commit(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->commit) - hdmi_ops->commit(ctx->hdmi_ctx->ctx); -} - -static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->dpms) - mixer_ops->dpms(ctx->mixer_ctx->ctx, mode); - - if (hdmi_ops && hdmi_ops->dpms) - hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode); -} - -static void drm_hdmi_apply(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - for (i = 0; i < MIXER_WIN_NR; i++) { - if (!ctx->enabled[i]) - continue; - if (mixer_ops && mixer_ops->win_commit) - mixer_ops->win_commit(ctx->mixer_ctx->ctx, i); - } - - if (hdmi_ops && hdmi_ops->commit) - hdmi_ops->commit(ctx->hdmi_ctx->ctx); -} - -static struct exynos_drm_manager_ops drm_hdmi_manager_ops = { - .dpms = drm_hdmi_dpms, - .apply = drm_hdmi_apply, - .enable_vblank = drm_hdmi_enable_vblank, - .disable_vblank = drm_hdmi_disable_vblank, - .mode_fixup = drm_hdmi_mode_fixup, - .mode_set = drm_hdmi_mode_set, - .get_max_resol = drm_hdmi_get_max_resol, - .commit = drm_hdmi_commit, -}; - -static void drm_mixer_mode_set(struct device *subdrv_dev, - struct exynos_drm_overlay *overlay) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->win_mode_set) - mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); -} - -static void drm_mixer_commit(struct device *subdrv_dev, int zpos) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("mixer window[%d] is wrong\n", win); - return; - } - - if (mixer_ops && mixer_ops->win_commit) - mixer_ops->win_commit(ctx->mixer_ctx->ctx, win); - - ctx->enabled[win] = true; -} - -static void drm_mixer_disable(struct device *subdrv_dev, int zpos) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("mixer window[%d] is wrong\n", win); - return; - } - - if (mixer_ops && mixer_ops->win_disable) - mixer_ops->win_disable(ctx->mixer_ctx->ctx, win); - - ctx->enabled[win] = false; -} - -static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { - .mode_set = drm_mixer_mode_set, - .commit = drm_mixer_commit, - .disable = drm_mixer_disable, -}; - -static struct exynos_drm_manager hdmi_manager = { - .pipe = -1, - .ops = &drm_hdmi_manager_ops, - .overlay_ops = &drm_hdmi_overlay_ops, - .display_ops = &drm_hdmi_display_ops, -}; - -static int hdmi_subdrv_probe(struct drm_device *drm_dev, - struct device *dev) -{ - struct exynos_drm_subdrv *subdrv = to_subdrv(dev); - struct drm_hdmi_context *ctx; - struct platform_device *pdev = to_platform_device(dev); - struct exynos_drm_common_hdmi_pd *pd; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - pd = pdev->dev.platform_data; - - if (!pd) { - DRM_DEBUG_KMS("platform data is null.\n"); - return -EFAULT; - } - - if (!pd->hdmi_dev) { - DRM_DEBUG_KMS("hdmi device is null.\n"); - return -EFAULT; - } - - if (!pd->mixer_dev) { - DRM_DEBUG_KMS("mixer device is null.\n"); - return -EFAULT; - } - - ctx = get_ctx_from_subdrv(subdrv); - - ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *) - to_context(pd->hdmi_dev); - if (!ctx->hdmi_ctx) { - DRM_DEBUG_KMS("hdmi context is null.\n"); - return -EFAULT; - } - - ctx->hdmi_ctx->drm_dev = drm_dev; - - ctx->mixer_ctx = (struct exynos_drm_hdmi_context *) - to_context(pd->mixer_dev); - if (!ctx->mixer_ctx) { - DRM_DEBUG_KMS("mixer context is null.\n"); - return -EFAULT; - } - - ctx->mixer_ctx->drm_dev = drm_dev; - - return 0; -} - -static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_subdrv *subdrv; - struct drm_hdmi_context *ctx; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - DRM_LOG_KMS("failed to alloc common hdmi context.\n"); - return -ENOMEM; - } - - subdrv = &ctx->subdrv; - - subdrv->dev = dev; - subdrv->manager = &hdmi_manager; - subdrv->probe = hdmi_subdrv_probe; - - platform_set_drvdata(pdev, subdrv); - - exynos_drm_subdrv_register(subdrv); - - return 0; -} - -static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) -{ - struct drm_hdmi_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); - kfree(ctx); - - return 0; -} - -struct platform_driver exynos_drm_common_hdmi_driver = { - .probe = exynos_drm_hdmi_probe, - .remove = __devexit_p(exynos_drm_hdmi_remove), - .driver = { - .name = "exynos-drm-hdmi", - .owner = THIS_MODULE, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.h deleted file mode 100644 index bd81269..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_hdmi.h +++ /dev/null @@ -1,77 +0,0 @@ -/* exynos_drm_hdmi.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authoer: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_HDMI_H_ -#define _EXYNOS_DRM_HDMI_H_ - -#define MIXER_WIN_NR 3 -#define MIXER_DEFAULT_WIN 0 - -/* - * exynos hdmi common context structure. - * - * @drm_dev: pointer to drm_device. - * @ctx: pointer to the context of specific device driver. - * this context should be hdmi_context or mixer_context. - */ -struct exynos_drm_hdmi_context { - struct drm_device *drm_dev; - void *ctx; -}; - -struct exynos_hdmi_ops { - /* display */ - bool (*is_connected)(void *ctx); - int (*get_edid)(void *ctx, struct drm_connector *connector, - u8 *edid, int len); - int (*check_timing)(void *ctx, void *timing); - int (*power_on)(void *ctx, int mode); - - /* manager */ - void (*mode_fixup)(void *ctx, struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - void (*mode_set)(void *ctx, void *mode); - void (*get_max_resol)(void *ctx, unsigned int *width, - unsigned int *height); - void (*commit)(void *ctx); - void (*dpms)(void *ctx, int mode); -}; - -struct exynos_mixer_ops { - /* manager */ - int (*enable_vblank)(void *ctx, int pipe); - void (*disable_vblank)(void *ctx); - void (*dpms)(void *ctx, int mode); - - /* overlay */ - void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); - void (*win_commit)(void *ctx, int zpos); - void (*win_disable)(void *ctx, int zpos); -}; - -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.c deleted file mode 100644 index f2ffa68..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.c +++ /dev/null @@ -1,329 +0,0 @@ -/* exynos_drm_iommu.c - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" - -#include <drm/exynos_drm.h> - -#include <plat/s5p-iovmm.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_iommu.h" - -static DEFINE_MUTEX(iommu_mutex); - -struct exynos_iommu_ops { - int (*setup)(struct device *dev); - void (*cleanup)(struct device *dev); - int (*activate)(struct device *dev); - void (*deactivate)(struct device *dev); - dma_addr_t (*map)(struct device *dev, struct scatterlist *sg, - off_t offset, size_t size); - void (*unmap)(struct device *dev, dma_addr_t iova); -}; - -static const struct exynos_iommu_ops iommu_ops = { - .setup = iovmm_setup, - .cleanup = iovmm_cleanup, - .activate = iovmm_activate, - .deactivate = iovmm_deactivate, - .map = iovmm_map, - .unmap = iovmm_unmap -}; - -static bool check_iommu_map_params(struct iommu_gem_map_params *params) -{ - if (!params) { - DRM_ERROR("params is null.\n"); - return false; - } - - if (!params->dev || !params->drm_dev || !params->file) { - DRM_ERROR("invalid params.\n"); - return false; - } - - return true; -} - -void exynos_drm_remove_iommu_list(struct list_head *iommu_list, - void *gem_obj) -{ - struct iommu_info_node *im, *t_im; - - list_for_each_entry_safe(im, t_im, iommu_list, list) { - if (im->gem_obj == gem_obj) { - list_del(&im->list); - kfree(im); - im = NULL; - break; - } - } - -} - -dma_addr_t exynos_drm_iommu_map_gem(struct iommu_gem_map_params *params, - struct list_head *iommu_list, - unsigned int gem_handle, - enum iommu_types type) -{ - struct sg_table *sgt; - struct iommu_info_node *node; - struct exynos_drm_gem_obj *obj; - dma_addr_t dma_addr; - - if (!is_iommu_type_valid(type)) { - DRM_ERROR("invalid iommu type.\n"); - return 0; - } - - if (!check_iommu_map_params(params)) - return 0; - - /* get gem object from specific gem framework. */ - obj = exynos_drm_gem_get_obj(params->drm_dev, gem_handle, - params->file); - if (IS_ERR(obj)) - return 0; - - mutex_lock(&iommu_mutex); - - /* - * if this gem object had already been mapped to iommu then - * return dma address mapped before this time. - */ - if (obj->iommu_info.mapped & (1 << type)) { - DRM_DEBUG_KMS("already mapped to iommu"); - mutex_unlock(&iommu_mutex); - return obj->iommu_info.dma_addrs[type]; - } - - sgt = obj->buffer->sgt; - - /* - * if not using iommu, just return base address to physical - * memory region of the gem. - */ - if (!iommu_ops.map) { - mutex_unlock(&iommu_mutex); - return sg_dma_address(&sgt->sgl[0]); - } - mutex_unlock(&iommu_mutex); - - /* - * allocate device address space for this driver and then - * map all pages contained in sg list to iommu table. - */ - dma_addr = iommu_ops.map(params->dev, sgt->sgl, (off_t)0, - (size_t)obj->size); - if (!dma_addr) { - mutex_unlock(&iommu_mutex); - return dma_addr; - } - - mutex_lock(&iommu_mutex); - - /* - * check map flag bit and device address mapped to iommu. - * this data would be used to avoid duplicated mapping. - */ - obj->iommu_info.mapped |= (1 << type); - obj->iommu_info.dma_addrs[type] = dma_addr; - obj->iommu_info.devs[type] = params->dev; - obj->iommu_info.iommu_lists[type] = iommu_list; - - params->gem_obj = obj; - - /* - * this gem object is referenced by this driver so - * the object refcount should be increased. - */ - drm_gem_object_reference(&obj->base); - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) { - DRM_ERROR("failed to allocate iommu node.\n"); - dma_addr = 0; - goto err; - } - - node->gem_obj = obj; - node->dma_addr = dma_addr; - mutex_unlock(&iommu_mutex); - - list_add_tail(&node->list, iommu_list); - - return dma_addr; -err: - mutex_unlock(&iommu_mutex); - iommu_ops.unmap(params->dev, dma_addr); - return dma_addr; -} - -void exynos_drm_iommu_unmap_gem(struct iommu_gem_map_params *params, - dma_addr_t dma_addr, - enum iommu_types type) -{ - struct exynos_drm_gem_obj *obj; - - if (!iommu_ops.unmap) - return; - - if (!is_iommu_type_valid(type)) { - DRM_ERROR("invalid iommu type.\n"); - return; - } - - if (!check_iommu_map_params(params)) - return; - - if (!params->gem_obj) - return; - - obj = (struct exynos_drm_gem_obj *)params->gem_obj; - - mutex_lock(&iommu_mutex); - if (!(obj->iommu_info.mapped & (1 << type))) { - DRM_DEBUG_KMS("not already mapped to iommu so just return\n"); - mutex_unlock(&iommu_mutex); - return; - } - - /* uncheck map flag bit. */ - obj->iommu_info.mapped &= ~(1 << type); - obj->iommu_info.dma_addrs[type] = 0; - mutex_unlock(&iommu_mutex); - - iommu_ops.unmap(params->dev, dma_addr); - - /* - * drop this gem object refcount to release allocated buffer - * and resources. - */ - drm_gem_object_unreference_unlocked(&obj->base); -} - -dma_addr_t exynos_drm_iommu_map(struct device *dev, dma_addr_t paddr, - size_t size) -{ - struct sg_table *sgt; - struct scatterlist *sgl; - dma_addr_t dma_addr = 0, tmp_addr; - unsigned int npages, i = 0; - int ret; - - /* if not using iommu, just return paddr. */ - if (!iommu_ops.map) - return paddr; - - npages = size >> PAGE_SHIFT; - - sgt = kzalloc(sizeof(struct sg_table) * npages, GFP_KERNEL); - if (!sgt) { - dev_err(dev, "failed to allocate sg table.\n"); - return dma_addr; - } - - ret = sg_alloc_table(sgt, npages, GFP_KERNEL); - if (ret < 0) { - dev_err(dev, "failed to initialize sg table.\n"); - goto err; - } - - sgl = sgt->sgl; - tmp_addr = paddr; - - while (i < npages) { - struct page *page = phys_to_page(tmp_addr); - sg_set_page(sgl, page, PAGE_SIZE, 0); - sg_dma_len(sgl) = PAGE_SIZE; - tmp_addr += PAGE_SIZE; - i++; - sgl = sg_next(sgl); - } - - /* - * allocate device address space for this driver and then - * map all pages contained in sg list to iommu table. - */ - dma_addr = iommu_ops.map(dev, sgt->sgl, (off_t)0, (size_t)size); - if (!dma_addr) - dev_err(dev, "failed to map cmdlist pool.\n"); - - sg_free_table(sgt); -err: - kfree(sgt); - sgt = NULL; - - return dma_addr; -} - - -void exynos_drm_iommu_unmap(struct device *dev, dma_addr_t dma_addr) -{ - if (iommu_ops.unmap) - iommu_ops.unmap(dev, dma_addr); -} - -int exynos_drm_iommu_setup(struct device *dev) -{ - /* - * allocate device address space to this driver and add vmm object - * to s5p_iovmm_list. please know that each iommu will use - * 1GB as its own device address apace. - * - * the device address space : 0x80000000 ~ 0xA0000000 - */ - if (iommu_ops.setup) - return iommu_ops.setup(dev); - - return 0; -} - -int exynos_drm_iommu_activate(struct device *dev) -{ - if (iommu_ops.activate) - return iovmm_activate(dev); - - return 0; -} - -void exynos_drm_iommu_deactivate(struct device *dev) -{ - if (iommu_ops.deactivate) - iommu_ops.deactivate(dev); -} - -void exynos_drm_iommu_cleanup(struct device *dev) -{ - if (iommu_ops.cleanup) - iommu_ops.cleanup(dev); -} - -MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DRM IOMMU Framework"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.h deleted file mode 100644 index aa267ba..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_iommu.h +++ /dev/null @@ -1,79 +0,0 @@ -/* exynos_drm_iommu.h - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Authoer: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_IOMMU_H_ -#define _EXYNOS_DRM_IOMMU_H_ - -enum iommu_types { - IOMMU_FIMD = 0, - IOMMU_HDMI, - IOMMU_G2D, - IOMMU_FIMC, - IOMMU_G3D, - IOMMU_ROTATOR, - IOMMU_MASK = 0x3f -}; - -struct iommu_gem_map_params { - struct device *dev; - struct drm_device *drm_dev; - struct drm_file *file; - void *gem_obj; -}; - -#define is_iommu_type_valid(t) (((1 << (t)) & ~(IOMMU_MASK)) ? false : true) - -void exynos_drm_remove_iommu_list(struct list_head *iommu_list, - void *gem_obj); - -/* get all pages to gem object and map them to iommu table. */ -dma_addr_t exynos_drm_iommu_map_gem(struct iommu_gem_map_params *params, - struct list_head *iommu_list, - unsigned int gem_handle, - enum iommu_types type); - -/* unmap device address space to gem object from iommu table. */ -void exynos_drm_iommu_unmap_gem(struct iommu_gem_map_params *params, - dma_addr_t dma_addr, - enum iommu_types type); - -/* map physical memory region pointed by paddr to iommu table. */ -dma_addr_t exynos_drm_iommu_map(struct device *dev, dma_addr_t paddr, - size_t size); - -/* unmap device address space pointed by dma_addr from iommu table. */ -void exynos_drm_iommu_unmap(struct device *dev, dma_addr_t dma_addr); - -/* setup device address space for device iommu. */ -int exynos_drm_iommu_setup(struct device *dev); - -int exynos_drm_iommu_activate(struct device *dev); - -void exynos_drm_iommu_deactivate(struct device *dev); - -/* clean up allocated device address space for device iommu. */ -void exynos_drm_iommu_cleanup(struct device *dev); - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.c deleted file mode 100644 index c4c6525..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim <jy0922.shim@samsung.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. - * - */ - -#include "drmP.h" - -#include "exynos_drm.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" - -struct exynos_plane { - struct drm_plane base; - struct exynos_drm_overlay overlay; - bool enabled; -}; - -static const uint32_t formats[] = { - DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV12M, - DRM_FORMAT_NV12MT, -}; - -static int -exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - struct exynos_drm_overlay *overlay = &exynos_plane->overlay; - struct exynos_drm_crtc_pos pos; - int ret; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos)); - pos.crtc_x = crtc_x; - pos.crtc_y = crtc_y; - pos.crtc_w = crtc_w; - pos.crtc_h = crtc_h; - - /* considering 16.16 fixed point of source values */ - pos.fb_x = src_x >> 16; - pos.fb_y = src_y >> 16; - pos.src_w = src_w >> 16; - pos.src_h = src_h >> 16; - - ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos); - if (ret < 0) - return ret; - - exynos_drm_fn_encoder(crtc, overlay, - exynos_drm_encoder_crtc_mode_set); - exynos_drm_fn_encoder(crtc, &overlay->zpos, - exynos_drm_encoder_crtc_plane_commit); - - exynos_plane->enabled = true; - - return 0; -} - -static int exynos_disable_plane(struct drm_plane *plane) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - struct exynos_drm_overlay *overlay = &exynos_plane->overlay; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!exynos_plane->enabled) - return 0; - - exynos_drm_fn_encoder(plane->crtc, &overlay->zpos, - exynos_drm_encoder_crtc_disable); - - exynos_plane->enabled = false; - exynos_plane->overlay.zpos = DEFAULT_ZPOS; - - return 0; -} - -static void exynos_plane_destroy(struct drm_plane *plane) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - exynos_disable_plane(plane); - drm_plane_cleanup(plane); - kfree(exynos_plane); -} - -static struct drm_plane_funcs exynos_plane_funcs = { - .update_plane = exynos_update_plane, - .disable_plane = exynos_disable_plane, - .destroy = exynos_plane_destroy, -}; - -int exynos_plane_init(struct drm_device *dev, unsigned int nr) -{ - struct exynos_plane *exynos_plane; - uint32_t possible_crtcs; - - exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); - if (!exynos_plane) - return -ENOMEM; - - /* all CRTCs are available */ - possible_crtcs = (1 << MAX_CRTC) - 1; - - exynos_plane->overlay.zpos = DEFAULT_ZPOS; - - return drm_plane_init(dev, &exynos_plane->base, possible_crtcs, - &exynos_plane_funcs, formats, ARRAY_SIZE(formats), - false); -} - -int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_plane_set_zpos *zpos_req = data; - struct drm_mode_object *obj; - struct drm_plane *plane; - struct exynos_plane *exynos_plane; - int ret = 0; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if (zpos_req->zpos < 0 || zpos_req->zpos >= MAX_PLANE) { - if (zpos_req->zpos != DEFAULT_ZPOS) { - DRM_ERROR("zpos not within limits\n"); - return -EINVAL; - } - } - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, zpos_req->plane_id, - DRM_MODE_OBJECT_PLANE); - if (!obj) { - DRM_DEBUG_KMS("Unknown plane ID %d\n", - zpos_req->plane_id); - ret = -EINVAL; - goto out; - } - - plane = obj_to_plane(obj); - exynos_plane = container_of(plane, struct exynos_plane, base); - - exynos_plane->overlay.zpos = zpos_req->zpos; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.h deleted file mode 100644 index 16b71f8..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_plane.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim <jy0922.shim@samsung.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. - * - */ - -int exynos_plane_init(struct drm_device *dev, unsigned int nr); -int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.c deleted file mode 100644 index 5bf1d6e..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.c +++ /dev/null @@ -1,904 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: YoungJun Cho <yj44.cho@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/err.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/pm_runtime.h> -#include <linux/pm_qos_params.h> - -#include "drmP.h" -#include "exynos_drm.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_iommu.h" - -/* Configuration */ -#define ROT_CONFIG 0x00 -#define ROT_CONFIG_IRQ (3 << 8) - -/* Image Control */ -#define ROT_CONTROL 0x10 -#define ROT_CONTROL_PATTERN_WRITE (1 << 16) -#define ROT_CONTROL_FMT_YCBCR420_2P (1 << 8) -#define ROT_CONTROL_FMT_RGB888 (6 << 8) -#define ROT_CONTROL_FMT_MASK (7 << 8) -#define ROT_CONTROL_FLIP_VERTICAL (2 << 6) -#define ROT_CONTROL_FLIP_HORIZONTAL (3 << 6) -#define ROT_CONTROL_FLIP_MASK (3 << 6) -#define ROT_CONTROL_ROT_90 (1 << 4) -#define ROT_CONTROL_ROT_180 (2 << 4) -#define ROT_CONTROL_ROT_270 (3 << 4) -#define ROT_CONTROL_ROT_MASK (3 << 4) -#define ROT_CONTROL_START (1 << 0) - -/* Status */ -#define ROT_STATUS 0x20 -#define ROT_STATUS_IRQ_PENDING(x) (1 << (x)) -#define ROT_STATUS_IRQ(x) (((x) >> 8) & 0x3) -#define ROT_STATUS_IRQ_VAL_COMPLETE 1 -#define ROT_STATUS_IRQ_VAL_ILLEGAL 2 - -/* Sourc Buffer Address */ -#define ROT_SRC_BUF_ADDR(n) (0x30 + ((n) << 2)) - -/* Source Buffer Size */ -#define ROT_SRC_BUF_SIZE 0x3c -#define ROT_SRC_BUF_SIZE_H(x) ((x) << 16) -#define ROT_SRC_BUF_SIZE_W(x) ((x) << 0) - -/* Source Crop Position */ -#define ROT_SRC_CROP_POS 0x40 -#define ROT_SRC_CROP_POS_Y(x) ((x) << 16) -#define ROT_SRC_CROP_POS_X(x) ((x) << 0) - -/* Source Crop Size */ -#define ROT_SRC_CROP_SIZE 0x44 -#define ROT_SRC_CROP_SIZE_H(x) ((x) << 16) -#define ROT_SRC_CROP_SIZE_W(x) ((x) << 0) - -/* Destination Buffer Address */ -#define ROT_DST_BUF_ADDR(n) (0x50 + ((n) << 2)) - -/* Destination Buffer Size */ -#define ROT_DST_BUF_SIZE 0x5c -#define ROT_DST_BUF_SIZE_H(x) ((x) << 16) -#define ROT_DST_BUF_SIZE_W(x) ((x) << 0) - -/* Destination Crop Position */ -#define ROT_DST_CROP_POS 0x60 -#define ROT_DST_CROP_POS_Y(x) ((x) << 16) -#define ROT_DST_CROP_POS_X(x) ((x) << 0) - -/* Round to nearest aligned value */ -#define ROT_ALIGN(x, align, mask) ((*(x) + (1 << ((align) - 1))) & (mask)) -/* Minimum limit value */ -#define ROT_MIN(min, mask) (((min) + ~(mask)) & (mask)) -/* Maximum limit value */ -#define ROT_MAX(max, mask) ((max) & (mask)) - -enum rot_irq_status { - ROT_IRQ_STATUS_COMPLETE = 8, - ROT_IRQ_STATUS_ILLEGAL = 9, -}; - -struct rot_limit { - u32 min_w; - u32 min_h; - u32 max_w; - u32 max_h; - u32 align; -}; - -struct rot_limit_table { - struct rot_limit ycbcr420_2p; - struct rot_limit rgb888; -}; - -struct rot_context { - struct rot_limit_table *limit_tbl; - struct clk *clock; - struct resource *regs_res; - void __iomem *regs; - int irq; - int exec_ret; - struct exynos_drm_subdrv subdrv; - struct completion complete; - struct mutex exec_mutex; - spinlock_t irq_lock; - struct pm_qos_request_list pm_qos; - bool suspended; -}; - -struct rot_buffer { - dma_addr_t src_addr[DRM_EXYNOS_ROT_MAX_BUF]; - dma_addr_t dst_addr[DRM_EXYNOS_ROT_MAX_BUF]; - void *src_gem_obj[DRM_EXYNOS_ROT_MAX_BUF]; - void *dst_gem_obj[DRM_EXYNOS_ROT_MAX_BUF]; - u32 src_cnt; - u32 dst_cnt; - u32 src_w; - u32 src_h; - u32 dst_w; - u32 dst_h; -}; - -static void rotator_reg_set_irq(struct rot_context *rot, bool enable) -{ - u32 value = readl(rot->regs + ROT_CONFIG); - - if (enable == true) - value |= ROT_CONFIG_IRQ; - else - value &= ~ROT_CONFIG_IRQ; - - writel(value, rot->regs + ROT_CONFIG); -} - -static void rotator_reg_set_format(struct rot_context *rot, u32 img_fmt) -{ - u32 value = readl(rot->regs + ROT_CONTROL); - value &= ~ROT_CONTROL_FMT_MASK; - - switch (img_fmt) { - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV12M: - value |= ROT_CONTROL_FMT_YCBCR420_2P; - break; - case DRM_FORMAT_RGB888: - value |= ROT_CONTROL_FMT_RGB888; - break; - default: - DRM_ERROR("invalid image format\n"); - return; - } - - writel(value, rot->regs + ROT_CONTROL); -} - -static void rotator_reg_set_flip(struct rot_context *rot, - enum drm_exynos_rot_flip flip) -{ - u32 value = readl(rot->regs + ROT_CONTROL); - value &= ~ROT_CONTROL_FLIP_MASK; - - switch (flip) { - case ROT_FLIP_VERTICAL: - value |= ROT_CONTROL_FLIP_VERTICAL; - break; - case ROT_FLIP_HORIZONTAL: - value |= ROT_CONTROL_FLIP_HORIZONTAL; - break; - default: - /* Flip None */ - break; - } - - writel(value, rot->regs + ROT_CONTROL); -} - -static void rotator_reg_set_rotation(struct rot_context *rot, - enum drm_exynos_rot_degree degree) -{ - u32 value = readl(rot->regs + ROT_CONTROL); - value &= ~ROT_CONTROL_ROT_MASK; - - switch (degree) { - case ROT_DEGREE_90: - value |= ROT_CONTROL_ROT_90; - break; - case ROT_DEGREE_180: - value |= ROT_CONTROL_ROT_180; - break; - case ROT_DEGREE_270: - value |= ROT_CONTROL_ROT_270; - break; - default: - /* Rotation 0 Degree */ - break; - } - - writel(value, rot->regs + ROT_CONTROL); -} - -static void rotator_reg_set_start(struct rot_context *rot) -{ - u32 value = readl(rot->regs + ROT_CONTROL); - - value |= ROT_CONTROL_START; - - writel(value, rot->regs + ROT_CONTROL); -} - -static enum rot_irq_status rotator_reg_get_irq_status(struct rot_context *rot) -{ - u32 value = readl(rot->regs + ROT_STATUS); - value = ROT_STATUS_IRQ(value); - - if (value == ROT_STATUS_IRQ_VAL_COMPLETE) - return ROT_IRQ_STATUS_COMPLETE; - else - return ROT_IRQ_STATUS_ILLEGAL; -} - -static void rotator_reg_set_irq_status_clear(struct rot_context *rot, - enum rot_irq_status status) -{ - u32 value = readl(rot->regs + ROT_STATUS); - - value |= ROT_STATUS_IRQ_PENDING((u32)status); - - writel(value, rot->regs + ROT_STATUS); -} - -static void rotator_reg_set_src_buf_addr(struct rot_context *rot, - dma_addr_t addr, int i) -{ - writel(addr, rot->regs + ROT_SRC_BUF_ADDR(i)); -} - -static void rotator_reg_set_src_buf_size(struct rot_context *rot, u32 w, u32 h) -{ - u32 value = ROT_SRC_BUF_SIZE_H(h) | ROT_SRC_BUF_SIZE_W(w); - - writel(value, rot->regs + ROT_SRC_BUF_SIZE); -} - -static void rotator_reg_set_src_crop_pos(struct rot_context *rot, u32 x, u32 y) -{ - u32 value = ROT_SRC_CROP_POS_Y(y) | ROT_SRC_CROP_POS_X(x); - - writel(value, rot->regs + ROT_SRC_CROP_POS); -} - -static void rotator_reg_set_src_crop_size(struct rot_context *rot, u32 w, u32 h) -{ - u32 value = ROT_SRC_CROP_SIZE_H(h) | ROT_SRC_CROP_SIZE_W(w); - - writel(value, rot->regs + ROT_SRC_CROP_SIZE); -} - -static void rotator_reg_set_dst_buf_addr(struct rot_context *rot, - dma_addr_t addr, int i) -{ - writel(addr, rot->regs + ROT_DST_BUF_ADDR(i)); -} - -static void rotator_reg_set_dst_buf_size(struct rot_context *rot, u32 w, u32 h) -{ - u32 value = ROT_DST_BUF_SIZE_H(h) | ROT_DST_BUF_SIZE_W(w); - - writel(value, rot->regs + ROT_DST_BUF_SIZE); -} - -static void rotator_reg_set_dst_crop_pos(struct rot_context *rot, u32 x, u32 y) -{ - u32 value = ROT_DST_CROP_POS_Y(y) | ROT_DST_CROP_POS_X(x); - - writel(value, rot->regs + ROT_DST_CROP_POS); -} - -static void rotator_reg_get_dump(struct rot_context *rot) -{ - u32 value, i; - - for (i = 0; i <= ROT_DST_CROP_POS; i += 0x4) { - value = readl(rot->regs + i); - DRM_INFO("+0x%x: 0x%x", i, value); - } -} - -static bool rotator_check_format_n_handle_valid(u32 img_fmt, - u32 src_buf_handle_cnt, - u32 dst_buf_handle_cnt) -{ - bool ret = false; - - if ((src_buf_handle_cnt != dst_buf_handle_cnt) - || (src_buf_handle_cnt == 0)) - return ret; - - switch (img_fmt) { - case DRM_FORMAT_NV12M: - if (src_buf_handle_cnt == 2) - ret = true; - break; - case DRM_FORMAT_NV12: - case DRM_FORMAT_RGB888: - if (src_buf_handle_cnt == 1) - ret = true; - break; - default: - DRM_ERROR("invalid image format\n"); - break; - } - - return ret; -} - -static void rotator_align_size(struct rot_limit *limit, u32 mask, u32 *w, - u32 *h) -{ - u32 value; - - value = ROT_ALIGN(w, limit->align, mask); - if (value < limit->min_w) - *w = ROT_MIN(limit->min_w, mask); - else if (value > limit->max_w) - *w = ROT_MAX(limit->max_w, mask); - else - *w = value; - - value = ROT_ALIGN(h, limit->align, mask); - if (value < limit->min_h) - *h = ROT_MIN(limit->min_h, mask); - else if (value > limit->max_h) - *h = ROT_MAX(limit->max_h, mask); - else - *h = value; -} - -static void rotator_align_buffer(struct rot_context *rot, - struct rot_buffer *buf, - struct drm_exynos_rot_buffer *req_buf, - struct drm_exynos_rot_control *control) -{ - struct rot_limit_table *limit_tbl = rot->limit_tbl; - struct rot_limit *limit; - u32 mask; - - /* Get size limit */ - if (control->img_fmt == DRM_FORMAT_RGB888) - limit = &limit_tbl->rgb888; - else - limit = &limit_tbl->ycbcr420_2p; - - /* Get mask for rounding to nearest aligned value */ - mask = ~((1 << limit->align) - 1); - - /* For source buffer */ - buf->src_w = req_buf->src_w; - buf->src_h = req_buf->src_h; - rotator_align_size(limit, mask, &buf->src_w, &buf->src_h); - - /* For destination buffer */ - buf->dst_w = req_buf->dst_w; - buf->dst_h = req_buf->dst_h; - rotator_align_size(limit, mask, &buf->dst_w, &buf->dst_h); -} - -static bool rotator_check_crop_boundary(struct rot_buffer *buf, - struct drm_exynos_rot_control *control, - struct drm_exynos_rot_crop *crop) -{ - bool ret = true; - - /* Check source crop position */ - if ((crop->src_x + crop->src_w > buf->src_w) - || (crop->src_y + crop->src_h > buf->src_h)) - return false; - - /* Check destination crop position */ - switch (control->degree) { - case ROT_DEGREE_90: - case ROT_DEGREE_270: - if ((crop->dst_x + crop->src_h > buf->dst_w) - || (crop->dst_y + crop->src_w > buf->dst_h)) - ret = false; - break; - default: - if ((crop->dst_x + crop->src_w > buf->dst_w) - || (crop->dst_y + crop->src_h > buf->dst_h)) - ret = false; - break; - } - - return ret; -} - -static int rotator_iommu_map(struct rot_buffer *buf, - struct drm_exynos_rot_buffer *req_buf, - struct iommu_gem_map_params *params, - struct list_head *iommu_list) -{ - /* For source buffer */ - buf->src_cnt = 0; - while (buf->src_cnt < req_buf->src_cnt) { - buf->src_addr[buf->src_cnt] = exynos_drm_iommu_map_gem(params, - iommu_list, - req_buf->src_handle[buf->src_cnt], - IOMMU_ROTATOR); - if (!buf->src_addr[buf->src_cnt]) { - DRM_ERROR("failed to map src handle[%u]\n", - buf->src_cnt); - return -EINVAL; - } - buf->src_gem_obj[(buf->src_cnt)++] = params->gem_obj; - } - - /* For destination buffer */ - buf->dst_cnt = 0; - while (buf->dst_cnt < req_buf->dst_cnt) { - buf->dst_addr[buf->dst_cnt] = exynos_drm_iommu_map_gem(params, - iommu_list, - req_buf->dst_handle[buf->dst_cnt], - IOMMU_ROTATOR); - if (!buf->dst_addr[buf->dst_cnt]) { - DRM_ERROR("failed to map dst handle[%u]\n", - buf->dst_cnt); - return -EINVAL; - } - buf->dst_gem_obj[(buf->dst_cnt)++] = params->gem_obj; - } - - return 0; -} - -static void rotator_iommu_unmap(struct rot_buffer *buf, - struct iommu_gem_map_params *params) -{ - /* For destination buffer */ - while (buf->dst_cnt > 0) { - params->gem_obj = buf->dst_gem_obj[--(buf->dst_cnt)]; - exynos_drm_iommu_unmap_gem(params, - buf->dst_addr[buf->dst_cnt], - IOMMU_ROTATOR); - } - - /* For source buffer */ - while (buf->src_cnt > 0) { - params->gem_obj = buf->src_gem_obj[--(buf->src_cnt)]; - exynos_drm_iommu_unmap_gem(params, - buf->src_addr[buf->src_cnt], - IOMMU_ROTATOR); - } -} - -static void rotator_execute(struct rot_context *rot, - struct rot_buffer *buf, - struct drm_exynos_rot_control *control, - struct drm_exynos_rot_crop *crop) -{ - int i; - - pm_runtime_get_sync(rot->subdrv.dev); - - /* Set interrupt enable */ - rotator_reg_set_irq(rot, true); - - /* Set control registers */ - rotator_reg_set_format(rot, control->img_fmt); - rotator_reg_set_flip(rot, control->flip); - rotator_reg_set_rotation(rot, control->degree); - - /* Set source buffer address */ - for (i = 0; i < DRM_EXYNOS_ROT_MAX_BUF; i++) - rotator_reg_set_src_buf_addr(rot, buf->src_addr[i], i); - - /* Set source buffer size */ - rotator_reg_set_src_buf_size(rot, buf->src_w, buf->src_h); - - /* Set destination buffer address */ - for (i = 0; i < DRM_EXYNOS_ROT_MAX_BUF; i++) - rotator_reg_set_dst_buf_addr(rot, buf->dst_addr[i], i); - - /* Set destination buffer size */ - rotator_reg_set_dst_buf_size(rot, buf->dst_w, buf->dst_h); - - /* Set source crop image position */ - rotator_reg_set_src_crop_pos(rot, crop->src_x, crop->src_y); - - /* Set source crop image size */ - rotator_reg_set_src_crop_size(rot, crop->src_w, crop->src_h); - - /* Set destination crop image position */ - rotator_reg_set_dst_crop_pos(rot, crop->dst_x, crop->dst_y); - - /* Start rotator operation */ - rotator_reg_set_start(rot); -} - -int exynos_drm_rotator_exec_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_rot_private *priv = file_priv->rot_priv; - struct device *dev = priv->dev; - struct rot_context *rot; - struct drm_exynos_rot_exec_data *req = data; - struct drm_exynos_rot_buffer *req_buf = &req->buf; - struct drm_exynos_rot_control *control = &req->control; - struct drm_exynos_rot_crop *crop = &req->crop; - struct rot_buffer buf; - struct iommu_gem_map_params params; - - if (!dev) { - DRM_ERROR("failed to get dev\n"); - return -ENODEV; - } - - rot = dev_get_drvdata(dev); - if (!rot) { - DRM_ERROR("failed to get drvdata\n"); - return -EFAULT; - } - - if (rot->suspended) { - DRM_ERROR("suspended state\n"); - return -EPERM; - } - - if (!rotator_check_format_n_handle_valid(control->img_fmt, - req_buf->src_cnt, - req_buf->dst_cnt)) { - DRM_ERROR("format or handles are invalid\n"); - return -EINVAL; - } - - init_completion(&rot->complete); - - /* Align buffer */ - rotator_align_buffer(rot, &buf, req_buf, control); - - /* Check crop boundary */ - if (!rotator_check_crop_boundary(&buf, control, crop)) { - DRM_ERROR("boundary errror\n"); - return -EINVAL; - } - - params.dev = dev; - params.drm_dev = drm_dev; - params.file = file; - - /* Map IOMMU */ - rot->exec_ret = rotator_iommu_map(&buf, req_buf, ¶ms, - &priv->iommu_list); - if (rot->exec_ret < 0) - goto err_iommu_map; - - /* Assign another src/dst_addr for NV12 image format */ - if (control->img_fmt == DRM_FORMAT_NV12) { - u32 size = crop->src_w * crop->src_h; - - buf.src_addr[buf.src_cnt + 1] = - buf.src_addr[buf.src_cnt] + size; - buf.dst_addr[buf.dst_cnt + 1] = - buf.dst_addr[buf.dst_cnt] + size; - } - - /* Execute */ - mutex_lock(&rot->exec_mutex); - rotator_execute(rot, &buf, control, crop); - if (!wait_for_completion_timeout(&rot->complete, 2 * HZ)) { - DRM_ERROR("timeout error\n"); - rot->exec_ret = -ETIMEDOUT; - mutex_unlock(&rot->exec_mutex); - goto err_iommu_map; - } - mutex_unlock(&rot->exec_mutex); - - /* Unmap IOMMU */ - rotator_iommu_unmap(&buf, ¶ms); - - return rot->exec_ret; - -err_iommu_map: - rotator_iommu_unmap(&buf, ¶ms); - return rot->exec_ret; -} -EXPORT_SYMBOL_GPL(exynos_drm_rotator_exec_ioctl); - -static irqreturn_t rotator_irq_thread(int irq, void *arg) -{ - struct rot_context *rot = (struct rot_context *)arg; - enum rot_irq_status irq_status; - unsigned long flags; - - pm_qos_update_request(&rot->pm_qos, 0); - - /* Get execution result */ - spin_lock_irqsave(&rot->irq_lock, flags); - irq_status = rotator_reg_get_irq_status(rot); - rotator_reg_set_irq_status_clear(rot, irq_status); - spin_unlock_irqrestore(&rot->irq_lock, flags); - - rot->exec_ret = 0; - if (irq_status != ROT_IRQ_STATUS_COMPLETE) { - DRM_ERROR("the SFR is set illegally\n"); - rot->exec_ret = -EINVAL; - rotator_reg_get_dump(rot); - } - - pm_runtime_put(rot->subdrv.dev); - - complete(&rot->complete); - - return IRQ_HANDLED; -} - -static int rotator_subdrv_open(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_rot_private *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "failed to allocate priv\n"); - return -ENOMEM; - } - - priv->dev = dev; - INIT_LIST_HEAD(&priv->iommu_list); - - file_priv->rot_priv = priv; - - return 0; -} - -static void rotator_subdrv_close(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file) -{ - struct drm_exynos_file_private *file_priv = file->driver_priv; - struct exynos_drm_rot_private *priv = file_priv->rot_priv; - struct iommu_gem_map_params params; - struct iommu_info_node *node, *n; - - params.dev = dev; - params.drm_dev = drm_dev; - params.file = file; - - list_for_each_entry_safe(node, n, &priv->iommu_list, list) { - params.gem_obj = node->gem_obj; - exynos_drm_iommu_unmap_gem(¶ms, node->dma_addr, - IOMMU_ROTATOR); - list_del(&node->list); - kfree(node); - node = NULL; - } - - kfree(priv); - - return; -} - -static int __devinit rotator_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct rot_context *rot; - struct resource *res; - struct exynos_drm_subdrv *subdrv; - int ret; - - rot = kzalloc(sizeof(*rot), GFP_KERNEL); - if (!rot) { - dev_err(dev, "failed to allocate rot\n"); - return -ENOMEM; - } - - rot->limit_tbl = (struct rot_limit_table *) - platform_get_device_id(pdev)->driver_data; - - mutex_init(&rot->exec_mutex); - spin_lock_init(&rot->irq_lock); - - ret = exynos_drm_iommu_setup(dev); - if (ret < 0) { - dev_err(dev, "failed to setup iommu\n"); - goto err_iommu_setup; - } - - ret = exynos_drm_iommu_activate(dev); - if (ret < 0) { - dev_err(dev, "failed to activate iommu\n"); - goto err_iommu_activate; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to find registers\n"); - ret = -ENOENT; - goto err_get_resource; - } - - rot->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!rot->regs_res) { - dev_err(dev, "failed to claim register region\n"); - ret = -ENOENT; - goto err_get_resource; - } - - rot->regs = ioremap(res->start, resource_size(res)); - if (!rot->regs) { - dev_err(dev, "failed to map register\n"); - ret = -ENXIO; - goto err_ioremap; - } - - rot->irq = platform_get_irq(pdev, 0); - if (rot->irq < 0) { - dev_err(dev, "faild to get irq\n"); - ret = rot->irq; - goto err_get_irq; - } - - ret = request_threaded_irq(rot->irq, NULL, rotator_irq_thread, - IRQF_ONESHOT, "drm_rotator", rot); - if (ret < 0) { - dev_err(dev, "failed to request irq\n"); - goto err_get_irq; - } - - rot->clock = clk_get(dev, "rotator"); - if (IS_ERR_OR_NULL(rot->clock)) { - dev_err(dev, "faild to get clock\n"); - ret = PTR_ERR(rot->clock); - goto err_clk_get; - } - - pm_runtime_enable(dev); - pm_qos_add_request(&rot->pm_qos, PM_QOS_BUS_DMA_THROUGHPUT, 0); - - subdrv = &rot->subdrv; - subdrv->dev = dev; - subdrv->open = rotator_subdrv_open; - subdrv->close = rotator_subdrv_close; - - platform_set_drvdata(pdev, rot); - - ret = exynos_drm_subdrv_register(subdrv); - if (ret < 0) { - dev_err(dev, "failed to register drm rotator device\n"); - goto err_subdrv_register; - } - - dev_info(dev, "The exynos rotator is probed successfully\n"); - - return 0; - -err_subdrv_register: - pm_runtime_disable(dev); - clk_put(rot->clock); -err_clk_get: - free_irq(rot->irq, rot); -err_get_irq: - iounmap(rot->regs); -err_ioremap: - release_resource(rot->regs_res); - kfree(rot->regs_res); -err_get_resource: - exynos_drm_iommu_deactivate(dev); -err_iommu_activate: - exynos_drm_iommu_cleanup(dev); -err_iommu_setup: - kfree(rot); - return ret; -} - -static int __devexit rotator_remove(struct platform_device *pdev) -{ - struct rot_context *rot = platform_get_drvdata(pdev); - - pm_qos_remove_request(&rot->pm_qos); - - exynos_drm_subdrv_unregister(&rot->subdrv); - - pm_runtime_disable(&pdev->dev); - clk_put(rot->clock); - - free_irq(rot->irq, rot); - - iounmap(rot->regs); - - release_resource(rot->regs_res); - kfree(rot->regs_res); - - exynos_drm_iommu_deactivate(&pdev->dev); - exynos_drm_iommu_cleanup(&pdev->dev); - - kfree(rot); - - return 0; -} - -struct rot_limit_table rot_limit_tbl = { - .ycbcr420_2p = { - .min_w = 32, - .min_h = 32, - .max_w = SZ_32K, - .max_h = SZ_32K, - .align = 3, - }, - .rgb888 = { - .min_w = 8, - .min_h = 8, - .max_w = SZ_8K, - .max_h = SZ_8K, - .align = 2, - }, -}; - -struct platform_device_id rotator_driver_ids[] = { - { - .name = "exynos-rot", - .driver_data = (unsigned long)&rot_limit_tbl, - }, - {}, -}; - -#ifdef CONFIG_PM_SLEEP -static int rotator_suspend(struct device *dev) -{ - struct rot_context *rot = dev_get_drvdata(dev); - - /* Check & wait for running state */ - mutex_lock(&rot->exec_mutex); - mutex_unlock(&rot->exec_mutex); - - rot->suspended = true; - - exynos_drm_iommu_deactivate(dev); - - return 0; -} - -static int rotator_resume(struct device *dev) -{ - struct rot_context *rot = dev_get_drvdata(dev); - - rot->suspended = false; - - exynos_drm_iommu_activate(dev); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int rotator_runtime_suspend(struct device *dev) -{ - struct rot_context *rot = dev_get_drvdata(dev); - - clk_disable(rot->clock); - - return 0; -} - -static int rotator_runtime_resume(struct device *dev) -{ - struct rot_context *rot = dev_get_drvdata(dev); - - clk_enable(rot->clock); - pm_qos_update_request(&rot->pm_qos, 400000); - - return 0; -} -#endif - -static const struct dev_pm_ops rotator_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(rotator_suspend, rotator_resume) - SET_RUNTIME_PM_OPS(rotator_runtime_suspend, rotator_runtime_resume, - NULL) -}; - -struct platform_driver rotator_driver = { - .probe = rotator_probe, - .remove = __devexit_p(rotator_remove), - .id_table = rotator_driver_ids, - .driver = { - .name = "exynos-rot", - .owner = THIS_MODULE, - .pm = &rotator_pm_ops, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.h deleted file mode 100644 index 5f383d5..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_rotator.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: YoungJun Cho <yj44.cho@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#ifndef _EXYNOS_DRM_ROTATOR_H_ -#define _EXYNOS_DRM_ROTATOR_H_ - -#ifdef CONFIG_DRM_EXYNOS_ROTATOR -extern int exynos_drm_rotator_exec_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -#else -static inline int exynos_drm_rotator_exec_ioctl(struct drm_device *dev, - void *data, - struct drm_file *file_priv) -{ - return -ENOTTY; -} -#endif - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_ump.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_ump.c deleted file mode 100644 index fd9ba2a..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_ump.c +++ /dev/null @@ -1,151 +0,0 @@ -/* exynos_drm_ump.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" - -#include <drm/exynos_drm.h> - -#include "exynos_drm_gem.h" -#include "ump_kernel_interface_ref_drv.h" - -static unsigned int exynos_drm_ump_get_handle(unsigned int id) -{ - return (unsigned int)ump_dd_handle_get((ump_secure_id)id); -} - -static int exynos_drm_ump_add_buffer(void *obj, - unsigned int *handle, unsigned int *id) -{ - struct exynos_drm_gem_obj *gem_obj = obj; - struct exynos_drm_gem_buf *buf = gem_obj->buffer; - ump_dd_physical_block *ump_mem_desc; - unsigned int nblocks; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (IS_NONCONTIG_BUFFER(gem_obj->flags)) { - unsigned int i = 0; - - if (!buf->pages) - return -EFAULT; - - nblocks = gem_obj->size >> PAGE_SHIFT; - ump_mem_desc = kzalloc(sizeof(*ump_mem_desc) * nblocks, - GFP_KERNEL); - if (!ump_mem_desc) { - DRM_ERROR("failed to alloc ump_mem_desc.\n"); - return -ENOMEM; - } - - /* - * if EXYNOS_BO_NONCONTIG type, gem object would already - * have pages allocated by gem creation so contain page - * frame numbers of all pages into ump descriptors. - */ - while (i < nblocks) { - ump_mem_desc[i].addr = - page_to_pfn(buf->pages[i]) << PAGE_SHIFT; - ump_mem_desc[i].size = PAGE_SIZE; - i++; - } - } else { - nblocks = 1; - - ump_mem_desc = kzalloc(sizeof(*ump_mem_desc), GFP_KERNEL); - if (!ump_mem_desc) { - DRM_ERROR("failed to alloc ump_mem_desc.\n"); - return -ENOMEM; - } - - /* - * it EXYNOS_DRM_GEM_PC type, gem would have just one - * physically continuous buffer so let a ump descriptor - * have one buffer address. - */ - ump_mem_desc[0].addr = (unsigned long)buf->dma_addr; - ump_mem_desc[0].size = buf->size; - } - - /* - * register memory information to ump descriptor table through - * the ump descriptor data and then return ump handle to it so that - * user can access the memory region through it. - */ - *handle = (unsigned int) - ump_dd_handle_create_from_phys_blocks(ump_mem_desc, nblocks); - if (!(*handle)) { - DRM_ERROR("failed to create ump handle.\n"); - kfree(ump_mem_desc); - return -EINVAL; - } - - *id = ump_dd_secure_id_get((ump_dd_handle)*handle); - - kfree(ump_mem_desc); - - DRM_DEBUG_KMS("ump handle : 0x%x, secure id = %d\n", *handle, *id); - DRM_INFO("ump handle : 0x%x, secure id = %d\n", *handle, *id); - - return 0; -} - -static void exynos_drm_ump_release_buffer(unsigned int handle) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!handle) { - DRM_DEBUG_KMS("invalid ump handle.\n"); - return; - } - - ump_dd_reference_release((ump_dd_handle)handle); -} - -static struct exynos_drm_private_cb ump_callback = { - .get_handle = exynos_drm_ump_get_handle, - .add_buffer = exynos_drm_ump_add_buffer, - .release_buffer = exynos_drm_ump_release_buffer, -}; - -static int exynos_drm_ump_init(void) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_priv_cb_register(&ump_callback); - - return 0; -} - -static void exynos_drm_ump_exit(void) -{ -} - -subsys_initcall(exynos_drm_ump_init); -module_exit(exynos_drm_ump_exit); - -MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DRM UMP Backend Module"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.c b/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.c deleted file mode 100644 index 876e460..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.c +++ /dev/null @@ -1,680 +0,0 @@ -/* exynos_drm_vidi.c - * - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: - * Inki Dae <inki.dae@samsung.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. - * - */ -#include "drmP.h" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include <drm/exynos_drm.h> - -#include "drm_edid.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" - -/* vidi has totally three virtual windows. */ -#define WINDOWS_NR 3 - -#define get_vidi_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct vidi_win_data { - unsigned int offset_x; - unsigned int offset_y; - unsigned int ovl_width; - unsigned int ovl_height; - unsigned int fb_width; - unsigned int fb_height; - unsigned int bpp; - dma_addr_t dma_addr; - void __iomem *vaddr; - unsigned int buf_offsize; - unsigned int line_size; /* bytes */ - bool enabled; -}; - -struct vidi_context { - struct exynos_drm_subdrv subdrv; - struct drm_crtc *crtc; - struct vidi_win_data win_data[WINDOWS_NR]; - struct edid *raw_edid; - unsigned int clkdiv; - unsigned int default_win; - unsigned long irq_flags; - unsigned int connected; - bool vblank_on; - bool suspended; - struct work_struct work; - struct mutex lock; -}; - -static const char fake_edid_info[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, - 0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd, - 0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00, - 0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, - 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, - 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, - 0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1, - 0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83, - 0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00, - 0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c, - 0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a, - 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00, - 0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, - 0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06 -}; - -static void vidi_fake_vblank_handler(struct work_struct *work); - -static bool vidi_display_is_connected(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * connection request would come from user side - * to do hotplug through specific ioctl. - */ - return ctx->connected ? true : false; -} - -static int vidi_get_edid(struct device *dev, struct drm_connector *connector, - u8 *edid, int len) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct edid *raw_edid; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * the edid data comes from user side and it would be set - * to ctx->raw_edid through specific ioctl. - */ - if (!ctx->raw_edid) { - DRM_DEBUG_KMS("raw_edid is null.\n"); - return -EFAULT; - } - - raw_edid = kzalloc(len, GFP_KERNEL); - if (!raw_edid) { - DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); - return -ENOMEM; - } - - memcpy(raw_edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) - * EDID_LENGTH, len)); - - /* attach the edid data to connector. */ - connector->display_info.raw_edid = (char *)raw_edid; - - memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) - * EDID_LENGTH, len)); - - return 0; -} - -static void *vidi_get_panel(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return NULL; -} - -static int vidi_check_timing(struct device *dev, void *timing) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return 0; -} - -static int vidi_display_power_on(struct device *dev, int mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - return 0; -} - -static struct exynos_drm_display_ops vidi_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_VIDI, - .is_connected = vidi_display_is_connected, - .get_edid = vidi_get_edid, - .get_panel = vidi_get_panel, - .check_timing = vidi_check_timing, - .power_on = vidi_display_power_on, -}; - -static void vidi_dpms(struct device *subdrv_dev, int mode) -{ - struct vidi_context *ctx = get_vidi_context(subdrv_dev); - - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); - - mutex_lock(&ctx->lock); - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* TODO. */ - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - /* TODO. */ - break; - default: - DRM_DEBUG_KMS("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&ctx->lock); -} - -static void vidi_apply(struct device *subdrv_dev) -{ - struct vidi_context *ctx = get_vidi_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; - struct exynos_drm_manager_ops *mgr_ops = mgr->ops; - struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; - struct vidi_win_data *win_data; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - for (i = 0; i < WINDOWS_NR; i++) { - win_data = &ctx->win_data[i]; - if (win_data->enabled && (ovl_ops && ovl_ops->commit)) - ovl_ops->commit(subdrv_dev, i); - } - - if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); -} - -static void vidi_commit(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; -} - -static int vidi_enable_vblank(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return -EPERM; - - if (!test_and_set_bit(0, &ctx->irq_flags)) - ctx->vblank_on = true; - - return 0; -} - -static void vidi_disable_vblank(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (test_and_clear_bit(0, &ctx->irq_flags)) - ctx->vblank_on = false; -} - -static struct exynos_drm_manager_ops vidi_manager_ops = { - .dpms = vidi_dpms, - .apply = vidi_apply, - .commit = vidi_commit, - .enable_vblank = vidi_enable_vblank, - .disable_vblank = vidi_disable_vblank, -}; - -static void vidi_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win; - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!overlay) { - dev_err(dev, "overlay is NULL\n"); - return; - } - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - offset = overlay->fb_x * (overlay->bpp >> 3); - offset += overlay->fb_y * overlay->pitch; - - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); - - win_data = &ctx->win_data[win]; - - win_data->offset_x = overlay->crtc_x; - win_data->offset_y = overlay->crtc_y; - win_data->ovl_width = overlay->crtc_width; - win_data->ovl_height = overlay->crtc_height; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - win_data->dma_addr = overlay->dma_addr[0] + offset; - win_data->vaddr = overlay->vaddr[0] + offset; - win_data->bpp = overlay->bpp; - win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * - (overlay->bpp >> 3); - win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); - - /* - * some parts of win_data should be transferred to user side - * through specific ioctl. - */ - - DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", - win_data->offset_x, win_data->offset_y); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", - (unsigned long)win_data->dma_addr, - (unsigned long)win_data->vaddr); - DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", - overlay->fb_width, overlay->crtc_width); -} - -static void vidi_win_commit(struct device *dev, int zpos) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win = zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - win_data->enabled = true; - - DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr); - - if (ctx->vblank_on) - schedule_work(&ctx->work); -} - -static void vidi_win_disable(struct device *dev, int zpos) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win = zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - win_data->enabled = false; - - /* TODO. */ -} - -static struct exynos_drm_overlay_ops vidi_overlay_ops = { - .mode_set = vidi_win_mode_set, - .commit = vidi_win_commit, - .disable = vidi_win_disable, -}; - -static struct exynos_drm_manager vidi_manager = { - .pipe = -1, - .ops = &vidi_manager_ops, - .overlay_ops = &vidi_overlay_ops, - .display_ops = &vidi_display_ops, -}; - -static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) { - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - /* - * don't off vblank if vblank_disable_allowed is 1, - * because vblank would be off by timer handler. - */ - if (!drm_dev->vblank_disable_allowed) - drm_vblank_off(drm_dev, crtc); - } - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static void vidi_fake_vblank_handler(struct work_struct *work) -{ - struct vidi_context *ctx = container_of(work, struct vidi_context, - work); - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; - - if (manager->pipe < 0) - return; - - /* FIXME!!! */ - msleep(20); - - drm_handle_vblank(subdrv->drm_dev, manager->pipe); - vidi_finish_pageflip(subdrv->drm_dev, manager->pipe); -} - -static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * enable drm irq mode. - * - with irq_enabled = 1, 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. - */ - drm_dev->irq_enabled = 1; - - /* - * with vblank_disable_allowed = 1, 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_dev->vblank_disable_allowed = 1; - - return 0; -} - -static void vidi_subdrv_remove(struct drm_device *drm_dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ -} - -static int vidi_power_on(struct vidi_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - vidi_enable_vblank(dev); - - vidi_apply(dev); - } else { - ctx->suspended = true; - } - - return 0; -} - -static int vidi_show_connection(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int rc; - struct vidi_context *ctx = get_vidi_context(dev); - - mutex_lock(&ctx->lock); - - rc = sprintf(buf, "%d\n", ctx->connected); - - mutex_unlock(&ctx->lock); - - return rc; -} - -static int vidi_store_connection(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct vidi_context *ctx = get_vidi_context(dev); - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = kstrtoint(buf, 0, &ctx->connected); - if (ret) - return ret; - - if (ctx->connected > 1) - return -EINVAL; - - DRM_DEBUG_KMS("requested connection.\n"); - - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); - - return len; -} - -static DEVICE_ATTR(connection, 0644, vidi_show_connection, - vidi_store_connection); - -int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct vidi_context *ctx = NULL; - struct drm_encoder *encoder; - struct exynos_drm_manager *manager; - struct exynos_drm_display_ops *display_ops; - struct drm_exynos_vidi_connection *vidi = data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!vidi) { - DRM_DEBUG_KMS("user data for vidi is null.\n"); - return -EINVAL; - } - - if (!vidi->edid) { - DRM_DEBUG_KMS("edid data is null.\n"); - return -EINVAL; - } - - if (vidi->connection > 1) { - DRM_DEBUG_KMS("connection should be 0 or 1.\n"); - return -EINVAL; - } - - list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list, - head) { - manager = exynos_drm_get_manager(encoder); - display_ops = manager->display_ops; - - if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) { - ctx = get_vidi_context(manager->dev); - break; - } - } - - if (!ctx) { - DRM_DEBUG_KMS("not found virtual device type encoder.\n"); - return -EINVAL; - } - - if (ctx->connected == vidi->connection) { - DRM_DEBUG_KMS("same connection request.\n"); - return -EINVAL; - } - - if (vidi->connection) - ctx->raw_edid = (struct edid *)vidi->edid; - - ctx->connected = vidi->connection; - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); - - return 0; -} - -static int __devinit vidi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct vidi_context *ctx; - struct exynos_drm_subdrv *subdrv; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->default_win = 0; - - INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - - /* for test */ - ctx->raw_edid = (struct edid *)fake_edid_info; - - subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &vidi_manager; - subdrv->probe = vidi_subdrv_probe; - subdrv->remove = vidi_subdrv_remove; - - mutex_init(&ctx->lock); - - platform_set_drvdata(pdev, ctx); - - ret = device_create_file(&pdev->dev, &dev_attr_connection); - if (ret < 0) - DRM_INFO("failed to create connection sysfs.\n"); - - exynos_drm_subdrv_register(subdrv); - - return 0; -} - -static int __devexit vidi_remove(struct platform_device *pdev) -{ - struct vidi_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); - - kfree(ctx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int vidi_suspend(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - return vidi_power_on(ctx, false); -} - -static int vidi_resume(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - return vidi_power_on(ctx, true); -} -#endif - -static const struct dev_pm_ops vidi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(vidi_suspend, vidi_resume) -}; - -struct platform_driver vidi_driver = { - .probe = vidi_probe, - .remove = __devexit_p(vidi_remove), - .driver = { - .name = "exynos-drm-vidi", - .owner = THIS_MODULE, - .pm = &vidi_pm_ops, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.h b/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.h deleted file mode 100644 index a4babe4..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_drm_vidi.h +++ /dev/null @@ -1,36 +0,0 @@ -/* exynos_drm_vidi.h - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Author: Inki Dae <inki.dae@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_VIDI_H_ -#define _EXYNOS_DRM_VIDI_H_ - -#ifdef CONFIG_DRM_EXYNOS_VIDI -int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); -#else -#define vidi_connection_ioctl NULL -#endif - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_hdmi.c b/drivers/gpu/drm/exynos_tmp/exynos_hdmi.c deleted file mode 100644 index 0c44cb7..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_hdmi.c +++ /dev/null @@ -1,2481 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim <sw0312.kim@samsung.com> - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * - * Based on drivers/media/video/s5p-tv/hdmi_drv.c - * - * 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. - * - */ - -#include "drmP.h" -#include "drm_edid.h" -#include "drm_crtc_helper.h" - -#include "regs-hdmi.h" - -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/wait.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/pm_runtime.h> -#include <linux/clk.h> -#include <linux/regulator/consumer.h> - -#include <drm/exynos_drm.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#include "exynos_hdmi.h" - -#define MAX_WIDTH 1920 -#define MAX_HEIGHT 1080 -#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct hdmi_resources { - struct clk *hdmi; - struct clk *sclk_hdmi; - struct clk *sclk_pixel; - struct clk *sclk_hdmiphy; - struct clk *hdmiphy; - struct regulator_bulk_data *regul_bulk; - int regul_count; -}; - -struct hdmi_context { - struct device *dev; - struct drm_device *drm_dev; - bool hpd; - bool powered; - bool is_v13; - bool dvi_mode; - struct mutex hdmi_mutex; - - struct resource *regs_res; - void __iomem *regs; - unsigned int external_irq; - unsigned int internal_irq; - - struct i2c_client *ddc_port; - struct i2c_client *hdmiphy_port; - - /* current hdmiphy conf index */ - int cur_conf; - - struct hdmi_resources res; - void *parent_ctx; - - void (*cfg_hpd)(bool external); - int (*get_hpd)(void); -}; - -/* HDMI Version 1.3 */ -static const u8 hdmiphy_v13_conf27[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, - 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf27_027[32] = { - 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, - 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf74_175[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, - 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf74_25[32] = { - 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, - 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, - 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, - 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf148_5[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, - 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, - 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, -}; - -struct hdmi_v13_tg_regs { - u8 cmd; - u8 h_fsz_l; - u8 h_fsz_h; - u8 hact_st_l; - u8 hact_st_h; - u8 hact_sz_l; - u8 hact_sz_h; - u8 v_fsz_l; - u8 v_fsz_h; - u8 vsync_l; - u8 vsync_h; - u8 vsync2_l; - u8 vsync2_h; - u8 vact_st_l; - u8 vact_st_h; - u8 vact_sz_l; - u8 vact_sz_h; - u8 field_chg_l; - u8 field_chg_h; - u8 vact_st2_l; - u8 vact_st2_h; - u8 vsync_top_hdmi_l; - u8 vsync_top_hdmi_h; - u8 vsync_bot_hdmi_l; - u8 vsync_bot_hdmi_h; - u8 field_top_hdmi_l; - u8 field_top_hdmi_h; - u8 field_bot_hdmi_l; - u8 field_bot_hdmi_h; -}; - -struct hdmi_v13_core_regs { - u8 h_blank[2]; - u8 v_blank[3]; - u8 h_v_line[3]; - u8 vsync_pol[1]; - u8 int_pro_mode[1]; - u8 v_blank_f[3]; - u8 h_sync_gen[3]; - u8 v_sync_gen1[3]; - u8 v_sync_gen2[3]; - u8 v_sync_gen3[3]; -}; - -struct hdmi_v13_preset_conf { - struct hdmi_v13_core_regs core; - struct hdmi_v13_tg_regs tg; -}; - -struct hdmi_v13_conf { - int width; - int height; - int vrefresh; - bool interlace; - const u8 *hdmiphy_data; - const struct hdmi_v13_preset_conf *conf; -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = { - .core = { - .h_blank = {0x8a, 0x00}, - .v_blank = {0x0d, 0x6a, 0x01}, - .h_v_line = {0x0d, 0xa2, 0x35}, - .vsync_pol = {0x01}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, - .h_sync_gen = {0x0e, 0x30, 0x11}, - .v_sync_gen1 = {0x0f, 0x90, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x5a, 0x03, /* h_fsz */ - 0x8a, 0x00, 0xd0, 0x02, /* hact */ - 0x0d, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0xe0, 0x01, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = { - .core = { - .h_blank = {0x72, 0x01}, - .v_blank = {0xee, 0xf2, 0x00}, - .h_v_line = {0xee, 0x22, 0x67}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x6c, 0x50, 0x02}, - .v_sync_gen1 = {0x0a, 0x50, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x72, 0x06, /* h_fsz */ - 0x71, 0x01, 0x01, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v_blank = {0x32, 0xB2, 0x00}, - .h_v_line = {0x65, 0x04, 0xa5}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f = {0x49, 0x2A, 0x23}, - .h_sync_gen = {0x0E, 0xEA, 0x08}, - .v_sync_gen1 = {0x07, 0x20, 0x00}, - .v_sync_gen2 = {0x39, 0x42, 0x23}, - .v_sync_gen3 = {0x38, 0x87, 0x73}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0A, /* h_fsz */ - 0xCF, 0x02, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v_blank = {0x65, 0x6c, 0x01}, - .h_v_line = {0x65, 0x04, 0xa5}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x0e, 0xea, 0x08}, - .v_sync_gen1 = {0x09, 0x40, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0A, /* h_fsz */ - 0xCF, 0x02, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v_blank = {0x32, 0xB2, 0x00}, - .h_v_line = {0x65, 0x84, 0x89}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f = {0x49, 0x2A, 0x23}, - .h_sync_gen = {0x56, 0x08, 0x02}, - .v_sync_gen1 = {0x07, 0x20, 0x00}, - .v_sync_gen2 = {0x39, 0x42, 0x23}, - .v_sync_gen3 = {0xa4, 0x44, 0x4a}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x17, 0x01, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v_blank = {0x65, 0x6c, 0x01}, - .h_v_line = {0x65, 0x84, 0x89}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x56, 0x08, 0x02}, - .v_sync_gen1 = {0x09, 0x40, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x17, 0x01, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_conf hdmi_v13_confs[] = { - { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, - { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, - { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p }, - { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 }, - { 1920, 1080, 50, false, hdmiphy_v13_conf148_5, - &hdmi_v13_conf_1080p50 }, - { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 }, - { 1920, 1080, 60, false, hdmiphy_v13_conf148_5, - &hdmi_v13_conf_1080p60 }, -}; - -/* HDMI Version 1.4 */ -static const u8 hdmiphy_conf27_027[32] = { - 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08, - 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, - 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, -}; - -static const u8 hdmiphy_conf74_176[32] = { - 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08, - 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80, - 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, -}; - -static const u8 hdmiphy_conf74_25[32] = { - 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08, - 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, - 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, -}; - -static const u8 hdmiphy_conf148_5[32] = { - 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08, - 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, - 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, -}; - -struct hdmi_tg_regs { - u8 cmd; - u8 h_fsz_l; - u8 h_fsz_h; - u8 hact_st_l; - u8 hact_st_h; - u8 hact_sz_l; - u8 hact_sz_h; - u8 v_fsz_l; - u8 v_fsz_h; - u8 vsync_l; - u8 vsync_h; - u8 vsync2_l; - u8 vsync2_h; - u8 vact_st_l; - u8 vact_st_h; - u8 vact_sz_l; - u8 vact_sz_h; - u8 field_chg_l; - u8 field_chg_h; - u8 vact_st2_l; - u8 vact_st2_h; - u8 vact_st3_l; - u8 vact_st3_h; - u8 vact_st4_l; - u8 vact_st4_h; - u8 vsync_top_hdmi_l; - u8 vsync_top_hdmi_h; - u8 vsync_bot_hdmi_l; - u8 vsync_bot_hdmi_h; - u8 field_top_hdmi_l; - u8 field_top_hdmi_h; - u8 field_bot_hdmi_l; - u8 field_bot_hdmi_h; - u8 tg_3d; -}; - -struct hdmi_core_regs { - u8 h_blank[2]; - u8 v2_blank[2]; - u8 v1_blank[2]; - u8 v_line[2]; - u8 h_line[2]; - u8 hsync_pol[1]; - u8 vsync_pol[1]; - u8 int_pro_mode[1]; - u8 v_blank_f0[2]; - u8 v_blank_f1[2]; - u8 h_sync_start[2]; - u8 h_sync_end[2]; - u8 v_sync_line_bef_2[2]; - u8 v_sync_line_bef_1[2]; - u8 v_sync_line_aft_2[2]; - u8 v_sync_line_aft_1[2]; - u8 v_sync_line_aft_pxl_2[2]; - u8 v_sync_line_aft_pxl_1[2]; - u8 v_blank_f2[2]; /* for 3D mode */ - u8 v_blank_f3[2]; /* for 3D mode */ - u8 v_blank_f4[2]; /* for 3D mode */ - u8 v_blank_f5[2]; /* for 3D mode */ - u8 v_sync_line_aft_3[2]; - u8 v_sync_line_aft_4[2]; - u8 v_sync_line_aft_5[2]; - u8 v_sync_line_aft_6[2]; - u8 v_sync_line_aft_pxl_3[2]; - u8 v_sync_line_aft_pxl_4[2]; - u8 v_sync_line_aft_pxl_5[2]; - u8 v_sync_line_aft_pxl_6[2]; - u8 vact_space_1[2]; - u8 vact_space_2[2]; - u8 vact_space_3[2]; - u8 vact_space_4[2]; - u8 vact_space_5[2]; - u8 vact_space_6[2]; -}; - -struct hdmi_preset_conf { - struct hdmi_core_regs core; - struct hdmi_tg_regs tg; -}; - -struct hdmi_conf { - int width; - int height; - int vrefresh; - bool interlace; - const u8 *hdmiphy_data; - const struct hdmi_preset_conf *conf; -}; - -static const struct hdmi_preset_conf hdmi_conf_480p60 = { - .core = { - .h_blank = {0x8a, 0x00}, - .v2_blank = {0x0d, 0x02}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x0d, 0x02}, - .h_line = {0x5a, 0x03}, - .hsync_pol = {0x01}, - .vsync_pol = {0x01}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x0e, 0x00}, - .h_sync_end = {0x4c, 0x00}, - .v_sync_line_bef_2 = {0x0f, 0x00}, - .v_sync_line_bef_1 = {0x09, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x5a, 0x03, /* h_fsz */ - 0x8a, 0x00, 0xd0, 0x02, /* hact */ - 0x0d, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0xe0, 0x01, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_720p50 = { - .core = { - .h_blank = {0xbc, 0x02}, - .v2_blank = {0xee, 0x02}, - .v1_blank = {0x1e, 0x00}, - .v_line = {0xee, 0x02}, - .h_line = {0xbc, 0x07}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0xb6, 0x01}, - .h_sync_end = {0xde, 0x01}, - .v_sync_line_bef_2 = {0x0a, 0x00}, - .v_sync_line_bef_1 = {0x05, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0xbc, 0x07, /* h_fsz */ - 0xbc, 0x02, 0x00, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_720p60 = { - .core = { - .h_blank = {0x72, 0x01}, - .v2_blank = {0xee, 0x02}, - .v1_blank = {0x1e, 0x00}, - .v_line = {0xee, 0x02}, - .h_line = {0x72, 0x06}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x6c, 0x00}, - .h_sync_end = {0x94, 0x00}, - .v_sync_line_bef_2 = {0x0a, 0x00}, - .v_sync_line_bef_1 = {0x05, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x72, 0x06, /* h_fsz */ - 0x72, 0x01, 0x00, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080i50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v2_blank = {0x32, 0x02}, - .v1_blank = {0x16, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x50, 0x0a}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f0 = {0x49, 0x02}, - .v_blank_f1 = {0x65, 0x04}, - .h_sync_start = {0x0e, 0x02}, - .h_sync_end = {0x3a, 0x02}, - .v_sync_line_bef_2 = {0x07, 0x00}, - .v_sync_line_bef_1 = {0x02, 0x00}, - .v_sync_line_aft_2 = {0x39, 0x02}, - .v_sync_line_aft_1 = {0x34, 0x02}, - .v_sync_line_aft_pxl_2 = {0x38, 0x07}, - .v_sync_line_aft_pxl_1 = {0x38, 0x07}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0a, /* h_fsz */ - 0xd0, 0x02, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080i60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v2_blank = {0x32, 0x02}, - .v1_blank = {0x16, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x98, 0x08}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f0 = {0x49, 0x02}, - .v_blank_f1 = {0x65, 0x04}, - .h_sync_start = {0x56, 0x00}, - .h_sync_end = {0x82, 0x00}, - .v_sync_line_bef_2 = {0x07, 0x00}, - .v_sync_line_bef_1 = {0x02, 0x00}, - .v_sync_line_aft_2 = {0x39, 0x02}, - .v_sync_line_aft_1 = {0x34, 0x02}, - .v_sync_line_aft_pxl_2 = {0xa4, 0x04}, - .v_sync_line_aft_pxl_1 = {0xa4, 0x04}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x18, 0x01, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080p30 = { - .core = { - .h_blank = {0x18, 0x01}, - .v2_blank = {0x65, 0x04}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x98, 0x08}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x56, 0x00}, - .h_sync_end = {0x82, 0x00}, - .v_sync_line_bef_2 = {0x09, 0x00}, - .v_sync_line_bef_1 = {0x04, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x18, 0x01, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080p50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v2_blank = {0x65, 0x04}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x50, 0x0a}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x0e, 0x02}, - .h_sync_end = {0x3a, 0x02}, - .v_sync_line_bef_2 = {0x09, 0x00}, - .v_sync_line_bef_1 = {0x04, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0a, /* h_fsz */ - 0xd0, 0x02, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080p60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v2_blank = {0x65, 0x04}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x98, 0x08}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x56, 0x00}, - .h_sync_end = {0x82, 0x00}, - .v_sync_line_bef_2 = {0x09, 0x00}, - .v_sync_line_bef_1 = {0x04, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x18, 0x01, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_conf hdmi_confs[] = { - { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 }, - { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 }, - { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, - { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, - { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, - { 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 }, -}; - - -static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) -{ - return readl(hdata->regs + reg_id); -} - -static inline void hdmi_reg_writeb(struct hdmi_context *hdata, - u32 reg_id, u8 value) -{ - writeb(value, hdata->regs + reg_id); -} - -static inline void hdmi_reg_writemask(struct hdmi_context *hdata, - u32 reg_id, u32 value, u32 mask) -{ - u32 old = readl(hdata->regs + reg_id); - value = (value & mask) | (old & ~mask); - writel(value, hdata->regs + reg_id); -} - -static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) -{ -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_V13_PHY_RSTOUT); - DUMPREG(HDMI_V13_PHY_VPLL); - DUMPREG(HDMI_V13_PHY_CMU); - DUMPREG(HDMI_V13_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_V13_PHY_STATUS); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_V13_HPD_GEN); - DUMPREG(HDMI_V13_DC_CONTROL); - DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_0); - DUMPREG(HDMI_V13_V_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_2); - DUMPREG(HDMI_V13_H_V_LINE_0); - DUMPREG(HDMI_V13_H_V_LINE_1); - DUMPREG(HDMI_V13_H_V_LINE_2); - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V13_V_BLANK_F_0); - DUMPREG(HDMI_V13_V_BLANK_F_1); - DUMPREG(HDMI_V13_V_BLANK_F_2); - DUMPREG(HDMI_V13_H_SYNC_GEN_0); - DUMPREG(HDMI_V13_H_SYNC_GEN_1); - DUMPREG(HDMI_V13_H_SYNC_GEN_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); -#undef DUMPREG -} - -static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - int i; - -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_INTC_CON_1); - DUMPREG(HDMI_INTC_FLAG_1); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_PHY_STATUS_PLL); - DUMPREG(HDMI_PHY_CON_0); - DUMPREG(HDMI_PHY_RSTOUT); - DUMPREG(HDMI_PHY_VPLL); - DUMPREG(HDMI_PHY_CMU); - DUMPREG(HDMI_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_ENC_EN); - DUMPREG(HDMI_DC_CONTROL); - DUMPREG(HDMI_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V2_BLANK_0); - DUMPREG(HDMI_V2_BLANK_1); - DUMPREG(HDMI_V1_BLANK_0); - DUMPREG(HDMI_V1_BLANK_1); - DUMPREG(HDMI_V_LINE_0); - DUMPREG(HDMI_V_LINE_1); - DUMPREG(HDMI_H_LINE_0); - DUMPREG(HDMI_H_LINE_1); - DUMPREG(HDMI_HSYNC_POL); - - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V_BLANK_F0_0); - DUMPREG(HDMI_V_BLANK_F0_1); - DUMPREG(HDMI_V_BLANK_F1_0); - DUMPREG(HDMI_V_BLANK_F1_1); - - DUMPREG(HDMI_H_SYNC_START_0); - DUMPREG(HDMI_H_SYNC_START_1); - DUMPREG(HDMI_H_SYNC_END_0); - DUMPREG(HDMI_H_SYNC_END_1); - - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); - - DUMPREG(HDMI_V_BLANK_F2_0); - DUMPREG(HDMI_V_BLANK_F2_1); - DUMPREG(HDMI_V_BLANK_F3_0); - DUMPREG(HDMI_V_BLANK_F3_1); - DUMPREG(HDMI_V_BLANK_F4_0); - DUMPREG(HDMI_V_BLANK_F4_1); - DUMPREG(HDMI_V_BLANK_F5_0); - DUMPREG(HDMI_V_BLANK_F5_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); - - DUMPREG(HDMI_VACT_SPACE_1_0); - DUMPREG(HDMI_VACT_SPACE_1_1); - DUMPREG(HDMI_VACT_SPACE_2_0); - DUMPREG(HDMI_VACT_SPACE_2_1); - DUMPREG(HDMI_VACT_SPACE_3_0); - DUMPREG(HDMI_VACT_SPACE_3_1); - DUMPREG(HDMI_VACT_SPACE_4_0); - DUMPREG(HDMI_VACT_SPACE_4_1); - DUMPREG(HDMI_VACT_SPACE_5_0); - DUMPREG(HDMI_VACT_SPACE_5_1); - DUMPREG(HDMI_VACT_SPACE_6_0); - DUMPREG(HDMI_VACT_SPACE_6_1); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VACT_ST3_L); - DUMPREG(HDMI_TG_VACT_ST3_H); - DUMPREG(HDMI_TG_VACT_ST4_L); - DUMPREG(HDMI_TG_VACT_ST4_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); - DUMPREG(HDMI_TG_3D); - - DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); - DUMPREG(HDMI_AVI_CON); - DUMPREG(HDMI_AVI_HEADER0); - DUMPREG(HDMI_AVI_HEADER1); - DUMPREG(HDMI_AVI_HEADER2); - DUMPREG(HDMI_AVI_CHECK_SUM); - DUMPREG(HDMI_VSI_CON); - DUMPREG(HDMI_VSI_HEADER0); - DUMPREG(HDMI_VSI_HEADER1); - DUMPREG(HDMI_VSI_HEADER2); - for (i = 0; i < 7; ++i) - DUMPREG(HDMI_VSI_DATA(i)); - -#undef DUMPREG -} - -static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - if (hdata->is_v13) - hdmi_v13_regs_dump(hdata, prefix); - else - hdmi_v14_regs_dump(hdata, prefix); -} - -static int hdmi_v13_conf_index(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) - if (hdmi_v13_confs[i].width == mode->hdisplay && - hdmi_v13_confs[i].height == mode->vdisplay && - hdmi_v13_confs[i].vrefresh == mode->vrefresh && - hdmi_v13_confs[i].interlace == - ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? - true : false)) - return i; - - return -EINVAL; -} - -static int hdmi_v14_conf_index(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i) - if (hdmi_confs[i].width == mode->hdisplay && - hdmi_confs[i].height == mode->vdisplay && - hdmi_confs[i].vrefresh == mode->vrefresh && - hdmi_confs[i].interlace == - ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? - true : false)) - return i; - - return -EINVAL; -} - -static int hdmi_conf_index(struct hdmi_context *hdata, - struct drm_display_mode *mode) -{ - if (hdata->is_v13) - return hdmi_v13_conf_index(mode); - - return hdmi_v14_conf_index(mode); -} - -static bool hdmi_is_connected(void *ctx) -{ - struct hdmi_context *hdata = ctx; - - return hdata->hpd; -} - -static int hdmi_get_edid(void *ctx, struct drm_connector *connector, - u8 *edid, int len) -{ - struct edid *raw_edid; - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!hdata->ddc_port) - return -ENODEV; - - raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); - if (raw_edid) { - hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); - memcpy(edid, raw_edid, min((1 + raw_edid->extensions) - * EDID_LENGTH, len)); - DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", - (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), - raw_edid->width_cm, raw_edid->height_cm); - } else { - return -ENODEV; - } - - return 0; -} - -static int hdmi_v13_check_timing(struct fb_videomode *check_timing) -{ - int i; - - DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", - check_timing->xres, check_timing->yres, - check_timing->refresh, (check_timing->vmode & - FB_VMODE_INTERLACED) ? true : false); - - for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) - if (hdmi_v13_confs[i].width == check_timing->xres && - hdmi_v13_confs[i].height == check_timing->yres && - hdmi_v13_confs[i].vrefresh == check_timing->refresh && - hdmi_v13_confs[i].interlace == - ((check_timing->vmode & FB_VMODE_INTERLACED) ? - true : false)) - return 0; - - /* TODO */ - - return -EINVAL; -} - -static int hdmi_v14_check_timing(struct fb_videomode *check_timing) -{ - int i; - - DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", - check_timing->xres, check_timing->yres, - check_timing->refresh, (check_timing->vmode & - FB_VMODE_INTERLACED) ? true : false); - - for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++) - if (hdmi_confs[i].width == check_timing->xres && - hdmi_confs[i].height == check_timing->yres && - hdmi_confs[i].vrefresh == check_timing->refresh && - hdmi_confs[i].interlace == - ((check_timing->vmode & FB_VMODE_INTERLACED) ? - true : false)) - return 0; - - /* TODO */ - - return -EINVAL; -} - -static int hdmi_check_timing(void *ctx, void *timing) -{ - struct hdmi_context *hdata = ctx; - struct fb_videomode *check_timing = timing; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, - check_timing->yres, check_timing->refresh, - check_timing->vmode); - - if (hdata->is_v13) - return hdmi_v13_check_timing(check_timing); - else - return hdmi_v14_check_timing(check_timing); -} - -static void hdmi_set_acr(u32 freq, u8 *acr) -{ - u32 n, cts; - - switch (freq) { - case 32000: - n = 4096; - cts = 27000; - break; - case 44100: - n = 6272; - cts = 30000; - break; - case 88200: - n = 12544; - cts = 30000; - break; - case 176400: - n = 25088; - cts = 30000; - break; - case 48000: - n = 6144; - cts = 27000; - break; - case 96000: - n = 12288; - cts = 27000; - break; - case 192000: - n = 24576; - cts = 27000; - break; - default: - n = 0; - cts = 0; - break; - } - - acr[1] = cts >> 16; - acr[2] = cts >> 8 & 0xff; - acr[3] = cts & 0xff; - - acr[4] = n >> 16; - acr[5] = n >> 8 & 0xff; - acr[6] = n & 0xff; -} - -static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr) -{ - hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]); - hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]); - hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]); - - if (hdata->is_v13) - hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4); - else - hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); -} - -static void hdmi_audio_init(struct hdmi_context *hdata) -{ - u32 sample_rate, bits_per_sample, frame_size_code; - u32 data_num, bit_ch, sample_frq; - u32 val; - u8 acr[7]; - - sample_rate = 44100; - bits_per_sample = 16; - frame_size_code = 0; - - switch (bits_per_sample) { - case 20: - data_num = 2; - bit_ch = 1; - break; - case 24: - data_num = 3; - bit_ch = 1; - break; - default: - data_num = 1; - bit_ch = 0; - break; - } - - hdmi_set_acr(sample_rate, acr); - hdmi_reg_acr(hdata, acr); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE - | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE - | HDMI_I2S_MUX_ENABLE); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN - | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); - - sample_frq = (sample_rate == 44100) ? 0 : - (sample_rate == 48000) ? 2 : - (sample_rate == 32000) ? 3 : - (sample_rate == 96000) ? 0xa : 0x0; - - hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); - hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); - - val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01; - hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val); - - /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */ - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5) - | HDMI_I2S_SEL_LRCK(6)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1) - | HDMI_I2S_SEL_SDATA2(4)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1) - | HDMI_I2S_SEL_SDATA2(2)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0)); - - /* I2S_CON_1 & 2 */ - hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE - | HDMI_I2S_L_CH_LOW_POL); - hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE - | HDMI_I2S_SET_BIT_CH(bit_ch) - | HDMI_I2S_SET_SDATA_BIT(data_num) - | HDMI_I2S_BASIC_FORMAT); - - /* Configure register related to CUV information */ - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 - | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH - | HDMI_I2S_COPYRIGHT - | HDMI_I2S_LINEAR_PCM - | HDMI_I2S_CONSUMER_FORMAT); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2 - | HDMI_I2S_SET_SMP_FREQ(sample_frq)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4, - HDMI_I2S_ORG_SMP_FREQ_44_1 - | HDMI_I2S_WORD_LEN_MAX24_24BITS - | HDMI_I2S_WORD_LEN_MAX_24BITS); - - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); -} - -static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) -{ - if (hdata->dvi_mode) - return; - - hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); - hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? - HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); -} - -static void hdmi_conf_reset(struct hdmi_context *hdata) -{ - u32 reg; - - if (hdata->is_v13) - reg = HDMI_V13_CORE_RSTOUT; - else - reg = HDMI_CORE_RSTOUT; - - /* resetting HDMI core */ - hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); - mdelay(10); - hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); - mdelay(10); -} - -static void hdmi_conf_init(struct hdmi_context *hdata) -{ - /* enable HPD interrupts */ - hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | - HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); - mdelay(10); - hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL | - HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); - - /* choose HDMI mode */ - hdmi_reg_writemask(hdata, HDMI_MODE_SEL, - HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); - /* disable bluescreen */ - hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); - - if (hdata->dvi_mode) { - /* choose DVI mode */ - hdmi_reg_writemask(hdata, HDMI_MODE_SEL, - HDMI_MODE_DVI_EN, HDMI_MODE_MASK); - hdmi_reg_writeb(hdata, HDMI_CON_2, - HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS); - } - - if (hdata->is_v13) { - /* choose bluescreen (fecal) color */ - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12); - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34); - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56); - - /* enable AVI packet every vsync, fixes purple line problem */ - hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02); - /* force RGB, look to CEA-861-D, table 7 for more detail */ - hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5); - hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); - - hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); - } else { - /* enable AVI packet every vsync, fixes purple line problem */ - hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5); - hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); - } -} - -static void hdmi_v13_timing_apply(struct hdmi_context *hdata) -{ - const struct hdmi_v13_preset_conf *conf = - hdmi_v13_confs[hdata->cur_conf].conf; - const struct hdmi_v13_core_regs *core = &conf->core; - const struct hdmi_v13_tg_regs *tg = &conf->tg; - int tries; - - /* setting core registers */ - hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); - hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]); - hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); - /* Timing generator registers */ - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); - - /* waiting for HDMIPHY's PLL to get to steady state */ - for (tries = 100; tries; --tries) { - u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS); - if (val & HDMI_PHY_STATUS_READY) - break; - mdelay(1); - } - /* steady state not achieved */ - if (tries == 0) { - DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); - hdmi_regs_dump(hdata, "timing apply"); - } - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); - clk_enable(hdata->res.sclk_hdmi); - - /* enable HDMI and timing generator */ - hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); - if (core->int_pro_mode[0]) - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | - HDMI_FIELD_EN); - else - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); -} - -static void hdmi_v14_timing_apply(struct hdmi_context *hdata) -{ - const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf; - const struct hdmi_core_regs *core = &conf->core; - const struct hdmi_tg_regs *tg = &conf->tg; - int tries; - - /* setting core registers */ - hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); - hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]); - hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]); - hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]); - hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]); - hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0, - core->v_sync_line_bef_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1, - core->v_sync_line_bef_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0, - core->v_sync_line_bef_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1, - core->v_sync_line_bef_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0, - core->v_sync_line_aft_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1, - core->v_sync_line_aft_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0, - core->v_sync_line_aft_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1, - core->v_sync_line_aft_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, - core->v_sync_line_aft_pxl_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1, - core->v_sync_line_aft_pxl_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, - core->v_sync_line_aft_pxl_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1, - core->v_sync_line_aft_pxl_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0, - core->v_sync_line_aft_3[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1, - core->v_sync_line_aft_3[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0, - core->v_sync_line_aft_4[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1, - core->v_sync_line_aft_4[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0, - core->v_sync_line_aft_5[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1, - core->v_sync_line_aft_5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0, - core->v_sync_line_aft_6[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1, - core->v_sync_line_aft_6[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, - core->v_sync_line_aft_pxl_3[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1, - core->v_sync_line_aft_pxl_3[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, - core->v_sync_line_aft_pxl_4[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1, - core->v_sync_line_aft_pxl_4[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, - core->v_sync_line_aft_pxl_5[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1, - core->v_sync_line_aft_pxl_5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, - core->v_sync_line_aft_pxl_6[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1, - core->v_sync_line_aft_pxl_6[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]); - - /* Timing generator registers */ - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d); - - /* waiting for HDMIPHY's PLL to get to steady state */ - for (tries = 100; tries; --tries) { - u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0); - if (val & HDMI_PHY_STATUS_READY) - break; - mdelay(1); - } - /* steady state not achieved */ - if (tries == 0) { - DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); - hdmi_regs_dump(hdata, "timing apply"); - } - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); - clk_enable(hdata->res.sclk_hdmi); - - /* enable HDMI and timing generator */ - hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); - if (core->int_pro_mode[0]) - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | - HDMI_FIELD_EN); - else - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); -} - -static void hdmi_timing_apply(struct hdmi_context *hdata) -{ - if (hdata->is_v13) - hdmi_v13_timing_apply(hdata); - else - hdmi_v14_timing_apply(hdata); -} - -static void hdmiphy_conf_reset(struct hdmi_context *hdata) -{ - u8 buffer[2]; - u32 reg; - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); - clk_enable(hdata->res.sclk_hdmi); - - /* operation mode */ - buffer[0] = 0x1f; - buffer[1] = 0x00; - - if (hdata->hdmiphy_port) - i2c_master_send(hdata->hdmiphy_port, buffer, 2); - - if (hdata->is_v13) - reg = HDMI_V13_PHY_RSTOUT; - else - reg = HDMI_PHY_RSTOUT; - - /* reset hdmiphy */ - hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); - mdelay(10); - hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT); - mdelay(10); -} - -static void hdmiphy_conf_apply(struct hdmi_context *hdata) -{ - const u8 *hdmiphy_data; - u8 buffer[32]; - u8 operation[2]; - u8 read_buffer[32] = {0, }; - int ret; - int i; - - if (!hdata->hdmiphy_port) { - DRM_ERROR("hdmiphy is not attached\n"); - return; - } - - /* pixel clock */ - if (hdata->is_v13) - hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; - else - hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; - - memcpy(buffer, hdmiphy_data, 32); - ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); - if (ret != 32) { - DRM_ERROR("failed to configure HDMIPHY via I2C\n"); - return; - } - - mdelay(10); - - /* operation mode */ - operation[0] = 0x1f; - operation[1] = 0x80; - - ret = i2c_master_send(hdata->hdmiphy_port, operation, 2); - if (ret != 2) { - DRM_ERROR("failed to enable hdmiphy\n"); - return; - } - - ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32); - if (ret < 0) { - DRM_ERROR("failed to read hdmiphy config\n"); - return; - } - - for (i = 0; i < ret; i++) - DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - " - "recv [0x%02x]\n", i, buffer[i], read_buffer[i]); -} - -static void hdmi_conf_apply(struct hdmi_context *hdata) -{ - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - hdmiphy_conf_reset(hdata); - hdmiphy_conf_apply(hdata); - - mutex_lock(&hdata->hdmi_mutex); - hdmi_conf_reset(hdata); - hdmi_conf_init(hdata); - mutex_unlock(&hdata->hdmi_mutex); - - hdmi_audio_init(hdata); - - /* setting core registers */ - hdmi_timing_apply(hdata); - hdmi_audio_control(hdata, true); - - hdmi_regs_dump(hdata, "start"); -} - -static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_display_mode *m; - struct hdmi_context *hdata = ctx; - int index; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - drm_mode_set_crtcinfo(adjusted_mode, 0); - - if (hdata->is_v13) - index = hdmi_v13_conf_index(adjusted_mode); - else - index = hdmi_v14_conf_index(adjusted_mode); - - /* just return if user desired mode exists. */ - if (index >= 0) - return; - - /* - * otherwise, find the most suitable mode among modes and change it - * to adjusted_mode. - */ - list_for_each_entry(m, &connector->modes, head) { - if (hdata->is_v13) - index = hdmi_v13_conf_index(m); - else - index = hdmi_v14_conf_index(m); - - if (index >= 0) { - DRM_INFO("desired mode doesn't exist so\n"); - DRM_INFO("use the most suitable mode among modes.\n"); - memcpy(adjusted_mode, m, sizeof(*m)); - break; - } - } -} - -static void hdmi_mode_set(void *ctx, void *mode) -{ - struct hdmi_context *hdata = ctx; - int conf_idx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - conf_idx = hdmi_conf_index(hdata, mode); - if (conf_idx >= 0) - hdata->cur_conf = conf_idx; - else - DRM_DEBUG_KMS("not supported mode\n"); -} - -static void hdmi_get_max_resol(void *ctx, unsigned int *width, - unsigned int *height) -{ - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - *width = MAX_WIDTH; - *height = MAX_HEIGHT; -} - -static void hdmi_commit(void *ctx) -{ - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - hdmi_conf_apply(hdata); -} - -static void hdmi_poweron(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mutex_lock(&hdata->hdmi_mutex); - if (hdata->powered) { - mutex_unlock(&hdata->hdmi_mutex); - return; - } - - hdata->powered = true; - - if (hdata->cfg_hpd) - hdata->cfg_hpd(true); - mutex_unlock(&hdata->hdmi_mutex); - - pm_runtime_get_sync(hdata->dev); - - regulator_bulk_enable(res->regul_count, res->regul_bulk); - clk_enable(res->hdmiphy); - clk_enable(res->hdmi); - clk_enable(res->sclk_hdmi); -} - -static void hdmi_poweroff(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mutex_lock(&hdata->hdmi_mutex); - if (!hdata->powered) - goto out; - mutex_unlock(&hdata->hdmi_mutex); - - /* - * The TV power domain needs any condition of hdmiphy to turn off and - * its reset state seems to meet the condition. - */ - hdmiphy_conf_reset(hdata); - - clk_disable(res->sclk_hdmi); - clk_disable(res->hdmi); - clk_disable(res->hdmiphy); - regulator_bulk_disable(res->regul_count, res->regul_bulk); - - pm_runtime_put_sync(hdata->dev); - - mutex_lock(&hdata->hdmi_mutex); - if (hdata->cfg_hpd) - hdata->cfg_hpd(false); - - hdata->powered = false; - -out: - mutex_unlock(&hdata->hdmi_mutex); -} - -static void hdmi_dpms(void *ctx, int mode) -{ - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - switch (mode) { - case DRM_MODE_DPMS_ON: - hdmi_poweron(hdata); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - hdmi_poweroff(hdata); - break; - default: - DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); - break; - } -} - -static struct exynos_hdmi_ops hdmi_ops = { - /* display */ - .is_connected = hdmi_is_connected, - .get_edid = hdmi_get_edid, - .check_timing = hdmi_check_timing, - - /* manager */ - .mode_fixup = hdmi_mode_fixup, - .mode_set = hdmi_mode_set, - .get_max_resol = hdmi_get_max_resol, - .commit = hdmi_commit, - .dpms = hdmi_dpms, -}; - -static irqreturn_t hdmi_external_irq_thread(int irq, void *arg) -{ - struct exynos_drm_hdmi_context *ctx = arg; - struct hdmi_context *hdata = ctx->ctx; - - if (!hdata->get_hpd) - goto out; - - mutex_lock(&hdata->hdmi_mutex); - hdata->hpd = hdata->get_hpd(); - mutex_unlock(&hdata->hdmi_mutex); - - if (ctx->drm_dev) - drm_helper_hpd_irq_event(ctx->drm_dev); - -out: - return IRQ_HANDLED; -} - -static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg) -{ - struct exynos_drm_hdmi_context *ctx = arg; - struct hdmi_context *hdata = ctx->ctx; - u32 intc_flag; - - intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); - /* clearing flags for HPD plug/unplug */ - if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) { - DRM_DEBUG_KMS("unplugged\n"); - hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, - HDMI_INTC_FLAG_HPD_UNPLUG); - } - if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) { - DRM_DEBUG_KMS("plugged\n"); - hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, - HDMI_INTC_FLAG_HPD_PLUG); - } - - mutex_lock(&hdata->hdmi_mutex); - hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS); - if (hdata->powered && hdata->hpd) { - mutex_unlock(&hdata->hdmi_mutex); - goto out; - } - mutex_unlock(&hdata->hdmi_mutex); - - if (ctx->drm_dev) - drm_helper_hpd_irq_event(ctx->drm_dev); - -out: - return IRQ_HANDLED; -} - -static int __devinit hdmi_resources_init(struct hdmi_context *hdata) -{ - struct device *dev = hdata->dev; - struct hdmi_resources *res = &hdata->res; - static char *supply[] = { - /* FIXME: control HDMI_EN gpio using fixed regulator */ - /* "hdmi-en", */ - "vdd", - "vdd_osc", - "vdd_pll", - }; - int i, ret; - - DRM_DEBUG_KMS("HDMI resource init\n"); - - memset(res, 0, sizeof *res); - - /* get clocks, power */ - res->hdmi = clk_get(dev, "hdmi"); - if (IS_ERR_OR_NULL(res->hdmi)) { - DRM_ERROR("failed to get clock 'hdmi'\n"); - goto fail; - } - res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); - if (IS_ERR_OR_NULL(res->sclk_hdmi)) { - DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); - goto fail; - } - res->sclk_pixel = clk_get(dev, "sclk_pixel"); - if (IS_ERR_OR_NULL(res->sclk_pixel)) { - DRM_ERROR("failed to get clock 'sclk_pixel'\n"); - goto fail; - } - res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy"); - if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) { - DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); - goto fail; - } - res->hdmiphy = clk_get(dev, "hdmiphy"); - if (IS_ERR_OR_NULL(res->hdmiphy)) { - DRM_ERROR("failed to get clock 'hdmiphy'\n"); - goto fail; - } - - clk_set_parent(res->sclk_hdmi, res->sclk_pixel); - - res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * - sizeof res->regul_bulk[0], GFP_KERNEL); - if (!res->regul_bulk) { - DRM_ERROR("failed to get memory for regulators\n"); - goto fail; - } - for (i = 0; i < ARRAY_SIZE(supply); ++i) { - res->regul_bulk[i].supply = supply[i]; - res->regul_bulk[i].consumer = NULL; - } - ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk); - if (ret) { - DRM_ERROR("failed to get regulators\n"); - goto fail; - } - res->regul_count = ARRAY_SIZE(supply); - - return 0; -fail: - DRM_ERROR("HDMI resource init - failed\n"); - return -ENODEV; -} - -static int hdmi_resources_cleanup(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - regulator_bulk_free(res->regul_count, res->regul_bulk); - /* kfree is NULL-safe */ - kfree(res->regul_bulk); - if (!IS_ERR_OR_NULL(res->hdmiphy)) - clk_put(res->hdmiphy); - if (!IS_ERR_OR_NULL(res->sclk_hdmiphy)) - clk_put(res->sclk_hdmiphy); - if (!IS_ERR_OR_NULL(res->sclk_pixel)) - clk_put(res->sclk_pixel); - if (!IS_ERR_OR_NULL(res->sclk_hdmi)) - clk_put(res->sclk_hdmi); - if (!IS_ERR_OR_NULL(res->hdmi)) - clk_put(res->hdmi); - memset(res, 0, sizeof *res); - - return 0; -} - -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy; - -void hdmi_attach_ddc_client(struct i2c_client *ddc) -{ - if (ddc) - hdmi_ddc = ddc; -} - -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) -{ - if (hdmiphy) - hdmi_hdmiphy = hdmiphy; -} - -static int __devinit hdmi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx; - struct hdmi_context *hdata; - struct exynos_drm_hdmi_pdata *pdata; - struct resource *res; - int ret; - - DRM_DEBUG_KMS("[%d]\n", __LINE__); - - pdata = pdev->dev.platform_data; - if (!pdata) { - DRM_ERROR("no platform data specified\n"); - return -EINVAL; - } - - drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL); - if (!drm_hdmi_ctx) { - DRM_ERROR("failed to allocate common hdmi context.\n"); - return -ENOMEM; - } - - hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL); - if (!hdata) { - DRM_ERROR("out of memory\n"); - kfree(drm_hdmi_ctx); - return -ENOMEM; - } - - mutex_init(&hdata->hdmi_mutex); - - drm_hdmi_ctx->ctx = (void *)hdata; - hdata->parent_ctx = (void *)drm_hdmi_ctx; - - platform_set_drvdata(pdev, drm_hdmi_ctx); - - hdata->is_v13 = pdata->is_v13; - hdata->cfg_hpd = pdata->cfg_hpd; - hdata->get_hpd = pdata->get_hpd; - hdata->dev = dev; - - ret = hdmi_resources_init(hdata); - if (ret) { - ret = -EINVAL; - goto err_data; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - DRM_ERROR("failed to find registers\n"); - ret = -ENOENT; - goto err_resource; - } - - hdata->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!hdata->regs_res) { - DRM_ERROR("failed to claim register region\n"); - ret = -ENOENT; - goto err_resource; - } - - hdata->regs = ioremap(res->start, resource_size(res)); - if (!hdata->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -ENXIO; - goto err_req_region; - } - - /* DDC i2c driver */ - if (i2c_add_driver(&ddc_driver)) { - DRM_ERROR("failed to register ddc i2c driver\n"); - ret = -ENOENT; - goto err_iomap; - } - - hdata->ddc_port = hdmi_ddc; - - /* hdmiphy i2c driver */ - if (i2c_add_driver(&hdmiphy_driver)) { - DRM_ERROR("failed to register hdmiphy i2c driver\n"); - ret = -ENOENT; - goto err_ddc; - } - - hdata->hdmiphy_port = hdmi_hdmiphy; - - hdata->external_irq = platform_get_irq_byname(pdev, "external_irq"); - if (hdata->external_irq < 0) { - DRM_ERROR("failed to get platform irq\n"); - ret = hdata->external_irq; - goto err_hdmiphy; - } - - hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq"); - if (hdata->internal_irq < 0) { - DRM_ERROR("failed to get platform internal irq\n"); - ret = hdata->internal_irq; - goto err_hdmiphy; - } - - ret = request_threaded_irq(hdata->external_irq, NULL, - hdmi_external_irq_thread, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "hdmi_external", drm_hdmi_ctx); - if (ret) { - DRM_ERROR("failed to register hdmi internal interrupt\n"); - goto err_hdmiphy; - } - - if (hdata->cfg_hpd) - hdata->cfg_hpd(false); - - ret = request_threaded_irq(hdata->internal_irq, NULL, - hdmi_internal_irq_thread, IRQF_ONESHOT, - "hdmi_internal", drm_hdmi_ctx); - if (ret) { - DRM_ERROR("failed to register hdmi internal interrupt\n"); - goto err_free_irq; - } - - /* register specific callbacks to common hdmi. */ - exynos_hdmi_ops_register(&hdmi_ops); - - pm_runtime_enable(dev); - - return 0; - -err_free_irq: - free_irq(hdata->external_irq, drm_hdmi_ctx); -err_hdmiphy: - i2c_del_driver(&hdmiphy_driver); -err_ddc: - i2c_del_driver(&ddc_driver); -err_iomap: - iounmap(hdata->regs); -err_req_region: - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); -err_resource: - hdmi_resources_cleanup(hdata); -err_data: - kfree(hdata); - kfree(drm_hdmi_ctx); - return ret; -} - -static int __devexit hdmi_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); - struct hdmi_context *hdata = ctx->ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - pm_runtime_disable(dev); - - free_irq(hdata->internal_irq, hdata); - - hdmi_resources_cleanup(hdata); - - iounmap(hdata->regs); - - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); - - /* hdmiphy i2c driver */ - i2c_del_driver(&hdmiphy_driver); - /* DDC i2c driver */ - i2c_del_driver(&ddc_driver); - - kfree(hdata); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int hdmi_suspend(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); - struct hdmi_context *hdata = ctx->ctx; - - disable_irq(hdata->internal_irq); - disable_irq(hdata->external_irq); - - hdata->hpd = false; - if (ctx->drm_dev) - drm_helper_hpd_irq_event(ctx->drm_dev); - - hdmi_poweroff(hdata); - - return 0; -} - -static int hdmi_resume(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); - struct hdmi_context *hdata = ctx->ctx; - - enable_irq(hdata->external_irq); - enable_irq(hdata->internal_irq); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume); - -struct platform_driver hdmi_driver = { - .probe = hdmi_probe, - .remove = __devexit_p(hdmi_remove), - .driver = { - .name = "exynos4-hdmi", - .owner = THIS_MODULE, - .pm = &hdmi_pm_ops, - }, -}; diff --git a/drivers/gpu/drm/exynos_tmp/exynos_hdmi.h b/drivers/gpu/drm/exynos_tmp/exynos_hdmi.h deleted file mode 100644 index 1c3b6d8..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_hdmi.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae <inki.dae@samsung.com> - * Seung-Woo Kim <sw0312.kim@samsung.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_HDMI_H_ -#define _EXYNOS_HDMI_H_ - -void hdmi_attach_ddc_client(struct i2c_client *ddc); -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy); - -extern struct i2c_driver hdmiphy_driver; -extern struct i2c_driver ddc_driver; - -#endif diff --git a/drivers/gpu/drm/exynos_tmp/exynos_hdmiphy.c b/drivers/gpu/drm/exynos_tmp/exynos_hdmiphy.c deleted file mode 100644 index 9fe2995..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_hdmiphy.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim <sw0312.kim@samsung.com> - * Inki Dae <inki.dae@samsung.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. - * - */ - -#include "drmP.h" - -#include <linux/kernel.h> -#include <linux/i2c.h> -#include <linux/module.h> - -#include "exynos_drm_drv.h" -#include "exynos_hdmi.h" - - -static int hdmiphy_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - hdmi_attach_hdmiphy_client(client); - - dev_info(&client->adapter->dev, "attached s5p_hdmiphy " - "into i2c adapter successfully\n"); - - return 0; -} - -static int hdmiphy_remove(struct i2c_client *client) -{ - dev_info(&client->adapter->dev, "detached s5p_hdmiphy " - "from i2c adapter successfully\n"); - - return 0; -} - -static const struct i2c_device_id hdmiphy_id[] = { - { "s5p_hdmiphy", 0 }, - { }, -}; - -struct i2c_driver hdmiphy_driver = { - .driver = { - .name = "s5p-hdmiphy", - .owner = THIS_MODULE, - }, - .id_table = hdmiphy_id, - .probe = hdmiphy_probe, - .remove = __devexit_p(hdmiphy_remove), - .command = NULL, -}; -EXPORT_SYMBOL(hdmiphy_driver); diff --git a/drivers/gpu/drm/exynos_tmp/exynos_mixer.c b/drivers/gpu/drm/exynos_tmp/exynos_mixer.c deleted file mode 100644 index 68ef010..0000000 --- a/drivers/gpu/drm/exynos_tmp/exynos_mixer.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim <sw0312.kim@samsung.com> - * Inki Dae <inki.dae@samsung.com> - * Joonyoung Shim <jy0922.shim@samsung.com> - * - * Based on drivers/media/video/s5p-tv/mixer_reg.c - * - * 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. - * - */ - -#include "drmP.h" - -#include "regs-mixer.h" -#include "regs-vp.h" - -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/wait.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/pm_runtime.h> -#include <linux/clk.h> -#include <linux/regulator/consumer.h> - -#include <drm/exynos_drm.h> - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct hdmi_win_data { - dma_addr_t dma_addr; - void __iomem *vaddr; - dma_addr_t chroma_dma_addr; - void __iomem *chroma_vaddr; - uint32_t pixel_format; - unsigned int bpp; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_width; - unsigned int crtc_height; - unsigned int fb_x; - unsigned int fb_y; - unsigned int fb_width; - unsigned int fb_height; - unsigned int src_width; - unsigned int src_height; - unsigned int mode_width; - unsigned int mode_height; - unsigned int scan_flags; -}; - -struct mixer_resources { - int irq; - void __iomem *mixer_regs; - void __iomem *vp_regs; - spinlock_t reg_slock; - struct clk *mixer; - struct clk *vp; - struct clk *sclk_mixer; - struct clk *sclk_hdmi; - struct clk *sclk_dac; -}; - -struct mixer_context { - struct device *dev; - int pipe; - bool interlace; - bool powered; - u32 int_en; - - struct mutex mixer_mutex; - struct mixer_resources mixer_res; - struct hdmi_win_data win_data[MIXER_WIN_NR]; -}; - -static const u8 filter_y_horiz_tap8[] = { - 0, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 0, 0, 0, - 0, 2, 4, 5, 6, 6, 6, 6, - 6, 5, 5, 4, 3, 2, 1, 1, - 0, -6, -12, -16, -18, -20, -21, -20, - -20, -18, -16, -13, -10, -8, -5, -2, - 127, 126, 125, 121, 114, 107, 99, 89, - 79, 68, 57, 46, 35, 25, 16, 8, -}; - -static const u8 filter_y_vert_tap4[] = { - 0, -3, -6, -8, -8, -8, -8, -7, - -6, -5, -4, -3, -2, -1, -1, 0, - 127, 126, 124, 118, 111, 102, 92, 81, - 70, 59, 48, 37, 27, 19, 11, 5, - 0, 5, 11, 19, 27, 37, 48, 59, - 70, 81, 92, 102, 111, 118, 124, 126, - 0, 0, -1, -1, -2, -3, -4, -5, - -6, -7, -8, -8, -8, -8, -6, -3, -}; - -static const u8 filter_cr_horiz_tap4[] = { - 0, -3, -6, -8, -8, -8, -8, -7, - -6, -5, -4, -3, -2, -1, -1, 0, - 127, 126, 124, 118, 111, 102, 92, 81, - 70, 59, 48, 37, 27, 19, 11, 5, -}; - -static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) -{ - return readl(res->vp_regs + reg_id); -} - -static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id, - u32 val) -{ - writel(val, res->vp_regs + reg_id); -} - -static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id, - u32 val, u32 mask) -{ - u32 old = vp_reg_read(res, reg_id); - - val = (val & mask) | (old & ~mask); - writel(val, res->vp_regs + reg_id); -} - -static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id) -{ - return readl(res->mixer_regs + reg_id); -} - -static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id, - u32 val) -{ - writel(val, res->mixer_regs + reg_id); -} - -static inline void mixer_reg_writemask(struct mixer_resources *res, - u32 reg_id, u32 val, u32 mask) -{ - u32 old = mixer_reg_read(res, reg_id); - - val = (val & mask) | (old & ~mask); - writel(val, res->mixer_regs + reg_id); -} - -static void mixer_regs_dump(struct mixer_context *ctx) -{ -#define DUMPREG(reg_id) \ -do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \ -} while (0) - - DUMPREG(MXR_STATUS); - DUMPREG(MXR_CFG); - DUMPREG(MXR_INT_EN); - DUMPREG(MXR_INT_STATUS); - - DUMPREG(MXR_LAYER_CFG); - DUMPREG(MXR_VIDEO_CFG); - - DUMPREG(MXR_GRAPHIC0_CFG); - DUMPREG(MXR_GRAPHIC0_BASE); - DUMPREG(MXR_GRAPHIC0_SPAN); - DUMPREG(MXR_GRAPHIC0_WH); - DUMPREG(MXR_GRAPHIC0_SXY); - DUMPREG(MXR_GRAPHIC0_DXY); - - DUMPREG(MXR_GRAPHIC1_CFG); - DUMPREG(MXR_GRAPHIC1_BASE); - DUMPREG(MXR_GRAPHIC1_SPAN); - DUMPREG(MXR_GRAPHIC1_WH); - DUMPREG(MXR_GRAPHIC1_SXY); - DUMPREG(MXR_GRAPHIC1_DXY); -#undef DUMPREG -} - -static void vp_regs_dump(struct mixer_context *ctx) -{ -#define DUMPREG(reg_id) \ -do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \ -} while (0) - - DUMPREG(VP_ENABLE); - DUMPREG(VP_SRESET); - DUMPREG(VP_SHADOW_UPDATE); - DUMPREG(VP_FIELD_ID); - DUMPREG(VP_MODE); - DUMPREG(VP_IMG_SIZE_Y); - DUMPREG(VP_IMG_SIZE_C); - DUMPREG(VP_PER_RATE_CTRL); - DUMPREG(VP_TOP_Y_PTR); - DUMPREG(VP_BOT_Y_PTR); - DUMPREG(VP_TOP_C_PTR); - DUMPREG(VP_BOT_C_PTR); - DUMPREG(VP_ENDIAN_MODE); - DUMPREG(VP_SRC_H_POSITION); - DUMPREG(VP_SRC_V_POSITION); - DUMPREG(VP_SRC_WIDTH); - DUMPREG(VP_SRC_HEIGHT); - DUMPREG(VP_DST_H_POSITION); - DUMPREG(VP_DST_V_POSITION); - DUMPREG(VP_DST_WIDTH); - DUMPREG(VP_DST_HEIGHT); - DUMPREG(VP_H_RATIO); - DUMPREG(VP_V_RATIO); - -#undef DUMPREG -} - -static inline void vp_filter_set(struct mixer_resources *res, - int reg_id, const u8 *data, unsigned int size) -{ - /* assure 4-byte align */ - BUG_ON(size & 3); - for (; size; size -= 4, reg_id += 4, data += 4) { - u32 val = (data[0] << 24) | (data[1] << 16) | - (data[2] << 8) | data[3]; - vp_reg_write(res, reg_id, val); - } -} - -static void vp_default_filter(struct mixer_resources *res) -{ - vp_filter_set(res, VP_POLY8_Y0_LL, - filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); - vp_filter_set(res, VP_POLY4_Y0_LL, - filter_y_vert_tap4, sizeof filter_y_vert_tap4); - vp_filter_set(res, VP_POLY4_C0_LL, - filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); -} - -static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) -{ - struct mixer_resources *res = &ctx->mixer_res; - - /* block update on vsync */ - mixer_reg_writemask(res, MXR_STATUS, enable ? - MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); - - vp_reg_write(res, VP_SHADOW_UPDATE, enable ? - VP_SHADOW_UPDATE_ENABLE : 0); -} - -static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val; - - /* choosing between interlace and progressive mode */ - val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE : - MXR_CFG_SCAN_PROGRASSIVE); - - /* choosing between porper HD and SD mode */ - if (height == 480) - val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD; - else if (height == 576) - val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD; - else if (height == 720) - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - else if (height == 1080) - val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD; - else - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK); -} - -static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val; - - if (height == 480) { - val = MXR_CFG_RGB601_0_255; - } else if (height == 576) { - val = MXR_CFG_RGB601_0_255; - } else if (height == 720) { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } else if (height == 1080) { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } else { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } - - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); -} - -static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val = enable ? ~0 : 0; - - switch (win) { - case 0: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); - break; - case 1: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); - break; - case 2: - vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE); - break; - } -} - -static void mixer_run(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); - - mixer_regs_dump(ctx); -} - -static void vp_video_buffer(struct mixer_context *ctx, int win) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - struct hdmi_win_data *win_data; - unsigned int x_ratio, y_ratio; - unsigned int buf_num; - dma_addr_t luma_addr[2], chroma_addr[2]; - bool tiled_mode = false; - bool crcb_mode = false; - u32 val; - - win_data = &ctx->win_data[win]; - - switch (win_data->pixel_format) { - case DRM_FORMAT_NV12MT: - tiled_mode = true; - case DRM_FORMAT_NV12M: - crcb_mode = false; - buf_num = 2; - break; - /* TODO: single buffer format NV12, NV21 */ - default: - /* ignore pixel format at disable time */ - if (!win_data->dma_addr) - break; - - DRM_ERROR("pixel format for vp is wrong [%d].\n", - win_data->pixel_format); - return; - } - - /* scaling feature: (src << 16) / dst */ - x_ratio = (win_data->src_width << 16) / win_data->crtc_width; - y_ratio = (win_data->src_height << 16) / win_data->crtc_height; - - if (buf_num == 2) { - luma_addr[0] = win_data->dma_addr; - chroma_addr[0] = win_data->chroma_dma_addr; - } else { - luma_addr[0] = win_data->dma_addr; - chroma_addr[0] = win_data->dma_addr - + (win_data->fb_width * win_data->fb_height); - } - - if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { - ctx->interlace = true; - if (tiled_mode) { - luma_addr[1] = luma_addr[0] + 0x40; - chroma_addr[1] = chroma_addr[0] + 0x40; - } else { - luma_addr[1] = luma_addr[0] + win_data->fb_width; - chroma_addr[1] = chroma_addr[0] + win_data->fb_width; - } - } else { - ctx->interlace = false; - luma_addr[1] = 0; - chroma_addr[1] = 0; - } - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - /* interlace or progressive scan mode */ - val = (ctx->interlace ? ~0 : 0); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP); - - /* setup format */ - val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12); - val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); - - /* setting size of input image */ - vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) | - VP_IMG_VSIZE(win_data->fb_height)); - /* chroma height has to reduced by 2 to avoid chroma distorions */ - vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) | - VP_IMG_VSIZE(win_data->fb_height / 2)); - - vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width); - vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height); - vp_reg_write(res, VP_SRC_H_POSITION, - VP_SRC_H_POSITION_VAL(win_data->fb_x)); - vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y); - - vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width); - vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x); - if (ctx->interlace) { - vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2); - vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2); - } else { - vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height); - vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y); - } - - vp_reg_write(res, VP_H_RATIO, x_ratio); - vp_reg_write(res, VP_V_RATIO, y_ratio); - - vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); - - /* set buffer address to vp */ - vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]); - vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]); - vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); - vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); - - mixer_cfg_scan(ctx, win_data->mode_height); - mixer_cfg_rgb_fmt(ctx, win_data->mode_height); - mixer_cfg_layer(ctx, win, true); - mixer_run(ctx); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); - - vp_regs_dump(ctx); -} - -static void mixer_graph_buffer(struct mixer_context *ctx, int win) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - struct hdmi_win_data *win_data; - unsigned int x_ratio, y_ratio; - unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; - dma_addr_t dma_addr; - unsigned int fmt; - u32 val; - - win_data = &ctx->win_data[win]; - - #define RGB565 4 - #define ARGB1555 5 - #define ARGB4444 6 - #define ARGB8888 7 - - switch (win_data->bpp) { - case 16: - fmt = ARGB4444; - break; - case 32: - fmt = ARGB8888; - break; - default: - fmt = ARGB8888; - } - - /* 2x scaling feature */ - x_ratio = 0; - y_ratio = 0; - - dst_x_offset = win_data->crtc_x; - dst_y_offset = win_data->crtc_y; - - /* converting dma address base and source offset */ - dma_addr = win_data->dma_addr - + (win_data->fb_x * win_data->bpp >> 3) - + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3); - src_x_offset = 0; - src_y_offset = 0; - - if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) - ctx->interlace = true; - else - ctx->interlace = false; - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - /* setup format */ - mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), - MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); - - /* setup geometry */ - mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width); - - val = MXR_GRP_WH_WIDTH(win_data->crtc_width); - val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height); - val |= MXR_GRP_WH_H_SCALE(x_ratio); - val |= MXR_GRP_WH_V_SCALE(y_ratio); - mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); - - /* setup offsets in source image */ - val = MXR_GRP_SXY_SX(src_x_offset); - val |= MXR_GRP_SXY_SY(src_y_offset); - mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val); - - /* setup offsets in display image */ - val = MXR_GRP_DXY_DX(dst_x_offset); - val |= MXR_GRP_DXY_DY(dst_y_offset); - mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val); - - /* set buffer address to mixer */ - mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); - - mixer_cfg_scan(ctx, win_data->mode_height); - mixer_cfg_rgb_fmt(ctx, win_data->mode_height); - mixer_cfg_layer(ctx, win, true); - mixer_run(ctx); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static void vp_win_reset(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - int tries = 100; - - vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING); - for (tries = 100; tries; --tries) { - /* waiting until VP_SRESET_PROCESSING is 0 */ - if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) - break; - mdelay(10); - } - WARN(tries == 0, "failed to reset Video Processor\n"); -} - -static void mixer_win_reset(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - u32 val; /* value stored to register */ - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); - - /* set output in RGB888 mode */ - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); - - /* 16 beat burst in DMA */ - mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, - MXR_STATUS_BURST_MASK); - - /* setting default layer priority: layer1 > layer0 > video - * because typical usage scenario would be - * layer1 - OSD - * layer0 - framebuffer - * video - video overlay - */ - val = MXR_LAYER_CFG_GRP1_VAL(3); - val |= MXR_LAYER_CFG_GRP0_VAL(2); - val |= MXR_LAYER_CFG_VP_VAL(1); - mixer_reg_write(res, MXR_LAYER_CFG, val); - - /* setting background color */ - mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); - mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); - mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); - - /* setting graphical layers */ - - val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ - val |= MXR_GRP_CFG_WIN_BLEND_EN; - val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ - - /* the same configuration for both layers */ - mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); - - val |= MXR_GRP_CFG_BLEND_PRE_MUL; - val |= MXR_GRP_CFG_PIXEL_BLEND_EN; - mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); - - /* configuration of Video Processor Registers */ - vp_win_reset(ctx); - vp_default_filter(res); - - /* disable all layers */ - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static void mixer_poweron(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mutex_lock(&ctx->mixer_mutex); - if (ctx->powered) { - mutex_unlock(&ctx->mixer_mutex); - return; - } - ctx->powered = true; - mutex_unlock(&ctx->mixer_mutex); - - pm_runtime_get_sync(ctx->dev); - - clk_enable(res->mixer); - clk_enable(res->vp); - clk_enable(res->sclk_mixer); - - mixer_reg_write(res, MXR_INT_EN, ctx->int_en); - mixer_win_reset(ctx); -} - -static void mixer_poweroff(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mutex_lock(&ctx->mixer_mutex); - if (!ctx->powered) - goto out; - mutex_unlock(&ctx->mixer_mutex); - - ctx->int_en = mixer_reg_read(res, MXR_INT_EN); - - clk_disable(res->mixer); - clk_disable(res->vp); - clk_disable(res->sclk_mixer); - - pm_runtime_put_sync(ctx->dev); - - mutex_lock(&ctx->mixer_mutex); - ctx->powered = false; - -out: - mutex_unlock(&ctx->mixer_mutex); -} - -static int mixer_enable_vblank(void *ctx, int pipe) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mixer_ctx->pipe = pipe; - - /* enable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC, - MXR_INT_EN_VSYNC); - - return 0; -} - -static void mixer_disable_vblank(void *ctx) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - /* disable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); -} - -static void mixer_dpms(void *ctx, int mode) -{ - struct mixer_context *mixer_ctx = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - switch (mode) { - case DRM_MODE_DPMS_ON: - mixer_poweron(mixer_ctx); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - mixer_poweroff(mixer_ctx); - break; - default: - DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); - break; - } -} - -static void mixer_win_mode_set(void *ctx, - struct exynos_drm_overlay *overlay) -{ - struct mixer_context *mixer_ctx = ctx; - struct hdmi_win_data *win_data; - int win; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!overlay) { - DRM_ERROR("overlay is NULL\n"); - return; - } - - DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", - overlay->fb_width, overlay->fb_height, - overlay->fb_x, overlay->fb_y, - overlay->crtc_width, overlay->crtc_height, - overlay->crtc_x, overlay->crtc_y); - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("mixer window[%d] is wrong\n", win); - return; - } - - win_data = &mixer_ctx->win_data[win]; - - win_data->dma_addr = overlay->dma_addr[0]; - win_data->vaddr = overlay->vaddr[0]; - win_data->chroma_dma_addr = overlay->dma_addr[1]; - win_data->chroma_vaddr = overlay->vaddr[1]; - win_data->pixel_format = overlay->pixel_format; - win_data->bpp = overlay->bpp; - - win_data->crtc_x = overlay->crtc_x; - win_data->crtc_y = overlay->crtc_y; - win_data->crtc_width = overlay->crtc_width; - win_data->crtc_height = overlay->crtc_height; - - win_data->fb_x = overlay->fb_x; - win_data->fb_y = overlay->fb_y; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - win_data->src_width = overlay->src_width; - win_data->src_height = overlay->src_height; - - win_data->mode_width = overlay->mode_width; - win_data->mode_height = overlay->mode_height; - - win_data->scan_flags = overlay->scan_flag; -} - -static void mixer_win_commit(void *ctx, int win) -{ - struct mixer_context *mixer_ctx = ctx; - - DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); - - if (win > 1) - vp_video_buffer(mixer_ctx, win); - else - mixer_graph_buffer(mixer_ctx, win); -} - -static void mixer_win_disable(void *ctx, int win) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - unsigned long flags; - - DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(mixer_ctx, false); - - mixer_cfg_layer(mixer_ctx, win, false); - - mixer_vsync_set_update(mixer_ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static struct exynos_mixer_ops mixer_ops = { - /* manager */ - .enable_vblank = mixer_enable_vblank, - .disable_vblank = mixer_disable_vblank, - .dpms = mixer_dpms, - - /* overlay */ - .win_mode_set = mixer_win_mode_set, - .win_commit = mixer_win_commit, - .win_disable = mixer_win_disable, -}; - -/* for pageflip event */ -static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static irqreturn_t mixer_irq_handler(int irq, void *arg) -{ - struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; - struct mixer_context *ctx = drm_hdmi_ctx->ctx; - struct mixer_resources *res = &ctx->mixer_res; - u32 val, base, shadow; - - spin_lock(&res->reg_slock); - - /* read interrupt status for handling and clearing flags for VSYNC */ - val = mixer_reg_read(res, MXR_INT_STATUS); - - /* handling VSYNC */ - if (val & MXR_INT_STATUS_VSYNC) { - /* interlace scan need to check shadow register */ - if (ctx->interlace) { - base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); - shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0)); - if (base != shadow) - goto out; - - base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1)); - shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1)); - if (base != shadow) - goto out; - } - - drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe); - mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe); - } - -out: - /* clear interrupts */ - if (~val & MXR_INT_EN_VSYNC) { - /* vsync interrupt use different bit for read and clear */ - val &= ~MXR_INT_EN_VSYNC; - val |= MXR_INT_CLEAR_VSYNC; - } - mixer_reg_write(res, MXR_INT_STATUS, val); - - spin_unlock(&res->reg_slock); - - return IRQ_HANDLED; -} - -static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, - struct platform_device *pdev) -{ - struct mixer_context *mixer_ctx = ctx->ctx; - struct device *dev = &pdev->dev; - struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; - struct resource *res; - int ret; - - spin_lock_init(&mixer_res->reg_slock); - - mixer_res->mixer = clk_get(dev, "mixer"); - if (IS_ERR_OR_NULL(mixer_res->mixer)) { - dev_err(dev, "failed to get clock 'mixer'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->vp = clk_get(dev, "vp"); - if (IS_ERR_OR_NULL(mixer_res->vp)) { - dev_err(dev, "failed to get clock 'vp'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer"); - if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) { - dev_err(dev, "failed to get clock 'sclk_mixer'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); - if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) { - dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_dac = clk_get(dev, "sclk_dac"); - if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) { - dev_err(dev, "failed to get clock 'sclk_dac'\n"); - ret = -ENODEV; - goto fail; - } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr"); - if (res == NULL) { - dev_err(dev, "get memory resource failed.\n"); - ret = -ENXIO; - goto fail; - } - - clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi); - - mixer_res->mixer_regs = ioremap(res->start, resource_size(res)); - if (mixer_res->mixer_regs == NULL) { - dev_err(dev, "register mapping failed.\n"); - ret = -ENXIO; - goto fail; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp"); - if (res == NULL) { - dev_err(dev, "get memory resource failed.\n"); - ret = -ENXIO; - goto fail_mixer_regs; - } - - mixer_res->vp_regs = ioremap(res->start, resource_size(res)); - if (mixer_res->vp_regs == NULL) { - dev_err(dev, "register mapping failed.\n"); - ret = -ENXIO; - goto fail_mixer_regs; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq"); - if (res == NULL) { - dev_err(dev, "get interrupt resource failed.\n"); - ret = -ENXIO; - goto fail_vp_regs; - } - - ret = request_irq(res->start, mixer_irq_handler, 0, "drm_mixer", ctx); - if (ret) { - dev_err(dev, "request interrupt failed.\n"); - goto fail_vp_regs; - } - mixer_res->irq = res->start; - - return 0; - -fail_vp_regs: - iounmap(mixer_res->vp_regs); - -fail_mixer_regs: - iounmap(mixer_res->mixer_regs); - -fail: - if (!IS_ERR_OR_NULL(mixer_res->sclk_dac)) - clk_put(mixer_res->sclk_dac); - if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) - clk_put(mixer_res->sclk_hdmi); - if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer)) - clk_put(mixer_res->sclk_mixer); - if (!IS_ERR_OR_NULL(mixer_res->vp)) - clk_put(mixer_res->vp); - if (!IS_ERR_OR_NULL(mixer_res->mixer)) - clk_put(mixer_res->mixer); - return ret; -} - -static void mixer_resources_cleanup(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - free_irq(res->irq, ctx); - - iounmap(res->vp_regs); - iounmap(res->mixer_regs); -} - -static int __devinit mixer_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx; - struct mixer_context *ctx; - int ret; - - dev_info(dev, "probe start\n"); - - drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL); - if (!drm_hdmi_ctx) { - DRM_ERROR("failed to allocate common hdmi context.\n"); - return -ENOMEM; - } - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - DRM_ERROR("failed to alloc mixer context.\n"); - kfree(drm_hdmi_ctx); - return -ENOMEM; - } - - mutex_init(&ctx->mixer_mutex); - - ctx->dev = &pdev->dev; - drm_hdmi_ctx->ctx = (void *)ctx; - - platform_set_drvdata(pdev, drm_hdmi_ctx); - - /* acquire resources: regs, irqs, clocks */ - ret = mixer_resources_init(drm_hdmi_ctx, pdev); - if (ret) - goto fail; - - /* register specific callback point to common hdmi. */ - exynos_mixer_ops_register(&mixer_ops); - - pm_runtime_enable(dev); - - return 0; - - -fail: - dev_info(dev, "probe failed\n"); - return ret; -} - -static int mixer_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx = - platform_get_drvdata(pdev); - struct mixer_context *ctx = drm_hdmi_ctx->ctx; - - dev_info(dev, "remove successful\n"); - - pm_runtime_disable(&pdev->dev); - - mixer_resources_cleanup(ctx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int mixer_suspend(struct device *dev) -{ - struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev); - struct mixer_context *ctx = drm_hdmi_ctx->ctx; - - mixer_poweroff(ctx); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(mixer_pm_ops, mixer_suspend, NULL); - -struct platform_driver mixer_driver = { - .driver = { - .name = "s5p-mixer", - .owner = THIS_MODULE, - .pm = &mixer_pm_ops, - }, - .probe = mixer_probe, - .remove = __devexit_p(mixer_remove), -}; diff --git a/drivers/gpu/drm/exynos_tmp/regs-hdmi.h b/drivers/gpu/drm/exynos_tmp/regs-hdmi.h deleted file mode 100644 index 93576a0..0000000 --- a/drivers/gpu/drm/exynos_tmp/regs-hdmi.h +++ /dev/null @@ -1,723 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-hdmi.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * HDMI register header file for Samsung TVOUT driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef SAMSUNG_REGS_HDMI_H -#define SAMSUNG_REGS_HDMI_H - -/* - * Register part -*/ - -/* HDMI Version 1.3 & Common */ -#define HDMI_CTRL_BASE(x) ((x) + 0x00000000) -#define HDMI_CORE_BASE(x) ((x) + 0x00010000) -#define HDMI_I2S_BASE(x) ((x) + 0x00040000) -#define HDMI_TG_BASE(x) ((x) + 0x00050000) - -/* Control registers */ -#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) -#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) -#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) -#define HDMI_V13_PHY_RSTOUT HDMI_CTRL_BASE(0x0014) -#define HDMI_V13_PHY_VPLL HDMI_CTRL_BASE(0x0018) -#define HDMI_V13_PHY_CMU HDMI_CTRL_BASE(0x001C) -#define HDMI_V13_CORE_RSTOUT HDMI_CTRL_BASE(0x0020) - -/* Core registers */ -#define HDMI_CON_0 HDMI_CORE_BASE(0x0000) -#define HDMI_CON_1 HDMI_CORE_BASE(0x0004) -#define HDMI_CON_2 HDMI_CORE_BASE(0x0008) -#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010) -#define HDMI_V13_PHY_STATUS HDMI_CORE_BASE(0x0014) -#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020) -#define HDMI_HPD HDMI_CORE_BASE(0x0030) -#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040) -#define HDMI_ENC_EN HDMI_CORE_BASE(0x0044) -#define HDMI_V13_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050) -#define HDMI_V13_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054) -#define HDMI_V13_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058) -#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0) -#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4) -#define HDMI_V13_V_BLANK_0 HDMI_CORE_BASE(0x00B0) -#define HDMI_V13_V_BLANK_1 HDMI_CORE_BASE(0x00B4) -#define HDMI_V13_V_BLANK_2 HDMI_CORE_BASE(0x00B8) -#define HDMI_V13_H_V_LINE_0 HDMI_CORE_BASE(0x00C0) -#define HDMI_V13_H_V_LINE_1 HDMI_CORE_BASE(0x00C4) -#define HDMI_V13_H_V_LINE_2 HDMI_CORE_BASE(0x00C8) -#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4) -#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8) -#define HDMI_V13_V_BLANK_F_0 HDMI_CORE_BASE(0x0110) -#define HDMI_V13_V_BLANK_F_1 HDMI_CORE_BASE(0x0114) -#define HDMI_V13_V_BLANK_F_2 HDMI_CORE_BASE(0x0118) -#define HDMI_V13_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120) -#define HDMI_V13_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124) -#define HDMI_V13_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128) -#define HDMI_V13_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130) -#define HDMI_V13_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134) -#define HDMI_V13_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138) -#define HDMI_V13_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140) -#define HDMI_V13_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144) -#define HDMI_V13_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148) -#define HDMI_V13_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150) -#define HDMI_V13_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154) -#define HDMI_V13_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158) -#define HDMI_V13_ACR_CON HDMI_CORE_BASE(0x0180) -#define HDMI_V13_ACR_CTS0 HDMI_CORE_BASE(0x0190) -#define HDMI_V13_AVI_CON HDMI_CORE_BASE(0x0300) -#define HDMI_V13_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n)) -#define HDMI_V13_DC_CONTROL HDMI_CORE_BASE(0x05C0) -#define HDMI_V13_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4) -#define HDMI_V13_HPD_GEN HDMI_CORE_BASE(0x05C8) -#define HDMI_V13_AUI_CON HDMI_CORE_BASE(0x0360) -#define HDMI_V13_SPD_CON HDMI_CORE_BASE(0x0400) - -/* Timing generator registers */ -#define HDMI_TG_CMD HDMI_TG_BASE(0x0000) -#define HDMI_TG_H_FSZ_L HDMI_TG_BASE(0x0018) -#define HDMI_TG_H_FSZ_H HDMI_TG_BASE(0x001C) -#define HDMI_TG_HACT_ST_L HDMI_TG_BASE(0x0020) -#define HDMI_TG_HACT_ST_H HDMI_TG_BASE(0x0024) -#define HDMI_TG_HACT_SZ_L HDMI_TG_BASE(0x0028) -#define HDMI_TG_HACT_SZ_H HDMI_TG_BASE(0x002C) -#define HDMI_TG_V_FSZ_L HDMI_TG_BASE(0x0030) -#define HDMI_TG_V_FSZ_H HDMI_TG_BASE(0x0034) -#define HDMI_TG_VSYNC_L HDMI_TG_BASE(0x0038) -#define HDMI_TG_VSYNC_H HDMI_TG_BASE(0x003C) -#define HDMI_TG_VSYNC2_L HDMI_TG_BASE(0x0040) -#define HDMI_TG_VSYNC2_H HDMI_TG_BASE(0x0044) -#define HDMI_TG_VACT_ST_L HDMI_TG_BASE(0x0048) -#define HDMI_TG_VACT_ST_H HDMI_TG_BASE(0x004C) -#define HDMI_TG_VACT_SZ_L HDMI_TG_BASE(0x0050) -#define HDMI_TG_VACT_SZ_H HDMI_TG_BASE(0x0054) -#define HDMI_TG_FIELD_CHG_L HDMI_TG_BASE(0x0058) -#define HDMI_TG_FIELD_CHG_H HDMI_TG_BASE(0x005C) -#define HDMI_TG_VACT_ST2_L HDMI_TG_BASE(0x0060) -#define HDMI_TG_VACT_ST2_H HDMI_TG_BASE(0x0064) -#define HDMI_TG_VSYNC_TOP_HDMI_L HDMI_TG_BASE(0x0078) -#define HDMI_TG_VSYNC_TOP_HDMI_H HDMI_TG_BASE(0x007C) -#define HDMI_TG_VSYNC_BOT_HDMI_L HDMI_TG_BASE(0x0080) -#define HDMI_TG_VSYNC_BOT_HDMI_H HDMI_TG_BASE(0x0084) -#define HDMI_TG_FIELD_TOP_HDMI_L HDMI_TG_BASE(0x0088) -#define HDMI_TG_FIELD_TOP_HDMI_H HDMI_TG_BASE(0x008C) -#define HDMI_TG_FIELD_BOT_HDMI_L HDMI_TG_BASE(0x0090) -#define HDMI_TG_FIELD_BOT_HDMI_H HDMI_TG_BASE(0x0094) - -/* - * Bit definition part - */ - -/* HDMI_INTC_CON */ -#define HDMI_INTC_EN_GLOBAL (1 << 6) -#define HDMI_INTC_EN_HPD_PLUG (1 << 3) -#define HDMI_INTC_EN_HPD_UNPLUG (1 << 2) - -/* HDMI_INTC_FLAG */ -#define HDMI_INTC_FLAG_HPD_PLUG (1 << 3) -#define HDMI_INTC_FLAG_HPD_UNPLUG (1 << 2) - -/* HDMI_PHY_RSTOUT */ -#define HDMI_PHY_SW_RSTOUT (1 << 0) - -/* HDMI_CORE_RSTOUT */ -#define HDMI_CORE_SW_RSTOUT (1 << 0) - -/* HDMI_CON_0 */ -#define HDMI_BLUE_SCR_EN (1 << 5) -#define HDMI_ASP_EN (1 << 2) -#define HDMI_ASP_DIS (0 << 2) -#define HDMI_ASP_MASK (1 << 2) -#define HDMI_EN (1 << 0) - -/* HDMI_CON_2 */ -#define HDMI_VID_PREAMBLE_DIS (1 << 5) -#define HDMI_GUARD_BAND_DIS (1 << 1) - -/* HDMI_PHY_STATUS */ -#define HDMI_PHY_STATUS_READY (1 << 0) - -/* HDMI_MODE_SEL */ -#define HDMI_MODE_HDMI_EN (1 << 1) -#define HDMI_MODE_DVI_EN (1 << 0) -#define HDMI_MODE_MASK (3 << 0) - -/* HDMI_TG_CMD */ -#define HDMI_TG_EN (1 << 0) -#define HDMI_FIELD_EN (1 << 1) - - -/* HDMI Version 1.4 */ -/* Control registers */ -/* #define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) */ -/* #define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) */ -#define HDMI_HDCP_KEY_LOAD HDMI_CTRL_BASE(0x0008) -/* #define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) */ -#define HDMI_INTC_CON_1 HDMI_CTRL_BASE(0x0010) -#define HDMI_INTC_FLAG_1 HDMI_CTRL_BASE(0x0014) -#define HDMI_PHY_STATUS_0 HDMI_CTRL_BASE(0x0020) -#define HDMI_PHY_STATUS_CMU HDMI_CTRL_BASE(0x0024) -#define HDMI_PHY_STATUS_PLL HDMI_CTRL_BASE(0x0028) -#define HDMI_PHY_CON_0 HDMI_CTRL_BASE(0x0030) -#define HDMI_HPD_CTRL HDMI_CTRL_BASE(0x0040) -#define HDMI_HPD_ST HDMI_CTRL_BASE(0x0044) -#define HDMI_HPD_TH_X HDMI_CTRL_BASE(0x0050) -#define HDMI_AUDIO_CLKSEL HDMI_CTRL_BASE(0x0070) -#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0074) -#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0078) -#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x007C) -#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0080) - -/* Video related registers */ -#define HDMI_YMAX HDMI_CORE_BASE(0x0060) -#define HDMI_YMIN HDMI_CORE_BASE(0x0064) -#define HDMI_CMAX HDMI_CORE_BASE(0x0068) -#define HDMI_CMIN HDMI_CORE_BASE(0x006C) - -#define HDMI_V2_BLANK_0 HDMI_CORE_BASE(0x00B0) -#define HDMI_V2_BLANK_1 HDMI_CORE_BASE(0x00B4) -#define HDMI_V1_BLANK_0 HDMI_CORE_BASE(0x00B8) -#define HDMI_V1_BLANK_1 HDMI_CORE_BASE(0x00BC) - -#define HDMI_V_LINE_0 HDMI_CORE_BASE(0x00C0) -#define HDMI_V_LINE_1 HDMI_CORE_BASE(0x00C4) -#define HDMI_H_LINE_0 HDMI_CORE_BASE(0x00C8) -#define HDMI_H_LINE_1 HDMI_CORE_BASE(0x00CC) - -#define HDMI_HSYNC_POL HDMI_CORE_BASE(0x00E0) - -#define HDMI_V_BLANK_F0_0 HDMI_CORE_BASE(0x0110) -#define HDMI_V_BLANK_F0_1 HDMI_CORE_BASE(0x0114) -#define HDMI_V_BLANK_F1_0 HDMI_CORE_BASE(0x0118) -#define HDMI_V_BLANK_F1_1 HDMI_CORE_BASE(0x011C) - -#define HDMI_H_SYNC_START_0 HDMI_CORE_BASE(0x0120) -#define HDMI_H_SYNC_START_1 HDMI_CORE_BASE(0x0124) -#define HDMI_H_SYNC_END_0 HDMI_CORE_BASE(0x0128) -#define HDMI_H_SYNC_END_1 HDMI_CORE_BASE(0x012C) - -#define HDMI_V_SYNC_LINE_BEF_2_0 HDMI_CORE_BASE(0x0130) -#define HDMI_V_SYNC_LINE_BEF_2_1 HDMI_CORE_BASE(0x0134) -#define HDMI_V_SYNC_LINE_BEF_1_0 HDMI_CORE_BASE(0x0138) -#define HDMI_V_SYNC_LINE_BEF_1_1 HDMI_CORE_BASE(0x013C) - -#define HDMI_V_SYNC_LINE_AFT_2_0 HDMI_CORE_BASE(0x0140) -#define HDMI_V_SYNC_LINE_AFT_2_1 HDMI_CORE_BASE(0x0144) -#define HDMI_V_SYNC_LINE_AFT_1_0 HDMI_CORE_BASE(0x0148) -#define HDMI_V_SYNC_LINE_AFT_1_1 HDMI_CORE_BASE(0x014C) - -#define HDMI_V_SYNC_LINE_AFT_PXL_2_0 HDMI_CORE_BASE(0x0150) -#define HDMI_V_SYNC_LINE_AFT_PXL_2_1 HDMI_CORE_BASE(0x0154) -#define HDMI_V_SYNC_LINE_AFT_PXL_1_0 HDMI_CORE_BASE(0x0158) -#define HDMI_V_SYNC_LINE_AFT_PXL_1_1 HDMI_CORE_BASE(0x015C) - -#define HDMI_V_BLANK_F2_0 HDMI_CORE_BASE(0x0160) -#define HDMI_V_BLANK_F2_1 HDMI_CORE_BASE(0x0164) -#define HDMI_V_BLANK_F3_0 HDMI_CORE_BASE(0x0168) -#define HDMI_V_BLANK_F3_1 HDMI_CORE_BASE(0x016C) -#define HDMI_V_BLANK_F4_0 HDMI_CORE_BASE(0x0170) -#define HDMI_V_BLANK_F4_1 HDMI_CORE_BASE(0x0174) -#define HDMI_V_BLANK_F5_0 HDMI_CORE_BASE(0x0178) -#define HDMI_V_BLANK_F5_1 HDMI_CORE_BASE(0x017C) - -#define HDMI_V_SYNC_LINE_AFT_3_0 HDMI_CORE_BASE(0x0180) -#define HDMI_V_SYNC_LINE_AFT_3_1 HDMI_CORE_BASE(0x0184) -#define HDMI_V_SYNC_LINE_AFT_4_0 HDMI_CORE_BASE(0x0188) -#define HDMI_V_SYNC_LINE_AFT_4_1 HDMI_CORE_BASE(0x018C) -#define HDMI_V_SYNC_LINE_AFT_5_0 HDMI_CORE_BASE(0x0190) -#define HDMI_V_SYNC_LINE_AFT_5_1 HDMI_CORE_BASE(0x0194) -#define HDMI_V_SYNC_LINE_AFT_6_0 HDMI_CORE_BASE(0x0198) -#define HDMI_V_SYNC_LINE_AFT_6_1 HDMI_CORE_BASE(0x019C) - -#define HDMI_V_SYNC_LINE_AFT_PXL_3_0 HDMI_CORE_BASE(0x01A0) -#define HDMI_V_SYNC_LINE_AFT_PXL_3_1 HDMI_CORE_BASE(0x01A4) -#define HDMI_V_SYNC_LINE_AFT_PXL_4_0 HDMI_CORE_BASE(0x01A8) -#define HDMI_V_SYNC_LINE_AFT_PXL_4_1 HDMI_CORE_BASE(0x01AC) -#define HDMI_V_SYNC_LINE_AFT_PXL_5_0 HDMI_CORE_BASE(0x01B0) -#define HDMI_V_SYNC_LINE_AFT_PXL_5_1 HDMI_CORE_BASE(0x01B4) -#define HDMI_V_SYNC_LINE_AFT_PXL_6_0 HDMI_CORE_BASE(0x01B8) -#define HDMI_V_SYNC_LINE_AFT_PXL_6_1 HDMI_CORE_BASE(0x01BC) - -#define HDMI_VACT_SPACE_1_0 HDMI_CORE_BASE(0x01C0) -#define HDMI_VACT_SPACE_1_1 HDMI_CORE_BASE(0x01C4) -#define HDMI_VACT_SPACE_2_0 HDMI_CORE_BASE(0x01C8) -#define HDMI_VACT_SPACE_2_1 HDMI_CORE_BASE(0x01CC) -#define HDMI_VACT_SPACE_3_0 HDMI_CORE_BASE(0x01D0) -#define HDMI_VACT_SPACE_3_1 HDMI_CORE_BASE(0x01D4) -#define HDMI_VACT_SPACE_4_0 HDMI_CORE_BASE(0x01D8) -#define HDMI_VACT_SPACE_4_1 HDMI_CORE_BASE(0x01DC) -#define HDMI_VACT_SPACE_5_0 HDMI_CORE_BASE(0x01E0) -#define HDMI_VACT_SPACE_5_1 HDMI_CORE_BASE(0x01E4) -#define HDMI_VACT_SPACE_6_0 HDMI_CORE_BASE(0x01E8) -#define HDMI_VACT_SPACE_6_1 HDMI_CORE_BASE(0x01EC) - -#define HDMI_GCP_CON HDMI_CORE_BASE(0x0200) -#define HDMI_GCP_BYTE1 HDMI_CORE_BASE(0x0210) -#define HDMI_GCP_BYTE2 HDMI_CORE_BASE(0x0214) -#define HDMI_GCP_BYTE3 HDMI_CORE_BASE(0x0218) - -/* Audio related registers */ -#define HDMI_ASP_CON HDMI_CORE_BASE(0x0300) -#define HDMI_ASP_SP_FLAT HDMI_CORE_BASE(0x0304) -#define HDMI_ASP_CHCFG0 HDMI_CORE_BASE(0x0310) -#define HDMI_ASP_CHCFG1 HDMI_CORE_BASE(0x0314) -#define HDMI_ASP_CHCFG2 HDMI_CORE_BASE(0x0318) -#define HDMI_ASP_CHCFG3 HDMI_CORE_BASE(0x031C) - -#define HDMI_ACR_CON HDMI_CORE_BASE(0x0400) -#define HDMI_ACR_MCTS0 HDMI_CORE_BASE(0x0410) -#define HDMI_ACR_MCTS1 HDMI_CORE_BASE(0x0414) -#define HDMI_ACR_MCTS2 HDMI_CORE_BASE(0x0418) -#define HDMI_ACR_CTS0 HDMI_CORE_BASE(0x0420) -#define HDMI_ACR_CTS1 HDMI_CORE_BASE(0x0424) -#define HDMI_ACR_CTS2 HDMI_CORE_BASE(0x0428) -#define HDMI_ACR_N0 HDMI_CORE_BASE(0x0430) -#define HDMI_ACR_N1 HDMI_CORE_BASE(0x0434) -#define HDMI_ACR_N2 HDMI_CORE_BASE(0x0438) - -/* Packet related registers */ -#define HDMI_ACP_CON HDMI_CORE_BASE(0x0500) -#define HDMI_ACP_TYPE HDMI_CORE_BASE(0x0514) -#define HDMI_ACP_DATA(n) HDMI_CORE_BASE(0x0520 + 4 * (n)) - -#define HDMI_ISRC_CON HDMI_CORE_BASE(0x0600) -#define HDMI_ISRC1_HEADER1 HDMI_CORE_BASE(0x0614) -#define HDMI_ISRC1_DATA(n) HDMI_CORE_BASE(0x0620 + 4 * (n)) -#define HDMI_ISRC2_DATA(n) HDMI_CORE_BASE(0x06A0 + 4 * (n)) - -#define HDMI_AVI_CON HDMI_CORE_BASE(0x0700) -#define HDMI_AVI_HEADER0 HDMI_CORE_BASE(0x0710) -#define HDMI_AVI_HEADER1 HDMI_CORE_BASE(0x0714) -#define HDMI_AVI_HEADER2 HDMI_CORE_BASE(0x0718) -#define HDMI_AVI_CHECK_SUM HDMI_CORE_BASE(0x071C) -#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0720 + 4 * (n)) - -#define HDMI_AUI_CON HDMI_CORE_BASE(0x0800) -#define HDMI_AUI_HEADER0 HDMI_CORE_BASE(0x0810) -#define HDMI_AUI_HEADER1 HDMI_CORE_BASE(0x0814) -#define HDMI_AUI_HEADER2 HDMI_CORE_BASE(0x0818) -#define HDMI_AUI_CHECK_SUM HDMI_CORE_BASE(0x081C) -#define HDMI_AUI_BYTE(n) HDMI_CORE_BASE(0x0820 + 4 * (n)) - -#define HDMI_MPG_CON HDMI_CORE_BASE(0x0900) -#define HDMI_MPG_CHECK_SUM HDMI_CORE_BASE(0x091C) -#define HDMI_MPG_DATA(n) HDMI_CORE_BASE(0x0920 + 4 * (n)) - -#define HDMI_SPD_CON HDMI_CORE_BASE(0x0A00) -#define HDMI_SPD_HEADER0 HDMI_CORE_BASE(0x0A10) -#define HDMI_SPD_HEADER1 HDMI_CORE_BASE(0x0A14) -#define HDMI_SPD_HEADER2 HDMI_CORE_BASE(0x0A18) -#define HDMI_SPD_DATA(n) HDMI_CORE_BASE(0x0A20 + 4 * (n)) - -#define HDMI_GAMUT_CON HDMI_CORE_BASE(0x0B00) -#define HDMI_GAMUT_HEADER0 HDMI_CORE_BASE(0x0B10) -#define HDMI_GAMUT_HEADER1 HDMI_CORE_BASE(0x0B14) -#define HDMI_GAMUT_HEADER2 HDMI_CORE_BASE(0x0B18) -#define HDMI_GAMUT_METADATA(n) HDMI_CORE_BASE(0x0B20 + 4 * (n)) - -#define HDMI_VSI_CON HDMI_CORE_BASE(0x0C00) -#define HDMI_VSI_HEADER0 HDMI_CORE_BASE(0x0C10) -#define HDMI_VSI_HEADER1 HDMI_CORE_BASE(0x0C14) -#define HDMI_VSI_HEADER2 HDMI_CORE_BASE(0x0C18) -#define HDMI_VSI_DATA(n) HDMI_CORE_BASE(0x0C20 + 4 * (n)) - -#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x0D00) -#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x0D04) - -#define HDMI_AN_SEED_SEL HDMI_CORE_BASE(0x0E48) -#define HDMI_AN_SEED_0 HDMI_CORE_BASE(0x0E58) -#define HDMI_AN_SEED_1 HDMI_CORE_BASE(0x0E5C) -#define HDMI_AN_SEED_2 HDMI_CORE_BASE(0x0E60) -#define HDMI_AN_SEED_3 HDMI_CORE_BASE(0x0E64) - -/* HDCP related registers */ -#define HDMI_HDCP_SHA1(n) HDMI_CORE_BASE(0x7000 + 4 * (n)) -#define HDMI_HDCP_KSV_LIST(n) HDMI_CORE_BASE(0x7050 + 4 * (n)) - -#define HDMI_HDCP_KSV_LIST_CON HDMI_CORE_BASE(0x7064) -#define HDMI_HDCP_SHA_RESULT HDMI_CORE_BASE(0x7070) -#define HDMI_HDCP_CTRL1 HDMI_CORE_BASE(0x7080) -#define HDMI_HDCP_CTRL2 HDMI_CORE_BASE(0x7084) -#define HDMI_HDCP_CHECK_RESULT HDMI_CORE_BASE(0x7090) -#define HDMI_HDCP_BKSV(n) HDMI_CORE_BASE(0x70A0 + 4 * (n)) -#define HDMI_HDCP_AKSV(n) HDMI_CORE_BASE(0x70C0 + 4 * (n)) -#define HDMI_HDCP_AN(n) HDMI_CORE_BASE(0x70E0 + 4 * (n)) - -#define HDMI_HDCP_BCAPS HDMI_CORE_BASE(0x7100) -#define HDMI_HDCP_BSTATUS_0 HDMI_CORE_BASE(0x7110) -#define HDMI_HDCP_BSTATUS_1 HDMI_CORE_BASE(0x7114) -#define HDMI_HDCP_RI_0 HDMI_CORE_BASE(0x7140) -#define HDMI_HDCP_RI_1 HDMI_CORE_BASE(0x7144) -#define HDMI_HDCP_I2C_INT HDMI_CORE_BASE(0x7180) -#define HDMI_HDCP_AN_INT HDMI_CORE_BASE(0x7190) -#define HDMI_HDCP_WDT_INT HDMI_CORE_BASE(0x71A0) -#define HDMI_HDCP_RI_INT HDMI_CORE_BASE(0x71B0) -#define HDMI_HDCP_RI_COMPARE_0 HDMI_CORE_BASE(0x71D0) -#define HDMI_HDCP_RI_COMPARE_1 HDMI_CORE_BASE(0x71D4) -#define HDMI_HDCP_FRAME_COUNT HDMI_CORE_BASE(0x71E0) - -#define HDMI_RGB_ROUND_EN HDMI_CORE_BASE(0xD500) -#define HDMI_VACT_SPACE_R_0 HDMI_CORE_BASE(0xD504) -#define HDMI_VACT_SPACE_R_1 HDMI_CORE_BASE(0xD508) -#define HDMI_VACT_SPACE_G_0 HDMI_CORE_BASE(0xD50C) -#define HDMI_VACT_SPACE_G_1 HDMI_CORE_BASE(0xD510) -#define HDMI_VACT_SPACE_B_0 HDMI_CORE_BASE(0xD514) -#define HDMI_VACT_SPACE_B_1 HDMI_CORE_BASE(0xD518) - -#define HDMI_BLUE_SCREEN_B_0 HDMI_CORE_BASE(0xD520) -#define HDMI_BLUE_SCREEN_B_1 HDMI_CORE_BASE(0xD524) -#define HDMI_BLUE_SCREEN_G_0 HDMI_CORE_BASE(0xD528) -#define HDMI_BLUE_SCREEN_G_1 HDMI_CORE_BASE(0xD52C) -#define HDMI_BLUE_SCREEN_R_0 HDMI_CORE_BASE(0xD530) -#define HDMI_BLUE_SCREEN_R_1 HDMI_CORE_BASE(0xD534) - -/* HDMI I2S register */ -#define HDMI_I2S_CLK_CON HDMI_I2S_BASE(0x000) -#define HDMI_I2S_CON_1 HDMI_I2S_BASE(0x004) -#define HDMI_I2S_CON_2 HDMI_I2S_BASE(0x008) -#define HDMI_I2S_PIN_SEL_0 HDMI_I2S_BASE(0x00c) -#define HDMI_I2S_PIN_SEL_1 HDMI_I2S_BASE(0x010) -#define HDMI_I2S_PIN_SEL_2 HDMI_I2S_BASE(0x014) -#define HDMI_I2S_PIN_SEL_3 HDMI_I2S_BASE(0x018) -#define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c) -#define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020) -#define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024) -#define HDMI_I2S_CH_ST_0 HDMI_I2S_BASE(0x028) -#define HDMI_I2S_CH_ST_1 HDMI_I2S_BASE(0x02c) -#define HDMI_I2S_CH_ST_2 HDMI_I2S_BASE(0x030) -#define HDMI_I2S_CH_ST_3 HDMI_I2S_BASE(0x034) -#define HDMI_I2S_CH_ST_4 HDMI_I2S_BASE(0x038) -#define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c) -#define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040) -#define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044) -#define HDMI_I2S_CH_ST_SH_3 HDMI_I2S_BASE(0x048) -#define HDMI_I2S_CH_ST_SH_4 HDMI_I2S_BASE(0x04c) -#define HDMI_I2S_VD_DATA HDMI_I2S_BASE(0x050) -#define HDMI_I2S_MUX_CH HDMI_I2S_BASE(0x054) -#define HDMI_I2S_MUX_CUV HDMI_I2S_BASE(0x058) -#define HDMI_I2S_IRQ_MASK HDMI_I2S_BASE(0x05c) -#define HDMI_I2S_IRQ_STATUS HDMI_I2S_BASE(0x060) - -/* I2S bit definition */ - -/* I2S_CLK_CON */ -#define HDMI_I2S_CLK_DIS (0) -#define HDMI_I2S_CLK_EN (1) - -/* I2S_CON_1 */ -#define HDMI_I2S_SCLK_FALLING_EDGE (0 << 1) -#define HDMI_I2S_SCLK_RISING_EDGE (1 << 1) -#define HDMI_I2S_L_CH_LOW_POL (0) -#define HDMI_I2S_L_CH_HIGH_POL (1) - -/* I2S_CON_2 */ -#define HDMI_I2S_MSB_FIRST_MODE (0 << 6) -#define HDMI_I2S_LSB_FIRST_MODE (1 << 6) -#define HDMI_I2S_BIT_CH_32FS (0 << 4) -#define HDMI_I2S_BIT_CH_48FS (1 << 4) -#define HDMI_I2S_BIT_CH_RESERVED (2 << 4) -#define HDMI_I2S_SDATA_16BIT (1 << 2) -#define HDMI_I2S_SDATA_20BIT (2 << 2) -#define HDMI_I2S_SDATA_24BIT (3 << 2) -#define HDMI_I2S_BASIC_FORMAT (0) -#define HDMI_I2S_L_JUST_FORMAT (2) -#define HDMI_I2S_R_JUST_FORMAT (3) -#define HDMI_I2S_CON_2_CLR (~(0xFF)) -#define HDMI_I2S_SET_BIT_CH(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SET_SDATA_BIT(x) (((x) & 0x7) << 2) - -/* I2S_PIN_SEL_0 */ -#define HDMI_I2S_SEL_SCLK(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_SCLK_DEFAULT_1 (0x7 << 4) -#define HDMI_I2S_SEL_LRCK(x) ((x) & 0x7) -#define HDMI_I2S_SEL_LRCK_DEFAULT_0 (0x7) - -/* I2S_PIN_SEL_1 */ -#define HDMI_I2S_SEL_SDATA1(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_SDATA1_DEFAULT_3 (0x7 << 4) -#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7) -#define HDMI_I2S_SEL_SDATA2_DEFAULT_2 (0x7) - -/* I2S_PIN_SEL_2 */ -#define HDMI_I2S_SEL_SDATA3(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_SDATA3_DEFAULT_5 (0x7 << 4) -#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7) -#define HDMI_I2S_SEL_SDATA2_DEFAULT_4 (0x7) - -/* I2S_PIN_SEL_3 */ -#define HDMI_I2S_SEL_DSD(x) ((x) & 0x7) -#define HDMI_I2S_SEL_DSD_DEFAULT_6 (0x7) - -/* I2S_DSD_CON */ -#define HDMI_I2S_DSD_CLK_RI_EDGE (1 << 1) -#define HDMI_I2S_DSD_CLK_FA_EDGE (0 << 1) -#define HDMI_I2S_DSD_ENABLE (1) -#define HDMI_I2S_DSD_DISABLE (0) - -/* I2S_MUX_CON */ -#define HDMI_I2S_NOISE_FILTER_ZERO (0 << 5) -#define HDMI_I2S_NOISE_FILTER_2_STAGE (1 << 5) -#define HDMI_I2S_NOISE_FILTER_3_STAGE (2 << 5) -#define HDMI_I2S_NOISE_FILTER_4_STAGE (3 << 5) -#define HDMI_I2S_NOISE_FILTER_5_STAGE (4 << 5) -#define HDMI_I2S_IN_DISABLE (1 << 4) -#define HDMI_I2S_IN_ENABLE (0 << 4) -#define HDMI_I2S_AUD_SPDIF (0 << 2) -#define HDMI_I2S_AUD_I2S (1 << 2) -#define HDMI_I2S_AUD_DSD (2 << 2) -#define HDMI_I2S_CUV_SPDIF_ENABLE (0 << 1) -#define HDMI_I2S_CUV_I2S_ENABLE (1 << 1) -#define HDMI_I2S_MUX_DISABLE (0) -#define HDMI_I2S_MUX_ENABLE (1) -#define HDMI_I2S_MUX_CON_CLR (~(0xFF)) - -/* I2S_CH_ST_CON */ -#define HDMI_I2S_CH_STATUS_RELOAD (1) -#define HDMI_I2S_CH_ST_CON_CLR (~(1)) - -/* I2S_CH_ST_0 / I2S_CH_ST_SH_0 */ -#define HDMI_I2S_CH_STATUS_MODE_0 (0 << 6) -#define HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH (0 << 3) -#define HDMI_I2S_2AUD_CH_WITH_PREEMPH (1 << 3) -#define HDMI_I2S_DEFAULT_EMPHASIS (0 << 3) -#define HDMI_I2S_COPYRIGHT (0 << 2) -#define HDMI_I2S_NO_COPYRIGHT (1 << 2) -#define HDMI_I2S_LINEAR_PCM (0 << 1) -#define HDMI_I2S_NO_LINEAR_PCM (1 << 1) -#define HDMI_I2S_CONSUMER_FORMAT (0) -#define HDMI_I2S_PROF_FORMAT (1) -#define HDMI_I2S_CH_ST_0_CLR (~(0xFF)) - -/* I2S_CH_ST_1 / I2S_CH_ST_SH_1 */ -#define HDMI_I2S_CD_PLAYER (0x00) -#define HDMI_I2S_DAT_PLAYER (0x03) -#define HDMI_I2S_DCC_PLAYER (0x43) -#define HDMI_I2S_MINI_DISC_PLAYER (0x49) - -/* I2S_CH_ST_2 / I2S_CH_ST_SH_2 */ -#define HDMI_I2S_CHANNEL_NUM_MASK (0xF << 4) -#define HDMI_I2S_SOURCE_NUM_MASK (0xF) -#define HDMI_I2S_SET_CHANNEL_NUM(x) (((x) & (0xF)) << 4) -#define HDMI_I2S_SET_SOURCE_NUM(x) ((x) & (0xF)) - -/* I2S_CH_ST_3 / I2S_CH_ST_SH_3 */ -#define HDMI_I2S_CLK_ACCUR_LEVEL_1 (1 << 4) -#define HDMI_I2S_CLK_ACCUR_LEVEL_2 (0 << 4) -#define HDMI_I2S_CLK_ACCUR_LEVEL_3 (2 << 4) -#define HDMI_I2S_SMP_FREQ_44_1 (0x0) -#define HDMI_I2S_SMP_FREQ_48 (0x2) -#define HDMI_I2S_SMP_FREQ_32 (0x3) -#define HDMI_I2S_SMP_FREQ_96 (0xA) -#define HDMI_I2S_SET_SMP_FREQ(x) ((x) & (0xF)) - -/* I2S_CH_ST_4 / I2S_CH_ST_SH_4 */ -#define HDMI_I2S_ORG_SMP_FREQ_44_1 (0xF << 4) -#define HDMI_I2S_ORG_SMP_FREQ_88_2 (0x7 << 4) -#define HDMI_I2S_ORG_SMP_FREQ_22_05 (0xB << 4) -#define HDMI_I2S_ORG_SMP_FREQ_176_4 (0x3 << 4) -#define HDMI_I2S_WORD_LEN_NOT_DEFINE (0x0 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_20BITS (0x1 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_22BITS (0x2 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_23BITS (0x4 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_24BITS (0x5 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_21BITS (0x6 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_16BITS (0x1 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_18BITS (0x2 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_19BITS (0x4 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_20BITS (0x5 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_17BITS (0x6 << 1) -#define HDMI_I2S_WORD_LEN_MAX_24BITS (1) -#define HDMI_I2S_WORD_LEN_MAX_20BITS (0) - -/* I2S_VD_DATA */ -#define HDMI_I2S_VD_AUD_SMP_RELIABLE (0) -#define HDMI_I2S_VD_AUD_SMP_UNRELIABLE (1) - -/* I2S_MUX_CH */ -#define HDMI_I2S_CH3_R_EN (1 << 7) -#define HDMI_I2S_CH3_L_EN (1 << 6) -#define HDMI_I2S_CH3_EN (3 << 6) -#define HDMI_I2S_CH2_R_EN (1 << 5) -#define HDMI_I2S_CH2_L_EN (1 << 4) -#define HDMI_I2S_CH2_EN (3 << 4) -#define HDMI_I2S_CH1_R_EN (1 << 3) -#define HDMI_I2S_CH1_L_EN (1 << 2) -#define HDMI_I2S_CH1_EN (3 << 2) -#define HDMI_I2S_CH0_R_EN (1 << 1) -#define HDMI_I2S_CH0_L_EN (1) -#define HDMI_I2S_CH0_EN (3) -#define HDMI_I2S_CH_ALL_EN (0xFF) -#define HDMI_I2S_MUX_CH_CLR (~HDMI_I2S_CH_ALL_EN) - -/* I2S_MUX_CUV */ -#define HDMI_I2S_CUV_R_EN (1 << 1) -#define HDMI_I2S_CUV_L_EN (1) -#define HDMI_I2S_CUV_RL_EN (0x03) - -/* I2S_IRQ_MASK */ -#define HDMI_I2S_INT2_DIS (0 << 1) -#define HDMI_I2S_INT2_EN (1 << 1) - -/* I2S_IRQ_STATUS */ -#define HDMI_I2S_INT2_STATUS (1 << 1) - -/* I2S_CUV_L_R */ -#define HDMI_I2S_CUV_R_DATA_MASK (0x7 << 4) -#define HDMI_I2S_CUV_L_DATA_MASK (0x7) - -/* Audio Related Packet bit definition */ - -/* ASP_CON */ -#define HDMI_AUD_DST_DOUBLE (1 << 7) -#define HDMI_AUD_NO_DST_DOUBLE (0 << 7) -#define HDMI_AUD_TYPE_SAMPLE (0 << 5) -#define HDMI_AUD_TYPE_ONE_BIT (1 << 5) -#define HDMI_AUD_TYPE_HBR (2 << 5) -#define HDMI_AUD_TYPE_DST (3 << 5) -#define HDMI_AUD_MODE_TWO_CH (0 << 4) -#define HDMI_AUD_MODE_MULTI_CH (1 << 4) -#define HDMI_AUD_SP_AUD3_EN (1 << 3) -#define HDMI_AUD_SP_AUD2_EN (1 << 2) -#define HDMI_AUD_SP_AUD1_EN (1 << 1) -#define HDMI_AUD_SP_AUD0_EN (1 << 0) -#define HDMI_AUD_SP_ALL_DIS (0 << 0) - -#define HDMI_AUD_SET_SP_PRE(x) ((x) & 0xF) - -/* ASP_SP_FLAT */ -#define HDMI_ASP_SP_FLAT_AUD_SAMPLE (0) - -/* ASP_CHCFG0/1/2/3 */ -#define HDMI_SPK3R_SEL_I_PCM0L (0 << 27) -#define HDMI_SPK3R_SEL_I_PCM0R (1 << 27) -#define HDMI_SPK3R_SEL_I_PCM1L (2 << 27) -#define HDMI_SPK3R_SEL_I_PCM1R (3 << 27) -#define HDMI_SPK3R_SEL_I_PCM2L (4 << 27) -#define HDMI_SPK3R_SEL_I_PCM2R (5 << 27) -#define HDMI_SPK3R_SEL_I_PCM3L (6 << 27) -#define HDMI_SPK3R_SEL_I_PCM3R (7 << 27) -#define HDMI_SPK3L_SEL_I_PCM0L (0 << 24) -#define HDMI_SPK3L_SEL_I_PCM0R (1 << 24) -#define HDMI_SPK3L_SEL_I_PCM1L (2 << 24) -#define HDMI_SPK3L_SEL_I_PCM1R (3 << 24) -#define HDMI_SPK3L_SEL_I_PCM2L (4 << 24) -#define HDMI_SPK3L_SEL_I_PCM2R (5 << 24) -#define HDMI_SPK3L_SEL_I_PCM3L (6 << 24) -#define HDMI_SPK3L_SEL_I_PCM3R (7 << 24) -#define HDMI_SPK2R_SEL_I_PCM0L (0 << 19) -#define HDMI_SPK2R_SEL_I_PCM0R (1 << 19) -#define HDMI_SPK2R_SEL_I_PCM1L (2 << 19) -#define HDMI_SPK2R_SEL_I_PCM1R (3 << 19) -#define HDMI_SPK2R_SEL_I_PCM2L (4 << 19) -#define HDMI_SPK2R_SEL_I_PCM2R (5 << 19) -#define HDMI_SPK2R_SEL_I_PCM3L (6 << 19) -#define HDMI_SPK2R_SEL_I_PCM3R (7 << 19) -#define HDMI_SPK2L_SEL_I_PCM0L (0 << 16) -#define HDMI_SPK2L_SEL_I_PCM0R (1 << 16) -#define HDMI_SPK2L_SEL_I_PCM1L (2 << 16) -#define HDMI_SPK2L_SEL_I_PCM1R (3 << 16) -#define HDMI_SPK2L_SEL_I_PCM2L (4 << 16) -#define HDMI_SPK2L_SEL_I_PCM2R (5 << 16) -#define HDMI_SPK2L_SEL_I_PCM3L (6 << 16) -#define HDMI_SPK2L_SEL_I_PCM3R (7 << 16) -#define HDMI_SPK1R_SEL_I_PCM0L (0 << 11) -#define HDMI_SPK1R_SEL_I_PCM0R (1 << 11) -#define HDMI_SPK1R_SEL_I_PCM1L (2 << 11) -#define HDMI_SPK1R_SEL_I_PCM1R (3 << 11) -#define HDMI_SPK1R_SEL_I_PCM2L (4 << 11) -#define HDMI_SPK1R_SEL_I_PCM2R (5 << 11) -#define HDMI_SPK1R_SEL_I_PCM3L (6 << 11) -#define HDMI_SPK1R_SEL_I_PCM3R (7 << 11) -#define HDMI_SPK1L_SEL_I_PCM0L (0 << 8) -#define HDMI_SPK1L_SEL_I_PCM0R (1 << 8) -#define HDMI_SPK1L_SEL_I_PCM1L (2 << 8) -#define HDMI_SPK1L_SEL_I_PCM1R (3 << 8) -#define HDMI_SPK1L_SEL_I_PCM2L (4 << 8) -#define HDMI_SPK1L_SEL_I_PCM2R (5 << 8) -#define HDMI_SPK1L_SEL_I_PCM3L (6 << 8) -#define HDMI_SPK1L_SEL_I_PCM3R (7 << 8) -#define HDMI_SPK0R_SEL_I_PCM0L (0 << 3) -#define HDMI_SPK0R_SEL_I_PCM0R (1 << 3) -#define HDMI_SPK0R_SEL_I_PCM1L (2 << 3) -#define HDMI_SPK0R_SEL_I_PCM1R (3 << 3) -#define HDMI_SPK0R_SEL_I_PCM2L (4 << 3) -#define HDMI_SPK0R_SEL_I_PCM2R (5 << 3) -#define HDMI_SPK0R_SEL_I_PCM3L (6 << 3) -#define HDMI_SPK0R_SEL_I_PCM3R (7 << 3) -#define HDMI_SPK0L_SEL_I_PCM0L (0) -#define HDMI_SPK0L_SEL_I_PCM0R (1) -#define HDMI_SPK0L_SEL_I_PCM1L (2) -#define HDMI_SPK0L_SEL_I_PCM1R (3) -#define HDMI_SPK0L_SEL_I_PCM2L (4) -#define HDMI_SPK0L_SEL_I_PCM2R (5) -#define HDMI_SPK0L_SEL_I_PCM3L (6) -#define HDMI_SPK0L_SEL_I_PCM3R (7) - -/* ACR_CON */ -#define HDMI_ALT_CTS_RATE_CTS_1 (0 << 3) -#define HDMI_ALT_CTS_RATE_CTS_11 (1 << 3) -#define HDMI_ALT_CTS_RATE_CTS_21 (2 << 3) -#define HDMI_ALT_CTS_RATE_CTS_31 (3 << 3) -#define HDMI_ACR_TX_MODE_NO_TX (0) -#define HDMI_ACR_TX_MODE_TX_ONCE (1) -#define HDMI_ACR_TX_MODE_TXCNT_VBI (2) -#define HDMI_ACR_TX_MODE_TX_VPC (3) -#define HDMI_ACR_TX_MODE_MESURE_CTS (4) - -/* ACR_MCTS0/1/2 */ - -/* ACR_CTS0/1/2 */ - -/* ACR_N0/1/2 */ - -/* ACR_LSB2 */ -#define HDMI_ACR_LSB2_MASK (0xFF) - -/* ACR_TXCNT */ -#define HDMI_ACR_TXCNT_MASK (0x1F) - -/* ACR_TXINTERNAL */ -#define HDMI_ACR_TX_INTERNAL_MASK (0xFF) - -/* ACR_CTS_OFFSET */ -#define HDMI_ACR_CTS_OFFSET_MASK (0xFF) - -/* GCP_CON */ -#define HDMI_GCP_CON_EN_1ST_VSYNC (1 << 3) -#define HDMI_GCP_CON_EN_2ST_VSYNC (1 << 2) -#define HDMI_GCP_CON_TRANS_EVERY_VSYNC (2) -#define HDMI_GCP_CON_NO_TRAN (0) -#define HDMI_GCP_CON_TRANS_ONCE (1) -#define HDMI_GCP_CON_TRANS_EVERY_VSYNC (2) - -/* GCP_BYTE1 */ -#define HDMI_GCP_BYTE1_MASK (0xFF) - -/* GCP_BYTE2 */ -#define HDMI_GCP_BYTE2_PP_MASK (0xF << 4) -#define HDMI_GCP_24BPP (1 << 2) -#define HDMI_GCP_30BPP (1 << 0 | 1 << 2) -#define HDMI_GCP_36BPP (1 << 1 | 1 << 2) -#define HDMI_GCP_48BPP (1 << 0 | 1 << 1 | 1 << 2) - -/* GCP_BYTE3 */ -#define HDMI_GCP_BYTE3_MASK (0xFF) - -/* Timing generator registers */ -/* TG configure/status registers */ -#define HDMI_TG_VACT_ST3_L HDMI_TG_BASE(0x0068) -#define HDMI_TG_VACT_ST3_H HDMI_TG_BASE(0x006c) -#define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070) -#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) -#define HDMI_TG_3D HDMI_TG_BASE(0x00F0) - -#endif /* SAMSUNG_REGS_HDMI_H */ diff --git a/drivers/gpu/drm/exynos_tmp/regs-mixer.h b/drivers/gpu/drm/exynos_tmp/regs-mixer.h deleted file mode 100644 index fd2f4d1..0000000 --- a/drivers/gpu/drm/exynos_tmp/regs-mixer.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-mixer.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Mixer register header file for Samsung Mixer driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ -#ifndef SAMSUNG_REGS_MIXER_H -#define SAMSUNG_REGS_MIXER_H - -/* - * Register part - */ -#define MXR_STATUS 0x0000 -#define MXR_CFG 0x0004 -#define MXR_INT_EN 0x0008 -#define MXR_INT_STATUS 0x000C -#define MXR_LAYER_CFG 0x0010 -#define MXR_VIDEO_CFG 0x0014 -#define MXR_GRAPHIC0_CFG 0x0020 -#define MXR_GRAPHIC0_BASE 0x0024 -#define MXR_GRAPHIC0_SPAN 0x0028 -#define MXR_GRAPHIC0_SXY 0x002C -#define MXR_GRAPHIC0_WH 0x0030 -#define MXR_GRAPHIC0_DXY 0x0034 -#define MXR_GRAPHIC0_BLANK 0x0038 -#define MXR_GRAPHIC1_CFG 0x0040 -#define MXR_GRAPHIC1_BASE 0x0044 -#define MXR_GRAPHIC1_SPAN 0x0048 -#define MXR_GRAPHIC1_SXY 0x004C -#define MXR_GRAPHIC1_WH 0x0050 -#define MXR_GRAPHIC1_DXY 0x0054 -#define MXR_GRAPHIC1_BLANK 0x0058 -#define MXR_BG_CFG 0x0060 -#define MXR_BG_COLOR0 0x0064 -#define MXR_BG_COLOR1 0x0068 -#define MXR_BG_COLOR2 0x006C -#define MXR_CM_COEFF_Y 0x0080 -#define MXR_CM_COEFF_CB 0x0084 -#define MXR_CM_COEFF_CR 0x0088 -#define MXR_GRAPHIC0_BASE_S 0x2024 -#define MXR_GRAPHIC1_BASE_S 0x2044 - -/* for parametrized access to layer registers */ -#define MXR_GRAPHIC_CFG(i) (0x0020 + (i) * 0x20) -#define MXR_GRAPHIC_BASE(i) (0x0024 + (i) * 0x20) -#define MXR_GRAPHIC_SPAN(i) (0x0028 + (i) * 0x20) -#define MXR_GRAPHIC_SXY(i) (0x002C + (i) * 0x20) -#define MXR_GRAPHIC_WH(i) (0x0030 + (i) * 0x20) -#define MXR_GRAPHIC_DXY(i) (0x0034 + (i) * 0x20) -#define MXR_GRAPHIC_BLANK(i) (0x0038 + (i) * 0x20) -#define MXR_GRAPHIC_BASE_S(i) (0x2024 + (i) * 0x20) - -/* - * Bit definition part - */ - -/* generates mask for range of bits */ -#define MXR_MASK(high_bit, low_bit) \ - (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit)) - -#define MXR_MASK_VAL(val, high_bit, low_bit) \ - (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit)) - -/* bits for MXR_STATUS */ -#define MXR_STATUS_16_BURST (1 << 7) -#define MXR_STATUS_BURST_MASK (1 << 7) -#define MXR_STATUS_BIG_ENDIAN (1 << 3) -#define MXR_STATUS_ENDIAN_MASK (1 << 3) -#define MXR_STATUS_SYNC_ENABLE (1 << 2) -#define MXR_STATUS_REG_RUN (1 << 0) - -/* bits for MXR_CFG */ -#define MXR_CFG_RGB601_0_255 (0 << 9) -#define MXR_CFG_RGB601_16_235 (1 << 9) -#define MXR_CFG_RGB709_0_255 (2 << 9) -#define MXR_CFG_RGB709_16_235 (3 << 9) -#define MXR_CFG_RGB_FMT_MASK 0x600 -#define MXR_CFG_OUT_YUV444 (0 << 8) -#define MXR_CFG_OUT_RGB888 (1 << 8) -#define MXR_CFG_OUT_MASK (1 << 8) -#define MXR_CFG_DST_SDO (0 << 7) -#define MXR_CFG_DST_HDMI (1 << 7) -#define MXR_CFG_DST_MASK (1 << 7) -#define MXR_CFG_SCAN_HD_720 (0 << 6) -#define MXR_CFG_SCAN_HD_1080 (1 << 6) -#define MXR_CFG_GRP1_ENABLE (1 << 5) -#define MXR_CFG_GRP0_ENABLE (1 << 4) -#define MXR_CFG_VP_ENABLE (1 << 3) -#define MXR_CFG_SCAN_INTERLACE (0 << 2) -#define MXR_CFG_SCAN_PROGRASSIVE (1 << 2) -#define MXR_CFG_SCAN_NTSC (0 << 1) -#define MXR_CFG_SCAN_PAL (1 << 1) -#define MXR_CFG_SCAN_SD (0 << 0) -#define MXR_CFG_SCAN_HD (1 << 0) -#define MXR_CFG_SCAN_MASK 0x47 - -/* bits for MXR_GRAPHICn_CFG */ -#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21) -#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) -#define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) -#define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) -#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) -#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) -#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) - -/* bits for MXR_GRAPHICn_WH */ -#define MXR_GRP_WH_H_SCALE(x) MXR_MASK_VAL(x, 28, 28) -#define MXR_GRP_WH_V_SCALE(x) MXR_MASK_VAL(x, 12, 12) -#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_GRAPHICn_SXY */ -#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_GRAPHICn_DXY */ -#define MXR_GRP_DXY_DX(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_DXY_DY(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_INT_EN */ -#define MXR_INT_EN_VSYNC (1 << 11) -#define MXR_INT_EN_ALL (0x0f << 8) - -/* bit for MXR_INT_STATUS */ -#define MXR_INT_CLEAR_VSYNC (1 << 11) -#define MXR_INT_STATUS_VSYNC (1 << 0) - -/* bit for MXR_LAYER_CFG */ -#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8) -#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4) -#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0) - -#endif /* SAMSUNG_REGS_MIXER_H */ - diff --git a/drivers/gpu/drm/exynos_tmp/regs-vp.h b/drivers/gpu/drm/exynos_tmp/regs-vp.h deleted file mode 100644 index 10b737a..0000000 --- a/drivers/gpu/drm/exynos_tmp/regs-vp.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-vp.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Video processor register header file for Samsung Mixer driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef SAMSUNG_REGS_VP_H -#define SAMSUNG_REGS_VP_H - -/* - * Register part - */ - -#define VP_ENABLE 0x0000 -#define VP_SRESET 0x0004 -#define VP_SHADOW_UPDATE 0x0008 -#define VP_FIELD_ID 0x000C -#define VP_MODE 0x0010 -#define VP_IMG_SIZE_Y 0x0014 -#define VP_IMG_SIZE_C 0x0018 -#define VP_PER_RATE_CTRL 0x001C -#define VP_TOP_Y_PTR 0x0028 -#define VP_BOT_Y_PTR 0x002C -#define VP_TOP_C_PTR 0x0030 -#define VP_BOT_C_PTR 0x0034 -#define VP_ENDIAN_MODE 0x03CC -#define VP_SRC_H_POSITION 0x0044 -#define VP_SRC_V_POSITION 0x0048 -#define VP_SRC_WIDTH 0x004C -#define VP_SRC_HEIGHT 0x0050 -#define VP_DST_H_POSITION 0x0054 -#define VP_DST_V_POSITION 0x0058 -#define VP_DST_WIDTH 0x005C -#define VP_DST_HEIGHT 0x0060 -#define VP_H_RATIO 0x0064 -#define VP_V_RATIO 0x0068 -#define VP_POLY8_Y0_LL 0x006C -#define VP_POLY4_Y0_LL 0x00EC -#define VP_POLY4_C0_LL 0x012C - -/* - * Bit definition part - */ - -/* generates mask for range of bits */ - -#define VP_MASK(high_bit, low_bit) \ - (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit)) - -#define VP_MASK_VAL(val, high_bit, low_bit) \ - (((val) << (low_bit)) & VP_MASK(high_bit, low_bit)) - - /* VP_ENABLE */ -#define VP_ENABLE_ON (1 << 0) - -/* VP_SRESET */ -#define VP_SRESET_PROCESSING (1 << 0) - -/* VP_SHADOW_UPDATE */ -#define VP_SHADOW_UPDATE_ENABLE (1 << 0) - -/* VP_MODE */ -#define VP_MODE_NV12 (0 << 6) -#define VP_MODE_NV21 (1 << 6) -#define VP_MODE_LINE_SKIP (1 << 5) -#define VP_MODE_MEM_LINEAR (0 << 4) -#define VP_MODE_MEM_TILED (1 << 4) -#define VP_MODE_FMT_MASK (5 << 4) -#define VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2) -#define VP_MODE_2D_IPC (1 << 1) - -/* VP_IMG_SIZE_Y */ -/* VP_IMG_SIZE_C */ -#define VP_IMG_HSIZE(x) VP_MASK_VAL(x, 29, 16) -#define VP_IMG_VSIZE(x) VP_MASK_VAL(x, 13, 0) - -/* VP_SRC_H_POSITION */ -#define VP_SRC_H_POSITION_VAL(x) VP_MASK_VAL(x, 14, 4) - -/* VP_ENDIAN_MODE */ -#define VP_ENDIAN_MODE_LITTLE (1 << 0) - -#endif /* SAMSUNG_REGS_VP_H */ |