From patchwork Tue Mar 11 11:26:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish S X-Patchwork-Id: 3815041 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 BC526BF540 for ; Wed, 12 Mar 2014 00:16:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AB2F720263 for ; Wed, 12 Mar 2014 00:16:17 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 8568D2022A for ; Wed, 12 Mar 2014 00:16:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 97EDFFAF83; Tue, 11 Mar 2014 17:16:01 -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 59289FAC6A for ; Tue, 11 Mar 2014 04:25:44 -0700 (PDT) Received: from epcpsbgr4.samsung.com (u144.gpu120.samsung.co.kr [203.254.230.144]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N2900JEPRQU9H00@mailout1.samsung.com> for dri-devel@lists.freedesktop.org; Tue, 11 Mar 2014 20:25:42 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.125]) by epcpsbgr4.samsung.com (EPCPMTA) with SMTP id B8.AB.10364.6B2FE135; Tue, 11 Mar 2014 20:25:42 +0900 (KST) X-AuditID: cbfee690-b7f266d00000287c-8c-531ef2b65d39 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 76.D8.28157.6B2FE135; Tue, 11 Mar 2014 20:25:42 +0900 (KST) Received: from chrome-server.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 <0N2900L92RQP0A00@mmp1.samsung.com>; Tue, 11 Mar 2014 20:25:42 +0900 (KST) From: Shirish S To: dri-devel@lists.freedesktop.org, inki.dae@samsung.com Subject: [PATCH] drm/exynos: add hdmi power on/off sequence Date: Tue, 11 Mar 2014 16:56:17 +0530 Message-id: <1394537177-17870-1-git-send-email-s.shirish@samsung.com> X-Mailer: git-send-email 1.7.10.4 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKLMWRmVeSWpSXmKPExsWyRsSkVnfbJ7lgg97n+hZXvr5ns5h0fwKL xbTZGxktmnYcZHNg8ZjdcJHF4373cSaPvi2rGAOYo7hsUlJzMstSi/TtErgyZp15zF5w17ri dPMapgbGJYZdjJwcEgImEg8PHWOCsMUkLtxbz9bFyMUhJLCUUeLauz1ADgdY0envQiA1QgKL gOLfdCFqepkkGs7/ZgFJsAmoS1ycvJoZxBYRsJR4sPU3mM0sYC2x+s4pRhBbGMj+Ne85WD2L gKrEzo3dYHFeAVeJ72372CCOUJTofjYB7AgJgdtsEnf2zWGEaBCQ+Db5EAvEQbISmw4wQ9RL ShxccYNlAqPgAkaGVYyiqQXJBcVJ6UUmesWJucWleel6yfm5mxiBQXj637MJOxjvHbA+xJgM NG4is5Rocj4wiPNK4g2NzYwsTE1MjY3MLc1IE1YS51V7lBQkJJCeWJKanZpakFoUX1Sak1p8 iJGJg1OqgTHlcAnP89dvE7ae0XpRUbf66v59wc/sDXknzi+wWtW/z6ZvY0DZrhixib9KHx19 pTF/3R7V0rtFz1+ECu+Qupp5zzftxArlevGzQud7332u5Pgt0Dvzxvn+gkj5826P112okJeJ 7i95Ob3m1o7fBnuslS79n2sZ9TS7pUItQf9iw776hFtM7vpKLMUZiYZazEXFiQBBi6vVWAIA AA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrEIsWRmVeSWpSXmKPExsVy+t9jAd1tn+SCDX4sUre48vU9m8Wk+xNY LKbN3sho0bTjIJsDi8fshossHve7jzN59G1ZxRjAHNXAaJORmpiSWqSQmpecn5KZl26r5B0c 7xxvamZgqGtoaWGupJCXmJtqq+TiE6DrlpkDtE9JoSwxpxQoFJBYXKykb4dpQmiIm64FTGOE rm9IEFyPkQEaSFjDmDHrzGP2grvWFaeb1zA1MC4x7GLk4JAQMJE4/V2oi5ETyBSTuHBvPRuI LSSwiFHi2jfdLkYuILuXSaLh/G8WkASbgLrExcmrmUFsEQFLiQdbf4PZzALWEqvvnGIEsYWB 7F/znoPVswioSuzc2A0W5xVwlfjeto8NYpmiRPezCWwTGLkXMDKsYhRNLUguKE5KzzXSK07M LS7NS9dLzs/dxAgO8WfSOxhXNVgcYhTgYFTi4V3hLxcsxJpYVlyZe4hRgoNZSYT34j2gEG9K YmVValF+fFFpTmrxIcZkoO0TmaVEk/OB8ZdXEm9obGJuamxqaWJhYmZJmrCSOO/BVutAIYH0 xJLU7NTUgtQimC1MHJxSDYz9/eXhuRMCbIxZlDqlJrB1lhlkWOlOcfZr5+nj3MvRxxDu848/ cH5f6s/UVcXzrVnX6+36seR97LfE8ISWhQndfPz56o/7jho5xujOc+CWeC1jvTDzFNssgT3x B/7kmE6753ezVs16sYIkn/68hTnqpWViqWlZXCrvGKpcDA/4don18woosRRnJBpqMRcVJwIA PJNTOLUCAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-Mailman-Approved-At: Tue, 11 Mar 2014 17:15:59 -0700 Cc: shirish@chromium.org, Shirish S 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@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 This patch implements the power on/off sequence (and its dependant functions) of HDMI exynos5250 as provided by the hardware team. Signed-off-by: Shirish S --- drivers/gpu/drm/exynos/exynos_hdmi.c | 137 +++++++++++++++++++++++++++++----- drivers/gpu/drm/exynos/regs-hdmi.h | 15 ++++ 2 files changed, 133 insertions(+), 19 deletions(-) mode change 100644 => 100755 drivers/gpu/drm/exynos/exynos_hdmi.c mode change 100644 => 100755 drivers/gpu/drm/exynos/regs-hdmi.h diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c old mode 100644 new mode 100755 index 12fdf55..ee000f7 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -180,6 +180,7 @@ struct hdmi_context { void __iomem *regs; int irq; + void __iomem *phy_pow_ctrl_reg; struct i2c_client *ddc_port; struct i2c_client *hdmiphy_port; @@ -387,6 +388,33 @@ static inline void hdmi_reg_writemask(struct hdmi_context *hdata, writel(value, hdata->regs + reg_id); } + +static inline void hdmi_phy_pow_ctrl_reg_writemask(struct hdmi_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 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 + return 0; +} + static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) { #define DUMPREG(reg_id) \ @@ -1386,19 +1414,14 @@ static void hdmi_mode_apply(struct hdmi_context *hdata) static void hdmiphy_conf_reset(struct hdmi_context *hdata) { - u8 buffer[2]; u32 reg; clk_disable_unprepare(hdata->res.sclk_hdmi); clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel); clk_prepare_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); + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_ENABLE_MODE_SET); if (hdata->type == HDMI_TYPE13) reg = HDMI_V13_PHY_RSTOUT; @@ -1414,16 +1437,42 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) static void hdmiphy_poweron(struct hdmi_context *hdata) { - if (hdata->type == HDMI_TYPE14) - hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, - HDMI_PHY_POWER_OFF_EN); + if (hdata->type == HDMI_TYPE13) + return; + + DRM_DEBUG_KMS("\n"); + + /* For PHY Mode Setting */ + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_ENABLE_MODE_SET); + /* Phy Power On */ + hdmiphy_reg_writeb(hdata, HDMIPHY_POWER, + HDMI_PHY_POWER_ON); + /* For PHY Mode Setting */ + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_DISABLE_MODE_SET); + /* PHY SW Reset */ + hdmiphy_conf_reset(hdata); } static void hdmiphy_poweroff(struct hdmi_context *hdata) { - if (hdata->type == HDMI_TYPE14) - hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, - HDMI_PHY_POWER_OFF_EN); + if (hdata->type == HDMI_TYPE13) + return; + + DRM_DEBUG_KMS("\n"); + + /* PHY SW Reset */ + hdmiphy_conf_reset(hdata); + /* For PHY Mode Setting */ + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_ENABLE_MODE_SET); + /* PHY Power Off */ + hdmiphy_reg_writeb(hdata, HDMIPHY_POWER, + HDMI_PHY_POWER_OFF); + /* For PHY Mode Setting */ + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_DISABLE_MODE_SET); } static void hdmiphy_conf_apply(struct hdmi_context *hdata) @@ -1476,6 +1525,14 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) DRM_ERROR("failed to read hdmiphy config\n"); return; } + usleep_range(10000, 12000); + + ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_DISABLE_MODE_SET); + if (ret < 0) { + DRM_ERROR("failed to enable hdmiphy\n"); + return; + } for (i = 0; i < ret; i++) DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - " @@ -1767,10 +1824,10 @@ static void hdmi_poweron(struct exynos_drm_display *display) if (regulator_bulk_enable(res->regul_count, res->regul_bulk)) DRM_DEBUG_KMS("failed to enable regulator bulk\n"); - clk_prepare_enable(res->hdmiphy); - clk_prepare_enable(res->hdmi); - clk_prepare_enable(res->sclk_hdmi); + hdmi_phy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_ENABLE, + PMU_HDMI_PHY_CONTROL_MASK); + /* HDMI PHY Enable and Power-On */ hdmiphy_poweron(hdata); hdmi_commit(display); } @@ -1790,11 +1847,16 @@ static void hdmi_poweroff(struct exynos_drm_display *display) * its reset state seems to meet the condition. */ hdmiphy_conf_reset(hdata); + + /* HDMI System Disable */ + hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); + hdmiphy_poweroff(hdata); - clk_disable_unprepare(res->sclk_hdmi); - clk_disable_unprepare(res->hdmi); - clk_disable_unprepare(res->hdmiphy); + /* HDMI PHY Disable */ + hdmi_phy_pow_ctrl_reg_writemask(hdata, PMU_HDMI_PHY_DISABLE, + PMU_HDMI_PHY_CONTROL_MASK); + regulator_bulk_disable(res->regul_count, res->regul_bulk); pm_runtime_put_sync(hdata->dev); @@ -1947,6 +2009,36 @@ err_data: return NULL; } +static int drm_hdmi_dt_parse_phy_pow_control(struct hdmi_context *hdata) +{ + struct device_node *phy_pow_ctrl_node; + u32 buf[2]; + int ret = 0; + + phy_pow_ctrl_node = of_find_node_by_name(NULL, "phy-power-control"); + if (!phy_pow_ctrl_node) + return 0; + + /* reg property holds two informations: addr of pmu register, size */ + if (of_property_read_u32_array(phy_pow_ctrl_node, "reg", + (u32 *)&buf, 2)) { + DRM_ERROR("faild to get phy power control reg\n"); + ret = -EINVAL; + goto fail; + } + + hdata->phy_pow_ctrl_reg = devm_ioremap(hdata->dev, buf[0], buf[1]); + if (!hdata->phy_pow_ctrl_reg) { + DRM_ERROR("failed to ioremap phy pmu reg\n"); + ret = -ENOMEM; + goto fail; + } + +fail: + of_node_put(phy_pow_ctrl_node); + return ret; +} + static struct of_device_id hdmi_match_types[] = { { .compatible = "samsung,exynos5-hdmi", @@ -2010,6 +2102,13 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) return ret; } + /* map hdmiphy power control reg */ + ret = drm_hdmi_dt_parse_phy_pow_control(hdata); + if (ret) { + DRM_ERROR("failed to map phy power control registers\n"); + return ret; + } + /* DDC i2c driver */ ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); if (!ddc_node) { diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h old mode 100644 new mode 100755 index ef1b3eb..e686fe9 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -578,4 +578,19 @@ #define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) #define HDMI_TG_3D HDMI_TG_BASE(0x00F0) +/* HDMI PHY Registers Offsets*/ + +#define HDMIPHY_POWER (0x74 >> 2) +#define HDMIPHY_MODE_SET_DONE (0x7C >> 2) + +/* HDMI PHY Values */ +#define HDMI_PHY_POWER_ON 0x80 +#define HDMI_PHY_POWER_OFF 0xFF +#define HDMI_PHY_DISABLE_MODE_SET 0x80 +#define HDMI_PHY_ENABLE_MODE_SET 0x00 + +#define PMU_HDMI_PHY_CONTROL_MASK (1 << 0) +#define PMU_HDMI_PHY_ENABLE (1) +#define PMU_HDMI_PHY_DISABLE (0) + #endif /* SAMSUNG_REGS_HDMI_H */