All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
@ 2017-03-01 22:39 ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hello,

This patch series refactors all the PHY handling code in order to allow
support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.

The series starts with a few cleanups and small fixes. Patch 1/9 just removes
unused code, patch 2/9 moves the color converter code out of the PHY configure
function as it isn't PHY-dependent, and patch 3/9 enables color conversion
even for DVI as it is needed to output RGB when the input format is YUV.

The next two patches fix the power down (4/9) and up (5/9) sequences to comply
with the HDMI TX PHY specifications. They are the biggest functional changes
in the whole set, and have been tested successfully (with the rest of the
series) on i.MX6Q and R-Car H3. I'll try to perform tests on RK3288 tomorrow
if nobody beats me to it (Neil, that's for you :-)). The PLL PHY lock delay
has been measured to be between 300µs and 350µs on R-Car H3 and between 400µs
and 600µs on i.MX6Q. The PHY power down delay has been measured to be less
than 50µs on both platforms, and was often close to instant with power down
reported in the first poll iteration. We should thus be more than safe with a
5ms timeout.

Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass a
PHY operations structure to support vendor PHYs. The existing PHY support code
is turned into a default Synopsys PHYs implementation for those PHY
operations.

Patch 7/9 further refactors the Synopsys PHY configuration function to make
it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
different register layout compared to the currently supported PHYs. Glue code
is again allowed to provide a custom PHY configuration implementation, with
the existing PHY support code turned into the default implementation for all
currently supported Synopsys PHYs.

Patch 8/9 is a small cleanup that removes the now unneeded device type for
glue code platform data, and patch 9/9 follows by switching the driver to
regmap in order to support vendor-specific register access more easily.

Kieran Bingham (2):
  drm: bridge: dw-hdmi: Add support for custom PHY configuration
  drm: bridge: dw-hdmi: Remove device type from platform data

Laurent Pinchart (5):
  drm: bridge: dw-hdmi: Remove unused functions
  drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  drm: bridge: dw-hdmi: Fix the PHY power down sequence
  drm: bridge: dw-hdmi: Fix the PHY power up sequence
  drm: bridge: dw-hdmi: Create PHY operations

Neil Armstrong (2):
  drm: bridge: dw-hdmi: Enable CSC even for DVI
  drm: bridge: dw-hdmi: Switch to regmap for register access

 drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++++++-----------
 drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
 include/drm/bridge/dw_hdmi.h                |  33 +-
 4 files changed, 304 insertions(+), 199 deletions(-)

-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
@ 2017-03-01 22:39 ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

Hello,

This patch series refactors all the PHY handling code in order to allow
support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.

The series starts with a few cleanups and small fixes. Patch 1/9 just removes
unused code, patch 2/9 moves the color converter code out of the PHY configure
function as it isn't PHY-dependent, and patch 3/9 enables color conversion
even for DVI as it is needed to output RGB when the input format is YUV.

The next two patches fix the power down (4/9) and up (5/9) sequences to comply
with the HDMI TX PHY specifications. They are the biggest functional changes
in the whole set, and have been tested successfully (with the rest of the
series) on i.MX6Q and R-Car H3. I'll try to perform tests on RK3288 tomorrow
if nobody beats me to it (Neil, that's for you :-)). The PLL PHY lock delay
has been measured to be between 300µs and 350µs on R-Car H3 and between 400µs
and 600µs on i.MX6Q. The PHY power down delay has been measured to be less
than 50µs on both platforms, and was often close to instant with power down
reported in the first poll iteration. We should thus be more than safe with a
5ms timeout.

Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass a
PHY operations structure to support vendor PHYs. The existing PHY support code
is turned into a default Synopsys PHYs implementation for those PHY
operations.

Patch 7/9 further refactors the Synopsys PHY configuration function to make
it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
different register layout compared to the currently supported PHYs. Glue code
is again allowed to provide a custom PHY configuration implementation, with
the existing PHY support code turned into the default implementation for all
currently supported Synopsys PHYs.

Patch 8/9 is a small cleanup that removes the now unneeded device type for
glue code platform data, and patch 9/9 follows by switching the driver to
regmap in order to support vendor-specific register access more easily.

Kieran Bingham (2):
  drm: bridge: dw-hdmi: Add support for custom PHY configuration
  drm: bridge: dw-hdmi: Remove device type from platform data

Laurent Pinchart (5):
  drm: bridge: dw-hdmi: Remove unused functions
  drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  drm: bridge: dw-hdmi: Fix the PHY power down sequence
  drm: bridge: dw-hdmi: Fix the PHY power up sequence
  drm: bridge: dw-hdmi: Create PHY operations

Neil Armstrong (2):
  drm: bridge: dw-hdmi: Enable CSC even for DVI
  drm: bridge: dw-hdmi: Switch to regmap for register access

 drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++++++-----------
 drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
 include/drm/bridge/dw_hdmi.h                |  33 +-
 4 files changed, 304 insertions(+), 199 deletions(-)

-- 
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] 52+ messages in thread

* [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Most of the hdmi_phy_test_*() functions are unused. Remove them.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 9a9ec27d9e28..ce7496399ccf 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
-static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
-					unsigned char bit)
-{
-	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
-		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
-				       unsigned char bit)
-{
-	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
-		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
-				     unsigned char bit)
-{
-	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
-}
-
-static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
-				      unsigned char bit)
-{
-	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
-}
-
 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
 	u32 val;
-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

Most of the hdmi_phy_test_*() functions are unused. Remove them.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 9a9ec27d9e28..ce7496399ccf 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
-static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
-					unsigned char bit)
-{
-	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
-		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
-				       unsigned char bit)
-{
-	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
-		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
-				     unsigned char bit)
-{
-	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
-}
-
-static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
-				      unsigned char bit)
-{
-	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
-}
-
 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
 	u32 val;
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v4 2/9] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, 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 ce7496399ccf..906583beb08b 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -914,7 +914,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, int cscon)
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
 	u8 val, msec;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
@@ -946,14 +946,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);
-
 	/* gen2 tx power off */
 	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
 
@@ -1028,10 +1020,6 @@ 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++) {
@@ -1040,8 +1028,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 		dw_hdmi_phy_enable_tmds(hdmi, 0);
 		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
-		/* Enable CSC */
-		ret = hdmi_phy_configure(hdmi, cscon);
+		ret = hdmi_phy_configure(hdmi);
 		if (ret)
 			return ret;
 	}
@@ -1303,6 +1290,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] 52+ messages in thread

* [PATCH v4 2/9] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

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 ce7496399ccf..906583beb08b 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -914,7 +914,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, int cscon)
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
 	u8 val, msec;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
@@ -946,14 +946,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);
-
 	/* gen2 tx power off */
 	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
 
@@ -1028,10 +1020,6 @@ 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++) {
@@ -1040,8 +1028,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 		dw_hdmi_phy_enable_tmds(hdmi, 0);
 		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
-		/* Enable CSC */
-		ret = hdmi_phy_configure(hdmi, cscon);
+		ret = hdmi_phy_configure(hdmi);
 		if (ret)
 			return ret;
 	}
@@ -1303,6 +1290,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

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

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

* [PATCH v4 3/9] drm: bridge: dw-hdmi: Enable CSC even for DVI
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

From: Neil Armstrong <narmstrong@baylibre.com>

If the input pixel format is not RGB, the CSC must be enabled in order to
provide valid pixel to DVI sinks.
This patch removes the hdmi only dependency on the CSC enabling.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 906583beb08b..d863b3393aee 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1291,8 +1291,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 		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))
+	/* Enable color space conversion if needed */
+	if (is_color_space_conversion(hdmi))
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
 			    HDMI_MC_FLOWCTRL);
 	else
-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 3/9] drm: bridge: dw-hdmi: Enable CSC even for DVI
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

From: Neil Armstrong <narmstrong@baylibre.com>

If the input pixel format is not RGB, the CSC must be enabled in order to
provide valid pixel to DVI sinks.
This patch removes the hdmi only dependency on the CSC enabling.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 906583beb08b..d863b3393aee 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1291,8 +1291,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 		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))
+	/* Enable color space conversion if needed */
+	if (is_color_space_conversion(hdmi))
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
 			    HDMI_MC_FLOWCTRL);
 	else
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v4 4/9] drm: bridge: dw-hdmi: Fix the PHY power down sequence
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

The PHY requires us to wait for the PHY to switch to low power mode
after deasserting TXPWRON and before asserting PDDQ in the power down
sequence, otherwise power down will fail.

The PHY power down can be monitored though the TX_READY bit, available
through I2C in the PHY registers, or the TX_PHY_LOCK bit, available
through the HDMI TX registers. As the two are equivalent, let's pick the
easier solution of polling the TX_PHY_LOCK bit.

The power down code is currently duplicated in multiple places. To avoid
spreading multiple calls to a TX_PHY_LOCK poll function, we have to
refactor the power down code and group it all in a single function.

Tests showed that one poll iteration was enough for TX_PHY_LOCK to
become low, without requiring any additional delay. Retrying the read
five times with a 1ms to 2ms delay between each attempt should thus be
more than enough.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index d863b3393aee..85348ba6bb1c 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;
 };
 
@@ -914,6 +915,40 @@ 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)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	unsigned int i;
+	u16 val;
+
+	if (phy->gen == 1) {
+		dw_hdmi_phy_enable_tmds(hdmi, 0);
+		dw_hdmi_phy_enable_powerdown(hdmi, true);
+		return;
+	}
+
+	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
+
+	/*
+	 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went
+	 * to low power mode.
+	 */
+	for (i = 0; i < 5; ++i) {
+		val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
+		if (!(val & HDMI_PHY_TX_PHY_LOCK))
+			break;
+
+		usleep_range(1000, 2000);
+	}
+
+	if (val & HDMI_PHY_TX_PHY_LOCK)
+		dev_warn(hdmi->dev, "PHY failed to power down\n");
+	else
+		dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i);
+
+	dw_hdmi_phy_gen2_pddq(hdmi, 1);
+}
+
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
 	u8 val, msec;
@@ -946,11 +981,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 		return -EINVAL;
 	}
 
-	/* 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);
 
 	/* Leave low power consumption mode by asserting SVSRET. */
 	if (hdmi->phy->has_svsret)
@@ -1025,8 +1056,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);
 
 		ret = hdmi_phy_configure(hdmi);
 		if (ret)
@@ -1256,8 +1285,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;
 }
@@ -1827,23 +1855,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] 52+ messages in thread

* [PATCH v4 4/9] drm: bridge: dw-hdmi: Fix the PHY power down sequence
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

The PHY requires us to wait for the PHY to switch to low power mode
after deasserting TXPWRON and before asserting PDDQ in the power down
sequence, otherwise power down will fail.

The PHY power down can be monitored though the TX_READY bit, available
through I2C in the PHY registers, or the TX_PHY_LOCK bit, available
through the HDMI TX registers. As the two are equivalent, let's pick the
easier solution of polling the TX_PHY_LOCK bit.

The power down code is currently duplicated in multiple places. To avoid
spreading multiple calls to a TX_PHY_LOCK poll function, we have to
refactor the power down code and group it all in a single function.

Tests showed that one poll iteration was enough for TX_PHY_LOCK to
become low, without requiring any additional delay. Retrying the read
five times with a 1ms to 2ms delay between each attempt should thus be
more than enough.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index d863b3393aee..85348ba6bb1c 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;
 };
 
@@ -914,6 +915,40 @@ 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)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	unsigned int i;
+	u16 val;
+
+	if (phy->gen == 1) {
+		dw_hdmi_phy_enable_tmds(hdmi, 0);
+		dw_hdmi_phy_enable_powerdown(hdmi, true);
+		return;
+	}
+
+	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
+
+	/*
+	 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went
+	 * to low power mode.
+	 */
+	for (i = 0; i < 5; ++i) {
+		val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
+		if (!(val & HDMI_PHY_TX_PHY_LOCK))
+			break;
+
+		usleep_range(1000, 2000);
+	}
+
+	if (val & HDMI_PHY_TX_PHY_LOCK)
+		dev_warn(hdmi->dev, "PHY failed to power down\n");
+	else
+		dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i);
+
+	dw_hdmi_phy_gen2_pddq(hdmi, 1);
+}
+
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
 	u8 val, msec;
@@ -946,11 +981,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 		return -EINVAL;
 	}
 
-	/* 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);
 
 	/* Leave low power consumption mode by asserting SVSRET. */
 	if (hdmi->phy->has_svsret)
@@ -1025,8 +1056,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);
 
 		ret = hdmi_phy_configure(hdmi);
 		if (ret)
@@ -1256,8 +1285,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;
 }
@@ -1827,23 +1855,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

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

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

* [PATCH v4 5/9] drm: bridge: dw-hdmi: Fix the PHY power up sequence
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

When powering the PHY up we need to wait for the PLL to lock. This is
done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register
(interrupt-based wait could be implemented as well but is likely
overkill). The bit is asserted when the PLL locks, but the current code
incorrectly waits for the bit to be deasserted. Fix it, and while at it,
replace the udelay() with a sleep as the code never runs in
non-sleepable context.

To be consistent with the power down implementation move the poll loop
to the power off function.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 85348ba6bb1c..0aa3ad404f77 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -949,9 +949,44 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
 	dw_hdmi_phy_gen2_pddq(hdmi, 1);
 }
 
+static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	unsigned int i;
+	u8 val;
+
+	if (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);
+		return 0;
+	}
+
+	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 0);
+
+	/* Wait for PHY PLL lock */
+	for (i = 0; i < 5; ++i) {
+		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+		if (val)
+			break;
+
+		usleep_range(1000, 2000);
+	}
+
+	if (!val) {
+		dev_err(hdmi->dev, "PHY PLL failed to lock\n");
+		return -ETIMEDOUT;
+	}
+
+	dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
+	return 0;
+}
+
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
-	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;
@@ -1019,33 +1054,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
 			   HDMI_3D_TX_PHY_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);
-
-	/* Wait for PHY PLL lock */
-	msec = 5;
-	do {
-		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
-		if (!val)
-			break;
-
-		if (msec == 0) {
-			dev_err(hdmi->dev, "PHY PLL not locked\n");
-			return -ETIMEDOUT;
-		}
-
-		udelay(1000);
-		msec--;
-	} while (1);
-
-	return 0;
+	return dw_hdmi_phy_power_on(hdmi);
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 5/9] drm: bridge: dw-hdmi: Fix the PHY power up sequence
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

When powering the PHY up we need to wait for the PLL to lock. This is
done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register
(interrupt-based wait could be implemented as well but is likely
overkill). The bit is asserted when the PLL locks, but the current code
incorrectly waits for the bit to be deasserted. Fix it, and while at it,
replace the udelay() with a sleep as the code never runs in
non-sleepable context.

To be consistent with the power down implementation move the poll loop
to the power off function.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 85348ba6bb1c..0aa3ad404f77 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -949,9 +949,44 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
 	dw_hdmi_phy_gen2_pddq(hdmi, 1);
 }
 
+static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	unsigned int i;
+	u8 val;
+
+	if (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);
+		return 0;
+	}
+
+	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 0);
+
+	/* Wait for PHY PLL lock */
+	for (i = 0; i < 5; ++i) {
+		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+		if (val)
+			break;
+
+		usleep_range(1000, 2000);
+	}
+
+	if (!val) {
+		dev_err(hdmi->dev, "PHY PLL failed to lock\n");
+		return -ETIMEDOUT;
+	}
+
+	dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
+	return 0;
+}
+
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
-	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;
@@ -1019,33 +1054,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
 			   HDMI_3D_TX_PHY_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);
-
-	/* Wait for PHY PLL lock */
-	msec = 5;
-	do {
-		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
-		if (!val)
-			break;
-
-		if (msec == 0) {
-			dev_err(hdmi->dev, "PHY PLL not locked\n");
-			return -ETIMEDOUT;
-		}
-
-		udelay(1000);
-		msec--;
-	} while (1);
-
-	return 0;
+	return dw_hdmi_phy_power_on(hdmi);
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v4 6/9] drm: bridge: dw-hdmi: Create PHY operations
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

The HDMI TX controller support different PHYs whose programming
interface can vary significantly, especially with vendor PHYs that are
not provided by Synopsys. To support them, create a PHY operation
structure that can be provided by the platform glue layer. The existing
PHY handling code (limited to Synopsys PHY support) is refactored into a
set of default PHY operations that are used automatically when the
platform glue doesn't provide its own operations.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 0aa3ad404f77..cb2703862be2 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -141,8 +141,12 @@ struct dw_hdmi {
 	u8 edid[HDMI_EDID_LEN];
 	bool cable_plugin;
 
-	const struct dw_hdmi_phy_data *phy;
-	bool phy_enabled;
+	struct {
+		const struct dw_hdmi_phy_ops *ops;
+		const char *name;
+		void *data;
+		bool enabled;
+	} phy;
 
 	struct drm_display_mode previous_mode;
 
@@ -831,6 +835,10 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
 		  HDMI_VP_CONF);
 }
 
