All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/29] R-Car Gen3 HDMI output support
@ 2016-12-20  1:33 Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 01/29] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and hdmi_phy_i2c_write Laurent Pinchart
                   ` (28 more replies)
  0 siblings, 29 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hello,

This patch series implements support for the HDMI output on Renesas R-Car Gen3
SoCs, and more specifically on the R-Car H3.

R-Car Gen3 SoCs include one or multiple Synopsys DWC HDMI TX controllers. The
series thus starts with 20 cleanup or feature patches for the dw-hdmi driver.
Patches 01/29 to 05/29 are small miscellaneous cleanups. Patch 06/29 fixes a
crash when the HPD interrupt is generated before the bridge gets attached to a
DRM device.

Patch 07/29 then starts refactoring the API towards platform glue by moving
common I/O and clock resource allocation to common code. Patches 08/29 and
09/29 continue by moving connector creation to the bridge attach operation to
comply with the DRM bridge API. Patch 10/29 implements a new API for platform
glue to register the bridge with the DRM core, for platform that doesn't use
the component framework.

Patches 11/29 to 20/29 refactor platform support in the dw-hdmi driver. This
is the largest change compared to v1. Patch 11/29 is a small cleanup and patch
12/29 a register rename to match available documentation. Patch 13/29 starts
making use of the hardware product ID to reject invalid devices and patch
14/29 and 15/29 continue with refactoring of audio DMA detection and overflow
workaround handling based on the device version. Patch 16/29 adds PHY type
detection at runtime and patch 17/29 reworks PHY power handling accordingly.
Patches 18/29 and 19/29 add support for custom PHYs, and patch 20/29 finally
removes the now unneeded device type field from platform data.

The next three patches add glue code for the DWC HDMI on Renesas R-Car Gen3
platforms. Patch 21/29 rework the DWC HDMI DT bindings to make them more
modular, and patch 22/29 makes use of them to document the R-Car Gen DWC HDMI
TX DT bindings. Patch 23/29 then implements the platform glue code.

The next three patches implement support for the R8A7795 HDMI outputs in the
R-Car DU driver. Patch 24/29 fixes a bug that makes the driver defer probe
forever if an encoder is disabled. Patch 25/29 implements DPLL support to
generate more precise clocks required by the HDMI controller, and patch 26/29
then enables the two HDMI output on the R-Car H3 SoC.

The last three patches enable the HDMI outputs on the H3 Salvator-X board by
adding the HDMI encoders to the R-Car H3 DT (27/29), adding HDMI connectors
and enabling the encoders (28/29) and adding the external dot clocks (29/29).

I have tested the code on a Renesas Salvator-X H3 board, a Rockchip RK3288
Rock2 board and an IMX6Q Rex Pro board. No issue due to the dw-hdmi rework
have been observed.

More improvements to the dw-hdmi driver would be beneficial. The PHY
modularization is based on the limited understanding of the HDMI PHYs used on
the three supported platforms and will possibly be enhanced later when adding
support for more platforms. The PHY used on Renesas platforms is probably
generic, but due to limited documentation and unavailability of public
datasheets from Synopsys I can't at the moment determine if the code could be
shared. I propose addressing this when another platform will be merged in
mainline using the same PHY.

The DT bindings would also benefit from a standardized definition of the
ports, and the reg-io-width property could possibly be deprecated in favour of
encoding the information in platform glue code. The patch series is however
big enough as is to be submitted for review and merge before the dw-hdmi
driver achieves perfection.

Kieran Bingham (4):
  drm: bridge: dw-hdmi: Remove unused function parameter
  drm: bridge: dw-hdmi: Remove PHY configuration resolution parameter
  drm: bridge: dw-hdmi: Add support for custom PHY configuration
  drm: bridge: dw-hdmi: Remove device type from platform data

Koji Matsuoka (4):
  drm: rcar-du: Add Gen3 HDMI encoder support
  drm: rcar-du: Add DPLL support
  drm: rcar-du: Add HDMI outputs to R8A7795 device description
  arm64: dts: r8a7795: salvator-x: Enable HDMI outputs

Laurent Pinchart (20):
  drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and
    hdmi_phy_i2c_write
  drm: bridge: dw-hdmi: Remove unneeded arguments to bind/unbind
    functions
  drm: bridge: dw-hdmi: Embed drm_bridge in struct dw_hdmi
  drm: bridge: dw-hdmi: Remove encoder field from struct dw_hdmi
  drm: bridge: dw-hdmi: Don't forward HPD events to DRM core before
    attach
  drm: bridge: dw-hdmi: Move IRQ and IO resource allocation to common
    code
  drm: bridge: dw-hdmi: Reorder functions to prepare for next commit
  drm: bridge: dw-hdmi: Create connector in the bridge attach operation
  drm: bridge: dw-hdmi: Implement DRM bridge registration
  drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET
  drm: bridge: dw-hdmi: Reject invalid product IDs
  drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register
  drm: bridge: dw-hdmi: Handle overflow workaround based on device
    version
  drm: bridge: dw-hdmi: Detect PHY type at runtime
  drm: bridge: dw-hdmi: Refactor PHY power handling
  drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  dt-bindings: display: dw-hdmi: Clean up DT bindings documentation
  dt-bindings: display: renesas: Add R-Car Gen3 HDMI TX DT bindings
  drm: rcar-du: Skip disabled outputs
  arm64: dts: r8a7795: salvator-x: Add DU1 and DU2 external dot clocks

Ulrich Hecht (1):
  arm64: dts: r8a7795: Add HDMI encoder support

 .../devicetree/bindings/display/bridge/dw_hdmi.txt |  85 ++--
 .../bindings/display/bridge/renesas,dw-hdmi.txt    |  75 +++
 .../devicetree/bindings/display/imx/hdmi.txt       |  51 +-
 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |  43 +-
 MAINTAINERS                                        |   1 +
 arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts |  73 +++
 arch/arm64/boot/dts/renesas/r8a7795.dtsi           |  50 ++
 drivers/gpu/drm/bridge/dw-hdmi.c                   | 557 +++++++++++++--------
 drivers/gpu/drm/bridge/dw-hdmi.h                   |  16 +-
 drivers/gpu/drm/imx/dw_hdmi-imx.c                  |  16 +-
 drivers/gpu/drm/rcar-du/Kconfig                    |   8 +
 drivers/gpu/drm/rcar-du/Makefile                   |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c             |  81 ++-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h             |   4 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c              |  13 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h              |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_kms.c              |   7 +
 drivers/gpu/drm/rcar-du/rcar_du_regs.h             |  23 +
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c             | 100 ++++
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        |  15 +-
 include/drm/bridge/dw_hdmi.h                       |  29 +-
 21 files changed, 923 insertions(+), 326 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
 create mode 100644 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* [PATCH v2 01/29] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and hdmi_phy_i2c_write
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 02/29] drm: bridge: dw-hdmi: Remove unneeded arguments to bind/unbind functions Laurent Pinchart
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The latter is just an int wrapper around the former void function that
unconditionally returns 0. As the return value is never checked, merge
the two functions into one.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index f5009ae39b89..a6685502571e 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -868,7 +868,7 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 	return true;
 }
 
-static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 				 unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
@@ -882,13 +882,6 @@ static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
 
-static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
-			      unsigned char addr)
-{
-	__hdmi_phy_i2c_write(hdmi, data, addr);
-	return 0;
-}
-
 static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
 {
 	hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0,
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 02/29] drm: bridge: dw-hdmi: Remove unneeded arguments to bind/unbind functions
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 01/29] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and hdmi_phy_i2c_write Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 03/29] drm: bridge: dw-hdmi: Remove unused function parameter Laurent Pinchart
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The master argument isn't used. The data argument, a void pointer, is
used by the bind function only where it's cast to a drm_device pointer,
which can easily be obtained from the encoder argument instead. Remove
them.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c            | 8 +++-----
 drivers/gpu/drm/imx/dw_hdmi-imx.c           | 4 ++--
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 4 ++--
 include/drm/bridge/dw_hdmi.h                | 5 ++---
 4 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index a6685502571e..f86894622070 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1854,12 +1854,10 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 	return 0;
 }
 
-int dw_hdmi_bind(struct device *dev, struct device *master,
-		 void *data, struct drm_encoder *encoder,
+int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 		 struct resource *iores, int irq,
 		 const struct dw_hdmi_plat_data *plat_data)
 {
-	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
@@ -1992,7 +1990,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	if (ret)
 		goto err_iahb;
 
-	ret = dw_hdmi_register(drm, hdmi);
+	ret = dw_hdmi_register(encoder->dev, hdmi);
 	if (ret)
 		goto err_iahb;
 
@@ -2059,7 +2057,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
+void dw_hdmi_unbind(struct device *dev)
 {
 	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 359cd2765552..f79665801543 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -249,7 +249,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
-	ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+	ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data);
 
 	/*
 	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
@@ -264,7 +264,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
 			       void *data)
 {
-	return dw_hdmi_unbind(dev, master, data);
+	return dw_hdmi_unbind(dev);
 }
 
 static const struct component_ops dw_hdmi_imx_ops = {
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 0665fb915579..e8fb5c56b224 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -301,7 +301,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
-	ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+	ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data);
 
 	/*
 	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
@@ -316,7 +316,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
 				    void *data)
 {
-	return dw_hdmi_unbind(dev, master, data);
+	return dw_hdmi_unbind(dev);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index bae79f3c4d28..11edda631a9d 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -56,9 +56,8 @@ struct dw_hdmi_plat_data {
 					   struct drm_display_mode *mode);
 };
 
-void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);
-int dw_hdmi_bind(struct device *dev, struct device *master,
-		 void *data, struct drm_encoder *encoder,
+void dw_hdmi_unbind(struct device *dev);
+int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 		 struct resource *iores, int irq,
 		 const struct dw_hdmi_plat_data *plat_data);
 
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 03/29] drm: bridge: dw-hdmi: Remove unused function parameter
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 01/29] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and hdmi_phy_i2c_write Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 02/29] drm: bridge: dw-hdmi: Remove unneeded arguments to bind/unbind functions Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 04/29] drm: bridge: dw-hdmi: Embed drm_bridge in struct dw_hdmi Laurent Pinchart
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Kieran Bingham

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The 'prep' parameter passed to hdmi_phy_configure() is useless. It is
hardcoded as 0, and if set, simply prevents the configure function from
executing.

Remove it.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index f86894622070..5f8044a7d602 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -931,7 +931,7 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
+static int hdmi_phy_configure(struct dw_hdmi *hdmi,
 			      unsigned char res, int cscon)
 {
 	unsigned res_idx;
@@ -941,9 +941,6 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
 
-	if (prep)
-		return -EINVAL;
-
 	switch (res) {
 	case 0:	/* color resolution 0 is 8 bit colour depth */
 	case 8:
@@ -1072,7 +1069,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
 		/* Enable CSC */
-		ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
+		ret = hdmi_phy_configure(hdmi, 8, cscon);
 		if (ret)
 			return ret;
 	}
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 04/29] drm: bridge: dw-hdmi: Embed drm_bridge in struct dw_hdmi
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (2 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 03/29] drm: bridge: dw-hdmi: Remove unused function parameter Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 05/29] drm: bridge: dw-hdmi: Remove encoder field from " Laurent Pinchart
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The drm_bridge instance is always needed, there's no point in allocating
it separately.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 5f8044a7d602..2c85b6c07a80 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -116,7 +116,7 @@ struct dw_hdmi_i2c {
 struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_encoder *encoder;
-	struct drm_bridge *bridge;
+	struct drm_bridge bridge;
 
 	struct platform_device *audio;
 	enum dw_hdmi_devtype dev_type;
@@ -1806,7 +1806,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
 		dev_dbg(hdmi->dev, "EVENT=%s\n",
 			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
-		drm_helper_hpd_irq_event(hdmi->bridge->dev);
+		drm_helper_hpd_irq_event(hdmi->bridge.dev);
 	}
 
 	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
@@ -1819,16 +1819,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 {
 	struct drm_encoder *encoder = hdmi->encoder;
-	struct drm_bridge *bridge;
+	struct drm_bridge *bridge = &hdmi->bridge;
 	int ret;
 
-	bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL);
-	if (!bridge) {
-		DRM_ERROR("Failed to allocate drm bridge\n");
-		return -ENOMEM;
-	}
-
-	hdmi->bridge = bridge;
 	bridge->driver_private = hdmi;
 	bridge->funcs = &dw_hdmi_bridge_funcs;
 	ret = drm_bridge_attach(encoder, bridge, NULL);
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 05/29] drm: bridge: dw-hdmi: Remove encoder field from struct dw_hdmi
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (3 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 04/29] drm: bridge: dw-hdmi: Embed drm_bridge in struct dw_hdmi Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 06/29] drm: bridge: dw-hdmi: Don't forward HPD events to DRM core before attach Laurent Pinchart
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The field isn't needed, remove it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 2c85b6c07a80..ef10bb866b2f 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -115,7 +115,6 @@ struct dw_hdmi_i2c {
 
 struct dw_hdmi {
 	struct drm_connector connector;
-	struct drm_encoder *encoder;
 	struct drm_bridge bridge;
 
 	struct platform_device *audio;
@@ -1816,9 +1815,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
+static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi)
 {
-	struct drm_encoder *encoder = hdmi->encoder;
 	struct drm_bridge *bridge = &hdmi->bridge;
 	int ret;
 
@@ -1835,7 +1833,7 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
 
-	drm_connector_init(drm, &hdmi->connector,
+	drm_connector_init(encoder->dev, &hdmi->connector,
 			   &dw_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
@@ -1867,7 +1865,6 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 	hdmi->dev = dev;
 	hdmi->dev_type = plat_data->dev_type;
 	hdmi->sample_rate = 48000;
-	hdmi->encoder = encoder;
 	hdmi->disabled = true;
 	hdmi->rxsense = true;
 	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
@@ -1980,7 +1977,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 	if (ret)
 		goto err_iahb;
 
-	ret = dw_hdmi_register(encoder->dev, hdmi);
+	ret = dw_hdmi_register(encoder, hdmi);
 	if (ret)
 		goto err_iahb;
 
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 06/29] drm: bridge: dw-hdmi: Don't forward HPD events to DRM core before attach
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (4 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 05/29] drm: bridge: dw-hdmi: Remove encoder field from " Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 07/29] drm: bridge: dw-hdmi: Move IRQ and IO resource allocation to common code Laurent Pinchart
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hotplug events should only be forwarded to the DRM core by the interrupt
handler when the bridge has been attached, otherwise the DRM device
pointer will be NULL, resulting in a crash.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index ef10bb866b2f..488dc1a9204f 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1805,7 +1805,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
 		dev_dbg(hdmi->dev, "EVENT=%s\n",
 			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
-		drm_helper_hpd_irq_event(hdmi->bridge.dev);
+		if (hdmi->bridge.dev)
+			drm_helper_hpd_irq_event(hdmi->bridge.dev);
 	}
 
 	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 07/29] drm: bridge: dw-hdmi: Move IRQ and IO resource allocation to common code
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (5 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 06/29] drm: bridge: dw-hdmi: Don't forward HPD events to DRM core before attach Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 08/29] drm: bridge: dw-hdmi: Reorder functions to prepare for next commit Laurent Pinchart
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

There's no need to duplicate identical code in multiple drivers (two at
the moment, one more to come soon). Move it to the dw-hdmi core where it
can be shared. If resource allocation ever becomes device-specific later
we'll always have the option of splitting it out again.

While it at pass the platform device to the bind function to avoid
having to cast struct device to struct platform_device.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c            | 13 ++++++++++---
 drivers/gpu/drm/imx/dw_hdmi-imx.c           | 12 +-----------
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 12 +-----------
 include/drm/bridge/dw_hdmi.h                |  3 +--
 4 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 488dc1a9204f..563cbec47da6 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1843,14 +1843,16 @@ static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi)
 	return 0;
 }
 
-int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
-		 struct resource *iores, int irq,
+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 		 const struct dw_hdmi_plat_data *plat_data)
 {
+	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
 	struct dw_hdmi *hdmi;
+	struct resource *iores;
+	int irq;
 	int ret;
 	u32 val = 1;
 	u8 config0;
@@ -1903,6 +1905,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 		dev_dbg(hdmi->dev, "no ddc property found\n");
 	}
 
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	hdmi->regs = devm_ioremap_resource(dev, iores);
 	if (IS_ERR(hdmi->regs)) {
 		ret = PTR_ERR(hdmi->regs);
@@ -1945,6 +1948,10 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 
 	initialize_hdmi_ih_mutes(hdmi);
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto err_iahb;
+
 	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
 					dw_hdmi_irq, IRQF_SHARED,
 					dev_name(dev), hdmi);
@@ -2025,7 +2032,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
 	if (hdmi->i2c)
 		dw_hdmi_i2c_init(hdmi);
 
-	dev_set_drvdata(dev, hdmi);
+	platform_set_drvdata(pdev, hdmi);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index f79665801543..f645275e6e63 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -207,8 +207,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct drm_encoder *encoder;
 	struct imx_hdmi *hdmi;
-	struct resource *iores;
-	int irq;
 	int ret;
 
 	if (!pdev->dev.of_node)
@@ -223,14 +221,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iores)
-		return -ENXIO;
-
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 	/*
 	 * If we failed to find the CRTC(s) which this encoder is
@@ -249,7 +239,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
-	ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data);
+	ret = dw_hdmi_bind(pdev, encoder, plat_data);
 
 	/*
 	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index e8fb5c56b224..a6d4a0236e8f 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -257,8 +257,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct drm_encoder *encoder;
 	struct rockchip_hdmi *hdmi;
-	struct resource *iores;
-	int irq;
 	int ret;
 
 	if (!pdev->dev.of_node)
@@ -273,14 +271,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iores)
-		return -ENXIO;
-
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 	/*
 	 * If we failed to find the CRTC(s) which this encoder is
@@ -301,7 +291,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
-	ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data);
+	ret = dw_hdmi_bind(pdev, encoder, plat_data);
 
 	/*
 	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 11edda631a9d..94ff6edd070b 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -57,8 +57,7 @@ struct dw_hdmi_plat_data {
 };
 
 void dw_hdmi_unbind(struct device *dev);
-int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder,
-		 struct resource *iores, int irq,
+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 		 const struct dw_hdmi_plat_data *plat_data);
 
 void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 08/29] drm: bridge: dw-hdmi: Reorder functions to prepare for next commit
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (6 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 07/29] drm: bridge: dw-hdmi: Move IRQ and IO resource allocation to common code Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 09/29] drm: bridge: dw-hdmi: Create connector in the bridge attach operation Laurent Pinchart
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The next commit will reference structures and functions in a way that
currently requires forward declarations. Reorder the functions to avoid
that. No functional change to the code is performed.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 72 ++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 563cbec47da6..92ce9e532603 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1575,42 +1575,6 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
 		hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
 }
 
-static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				    struct drm_display_mode *orig_mode,
-				    struct drm_display_mode *mode)
-{
-	struct dw_hdmi *hdmi = bridge->driver_private;
-
-	mutex_lock(&hdmi->mutex);
-
-	/* Store the display mode for plugin/DKMS poweron events */
-	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
-
-	mutex_unlock(&hdmi->mutex);
-}
-
-static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
-{
-	struct dw_hdmi *hdmi = bridge->driver_private;
-
-	mutex_lock(&hdmi->mutex);
-	hdmi->disabled = true;
-	dw_hdmi_update_power(hdmi);
-	dw_hdmi_update_phy_mask(hdmi);
-	mutex_unlock(&hdmi->mutex);
-}
-
-static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
-{
-	struct dw_hdmi *hdmi = bridge->driver_private;
-
-	mutex_lock(&hdmi->mutex);
-	hdmi->disabled = false;
-	dw_hdmi_update_power(hdmi);
-	dw_hdmi_update_phy_mask(hdmi);
-	mutex_unlock(&hdmi->mutex);
-}
-
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -1703,6 +1667,42 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
 	.best_encoder = drm_atomic_helper_best_encoder,
 };
 
+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+				    struct drm_display_mode *orig_mode,
+				    struct drm_display_mode *mode)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+
+	mutex_lock(&hdmi->mutex);
+
+	/* Store the display mode for plugin/DKMS poweron events */
+	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+
+	mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+
+	mutex_lock(&hdmi->mutex);
+	hdmi->disabled = true;
+	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
+	mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+
+	mutex_lock(&hdmi->mutex);
+	hdmi->disabled = false;
+	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
+	mutex_unlock(&hdmi->mutex);
+}
+
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.enable = dw_hdmi_bridge_enable,
 	.disable = dw_hdmi_bridge_disable,
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 09/29] drm: bridge: dw-hdmi: Create connector in the bridge attach operation
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (7 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 08/29] drm: bridge: dw-hdmi: Reorder functions to prepare for next commit Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 10/29] drm: bridge: dw-hdmi: Implement DRM bridge registration Laurent Pinchart
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The DRM device is not guaranteed by the bridge API to be available
before the attach callback. The driver performs properly at the moment
as it doesn't use the drm_bridge_add() registration method. As this will
be changed later, move connector creation to attach time to ensure
compatibility with the API.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 92ce9e532603..88cd40adb977 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1667,6 +1667,25 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
 	.best_encoder = drm_atomic_helper_best_encoder,
 };
 
+static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+	struct drm_encoder *encoder = bridge->encoder;
+	struct drm_connector *connector = &hdmi->connector;
+
+	connector->interlace_allowed = 1;
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
+
+	drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs,
+			   DRM_MODE_CONNECTOR_HDMIA);
+
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	return 0;
+}
+
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 				    struct drm_display_mode *orig_mode,
 				    struct drm_display_mode *mode)
@@ -1704,6 +1723,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 }
 
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
+	.attach = dw_hdmi_bridge_attach,
 	.enable = dw_hdmi_bridge_enable,
 	.disable = dw_hdmi_bridge_disable,
 	.mode_set = dw_hdmi_bridge_mode_set,
@@ -1829,17 +1849,6 @@ static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi)
 		return -EINVAL;
 	}
 
-	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
-
-	drm_connector_helper_add(&hdmi->connector,
-				 &dw_hdmi_connector_helper_funcs);
-
-	drm_connector_init(encoder->dev, &hdmi->connector,
-			   &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
-
-	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
-
 	return 0;
 }
 
@@ -1862,8 +1871,6 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 	if (!hdmi)
 		return -ENOMEM;
 
-	hdmi->connector.interlace_allowed = 1;
-
 	hdmi->plat_data = plat_data;
 	hdmi->dev = dev;
 	hdmi->dev_type = plat_data->dev_type;
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 10/29] drm: bridge: dw-hdmi: Implement DRM bridge registration
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (8 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 09/29] drm: bridge: dw-hdmi: Create connector in the bridge attach operation Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 11/29] drm: bridge: dw-hdmi: Remove PHY configuration resolution parameter Laurent Pinchart
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

As an option for drivers not based on the component framework, register
the bridge with the DRM core with the DRM bridge API. Existing drivers
based on dw_hdmi_bind() and dw_hdmi_unbind() are not affected as those
functions are preserved with their current behaviour.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 112 ++++++++++++++++++++++++++++-----------
 include/drm/bridge/dw_hdmi.h     |   3 ++
 2 files changed, 83 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 88cd40adb977..107fea49c4c6 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1836,24 +1836,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi)
-{
-	struct drm_bridge *bridge = &hdmi->bridge;
-	int ret;
-
-	bridge->driver_private = hdmi;
-	bridge->funcs = &dw_hdmi_bridge_funcs;
-	ret = drm_bridge_attach(encoder, bridge, NULL);
-	if (ret) {
-		DRM_ERROR("Failed to initialize bridge with drm\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-		 const struct dw_hdmi_plat_data *plat_data)
+static struct dw_hdmi *
+__dw_hdmi_probe(struct platform_device *pdev,
+		const struct dw_hdmi_plat_data *plat_data)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -1869,7 +1854,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 
 	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	hdmi->plat_data = plat_data;
 	hdmi->dev = dev;
@@ -1896,7 +1881,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 		break;
 	default:
 		dev_err(dev, "reg-io-width must be 1 or 4\n");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
@@ -1905,7 +1890,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 		of_node_put(ddc_node);
 		if (!hdmi->ddc) {
 			dev_dbg(hdmi->dev, "failed to read ddc node\n");
-			return -EPROBE_DEFER;
+			return ERR_PTR(-EPROBE_DEFER);
 		}
 
 	} else {
@@ -1956,8 +1941,10 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 	initialize_hdmi_ih_mutes(hdmi);
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
+	if (irq < 0) {
+		ret = irq;
 		goto err_iahb;
+	}
 
 	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
 					dw_hdmi_irq, IRQF_SHARED,
@@ -1988,11 +1975,11 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
 		    HDMI_IH_PHY_STAT0);
 
-	ret = dw_hdmi_fb_registered(hdmi);
-	if (ret)
-		goto err_iahb;
+	hdmi->bridge.driver_private = hdmi;
+	hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
+	hdmi->bridge.of_node = pdev->dev.of_node;
 
-	ret = dw_hdmi_register(encoder, hdmi);
+	ret = dw_hdmi_fb_registered(hdmi);
 	if (ret)
 		goto err_iahb;
 
@@ -2041,7 +2028,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 
 	platform_set_drvdata(pdev, hdmi);
 
-	return 0;
+	return hdmi;
 
 err_iahb:
 	if (hdmi->i2c) {
@@ -2055,14 +2042,11 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 err_res:
 	i2c_put_adapter(hdmi->ddc);
 
-	return ret;
+	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void dw_hdmi_unbind(struct device *dev)
+static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
-	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
 	if (hdmi->audio && !IS_ERR(hdmi->audio))
 		platform_device_unregister(hdmi->audio);
 
@@ -2077,6 +2061,70 @@ void dw_hdmi_unbind(struct device *dev)
 	else
 		i2c_put_adapter(hdmi->ddc);
 }
+
+/* -----------------------------------------------------------------------------
+ * Probe/remove API, used from platforms based on the DRM bridge API.
+ */
+int dw_hdmi_probe(struct platform_device *pdev,
+		  const struct dw_hdmi_plat_data *plat_data)
+{
+	struct dw_hdmi *hdmi;
+	int ret;
+
+	hdmi = __dw_hdmi_probe(pdev, plat_data);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
+
+	ret = drm_bridge_add(&hdmi->bridge);
+	if (ret < 0) {
+		__dw_hdmi_remove(hdmi);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_probe);
+
+void dw_hdmi_remove(struct platform_device *pdev)
+{
+	struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&hdmi->bridge);
+
+	__dw_hdmi_remove(hdmi);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_remove);
+
+/* -----------------------------------------------------------------------------
+ * Bind/unbind API, used from platforms based on the component framework.
+ */
+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
+		 const struct dw_hdmi_plat_data *plat_data)
+{
+	struct dw_hdmi *hdmi;
+	int ret;
+
+	hdmi = __dw_hdmi_probe(pdev, plat_data);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
+
+	ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL);
+	if (ret) {
+		dw_hdmi_remove(pdev);
+		DRM_ERROR("Failed to initialize bridge with drm\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_bind);
+
+void dw_hdmi_unbind(struct device *dev)
+{
+	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
+
+	__dw_hdmi_remove(hdmi);
+}
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 94ff6edd070b..3bb22a849830 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -56,6 +56,9 @@ struct dw_hdmi_plat_data {
 					   struct drm_display_mode *mode);
 };
 
+int dw_hdmi_probe(struct platform_device *pdev,
+		  const struct dw_hdmi_plat_data *plat_data);
+void dw_hdmi_remove(struct platform_device *pdev);
 void dw_hdmi_unbind(struct device *dev);
 int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 		 const struct dw_hdmi_plat_data *plat_data);
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 11/29] drm: bridge: dw-hdmi: Remove PHY configuration resolution parameter
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (9 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 10/29] drm: bridge: dw-hdmi: Implement DRM bridge registration Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET Laurent Pinchart
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Kieran Bingham

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The current code hard codes the call of hdmi_phy_configure() to be 8bpp
and provides extraneous error checking to verify that this hardcoded
value is correct. Simplify the implementation by removing the argument.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 107fea49c4c6..b4fb0bd78910 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -930,31 +930,14 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-static int hdmi_phy_configure(struct dw_hdmi *hdmi,
-			      unsigned char res, int cscon)
+static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 {
-	unsigned res_idx;
 	u8 val, msec;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
 	const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
 
-	switch (res) {
-	case 0:	/* color resolution 0 is 8 bit colour depth */
-	case 8:
-		res_idx = DW_HDMI_RES_8;
-		break;
-	case 10:
-		res_idx = DW_HDMI_RES_10;
-		break;
-	case 12:
-		res_idx = DW_HDMI_RES_12;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	/* PLL/MPLL Cfg - always match on final entry */
 	for (; mpll_config->mpixelclock != ~0UL; mpll_config++)
 		if (hdmi->hdmi_data.video_mode.mpixelclock <=
@@ -1004,11 +987,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi,
 		    HDMI_PHY_I2CM_SLAVE_ADDR);
 	hdmi_phy_test_clear(hdmi, 0);
 
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].cpce, 0x06);
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].gmp, 0x15);
+	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 0x06);
+	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 0x15);
 
 	/* CURRCTRL */
-	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[res_idx], 0x10);
+	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 0x10);
 
 	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
 	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
@@ -1068,7 +1051,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
 		/* Enable CSC */
-		ret = hdmi_phy_configure(hdmi, 8, cscon);
+		ret = hdmi_phy_configure(hdmi, cscon);
 		if (ret)
 			return ret;
 	}
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (10 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 11/29] drm: bridge: dw-hdmi: Remove PHY configuration resolution parameter Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 10:58     ` Jose Abreu
  2016-12-20  1:33 ` [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs Laurent Pinchart
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The bit is documented in a Rockchip BSP as

 #define m_SVSRET_SIG		(1 << 5) /* depend on PHY_MHL_COMB0=1 */

This is confirmed by a Renesas platform, which uses a 2.0 DWC HDMI TX as
the RK3288. Rename the bit accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 8 ++++----
 drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index b4fb0bd78910..06c252f560ad 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -895,11 +895,11 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_ENTMDS_MASK);
 }
 
-static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-			 HDMI_PHY_CONF0_SPARECTRL_OFFSET,
-			 HDMI_PHY_CONF0_SPARECTRL_MASK);
+			 HDMI_PHY_CONF0_SVSRET_OFFSET,
+			 HDMI_PHY_CONF0_SVSRET_MASK);
 }
 
 static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
@@ -1014,7 +1014,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
 	if (hdmi->dev_type == RK3288_HDMI)
-		dw_hdmi_phy_enable_spare(hdmi, 1);
+		dw_hdmi_phy_enable_svsret(hdmi, 1);
 
 	/*Wait for PHY PLL lock */
 	msec = 5;
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
index 55135bbd0c16..08235aef2fa3 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi.h
@@ -847,8 +847,8 @@ enum {
 	HDMI_PHY_CONF0_PDZ_OFFSET = 7,
 	HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
 	HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
-	HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
-	HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
+	HDMI_PHY_CONF0_SVSRET_MASK = 0x20,
+	HDMI_PHY_CONF0_SVSRET_OFFSET = 5,
 	HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
 	HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
 	HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (11 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 10:59     ` Jose Abreu
  2016-12-20  1:33 ` [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register Laurent Pinchart
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The DWC HDMI TX can be recognized by the two product identification
registers. If the registers don't read as expect the IP will be very
different than what the driver has been designed for, or will be
misconfigured in a way that makes it non-operational (invalid memory
address, incorrect clocks, ...). We should reject this situation with an
error.

While this isn't critical for proper operation with supported IPs at the
moment, the driver will soon gain automatic device-specific handling
based on runtime device identification. This change makes it easier to
implement that without having to default to a random guess in case the
device can't be identified.

While at it print a readable version number in the device identification
message instead of raw register values.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 25 +++++++++++++++++++------
 drivers/gpu/drm/bridge/dw-hdmi.h |  8 ++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 06c252f560ad..1809247745b8 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1832,6 +1832,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	int irq;
 	int ret;
 	u32 val = 1;
+	u16 version;
+	u8 prod_id0;
+	u8 prod_id1;
 	u8 config0;
 	u8 config1;
 
@@ -1914,12 +1917,22 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	}
 
 	/* Product and revision IDs */
-	dev_info(dev,
-		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
-		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
-		 hdmi_readb(hdmi, HDMI_REVISION_ID),
-		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
-		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
+	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
+		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
+	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
+	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
+
+	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
+	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
+		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
+			version, prod_id0, prod_id1);
+		ret = -ENODEV;
+		goto err_iahb;
+	}
+
+	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
+		 version >> 12, version & 0xfff,
+		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
 
 	initialize_hdmi_ih_mutes(hdmi);
 
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
index 08235aef2fa3..91d7fabbd6e5 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi.h
@@ -545,6 +545,14 @@
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* PRODUCT_ID0 field values */
+	HDMI_PRODUCT_ID0_HDMI_TX = 0xa0,
+
+/* PRODUCT_ID1 field values */
+	HDMI_PRODUCT_ID1_HDCP = 0xc0,
+	HDMI_PRODUCT_ID1_HDMI_RX = 0x02,
+	HDMI_PRODUCT_ID1_HDMI_TX = 0x01,
+
 /* CONFIG0_ID field values */
 	HDMI_CONFIG0_I2S = 0x10,
 
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (12 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 11:00     ` Jose Abreu
  2016-12-20  1:33 ` [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version Laurent Pinchart
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Bit 0 in CONFIG1_ID tells whether the IP core uses an AHB slave
interface for control. The correct way to identify AHB audio DMA support
is through bit 1 in CONFIG3_ID.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++---
 drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 1809247745b8..730a7558d4d4 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1836,7 +1836,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	u8 prod_id0;
 	u8 prod_id1;
 	u8 config0;
-	u8 config1;
+	u8 config3;
 
 	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
@@ -1988,9 +1988,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	pdevinfo.id = PLATFORM_DEVID_AUTO;
 
 	config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
-	config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID);
+	config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
 
-	if (config1 & HDMI_CONFIG1_AHB) {
+	if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
 		struct dw_hdmi_audio_data audio;
 
 		audio.phys = iores->start;
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
index 91d7fabbd6e5..a4fd64a203c9 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi.h
@@ -559,6 +559,10 @@ enum {
 /* CONFIG1_ID field values */
 	HDMI_CONFIG1_AHB = 0x01,
 
+/* CONFIG3_ID field values */
+	HDMI_CONFIG3_AHBAUDDMA = 0x02,
+	HDMI_CONFIG3_GPAUD = 0x01,
+
 /* IH_FC_INT2 field values */
 	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
 	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (13 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 11:32     ` Jose Abreu
  2016-12-20  1:33 ` [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime Laurent Pinchart
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Use the device version queried at runtime instead of the device type
provided through platform data to handle the overflow workaround. This
will make support of other SoCs integrating the same HDMI TX controller
version easier.

Among the supported platforms only i.MX6DL and i.MX6Q have been
identified as needing the workaround. Disabling it on Rockchip RK3288
(which integrates a v2.00a controller) didn't produce any error or
artifact.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 46 ++++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 730a7558d4d4..f4faa14213e5 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -117,8 +117,10 @@ struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_bridge bridge;
 
-	struct platform_device *audio;
 	enum dw_hdmi_devtype dev_type;
+	unsigned int version;
+
+	struct platform_device *audio;
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
@@ -1323,19 +1325,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
 /* Workaround to clear the overflow condition */
 static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 {
-	int count;
+	unsigned int count;
+	unsigned int i;
 	u8 val;
 
-	/* TMDS software reset */
-	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
+	/*
+	 * Under some circumstances the Frame Composer arithmetic unit can miss
+	 * an FC register write due to being busy processing the previous one.
+	 * The issue can be worked around by issuing a TMDS software reset and
+	 * then write one of the FC registers several times.
+	 *
+	 * The number of iterations matters and depends on the HDMI TX revision
+	 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
+	 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
+	 * 4 and 1 iterations respectively.
+	 */
 
-	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
-	if (hdmi->dev_type == IMX6DL_HDMI) {
-		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
+	switch (hdmi->version) {
+	case 0x130a:
+		count = 4;
+		break;
+	case 0x131a:
+		count = 1;
+		break;
+	default:
 		return;
 	}
 
-	for (count = 0; count < 4; count++)
+	/* TMDS software reset */
+	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
+
+	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
+	for (i = 0; i < count; i++)
 		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
 }
 
@@ -1832,7 +1853,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	int irq;
 	int ret;
 	u32 val = 1;
-	u16 version;
 	u8 prod_id0;
 	u8 prod_id1;
 	u8 config0;
@@ -1917,21 +1937,21 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	}
 
 	/* Product and revision IDs */
-	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
-		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
+	hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
+		      | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
 	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
 	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
 
 	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
 	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
 		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
-			version, prod_id0, prod_id1);
+			hdmi->version, prod_id0, prod_id1);
 		ret = -ENODEV;
 		goto err_iahb;
 	}
 
 	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
-		 version >> 12, version & 0xfff,
+		 hdmi->version >> 12, hdmi->version & 0xfff,
 		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
 
 	initialize_hdmi_ih_mutes(hdmi);
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (14 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 11:39     ` Jose Abreu
  2016-12-20  1:33 ` [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling Laurent Pinchart
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Detect the PHY type and use it to handle the PHY type-specific SVSRET
signal.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 68 ++++++++++++++++++++++++++++++++++++++--
 include/drm/bridge/dw_hdmi.h     | 10 ++++++
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index f4faa14213e5..ef4f2f96ed2c 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -113,6 +113,12 @@ struct dw_hdmi_i2c {
 	bool			is_regaddr;
 };
 
+struct dw_hdmi_phy_data {
+	enum dw_hdmi_phy_type type;
+	const char *name;
+	bool has_svsret;
+};
+
 struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_bridge bridge;
@@ -134,7 +140,9 @@ struct dw_hdmi {
 	u8 edid[HDMI_EDID_LEN];
 	bool cable_plugin;
 
+	const struct dw_hdmi_phy_data *phy;
 	bool phy_enabled;
+
 	struct drm_display_mode previous_mode;
 
 	struct i2c_adapter *ddc;
@@ -1015,7 +1023,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
-	if (hdmi->dev_type == RK3288_HDMI)
+	/* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */
+	if (hdmi->phy->has_svsret)
 		dw_hdmi_phy_enable_svsret(hdmi, 1);
 
 	/*Wait for PHY PLL lock */
@@ -1840,6 +1849,54 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
+	{
+		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
+		.name = "DWC HDMI TX PHY",
+	}, {
+		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
+		.name = "DWC MHL PHY + HEAC PHY",
+		.has_svsret = true,
+	}, {
+		.type = DW_HDMI_PHY_DWC_MHL_PHY,
+		.name = "DWC MHL PHY",
+		.has_svsret = true,
+	}, {
+		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
+		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
+	}, {
+		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
+		.name = "DWC HDMI 3D TX PHY",
+	}, {
+		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
+		.name = "DWC HDMI 2.0 TX PHY",
+		.has_svsret = true,
+	}
+};
+
+static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
+{
+	unsigned int i;
+	u8 phy_type;
+
+	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
+
+	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
+		if (dw_hdmi_phys[i].type == phy_type) {
+			hdmi->phy = &dw_hdmi_phys[i];
+			return 0;
+		}
+	}
+
+	if (phy_type == DW_HDMI_PHY_VENDOR_PHY)
+		dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n");
+	else
+		dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n",
+			phy_type);
+
+	return -ENODEV;
+}
+
 static struct dw_hdmi *
 __dw_hdmi_probe(struct platform_device *pdev,
 		const struct dw_hdmi_plat_data *plat_data)
@@ -1950,9 +2007,14 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		goto err_iahb;
 	}
 
-	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
+	ret = dw_hdmi_detect_phy(hdmi);
+	if (ret < 0)
+		goto err_iahb;
+
+	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n",
 		 hdmi->version >> 12, hdmi->version & 0xfff,
-		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
+		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without",
+		 hdmi->phy->name);
 
 	initialize_hdmi_ih_mutes(hdmi);
 
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 3bb22a849830..b080a171a23f 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -27,6 +27,16 @@ enum dw_hdmi_devtype {
 	RK3288_HDMI,
 };
 
+enum dw_hdmi_phy_type {
+	DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00,
+	DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2,
+	DW_HDMI_PHY_DWC_MHL_PHY = 0xc2,
+	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2,
+	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2,
+	DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3,
+	DW_HDMI_PHY_VENDOR_PHY = 0xfe,
+};
+
 struct dw_hdmi_mpll_config {
 	unsigned long mpixelclock;
 	struct {
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (15 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20 11:45   ` Russell King - ARM Linux
  2016-12-20  1:33 ` [PATCH v2 18/29] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code Laurent Pinchart
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Instead of spreading version-dependent PHY power handling code around,
group it in two functions to power the PHY on and off and use them
through the driver.

Powering off the PHY at the beginning of the setup phase is currently
split in two locations for first and second generation PHYs, group all
the operations in the dw_hdmi_phy_init() function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 54 ++++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index ef4f2f96ed2c..6167eb6806fe 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -116,6 +116,7 @@ struct dw_hdmi_i2c {
 struct dw_hdmi_phy_data {
 	enum dw_hdmi_phy_type type;
 	const char *name;
+	unsigned int gen;
 	bool has_svsret;
 };
 
@@ -940,6 +941,31 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
+static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
+{
+	if (hdmi->phy->gen == 1) {
+		dw_hdmi_phy_enable_tmds(hdmi, 0);
+		dw_hdmi_phy_enable_powerdown(hdmi, true);
+	} else {
+		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
+		dw_hdmi_phy_gen2_pddq(hdmi, 1);
+	}
+}
+
+static void dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
+{
+	if (hdmi->phy->gen == 1) {
+		dw_hdmi_phy_enable_powerdown(hdmi, false);
+
+		/* Toggle TMDS enable. */
+		dw_hdmi_phy_enable_tmds(hdmi, 0);
+		dw_hdmi_phy_enable_tmds(hdmi, 1);
+	} else {
+		dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+		dw_hdmi_phy_gen2_pddq(hdmi, 0);
+	}
+}
+
 static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 {
 	u8 val, msec;
@@ -980,11 +1006,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 
 	hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
 
-	/* gen2 tx power off */
-	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
-
-	/* gen2 pddq */
-	dw_hdmi_phy_gen2_pddq(hdmi, 1);
+	dw_hdmi_phy_power_off(hdmi);
 
 	/* PHY reset */
 	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
@@ -1013,15 +1035,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 	/* REMOVE CLK TERM */
 	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
 
-	dw_hdmi_phy_enable_powerdown(hdmi, false);
-
-	/* toggle TMDS enable */
-	dw_hdmi_phy_enable_tmds(hdmi, 0);
-	dw_hdmi_phy_enable_tmds(hdmi, 1);
-
-	/* gen2 tx power on */
-	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
-	dw_hdmi_phy_gen2_pddq(hdmi, 0);
+	dw_hdmi_phy_power_on(hdmi);
 
 	/* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */
 	if (hdmi->phy->has_svsret)
@@ -1058,8 +1072,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 	for (i = 0; i < 2; i++) {
 		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
 		dw_hdmi_phy_sel_interface_control(hdmi, 0);
-		dw_hdmi_phy_enable_tmds(hdmi, 0);
-		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
 		/* Enable CSC */
 		ret = hdmi_phy_configure(hdmi, cscon);
@@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
 	if (!hdmi->phy_enabled)
 		return;
 
-	dw_hdmi_phy_enable_tmds(hdmi, 0);
-	dw_hdmi_phy_enable_powerdown(hdmi, true);
-
+	dw_hdmi_phy_power_off(hdmi);
 	hdmi->phy_enabled = false;
 }
 
@@ -1853,23 +1863,29 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
 	{
 		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
 		.name = "DWC HDMI TX PHY",
+		.gen = 1,
 	}, {
 		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
 		.name = "DWC MHL PHY + HEAC PHY",
+		.gen = 2,
 		.has_svsret = true,
 	}, {
 		.type = DW_HDMI_PHY_DWC_MHL_PHY,
 		.name = "DWC MHL PHY",
+		.gen = 2,
 		.has_svsret = true,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
 		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
+		.gen = 2,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
 		.name = "DWC HDMI 3D TX PHY",
+		.gen = 2,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
 		.name = "DWC HDMI 2.0 TX PHY",
+		.gen = 2,
 		.has_svsret = true,
 	}
 };
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 18/29] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (16 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 19/29] drm: bridge: dw-hdmi: Add support for custom PHY configuration Laurent Pinchart
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The color space converter isn't part of the PHY, move its configuration
out of PHY code.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 6167eb6806fe..7c69c8c0285e 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -966,7 +966,7 @@ static void dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 	}
 }
 
-static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
 	u8 val, msec;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
@@ -998,14 +998,6 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 		return -EINVAL;
 	}
 
-	/* Enable csc path */
-	if (cscon)
-		val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
-	else
-		val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
-
-	hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
-
 	dw_hdmi_phy_power_off(hdmi);
 
 	/* PHY reset */
@@ -1063,18 +1055,13 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 {
 	int i, ret;
-	bool cscon;
-
-	/*check csc whether needed activated in HDMI mode */
-	cscon = hdmi->sink_is_hdmi && is_color_space_conversion(hdmi);
 
 	/* HDMI Phy spec says to do the phy initialization sequence twice */
 	for (i = 0; i < 2; i++) {
 		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
 		dw_hdmi_phy_sel_interface_control(hdmi, 0);
 
-		/* Enable CSC */
-		ret = hdmi_phy_configure(hdmi, cscon);
+		ret = hdmi_phy_configure(hdmi);
 		if (ret)
 			return ret;
 	}
@@ -1334,6 +1321,14 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
 		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
 	}
+
+	/* Enable color space conversion if needed (for HDMI sinks only). */
+	if (hdmi->sink_is_hdmi && is_color_space_conversion(hdmi))
+		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
+			    HDMI_MC_FLOWCTRL);
+	else
+		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
+			    HDMI_MC_FLOWCTRL);
 }
 
 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 19/29] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (17 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 18/29] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 20/29] drm: bridge: dw-hdmi: Remove device type from platform data Laurent Pinchart
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Kieran Bingham

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The DWC HDMI TX controller interfaces with a companion PHY. While
Synopsys provides multiple standard PHYs, SoC vendors can also integrate
a custom PHY.

Modularize PHY configuration to support vendor PHYs through platform
data. The existing PHY configuration code was originally written to
support the DWC HDMI 3D TX PHY, and seems to be compatible with the DWC
MLP PHY. The HDMI 2.0 PHY will require a separate configuration
function.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Check pdata->phy_configure in hdmi_phy_configure() to avoid
  dereferencing NULL pointer.
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 107 ++++++++++++++++++++++++++-------------
 include/drm/bridge/dw_hdmi.h     |   7 +++
 2 files changed, 79 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 7c69c8c0285e..ebea96ad5dd0 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -118,6 +118,9 @@ struct dw_hdmi_phy_data {
 	const char *name;
 	unsigned int gen;
 	bool has_svsret;
+	int (*configure)(struct dw_hdmi *hdmi,
+			 const struct dw_hdmi_plat_data *pdata,
+			 unsigned long mpixelclock);
 };
 
 struct dw_hdmi {
@@ -878,8 +881,8 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 	return true;
 }
 
-static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
-				 unsigned char addr)
+void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+			   unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
 	hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
@@ -891,6 +894,7 @@ static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 		    HDMI_PHY_I2CM_OPERATION_ADDR);
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
 
 static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
 {
@@ -966,37 +970,62 @@ static void dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 	}
 }
 
-static int hdmi_phy_configure(struct dw_hdmi *hdmi)
+/*
+ * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available
+ * information the DWC MHL PHY has the same register layout and is thus also
+ * supported by this function.
+ */
+static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
+		const struct dw_hdmi_plat_data *pdata,
+		unsigned long mpixelclock)
 {
-	u8 val, msec;
-	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
 	const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
 
 	/* PLL/MPLL Cfg - always match on final entry */
 	for (; mpll_config->mpixelclock != ~0UL; mpll_config++)
-		if (hdmi->hdmi_data.video_mode.mpixelclock <=
-		    mpll_config->mpixelclock)
+		if (mpixelclock <= mpll_config->mpixelclock)
 			break;
 
 	for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++)
-		if (hdmi->hdmi_data.video_mode.mpixelclock <=
-		    curr_ctrl->mpixelclock)
+		if (mpixelclock <= curr_ctrl->mpixelclock)
 			break;
 
 	for (; phy_config->mpixelclock != ~0UL; phy_config++)
-		if (hdmi->hdmi_data.video_mode.mpixelclock <=
-		    phy_config->mpixelclock)
+		if (mpixelclock <= phy_config->mpixelclock)
 			break;
 
 	if (mpll_config->mpixelclock == ~0UL ||
 	    curr_ctrl->mpixelclock == ~0UL ||
-	    phy_config->mpixelclock == ~0UL) {
-		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
-			hdmi->hdmi_data.video_mode.mpixelclock);
+	    phy_config->mpixelclock == ~0UL)
 		return -EINVAL;
-	}
+
+	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 0x06);
+	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 0x15);
+
+	/* CURRCTRL */
+	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 0x10);
+
+	dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
+	dw_hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19); /* TXTERM */
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, 0x09); /* CKSYMTXCTRL */
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, 0x0E); /* VLEVCTRL */
+
+	/* REMOVE CLK TERM */
+	dw_hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
+
+	return 0;
+}
+
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
+{
+	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
+	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
+	u8 val, msec;
+	int ret;
 
 	dw_hdmi_phy_power_off(hdmi);
 
@@ -1011,21 +1040,16 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 		    HDMI_PHY_I2CM_SLAVE_ADDR);
 	hdmi_phy_test_clear(hdmi, 0);
 
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 0x06);
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 0x15);
-
-	/* CURRCTRL */
-	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 0x10);
-
-	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
-	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
-
-	hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19);  /* TXTERM */
-	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, 0x09); /* CKSYMTXCTRL */
-	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, 0x0E); /* VLEVCTRL */
-
-	/* REMOVE CLK TERM */
-	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
+	/* Write to the PHY as configured by the platform */
+	if (pdata->configure_phy)
+		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
+	else
+		ret = hdmi->phy->configure(hdmi, pdata, mpixelclock);
+	if (ret) {
+		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
+			mpixelclock);
+		return ret;
+	}
 
 	dw_hdmi_phy_power_on(hdmi);
 
@@ -1864,24 +1888,31 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
 		.name = "DWC MHL PHY + HEAC PHY",
 		.gen = 2,
 		.has_svsret = true,
+		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
 	}, {
 		.type = DW_HDMI_PHY_DWC_MHL_PHY,
 		.name = "DWC MHL PHY",
 		.gen = 2,
 		.has_svsret = true,
+		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
 		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
 		.gen = 2,
+		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
 		.name = "DWC HDMI 3D TX PHY",
 		.gen = 2,
+		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
 	}, {
 		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
 		.name = "DWC HDMI 2.0 TX PHY",
 		.gen = 2,
 		.has_svsret = true,
+	}, {
+		.type = DW_HDMI_PHY_VENDOR_PHY,
+		.name = "Vendor PHY",
 	}
 };
 
@@ -1895,17 +1926,23 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
 		if (dw_hdmi_phys[i].type == phy_type) {
 			hdmi->phy = &dw_hdmi_phys[i];
-			return 0;
+			break;
 		}
 	}
 
-	if (phy_type == DW_HDMI_PHY_VENDOR_PHY)
-		dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n");
-	else
+	if (!hdmi->phy) {
 		dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n",
 			phy_type);
+		return -ENODEV;
+	}
+
+	if (!hdmi->phy->configure && !hdmi->plat_data->configure_phy) {
+		dev_err(hdmi->dev, "%s requires platform support\n",
+			hdmi->phy->name);
+		return -ENODEV;
+	}
 
-	return -ENODEV;
+	return 0;
 }
 
 static struct dw_hdmi *
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index b080a171a23f..c539f64a280a 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -62,6 +62,9 @@ struct dw_hdmi_plat_data {
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config;
+	int (*configure_phy)(struct dw_hdmi *hdmi,
+			     const struct dw_hdmi_plat_data *pdata,
+			     unsigned long mpixelclock);
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
 };
@@ -77,4 +80,8 @@ 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);
 
+/* PHY configuration */
+void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+			   unsigned char addr);
+
 #endif /* __IMX_HDMI_H__ */
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 20/29] drm: bridge: dw-hdmi: Remove device type from platform data
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (18 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 19/29] drm: bridge: dw-hdmi: Add support for custom PHY configuration Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 21/29] dt-bindings: display: dw-hdmi: Clean up DT bindings documentation Laurent Pinchart
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Kieran Bingham

From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

The device type isn't used anymore now that workarounds and PHY-specific
operations are performed based on version information read at runtime.
Remove it.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c            | 2 --
 drivers/gpu/drm/imx/dw_hdmi-imx.c           | 2 --
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 -
 include/drm/bridge/dw_hdmi.h                | 7 -------
 4 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index ebea96ad5dd0..8480f95d3e0b 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -127,7 +127,6 @@ struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_bridge bridge;
 
-	enum dw_hdmi_devtype dev_type;
 	unsigned int version;
 
 	struct platform_device *audio;
@@ -1969,7 +1968,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
 
 	hdmi->plat_data = plat_data;
 	hdmi->dev = dev;
-	hdmi->dev_type = plat_data->dev_type;
 	hdmi->sample_rate = 48000;
 	hdmi->disabled = true;
 	hdmi->rxsense = true;
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index f645275e6e63..f039641070ac 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -175,7 +175,6 @@ static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
 	.mpll_cfg   = imx_mpll_cfg,
 	.cur_ctr    = imx_cur_ctr,
 	.phy_config = imx_phy_config,
-	.dev_type   = IMX6Q_HDMI,
 	.mode_valid = imx6q_hdmi_mode_valid,
 };
 
@@ -183,7 +182,6 @@ static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
 	.mpll_cfg = imx_mpll_cfg,
 	.cur_ctr  = imx_cur_ctr,
 	.phy_config = imx_phy_config,
-	.dev_type = IMX6DL_HDMI,
 	.mode_valid = imx6dl_hdmi_mode_valid,
 };
 
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index a6d4a0236e8f..d53827413996 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -237,7 +237,6 @@ static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
 	.mpll_cfg   = rockchip_mpll_cfg,
 	.cur_ctr    = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
-	.dev_type   = RK3288_HDMI,
 };
 
 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index c539f64a280a..735a8ab2509c 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -21,12 +21,6 @@ enum {
 	DW_HDMI_RES_MAX,
 };
 
-enum dw_hdmi_devtype {
-	IMX6Q_HDMI,
-	IMX6DL_HDMI,
-	RK3288_HDMI,
-};
-
 enum dw_hdmi_phy_type {
 	DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00,
 	DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2,
@@ -58,7 +52,6 @@ struct dw_hdmi_phy_config {
 };
 
 struct dw_hdmi_plat_data {
-	enum dw_hdmi_devtype dev_type;
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config;
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 21/29] dt-bindings: display: dw-hdmi: Clean up DT bindings documentation
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (19 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 20/29] drm: bridge: dw-hdmi: Remove device type from platform data Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 22/29] dt-bindings: display: renesas: Add R-Car Gen3 HDMI TX DT bindings Laurent Pinchart
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Make it clear that the core bridge/dw_hdmi.txt document isn't a device
tree binding by itself but is meant to be referenced by platform device
tree bindings, and update the Rockchip and Freescale DWC HDMI TX
bindings to reference it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/display/bridge/dw_hdmi.txt | 85 +++++++++-------------
 .../devicetree/bindings/display/imx/hdmi.txt       | 51 +++++++------
 .../bindings/display/rockchip/dw_hdmi-rockchip.txt | 43 +++++++----
 3 files changed, 91 insertions(+), 88 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
index 5e9a84d6e5f1..33bf981fbe33 100644
--- a/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
+++ b/Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt
@@ -1,52 +1,33 @@
-DesignWare HDMI bridge bindings
-
-Required properties:
-- compatible: platform specific such as:
-   * "snps,dw-hdmi-tx"
-   * "fsl,imx6q-hdmi"
-   * "fsl,imx6dl-hdmi"
-   * "rockchip,rk3288-dw-hdmi"
-- reg: Physical base address and length of the controller's registers.
-- interrupts: The HDMI interrupt number
-- clocks, clock-names : must have the phandles to the HDMI iahb and isfr clocks,
-  as described in Documentation/devicetree/bindings/clock/clock-bindings.txt,
-  the clocks are soc specific, the clock-names should be "iahb", "isfr"
--port@[X]: SoC specific port nodes with endpoint definitions as defined
-   in Documentation/devicetree/bindings/media/video-interfaces.txt,
-   please refer to the SoC specific binding document:
-    * Documentation/devicetree/bindings/display/imx/hdmi.txt
-    * Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
-
-Optional properties
-- reg-io-width: the width of the reg:1,4, default set to 1 if not present
-- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing,
-  if the property is omitted, a functionally reduced I2C bus
-  controller on DW HDMI is probed
-- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
-
-Example:
-	hdmi: hdmi@0120000 {
-		compatible = "fsl,imx6q-hdmi";
-		reg = <0x00120000 0x9000>;
-		interrupts = <0 115 0x04>;
-		gpr = <&gpr>;
-		clocks = <&clks 123>, <&clks 124>;
-		clock-names = "iahb", "isfr";
-		ddc-i2c-bus = <&i2c2>;
-
-		port@0 {
-			reg = <0>;
-
-			hdmi_mux_0: endpoint {
-				remote-endpoint = <&ipu1_di0_hdmi>;
-			};
-		};
-
-		port@1 {
-			reg = <1>;
-
-			hdmi_mux_1: endpoint {
-				remote-endpoint = <&ipu1_di1_hdmi>;
-			};
-		};
-	};
+Synopsys DesignWare HDMI TX Encoder
+===================================
+
+This document defines device tree properties for the Synopsys DesignWare HDMI
+TX Encoder (DWC HDMI TX). It doesn't constitue a device tree binding
+specification by itself but is meant to be referenced by platform-specific
+device tree bindings.
+
+When referenced from platform device tree bindings the properties defined in
+this document are defined as follows. The platform device tree bindings are
+responsible for defining whether each property is required or optional.
+
+- reg: Memory mapped base address and length of the DWC HDMI TX registers.
+
+- reg-io-width: Width of the registers specified by the reg property. The
+  value is expressed in bytes and must be equal to 1 or 4 if specified. The
+  register width defaults to 1 if the property is not present.
+
+- interrupts: Reference to the DWC HDMI TX interrupt.
+
+- clocks: References to all the clocks specified in the clock-names property
+  as specified in Documentation/devicetree/bindings/clock/clock-bindings.txt.
+
+- clock-names: The DWC HDMI TX uses the following clocks.
+
+  - "iahb" is the bus clock for either AHB and APB (mandatory).
+  - "isfr" is the internal register configuration clock (mandatory).
+  - "cec" is the HDMI CEC controller main clock (optional).
+
+- ports: The connectivity of the DWC HDMI TX with the rest of the system is
+  expressed in using ports as specified in the device graph bindings defined
+  in Documentation/devicetree/bindings/graph.txt. The numbering of the ports
+  is platform-specific.
diff --git a/Documentation/devicetree/bindings/display/imx/hdmi.txt b/Documentation/devicetree/bindings/display/imx/hdmi.txt
index 1b756cf9afb0..66a8f86e5d12 100644
--- a/Documentation/devicetree/bindings/display/imx/hdmi.txt
+++ b/Documentation/devicetree/bindings/display/imx/hdmi.txt
@@ -1,29 +1,36 @@
-Device-Tree bindings for HDMI Transmitter
+Freescale i.MX6 DWC HDMI TX Encoder
+===================================
 
-HDMI Transmitter
-================
+The HDMI transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
+with a companion PHY IP.
+
+These DT bindings follow the Synopsys DWC HDMI TX bindings defined in
+Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt with the
+following device-specific properties.
 
-The HDMI Transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
-with accompanying PHY IP.
 
 Required properties:
- - #address-cells : should be <1>
- - #size-cells : should be <0>
- - compatible : should be "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi".
- - gpr : should be <&gpr>.
-   The phandle points to the iomuxc-gpr region containing the HDMI
-   multiplexer control register.
- - clocks, clock-names : phandles to the HDMI iahb and isrf clocks, as described
-   in Documentation/devicetree/bindings/clock/clock-bindings.txt and
-   Documentation/devicetree/bindings/clock/imx6q-clock.txt.
- - port@[0-4]: Up to four port nodes with endpoint definitions as defined in
-   Documentation/devicetree/bindings/media/video-interfaces.txt,
-   corresponding to the four inputs to the HDMI multiplexer.
-
-Optional properties:
- - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
-
-example:
+
+- compatible : Shall be one of "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi".
+- reg: See dw_hdmi.txt.
+- interrupts: HDMI interrupt number
+- clocks: See dw_hdmi.txt.
+- clock-names: Shall contain "iahb" and "isfr" as defined in dw_hdmi.txt.
+- ports: See dw_hdmi.txt. The DWC HDMI shall have between one and four ports,
+  numbered 0 to 3, corresponding to the four inputs of the HDMI multiplexer.
+  Each port shall have a single endpoint.
+- gpr : Shall contain a phandle to the iomuxc-gpr region containing the HDMI
+  multiplexer control register.
+
+Optional properties
+
+- ddc-i2c-bus: The HDMI DDC bus can be connected to either a system I2C master
+  or the functionally-reduced I2C master contained in the DWC HDMI. When
+  connected to a system I2C master this property contains a phandle to that
+  I2C master controller.
+
+
+Example:
 
 	gpr: iomuxc-gpr@020e0000 {
 		/* ... */
diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 668091f27674..046076c6b277 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -1,24 +1,39 @@
-Rockchip specific extensions to the Synopsys Designware HDMI
-================================
+Rockchip DWC HDMI TX Encoder
+============================
+
+The HDMI transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
+with a companion PHY IP.
+
+These DT bindings follow the Synopsys DWC HDMI TX bindings defined in
+Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt with the
+following device-specific properties.
+
 
 Required properties:
-- compatible: "rockchip,rk3288-dw-hdmi";
-- reg: Physical base address and length of the controller's registers.
-- clocks: phandle to hdmi iahb and isfr clocks.
-- clock-names: should be "iahb" "isfr"
-- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
+
+- compatible: Shall contain "rockchip,rk3288-dw-hdmi".
+- reg: See dw_hdmi.txt.
+- reg-io-width: See dw_hdmi.txt. Shall be 4.
 - interrupts: HDMI interrupt number
-- ports: contain a port node with endpoint definitions as defined in
-  Documentation/devicetree/bindings/media/video-interfaces.txt. For
-  vopb,set the reg = <0> and set the reg = <1> for vopl.
-- reg-io-width: the width of the reg:1,4, the value should be 4 on
-  rk3288 platform
+- clocks: See dw_hdmi.txt.
+- clock-names: Shall contain "iahb" and "isfr" as defined in dw_hdmi.txt.
+- ports: See dw_hdmi.txt. The DWC HDMI shall have a single port numbered 0
+  corresponding to the video input of the controller. The port shall have two
+  endpoints, numbered 0 and 1, connected respectively to the vopb and vopl.
+- rockchip,grf: Shall reference the GRF to mux vopl/vopb.
 
 Optional properties
-- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
-- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
+
+- ddc-i2c-bus: The HDMI DDC bus can be connected to either a system I2C master
+  or the functionally-reduced I2C master contained in the DWC HDMI. When
+  connected to a system I2C master this property contains a phandle to that
+  I2C master controller.
+- clock-names: See dw_hdmi.txt. The "cec" clock is optional.
+- clock-names: May contain "cec" as defined in dw_hdmi.txt.
+
 
 Example:
+
 hdmi: hdmi@ff980000 {
 	compatible = "rockchip,rk3288-dw-hdmi";
 	reg = <0xff980000 0x20000>;
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 22/29] dt-bindings: display: renesas: Add R-Car Gen3 HDMI TX DT bindings
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (20 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 21/29] dt-bindings: display: dw-hdmi: Clean up DT bindings documentation Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 23/29] drm: rcar-du: Add Gen3 HDMI encoder support Laurent Pinchart
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The Renesas R-Car Gen3 SoCs use a Synopsys DWC HDMI TX encoder IP. Add
corresponding device tree bindings based on the DWC HDMI TX bindings
model.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/display/bridge/renesas,dw-hdmi.txt    | 75 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
new file mode 100644
index 000000000000..f6b3f36d422b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
@@ -0,0 +1,75 @@
+Renesas Gen3 DWC HDMI TX Encoder
+================================
+
+The HDMI transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
+with a companion PHY IP.
+
+These DT bindings follow the Synopsys DWC HDMI TX bindings defined in
+Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt with the
+following device-specific properties.
+
+
+Required properties:
+
+- compatible : Shall contain one or more of
+  - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX
+  - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX
+
+    When compatible with generic versions, nodes must list the SoC-specific
+    version corresponding to the platform first, followed by the
+    family-specific version.
+
+- reg: See dw_hdmi.txt.
+- interrupts: HDMI interrupt number
+- clocks: See dw_hdmi.txt.
+- clock-names: Shall contain "iahb" and "isfr" as defined in dw_hdmi.txt.
+- ports: See dw_hdmi.txt. The DWC HDMI shall have one port numbered 0
+  corresponding to the video input of the controller and one port numbered 1
+  corresponding to its HDMI output. Each port shall have a single endpoint.
+
+Optional properties:
+
+- power-domains: Shall reference the power domain that contains the DWC HDMI,
+  if any.
+
+
+Example:
+
+	hdmi0: hdmi0@fead0000 {
+		compatible = "renesas,r8a7795-dw-hdmi";
+		reg = <0 0xfead0000 0 0x10000>;
+		interrupts = <0 389 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>;
+		clock-names = "iahb", "isfr";
+		power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				dw_hdmi0_in: endpoint {
+					remote-endpoint = <&du_out_hdmi0>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				rcar_dw_hdmi0_out: endpoint {
+					remote-endpoint = <&hdmi0_con>;
+				};
+			};
+		};
+	};
+
+	hdmi0-out {
+		compatible = "hdmi-connector";
+		label = "HDMI0 OUT";
+		type = "a";
+
+		port {
+			hdmi0_con: endpoint {
+				remote-endpoint = <&rcar_dw_hdmi0_out>;
+			};
+		};
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 1a7a773114aa..162d904d5cc3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4247,6 +4247,7 @@ S:	Supported
 F:	drivers/gpu/drm/rcar-du/
 F:	drivers/gpu/drm/shmobile/
 F:	include/linux/platform_data/shmob_drm.h
+F:	Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
 F:	Documentation/devicetree/bindings/display/renesas,du.txt
 
 DRM DRIVER FOR QXL VIRTUAL GPU
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 23/29] drm: rcar-du: Add Gen3 HDMI encoder support
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (21 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 22/29] dt-bindings: display: renesas: Add R-Car Gen3 HDMI TX DT bindings Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 24/29] drm: rcar-du: Skip disabled outputs Laurent Pinchart
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

The R-Car Gen3 SoCs include on-chip DesignWare HDMI encoders. Support
them with a platform driver to provide platform glue data to the dw-hdmi
driver.

The driver is a complete rewrite of code coming from the Renesas BSP,
save for the values in the PHY parameters table.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/Kconfig        |   8 +++
 drivers/gpu/drm/rcar-du/Makefile       |   1 +
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 100 +++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index 06121eeba9e5..a356d2f2f6d6 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -11,6 +11,14 @@ config DRM_RCAR_DU
 	  Choose this option if you have an R-Car chipset.
 	  If M is selected the module will be called rcar-du-drm.
 
+config DRM_RCAR_DW_HDMI
+	bool "R-Car DU Gen3 HDMI Encoder Support"
+	depends on DRM_RCAR_DU
+	depends on OF
+	select DRM_DW_HDMI
+	help
+	  Enable support for R-Car Gen3 internal HDMI encoder.
+
 config DRM_RCAR_LVDS
 	bool "R-Car DU LVDS Encoder Support"
 	depends on DRM_RCAR_DU
diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile
index a492e6858691..2131e722de3b 100644
--- a/drivers/gpu/drm/rcar-du/Makefile
+++ b/drivers/gpu/drm/rcar-du/Makefile
@@ -11,3 +11,4 @@ rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)	+= rcar_du_lvdsenc.o
 rcar-du-drm-$(CONFIG_DRM_RCAR_VSP)	+= rcar_du_vsp.o
 
 obj-$(CONFIG_DRM_RCAR_DU)		+= rcar-du-drm.o
+obj-$(CONFIG_DRM_RCAR_DW_HDMI)		+= rcar_dw_hdmi.o
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
new file mode 100644
index 000000000000..7539626b8ebd
--- /dev/null
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -0,0 +1,100 @@
+/*
+ * R-Car Gen3 HDMI PHY
+ *
+ * Copyright (C) 2016 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * 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 <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <drm/bridge/dw_hdmi.h>
+
+#define RCAR_HDMI_PHY_OPMODE_PLLCFG	0x06	/* Mode of operation and PLL dividers */
+#define RCAR_HDMI_PHY_PLLCURRGMPCTRL	0x10	/* PLL current and Gmp (conductance) */
+#define RCAR_HDMI_PHY_PLLDIVCTRL	0x11	/* PLL dividers */
+
+struct rcar_hdmi_phy_params {
+	unsigned long mpixelclock;
+	u16 opmode_div;	/* Mode of operation and PLL dividers */
+	u16 curr_gmp;	/* PLL current and Gmp (conductance) */
+	u16 div;	/* PLL dividers */
+};
+
+static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
+	{ 35500000,  0x0003, 0x0344, 0x0328 },
+	{ 44900000,  0x0003, 0x0285, 0x0128 },
+	{ 71000000,  0x0002, 0x1184, 0x0314 },
+	{ 90000000,  0x0002, 0x1144, 0x0114 },
+	{ 140250000, 0x0001, 0x20c4, 0x030a },
+	{ 182750000, 0x0001, 0x2084, 0x010a },
+	{ 281250000, 0x0000, 0x0084, 0x0305 },
+	{ 297000000, 0x0000, 0x0084, 0x0105 },
+	{ ~0UL,      0x0000, 0x0000, 0x0000 },
+};
+
+static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
+				   const struct dw_hdmi_plat_data *pdata,
+				   unsigned long mpixelclock)
+{
+	const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
+
+	for (; params && params->mpixelclock != ~0UL; ++params) {
+		if (mpixelclock <= params->mpixelclock)
+			break;
+	}
+
+	if (params->mpixelclock == ~0UL)
+		return -EINVAL;
+
+	dw_hdmi_phy_i2c_write(hdmi, params->opmode_div,
+			      RCAR_HDMI_PHY_OPMODE_PLLCFG);
+	dw_hdmi_phy_i2c_write(hdmi, params->curr_gmp,
+			      RCAR_HDMI_PHY_PLLCURRGMPCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, params->div, RCAR_HDMI_PHY_PLLDIVCTRL);
+
+	return 0;
+}
+
+static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = {
+	.configure_phy	= rcar_hdmi_phy_configure,
+};
+
+static int rcar_dw_hdmi_probe(struct platform_device *pdev)
+{
+	return dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data);
+}
+
+static int rcar_dw_hdmi_remove(struct platform_device *pdev)
+{
+	dw_hdmi_remove(pdev);
+
+	return 0;
+}
+
+static const struct of_device_id rcar_dw_hdmi_of_table[] = {
+	{ .compatible = "renesas,rcar-gen3-hdmi" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, rcar_dw_hdmi_of_table);
+
+static struct platform_driver rcar_dw_hdmi_platform_driver = {
+	.probe		= rcar_dw_hdmi_probe,
+	.remove		= rcar_dw_hdmi_remove,
+	.driver		= {
+		.name	= "rcar-dw-hdmi",
+		.of_match_table = rcar_dw_hdmi_of_table,
+	},
+};
+
+module_platform_driver(rcar_dw_hdmi_platform_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Renesas R-Car Gen3 HDMI Encoder Driver");
+MODULE_LICENSE("GPL");
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 24/29] drm: rcar-du: Skip disabled outputs
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (22 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 23/29] drm: rcar-du: Add Gen3 HDMI encoder support Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 25/29] drm: rcar-du: Add DPLL support Laurent Pinchart
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

When a DT node connected to a DU output is disabled no bridge will ever
be instantiated for it. Skip the output in that case.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index aa84689043ae..7a6bd8bdba05 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -384,6 +384,13 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 		return -ENODEV;
 	}
 
+	if (!of_device_is_available(entity)) {
+		dev_dbg(rcdu->dev,
+			"connected entity %s is disabled, skipping\n",
+			entity->full_name);
+		return -ENODEV;
+	}
+
 	entity_ep_node = of_parse_phandle(ep->local_node, "remote-endpoint", 0);
 
 	for_each_endpoint_of_node(entity, ep_node) {
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 25/29] drm: rcar-du: Add DPLL support
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (23 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 24/29] drm: rcar-du: Skip disabled outputs Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 26/29] drm: rcar-du: Add HDMI outputs to R8A7795 device description Laurent Pinchart
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

The implementation hardcodes a workaround for the H3 ES1.x SoC
regardless of the SoC revision, as the workaround can be safely applied
on all devices in the Gen3 family without any side effect.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 81 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
 drivers/gpu/drm/rcar-du/rcar_du_regs.h | 23 ++++++++++
 4 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index a2ec6d8796a0..cec20abd61aa 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -106,9 +106,62 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
  * Hardware Setup
  */
 
+struct dpll_info {
+	unsigned int output;
+	unsigned int fdpll;
+	unsigned int n;
+	unsigned int m;
+};
+
+static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
+				 struct dpll_info *dpll,
+				 unsigned long input,
+				 unsigned long target)
+{
+	unsigned long best_diff = (unsigned long)-1;
+	unsigned long diff;
+	unsigned int fdpll;
+	unsigned int m;
+	unsigned int n;
+
+	for (n = 39; n < 120; n++) {
+		for (m = 0; m < 4; m++) {
+			for (fdpll = 1; fdpll < 32; fdpll++) {
+				unsigned long output;
+
+				/* 1/2 (FRQSEL=1) for duty rate 50% */
+				output = input * (n + 1) / (m + 1)
+				       / (fdpll + 1) / 2;
+
+				if (output >= 400000000)
+					continue;
+
+				diff = abs((long)output - (long)target);
+				if (best_diff > diff) {
+					best_diff = diff;
+					dpll->n = n;
+					dpll->m = m;
+					dpll->fdpll = fdpll;
+					dpll->output = output;
+				}
+
+				if (diff == 0)
+					goto done;
+			}
+		}
+	}
+
+done:
+	dev_dbg(rcrtc->group->dev->dev,
+		"output:%u, fdpll:%u, n:%u, m:%u, diff:%lu\n",
+		 dpll->output, dpll->fdpll, dpll->n, dpll->m,
+		 best_diff);
+}
+
 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 {
 	const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
+	struct rcar_du_device *rcdu = rcrtc->group->dev;
 	unsigned long mode_clock = mode->clock * 1000;
 	unsigned long clk;
 	u32 value;
@@ -124,12 +177,18 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 	escr = div | ESCR_DCLKSEL_CLKS;
 
 	if (rcrtc->extclock) {
+		struct dpll_info dpll = { 0 };
 		unsigned long extclk;
 		unsigned long extrate;
 		unsigned long rate;
 		u32 extdiv;
 
 		extclk = clk_get_rate(rcrtc->extclock);
+		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
+			rcar_du_dpll_divider(rcrtc, &dpll, extclk, mode_clock);
+			extclk = dpll.output;
+		}
+
 		extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
 		extdiv = clamp(extdiv, 1U, 64U) - 1;
 
@@ -140,7 +199,27 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 		    abs((long)rate - (long)mode_clock)) {
 			dev_dbg(rcrtc->group->dev->dev,
 				"crtc%u: using external clock\n", rcrtc->index);
-			escr = extdiv | ESCR_DCLKSEL_DCLKIN;
+
+			if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
+				u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
+					   | DPLLCR_FDPLL(dpll.fdpll)
+					   | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
+					   | DPLLCR_STBY;
+
+				if (rcrtc->index == 1)
+					dpllcr |= DPLLCR_PLCS1
+					       |  DPLLCR_INCS_DOTCLKIN1;
+				else
+					dpllcr |= DPLLCR_PLCS0
+					       |  DPLLCR_INCS_DOTCLKIN0;
+
+				rcar_du_group_write(rcrtc->group, DPLLCR,
+						    dpllcr);
+
+				escr = ESCR_DCLKSEL_DCLKIN | 1;
+			} else {
+				escr = ESCR_DCLKSEL_DCLKIN | extdiv;
+			}
 		}
 	}
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 4da5edacab19..74352140f55f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -163,6 +163,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 		},
 	},
 	.num_lvds = 1,
+	.dpll_ch =  BIT(1) | BIT(2),
 };
 
 static const struct rcar_du_device_info rcar_du_r8a7796_info = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 9393b26efe89..c4b6b7238601 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -65,6 +65,7 @@ struct rcar_du_device_info {
 	unsigned int num_crtcs;
 	struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
 	unsigned int num_lvds;
+	unsigned int dpll_ch;
 };
 
 #define RCAR_DU_MAX_CRTCS		4
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
index fedb0161e234..d5bae99d3cfe 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
@@ -277,6 +277,29 @@
 #define DEFR10_TSEL_H3_TCON1	(0 << 1) /* DEFR102 register only (DU2/DU3) */
 #define DEFR10_DEFE10		(1 << 0)
 
+#define DPLLCR			0x20044
+#define DPLLCR_CODE		(0x95 << 24)
+#define DPLLCR_PLCS1		(1 << 23)
+/*
+ * PLCS0 is bit 21, but H3 ES1.x requires bit 20 to be set as well. As bit 20
+ * isn't implemented by other SoC in the Gen3 family it can safely be set
+ * unconditionally.
+ */
+#define DPLLCR_PLCS0		(3 << 20)
+#define DPLLCR_CLKE		(1 << 18)
+#define DPLLCR_FDPLL(n)		((n) << 12)
+#define DPLLCR_N(n)		((n) << 5)
+#define DPLLCR_M(n)		((n) << 3)
+#define DPLLCR_STBY		(1 << 2)
+#define DPLLCR_INCS_DOTCLKIN0	(0 << 0)
+#define DPLLCR_INCS_DOTCLKIN1	(1 << 1)
+
+#define DPLLC2R			0x20048
+#define DPLLC2R_CODE		(0x95 << 24)
+#define DPLLC2R_SELC		(1 << 12)
+#define DPLLC2R_M(n)		((n) << 8)
+#define DPLLC2R_FDPLL(n)	((n) << 0)
+
 /* -----------------------------------------------------------------------------
  * Display Timing Generation Registers
  */
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 26/29] drm: rcar-du: Add HDMI outputs to R8A7795 device description
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (24 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 25/29] drm: rcar-du: Add DPLL support Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 27/29] arm64: dts: r8a7795: Add HDMI encoder support Laurent Pinchart
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Update the device description with the two available HDMI outputs.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  4 +++-
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 12 ++++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 6f08b7e7db06..459e5390d6e0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -1,7 +1,7 @@
 /*
  * rcar_du_crtc.h  --  R-Car Display Unit CRTCs
  *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -61,6 +61,8 @@ enum rcar_du_output {
 	RCAR_DU_OUTPUT_DPAD1,
 	RCAR_DU_OUTPUT_LVDS0,
 	RCAR_DU_OUTPUT_LVDS1,
+	RCAR_DU_OUTPUT_HDMI0,
+	RCAR_DU_OUTPUT_HDMI1,
 	RCAR_DU_OUTPUT_TCON,
 	RCAR_DU_OUTPUT_MAX,
 };
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 74352140f55f..3107719c4653 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -150,13 +150,21 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
 		  | RCAR_DU_FEATURE_VSP1_SOURCE,
 	.num_crtcs = 4,
 	.routes = {
-		/* R8A7795 has one RGB output, one LVDS output and two
-		 * (currently unsupported) HDMI outputs.
+		/* R8A7795 has one RGB output, two HDMI outputs and one
+		 * LVDS output.
 		 */
 		[RCAR_DU_OUTPUT_DPAD0] = {
 			.possible_crtcs = BIT(3),
 			.port = 0,
 		},
+		[RCAR_DU_OUTPUT_HDMI0] = {
+			.possible_crtcs = BIT(1),
+			.port = 1,
+		},
+		[RCAR_DU_OUTPUT_HDMI1] = {
+			.possible_crtcs = BIT(2),
+			.port = 2,
+		},
 		[RCAR_DU_OUTPUT_LVDS0] = {
 			.possible_crtcs = BIT(0),
 			.port = 3,
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 27/29] arm64: dts: r8a7795: Add HDMI encoder support
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (25 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 26/29] drm: rcar-du: Add HDMI outputs to R8A7795 device description Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:33 ` [PATCH v2 28/29] arm64: dts: r8a7795: salvator-x: Enable HDMI outputs Laurent Pinchart
  2016-12-20  1:34 ` [PATCH v2 29/29] arm64: dts: r8a7795: salvator-x: Add DU1 and DU2 external dot clocks Laurent Pinchart
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Ulrich Hecht

From: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>

Add DT nodes for the two HDMI encoders in disabled state.

Based on work by Koji Matsuoka.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 50 ++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 9b717dee1f7b..5e8f231cf5a0 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1590,11 +1590,13 @@
 				port@1 {
 					reg = <1>;
 					du_out_hdmi0: endpoint {
+						remote-endpoint = <&dw_hdmi0_in>;
 					};
 				};
 				port@2 {
 					reg = <2>;
 					du_out_hdmi1: endpoint {
+						remote-endpoint = <&dw_hdmi1_in>;
 					};
 				};
 				port@3 {
@@ -1604,5 +1606,53 @@
 				};
 			};
 		};
+
+		hdmi0: hdmi0@fead0000 {
+			compatible = "renesas,r8a7795-hdmi", "renesas,rcar-gen3-hdmi";
+			reg = <0 0xfead0000 0 0x10000>;
+			interrupts = <0 389 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 729>, <&cpg CPG_CORE R8A7795_CLK_HDMI>;
+			clock-names = "iahb", "isfr";
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					dw_hdmi0_in: endpoint {
+						remote-endpoint = <&du_out_hdmi0>;
+					};
+				};
+				port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		hdmi1: hdmi1@feae0000 {
+			compatible = "renesas,r8a7795-hdmi", "renesas,rcar-gen3-hdmi";
+			reg = <0 0xfeae0000 0 0x10000>;
+			interrupts = <0 436 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 728>, <&cpg CPG_CORE R8A7795_CLK_HDMI>;
+			clock-names = "iahb", "isfr";
+			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					dw_hdmi1_in: endpoint {
+						remote-endpoint = <&du_out_hdmi1>;
+					};
+				};
+				port@1 {
+					reg = <1>;
+				};
+			};
+		};
 	};
 };
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 28/29] arm64: dts: r8a7795: salvator-x: Enable HDMI outputs
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (26 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 27/29] arm64: dts: r8a7795: Add HDMI encoder support Laurent Pinchart
@ 2016-12-20  1:33 ` Laurent Pinchart
  2016-12-20  1:34 ` [PATCH v2 29/29] arm64: dts: r8a7795: salvator-x: Add DU1 and DU2 external dot clocks Laurent Pinchart
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:33 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc, Koji Matsuoka

From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>

Instantiate the HDMI connectors and enable the encoders.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
index 73a22b93f7b1..08554b4d7e86 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -147,6 +147,30 @@
 		};
 	};
 
+	hdmi0-out {
+		compatible = "hdmi-connector";
+		label = "HDMI0 OUT";
+		type = "a";
+
+		port {
+			hdmi0_con: endpoint {
+				remote-endpoint = <&rcar_dw_hdmi0_out>;
+			};
+		};
+	};
+
+	hdmi1-out {
+		compatible = "hdmi-connector";
+		label = "HDMI1 OUT";
+		type = "a";
+
+		port {
+			hdmi1_con: endpoint {
+				remote-endpoint = <&rcar_dw_hdmi1_out>;
+			};
+		};
+	};
+
 	vga-encoder {
 		compatible = "adi,adv7123";
 
@@ -190,6 +214,32 @@
 	};
 };
 
+&hdmi0 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+			rcar_dw_hdmi0_out: endpoint {
+				remote-endpoint = <&hdmi0_con>;
+			};
+		};
+	};
+};
+
+&hdmi1 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+			rcar_dw_hdmi1_out: endpoint {
+				remote-endpoint = <&hdmi1_con>;
+			};
+		};
+	};
+};
+
 &du {
 	pinctrl-0 = <&du_pins>;
 	pinctrl-names = "default";
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* [PATCH v2 29/29] arm64: dts: r8a7795: salvator-x: Add DU1 and DU2 external dot clocks
  2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
                   ` (27 preceding siblings ...)
  2016-12-20  1:33 ` [PATCH v2 28/29] arm64: dts: r8a7795: salvator-x: Enable HDMI outputs Laurent Pinchart
@ 2016-12-20  1:34 ` Laurent Pinchart
  28 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20  1:34 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

