From patchwork Tue Oct 22 10:11:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 3086811 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 DB17CBF924 for ; Wed, 23 Oct 2013 08:35:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BDEDF202E6 for ; Wed, 23 Oct 2013 08:35:12 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 292DC202BE for ; Wed, 23 Oct 2013 08:35:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1CD8EE7127 for ; Wed, 23 Oct 2013 01:35:11 -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 8D0F9E6533 for ; Tue, 22 Oct 2013 02:50:50 -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:49 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id 38.08.07052.97A46625; Tue, 22 Oct 2013 18:50:49 +0900 (KST) X-AuditID: cbfee691-b7f866d000001b8c-c6-52664a797891 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 1D.B1.08134.97A46625; Tue, 22 Oct 2013 18:50:49 +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:49 +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 3/7] drm/exynos: add hdmiphy platform driver for exynos5420 Date: Tue, 22 Oct 2013 15:41:04 +0530 Message-id: <1382436668-15813-4-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+NgFprJIsWRmVeSWpSXmKPExsWyRsSkRrfSKy3IoKdT22L+kXOsFle+vmez mHR/AovF911f2C16F1xls9j0+BqrxYzz+5gsFr6It5iy6DCrxeE37awWdzecZbSYMfklm8Wq XX8YHXg9ZjdcZPHYOesuu8f97uNMHpuX1Hv0bVnF6PF5k1wAWxSXTUpqTmZZapG+XQJXRsel JSwFH0orfh85x9LAeDSui5GTQ0LAROLYkW52CFtM4sK99WxdjFwcQgJLGSWav5xjhCl6338F KrGIUeLm+jmsEM5sJonpB1qYQKrYBHQlZh98BtYhItDFKHGwkwWkiFngEaPEjkd7mEESwgJ+ Eicv97OB2CwCqhIn2++B7eYV8JDYePMH1DpFie5nE8BqOAU8JS6fPcQCYgsB1fy69gtsqITA OXaJhknfWSAGCUh8mwxSxAGUkJXYdIAZYo6kxMEVN1gmMAovYGRYxSiaWpBcUJyUXmSqV5yY W1yal66XnJ+7iREYLaf/PZu4g/H+AetDjMlA4yYyS4km5wOjLa8k3tDYzMjC1MTU2Mjc0ow0 YSVx3vRHSUFCAumJJanZqakFqUXxRaU5qcWHGJk4OKUaGPeuFU/7nyW+P7Zh/Snt7DXhS+s/ n5Na8fVylonk2lU7Fuem9uwptpnsf4h/sazKU7HH23i/bD4Zm6RSuaym1DLp387Tt0Tarjhu OSAVmHZ3/UOjqnNbQsJWC25deVWVo6aJt+7SwnAG/ys+KVnbXkStSG+YyRAcmSigO3M1U+CS 0/Kn2LQfyCqxFGckGmoxFxUnAgBo2domrAIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrGIsWRmVeSWpSXmKPExsVy+t9jAd1Kr7Qgg2Udihbzj5xjtbjy9T2b xaT7E1gsvu/6wm7Ru+Aqm8Wmx9dYLWac38dksfBFvMWURYdZLQ6/aWe1uLvhLKPFjMkv2SxW 7frD6MDrMbvhIovHzll32T3udx9n8ti8pN6jb8sqRo/Pm+QC2KIaGG0yUhNTUosUUvOS81My 89JtlbyD453jTc0MDHUNLS3MlRTyEnNTbZVcfAJ03TJzgA5VUihLzCkFCgUkFhcr6dthmhAa 4qZrAdMYoesbEgTXY2SABhLWMGZ0XFrCUvChtOL3kXMsDYxH47oYOTkkBEwk3vdfYYOwxSQu 3FsPZHNxCAksYpS4uX4OK4Qzm0li+oEWJpAqNgFdidkHnzGC2CICXYwSBztZQIqYBR4xSux4 tIcZJCEs4Cdx8nI/2FgWAVWJk+332EFsXgEPiY03fzBCrFOU6H42AayGU8BT4vLZQywgthBQ za9rv1gmMPIuYGRYxSiaWpBcUJyUnmukV5yYW1yal66XnJ+7iREci8+kdzCuarA4xCjAwajE w5thlRokxJpYVlyZe4hRgoNZSYT3r2FakBBvSmJlVWpRfnxRaU5q8SHGZKCrJjJLiSbnA9NE Xkm8obGJuamxqaWJhYmZJWnCSuK8B1utA4UE0hNLUrNTUwtSi2C2MHFwSjUwRv44X3JmZ1aF a8HbGxzbb5w4rnRjcvor37vyawKyfKZfuxzuH73DluX7seyKDw4/iwKktq3IrJ17qEpVtrdl o+CKtxkC7ZVuHHWzSk+ZbhRUKdn4rGKxdjLjid7cepEc9llGTUsFP3oYNU+4dVnr9bevEbFb nprwbZr7SMErbeHEPy1TfK6pK7EUZyQaajEXFScCAKItUUUJAwAA 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 Exynos5420 hdmiphy device is a platform device, unlike predecessor SoCs where it used to be a I2C device. This support is added to the hdmiphy platform driver. Signed-off-by: Rahul Sharma --- drivers/gpu/drm/exynos/Makefile | 1 + drivers/gpu/drm/exynos/exynos_hdmi.c | 61 +++- drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c | 363 ++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h | 1 + 4 files changed, 413 insertions(+), 13 deletions(-) create mode 100644 drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 463239b..eedd145 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile @@ -13,6 +13,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o \ exynos_ddc.o exynos_hdmiphy_i2c.o \ + exynos_hdmiphy_platform.o \ exynos_drm_hdmi.o exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 444541d..e199d7d 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -1608,10 +1609,14 @@ static int hdmi_register_phy_device(struct hdmi_context *hdata, bool i2c_dev) { struct device_node *np; struct i2c_client *client; + struct platform_device *pdev; int ret; /* register hdmiphy driver */ - ret = exynos_hdmiphy_i2c_driver_register(); + if (i2c_dev) + ret = exynos_hdmiphy_i2c_driver_register(); + else + ret = exynos_hdmiphy_platform_driver_register(); if (ret) { DRM_ERROR("failed to register phy driver. ret %d.\n", ret); goto err; @@ -1624,16 +1629,29 @@ static int hdmi_register_phy_device(struct hdmi_context *hdata, bool i2c_dev) goto err; } - /* find hdmi phy on i2c bus */ - client = of_find_i2c_device_by_node(np); - if (!client) { - DRM_ERROR("Could not find i2c 'phy' device\n"); - ret = -ENODEV; - goto err; + if (i2c_dev) { + /* find hdmi phy on i2c bus */ + client = of_find_i2c_device_by_node(np); + if (!client) { + DRM_ERROR("Could not find i2c 'phy' device\n"); + ret = -ENODEV; + goto err; + } + hdata->phy_dev = &client->dev; + hdata->phy_ops = exynos_hdmiphy_i2c_device_get_ops( + hdata->phy_dev); + } else { + /* find hdmi phy on platform bus */ + pdev = of_find_device_by_node(np); + if (!pdev) { + DRM_ERROR("Could not find platform 'phy' device\n"); + ret = -ENODEV; + goto err; + } + hdata->phy_dev = &pdev->dev; + hdata->phy_ops = exynos_hdmiphy_platform_device_get_ops( + hdata->phy_dev); } - hdata->phy_dev = &client->dev; - hdata->phy_ops = exynos_hdmiphy_i2c_device_get_ops( - hdata->phy_dev); if (!hdata->phy_ops) { ret = -EINVAL; @@ -1652,6 +1670,11 @@ static struct hdmi_drv_data exynos5250_hdmi_drv_data = { .i2c_hdmiphy = 1, }; +static struct hdmi_drv_data exynos5420_hdmi_drv_data = { + .type = HDMI_TYPE14, + .i2c_hdmiphy = 0, +}; + static struct of_device_id hdmi_match_types[] = { { .compatible = "samsung,exynos5-hdmi", @@ -1660,6 +1683,9 @@ static struct of_device_id hdmi_match_types[] = { .compatible = "samsung,exynos4212-hdmi", .data = &exynos5250_hdmi_drv_data, }, { + .compatible = "samsung,exynos5420-hdmi", + .data = &exynos5420_hdmi_drv_data, + }, { /* end node */ } }; @@ -1767,7 +1793,10 @@ static int hdmi_probe(struct platform_device *pdev) return 0; err_hdmiphy: - exynos_hdmiphy_i2c_driver_unregister(); + if (drv->i2c_hdmiphy) + exynos_hdmiphy_i2c_driver_unregister(); + else + exynos_hdmiphy_platform_driver_unregister(); err_ddc: i2c_del_driver(&ddc_driver); return ret; @@ -1776,11 +1805,17 @@ err_ddc: static int hdmi_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); + struct hdmi_context *hdata = ctx->ctx; pm_runtime_disable(dev); - /* hdmiphy i2c driver */ - exynos_hdmiphy_i2c_driver_unregister(); + /* hdmiphy driver */ + if (i2c_verify_client(hdata->phy_dev)) + exynos_hdmiphy_i2c_driver_unregister(); + else + exynos_hdmiphy_platform_driver_unregister(); + /* DDC i2c driver */ i2c_del_driver(&ddc_driver); diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c b/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c new file mode 100644 index 0000000..053d854 --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy_platform.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2013 Samsung Electronics Co.Ltd + * Authors: + * Rahul Sharma + * + * 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 + +#include +#include + +#include "regs-hdmiphy.h" +#include "exynos_hdmiphy.h" +#include "exynos_hdmiphy_priv.h" + +/* default phy config settings for exynos5420 */ +static struct hdmiphy_config hdmiphy_5420_configs[] = { + { + .pixel_clock = 25200000, + .conf = { + 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8, 0x82, + 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x06, + 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 27000000, + .conf = { + 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0, 0x98, + 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x06, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 27027000, + .conf = { + 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8, 0x43, + 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x06, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 36000000, + .conf = { + 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8, 0x02, + 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 40000000, + .conf = { + 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8, 0x87, + 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 65000000, + .conf = { + 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8, 0x82, + 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 71000000, + .conf = { + 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8, 0x85, + 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 74176000, + .conf = { + 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8, 0x81, + 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x56, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 74250000, + .conf = { + 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0xC8, 0x81, + 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x56, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 83500000, + .conf = { + 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8, 0x85, + 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 106500000, + .conf = { + 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8, 0x84, + 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 108000000, + .conf = { + 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8, 0x82, + 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 146250000, + .conf = { + 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8, 0x83, + 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80, 0x08, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, + { + .pixel_clock = 148500000, + .conf = { + 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0xC8, 0x81, + 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80, 0x66, + 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66, 0x54, + 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80, + }, + }, +}; + +static struct hdmiphy_config *hdmiphy_find_conf(struct hdmiphy_context *hdata, + unsigned int pixel_clk) +{ + int i; + + for (i = 0; i < hdata->nr_confs; i++) + if (hdata->confs[i].pixel_clock == pixel_clk) + return &hdata->confs[i]; + + return NULL; +} + +static int hdmiphy_reg_writeb(struct hdmiphy_context *hdata, + u32 reg_offset, u8 value) +{ + if (reg_offset >= HDMIPHY_REG_COUNT) + return -EINVAL; + + writeb(value, hdata->regs + (reg_offset<<2)); + return 0; +} + +static int hdmiphy_reg_write_buf(struct hdmiphy_context *hdata, + u32 reg_offset, const u8 *buf, u32 len) +{ + int i; + + if ((reg_offset + len) > HDMIPHY_REG_COUNT) + return -EINVAL; + + for (i = 0; i < len; i++) + writeb(buf[i], hdata->regs + + ((reg_offset + i)<<2)); + return 0; +} + +static int hdmiphy_check_mode(struct device *dev, + struct drm_display_mode *mode) +{ + struct hdmiphy_context *hdata = dev_get_drvdata(dev); + const struct hdmiphy_config *conf; + + DRM_DEBUG("%s xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", + __func__, mode->hdisplay, mode->vdisplay, + mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE) + ? true : false, mode->clock * 1000); + + conf = hdmiphy_find_conf(hdata, mode->clock * 1000); + if (!conf) { + DRM_DEBUG("Display Mode is not supported.\n"); + return -EINVAL; + } + return 0; +} + +static int hdmiphy_mode_set(struct device *dev, + struct drm_display_mode *mode) +{ + struct hdmiphy_context *hdata = dev_get_drvdata(dev); + + DRM_DEBUG_KMS("[%d]\n", __LINE__); + + hdata->current_conf = hdmiphy_find_conf(hdata, mode->clock * 1000); + if (!hdata->current_conf) { + DRM_ERROR("Display Mode is not supported.\n"); + return -EINVAL; + } + return 0; +} + +static int hdmiphy_commit(struct device *dev) +{ + struct hdmiphy_context *hdata = dev_get_drvdata(dev); + int ret; + + DRM_DEBUG_KMS("[%d]\n", __LINE__); + + ret = hdmiphy_reg_write_buf(hdata, 1, hdata->current_conf->conf, + HDMIPHY_REG_COUNT - 1); + if (ret) { + DRM_ERROR("failed to configure hdmiphy. ret %d.\n", ret); + return ret; + } + + /* need this delay before phy can be set to operation. */ + usleep_range(10000, 12000); + return 0; +} + +static void hdmiphy_enable(struct device *dev, int enable) +{ + struct hdmiphy_context *hdata = dev_get_drvdata(dev); + + DRM_DEBUG_KMS("[%d]\n", __LINE__); + + if (enable) + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMIPHY_MODE_EN); + else + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, 0); +} + +static void hdmiphy_poweron(struct device *dev, int mode) +{ + + DRM_DEBUG_KMS("[%d]\n", __LINE__); + +} + +struct exynos_hdmiphy_ops *exynos_hdmiphy_platform_device_get_ops + (struct device *dev) +{ + struct hdmiphy_context *hdata = dev_get_drvdata(dev); + DRM_DEBUG_KMS("[%d]\n", __LINE__); + + if (hdata) + return hdata->ops; + + return NULL; +} + +static struct exynos_hdmiphy_ops phy_ops = { + .check_mode = hdmiphy_check_mode, + .mode_set = hdmiphy_mode_set, + .commit = hdmiphy_commit, + .enable = hdmiphy_enable, + .poweron = hdmiphy_poweron, +}; + +static struct hdmiphy_drv_data exynos5420_hdmiphy_drv_data = { + .confs = hdmiphy_5420_configs, + .count = ARRAY_SIZE(hdmiphy_5420_configs) +}; + +static struct of_device_id hdmiphy_platform_device_match_types[] = { + { + .compatible = "samsung,exynos5420-hdmiphy", + .data = &exynos5420_hdmiphy_drv_data, + }, { + /* end node */ + } +}; + +static int hdmiphy_platform_device_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hdmiphy_context *hdata; + struct hdmiphy_drv_data *drv; + struct resource *res; + const struct of_device_id *match; + + DRM_DEBUG_KMS("[%d]\n", __LINE__); + + hdata = devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL); + if (!hdata) { + DRM_ERROR("failed to allocate hdmiphy context.\n"); + return -ENOMEM; + } + + match = of_match_node(of_match_ptr( + hdmiphy_platform_device_match_types), + dev->of_node); + + if (!match) + return -ENODEV; + + drv = (struct hdmiphy_drv_data *)match->data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + DRM_ERROR("failed to find phy registers\n"); + return -ENOENT; + } + + hdata->regs = devm_request_and_ioremap(&pdev->dev, res); + if (!hdata->regs) { + DRM_ERROR("failed to map registers\n"); + return -ENXIO; + } + + hdata->confs = drv->confs; + hdata->nr_confs = drv->count; + hdata->ops = &phy_ops; + + platform_set_drvdata(pdev, hdata); + return 0; +} + +struct platform_driver hdmiphy_platform_driver = { + .driver = { + .name = "exynos-hdmiphy", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr( + hdmiphy_platform_device_match_types), + }, + .probe = hdmiphy_platform_device_probe, +}; + +int exynos_hdmiphy_platform_driver_register(void) +{ + int ret; + + ret = platform_driver_register(&hdmiphy_platform_driver); + if (ret) + return ret; + + return 0; +} + +void exynos_hdmiphy_platform_driver_unregister(void) +{ + platform_driver_unregister(&hdmiphy_platform_driver); +} diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h b/drivers/gpu/drm/exynos/exynos_hdmiphy_priv.h index 4948c81..9ba46d4 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 *regs; struct exynos_hdmiphy_ops *ops; struct hdmiphy_config *confs; unsigned int nr_confs;