+/* -----------------------------------------------------------------------------
+ * Synopsys PHY Handling
+ */
+
 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 				       unsigned char bit)
 {
@@ -987,6 +995,7 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
 	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;
@@ -1019,7 +1028,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	dw_hdmi_phy_power_off(hdmi);
 
 	/* Leave low power consumption mode by asserting SVSRET. */
-	if (hdmi->phy->has_svsret)
+	if (phy->has_svsret)
 		dw_hdmi_phy_enable_svsret(hdmi, 1);
 
 	/* PHY reset. The reset signal is active high on Gen2 PHYs. */
@@ -1057,7 +1066,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	return dw_hdmi_phy_power_on(hdmi);
 }
 
-static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
+			    struct drm_display_mode *mode)
 {
 	int i, ret;
 
@@ -1071,10 +1081,31 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 			return ret;
 	}
 
-	hdmi->phy_enabled = true;
 	return 0;
 }
 
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
+{
+	dw_hdmi_phy_power_off(hdmi);
+}
+
+static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
+						      void *data)
+{
+	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
+		connector_status_connected : connector_status_disconnected;
+}
+
+static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
+	.init = dw_hdmi_phy_init,
+	.disable = dw_hdmi_phy_disable,
+	.read_hpd = dw_hdmi_phy_read_hpd,
+};
+
+/* -----------------------------------------------------------------------------
+ * HDMI TX Setup
+ */
+
 static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 {
 	u8 de;
@@ -1289,16 +1320,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
-static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
-{
-	if (!hdmi->phy_enabled)
-		return;
-
-	dw_hdmi_phy_power_off(hdmi);
-
-	hdmi->phy_enabled = false;
-}
-
 /* HDMI Initialization Step B.4 */
 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
@@ -1431,9 +1452,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_av_composer(hdmi, mode);
 
 	/* HDMI Initializateion Step B.2 */
-	ret = dw_hdmi_phy_init(hdmi);
+	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
 	if (ret)
 		return ret;
+	hdmi->phy.enabled = true;
 
 	/* HDMI Initialization Step B.3 */
 	dw_hdmi_enable_video_path(hdmi);
@@ -1548,7 +1570,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
-	dw_hdmi_phy_disable(hdmi);
+	if (hdmi->phy.enabled) {
+		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
+		hdmi->phy.enabled = false;
+	}
+
 	hdmi->bridge_is_on = false;
 }
 
@@ -1611,8 +1637,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 
-	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
-		connector_status_connected : connector_status_disconnected;
+	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -1898,19 +1923,31 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 
 	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
 
+	if (phy_type == DW_HDMI_PHY_VENDOR_PHY) {
+		/* Vendor PHYs require support from the glue layer. */
+		if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
+			dev_err(hdmi->dev,
+				"Vendor HDMI PHY not supported by glue layer\n");
+			return -ENODEV;
+		}
+
+		hdmi->phy.ops = hdmi->plat_data->phy_ops;
+		hdmi->phy.data = hdmi->plat_data->phy_data;
+		hdmi->phy.name = hdmi->plat_data->phy_name;
+		return 0;
+	}
+
+	/* Synopsys PHYs are handled internally. */
 	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
 		if (dw_hdmi_phys[i].type == phy_type) {
-			hdmi->phy = &dw_hdmi_phys[i];
+			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
+			hdmi->phy.name = dw_hdmi_phys[i].name;
+			hdmi->phy.data = (void *)&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);
-
+	dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type);
 	return -ENODEV;
 }
 
@@ -2031,7 +2068,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	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",
-		 hdmi->phy->name);
+		 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 b080a171a23f..0f583ca7e66e 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -57,13 +57,27 @@ struct dw_hdmi_phy_config {
 	u16 vlev_ctr;   /* voltage level control */
 };
 
+struct dw_hdmi_phy_ops {
+	int (*init)(struct dw_hdmi *hdmi, void *data,
+		    struct drm_display_mode *mode);
+	void (*disable)(struct dw_hdmi *hdmi, void *data);
+	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
+};
+
 struct dw_hdmi_plat_data {
 	enum dw_hdmi_devtype dev_type;
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+					   struct drm_display_mode *mode);
+
+	/* Vendor PHY support */
+	const struct dw_hdmi_phy_ops *phy_ops;
+	const char *phy_name;
+	void *phy_data;
+
+	/* Synopsys PHY support */
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config;
-	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-					   struct drm_display_mode *mode);
 };
 
 int dw_hdmi_probe(struct platform_device *pdev,
-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 6/9] drm: bridge: dw-hdmi: Create PHY operations
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

The HDMI TX controller support different PHYs whose programming
interface can vary significantly, especially with vendor PHYs that are
not provided by Synopsys. To support them, create a PHY operation
structure that can be provided by the platform glue layer. The existing
PHY handling code (limited to Synopsys PHY support) is refactored into a
set of default PHY operations that are used automatically when the
platform glue doesn't provide its own operations.

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

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 0aa3ad404f77..cb2703862be2 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -141,8 +141,12 @@ struct dw_hdmi {
 	u8 edid[HDMI_EDID_LEN];
 	bool cable_plugin;
 
-	const struct dw_hdmi_phy_data *phy;
-	bool phy_enabled;
+	struct {
+		const struct dw_hdmi_phy_ops *ops;
+		const char *name;
+		void *data;
+		bool enabled;
+	} phy;
 
 	struct drm_display_mode previous_mode;
 
@@ -831,6 +835,10 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
 		  HDMI_VP_CONF);
 }
 
+/* -----------------------------------------------------------------------------
+ * Synopsys PHY Handling
+ */
+
 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 				       unsigned char bit)
 {
@@ -987,6 +995,7 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 
 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 {
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
 	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;
@@ -1019,7 +1028,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	dw_hdmi_phy_power_off(hdmi);
 
 	/* Leave low power consumption mode by asserting SVSRET. */
-	if (hdmi->phy->has_svsret)
+	if (phy->has_svsret)
 		dw_hdmi_phy_enable_svsret(hdmi, 1);
 
 	/* PHY reset. The reset signal is active high on Gen2 PHYs. */
@@ -1057,7 +1066,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 	return dw_hdmi_phy_power_on(hdmi);
 }
 
-static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
+			    struct drm_display_mode *mode)
 {
 	int i, ret;
 
@@ -1071,10 +1081,31 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 			return ret;
 	}
 
-	hdmi->phy_enabled = true;
 	return 0;
 }
 
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
+{
+	dw_hdmi_phy_power_off(hdmi);
+}
+
+static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
+						      void *data)
+{
+	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
+		connector_status_connected : connector_status_disconnected;
+}
+
+static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
+	.init = dw_hdmi_phy_init,
+	.disable = dw_hdmi_phy_disable,
+	.read_hpd = dw_hdmi_phy_read_hpd,
+};
+
+/* -----------------------------------------------------------------------------
+ * HDMI TX Setup
+ */
+
 static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 {
 	u8 de;
@@ -1289,16 +1320,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
-static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
-{
-	if (!hdmi->phy_enabled)
-		return;
-
-	dw_hdmi_phy_power_off(hdmi);
-
-	hdmi->phy_enabled = false;
-}
-
 /* HDMI Initialization Step B.4 */
 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
@@ -1431,9 +1452,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_av_composer(hdmi, mode);
 
 	/* HDMI Initializateion Step B.2 */
-	ret = dw_hdmi_phy_init(hdmi);
+	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
 	if (ret)
 		return ret;
+	hdmi->phy.enabled = true;
 
 	/* HDMI Initialization Step B.3 */
 	dw_hdmi_enable_video_path(hdmi);
@@ -1548,7 +1570,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
-	dw_hdmi_phy_disable(hdmi);
+	if (hdmi->phy.enabled) {
+		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
+		hdmi->phy.enabled = false;
+	}
+
 	hdmi->bridge_is_on = false;
 }
 
@@ -1611,8 +1637,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 
-	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
-		connector_status_connected : connector_status_disconnected;
+	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -1898,19 +1923,31 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 
 	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
 
+	if (phy_type == DW_HDMI_PHY_VENDOR_PHY) {
+		/* Vendor PHYs require support from the glue layer. */
+		if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
+			dev_err(hdmi->dev,
+				"Vendor HDMI PHY not supported by glue layer\n");
+			return -ENODEV;
+		}
+
+		hdmi->phy.ops = hdmi->plat_data->phy_ops;
+		hdmi->phy.data = hdmi->plat_data->phy_data;
+		hdmi->phy.name = hdmi->plat_data->phy_name;
+		return 0;
+	}
+
+	/* Synopsys PHYs are handled internally. */
 	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
 		if (dw_hdmi_phys[i].type == phy_type) {
-			hdmi->phy = &dw_hdmi_phys[i];
+			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
+			hdmi->phy.name = dw_hdmi_phys[i].name;
+			hdmi->phy.data = (void *)&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);
-
+	dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type);
 	return -ENODEV;
 }
 
@@ -2031,7 +2068,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	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",
-		 hdmi->phy->name);
+		 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 b080a171a23f..0f583ca7e66e 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -57,13 +57,27 @@ struct dw_hdmi_phy_config {
 	u16 vlev_ctr;   /* voltage level control */
 };
 
+struct dw_hdmi_phy_ops {
+	int (*init)(struct dw_hdmi *hdmi, void *data,
+		    struct drm_display_mode *mode);
+	void (*disable)(struct dw_hdmi *hdmi, void *data);
+	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
+};
+
 struct dw_hdmi_plat_data {
 	enum dw_hdmi_devtype dev_type;
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+					   struct drm_display_mode *mode);
+
+	/* Vendor PHY support */
+	const struct dw_hdmi_phy_ops *phy_ops;
+	const char *phy_name;
+	void *phy_data;
+
+	/* Synopsys PHY support */
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config;
-	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-					   struct drm_display_mode *mode);
 };
 
 int dw_hdmi_probe(struct platform_device *pdev,
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

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 | 109 ++++++++++++++++++++++++++-------------
 include/drm/bridge/dw_hdmi.h     |   7 +++
 2 files changed, 81 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index cb2703862be2..b835d81bb471 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 {
@@ -860,8 +863,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);
@@ -873,6 +876,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)
 {
@@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 	return 0;
 }
 
-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)
 {
-	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
-	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,
+			      HDMI_3D_TX_PHY_CPCE_CTRL);
+	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
+			      HDMI_3D_TX_PHY_GMPCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
+			      HDMI_3D_TX_PHY_CURRCTRL);
+
+	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
+			      HDMI_3D_TX_PHY_MSM_CTRL);
+
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
+			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
+			      HDMI_3D_TX_PHY_VLEVCTRL);
+
+	/* Override and disable clock termination. */
+	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
+			      HDMI_3D_TX_PHY_CKCALCTRL);
+
+	return 0;
+}
+
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
+	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
+	int ret;
 
 	dw_hdmi_phy_power_off(hdmi);
 
@@ -1042,26 +1076,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,
-			   HDMI_3D_TX_PHY_CPCE_CTRL);
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
-			   HDMI_3D_TX_PHY_GMPCTRL);
-	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
-			   HDMI_3D_TX_PHY_CURRCTRL);
-
-	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
-	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
-			   HDMI_3D_TX_PHY_MSM_CTRL);
-
-	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
-	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
-			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
-	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
-			   HDMI_3D_TX_PHY_VLEVCTRL);
-
-	/* Override and disable clock termination. */
-	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
-			   HDMI_3D_TX_PHY_CKCALCTRL);
+	/* Write to the PHY as configured by the platform */
+	if (pdata->configure_phy)
+		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
+	else
+		ret = phy->configure(hdmi, pdata, mpixelclock);
+	if (ret) {
+		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
+			mpixelclock);
+		return ret;
+	}
 
 	return dw_hdmi_phy_power_on(hdmi);
 }
@@ -1895,24 +1919,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",
 	}
 };
 
@@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
 			hdmi->phy.name = dw_hdmi_phys[i].name;
 			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
+
+			if (!dw_hdmi_phys[i].configure &&
+			    !hdmi->plat_data->configure_phy) {
+				dev_err(hdmi->dev, "%s requires platform support\n",
+					hdmi->phy.name);
+				return -ENODEV;
+			}
+
 			return 0;
 		}
 	}
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 0f583ca7e66e..dd330259a3dc 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -78,6 +78,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);
 };
 
 int dw_hdmi_probe(struct platform_device *pdev,
@@ -91,4 +94,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] 52+ messages in thread

* [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

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 | 109 ++++++++++++++++++++++++++-------------
 include/drm/bridge/dw_hdmi.h     |   7 +++
 2 files changed, 81 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index cb2703862be2..b835d81bb471 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 {
@@ -860,8 +863,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);
@@ -873,6 +876,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)
 {
@@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
 	return 0;
 }
 
-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)
 {
-	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
-	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,
+			      HDMI_3D_TX_PHY_CPCE_CTRL);
+	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
+			      HDMI_3D_TX_PHY_GMPCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
+			      HDMI_3D_TX_PHY_CURRCTRL);
+
+	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
+			      HDMI_3D_TX_PHY_MSM_CTRL);
+
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
+			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
+	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
+			      HDMI_3D_TX_PHY_VLEVCTRL);
+
+	/* Override and disable clock termination. */
+	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
+			      HDMI_3D_TX_PHY_CKCALCTRL);
+
+	return 0;
+}
+
+static int hdmi_phy_configure(struct dw_hdmi *hdmi)
+{
+	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
+	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
+	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
+	int ret;
 
 	dw_hdmi_phy_power_off(hdmi);
 
@@ -1042,26 +1076,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,
-			   HDMI_3D_TX_PHY_CPCE_CTRL);
-	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
-			   HDMI_3D_TX_PHY_GMPCTRL);
-	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
-			   HDMI_3D_TX_PHY_CURRCTRL);
-
-	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
-	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
-			   HDMI_3D_TX_PHY_MSM_CTRL);
-
-	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
-	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
-			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
-	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
-			   HDMI_3D_TX_PHY_VLEVCTRL);
-
-	/* Override and disable clock termination. */
-	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
-			   HDMI_3D_TX_PHY_CKCALCTRL);
+	/* Write to the PHY as configured by the platform */
+	if (pdata->configure_phy)
+		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
+	else
+		ret = phy->configure(hdmi, pdata, mpixelclock);
+	if (ret) {
+		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
+			mpixelclock);
+		return ret;
+	}
 
 	return dw_hdmi_phy_power_on(hdmi);
 }
@@ -1895,24 +1919,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",
 	}
 };
 
@@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
 			hdmi->phy.name = dw_hdmi_phys[i].name;
 			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
+
+			if (!dw_hdmi_phys[i].configure &&
+			    !hdmi->plat_data->configure_phy) {
+				dev_err(hdmi->dev, "%s requires platform support\n",
+					hdmi->phy.name);
+				return -ENODEV;
+			}
+
 			return 0;
 		}
 	}
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 0f583ca7e66e..dd330259a3dc 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -78,6 +78,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);
 };
 
 int dw_hdmi_probe(struct platform_device *pdev,
@@ -91,4 +94,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

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

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

* [PATCH v4 8/9] drm: bridge: dw-hdmi: Remove device type from platform data
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-01 22:39   ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

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 b835d81bb471..132c00685796 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;
@@ -2014,7 +2013,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 dd330259a3dc..545f04fae3b6 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,
@@ -65,7 +59,6 @@ struct dw_hdmi_phy_ops {
 };
 
 struct dw_hdmi_plat_data {
-	enum dw_hdmi_devtype dev_type;
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
 
-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 8/9] drm: bridge: dw-hdmi: Remove device type from platform data
@ 2017-03-01 22:39   ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Fabio Estevam, Jose Abreu, Neil Armstrong, Kieran Bingham,
	linux-renesas-soc, Nickey Yang, Russell King, Andy Yan,
	Vladimir Zapolskiy

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 b835d81bb471..132c00685796 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;
@@ -2014,7 +2013,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 dd330259a3dc..545f04fae3b6 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,
@@ -65,7 +59,6 @@ struct dw_hdmi_phy_ops {
 };
 
 struct dw_hdmi_plat_data {
-	enum dw_hdmi_devtype dev_type;
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
 
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v4 9/9] drm: bridge: dw-hdmi: Switch to regmap for register access
  2017-03-01 22:39 ` Laurent Pinchart
                   ` (8 preceding siblings ...)
  (?)
@ 2017-03-01 22:39 ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-01 22:39 UTC (permalink / raw)
  To: dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

From: Neil Armstrong <narmstrong@baylibre.com>

The Synopsys Designware HDMI TX Controller does not enforce register
access on platforms instanciating it. The current driver supports two
different types of memory-mapped flat register access, but in order to
support the Amlogic Meson SoCs integration, and provide a more generic
way to handle all sorts of register mapping, switch the register access
to use the regmap infrastructure.

In the case of registers that are not flat memory-mapped or do not
conform to the current driver implementation, a regmap struct can be
given in the plat_data and be used at probe or bind.

Since the AHB audio driver is only available with direct memory access,
only allow the I2S audio driver to be registered is directly
memory-mapped.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 109 +++++++++++++++++++++------------------
 include/drm/bridge/dw_hdmi.h     |   1 +
 2 files changed, 59 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 132c00685796..026a0dce7661 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -19,6 +19,7 @@
 #include <linux/hdmi.h>
 #include <linux/mutex.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <linux/spinlock.h>
 
 #include <drm/drm_of.h>
@@ -171,8 +172,8 @@ struct dw_hdmi {
 	unsigned int audio_n;
 	bool audio_enable;
 
-	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
-	u8 (*read)(struct dw_hdmi *hdmi, int offset);
+	unsigned int reg_shift;
+	struct regmap *regm;
 };
 
 #define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -183,42 +184,23 @@ struct dw_hdmi {
 	(HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \
 	 HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3)
 
-static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
-{
-	writel(val, hdmi->regs + (offset << 2));
-}
-
-static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset)
-{
-	return readl(hdmi->regs + (offset << 2));
-}
-
-static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
-{
-	writeb(val, hdmi->regs + offset);
-}
-
-static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset)
-{
-	return readb(hdmi->regs + offset);
-}
-
 static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
 {
-	hdmi->write(hdmi, val, offset);
+	regmap_write(hdmi->regm, offset << hdmi->reg_shift, val);
 }
 
 static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
 {
-	return hdmi->read(hdmi, offset);
+	unsigned int val = 0;
+
+	regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val);
+
+	return val;
 }
 
 static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 {
-	u8 val = hdmi_readb(hdmi, reg) & ~mask;
-
-	val |= data & mask;
-	hdmi_writeb(hdmi, val, reg);
+	regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data);
 }
 
 static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