The DU1 and DU2 external dot clocks are fixed frequency clock generators
running at 33MHz.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
index 08554b4d7e86..b6dc6f5188d6 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -147,6 +147,19 @@
 		};
 	};
 
+	/* External DU dot clocks */
+	x21_clk: x21-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <33000000>;
+	};
+
+	x22_clk: x22-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <33000000>;
+	};
+
 	hdmi0-out {
 		compatible = "hdmi-connector";
 		label = "HDMI0 OUT";
@@ -245,6 +258,16 @@
 	pinctrl-names = "default";
 	status = "okay";
 
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 721>,
+		 <&cpg CPG_MOD 727>,
+		 <&x21_clk>,
+		 <&x22_clk>;
+	clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+		      "dclkin.1", "dclkin.2";
+
 	ports {
 		port@0 {
 			endpoint {
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET
  2016-12-20  1:33 ` [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET Laurent Pinchart
@ 2016-12-20 10:58     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 10:58 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> The bit is documented in a Rockchip BSP as
>
>  #define m_SVSRET_SIG		(1 << 5) /* depend on PHY_MHL_COMB0=1 */
>
> This is confirmed by a Renesas platform, which uses a 2.0 DWC HDMI TX as
> the RK3288. Rename the bit accordingly.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 8 ++++----
>  drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++--
>  2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index b4fb0bd78910..06c252f560ad 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -895,11 +895,11 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
>  			 HDMI_PHY_CONF0_ENTMDS_MASK);
>  }
>  
> -static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
> +static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
>  {
>  	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
> -			 HDMI_PHY_CONF0_SPARECTRL_OFFSET,
> -			 HDMI_PHY_CONF0_SPARECTRL_MASK);
> +			 HDMI_PHY_CONF0_SVSRET_OFFSET,
> +			 HDMI_PHY_CONF0_SVSRET_MASK);
>  }
>  
>  static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
> @@ -1014,7 +1014,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
>  	dw_hdmi_phy_gen2_pddq(hdmi, 0);
>  
>  	if (hdmi->dev_type == RK3288_HDMI)
> -		dw_hdmi_phy_enable_spare(hdmi, 1);
> +		dw_hdmi_phy_enable_svsret(hdmi, 1);
>  
>  	/*Wait for PHY PLL lock */
>  	msec = 5;
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 55135bbd0c16..08235aef2fa3 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -847,8 +847,8 @@ enum {
>  	HDMI_PHY_CONF0_PDZ_OFFSET = 7,
>  	HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
>  	HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
> -	HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
> -	HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
> +	HDMI_PHY_CONF0_SVSRET_MASK = 0x20,
> +	HDMI_PHY_CONF0_SVSRET_OFFSET = 5,
>  	HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
>  	HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
>  	HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET
@ 2016-12-20 10:58     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 10:58 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> The bit is documented in a Rockchip BSP as
>
>  #define m_SVSRET_SIG		(1 << 5) /* depend on PHY_MHL_COMB0=1 */
>
> This is confirmed by a Renesas platform, which uses a 2.0 DWC HDMI TX as
> the RK3288. Rename the bit accordingly.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 8 ++++----
>  drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++--
>  2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index b4fb0bd78910..06c252f560ad 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -895,11 +895,11 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
>  			 HDMI_PHY_CONF0_ENTMDS_MASK);
>  }
>  
> -static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
> +static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
>  {
>  	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
> -			 HDMI_PHY_CONF0_SPARECTRL_OFFSET,
> -			 HDMI_PHY_CONF0_SPARECTRL_MASK);
> +			 HDMI_PHY_CONF0_SVSRET_OFFSET,
> +			 HDMI_PHY_CONF0_SVSRET_MASK);
>  }
>  
>  static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
> @@ -1014,7 +1014,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
>  	dw_hdmi_phy_gen2_pddq(hdmi, 0);
>  
>  	if (hdmi->dev_type == RK3288_HDMI)
> -		dw_hdmi_phy_enable_spare(hdmi, 1);
> +		dw_hdmi_phy_enable_svsret(hdmi, 1);
>  
>  	/*Wait for PHY PLL lock */
>  	msec = 5;
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 55135bbd0c16..08235aef2fa3 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -847,8 +847,8 @@ enum {
>  	HDMI_PHY_CONF0_PDZ_OFFSET = 7,
>  	HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
>  	HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
> -	HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
> -	HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
> +	HDMI_PHY_CONF0_SVSRET_MASK = 0x20,
> +	HDMI_PHY_CONF0_SVSRET_OFFSET = 5,
>  	HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
>  	HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
>  	HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs
  2016-12-20  1:33 ` [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs Laurent Pinchart
@ 2016-12-20 10:59     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 10:59 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> The DWC HDMI TX can be recognized by the two product identification
> registers. If the registers don't read as expect the IP will be very
> different than what the driver has been designed for, or will be
> misconfigured in a way that makes it non-operational (invalid memory
> address, incorrect clocks, ...). We should reject this situation with an
> error.
>
> While this isn't critical for proper operation with supported IPs at the
> moment, the driver will soon gain automatic device-specific handling
> based on runtime device identification. This change makes it easier to
> implement that without having to default to a random guess in case the
> device can't be identified.
>
> While at it print a readable version number in the device identification
> message instead of raw register values.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 25 +++++++++++++++++++------
>  drivers/gpu/drm/bridge/dw-hdmi.h |  8 ++++++++
>  2 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 06c252f560ad..1809247745b8 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1832,6 +1832,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	int irq;
>  	int ret;
>  	u32 val = 1;
> +	u16 version;
> +	u8 prod_id0;
> +	u8 prod_id1;
>  	u8 config0;
>  	u8 config1;
>  
> @@ -1914,12 +1917,22 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	}
>  
>  	/* Product and revision IDs */
> -	dev_info(dev,
> -		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
> -		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
> -		 hdmi_readb(hdmi, HDMI_REVISION_ID),
> -		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
> -		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
> +	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> +		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
> +	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
> +	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
> +
> +	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
> +	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
> +		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
> +			version, prod_id0, prod_id1);
> +		ret = -ENODEV;
> +		goto err_iahb;
> +	}
> +
> +	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> +		 version >> 12, version & 0xfff,
> +		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
>  
>  	initialize_hdmi_ih_mutes(hdmi);
>  
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 08235aef2fa3..91d7fabbd6e5 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -545,6 +545,14 @@
>  #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
>  
>  enum {
> +/* PRODUCT_ID0 field values */
> +	HDMI_PRODUCT_ID0_HDMI_TX = 0xa0,
> +
> +/* PRODUCT_ID1 field values */
> +	HDMI_PRODUCT_ID1_HDCP = 0xc0,
> +	HDMI_PRODUCT_ID1_HDMI_RX = 0x02,
> +	HDMI_PRODUCT_ID1_HDMI_TX = 0x01,
> +
>  /* CONFIG0_ID field values */
>  	HDMI_CONFIG0_I2S = 0x10,
>  

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs
@ 2016-12-20 10:59     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 10:59 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> The DWC HDMI TX can be recognized by the two product identification
> registers. If the registers don't read as expect the IP will be very
> different than what the driver has been designed for, or will be
> misconfigured in a way that makes it non-operational (invalid memory
> address, incorrect clocks, ...). We should reject this situation with an
> error.
>
> While this isn't critical for proper operation with supported IPs at the
> moment, the driver will soon gain automatic device-specific handling
> based on runtime device identification. This change makes it easier to
> implement that without having to default to a random guess in case the
> device can't be identified.
>
> While at it print a readable version number in the device identification
> message instead of raw register values.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 25 +++++++++++++++++++------
>  drivers/gpu/drm/bridge/dw-hdmi.h |  8 ++++++++
>  2 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 06c252f560ad..1809247745b8 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1832,6 +1832,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	int irq;
>  	int ret;
>  	u32 val = 1;
> +	u16 version;
> +	u8 prod_id0;
> +	u8 prod_id1;
>  	u8 config0;
>  	u8 config1;
>  
> @@ -1914,12 +1917,22 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	}
>  
>  	/* Product and revision IDs */
> -	dev_info(dev,
> -		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
> -		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
> -		 hdmi_readb(hdmi, HDMI_REVISION_ID),
> -		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
> -		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
> +	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> +		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
> +	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
> +	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
> +
> +	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
> +	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
> +		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
> +			version, prod_id0, prod_id1);
> +		ret = -ENODEV;
> +		goto err_iahb;
> +	}
> +
> +	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> +		 version >> 12, version & 0xfff,
> +		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
>  
>  	initialize_hdmi_ih_mutes(hdmi);
>  
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 08235aef2fa3..91d7fabbd6e5 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -545,6 +545,14 @@
>  #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
>  
>  enum {
> +/* PRODUCT_ID0 field values */
> +	HDMI_PRODUCT_ID0_HDMI_TX = 0xa0,
> +
> +/* PRODUCT_ID1 field values */
> +	HDMI_PRODUCT_ID1_HDCP = 0xc0,
> +	HDMI_PRODUCT_ID1_HDMI_RX = 0x02,
> +	HDMI_PRODUCT_ID1_HDMI_TX = 0x01,
> +
>  /* CONFIG0_ID field values */
>  	HDMI_CONFIG0_I2S = 0x10,
>  

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register
  2016-12-20  1:33 ` [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register Laurent Pinchart
@ 2016-12-20 11:00     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:00 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Bit 0 in CONFIG1_ID tells whether the IP core uses an AHB slave
> interface for control. The correct way to identify AHB audio DMA support
> is through bit 1 in CONFIG3_ID.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++---
>  drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++++
>  2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 1809247745b8..730a7558d4d4 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1836,7 +1836,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	u8 prod_id0;
>  	u8 prod_id1;
>  	u8 config0;
> -	u8 config1;
> +	u8 config3;
>  
>  	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
>  	if (!hdmi)
> @@ -1988,9 +1988,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	pdevinfo.id = PLATFORM_DEVID_AUTO;
>  
>  	config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
> -	config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID);
> +	config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
>  
> -	if (config1 & HDMI_CONFIG1_AHB) {
> +	if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
>  		struct dw_hdmi_audio_data audio;
>  
>  		audio.phys = iores->start;
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 91d7fabbd6e5..a4fd64a203c9 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -559,6 +559,10 @@ enum {
>  /* CONFIG1_ID field values */
>  	HDMI_CONFIG1_AHB = 0x01,
>  
> +/* CONFIG3_ID field values */
> +	HDMI_CONFIG3_AHBAUDDMA = 0x02,
> +	HDMI_CONFIG3_GPAUD = 0x01,
> +
>  /* IH_FC_INT2 field values */
>  	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
>  	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register
@ 2016-12-20 11:00     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:00 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Bit 0 in CONFIG1_ID tells whether the IP core uses an AHB slave
> interface for control. The correct way to identify AHB audio DMA support
> is through bit 1 in CONFIG3_ID.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++---
>  drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++++
>  2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 1809247745b8..730a7558d4d4 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1836,7 +1836,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	u8 prod_id0;
>  	u8 prod_id1;
>  	u8 config0;
> -	u8 config1;
> +	u8 config3;
>  
>  	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
>  	if (!hdmi)
> @@ -1988,9 +1988,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	pdevinfo.id = PLATFORM_DEVID_AUTO;
>  
>  	config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
> -	config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID);
> +	config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
>  
> -	if (config1 & HDMI_CONFIG1_AHB) {
> +	if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
>  		struct dw_hdmi_audio_data audio;
>  
>  		audio.phys = iores->start;
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
> index 91d7fabbd6e5..a4fd64a203c9 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.h
> @@ -559,6 +559,10 @@ enum {
>  /* CONFIG1_ID field values */
>  	HDMI_CONFIG1_AHB = 0x01,
>  
> +/* CONFIG3_ID field values */
> +	HDMI_CONFIG3_AHBAUDDMA = 0x02,
> +	HDMI_CONFIG3_GPAUD = 0x01,
> +
>  /* IH_FC_INT2 field values */
>  	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
>  	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version
  2016-12-20  1:33 ` [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version Laurent Pinchart
@ 2016-12-20 11:32     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:32 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Use the device version queried at runtime instead of the device type
> provided through platform data to handle the overflow workaround. This
> will make support of other SoCs integrating the same HDMI TX controller
> version easier.
>
> Among the supported platforms only i.MX6DL and i.MX6Q have been
> identified as needing the workaround. Disabling it on Rockchip RK3288
> (which integrates a v2.00a controller) didn't produce any error or
> artifact.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu
> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 46 ++++++++++++++++++++++++++++------------
>  1 file changed, 33 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 730a7558d4d4..f4faa14213e5 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -117,8 +117,10 @@ struct dw_hdmi {
>  	struct drm_connector connector;
>  	struct drm_bridge bridge;
>  
> -	struct platform_device *audio;
>  	enum dw_hdmi_devtype dev_type;
> +	unsigned int version;
> +
> +	struct platform_device *audio;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1323,19 +1325,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  /* Workaround to clear the overflow condition */
>  static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
>  {
> -	int count;
> +	unsigned int count;
> +	unsigned int i;
>  	u8 val;
>  
> -	/* TMDS software reset */
> -	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
> +	/*
> +	 * Under some circumstances the Frame Composer arithmetic unit can miss
> +	 * an FC register write due to being busy processing the previous one.
> +	 * The issue can be worked around by issuing a TMDS software reset and
> +	 * then write one of the FC registers several times.
> +	 *
> +	 * The number of iterations matters and depends on the HDMI TX revision
> +	 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
> +	 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
> +	 * 4 and 1 iterations respectively.
> +	 */
>  
> -	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
> -	if (hdmi->dev_type == IMX6DL_HDMI) {
> -		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
> +	switch (hdmi->version) {
> +	case 0x130a:
> +		count = 4;
> +		break;
> +	case 0x131a:
> +		count = 1;
> +		break;
> +	default:
>  		return;
>  	}
>  
> -	for (count = 0; count < 4; count++)
> +	/* TMDS software reset */
> +	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
> +
> +	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
> +	for (i = 0; i < count; i++)
>  		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
>  }
>  
> @@ -1832,7 +1853,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	int irq;
>  	int ret;
>  	u32 val = 1;
> -	u16 version;
>  	u8 prod_id0;
>  	u8 prod_id1;
>  	u8 config0;
> @@ -1917,21 +1937,21 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	}
>  
>  	/* Product and revision IDs */
> -	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> -		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
> +	hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> +		      | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
>  	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
>  	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
>  
>  	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
>  	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
>  		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
> -			version, prod_id0, prod_id1);
> +			hdmi->version, prod_id0, prod_id1);
>  		ret = -ENODEV;
>  		goto err_iahb;
>  	}
>  
>  	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> -		 version >> 12, version & 0xfff,
> +		 hdmi->version >> 12, hdmi->version & 0xfff,
>  		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
>  
>  	initialize_hdmi_ih_mutes(hdmi);

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version
@ 2016-12-20 11:32     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:32 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Use the device version queried at runtime instead of the device type
> provided through platform data to handle the overflow workaround. This
> will make support of other SoCs integrating the same HDMI TX controller
> version easier.
>
> Among the supported platforms only i.MX6DL and i.MX6Q have been
> identified as needing the workaround. Disabling it on Rockchip RK3288
> (which integrates a v2.00a controller) didn't produce any error or
> artifact.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu
> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 46 ++++++++++++++++++++++++++++------------
>  1 file changed, 33 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 730a7558d4d4..f4faa14213e5 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -117,8 +117,10 @@ struct dw_hdmi {
>  	struct drm_connector connector;
>  	struct drm_bridge bridge;
>  
> -	struct platform_device *audio;
>  	enum dw_hdmi_devtype dev_type;
> +	unsigned int version;
> +
> +	struct platform_device *audio;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1323,19 +1325,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  /* Workaround to clear the overflow condition */
>  static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
>  {
> -	int count;
> +	unsigned int count;
> +	unsigned int i;
>  	u8 val;
>  
> -	/* TMDS software reset */
> -	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
> +	/*
> +	 * Under some circumstances the Frame Composer arithmetic unit can miss
> +	 * an FC register write due to being busy processing the previous one.
> +	 * The issue can be worked around by issuing a TMDS software reset and
> +	 * then write one of the FC registers several times.
> +	 *
> +	 * The number of iterations matters and depends on the HDMI TX revision
> +	 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
> +	 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
> +	 * 4 and 1 iterations respectively.
> +	 */
>  
> -	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
> -	if (hdmi->dev_type == IMX6DL_HDMI) {
> -		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
> +	switch (hdmi->version) {
> +	case 0x130a:
> +		count = 4;
> +		break;
> +	case 0x131a:
> +		count = 1;
> +		break;
> +	default:
>  		return;
>  	}
>  
> -	for (count = 0; count < 4; count++)
> +	/* TMDS software reset */
> +	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
> +
> +	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
> +	for (i = 0; i < count; i++)
>  		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
>  }
>  
> @@ -1832,7 +1853,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	int irq;
>  	int ret;
>  	u32 val = 1;
> -	u16 version;
>  	u8 prod_id0;
>  	u8 prod_id1;
>  	u8 config0;
> @@ -1917,21 +1937,21 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	}
>  
>  	/* Product and revision IDs */
> -	version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> -		| (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
> +	hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
> +		      | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
>  	prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
>  	prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
>  
>  	if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
>  	    (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
>  		dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
> -			version, prod_id0, prod_id1);
> +			hdmi->version, prod_id0, prod_id1);
>  		ret = -ENODEV;
>  		goto err_iahb;
>  	}
>  
>  	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> -		 version >> 12, version & 0xfff,
> +		 hdmi->version >> 12, hdmi->version & 0xfff,
>  		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
>  
>  	initialize_hdmi_ih_mutes(hdmi);

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2016-12-20  1:33 ` [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime Laurent Pinchart
@ 2016-12-20 11:39     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:39 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> signal.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 ++++++++++++++++++++++++++++++++++++++--
>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>  2 files changed, 75 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index f4faa14213e5..ef4f2f96ed2c 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -113,6 +113,12 @@ struct dw_hdmi_i2c {
>  	bool			is_regaddr;
>  };
>  
> +struct dw_hdmi_phy_data {
> +	enum dw_hdmi_phy_type type;
> +	const char *name;
> +	bool has_svsret;
> +};
> +
>  struct dw_hdmi {
>  	struct drm_connector connector;
>  	struct drm_bridge bridge;
> @@ -134,7 +140,9 @@ struct dw_hdmi {
>  	u8 edid[HDMI_EDID_LEN];
>  	bool cable_plugin;
>  
> +	const struct dw_hdmi_phy_data *phy;
>  	bool phy_enabled;
> +
>  	struct drm_display_mode previous_mode;
>  
>  	struct i2c_adapter *ddc;
> @@ -1015,7 +1023,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
>  	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
>  	dw_hdmi_phy_gen2_pddq(hdmi, 0);
>  
> -	if (hdmi->dev_type == RK3288_HDMI)
> +	/* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */
> +	if (hdmi->phy->has_svsret)
>  		dw_hdmi_phy_enable_svsret(hdmi, 1);

I didn't review the original code but according to the docs the
svsret signal should be set before de-asserting phy reset.

>  
>  	/*Wait for PHY PLL lock */
> @@ -1840,6 +1849,54 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
> +	{
> +		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
> +		.name = "DWC HDMI TX PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
> +		.name = "DWC MHL PHY + HEAC PHY",
> +		.has_svsret = true,
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_MHL_PHY,
> +		.name = "DWC MHL PHY",
> +		.has_svsret = true,
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
> +		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
> +		.name = "DWC HDMI 3D TX PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
> +		.name = "DWC HDMI 2.0 TX PHY",
> +		.has_svsret = true,

Hmm, what I have here is that only MHL phys have svsret. Is this
case for your phy?

Best regards,
Jose Miguel Abreu
> +	}
> +};
> +
> +static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
> +{
> +	unsigned int i;
> +	u8 phy_type;
> +
> +	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
> +
> +	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
> +		if (dw_hdmi_phys[i].type == phy_type) {
> +			hdmi->phy = &dw_hdmi_phys[i];
> +			return 0;
> +		}
> +	}
> +
> +	if (phy_type == DW_HDMI_PHY_VENDOR_PHY)
> +		dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n");
> +	else
> +		dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n",
> +			phy_type);
> +
> +	return -ENODEV;
> +}
> +
>  static struct dw_hdmi *
>  __dw_hdmi_probe(struct platform_device *pdev,
>  		const struct dw_hdmi_plat_data *plat_data)
> @@ -1950,9 +2007,14 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		goto err_iahb;
>  	}
>  
> -	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> +	ret = dw_hdmi_detect_phy(hdmi);
> +	if (ret < 0)
> +		goto err_iahb;
> +
> +	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n",
>  		 hdmi->version >> 12, hdmi->version & 0xfff,
> -		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
> +		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without",
> +		 hdmi->phy->name);
>  
>  	initialize_hdmi_ih_mutes(hdmi);
>  
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 3bb22a849830..b080a171a23f 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -27,6 +27,16 @@ enum dw_hdmi_devtype {
>  	RK3288_HDMI,
>  };
>  
> +enum dw_hdmi_phy_type {
> +	DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00,
> +	DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2,
> +	DW_HDMI_PHY_DWC_MHL_PHY = 0xc2,
> +	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2,
> +	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2,
> +	DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3,
> +	DW_HDMI_PHY_VENDOR_PHY = 0xfe,
> +};
> +
>  struct dw_hdmi_mpll_config {
>  	unsigned long mpixelclock;
>  	struct {

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2016-12-20 11:39     ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 11:39 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 01:33, Laurent Pinchart wrote:
> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> signal.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 ++++++++++++++++++++++++++++++++++++++--
>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>  2 files changed, 75 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index f4faa14213e5..ef4f2f96ed2c 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -113,6 +113,12 @@ struct dw_hdmi_i2c {
>  	bool			is_regaddr;
>  };
>  
> +struct dw_hdmi_phy_data {
> +	enum dw_hdmi_phy_type type;
> +	const char *name;
> +	bool has_svsret;
> +};
> +
>  struct dw_hdmi {
>  	struct drm_connector connector;
>  	struct drm_bridge bridge;
> @@ -134,7 +140,9 @@ struct dw_hdmi {
>  	u8 edid[HDMI_EDID_LEN];
>  	bool cable_plugin;
>  
> +	const struct dw_hdmi_phy_data *phy;
>  	bool phy_enabled;
> +
>  	struct drm_display_mode previous_mode;
>  
>  	struct i2c_adapter *ddc;
> @@ -1015,7 +1023,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon)
>  	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
>  	dw_hdmi_phy_gen2_pddq(hdmi, 0);
>  
> -	if (hdmi->dev_type == RK3288_HDMI)
> +	/* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */
> +	if (hdmi->phy->has_svsret)
>  		dw_hdmi_phy_enable_svsret(hdmi, 1);

I didn't review the original code but according to the docs the
svsret signal should be set before de-asserting phy reset.

>  
>  	/*Wait for PHY PLL lock */
> @@ -1840,6 +1849,54 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
> +	{
> +		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
> +		.name = "DWC HDMI TX PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
> +		.name = "DWC MHL PHY + HEAC PHY",
> +		.has_svsret = true,
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_MHL_PHY,
> +		.name = "DWC MHL PHY",
> +		.has_svsret = true,
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
> +		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
> +		.name = "DWC HDMI 3D TX PHY",
> +	}, {
> +		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
> +		.name = "DWC HDMI 2.0 TX PHY",
> +		.has_svsret = true,

Hmm, what I have here is that only MHL phys have svsret. Is this
case for your phy?

Best regards,
Jose Miguel Abreu
> +	}
> +};
> +
> +static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
> +{
> +	unsigned int i;
> +	u8 phy_type;
> +
> +	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
> +
> +	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
> +		if (dw_hdmi_phys[i].type == phy_type) {
> +			hdmi->phy = &dw_hdmi_phys[i];
> +			return 0;
> +		}
> +	}
> +
> +	if (phy_type == DW_HDMI_PHY_VENDOR_PHY)
> +		dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n");
> +	else
> +		dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n",
> +			phy_type);
> +
> +	return -ENODEV;
> +}
> +
>  static struct dw_hdmi *
>  __dw_hdmi_probe(struct platform_device *pdev,
>  		const struct dw_hdmi_plat_data *plat_data)
> @@ -1950,9 +2007,14 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		goto err_iahb;
>  	}
>  
> -	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n",
> +	ret = dw_hdmi_detect_phy(hdmi);
> +	if (ret < 0)
> +		goto err_iahb;
> +
> +	dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n",
>  		 hdmi->version >> 12, hdmi->version & 0xfff,
> -		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without");
> +		 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without",
> +		 hdmi->phy->name);
>  
>  	initialize_hdmi_ih_mutes(hdmi);
>  
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 3bb22a849830..b080a171a23f 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -27,6 +27,16 @@ enum dw_hdmi_devtype {
>  	RK3288_HDMI,
>  };
>  
> +enum dw_hdmi_phy_type {
> +	DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00,
> +	DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2,
> +	DW_HDMI_PHY_DWC_MHL_PHY = 0xc2,
> +	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2,
> +	DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2,
> +	DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3,
> +	DW_HDMI_PHY_VENDOR_PHY = 0xfe,
> +};
> +
>  struct dw_hdmi_mpll_config {
>  	unsigned long mpixelclock;
>  	struct {

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2016-12-20  1:33 ` [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling Laurent Pinchart
@ 2016-12-20 11:45   ` Russell King - ARM Linux
  2016-12-20 12:17       ` Jose Abreu
  2016-12-20 13:50       ` Laurent Pinchart
  0 siblings, 2 replies; 73+ messages in thread
From: Russell King - ARM Linux @ 2016-12-20 11:45 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Ulrich Hecht, Vladimir Zapolskiy, linux-renesas-soc

On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> Instead of spreading version-dependent PHY power handling code around,
> group it in two functions to power the PHY on and off and use them
> through the driver.
> 
> Powering off the PHY at the beginning of the setup phase is currently
> split in two locations for first and second generation PHYs, group all
> the operations in the dw_hdmi_phy_init() function.

This changes the behaviour of the driver.

> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> +{
> +	if (hdmi->phy->gen == 1) {
> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> +	} else {
> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +	}
> +}

> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
>  	if (!hdmi->phy_enabled)
>  		return;
>  
> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> -
> +	dw_hdmi_phy_power_off(hdmi);

This makes dw_hdmi_phy_disable() power down a gen2 phy.

The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
gen2 phy.  I've been carrying this change for a while, which I've had
to revert (and finally expunge), as it causes problems on iMX6:

@@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
        if (!hdmi->phy_enabled)
                return;

+       /* Actually set the phy into low power mode */
+       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
+
+       /* FIXME: We should wait for TX_READY to be deasserted */
+
+       dw_hdmi_phy_gen2_pddq(hdmi, 1);
+
+       /* This appears to have no effect on iMX6 */
        dw_hdmi_phy_enable_tmds(hdmi, 0);
        dw_hdmi_phy_enable_powerdown(hdmi, true);

So, I think your change here will cause problems for iMX6.

>From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
bouncing when the PHY is powered down.  I can't promise when I'll be
able to check for that again.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2016-12-20 11:45   ` Russell King - ARM Linux
@ 2016-12-20 12:17       ` Jose Abreu
  2016-12-20 13:50       ` Laurent Pinchart
  1 sibling, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 12:17 UTC (permalink / raw)
  To: Russell King - ARM Linux, Laurent Pinchart
  Cc: dri-devel, Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Ulrich Hecht, Vladimir Zapolskiy, linux-renesas-soc

Hi Russell,


On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>> Instead of spreading version-dependent PHY power handling code around,
>> group it in two functions to power the PHY on and off and use them
>> through the driver.
>>
>> Powering off the PHY at the beginning of the setup phase is currently
>> split in two locations for first and second generation PHYs, group all
>> the operations in the dw_hdmi_phy_init() function.
> This changes the behaviour of the driver.
>
>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>> +{
>> +	if (hdmi->phy->gen == 1) {
>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>> +	} else {
>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>> +	}
>> +}
>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
>>  	if (!hdmi->phy_enabled)
>>  		return;
>>  
>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>> -
>> +	dw_hdmi_phy_power_off(hdmi);
> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>
> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> gen2 phy.  I've been carrying this change for a while, which I've had
> to revert (and finally expunge), as it causes problems on iMX6:
>
> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
>         if (!hdmi->phy_enabled)
>                 return;
>
> +       /* Actually set the phy into low power mode */
> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +       /* FIXME: We should wait for TX_READY to be deasserted */
> +
> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +
> +       /* This appears to have no effect on iMX6 */
>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>
> So, I think your change here will cause problems for iMX6.
>
> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> bouncing when the PHY is powered down.  I can't promise when I'll be
> able to check for that again.
>

Indeed TX_READY must be low before asserting pddq. HPD and
RXSENSE should work in power down mode by enabling enhpdrxsense
bit in phy_conf0 BUT to enter power down you must disable
TX_PWRON, enhpdrxsense and enable PDDQ and PHY _RESET. Only after
doing this (and consequently entering power down mode) you can
enable again enhpdrxsense.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2016-12-20 12:17       ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 12:17 UTC (permalink / raw)
  To: Russell King - ARM Linux, Laurent Pinchart
  Cc: dri-devel, Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Ulrich Hecht, Vladimir Zapolskiy, linux-renesas-soc

Hi Russell,


On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>> Instead of spreading version-dependent PHY power handling code around,
>> group it in two functions to power the PHY on and off and use them
>> through the driver.
>>
>> Powering off the PHY at the beginning of the setup phase is currently
>> split in two locations for first and second generation PHYs, group all
>> the operations in the dw_hdmi_phy_init() function.
> This changes the behaviour of the driver.
>
>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>> +{
>> +	if (hdmi->phy->gen == 1) {
>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>> +	} else {
>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>> +	}
>> +}
>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
>>  	if (!hdmi->phy_enabled)
>>  		return;
>>  
>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>> -
>> +	dw_hdmi_phy_power_off(hdmi);
> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>
> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> gen2 phy.  I've been carrying this change for a while, which I've had
> to revert (and finally expunge), as it causes problems on iMX6:
>
> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
>         if (!hdmi->phy_enabled)
>                 return;
>
> +       /* Actually set the phy into low power mode */
> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +       /* FIXME: We should wait for TX_READY to be deasserted */
> +
> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +
> +       /* This appears to have no effect on iMX6 */
>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>
> So, I think your change here will cause problems for iMX6.
>
> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> bouncing when the PHY is powered down.  I can't promise when I'll be
> able to check for that again.
>

Indeed TX_READY must be low before asserting pddq. HPD and
RXSENSE should work in power down mode by enabling enhpdrxsense
bit in phy_conf0 BUT to enter power down you must disable
TX_PWRON, enhpdrxsense and enable PDDQ and PHY _RESET. Only after
doing this (and consequently entering power down mode) you can
enable again enhpdrxsense.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2016-12-20 11:39     ` Jose Abreu
  (?)
@ 2016-12-20 13:11     ` Laurent Pinchart
  2016-12-20 15:01         ` Jose Abreu
  -1 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20 13:11 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Jose,

On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
> On 20-12-2016 01:33, Laurent Pinchart wrote:
> > Detect the PHY type and use it to handle the PHY type-specific SVSRET
> > signal.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++++--
> >  include/drm/bridge/dw_hdmi.h     | 10 ++++++
> >  2 files changed, 75 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
> > 100644
> > --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/dw-hdmi.c

[snip]

> >  	struct i2c_adapter *ddc;
> > @@ -1015,7 +1023,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi,
> > int cscon)> 
> >  	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
> >  	dw_hdmi_phy_gen2_pddq(hdmi, 0);
> > 
> > -	if (hdmi->dev_type == RK3288_HDMI)
> > +	/* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */
> > +	if (hdmi->phy->has_svsret)
> >  		dw_hdmi_phy_enable_svsret(hdmi, 1);
> 
> I didn't review the original code but according to the docs the
> svsret signal should be set before de-asserting phy reset.

I don't have access to the documentation so I can't comment on that :-) What  
does the SVSRET signal control (and what does the name stand for) ?

By de-asserting PHY reset, do you mean

        /* PHY reset */
        hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
        hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);

? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT as 
0x00, which I believe leads to correct operation on Gen2 PHYs, but is 
incorrect on Gen1 PHYs that have an active low reset signal. Could you confirm 
that ? The DEASSERT and ASSERT macros should be renamed as they're obviously 
incorrect.

I can move the SVSRET assertion before PHY reset and test it on RK3288 and R-
Car H3.

> >  	/*Wait for PHY PLL lock */
> > 
> > @@ -1840,6 +1849,54 @@ static irqreturn_t dw_hdmi_irq(int irq, void
> > *dev_id)
> >  	return IRQ_HANDLED;
> >  }
> > 
> > +static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
> > +	{
> > +		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
> > +		.name = "DWC HDMI TX PHY",
> > +	}, {
> > +		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
> > +		.name = "DWC MHL PHY + HEAC PHY",
> > +		.has_svsret = true,
> > +	}, {
> > +		.type = DW_HDMI_PHY_DWC_MHL_PHY,
> > +		.name = "DWC MHL PHY",
> > +		.has_svsret = true,
> > +	}, {
> > +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
> > +		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
> > +	}, {
> > +		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
> > +		.name = "DWC HDMI 3D TX PHY",
> > +	}, {
> > +		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
> > +		.name = "DWC HDMI 2.0 TX PHY",
> > +		.has_svsret = true,
> 
> Hmm, what I have here is that only MHL phys have svsret. Is this
> case for your phy?

The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but doesn't 
document it any further. If I don't set SVSRET the HDMI output stays dead, so 
I assume I need to set it :-)

> > +	}
> > +};

[snip]

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2016-12-20 11:45   ` Russell King - ARM Linux
@ 2016-12-20 13:50       ` Laurent Pinchart
  2016-12-20 13:50       ` Laurent Pinchart
  1 sibling, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20 13:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam, Jose Abreu,
	Kieran Bingham, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Russell,

Thank you for the review.

On Tuesday 20 Dec 2016 11:45:53 Russell King - ARM Linux wrote:
> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> > Instead of spreading version-dependent PHY power handling code around,
> > group it in two functions to power the PHY on and off and use them
> > through the driver.
> > 
> > Powering off the PHY at the beginning of the setup phase is currently
> > split in two locations for first and second generation PHYs, group all
> > the operations in the dw_hdmi_phy_init() function.
> 
> This changes the behaviour of the driver.

It does, but slightly only (I'm of course very aware that slightly can easily 
be way too much :-)).

Let's analyse the differences, starting with PHY initialization in 
dw_hdmi_phy_init(). Before this patch, the function calls

        for (i = 0; i < 2; i++) {
                dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
                dw_hdmi_phy_sel_interface_control(hdmi, 0);
                dw_hdmi_phy_enable_tmds(hdmi, 0);
                dw_hdmi_phy_enable_powerdown(hdmi, true);

                /* Enable CSC */
                ret = hdmi_phy_configure(hdmi, cscon);
                if (ret)
                        return ret;
        }

and hdmi_phy_configure() starts with (I've removed lines that don't touch the 
hardware)

        /* Enable csc path */
        if (cscon)
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
        else
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;

        hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);

        /* gen2 tx power off */
        dw_hdmi_phy_gen2_txpwron(hdmi, 0);

        /* gen2 pddq */
        dw_hdmi_phy_gen2_pddq(hdmi, 1);

After the change, dw_hdmi_phy_init() calls

        for (i = 0; i < 2; i++) {
                dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
                dw_hdmi_phy_sel_interface_control(hdmi, 0);

                /* Enable CSC */
                ret = hdmi_phy_configure(hdmi, cscon);
                if (ret)
                        return ret;
        }

and hdmi_phy_configure() starts with

        /* Enable csc path */
        if (cscon)
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
        else
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;

        hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);

        dw_hdmi_phy_power_off(hdmi);

