From patchwork Sun Apr 20 10:21:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 4020961 Return-Path: X-Original-To: patchwork-linux-samsung-soc@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 755529F369 for ; Sun, 20 Apr 2014 10:22:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 62E552022D for ; Sun, 20 Apr 2014 10:22:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2AB3E20254 for ; Sun, 20 Apr 2014 10:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755312AbaDTKWM (ORCPT ); Sun, 20 Apr 2014 06:22:12 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:36337 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754905AbaDTKWJ (ORCPT ); Sun, 20 Apr 2014 06:22:09 -0400 Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N4B006IHRGSIF30@mailout3.samsung.com> for linux-samsung-soc@vger.kernel.org; Sun, 20 Apr 2014 19:22:04 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id 35.4C.11496.CCF93535; Sun, 20 Apr 2014 19:22:04 +0900 (KST) X-AuditID: cbfee691-b7f3e6d000002ce8-89-53539fcc446c Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 0F.1F.25708.CCF93535; Sun, 20 Apr 2014 19:22:04 +0900 (KST) Received: from localhost.localdomain ([107.108.83.245]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N4B00LC2RGD0880@mmp2.samsung.com>; Sun, 20 Apr 2014 19:22:04 +0900 (KST) From: Rahul Sharma To: dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Cc: inki.dae@samsung.com, r.sh.open@gmail.com, joshi@samsung.com, Rahul Sharma Subject: [PATCH v2 2/3] drm/exynos: add support for apb mapped phys in hdmi driver Date: Sun, 20 Apr 2014 15:51:16 +0530 Message-id: <1397989277-29602-3-git-send-email-rahul.sharma@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1397989277-29602-1-git-send-email-rahul.sharma@samsung.com> References: <1397989277-29602-1-git-send-email-rahul.sharma@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrFLMWRmVeSWpSXmKPExsWyRsSkRvfM/OBgg+snFS2ufH3PZjHp/gQW i++7vrBbzDi/j8li4Yt4iymLDrM6sHnsnHWX3eN+93Emj74tqxg9Pm+SC2CJ4rJJSc3JLEst 0rdL4Mp4MnsKY8Fnq4oJ76czNjCe0+9i5OSQEDCR+D95BguELSZx4d56ti5GLg4hgaWMEmdu TmWCKTr7u4sFIjGdUeLE0S5mCKedSWJyVyMrSBWbgK7E7IPPGEFsEQE3iabDM8HizALZEocP vASLCwuESPx/fp4dxGYRUJU4P7EdbAOvgIfE18tvgeIcQNsUJOZMsgExOQU8JU4v5QSpEAKq eH6ygwlkrYRAN7vE8y23ocYISHybfIgFolVWYtMBZoibJSUOrrjBMoFReAEjwypG0dSC5ILi pPQiU73ixNzi0rx0veT83E2MwHA+/e/ZxB2M9w9YH2JMBho3kVlKNDkfGA95JfGGxmZGFqYm psZG5pZmpAkrifOmP0oKEhJITyxJzU5NLUgtii8qzUktPsTIxMEp1cB4wpFFJKN1wnrh4xsv zVkhLqTZoJ7yclNy0+xtp21V2u70aR8s1mv+ZHxZuGBFRe2sjhOrX+mUuUfsOldZsflxsrdI Dndb4LxDlbdOckSU6bmcne/PWm1tF274Qv3WzDtTF1Yv5DLSZYw6xHvn2g+jyyvfXXP56Ju/ 4pDEng3f7qbYlX0TPXxOiaU4I9FQi7moOBEAwIwxfn0CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrOIsWRmVeSWpSXmKPExsVy+t9jQd0z84ODDTrPi1lc+fqezWLS/Qks Ft93fWG3mHF+H5PFwhfxFlMWHWZ1YPPYOesuu8f97uNMHn1bVjF6fN4kF8AS1cBok5GamJJa pJCal5yfkpmXbqvkHRzvHG9qZmCoa2hpYa6kkJeYm2qr5OIToOuWmQO0XEmhLDGnFCgUkFhc rKRvh2lCaIibrgVMY4Sub0gQXI+RARpIWMOY8WT2FMaCz1YVE95PZ2xgPKffxcjJISFgInH2 dxcLhC0mceHeerYuRi4OIYHpjBInjnYxQzjtTBKTuxpZQarYBHQlZh98xghiiwi4STQdngkW ZxbIljh84CVYXFggROL/8/PsIDaLgKrE+YntTCA2r4CHxNfLb4HiHEDbFCTmTLIBMTkFPCVO L+UEqRACqnh+soNpAiPvAkaGVYyiqQXJBcVJ6blGesWJucWleel6yfm5mxjB0fJMegfjqgaL Q4wCHIxKPLwC6cHBQqyJZcWVuYcYJTiYlUR4k+cBhXhTEiurUovy44tKc1KLDzEmA900kVlK NDkfGMl5JfGGxibmpsamliYWJmaWpAkrifMebLUOFBJITyxJzU5NLUgtgtnCxMEp1cDIltFZ ancvs3HvjrfTPTcsV2TLDb50KDnRI6BgeSv/MruLJ7lrDuyX2c8x/6tBTGfEe93TMiYXVkyp vHDkzYy/3LG+3Fn/ov5pT/+t5Sn1dLbi/asSHjd9lpausSjwu/ZsHfN3jYvfek+vfb5Ym1P6 +n25i/K5zAo8cqLP6lcd6XCxODOpzuSHEktxRqKhFnNRcSIAppAlLNoCAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 438eeda..f4566b1 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 @@ -67,6 +68,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,6 +199,9 @@ struct hdmi_context { struct hdmi_resources res; int hpd_gpio; + void __iomem *regs_hdmiphy; + const struct hdmiphy_config *phy_confs; + unsigned int phy_conf_count; enum hdmi_type type; }; @@ -205,14 +211,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[] = { { @@ -427,6 +425,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); @@ -446,6 +459,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) \ @@ -849,20 +904,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); @@ -1514,17 +1559,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) { @@ -1532,26 +1569,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; } @@ -2070,6 +2098,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; @@ -2103,10 +2133,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) { @@ -2114,11 +2140,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 ef1b3eb..84a69cd 100644 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -578,4 +578,11 @@ #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 + #endif /* SAMSUNG_REGS_HDMI_H */