@@ -1989,6 +1971,20 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 	return -ENODEV;
 }
 
+static const struct regmap_config hdmi_regmap_8bit_config = {
+	.reg_bits	= 32,
+	.val_bits	= 8,
+	.reg_stride	= 1,
+	.max_register	= HDMI_I2CM_FS_SCL_LCNT_0_ADDR,
+};
+
+static const struct regmap_config hdmi_regmap_32bit_config = {
+	.reg_bits	= 32,
+	.val_bits	= 32,
+	.reg_stride	= 4,
+	.max_register	= HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2,
+};
+
 static struct dw_hdmi *
 __dw_hdmi_probe(struct platform_device *pdev,
 		const struct dw_hdmi_plat_data *plat_data)
@@ -1998,7 +1994,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
 	struct dw_hdmi *hdmi;
-	struct resource *iores;
+	struct resource *iores = NULL;
 	int irq;
 	int ret;
 	u32 val = 1;
@@ -2022,22 +2018,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	mutex_init(&hdmi->audio_mutex);
 	spin_lock_init(&hdmi->audio_lock);
 
-	of_property_read_u32(np, "reg-io-width", &val);
-
-	switch (val) {
-	case 4:
-		hdmi->write = dw_hdmi_writel;
-		hdmi->read = dw_hdmi_readl;
-		break;
-	case 1:
-		hdmi->write = dw_hdmi_writeb;
-		hdmi->read = dw_hdmi_readb;
-		break;
-	default:
-		dev_err(dev, "reg-io-width must be 1 or 4\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
@@ -2051,11 +2031,38 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		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);
-		goto err_res;
+	if (!plat_data->regm) {
+		const struct regmap_config *reg_config;
+
+		of_property_read_u32(np, "reg-io-width", &val);
+		switch (val) {
+		case 4:
+			reg_config = &hdmi_regmap_32bit_config;
+			hdmi->reg_shift = 2;
+			break;
+		case 1:
+			reg_config = &hdmi_regmap_8bit_config;
+			break;
+		default:
+			dev_err(dev, "reg-io-width must be 1 or 4\n");
+			return ERR_PTR(-EINVAL);
+		}
+
+		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);
+			goto err_res;
+		}
+
+		hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config);
+		if (IS_ERR(hdmi->regm)) {
+			dev_err(dev, "Failed to configure regmap\n");
+			ret = PTR_ERR(hdmi->regm);
+			goto err_res;
+		}
+	} else {
+		hdmi->regm = plat_data->regm;
 	}
 
 	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
@@ -2165,7 +2172,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
 	config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
 
-	if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
+	if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) {
 		struct dw_hdmi_audio_data audio;
 
 		audio.phys = iores->start;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 545f04fae3b6..bcceee8114a4 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -59,6 +59,7 @@ struct dw_hdmi_phy_ops {
 };
 
 struct dw_hdmi_plat_data {
+	struct regmap *regm;
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   struct drm_display_mode *mode);
 
-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
  2017-03-01 22:39 ` Laurent Pinchart
@ 2017-03-02 11:27   ` Neil Armstrong
  -1 siblings, 0 replies; 52+ messages in thread
From: Neil Armstrong @ 2017-03-02 11:27 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham, Nickey Yang,
	Russell King, Vladimir Zapolskiy, linux-renesas-soc

On 03/01/2017 11:39 PM, Laurent Pinchart wrote:
> Hello,
> 
> This patch series refactors all the PHY handling code in order to allow
> support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.
> 
> The series starts with a few cleanups and small fixes. Patch 1/9 just removes
> unused code, patch 2/9 moves the color converter code out of the PHY configure
> function as it isn't PHY-dependent, and patch 3/9 enables color conversion
> even for DVI as it is needed to output RGB when the input format is YUV.
> 
> The next two patches fix the power down (4/9) and up (5/9) sequences to comply
> with the HDMI TX PHY specifications. They are the biggest functional changes
> in the whole set, and have been tested successfully (with the rest of the
> series) on i.MX6Q and R-Car H3. I'll try to perform tests on RK3288 tomorrow
> if nobody beats me to it (Neil, that's for you :-)). 

Done !

Tested on RK3288 on ACT8846 EVB Board and Amlogic S905X P230 Board.

Tested-by: Neil Armstrong <narmstrong@baylibre.com>

Thanks,
Neil

> The PLL PHY lock delay
> has been measured to be between 300µs and 350µs on R-Car H3 and between 400µs
> and 600µs on i.MX6Q. The PHY power down delay has been measured to be less
> than 50µs on both platforms, and was often close to instant with power down
> reported in the first poll iteration. We should thus be more than safe with a
> 5ms timeout.
> 
> Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass a
> PHY operations structure to support vendor PHYs. The existing PHY support code
> is turned into a default Synopsys PHYs implementation for those PHY
> operations.
> 
> Patch 7/9 further refactors the Synopsys PHY configuration function to make
> it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
> different register layout compared to the currently supported PHYs. Glue code
> is again allowed to provide a custom PHY configuration implementation, with
> the existing PHY support code turned into the default implementation for all
> currently supported Synopsys PHYs.
> 
> Patch 8/9 is a small cleanup that removes the now unneeded device type for
> glue code platform data, and patch 9/9 follows by switching the driver to
> regmap in order to support vendor-specific register access more easily.
> 
> Kieran Bingham (2):
>   drm: bridge: dw-hdmi: Add support for custom PHY configuration
>   drm: bridge: dw-hdmi: Remove device type from platform data
> 
> Laurent Pinchart (5):
>   drm: bridge: dw-hdmi: Remove unused functions
>   drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
>   drm: bridge: dw-hdmi: Fix the PHY power down sequence
>   drm: bridge: dw-hdmi: Fix the PHY power up sequence
>   drm: bridge: dw-hdmi: Create PHY operations
> 
> Neil Armstrong (2):
>   drm: bridge: dw-hdmi: Enable CSC even for DVI
>   drm: bridge: dw-hdmi: Switch to regmap for register access
> 
>  drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++++++-----------
>  drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
>  include/drm/bridge/dw_hdmi.h                |  33 +-
>  4 files changed, 304 insertions(+), 199 deletions(-)
> 

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

* Re: [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
@ 2017-03-02 11:27   ` Neil Armstrong
  0 siblings, 0 replies; 52+ messages in thread
From: Neil Armstrong @ 2017-03-02 11:27 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Fabio Estevam, Jose Abreu, Kieran Bingham, linux-renesas-soc,
	Nickey Yang, Russell King, Andy Yan, Vladimir Zapolskiy

On 03/01/2017 11:39 PM, Laurent Pinchart wrote:
> Hello,
> 
> This patch series refactors all the PHY handling code in order to allow
> support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.
> 
> The series starts with a few cleanups and small fixes. Patch 1/9 just removes
> unused code, patch 2/9 moves the color converter code out of the PHY configure
> function as it isn't PHY-dependent, and patch 3/9 enables color conversion
> even for DVI as it is needed to output RGB when the input format is YUV.
> 
> The next two patches fix the power down (4/9) and up (5/9) sequences to comply
> with the HDMI TX PHY specifications. They are the biggest functional changes
> in the whole set, and have been tested successfully (with the rest of the
> series) on i.MX6Q and R-Car H3. I'll try to perform tests on RK3288 tomorrow
> if nobody beats me to it (Neil, that's for you :-)). 

Done !

Tested on RK3288 on ACT8846 EVB Board and Amlogic S905X P230 Board.

Tested-by: Neil Armstrong <narmstrong@baylibre.com>

Thanks,
Neil

> The PLL PHY lock delay
> has been measured to be between 300µs and 350µs on R-Car H3 and between 400µs
> and 600µs on i.MX6Q. The PHY power down delay has been measured to be less
> than 50µs on both platforms, and was often close to instant with power down
> reported in the first poll iteration. We should thus be more than safe with a
> 5ms timeout.
> 
> Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass a
> PHY operations structure to support vendor PHYs. The existing PHY support code
> is turned into a default Synopsys PHYs implementation for those PHY
> operations.
> 
> Patch 7/9 further refactors the Synopsys PHY configuration function to make
> it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
> different register layout compared to the currently supported PHYs. Glue code
> is again allowed to provide a custom PHY configuration implementation, with
> the existing PHY support code turned into the default implementation for all
> currently supported Synopsys PHYs.
> 
> Patch 8/9 is a small cleanup that removes the now unneeded device type for
> glue code platform data, and patch 9/9 follows by switching the driver to
> regmap in order to support vendor-specific register access more easily.
> 
> Kieran Bingham (2):
>   drm: bridge: dw-hdmi: Add support for custom PHY configuration
>   drm: bridge: dw-hdmi: Remove device type from platform data
> 
> Laurent Pinchart (5):
>   drm: bridge: dw-hdmi: Remove unused functions
>   drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
>   drm: bridge: dw-hdmi: Fix the PHY power down sequence
>   drm: bridge: dw-hdmi: Fix the PHY power up sequence
>   drm: bridge: dw-hdmi: Create PHY operations
> 
> Neil Armstrong (2):
>   drm: bridge: dw-hdmi: Enable CSC even for DVI
>   drm: bridge: dw-hdmi: Switch to regmap for register access
> 
>  drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++++++-----------
>  drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
>  include/drm/bridge/dw_hdmi.h                |  33 +-
>  4 files changed, 304 insertions(+), 199 deletions(-)
> 

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

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

* Re: [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
  2017-03-02 11:27   ` Neil Armstrong
@ 2017-03-02 11:30     ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 11:30 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam, Jose Abreu,
	Kieran Bingham, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Neil,

On Thursday 02 Mar 2017 12:27:52 Neil Armstrong wrote:
> On 03/01/2017 11:39 PM, Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series refactors all the PHY handling code in order to allow
> > support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.
> > 
> > The series starts with a few cleanups and small fixes. Patch 1/9 just
> > removes unused code, patch 2/9 moves the color converter code out of the
> > PHY configure function as it isn't PHY-dependent, and patch 3/9 enables
> > color conversion even for DVI as it is needed to output RGB when the
> > input format is YUV.
> > 
> > The next two patches fix the power down (4/9) and up (5/9) sequences to
> > comply with the HDMI TX PHY specifications. They are the biggest
> > functional changes in the whole set, and have been tested successfully
> > (with the rest of the series) on i.MX6Q and R-Car H3. I'll try to perform
> > tests on RK3288 tomorrow if nobody beats me to it (Neil, that's for you
> > :-)).
> 
> Done !
> 
> Tested on RK3288 on ACT8846 EVB Board and Amlogic S905X P230 Board.
> 
> Tested-by: Neil Armstrong <narmstrong@baylibre.com>

Thank you ! I manage to test it on a remote RK3288 board too today, and the 
PLL lock delay was between 150µs and 450µs.

> > The PLL PHY lock delay has been measured to be between 300µs and 350µs on
> > R-Car H3 and between 400µs and 600µs on i.MX6Q. The PHY power down delay
> > has been measured to be less than 50µs on both platforms, and was often
> > close to instant with power down reported in the first poll iteration. We
> > should thus be more than safe with a 5ms timeout.
> > 
> > Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass
> > a PHY operations structure to support vendor PHYs. The existing PHY
> > support code is turned into a default Synopsys PHYs implementation for
> > those PHY operations.
> > 
> > Patch 7/9 further refactors the Synopsys PHY configuration function to
> > make
> > it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
> > different register layout compared to the currently supported PHYs. Glue
> > code is again allowed to provide a custom PHY configuration
> > implementation, with the existing PHY support code turned into the
> > default implementation for all currently supported Synopsys PHYs.
> > 
> > Patch 8/9 is a small cleanup that removes the now unneeded device type for
> > glue code platform data, and patch 9/9 follows by switching the driver to
> > regmap in order to support vendor-specific register access more easily.
> > 
> > Kieran Bingham (2):
> >   drm: bridge: dw-hdmi: Add support for custom PHY configuration
> >   drm: bridge: dw-hdmi: Remove device type from platform data
> > 
> > Laurent Pinchart (5):
> >   drm: bridge: dw-hdmi: Remove unused functions
> >   drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
> >   drm: bridge: dw-hdmi: Fix the PHY power down sequence
> >   drm: bridge: dw-hdmi: Fix the PHY power up sequence
> >   drm: bridge: dw-hdmi: Create PHY operations
> > 
> > Neil Armstrong (2):
> >   drm: bridge: dw-hdmi: Enable CSC even for DVI
> >   drm: bridge: dw-hdmi: Switch to regmap for register access
> >  
> >  drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++---------
> >  drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
> >  include/drm/bridge/dw_hdmi.h                |  33 +-
> >  4 files changed, 304 insertions(+), 199 deletions(-)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support
@ 2017-03-02 11:30     ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 11:30 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Fabio Estevam, Jose Abreu, Laurent Pinchart, Kieran Bingham,
	dri-devel, linux-renesas-soc, Nickey Yang, Russell King,
	Andy Yan, Vladimir Zapolskiy

Hi Neil,

On Thursday 02 Mar 2017 12:27:52 Neil Armstrong wrote:
> On 03/01/2017 11:39 PM, Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series refactors all the PHY handling code in order to allow
> > support of vendor PHYs and Synopsys DWC HDMI 2.0 TX PHYs.
> > 
> > The series starts with a few cleanups and small fixes. Patch 1/9 just
> > removes unused code, patch 2/9 moves the color converter code out of the
> > PHY configure function as it isn't PHY-dependent, and patch 3/9 enables
> > color conversion even for DVI as it is needed to output RGB when the
> > input format is YUV.
> > 
> > The next two patches fix the power down (4/9) and up (5/9) sequences to
> > comply with the HDMI TX PHY specifications. They are the biggest
> > functional changes in the whole set, and have been tested successfully
> > (with the rest of the series) on i.MX6Q and R-Car H3. I'll try to perform
> > tests on RK3288 tomorrow if nobody beats me to it (Neil, that's for you
> > :-)).
> 
> Done !
> 
> Tested on RK3288 on ACT8846 EVB Board and Amlogic S905X P230 Board.
> 
> Tested-by: Neil Armstrong <narmstrong@baylibre.com>

Thank you ! I manage to test it on a remote RK3288 board too today, and the 
PLL lock delay was between 150µs and 450µs.

> > The PLL PHY lock delay has been measured to be between 300µs and 350µs on
> > R-Car H3 and between 400µs and 600µs on i.MX6Q. The PHY power down delay
> > has been measured to be less than 50µs on both platforms, and was often
> > close to instant with power down reported in the first poll iteration. We
> > should thus be more than safe with a 5ms timeout.
> > 
> > Patch 6/9 breaks the PHY operations out. Glue code is then allowed to pass
> > a PHY operations structure to support vendor PHYs. The existing PHY
> > support code is turned into a default Synopsys PHYs implementation for
> > those PHY operations.
> > 
> > Patch 7/9 further refactors the Synopsys PHY configuration function to
> > make
> > it modular, in order to support DWC HDMI 2.0 TX PHYs that have a very
> > different register layout compared to the currently supported PHYs. Glue
> > code is again allowed to provide a custom PHY configuration
> > implementation, with the existing PHY support code turned into the
> > default implementation for all currently supported Synopsys PHYs.
> > 
> > Patch 8/9 is a small cleanup that removes the now unneeded device type for
> > glue code platform data, and patch 9/9 follows by switching the driver to
> > regmap in order to support vendor-specific register access more easily.
> > 
> > Kieran Bingham (2):
> >   drm: bridge: dw-hdmi: Add support for custom PHY configuration
> >   drm: bridge: dw-hdmi: Remove device type from platform data
> > 
> > Laurent Pinchart (5):
> >   drm: bridge: dw-hdmi: Remove unused functions
> >   drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
> >   drm: bridge: dw-hdmi: Fix the PHY power down sequence
> >   drm: bridge: dw-hdmi: Fix the PHY power up sequence
> >   drm: bridge: dw-hdmi: Create PHY operations
> > 
> > Neil Armstrong (2):
> >   drm: bridge: dw-hdmi: Enable CSC even for DVI
> >   drm: bridge: dw-hdmi: Switch to regmap for register access
> >  
> >  drivers/gpu/drm/bridge/dw-hdmi.c            | 467 +++++++++++++---------
> >  drivers/gpu/drm/imx/dw_hdmi-imx.c           |   2 -
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   1 -
> >  include/drm/bridge/dw_hdmi.h                |  33 +-
> >  4 files changed, 304 insertions(+), 199 deletions(-)

-- 
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] 52+ messages in thread

