From patchwork Wed Apr 2 17:13:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 3933241 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3E3A2C0DA2 for ; Thu, 3 Apr 2014 15:52:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2C39D20272 for ; Thu, 3 Apr 2014 15:52:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1FB2A202EA for ; Thu, 3 Apr 2014 15:52:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 617316E46E; Thu, 3 Apr 2014 08:52:07 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by gabe.freedesktop.org (Postfix) with ESMTP id 44C596EBD4 for ; Wed, 2 Apr 2014 10:14:30 -0700 (PDT) Received: from epcpsbgr4.samsung.com (u144.gpu120.samsung.co.kr [203.254.230.144]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N3E00JM6YK5Q6C0@mailout3.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 03 Apr 2014 02:14:29 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.123]) by epcpsbgr4.samsung.com (EPCPMTA) with SMTP id B5.D8.10364.5754C335; Thu, 03 Apr 2014 02:14:29 +0900 (KST) X-AuditID: cbfee690-b7f266d00000287c-36-533c4575e36c Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 19.83.29263.5754C335; Thu, 03 Apr 2014 02:14:29 +0900 (KST) Received: from localhost.localdomain ([107.108.83.245]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N3E008ZSYJTP380@mmp1.samsung.com>; Thu, 03 Apr 2014 02:14:29 +0900 (KST) From: Rahul Sharma To: dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH 4/5] drm/exynos: add support for apb mapped phys in hdmi driver Date: Wed, 02 Apr 2014 22:43:45 +0530 Message-id: <1396458826-3051-5-git-send-email-rahul.sharma@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1396458826-3051-1-git-send-email-rahul.sharma@samsung.com> References: <1396458826-3051-1-git-send-email-rahul.sharma@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrFLMWRmVeSWpSXmKPExsWyRsSkWrfU1SbY4MA1eYsrX9+zWUy6P4HF 4vuuL+wWM87vY7JY+CLeYsqiw6wObB47Z91l97jffZzJo2/LKkaPz5vkAliiuGxSUnMyy1KL 9O0SuDJmfTvNUvDNuuLFiltMDYxbDboYOTkkBEwkJv9pZ4SwxSQu3FvP1sXIxSEksJRRYtPZ 66wwRef39LFAJBYxShzafRKqqp1J4s3uG0wgVWwCuhKzDz4DGyUi4CbRdHgmWDezQLbE4QMv geIcHMIC/hLXjimDhFkEVCX6Z08Aa+UVcJdY8/4NO0iJhICCxJxJNiBhTgEPiU9PX4NNFAIq +bynmRVkrYRAN7vEq+vdrBBzBCS+TT7EAtErK7HpADPEzZISB1fcYJnAKLyAkWEVo2hqQXJB cVJ6kYlecWJucWleul5yfu4mRmA4n/73bMIOxnsHrA8xJgONm8gsJZqcD4yHvJJ4Q2MzIwtT E1NjI3NLM9KElcR51R4lBQkJpCeWpGanphakFsUXleakFh9iZOLglGpgXLByztWDj3m1KwWM v39T6vlbX2Z6Tv//DS6LvveV+z6WLjtd7hp3MOaaSrLGzdDX2tYPWd93P/my/P3Eb7rHDey2 X+L2FgnQFmIo/NW7PubafKkJGTKJovOyy1OflnQqyQdybNcPZndIadrIddc0fQXnNSPzLNHq FwpF62ubxA9YLT3FlyyjxFKckWioxVxUnAgA4Z60CH0CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrOIsWRmVeSWpSXmKPExsVy+t9jAd1SV5tgg02fhS2ufH3PZjHp/gQW i++7vrBbzDi/j8li4Yt4iymLDrM6sHnsnHWX3eN+93Emj74tqxg9Pm+SC2CJamC0yUhNTEkt UkjNS85PycxLt1XyDo53jjc1MzDUNbS0MFdSyEvMTbVVcvEJ0HXLzAFarqRQlphTChQKSCwu VtK3wzQhNMRN1wKmMULXNyQIrsfIAA0krGHMmPXtNEvBN+uKFytuMTUwbjXoYuTkkBAwkTi/ p48FwhaTuHBvPVsXIxeHkMAiRolDu09COe1MEm9232ACqWIT0JWYffAZI4gtIuAm0XR4JiuI zSyQLXH4wEugOAeHsIC/xLVjyiBhFgFVif7ZE8BaeQXcJda8f8MOUiIhoCAxZ5INSJhTwEPi 09PXYBOFgEo+72lmncDIu4CRYRWjaGpBckFxUnquoV5xYm5xaV66XnJ+7iZGcLQ8k9rBuLLB 4hCjAAejEg+vhZRNsBBrYllxZe4hRgkOZiUR3id2QCHelMTKqtSi/Pii0pzU4kOMyUBHTWSW Ek3OB0ZyXkm8obGJuamxqaWJhYmZJWnCSuK8B1qtA4UE0hNLUrNTUwtSi2C2MHFwSjUwGi4x NK0v+hfxKq/Q/OJ9lYeq5xaevVBsK9vjU28z2fGW8vtEn+4nr481cyj68tzfw+bi8vb42u08 3x48ttsl5nOBw/co1/+rfC61rQcfvlt5I4sh84JmjL38l7TTtx4wO7xiX+o8v+iDuZeoXclR GxfHHT6qSypZmX+n2sXmVTiaTdgzsbdQiaU4I9FQi7moOBEAZxcjXdoCAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-Mailman-Approved-At: Thu, 03 Apr 2014 08:52:03 -0700 Cc: joshi@samsung.com, Rahul Sharma X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Rahul Sharma Previous SoCs have hdmi phys which are accessible through dedicated i2c lines. Newer SoCs have Apb mapped hdmi phys. Hdmi driver is modified to support apb mapped phys. Signed-off-by: Rahul Sharma --- drivers/gpu/drm/exynos/exynos_hdmi.c | 142 +++++++++++++++++++++------------- drivers/gpu/drm/exynos/regs-hdmi.h | 7 ++ 2 files changed, 96 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 5b2cfe7..5989770 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,8 @@ enum hdmi_type { struct hdmi_driver_data { unsigned int type; + const struct hdmiphy_config *phy_confs; + unsigned int phy_conf_count; unsigned int is_apb_phy:1; }; @@ -196,9 +199,12 @@ struct hdmi_context { struct hdmi_resources res; int hpd_gpio; + void __iomem *regs_hdmiphy; struct regmap *pmureg; enum hdmi_type type; + const struct hdmiphy_config *phy_confs; + unsigned int phy_conf_count; }; struct hdmiphy_config { @@ -206,14 +212,6 @@ struct hdmiphy_config { u8 conf[32]; }; -struct hdmi_driver_data exynos4212_hdmi_driver_data = { - .type = HDMI_TYPE14, -}; - -struct hdmi_driver_data exynos5_hdmi_driver_data = { - .type = HDMI_TYPE14, -}; - /* list of phy config settings */ static const struct hdmiphy_config hdmiphy_v13_configs[] = { { @@ -428,6 +426,21 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = { }, }; + +struct hdmi_driver_data exynos4212_hdmi_driver_data = { + .type = HDMI_TYPE14, + .phy_confs = hdmiphy_v14_configs, + .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs), + .is_apb_phy = 0, +}; + +struct hdmi_driver_data exynos5_hdmi_driver_data = { + .type = HDMI_TYPE14, + .phy_confs = hdmiphy_v13_configs, + .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs), + .is_apb_phy = 0, +}; + static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) { return readl(hdata->regs + reg_id); @@ -447,6 +460,48 @@ static inline void hdmi_reg_writemask(struct hdmi_context *hdata, writel(value, hdata->regs + reg_id); } +static int hdmiphy_reg_writeb(struct hdmi_context *hdata, + u32 reg_offset, u8 value) +{ + if (hdata->hdmiphy_port) { + u8 buffer[2]; + int ret; + + buffer[0] = reg_offset; + buffer[1] = value; + + ret = i2c_master_send(hdata->hdmiphy_port, buffer, 2); + if (ret == 2) + return 0; + return ret; + } else { + writeb(value, hdata->regs_hdmiphy + (reg_offset<<2)); + return 0; + } +} + +static int hdmiphy_reg_write_buf(struct hdmi_context *hdata, + u32 reg_offset, const u8 *buf, u32 len) +{ + if ((reg_offset + len) > 32) + return -EINVAL; + + if (hdata->hdmiphy_port) { + int ret; + + ret = i2c_master_send(hdata->hdmiphy_port, buf, len); + if (ret == len) + return 0; + return ret; + } else { + int i; + for (i = 0; i < len; i++) + writeb(buf[i], hdata->regs_hdmiphy + + ((reg_offset + i)<<2)); + return 0; + } +} + static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) { #define DUMPREG(reg_id) \ @@ -850,20 +905,10 @@ static int hdmi_get_modes(struct drm_connector *connector) static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) { - const struct hdmiphy_config *confs; - int count, i; - - if (hdata->type == HDMI_TYPE13) { - confs = hdmiphy_v13_configs; - count = ARRAY_SIZE(hdmiphy_v13_configs); - } else if (hdata->type == HDMI_TYPE14) { - confs = hdmiphy_v14_configs; - count = ARRAY_SIZE(hdmiphy_v14_configs); - } else - return -EINVAL; + int i; - for (i = 0; i < count; i++) - if (confs[i].pixel_clock == pixel_clock) + for (i = 0; i < hdata->phy_conf_count; i++) + if (hdata->phy_confs[i].pixel_clock == pixel_clock) return i; DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); @@ -1515,17 +1560,9 @@ static void hdmiphy_poweroff(struct hdmi_context *hdata) static void hdmiphy_conf_apply(struct hdmi_context *hdata) { - const u8 *hdmiphy_data; - u8 buffer[32]; - u8 operation[2]; int ret; int i; - if (!hdata->hdmiphy_port) { - DRM_ERROR("hdmiphy is not attached\n"); - return; - } - /* pixel clock */ i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock); if (i < 0) { @@ -1533,26 +1570,17 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) return; } - if (hdata->type == HDMI_TYPE13) - hdmiphy_data = hdmiphy_v13_configs[i].conf; - else - hdmiphy_data = hdmiphy_v14_configs[i].conf; - - 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"); + ret = hdmiphy_reg_write_buf(hdata, 0, hdata->phy_confs[i].conf, 32); + if (ret) { + DRM_ERROR("failed to configure hdmiphy\n"); return; } usleep_range(10000, 12000); - /* operation mode */ - operation[0] = 0x1f; - operation[1] = 0x80; - - ret = i2c_master_send(hdata->hdmiphy_port, operation, 2); - if (ret != 2) { + ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_DISABLE_MODE_SET); + if (ret) { DRM_ERROR("failed to enable hdmiphy\n"); return; } @@ -2059,6 +2087,8 @@ static int hdmi_probe(struct platform_device *pdev) drv_data = (struct hdmi_driver_data *)match->data; hdata->type = drv_data->type; + hdata->phy_confs = drv_data->phy_confs; + hdata->phy_conf_count = drv_data->phy_conf_count; hdata->hpd_gpio = pdata->hpd_gpio; hdata->dev = dev; @@ -2092,10 +2122,6 @@ static int hdmi_probe(struct platform_device *pdev) return -ENODEV; } - /* Not support APB PHY yet. */ - if (drv_data->is_apb_phy) - return -EPERM; - /* hdmiphy i2c driver */ phy_node = of_parse_phandle(dev->of_node, "phy", 0); if (!phy_node) { @@ -2103,11 +2129,21 @@ static int hdmi_probe(struct platform_device *pdev) ret = -ENODEV; goto err_ddc; } - hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node); - if (!hdata->hdmiphy_port) { - DRM_ERROR("Failed to get hdmi phy i2c client from node\n"); - ret = -ENODEV; - goto err_ddc; + + if (drv_data->is_apb_phy) { + hdata->regs_hdmiphy = of_iomap(phy_node, 0); + if (!hdata->regs_hdmiphy) { + DRM_ERROR("failed to ioremap hdmi phy\n"); + ret = -ENOMEM; + goto err_ddc; + } + } else { + hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node); + if (!hdata->hdmiphy_port) { + DRM_ERROR("Failed to get hdmi phy i2c client\n"); + ret = -ENODEV; + goto err_ddc; + } } hdata->irq = gpio_to_irq(hdata->hpd_gpio); diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h index 9811d6f..344a5db 100644 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -578,6 +578,13 @@ #define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) #define HDMI_TG_3D HDMI_TG_BASE(0x00F0) +/* HDMI PHY Registers Offsets*/ +#define HDMIPHY_MODE_SET_DONE (0x7C >> 2) + +/* HDMI PHY Values */ +#define HDMI_PHY_DISABLE_MODE_SET 0x80 +#define HDMI_PHY_ENABLE_MODE_SET 0x00 + /* PMU Registers for PHY */ #define PMU_HDMI_PHY_CONTROL 0x700 #define PMU_HDMI_PHY_ENABLE_BIT (1<<0)