with dw_hdmi_phy_power_off() defined as

        if (hdmi->phy->gen == 1) {
                dw_hdmi_phy_enable_tmds(hdmi, 0);
                dw_hdmi_phy_enable_powerdown(hdmi, true);
        } else {
                dw_hdmi_phy_gen2_txpwron(hdmi, 0);
                dw_hdmi_phy_gen2_pddq(hdmi, 1);
        }

This patch thus changes the behaviour in two ways:

- Move the dw_hdmi_phy_enable_tmds() and dw_hdmi_phy_enable_powerdown() calls 
after CSC configuration (HDMI_MC_FLOWCTRL).

- Only touch the power bits related to the PHY generation.

I believe the first change to be harmless. Furthermore, given that the i.MX6 
and Rockchip SoCs use a Gen2 PHY, the TMDS and POWERDOWN bits should be no-
ops, so it should have no effect at all on those platforms.

I also believe the second change to be harmless as the TMDS and POWERDOWN bits 
should be no-ops on i.MX6 and Rockchip. I have tested this patch series on 
RK3288 and i.MX6Q and haven't noticed any regression.

The power on path should similarly be fine too, as the change

-       dw_hdmi_phy_enable_powerdown(hdmi, false);
-
-       /* toggle TMDS enable */
-       dw_hdmi_phy_enable_tmds(hdmi, 0);
-       dw_hdmi_phy_enable_tmds(hdmi, 1);
-
-       /* gen2 tx power on */
-       dw_hdmi_phy_gen2_txpwron(hdmi, 1);
-       dw_hdmi_phy_gen2_pddq(hdmi, 0);
+       dw_hdmi_phy_power_on(hdmi);