* Re: [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:19     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:19 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> Most of the hdmi_phy_test_*() functions are unused. Remove them.
>
> 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 | 26 --------------------------
>  1 file changed, 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 9a9ec27d9e28..ce7496399ccf 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>  		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
>  }
>  
> -static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
> -					unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
> -		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
> -				       unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
> -		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
> -				     unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
> -}
> -
> -static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
> -				      unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
> -}
> -
>  static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
>  {
>  	u32 val;

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

* Re: [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
@ 2017-03-02 12:19     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:19 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> Most of the hdmi_phy_test_*() functions are unused. Remove them.
>
> 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 | 26 --------------------------
>  1 file changed, 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 9a9ec27d9e28..ce7496399ccf 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>  		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
>  }
>  
> -static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
> -					unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
> -		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
> -				       unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
> -		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
> -				     unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
> -}
> -
> -static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
> -				      unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
> -}
> -
>  static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
>  {
>  	u32 val;

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

* Re: [PATCH v4 2/9] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:21     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:21 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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>

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

Best regards,
Jose Miguel Abreu

> ---
>  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 ce7496399ccf..906583beb08b 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -914,7 +914,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, int cscon)
> +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
>  	u8 val, msec;
>  	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> @@ -946,14 +946,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);
> -
>  	/* gen2 tx power off */
>  	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>  
> @@ -1028,10 +1020,6 @@ 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++) {
> @@ -1040,8 +1028,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
>  		dw_hdmi_phy_enable_tmds(hdmi, 0);
>  		dw_hdmi_phy_enable_powerdown(hdmi, true);
>  
> -		/* Enable CSC */
> -		ret = hdmi_phy_configure(hdmi, cscon);
> +		ret = hdmi_phy_configure(hdmi);
>  		if (ret)
>  			return ret;
>  	}
> @@ -1303,6 +1290,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)

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

* Re: [PATCH v4 2/9] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code
@ 2017-03-02 12:21     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:21 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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>

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

Best regards,
Jose Miguel Abreu

> ---
>  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 ce7496399ccf..906583beb08b 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -914,7 +914,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, int cscon)
> +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
>  	u8 val, msec;
>  	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> @@ -946,14 +946,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);
> -
>  	/* gen2 tx power off */
>  	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
>  
> @@ -1028,10 +1020,6 @@ 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++) {
> @@ -1040,8 +1028,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
>  		dw_hdmi_phy_enable_tmds(hdmi, 0);
>  		dw_hdmi_phy_enable_powerdown(hdmi, true);
>  
> -		/* Enable CSC */
> -		ret = hdmi_phy_configure(hdmi, cscon);
> +		ret = hdmi_phy_configure(hdmi);
>  		if (ret)
>  			return ret;
>  	}
> @@ -1303,6 +1290,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)

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

* Re: [PATCH v4 4/9] drm: bridge: dw-hdmi: Fix the PHY power down sequence
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:27     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:27 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> The PHY requires us to wait for the PHY to switch to low power mode
> after deasserting TXPWRON and before asserting PDDQ in the power down
> sequence, otherwise power down will fail.
>
> The PHY power down can be monitored though the TX_READY bit, available
> through I2C in the PHY registers, or the TX_PHY_LOCK bit, available
> through the HDMI TX registers. As the two are equivalent, let's pick the
> easier solution of polling the TX_PHY_LOCK bit.
>
> The power down code is currently duplicated in multiple places. To avoid
> spreading multiple calls to a TX_PHY_LOCK poll function, we have to
> refactor the power down code and group it all in a single function.
>
> Tests showed that one poll iteration was enough for TX_PHY_LOCK to
> become low, without requiring any additional delay. Retrying the read
> five times with a 1ms to 2ms delay between each attempt should thus be
> more than enough.
>
> 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 | 52 +++++++++++++++++++++++++++++++++-------
>  1 file changed, 43 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index d863b3393aee..85348ba6bb1c 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;
>  };
>  
> @@ -914,6 +915,40 @@ 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)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	unsigned int i;
> +	u16 val;
> +
> +	if (phy->gen == 1) {
> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> +		return;
> +	}
> +
> +	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +	/*
> +	 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went
> +	 * to low power mode.
> +	 */
> +	for (i = 0; i < 5; ++i) {
> +		val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
> +		if (!(val & HDMI_PHY_TX_PHY_LOCK))
> +			break;
> +
> +		usleep_range(1000, 2000);
> +	}
> +
> +	if (val & HDMI_PHY_TX_PHY_LOCK)
> +		dev_warn(hdmi->dev, "PHY failed to power down\n");
> +	else
> +		dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i);
> +
> +	dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +}
> +
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
>  	u8 val, msec;
> @@ -946,11 +981,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  		return -EINVAL;
>  	}
>  
> -	/* 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);
>  
>  	/* Leave low power consumption mode by asserting SVSRET. */
>  	if (hdmi->phy->has_svsret)
> @@ -1025,8 +1056,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);
>  
>  		ret = hdmi_phy_configure(hdmi);
>  		if (ret)
> @@ -1256,8 +1285,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;
>  }
> @@ -1827,23 +1855,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,
>  	}
>  };

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

* Re: [PATCH v4 4/9] drm: bridge: dw-hdmi: Fix the PHY power down sequence
@ 2017-03-02 12:27     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:27 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> The PHY requires us to wait for the PHY to switch to low power mode
> after deasserting TXPWRON and before asserting PDDQ in the power down
> sequence, otherwise power down will fail.
>
> The PHY power down can be monitored though the TX_READY bit, available
> through I2C in the PHY registers, or the TX_PHY_LOCK bit, available
> through the HDMI TX registers. As the two are equivalent, let's pick the
> easier solution of polling the TX_PHY_LOCK bit.
>
> The power down code is currently duplicated in multiple places. To avoid
> spreading multiple calls to a TX_PHY_LOCK poll function, we have to
> refactor the power down code and group it all in a single function.
>
> Tests showed that one poll iteration was enough for TX_PHY_LOCK to
> become low, without requiring any additional delay. Retrying the read
> five times with a 1ms to 2ms delay between each attempt should thus be
> more than enough.
>
> 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 | 52 +++++++++++++++++++++++++++++++++-------
>  1 file changed, 43 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index d863b3393aee..85348ba6bb1c 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;
>  };
>  
> @@ -914,6 +915,40 @@ 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)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	unsigned int i;
> +	u16 val;
> +
> +	if (phy->gen == 1) {
> +		dw_hdmi_phy_enable_tmds(hdmi, 0);
> +		dw_hdmi_phy_enable_powerdown(hdmi, true);
> +		return;
> +	}
> +
> +	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
> +
> +	/*
> +	 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went
> +	 * to low power mode.
> +	 */
> +	for (i = 0; i < 5; ++i) {
> +		val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
> +		if (!(val & HDMI_PHY_TX_PHY_LOCK))
> +			break;
> +
> +		usleep_range(1000, 2000);
> +	}
> +
> +	if (val & HDMI_PHY_TX_PHY_LOCK)
> +		dev_warn(hdmi->dev, "PHY failed to power down\n");
> +	else
> +		dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i);
> +
> +	dw_hdmi_phy_gen2_pddq(hdmi, 1);
> +}
> +
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
>  	u8 val, msec;
> @@ -946,11 +981,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  		return -EINVAL;
>  	}
>  
> -	/* 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);
>  
>  	/* Leave low power consumption mode by asserting SVSRET. */
>  	if (hdmi->phy->has_svsret)
> @@ -1025,8 +1056,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);
>  
>  		ret = hdmi_phy_configure(hdmi);
>  		if (ret)
> @@ -1256,8 +1285,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;
>  }
> @@ -1827,23 +1855,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,
>  	}
>  };

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

* Re: [PATCH v4 5/9] drm: bridge: dw-hdmi: Fix the PHY power up sequence
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:30     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:30 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> When powering the PHY up we need to wait for the PLL to lock. This is
> done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register
> (interrupt-based wait could be implemented as well but is likely
> overkill). The bit is asserted when the PLL locks, but the current code
> incorrectly waits for the bit to be deasserted. Fix it, and while at it,
> replace the udelay() with a sleep as the code never runs in
> non-sleepable context.
>
> To be consistent with the power down implementation move the poll loop
> to the power off function.
>
> 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 | 65 +++++++++++++++++++++++-----------------
>  1 file changed, 37 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 85348ba6bb1c..0aa3ad404f77 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -949,9 +949,44 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>  	dw_hdmi_phy_gen2_pddq(hdmi, 1);
>  }
>  
> +static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	unsigned int i;
> +	u8 val;
> +
> +	if (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);
> +		return 0;
> +	}
> +
> +	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
> +	dw_hdmi_phy_gen2_pddq(hdmi, 0);
> +
> +	/* Wait for PHY PLL lock */
> +	for (i = 0; i < 5; ++i) {
> +		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
> +		if (val)
> +			break;
> +
> +		usleep_range(1000, 2000);
> +	}
> +
> +	if (!val) {
> +		dev_err(hdmi->dev, "PHY PLL failed to lock\n");
> +		return -ETIMEDOUT;
> +	}
> +
> +	dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
> +	return 0;
> +}
> +
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
> -	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;
> @@ -1019,33 +1054,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
>  			   HDMI_3D_TX_PHY_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);
> -
> -	/* Wait for PHY PLL lock */
> -	msec = 5;
> -	do {
> -		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
> -		if (!val)
> -			break;
> -
> -		if (msec == 0) {
> -			dev_err(hdmi->dev, "PHY PLL not locked\n");
> -			return -ETIMEDOUT;
> -		}
> -
> -		udelay(1000);
> -		msec--;
> -	} while (1);
> -
> -	return 0;
> +	return dw_hdmi_phy_power_on(hdmi);
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)

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

* Re: [PATCH v4 5/9] drm: bridge: dw-hdmi: Fix the PHY power up sequence
@ 2017-03-02 12:30     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:30 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> When powering the PHY up we need to wait for the PLL to lock. This is
> done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register
> (interrupt-based wait could be implemented as well but is likely
> overkill). The bit is asserted when the PLL locks, but the current code
> incorrectly waits for the bit to be deasserted. Fix it, and while at it,
> replace the udelay() with a sleep as the code never runs in
> non-sleepable context.
>
> To be consistent with the power down implementation move the poll loop
> to the power off function.
>
> 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 | 65 +++++++++++++++++++++++-----------------
>  1 file changed, 37 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 85348ba6bb1c..0aa3ad404f77 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -949,9 +949,44 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
>  	dw_hdmi_phy_gen2_pddq(hdmi, 1);
>  }
>  
> +static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	unsigned int i;
> +	u8 val;
> +
> +	if (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);
> +		return 0;
> +	}
> +
> +	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
> +	dw_hdmi_phy_gen2_pddq(hdmi, 0);
> +
> +	/* Wait for PHY PLL lock */
> +	for (i = 0; i < 5; ++i) {
> +		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
> +		if (val)
> +			break;
> +
> +		usleep_range(1000, 2000);
> +	}
> +
> +	if (!val) {
> +		dev_err(hdmi->dev, "PHY PLL failed to lock\n");
> +		return -ETIMEDOUT;
> +	}
> +
> +	dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
> +	return 0;
> +}
> +
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
> -	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;
> @@ -1019,33 +1054,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
>  			   HDMI_3D_TX_PHY_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);
> -
> -	/* Wait for PHY PLL lock */
> -	msec = 5;
> -	do {
> -		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
> -		if (!val)
> -			break;
> -
> -		if (msec == 0) {
> -			dev_err(hdmi->dev, "PHY PLL not locked\n");
> -			return -ETIMEDOUT;
> -		}
> -
> -		udelay(1000);
> -		msec--;
> -	} while (1);
> -
> -	return 0;
> +	return dw_hdmi_phy_power_on(hdmi);
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)

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

