From patchwork Mon Apr 1 19:15:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jernej_=C5=A0krabec?= X-Patchwork-Id: 10881205 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9020417EE for ; Tue, 2 Apr 2019 07:44:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E7B1286DD for ; Tue, 2 Apr 2019 07:44:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 73339286F7; Tue, 2 Apr 2019 07:44:14 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B8ED0286DD for ; Tue, 2 Apr 2019 07:44:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C82D56E6F3; Tue, 2 Apr 2019 07:43:53 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.siol.net (mailoutvs63.siol.net [185.57.226.254]) by gabe.freedesktop.org (Postfix) with ESMTPS id 87FBC6E6D8 for ; Mon, 1 Apr 2019 19:15:30 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTP id D4873521529; Mon, 1 Apr 2019 21:15:28 +0200 (CEST) X-Virus-Scanned: amavisd-new at psrvmta11.zcs-production.pri Received: from mail.siol.net ([127.0.0.1]) by localhost (psrvmta11.zcs-production.pri [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id HlbkJBj15cao; Mon, 1 Apr 2019 21:15:28 +0200 (CEST) Received: from mail.siol.net (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTPS id 78F1B52065A; Mon, 1 Apr 2019 21:15:28 +0200 (CEST) Received: from localhost.localdomain (cpe-86-58-52-202.static.triera.net [86.58.52.202]) (Authenticated sender: 031275009) by mail.siol.net (Postfix) with ESMTPSA id 05EB2520886; Mon, 1 Apr 2019 21:15:24 +0200 (CEST) From: Jernej Skrabec To: maxime.ripard@bootlin.com Subject: [PATCH v2 1/2] drm/bridge/synopsys: dw-hdmi: Add an option to suppress loading CEC driver Date: Mon, 1 Apr 2019 21:15:12 +0200 Message-Id: <20190401191513.23159-2-jernej.skrabec@siol.net> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190401191513.23159-1-jernej.skrabec@siol.net> References: <20190401191513.23159-1-jernej.skrabec@siol.net> MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 02 Apr 2019 07:43:52 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: narmstrong@baylibre.com, airlied@linux.ie, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, wens@csie.org, Laurent.pinchart@ideasonboard.com, linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP DW HDMI controller on some Allwinner SoCs has support for CEC, but due to additional logic put between CEC controller and pins, it doesn't work correctly, at least not with a lot of instrusive changes. Fortunately, it's still possible to bitbang protocol. For such cases, add a platform option to suppress loading CEC driver. If DW HDMI CEC driver would be loaded, it wouldn't work anyway and would only cause a confusion with multiple /dev entries. Reviewed-by: Neil Armstrong Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- include/drm/bridge/dw_hdmi.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index db761329a1e3..d2b0aa8d964c 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2660,7 +2660,7 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->audio = platform_device_register_full(&pdevinfo); } - if (config0 & HDMI_CONFIG0_CEC) { + if (!plat_data->disable_cec && (config0 & HDMI_CONFIG0_CEC)) { cec.hdmi = hdmi; cec.ops = &dw_hdmi_cec_ops; cec.irq = irq; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 66e70770cce5..c03bea3a1a36 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -144,6 +144,8 @@ struct dw_hdmi_plat_data { int (*configure_phy)(struct dw_hdmi *hdmi, const struct dw_hdmi_plat_data *pdata, unsigned long mpixelclock); + + unsigned int disable_cec : 1; }; struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, From patchwork Mon Apr 1 19:15:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jernej_=C5=A0krabec?= X-Patchwork-Id: 10881211 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E19AB922 for ; Tue, 2 Apr 2019 07:44:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF64C1FF28 for ; Tue, 2 Apr 2019 07:44:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3A6E286D4; Tue, 2 Apr 2019 07:44:37 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BDEF31FF28 for ; Tue, 2 Apr 2019 07:44:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 34C816E713; Tue, 2 Apr 2019 07:43:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.siol.net (mailoutvs7.siol.net [185.57.226.198]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8459D6E6DA for ; Mon, 1 Apr 2019 19:15:34 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTP id BF5D252065A; Mon, 1 Apr 2019 21:15:32 +0200 (CEST) X-Virus-Scanned: amavisd-new at psrvmta11.zcs-production.pri Received: from mail.siol.net ([127.0.0.1]) by localhost (psrvmta11.zcs-production.pri [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id jt11YcywMIke; Mon, 1 Apr 2019 21:15:32 +0200 (CEST) Received: from mail.siol.net (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTPS id 31E2B520746; Mon, 1 Apr 2019 21:15:32 +0200 (CEST) Received: from localhost.localdomain (cpe-86-58-52-202.static.triera.net [86.58.52.202]) (Authenticated sender: 031275009) by mail.siol.net (Postfix) with ESMTPSA id BD97E520886; Mon, 1 Apr 2019 21:15:28 +0200 (CEST) From: Jernej Skrabec To: maxime.ripard@bootlin.com Subject: [PATCH v2 2/2] drm/sun4i: dw-hdmi: Bit bang CEC on some SoCs Date: Mon, 1 Apr 2019 21:15:13 +0200 Message-Id: <20190401191513.23159-3-jernej.skrabec@siol.net> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190401191513.23159-1-jernej.skrabec@siol.net> References: <20190401191513.23159-1-jernej.skrabec@siol.net> MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 02 Apr 2019 07:43:52 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: narmstrong@baylibre.com, airlied@linux.ie, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, wens@csie.org, Laurent.pinchart@ideasonboard.com, linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP All DW HDMI controllers used by Allwinner SoCs include CEC controller. However, due to additional logic put between CEC controller and pins, CEC communication doesn't work well on some of them. Based on observations, it seems that only outgoing messages are properly transmitted. It's possible that it would still work correctly if pins are switched between input and output mode manually in right moment. But that's very error prone. It's better and easier just to bit bang protocol. Enable bit banging just for controller and phy combination found in H3 and other 40nm SoCs. Other combinations work (H6) or the status is unknown (A83T). Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/Kconfig | 10 ++++ drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 11 ++++ drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 83 +++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig index 1dbbc3a1b763..7149c72e44c8 100644 --- a/drivers/gpu/drm/sun4i/Kconfig +++ b/drivers/gpu/drm/sun4i/Kconfig @@ -60,6 +60,16 @@ config DRM_SUN8I_DW_HDMI DesignWare HDMI controller with custom HDMI PHY. If M is selected the module will be called sun8i_dw_hdmi. +config DRM_SUN8I_DW_HDMI_CEC + bool "Allwinner DesignWare HDMI CEC Support for 40nm SoCs" + depends on DRM_SUN8I_DW_HDMI + select CEC_CORE + select CEC_PIN + help + Choose this option if you have an 40nm Allwinner SoC with + the DesignWare HDMI controller with custom HDMI PHY and + you want to use CEC. + config DRM_SUN8I_MIXER tristate "Support for Allwinner Display Engine 2.0 Mixer" default MACH_SUN8I diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 720c5aa8adc1..49ca001923e3 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -12,6 +12,7 @@ #include #include #include +#include #define SUN8I_HDMI_PHY_DBG_CTRL_REG 0x0000 #define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK BIT(0) @@ -144,6 +145,13 @@ #define SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK GENMASK(5, 0) #define SUN8I_HDMI_PHY_CEC_REG 0x003c +#define SUN8I_HDMI_PHY_CEC_PIN_CTRL BIT(7) +/* + * Documentation says that this bit is output enable. However, + * it seems that this bit is actually output disable. + */ +#define SUN8I_HDMI_PHY_CEC_OUT_DIS BIT(2) +#define SUN8I_HDMI_PHY_CEC_IN_DATA BIT(1) struct sun8i_hdmi_phy; @@ -151,6 +159,7 @@ struct sun8i_hdmi_phy_variant { bool has_phy_clk; bool has_second_pll; unsigned int is_custom_phy : 1; + unsigned int bit_bang_cec : 1; const struct dw_hdmi_curr_ctrl *cur_ctr; const struct dw_hdmi_mpll_config *mpll_cfg; const struct dw_hdmi_phy_config *phy_cfg; @@ -163,6 +172,8 @@ struct sun8i_hdmi_phy_variant { }; struct sun8i_hdmi_phy { + struct cec_adapter *cec_adapter; + struct cec_notifier *cec_notifier; struct clk *clk_bus; struct clk *clk_mod; struct clk *clk_phy; diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 66ea3a902e36..8fd6bf91714e 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -503,8 +503,9 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy) regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK, 0); - /* set HW control of CEC pins */ - regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, 0); + /* manual control of CEC pins */ + regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, + SUN8I_HDMI_PHY_CEC_PIN_CTRL); /* read calibration data */ regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val); @@ -530,8 +531,49 @@ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, plat_data->cur_ctr = variant->cur_ctr; plat_data->phy_config = variant->phy_cfg; } + plat_data->disable_cec = phy->variant->bit_bang_cec; } +#ifdef CONFIG_DRM_SUN8I_DW_HDMI_CEC +static bool sun8i_hdmi_phy_cec_pin_read(struct cec_adapter *adap) +{ + struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap); + unsigned int val; + + regmap_read(phy->regs, SUN8I_HDMI_PHY_CEC_REG, &val); + + return val & SUN8I_HDMI_PHY_CEC_IN_DATA; +} + +static void sun8i_hdmi_phy_cec_pin_low(struct cec_adapter *adap) +{ + struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap); + + /* Start driving the CEC pin low */ + regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, + SUN8I_HDMI_PHY_CEC_PIN_CTRL); +} + +static void sun8i_hdmi_phy_cec_pin_high(struct cec_adapter *adap) +{ + struct sun8i_hdmi_phy *phy = cec_get_drvdata(adap); + + /* + * Stop driving the CEC pin, the pull up will take over + * unless another CEC device is driving the pin low. + */ + regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, + SUN8I_HDMI_PHY_CEC_PIN_CTRL | + SUN8I_HDMI_PHY_CEC_OUT_DIS); +} + +static const struct cec_pin_ops sun8i_hdmi_phy_cec_pin_ops = { + .read = sun8i_hdmi_phy_cec_pin_read, + .low = sun8i_hdmi_phy_cec_pin_low, + .high = sun8i_hdmi_phy_cec_pin_high, +}; +#endif + static struct regmap_config sun8i_hdmi_phy_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -548,6 +590,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = { }; static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = { + .bit_bang_cec = true, .has_phy_clk = true, .is_custom_phy = true, .phy_init = &sun8i_hdmi_phy_init_h3, @@ -556,6 +599,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = { }; static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = { + .bit_bang_cec = true, .has_phy_clk = true, .has_second_pll = true, .is_custom_phy = true, @@ -565,6 +609,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = { }; static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = { + .bit_bang_cec = true, .has_phy_clk = true, .is_custom_phy = true, .phy_init = &sun8i_hdmi_phy_init_h3, @@ -708,10 +753,40 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) goto err_disable_clk_bus; } +#ifdef CONFIG_DRM_SUN8I_DW_HDMI_CEC + if (phy->variant->bit_bang_cec) { + phy->cec_notifier = cec_notifier_get(dev); + if (!phy->cec_notifier) { + ret = -ENOMEM; + goto err_disable_clk_mod; + } + + phy->cec_adapter = + cec_pin_allocate_adapter(&sun8i_hdmi_phy_cec_pin_ops, + phy, "sun8i-cec", + CEC_CAP_DEFAULTS); + ret = PTR_ERR_OR_ZERO(phy->cec_adapter); + if (ret < 0) + goto err_put_cec_notifier; + + ret = cec_register_adapter(phy->cec_adapter, dev); + if (ret < 0) + goto err_delete_cec_adapter; + + cec_register_cec_notifier(phy->cec_adapter, phy->cec_notifier); + } +#endif + hdmi->phy = phy; return 0; +err_delete_cec_adapter: + cec_delete_adapter(phy->cec_adapter); +err_put_cec_notifier: + cec_notifier_put(phy->cec_notifier); +err_disable_clk_mod: + clk_disable_unprepare(phy->clk_mod); err_disable_clk_bus: clk_disable_unprepare(phy->clk_bus); err_deassert_rst_phy: @@ -736,6 +811,10 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) { struct sun8i_hdmi_phy *phy = hdmi->phy; + cec_unregister_adapter(phy->cec_adapter); + if (phy->cec_notifier) + cec_notifier_put(phy->cec_notifier); + clk_disable_unprepare(phy->clk_mod); clk_disable_unprepare(phy->clk_bus); clk_disable_unprepare(phy->clk_phy);