results in

static void dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
{
	if (hdmi->phy->gen == 1) {
		dw_hdmi_phy_enable_powerdown(hdmi, false);

		/* Toggle TMDS enable. */
		dw_hdmi_phy_enable_tmds(hdmi, 0);
		dw_hdmi_phy_enable_tmds(hdmi, 1);
	} else {
		dw_hdmi_phy_gen2_txpwron(hdmi, 1);
		dw_hdmi_phy_gen2_pddq(hdmi, 0);
	}
}

which splits the Gen1/Gen2 code but doesn't reorder anything.

The last change is in dw_hdmi_phy_disable(), see below.

> > +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> > +{
> > +	if (hdmi->phy->gen == 1) {
> > +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> > +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> > +	} else {
> > +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> > +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> > +	}
> > +}
> > 
> > @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> > *hdmi)
> >  	if (!hdmi->phy_enabled)
> >  		return;
> > 
> > -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> > -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> > -
> > +	dw_hdmi_phy_power_off(hdmi);
> 
> This makes dw_hdmi_phy_disable() power down a gen2 phy.

That's correct.

> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> gen2 phy.

To the best of my knowledge, based on the documentation I've been able to 
gather, the information I've received from different developers and the tests 
I've performed so far, this is the case.

> I've been carrying this change for a while, which I've had
> to revert (and finally expunge), as it causes problems on iMX6:
> 
> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
> if (!hdmi->phy_enabled)
>                 return;
> 
> +       /* Actually set the phy into low power mode */
> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +       /* FIXME: We should wait for TX_READY to be deasserted */
> +
> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +
> +       /* This appears to have no effect on iMX6 */
>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> 
> So, I think your change here will cause problems for iMX6.
> 
> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> bouncing when the PHY is powered down.  I can't promise when I'll be
> able to check for that again.