* Re: [PATCH v4 6/9] drm: bridge: dw-hdmi: Create PHY operations
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:34     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:34 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> The HDMI TX controller support different PHYs whose programming
> interface can vary significantly, especially with vendor PHYs that are
> not provided by Synopsys. To support them, create a PHY operation
> structure that can be provided by the platform glue layer. The existing
> PHY handling code (limited to Synopsys PHY support) is refactored into a
> set of default PHY operations that are used automatically when the
> platform glue doesn't provide its own operations.
>
> 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 | 91 ++++++++++++++++++++++++++++------------
>  include/drm/bridge/dw_hdmi.h     | 18 +++++++-
>  2 files changed, 80 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 0aa3ad404f77..cb2703862be2 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -141,8 +141,12 @@ struct dw_hdmi {
>  	u8 edid[HDMI_EDID_LEN];
>  	bool cable_plugin;
>  
> -	const struct dw_hdmi_phy_data *phy;
> -	bool phy_enabled;
> +	struct {
> +		const struct dw_hdmi_phy_ops *ops;
> +		const char *name;
> +		void *data;
> +		bool enabled;
> +	} phy;
>  
>  	struct drm_display_mode previous_mode;
>  
> @@ -831,6 +835,10 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
>  		  HDMI_VP_CONF);
>  }
>  
> +/* -----------------------------------------------------------------------------
> + * Synopsys PHY Handling
> + */
> +
>  static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>  				       unsigned char bit)
>  {
> @@ -987,6 +995,7 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>  
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
>  	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;
> @@ -1019,7 +1028,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	dw_hdmi_phy_power_off(hdmi);
>  
>  	/* Leave low power consumption mode by asserting SVSRET. */
> -	if (hdmi->phy->has_svsret)
> +	if (phy->has_svsret)
>  		dw_hdmi_phy_enable_svsret(hdmi, 1);
>  
>  	/* PHY reset. The reset signal is active high on Gen2 PHYs. */
> @@ -1057,7 +1066,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	return dw_hdmi_phy_power_on(hdmi);
>  }
>  
> -static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
> +static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> +			    struct drm_display_mode *mode)
>  {
>  	int i, ret;
>  
> @@ -1071,10 +1081,31 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
>  			return ret;
>  	}
>  
> -	hdmi->phy_enabled = true;
>  	return 0;
>  }
>  
> +static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
> +{
> +	dw_hdmi_phy_power_off(hdmi);
> +}
> +
> +static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
> +						      void *data)
> +{
> +	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
> +		connector_status_connected : connector_status_disconnected;
> +}
> +
> +static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
> +	.init = dw_hdmi_phy_init,
> +	.disable = dw_hdmi_phy_disable,
> +	.read_hpd = dw_hdmi_phy_read_hpd,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * HDMI TX Setup
> + */
> +
>  static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
>  {
>  	u8 de;
> @@ -1289,16 +1320,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
>  }
>  
> -static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
> -{
> -	if (!hdmi->phy_enabled)
> -		return;
> -
> -	dw_hdmi_phy_power_off(hdmi);
> -
> -	hdmi->phy_enabled = false;
> -}
> -
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> @@ -1431,9 +1452,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	hdmi_av_composer(hdmi, mode);
>  
>  	/* HDMI Initializateion Step B.2 */
> -	ret = dw_hdmi_phy_init(hdmi);
> +	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
>  	if (ret)
>  		return ret;
> +	hdmi->phy.enabled = true;
>  
>  	/* HDMI Initialization Step B.3 */
>  	dw_hdmi_enable_video_path(hdmi);
> @@ -1548,7 +1570,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
>  
>  static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
>  {
> -	dw_hdmi_phy_disable(hdmi);
> +	if (hdmi->phy.enabled) {
> +		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
> +		hdmi->phy.enabled = false;
> +	}
> +
>  	hdmi->bridge_is_on = false;
>  }
>  
> @@ -1611,8 +1637,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  
> -	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
> -		connector_status_connected : connector_status_disconnected;
> +	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>  }
>  
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -1898,19 +1923,31 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  
>  	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
>  
> +	if (phy_type == DW_HDMI_PHY_VENDOR_PHY) {
> +		/* Vendor PHYs require support from the glue layer. */
> +		if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
> +			dev_err(hdmi->dev,
> +				"Vendor HDMI PHY not supported by glue layer\n");
> +			return -ENODEV;
> +		}
> +
> +		hdmi->phy.ops = hdmi->plat_data->phy_ops;
> +		hdmi->phy.data = hdmi->plat_data->phy_data;
> +		hdmi->phy.name = hdmi->plat_data->phy_name;
> +		return 0;
> +	}
> +
> +	/* Synopsys PHYs are handled internally. */
>  	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
>  		if (dw_hdmi_phys[i].type == phy_type) {
> -			hdmi->phy = &dw_hdmi_phys[i];
> +			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
> +			hdmi->phy.name = dw_hdmi_phys[i].name;
> +			hdmi->phy.data = (void *)&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);
> -
> +	dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type);
>  	return -ENODEV;
>  }
>  
> @@ -2031,7 +2068,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	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",
> -		 hdmi->phy->name);
> +		 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 b080a171a23f..0f583ca7e66e 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -57,13 +57,27 @@ struct dw_hdmi_phy_config {
>  	u16 vlev_ctr;   /* voltage level control */
>  };
>  
> +struct dw_hdmi_phy_ops {
> +	int (*init)(struct dw_hdmi *hdmi, void *data,
> +		    struct drm_display_mode *mode);
> +	void (*disable)(struct dw_hdmi *hdmi, void *data);
> +	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
> +};
> +
>  struct dw_hdmi_plat_data {
>  	enum dw_hdmi_devtype dev_type;
> +	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> +					   struct drm_display_mode *mode);
> +
> +	/* Vendor PHY support */
> +	const struct dw_hdmi_phy_ops *phy_ops;
> +	const char *phy_name;
> +	void *phy_data;
> +
> +	/* Synopsys PHY support */
>  	const struct dw_hdmi_mpll_config *mpll_cfg;
>  	const struct dw_hdmi_curr_ctrl *cur_ctr;
>  	const struct dw_hdmi_phy_config *phy_config;
> -	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> -					   struct drm_display_mode *mode);
>  };
>  
>  int dw_hdmi_probe(struct platform_device *pdev,

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

* Re: [PATCH v4 6/9] drm: bridge: dw-hdmi: Create PHY operations
@ 2017-03-02 12:34     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:34 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> The HDMI TX controller support different PHYs whose programming
> interface can vary significantly, especially with vendor PHYs that are
> not provided by Synopsys. To support them, create a PHY operation
> structure that can be provided by the platform glue layer. The existing
> PHY handling code (limited to Synopsys PHY support) is refactored into a
> set of default PHY operations that are used automatically when the
> platform glue doesn't provide its own operations.
>
> 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 | 91 ++++++++++++++++++++++++++++------------
>  include/drm/bridge/dw_hdmi.h     | 18 +++++++-
>  2 files changed, 80 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 0aa3ad404f77..cb2703862be2 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -141,8 +141,12 @@ struct dw_hdmi {
>  	u8 edid[HDMI_EDID_LEN];
>  	bool cable_plugin;
>  
> -	const struct dw_hdmi_phy_data *phy;
> -	bool phy_enabled;
> +	struct {
> +		const struct dw_hdmi_phy_ops *ops;
> +		const char *name;
> +		void *data;
> +		bool enabled;
> +	} phy;
>  
>  	struct drm_display_mode previous_mode;
>  
> @@ -831,6 +835,10 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
>  		  HDMI_VP_CONF);
>  }
>  
> +/* -----------------------------------------------------------------------------
> + * Synopsys PHY Handling
> + */
> +
>  static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>  				       unsigned char bit)
>  {
> @@ -987,6 +995,7 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>  
>  static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  {
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
>  	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;
> @@ -1019,7 +1028,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	dw_hdmi_phy_power_off(hdmi);
>  
>  	/* Leave low power consumption mode by asserting SVSRET. */
> -	if (hdmi->phy->has_svsret)
> +	if (phy->has_svsret)
>  		dw_hdmi_phy_enable_svsret(hdmi, 1);
>  
>  	/* PHY reset. The reset signal is active high on Gen2 PHYs. */
> @@ -1057,7 +1066,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  	return dw_hdmi_phy_power_on(hdmi);
>  }
>  
> -static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
> +static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> +			    struct drm_display_mode *mode)
>  {
>  	int i, ret;
>  
> @@ -1071,10 +1081,31 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
>  			return ret;
>  	}
>  
> -	hdmi->phy_enabled = true;
>  	return 0;
>  }
>  
> +static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
> +{
> +	dw_hdmi_phy_power_off(hdmi);
> +}
> +
> +static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
> +						      void *data)
> +{
> +	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
> +		connector_status_connected : connector_status_disconnected;
> +}
> +
> +static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
> +	.init = dw_hdmi_phy_init,
> +	.disable = dw_hdmi_phy_disable,
> +	.read_hpd = dw_hdmi_phy_read_hpd,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * HDMI TX Setup
> + */
> +
>  static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
>  {
>  	u8 de;
> @@ -1289,16 +1320,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
>  }
>  
> -static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
> -{
> -	if (!hdmi->phy_enabled)
> -		return;
> -
> -	dw_hdmi_phy_power_off(hdmi);
> -
> -	hdmi->phy_enabled = false;
> -}
> -
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> @@ -1431,9 +1452,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	hdmi_av_composer(hdmi, mode);
>  
>  	/* HDMI Initializateion Step B.2 */
> -	ret = dw_hdmi_phy_init(hdmi);
> +	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
>  	if (ret)
>  		return ret;
> +	hdmi->phy.enabled = true;
>  
>  	/* HDMI Initialization Step B.3 */
>  	dw_hdmi_enable_video_path(hdmi);
> @@ -1548,7 +1570,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
>  
>  static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
>  {
> -	dw_hdmi_phy_disable(hdmi);
> +	if (hdmi->phy.enabled) {
> +		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
> +		hdmi->phy.enabled = false;
> +	}
> +
>  	hdmi->bridge_is_on = false;
>  }
>  
> @@ -1611,8 +1637,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  
> -	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
> -		connector_status_connected : connector_status_disconnected;
> +	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>  }
>  
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -1898,19 +1923,31 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  
>  	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
>  
> +	if (phy_type == DW_HDMI_PHY_VENDOR_PHY) {
> +		/* Vendor PHYs require support from the glue layer. */
> +		if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
> +			dev_err(hdmi->dev,
> +				"Vendor HDMI PHY not supported by glue layer\n");
> +			return -ENODEV;
> +		}
> +
> +		hdmi->phy.ops = hdmi->plat_data->phy_ops;
> +		hdmi->phy.data = hdmi->plat_data->phy_data;
> +		hdmi->phy.name = hdmi->plat_data->phy_name;
> +		return 0;
> +	}
> +
> +	/* Synopsys PHYs are handled internally. */
>  	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
>  		if (dw_hdmi_phys[i].type == phy_type) {
> -			hdmi->phy = &dw_hdmi_phys[i];
> +			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
> +			hdmi->phy.name = dw_hdmi_phys[i].name;
> +			hdmi->phy.data = (void *)&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);
> -
> +	dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type);
>  	return -ENODEV;
>  }
>  
> @@ -2031,7 +2068,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	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",
> -		 hdmi->phy->name);
> +		 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 b080a171a23f..0f583ca7e66e 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -57,13 +57,27 @@ struct dw_hdmi_phy_config {
>  	u16 vlev_ctr;   /* voltage level control */
>  };
>  
> +struct dw_hdmi_phy_ops {
> +	int (*init)(struct dw_hdmi *hdmi, void *data,
> +		    struct drm_display_mode *mode);
> +	void (*disable)(struct dw_hdmi *hdmi, void *data);
> +	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
> +};
> +
>  struct dw_hdmi_plat_data {
>  	enum dw_hdmi_devtype dev_type;
> +	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> +					   struct drm_display_mode *mode);
> +
> +	/* Vendor PHY support */
> +	const struct dw_hdmi_phy_ops *phy_ops;
> +	const char *phy_name;
> +	void *phy_data;
> +
> +	/* Synopsys PHY support */
>  	const struct dw_hdmi_mpll_config *mpll_cfg;
>  	const struct dw_hdmi_curr_ctrl *cur_ctr;
>  	const struct dw_hdmi_phy_config *phy_config;
> -	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> -					   struct drm_display_mode *mode);
>  };
>  
>  int dw_hdmi_probe(struct platform_device *pdev,

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:50     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:50 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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 | 109 ++++++++++++++++++++++++++-------------
>  include/drm/bridge/dw_hdmi.h     |   7 +++
>  2 files changed, 81 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index cb2703862be2..b835d81bb471 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 {
> @@ -860,8 +863,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);
> @@ -873,6 +876,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)
>  {
> @@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>  	return 0;
>  }
>  
> -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)
>  {
> -	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> -	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,
> +			      HDMI_3D_TX_PHY_CPCE_CTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> +			      HDMI_3D_TX_PHY_GMPCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> +			      HDMI_3D_TX_PHY_CURRCTRL);
> +
> +	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> +			      HDMI_3D_TX_PHY_MSM_CTRL);
> +
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> +			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> +			      HDMI_3D_TX_PHY_VLEVCTRL);
> +
> +	/* Override and disable clock termination. */
> +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> +			      HDMI_3D_TX_PHY_CKCALCTRL);
> +
> +	return 0;
> +}
> +
> +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> +	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
> +	int ret;
>  
>  	dw_hdmi_phy_power_off(hdmi);
>  
> @@ -1042,26 +1076,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,
> -			   HDMI_3D_TX_PHY_CPCE_CTRL);
> -	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> -			   HDMI_3D_TX_PHY_GMPCTRL);
> -	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> -			   HDMI_3D_TX_PHY_CURRCTRL);
> -
> -	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> -			   HDMI_3D_TX_PHY_MSM_CTRL);
> -
> -	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> -	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> -			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
> -	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> -			   HDMI_3D_TX_PHY_VLEVCTRL);
> -
> -	/* Override and disable clock termination. */
> -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> -			   HDMI_3D_TX_PHY_CKCALCTRL);
> +	/* Write to the PHY as configured by the platform */
> +	if (pdata->configure_phy)
> +		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
> +	else
> +		ret = phy->configure(hdmi, pdata, mpixelclock);
> +	if (ret) {
> +		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
> +			mpixelclock);
> +		return ret;
> +	}
>  
>  	return dw_hdmi_phy_power_on(hdmi);
>  }
> @@ -1895,24 +1919,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",
>  	}
>  };
>  
> @@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
>  			hdmi->phy.name = dw_hdmi_phys[i].name;
>  			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
> +
> +			if (!dw_hdmi_phys[i].configure &&
> +			    !hdmi->plat_data->configure_phy) {
> +				dev_err(hdmi->dev, "%s requires platform support\n",
> +					hdmi->phy.name);
> +				return -ENODEV;
> +			}
> +
>  			return 0;
>  		}
>  	}
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 0f583ca7e66e..dd330259a3dc 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -78,6 +78,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);
>  };
>  
>  int dw_hdmi_probe(struct platform_device *pdev,
> @@ -91,4 +94,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__ */

Hmm, this is kind of confusing. Why do you need a phy_ops and
then a separate configure_phy function? Can't we just use phy_ops
always? If its external phy then it would need to implement all
phy_ops functions.

Best regards,
Jose Miguel Abreu

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-02 12:50     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:50 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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 | 109 ++++++++++++++++++++++++++-------------
>  include/drm/bridge/dw_hdmi.h     |   7 +++
>  2 files changed, 81 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index cb2703862be2..b835d81bb471 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 {
> @@ -860,8 +863,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);
> @@ -873,6 +876,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)
>  {
> @@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
>  	return 0;
>  }
>  
> -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)
>  {
> -	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> -	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,
> +			      HDMI_3D_TX_PHY_CPCE_CTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> +			      HDMI_3D_TX_PHY_GMPCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> +			      HDMI_3D_TX_PHY_CURRCTRL);
> +
> +	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> +			      HDMI_3D_TX_PHY_MSM_CTRL);
> +
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> +			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
> +	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> +			      HDMI_3D_TX_PHY_VLEVCTRL);
> +
> +	/* Override and disable clock termination. */
> +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> +			      HDMI_3D_TX_PHY_CKCALCTRL);
> +
> +	return 0;
> +}
> +
> +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
> +{
> +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> +	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> +	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
> +	int ret;
>  
>  	dw_hdmi_phy_power_off(hdmi);
>  
> @@ -1042,26 +1076,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,
> -			   HDMI_3D_TX_PHY_CPCE_CTRL);
> -	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> -			   HDMI_3D_TX_PHY_GMPCTRL);
> -	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> -			   HDMI_3D_TX_PHY_CURRCTRL);
> -
> -	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> -			   HDMI_3D_TX_PHY_MSM_CTRL);
> -
> -	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> -	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> -			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
> -	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> -			   HDMI_3D_TX_PHY_VLEVCTRL);
> -
> -	/* Override and disable clock termination. */
> -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> -			   HDMI_3D_TX_PHY_CKCALCTRL);
> +	/* Write to the PHY as configured by the platform */
> +	if (pdata->configure_phy)
> +		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
> +	else
> +		ret = phy->configure(hdmi, pdata, mpixelclock);
> +	if (ret) {
> +		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
> +			mpixelclock);
> +		return ret;
> +	}
>  
>  	return dw_hdmi_phy_power_on(hdmi);
>  }
> @@ -1895,24 +1919,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",
>  	}
>  };
>  
> @@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
>  			hdmi->phy.name = dw_hdmi_phys[i].name;
>  			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
> +
> +			if (!dw_hdmi_phys[i].configure &&
> +			    !hdmi->plat_data->configure_phy) {
> +				dev_err(hdmi->dev, "%s requires platform support\n",
> +					hdmi->phy.name);
> +				return -ENODEV;
> +			}
> +
>  			return 0;
>  		}
>  	}
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 0f583ca7e66e..dd330259a3dc 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -78,6 +78,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);
>  };
>  
>  int dw_hdmi_probe(struct platform_device *pdev,
> @@ -91,4 +94,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__ */

Hmm, this is kind of confusing. Why do you need a phy_ops and
then a separate configure_phy function? Can't we just use phy_ops
always? If its external phy then it would need to implement all
phy_ops functions.

Best regards,
Jose Miguel Abreu

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

* Re: [PATCH v4 8/9] drm: bridge: dw-hdmi: Remove device type from platform data
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-02 12:51     ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:51 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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>

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

Best regards,
Jose Miguel Abreu

> ---
>  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 b835d81bb471..132c00685796 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;
> @@ -2014,7 +2013,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 dd330259a3dc..545f04fae3b6 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,
> @@ -65,7 +59,6 @@ struct dw_hdmi_phy_ops {
>  };
>  
>  struct dw_hdmi_plat_data {
> -	enum dw_hdmi_devtype dev_type;
>  	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
>  					   struct drm_display_mode *mode);
>  

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

* Re: [PATCH v4 8/9] drm: bridge: dw-hdmi: Remove device type from platform data
@ 2017-03-02 12:51     ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 12:51 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Nickey Yang, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


On 01-03-2017 22:39, Laurent Pinchart wrote:
> 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>

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

Best regards,
Jose Miguel Abreu

> ---
>  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 b835d81bb471..132c00685796 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;
> @@ -2014,7 +2013,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 dd330259a3dc..545f04fae3b6 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,
> @@ -65,7 +59,6 @@ struct dw_hdmi_phy_ops {
>  };
>  
>  struct dw_hdmi_plat_data {
> -	enum dw_hdmi_devtype dev_type;
>  	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
>  					   struct drm_display_mode *mode);
>  

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-02 12:50     ` Jose Abreu
@ 2017-03-02 13:41       ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 13:41 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Jose,

On Thursday 02 Mar 2017 12:50:13 Jose Abreu wrote:
> On 01-03-2017 22:39, Laurent Pinchart wrote:
> > 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 | 109 ++++++++++++++++++++++------------
> >  include/drm/bridge/dw_hdmi.h     |   7 +++
> >  2 files changed, 81 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/dw-hdmi.c index cb2703862be2..b835d81bb471
> > 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 {
> > @@ -860,8 +863,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);
> > @@ -873,6 +876,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)
> >  {
> > @@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi
> > *hdmi)
> >  	return 0;
> >  }
> > 
> > -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)
> >  {
> > -	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> > -	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,
> > +			      HDMI_3D_TX_PHY_CPCE_CTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> > +			      HDMI_3D_TX_PHY_GMPCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> > +			      HDMI_3D_TX_PHY_CURRCTRL);
> > +
> > +	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> > +			      HDMI_3D_TX_PHY_MSM_CTRL);
> > +
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> > +			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> > +			      HDMI_3D_TX_PHY_VLEVCTRL);
> > +
> > +	/* Override and disable clock termination. */
> > +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> > +			      HDMI_3D_TX_PHY_CKCALCTRL);
> > +
> > +	return 0;
> > +}
> > +
> > +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
> > +{
> > +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> > +	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> > +	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
> > +	int ret;
> > 
> >  	dw_hdmi_phy_power_off(hdmi);
> > 
> > @@ -1042,26 +1076,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,
> > -			   HDMI_3D_TX_PHY_CPCE_CTRL);
> > -	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> > -			   HDMI_3D_TX_PHY_GMPCTRL);
> > -	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> > -			   HDMI_3D_TX_PHY_CURRCTRL);
> > -
> > -	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> > -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> > -			   HDMI_3D_TX_PHY_MSM_CTRL);
> > -
> > -	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> > -	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> > -			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
> > -	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> > -			   HDMI_3D_TX_PHY_VLEVCTRL);
> > -
> > -	/* Override and disable clock termination. */
> > -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> > -			   HDMI_3D_TX_PHY_CKCALCTRL);
> > +	/* Write to the PHY as configured by the platform */
> > +	if (pdata->configure_phy)
> > +		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
> > +	else
> > +		ret = phy->configure(hdmi, pdata, mpixelclock);
> > +	if (ret) {
> > +		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
> > +			mpixelclock);
> > +		return ret;
> > +	}
> > 
> >  	return dw_hdmi_phy_power_on(hdmi);
> >  }
> > @@ -1895,24 +1919,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",
> >  	}
> >  };
> > 
> > @@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
> >  			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
> >  			hdmi->phy.name = dw_hdmi_phys[i].name;
> >  			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
> > +
> > +			if (!dw_hdmi_phys[i].configure &&
> > +			    !hdmi->plat_data->configure_phy) {
> > +				dev_err(hdmi->dev, "%s requires platform
> > support\n",
> > +					hdmi->phy.name);
> > +				return -ENODEV;
> > +			}
> > +
> >  			return 0;
> >  		}
> >  	}
> > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > index 0f583ca7e66e..dd330259a3dc 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -78,6 +78,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);
> >  };
> >  
> >  int dw_hdmi_probe(struct platform_device *pdev,
> > @@ -91,4 +94,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__ */
> 
> Hmm, this is kind of confusing. Why do you need a phy_ops and
> then a separate configure_phy function? Can't we just use phy_ops
> always? If its external phy then it would need to implement all
> phy_ops functions.

The phy_ops are indeed meant to support vendor PHYs. The .configure_phy() 
operation is meant to support Synopsys PHYs that don't comply with the HDMI TX 
MHL and 3D PHYs I2C register layout and thus need a different configure 
function, but can share the other operations with the HDMI TX MHL and 3D PHYs. 
Ideally I'd like to move that code to the dw-hdmi core, but at the moment I 
don't have enough information to decide whether the register layout 
corresponds to the standard Synopsys HDMI TX 2.0 PHY or if it has been 
modified by the vendor. Once we'll have a second SoC using the same PHY we 
should have more information to consolidate the code. Of course, if you can 
share the HDMI TX 2.0 PHY datasheet, I won't mind reworking the code now ;-)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-02 13:41       ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 13:41 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Neil Armstrong, Kieran Bingham,
	dri-devel, linux-renesas-soc, Nickey Yang, Russell King,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 02 Mar 2017 12:50:13 Jose Abreu wrote:
> On 01-03-2017 22:39, Laurent Pinchart wrote:
> > 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 | 109 ++++++++++++++++++++++------------
> >  include/drm/bridge/dw_hdmi.h     |   7 +++
> >  2 files changed, 81 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/dw-hdmi.c index cb2703862be2..b835d81bb471
> > 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 {
> > @@ -860,8 +863,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);
> > @@ -873,6 +876,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)
> >  {
> > @@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi
> > *hdmi)
> >  	return 0;
> >  }
> > 
> > -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)
> >  {
> > -	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> > -	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,
> > +			      HDMI_3D_TX_PHY_CPCE_CTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> > +			      HDMI_3D_TX_PHY_GMPCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> > +			      HDMI_3D_TX_PHY_CURRCTRL);
> > +
> > +	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> > +			      HDMI_3D_TX_PHY_MSM_CTRL);
> > +
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> > +			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
> > +	dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> > +			      HDMI_3D_TX_PHY_VLEVCTRL);
> > +
> > +	/* Override and disable clock termination. */
> > +	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> > +			      HDMI_3D_TX_PHY_CKCALCTRL);
> > +
> > +	return 0;
> > +}
> > +
> > +static int hdmi_phy_configure(struct dw_hdmi *hdmi)
> > +{
> > +	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
> > +	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> > +	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
> > +	int ret;
> > 
> >  	dw_hdmi_phy_power_off(hdmi);
> > 
> > @@ -1042,26 +1076,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,
> > -			   HDMI_3D_TX_PHY_CPCE_CTRL);
> > -	hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
> > -			   HDMI_3D_TX_PHY_GMPCTRL);
> > -	hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
> > -			   HDMI_3D_TX_PHY_CURRCTRL);
> > -
> > -	hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
> > -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
> > -			   HDMI_3D_TX_PHY_MSM_CTRL);
> > -
> > -	hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
> > -	hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
> > -			   HDMI_3D_TX_PHY_CKSYMTXCTRL);
> > -	hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
> > -			   HDMI_3D_TX_PHY_VLEVCTRL);
> > -
> > -	/* Override and disable clock termination. */
> > -	hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
> > -			   HDMI_3D_TX_PHY_CKCALCTRL);
> > +	/* Write to the PHY as configured by the platform */
> > +	if (pdata->configure_phy)
> > +		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
> > +	else
> > +		ret = phy->configure(hdmi, pdata, mpixelclock);
> > +	if (ret) {
> > +		dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
> > +			mpixelclock);
> > +		return ret;
> > +	}
> > 
> >  	return dw_hdmi_phy_power_on(hdmi);
> >  }
> > @@ -1895,24 +1919,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",
> >  	}
> >  };
> > 
> > @@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
> >  			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
> >  			hdmi->phy.name = dw_hdmi_phys[i].name;
> >  			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
> > +
> > +			if (!dw_hdmi_phys[i].configure &&
> > +			    !hdmi->plat_data->configure_phy) {
> > +				dev_err(hdmi->dev, "%s requires platform
> > support\n",
> > +					hdmi->phy.name);
> > +				return -ENODEV;
> > +			}
> > +
> >  			return 0;
> >  		}
> >  	}
> > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > index 0f583ca7e66e..dd330259a3dc 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -78,6 +78,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);
> >  };
> >  
> >  int dw_hdmi_probe(struct platform_device *pdev,
> > @@ -91,4 +94,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__ */
> 
> Hmm, this is kind of confusing. Why do you need a phy_ops and
> then a separate configure_phy function? Can't we just use phy_ops
> always? If its external phy then it would need to implement all
> phy_ops functions.

The phy_ops are indeed meant to support vendor PHYs. The .configure_phy() 
operation is meant to support Synopsys PHYs that don't comply with the HDMI TX 
MHL and 3D PHYs I2C register layout and thus need a different configure 
function, but can share the other operations with the HDMI TX MHL and 3D PHYs. 
Ideally I'd like to move that code to the dw-hdmi core, but at the moment I 
don't have enough information to decide whether the register layout 
corresponds to the standard Synopsys HDMI TX 2.0 PHY or if it has been 
modified by the vendor. Once we'll have a second SoC using the same PHY we 
should have more information to consolidate the code. Of course, if you can 
share the HDMI TX 2.0 PHY datasheet, I won't mind reworking the code now ;-)

-- 
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] 52+ messages in thread

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-02 13:41       ` Laurent Pinchart
@ 2017-03-02 14:50         ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 14:50 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Laurent,


On 02-03-2017 13:41, Laurent Pinchart wrote:
>
>> Hmm, this is kind of confusing. Why do you need a phy_ops and
>> then a separate configure_phy function? Can't we just use phy_ops
>> always? If its external phy then it would need to implement all
>> phy_ops functions.
> The phy_ops are indeed meant to support vendor PHYs. The .configure_phy() 
> operation is meant to support Synopsys PHYs that don't comply with the HDMI TX 
> MHL and 3D PHYs I2C register layout and thus need a different configure 
> function, but can share the other operations with the HDMI TX MHL and 3D PHYs. 
> Ideally I'd like to move that code to the dw-hdmi core, but at the moment I 
> don't have enough information to decide whether the register layout 
> corresponds to the standard Synopsys HDMI TX 2.0 PHY or if it has been 
> modified by the vendor. Once we'll have a second SoC using the same PHY we 
> should have more information to consolidate the code. Of course, if you can 
> share the HDMI TX 2.0 PHY datasheet, I won't mind reworking the code now ;-)
>

Well, if I want to keep my job I can't share the datasheet, and I
do want to keep my job :)

