From mboxrd@z Thu Jan 1 00:00:00 1970 From: laurent.pinchart@ideasonboard.com (Laurent Pinchart) Date: Tue, 17 Jan 2017 16:54:16 +0200 Subject: [RFC/RFT PATCH 2/4] drm/bridge: dw-hdmi: Add support for custom PHY handling In-Reply-To: <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> References: <1484656294-6140-1-git-send-email-narmstrong@baylibre.com> <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> Message-ID: <1766052.45cMAnqkLu@avalon> To: linus-amlogic@lists.infradead.org List-Id: linus-amlogic.lists.infradead.org Hi Neil, Thank you for the patch. On Tuesday 17 Jan 2017 13:31:32 Neil Armstrong wrote: > The Synopsys DesignWare HDMI TX Controller support various Transceivers > (PHY) attached to the controller, but also allows fully custom PHYs to be > connected. > > Add PHY init, disable functions in plat_data to handle fully custom PHY > init. > > Some custom PHYs also handles the HPD and RxSense separately and do not use > the internal signals exported in the Controller's IRQ stat, so a read_hpd > is provided to switch to HPD status polling. > To complete the implementation, add a function to mimic the Controllers > interrupt HPD and RxSense handling from the vendor PHY wrapper code. I believe this goes in the right direction. PHY handling needs to be decoupled from the TX controller. As you've noticed I've taken a first step in that direction with "drm: bridge: dw-hdmi: Refactor PHY power handling", but that's not enough. Issues were reported with that patch which I plan to rework. If that's fine with you, I'll rebase it on top of this patch (that I will likely modify) and plan to get the result ready for v4.12. > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/dw-hdmi.c | 78 +++++++++++++++++++++++++++++-------- > include/drm/bridge/dw_hdmi.h | 8 +++++ > 2 files changed, 70 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c > b/drivers/gpu/drm/bridge/dw-hdmi.c index 13747fe..923e250 100644 > --- a/drivers/gpu/drm/bridge/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/dw-hdmi.c > @@ -1434,9 +1434,18 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct > drm_display_mode *mode) hdmi_av_composer(hdmi, mode); > > /* HDMI Initializateion Step B.2 */ > - ret = dw_hdmi_phy_init(hdmi); > - if (ret) > - return ret; > + if (hdmi->plat_data->hdmi_phy_init) { > + ret = hdmi->plat_data->hdmi_phy_init(hdmi, hdmi->plat_data, > + &hdmi->previous_mode); > + if (ret) > + return ret; > + > + hdmi->phy_enabled = true; > + } else { > + ret = dw_hdmi_phy_init(hdmi); > + if (ret) > + return ret; > + } > > /* HDMI Initialization Step B.3 */ > dw_hdmi_enable_video_path(hdmi); > @@ -1551,7 +1560,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi) > > static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) > { > - dw_hdmi_phy_disable(hdmi); > + if (hdmi->phy_enabled && hdmi->plat_data->hdmi_phy_disable) { > + hdmi->plat_data->hdmi_phy_disable(hdmi, hdmi->plat_data); > + hdmi->phy_enabled = false; > + } else > + dw_hdmi_phy_disable(hdmi); > hdmi->bridge_is_on = false; > } > > @@ -1593,6 +1606,9 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi > *hdmi) { > u8 old_mask = hdmi->phy_mask; > > + if (hdmi->plat_data && hdmi->plat_data->hdmi_read_hpd) > + return; > + > if (hdmi->force || hdmi->disabled || !hdmi->rxsense) > hdmi->phy_mask |= HDMI_PHY_RX_SENSE; > else > @@ -1614,6 +1630,11 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi > *hdmi) dw_hdmi_update_phy_mask(hdmi); > mutex_unlock(&hdmi->mutex); > > + if (hdmi->plat_data && hdmi->plat_data->hdmi_read_hpd) > + return hdmi->plat_data->hdmi_read_hpd(hdmi, hdmi->plat_data) ? > + connector_status_connected : > + connector_status_disconnected; > + > return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? > connector_status_connected : connector_status_disconnected; > } > @@ -1901,6 +1922,26 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) > } > }; > > +void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) > +{ > + struct dw_hdmi *hdmi = dev_get_drvdata(dev); > + > + mutex_lock(&hdmi->mutex); > + > + if (!hdmi->disabled && !hdmi->force) { > + if (!rx_sense) > + hdmi->rxsense = false; > + > + if (hpd) > + hdmi->rxsense = true; > + > + dw_hdmi_update_power(hdmi); > + dw_hdmi_update_phy_mask(hdmi); > + } > + mutex_unlock(&hdmi->mutex); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); > + > static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > { > unsigned int i; > @@ -1921,7 +1962,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > return -ENODEV; > } > > - if (!hdmi->phy->configure && !hdmi->plat_data->configure_phy) { > + if (!hdmi->phy->configure && > + !hdmi->plat_data->configure_phy && > + !hdmi->plat_data->hdmi_phy_init) { > dev_err(hdmi->dev, "%s requires platform support\n", > hdmi->phy->name); > return -ENODEV; > @@ -2101,15 +2144,17 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > hdmi->ddc = NULL; > } > > - /* > - * Configure registers related to HDMI interrupt > - * generation before registering IRQ. > - */ > - hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); > + if (!hdmi->plat_data || !hdmi->plat_data->hdmi_read_hpd) { > + /* > + * Configure registers related to HDMI interrupt > + * generation before registering IRQ. > + */ > + hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); > > - /* Clear Hotplug interrupts */ > - hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, > - HDMI_IH_PHY_STAT0); > + /* Clear Hotplug interrupts */ > + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, > + HDMI_IH_PHY_STAT0); > + } > > hdmi->bridge.driver_private = hdmi; > hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; > @@ -2119,9 +2164,10 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > if (ret) > goto err_iahb; > > - /* Unmute interrupts */ > - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), > - HDMI_IH_MUTE_PHY_STAT0); > + if (!hdmi->plat_data || !hdmi->plat_data->hdmi_read_hpd) > + /* Unmute interrupts */ > + hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), > + HDMI_IH_MUTE_PHY_STAT0); > > memset(&pdevinfo, 0, sizeof(pdevinfo)); > pdevinfo.parent = dev; > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h > index 163842d..d6a0ab3 100644 > --- a/include/drm/bridge/dw_hdmi.h > +++ b/include/drm/bridge/dw_hdmi.h > @@ -61,6 +61,13 @@ struct dw_hdmi_plat_data { > enum drm_mode_status (*mode_valid)(struct drm_connector *connector, > struct drm_display_mode *mode); > struct regmap *regm; > + int (*hdmi_phy_init)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data, > + struct drm_display_mode *mode); > + void (*hdmi_phy_disable)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data); > + bool (*hdmi_read_hpd)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data); > }; > > int dw_hdmi_probe(struct platform_device *pdev, > @@ -70,6 +77,7 @@ int dw_hdmi_probe(struct platform_device *pdev, > int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, > const struct dw_hdmi_plat_data *plat_data); > > +void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); > void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [RFC/RFT PATCH 2/4] drm/bridge: dw-hdmi: Add support for custom PHY handling Date: Tue, 17 Jan 2017 16:54:16 +0200 Message-ID: <1766052.45cMAnqkLu@avalon> References: <1484656294-6140-1-git-send-email-narmstrong@baylibre.com> <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [185.26.127.97]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1DC796E3E1 for ; Tue, 17 Jan 2017 14:54:01 +0000 (UTC) In-Reply-To: <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Neil Armstrong Cc: Jose.Abreu@synopsys.com, laurent.pinchart+renesas@ideasonboard.com, kieran.bingham@ideasonboard.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org List-Id: dri-devel@lists.freedesktop.org SGkgTmVpbCwKClRoYW5rIHlvdSBmb3IgdGhlIHBhdGNoLgoKT24gVHVlc2RheSAxNyBKYW4gMjAx NyAxMzozMTozMiBOZWlsIEFybXN0cm9uZyB3cm90ZToKPiBUaGUgU3lub3BzeXMgRGVzaWduV2Fy ZSBIRE1JIFRYIENvbnRyb2xsZXIgc3VwcG9ydCB2YXJpb3VzIFRyYW5zY2VpdmVycwo+IChQSFkp IGF0dGFjaGVkIHRvIHRoZSBjb250cm9sbGVyLCBidXQgYWxzbyBhbGxvd3MgZnVsbHkgY3VzdG9t IFBIWXMgdG8gYmUKPiBjb25uZWN0ZWQuCj4gCj4gQWRkIFBIWSBpbml0LCBkaXNhYmxlIGZ1bmN0 aW9ucyBpbiBwbGF0X2RhdGEgdG8gaGFuZGxlIGZ1bGx5IGN1c3RvbSBQSFkKPiBpbml0Lgo+IAo+ IFNvbWUgY3VzdG9tIFBIWXMgYWxzbyBoYW5kbGVzIHRoZSBIUEQgYW5kIFJ4U2Vuc2Ugc2VwYXJh dGVseSBhbmQgZG8gbm90IHVzZQo+IHRoZSBpbnRlcm5hbCBzaWduYWxzIGV4cG9ydGVkIGluIHRo ZSBDb250cm9sbGVyJ3MgSVJRIHN0YXQsIHNvIGEgcmVhZF9ocGQKPiBpcyBwcm92aWRlZCB0byBz d2l0Y2ggdG8gSFBEIHN0YXR1cyBwb2xsaW5nLgo+IFRvIGNvbXBsZXRlIHRoZSBpbXBsZW1lbnRh dGlvbiwgYWRkIGEgZnVuY3Rpb24gdG8gbWltaWMgdGhlIENvbnRyb2xsZXJzCj4gaW50ZXJydXB0 IEhQRCBhbmQgUnhTZW5zZSBoYW5kbGluZyBmcm9tIHRoZSB2ZW5kb3IgUEhZIHdyYXBwZXIgY29k ZS4KCkkgYmVsaWV2ZSB0aGlzIGdvZXMgaW4gdGhlIHJpZ2h0IGRpcmVjdGlvbi4gUEhZIGhhbmRs aW5nIG5lZWRzIHRvIGJlIGRlY291cGxlZCAKZnJvbSB0aGUgVFggY29udHJvbGxlci4gQXMgeW91 J3ZlIG5vdGljZWQgSSd2ZSB0YWtlbiBhIGZpcnN0IHN0ZXAgaW4gdGhhdCAKZGlyZWN0aW9uIHdp dGggImRybTogYnJpZGdlOiBkdy1oZG1pOiBSZWZhY3RvciBQSFkgcG93ZXIgaGFuZGxpbmciLCBi dXQgdGhhdCdzIApub3QgZW5vdWdoLiBJc3N1ZXMgd2VyZSByZXBvcnRlZCB3aXRoIHRoYXQgcGF0 Y2ggd2hpY2ggSSBwbGFuIHRvIHJld29yay4gSWYgCnRoYXQncyBmaW5lIHdpdGggeW91LCBJJ2xs IHJlYmFzZSBpdCBvbiB0b3Agb2YgdGhpcyBwYXRjaCAodGhhdCBJIHdpbGwgbGlrZWx5IAptb2Rp ZnkpIGFuZCBwbGFuIHRvIGdldCB0aGUgcmVzdWx0IHJlYWR5IGZvciB2NC4xMi4KCj4gU2lnbmVk LW9mZi1ieTogTmVpbCBBcm1zdHJvbmcgPG5hcm1zdHJvbmdAYmF5bGlicmUuY29tPgo+IC0tLQo+ ICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R3LWhkbWkuYyB8IDc4ICsrKysrKysrKysrKysrKysr KysrKysrKysrKysrLS0tLS0tLS0KPiAgaW5jbHVkZS9kcm0vYnJpZGdlL2R3X2hkbWkuaCAgICAg fCAgOCArKysrKwo+ICAyIGZpbGVzIGNoYW5nZWQsIDcwIGluc2VydGlvbnMoKyksIDE2IGRlbGV0 aW9ucygtKQo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R3LWhkbWku Ywo+IGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9kdy1oZG1pLmMgaW5kZXggMTM3NDdmZS4uOTIz ZTI1MCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R3LWhkbWkuYwo+ICsr KyBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvZHctaGRtaS5jCj4gQEAgLTE0MzQsOSArMTQzNCwx OCBAQCBzdGF0aWMgaW50IGR3X2hkbWlfc2V0dXAoc3RydWN0IGR3X2hkbWkgKmhkbWksIHN0cnVj dAo+IGRybV9kaXNwbGF5X21vZGUgKm1vZGUpIGhkbWlfYXZfY29tcG9zZXIoaGRtaSwgbW9kZSk7 Cj4gCj4gIAkvKiBIRE1JIEluaXRpYWxpemF0ZWlvbiBTdGVwIEIuMiAqLwo+IC0JcmV0ID0gZHdf aGRtaV9waHlfaW5pdChoZG1pKTsKPiAtCWlmIChyZXQpCj4gLQkJcmV0dXJuIHJldDsKPiArCWlm IChoZG1pLT5wbGF0X2RhdGEtPmhkbWlfcGh5X2luaXQpIHsKPiArCQlyZXQgPSBoZG1pLT5wbGF0 X2RhdGEtPmhkbWlfcGh5X2luaXQoaGRtaSwgaGRtaS0+cGxhdF9kYXRhLAo+ICsJCQkJCQkgICAg ICZoZG1pLT5wcmV2aW91c19tb2RlKTsKPiArCQlpZiAocmV0KQo+ICsJCQlyZXR1cm4gcmV0Owo+ ICsKPiArCQloZG1pLT5waHlfZW5hYmxlZCA9IHRydWU7Cj4gKwl9IGVsc2Ugewo+ICsJCXJldCA9 IGR3X2hkbWlfcGh5X2luaXQoaGRtaSk7Cj4gKwkJaWYgKHJldCkKPiArCQkJcmV0dXJuIHJldDsK PiArCX0KPiAKPiAgCS8qIEhETUkgSW5pdGlhbGl6YXRpb24gU3RlcCBCLjMgKi8KPiAgCWR3X2hk bWlfZW5hYmxlX3ZpZGVvX3BhdGgoaGRtaSk7Cj4gQEAgLTE1NTEsNyArMTU2MCwxMSBAQCBzdGF0 aWMgdm9pZCBkd19oZG1pX3Bvd2Vyb24oc3RydWN0IGR3X2hkbWkgKmhkbWkpCj4gCj4gIHN0YXRp YyB2b2lkIGR3X2hkbWlfcG93ZXJvZmYoc3RydWN0IGR3X2hkbWkgKmhkbWkpCj4gIHsKPiAtCWR3 X2hkbWlfcGh5X2Rpc2FibGUoaGRtaSk7Cj4gKwlpZiAoaGRtaS0+cGh5X2VuYWJsZWQgJiYgaGRt aS0+cGxhdF9kYXRhLT5oZG1pX3BoeV9kaXNhYmxlKSB7Cj4gKwkJaGRtaS0+cGxhdF9kYXRhLT5o ZG1pX3BoeV9kaXNhYmxlKGhkbWksIGhkbWktPnBsYXRfZGF0YSk7Cj4gKwkJaGRtaS0+cGh5X2Vu YWJsZWQgPSBmYWxzZTsKPiArCX0gZWxzZQo+ICsJCWR3X2hkbWlfcGh5X2Rpc2FibGUoaGRtaSk7 Cj4gIAloZG1pLT5icmlkZ2VfaXNfb24gPSBmYWxzZTsKPiAgfQo+IAo+IEBAIC0xNTkzLDYgKzE2 MDYsOSBAQCBzdGF0aWMgdm9pZCBkd19oZG1pX3VwZGF0ZV9waHlfbWFzayhzdHJ1Y3QgZHdfaGRt aQo+ICpoZG1pKSB7Cj4gIAl1OCBvbGRfbWFzayA9IGhkbWktPnBoeV9tYXNrOwo+IAo+ICsJaWYg KGhkbWktPnBsYXRfZGF0YSAmJiBoZG1pLT5wbGF0X2RhdGEtPmhkbWlfcmVhZF9ocGQpCj4gKwkJ cmV0dXJuOwo+ICsKPiAgCWlmIChoZG1pLT5mb3JjZSB8fCBoZG1pLT5kaXNhYmxlZCB8fCAhaGRt aS0+cnhzZW5zZSkKPiAgCQloZG1pLT5waHlfbWFzayB8PSBIRE1JX1BIWV9SWF9TRU5TRTsKPiAg CWVsc2UKPiBAQCAtMTYxNCw2ICsxNjMwLDExIEBAIHN0YXRpYyB2b2lkIGR3X2hkbWlfdXBkYXRl X3BoeV9tYXNrKHN0cnVjdCBkd19oZG1pCj4gKmhkbWkpIGR3X2hkbWlfdXBkYXRlX3BoeV9tYXNr KGhkbWkpOwo+ICAJbXV0ZXhfdW5sb2NrKCZoZG1pLT5tdXRleCk7Cj4gCj4gKwlpZiAoaGRtaS0+ cGxhdF9kYXRhICYmIGhkbWktPnBsYXRfZGF0YS0+aGRtaV9yZWFkX2hwZCkKPiArCQlyZXR1cm4g aGRtaS0+cGxhdF9kYXRhLT5oZG1pX3JlYWRfaHBkKGhkbWksIGhkbWktPnBsYXRfZGF0YSkgPwo+ ICsJCQljb25uZWN0b3Jfc3RhdHVzX2Nvbm5lY3RlZCA6Cj4gKwkJCWNvbm5lY3Rvcl9zdGF0dXNf ZGlzY29ubmVjdGVkOwo+ICsKPiAgCXJldHVybiBoZG1pX3JlYWRiKGhkbWksIEhETUlfUEhZX1NU QVQwKSAmIEhETUlfUEhZX0hQRCA/Cj4gIAkJY29ubmVjdG9yX3N0YXR1c19jb25uZWN0ZWQgOiBj b25uZWN0b3Jfc3RhdHVzX2Rpc2Nvbm5lY3RlZDsKPiAgfQo+IEBAIC0xOTAxLDYgKzE5MjIsMjYg QEAgc3RhdGljIGlycXJldHVybl90IGR3X2hkbWlfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCkK PiB9Cj4gIH07Cj4gCj4gK3ZvaWQgZHdfaGRtaV9zZXR1cF9yeF9zZW5zZShzdHJ1Y3QgZGV2aWNl ICpkZXYsIGJvb2wgaHBkLCBib29sIHJ4X3NlbnNlKQo+ICt7Cj4gKwlzdHJ1Y3QgZHdfaGRtaSAq aGRtaSA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+ICsKPiArCW11dGV4X2xvY2soJmhkbWktPm11 dGV4KTsKPiArCj4gKwlpZiAoIWhkbWktPmRpc2FibGVkICYmICFoZG1pLT5mb3JjZSkgewo+ICsJ CWlmICghcnhfc2Vuc2UpCj4gKwkJCWhkbWktPnJ4c2Vuc2UgPSBmYWxzZTsKPiArCj4gKwkJaWYg KGhwZCkKPiArCQkJaGRtaS0+cnhzZW5zZSA9IHRydWU7Cj4gKwo+ICsJCWR3X2hkbWlfdXBkYXRl X3Bvd2VyKGhkbWkpOwo+ICsJCWR3X2hkbWlfdXBkYXRlX3BoeV9tYXNrKGhkbWkpOwo+ICsJfQo+ ICsJbXV0ZXhfdW5sb2NrKCZoZG1pLT5tdXRleCk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwo ZHdfaGRtaV9zZXR1cF9yeF9zZW5zZSk7Cj4gKwo+ICBzdGF0aWMgaW50IGR3X2hkbWlfZGV0ZWN0 X3BoeShzdHJ1Y3QgZHdfaGRtaSAqaGRtaSkKPiAgewo+ICAJdW5zaWduZWQgaW50IGk7Cj4gQEAg LTE5MjEsNyArMTk2Miw5IEBAIHN0YXRpYyBpbnQgZHdfaGRtaV9kZXRlY3RfcGh5KHN0cnVjdCBk d19oZG1pICpoZG1pKQo+ICAJCXJldHVybiAtRU5PREVWOwo+ICAJfQo+IAo+IC0JaWYgKCFoZG1p LT5waHktPmNvbmZpZ3VyZSAmJiAhaGRtaS0+cGxhdF9kYXRhLT5jb25maWd1cmVfcGh5KSB7Cj4g KwlpZiAoIWhkbWktPnBoeS0+Y29uZmlndXJlICYmCj4gKwkgICAgIWhkbWktPnBsYXRfZGF0YS0+ Y29uZmlndXJlX3BoeSAmJgo+ICsJICAgICFoZG1pLT5wbGF0X2RhdGEtPmhkbWlfcGh5X2luaXQp IHsKPiAgCQlkZXZfZXJyKGhkbWktPmRldiwgIiVzIHJlcXVpcmVzIHBsYXRmb3JtIHN1cHBvcnRc biIsCj4gIAkJCWhkbWktPnBoeS0+bmFtZSk7Cj4gIAkJcmV0dXJuIC1FTk9ERVY7Cj4gQEAgLTIx MDEsMTUgKzIxNDQsMTcgQEAgc3RhdGljIGludCBkd19oZG1pX2RldGVjdF9waHkoc3RydWN0IGR3 X2hkbWkgKmhkbWkpCj4gIAkJCWhkbWktPmRkYyA9IE5VTEw7Cj4gIAl9Cj4gCj4gLQkvKgo+IC0J ICogQ29uZmlndXJlIHJlZ2lzdGVycyByZWxhdGVkIHRvIEhETUkgaW50ZXJydXB0Cj4gLQkgKiBn ZW5lcmF0aW9uIGJlZm9yZSByZWdpc3RlcmluZyBJUlEuCj4gLQkgKi8KPiAtCWhkbWlfd3JpdGVi KGhkbWksIEhETUlfUEhZX0hQRCB8IEhETUlfUEhZX1JYX1NFTlNFLCBIRE1JX1BIWV9QT0wwKTsK PiArCWlmICghaGRtaS0+cGxhdF9kYXRhIHx8ICFoZG1pLT5wbGF0X2RhdGEtPmhkbWlfcmVhZF9o cGQpIHsKPiArCQkvKgo+ICsJCSAqIENvbmZpZ3VyZSByZWdpc3RlcnMgcmVsYXRlZCB0byBIRE1J IGludGVycnVwdAo+ICsJCSAqIGdlbmVyYXRpb24gYmVmb3JlIHJlZ2lzdGVyaW5nIElSUS4KPiAr CQkgKi8KPiArCQloZG1pX3dyaXRlYihoZG1pLCBIRE1JX1BIWV9IUEQgfCBIRE1JX1BIWV9SWF9T RU5TRSwgCkhETUlfUEhZX1BPTDApOwo+IAo+IC0JLyogQ2xlYXIgSG90cGx1ZyBpbnRlcnJ1cHRz ICovCj4gLQloZG1pX3dyaXRlYihoZG1pLCBIRE1JX0lIX1BIWV9TVEFUMF9IUEQgfCBIRE1JX0lI X1BIWV9TVEFUMF9SWF9TRU5TRSwKPiAtCQkgICAgSERNSV9JSF9QSFlfU1RBVDApOwo+ICsJCS8q IENsZWFyIEhvdHBsdWcgaW50ZXJydXB0cyAqLwo+ICsJCWhkbWlfd3JpdGViKGhkbWksIEhETUlf SUhfUEhZX1NUQVQwX0hQRCB8IApIRE1JX0lIX1BIWV9TVEFUMF9SWF9TRU5TRSwKPiArCQkJICAg IEhETUlfSUhfUEhZX1NUQVQwKTsKPiArCX0KPiAKPiAgCWhkbWktPmJyaWRnZS5kcml2ZXJfcHJp dmF0ZSA9IGhkbWk7Cj4gIAloZG1pLT5icmlkZ2UuZnVuY3MgPSAmZHdfaGRtaV9icmlkZ2VfZnVu Y3M7Cj4gQEAgLTIxMTksOSArMjE2NCwxMCBAQCBzdGF0aWMgaW50IGR3X2hkbWlfZGV0ZWN0X3Bo eShzdHJ1Y3QgZHdfaGRtaSAqaGRtaSkKPiAgCWlmIChyZXQpCj4gIAkJZ290byBlcnJfaWFoYjsK PiAKPiAtCS8qIFVubXV0ZSBpbnRlcnJ1cHRzICovCj4gLQloZG1pX3dyaXRlYihoZG1pLCB+KEhE TUlfSUhfUEhZX1NUQVQwX0hQRCB8IApIRE1JX0lIX1BIWV9TVEFUMF9SWF9TRU5TRSksCj4gLQkJ ICAgIEhETUlfSUhfTVVURV9QSFlfU1RBVDApOwo+ICsJaWYgKCFoZG1pLT5wbGF0X2RhdGEgfHwg IWhkbWktPnBsYXRfZGF0YS0+aGRtaV9yZWFkX2hwZCkKPiArCQkvKiBVbm11dGUgaW50ZXJydXB0 cyAqLwo+ICsJCWhkbWlfd3JpdGViKGhkbWksIH4oSERNSV9JSF9QSFlfU1RBVDBfSFBEIHwgCkhE TUlfSUhfUEhZX1NUQVQwX1JYX1NFTlNFKSwKPiArCQkJICAgIEhETUlfSUhfTVVURV9QSFlfU1RB VDApOwo+IAo+ICAJbWVtc2V0KCZwZGV2aW5mbywgMCwgc2l6ZW9mKHBkZXZpbmZvKSk7Cj4gIAlw ZGV2aW5mby5wYXJlbnQgPSBkZXY7Cj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvZHJtL2JyaWRnZS9k d19oZG1pLmggYi9pbmNsdWRlL2RybS9icmlkZ2UvZHdfaGRtaS5oCj4gaW5kZXggMTYzODQyZC4u ZDZhMGFiMyAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2RybS9icmlkZ2UvZHdfaGRtaS5oCj4gKysr IGIvaW5jbHVkZS9kcm0vYnJpZGdlL2R3X2hkbWkuaAo+IEBAIC02MSw2ICs2MSwxMyBAQCBzdHJ1 Y3QgZHdfaGRtaV9wbGF0X2RhdGEgewo+ICAJZW51bSBkcm1fbW9kZV9zdGF0dXMgKCptb2RlX3Zh bGlkKShzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLAo+ICAJCQkJCSAgIHN0cnVjdCBk cm1fZGlzcGxheV9tb2RlICptb2RlKTsKPiAgCXN0cnVjdCByZWdtYXAgKnJlZ207Cj4gKwlpbnQg KCpoZG1pX3BoeV9pbml0KShzdHJ1Y3QgZHdfaGRtaSAqaGRtaSwKPiArCQkJICAgICBjb25zdCBz dHJ1Y3QgZHdfaGRtaV9wbGF0X2RhdGEgKmRhdGEsCj4gKwkJCSAgICAgc3RydWN0IGRybV9kaXNw bGF5X21vZGUgKm1vZGUpOwo+ICsJdm9pZCAoKmhkbWlfcGh5X2Rpc2FibGUpKHN0cnVjdCBkd19o ZG1pICpoZG1pLAo+ICsJCQkJIGNvbnN0IHN0cnVjdCBkd19oZG1pX3BsYXRfZGF0YSAqZGF0YSk7 Cj4gKwlib29sICgqaGRtaV9yZWFkX2hwZCkoc3RydWN0IGR3X2hkbWkgKmhkbWksCj4gKwkJCSAg ICAgIGNvbnN0IHN0cnVjdCBkd19oZG1pX3BsYXRfZGF0YSAqZGF0YSk7Cj4gIH07Cj4gCj4gIGlu dCBkd19oZG1pX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsCj4gQEAgLTcwLDYg Kzc3LDcgQEAgaW50IGR3X2hkbWlfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiwK PiAgaW50IGR3X2hkbWlfYmluZChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LCBzdHJ1Y3Qg ZHJtX2VuY29kZXIgKmVuY29kZXIsCj4gY29uc3Qgc3RydWN0IGR3X2hkbWlfcGxhdF9kYXRhICpw bGF0X2RhdGEpOwo+IAo+ICt2b2lkIGR3X2hkbWlfc2V0dXBfcnhfc2Vuc2Uoc3RydWN0IGRldmlj ZSAqZGV2LCBib29sIGhwZCwgYm9vbCByeF9zZW5zZSk7Cj4gIHZvaWQgZHdfaGRtaV9zZXRfc2Ft cGxlX3JhdGUoc3RydWN0IGR3X2hkbWkgKmhkbWksIHVuc2lnbmVkIGludCByYXRlKTsKPiAgdm9p ZCBkd19oZG1pX2F1ZGlvX2VuYWJsZShzdHJ1Y3QgZHdfaGRtaSAqaGRtaSk7Cj4gIHZvaWQgZHdf aGRtaV9hdWRpb19kaXNhYmxlKHN0cnVjdCBkd19oZG1pICpoZG1pKTsKCi0tIApSZWdhcmRzLAoK TGF1cmVudCBQaW5jaGFydAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0 b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJp LWRldmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751345AbdAQOy2 (ORCPT ); Tue, 17 Jan 2017 09:54:28 -0500 Received: from galahad.ideasonboard.com ([185.26.127.97]:34834 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751099AbdAQOyC (ORCPT ); Tue, 17 Jan 2017 09:54:02 -0500 From: Laurent Pinchart To: Neil Armstrong Cc: dri-devel@lists.freedesktop.org, laurent.pinchart+renesas@ideasonboard.com, Jose.Abreu@synopsys.com, kieran.bingham@ideasonboard.com, linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [RFC/RFT PATCH 2/4] drm/bridge: dw-hdmi: Add support for custom PHY handling Date: Tue, 17 Jan 2017 16:54:16 +0200 Message-ID: <1766052.45cMAnqkLu@avalon> User-Agent: KMail/4.14.10 (Linux/4.8.6-gentoo; KDE/4.14.24; x86_64; ; ) In-Reply-To: <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> References: <1484656294-6140-1-git-send-email-narmstrong@baylibre.com> <1484656294-6140-3-git-send-email-narmstrong@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Neil, Thank you for the patch. On Tuesday 17 Jan 2017 13:31:32 Neil Armstrong wrote: > The Synopsys DesignWare HDMI TX Controller support various Transceivers > (PHY) attached to the controller, but also allows fully custom PHYs to be > connected. > > Add PHY init, disable functions in plat_data to handle fully custom PHY > init. > > Some custom PHYs also handles the HPD and RxSense separately and do not use > the internal signals exported in the Controller's IRQ stat, so a read_hpd > is provided to switch to HPD status polling. > To complete the implementation, add a function to mimic the Controllers > interrupt HPD and RxSense handling from the vendor PHY wrapper code. I believe this goes in the right direction. PHY handling needs to be decoupled from the TX controller. As you've noticed I've taken a first step in that direction with "drm: bridge: dw-hdmi: Refactor PHY power handling", but that's not enough. Issues were reported with that patch which I plan to rework. If that's fine with you, I'll rebase it on top of this patch (that I will likely modify) and plan to get the result ready for v4.12. > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/dw-hdmi.c | 78 +++++++++++++++++++++++++++++-------- > include/drm/bridge/dw_hdmi.h | 8 +++++ > 2 files changed, 70 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c > b/drivers/gpu/drm/bridge/dw-hdmi.c index 13747fe..923e250 100644 > --- a/drivers/gpu/drm/bridge/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/dw-hdmi.c > @@ -1434,9 +1434,18 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct > drm_display_mode *mode) hdmi_av_composer(hdmi, mode); > > /* HDMI Initializateion Step B.2 */ > - ret = dw_hdmi_phy_init(hdmi); > - if (ret) > - return ret; > + if (hdmi->plat_data->hdmi_phy_init) { > + ret = hdmi->plat_data->hdmi_phy_init(hdmi, hdmi->plat_data, > + &hdmi->previous_mode); > + if (ret) > + return ret; > + > + hdmi->phy_enabled = true; > + } else { > + ret = dw_hdmi_phy_init(hdmi); > + if (ret) > + return ret; > + } > > /* HDMI Initialization Step B.3 */ > dw_hdmi_enable_video_path(hdmi); > @@ -1551,7 +1560,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi) > > static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) > { > - dw_hdmi_phy_disable(hdmi); > + if (hdmi->phy_enabled && hdmi->plat_data->hdmi_phy_disable) { > + hdmi->plat_data->hdmi_phy_disable(hdmi, hdmi->plat_data); > + hdmi->phy_enabled = false; > + } else > + dw_hdmi_phy_disable(hdmi); > hdmi->bridge_is_on = false; > } > > @@ -1593,6 +1606,9 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi > *hdmi) { > u8 old_mask = hdmi->phy_mask; > > + if (hdmi->plat_data && hdmi->plat_data->hdmi_read_hpd) > + return; > + > if (hdmi->force || hdmi->disabled || !hdmi->rxsense) > hdmi->phy_mask |= HDMI_PHY_RX_SENSE; > else > @@ -1614,6 +1630,11 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi > *hdmi) dw_hdmi_update_phy_mask(hdmi); > mutex_unlock(&hdmi->mutex); > > + if (hdmi->plat_data && hdmi->plat_data->hdmi_read_hpd) > + return hdmi->plat_data->hdmi_read_hpd(hdmi, hdmi->plat_data) ? > + connector_status_connected : > + connector_status_disconnected; > + > return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? > connector_status_connected : connector_status_disconnected; > } > @@ -1901,6 +1922,26 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) > } > }; > > +void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) > +{ > + struct dw_hdmi *hdmi = dev_get_drvdata(dev); > + > + mutex_lock(&hdmi->mutex); > + > + if (!hdmi->disabled && !hdmi->force) { > + if (!rx_sense) > + hdmi->rxsense = false; > + > + if (hpd) > + hdmi->rxsense = true; > + > + dw_hdmi_update_power(hdmi); > + dw_hdmi_update_phy_mask(hdmi); > + } > + mutex_unlock(&hdmi->mutex); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); > + > static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > { > unsigned int i; > @@ -1921,7 +1962,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > return -ENODEV; > } > > - if (!hdmi->phy->configure && !hdmi->plat_data->configure_phy) { > + if (!hdmi->phy->configure && > + !hdmi->plat_data->configure_phy && > + !hdmi->plat_data->hdmi_phy_init) { > dev_err(hdmi->dev, "%s requires platform support\n", > hdmi->phy->name); > return -ENODEV; > @@ -2101,15 +2144,17 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > hdmi->ddc = NULL; > } > > - /* > - * Configure registers related to HDMI interrupt > - * generation before registering IRQ. > - */ > - hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); > + if (!hdmi->plat_data || !hdmi->plat_data->hdmi_read_hpd) { > + /* > + * Configure registers related to HDMI interrupt > + * generation before registering IRQ. > + */ > + hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); > > - /* Clear Hotplug interrupts */ > - hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, > - HDMI_IH_PHY_STAT0); > + /* Clear Hotplug interrupts */ > + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, > + HDMI_IH_PHY_STAT0); > + } > > hdmi->bridge.driver_private = hdmi; > hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; > @@ -2119,9 +2164,10 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) > if (ret) > goto err_iahb; > > - /* Unmute interrupts */ > - hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), > - HDMI_IH_MUTE_PHY_STAT0); > + if (!hdmi->plat_data || !hdmi->plat_data->hdmi_read_hpd) > + /* Unmute interrupts */ > + hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), > + HDMI_IH_MUTE_PHY_STAT0); > > memset(&pdevinfo, 0, sizeof(pdevinfo)); > pdevinfo.parent = dev; > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h > index 163842d..d6a0ab3 100644 > --- a/include/drm/bridge/dw_hdmi.h > +++ b/include/drm/bridge/dw_hdmi.h > @@ -61,6 +61,13 @@ struct dw_hdmi_plat_data { > enum drm_mode_status (*mode_valid)(struct drm_connector *connector, > struct drm_display_mode *mode); > struct regmap *regm; > + int (*hdmi_phy_init)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data, > + struct drm_display_mode *mode); > + void (*hdmi_phy_disable)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data); > + bool (*hdmi_read_hpd)(struct dw_hdmi *hdmi, > + const struct dw_hdmi_plat_data *data); > }; > > int dw_hdmi_probe(struct platform_device *pdev, > @@ -70,6 +77,7 @@ int dw_hdmi_probe(struct platform_device *pdev, > int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, > const struct dw_hdmi_plat_data *plat_data); > > +void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); > void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); -- Regards, Laurent Pinchart