The current code is supposed to power the PHY down in dw_hdmi_phy_disable() 
but doesn't do so as it only handles Gen1 PHY signals there. Gen2 PHYs thus 
always stay enabled.

If this causes an issue on i.MX6 related to RXSENSE and HPD, I think it should 
be handled by explicitly skipping power down in dw_hdmi_phy_disable() instead 
of pretending we power the PHY down. This could be achieved through a quirk 
flag if the issue is specific to i.MX6, or based on the PHY model if the issue 
is present in all DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC PHYs. Jose, would you 
happen to be aware of RXSENSE/HPD issues when the PHY is disabled ?

If there's an easy way to reproduce the problem on i.MX6Q I can try locally. I 
unfortunately don't have access to i.MX6DL.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2016-12-20 13:50       ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2016-12-20 13:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Fabio Estevam, Jose Abreu, Laurent Pinchart, Kieran Bingham,
	dri-devel, linux-renesas-soc, Ulrich Hecht, Andy Yan,
	Vladimir Zapolskiy

Hi Russell,

Thank you for the review.

On Tuesday 20 Dec 2016 11:45:53 Russell King - ARM Linux wrote:
> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> > Instead of spreading version-dependent PHY power handling code around,
> > group it in two functions to power the PHY on and off and use them
> > through the driver.
> > 
> > Powering off the PHY at the beginning of the setup phase is currently
> > split in two locations for first and second generation PHYs, group all
> > the operations in the dw_hdmi_phy_init() function.
> 
> This changes the behaviour of the driver.

It does, but slightly only (I'm of course very aware that slightly can easily 
be way too much :-)).

Let's analyse the differences, starting with PHY initialization in 
dw_hdmi_phy_init(). Before this patch, the function calls

        for (i = 0; i < 2; i++) {
                dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
                dw_hdmi_phy_sel_interface_control(hdmi, 0);
                dw_hdmi_phy_enable_tmds(hdmi, 0);
                dw_hdmi_phy_enable_powerdown(hdmi, true);

                /* Enable CSC */
                ret = hdmi_phy_configure(hdmi, cscon);
                if (ret)
                        return ret;
        }

and hdmi_phy_configure() starts with (I've removed lines that don't touch the 
hardware)

        /* Enable csc path */
        if (cscon)
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
        else
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;

        hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);

        /* gen2 tx power off */
        dw_hdmi_phy_gen2_txpwron(hdmi, 0);

        /* gen2 pddq */
        dw_hdmi_phy_gen2_pddq(hdmi, 1);

After the change, dw_hdmi_phy_init() calls

        for (i = 0; i < 2; i++) {
                dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
                dw_hdmi_phy_sel_interface_control(hdmi, 0);

                /* Enable CSC */
                ret = hdmi_phy_configure(hdmi, cscon);
                if (ret)
                        return ret;
        }

and hdmi_phy_configure() starts with

        /* Enable csc path */
        if (cscon)
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
        else
                val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;

        hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);

        dw_hdmi_phy_power_off(hdmi);

with dw_hdmi_phy_power_off() defined as

        if (hdmi->phy->gen == 1) {
                dw_hdmi_phy_enable_tmds(hdmi, 0);
                dw_hdmi_phy_enable_powerdown(hdmi, true);
        } else {
                dw_hdmi_phy_gen2_txpwron(hdmi, 0);
                dw_hdmi_phy_gen2_pddq(hdmi, 1);
        }

This patch thus changes the behaviour in two ways:

- Move the dw_hdmi_phy_enable_tmds() and dw_hdmi_phy_enable_powerdown() calls 
after CSC configuration (HDMI_MC_FLOWCTRL).

- Only touch the power bits related to the PHY generation.

I believe the first change to be harmless. Furthermore, given that the i.MX6 
and Rockchip SoCs use a Gen2 PHY, the TMDS and POWERDOWN bits should be no-
ops, so it should have no effect at all on those platforms.

I also believe the second change to be harmless as the TMDS and POWERDOWN bits 
should be no-ops on i.MX6 and Rockchip. I have tested this patch series on 
RK3288 and i.MX6Q and haven't noticed any regression.

The power on path should similarly be fine too, as the change

-       dw_hdmi_phy_enable_powerdown(hdmi, false);
-
-       /* toggle TMDS enable */
-       dw_hdmi_phy_enable_tmds(hdmi, 0);
-       dw_hdmi_phy_enable_tmds(hdmi, 1);
-
-       /* gen2 tx power on */
-       dw_hdmi_phy_gen2_txpwron(hdmi, 1);
-       dw_hdmi_phy_gen2_pddq(hdmi, 0);
+       dw_hdmi_phy_power_on(hdmi);