As far as I know this shouldn't change much. I already used (it
was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY. But
I am not following your logic here, sorry: You are mentioning a
custom phy, right? If its custom then it should implement its own
phy_ops. And I don't think that phy logic should go into core,
this should all be extracted because I really believe it will
make the code easier to read. Imagine this organization:

    Folders/Files:
        drm/bridge/dw-hdmi/dw-hdmi-core.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
    Structures:
        dw_hdmi_pdata
        dw_hdmi_phy_pdata
        dw_hdmi_phy_ops

As the phy is interacted using controller we would need to pass
some callbacks to the phy, but ultimately the phy would be a
platform driver which could have its own compatible string that
would be associated with controller (not sure exactly about this
because I only used this in non-dt).

This is just an idea though. I followed this logic in the RX side
and its very easy to add a new phy now, its a matter of creating
a new file, implement ops and associate it with controller. Of
course some phys will be very similar, for that we can use minor
tweaks via id detection.

What do you think?

Best regards,
Jose Miguel Abreu

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-02 14:50         ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-02 14:50 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Laurent,


On 02-03-2017 13:41, Laurent Pinchart wrote:
>
>> Hmm, this is kind of confusing. Why do you need a phy_ops and
>> then a separate configure_phy function? Can't we just use phy_ops
>> always? If its external phy then it would need to implement all
>> phy_ops functions.
> The phy_ops are indeed meant to support vendor PHYs. The .configure_phy() 
> operation is meant to support Synopsys PHYs that don't comply with the HDMI TX 
> MHL and 3D PHYs I2C register layout and thus need a different configure 
> function, but can share the other operations with the HDMI TX MHL and 3D PHYs. 
> Ideally I'd like to move that code to the dw-hdmi core, but at the moment I 
> don't have enough information to decide whether the register layout 
> corresponds to the standard Synopsys HDMI TX 2.0 PHY or if it has been 
> modified by the vendor. Once we'll have a second SoC using the same PHY we 
> should have more information to consolidate the code. Of course, if you can 
> share the HDMI TX 2.0 PHY datasheet, I won't mind reworking the code now ;-)
>

Well, if I want to keep my job I can't share the datasheet, and I
do want to keep my job :)

As far as I know this shouldn't change much. I already used (it
was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY. But
I am not following your logic here, sorry: You are mentioning a
custom phy, right? If its custom then it should implement its own
phy_ops. And I don't think that phy logic should go into core,
this should all be extracted because I really believe it will
make the code easier to read. Imagine this organization:

    Folders/Files:
        drm/bridge/dw-hdmi/dw-hdmi-core.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
        drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
    Structures:
        dw_hdmi_pdata
        dw_hdmi_phy_pdata
        dw_hdmi_phy_ops

As the phy is interacted using controller we would need to pass
some callbacks to the phy, but ultimately the phy would be a
platform driver which could have its own compatible string that
would be associated with controller (not sure exactly about this
because I only used this in non-dt).

This is just an idea though. I followed this logic in the RX side
and its very easy to add a new phy now, its a matter of creating
a new file, implement ops and associate it with controller. Of
course some phys will be very similar, for that we can use minor
tweaks via id detection.

What do you think?

Best regards,
Jose Miguel Abreu

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-02 14:50         ` Jose Abreu
@ 2017-03-02 15:38           ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 15:38 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Jose,

On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
> On 02-03-2017 13:41, Laurent Pinchart wrote:
> >> Hmm, this is kind of confusing. Why do you need a phy_ops and
> >> then a separate configure_phy function? Can't we just use phy_ops
> >> always? If its external phy then it would need to implement all
> >> phy_ops functions.
> > 
> > The phy_ops are indeed meant to support vendor PHYs. The .configure_phy()
> > operation is meant to support Synopsys PHYs that don't comply with the
> > HDMI TX MHL and 3D PHYs I2C register layout and thus need a different
> > configure function, but can share the other operations with the HDMI TX
> > MHL and 3D PHYs. Ideally I'd like to move that code to the dw-hdmi core,
> > but at the moment I don't have enough information to decide whether the
> > register layout corresponds to the standard Synopsys HDMI TX 2.0 PHY or
> > if it has been modified by the vendor. Once we'll have a second SoC using
> > the same PHY we should have more information to consolidate the code. Of
> > course, if you can share the HDMI TX 2.0 PHY datasheet, I won't mind
> > reworking the code now ;-)
>
> Well, if I want to keep my job I can't share the datasheet, and I
> do want to keep my job :)

That's so selfish :-D

> As far as I know this shouldn't change much. I already used (it
> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.

I really wonder what exactly has been integrated in the Renesas R-Car Gen3 
SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the registers 
seem different compared to the 2.0 PHY you've tested.

> But I am not following your logic here, sorry: You are mentioning a
> custom phy, right?

Custom is probably a bad name. From what I've been told it's a standard 
Synopsys PHY, but I can't rule out vendor-specific customizations.

> If its custom then it should implement its own phy_ops. And I don't think
> that phy logic should go into core, this should all be extracted because I
> really believe it will make the code easier to read. Imagine this
> organization:
> 
>     Folders/Files:
>         drm/bridge/dw-hdmi/dw-hdmi-core.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
>     Structures:
>         dw_hdmi_pdata
>         dw_hdmi_phy_pdata
>         dw_hdmi_phy_ops

That looks good to me.

> As the phy is interacted using controller we would need to pass
> some callbacks to the phy, but ultimately the phy would be a
> platform driver which could have its own compatible string that
> would be associated with controller (not sure exactly about this
> because I only used this in non-dt).

We already have glue code, having to provide separate glue and PHY drivers 
seems a bit overkill to me. If we could get rid of glue code by adding a node 
for the PHY in DT that would be nice, but if we have to keep the glue then we 
can as well use platform data there.

> This is just an idea though. I followed this logic in the RX side
> and its very easy to add a new phy now, its a matter of creating
> a new file, implement ops and associate it with controller. Of
> course some phys will be very similar, for that we can use minor
> tweaks via id detection.
> 
> What do you think?

It sounds neat overall, but I wonder whether it should really block this 
series, or be added on top of it :-) I think we're already moving in the right 
direction here.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-02 15:38           ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-02 15:38 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Neil Armstrong, Kieran Bingham,
	dri-devel, linux-renesas-soc, Nickey Yang, Russell King,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
> On 02-03-2017 13:41, Laurent Pinchart wrote:
> >> Hmm, this is kind of confusing. Why do you need a phy_ops and
> >> then a separate configure_phy function? Can't we just use phy_ops
> >> always? If its external phy then it would need to implement all
> >> phy_ops functions.
> > 
> > The phy_ops are indeed meant to support vendor PHYs. The .configure_phy()
> > operation is meant to support Synopsys PHYs that don't comply with the
> > HDMI TX MHL and 3D PHYs I2C register layout and thus need a different
> > configure function, but can share the other operations with the HDMI TX
> > MHL and 3D PHYs. Ideally I'd like to move that code to the dw-hdmi core,
> > but at the moment I don't have enough information to decide whether the
> > register layout corresponds to the standard Synopsys HDMI TX 2.0 PHY or
> > if it has been modified by the vendor. Once we'll have a second SoC using
> > the same PHY we should have more information to consolidate the code. Of
> > course, if you can share the HDMI TX 2.0 PHY datasheet, I won't mind
> > reworking the code now ;-)
>
> Well, if I want to keep my job I can't share the datasheet, and I
> do want to keep my job :)

That's so selfish :-D

> As far as I know this shouldn't change much. I already used (it
> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.

I really wonder what exactly has been integrated in the Renesas R-Car Gen3 
SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the registers 
seem different compared to the 2.0 PHY you've tested.

> But I am not following your logic here, sorry: You are mentioning a
> custom phy, right?

Custom is probably a bad name. From what I've been told it's a standard 
Synopsys PHY, but I can't rule out vendor-specific customizations.

> If its custom then it should implement its own phy_ops. And I don't think
> that phy logic should go into core, this should all be extracted because I
> really believe it will make the code easier to read. Imagine this
> organization:
> 
>     Folders/Files:
>         drm/bridge/dw-hdmi/dw-hdmi-core.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
>     Structures:
>         dw_hdmi_pdata
>         dw_hdmi_phy_pdata
>         dw_hdmi_phy_ops

That looks good to me.

> As the phy is interacted using controller we would need to pass
> some callbacks to the phy, but ultimately the phy would be a
> platform driver which could have its own compatible string that
> would be associated with controller (not sure exactly about this
> because I only used this in non-dt).

We already have glue code, having to provide separate glue and PHY drivers 
seems a bit overkill to me. If we could get rid of glue code by adding a node 
for the PHY in DT that would be nice, but if we have to keep the glue then we 
can as well use platform data there.

> This is just an idea though. I followed this logic in the RX side
> and its very easy to add a new phy now, its a matter of creating
> a new file, implement ops and associate it with controller. Of
> course some phys will be very similar, for that we can use minor
> tweaks via id detection.
> 
> What do you think?

It sounds neat overall, but I wonder whether it should really block this 
series, or be added on top of it :-) I think we're already moving in the right 
direction here.

-- 
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] 52+ messages in thread

* Re: [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
  2017-03-01 22:39   ` Laurent Pinchart
@ 2017-03-03  6:30     ` Nickey.Yang
  -1 siblings, 0 replies; 52+ messages in thread
From: Nickey.Yang @ 2017-03-03  6:30 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


锟斤拷 2017锟斤拷03锟斤拷02锟斤拷 06:39, Laurent Pinchart 写锟斤拷:
> Most of the hdmi_phy_test_*() functions are unused. Remove them.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Tested-by: Nickey Yang <nickey.yang@rock-chips.com>

Best regards,
Nickey Yang
> ---
>   drivers/gpu/drm/bridge/dw-hdmi.c | 26 --------------------------
>   1 file changed, 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 9a9ec27d9e28..ce7496399ccf 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>   		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
>   }
>   
> -static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
> -					unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
> -		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
> -				       unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
> -		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
> -				     unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
> -}
> -
> -static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
> -				      unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
> -}
> -
>   static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
>   {
>   	u32 val;

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

* Re: [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions
@ 2017-03-03  6:30     ` Nickey.Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Nickey.Yang @ 2017-03-03  6:30 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Andy Yan, Fabio Estevam, Jose Abreu, Kieran Bingham,
	Neil Armstrong, Russell King, Vladimir Zapolskiy,
	linux-renesas-soc

