From patchwork Tue Oct 22 10:11:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 3086821 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id EA2559F2B7 for ; Wed, 23 Oct 2013 08:36:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 79B1E20138 for ; Wed, 23 Oct 2013 08:36:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D6454202BE for ; Wed, 23 Oct 2013 08:36:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C924FE64D3 for ; Wed, 23 Oct 2013 01:36:16 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) by gabe.freedesktop.org (Postfix) with ESMTP id D5FC3E69B8 for ; Tue, 22 Oct 2013 02:50:53 -0700 (PDT) Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MV200AM4DZZQVQ0@mailout1.samsung.com> for dri-devel@lists.freedesktop.org; Tue, 22 Oct 2013 18:50:52 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id A0.18.07052.C7A46625; Tue, 22 Oct 2013 18:50:52 +0900 (KST) X-AuditID: cbfee691-b7f866d000001b8c-f9-52664a7c7394 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 9F.B1.08134.B7A46625; Tue, 22 Oct 2013 18:50:52 +0900 (KST) Received: from chromeserver-PowerEdge-T410.sisodomain.com ([107.108.73.106]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MV2003SXE0AWV00@mmp1.samsung.com>; Tue, 22 Oct 2013 18:50:51 +0900 (KST) From: Rahul Sharma To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, dri-devel@lists.freedesktop.org Subject: [PATCH v2 4/7] drm/exynos: add hdmiphy pmu bit control in hdmiphy drivers Date: Tue, 22 Oct 2013 15:41:05 +0530 Message-id: <1382436668-15813-5-git-send-email-rahul.sharma@samsung.com> X-Mailer: git-send-email 1.7.10.4 In-reply-to: <1382436668-15813-1-git-send-email-rahul.sharma@samsung.com> References: <1382436668-15813-1-git-send-email-rahul.sharma@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprJIsWRmVeSWpSXmKPExsWyRsSkRrfGKy3IYE2roMX8I+dYLa58fc9m Men+BBaL77u+sFv0LrjKZrHp8TVWixnn9zFZLHwRbzFl0WFWi8Nv2lkt7m44y2gxY/JLNotV u/4wOvB6zG64yOKxc9Zddo/73ceZPDYvqffo27KK0ePzJrkAtigum5TUnMyy1CJ9uwSujAmr 1rEVfLas6Fz4jq2BcZ1BFyMnh4SAicSLM7uZIWwxiQv31rN1MXJxCAksZZS4d7CNDaboffMO RojEIkaJeR/+MEM4s5kkTs15DdbOJqArMfvgM0YQW0Sgi1HiYCcLSBGzwCNGiR2P9oAVCQuE SCzacpgVxGYRUJVY++4SE4jNK+AhsWXtMxaIdYoS3c8mgK3mFPCUuHz2EFhcCKjm17VfYEMl BC6xS5zc+Z0JYpCAxLfJIEUcQAlZiU0HoP6RlDi44gbLBEbhBYwMqxhFUwuSC4qT0otM9YoT c4tL89L1kvNzNzECo+X0v2cTdzDeP2B9iDEZaNxEZinR5HxgtOWVxBsamxlZmJqYGhuZW5qR Jqwkzpv+KClISCA9sSQ1OzW1ILUovqg0J7X4ECMTB6dUA2Psf8+C70VWbr58vtqJ1ZzSh/zd 11bY2YjdP161Z8OEDSLsy3cnZd0qLOg/zb8opeL+VP+Usv1Hazq5r4hfm6MTvXhb5NrG2Zu2 /fmkIiZz5hrv46pDW/LDtJp6ZogZvtc8y1Snf3R3KKv92ScHTzx9r6Z67q7Fn1VRm08+2dk2 T9zfMtDDqUGJpTgj0VCLuag4EQCGeI7irAIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrGIsWRmVeSWpSXmKPExsVy+t9jAd0ar7Qgg+1P2CzmHznHanHl63s2 i0n3J7BYfN/1hd2id8FVNotNj6+xWsw4v4/JYuGLeIspiw6zWhx+085qcXfDWUaLGZNfslms 2vWH0YHXY3bDRRaPnbPusnvc7z7O5LF5Sb1H35ZVjB6fN8kFsEU1MNpkpCampBYppOYl56dk 5qXbKnkHxzvHm5oZGOoaWlqYKynkJeam2iq5+AToumXmAB2qpFCWmFMKFApILC5W0rfDNCE0 xE3XAqYxQtc3JAiux8gADSSsYcyYsGodW8Fny4rOhe/YGhjXGXQxcnJICJhIvG/ewQhhi0lc uLeerYuRi0NIYBGjxLwPf5ghnNlMEqfmvGYGqWIT0JWYffAZWIeIQBejxMFOFpAiZoFHjBI7 Hu0BKxIWCJFYtOUwK4jNIqAqsfbdJSYQm1fAQ2LL2mcsEOsUJbqfTWADsTkFPCUunz0EFhcC qvl17RfLBEbeBYwMqxhFUwuSC4qT0nON9IoTc4tL89L1kvNzNzGCY/GZ9A7GVQ0WhxgFOBiV eHgzrFKDhFgTy4orcw8xSnAwK4nw/jVMCxLiTUmsrEotyo8vKs1JLT7EmAx01URmKdHkfGCa yCuJNzQ2MTc1NrU0sTAxsyRNWEmc92CrdaCQQHpiSWp2ampBahHMFiYOTqkGxqav5SzF/uzf 9x7sXPH8dv/3FTkGXje/nGIyFOpcPGu18CUB6x0aUSfZ/x+T3vSOP/DUPO3vjYv7/7uyHj51 9TtL7/GH8/c5JfoVWG+b+3jmormXc7LcFhr4NP9e1Ru6zUN47bwfjq1sc9IDH5UIu/dFukyY WLJB0PKh8GHHH/4Hu8+vPvLnTaQSS3FGoqEWc1FxIgDs6MGlCQMAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-Mailman-Approved-At: Wed, 23 Oct 2013 01:32:23 -0700 Cc: kgene.kim@samsung.com, sw0312.kim@samsung.com, joshi@samsung.com, s.nawrocki@samsung.com, Rahul Sharma 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 X-Spam-Status: No, score=-4.6 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 Before hdmiphy operation like config, start etc, hdmiphy bit in PMU block should be enabled. Earlier this happens in hdmi driver through a dummy "hdmiphy" clock. Pmu bit control is added in both i2c and platform driver for exynos hdmiphy. Signed-off-by: Rahul Sharma --- .../devicetree/bindings/video/exynos_hdmiphy.txt | 8 ++- drivers/gpu/drm/exynos/exynos_hdmiphy_i2c.c | 55 ++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c | 55 ++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h | 1 + 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt index 162f641..91e6578 100644 --- a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt +++ b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt @@ -5,11 +5,17 @@ Required properties: 1) "samsung,exynos5-hdmiphy" 2) "samsung,exynos4210-hdmiphy". 3) "samsung,exynos4212-hdmiphy". -- reg: I2C address of the hdmiphy device. +- reg: Physical address of the hdmiphy device. +- phy-power-control: this child node represents phy power control + register which is inside the pmu block (power management unit). Example: hdmiphy { compatible = "samsung,exynos4210-hdmiphy"; reg = <0x38>; + + phy-power-control { + reg = <0x10040700 0x04>; + }; }; diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy_i2c.c b/drivers/gpu/drm/exynos/exynos_hdmiphy_i2c.c index 76b3a74..6b411bd 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmiphy_i2c.c +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy_i2c.c @@ -201,6 +201,47 @@ static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata, return NULL; } +static int hdmiphy_dt_parse_power_control(struct i2c_client *client) +{ + struct device_node *phy_pow_ctrl_node; + struct hdmiphy_context *hdata = i2c_get_clientdata(client); + u32 buf[2]; + int ret = 0; + + phy_pow_ctrl_node = of_get_child_by_name(client->dev.of_node, + "phy-power-control"); + if (!phy_pow_ctrl_node) { + DRM_ERROR("Failed to find phy power control node\n"); + return -ENODEV; + } + + /* reg property holds two informations: addr of pmu register, size */ + if (of_property_read_u32_array(phy_pow_ctrl_node, "reg", buf, 2)) { + DRM_ERROR("faild to get phy power control reg\n"); + ret = -EINVAL; + goto out; + } + + hdata->phy_pow_ctrl_reg = devm_ioremap(&client->dev, buf[0], buf[1]); + if (!hdata->phy_pow_ctrl_reg) { + DRM_ERROR("failed to ioremap phy pmu reg\n"); + ret = -ENOMEM; + } + +out: + of_node_put(phy_pow_ctrl_node); + return ret; +} + +static inline void hdmiphy_pow_ctrl_reg_writemask( + struct hdmiphy_context *hdata, + u32 value, u32 mask) +{ + u32 old = readl(hdata->phy_pow_ctrl_reg); + value = (value & mask) | (old & ~mask); + writel(value, hdata->phy_pow_ctrl_reg); +} + static int hdmiphy_reg_writeb(struct device *dev, u32 reg_offset, u8 value) { @@ -313,9 +354,16 @@ static void hdmiphy_enable(struct device *dev, int enable) static void hdmiphy_poweron(struct device *dev, int mode) { + struct hdmiphy_context *hdata = dev_get_drvdata(dev); DRM_DEBUG_KMS("[%d]\n", __LINE__); + if (mode) + hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_ENABLE, + PMU_HDMI_PHY_CONTROL_MASK); + else + hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_DISABLE, + PMU_HDMI_PHY_CONTROL_MASK); } struct exynos_hdmiphy_ops *exynos_hdmiphy_i2c_device_get_ops @@ -370,6 +418,7 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client, struct hdmiphy_context *hdata; struct hdmiphy_drv_data *drv; const struct of_device_id *match; + int ret; DRM_DEBUG_KMS("[%d]\n", __LINE__); @@ -393,6 +442,12 @@ static int hdmiphy_i2c_device_probe(struct i2c_client *client, hdata->ops = &phy_ops; i2c_set_clientdata(client, hdata); + ret = hdmiphy_dt_parse_power_control(client); + if (ret) { + DRM_ERROR("failed to map hdmiphy pow control reg.\n"); + return ret; + } + return 0; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c b/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c index 053d854..8fe1786 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c @@ -160,6 +160,47 @@ static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata, return NULL; } +static int hdmiphy_dt_parse_power_control(struct platform_device *pdev) +{ + struct device_node *phy_pow_ctrl_node; + struct hdmiphy_context *hdata = platform_get_drvdata(pdev); + u32 buf[2]; + int ret = 0; + + phy_pow_ctrl_node = of_get_child_by_name(pdev->dev.of_node, + "phy-power-control"); + if (!phy_pow_ctrl_node) { + DRM_ERROR("Failed to find phy power control node\n"); + return -ENODEV; + } + + /* reg property holds two informations: addr of pmu register, size */ + if (of_property_read_u32_array(phy_pow_ctrl_node, "reg", buf, 2)) { + DRM_ERROR("faild to get phy power control reg\n"); + ret = -EINVAL; + goto out; + } + + hdata->phy_pow_ctrl_reg = devm_ioremap(&pdev->dev, buf[0], buf[1]); + if (!hdata->phy_pow_ctrl_reg) { + DRM_ERROR("failed to ioremap phy pmu reg\n"); + ret = -ENOMEM; + } + +out: + of_node_put(phy_pow_ctrl_node); + return ret; +} + +static void hdmiphy_pow_ctrl_reg_writemask( + struct hdmiphy_context *hdata, + u32 value, u32 mask) +{ + u32 old = readl(hdata->phy_pow_ctrl_reg); + value = (value & mask) | (old & ~mask); + writel(value, hdata->phy_pow_ctrl_reg); +} + static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata, u32 reg_offset, u8 value) { @@ -252,9 +293,16 @@ static void hdmiphy_enable(struct device *dev, int enable) static void hdmiphy_poweron(struct device *dev, int mode) { + struct hdmiphy_context *hdata = dev_get_drvdata(dev); DRM_DEBUG_KMS("[%d]\n", __LINE__); + if (mode) + hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_ENABLE, + PMU_HDMI_PHY_CONTROL_MASK); + else + hdmiphy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_DISABLE, + PMU_HDMI_PHY_CONTROL_MASK); } struct exynos_hdmiphy_ops *exynos_hdmiphy_platform_device_get_ops @@ -298,6 +346,7 @@ static int hdmiphy_platform_device_probe(struct platform_device *pdev) struct hdmiphy_drv_data *drv; struct resource *res; const struct of_device_id *match; + int ret; DRM_DEBUG_KMS("[%d]\n", __LINE__); @@ -333,6 +382,12 @@ static int hdmiphy_platform_device_probe(struct platform_device *pdev) hdata->ops = &phy_ops; platform_set_drvdata(pdev, hdata); + ret = hdmiphy_dt_parse_power_control(pdev); + if (ret) { + DRM_ERROR("failed to map hdmiphy pow control reg.\n"); + return ret; + } + return 0; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h b/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h index 9ba46d4..5987baf 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h @@ -15,6 +15,7 @@ struct hdmiphy_context { /* hdmiphy resources */ + void __iomem *phy_pow_ctrl_reg; void __iomem *regs; struct exynos_hdmiphy_ops *ops; struct hdmiphy_config *confs;