results in

static void dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
{
	if (hdmi->phy->gen == 1) {
		dw_hdmi_phy_enable_powerdown(hdmi, false);

		/* Toggle TMDS enable. */
		dw_hdmi_phy_enable_tmds(hdmi, 0);
		dw_hdmi_phy_enable_tmds(hdmi, 1);
	} else {
		dw_hdmi_phy_gen2_txpwron(hdmi, 1);
		dw_hdmi_phy_gen2_pddq(hdmi, 0);
	}
}

which splits the Gen1/Gen2 code but doesn't reorder anything.

The last change is in dw_hdmi_phy_disable(), see below.

> > +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> > +{
> > +	if (hdmi->phy->gen == 1) {
> > +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> > +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> > +	} else {
> > +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> > +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> > +	}
> > +}
> > 
> > @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> > *hdmi)
> >  	if (!hdmi->phy_enabled)
> >  		return;
> > 
> > -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> > -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> > -
> > +	dw_hdmi_phy_power_off(hdmi);
> 
> This makes dw_hdmi_phy_disable() power down a gen2 phy.

That's correct.

> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> gen2 phy.

To the best of my knowledge, based on the documentation I've been able to 
gather, the information I've received from different developers and the tests 
I've performed so far, this is the case.

> I've been carrying this change for a while, which I've had
> to revert (and finally expunge), as it causes problems on iMX6:
> 
> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
> if (!hdmi->phy_enabled)
>                 return;
> 
> +       /* Actually set the phy into low power mode */
> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +       /* FIXME: We should wait for TX_READY to be deasserted */
> +
> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +
> +       /* This appears to have no effect on iMX6 */
>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> 
> So, I think your change here will cause problems for iMX6.
> 
> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> bouncing when the PHY is powered down.  I can't promise when I'll be
> able to check for that again.

The current code is supposed to power the PHY down in dw_hdmi_phy_disable() 
but doesn't do so as it only handles Gen1 PHY signals there. Gen2 PHYs thus 
always stay enabled.

If this causes an issue on i.MX6 related to RXSENSE and HPD, I think it should 
be handled by explicitly skipping power down in dw_hdmi_phy_disable() instead 
of pretending we power the PHY down. This could be achieved through a quirk 
flag if the issue is specific to i.MX6, or based on the PHY model if the issue 
is present in all DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC PHYs. Jose, would you 
happen to be aware of RXSENSE/HPD issues when the PHY is disabled ?

If there's an easy way to reproduce the problem on i.MX6Q I can try locally. I 
unfortunately don't have access to i.MX6DL.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2016-12-20 13:11     ` Laurent Pinchart
@ 2016-12-20 15:01         ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 15:01 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 13:11, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
>> On 20-12-2016 01:33, Laurent Pinchart wrote:
>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
>>> signal.
>>>
>>> Signed-off-by: Laurent Pinchart
>>> <laurent.pinchart+renesas@ideasonboard.com>
>>> ---
>>>
>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++++--
>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>>>  2 files changed, 75 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
>>> 100644
>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c

[snip]

> I don't have access to the documentation so I can't comment on that :-) What  
> does the SVSRET signal control (and what does the name stand for) ?

SVSRET stands for SVSRET :) (no idea what it means) Its a low
power mode of consumption.

>
> By de-asserting PHY reset, do you mean
>
>         /* PHY reset */
>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
>
> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT as 
> 0x00, which I believe leads to correct operation on Gen2 PHYs, but is 
> incorrect on Gen1 PHYs that have an active low reset signal. Could you confirm 
> that ? The DEASSERT and ASSERT macros should be renamed as they're obviously 
> incorrect.

Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
for a PHY-dependent time. Newer phys require PHYRSTZ to be
asserted (i.e. high) for, again, a PHY-dependent time.

This is the kind of things that made me suggest you to extract
all the phy configuration from dw-hdmi. I think that having a
bunch of if's because of all the phy's that we need to support
does not make much sense. The downside is, of course, having code
duplicated.

>
> I can move the SVSRET assertion before PHY reset and test it on RK3288 and R-
> Car H3.

Probably wont make much difference unless you have a way to
measure how much power the phy is consuming. But I think it is
the right thing to do according to docs.

[snip]

> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but doesn't 
> document it any further. If I don't set SVSRET the HDMI output stays dead, so 
> I assume I need to set it :-)
>

Hmm, ok. I still haven't figured out which phy you are using so
can't comment much further.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2016-12-20 15:01         ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2016-12-20 15:01 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 20-12-2016 13:11, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
>> On 20-12-2016 01:33, Laurent Pinchart wrote:
>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
>>> signal.
>>>
>>> Signed-off-by: Laurent Pinchart
>>> <laurent.pinchart+renesas@ideasonboard.com>
>>> ---
>>>
>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++++--
>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>>>  2 files changed, 75 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
>>> 100644
>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c

[snip]

> I don't have access to the documentation so I can't comment on that :-) What  
> does the SVSRET signal control (and what does the name stand for) ?

SVSRET stands for SVSRET :) (no idea what it means) Its a low
power mode of consumption.

>
> By de-asserting PHY reset, do you mean
>
>         /* PHY reset */
>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
>
> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT as 
> 0x00, which I believe leads to correct operation on Gen2 PHYs, but is 
> incorrect on Gen1 PHYs that have an active low reset signal. Could you confirm 
> that ? The DEASSERT and ASSERT macros should be renamed as they're obviously 
> incorrect.

Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
for a PHY-dependent time. Newer phys require PHYRSTZ to be
asserted (i.e. high) for, again, a PHY-dependent time.

This is the kind of things that made me suggest you to extract
all the phy configuration from dw-hdmi. I think that having a
bunch of if's because of all the phy's that we need to support
does not make much sense. The downside is, of course, having code
duplicated.

>
> I can move the SVSRET assertion before PHY reset and test it on RK3288 and R-
> Car H3.

Probably wont make much difference unless you have a way to
measure how much power the phy is consuming. But I think it is
the right thing to do according to docs.

[snip]

> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but doesn't 
> document it any further. If I don't set SVSRET the HDMI output stays dead, so 
> I assume I need to set it :-)
>

Hmm, ok. I still haven't figured out which phy you are using so
can't comment much further.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2016-12-20 15:01         ` Jose Abreu
@ 2017-01-05  0:15           ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05  0:15 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Jose,

On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
> On 20-12-2016 13:11, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
> >> On 20-12-2016 01:33, Laurent Pinchart wrote:
> >>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> >>> signal.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> <laurent.pinchart+renesas@ideasonboard.com>
> >>> ---
> >>> 
> >>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++--
> >>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
> >>>  2 files changed, 75 insertions(+), 3 deletions(-)
> >>> 
> >>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
> >>> 100644
> >>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> 
> [snip]
> 
> > I don't have access to the documentation so I can't comment on that :-)
> > What does the SVSRET signal control (and what does the name stand for) ?
>
> SVSRET stands for SVSRET :) (no idea what it means) Its a low
> power mode of consumption.
> 
> > By de-asserting PHY reset, do you mean
> > 
> >         /* PHY reset */
> >         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
> >         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
> > 
> > ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
> > as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
> > incorrect on Gen1 PHYs that have an active low reset signal. Could you
> > confirm that ? The DEASSERT and ASSERT macros should be renamed as
> > they're obviously incorrect.
> 
> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
> for a PHY-dependent time. Newer phys require PHYRSTZ to be
> asserted (i.e. high) for, again, a PHY-dependent time.

Thanks for the confirmation, I'll rename the macros.

> This is the kind of things that made me suggest you to extract
> all the phy configuration from dw-hdmi. I think that having a
> bunch of if's because of all the phy's that we need to support
> does not make much sense. The downside is, of course, having code
> duplicated.

I agree with you in principle, but I'd rather do that when I'll have devices 
to test the code on. The three devices (soon to be) supported in mainline by 
the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use Gen2 PHYs, so I 
can't test the Gen1 code paths meaningfully at the moment.

> > I can move the SVSRET assertion before PHY reset and test it on RK3288 and
> > R-Car H3.
> 
> Probably wont make much difference unless you have a way to
> measure how much power the phy is consuming. But I think it is
> the right thing to do according to docs.

The init sequence is currently

- Power the PHY off (TXPWRON = 0, PDDQ = 1)
- Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
- Configure the PHY through I2C
- Power the PHY on (TXPWRON = 1, PDDQ = 0)
- Set SVSRET
- Wait for PHY PLL lock

I've tried moving SVSRET right before the reset and everything still seems to 
work fine, so I'll submit a patch.

Is the rest of the sequence correct ? When should SVSRET be deasserted (the 
driver currently keeps it asserted at all times) ?

Speaking of reset, I believe support for HEAC PHYs is broken, given that the 
driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST register) but 
never deasserts it.

> [snip]
> 
> > The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
> > doesn't document it any further. If I don't set SVSRET the HDMI output
> > stays dead, so I assume I need to set it :-)
> 
> Hmm, ok. I still haven't figured out which phy you are using so
> can't comment much further.

I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY as 
tests show it's needed.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2017-01-05  0:15           ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05  0:15 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-renesas-soc, Ulrich Hecht, Russell King, Andy Yan,
	Vladimir Zapolskiy

Hi Jose,

On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
> On 20-12-2016 13:11, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
> >> On 20-12-2016 01:33, Laurent Pinchart wrote:
> >>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> >>> signal.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> <laurent.pinchart+renesas@ideasonboard.com>
> >>> ---
> >>> 
> >>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++--
> >>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
> >>>  2 files changed, 75 insertions(+), 3 deletions(-)
> >>> 
> >>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
> >>> 100644
> >>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> 
> [snip]
> 
> > I don't have access to the documentation so I can't comment on that :-)
> > What does the SVSRET signal control (and what does the name stand for) ?
>
> SVSRET stands for SVSRET :) (no idea what it means) Its a low
> power mode of consumption.
> 
> > By de-asserting PHY reset, do you mean
> > 
> >         /* PHY reset */
> >         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
> >         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
> > 
> > ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
> > as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
> > incorrect on Gen1 PHYs that have an active low reset signal. Could you
> > confirm that ? The DEASSERT and ASSERT macros should be renamed as
> > they're obviously incorrect.
> 
> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
> for a PHY-dependent time. Newer phys require PHYRSTZ to be
> asserted (i.e. high) for, again, a PHY-dependent time.

Thanks for the confirmation, I'll rename the macros.

> This is the kind of things that made me suggest you to extract
> all the phy configuration from dw-hdmi. I think that having a
> bunch of if's because of all the phy's that we need to support
> does not make much sense. The downside is, of course, having code
> duplicated.

I agree with you in principle, but I'd rather do that when I'll have devices 
to test the code on. The three devices (soon to be) supported in mainline by 
the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use Gen2 PHYs, so I 
can't test the Gen1 code paths meaningfully at the moment.

> > I can move the SVSRET assertion before PHY reset and test it on RK3288 and
> > R-Car H3.
> 
> Probably wont make much difference unless you have a way to
> measure how much power the phy is consuming. But I think it is
> the right thing to do according to docs.

The init sequence is currently

- Power the PHY off (TXPWRON = 0, PDDQ = 1)
- Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
- Configure the PHY through I2C
- Power the PHY on (TXPWRON = 1, PDDQ = 0)
- Set SVSRET
- Wait for PHY PLL lock

I've tried moving SVSRET right before the reset and everything still seems to 
work fine, so I'll submit a patch.

Is the rest of the sequence correct ? When should SVSRET be deasserted (the 
driver currently keeps it asserted at all times) ?

Speaking of reset, I believe support for HEAC PHYs is broken, given that the 
driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST register) but 
never deasserts it.

> [snip]
> 
> > The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
> > doesn't document it any further. If I don't set SVSRET the HDMI output
> > stays dead, so I assume I need to set it :-)
> 
> Hmm, ok. I still haven't figured out which phy you are using so
> can't comment much further.

I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY as 
tests show it's needed.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2017-01-05  0:15           ` Laurent Pinchart
@ 2017-01-05 10:33             ` Jose Abreu
  -1 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 10:33 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 05-01-2017 00:15, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
>> On 20-12-2016 13:11, Laurent Pinchart wrote:
>>> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
>>>> On 20-12-2016 01:33, Laurent Pinchart wrote:
>>>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
>>>>> signal.
>>>>>
>>>>> Signed-off-by: Laurent Pinchart
>>>>> <laurent.pinchart+renesas@ideasonboard.com>
>>>>> ---
>>>>>
>>>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++--
>>>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>>>>>  2 files changed, 75 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
>>>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
>>>>> 100644
>>>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
>>>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
>> [snip]
>>
>>> I don't have access to the documentation so I can't comment on that :-)
>>> What does the SVSRET signal control (and what does the name stand for) ?
>> SVSRET stands for SVSRET :) (no idea what it means) Its a low
>> power mode of consumption.
>>
>>> By de-asserting PHY reset, do you mean
>>>
>>>         /* PHY reset */
>>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
>>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
>>>
>>> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
>>> as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
>>> incorrect on Gen1 PHYs that have an active low reset signal. Could you
>>> confirm that ? The DEASSERT and ASSERT macros should be renamed as
>>> they're obviously incorrect.
>> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
>> for a PHY-dependent time. Newer phys require PHYRSTZ to be
>> asserted (i.e. high) for, again, a PHY-dependent time.
> Thanks for the confirmation, I'll rename the macros.
>
>> This is the kind of things that made me suggest you to extract
>> all the phy configuration from dw-hdmi. I think that having a
>> bunch of if's because of all the phy's that we need to support
>> does not make much sense. The downside is, of course, having code
>> duplicated.
> I agree with you in principle, but I'd rather do that when I'll have devices 
> to test the code on. The three devices (soon to be) supported in mainline by 
> the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use Gen2 PHYs, so I 
> can't test the Gen1 code paths meaningfully at the moment.
>
>>> I can move the SVSRET assertion before PHY reset and test it on RK3288 and
>>> R-Car H3.
>> Probably wont make much difference unless you have a way to
>> measure how much power the phy is consuming. But I think it is
>> the right thing to do according to docs.
> The init sequence is currently
>
> - Power the PHY off (TXPWRON = 0, PDDQ = 1)
> - Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
> - Configure the PHY through I2C
> - Power the PHY on (TXPWRON = 1, PDDQ = 0)
> - Set SVSRET
> - Wait for PHY PLL lock

What I have here for the most recent phy we tested is this:
    - Board specific configuration (should not be needed by you)
    - Set MC_PHY_RST high
    - Set TXPWRON = 0
    - Set PDDQ = 1
    - Set SVSRET = 0
    - Board specific impendance calibration reset (should not be
needed by you)
    - Set SVSRET = 1
    - Set MC_PHY_RST low
    - Configure phy through I2C
    - Set PDDQ = 0
    - Set TXPWRON = 1,
    - Wait for phy pll lock

>
> I've tried moving SVSRET right before the reset and everything still seems to 
> work fine, so I'll submit a patch.
>
> Is the rest of the sequence correct ? When should SVSRET be deasserted (the 
> driver currently keeps it asserted at all times) ?

It should not be deasserted.

>
> Speaking of reset, I believe support for HEAC PHYs is broken, given that the 
> driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST register) but 
> never deasserts it.

Hmm, probably, but not sure. I never tested this in older phys.

>
>> [snip]
>>
>>> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
>>> doesn't document it any further. If I don't set SVSRET the HDMI output
>>> stays dead, so I assume I need to set it :-)
>> Hmm, ok. I still haven't figured out which phy you are using so
>> can't comment much further.
> I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY as 
> tests show it's needed.
>

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2017-01-05 10:33             ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 10:33 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 05-01-2017 00:15, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
>> On 20-12-2016 13:11, Laurent Pinchart wrote:
>>> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
>>>> On 20-12-2016 01:33, Laurent Pinchart wrote:
>>>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
>>>>> signal.
>>>>>
>>>>> Signed-off-by: Laurent Pinchart
>>>>> <laurent.pinchart+renesas@ideasonboard.com>
>>>>> ---
>>>>>
>>>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++++--
>>>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
>>>>>  2 files changed, 75 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
>>>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
>>>>> 100644
>>>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
>>>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
>> [snip]
>>
>>> I don't have access to the documentation so I can't comment on that :-)
>>> What does the SVSRET signal control (and what does the name stand for) ?
>> SVSRET stands for SVSRET :) (no idea what it means) Its a low
>> power mode of consumption.
>>
>>> By de-asserting PHY reset, do you mean
>>>
>>>         /* PHY reset */
>>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
>>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
>>>
>>> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
>>> as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
>>> incorrect on Gen1 PHYs that have an active low reset signal. Could you
>>> confirm that ? The DEASSERT and ASSERT macros should be renamed as
>>> they're obviously incorrect.
>> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
>> for a PHY-dependent time. Newer phys require PHYRSTZ to be
>> asserted (i.e. high) for, again, a PHY-dependent time.
> Thanks for the confirmation, I'll rename the macros.
>
>> This is the kind of things that made me suggest you to extract
>> all the phy configuration from dw-hdmi. I think that having a
>> bunch of if's because of all the phy's that we need to support
>> does not make much sense. The downside is, of course, having code
>> duplicated.
> I agree with you in principle, but I'd rather do that when I'll have devices 
> to test the code on. The three devices (soon to be) supported in mainline by 
> the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use Gen2 PHYs, so I 
> can't test the Gen1 code paths meaningfully at the moment.
>
>>> I can move the SVSRET assertion before PHY reset and test it on RK3288 and
>>> R-Car H3.
>> Probably wont make much difference unless you have a way to
>> measure how much power the phy is consuming. But I think it is
>> the right thing to do according to docs.
> The init sequence is currently
>
> - Power the PHY off (TXPWRON = 0, PDDQ = 1)
> - Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
> - Configure the PHY through I2C
> - Power the PHY on (TXPWRON = 1, PDDQ = 0)
> - Set SVSRET
> - Wait for PHY PLL lock

What I have here for the most recent phy we tested is this:
    - Board specific configuration (should not be needed by you)
    - Set MC_PHY_RST high
    - Set TXPWRON = 0
    - Set PDDQ = 1
    - Set SVSRET = 0
    - Board specific impendance calibration reset (should not be
needed by you)
    - Set SVSRET = 1
    - Set MC_PHY_RST low
    - Configure phy through I2C
    - Set PDDQ = 0
    - Set TXPWRON = 1,
    - Wait for phy pll lock

>
> I've tried moving SVSRET right before the reset and everything still seems to 
> work fine, so I'll submit a patch.
>
> Is the rest of the sequence correct ? When should SVSRET be deasserted (the 
> driver currently keeps it asserted at all times) ?

It should not be deasserted.

>
> Speaking of reset, I believe support for HEAC PHYs is broken, given that the 
> driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST register) but 
> never deasserts it.

Hmm, probably, but not sure. I never tested this in older phys.

>
>> [snip]
>>
>>> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
>>> doesn't document it any further. If I don't set SVSRET the HDMI output
>>> stays dead, so I assume I need to set it :-)
>> Hmm, ok. I still haven't figured out which phy you are using so
>> can't comment much further.
> I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY as 
> tests show it's needed.
>

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2017-01-05 10:33             ` Jose Abreu
@ 2017-01-05 11:44               ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05 11:44 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Jose,

On Thursday 05 Jan 2017 10:33:55 Jose Abreu wrote:
> On 05-01-2017 00:15, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
> >> On 20-12-2016 13:11, Laurent Pinchart wrote:
> >>> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
> >>>> On 20-12-2016 01:33, Laurent Pinchart wrote:
> >>>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> >>>>> signal.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> ---
> >>>>> 
> >>>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++--
> >>>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
> >>>>>  2 files changed, 75 insertions(+), 3 deletions(-)
> >>>>> 
> >>>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
> >>>>> 100644
> >>>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> >> 
> >> [snip]
> >> 
> >>> I don't have access to the documentation so I can't comment on that :-)
> >>> What does the SVSRET signal control (and what does the name stand for) ?
> >> 
> >> SVSRET stands for SVSRET :) (no idea what it means) Its a low
> >> power mode of consumption.
> >> 
> >>> By de-asserting PHY reset, do you mean
> >>> 
> >>>         /* PHY reset */
> >>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
> >>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
> >>> 
> >>> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
> >>> as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
> >>> incorrect on Gen1 PHYs that have an active low reset signal. Could you
> >>> confirm that ? The DEASSERT and ASSERT macros should be renamed as
> >>> they're obviously incorrect.
> >> 
> >> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
> >> for a PHY-dependent time. Newer phys require PHYRSTZ to be
> >> asserted (i.e. high) for, again, a PHY-dependent time.
> > 
> > Thanks for the confirmation, I'll rename the macros.
> > 
> >> This is the kind of things that made me suggest you to extract
> >> all the phy configuration from dw-hdmi. I think that having a
> >> bunch of if's because of all the phy's that we need to support
> >> does not make much sense. The downside is, of course, having code
> >> duplicated.
> > 
> > I agree with you in principle, but I'd rather do that when I'll have
> > devices to test the code on. The three devices (soon to be) supported in
> > mainline by the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use
> > Gen2 PHYs, so I can't test the Gen1 code paths meaningfully at the
> > moment.
> > 
> >>> I can move the SVSRET assertion before PHY reset and test it on RK3288
> >>> and R-Car H3.
> >> 
> >> Probably wont make much difference unless you have a way to
> >> measure how much power the phy is consuming. But I think it is
> >> the right thing to do according to docs.
> > 
> > The init sequence is currently
> > 
> > - Power the PHY off (TXPWRON = 0, PDDQ = 1)
> > - Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
> > - Configure the PHY through I2C
> > - Power the PHY on (TXPWRON = 1, PDDQ = 0)
> > - Set SVSRET
> > - Wait for PHY PLL lock
> 
> What I have here for the most recent phy we tested is this:
>     - Board specific configuration (should not be needed by you)
>     - Set MC_PHY_RST high
>     - Set TXPWRON = 0
>     - Set PDDQ = 1
>     - Set SVSRET = 0
>     - Board specific impendance calibration reset (should not be
> needed by you)
>     - Set SVSRET = 1
>     - Set MC_PHY_RST low
>     - Configure phy through I2C
>     - Set PDDQ = 0
>     - Set TXPWRON = 1,
>     - Wait for phy pll lock

Thank you, I'll test that.

> > I've tried moving SVSRET right before the reset and everything still seems
> > to work fine, so I'll submit a patch.
> > 
> > Is the rest of the sequence correct ? When should SVSRET be deasserted
> > (the driver currently keeps it asserted at all times) ?
> 
> It should not be deasserted.

At all ? Even when powering the PHY down ?

> > Speaking of reset, I believe support for HEAC PHYs is broken, given that
> > the driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST
> > register) but never deasserts it.
> 
> Hmm, probably, but not sure. I never tested this in older phys.

One more item we'll fix when we'll be able to test it :-)

> >> [snip]
> >> 
> >>> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
> >>> doesn't document it any further. If I don't set SVSRET the HDMI output
> >>> stays dead, so I assume I need to set it :-)
> >> 
> >> Hmm, ok. I still haven't figured out which phy you are using so
> >> can't comment much further.
> > 
> > I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY
> > as tests show it's needed.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2017-01-05 11:44               ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05 11:44 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-renesas-soc, Ulrich Hecht, Russell King, Andy Yan,
	Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 10:33:55 Jose Abreu wrote:
> On 05-01-2017 00:15, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 15:01:52 Jose Abreu wrote:
> >> On 20-12-2016 13:11, Laurent Pinchart wrote:
> >>> On Tuesday 20 Dec 2016 11:39:21 Jose Abreu wrote:
> >>>> On 20-12-2016 01:33, Laurent Pinchart wrote:
> >>>>> Detect the PHY type and use it to handle the PHY type-specific SVSRET
> >>>>> signal.
> >>>>> 
> >>>>> Signed-off-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> >>>>> ---
> >>>>> 
> >>>>>  drivers/gpu/drm/bridge/dw-hdmi.c | 68 +++++++++++++++++++++++++++++--
> >>>>>  include/drm/bridge/dw_hdmi.h     | 10 ++++++
> >>>>>  2 files changed, 75 insertions(+), 3 deletions(-)
> >>>>> 
> >>>>> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>>>> b/drivers/gpu/drm/bridge/dw-hdmi.c index f4faa14213e5..ef4f2f96ed2c
> >>>>> 100644
> >>>>> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> >>>>> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> >> 
> >> [snip]
> >> 
> >>> I don't have access to the documentation so I can't comment on that :-)
> >>> What does the SVSRET signal control (and what does the name stand for) ?
> >> 
> >> SVSRET stands for SVSRET :) (no idea what it means) Its a low
> >> power mode of consumption.
> >> 
> >>> By de-asserting PHY reset, do you mean
> >>> 
> >>>         /* PHY reset */
> >>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
> >>>         hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
> >>> 
> >>> ? HDMI_MC_PHYRSTZ_DEASSERT is defined as 0x01 and HDMI_MC_PHYRSTZ_ASSERT
> >>> as 0x00, which I believe leads to correct operation on Gen2 PHYs, but is
> >>> incorrect on Gen1 PHYs that have an active low reset signal. Could you
> >>> confirm that ? The DEASSERT and ASSERT macros should be renamed as
> >>> they're obviously incorrect.
> >> 
> >> Correct. Older phys require PHYRSTZ to be deasserted (i.e. low)
> >> for a PHY-dependent time. Newer phys require PHYRSTZ to be
> >> asserted (i.e. high) for, again, a PHY-dependent time.
> > 
> > Thanks for the confirmation, I'll rename the macros.
> > 
> >> This is the kind of things that made me suggest you to extract
> >> all the phy configuration from dw-hdmi. I think that having a
> >> bunch of if's because of all the phy's that we need to support
> >> does not make much sense. The downside is, of course, having code
> >> duplicated.
> > 
> > I agree with you in principle, but I'd rather do that when I'll have
> > devices to test the code on. The three devices (soon to be) supported in
> > mainline by the dw-hdmi drivers, i.MX6, RK3288 and R-Car Gen3, all use
> > Gen2 PHYs, so I can't test the Gen1 code paths meaningfully at the
> > moment.
> > 
> >>> I can move the SVSRET assertion before PHY reset and test it on RK3288
> >>> and R-Car H3.
> >> 
> >> Probably wont make much difference unless you have a way to
> >> measure how much power the phy is consuming. But I think it is
> >> the right thing to do according to docs.
> > 
> > The init sequence is currently
> > 
> > - Power the PHY off (TXPWRON = 0, PDDQ = 1)
> > - Reset the PHY (through HDMI_MC_PHYRSTZ and HDMI_MC_HEACPHY_RST)
> > - Configure the PHY through I2C
> > - Power the PHY on (TXPWRON = 1, PDDQ = 0)
> > - Set SVSRET
> > - Wait for PHY PLL lock
> 
> What I have here for the most recent phy we tested is this:
>     - Board specific configuration (should not be needed by you)
>     - Set MC_PHY_RST high
>     - Set TXPWRON = 0
>     - Set PDDQ = 1
>     - Set SVSRET = 0
>     - Board specific impendance calibration reset (should not be
> needed by you)
>     - Set SVSRET = 1
>     - Set MC_PHY_RST low
>     - Configure phy through I2C
>     - Set PDDQ = 0
>     - Set TXPWRON = 1,
>     - Wait for phy pll lock

