From patchwork Thu Dec 6 12:08:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chandrasekar R X-Patchwork-Id: 1845381 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 945EF3FCA5 for ; Thu, 6 Dec 2012 15:42:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 53238E5F83 for ; Thu, 6 Dec 2012 07:42:40 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) by gabe.freedesktop.org (Postfix) with ESMTP id 38065E676D for ; Thu, 6 Dec 2012 04:13:12 -0800 (PST) Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MEL00MOXZ9638J0@mailout2.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 06 Dec 2012 21:12:42 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.125]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 10.ED.01231.ABB80C05; Thu, 06 Dec 2012 21:12:42 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-2a-50c08bba9b63 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 8F.DD.01231.9BB80C05; Thu, 06 Dec 2012 21:12:41 +0900 (KST) Received: from sekar-ubuntu.sisodomain.com ([107.108.73.178]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MEL008T3Z2ZPL00@mmp1.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 06 Dec 2012 21:12:41 +0900 (KST) From: "R. Chandrasekar" To: linux-samsung-soc@vger.kernel.org, devicetree-discuss@lists.ozlabs.org, dri-devel@lists.freedesktop.org Subject: [PATCH 3/3] drm: mie: add mie driver for exynos Date: Thu, 06 Dec 2012 17:38:15 +0530 Message-id: <1354795695-28009-4-git-send-email-rcsekar@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1354795695-28009-1-git-send-email-rcsekar@samsung.com> References: <1354795695-28009-1-git-send-email-rcsekar@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrDLMWRmVeSWpSXmKPExsWyRsSkVndX94EAg85d3BZXvr5nc2D0uN99 nCmAMYrLJiU1J7MstUjfLoErY8/544wFvxIrvqzawtbAuC2gi5GTQ0LARKK/YSkbhC0mceHe eiCbi0NIYCmjxK21y9hhim48OMkCYgsJLGKUOHNcFKJoA5NE08ELjCAJNgFdifcdD8CKRARy JRr+trOAFDEL9DNKrGy5CpYQFrCQePf/GzOIzSKgKnHg53awZl4BZ4mDOztYuxg5gLYpSMyZ ZAMS5hRwkfjS+pwZYrGzxN8F65ggWgUkvk0+xAJRLiux6QAzyCoJgdtsEq1zH0F9IylxcMUN lgmMwgsYGVYxiqYWJBcUJ6XnGuoVJ+YWl+al6yXn525iBAbh6X/PpHYwrmywOMQowMGoxMNr Wb0/QIg1say4MvcQowQHs5IIb0zHgQAh3pTEyqrUovz4otKc1OJDjD5Al0xklhJNzgdGSF5J vKGxibmpsamlkZGZqSkOYSVx3maPlAAhgfTEktTs1NSC1CKYcUwcnFINjLWtppMUTtvKfrof 9a51S8mZxxP2OX42eJ6UyZEimxYeoGod1ysWbFhldECv2ves+auT02SZYj9tlpXkdPjatMV6 B6f4+VThprsTuVdJpCwPY0i05WdfXv6Eveb+m5mJc9oTCkV2+q7gfpB/56Ht5eX7J8lOuFx7 dtfU9Q3HXrTu+TLx3Jv1X5RYijMSDbWYi4oTAXsvrjtvAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmkeLIzCtJLcpLzFFi42I5/e+xgO7O7gMBBqc+WVpc+fqezYHR4373 caYAxqgGRpuM1MSU1CKF1Lzk/JTMvHRbJe/geOd4UzMDQ11DSwtzJYW8xNxUWyUXnwBdt8wc oLFKCmWJOaVAoYDE4mIlfTtME0JD3HQtYBojdH1DguB6jAzQQMIaxow9548zFvxKrPiyagtb A+O2gC5GTg4JAROJGw9OskDYYhIX7q1nA7GFBBYxSpw5LtrFyAVkb2CSaDp4gREkwSagK/G+ 4wFYg4hArkTD33YWkCJmgX5GiZUtV8ESwgIWEu/+f2MGsVkEVCUO/NwO1swr4CxxcGcHaxcj B9A2BYk5k2xAwpwCLhJfWp8zQyx2lvi7YB3TBEbeBYwMqxhFUwuSC4qT0nMN9YoTc4tL89L1 kvNzNzGCQ/yZ1A7GlQ0WhxgFOBiVeHgtq/cHCLEmlhVX5h5ilOBgVhLhjek4ECDEm5JYWZVa lB9fVJqTWnyI0QfoqInMUqLJ+cD4yyuJNzQ2MTc1NrU0sTAxs8QhrCTO2+yREiAkkJ5Ykpqd mlqQWgQzjomDU6qBMf/lBAXZW/E3dYo6L+fP7JozZYJ4WYqor+tSpWkRh6UCLAM6Zp/nvLn6 Us4t3s7nk7l3NjsUTy1+WdmRFPxs5q2Z72esl1KbOfftfZUZXyVMNq85Kxp/8cBnttrTz7y/ fn/xsqXWp8WkSzmitvvZpzMH5+zMXpDv0Rq64KXBNCWBPy+q5jrf5VJiKc5INNRiLipOBAC4 8/LRngIAAA== X-CFilter-Loop: Reflected X-Mailman-Approved-At: Thu, 06 Dec 2012 07:30:39 -0800 Cc: kgene.kim@samsung.com, rcsekar@samsung.com, joshi@samsung.com, kyungmin.park@samsung.com, rcsekar.samsung@gmail.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: "R. Chandrasekar" Adding driver for the Mobile Image Enhancement (MIE) module of exynos SoC. This cl scope is limited to dithereing. mie dithering function is enabled from fimd Signed-off-by: R. Chandrasekar Change-Id: I05be2a2a5484719ff7bdeff722d95223191b077f --- drivers/gpu/drm/exynos/Kconfig | 7 + drivers/gpu/drm/exynos/Makefile | 1 + drivers/gpu/drm/exynos/exynos_drm_mie.c | 250 ++++++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_mie.h | 50 ++++++ drivers/gpu/drm/exynos/exynos_regs-mie.h | 75 +++++++++ 5 files changed, 383 insertions(+) create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mie.c create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mie.h create mode 100644 drivers/gpu/drm/exynos/exynos_regs-mie.h diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 86fb75d..6a0794f 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -28,6 +28,13 @@ config DRM_EXYNOS_FIMD help Choose this option if you want to use Exynos FIMD for DRM. +config DRM_EXYNOS_MIE + bool "Exynos DRM MIE" + depends on DRM_EXYNOS + help + Choose this option if you want to use Exynos MIE for DRM. + MIE provides only dithering functionality. + config DRM_EXYNOS_HDMI bool "Exynos DRM HDMI" depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 26813b8..aa25e9d 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile @@ -16,5 +16,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.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_MIE) += exynos_drm_mie.o obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o diff --git a/drivers/gpu/drm/exynos/exynos_drm_mie.c b/drivers/gpu/drm/exynos/exynos_drm_mie.c new file mode 100644 index 0000000..63de92c --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_drm_mie.c @@ -0,0 +1,250 @@ +/* exynos_drm_mie.c + * + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * Authors: + * R. Chandrasekar + * + * 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 +#include +#include +#include +#include "exynos_drm_drv.h" +#include "exynos_regs-mie.h" +#include "exynos_drm_mie.h" +#include "exynos_drm_fimd_common.h" + +struct mie_context { + void __iomem *regs; + struct mie_plugin plugin; + bool enabled; + bool configured; +}; + +#define get_mie_context(dev) platform_get_drvdata(to_platform_device(dev)) + +static int mie_dither_enable(struct device *dev, bool enable) +{ + struct mie_context *ctx = NULL; + int reg; + + DRM_DEBUG_KMS(" %s Called\n", __func__); + + if (!dev) { + DRM_DEBUG_KMS("[mie] invalid device @ %s\n", __func__); + return -EINVAL; + } + + ctx = get_mie_context(dev); + + if (!ctx) { + dev_err(dev, "[mie] invalid context.\n"); + return -EINVAL; + } + + reg = readl(ctx->regs + MIE_AUXCON); + reg &= ~MIE_DITHCON_EN; /* Clear Enable */ + + if (enable) { + if (!ctx->configured) { + DRM_DEBUG_KMS("MIE Not Configured "); + DRM_DEBUG_KMS("Confgure mie before calling enable\n"); + return -EINVAL; + } + reg |= MIE_DITHCON_EN; /* Set Enable */ + } + + writel(MIE_DITHCON_EN, ctx->regs + MIE_AUXCON); + ctx->enabled = enable; + + return 0; +} + +static int mie_configure_dither(struct device *dev, + struct mie_settings *settings) +{ + struct mie_context *ctx; + unsigned long val; + int i, rgb_mode; + + DRM_DEBUG_KMS(" %s Called\n", __func__); + + if (!dev) { + DRM_DEBUG_KMS("[mie] invalid mie device @ %s\n", __func__); + return -EINVAL; + } + + if (!settings) { + DRM_DEBUG_KMS("[mie] Settings ptr is null @ %s\n", __func__); + return -EINVAL; + } + + ctx = get_mie_context(dev); + + if (!ctx) { + dev_err(dev, "[mie] invalid context.\n"); + return -EINVAL; + } + + DRM_DEBUG_KMS("Xres = %d, Yres = %d, LeftMargin = %d\n", settings->xres, + settings->yres, settings->left_margin); + + if (settings->dither_mode == DITHER_6BIT) + rgb_mode = MIE_RGB6MODE; + else if (settings->dither_mode == DITHER_8BIT) + rgb_mode = MIE_RGB8MODE; + else + return -EINVAL; + + writel(MIE_HRESOL(settings->xres) | MIE_VRESOL(settings->yres) | + MIE_MODE_UI, ctx->regs + MIE_CTRL1); + + writel(MIE_WINHADDR0(0) | MIE_WINHADDR1(settings->xres), + ctx->regs + MIE_WINHADDR); + writel(MIE_WINVADDR0(0) | MIE_WINVADDR1(settings->yres), + ctx->regs + MIE_WINVADDR); + + val = (settings->xres + settings->left_margin + + settings->right_margin + settings->hsync_len) * + (settings->yres + settings->upper_margin + + settings->lower_margin + settings->vsync_len) / + (MIE_PWMCLKVAL + 1); + + writel(PWMCLKCNT(val), ctx->regs + MIE_PWMCLKCNT); + + writel((MIE_VBPD(settings->upper_margin)) | + MIE_VFPD(settings->lower_margin) | + MIE_VSPW(settings->vsync_len), ctx->regs + MIE_PWMVIDTCON1); + + writel(MIE_HBPD(settings->left_margin) | + MIE_HFPD(settings->right_margin) | + MIE_HSPW(settings->hsync_len), ctx->regs + MIE_PWMVIDTCON2); + + val = readl(ctx->regs + MIE_AUXCON); + val &= ~MIE_RGBMODE; + val |= rgb_mode; + writel(val, ctx->regs + MIE_AUXCON); + writel(MIE_RGB8MODE, ctx->regs + MIE_AUXCON); + + + /* Bypass MIE image brightness enhancement */ + for (i = 0; i <= MIE_MAX_BRIGHTNESS_CNT_REGS; i += 4) { + writel(0, ctx->regs + MIE_BRIGTNESS_REG1_OFFSET + i); + writel(0, ctx->regs + MIE_BRIGTNESS_REG2_OFFSET + i); + } + + ctx->configured = true; + + return 0; +} + + +int mie_get_dither_state(struct device *dev, bool *is_enabled) +{ + struct mie_context *ctx = NULL; + + DRM_DEBUG_KMS(" %s Called\n", __func__); + + if (!dev) { + DRM_DEBUG_KMS("[mie] invalid device.\n"); + return -EINVAL; + } + + ctx = get_mie_context(dev); + + if ((ctx) && (is_enabled)) + *is_enabled = ctx->enabled; + else + return -EINVAL; + + return 0; +} + +static int __devinit mie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mie_context *ctx; + struct resource *res; + + DRM_DEBUG_KMS(" %s Called\n", __func__); + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + dev_err(dev, "[mie] context alocation failed\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "[mie] failed to find registers\n"); + return -ENOENT; + } + + ctx->regs = devm_request_and_ioremap(dev, res); + if (!ctx->regs) { + dev_err(dev, "[mie] failed to map registers\n"); + return -ENXIO; + } + + ctx->configured = false; + ctx->enabled = false; + + ctx->plugin.dev = dev; + ctx->plugin.ops.fn_dither_enable = mie_dither_enable; + ctx->plugin.ops.fn_get_dither_state = mie_get_dither_state; + ctx->plugin.ops.fn_configure_dither = mie_configure_dither; + + fimd_add_mie_plugin(&ctx->plugin); + + platform_set_drvdata(pdev, ctx); + + return 0; +} + +static int __devexit mie_remove(struct platform_device *pdev) +{ + DRM_DEBUG_KMS(" %s Called\n", __func__); + return 0; +} + +static const struct of_device_id mie_dt_match[] = { + { + .compatible = "samsung,exynos5-mie", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, mie_dt_match); + +struct platform_device_id mie_driver_ids[] = { + { + .name = "exynos5-mie", + }, + {}, +}; + +MODULE_DEVICE_TABLE(platform, exynos_drm_driver_ids); + +struct platform_driver mie_driver = { + .probe = mie_probe, + .remove = __devexit_p(mie_remove), + .id_table = mie_driver_ids, + .driver = { + .name = "exynos-drm-mie", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mie_dt_match), + }, +}; + +module_platform_driver(mie_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("R. Chandrasekar "); +MODULE_DESCRIPTION("Samsung Mobile Image Enhancement Driver"); diff --git a/drivers/gpu/drm/exynos/exynos_drm_mie.h b/drivers/gpu/drm/exynos/exynos_drm_mie.h new file mode 100644 index 0000000..f6eaad8 --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_drm_mie.h @@ -0,0 +1,50 @@ +/* exynos_drm_mie.h + * + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * Authors: + * R. Chandrasekar + * + * 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. + * + */ + +#ifndef __EXYNOS_DRM_MIE_H +#define __EXYNOS_DRM_MIE_H + +#define MIE_DITHER_EN 1 + +enum en_dither_mode { + DITHER_6BIT, + DITHER_8BIT, + + INVALID_DITHER_MODE +}; + +struct mie_settings { + u32 xres; + u32 yres; + u32 left_margin; + u32 right_margin; + u32 upper_margin; + u32 lower_margin; + u32 hsync_len; + u32 vsync_len; + enum en_dither_mode dither_mode; +}; + +struct mie_plugin_ops { + int (*fn_dither_enable)(struct device *dev, bool enable); + int (*fn_get_dither_state)(struct device *dev, bool *is_enabled); + int (*fn_configure_dither)(struct device *dev, + struct mie_settings *settings); +}; + +struct mie_plugin { + struct device *dev; + struct mie_plugin_ops ops; +}; + +#endif /*__EXYNOS_DRM_MIE_H */ diff --git a/drivers/gpu/drm/exynos/exynos_regs-mie.h b/drivers/gpu/drm/exynos/exynos_regs-mie.h new file mode 100644 index 0000000..6b3dba2 --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_regs-mie.h @@ -0,0 +1,75 @@ +/* exynos_regs-mie.h + * + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * Authors: + * R. Chandrasekar + * + * 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. + * + */ + +#ifndef __EXYNOS_REGS_MIE_H +#define __EXYNOS_REGS_MIE_H + +#define MIE_MAX_BRIGHTNESS_CNT_REGS 0x30 /* Max Brightness registers */ +#define MIE_BRIGTNESS_REG1_OFFSET 0x100 /* Brightness register set1 */ +#define MIE_BRIGTNESS_REG2_OFFSET 0x200 /* Brightness register set1 */ + +/* MIE registers */ + +#define MIE_CTRL1 0x0 /* MIE Control Register 1 */ +#define MIE_HRESOL_SHIFT 18 +#define MIE_HRESOL(x) ((x & 0xfff) << MIE_HRESOL_SHIFT) +#define MIE_VRESOL_SHIFT 7 +#define MIE_VRESOL(x) ((x & 0x7ff) << MIE_VRESOL_SHIFT) +#define MIE_MODE_UI (1 << 5) + +/* Specifies Horizontal window position */ +#define MIE_WINHADDR 0x10 +#define MIE_WINHADDR0_SHIFT 0 +#define MIE_WINHADDR1_SHIFT 20 +#define MIE_WINHADDR0(x) ((x & 0xfff) << MIE_WINHADDR0_SHIFT) +#define MIE_WINHADDR1(x) (((x-1) & 0xfff)\ + << MIE_WINHADDR1_SHIFT) + +/* Specifies Vertical window position */ +#define MIE_WINVADDR 0x14 +#define MIE_WINVADDR0_SHIFT 0 +#define MIE_WINVADDR1_SHIFT 21 +#define MIE_WINVADDR0(x) ((x & 0x7ff) << MIE_WINVADDR0_SHIFT) +#define MIE_WINVADDR1(x) (((x - 1) & 0x7ff)\ + << MIE_WINVADDR1_SHIFT) + +/* PWM Clock Count Register */ +#define MIE_PWMCLKCNT 0x20 +#define MIE_PWMCLKVAL 1 +#define PWMCLKCNT(x) ((x & 0x3fffff) << 4) + +/* PWM Control Register 1 */ +#define MIE_PWMVIDTCON1 0x38 +#define MIE_VBPD(x) ((x - 1) << 16) +#define MIE_VFPD(x) ((x - 1) << 8) +#define MIE_VSPW(x) (x - 1) + +/* PWM Control Register 2 */ +#define MIE_PWMVIDTCON2 0x3c +#define MIE_HBPD(x) ((x - 1) << 16) +#define MIE_HFPD(x) ((x - 1) << 8) +#define MIE_HSPW(x) (x - 1) + +/* AUX Control Register */ +#define MIE_AUXCON 0x300 +#define MIE_DITHCON 1 +#define MIE_DITHCON_EN 0x1 +#define MIE_DITHCON_DISABLE 0 + +#define MIE_RGBMODE 2 +#define MIE_RGBMODE_SHIFT 1 +#define MIE_RGB6MODE (0 << MIE_RGBMODE_SHIFT) +#define MIE_RGB8MODE (1 << MIE_RGBMODE_SHIFT) + +#endif /* __EXYNOS_REGS_MIE_H */ +