Hi Laurent,


在 2017年03月02日 06:39, Laurent Pinchart 写道:
> Most of the hdmi_phy_test_*() functions are unused. Remove them.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Tested-by: Nickey Yang <nickey.yang@rock-chips.com>

Best regards,
Nickey Yang
> ---
>   drivers/gpu/drm/bridge/dw-hdmi.c | 26 --------------------------
>   1 file changed, 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index 9a9ec27d9e28..ce7496399ccf 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
>   		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
>   }
>   
> -static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
> -					unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
> -		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
> -				       unsigned char bit)
> -{
> -	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
> -		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
> -}
> -
> -static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
> -				     unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
> -}
> -
> -static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
> -				      unsigned char bit)
> -{
> -	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
> -}
> -
>   static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
>   {
>   	u32 val;

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-02 15:38           ` Laurent Pinchart
@ 2017-03-03 15:57             ` Jose Abreu
  -1 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-03 15:57 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Laurent,


On 02-03-2017 15:38, Laurent Pinchart wrote:
> Hi Jose,
>
> On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
>> On 02-03-2017 13:41, Laurent Pinchart wrote:
>>>> Hmm, this is kind of confusing. Why do you need a phy_ops and
>>>> then a separate configure_phy function? Can't we just use phy_ops
>>>> always? If its external phy then it would need to implement all
>>>> phy_ops functions.
>>> The phy_ops are indeed meant to support vendor PHYs. The .configure_phy()
>>> operation is meant to support Synopsys PHYs that don't comply with the
>>> HDMI TX MHL and 3D PHYs I2C register layout and thus need a different
>>> configure function, but can share the other operations with the HDMI TX
>>> MHL and 3D PHYs. Ideally I'd like to move that code to the dw-hdmi core,
>>> but at the moment I don't have enough information to decide whether the
>>> register layout corresponds to the standard Synopsys HDMI TX 2.0 PHY or
>>> if it has been modified by the vendor. Once we'll have a second SoC using
>>> the same PHY we should have more information to consolidate the code. Of
>>> course, if you can share the HDMI TX 2.0 PHY datasheet, I won't mind
>>> reworking the code now ;-)
>> Well, if I want to keep my job I can't share the datasheet, and I
>> do want to keep my job :)
> That's so selfish :-D
>
>> As far as I know this shouldn't change much. I already used (it
>> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.
> I really wonder what exactly has been integrated in the Renesas R-Car Gen3 
> SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the registers 
> seem different compared to the 2.0 PHY you've tested.
>
>> But I am not following your logic here, sorry: You are mentioning a
>> custom phy, right?
> Custom is probably a bad name. From what I've been told it's a standard 
> Synopsys PHY, but I can't rule out vendor-specific customizations.
>
>> If its custom then it should implement its own phy_ops. And I don't think
>> that phy logic should go into core, this should all be extracted because I
>> really believe it will make the code easier to read. Imagine this
>> organization:
>>
>>     Folders/Files:
>>         drm/bridge/dw-hdmi/dw-hdmi-core.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
>>     Structures:
>>         dw_hdmi_pdata
>>         dw_hdmi_phy_pdata
>>         dw_hdmi_phy_ops
> That looks good to me.
>
>> As the phy is interacted using controller we would need to pass
>> some callbacks to the phy, but ultimately the phy would be a
>> platform driver which could have its own compatible string that
>> would be associated with controller (not sure exactly about this
>> because I only used this in non-dt).
> We already have glue code, having to provide separate glue and PHY drivers 
> seems a bit overkill to me. If we could get rid of glue code by adding a node 
> for the PHY in DT that would be nice, but if we have to keep the glue then we 
> can as well use platform data there.
>
>> This is just an idea though. I followed this logic in the RX side
>> and its very easy to add a new phy now, its a matter of creating
>> a new file, implement ops and associate it with controller. Of
>> course some phys will be very similar, for that we can use minor
>> tweaks via id detection.
>>
>> What do you think?
> It sounds neat overall, but I wonder whether it should really block this 
> series, or be added on top of it :-) I think we're already moving in the right 
> direction here.
>

This series is definitely a good starting point and a good
improvement. We can think later about abstracting even more the
phy from the controller. I think this will be a major step and
will reflect better how the HW is modeled.

You can add my reviewed-by in all the patches in this series in
your next submission (or in the merge).

Also, if you do a next submission what do you think about moving
all the dw-hdmi files to a new folder called for example
'synopsys' or 'dw-hdmi'? Because we already have 5 files. I think
'synopsys' instead of 'dw-hdmi' would be better because in the
future we may add support for other protocols (for example
display port).

Side note: I think you missed in the cc Archit Taneja

Best regards,
Jose Miguel Abreu

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-03 15:57             ` Jose Abreu
  0 siblings, 0 replies; 52+ messages in thread
From: Jose Abreu @ 2017-03-03 15:57 UTC (permalink / raw)
  To: Laurent Pinchart, Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc

Hi Laurent,


On 02-03-2017 15:38, Laurent Pinchart wrote:
> Hi Jose,
>
> On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
>> On 02-03-2017 13:41, Laurent Pinchart wrote:
>>>> Hmm, this is kind of confusing. Why do you need a phy_ops and
>>>> then a separate configure_phy function? Can't we just use phy_ops
>>>> always? If its external phy then it would need to implement all
>>>> phy_ops functions.
>>> The phy_ops are indeed meant to support vendor PHYs. The .configure_phy()
>>> operation is meant to support Synopsys PHYs that don't comply with the
>>> HDMI TX MHL and 3D PHYs I2C register layout and thus need a different
>>> configure function, but can share the other operations with the HDMI TX
>>> MHL and 3D PHYs. Ideally I'd like to move that code to the dw-hdmi core,
>>> but at the moment I don't have enough information to decide whether the
>>> register layout corresponds to the standard Synopsys HDMI TX 2.0 PHY or
>>> if it has been modified by the vendor. Once we'll have a second SoC using
>>> the same PHY we should have more information to consolidate the code. Of
>>> course, if you can share the HDMI TX 2.0 PHY datasheet, I won't mind
>>> reworking the code now ;-)
>> Well, if I want to keep my job I can't share the datasheet, and I
>> do want to keep my job :)
> That's so selfish :-D
>
>> As far as I know this shouldn't change much. I already used (it
>> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.
> I really wonder what exactly has been integrated in the Renesas R-Car Gen3 
> SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the registers 
> seem different compared to the 2.0 PHY you've tested.
>
>> But I am not following your logic here, sorry: You are mentioning a
>> custom phy, right?
> Custom is probably a bad name. From what I've been told it's a standard 
> Synopsys PHY, but I can't rule out vendor-specific customizations.
>
>> If its custom then it should implement its own phy_ops. And I don't think
>> that phy logic should go into core, this should all be extracted because I
>> really believe it will make the code easier to read. Imagine this
>> organization:
>>
>>     Folders/Files:
>>         drm/bridge/dw-hdmi/dw-hdmi-core.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
>>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
>>     Structures:
>>         dw_hdmi_pdata
>>         dw_hdmi_phy_pdata
>>         dw_hdmi_phy_ops
> That looks good to me.
>
>> As the phy is interacted using controller we would need to pass
>> some callbacks to the phy, but ultimately the phy would be a
>> platform driver which could have its own compatible string that
>> would be associated with controller (not sure exactly about this
>> because I only used this in non-dt).
> We already have glue code, having to provide separate glue and PHY drivers 
> seems a bit overkill to me. If we could get rid of glue code by adding a node 
> for the PHY in DT that would be nice, but if we have to keep the glue then we 
> can as well use platform data there.
>
>> This is just an idea though. I followed this logic in the RX side
>> and its very easy to add a new phy now, its a matter of creating
>> a new file, implement ops and associate it with controller. Of
>> course some phys will be very similar, for that we can use minor
>> tweaks via id detection.
>>
>> What do you think?
> It sounds neat overall, but I wonder whether it should really block this 
> series, or be added on top of it :-) I think we're already moving in the right 
> direction here.
>

This series is definitely a good starting point and a good
improvement. We can think later about abstracting even more the
phy from the controller. I think this will be a major step and
will reflect better how the HW is modeled.

You can add my reviewed-by in all the patches in this series in
your next submission (or in the merge).

Also, if you do a next submission what do you think about moving
all the dw-hdmi files to a new folder called for example
'synopsys' or 'dw-hdmi'? Because we already have 5 files. I think
'synopsys' instead of 'dw-hdmi' would be better because in the
future we may add support for other protocols (for example
display port).

Side note: I think you missed in the cc Archit Taneja

Best regards,
Jose Miguel Abreu

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

* [PATCH] drm: bridge: dw-hdmi: Move the driver to a separate directory.
  2017-03-01 22:39 ` Laurent Pinchart
                   ` (10 preceding siblings ...)
  (?)
@ 2017-03-03 16:50 ` Laurent Pinchart
  2017-03-03 16:59   ` Jose Abreu
  -1 siblings, 1 reply; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-03 16:50 UTC (permalink / raw)
  To: dri-devel; +Cc: Jose Abreu

The driver is already made of 5 separate source files. Move it to a
newly created directory named synopsys where more Synopsys bridge
drivers can be added later (for the DisplayPort controller for
instance).

Suggested-by: Jose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/Kconfig                     |  2 ++
 drivers/gpu/drm/bridge/Makefile                    |  4 +---
 drivers/gpu/drm/bridge/synopsys/Kconfig            | 23 ++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/Makefile           |  5 +++++
 .../drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c  |  0
 .../gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h  |  0
 .../drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c  |  0
 drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c    |  0
 drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h    |  0
 9 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/synopsys/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/synopsys/Makefile
 rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c (100%)
 rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h (100%)
 rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c (100%)
 rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c (100%)
 rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h (100%)

Hi Jose,

Here's the patch you've requested, to be applied on top of the
"[PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support" series.

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index eb8688ec6f18..68ceba083ca1 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -101,4 +101,6 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 
+source "drivers/gpu/drm/bridge/synopsys/Kconfig"
+
 endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 2e83a7855399..103f82e63102 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -2,9 +2,6 @@ ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
-obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
-obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
-obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
@@ -13,3 +10,4 @@ obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
 obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
 obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
+obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
new file mode 100644
index 000000000000..4d260755f010
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -0,0 +1,23 @@
+config DRM_DW_HDMI
+	tristate
+	select DRM_KMS_HELPER
+
+config DRM_DW_HDMI_AHB_AUDIO
+	tristate "Synopsis Designware AHB Audio interface"
+	depends on DRM_DW_HDMI && SND
+	select SND_PCM
+	select SND_PCM_ELD
+	select SND_PCM_IEC958
+	help
+	  Support the AHB Audio interface which is part of the Synopsis
+	  Designware HDMI block.  This is used in conjunction with
+	  the i.MX6 HDMI driver.
+
+config DRM_DW_HDMI_I2S_AUDIO
+	tristate "Synopsis Designware I2S Audio interface"
+	depends on SND_SOC
+	depends on DRM_DW_HDMI
+	select SND_SOC_HDMI_CODEC
+	help
+	  Support the I2S Audio interface which is part of the Synopsis
+	  Designware HDMI block.
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
new file mode 100644
index 000000000000..17aa7a65b57e
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -0,0 +1,5 @@
+#ccflags-y := -Iinclude/drm
+
+obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
diff --git a/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
similarity index 100%
rename from drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
similarity index 100%
rename from drivers/gpu/drm/bridge/dw-hdmi-audio.h
rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
similarity index 100%
rename from drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
similarity index 100%
rename from drivers/gpu/drm/bridge/dw-hdmi.c
rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
similarity index 100%
rename from drivers/gpu/drm/bridge/dw-hdmi.h
rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
-- 
Regards,

Laurent Pinchart

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

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
  2017-03-03 15:57             ` Jose Abreu
@ 2017-03-03 16:56               ` Laurent Pinchart
  -1 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-03 16:56 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Laurent Pinchart, dri-devel, Andy Yan, Fabio Estevam,
	Kieran Bingham, Neil Armstrong, Nickey Yang, Russell King,
	Vladimir Zapolskiy, linux-renesas-soc, Archit Taneja

Hi Jose,

(CC'ing Archit)

On Friday 03 Mar 2017 15:57:57 Jose Abreu wrote:
> On 02-03-2017 15:38, Laurent Pinchart wrote:
> > On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
> >> On 02-03-2017 13:41, Laurent Pinchart wrote:
> >>>> Hmm, this is kind of confusing. Why do you need a phy_ops and
> >>>> then a separate configure_phy function? Can't we just use phy_ops
> >>>> always? If its external phy then it would need to implement all
> >>>> phy_ops functions.
> >>> 
> >>> The phy_ops are indeed meant to support vendor PHYs. The
> >>> .configure_phy() operation is meant to support Synopsys PHYs that don't
> >>> comply with the HDMI TX MHL and 3D PHYs I2C register layout and thus
> >>> need a different configure function, but can share the other operations
> >>> with the HDMI TX MHL and 3D PHYs. Ideally I'd like to move that code to
> >>> the dw-hdmi core, but at the moment I don't have enough information to
> >>> decide whether the register layout corresponds to the standard Synopsys
> >>> HDMI TX 2.0 PHY or if it has been modified by the vendor. Once we'll
> >>> have a second SoC using the same PHY we should have more information to
> >>> consolidate the code. Of course, if you can share the HDMI TX 2.0 PHY
> >>> datasheet, I won't mind reworking the code now ;-)
> >> 
> >> Well, if I want to keep my job I can't share the datasheet, and I
> >> do want to keep my job :)
> > 
> > That's so selfish :-D
> > 
> >> As far as I know this shouldn't change much. I already used (it
> >> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.
> > 
> > I really wonder what exactly has been integrated in the Renesas R-Car Gen3
> > SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the
> > registers seem different compared to the 2.0 PHY you've tested.
> > 
> >> But I am not following your logic here, sorry: You are mentioning a
> >> custom phy, right?
> > 
> > Custom is probably a bad name. From what I've been told it's a standard
> > Synopsys PHY, but I can't rule out vendor-specific customizations.
> > 
> >> If its custom then it should implement its own phy_ops. And I don't think
> >> that phy logic should go into core, this should all be extracted because
> >> I really believe it will make the code easier to read. Imagine this
> >> 
> >> organization:
> >>     Folders/Files:
> >>         drm/bridge/dw-hdmi/dw-hdmi-core.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
> >>     
> >>     Structures:
> >>         dw_hdmi_pdata
> >>         dw_hdmi_phy_pdata
> >>         dw_hdmi_phy_ops
> > 
> > That looks good to me.
> > 
> >> As the phy is interacted using controller we would need to pass
> >> some callbacks to the phy, but ultimately the phy would be a
> >> platform driver which could have its own compatible string that
> >> would be associated with controller (not sure exactly about this
> >> because I only used this in non-dt).
> > 
> > We already have glue code, having to provide separate glue and PHY drivers
> > seems a bit overkill to me. If we could get rid of glue code by adding a
> > node for the PHY in DT that would be nice, but if we have to keep the
> > glue then we can as well use platform data there.
> > 
> >> This is just an idea though. I followed this logic in the RX side
> >> and its very easy to add a new phy now, its a matter of creating
> >> a new file, implement ops and associate it with controller. Of
> >> course some phys will be very similar, for that we can use minor
> >> tweaks via id detection.
> >> 
> >> What do you think?
> > 
> > It sounds neat overall, but I wonder whether it should really block this
> > series, or be added on top of it :-) I think we're already moving in the
> > right direction here.
> 
> This series is definitely a good starting point and a good
> improvement. We can think later about abstracting even more the
> phy from the controller. I think this will be a major step and
> will reflect better how the HW is modeled.
> 
> You can add my reviewed-by in all the patches in this series in
> your next submission (or in the merge).

Thank you !

> Also, if you do a next submission what do you think about moving
> all the dw-hdmi files to a new folder called for example
> 'synopsys' or 'dw-hdmi'? Because we already have 5 files. I think
> 'synopsys' instead of 'dw-hdmi' would be better because in the
> future we may add support for other protocols (for example
> display port).

I've posted a patch for that.

> Side note: I think you missed in the cc Archit Taneja

Oops, indeed :-/ Fixed on this patch, and I'll make sure to CC him on v5.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration
@ 2017-03-03 16:56               ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-03 16:56 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Fabio Estevam, Laurent Pinchart, Neil Armstrong, Kieran Bingham,
	dri-devel, linux-renesas-soc, Nickey Yang, Russell King,
	Andy Yan, Vladimir Zapolskiy

Hi Jose,

(CC'ing Archit)

On Friday 03 Mar 2017 15:57:57 Jose Abreu wrote:
> On 02-03-2017 15:38, Laurent Pinchart wrote:
> > On Thursday 02 Mar 2017 14:50:02 Jose Abreu wrote:
> >> On 02-03-2017 13:41, Laurent Pinchart wrote:
> >>>> Hmm, this is kind of confusing. Why do you need a phy_ops and
> >>>> then a separate configure_phy function? Can't we just use phy_ops
> >>>> always? If its external phy then it would need to implement all
> >>>> phy_ops functions.
> >>> 
> >>> The phy_ops are indeed meant to support vendor PHYs. The
> >>> .configure_phy() operation is meant to support Synopsys PHYs that don't
> >>> comply with the HDMI TX MHL and 3D PHYs I2C register layout and thus
> >>> need a different configure function, but can share the other operations
> >>> with the HDMI TX MHL and 3D PHYs. Ideally I'd like to move that code to
> >>> the dw-hdmi core, but at the moment I don't have enough information to
> >>> decide whether the register layout corresponds to the standard Synopsys
> >>> HDMI TX 2.0 PHY or if it has been modified by the vendor. Once we'll
> >>> have a second SoC using the same PHY we should have more information to
> >>> consolidate the code. Of course, if you can share the HDMI TX 2.0 PHY
> >>> datasheet, I won't mind reworking the code now ;-)
> >> 
> >> Well, if I want to keep my job I can't share the datasheet, and I
> >> do want to keep my job :)
> > 
> > That's so selfish :-D
> > 
> >> As far as I know this shouldn't change much. I already used (it
> >> was like a year ago) the dw-hdmi driver in a HDMI TX 2.0 PHY.
> > 
> > I really wonder what exactly has been integrated in the Renesas R-Car Gen3
> > SoC. The PHY is certainly reported as an HDMI TX 2.0 PHY, but the
> > registers seem different compared to the 2.0 PHY you've tested.
> > 
> >> But I am not following your logic here, sorry: You are mentioning a
> >> custom phy, right?
> > 
> > Custom is probably a bad name. From what I've been told it's a standard
> > Synopsys PHY, but I can't rule out vendor-specific customizations.
> > 
> >> If its custom then it should implement its own phy_ops. And I don't think
> >> that phy logic should go into core, this should all be extracted because
> >> I really believe it will make the code easier to read. Imagine this
> >> 
> >> organization:
> >>     Folders/Files:
> >>         drm/bridge/dw-hdmi/dw-hdmi-core.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-synopsys.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-*renesas*.c
> >>         drm/bridge/dw-hdmi/dw-hdmi-phy-something.c
> >>     
> >>     Structures:
> >>         dw_hdmi_pdata
> >>         dw_hdmi_phy_pdata
> >>         dw_hdmi_phy_ops
> > 
> > That looks good to me.
> > 
> >> As the phy is interacted using controller we would need to pass
> >> some callbacks to the phy, but ultimately the phy would be a
> >> platform driver which could have its own compatible string that
> >> would be associated with controller (not sure exactly about this
> >> because I only used this in non-dt).
> > 
> > We already have glue code, having to provide separate glue and PHY drivers
> > seems a bit overkill to me. If we could get rid of glue code by adding a
> > node for the PHY in DT that would be nice, but if we have to keep the
> > glue then we can as well use platform data there.
> > 
> >> This is just an idea though. I followed this logic in the RX side
> >> and its very easy to add a new phy now, its a matter of creating
> >> a new file, implement ops and associate it with controller. Of
> >> course some phys will be very similar, for that we can use minor
> >> tweaks via id detection.
> >> 
> >> What do you think?
> > 
> > It sounds neat overall, but I wonder whether it should really block this
> > series, or be added on top of it :-) I think we're already moving in the
> > right direction here.
> 
> This series is definitely a good starting point and a good
> improvement. We can think later about abstracting even more the
> phy from the controller. I think this will be a major step and
> will reflect better how the HW is modeled.
> 
> You can add my reviewed-by in all the patches in this series in
> your next submission (or in the merge).

Thank you !

> Also, if you do a next submission what do you think about moving
> all the dw-hdmi files to a new folder called for example
> 'synopsys' or 'dw-hdmi'? Because we already have 5 files. I think
> 'synopsys' instead of 'dw-hdmi' would be better because in the
> future we may add support for other protocols (for example
> display port).

I've posted a patch for that.

> Side note: I think you missed in the cc Archit Taneja

Oops, indeed :-/ Fixed on this patch, and I'll make sure to CC him on v5.

-- 
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] 52+ messages in thread

* Re: [PATCH] drm: bridge: dw-hdmi: Move the driver to a separate directory.
  2017-03-03 16:50 ` [PATCH] drm: bridge: dw-hdmi: Move the driver to a separate directory Laurent Pinchart
@ 2017-03-03 16:59   ` Jose Abreu
  2017-03-03 17:04     ` Laurent Pinchart
  0 siblings, 1 reply; 52+ messages in thread
From: Jose Abreu @ 2017-03-03 16:59 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel

Hi Laurent,


On 03-03-2017 16:50, Laurent Pinchart wrote:
> The driver is already made of 5 separate source files. Move it to a
> newly created directory named synopsys where more Synopsys bridge
> drivers can be added later (for the DisplayPort controller for
> instance).
>
> Suggested-by: Jose Abreu <Jose.Abreu@synopsys.com>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Thanks a lot!

There are typo errors (which were there before, I just noticed
them now), please see bellow.

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

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/Kconfig                     |  2 ++
>  drivers/gpu/drm/bridge/Makefile                    |  4 +---
>  drivers/gpu/drm/bridge/synopsys/Kconfig            | 23 ++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/Makefile           |  5 +++++
>  .../drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c  |  0
>  .../gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h  |  0
>  .../drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c  |  0
>  drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c    |  0
>  drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h    |  0
>  9 files changed, 31 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/Kconfig
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/Makefile
>  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c (100%)
>  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h (100%)
>  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c (100%)
>  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c (100%)
>  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h (100%)
>
> Hi Jose,
>
> Here's the patch you've requested, to be applied on top of the
> "[PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support" series.
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index eb8688ec6f18..68ceba083ca1 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -101,4 +101,6 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
>  
>  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
>  
> +source "drivers/gpu/drm/bridge/synopsys/Kconfig"
> +
>  endmenu
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 2e83a7855399..103f82e63102 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -2,9 +2,6 @@ ccflags-y := -Iinclude/drm
>  
>  obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
>  obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
> -obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> -obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> -obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>  obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
>  obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
>  obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
> @@ -13,3 +10,4 @@ obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
>  obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
>  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
>  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> +obj-y += synopsys/
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> new file mode 100644
> index 000000000000..4d260755f010
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -0,0 +1,23 @@
> +config DRM_DW_HDMI
> +	tristate
> +	select DRM_KMS_HELPER
> +
> +config DRM_DW_HDMI_AHB_AUDIO
> +	tristate "Synopsis Designware AHB Audio interface"

"Synopsis" -> "Synopsys"

> +	depends on DRM_DW_HDMI && SND
> +	select SND_PCM
> +	select SND_PCM_ELD
> +	select SND_PCM_IEC958
> +	help
> +	  Support the AHB Audio interface which is part of the Synopsis

"Synopsis" -> "Synopsys"
> +	  Designware HDMI block.  This is used in conjunction with
> +	  the i.MX6 HDMI driver.
> +
> +config DRM_DW_HDMI_I2S_AUDIO
> +	tristate "Synopsis Designware I2S Audio interface"

"Synopsis" -> "Synopsys"

> +	depends on SND_SOC
> +	depends on DRM_DW_HDMI
> +	select SND_SOC_HDMI_CODEC
> +	help
> +	  Support the I2S Audio interface which is part of the Synopsis

"Synopsis" -> "Synopsys"

> +	  Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> new file mode 100644
> index 000000000000..17aa7a65b57e
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -0,0 +1,5 @@
> +#ccflags-y := -Iinclude/drm
> +
> +obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> +obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
> similarity index 100%
> rename from drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
> rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
> similarity index 100%
> rename from drivers/gpu/drm/bridge/dw-hdmi-audio.h
> rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> similarity index 100%
> rename from drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
> rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> similarity index 100%
> rename from drivers/gpu/drm/bridge/dw-hdmi.c
> rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> similarity index 100%
> rename from drivers/gpu/drm/bridge/dw-hdmi.h
> rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.h

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

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

* Re: [PATCH] drm: bridge: dw-hdmi: Move the driver to a separate directory.
  2017-03-03 16:59   ` Jose Abreu
@ 2017-03-03 17:04     ` Laurent Pinchart
  0 siblings, 0 replies; 52+ messages in thread
From: Laurent Pinchart @ 2017-03-03 17:04 UTC (permalink / raw)
  To: Jose Abreu; +Cc: Laurent Pinchart, dri-devel

Hi Jose,

On Friday 03 Mar 2017 16:59:51 Jose Abreu wrote:
> On 03-03-2017 16:50, Laurent Pinchart wrote:
> > The driver is already made of 5 separate source files. Move it to a
> > newly created directory named synopsys where more Synopsys bridge
> > drivers can be added later (for the DisplayPort controller for
> > instance).
> > 
> > Suggested-by: Jose Abreu <Jose.Abreu@synopsys.com>
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> Thanks a lot!
> 
> There are typo errors (which were there before, I just noticed
> them now), please see bellow.

Oops. Will be fixed in v5. Thanks for the review.

> Reviewed-by: Jose Abreu <joabreu@synopsys.com>
> 
> Best regards,
> Jose Miguel Abreu
> 
> > ---
> > 
> >  drivers/gpu/drm/bridge/Kconfig                     |  2 ++
> >  drivers/gpu/drm/bridge/Makefile                    |  4 +---
> >  drivers/gpu/drm/bridge/synopsys/Kconfig            | 23
> >  ++++++++++++++++++++++ drivers/gpu/drm/bridge/synopsys/Makefile         
> >   |  5 +++++
> >  .../drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c  |  0
> >  .../gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h  |  0
> >  .../drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c  |  0
> >  drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c    |  0
> >  drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h    |  0
> >  9 files changed, 31 insertions(+), 3 deletions(-)
> >  create mode 100644 drivers/gpu/drm/bridge/synopsys/Kconfig
> >  create mode 100644 drivers/gpu/drm/bridge/synopsys/Makefile
> >  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-ahb-audio.c (100%)
> >  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-audio.h (100%)
> >  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi-i2s-audio.c (100%)
> >  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.c (100%)
> >  rename drivers/gpu/drm/bridge/{ => synopsys}/dw-hdmi.h (100%)
> > 
> > Hi Jose,
> > 
> > Here's the patch you've requested, to be applied on top of the
> > "[PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support" series.
> > 
> > diff --git a/drivers/gpu/drm/bridge/Kconfig
> > b/drivers/gpu/drm/bridge/Kconfig index eb8688ec6f18..68ceba083ca1 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -101,4 +101,6 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
> > 
> >  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> > 
> > +source "drivers/gpu/drm/bridge/synopsys/Kconfig"
> > +
> > 
> >  endmenu
> > 
> > diff --git a/drivers/gpu/drm/bridge/Makefile
> > b/drivers/gpu/drm/bridge/Makefile index 2e83a7855399..103f82e63102 100644
> > --- a/drivers/gpu/drm/bridge/Makefile
> > +++ b/drivers/gpu/drm/bridge/Makefile
> > @@ -2,9 +2,6 @@ ccflags-y := -Iinclude/drm
> > 
> >  obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
> >  obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
> > 
> > -obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> > -obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> > -obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> > 
> >  obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
> >  obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
> >  obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
> > 
> > @@ -13,3 +10,4 @@ obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
> > 
> >  obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> >  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
> >  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> > 
> > +obj-y += synopsys/
> > diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
> > b/drivers/gpu/drm/bridge/synopsys/Kconfig new file mode 100644
> > index 000000000000..4d260755f010
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > @@ -0,0 +1,23 @@
> > +config DRM_DW_HDMI
> > +	tristate
> > +	select DRM_KMS_HELPER
> > +
> > +config DRM_DW_HDMI_AHB_AUDIO
> > +	tristate "Synopsis Designware AHB Audio interface"
> 
> "Synopsis" -> "Synopsys"
> 
> > +	depends on DRM_DW_HDMI && SND
> > +	select SND_PCM
> > +	select SND_PCM_ELD
> > +	select SND_PCM_IEC958
> > +	help
> > +	  Support the AHB Audio interface which is part of the Synopsis
> 
> "Synopsis" -> "Synopsys"
> 
> > +	  Designware HDMI block.  This is used in conjunction with
> > +	  the i.MX6 HDMI driver.
> > +
> > +config DRM_DW_HDMI_I2S_AUDIO
> > +	tristate "Synopsis Designware I2S Audio interface"
> 
> "Synopsis" -> "Synopsys"
> 
> > +	depends on SND_SOC
> > +	depends on DRM_DW_HDMI
> > +	select SND_SOC_HDMI_CODEC
> > +	help
> > +	  Support the I2S Audio interface which is part of the Synopsis
> 
> "Synopsis" -> "Synopsys"
> 
> > +	  Designware HDMI block.
> > diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
> > b/drivers/gpu/drm/bridge/synopsys/Makefile new file mode 100644
> > index 000000000000..17aa7a65b57e
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> > @@ -0,0 +1,5 @@
> > +#ccflags-y := -Iinclude/drm
> > +
> > +obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> > +obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> > +obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c similarity index
> > 100%
> > rename from drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
> > rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h similarity index 100%
> > rename from drivers/gpu/drm/bridge/dw-hdmi-audio.h
> > rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c similarity index
> > 100%
> > rename from drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
> > rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c similarity index 100%
> > rename from drivers/gpu/drm/bridge/dw-hdmi.c
> > rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h similarity index 100%
> > rename from drivers/gpu/drm/bridge/dw-hdmi.h
> > rename to drivers/gpu/drm/bridge/synopsys/dw-hdmi.h

-- 
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] 52+ messages in thread

end of thread, other threads:[~2017-03-03 19:59 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-01 22:39 [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support Laurent Pinchart
2017-03-01 22:39 ` Laurent Pinchart
2017-03-01 22:39 ` [PATCH v4 1/9] drm: bridge: dw-hdmi: Remove unused functions Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:19   ` Jose Abreu
2017-03-02 12:19     ` Jose Abreu
2017-03-03  6:30   ` Nickey.Yang
2017-03-03  6:30     ` Nickey.Yang
2017-03-01 22:39 ` [PATCH v4 2/9] drm: bridge: dw-hdmi: Move CSC configuration out of PHY code Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:21   ` Jose Abreu
2017-03-02 12:21     ` Jose Abreu
2017-03-01 22:39 ` [PATCH v4 3/9] drm: bridge: dw-hdmi: Enable CSC even for DVI Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-01 22:39 ` [PATCH v4 4/9] drm: bridge: dw-hdmi: Fix the PHY power down sequence Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:27   ` Jose Abreu
2017-03-02 12:27     ` Jose Abreu
2017-03-01 22:39 ` [PATCH v4 5/9] drm: bridge: dw-hdmi: Fix the PHY power up sequence Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:30   ` Jose Abreu
2017-03-02 12:30     ` Jose Abreu
2017-03-01 22:39 ` [PATCH v4 6/9] drm: bridge: dw-hdmi: Create PHY operations Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:34   ` Jose Abreu
2017-03-02 12:34     ` Jose Abreu
2017-03-01 22:39 ` [PATCH v4 7/9] drm: bridge: dw-hdmi: Add support for custom PHY configuration Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:50   ` Jose Abreu
2017-03-02 12:50     ` Jose Abreu
2017-03-02 13:41     ` Laurent Pinchart
2017-03-02 13:41       ` Laurent Pinchart
2017-03-02 14:50       ` Jose Abreu
2017-03-02 14:50         ` Jose Abreu
2017-03-02 15:38         ` Laurent Pinchart
2017-03-02 15:38           ` Laurent Pinchart
2017-03-03 15:57           ` Jose Abreu
2017-03-03 15:57             ` Jose Abreu
2017-03-03 16:56             ` Laurent Pinchart
2017-03-03 16:56               ` Laurent Pinchart
2017-03-01 22:39 ` [PATCH v4 8/9] drm: bridge: dw-hdmi: Remove device type from platform data Laurent Pinchart
2017-03-01 22:39   ` Laurent Pinchart
2017-03-02 12:51   ` Jose Abreu
2017-03-02 12:51     ` Jose Abreu
2017-03-01 22:39 ` [PATCH v4 9/9] drm: bridge: dw-hdmi: Switch to regmap for register access Laurent Pinchart
2017-03-02 11:27 ` [PATCH v4 0/9] drm: bridge: dw-hdmi: Refactor PHY support Neil Armstrong
2017-03-02 11:27   ` Neil Armstrong
2017-03-02 11:30   ` Laurent Pinchart
2017-03-02 11:30     ` Laurent Pinchart
2017-03-03 16:50 ` [PATCH] drm: bridge: dw-hdmi: Move the driver to a separate directory Laurent Pinchart
2017-03-03 16:59   ` Jose Abreu
2017-03-03 17:04     ` 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.