Thank you, I'll test that.

> > I've tried moving SVSRET right before the reset and everything still seems
> > to work fine, so I'll submit a patch.
> > 
> > Is the rest of the sequence correct ? When should SVSRET be deasserted
> > (the driver currently keeps it asserted at all times) ?
> 
> It should not be deasserted.

At all ? Even when powering the PHY down ?

> > Speaking of reset, I believe support for HEAC PHYs is broken, given that
> > the driver asserts the reset signal (through the HDMI_MC_HEACPHY_RST
> > register) but never deasserts it.
> 
> Hmm, probably, but not sure. I never tested this in older phys.

One more item we'll fix when we'll be able to test it :-)

> >> [snip]
> >> 
> >>> The SoC datasheet mentions the SVSRET bit in the HDMI TX registers but
> >>> doesn't document it any further. If I don't set SVSRET the HDMI output
> >>> stays dead, so I assume I need to set it :-)
> >> 
> >> Hmm, ok. I still haven't figured out which phy you are using so
> >> can't comment much further.
> > 
> > I'll then leave has_svsret set to true for DW_HDMI_PHY_DWC_HDMI20_TX_PHY
> > as tests show it's needed.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2016-12-20 12:17       ` Jose Abreu
  (?)
@ 2017-01-05 12:29       ` Laurent Pinchart
  2017-01-05 15:06           ` Jose Abreu
  -1 siblings, 1 reply; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05 12:29 UTC (permalink / raw)
  To: dri-devel
  Cc: Jose Abreu, Russell King - ARM Linux, Laurent Pinchart,
	Fabio Estevam, Kieran Bingham, linux-renesas-soc, Ulrich Hecht,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> > On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >> Instead of spreading version-dependent PHY power handling code around,
> >> group it in two functions to power the PHY on and off and use them
> >> through the driver.
> >> 
> >> Powering off the PHY at the beginning of the setup phase is currently
> >> split in two locations for first and second generation PHYs, group all
> >> the operations in the dw_hdmi_phy_init() function.
> > 
> > This changes the behaviour of the driver.
> > 
> >> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >> +{
> >> +	if (hdmi->phy->gen == 1) {
> >> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >> +	} else {
> >> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >> +	}
> >> +}
> >> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >> *hdmi)
> >> 
> >>  	if (!hdmi->phy_enabled)
> >>  	
> >>  		return;
> >> 
> >> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >> -
> >> +	dw_hdmi_phy_power_off(hdmi);
> > 
> > This makes dw_hdmi_phy_disable() power down a gen2 phy.
> > 
> > The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> > gen2 phy.  I've been carrying this change for a while, which I've had
> > to revert (and finally expunge), as it causes problems on iMX6:
> > 
> > @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> > *hdmi)> 
> >         if (!hdmi->phy_enabled)
> >         
> >                 return;
> > 
> > +       /* Actually set the phy into low power mode */
> > +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> > +
> > +       /* FIXME: We should wait for TX_READY to be deasserted */
> > +
> > +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> > +
> > +       /* This appears to have no effect on iMX6 */
> > 
> >         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >         dw_hdmi_phy_enable_powerdown(hdmi, true);
> > 
> > So, I think your change here will cause problems for iMX6.
> > 
> > From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> > bouncing when the PHY is powered down.  I can't promise when I'll be
> > able to check for that again.
> 
> Indeed TX_READY must be low before asserting pddq.

The TX_READY signal is documented in the i.MX6 datasheet as being a PHY output 
signal, but there seems to be no HDMI TX register from which its state can be 
read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register through I2C ? How 
long is the PHY expected to take to set TX_READY to 0 ?

> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
> consequently entering power down mode) you can enable again enhpdrxsense.

Thanks, I'll give it a try.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
  2017-01-05 11:44               ` Laurent Pinchart
@ 2017-01-05 14:27                 ` Jose Abreu
  -1 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 14:27 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 05-01-2017 11:44, Laurent Pinchart wrote:

[snip]

>>> I've tried moving SVSRET right before the reset and everything still seems
>>> to work fine, so I'll submit a patch.
>>>
>>> Is the rest of the sequence correct ? When should SVSRET be deasserted
>>> (the driver currently keeps it asserted at all times) ?
>> It should not be deasserted.
> At all ? Even when powering the PHY down ?

The source code I have here does not deassert the signal, even
when powering down BUT I am checking the docs and this signal can
optionally go low after the phy goes to power down mode (i.e.
after all power down sequence is correctly done, this includes
waiting for TX_READY to go low as Russell King previously said),
though its not mandatory. I think I miss explained how this mode
works: When deasserted the phy goes to low power mode, thats why
you need to assert it in power up. We can try to add this in
power down sequence but its very important to check the status of
TX_READY before changing SVSRET.

Best regards,
Jose Miguel Abreu

[snip]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime
@ 2017-01-05 14:27                 ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 14:27 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Russell King, Ulrich Hecht, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 05-01-2017 11:44, Laurent Pinchart wrote:

[snip]

>>> I've tried moving SVSRET right before the reset and everything still seems
>>> to work fine, so I'll submit a patch.
>>>
>>> Is the rest of the sequence correct ? When should SVSRET be deasserted
>>> (the driver currently keeps it asserted at all times) ?
>> It should not be deasserted.
> At all ? Even when powering the PHY down ?

The source code I have here does not deassert the signal, even
when powering down BUT I am checking the docs and this signal can
optionally go low after the phy goes to power down mode (i.e.
after all power down sequence is correctly done, this includes
waiting for TX_READY to go low as Russell King previously said),
though its not mandatory. I think I miss explained how this mode
works: When deasserted the phy goes to low power mode, thats why
you need to assert it in power up. We can try to add this in
power down sequence but its very important to check the status of
TX_READY before changing SVSRET.

Best regards,
Jose Miguel Abreu

[snip]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-05 12:29       ` Laurent Pinchart
@ 2017-01-05 15:06           ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 15:06 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


On 05-01-2017 12:29, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>>>> Instead of spreading version-dependent PHY power handling code around,
>>>> group it in two functions to power the PHY on and off and use them
>>>> through the driver.
>>>>
>>>> Powering off the PHY at the beginning of the setup phase is currently
>>>> split in two locations for first and second generation PHYs, group all
>>>> the operations in the dw_hdmi_phy_init() function.
>>> This changes the behaviour of the driver.
>>>
>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>>>> +{
>>>> +	if (hdmi->phy->gen == 1) {
>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>> +	} else {
>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>> +	}
>>>> +}
>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>> *hdmi)
>>>>
>>>>  	if (!hdmi->phy_enabled)
>>>>  	
>>>>  		return;
>>>>
>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>> -
>>>> +	dw_hdmi_phy_power_off(hdmi);
>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>>>
>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
>>> gen2 phy.  I've been carrying this change for a while, which I've had
>>> to revert (and finally expunge), as it causes problems on iMX6:
>>>
>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>> *hdmi)> 
>>>         if (!hdmi->phy_enabled)
>>>         
>>>                 return;
>>>
>>> +       /* Actually set the phy into low power mode */
>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>> +
>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
>>> +
>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>> +
>>> +       /* This appears to have no effect on iMX6 */
>>>
>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>
>>> So, I think your change here will cause problems for iMX6.
>>>
>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
>>> bouncing when the PHY is powered down.  I can't promise when I'll be
>>> able to check for that again.
>> Indeed TX_READY must be low before asserting pddq.
> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY output 
> signal, but there seems to be no HDMI TX register from which its state can be 
> read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register through I2C ? How 
> long is the PHY expected to take to set TX_READY to 0 ?

TX_READY can be read from register 0x1A of phy, BIT(2) (through
I2C). Not sure if same offset for all phys though.

Best regards,
Jose Miguel Abreu

>
>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
>> consequently entering power down mode) you can enable again enhpdrxsense.
> Thanks, I'll give it a try.
>

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-01-05 15:06           ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-05 15:06 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


On 05-01-2017 12:29, Laurent Pinchart wrote:
> Hi Jose,
>
> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>>>> Instead of spreading version-dependent PHY power handling code around,
>>>> group it in two functions to power the PHY on and off and use them
>>>> through the driver.
>>>>
>>>> Powering off the PHY at the beginning of the setup phase is currently
>>>> split in two locations for first and second generation PHYs, group all
>>>> the operations in the dw_hdmi_phy_init() function.
>>> This changes the behaviour of the driver.
>>>
>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>>>> +{
>>>> +	if (hdmi->phy->gen == 1) {
>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>> +	} else {
>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>> +	}
>>>> +}
>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>> *hdmi)
>>>>
>>>>  	if (!hdmi->phy_enabled)
>>>>  	
>>>>  		return;
>>>>
>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>> -
>>>> +	dw_hdmi_phy_power_off(hdmi);
>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>>>
>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
>>> gen2 phy.  I've been carrying this change for a while, which I've had
>>> to revert (and finally expunge), as it causes problems on iMX6:
>>>
>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>> *hdmi)> 
>>>         if (!hdmi->phy_enabled)
>>>         
>>>                 return;
>>>
>>> +       /* Actually set the phy into low power mode */
>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>> +
>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
>>> +
>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>> +
>>> +       /* This appears to have no effect on iMX6 */
>>>
>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>
>>> So, I think your change here will cause problems for iMX6.
>>>
>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
>>> bouncing when the PHY is powered down.  I can't promise when I'll be
>>> able to check for that again.
>> Indeed TX_READY must be low before asserting pddq.
> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY output 
> signal, but there seems to be no HDMI TX register from which its state can be 
> read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register through I2C ? How 
> long is the PHY expected to take to set TX_READY to 0 ?

TX_READY can be read from register 0x1A of phy, BIT(2) (through
I2C). Not sure if same offset for all phys though.

Best regards,
Jose Miguel Abreu

>
>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
>> consequently entering power down mode) you can enable again enhpdrxsense.
> Thanks, I'll give it a try.
>

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-05 15:06           ` Jose Abreu
@ 2017-01-05 15:33             ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05 15:33 UTC (permalink / raw)
  To: Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> On 05-01-2017 12:29, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>> Instead of spreading version-dependent PHY power handling code around,
> >>>> group it in two functions to power the PHY on and off and use them
> >>>> through the driver.
> >>>> 
> >>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>> split in two locations for first and second generation PHYs, group all
> >>>> the operations in the dw_hdmi_phy_init() function.
> >>> 
> >>> This changes the behaviour of the driver.
> >>> 
> >>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>> +{
> >>>> +	if (hdmi->phy->gen == 1) {
> >>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> +	} else {
> >>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +	}
> >>>> +}
> >>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>> 
> >>>>  	if (!hdmi->phy_enabled)
> >>>>  	
> >>>>  		return;
> >>>> 
> >>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> -
> >>>> +	dw_hdmi_phy_power_off(hdmi);
> >>> 
> >>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>> 
> >>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>> to revert (and finally expunge), as it causes problems on iMX6:
> >>> 
> >>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>> *hdmi)>
> >>> 
> >>>         if (!hdmi->phy_enabled)
> >>>         
> >>>                 return;
> >>> 
> >>> +       /* Actually set the phy into low power mode */
> >>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>> +
> >>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>> +
> >>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>> +
> >>> +       /* This appears to have no effect on iMX6 */
> >>> 
> >>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>> 
> >>> So, I think your change here will cause problems for iMX6.
> >>> 
> >>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>> able to check for that again.
> >> 
> >> Indeed TX_READY must be low before asserting pddq.
> > 
> > The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> > output signal, but there seems to be no HDMI TX register from which its
> > state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> > through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
> 
> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> I2C).

That's what I thought, I'll poll that then. Do you have any idea how long it's 
supposed to take, to set an appropriate timeout ?

> Not sure if same offset for all phys though.

Most probably not, it would be too easy :-) I'll investigate (which will 
likely include lots of guesswork). If you can find any information about that 
(and especially about the MHL and HDMI 2.0 PHYs) that would be very 
appreciated, as I don't have access to any documentation that mentions a 
TX_READY bit for those.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-01-05 15:33             ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-05 15:33 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Russell King - ARM Linux,
	dri-devel, Kieran Bingham, linux-renesas-soc, Ulrich Hecht,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> On 05-01-2017 12:29, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>> Instead of spreading version-dependent PHY power handling code around,
> >>>> group it in two functions to power the PHY on and off and use them
> >>>> through the driver.
> >>>> 
> >>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>> split in two locations for first and second generation PHYs, group all
> >>>> the operations in the dw_hdmi_phy_init() function.
> >>> 
> >>> This changes the behaviour of the driver.
> >>> 
> >>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>> +{
> >>>> +	if (hdmi->phy->gen == 1) {
> >>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> +	} else {
> >>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +	}
> >>>> +}
> >>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>> 
> >>>>  	if (!hdmi->phy_enabled)
> >>>>  	
> >>>>  		return;
> >>>> 
> >>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> -
> >>>> +	dw_hdmi_phy_power_off(hdmi);
> >>> 
> >>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>> 
> >>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>> to revert (and finally expunge), as it causes problems on iMX6:
> >>> 
> >>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>> *hdmi)>
> >>> 
> >>>         if (!hdmi->phy_enabled)
> >>>         
> >>>                 return;
> >>> 
> >>> +       /* Actually set the phy into low power mode */
> >>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>> +
> >>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>> +
> >>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>> +
> >>> +       /* This appears to have no effect on iMX6 */
> >>> 
> >>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>> 
> >>> So, I think your change here will cause problems for iMX6.
> >>> 
> >>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>> able to check for that again.
> >> 
> >> Indeed TX_READY must be low before asserting pddq.
> > 
> > The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> > output signal, but there seems to be no HDMI TX register from which its
> > state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> > through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
> 
> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> I2C).

That's what I thought, I'll poll that then. Do you have any idea how long it's 
supposed to take, to set an appropriate timeout ?

> Not sure if same offset for all phys though.

Most probably not, it would be too easy :-) I'll investigate (which will 
likely include lots of guesswork). If you can find any information about that 
(and especially about the MHL and HDMI 2.0 PHYs) that would be very 
appreciated, as I don't have access to any documentation that mentions a 
TX_READY bit for those.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-05 15:33             ` Laurent Pinchart
@ 2017-01-06  1:48               ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-06  1:48 UTC (permalink / raw)
  To: Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 17:33:58 Laurent Pinchart wrote:
> On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> > On 05-01-2017 12:29, Laurent Pinchart wrote:
> >> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>>> Instead of spreading version-dependent PHY power handling code
> >>>>> around, group it in two functions to power the PHY on and off and use
> >>>>> them through the driver.
> >>>>> 
> >>>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>>> split in two locations for first and second generation PHYs, group
> >>>>> all the operations in the dw_hdmi_phy_init() function.
> >>>> 
> >>>> This changes the behaviour of the driver.
> >>>> 
> >>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>>> +{
> >>>>> +	if (hdmi->phy->gen == 1) {
> >>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> +	} else {
> >>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>> +	}
> >>>>> +}
> >>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>> *hdmi)
> >>>>>  	if (!hdmi->phy_enabled)
> >>>>>  		return;
> >>>>> 
> >>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> -
> >>>>> +	dw_hdmi_phy_power_off(hdmi);
> >>>> 
> >>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>>> 
> >>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>>> to revert (and finally expunge), as it causes problems on iMX6:
> >>>> 
> >>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>>         if (!hdmi->phy_enabled)
> >>>>                 return;
> >>>> 
> >>>> +       /* Actually set the phy into low power mode */
> >>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +
> >>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>>> +
> >>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +
> >>>> +       /* This appears to have no effect on iMX6 */
> >>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> 
> >>>> So, I think your change here will cause problems for iMX6.
> >>>> 
> >>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>>> able to check for that again.
> >>> 
> >>> Indeed TX_READY must be low before asserting pddq.
> >> 
> >> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >> output signal, but there seems to be no HDMI TX register from which its
> >> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >> ?
> > 
> > TX_READY can be read from register 0x1A of phy, BIT(2) (through
> > I2C).
> 
> That's what I thought, I'll poll that then. Do you have any idea how long
> it's supposed to take, to set an appropriate timeout ?

On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down the 
PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On RK3288 (MHL 
PHY) the register reads as 0x0207 and as 0x0000 immediately after deasserting 
TXPWRON. It seems that one I2C read is a sufficient delay for TX_READY to go 
low.

> > Not sure if same offset for all phys though.
> 
> Most probably not, it would be too easy :-) I'll investigate (which will
> likely include lots of guesswork). If you can find any information about
> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
> appreciated, as I don't have access to any documentation that mentions a
> TX_READY bit for those.

I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the TX_READY 
bit was in the same register at the same position.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-01-06  1:48               ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-06  1:48 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Russell King - ARM Linux,
	dri-devel, Kieran Bingham, linux-renesas-soc, Ulrich Hecht,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 17:33:58 Laurent Pinchart wrote:
> On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> > On 05-01-2017 12:29, Laurent Pinchart wrote:
> >> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>>> Instead of spreading version-dependent PHY power handling code
> >>>>> around, group it in two functions to power the PHY on and off and use
> >>>>> them through the driver.
> >>>>> 
> >>>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>>> split in two locations for first and second generation PHYs, group
> >>>>> all the operations in the dw_hdmi_phy_init() function.
> >>>> 
> >>>> This changes the behaviour of the driver.
> >>>> 
> >>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>>> +{
> >>>>> +	if (hdmi->phy->gen == 1) {
> >>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> +	} else {
> >>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>> +	}
> >>>>> +}
> >>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>> *hdmi)
> >>>>>  	if (!hdmi->phy_enabled)
> >>>>>  		return;
> >>>>> 
> >>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> -
> >>>>> +	dw_hdmi_phy_power_off(hdmi);
> >>>> 
> >>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>>> 
> >>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>>> to revert (and finally expunge), as it causes problems on iMX6:
> >>>> 
> >>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>>         if (!hdmi->phy_enabled)
> >>>>                 return;
> >>>> 
> >>>> +       /* Actually set the phy into low power mode */
> >>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +
> >>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>>> +
> >>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +
> >>>> +       /* This appears to have no effect on iMX6 */
> >>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> 
> >>>> So, I think your change here will cause problems for iMX6.
> >>>> 
> >>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>>> able to check for that again.
> >>> 
> >>> Indeed TX_READY must be low before asserting pddq.
> >> 
> >> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >> output signal, but there seems to be no HDMI TX register from which its
> >> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >> ?
> > 
> > TX_READY can be read from register 0x1A of phy, BIT(2) (through
> > I2C).
> 
> That's what I thought, I'll poll that then. Do you have any idea how long
> it's supposed to take, to set an appropriate timeout ?

On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down the 
PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On RK3288 (MHL 
PHY) the register reads as 0x0207 and as 0x0000 immediately after deasserting 
TXPWRON. It seems that one I2C read is a sufficient delay for TX_READY to go 
low.

> > Not sure if same offset for all phys though.
> 
> Most probably not, it would be too easy :-) I'll investigate (which will
> likely include lots of guesswork). If you can find any information about
> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
> appreciated, as I don't have access to any documentation that mentions a
> TX_READY bit for those.

I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the TX_READY 
bit was in the same register at the same position.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-06  1:48               ` Laurent Pinchart
@ 2017-01-06 10:07                 ` Jose Abreu
  -1 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-06 10:07 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


Sorry for the delayed answer but I am quite busy at the moment.


On 06-01-2017 01:48, Laurent Pinchart wrote:

[snip]

>>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
>>>> output signal, but there seems to be no HDMI TX register from which its
>>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
>>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
>>>> ?
>>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
>>> I2C).
>> That's what I thought, I'll poll that then. Do you have any idea how long
>> it's supposed to take, to set an appropriate timeout ?

For 3d tx phy and for 25 MHz input reference clock the power-up
time is ~1ms, there is no data in the docs to power-down time but
it should be similar. Reference clock value is board dependent
and the minimum value for HDMI shall be 13.5MHz.

> On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down the 
> PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On RK3288 (MHL 
> PHY) the register reads as 0x0207 and as 0x0000 immediately after deasserting 
> TXPWRON. It seems that one I2C read is a sufficient delay for TX_READY to go 
> low.
>>> Not sure if same offset for all phys though.
>> Most probably not, it would be too easy :-) I'll investigate (which will
>> likely include lots of guesswork). If you can find any information about
>> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
>> appreciated, as I don't have access to any documentation that mentions a
>> TX_READY bit for those.
> I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the TX_READY 
> bit was in the same register at the same position.
>

The info I got the register offset is from an HDMI 2.0 phy :)
Notice that there are a lot of phy versions and some of them
(used in dw-hdmi) maybe customized, I don't think I have access
to that custom phys documentation. Please test the HDMI 2.0 phy
and check if the register is the same, it should be. In the
meantime it would really be helpful if some of the developers
that used dw-hdmi supplied this info about the registers as they
should know exactly what phy was used.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-01-06 10:07                 ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-01-06 10:07 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


Sorry for the delayed answer but I am quite busy at the moment.


On 06-01-2017 01:48, Laurent Pinchart wrote:

[snip]

>>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
>>>> output signal, but there seems to be no HDMI TX register from which its
>>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
>>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
>>>> ?
>>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
>>> I2C).
>> That's what I thought, I'll poll that then. Do you have any idea how long
>> it's supposed to take, to set an appropriate timeout ?

For 3d tx phy and for 25 MHz input reference clock the power-up
time is ~1ms, there is no data in the docs to power-down time but
it should be similar. Reference clock value is board dependent
and the minimum value for HDMI shall be 13.5MHz.

> On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down the 
> PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On RK3288 (MHL 
> PHY) the register reads as 0x0207 and as 0x0000 immediately after deasserting 
> TXPWRON. It seems that one I2C read is a sufficient delay for TX_READY to go 
> low.
>>> Not sure if same offset for all phys though.
>> Most probably not, it would be too easy :-) I'll investigate (which will
>> likely include lots of guesswork). If you can find any information about
>> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
>> appreciated, as I don't have access to any documentation that mentions a
>> TX_READY bit for those.
> I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the TX_READY 
> bit was in the same register at the same position.
>

The info I got the register offset is from an HDMI 2.0 phy :)
Notice that there are a lot of phy versions and some of them
(used in dw-hdmi) maybe customized, I don't think I have access
to that custom phys documentation. Please test the HDMI 2.0 phy
and check if the register is the same, it should be. In the
meantime it would really be helpful if some of the developers
that used dw-hdmi supplied this info about the registers as they
should know exactly what phy was used.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-06 10:07                 ` Jose Abreu
@ 2017-01-06 14:52                   ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-06 14:52 UTC (permalink / raw)
  To: Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Friday 06 Jan 2017 10:07:03 Jose Abreu wrote:
> Hi Laurent,
> 
> Sorry for the delayed answer but I am quite busy at the moment.

No worries, your help is really appreciated.

> On 06-01-2017 01:48, Laurent Pinchart wrote:
> 
> [snip]
> 
> >>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >>>> output signal, but there seems to be no HDMI TX register from which its
> >>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >>>> ?
> >>> 
> >>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> >>> I2C).
> >> 
> >> That's what I thought, I'll poll that then. Do you have any idea how long
> >> it's supposed to take, to set an appropriate timeout ?
> 
> For 3d tx phy and for 25 MHz input reference clock the power-up
> time is ~1ms, there is no data in the docs to power-down time but
> it should be similar. Reference clock value is board dependent
> and the minimum value for HDMI shall be 13.5MHz.
> 
> > On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down
> > the PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On
> > RK3288 (MHL PHY) the register reads as 0x0207 and as 0x0000 immediately
> > after deasserting TXPWRON. It seems that one I2C read is a sufficient
> > delay for TX_READY to go low.
> > 
> >>> Not sure if same offset for all phys though.
> >> 
> >> Most probably not, it would be too easy :-) I'll investigate (which will
> >> likely include lots of guesswork). If you can find any information about
> >> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
> >> appreciated, as I don't have access to any documentation that mentions a
> >> TX_READY bit for those.
> > 
> > I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the
> > TX_READY bit was in the same register at the same position.
> 
> The info I got the register offset is from an HDMI 2.0 phy :)

That's good news :-)

> Notice that there are a lot of phy versions and some of them
> (used in dw-hdmi) maybe customized, I don't think I have access
> to that custom phys documentation.

I think we will eventually have to implement PHY-specific power up and power 
down sequences, but for now a common sequence should work.

> Please test the HDMI 2.0 phy and check if the register is the same, it
> should be.

I did, and it is \o/ I'll send patches.

> In the meantime it would really be helpful if some of the developers
> that used dw-hdmi supplied this info about the registers as they
> should know exactly what phy was used.

I will ask internally for the R-Car H3 SoC.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-01-06 14:52                   ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-01-06 14:52 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Russell King - ARM Linux,
	dri-devel, Kieran Bingham, linux-renesas-soc, Ulrich Hecht,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Friday 06 Jan 2017 10:07:03 Jose Abreu wrote:
> Hi Laurent,
> 
> Sorry for the delayed answer but I am quite busy at the moment.

No worries, your help is really appreciated.

> On 06-01-2017 01:48, Laurent Pinchart wrote:
> 
> [snip]
> 
> >>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >>>> output signal, but there seems to be no HDMI TX register from which its
> >>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >>>> ?
> >>> 
> >>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> >>> I2C).
> >> 
> >> That's what I thought, I'll poll that then. Do you have any idea how long
> >> it's supposed to take, to set an appropriate timeout ?
> 
> For 3d tx phy and for 25 MHz input reference clock the power-up
> time is ~1ms, there is no data in the docs to power-down time but
> it should be similar. Reference clock value is board dependent
> and the minimum value for HDMI shall be 13.5MHz.
> 
> > On i.MX6 (3D TX PHY) register 0x1a reads as 0x0007 before powering down
> > the PHY (by deasserting TXPWRON) and as 0x0000 immediately after. On
> > RK3288 (MHL PHY) the register reads as 0x0207 and as 0x0000 immediately
> > after deasserting TXPWRON. It seems that one I2C read is a sufficient
> > delay for TX_READY to go low.
> > 
> >>> Not sure if same offset for all phys though.
> >> 
> >> Most probably not, it would be too easy :-) I'll investigate (which will
> >> likely include lots of guesswork). If you can find any information about
> >> that (and especially about the MHL and HDMI 2.0 PHYs) that would be very
> >> appreciated, as I don't have access to any documentation that mentions a
> >> TX_READY bit for those.
> > 
> > I haven't tested the HDMI 2.0 PHY yet, but I'd be surprised if the
> > TX_READY bit was in the same register at the same position.
> 
> The info I got the register offset is from an HDMI 2.0 phy :)

That's good news :-)

> Notice that there are a lot of phy versions and some of them
> (used in dw-hdmi) maybe customized, I don't think I have access
> to that custom phys documentation.

I think we will eventually have to implement PHY-specific power up and power 
down sequences, but for now a common sequence should work.

> Please test the HDMI 2.0 phy and check if the register is the same, it
> should be.

I did, and it is \o/ I'll send patches.

> In the meantime it would really be helpful if some of the developers
> that used dw-hdmi supplied this info about the registers as they
> should know exactly what phy was used.

I will ask internally for the R-Car H3 SoC.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-01-05 15:06           ` Jose Abreu
@ 2017-03-01 11:09             ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-03-01 11:09 UTC (permalink / raw)
  To: dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> On 05-01-2017 12:29, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>> Instead of spreading version-dependent PHY power handling code around,
> >>>> group it in two functions to power the PHY on and off and use them
> >>>> through the driver.
> >>>> 
> >>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>> split in two locations for first and second generation PHYs, group all
> >>>> the operations in the dw_hdmi_phy_init() function.
> >>> 
> >>> This changes the behaviour of the driver.
> >>> 
> >>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>> +{
> >>>> +	if (hdmi->phy->gen == 1) {
> >>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> +	} else {
> >>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +	}
> >>>> +}
> >>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>>  	if (!hdmi->phy_enabled)
> >>>>  		return;
> >>>> 
> >>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> -
> >>>> +	dw_hdmi_phy_power_off(hdmi);
> >>> 
> >>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>> 
> >>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>> to revert (and finally expunge), as it causes problems on iMX6:
> >>> 
> >>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>> *hdmi)
> >>>         if (!hdmi->phy_enabled)
> >>>                 return;
> >>> 
> >>> +       /* Actually set the phy into low power mode */
> >>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>> +
> >>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>> +
> >>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>> +
> >>> +       /* This appears to have no effect on iMX6 */
> >>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>> 
> >>> So, I think your change here will cause problems for iMX6.
> >>> 
> >>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>> able to check for that again.
> >> 
> >> Indeed TX_READY must be low before asserting pddq.
> > 
> > The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> > output signal, but there seems to be no HDMI TX register from which its
> > state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> > through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
> 
> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> I2C). Not sure if same offset for all phys though.

I have been told that another option is to poll the TX_PHY_LOCK bit in the 
phy_stat0 register. That would be a simpler solution that doesn't require I2C 
access. Could you confirm (or disconfirm) this ?

> >> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
> >> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
> >> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
> >> consequently entering power down mode) you can enable again enhpdrxsense.
> > 
> > Thanks, I'll give it a try.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-03-01 11:09             ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-03-01 11:09 UTC (permalink / raw)
  To: dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> On 05-01-2017 12:29, Laurent Pinchart wrote:
> > On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>> Instead of spreading version-dependent PHY power handling code around,
> >>>> group it in two functions to power the PHY on and off and use them
> >>>> through the driver.
> >>>> 
> >>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>> split in two locations for first and second generation PHYs, group all
> >>>> the operations in the dw_hdmi_phy_init() function.
> >>> 
> >>> This changes the behaviour of the driver.
> >>> 
> >>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>> +{
> >>>> +	if (hdmi->phy->gen == 1) {
> >>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> +	} else {
> >>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>> +	}
> >>>> +}
> >>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>> *hdmi)
> >>>>  	if (!hdmi->phy_enabled)
> >>>>  		return;
> >>>> 
> >>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>> -
> >>>> +	dw_hdmi_phy_power_off(hdmi);
> >>> 
> >>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>> 
> >>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>> to revert (and finally expunge), as it causes problems on iMX6:
> >>> 
> >>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>> *hdmi)
> >>>         if (!hdmi->phy_enabled)
> >>>                 return;
> >>> 
> >>> +       /* Actually set the phy into low power mode */
> >>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>> +
> >>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>> +
> >>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>> +
> >>> +       /* This appears to have no effect on iMX6 */
> >>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>> 
> >>> So, I think your change here will cause problems for iMX6.
> >>> 
> >>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>> able to check for that again.
> >> 
> >> Indeed TX_READY must be low before asserting pddq.
> > 
> > The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> > output signal, but there seems to be no HDMI TX register from which its
> > state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> > through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
> 
> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> I2C). Not sure if same offset for all phys though.

I have been told that another option is to poll the TX_PHY_LOCK bit in the 
phy_stat0 register. That would be a simpler solution that doesn't require I2C 
access. Could you confirm (or disconfirm) this ?

> >> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
> >> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
> >> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
> >> consequently entering power down mode) you can enable again enhpdrxsense.
> > 
> > Thanks, I'll give it a try.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-03-01 11:09             ` Laurent Pinchart
@ 2017-03-01 16:25               ` Jose Abreu
  -1 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-03-01 16:25 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


On 01-03-2017 11:09, Laurent Pinchart wrote:
> Hi Jose,
>
> On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
>> On 05-01-2017 12:29, Laurent Pinchart wrote:
>>> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
>>>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
>>>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>>>>>> Instead of spreading version-dependent PHY power handling code around,
>>>>>> group it in two functions to power the PHY on and off and use them
>>>>>> through the driver.
>>>>>>
>>>>>> Powering off the PHY at the beginning of the setup phase is currently
>>>>>> split in two locations for first and second generation PHYs, group all
>>>>>> the operations in the dw_hdmi_phy_init() function.
>>>>> This changes the behaviour of the driver.
>>>>>
>>>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>>>>>> +{
>>>>>> +	if (hdmi->phy->gen == 1) {
>>>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>> +	} else {
>>>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>>>> +	}
>>>>>> +}
>>>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>>>> *hdmi)
>>>>>>  	if (!hdmi->phy_enabled)
>>>>>>  		return;
>>>>>>
>>>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>> -
>>>>>> +	dw_hdmi_phy_power_off(hdmi);
>>>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>>>>>
>>>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
>>>>> gen2 phy.  I've been carrying this change for a while, which I've had
>>>>> to revert (and finally expunge), as it causes problems on iMX6:
>>>>>
>>>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>>> *hdmi)
>>>>>         if (!hdmi->phy_enabled)
>>>>>                 return;
>>>>>
>>>>> +       /* Actually set the phy into low power mode */
>>>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>>> +
>>>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
>>>>> +
>>>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>>> +
>>>>> +       /* This appears to have no effect on iMX6 */
>>>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>
>>>>> So, I think your change here will cause problems for iMX6.
>>>>>
>>>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
>>>>> bouncing when the PHY is powered down.  I can't promise when I'll be
>>>>> able to check for that again.
>>>> Indeed TX_READY must be low before asserting pddq.
>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
>>> output signal, but there seems to be no HDMI TX register from which its
>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
>> I2C). Not sure if same offset for all phys though.
> I have been told that another option is to poll the TX_PHY_LOCK bit in the 
> phy_stat0 register. That would be a simpler solution that doesn't require I2C 
> access. Could you confirm (or disconfirm) this ?

Yes (In our implementation we have TX_PHY_LOCK wired up to
TX_READY that comes from phy. But if using a custom phy or an
unusual implementation then this may not hold).

Best regards,
Jose Miguel Abreu

>>>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
>>>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
>>>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
>>>> consequently entering power down mode) you can enable again enhpdrxsense.
>>> Thanks, I'll give it a try.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-03-01 16:25               ` Jose Abreu
  0 siblings, 0 replies; 73+ messages in thread
From: Jose Abreu @ 2017-03-01 16:25 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Jose Abreu, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Laurent,


On 01-03-2017 11:09, Laurent Pinchart wrote:
> Hi Jose,
>
> On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
>> On 05-01-2017 12:29, Laurent Pinchart wrote:
>>> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
>>>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
>>>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
>>>>>> Instead of spreading version-dependent PHY power handling code around,
>>>>>> group it in two functions to power the PHY on and off and use them
>>>>>> through the driver.
>>>>>>
>>>>>> Powering off the PHY at the beginning of the setup phase is currently
>>>>>> split in two locations for first and second generation PHYs, group all
>>>>>> the operations in the dw_hdmi_phy_init() function.
>>>>> This changes the behaviour of the driver.
>>>>>
>>>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>>>>>> +{
>>>>>> +	if (hdmi->phy->gen == 1) {
>>>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>> +	} else {
>>>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>>>> +	}
>>>>>> +}
>>>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>>>> *hdmi)
>>>>>>  	if (!hdmi->phy_enabled)
>>>>>>  		return;
>>>>>>
>>>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>> -
>>>>>> +	dw_hdmi_phy_power_off(hdmi);
>>>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
>>>>>
>>>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
>>>>> gen2 phy.  I've been carrying this change for a while, which I've had
>>>>> to revert (and finally expunge), as it causes problems on iMX6:
>>>>>
>>>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
>>>>> *hdmi)
>>>>>         if (!hdmi->phy_enabled)
>>>>>                 return;
>>>>>
>>>>> +       /* Actually set the phy into low power mode */
>>>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>>>>> +
>>>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
>>>>> +
>>>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
>>>>> +
>>>>> +       /* This appears to have no effect on iMX6 */
>>>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
>>>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
>>>>>
>>>>> So, I think your change here will cause problems for iMX6.
>>>>>
>>>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
>>>>> bouncing when the PHY is powered down.  I can't promise when I'll be
>>>>> able to check for that again.
>>>> Indeed TX_READY must be low before asserting pddq.
>>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
>>> output signal, but there seems to be no HDMI TX register from which its
>>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
>>> through I2C ? How long is the PHY expected to take to set TX_READY to 0 ?
>> TX_READY can be read from register 0x1A of phy, BIT(2) (through
>> I2C). Not sure if same offset for all phys though.
> I have been told that another option is to poll the TX_PHY_LOCK bit in the 
> phy_stat0 register. That would be a simpler solution that doesn't require I2C 
> access. Could you confirm (or disconfirm) this ?

Yes (In our implementation we have TX_PHY_LOCK wired up to
TX_READY that comes from phy. But if using a custom phy or an
unusual implementation then this may not hold).

Best regards,
Jose Miguel Abreu

>>>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
>>>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
>>>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
>>>> consequently entering power down mode) you can enable again enhpdrxsense.
>>> Thanks, I'll give it a try.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
  2017-03-01 16:25               ` Jose Abreu
@ 2017-03-01 22:47                 ` Laurent Pinchart
  -1 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:47 UTC (permalink / raw)
  To: Jose Abreu
  Cc: dri-devel, Fabio Estevam, Laurent Pinchart,
	Russell King - ARM Linux, Kieran Bingham, linux-renesas-soc,
	Ulrich Hecht, Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Wednesday 01 Mar 2017 16:25:46 Jose Abreu wrote:
> On 01-03-2017 11:09, Laurent Pinchart wrote:
> > On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> >> On 05-01-2017 12:29, Laurent Pinchart wrote:
> >>> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >>>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>>>> Instead of spreading version-dependent PHY power handling code
> >>>>>> around, group it in two functions to power the PHY on and off and use
> >>>>>> them through the driver.
> >>>>>> 
> >>>>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>>>> split in two locations for first and second generation PHYs, group
> >>>>>> all the operations in the dw_hdmi_phy_init() function.
> >>>>> 
> >>>>> This changes the behaviour of the driver.
> >>>>> 
> >>>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>>>> +{
> >>>>>> +	if (hdmi->phy->gen == 1) {
> >>>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>>> +	} else {
> >>>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>>> +	}
> >>>>>> +}
> >>>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>>> *hdmi)
> >>>>>>  	if (!hdmi->phy_enabled)
> >>>>>>  		return;
> >>>>>> 
> >>>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>>> -
> >>>>>> +	dw_hdmi_phy_power_off(hdmi);
> >>>>> 
> >>>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>>>> 
> >>>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>>>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>>>> to revert (and finally expunge), as it causes problems on iMX6:
> >>>>> 
> >>>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>> *hdmi)
> >>>>>         if (!hdmi->phy_enabled)
> >>>>>                 return;
> >>>>> 
> >>>>> +       /* Actually set the phy into low power mode */
> >>>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>> +
> >>>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>>>> +
> >>>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>> +
> >>>>> +       /* This appears to have no effect on iMX6 */
> >>>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> 
> >>>>> So, I think your change here will cause problems for iMX6.
> >>>>> 
> >>>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>>>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>>>> able to check for that again.
> >>>> 
> >>>> Indeed TX_READY must be low before asserting pddq.
> >>> 
> >>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >>> output signal, but there seems to be no HDMI TX register from which its
> >>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >>> ?
> >> 
> >> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> >> I2C). Not sure if same offset for all phys though.
> > 
> > I have been told that another option is to poll the TX_PHY_LOCK bit in the
> > phy_stat0 register. That would be a simpler solution that doesn't require
> > I2C access. Could you confirm (or disconfirm) this ?
> 
> Yes (In our implementation we have TX_PHY_LOCK wired up to
> TX_READY that comes from phy. But if using a custom phy or an
> unusual implementation then this may not hold).

Thank you for the information. I've submitted a v4 that poll the TX_PHY_LOCK 
bit.  With the patch series applied the vendor PHY handling code already 
delegates PHY power control to the glue code, there's thus no issue there. For 
platforms using a Synopsys PHY, all the ones we have to support today have 
TX_READY wired to the PHY lock signal so we should be good as well there. If 
that doesn't remain true in the future we'll fix it.

> >>>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
> >>>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
> >>>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
> >>>> consequently entering power down mode) you can enable again
> >>>> enhpdrxsense.
> >>> 
> >>> Thanks, I'll give it a try.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling
@ 2017-03-01 22:47                 ` Laurent Pinchart
  0 siblings, 0 replies; 73+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:47 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Russell King - ARM Linux,
	dri-devel, Kieran Bingham, linux-renesas-soc, Ulrich Hecht,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Wednesday 01 Mar 2017 16:25:46 Jose Abreu wrote:
> On 01-03-2017 11:09, Laurent Pinchart wrote:
> > On Thursday 05 Jan 2017 15:06:49 Jose Abreu wrote:
> >> On 05-01-2017 12:29, Laurent Pinchart wrote:
> >>> On Tuesday 20 Dec 2016 12:17:23 Jose Abreu wrote:
> >>>> On 20-12-2016 11:45, Russell King - ARM Linux wrote:
> >>>>> On Tue, Dec 20, 2016 at 03:33:48AM +0200, Laurent Pinchart wrote:
> >>>>>> Instead of spreading version-dependent PHY power handling code
> >>>>>> around, group it in two functions to power the PHY on and off and use
> >>>>>> them through the driver.
> >>>>>> 
> >>>>>> Powering off the PHY at the beginning of the setup phase is currently
> >>>>>> split in two locations for first and second generation PHYs, group
> >>>>>> all the operations in the dw_hdmi_phy_init() function.
> >>>>> 
> >>>>> This changes the behaviour of the driver.
> >>>>> 
> >>>>>> +static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
> >>>>>> +{
> >>>>>> +	if (hdmi->phy->gen == 1) {
> >>>>>> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>>> +	} else {
> >>>>>> +		dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>>> +		dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>>> +	}
> >>>>>> +}
> >>>>>> @@ -1290,9 +1302,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>>> *hdmi)
> >>>>>>  	if (!hdmi->phy_enabled)
> >>>>>>  		return;
> >>>>>> 
> >>>>>> -	dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>> -	dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>>> -
> >>>>>> +	dw_hdmi_phy_power_off(hdmi);
> >>>>> 
> >>>>> This makes dw_hdmi_phy_disable() power down a gen2 phy.
> >>>>> 
> >>>>> The iMX6 has a DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY phy, which you list as a
> >>>>> gen2 phy.  I've been carrying this change for a while, which I've had
> >>>>> to revert (and finally expunge), as it causes problems on iMX6:
> >>>>> 
> >>>>> @@ -1112,6 +1112,14 @@ static void dw_hdmi_phy_disable(struct dw_hdmi
> >>>>> *hdmi)
> >>>>>         if (!hdmi->phy_enabled)
> >>>>>                 return;
> >>>>> 
> >>>>> +       /* Actually set the phy into low power mode */
> >>>>> +       dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> >>>>> +
> >>>>> +       /* FIXME: We should wait for TX_READY to be deasserted */
> >>>>> +
> >>>>> +       dw_hdmi_phy_gen2_pddq(hdmi, 1);
> >>>>> +
> >>>>> +       /* This appears to have no effect on iMX6 */
> >>>>>         dw_hdmi_phy_enable_tmds(hdmi, 0);
> >>>>>         dw_hdmi_phy_enable_powerdown(hdmi, true);
> >>>>> 
> >>>>> So, I think your change here will cause problems for iMX6.
> >>>>> 
> >>>>> From what I remember, it seems that iMX6 has issues with RXSENSE/HPD
> >>>>> bouncing when the PHY is powered down.  I can't promise when I'll be
> >>>>> able to check for that again.
> >>>> 
> >>>> Indeed TX_READY must be low before asserting pddq.
> >>> 
> >>> The TX_READY signal is documented in the i.MX6 datasheet as being a PHY
> >>> output signal, but there seems to be no HDMI TX register from which its
> >>> state can be read. Do I need to poll the HDMI_PHY_PTRPT_ENBL register
> >>> through I2C ? How long is the PHY expected to take to set TX_READY to 0
> >>> ?
> >> 
> >> TX_READY can be read from register 0x1A of phy, BIT(2) (through
> >> I2C). Not sure if same offset for all phys though.
> > 
> > I have been told that another option is to poll the TX_PHY_LOCK bit in the
> > phy_stat0 register. That would be a simpler solution that doesn't require
> > I2C access. Could you confirm (or disconfirm) this ?
> 
> Yes (In our implementation we have TX_PHY_LOCK wired up to
> TX_READY that comes from phy. But if using a custom phy or an
> unusual implementation then this may not hold).

Thank you for the information. I've submitted a v4 that poll the TX_PHY_LOCK 
bit.  With the patch series applied the vendor PHY handling code already 
delegates PHY power control to the glue code, there's thus no issue there. For 
platforms using a Synopsys PHY, all the ones we have to support today have 
TX_READY wired to the PHY lock signal so we should be good as well there. If 
that doesn't remain true in the future we'll fix it.

> >>>> HPD and RXSENSE should work in power down mode by enabling enhpdrxsense
> >>>> bit in phy_conf0 BUT to enter power down you must disable TX_PWRON,
> >>>> enhpdrxsense and enable PDDQ and PHY_RESET. Only after doing this (and
> >>>> consequently entering power down mode) you can enable again
> >>>> enhpdrxsense.
> >>> 
> >>> Thanks, I'll give it a try.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 73+ messages in thread

end of thread, other threads:[~2017-03-01 22:47 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-20  1:33 [PATCH v2 00/29] R-Car Gen3 HDMI output support Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 01/29] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and hdmi_phy_i2c_write Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 02/29] drm: bridge: dw-hdmi: Remove unneeded arguments to bind/unbind functions Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 03/29] drm: bridge: dw-hdmi: Remove unused function parameter Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 04/29] drm: bridge: dw-hdmi: Embed drm_bridge in struct dw_hdmi Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 05/29] drm: bridge: dw-hdmi: Remove encoder field from " Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 06/29] drm: bridge: dw-hdmi: Don't forward HPD events to DRM core before attach Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 07/29] drm: bridge: dw-hdmi: Move IRQ and IO resource allocation to common code Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 08/29] drm: bridge: dw-hdmi: Reorder functions to prepare for next commit Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 09/29] drm: bridge: dw-hdmi: Create connector in the bridge attach operation Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 10/29] drm: bridge: dw-hdmi: Implement DRM bridge registration Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 11/29] drm: bridge: dw-hdmi: Remove PHY configuration resolution parameter Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 12/29] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to SVSRET Laurent Pinchart
2016-12-20 10:58   ` Jose Abreu
2016-12-20 10:58     ` Jose Abreu
2016-12-20  1:33 ` [PATCH v2 13/29] drm: bridge: dw-hdmi: Reject invalid product IDs Laurent Pinchart
2016-12-20 10:59   ` Jose Abreu
2016-12-20 10:59     ` Jose Abreu
2016-12-20  1:33 ` [PATCH v2 14/29] drm: bridge: dw-hdmi: Detect AHB audio DMA using correct register Laurent Pinchart
2016-12-20 11:00   ` Jose Abreu
2016-12-20 11:00     ` Jose Abreu
2016-12-20  1:33 ` [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version Laurent Pinchart
2016-12-20 11:32   ` Jose Abreu
2016-12-20 11:32     ` Jose Abreu
2016-12-20  1:33 ` [PATCH v2 16/29] drm: bridge: dw-hdmi: Detect PHY type at runtime Laurent Pinchart
2016-12-20 11:39   ` Jose Abreu
2016-12-20 11:39     ` Jose Abreu
2016-12-20 13:11     ` Laurent Pinchart
2016-12-20 15:01       ` Jose Abreu
2016-12-20 15:01         ` Jose Abreu
2017-01-05  0:15         ` Laurent Pinchart
2017-01-05  0:15           ` Laurent Pinchart
2017-01-05 10:33           ` Jose Abreu
2017-01-05 10:33             ` Jose Abreu
2017-01-05 11:44             ` Laurent Pinchart
2017-01-05 11:44               ` Laurent Pinchart
2017-01-05 14:27               ` Jose Abreu
2017-01-05 14:27                 ` Jose Abreu
2016-12-20  1:33 ` [PATCH v2 17/29] drm: bridge: dw-hdmi: Refactor PHY power handling Laurent Pinchart
2016-12-20 11:45   ` Russell King - ARM Linux
2016-12-20 12:17     ` Jose Abreu
2016-12-20 12:17       ` Jose Abreu
2017-01-05 12:29       ` Laurent Pinchart
2017-01-05 15:06         ` Jose Abreu
2017-01-05 15:06           ` Jose Abreu
2017-01-05 15:33           ` Laurent Pinchart
2017-01-05 15:33             ` Laurent Pinchart
2017-01-06  1:48             ` Laurent Pinchart
2017-01-06  1:48               ` Laurent Pinchart
2017-01-06 10:07               ` Jose Abreu
2017-01-06 10:07                 ` Jose Abreu
2017-01-06 14:52                 ` Laurent Pinchart
2017-01-06 14:52                   ` Laurent Pinchart
2017-03-01 11:09           ` Laurent Pinchart
2017-03-01 11:09             ` Laurent Pinchart
2017-03-01 16:25             ` Jose Abreu
2017-03-01 16:25               ` Jose Abreu
2017-03-01 22:47               ` Laurent Pinchart
2017-03-01 22:47                 ` Laurent Pinchart
2016-12-20 13:50     ` Laurent Pinchart
2016-12-20 13:50       ` Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 18/29] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 19/29] drm: bridge: dw-hdmi: Add support for custom PHY configuration Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 20/29] drm: bridge: dw-hdmi: Remove device type from platform data Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 21/29] dt-bindings: display: dw-hdmi: Clean up DT bindings documentation Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 22/29] dt-bindings: display: renesas: Add R-Car Gen3 HDMI TX DT bindings Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 23/29] drm: rcar-du: Add Gen3 HDMI encoder support Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 24/29] drm: rcar-du: Skip disabled outputs Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 25/29] drm: rcar-du: Add DPLL support Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 26/29] drm: rcar-du: Add HDMI outputs to R8A7795 device description Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 27/29] arm64: dts: r8a7795: Add HDMI encoder support Laurent Pinchart
2016-12-20  1:33 ` [PATCH v2 28/29] arm64: dts: r8a7795: salvator-x: Enable HDMI outputs Laurent Pinchart
2016-12-20  1:34 ` [PATCH v2 29/29] arm64: dts: r8a7795: salvator-x: Add DU1 and DU2 external dot clocks Laurent Pinchart

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.