From patchwork Sat Sep 30 01:44:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: crj X-Patchwork-Id: 9978995 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DCAE96034B for ; Sat, 30 Sep 2017 01:45:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDBDA297A4 for ; Sat, 30 Sep 2017 01:45:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C2501298A4; Sat, 30 Sep 2017 01:45:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_WEB autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6B90729879 for ; Sat, 30 Sep 2017 01:45:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=tldrz1o95ezQy2Xgk7mmHYrxnxPdNOqBGyYPyvrZpsc=; b=n7P3SQjdjrPB7/3XZy/oUHn4XL auhxk+iAiDbHqK+H/uvglU6Dr6w8+XfjT9NcwxV6WFbHcuT60bILjsuZRkEuQ47CtvL96ZHIkx3Iw QKzZzLx1sRGhGBF5Bo6PYeKvc1K39vcvEGscKljSl9Vn4h95JYR9v/qAtIzDIsHdMrVRVu5pXB2Dh qsPHLdnL5pGpKn608wHP0tSUqvXE5xz1OUzNkufRdlipvVQ5vGB7kUKydZMgjYlNJDUIEIgFG7Agd 0vdCuiBCMIH91pm5/dnXxQxi6NGWDGIRpNQAUDKahitKG1mcf6+G93w/Z/OolFYFK71bLC51vt3rC SMcspseA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dy6qH-00080N-Vx; Sat, 30 Sep 2017 01:45:21 +0000 Received: from regular1.263xmail.com ([211.150.99.135]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dy6qD-0006ei-JZ for linux-rockchip@lists.infradead.org; Sat, 30 Sep 2017 01:45:19 +0000 Received: from algea.cao?rock-chips.com (unknown [192.168.167.110]) by regular1.263xmail.com (Postfix) with ESMTP id 86C631DFEA; Sat, 30 Sep 2017 09:44:53 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id AE27B3C6; Sat, 30 Sep 2017 09:44:48 +0800 (CST) X-RL-SENDER: algea.cao@rock-chips.com X-FST-TO: daniel.vetter@intel.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: algea.cao@rock-chips.com X-UNIQUE-TAG: X-ATTACHMENT-NUM: 0 X-SENDER: algea.cao@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 1023CGSF4V; Sat, 30 Sep 2017 09:44:50 +0800 (CST) From: Algea Cao To: daniel.vetter@intel.com, jani.nikula@linux.intel.com, seanpaul@chromium.org, airlied@linux.ie, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org Subject: [PATCH v2 4/7] drm/rockchip: dw_hdmi: add inno hdmi phy ops Date: Sat, 30 Sep 2017 09:44:46 +0800 Message-Id: <1506735886-151761-1-git-send-email-algea.cao@rock-chips.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1506735713-147081-0> References: <1506735713-147081-0> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170929_184518_289402_E7C0B673 X-CRM114-Status: GOOD ( 12.04 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Algea Cao , yang.zheng@rock-chips.com, kever.yang@rock-chips.com, mark.yao@rock-chips.com MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Because some RK chips use inno hdmi phy, such as RK3328, we add inno hdmi phy ops. Signed-off-by: Algea Cao --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 110 +++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 09c77f9..7658b2f 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -12,7 +12,7 @@ #include #include #include - +#include #include #include #include @@ -26,6 +26,18 @@ #define RK3288_HDMI_LCDC_SEL BIT(4) #define RK3399_GRF_SOC_CON20 0x6250 #define RK3399_HDMI_LCDC_SEL BIT(6) +#define RK3328_GRF_SOC_CON2 0x0408 +#define RK3328_DDC_MASK_EN ((3 << 10) | (3 << (10 + 16))) +#define RK3328_GRF_SOC_CON3 0x040c +#define RK3328_IO_CTRL_BY_HDMI (0xf0000000 | BIT(13) | BIT(12)) +#define RK3328_GRF_SOC_CON4 0x0410 +#define RK3328_IO_3V_DOMAIN (7 << (9 + 16)) +#define RK3328_IO_5V_DOMAIN ((7 << 9) | (3 << (9 + 16))) +#define RK3328_HPD_3V (BIT(8 + 16) | BIT(13 + 16)) +#define RK3228_GRF_SOC_CON2 0x0408 +#define RK3228_DDC_MASK_EN ((3 << 13) | (3 << (13 + 16))) +#define RK3228_GRF_SOC_CON6 0x0418 +#define RK3228_IO_3V_DOMAIN ((7 << 4) | (7 << (4 + 16))) #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) @@ -49,10 +61,82 @@ struct rockchip_hdmi { enum dw_hdmi_devtype dev_type; struct clk *vpll_clk; struct clk *grf_clk; + struct phy *phy; }; #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) +static int +inno_dw_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data, + struct drm_display_mode *mode) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + + return phy_power_on(hdmi->phy); +} + +static void inno_dw_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + + phy_power_off(hdmi->phy); +} + +static enum drm_connector_status +inno_dw_hdmi_phy_read_hpd(struct dw_hdmi *dw_hdmi, void *data) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + enum drm_connector_status status; + + status = dw_hdmi_phy_read_hpd(dw_hdmi, data); + + if (hdmi->dev_type == RK3228_HDMI) + return status; + + if (status == connector_status_connected) + regmap_write(hdmi->regmap, + RK3328_GRF_SOC_CON4, + RK3328_IO_5V_DOMAIN); + else + regmap_write(hdmi->regmap, + RK3328_GRF_SOC_CON4, + RK3328_IO_3V_DOMAIN); + return status; +} + +static int inno_dw_hdmi_init(struct rockchip_hdmi *hdmi) +{ + int ret; + + ret = clk_prepare_enable(hdmi->grf_clk); + if (ret < 0) { + dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret); + return -EPROBE_DEFER; + } + if (hdmi->dev_type == RK3328_HDMI) { + /* Map HPD pin to 3V io */ + regmap_write(hdmi->regmap, + RK3328_GRF_SOC_CON4, + RK3328_IO_3V_DOMAIN | + RK3328_HPD_3V); + /* Map ddc pin to 5V io */ + regmap_write(hdmi->regmap, + RK3328_GRF_SOC_CON3, + RK3328_IO_CTRL_BY_HDMI); + regmap_write(hdmi->regmap, + RK3328_GRF_SOC_CON2, + RK3328_DDC_MASK_EN | + BIT(18)); + } else { + regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2, + RK3228_DDC_MASK_EN); + regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON6, + RK3228_IO_3V_DOMAIN); + } + clk_disable_unprepare(hdmi->grf_clk); + return 0; +} + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { 27000000, { @@ -294,6 +378,12 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun .atomic_check = dw_hdmi_rockchip_encoder_atomic_check, }; +static const struct dw_hdmi_phy_ops inno_dw_hdmi_phy_ops = { + .init = inno_dw_hdmi_phy_init, + .disable = inno_dw_hdmi_phy_disable, + .read_hpd = inno_dw_hdmi_phy_read_hpd, +}; + static struct rockchip_hdmi_chip_data rk3288_chip_data = { .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL), @@ -317,6 +407,8 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { .mode_valid = dw_hdmi_rockchip_mode_valid, + .phy_ops = &inno_dw_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", .dev_type = RK3328_HDMI, }; static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { @@ -346,7 +438,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); - const struct dw_hdmi_plat_data *plat_data; + struct dw_hdmi_plat_data *plat_data; const struct of_device_id *match; struct drm_device *drm = data; struct drm_encoder *encoder; @@ -361,7 +453,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return -ENOMEM; match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node); - plat_data = match->data; + plat_data = (struct dw_hdmi_plat_data *)match->data; hdmi->dev = &pdev->dev; hdmi->chip_data = plat_data->phy_data; hdmi->dev_type = plat_data->dev_type; @@ -383,6 +475,18 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return ret; } + if (hdmi->dev_type == RK3328_HDMI || hdmi->dev_type == RK3228_HDMI) { + hdmi->phy = devm_phy_get(dev, "hdmi_phy"); + if (IS_ERR(hdmi->phy)) { + ret = PTR_ERR(hdmi->phy); + dev_err(dev, "failed to get phy: %d\n", ret); + return ret; + } + plat_data->phy_data = hdmi; + ret = inno_dw_hdmi_init(hdmi); + if (ret < 0) + return ret; + } drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL);