All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v15 0/12] dw-hdmi: convert imx hdmi to bridge/dw_hdmi
@ 2014-12-02  7:36 ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:36 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan


We found Freescale imx6 and Rockchip rk3288 and Ingenic JZ4780 (Xburst/MIPS)
use the interface compatible Designware HDMI IP, but they also have some
lightly differences, such as phy pll configuration, register width(imx hdmi
register is one byte, but rk3288 is 4 bytes width and can only be accessed
by word), 4K support(imx6 doesn't support 4k, but rk3288 does), and HDMI2.0
support.

To reuse the imx-hdmi driver, we make this patch set:
(1): fix some CodingStyle warning to make checkpatch happy
(2): convert imx-hdmi to drm_bridge
(3): split platform specific code
(4): move imx-hdmi to bridge/dw_hdmi
(5): extend dw_hdmi.c to support rk3288 hdmi
(6): add rockchip rk3288 platform specific code dw_hdmi-rockchip.c

Changes in v15:
- add prefix dw_hdmi/DW_HDMI for public used dw_hdmi structs
  adviced by Philipp Zabel
- remove THIS_MODULE in platform driver
- remove unio of the multi-byte register access, adviced by Philipp Zabel

Changes in v14:
- add defer probing, adviced by Philipp Zabel
- remove drm_connector_register, because imx-drm core has registered
connector

Changes in v13:
- patch against drm-next
- split platform specific phy configuration
- split phy configuration from patch#4

Changes in v12:
- refactor of_node_put(ddc_node)
- squash patch <convert dw_hdmi to drm_bridge>
- add comment for the depend on patch

Changes in v11:
- squash patch  <split some phy configuration to platform driver>

Changes in v10:
- split generic dw_hdmi.c improvements from patch#11 (add rk3288 support)
- add more display mode support mpll configuration for rk3288

Changes in v9:
- move some phy configuration to platform driver

Changes in v8:
- correct some spelling mistake
- modify ddc-i2c-bus and interrupt description
- Add documentation for rockchip dw hdmi

Changes in v7:
- remove unused variables from structure dw_hdmi
- remove a wrong modification
- add copyrights for dw_hdmi-imx.c

Changes in v6:
- rearrange the patch order
- refactor register access without reg_shift

Changes in v5:
- refactor reg-io-width

Changes in v4:
- fix checkpatch CHECK
- defer probe ddc i2c adapter

Changes in v3:
- split multi-register access to one indepent patch

Andy Yan (12):
  drm: imx: imx-hdmi: make checkpatch happy
  drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter
  drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode
  drm: imx: imx-hdmi: split phy configuration to platform driver
  drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
  dt-bindings: add document for dw_hdmi
  drm: bridge/dw_hdmi: add support for multi-byte register width access
  drm: bridge/dw_hdmi: add mode_valid support
  drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
  drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare
  dt-bindings: Add documentation for rockchip dw hdmi
  drm: bridge/dw_hdmi: add rockchip rk3288 support

 .../devicetree/bindings/drm/bridge/dw_hdmi.txt     |  40 ++
 .../devicetree/bindings/video/dw_hdmi-rockchip.txt |  43 ++
 drivers/gpu/drm/bridge/Kconfig                     |   5 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 .../gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c}   | 745 +++++++++------------
 .../gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h}   |   4 +-
 drivers/gpu/drm/imx/Kconfig                        |   1 +
 drivers/gpu/drm/imx/Makefile                       |   2 +-
 drivers/gpu/drm/imx/dw_hdmi-imx.c                  | 280 ++++++++
 drivers/gpu/drm/rockchip/Kconfig                   |  10 +
 drivers/gpu/drm/rockchip/Makefile                  |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        | 354 ++++++++++
 include/drm/bridge/dw_hdmi.h                       |  60 ++
 13 files changed, 1129 insertions(+), 418 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
 create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
 rename drivers/gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c} (71%)
 rename drivers/gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h} (99%)
 create mode 100644 drivers/gpu/drm/imx/dw_hdmi-imx.c
 create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
 create mode 100644 include/drm/bridge/dw_hdmi.h

-- 
1.9.1



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

* [PATCH v15 0/12] dw-hdmi: convert imx hdmi to bridge/dw_hdmi
@ 2014-12-02  7:36 ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:36 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, Philipp Zabel, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	djkurtz-hpIqsD4AKlfQT0dZR+AlfA, ykk-TNX95d0MmH7DzftRWevZcw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	jay.xu-TNX95d0MmH7DzftRWevZcw, Pawel Moll,
	mark.yao-TNX95d0MmH7DzftRWevZcw, Mark Rutland,
	vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA, Ian Campbell,
	Kumar Gala, Andy Yan


We found Freescale imx6 and Rockchip rk3288 and Ingenic JZ4780 (Xburst/MIPS)
use the interface compatible Designware HDMI IP, but they also have some
lightly differences, such as phy pll configuration, register width(imx hdmi
register is one byte, but rk3288 is 4 bytes width and can only be accessed
by word), 4K support(imx6 doesn't support 4k, but rk3288 does), and HDMI2.0
support.

To reuse the imx-hdmi driver, we make this patch set:
(1): fix some CodingStyle warning to make checkpatch happy
(2): convert imx-hdmi to drm_bridge
(3): split platform specific code
(4): move imx-hdmi to bridge/dw_hdmi
(5): extend dw_hdmi.c to support rk3288 hdmi
(6): add rockchip rk3288 platform specific code dw_hdmi-rockchip.c

Changes in v15:
- add prefix dw_hdmi/DW_HDMI for public used dw_hdmi structs
  adviced by Philipp Zabel
- remove THIS_MODULE in platform driver
- remove unio of the multi-byte register access, adviced by Philipp Zabel

Changes in v14:
- add defer probing, adviced by Philipp Zabel
- remove drm_connector_register, because imx-drm core has registered
connector

Changes in v13:
- patch against drm-next
- split platform specific phy configuration
- split phy configuration from patch#4

Changes in v12:
- refactor of_node_put(ddc_node)
- squash patch <convert dw_hdmi to drm_bridge>
- add comment for the depend on patch

Changes in v11:
- squash patch  <split some phy configuration to platform driver>

Changes in v10:
- split generic dw_hdmi.c improvements from patch#11 (add rk3288 support)
- add more display mode support mpll configuration for rk3288

Changes in v9:
- move some phy configuration to platform driver

Changes in v8:
- correct some spelling mistake
- modify ddc-i2c-bus and interrupt description
- Add documentation for rockchip dw hdmi

Changes in v7:
- remove unused variables from structure dw_hdmi
- remove a wrong modification
- add copyrights for dw_hdmi-imx.c

Changes in v6:
- rearrange the patch order
- refactor register access without reg_shift

Changes in v5:
- refactor reg-io-width

Changes in v4:
- fix checkpatch CHECK
- defer probe ddc i2c adapter

Changes in v3:
- split multi-register access to one indepent patch

Andy Yan (12):
  drm: imx: imx-hdmi: make checkpatch happy
  drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter
  drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode
  drm: imx: imx-hdmi: split phy configuration to platform driver
  drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
  dt-bindings: add document for dw_hdmi
  drm: bridge/dw_hdmi: add support for multi-byte register width access
  drm: bridge/dw_hdmi: add mode_valid support
  drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
  drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare
  dt-bindings: Add documentation for rockchip dw hdmi
  drm: bridge/dw_hdmi: add rockchip rk3288 support

 .../devicetree/bindings/drm/bridge/dw_hdmi.txt     |  40 ++
 .../devicetree/bindings/video/dw_hdmi-rockchip.txt |  43 ++
 drivers/gpu/drm/bridge/Kconfig                     |   5 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 .../gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c}   | 745 +++++++++------------
 .../gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h}   |   4 +-
 drivers/gpu/drm/imx/Kconfig                        |   1 +
 drivers/gpu/drm/imx/Makefile                       |   2 +-
 drivers/gpu/drm/imx/dw_hdmi-imx.c                  | 280 ++++++++
 drivers/gpu/drm/rockchip/Kconfig                   |  10 +
 drivers/gpu/drm/rockchip/Makefile                  |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        | 354 ++++++++++
 include/drm/bridge/dw_hdmi.h                       |  60 ++
 13 files changed, 1129 insertions(+), 418 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
 create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
 rename drivers/gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c} (71%)
 rename drivers/gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h} (99%)
 create mode 100644 drivers/gpu/drm/imx/dw_hdmi-imx.c
 create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
 create mode 100644 include/drm/bridge/dw_hdmi.h

-- 
1.9.1


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v15 01/12] drm: imx: imx-hdmi: make checkpatch happy
@ 2014-12-02  7:38   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:38 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

CHECK: Alignment should match open parenthesis
+       if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
+               (hdmi->vic == 12) || (hdmi->vic == 13) ||

CHECK: braces {} should be used on all arms of this statement
+       if (hdmi->hdmi_data.video_mode.mdvi)
[...]
+       else {
[...]

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

---

Changes in v15: None
Changes in v14: None
Changes in v13:
- patch against drm-next

Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6:
- rearrange the patch order

Changes in v5: None
Changes in v4:
- fix checkpatch CHECK

Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c | 97 +++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index aaec6b2..79daec4 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -163,7 +163,7 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 }
 
 static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
-		      u8 shift, u8 mask)
+			     u8 shift, u8 mask)
 {
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
@@ -327,7 +327,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 }
 
 static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
-	unsigned long pixel_clk)
+				     unsigned long pixel_clk)
 {
 	unsigned int clk_n, clk_cts;
 
@@ -338,7 +338,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
 
 	if (!clk_cts) {
 		dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
-			 __func__, pixel_clk);
+			__func__, pixel_clk);
 		return;
 	}
 
@@ -477,13 +477,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 		u16 coeff_b = (*csc_coeff)[1][i];
 		u16 coeff_c = (*csc_coeff)[2][i];
 
-		hdmi_writeb(hdmi, coeff_a & 0xff,
-			HDMI_CSC_COEF_A1_LSB + i * 2);
+		hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
 		hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
-		hdmi_writeb(hdmi, coeff_c & 0xff,
-			HDMI_CSC_COEF_C1_LSB + i * 2);
+		hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
 	}
 
@@ -535,21 +533,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
 	u8 val, vp_conf;
 
-	if (hdmi_data->enc_out_format == RGB
-		|| hdmi_data->enc_out_format == YCBCR444) {
-		if (!hdmi_data->enc_color_depth)
+	if (hdmi_data->enc_out_format == RGB ||
+	    hdmi_data->enc_out_format == YCBCR444) {
+		if (!hdmi_data->enc_color_depth) {
 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-		else if (hdmi_data->enc_color_depth == 8) {
+		} else if (hdmi_data->enc_color_depth == 8) {
 			color_depth = 4;
 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-		} else if (hdmi_data->enc_color_depth == 10)
+		} else if (hdmi_data->enc_color_depth == 10) {
 			color_depth = 5;
-		else if (hdmi_data->enc_color_depth == 12)
+		} else if (hdmi_data->enc_color_depth == 12) {
 			color_depth = 6;
-		else if (hdmi_data->enc_color_depth == 16)
+		} else if (hdmi_data->enc_color_depth == 16) {
 			color_depth = 7;
-		else
+		} else {
 			return;
+		}
 	} else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
 		if (!hdmi_data->enc_color_depth ||
 		    hdmi_data->enc_color_depth == 8)
@@ -561,8 +560,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 		else
 			return;
 		output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
-	} else
+	} else {
 		return;
+	}
 
 	/* set the packetizer registers */
 	val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
@@ -623,34 +623,34 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 }
 
 static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
-						unsigned char bit)
+				       unsigned char bit)
 {
 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
 static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
-						unsigned char bit)
+					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 imx_hdmi *hdmi,
-						unsigned char bit)
+				       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 imx_hdmi *hdmi,
-						unsigned char bit)
+				     unsigned char bit)
 {
 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
 }
 
 static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
-						unsigned char bit)
+				      unsigned char bit)
 {
 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
 }
@@ -666,21 +666,21 @@ static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
 }
 
 static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-			      unsigned char addr)
+				 unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
 	hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
 	hdmi_writeb(hdmi, (unsigned char)(data >> 8),
-		HDMI_PHY_I2CM_DATAO_1_ADDR);
+		    HDMI_PHY_I2CM_DATAO_1_ADDR);
 	hdmi_writeb(hdmi, (unsigned char)(data >> 0),
-		HDMI_PHY_I2CM_DATAO_0_ADDR);
+		    HDMI_PHY_I2CM_DATAO_0_ADDR);
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
-		HDMI_PHY_I2CM_OPERATION_ADDR);
+		    HDMI_PHY_I2CM_OPERATION_ADDR);
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
 
 static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-				     unsigned char addr)
+			      unsigned char addr)
 {
 	__hdmi_phy_i2c_write(hdmi, data, addr);
 	return 0;
@@ -839,7 +839,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 
 	hdmi_phy_test_clear(hdmi, 1);
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
-			HDMI_PHY_I2CM_SLAVE_ADDR);
+		    HDMI_PHY_I2CM_SLAVE_ADDR);
 	hdmi_phy_test_clear(hdmi, 0);
 
 	/* PLL/MPLL Cfg - always match on final entry */
@@ -857,9 +857,8 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 			break;
 
 	if (i >= ARRAY_SIZE(curr_ctrl)) {
-		dev_err(hdmi->dev,
-				"Pixel clock %d - unsupported by HDMI\n",
-				hdmi->hdmi_data.video_mode.mpixelclock);
+		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
+			hdmi->hdmi_data.video_mode.mpixelclock);
 		return -EINVAL;
 	}
 
@@ -1223,21 +1222,21 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	}
 
 	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
-		(hdmi->vic == 21) || (hdmi->vic == 22) ||
-		(hdmi->vic == 2) || (hdmi->vic == 3) ||
-		(hdmi->vic == 17) || (hdmi->vic == 18))
+	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
+	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
+	    (hdmi->vic == 17) || (hdmi->vic == 18))
 		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
 	else
 		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
 
 	if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
-		(hdmi->vic == 12) || (hdmi->vic == 13) ||
-		(hdmi->vic == 14) || (hdmi->vic == 15) ||
-		(hdmi->vic == 25) || (hdmi->vic == 26) ||
-		(hdmi->vic == 27) || (hdmi->vic == 28) ||
-		(hdmi->vic == 29) || (hdmi->vic == 30) ||
-		(hdmi->vic == 35) || (hdmi->vic == 36) ||
-		(hdmi->vic == 37) || (hdmi->vic == 38))
+	    (hdmi->vic == 12) || (hdmi->vic == 13) ||
+	    (hdmi->vic == 14) || (hdmi->vic == 15) ||
+	    (hdmi->vic == 25) || (hdmi->vic == 26) ||
+	    (hdmi->vic == 27) || (hdmi->vic == 28) ||
+	    (hdmi->vic == 29) || (hdmi->vic == 30) ||
+	    (hdmi->vic == 35) || (hdmi->vic == 36) ||
+	    (hdmi->vic == 37) || (hdmi->vic == 38))
 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
 	else
 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
@@ -1266,9 +1265,9 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	imx_hdmi_enable_video_path(hdmi);
 
 	/* not for DVI mode */
-	if (hdmi->hdmi_data.video_mode.mdvi)
+	if (hdmi->hdmi_data.video_mode.mdvi) {
 		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
-	else {
+	} else {
 		dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
 
 		/* HDMI Initialization Step E - Configure audio */
@@ -1525,7 +1524,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
 			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
-				HDMI_PHY_POL0);
+				  HDMI_PHY_POL0);
 
 			imx_hdmi_poweroff(hdmi);
 		}
@@ -1554,7 +1553,7 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 			 DRM_MODE_ENCODER_TMDS);
 
 	drm_connector_helper_add(&hdmi->connector,
-			&imx_hdmi_connector_helper_funcs);
+				 &imx_hdmi_connector_helper_funcs);
 	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
@@ -1671,11 +1670,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	/* Product and revision IDs */
 	dev_info(dev,
-		"Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
-		hdmi_readb(hdmi, HDMI_DESIGN_ID),
-		hdmi_readb(hdmi, HDMI_REVISION_ID),
-		hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
-		hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
+		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
+		 hdmi_readb(hdmi, HDMI_REVISION_ID),
+		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
+		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
 
 	initialize_hdmi_ih_mutes(hdmi);
 
-- 
1.9.1



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

* [PATCH v15 01/12] drm: imx: imx-hdmi: make checkpatch happy
@ 2014-12-02  7:38   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:38 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, Philipp Zabel, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	djkurtz-hpIqsD4AKlfQT0dZR+AlfA, ykk-TNX95d0MmH7DzftRWevZcw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	jay.xu-TNX95d0MmH7DzftRWevZcw, Pawel Moll,
	mark.yao-TNX95d0MmH7DzftRWevZcw, Mark Rutland,
	vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA, Ian Campbell,
	Kumar Gala, Andy Yan

CHECK: Alignment should match open parenthesis
+       if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
+               (hdmi->vic == 12) || (hdmi->vic == 13) ||

CHECK: braces {} should be used on all arms of this statement
+       if (hdmi->hdmi_data.video_mode.mdvi)
[...]
+       else {
[...]

Signed-off-by: Andy Yan <andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Reviewed-by: Daniel Kurtz <djkurtz-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

---

Changes in v15: None
Changes in v14: None
Changes in v13:
- patch against drm-next

Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6:
- rearrange the patch order

Changes in v5: None
Changes in v4:
- fix checkpatch CHECK

Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c | 97 +++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index aaec6b2..79daec4 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -163,7 +163,7 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 }
 
 static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
-		      u8 shift, u8 mask)
+			     u8 shift, u8 mask)
 {
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
@@ -327,7 +327,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 }
 
 static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
-	unsigned long pixel_clk)
+				     unsigned long pixel_clk)
 {
 	unsigned int clk_n, clk_cts;
 
@@ -338,7 +338,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
 
 	if (!clk_cts) {
 		dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
-			 __func__, pixel_clk);
+			__func__, pixel_clk);
 		return;
 	}
 
@@ -477,13 +477,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 		u16 coeff_b = (*csc_coeff)[1][i];
 		u16 coeff_c = (*csc_coeff)[2][i];
 
-		hdmi_writeb(hdmi, coeff_a & 0xff,
-			HDMI_CSC_COEF_A1_LSB + i * 2);
+		hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
 		hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
-		hdmi_writeb(hdmi, coeff_c & 0xff,
-			HDMI_CSC_COEF_C1_LSB + i * 2);
+		hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
 		hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
 	}
 
@@ -535,21 +533,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
 	u8 val, vp_conf;
 
-	if (hdmi_data->enc_out_format == RGB
-		|| hdmi_data->enc_out_format == YCBCR444) {
-		if (!hdmi_data->enc_color_depth)
+	if (hdmi_data->enc_out_format == RGB ||
+	    hdmi_data->enc_out_format == YCBCR444) {
+		if (!hdmi_data->enc_color_depth) {
 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-		else if (hdmi_data->enc_color_depth == 8) {
+		} else if (hdmi_data->enc_color_depth == 8) {
 			color_depth = 4;
 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-		} else if (hdmi_data->enc_color_depth == 10)
+		} else if (hdmi_data->enc_color_depth == 10) {
 			color_depth = 5;
-		else if (hdmi_data->enc_color_depth == 12)
+		} else if (hdmi_data->enc_color_depth == 12) {
 			color_depth = 6;
-		else if (hdmi_data->enc_color_depth == 16)
+		} else if (hdmi_data->enc_color_depth == 16) {
 			color_depth = 7;
-		else
+		} else {
 			return;
+		}
 	} else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
 		if (!hdmi_data->enc_color_depth ||
 		    hdmi_data->enc_color_depth == 8)
@@ -561,8 +560,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 		else
 			return;
 		output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
-	} else
+	} else {
 		return;
+	}
 
 	/* set the packetizer registers */
 	val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
@@ -623,34 +623,34 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 }
 
 static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
-						unsigned char bit)
+				       unsigned char bit)
 {
 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
 static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
-						unsigned char bit)
+					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 imx_hdmi *hdmi,
-						unsigned char bit)
+				       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 imx_hdmi *hdmi,
-						unsigned char bit)
+				     unsigned char bit)
 {
 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
 }
 
 static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
-						unsigned char bit)
+				      unsigned char bit)
 {
 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
 }
@@ -666,21 +666,21 @@ static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
 }
 
 static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-			      unsigned char addr)
+				 unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
 	hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
 	hdmi_writeb(hdmi, (unsigned char)(data >> 8),
-		HDMI_PHY_I2CM_DATAO_1_ADDR);
+		    HDMI_PHY_I2CM_DATAO_1_ADDR);
 	hdmi_writeb(hdmi, (unsigned char)(data >> 0),
-		HDMI_PHY_I2CM_DATAO_0_ADDR);
+		    HDMI_PHY_I2CM_DATAO_0_ADDR);
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
-		HDMI_PHY_I2CM_OPERATION_ADDR);
+		    HDMI_PHY_I2CM_OPERATION_ADDR);
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
 
 static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-				     unsigned char addr)
+			      unsigned char addr)
 {
 	__hdmi_phy_i2c_write(hdmi, data, addr);
 	return 0;
@@ -839,7 +839,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 
 	hdmi_phy_test_clear(hdmi, 1);
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
-			HDMI_PHY_I2CM_SLAVE_ADDR);
+		    HDMI_PHY_I2CM_SLAVE_ADDR);
 	hdmi_phy_test_clear(hdmi, 0);
 
 	/* PLL/MPLL Cfg - always match on final entry */
@@ -857,9 +857,8 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 			break;
 
 	if (i >= ARRAY_SIZE(curr_ctrl)) {
-		dev_err(hdmi->dev,
-				"Pixel clock %d - unsupported by HDMI\n",
-				hdmi->hdmi_data.video_mode.mpixelclock);
+		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
+			hdmi->hdmi_data.video_mode.mpixelclock);
 		return -EINVAL;
 	}
 
@@ -1223,21 +1222,21 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	}
 
 	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
-		(hdmi->vic == 21) || (hdmi->vic == 22) ||
-		(hdmi->vic == 2) || (hdmi->vic == 3) ||
-		(hdmi->vic == 17) || (hdmi->vic == 18))
+	    (hdmi->vic == 21) || (hdmi->vic == 22) ||
+	    (hdmi->vic == 2) || (hdmi->vic == 3) ||
+	    (hdmi->vic == 17) || (hdmi->vic == 18))
 		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
 	else
 		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
 
 	if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
-		(hdmi->vic == 12) || (hdmi->vic == 13) ||
-		(hdmi->vic == 14) || (hdmi->vic == 15) ||
-		(hdmi->vic == 25) || (hdmi->vic == 26) ||
-		(hdmi->vic == 27) || (hdmi->vic == 28) ||
-		(hdmi->vic == 29) || (hdmi->vic == 30) ||
-		(hdmi->vic == 35) || (hdmi->vic == 36) ||
-		(hdmi->vic == 37) || (hdmi->vic == 38))
+	    (hdmi->vic == 12) || (hdmi->vic == 13) ||
+	    (hdmi->vic == 14) || (hdmi->vic == 15) ||
+	    (hdmi->vic == 25) || (hdmi->vic == 26) ||
+	    (hdmi->vic == 27) || (hdmi->vic == 28) ||
+	    (hdmi->vic == 29) || (hdmi->vic == 30) ||
+	    (hdmi->vic == 35) || (hdmi->vic == 36) ||
+	    (hdmi->vic == 37) || (hdmi->vic == 38))
 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
 	else
 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
@@ -1266,9 +1265,9 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	imx_hdmi_enable_video_path(hdmi);
 
 	/* not for DVI mode */
-	if (hdmi->hdmi_data.video_mode.mdvi)
+	if (hdmi->hdmi_data.video_mode.mdvi) {
 		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
-	else {
+	} else {
 		dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
 
 		/* HDMI Initialization Step E - Configure audio */
@@ -1525,7 +1524,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
 			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
-				HDMI_PHY_POL0);
+				  HDMI_PHY_POL0);
 
 			imx_hdmi_poweroff(hdmi);
 		}
@@ -1554,7 +1553,7 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 			 DRM_MODE_ENCODER_TMDS);
 
 	drm_connector_helper_add(&hdmi->connector,
-			&imx_hdmi_connector_helper_funcs);
+				 &imx_hdmi_connector_helper_funcs);
 	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
@@ -1671,11 +1670,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	/* Product and revision IDs */
 	dev_info(dev,
-		"Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
-		hdmi_readb(hdmi, HDMI_DESIGN_ID),
-		hdmi_readb(hdmi, HDMI_REVISION_ID),
-		hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
-		hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
+		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
+		 hdmi_readb(hdmi, HDMI_REVISION_ID),
+		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
+		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
 
 	initialize_hdmi_ih_mutes(hdmi);
 
-- 
1.9.1


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v15 02/12] drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:39   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:39 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

drm driver may probe before the i2c bus, so the driver should
defer probing until it is available

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12:
- refactor of_node_put(ddc_node)

Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- defer probe ddc i2c adapter

Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index 79daec4..8029a07 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -1611,10 +1611,12 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
-		if (!hdmi->ddc)
+		of_node_put(ddc_node);
+		if (!hdmi->ddc) {
 			dev_dbg(hdmi->dev, "failed to read ddc node\n");
+			return -EPROBE_DEFER;
+		}
 
-		of_node_put(ddc_node);
 	} else {
 		dev_dbg(hdmi->dev, "no ddc property found\n");
 	}
-- 
1.9.1



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

* [PATCH v15 02/12] drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter
@ 2014-12-02  7:39   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:39 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

drm driver may probe before the i2c bus, so the driver should
defer probing until it is available

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12:
- refactor of_node_put(ddc_node)

Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- defer probe ddc i2c adapter

Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index 79daec4..8029a07 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -1611,10 +1611,12 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
-		if (!hdmi->ddc)
+		of_node_put(ddc_node);
+		if (!hdmi->ddc) {
 			dev_dbg(hdmi->dev, "failed to read ddc node\n");
+			return -EPROBE_DEFER;
+		}
 
-		of_node_put(ddc_node);
 	} else {
 		dev_dbg(hdmi->dev, "no ddc property found\n");
 	}
-- 
1.9.1

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

* [PATCH v15 03/12] drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:39   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:39 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

IMX6 and Rockchip RK3288 and JZ4780 (Ingenic Xburst/MIPS)
use the interface compatible Designware HDMI IP, but they
also have some lightly differences, such as phy pll configuration,
register width, 4K support, clk useage, and the crtc mux configuration
is also platform specific.

To reuse the imx hdmi driver, convert it to drm_bridge

handle encoder in imx-hdmi_pltfm.c, as most of the encoder
operation are platform specific such as crtc select and
panel format set

This patch depends on Russell King's patch:
 drm: imx: convert imx-drm to use the generic DRM OF helper
 http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2014-July/053484.html

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Yakir Yang <ykk@rock-chips.com>

---

Changes in v15: None
Changes in v14:
- add defer probing, adviced by Philipp Zabel

Changes in v13:
- split platform specific phy configuration

Changes in v12:
- squash patch <convert dw_hdmi to drm_bridge>

Changes in v11:
- squash patch  <split some phy configuration to platform driver>

Changes in v10:
- split generic dw_hdmi.c improvements from patch#11 (add rk3288 support)

Changes in v9: None
Changes in v8: None
Changes in v7:
- remove unused variables from structure dw_hdmi
- remove a wrong modification
- add copyrights for dw_hdmi-imx.c

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/imx/Makefile         |   2 +-
 drivers/gpu/drm/imx/imx-hdmi.c       | 298 ++++++++++++-----------------------
 drivers/gpu/drm/imx/imx-hdmi.h       |  14 ++
 drivers/gpu/drm/imx/imx-hdmi_pltfm.c | 226 ++++++++++++++++++++++++++
 4 files changed, 339 insertions(+), 201 deletions(-)
 create mode 100644 drivers/gpu/drm/imx/imx-hdmi_pltfm.c

diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 582c438..63cf56a 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 
 imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
 obj-$(CONFIG_DRM_IMX_IPUV3)	+= imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
+obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o imx-hdmi_pltfm.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index 8029a07..f05b404 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -12,25 +12,19 @@
  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  */
 
-#include <linux/component.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/clk.h>
 #include <linux/hdmi.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of_device.h>
 
+#include <drm/drm_of.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
-#include <video/imx-ipu-v3.h>
 
 #include "imx-hdmi.h"
-#include "imx-drm.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -54,11 +48,6 @@ enum hdmi_datamap {
 	YCbCr422_12B = 0x12,
 };
 
-enum imx_hdmi_devtype {
-	IMX6Q_HDMI,
-	IMX6DL_HDMI,
-};
-
 static const u16 csc_coeff_default[3][4] = {
 	{ 0x2000, 0x0000, 0x0000, 0x0000 },
 	{ 0x0000, 0x2000, 0x0000, 0x0000 },
@@ -113,14 +102,14 @@ struct hdmi_data_info {
 
 struct imx_hdmi {
 	struct drm_connector connector;
-	struct drm_encoder encoder;
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
 
 	enum imx_hdmi_devtype dev_type;
 	struct device *dev;
-	struct clk *isfr_clk;
-	struct clk *iahb_clk;
 
 	struct hdmi_data_info hdmi_data;
+	const struct imx_hdmi_plat_data *plat_data;
 	int vic;
 
 	u8 edid[HDMI_EDID_LEN];
@@ -137,13 +126,6 @@ struct imx_hdmi {
 	int ratio;
 };
 
-static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
-{
-	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
-			   IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
-			   ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
-}
-
 static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
 {
 	writeb(val, hdmi->regs + offset);
@@ -1371,6 +1353,50 @@ static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
 	imx_hdmi_phy_disable(hdmi);
 }
 
+static void imx_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adjusted_mode)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_setup(hdmi, mode);
+
+	/* Store the display mode for plugin/DKMS poweron events */
+	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+}
+
+static bool imx_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void imx_hdmi_bridge_disable(struct drm_bridge *bridge)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_poweroff(hdmi);
+}
+
+static void imx_hdmi_bridge_enable(struct drm_bridge *bridge)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_poweron(hdmi);
+}
+
+static void imx_hdmi_bridge_destroy(struct drm_bridge *bridge)
+{
+	drm_bridge_cleanup(bridge);
+	kfree(bridge);
+}
+
+static void imx_hdmi_bridge_nope(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
 static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
 							*connector, bool force)
 {
@@ -1412,78 +1438,20 @@ static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
 	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
 					     connector);
 
-	return &hdmi->encoder;
+	return hdmi->encoder;
 }
 
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-			struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
+static void imx_hdmi_connector_destroy(struct drm_connector *connector)
 {
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	imx_hdmi_setup(hdmi, mode);
-
-	/* Store the display mode for plugin/DKMS poweron events */
-	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
 }
 
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-			const struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	if (mode)
-		imx_hdmi_poweroff(hdmi);
-	else
-		imx_hdmi_poweron(hdmi);
-}
-
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	imx_hdmi_poweroff(hdmi);
-	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
-}
-
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
-
-	imx_hdmi_set_ipu_di_mux(hdmi, mux);
-
-	imx_hdmi_poweron(hdmi);
-}
-
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
-	.destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
-	.dpms = imx_hdmi_encoder_dpms,
-	.prepare = imx_hdmi_encoder_prepare,
-	.commit = imx_hdmi_encoder_commit,
-	.mode_set = imx_hdmi_encoder_mode_set,
-	.mode_fixup = imx_hdmi_encoder_mode_fixup,
-	.disable = imx_hdmi_encoder_disable,
-};
-
 static struct drm_connector_funcs imx_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = imx_hdmi_connector_detect,
-	.destroy = imx_drm_connector_destroy,
+	.destroy = imx_hdmi_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
@@ -1491,6 +1459,16 @@ static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
 	.best_encoder = imx_hdmi_connector_best_encoder,
 };
 
+struct drm_bridge_funcs imx_hdmi_bridge_funcs = {
+	.enable = imx_hdmi_bridge_enable,
+	.disable = imx_hdmi_bridge_disable,
+	.pre_enable = imx_hdmi_bridge_nope,
+	.post_disable = imx_hdmi_bridge_nope,
+	.mode_set = imx_hdmi_bridge_mode_set,
+	.mode_fixup = imx_hdmi_bridge_mode_fixup,
+	.destroy = imx_hdmi_bridge_destroy,
+};
+
 static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
 {
 	struct imx_hdmi *hdmi = dev_id;
@@ -1539,54 +1517,45 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 
 static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 {
+	struct drm_encoder *encoder = hdmi->encoder;
+	struct drm_bridge *bridge;
 	int ret;
 
-	ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
-				       hdmi->dev->of_node);
-	if (ret)
-		return ret;
+	bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("Failed to allocate drm bridge\n");
+		return -ENOMEM;
+	}
 
-	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	hdmi->bridge = bridge;
+	bridge->driver_private = hdmi;
 
-	drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS);
+	ret = drm_bridge_init(drm, bridge, &imx_hdmi_bridge_funcs);
+	if (ret) {
+		DRM_ERROR("Failed to initialize bridge with drm\n");
+		return -EINVAL;
+	}
+
+	encoder->bridge = bridge;
+	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &imx_hdmi_connector_helper_funcs);
 	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
-	hdmi->connector.encoder = &hdmi->encoder;
+	hdmi->connector.encoder = encoder;
 
-	drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
+	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
 
 	return 0;
 }
 
-static struct platform_device_id imx_hdmi_devtype[] = {
-	{
-		.name = "imx6q-hdmi",
-		.driver_data = IMX6Q_HDMI,
-	}, {
-		.name = "imx6dl-hdmi",
-		.driver_data = IMX6DL_HDMI,
-	}, { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
-
-static const struct of_device_id imx_hdmi_dt_ids[] = {
-{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
-{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
-{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
-
-static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
+int imx_hdmi_bind(struct device *dev, struct device *master,
+		  void *data, struct drm_encoder *encoder,
+		  const struct imx_hdmi_plat_data *plat_data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	const struct of_device_id *of_id =
-				of_match_device(imx_hdmi_dt_ids, dev);
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct device_node *ddc_node;
@@ -1594,19 +1563,16 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	struct resource *iores;
 	int ret, irq;
 
-	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
 		return -ENOMEM;
 
-	hdmi->dev = dev;
+	hdmi->plat_data = plat_data;
+	hdmi->dev = &pdev->dev;
+	hdmi->dev_type = plat_data->dev_type;
 	hdmi->sample_rate = 48000;
 	hdmi->ratio = 100;
-
-	if (of_id) {
-		const struct platform_device_id *device_id = of_id->data;
-
-		hdmi->dev_type = device_id->driver_data;
-	}
+	hdmi->encoder = encoder;
 
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
@@ -1636,40 +1602,6 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
-	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
-	if (IS_ERR(hdmi->regmap))
-		return PTR_ERR(hdmi->regmap);
-
-	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
-	if (IS_ERR(hdmi->isfr_clk)) {
-		ret = PTR_ERR(hdmi->isfr_clk);
-		dev_err(hdmi->dev,
-			"Unable to get HDMI isfr clk: %d\n", ret);
-		return ret;
-	}
-
-	ret = clk_prepare_enable(hdmi->isfr_clk);
-	if (ret) {
-		dev_err(hdmi->dev,
-			"Cannot enable HDMI isfr clock: %d\n", ret);
-		return ret;
-	}
-
-	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
-	if (IS_ERR(hdmi->iahb_clk)) {
-		ret = PTR_ERR(hdmi->iahb_clk);
-		dev_err(hdmi->dev,
-			"Unable to get HDMI iahb clk: %d\n", ret);
-		goto err_isfr;
-	}
-
-	ret = clk_prepare_enable(hdmi->iahb_clk);
-	if (ret) {
-		dev_err(hdmi->dev,
-			"Cannot enable HDMI iahb clock: %d\n", ret);
-		goto err_isfr;
-	}
-
 	/* Product and revision IDs */
 	dev_info(dev,
 		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
@@ -1697,11 +1629,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	ret = imx_hdmi_fb_registered(hdmi);
 	if (ret)
-		goto err_iahb;
+		return ret;
 
 	ret = imx_hdmi_register(drm, hdmi);
 	if (ret)
-		goto err_iahb;
+		return ret;
 
 	/* Unmute interrupts */
 	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
@@ -1709,17 +1641,10 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
-
-err_iahb:
-	clk_disable_unprepare(hdmi->iahb_clk);
-err_isfr:
-	clk_disable_unprepare(hdmi->isfr_clk);
-
-	return ret;
 }
+EXPORT_SYMBOL_GPL(imx_hdmi_bind);
 
-static void imx_hdmi_unbind(struct device *dev, struct device *master,
-	void *data)
+void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct imx_hdmi *hdmi = dev_get_drvdata(dev);
 
@@ -1727,42 +1652,15 @@ static void imx_hdmi_unbind(struct device *dev, struct device *master,
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
 	hdmi->connector.funcs->destroy(&hdmi->connector);
-	hdmi->encoder.funcs->destroy(&hdmi->encoder);
+	hdmi->encoder->funcs->destroy(hdmi->encoder);
 
-	clk_disable_unprepare(hdmi->iahb_clk);
-	clk_disable_unprepare(hdmi->isfr_clk);
 	i2c_put_adapter(hdmi->ddc);
 }
-
-static const struct component_ops hdmi_ops = {
-	.bind	= imx_hdmi_bind,
-	.unbind	= imx_hdmi_unbind,
-};
-
-static int imx_hdmi_platform_probe(struct platform_device *pdev)
-{
-	return component_add(&pdev->dev, &hdmi_ops);
-}
-
-static int imx_hdmi_platform_remove(struct platform_device *pdev)
-{
-	component_del(&pdev->dev, &hdmi_ops);
-	return 0;
-}
-
-static struct platform_driver imx_hdmi_driver = {
-	.probe  = imx_hdmi_platform_probe,
-	.remove = imx_hdmi_platform_remove,
-	.driver = {
-		.name = "imx-hdmi",
-		.owner = THIS_MODULE,
-		.of_match_table = imx_hdmi_dt_ids,
-	},
-};
-
-module_platform_driver(imx_hdmi_driver);
+EXPORT_SYMBOL_GPL(imx_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
 MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:imx-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h
index 39b6776..14e593e 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/imx/imx-hdmi.h
@@ -1029,4 +1029,18 @@ enum {
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
 };
+
+enum imx_hdmi_devtype {
+	IMX6Q_HDMI,
+	IMX6DL_HDMI,
+};
+
+struct imx_hdmi_plat_data {
+	enum imx_hdmi_devtype dev_type;
+};
+
+int imx_hdmi_bind(struct device *dev, struct device *master,
+		  void *data, struct drm_encoder *encoder,
+		  const struct imx_hdmi_plat_data *plat_data);
+void imx_hdmi_unbind(struct device *dev, struct device *master, void *data);
 #endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
new file mode 100644
index 0000000..8ab70c8
--- /dev/null
+++ b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
@@ -0,0 +1,226 @@
+/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ *
+ * derived from imx-hdmi.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <video/imx-ipu-v3.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+
+#include "imx-drm.h"
+#include "imx-hdmi.h"
+
+struct imx_hdmi_priv {
+	struct device *dev;
+	struct drm_encoder encoder;
+	struct clk *isfr_clk;
+	struct clk *iahb_clk;
+	struct regmap *regmap;
+};
+
+static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
+{
+	struct device_node *np = hdmi->dev->of_node;
+
+	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+	if (IS_ERR(hdmi->regmap)) {
+		dev_err(hdmi->dev, "Unable to get gpr\n");
+		return PTR_ERR(hdmi->regmap);
+	}
+
+	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
+	if (IS_ERR(hdmi->isfr_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI isfr clk\n");
+		return PTR_ERR(hdmi->isfr_clk);
+	}
+
+	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
+	if (IS_ERR(hdmi->iahb_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI iahb clk\n");
+		return PTR_ERR(hdmi->iahb_clk);
+	}
+
+	return 0;
+}
+
+static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
+					const struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+{
+	struct imx_hdmi_priv *hdmi = container_of(encoder,
+						  struct imx_hdmi_priv,
+						  encoder);
+	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+
+	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
+			   IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
+			   mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
+}
+
+static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+{
+	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
+}
+
+static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
+	.mode_fixup = imx_hdmi_encoder_mode_fixup,
+	.mode_set = imx_hdmi_encoder_mode_set,
+	.prepare = imx_hdmi_encoder_prepare,
+	.commit = imx_hdmi_encoder_commit,
+	.disable = imx_hdmi_encoder_disable,
+};
+
+static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.dev_type = IMX6Q_HDMI,
+};
+
+static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.dev_type = IMX6DL_HDMI,
+};
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-hdmi",
+	  .data = &imx6q_hdmi_drv_data
+	}, {
+	  .compatible = "fsl,imx6dl-hdmi",
+	  .data = &imx6dl_hdmi_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct imx_hdmi_plat_data *plat_data;
+	const struct of_device_id *match;
+	struct drm_device *drm = data;
+	struct drm_encoder *encoder;
+	struct imx_hdmi_priv *hdmi;
+	int ret;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	match = of_match_node(imx_hdmi_dt_ids, pdev->dev.of_node);
+	plat_data = match->data;
+	hdmi->dev = &pdev->dev;
+	encoder = &hdmi->encoder;
+	platform_set_drvdata(pdev, hdmi);
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+	/*
+	 * If we failed to find the CRTC(s) which this encoder is
+	 * supposed to be connected to, it's because the CRTC has
+	 * not been registered yet.  Defer probing, and hope that
+	 * the required CRTC is added later.
+	 */
+	if (encoder->possible_crtcs == 0)
+		return -EPROBE_DEFER;
+
+	ret = imx_hdmi_parse_dt(hdmi);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(hdmi->isfr_clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable HDMI isfr clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->iahb_clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable HDMI iahb clock: %d\n", ret);
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &imx_hdmi_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &imx_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	return imx_hdmi_bind(dev, master, data, encoder, plat_data);
+}
+
+static void imx_hdmi_pltfm_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct imx_hdmi_priv *hdmi = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(hdmi->isfr_clk);
+	clk_disable_unprepare(hdmi->iahb_clk);
+
+	return imx_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops imx_hdmi_ops = {
+	.bind	= imx_hdmi_pltfm_bind,
+	.unbind	= imx_hdmi_pltfm_unbind,
+};
+
+static int imx_hdmi_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &imx_hdmi_ops);
+}
+
+static int imx_hdmi_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &imx_hdmi_ops);
+
+	return 0;
+}
+
+static struct platform_driver imx_hdmi_pltfm_driver = {
+	.probe  = imx_hdmi_probe,
+	.remove = imx_hdmi_remove,
+	.driver = {
+		.name = "hdmi-imx",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_hdmi_dt_ids,
+	},
+};
+
+module_platform_driver(imx_hdmi_pltfm_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:hdmi-imx");
-- 
1.9.1



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

* [PATCH v15 03/12] drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode
@ 2014-12-02  7:39   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:39 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

IMX6 and Rockchip RK3288 and JZ4780 (Ingenic Xburst/MIPS)
use the interface compatible Designware HDMI IP, but they
also have some lightly differences, such as phy pll configuration,
register width, 4K support, clk useage, and the crtc mux configuration
is also platform specific.

To reuse the imx hdmi driver, convert it to drm_bridge

handle encoder in imx-hdmi_pltfm.c, as most of the encoder
operation are platform specific such as crtc select and
panel format set

This patch depends on Russell King's patch:
 drm: imx: convert imx-drm to use the generic DRM OF helper
 http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2014-July/053484.html

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Yakir Yang <ykk@rock-chips.com>

---

Changes in v15: None
Changes in v14:
- add defer probing, adviced by Philipp Zabel

Changes in v13:
- split platform specific phy configuration

Changes in v12:
- squash patch <convert dw_hdmi to drm_bridge>

Changes in v11:
- squash patch  <split some phy configuration to platform driver>

Changes in v10:
- split generic dw_hdmi.c improvements from patch#11 (add rk3288 support)

Changes in v9: None
Changes in v8: None
Changes in v7:
- remove unused variables from structure dw_hdmi
- remove a wrong modification
- add copyrights for dw_hdmi-imx.c

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/imx/Makefile         |   2 +-
 drivers/gpu/drm/imx/imx-hdmi.c       | 298 ++++++++++++-----------------------
 drivers/gpu/drm/imx/imx-hdmi.h       |  14 ++
 drivers/gpu/drm/imx/imx-hdmi_pltfm.c | 226 ++++++++++++++++++++++++++
 4 files changed, 339 insertions(+), 201 deletions(-)
 create mode 100644 drivers/gpu/drm/imx/imx-hdmi_pltfm.c

diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 582c438..63cf56a 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 
 imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
 obj-$(CONFIG_DRM_IMX_IPUV3)	+= imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
+obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o imx-hdmi_pltfm.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index 8029a07..f05b404 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -12,25 +12,19 @@
  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  */
 
-#include <linux/component.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/clk.h>
 #include <linux/hdmi.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of_device.h>
 
+#include <drm/drm_of.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
-#include <video/imx-ipu-v3.h>
 
 #include "imx-hdmi.h"
-#include "imx-drm.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -54,11 +48,6 @@ enum hdmi_datamap {
 	YCbCr422_12B = 0x12,
 };
 
-enum imx_hdmi_devtype {
-	IMX6Q_HDMI,
-	IMX6DL_HDMI,
-};
-
 static const u16 csc_coeff_default[3][4] = {
 	{ 0x2000, 0x0000, 0x0000, 0x0000 },
 	{ 0x0000, 0x2000, 0x0000, 0x0000 },
@@ -113,14 +102,14 @@ struct hdmi_data_info {
 
 struct imx_hdmi {
 	struct drm_connector connector;
-	struct drm_encoder encoder;
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
 
 	enum imx_hdmi_devtype dev_type;
 	struct device *dev;
-	struct clk *isfr_clk;
-	struct clk *iahb_clk;
 
 	struct hdmi_data_info hdmi_data;
+	const struct imx_hdmi_plat_data *plat_data;
 	int vic;
 
 	u8 edid[HDMI_EDID_LEN];
@@ -137,13 +126,6 @@ struct imx_hdmi {
 	int ratio;
 };
 
-static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
-{
-	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
-			   IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
-			   ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
-}
-
 static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
 {
 	writeb(val, hdmi->regs + offset);
@@ -1371,6 +1353,50 @@ static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
 	imx_hdmi_phy_disable(hdmi);
 }
 
+static void imx_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adjusted_mode)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_setup(hdmi, mode);
+
+	/* Store the display mode for plugin/DKMS poweron events */
+	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+}
+
+static bool imx_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void imx_hdmi_bridge_disable(struct drm_bridge *bridge)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_poweroff(hdmi);
+}
+
+static void imx_hdmi_bridge_enable(struct drm_bridge *bridge)
+{
+	struct imx_hdmi *hdmi = bridge->driver_private;
+
+	imx_hdmi_poweron(hdmi);
+}
+
+static void imx_hdmi_bridge_destroy(struct drm_bridge *bridge)
+{
+	drm_bridge_cleanup(bridge);
+	kfree(bridge);
+}
+
+static void imx_hdmi_bridge_nope(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
 static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
 							*connector, bool force)
 {
@@ -1412,78 +1438,20 @@ static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
 	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
 					     connector);
 
-	return &hdmi->encoder;
+	return hdmi->encoder;
 }
 
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-			struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
+static void imx_hdmi_connector_destroy(struct drm_connector *connector)
 {
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	imx_hdmi_setup(hdmi, mode);
-
-	/* Store the display mode for plugin/DKMS poweron events */
-	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
 }
 
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-			const struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	if (mode)
-		imx_hdmi_poweroff(hdmi);
-	else
-		imx_hdmi_poweron(hdmi);
-}
-
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-	imx_hdmi_poweroff(hdmi);
-	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
-}
-
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
-{
-	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
-
-	imx_hdmi_set_ipu_di_mux(hdmi, mux);
-
-	imx_hdmi_poweron(hdmi);
-}
-
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
-	.destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
-	.dpms = imx_hdmi_encoder_dpms,
-	.prepare = imx_hdmi_encoder_prepare,
-	.commit = imx_hdmi_encoder_commit,
-	.mode_set = imx_hdmi_encoder_mode_set,
-	.mode_fixup = imx_hdmi_encoder_mode_fixup,
-	.disable = imx_hdmi_encoder_disable,
-};
-
 static struct drm_connector_funcs imx_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = imx_hdmi_connector_detect,
-	.destroy = imx_drm_connector_destroy,
+	.destroy = imx_hdmi_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
@@ -1491,6 +1459,16 @@ static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
 	.best_encoder = imx_hdmi_connector_best_encoder,
 };
 
+struct drm_bridge_funcs imx_hdmi_bridge_funcs = {
+	.enable = imx_hdmi_bridge_enable,
+	.disable = imx_hdmi_bridge_disable,
+	.pre_enable = imx_hdmi_bridge_nope,
+	.post_disable = imx_hdmi_bridge_nope,
+	.mode_set = imx_hdmi_bridge_mode_set,
+	.mode_fixup = imx_hdmi_bridge_mode_fixup,
+	.destroy = imx_hdmi_bridge_destroy,
+};
+
 static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
 {
 	struct imx_hdmi *hdmi = dev_id;
@@ -1539,54 +1517,45 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 
 static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 {
+	struct drm_encoder *encoder = hdmi->encoder;
+	struct drm_bridge *bridge;
 	int ret;
 
-	ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
-				       hdmi->dev->of_node);
-	if (ret)
-		return ret;
+	bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("Failed to allocate drm bridge\n");
+		return -ENOMEM;
+	}
 
-	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	hdmi->bridge = bridge;
+	bridge->driver_private = hdmi;
 
-	drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS);
+	ret = drm_bridge_init(drm, bridge, &imx_hdmi_bridge_funcs);
+	if (ret) {
+		DRM_ERROR("Failed to initialize bridge with drm\n");
+		return -EINVAL;
+	}
+
+	encoder->bridge = bridge;
+	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &imx_hdmi_connector_helper_funcs);
 	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
-	hdmi->connector.encoder = &hdmi->encoder;
+	hdmi->connector.encoder = encoder;
 
-	drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
+	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
 
 	return 0;
 }
 
-static struct platform_device_id imx_hdmi_devtype[] = {
-	{
-		.name = "imx6q-hdmi",
-		.driver_data = IMX6Q_HDMI,
-	}, {
-		.name = "imx6dl-hdmi",
-		.driver_data = IMX6DL_HDMI,
-	}, { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
-
-static const struct of_device_id imx_hdmi_dt_ids[] = {
-{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
-{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
-{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
-
-static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
+int imx_hdmi_bind(struct device *dev, struct device *master,
+		  void *data, struct drm_encoder *encoder,
+		  const struct imx_hdmi_plat_data *plat_data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	const struct of_device_id *of_id =
-				of_match_device(imx_hdmi_dt_ids, dev);
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct device_node *ddc_node;
@@ -1594,19 +1563,16 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	struct resource *iores;
 	int ret, irq;
 
-	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
 		return -ENOMEM;
 
-	hdmi->dev = dev;
+	hdmi->plat_data = plat_data;
+	hdmi->dev = &pdev->dev;
+	hdmi->dev_type = plat_data->dev_type;
 	hdmi->sample_rate = 48000;
 	hdmi->ratio = 100;
-
-	if (of_id) {
-		const struct platform_device_id *device_id = of_id->data;
-
-		hdmi->dev_type = device_id->driver_data;
-	}
+	hdmi->encoder = encoder;
 
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
@@ -1636,40 +1602,6 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
-	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
-	if (IS_ERR(hdmi->regmap))
-		return PTR_ERR(hdmi->regmap);
-
-	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
-	if (IS_ERR(hdmi->isfr_clk)) {
-		ret = PTR_ERR(hdmi->isfr_clk);
-		dev_err(hdmi->dev,
-			"Unable to get HDMI isfr clk: %d\n", ret);
-		return ret;
-	}
-
-	ret = clk_prepare_enable(hdmi->isfr_clk);
-	if (ret) {
-		dev_err(hdmi->dev,
-			"Cannot enable HDMI isfr clock: %d\n", ret);
-		return ret;
-	}
-
-	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
-	if (IS_ERR(hdmi->iahb_clk)) {
-		ret = PTR_ERR(hdmi->iahb_clk);
-		dev_err(hdmi->dev,
-			"Unable to get HDMI iahb clk: %d\n", ret);
-		goto err_isfr;
-	}
-
-	ret = clk_prepare_enable(hdmi->iahb_clk);
-	if (ret) {
-		dev_err(hdmi->dev,
-			"Cannot enable HDMI iahb clock: %d\n", ret);
-		goto err_isfr;
-	}
-
 	/* Product and revision IDs */
 	dev_info(dev,
 		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
@@ -1697,11 +1629,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	ret = imx_hdmi_fb_registered(hdmi);
 	if (ret)
-		goto err_iahb;
+		return ret;
 
 	ret = imx_hdmi_register(drm, hdmi);
 	if (ret)
-		goto err_iahb;
+		return ret;
 
 	/* Unmute interrupts */
 	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
@@ -1709,17 +1641,10 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
-
-err_iahb:
-	clk_disable_unprepare(hdmi->iahb_clk);
-err_isfr:
-	clk_disable_unprepare(hdmi->isfr_clk);
-
-	return ret;
 }
+EXPORT_SYMBOL_GPL(imx_hdmi_bind);
 
-static void imx_hdmi_unbind(struct device *dev, struct device *master,
-	void *data)
+void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct imx_hdmi *hdmi = dev_get_drvdata(dev);
 
@@ -1727,42 +1652,15 @@ static void imx_hdmi_unbind(struct device *dev, struct device *master,
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
 	hdmi->connector.funcs->destroy(&hdmi->connector);
-	hdmi->encoder.funcs->destroy(&hdmi->encoder);
+	hdmi->encoder->funcs->destroy(hdmi->encoder);
 
-	clk_disable_unprepare(hdmi->iahb_clk);
-	clk_disable_unprepare(hdmi->isfr_clk);
 	i2c_put_adapter(hdmi->ddc);
 }
-
-static const struct component_ops hdmi_ops = {
-	.bind	= imx_hdmi_bind,
-	.unbind	= imx_hdmi_unbind,
-};
-
-static int imx_hdmi_platform_probe(struct platform_device *pdev)
-{
-	return component_add(&pdev->dev, &hdmi_ops);
-}
-
-static int imx_hdmi_platform_remove(struct platform_device *pdev)
-{
-	component_del(&pdev->dev, &hdmi_ops);
-	return 0;
-}
-
-static struct platform_driver imx_hdmi_driver = {
-	.probe  = imx_hdmi_platform_probe,
-	.remove = imx_hdmi_platform_remove,
-	.driver = {
-		.name = "imx-hdmi",
-		.owner = THIS_MODULE,
-		.of_match_table = imx_hdmi_dt_ids,
-	},
-};
-
-module_platform_driver(imx_hdmi_driver);
+EXPORT_SYMBOL_GPL(imx_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
 MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:imx-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h
index 39b6776..14e593e 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/imx/imx-hdmi.h
@@ -1029,4 +1029,18 @@ enum {
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
 };
+
+enum imx_hdmi_devtype {
+	IMX6Q_HDMI,
+	IMX6DL_HDMI,
+};
+
+struct imx_hdmi_plat_data {
+	enum imx_hdmi_devtype dev_type;
+};
+
+int imx_hdmi_bind(struct device *dev, struct device *master,
+		  void *data, struct drm_encoder *encoder,
+		  const struct imx_hdmi_plat_data *plat_data);
+void imx_hdmi_unbind(struct device *dev, struct device *master, void *data);
 #endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
new file mode 100644
index 0000000..8ab70c8
--- /dev/null
+++ b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
@@ -0,0 +1,226 @@
+/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ *
+ * derived from imx-hdmi.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <video/imx-ipu-v3.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+
+#include "imx-drm.h"
+#include "imx-hdmi.h"
+
+struct imx_hdmi_priv {
+	struct device *dev;
+	struct drm_encoder encoder;
+	struct clk *isfr_clk;
+	struct clk *iahb_clk;
+	struct regmap *regmap;
+};
+
+static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
+{
+	struct device_node *np = hdmi->dev->of_node;
+
+	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+	if (IS_ERR(hdmi->regmap)) {
+		dev_err(hdmi->dev, "Unable to get gpr\n");
+		return PTR_ERR(hdmi->regmap);
+	}
+
+	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
+	if (IS_ERR(hdmi->isfr_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI isfr clk\n");
+		return PTR_ERR(hdmi->isfr_clk);
+	}
+
+	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
+	if (IS_ERR(hdmi->iahb_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI iahb clk\n");
+		return PTR_ERR(hdmi->iahb_clk);
+	}
+
+	return 0;
+}
+
+static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
+					const struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+{
+	struct imx_hdmi_priv *hdmi = container_of(encoder,
+						  struct imx_hdmi_priv,
+						  encoder);
+	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+
+	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
+			   IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
+			   mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
+}
+
+static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+{
+	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
+}
+
+static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
+	.mode_fixup = imx_hdmi_encoder_mode_fixup,
+	.mode_set = imx_hdmi_encoder_mode_set,
+	.prepare = imx_hdmi_encoder_prepare,
+	.commit = imx_hdmi_encoder_commit,
+	.disable = imx_hdmi_encoder_disable,
+};
+
+static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.dev_type = IMX6Q_HDMI,
+};
+
+static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.dev_type = IMX6DL_HDMI,
+};
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-hdmi",
+	  .data = &imx6q_hdmi_drv_data
+	}, {
+	  .compatible = "fsl,imx6dl-hdmi",
+	  .data = &imx6dl_hdmi_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct imx_hdmi_plat_data *plat_data;
+	const struct of_device_id *match;
+	struct drm_device *drm = data;
+	struct drm_encoder *encoder;
+	struct imx_hdmi_priv *hdmi;
+	int ret;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	match = of_match_node(imx_hdmi_dt_ids, pdev->dev.of_node);
+	plat_data = match->data;
+	hdmi->dev = &pdev->dev;
+	encoder = &hdmi->encoder;
+	platform_set_drvdata(pdev, hdmi);
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+	/*
+	 * If we failed to find the CRTC(s) which this encoder is
+	 * supposed to be connected to, it's because the CRTC has
+	 * not been registered yet.  Defer probing, and hope that
+	 * the required CRTC is added later.
+	 */
+	if (encoder->possible_crtcs == 0)
+		return -EPROBE_DEFER;
+
+	ret = imx_hdmi_parse_dt(hdmi);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(hdmi->isfr_clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable HDMI isfr clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->iahb_clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable HDMI iahb clock: %d\n", ret);
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &imx_hdmi_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &imx_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	return imx_hdmi_bind(dev, master, data, encoder, plat_data);
+}
+
+static void imx_hdmi_pltfm_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct imx_hdmi_priv *hdmi = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(hdmi->isfr_clk);
+	clk_disable_unprepare(hdmi->iahb_clk);
+
+	return imx_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops imx_hdmi_ops = {
+	.bind	= imx_hdmi_pltfm_bind,
+	.unbind	= imx_hdmi_pltfm_unbind,
+};
+
+static int imx_hdmi_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &imx_hdmi_ops);
+}
+
+static int imx_hdmi_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &imx_hdmi_ops);
+
+	return 0;
+}
+
+static struct platform_driver imx_hdmi_pltfm_driver = {
+	.probe  = imx_hdmi_probe,
+	.remove = imx_hdmi_remove,
+	.driver = {
+		.name = "hdmi-imx",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_hdmi_dt_ids,
+	},
+};
+
+module_platform_driver(imx_hdmi_pltfm_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:hdmi-imx");
-- 
1.9.1

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

* [PATCH v15 04/12] drm: imx: imx-hdmi: split phy configuration to platform driver
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:40   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:40 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

hdmi phy configuration is platform specific, which can be adusted
according to the board to get the best SI

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13:
- split phy configuration from patch#4

Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c       | 85 +++++++-----------------------------
 drivers/gpu/drm/imx/imx-hdmi.h       | 29 ++++++++++++
 drivers/gpu/drm/imx/imx-hdmi_pltfm.c | 57 ++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index f05b404..99c2966 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -710,76 +710,14 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-enum {
-	RES_8,
-	RES_10,
-	RES_12,
-	RES_MAX,
-};
-
-struct mpll_config {
-	unsigned long mpixelclock;
-	struct {
-		u16 cpce;
-		u16 gmp;
-	} res[RES_MAX];
-};
-
-static const struct mpll_config mpll_config[] = {
-	{
-		45250000, {
-			{ 0x01e0, 0x0000 },
-			{ 0x21e1, 0x0000 },
-			{ 0x41e2, 0x0000 }
-		},
-	}, {
-		92500000, {
-			{ 0x0140, 0x0005 },
-			{ 0x2141, 0x0005 },
-			{ 0x4142, 0x0005 },
-		},
-	}, {
-		148500000, {
-			{ 0x00a0, 0x000a },
-			{ 0x20a1, 0x000a },
-			{ 0x40a2, 0x000a },
-		},
-	}, {
-		~0UL, {
-			{ 0x00a0, 0x000a },
-			{ 0x2001, 0x000f },
-			{ 0x4002, 0x000f },
-		},
-	}
-};
-
-struct curr_ctrl {
-	unsigned long mpixelclock;
-	u16 curr[RES_MAX];
-};
-
-static const struct curr_ctrl curr_ctrl[] = {
-	/*	pixelclk     bpp8    bpp10   bpp12 */
-	{
-		 54000000, { 0x091c, 0x091c, 0x06dc },
-	}, {
-		 58400000, { 0x091c, 0x06dc, 0x06dc },
-	}, {
-		 72000000, { 0x06dc, 0x06dc, 0x091c },
-	}, {
-		 74250000, { 0x06dc, 0x0b5c, 0x091c },
-	}, {
-		118800000, { 0x091c, 0x091c, 0x06dc },
-	}, {
-		216000000, { 0x06dc, 0x0b5c, 0x091c },
-	}
-};
-
 static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 			      unsigned char res, int cscon)
 {
 	unsigned res_idx, i;
 	u8 val, msec;
+	const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
+	const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
+	const struct sym_term *sym_term =  hdmi->plat_data->sym_term;
 
 	if (prep)
 		return -EINVAL;
@@ -825,7 +763,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_phy_test_clear(hdmi, 0);
 
 	/* PLL/MPLL Cfg - always match on final entry */
-	for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
+	for (i = 0; mpll_config[i].mpixelclock != (~0UL); i++)
 		if (hdmi->hdmi_data.video_mode.mpixelclock <=
 		    mpll_config[i].mpixelclock)
 			break;
@@ -833,12 +771,12 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
 	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
 
-	for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
+	for (i = 0; curr_ctrl[i].mpixelclock != (~0UL); i++)
 		if (hdmi->hdmi_data.video_mode.mpixelclock <=
 		    curr_ctrl[i].mpixelclock)
 			break;
 
-	if (i >= ARRAY_SIZE(curr_ctrl)) {
+	if (curr_ctrl[i].mpixelclock == (~0UL)) {
 		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
 			hdmi->hdmi_data.video_mode.mpixelclock);
 		return -EINVAL;
@@ -849,10 +787,17 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 
 	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
 	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+
+	for (i = 0; sym_term[i].mpixelclock != (~0UL); i++)
+		if (hdmi->hdmi_data.video_mode.mpixelclock <=
+		    sym_term[i].mpixelclock)
+			break;
+
 	/* RESISTANCE TERM 133Ohm Cfg */
-	hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
+	hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19);  /* TXTERM */
 	/* PREEMP Cgf 0.00 */
-	hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
+	hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09);  /* CKSYMTXCTRL */
+
 	/* TX/CK LVL 10 */
 	hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
 	/* REMOVE CLK TERM */
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h
index 14e593e..bced9ef 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/imx/imx-hdmi.h
@@ -1037,6 +1037,35 @@ enum imx_hdmi_devtype {
 
 struct imx_hdmi_plat_data {
 	enum imx_hdmi_devtype dev_type;
+	const struct mpll_config *mpll_cfg;
+	const struct curr_ctrl *cur_ctr;
+	const struct sym_term *sym_term;
+};
+
+enum {
+	RES_8,
+	RES_10,
+	RES_12,
+	RES_MAX,
+};
+
+struct mpll_config {
+	unsigned long mpixelclock;
+	struct {
+		u16 cpce;
+		u16 gmp;
+	} res[RES_MAX];
+};
+
+struct curr_ctrl {
+	unsigned long mpixelclock;
+	u16 curr[RES_MAX];
+};
+
+struct sym_term {
+	unsigned long mpixelclock;
+	u16 sym_ctr;    /*clock symbol and transmitter control*/
+	u16 term;       /*transmission termination value*/
 };
 
 int imx_hdmi_bind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
index 8ab70c8..da330e0 100644
--- a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
+++ b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
@@ -31,6 +31,57 @@ struct imx_hdmi_priv {
 	struct regmap *regmap;
 };
 
+static const struct mpll_config imx_mpll_cfg[] = {
+	{
+		45250000, {
+			{ 0x01e0, 0x0000 },
+			{ 0x21e1, 0x0000 },
+			{ 0x41e2, 0x0000 }
+		},
+	}, {
+		92500000, {
+			{ 0x0140, 0x0005 },
+			{ 0x2141, 0x0005 },
+			{ 0x4142, 0x0005 },
+	},
+	}, {
+		148500000, {
+			{ 0x00a0, 0x000a },
+			{ 0x20a1, 0x000a },
+			{ 0x40a2, 0x000a },
+		},
+	}, {
+		~0UL, {
+			{ 0x00a0, 0x000a },
+			{ 0x2001, 0x000f },
+			{ 0x4002, 0x000f },
+		},
+	}
+};
+
+static const struct curr_ctrl imx_cur_ctr[] = {
+	/*      pixelclk     bpp8    bpp10   bpp12 */
+	{
+		54000000, { 0x091c, 0x091c, 0x06dc },
+	}, {
+		58400000, { 0x091c, 0x06dc, 0x06dc },
+	}, {
+		72000000, { 0x06dc, 0x06dc, 0x091c },
+	}, {
+		74250000, { 0x06dc, 0x0b5c, 0x091c },
+	}, {
+		118800000, { 0x091c, 0x091c, 0x06dc },
+	}, {
+		216000000, { 0x06dc, 0x0b5c, 0x091c },
+	}
+};
+
+static const struct sym_term imx_sym_term[] = {
+	/*pixelclk   symbol   term*/
+	{ 148500000, 0x800d, 0x0005 },
+	{ ~0UL,      0x0000, 0x0000 }
+};
+
 static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
 {
 	struct device_node *np = hdmi->dev->of_node;
@@ -103,10 +154,16 @@ static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
 };
 
 static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.mpll_cfg = imx_mpll_cfg,
+	.cur_ctr  = imx_cur_ctr,
+	.sym_term = imx_sym_term,
 	.dev_type = IMX6Q_HDMI,
 };
 
 static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.mpll_cfg = imx_mpll_cfg,
+	.cur_ctr  = imx_cur_ctr,
+	.sym_term = imx_sym_term,
 	.dev_type = IMX6DL_HDMI,
 };
 
-- 
1.9.1



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

* [PATCH v15 04/12] drm: imx: imx-hdmi: split phy configuration to platform driver
@ 2014-12-02  7:40   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:40 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

hdmi phy configuration is platform specific, which can be adusted
according to the board to get the best SI

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13:
- split phy configuration from patch#4

Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/imx/imx-hdmi.c       | 85 +++++++-----------------------------
 drivers/gpu/drm/imx/imx-hdmi.h       | 29 ++++++++++++
 drivers/gpu/drm/imx/imx-hdmi_pltfm.c | 57 ++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
index f05b404..99c2966 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/imx/imx-hdmi.c
@@ -710,76 +710,14 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-enum {
-	RES_8,
-	RES_10,
-	RES_12,
-	RES_MAX,
-};
-
-struct mpll_config {
-	unsigned long mpixelclock;
-	struct {
-		u16 cpce;
-		u16 gmp;
-	} res[RES_MAX];
-};
-
-static const struct mpll_config mpll_config[] = {
-	{
-		45250000, {
-			{ 0x01e0, 0x0000 },
-			{ 0x21e1, 0x0000 },
-			{ 0x41e2, 0x0000 }
-		},
-	}, {
-		92500000, {
-			{ 0x0140, 0x0005 },
-			{ 0x2141, 0x0005 },
-			{ 0x4142, 0x0005 },
-		},
-	}, {
-		148500000, {
-			{ 0x00a0, 0x000a },
-			{ 0x20a1, 0x000a },
-			{ 0x40a2, 0x000a },
-		},
-	}, {
-		~0UL, {
-			{ 0x00a0, 0x000a },
-			{ 0x2001, 0x000f },
-			{ 0x4002, 0x000f },
-		},
-	}
-};
-
-struct curr_ctrl {
-	unsigned long mpixelclock;
-	u16 curr[RES_MAX];
-};
-
-static const struct curr_ctrl curr_ctrl[] = {
-	/*	pixelclk     bpp8    bpp10   bpp12 */
-	{
-		 54000000, { 0x091c, 0x091c, 0x06dc },
-	}, {
-		 58400000, { 0x091c, 0x06dc, 0x06dc },
-	}, {
-		 72000000, { 0x06dc, 0x06dc, 0x091c },
-	}, {
-		 74250000, { 0x06dc, 0x0b5c, 0x091c },
-	}, {
-		118800000, { 0x091c, 0x091c, 0x06dc },
-	}, {
-		216000000, { 0x06dc, 0x0b5c, 0x091c },
-	}
-};
-
 static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 			      unsigned char res, int cscon)
 {
 	unsigned res_idx, i;
 	u8 val, msec;
+	const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
+	const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
+	const struct sym_term *sym_term =  hdmi->plat_data->sym_term;
 
 	if (prep)
 		return -EINVAL;
@@ -825,7 +763,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_phy_test_clear(hdmi, 0);
 
 	/* PLL/MPLL Cfg - always match on final entry */
-	for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
+	for (i = 0; mpll_config[i].mpixelclock != (~0UL); i++)
 		if (hdmi->hdmi_data.video_mode.mpixelclock <=
 		    mpll_config[i].mpixelclock)
 			break;
@@ -833,12 +771,12 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
 	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
 
-	for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
+	for (i = 0; curr_ctrl[i].mpixelclock != (~0UL); i++)
 		if (hdmi->hdmi_data.video_mode.mpixelclock <=
 		    curr_ctrl[i].mpixelclock)
 			break;
 
-	if (i >= ARRAY_SIZE(curr_ctrl)) {
+	if (curr_ctrl[i].mpixelclock == (~0UL)) {
 		dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
 			hdmi->hdmi_data.video_mode.mpixelclock);
 		return -EINVAL;
@@ -849,10 +787,17 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 
 	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
 	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+
+	for (i = 0; sym_term[i].mpixelclock != (~0UL); i++)
+		if (hdmi->hdmi_data.video_mode.mpixelclock <=
+		    sym_term[i].mpixelclock)
+			break;
+
 	/* RESISTANCE TERM 133Ohm Cfg */
-	hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
+	hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19);  /* TXTERM */
 	/* PREEMP Cgf 0.00 */
-	hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
+	hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09);  /* CKSYMTXCTRL */
+
 	/* TX/CK LVL 10 */
 	hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
 	/* REMOVE CLK TERM */
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h
index 14e593e..bced9ef 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/imx/imx-hdmi.h
@@ -1037,6 +1037,35 @@ enum imx_hdmi_devtype {
 
 struct imx_hdmi_plat_data {
 	enum imx_hdmi_devtype dev_type;
+	const struct mpll_config *mpll_cfg;
+	const struct curr_ctrl *cur_ctr;
+	const struct sym_term *sym_term;
+};
+
+enum {
+	RES_8,
+	RES_10,
+	RES_12,
+	RES_MAX,
+};
+
+struct mpll_config {
+	unsigned long mpixelclock;
+	struct {
+		u16 cpce;
+		u16 gmp;
+	} res[RES_MAX];
+};
+
+struct curr_ctrl {
+	unsigned long mpixelclock;
+	u16 curr[RES_MAX];
+};
+
+struct sym_term {
+	unsigned long mpixelclock;
+	u16 sym_ctr;    /*clock symbol and transmitter control*/
+	u16 term;       /*transmission termination value*/
 };
 
 int imx_hdmi_bind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
index 8ab70c8..da330e0 100644
--- a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
+++ b/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
@@ -31,6 +31,57 @@ struct imx_hdmi_priv {
 	struct regmap *regmap;
 };
 
+static const struct mpll_config imx_mpll_cfg[] = {
+	{
+		45250000, {
+			{ 0x01e0, 0x0000 },
+			{ 0x21e1, 0x0000 },
+			{ 0x41e2, 0x0000 }
+		},
+	}, {
+		92500000, {
+			{ 0x0140, 0x0005 },
+			{ 0x2141, 0x0005 },
+			{ 0x4142, 0x0005 },
+	},
+	}, {
+		148500000, {
+			{ 0x00a0, 0x000a },
+			{ 0x20a1, 0x000a },
+			{ 0x40a2, 0x000a },
+		},
+	}, {
+		~0UL, {
+			{ 0x00a0, 0x000a },
+			{ 0x2001, 0x000f },
+			{ 0x4002, 0x000f },
+		},
+	}
+};
+
+static const struct curr_ctrl imx_cur_ctr[] = {
+	/*      pixelclk     bpp8    bpp10   bpp12 */
+	{
+		54000000, { 0x091c, 0x091c, 0x06dc },
+	}, {
+		58400000, { 0x091c, 0x06dc, 0x06dc },
+	}, {
+		72000000, { 0x06dc, 0x06dc, 0x091c },
+	}, {
+		74250000, { 0x06dc, 0x0b5c, 0x091c },
+	}, {
+		118800000, { 0x091c, 0x091c, 0x06dc },
+	}, {
+		216000000, { 0x06dc, 0x0b5c, 0x091c },
+	}
+};
+
+static const struct sym_term imx_sym_term[] = {
+	/*pixelclk   symbol   term*/
+	{ 148500000, 0x800d, 0x0005 },
+	{ ~0UL,      0x0000, 0x0000 }
+};
+
 static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
 {
 	struct device_node *np = hdmi->dev->of_node;
@@ -103,10 +154,16 @@ static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
 };
 
 static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.mpll_cfg = imx_mpll_cfg,
+	.cur_ctr  = imx_cur_ctr,
+	.sym_term = imx_sym_term,
 	.dev_type = IMX6Q_HDMI,
 };
 
 static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.mpll_cfg = imx_mpll_cfg,
+	.cur_ctr  = imx_cur_ctr,
+	.sym_term = imx_sym_term,
 	.dev_type = IMX6DL_HDMI,
 };
 
-- 
1.9.1

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

* [PATCH v15 05/12] drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
@ 2014-12-02  7:41   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:41 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

the original imx hdmi driver is under drm/imx/,
which depends on imx-drm, so move the imx hdmi
driver out to drm/bridge and rename it to dw_hdmi

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15:
- add prefix dw_hdmi/DW_HDMI for public used dw_hdmi structs
  adviced by Philipp Zabel
- remove THIS_MODULE in platform driver

Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/Kconfig                     |   5 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 .../gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c}   | 282 +++++++++++----------
 .../gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h}   |  42 ---
 drivers/gpu/drm/imx/Kconfig                        |   1 +
 drivers/gpu/drm/imx/Makefile                       |   2 +-
 .../drm/imx/{imx-hdmi_pltfm.c => dw_hdmi-imx.c}    | 129 +++++-----
 include/drm/bridge/dw_hdmi.h                       |  59 +++++
 8 files changed, 272 insertions(+), 249 deletions(-)
 rename drivers/gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c} (83%)
 rename drivers/gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h} (98%)
 rename drivers/gpu/drm/imx/{imx-hdmi_pltfm.c => dw_hdmi-imx.c} (58%)
 create mode 100644 include/drm/bridge/dw_hdmi.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 884923f..26162ef 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,3 +3,8 @@ config DRM_PTN3460
 	depends on DRM
 	select DRM_KMS_HELPER
 	---help---
+
+config DRM_DW_HDMI
+	bool "Synopsys DesignWare High-Definition Multimedia Interface"
+	depends on DRM
+	select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index b4733e1..d8a8cfd 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,3 +1,4 @@
 ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
+obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
similarity index 83%
rename from drivers/gpu/drm/imx/imx-hdmi.c
rename to drivers/gpu/drm/bridge/dw_hdmi.c
index 99c2966..6f5b70a 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -6,12 +6,11 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
- * for SLISHDMI13T and SLIPHDMIT IP cores
+ * Designware High-Definition Multimedia Interface (HDMI) driver
  *
  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  */
-
+#include <linux/module.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -23,8 +22,9 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
+#include <drm/bridge/dw_hdmi.h>
 
-#include "imx-hdmi.h"
+#include "dw_hdmi.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -100,16 +100,17 @@ struct hdmi_data_info {
 	struct hdmi_vmode video_mode;
 };
 
-struct imx_hdmi {
+struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 
-	enum imx_hdmi_devtype dev_type;
+	enum dw_hdmi_devtype dev_type;
 	struct device *dev;
 
 	struct hdmi_data_info hdmi_data;
-	const struct imx_hdmi_plat_data *plat_data;
+	const struct dw_hdmi_plat_data *plat_data;
+
 	int vic;
 
 	u8 edid[HDMI_EDID_LEN];
@@ -126,17 +127,17 @@ struct imx_hdmi {
 	int ratio;
 };
 
-static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
+static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
 {
 	writeb(val, hdmi->regs + offset);
 }
 
-static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
 {
 	return readb(hdmi->regs + offset);
 }
 
-static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
+static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 {
 	u8 val = hdmi_readb(hdmi, reg) & ~mask;
 
@@ -144,13 +145,13 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 	hdmi_writeb(hdmi, val, reg);
 }
 
-static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
+static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
 			     u8 shift, u8 mask)
 {
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
 
-static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
+static void hdmi_set_clock_regenerator_n(struct dw_hdmi *hdmi,
 					 unsigned int value)
 {
 	hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
@@ -161,7 +162,7 @@ static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
 }
 
-static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
+static void hdmi_regenerate_cts(struct dw_hdmi *hdmi, unsigned int cts)
 {
 	/* Must be set/cleared first */
 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
@@ -308,7 +309,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 	return (cts * ratio) / 100;
 }
 
-static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
+static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
 				     unsigned long pixel_clk)
 {
 	unsigned int clk_n, clk_cts;
@@ -332,12 +333,12 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
 	hdmi_regenerate_cts(hdmi, clk_cts);
 }
 
-static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
+static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
 {
 	hdmi_set_clk_regenerator(hdmi, 74250000);
 }
 
-static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
+static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
 {
 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
 }
@@ -349,7 +350,7 @@ static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
  *			pin{31~24} <==> G[7:0]
  *			pin{15~8}  <==> B[7:0]
  */
-static void hdmi_video_sample(struct imx_hdmi *hdmi)
+static void hdmi_video_sample(struct dw_hdmi *hdmi)
 {
 	int color_format = 0;
 	u8 val;
@@ -405,12 +406,12 @@ static void hdmi_video_sample(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
 }
 
-static int is_color_space_conversion(struct imx_hdmi *hdmi)
+static int is_color_space_conversion(struct dw_hdmi *hdmi)
 {
 	return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
 }
 
-static int is_color_space_decimation(struct imx_hdmi *hdmi)
+static int is_color_space_decimation(struct dw_hdmi *hdmi)
 {
 	if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
 		return 0;
@@ -420,7 +421,7 @@ static int is_color_space_decimation(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static int is_color_space_interpolation(struct imx_hdmi *hdmi)
+static int is_color_space_interpolation(struct dw_hdmi *hdmi)
 {
 	if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
 		return 0;
@@ -430,7 +431,7 @@ static int is_color_space_interpolation(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
+static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
 {
 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
 	unsigned i;
@@ -471,7 +472,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 		  HDMI_CSC_SCALE);
 }
 
-static void hdmi_video_csc(struct imx_hdmi *hdmi)
+static void hdmi_video_csc(struct dw_hdmi *hdmi)
 {
 	int color_depth = 0;
 	int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
@@ -499,7 +500,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
 	hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
 		  HDMI_CSC_SCALE);
 
-	imx_hdmi_update_csc_coeffs(hdmi);
+	dw_hdmi_update_csc_coeffs(hdmi);
 }
 
 /*
@@ -507,7 +508,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
  * for example, if input is YCC422 mode or repeater is used,
  * data should be repacked this module can be bypassed.
  */
-static void hdmi_video_packetize(struct imx_hdmi *hdmi)
+static void hdmi_video_packetize(struct dw_hdmi *hdmi)
 {
 	unsigned int color_depth = 0;
 	unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
@@ -604,40 +605,40 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 		  HDMI_VP_CONF);
 }
 
-static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
+static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 				       unsigned char bit)
 {
 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
-static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi, int msec)
+static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
 	while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
 		if (msec-- == 0)
@@ -647,7 +648,7 @@ static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
 	return true;
 }
 
-static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 				 unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
@@ -661,63 +662,64 @@ static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
 
-static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 			      unsigned char addr)
 {
 	__hdmi_phy_i2c_write(hdmi, data, addr);
 	return 0;
 }
 
-static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_power(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_PDZ_OFFSET,
 			 HDMI_PHY_CONF0_PDZ_MASK);
 }
 
-static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_ENTMDS_OFFSET,
 			 HDMI_PHY_CONF0_ENTMDS_MASK);
 }
 
-static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
 			 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
 }
 
-static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
 			 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
 }
 
-static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
 			 HDMI_PHY_CONF0_SELDATAENPOL_MASK);
 }
 
-static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_SELDIPIF_OFFSET,
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
+static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 			      unsigned char res, int cscon)
 {
 	unsigned res_idx, i;
 	u8 val, msec;
-	const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
-	const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
-	const struct sym_term *sym_term =  hdmi->plat_data->sym_term;
+	const struct dw_hdmi_mpll_config *mpll_config =
+						hdmi->plat_data->mpll_cfg;
+	const struct dw_hdmi_curr_ctrl *curr_ctrl = hdmi->plat_data->cur_ctr;
+	const struct dw_hdmi_sym_term *sym_term =  hdmi->plat_data->sym_term;
 
 	if (prep)
 		return -EINVAL;
@@ -725,13 +727,13 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	switch (res) {
 	case 0:	/* color resolution 0 is 8 bit colour depth */
 	case 8:
-		res_idx = RES_8;
+		res_idx = DW_HDMI_RES_8;
 		break;
 	case 10:
-		res_idx = RES_10;
+		res_idx = DW_HDMI_RES_10;
 		break;
 	case 12:
-		res_idx = RES_12;
+		res_idx = DW_HDMI_RES_12;
 		break;
 	default:
 		return -EINVAL;
@@ -746,10 +748,10 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
 
 	/* gen2 tx power off */
-	imx_hdmi_phy_gen2_txpwron(hdmi, 0);
+	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
 
 	/* gen2 pddq */
-	imx_hdmi_phy_gen2_pddq(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 1);
 
 	/* PHY reset */
 	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
@@ -803,15 +805,15 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	/* REMOVE CLK TERM */
 	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
 
-	imx_hdmi_phy_enable_power(hdmi, 1);
+	dw_hdmi_phy_enable_power(hdmi, 1);
 
 	/* toggle TMDS enable */
-	imx_hdmi_phy_enable_tmds(hdmi, 0);
-	imx_hdmi_phy_enable_tmds(hdmi, 1);
+	dw_hdmi_phy_enable_tmds(hdmi, 0);
+	dw_hdmi_phy_enable_tmds(hdmi, 1);
 
 	/* gen2 tx power on */
-	imx_hdmi_phy_gen2_txpwron(hdmi, 1);
-	imx_hdmi_phy_gen2_pddq(hdmi, 0);
+	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
 	/*Wait for PHY PLL lock */
 	msec = 5;
@@ -832,7 +834,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	return 0;
 }
 
-static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 {
 	int i, ret;
 	bool cscon = false;
@@ -843,10 +845,10 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
 
 	/* HDMI Phy spec says to do the phy initialization sequence twice */
 	for (i = 0; i < 2; i++) {
-		imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
-		imx_hdmi_phy_sel_interface_control(hdmi, 0);
-		imx_hdmi_phy_enable_tmds(hdmi, 0);
-		imx_hdmi_phy_enable_power(hdmi, 0);
+		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_power(hdmi, 0);
 
 		/* Enable CSC */
 		ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
@@ -858,7 +860,7 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
+static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 {
 	u8 de;
 
@@ -877,7 +879,7 @@ static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
 		  HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
 }
 
-static void hdmi_config_AVI(struct imx_hdmi *hdmi)
+static void hdmi_config_AVI(struct dw_hdmi *hdmi)
 {
 	u8 val, pix_fmt, under_scan;
 	u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
@@ -971,7 +973,7 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
 }
 
-static void hdmi_av_composer(struct imx_hdmi *hdmi,
+static void hdmi_av_composer(struct dw_hdmi *hdmi,
 			     const struct drm_display_mode *mode)
 {
 	u8 inv_val;
@@ -1055,19 +1057,19 @@ static void hdmi_av_composer(struct imx_hdmi *hdmi,
 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
-static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
 {
 	if (!hdmi->phy_enabled)
 		return;
 
-	imx_hdmi_phy_enable_tmds(hdmi, 0);
-	imx_hdmi_phy_enable_power(hdmi, 0);
+	dw_hdmi_phy_enable_tmds(hdmi, 0);
+	dw_hdmi_phy_enable_power(hdmi, 0);
 
 	hdmi->phy_enabled = false;
 }
 
 /* HDMI Initialization Step B.4 */
-static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
+static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
 	u8 clkdis;
 
@@ -1096,13 +1098,13 @@ static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
 	}
 }
 
-static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
 {
 	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
 }
 
 /* Workaround to clear the overflow condition */
-static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
+static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 {
 	int count;
 	u8 val;
@@ -1120,19 +1122,19 @@ static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
 		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
 }
 
-static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
 	hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
 }
 
-static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
 		    HDMI_IH_MUTE_FC_STAT2);
 }
 
-static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
+static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 {
 	int ret;
 
@@ -1184,12 +1186,12 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_av_composer(hdmi, mode);
 
 	/* HDMI Initializateion Step B.2 */
-	ret = imx_hdmi_phy_init(hdmi);
+	ret = dw_hdmi_phy_init(hdmi);
 	if (ret)
 		return ret;
 
 	/* HDMI Initialization Step B.3 */
-	imx_hdmi_enable_video_path(hdmi);
+	dw_hdmi_enable_video_path(hdmi);
 
 	/* not for DVI mode */
 	if (hdmi->hdmi_data.video_mode.mdvi) {
@@ -1210,7 +1212,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_video_sample(hdmi);
 	hdmi_tx_hdcp_config(hdmi);
 
-	imx_hdmi_clear_overflow(hdmi);
+	dw_hdmi_clear_overflow(hdmi);
 	if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
 		hdmi_enable_overflow_interrupts(hdmi);
 
@@ -1218,7 +1220,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 }
 
 /* Wait until we are registered to enable interrupts */
-static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
+static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
 		    HDMI_PHY_I2CM_INT_ADDR);
@@ -1236,7 +1238,7 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
+static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 {
 	u8 ih_mute;
 
@@ -1288,73 +1290,73 @@ static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
 }
 
-static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
+static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
-	imx_hdmi_setup(hdmi, &hdmi->previous_mode);
+	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
-static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
+static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
-	imx_hdmi_phy_disable(hdmi);
+	dw_hdmi_phy_disable(hdmi);
 }
 
-static void imx_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adjusted_mode)
+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+				    struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_setup(hdmi, mode);
+	dw_hdmi_setup(hdmi, mode);
 
 	/* Store the display mode for plugin/DKMS poweron events */
 	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
 }
 
-static bool imx_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
-				       const struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
+static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				      const struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
 {
 	return true;
 }
 
-static void imx_hdmi_bridge_disable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_poweroff(hdmi);
+	dw_hdmi_poweroff(hdmi);
 }
 
-static void imx_hdmi_bridge_enable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_poweron(hdmi);
+	dw_hdmi_poweron(hdmi);
 }
 
-static void imx_hdmi_bridge_destroy(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_destroy(struct drm_bridge *bridge)
 {
 	drm_bridge_cleanup(bridge);
 	kfree(bridge);
 }
 
-static void imx_hdmi_bridge_nope(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_nope(struct drm_bridge *bridge)
 {
 	/* do nothing */
 }
 
-static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
-							*connector, bool force)
+static enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
 		connector_status_connected : connector_status_disconnected;
 }
 
-static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
+static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 	struct edid *edid;
 	int ret;
@@ -1377,46 +1379,46 @@ static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
 	return 0;
 }
 
-static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
+static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector
 							   *connector)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
 	return hdmi->encoder;
 }
 
-static void imx_hdmi_connector_destroy(struct drm_connector *connector)
+static void dw_hdmi_connector_destroy(struct drm_connector *connector)
 {
 	drm_connector_unregister(connector);
 	drm_connector_cleanup(connector);
 }
 
-static struct drm_connector_funcs imx_hdmi_connector_funcs = {
+static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
-	.detect = imx_hdmi_connector_detect,
-	.destroy = imx_hdmi_connector_destroy,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
 };
 
-static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
-	.get_modes = imx_hdmi_connector_get_modes,
-	.best_encoder = imx_hdmi_connector_best_encoder,
+static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
+	.get_modes = dw_hdmi_connector_get_modes,
+	.best_encoder = dw_hdmi_connector_best_encoder,
 };
 
-struct drm_bridge_funcs imx_hdmi_bridge_funcs = {
-	.enable = imx_hdmi_bridge_enable,
-	.disable = imx_hdmi_bridge_disable,
-	.pre_enable = imx_hdmi_bridge_nope,
-	.post_disable = imx_hdmi_bridge_nope,
-	.mode_set = imx_hdmi_bridge_mode_set,
-	.mode_fixup = imx_hdmi_bridge_mode_fixup,
-	.destroy = imx_hdmi_bridge_destroy,
+struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
+	.enable = dw_hdmi_bridge_enable,
+	.disable = dw_hdmi_bridge_disable,
+	.pre_enable = dw_hdmi_bridge_nope,
+	.post_disable = dw_hdmi_bridge_nope,
+	.mode_set = dw_hdmi_bridge_mode_set,
+	.mode_fixup = dw_hdmi_bridge_mode_fixup,
+	.destroy = dw_hdmi_bridge_destroy,
 };
 
-static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 {
-	struct imx_hdmi *hdmi = dev_id;
+	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
 
 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
@@ -1426,9 +1428,9 @@ static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
 	return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
 }
 
-static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 {
-	struct imx_hdmi *hdmi = dev_id;
+	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
 	u8 phy_int_pol;
 
@@ -1442,14 +1444,14 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 
 			hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
 
-			imx_hdmi_poweron(hdmi);
+			dw_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
 			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
 				  HDMI_PHY_POL0);
 
-			imx_hdmi_poweroff(hdmi);
+			dw_hdmi_poweroff(hdmi);
 		}
 		drm_helper_hpd_irq_event(hdmi->connector.dev);
 	}
@@ -1460,7 +1462,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
+static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 {
 	struct drm_encoder *encoder = hdmi->encoder;
 	struct drm_bridge *bridge;
@@ -1475,7 +1477,7 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	hdmi->bridge = bridge;
 	bridge->driver_private = hdmi;
 
-	ret = drm_bridge_init(drm, bridge, &imx_hdmi_bridge_funcs);
+	ret = drm_bridge_init(drm, bridge, &dw_hdmi_bridge_funcs);
 	if (ret) {
 		DRM_ERROR("Failed to initialize bridge with drm\n");
 		return -EINVAL;
@@ -1485,8 +1487,8 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
 	drm_connector_helper_add(&hdmi->connector,
-				 &imx_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
+				 &dw_hdmi_connector_helper_funcs);
+	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
@@ -1496,15 +1498,15 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	return 0;
 }
 
-int imx_hdmi_bind(struct device *dev, struct device *master,
-		  void *data, struct drm_encoder *encoder,
-		  const struct imx_hdmi_plat_data *plat_data)
+int dw_hdmi_bind(struct device *dev, struct device *master,
+		 void *data, struct drm_encoder *encoder,
+		 const struct dw_hdmi_plat_data *plat_data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct device_node *ddc_node;
-	struct imx_hdmi *hdmi;
+	struct dw_hdmi *hdmi;
 	struct resource *iores;
 	int ret, irq;
 
@@ -1536,8 +1538,8 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 	if (irq < 0)
 		return irq;
 
-	ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
-					imx_hdmi_irq, IRQF_SHARED,
+	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
+					dw_hdmi_irq, IRQF_SHARED,
 					dev_name(dev), hdmi);
 	if (ret)
 		return ret;
@@ -1572,11 +1574,11 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 	/* Clear Hotplug interrupts */
 	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
 
-	ret = imx_hdmi_fb_registered(hdmi);
+	ret = dw_hdmi_fb_registered(hdmi);
 	if (ret)
 		return ret;
 
-	ret = imx_hdmi_register(drm, hdmi);
+	ret = dw_hdmi_register(drm, hdmi);
 	if (ret)
 		return ret;
 
@@ -1587,11 +1589,11 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(imx_hdmi_bind);
+EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
-	struct imx_hdmi *hdmi = dev_get_drvdata(dev);
+	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
@@ -1601,11 +1603,11 @@ void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
 
 	i2c_put_adapter(hdmi->ddc);
 }
-EXPORT_SYMBOL_GPL(imx_hdmi_unbind);
+EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
 MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
-MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
+MODULE_DESCRIPTION("DW HDMI transmitter driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-hdmi");
+MODULE_ALIAS("platform:dw-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
similarity index 98%
rename from drivers/gpu/drm/imx/imx-hdmi.h
rename to drivers/gpu/drm/bridge/dw_hdmi.h
index bced9ef..baa7849 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -1030,46 +1030,4 @@ enum {
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
 };
 
-enum imx_hdmi_devtype {
-	IMX6Q_HDMI,
-	IMX6DL_HDMI,
-};
-
-struct imx_hdmi_plat_data {
-	enum imx_hdmi_devtype dev_type;
-	const struct mpll_config *mpll_cfg;
-	const struct curr_ctrl *cur_ctr;
-	const struct sym_term *sym_term;
-};
-
-enum {
-	RES_8,
-	RES_10,
-	RES_12,
-	RES_MAX,
-};
-
-struct mpll_config {
-	unsigned long mpixelclock;
-	struct {
-		u16 cpce;
-		u16 gmp;
-	} res[RES_MAX];
-};
-
-struct curr_ctrl {
-	unsigned long mpixelclock;
-	u16 curr[RES_MAX];
-};
-
-struct sym_term {
-	unsigned long mpixelclock;
-	u16 sym_ctr;    /*clock symbol and transmitter control*/
-	u16 term;       /*transmission termination value*/
-};
-
-int imx_hdmi_bind(struct device *dev, struct device *master,
-		  void *data, struct drm_encoder *encoder,
-		  const struct imx_hdmi_plat_data *plat_data);
-void imx_hdmi_unbind(struct device *dev, struct device *master, void *data);
 #endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 82fb758..7070077 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -48,6 +48,7 @@ config DRM_IMX_IPUV3
 
 config DRM_IMX_HDMI
 	tristate "Freescale i.MX DRM HDMI"
+	select DRM_DW_HDMI
 	depends on DRM_IMX
 	help
 	  Choose this if you want to use HDMI on i.MX6.
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 63cf56a..f3ecd89 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 
 imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
 obj-$(CONFIG_DRM_IMX_IPUV3)	+= imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o imx-hdmi_pltfm.o
+obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
similarity index 58%
rename from drivers/gpu/drm/imx/imx-hdmi_pltfm.c
rename to drivers/gpu/drm/imx/dw_hdmi-imx.c
index da330e0..d74c1f6 100644
--- a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  *
- * derived from imx-hdmi.c
+ * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,6 +11,7 @@
 #include <linux/component.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <drm/bridge/dw_hdmi.h>
 #include <video/imx-ipu-v3.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
@@ -21,9 +22,8 @@
 #include <drm/drm_encoder_slave.h>
 
 #include "imx-drm.h"
-#include "imx-hdmi.h"
 
-struct imx_hdmi_priv {
+struct imx_hdmi {
 	struct device *dev;
 	struct drm_encoder encoder;
 	struct clk *isfr_clk;
@@ -31,7 +31,7 @@ struct imx_hdmi_priv {
 	struct regmap *regmap;
 };
 
-static const struct mpll_config imx_mpll_cfg[] = {
+static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = {
 	{
 		45250000, {
 			{ 0x01e0, 0x0000 },
@@ -59,7 +59,7 @@ static const struct mpll_config imx_mpll_cfg[] = {
 	}
 };
 
-static const struct curr_ctrl imx_cur_ctr[] = {
+static const struct dw_hdmi_curr_ctrl imx_cur_ctr[] = {
 	/*      pixelclk     bpp8    bpp10   bpp12 */
 	{
 		54000000, { 0x091c, 0x091c, 0x06dc },
@@ -76,13 +76,13 @@ static const struct curr_ctrl imx_cur_ctr[] = {
 	}
 };
 
-static const struct sym_term imx_sym_term[] = {
+static const struct dw_hdmi_sym_term imx_sym_term[] = {
 	/*pixelclk   symbol   term*/
 	{ 148500000, 0x800d, 0x0005 },
 	{ ~0UL,      0x0000, 0x0000 }
 };
 
-static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
+static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
 {
 	struct device_node *np = hdmi->dev->of_node;
 
@@ -107,28 +107,26 @@ static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
 	return 0;
 }
 
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
 {
 }
 
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-					const struct drm_display_mode *mode,
-					struct drm_display_mode *adjusted_mode)
+static bool dw_hdmi_imx_encoder_mode_fixup(struct drm_encoder *encoder,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
 {
 	return true;
 }
 
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-				      struct drm_display_mode *mode,
-				      struct drm_display_mode *adjusted_mode)
+static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
+					 struct drm_display_mode *mode,
+					 struct drm_display_mode *adjusted_mode)
 {
 }
 
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
 {
-	struct imx_hdmi_priv *hdmi = container_of(encoder,
-						  struct imx_hdmi_priv,
-						  encoder);
+	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
 	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 
 	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
@@ -136,38 +134,38 @@ static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
 			   mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
 }
 
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
 {
 	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
 }
 
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
-	.mode_fixup = imx_hdmi_encoder_mode_fixup,
-	.mode_set = imx_hdmi_encoder_mode_set,
-	.prepare = imx_hdmi_encoder_prepare,
-	.commit = imx_hdmi_encoder_commit,
-	.disable = imx_hdmi_encoder_disable,
+static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
+	.mode_fixup = dw_hdmi_imx_encoder_mode_fixup,
+	.mode_set = dw_hdmi_imx_encoder_mode_set,
+	.prepare = dw_hdmi_imx_encoder_prepare,
+	.commit = dw_hdmi_imx_encoder_commit,
+	.disable = dw_hdmi_imx_encoder_disable,
 };
 
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
+static struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
 
-static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
-	.mpll_cfg = imx_mpll_cfg,
-	.cur_ctr  = imx_cur_ctr,
-	.sym_term = imx_sym_term,
-	.dev_type = IMX6Q_HDMI,
+static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.mpll_cfg		= imx_mpll_cfg,
+	.cur_ctr		= imx_cur_ctr,
+	.sym_term		= imx_sym_term,
+	.dev_type		= IMX6Q_HDMI,
 };
 
-static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
-	.mpll_cfg = imx_mpll_cfg,
-	.cur_ctr  = imx_cur_ctr,
-	.sym_term = imx_sym_term,
-	.dev_type = IMX6DL_HDMI,
+static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.mpll_cfg		= imx_mpll_cfg,
+	.cur_ctr		= imx_cur_ctr,
+	.sym_term		= imx_sym_term,
+	.dev_type		= IMX6DL_HDMI,
 };
 
-static const struct of_device_id imx_hdmi_dt_ids[] = {
+static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx6q-hdmi",
 	  .data = &imx6q_hdmi_drv_data
 	}, {
@@ -176,17 +174,17 @@ static const struct of_device_id imx_hdmi_dt_ids[] = {
 	},
 	{},
 };
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
 
-static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
-			       void *data)
+static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
+			    void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	const struct imx_hdmi_plat_data *plat_data;
+	const struct dw_hdmi_plat_data *plat_data;
 	const struct of_device_id *match;
 	struct drm_device *drm = data;
 	struct drm_encoder *encoder;
-	struct imx_hdmi_priv *hdmi;
+	struct imx_hdmi *hdmi;
 	int ret;
 
 	if (!pdev->dev.of_node)
@@ -196,7 +194,7 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 	if (!hdmi)
 		return -ENOMEM;
 
-	match = of_match_node(imx_hdmi_dt_ids, pdev->dev.of_node);
+	match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node);
 	plat_data = match->data;
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
@@ -212,7 +210,7 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 	if (encoder->possible_crtcs == 0)
 		return -EPROBE_DEFER;
 
-	ret = imx_hdmi_parse_dt(hdmi);
+	ret = dw_hdmi_imx_parse_dt(hdmi);
 	if (ret < 0)
 		return ret;
 
@@ -228,56 +226,55 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	drm_encoder_helper_add(encoder, &imx_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &imx_hdmi_encoder_funcs,
+	drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS);
 
-	return imx_hdmi_bind(dev, master, data, encoder, plat_data);
+	return dw_hdmi_bind(dev, master, data, encoder, plat_data);
 }
 
-static void imx_hdmi_pltfm_unbind(struct device *dev, struct device *master,
-				  void *data)
+static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
+			       void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct imx_hdmi_priv *hdmi = platform_get_drvdata(pdev);
+	struct imx_hdmi *hdmi = platform_get_drvdata(pdev);
 
 	clk_disable_unprepare(hdmi->isfr_clk);
 	clk_disable_unprepare(hdmi->iahb_clk);
 
-	return imx_hdmi_unbind(dev, master, data);
+	return dw_hdmi_unbind(dev, master, data);
 }
 
-static const struct component_ops imx_hdmi_ops = {
-	.bind	= imx_hdmi_pltfm_bind,
-	.unbind	= imx_hdmi_pltfm_unbind,
+static const struct component_ops dw_hdmi_imx_ops = {
+	.bind	= dw_hdmi_imx_bind,
+	.unbind	= dw_hdmi_imx_unbind,
 };
 
-static int imx_hdmi_probe(struct platform_device *pdev)
+static int dw_hdmi_imx_probe(struct platform_device *pdev)
 {
-	return component_add(&pdev->dev, &imx_hdmi_ops);
+	return component_add(&pdev->dev, &dw_hdmi_imx_ops);
 }
 
-static int imx_hdmi_remove(struct platform_device *pdev)
+static int dw_hdmi_imx_remove(struct platform_device *pdev)
 {
-	component_del(&pdev->dev, &imx_hdmi_ops);
+	component_del(&pdev->dev, &dw_hdmi_imx_ops);
 
 	return 0;
 }
 
-static struct platform_driver imx_hdmi_pltfm_driver = {
-	.probe  = imx_hdmi_probe,
-	.remove = imx_hdmi_remove,
+static struct platform_driver dw_hdmi_imx_platform_driver = {
+	.probe  = dw_hdmi_imx_probe,
+	.remove = dw_hdmi_imx_remove,
 	.driver = {
-		.name = "hdmi-imx",
-		.owner = THIS_MODULE,
-		.of_match_table = imx_hdmi_dt_ids,
+		.name = "dwhdmi-imx",
+		.of_match_table = dw_hdmi_imx_dt_ids,
 	},
 };
 
-module_platform_driver(imx_hdmi_pltfm_driver);
+module_platform_driver(dw_hdmi_imx_platform_driver);
 
 MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
 MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:hdmi-imx");
+MODULE_ALIAS("platform:dwhdmi-imx");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
new file mode 100644
index 0000000..fff6ae6
--- /dev/null
+++ b/include/drm/bridge/dw_hdmi.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DW_HDMI__
+#define __DW_HDMI__
+
+#include <drm/drmP.h>
+
+enum {
+	DW_HDMI_RES_8,
+	DW_HDMI_RES_10,
+	DW_HDMI_RES_12,
+	DW_HDMI_RES_MAX,
+};
+
+enum dw_hdmi_devtype {
+	IMX6Q_HDMI,
+	IMX6DL_HDMI,
+};
+
+struct dw_hdmi_mpll_config {
+	unsigned long mpixelclock;
+	struct {
+		u16 cpce;
+		u16 gmp;
+	} res[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_curr_ctrl {
+	unsigned long mpixelclock;
+	u16 curr[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_sym_term {
+	unsigned long mpixelclock;
+	u16 sym_ctr;    /*clock symbol and transmitter control*/
+	u16 term;       /*transmission termination value*/
+};
+
+struct dw_hdmi_plat_data {
+	enum dw_hdmi_devtype dev_type;
+	const struct dw_hdmi_mpll_config *mpll_cfg;
+	const struct dw_hdmi_curr_ctrl *cur_ctr;
+	const struct dw_hdmi_sym_term *sym_term;
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+			      struct drm_display_mode *mode);
+};
+
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);
+int dw_hdmi_bind(struct device *dev, struct device *master,
+		 void *data, struct drm_encoder *encoder,
+		 const struct dw_hdmi_plat_data *plat_data);
+#endif /* __IMX_HDMI_H__ */
-- 
1.9.1



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

* [PATCH v15 05/12] drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
@ 2014-12-02  7:41   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:41 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, Philipp Zabel, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	djkurtz-hpIqsD4AKlfQT0dZR+AlfA, ykk-TNX95d0MmH7DzftRWevZcw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	jay.xu-TNX95d0MmH7DzftRWevZcw, Pawel Moll,
	mark.yao-TNX95d0MmH7DzftRWevZcw, Mark Rutland,
	vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA, Ian Campbell,
	Kumar Gala, Andy Yan

the original imx hdmi driver is under drm/imx/,
which depends on imx-drm, so move the imx hdmi
driver out to drm/bridge and rename it to dw_hdmi

Signed-off-by: Andy Yan <andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

---

Changes in v15:
- add prefix dw_hdmi/DW_HDMI for public used dw_hdmi structs
  adviced by Philipp Zabel
- remove THIS_MODULE in platform driver

Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/Kconfig                     |   5 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 .../gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c}   | 282 +++++++++++----------
 .../gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h}   |  42 ---
 drivers/gpu/drm/imx/Kconfig                        |   1 +
 drivers/gpu/drm/imx/Makefile                       |   2 +-
 .../drm/imx/{imx-hdmi_pltfm.c => dw_hdmi-imx.c}    | 129 +++++-----
 include/drm/bridge/dw_hdmi.h                       |  59 +++++
 8 files changed, 272 insertions(+), 249 deletions(-)
 rename drivers/gpu/drm/{imx/imx-hdmi.c => bridge/dw_hdmi.c} (83%)
 rename drivers/gpu/drm/{imx/imx-hdmi.h => bridge/dw_hdmi.h} (98%)
 rename drivers/gpu/drm/imx/{imx-hdmi_pltfm.c => dw_hdmi-imx.c} (58%)
 create mode 100644 include/drm/bridge/dw_hdmi.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 884923f..26162ef 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,3 +3,8 @@ config DRM_PTN3460
 	depends on DRM
 	select DRM_KMS_HELPER
 	---help---
+
+config DRM_DW_HDMI
+	bool "Synopsys DesignWare High-Definition Multimedia Interface"
+	depends on DRM
+	select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index b4733e1..d8a8cfd 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,3 +1,4 @@
 ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
+obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
similarity index 83%
rename from drivers/gpu/drm/imx/imx-hdmi.c
rename to drivers/gpu/drm/bridge/dw_hdmi.c
index 99c2966..6f5b70a 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -6,12 +6,11 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
- * for SLISHDMI13T and SLIPHDMIT IP cores
+ * Designware High-Definition Multimedia Interface (HDMI) driver
  *
  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
  */
-
+#include <linux/module.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -23,8 +22,9 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
+#include <drm/bridge/dw_hdmi.h>
 
-#include "imx-hdmi.h"
+#include "dw_hdmi.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -100,16 +100,17 @@ struct hdmi_data_info {
 	struct hdmi_vmode video_mode;
 };
 
-struct imx_hdmi {
+struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 
-	enum imx_hdmi_devtype dev_type;
+	enum dw_hdmi_devtype dev_type;
 	struct device *dev;
 
 	struct hdmi_data_info hdmi_data;
-	const struct imx_hdmi_plat_data *plat_data;
+	const struct dw_hdmi_plat_data *plat_data;
+
 	int vic;
 
 	u8 edid[HDMI_EDID_LEN];
@@ -126,17 +127,17 @@ struct imx_hdmi {
 	int ratio;
 };
 
-static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
+static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
 {
 	writeb(val, hdmi->regs + offset);
 }
 
-static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
 {
 	return readb(hdmi->regs + offset);
 }
 
-static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
+static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 {
 	u8 val = hdmi_readb(hdmi, reg) & ~mask;
 
@@ -144,13 +145,13 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 	hdmi_writeb(hdmi, val, reg);
 }
 
-static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
+static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
 			     u8 shift, u8 mask)
 {
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
 
-static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
+static void hdmi_set_clock_regenerator_n(struct dw_hdmi *hdmi,
 					 unsigned int value)
 {
 	hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
@@ -161,7 +162,7 @@ static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
 }
 
-static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
+static void hdmi_regenerate_cts(struct dw_hdmi *hdmi, unsigned int cts)
 {
 	/* Must be set/cleared first */
 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
@@ -308,7 +309,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 	return (cts * ratio) / 100;
 }
 
-static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
+static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
 				     unsigned long pixel_clk)
 {
 	unsigned int clk_n, clk_cts;
@@ -332,12 +333,12 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
 	hdmi_regenerate_cts(hdmi, clk_cts);
 }
 
-static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
+static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
 {
 	hdmi_set_clk_regenerator(hdmi, 74250000);
 }
 
-static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
+static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
 {
 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
 }
@@ -349,7 +350,7 @@ static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
  *			pin{31~24} <==> G[7:0]
  *			pin{15~8}  <==> B[7:0]
  */
-static void hdmi_video_sample(struct imx_hdmi *hdmi)
+static void hdmi_video_sample(struct dw_hdmi *hdmi)
 {
 	int color_format = 0;
 	u8 val;
@@ -405,12 +406,12 @@ static void hdmi_video_sample(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
 }
 
-static int is_color_space_conversion(struct imx_hdmi *hdmi)
+static int is_color_space_conversion(struct dw_hdmi *hdmi)
 {
 	return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
 }
 
-static int is_color_space_decimation(struct imx_hdmi *hdmi)
+static int is_color_space_decimation(struct dw_hdmi *hdmi)
 {
 	if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
 		return 0;
@@ -420,7 +421,7 @@ static int is_color_space_decimation(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static int is_color_space_interpolation(struct imx_hdmi *hdmi)
+static int is_color_space_interpolation(struct dw_hdmi *hdmi)
 {
 	if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
 		return 0;
@@ -430,7 +431,7 @@ static int is_color_space_interpolation(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
+static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
 {
 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
 	unsigned i;
@@ -471,7 +472,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 		  HDMI_CSC_SCALE);
 }
 
-static void hdmi_video_csc(struct imx_hdmi *hdmi)
+static void hdmi_video_csc(struct dw_hdmi *hdmi)
 {
 	int color_depth = 0;
 	int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
@@ -499,7 +500,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
 	hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
 		  HDMI_CSC_SCALE);
 
-	imx_hdmi_update_csc_coeffs(hdmi);
+	dw_hdmi_update_csc_coeffs(hdmi);
 }
 
 /*
@@ -507,7 +508,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
  * for example, if input is YCC422 mode or repeater is used,
  * data should be repacked this module can be bypassed.
  */
-static void hdmi_video_packetize(struct imx_hdmi *hdmi)
+static void hdmi_video_packetize(struct dw_hdmi *hdmi)
 {
 	unsigned int color_depth = 0;
 	unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
@@ -604,40 +605,40 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
 		  HDMI_VP_CONF);
 }
 
-static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
+static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
 				       unsigned char bit)
 {
 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
 }
 
-static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi,
+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 imx_hdmi *hdmi, int msec)
+static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
 	while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
 		if (msec-- == 0)
@@ -647,7 +648,7 @@ static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
 	return true;
 }
 
-static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 				 unsigned char addr)
 {
 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
@@ -661,63 +662,64 @@ static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
 	hdmi_phy_wait_i2c_done(hdmi, 1000);
 }
 
-static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 			      unsigned char addr)
 {
 	__hdmi_phy_i2c_write(hdmi, data, addr);
 	return 0;
 }
 
-static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_power(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_PDZ_OFFSET,
 			 HDMI_PHY_CONF0_PDZ_MASK);
 }
 
-static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_ENTMDS_OFFSET,
 			 HDMI_PHY_CONF0_ENTMDS_MASK);
 }
 
-static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
 			 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
 }
 
-static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
 			 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
 }
 
-static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
 			 HDMI_PHY_CONF0_SELDATAENPOL_MASK);
 }
 
-static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_SELDIPIF_OFFSET,
 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
+static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 			      unsigned char res, int cscon)
 {
 	unsigned res_idx, i;
 	u8 val, msec;
-	const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
-	const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
-	const struct sym_term *sym_term =  hdmi->plat_data->sym_term;
+	const struct dw_hdmi_mpll_config *mpll_config =
+						hdmi->plat_data->mpll_cfg;
+	const struct dw_hdmi_curr_ctrl *curr_ctrl = hdmi->plat_data->cur_ctr;
+	const struct dw_hdmi_sym_term *sym_term =  hdmi->plat_data->sym_term;
 
 	if (prep)
 		return -EINVAL;
@@ -725,13 +727,13 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	switch (res) {
 	case 0:	/* color resolution 0 is 8 bit colour depth */
 	case 8:
-		res_idx = RES_8;
+		res_idx = DW_HDMI_RES_8;
 		break;
 	case 10:
-		res_idx = RES_10;
+		res_idx = DW_HDMI_RES_10;
 		break;
 	case 12:
-		res_idx = RES_12;
+		res_idx = DW_HDMI_RES_12;
 		break;
 	default:
 		return -EINVAL;
@@ -746,10 +748,10 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
 
 	/* gen2 tx power off */
-	imx_hdmi_phy_gen2_txpwron(hdmi, 0);
+	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
 
 	/* gen2 pddq */
-	imx_hdmi_phy_gen2_pddq(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 1);
 
 	/* PHY reset */
 	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
@@ -803,15 +805,15 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	/* REMOVE CLK TERM */
 	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
 
-	imx_hdmi_phy_enable_power(hdmi, 1);
+	dw_hdmi_phy_enable_power(hdmi, 1);
 
 	/* toggle TMDS enable */
-	imx_hdmi_phy_enable_tmds(hdmi, 0);
-	imx_hdmi_phy_enable_tmds(hdmi, 1);
+	dw_hdmi_phy_enable_tmds(hdmi, 0);
+	dw_hdmi_phy_enable_tmds(hdmi, 1);
 
 	/* gen2 tx power on */
-	imx_hdmi_phy_gen2_txpwron(hdmi, 1);
-	imx_hdmi_phy_gen2_pddq(hdmi, 0);
+	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
 	/*Wait for PHY PLL lock */
 	msec = 5;
@@ -832,7 +834,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 	return 0;
 }
 
-static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 {
 	int i, ret;
 	bool cscon = false;
@@ -843,10 +845,10 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
 
 	/* HDMI Phy spec says to do the phy initialization sequence twice */
 	for (i = 0; i < 2; i++) {
-		imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
-		imx_hdmi_phy_sel_interface_control(hdmi, 0);
-		imx_hdmi_phy_enable_tmds(hdmi, 0);
-		imx_hdmi_phy_enable_power(hdmi, 0);
+		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_power(hdmi, 0);
 
 		/* Enable CSC */
 		ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
@@ -858,7 +860,7 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
+static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 {
 	u8 de;
 
@@ -877,7 +879,7 @@ static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
 		  HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
 }
 
-static void hdmi_config_AVI(struct imx_hdmi *hdmi)
+static void hdmi_config_AVI(struct dw_hdmi *hdmi)
 {
 	u8 val, pix_fmt, under_scan;
 	u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
@@ -971,7 +973,7 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
 }
 
-static void hdmi_av_composer(struct imx_hdmi *hdmi,
+static void hdmi_av_composer(struct dw_hdmi *hdmi,
 			     const struct drm_display_mode *mode)
 {
 	u8 inv_val;
@@ -1055,19 +1057,19 @@ static void hdmi_av_composer(struct imx_hdmi *hdmi,
 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
-static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
 {
 	if (!hdmi->phy_enabled)
 		return;
 
-	imx_hdmi_phy_enable_tmds(hdmi, 0);
-	imx_hdmi_phy_enable_power(hdmi, 0);
+	dw_hdmi_phy_enable_tmds(hdmi, 0);
+	dw_hdmi_phy_enable_power(hdmi, 0);
 
 	hdmi->phy_enabled = false;
 }
 
 /* HDMI Initialization Step B.4 */
-static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
+static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
 	u8 clkdis;
 
@@ -1096,13 +1098,13 @@ static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
 	}
 }
 
-static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
 {
 	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
 }
 
 /* Workaround to clear the overflow condition */
-static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
+static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 {
 	int count;
 	u8 val;
@@ -1120,19 +1122,19 @@ static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
 		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
 }
 
-static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
 	hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
 }
 
-static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
 		    HDMI_IH_MUTE_FC_STAT2);
 }
 
-static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
+static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 {
 	int ret;
 
@@ -1184,12 +1186,12 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_av_composer(hdmi, mode);
 
 	/* HDMI Initializateion Step B.2 */
-	ret = imx_hdmi_phy_init(hdmi);
+	ret = dw_hdmi_phy_init(hdmi);
 	if (ret)
 		return ret;
 
 	/* HDMI Initialization Step B.3 */
-	imx_hdmi_enable_video_path(hdmi);
+	dw_hdmi_enable_video_path(hdmi);
 
 	/* not for DVI mode */
 	if (hdmi->hdmi_data.video_mode.mdvi) {
@@ -1210,7 +1212,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_video_sample(hdmi);
 	hdmi_tx_hdcp_config(hdmi);
 
-	imx_hdmi_clear_overflow(hdmi);
+	dw_hdmi_clear_overflow(hdmi);
 	if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
 		hdmi_enable_overflow_interrupts(hdmi);
 
@@ -1218,7 +1220,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 }
 
 /* Wait until we are registered to enable interrupts */
-static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
+static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
 {
 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
 		    HDMI_PHY_I2CM_INT_ADDR);
@@ -1236,7 +1238,7 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
 	return 0;
 }
 
-static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
+static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 {
 	u8 ih_mute;
 
@@ -1288,73 +1290,73 @@ static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
 	hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
 }
 
-static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
+static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
-	imx_hdmi_setup(hdmi, &hdmi->previous_mode);
+	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
-static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
+static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
-	imx_hdmi_phy_disable(hdmi);
+	dw_hdmi_phy_disable(hdmi);
 }
 
-static void imx_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adjusted_mode)
+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+				    struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_setup(hdmi, mode);
+	dw_hdmi_setup(hdmi, mode);
 
 	/* Store the display mode for plugin/DKMS poweron events */
 	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
 }
 
-static bool imx_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
-				       const struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
+static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				      const struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
 {
 	return true;
 }
 
-static void imx_hdmi_bridge_disable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_poweroff(hdmi);
+	dw_hdmi_poweroff(hdmi);
 }
 
-static void imx_hdmi_bridge_enable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 {
-	struct imx_hdmi *hdmi = bridge->driver_private;
+	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	imx_hdmi_poweron(hdmi);
+	dw_hdmi_poweron(hdmi);
 }
 
-static void imx_hdmi_bridge_destroy(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_destroy(struct drm_bridge *bridge)
 {
 	drm_bridge_cleanup(bridge);
 	kfree(bridge);
 }
 
-static void imx_hdmi_bridge_nope(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_nope(struct drm_bridge *bridge)
 {
 	/* do nothing */
 }
 
-static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
-							*connector, bool force)
+static enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
 		connector_status_connected : connector_status_disconnected;
 }
 
-static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
+static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 	struct edid *edid;
 	int ret;
@@ -1377,46 +1379,46 @@ static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
 	return 0;
 }
 
-static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
+static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector
 							   *connector)
 {
-	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
 	return hdmi->encoder;
 }
 
-static void imx_hdmi_connector_destroy(struct drm_connector *connector)
+static void dw_hdmi_connector_destroy(struct drm_connector *connector)
 {
 	drm_connector_unregister(connector);
 	drm_connector_cleanup(connector);
 }
 
-static struct drm_connector_funcs imx_hdmi_connector_funcs = {
+static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
-	.detect = imx_hdmi_connector_detect,
-	.destroy = imx_hdmi_connector_destroy,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
 };
 
-static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
-	.get_modes = imx_hdmi_connector_get_modes,
-	.best_encoder = imx_hdmi_connector_best_encoder,
+static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
+	.get_modes = dw_hdmi_connector_get_modes,
+	.best_encoder = dw_hdmi_connector_best_encoder,
 };
 
-struct drm_bridge_funcs imx_hdmi_bridge_funcs = {
-	.enable = imx_hdmi_bridge_enable,
-	.disable = imx_hdmi_bridge_disable,
-	.pre_enable = imx_hdmi_bridge_nope,
-	.post_disable = imx_hdmi_bridge_nope,
-	.mode_set = imx_hdmi_bridge_mode_set,
-	.mode_fixup = imx_hdmi_bridge_mode_fixup,
-	.destroy = imx_hdmi_bridge_destroy,
+struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
+	.enable = dw_hdmi_bridge_enable,
+	.disable = dw_hdmi_bridge_disable,
+	.pre_enable = dw_hdmi_bridge_nope,
+	.post_disable = dw_hdmi_bridge_nope,
+	.mode_set = dw_hdmi_bridge_mode_set,
+	.mode_fixup = dw_hdmi_bridge_mode_fixup,
+	.destroy = dw_hdmi_bridge_destroy,
 };
 
-static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 {
-	struct imx_hdmi *hdmi = dev_id;
+	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
 
 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
@@ -1426,9 +1428,9 @@ static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
 	return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
 }
 
-static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 {
-	struct imx_hdmi *hdmi = dev_id;
+	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
 	u8 phy_int_pol;
 
@@ -1442,14 +1444,14 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 
 			hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
 
-			imx_hdmi_poweron(hdmi);
+			dw_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
 			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
 				  HDMI_PHY_POL0);
 
-			imx_hdmi_poweroff(hdmi);
+			dw_hdmi_poweroff(hdmi);
 		}
 		drm_helper_hpd_irq_event(hdmi->connector.dev);
 	}
@@ -1460,7 +1462,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
+static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 {
 	struct drm_encoder *encoder = hdmi->encoder;
 	struct drm_bridge *bridge;
@@ -1475,7 +1477,7 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	hdmi->bridge = bridge;
 	bridge->driver_private = hdmi;
 
-	ret = drm_bridge_init(drm, bridge, &imx_hdmi_bridge_funcs);
+	ret = drm_bridge_init(drm, bridge, &dw_hdmi_bridge_funcs);
 	if (ret) {
 		DRM_ERROR("Failed to initialize bridge with drm\n");
 		return -EINVAL;
@@ -1485,8 +1487,8 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
 	drm_connector_helper_add(&hdmi->connector,
-				 &imx_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
+				 &dw_hdmi_connector_helper_funcs);
+	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
@@ -1496,15 +1498,15 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 	return 0;
 }
 
-int imx_hdmi_bind(struct device *dev, struct device *master,
-		  void *data, struct drm_encoder *encoder,
-		  const struct imx_hdmi_plat_data *plat_data)
+int dw_hdmi_bind(struct device *dev, struct device *master,
+		 void *data, struct drm_encoder *encoder,
+		 const struct dw_hdmi_plat_data *plat_data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct device_node *ddc_node;
-	struct imx_hdmi *hdmi;
+	struct dw_hdmi *hdmi;
 	struct resource *iores;
 	int ret, irq;
 
@@ -1536,8 +1538,8 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 	if (irq < 0)
 		return irq;
 
-	ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
-					imx_hdmi_irq, IRQF_SHARED,
+	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
+					dw_hdmi_irq, IRQF_SHARED,
 					dev_name(dev), hdmi);
 	if (ret)
 		return ret;
@@ -1572,11 +1574,11 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 	/* Clear Hotplug interrupts */
 	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
 
-	ret = imx_hdmi_fb_registered(hdmi);
+	ret = dw_hdmi_fb_registered(hdmi);
 	if (ret)
 		return ret;
 
-	ret = imx_hdmi_register(drm, hdmi);
+	ret = dw_hdmi_register(drm, hdmi);
 	if (ret)
 		return ret;
 
@@ -1587,11 +1589,11 @@ int imx_hdmi_bind(struct device *dev, struct device *master,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(imx_hdmi_bind);
+EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
-	struct imx_hdmi *hdmi = dev_get_drvdata(dev);
+	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
@@ -1601,11 +1603,11 @@ void imx_hdmi_unbind(struct device *dev, struct device *master, void *data)
 
 	i2c_put_adapter(hdmi->ddc);
 }
-EXPORT_SYMBOL_GPL(imx_hdmi_unbind);
+EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>");
 MODULE_AUTHOR("Andy Yan <andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
 MODULE_AUTHOR("Yakir Yang <ykk-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
-MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
+MODULE_DESCRIPTION("DW HDMI transmitter driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-hdmi");
+MODULE_ALIAS("platform:dw-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
similarity index 98%
rename from drivers/gpu/drm/imx/imx-hdmi.h
rename to drivers/gpu/drm/bridge/dw_hdmi.h
index bced9ef..baa7849 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -1030,46 +1030,4 @@ enum {
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
 };
 
-enum imx_hdmi_devtype {
-	IMX6Q_HDMI,
-	IMX6DL_HDMI,
-};
-
-struct imx_hdmi_plat_data {
-	enum imx_hdmi_devtype dev_type;
-	const struct mpll_config *mpll_cfg;
-	const struct curr_ctrl *cur_ctr;
-	const struct sym_term *sym_term;
-};
-
-enum {
-	RES_8,
-	RES_10,
-	RES_12,
-	RES_MAX,
-};
-
-struct mpll_config {
-	unsigned long mpixelclock;
-	struct {
-		u16 cpce;
-		u16 gmp;
-	} res[RES_MAX];
-};
-
-struct curr_ctrl {
-	unsigned long mpixelclock;
-	u16 curr[RES_MAX];
-};
-
-struct sym_term {
-	unsigned long mpixelclock;
-	u16 sym_ctr;    /*clock symbol and transmitter control*/
-	u16 term;       /*transmission termination value*/
-};
-
-int imx_hdmi_bind(struct device *dev, struct device *master,
-		  void *data, struct drm_encoder *encoder,
-		  const struct imx_hdmi_plat_data *plat_data);
-void imx_hdmi_unbind(struct device *dev, struct device *master, void *data);
 #endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 82fb758..7070077 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -48,6 +48,7 @@ config DRM_IMX_IPUV3
 
 config DRM_IMX_HDMI
 	tristate "Freescale i.MX DRM HDMI"
+	select DRM_DW_HDMI
 	depends on DRM_IMX
 	help
 	  Choose this if you want to use HDMI on i.MX6.
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 63cf56a..f3ecd89 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 
 imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
 obj-$(CONFIG_DRM_IMX_IPUV3)	+= imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o imx-hdmi_pltfm.o
+obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
similarity index 58%
rename from drivers/gpu/drm/imx/imx-hdmi_pltfm.c
rename to drivers/gpu/drm/imx/dw_hdmi-imx.c
index da330e0..d74c1f6 100644
--- a/drivers/gpu/drm/imx/imx-hdmi_pltfm.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  *
- * derived from imx-hdmi.c
+ * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,6 +11,7 @@
 #include <linux/component.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <drm/bridge/dw_hdmi.h>
 #include <video/imx-ipu-v3.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
@@ -21,9 +22,8 @@
 #include <drm/drm_encoder_slave.h>
 
 #include "imx-drm.h"
-#include "imx-hdmi.h"
 
-struct imx_hdmi_priv {
+struct imx_hdmi {
 	struct device *dev;
 	struct drm_encoder encoder;
 	struct clk *isfr_clk;
@@ -31,7 +31,7 @@ struct imx_hdmi_priv {
 	struct regmap *regmap;
 };
 
-static const struct mpll_config imx_mpll_cfg[] = {
+static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = {
 	{
 		45250000, {
 			{ 0x01e0, 0x0000 },
@@ -59,7 +59,7 @@ static const struct mpll_config imx_mpll_cfg[] = {
 	}
 };
 
-static const struct curr_ctrl imx_cur_ctr[] = {
+static const struct dw_hdmi_curr_ctrl imx_cur_ctr[] = {
 	/*      pixelclk     bpp8    bpp10   bpp12 */
 	{
 		54000000, { 0x091c, 0x091c, 0x06dc },
@@ -76,13 +76,13 @@ static const struct curr_ctrl imx_cur_ctr[] = {
 	}
 };
 
-static const struct sym_term imx_sym_term[] = {
+static const struct dw_hdmi_sym_term imx_sym_term[] = {
 	/*pixelclk   symbol   term*/
 	{ 148500000, 0x800d, 0x0005 },
 	{ ~0UL,      0x0000, 0x0000 }
 };
 
-static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
+static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
 {
 	struct device_node *np = hdmi->dev->of_node;
 
@@ -107,28 +107,26 @@ static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
 	return 0;
 }
 
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
 {
 }
 
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-					const struct drm_display_mode *mode,
-					struct drm_display_mode *adjusted_mode)
+static bool dw_hdmi_imx_encoder_mode_fixup(struct drm_encoder *encoder,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
 {
 	return true;
 }
 
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-				      struct drm_display_mode *mode,
-				      struct drm_display_mode *adjusted_mode)
+static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
+					 struct drm_display_mode *mode,
+					 struct drm_display_mode *adjusted_mode)
 {
 }
 
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
 {
-	struct imx_hdmi_priv *hdmi = container_of(encoder,
-						  struct imx_hdmi_priv,
-						  encoder);
+	struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
 	int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 
 	regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
@@ -136,38 +134,38 @@ static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
 			   mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
 }
 
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
 {
 	imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
 }
 
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
-	.mode_fixup = imx_hdmi_encoder_mode_fixup,
-	.mode_set = imx_hdmi_encoder_mode_set,
-	.prepare = imx_hdmi_encoder_prepare,
-	.commit = imx_hdmi_encoder_commit,
-	.disable = imx_hdmi_encoder_disable,
+static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
+	.mode_fixup = dw_hdmi_imx_encoder_mode_fixup,
+	.mode_set = dw_hdmi_imx_encoder_mode_set,
+	.prepare = dw_hdmi_imx_encoder_prepare,
+	.commit = dw_hdmi_imx_encoder_commit,
+	.disable = dw_hdmi_imx_encoder_disable,
 };
 
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
+static struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
 
-static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
-	.mpll_cfg = imx_mpll_cfg,
-	.cur_ctr  = imx_cur_ctr,
-	.sym_term = imx_sym_term,
-	.dev_type = IMX6Q_HDMI,
+static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
+	.mpll_cfg		= imx_mpll_cfg,
+	.cur_ctr		= imx_cur_ctr,
+	.sym_term		= imx_sym_term,
+	.dev_type		= IMX6Q_HDMI,
 };
 
-static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
-	.mpll_cfg = imx_mpll_cfg,
-	.cur_ctr  = imx_cur_ctr,
-	.sym_term = imx_sym_term,
-	.dev_type = IMX6DL_HDMI,
+static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
+	.mpll_cfg		= imx_mpll_cfg,
+	.cur_ctr		= imx_cur_ctr,
+	.sym_term		= imx_sym_term,
+	.dev_type		= IMX6DL_HDMI,
 };
 
-static const struct of_device_id imx_hdmi_dt_ids[] = {
+static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx6q-hdmi",
 	  .data = &imx6q_hdmi_drv_data
 	}, {
@@ -176,17 +174,17 @@ static const struct of_device_id imx_hdmi_dt_ids[] = {
 	},
 	{},
 };
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
 
-static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
-			       void *data)
+static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
+			    void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	const struct imx_hdmi_plat_data *plat_data;
+	const struct dw_hdmi_plat_data *plat_data;
 	const struct of_device_id *match;
 	struct drm_device *drm = data;
 	struct drm_encoder *encoder;
-	struct imx_hdmi_priv *hdmi;
+	struct imx_hdmi *hdmi;
 	int ret;
 
 	if (!pdev->dev.of_node)
@@ -196,7 +194,7 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 	if (!hdmi)
 		return -ENOMEM;
 
-	match = of_match_node(imx_hdmi_dt_ids, pdev->dev.of_node);
+	match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node);
 	plat_data = match->data;
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
@@ -212,7 +210,7 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 	if (encoder->possible_crtcs == 0)
 		return -EPROBE_DEFER;
 
-	ret = imx_hdmi_parse_dt(hdmi);
+	ret = dw_hdmi_imx_parse_dt(hdmi);
 	if (ret < 0)
 		return ret;
 
@@ -228,56 +226,55 @@ static int imx_hdmi_pltfm_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	drm_encoder_helper_add(encoder, &imx_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &imx_hdmi_encoder_funcs,
+	drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS);
 
-	return imx_hdmi_bind(dev, master, data, encoder, plat_data);
+	return dw_hdmi_bind(dev, master, data, encoder, plat_data);
 }
 
-static void imx_hdmi_pltfm_unbind(struct device *dev, struct device *master,
-				  void *data)
+static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
+			       void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct imx_hdmi_priv *hdmi = platform_get_drvdata(pdev);
+	struct imx_hdmi *hdmi = platform_get_drvdata(pdev);
 
 	clk_disable_unprepare(hdmi->isfr_clk);
 	clk_disable_unprepare(hdmi->iahb_clk);
 
-	return imx_hdmi_unbind(dev, master, data);
+	return dw_hdmi_unbind(dev, master, data);
 }
 
-static const struct component_ops imx_hdmi_ops = {
-	.bind	= imx_hdmi_pltfm_bind,
-	.unbind	= imx_hdmi_pltfm_unbind,
+static const struct component_ops dw_hdmi_imx_ops = {
+	.bind	= dw_hdmi_imx_bind,
+	.unbind	= dw_hdmi_imx_unbind,
 };
 
-static int imx_hdmi_probe(struct platform_device *pdev)
+static int dw_hdmi_imx_probe(struct platform_device *pdev)
 {
-	return component_add(&pdev->dev, &imx_hdmi_ops);
+	return component_add(&pdev->dev, &dw_hdmi_imx_ops);
 }
 
-static int imx_hdmi_remove(struct platform_device *pdev)
+static int dw_hdmi_imx_remove(struct platform_device *pdev)
 {
-	component_del(&pdev->dev, &imx_hdmi_ops);
+	component_del(&pdev->dev, &dw_hdmi_imx_ops);
 
 	return 0;
 }
 
-static struct platform_driver imx_hdmi_pltfm_driver = {
-	.probe  = imx_hdmi_probe,
-	.remove = imx_hdmi_remove,
+static struct platform_driver dw_hdmi_imx_platform_driver = {
+	.probe  = dw_hdmi_imx_probe,
+	.remove = dw_hdmi_imx_remove,
 	.driver = {
-		.name = "hdmi-imx",
-		.owner = THIS_MODULE,
-		.of_match_table = imx_hdmi_dt_ids,
+		.name = "dwhdmi-imx",
+		.of_match_table = dw_hdmi_imx_dt_ids,
 	},
 };
 
-module_platform_driver(imx_hdmi_pltfm_driver);
+module_platform_driver(dw_hdmi_imx_platform_driver);
 
 MODULE_AUTHOR("Andy Yan <andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
 MODULE_AUTHOR("Yakir Yang <ykk-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
 MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:hdmi-imx");
+MODULE_ALIAS("platform:dwhdmi-imx");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
new file mode 100644
index 0000000..fff6ae6
--- /dev/null
+++ b/include/drm/bridge/dw_hdmi.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DW_HDMI__
+#define __DW_HDMI__
+
+#include <drm/drmP.h>
+
+enum {
+	DW_HDMI_RES_8,
+	DW_HDMI_RES_10,
+	DW_HDMI_RES_12,
+	DW_HDMI_RES_MAX,
+};
+
+enum dw_hdmi_devtype {
+	IMX6Q_HDMI,
+	IMX6DL_HDMI,
+};
+
+struct dw_hdmi_mpll_config {
+	unsigned long mpixelclock;
+	struct {
+		u16 cpce;
+		u16 gmp;
+	} res[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_curr_ctrl {
+	unsigned long mpixelclock;
+	u16 curr[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_sym_term {
+	unsigned long mpixelclock;
+	u16 sym_ctr;    /*clock symbol and transmitter control*/
+	u16 term;       /*transmission termination value*/
+};
+
+struct dw_hdmi_plat_data {
+	enum dw_hdmi_devtype dev_type;
+	const struct dw_hdmi_mpll_config *mpll_cfg;
+	const struct dw_hdmi_curr_ctrl *cur_ctr;
+	const struct dw_hdmi_sym_term *sym_term;
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+			      struct drm_display_mode *mode);
+};
+
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);
+int dw_hdmi_bind(struct device *dev, struct device *master,
+		 void *data, struct drm_encoder *encoder,
+		 const struct dw_hdmi_plat_data *plat_data);
+#endif /* __IMX_HDMI_H__ */
-- 
1.9.1


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:42   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:42 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8:
- correct some spelling mistake
- modify ddc-i2c-bus and interrupt description

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/drm/bridge/dw_hdmi.txt     | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
new file mode 100644
index 0000000..107c1ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
@@ -0,0 +1,40 @@
+DesignWare HDMI bridge bindings
+
+Required properities:
+- compatible: platform specific such as:
+   * "fsl,imx6q-hdmi"
+   * "fsl,imx6dl-hdmi"
+   * "rockchip,rk3288-dw-hdmi"
+- reg: Physical base address and length of the controller's registers.
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- interrupts: The HDMI interrupt number
+
+Optional properties
+- reg-io-width: the width of the reg:1,4, default set to 1 if not present
+
+Example:
+	hdmi: hdmi@0120000 {
+		compatible = "fsl,imx6q-hdmi";
+		reg = <0x00120000 0x9000>;
+		interrupts = <0 115 0x04>;
+		gpr = <&gpr>;
+		clocks = <&clks 123>, <&clks 124>;
+		clock-names = "iahb", "isfr";
+		ddc-i2c-bus = <&i2c2>;
+
+		port@0 {
+			reg = <0>;
+
+			hdmi_mux_0: endpoint {
+				remote-endpoint = <&ipu1_di0_hdmi>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			hdmi_mux_1: endpoint {
+				remote-endpoint = <&ipu1_di1_hdmi>;
+			};
+		};
+	};
-- 
1.9.1



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

* [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-02  7:42   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:42 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8:
- correct some spelling mistake
- modify ddc-i2c-bus and interrupt description

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/drm/bridge/dw_hdmi.txt     | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
new file mode 100644
index 0000000..107c1ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
@@ -0,0 +1,40 @@
+DesignWare HDMI bridge bindings
+
+Required properities:
+- compatible: platform specific such as:
+   * "fsl,imx6q-hdmi"
+   * "fsl,imx6dl-hdmi"
+   * "rockchip,rk3288-dw-hdmi"
+- reg: Physical base address and length of the controller's registers.
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- interrupts: The HDMI interrupt number
+
+Optional properties
+- reg-io-width: the width of the reg:1,4, default set to 1 if not present
+
+Example:
+	hdmi: hdmi@0120000 {
+		compatible = "fsl,imx6q-hdmi";
+		reg = <0x00120000 0x9000>;
+		interrupts = <0 115 0x04>;
+		gpr = <&gpr>;
+		clocks = <&clks 123>, <&clks 124>;
+		clock-names = "iahb", "isfr";
+		ddc-i2c-bus = <&i2c2>;
+
+		port@0 {
+			reg = <0>;
+
+			hdmi_mux_0: endpoint {
+				remote-endpoint = <&ipu1_di0_hdmi>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			hdmi_mux_1: endpoint {
+				remote-endpoint = <&ipu1_di1_hdmi>;
+			};
+		};
+	};
-- 
1.9.1

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

* [PATCH v15 07/12] drm: bridge/dw_hdmi: add support for multi-byte register width access
  2014-12-02  7:36 ` Andy Yan
                   ` (6 preceding siblings ...)
  (?)
@ 2014-12-02  7:42 ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:42 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

On rockchip rk3288, only word(32-bit) accesses are
permitted for hdmi registers.  Byte width accesses (writeb,
readb) generate an imprecise external abort.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15:
- remove unio of the multi-byte register access, adviced by Philipp Zabel

Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6:
- refactor register access without reg_shift

Changes in v5:
- refactor reg-io-width

Changes in v4: None
Changes in v3:
- split multi-register access to one indepent patch

 drivers/gpu/drm/bridge/dw_hdmi.c | 44 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 6f5b70a..0e8afd6 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -125,18 +125,41 @@ struct dw_hdmi {
 
 	unsigned int sample_rate;
 	int ratio;
+
+	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+	u8 (*read)(struct dw_hdmi *hdmi, int offset);
 };
 
-static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
+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 inline u8 hdmi_readb(struct dw_hdmi *hdmi, int 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);
+}
+
+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
+{
+	return hdmi->read(hdmi, offset);
+}
+
 static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
 {
 	u8 val = hdmi_readb(hdmi, reg) & ~mask;
@@ -1509,6 +1532,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	struct dw_hdmi *hdmi;
 	struct resource *iores;
 	int ret, irq;
+	u32 val = 1;
 
 	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
@@ -1521,6 +1545,22 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->ratio = 100;
 	hdmi->encoder = encoder;
 
+	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 -EINVAL;
+	}
+
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
-- 
1.9.1



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

* [PATCH v15 08/12] drm: bridge/dw_hdmi: add mode_valid support
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:43   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:43 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

some platform may not support all the display mode,
add mode_valid interface check it

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14:
- remove drm_connector_register, because imx-drm core has registered
connector

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 0e8afd6..65cb077 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1402,6 +1402,20 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 	return 0;
 }
 
+static enum drm_mode_status
+dw_hdmi_connector_mode_valid(struct drm_connector *connector,
+			     struct drm_display_mode *mode)
+{
+	struct dw_hdmi *hdmi = container_of(connector,
+					   struct dw_hdmi, connector);
+	enum drm_mode_status mode_status = MODE_OK;
+
+	if (hdmi->plat_data->mode_valid)
+		mode_status = hdmi->plat_data->mode_valid(connector, mode);
+
+	return mode_status;
+}
+
 static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector
 							   *connector)
 {
@@ -1426,6 +1440,7 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
+	.mode_valid = dw_hdmi_connector_mode_valid,
 	.best_encoder = dw_hdmi_connector_best_encoder,
 };
 
-- 
1.9.1



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

* [PATCH v15 08/12] drm: bridge/dw_hdmi: add mode_valid support
@ 2014-12-02  7:43   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:43 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

some platform may not support all the display mode,
add mode_valid interface check it

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14:
- remove drm_connector_register, because imx-drm core has registered
connector

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 0e8afd6..65cb077 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1402,6 +1402,20 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 	return 0;
 }
 
+static enum drm_mode_status
+dw_hdmi_connector_mode_valid(struct drm_connector *connector,
+			     struct drm_display_mode *mode)
+{
+	struct dw_hdmi *hdmi = container_of(connector,
+					   struct dw_hdmi, connector);
+	enum drm_mode_status mode_status = MODE_OK;
+
+	if (hdmi->plat_data->mode_valid)
+		mode_status = hdmi->plat_data->mode_valid(connector, mode);
+
+	return mode_status;
+}
+
 static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector
 							   *connector)
 {
@@ -1426,6 +1440,7 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
+	.mode_valid = dw_hdmi_connector_mode_valid,
 	.best_encoder = dw_hdmi_connector_best_encoder,
 };
 
-- 
1.9.1

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

* [PATCH v15 09/12] drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:43   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:43 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

HDMI_IH_I2CMPHY_STAT0 is a clear on write register, which indicates i2cm
operation status(i2c transfer done or error), every hdmi phy register
configuration must check this register to make sure the configuration
has complete. But the indication bit should be cleared after check, otherwise
the corresponding bit will hold on forever, this may give a wrong signal for
next check.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 65cb077..13ace4e 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -663,11 +663,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
 
 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
-	while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
+	u32 val;
+
+	while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
 		if (msec-- == 0)
 			return false;
 		udelay(1000);
 	}
+	hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
+
 	return true;
 }
 
-- 
1.9.1



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

* [PATCH v15 09/12] drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
@ 2014-12-02  7:43   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:43 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

HDMI_IH_I2CMPHY_STAT0 is a clear on write register, which indicates i2cm
operation status(i2c transfer done or error), every hdmi phy register
configuration must check this register to make sure the configuration
has complete. But the indication bit should be cleared after check, otherwise
the corresponding bit will hold on forever, this may give a wrong signal for
next check.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 65cb077..13ace4e 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -663,11 +663,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
 
 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
 {
-	while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
+	u32 val;
+
+	while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
 		if (msec-- == 0)
 			return false;
 		udelay(1000);
 	}
+	hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
+
 	return true;
 }
 
-- 
1.9.1

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

* [PATCH v15 10/12] drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:44   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:44 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

RK3288 HDMI will not work without the spare bit of
HDMI_PHY_CONF0 enable

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 7 +++++++
 drivers/gpu/drm/bridge/dw_hdmi.h | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 13ace4e..961693a 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -710,6 +710,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_ENTMDS_MASK);
 }
 
+static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
+{
+	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+			 HDMI_PHY_CONF0_SPARECTRL_OFFSET,
+			 HDMI_PHY_CONF0_SPARECTRL_MASK);
+}
+
 static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index baa7849..175dbc8 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -837,7 +837,8 @@ enum {
 	HDMI_PHY_CONF0_PDZ_OFFSET = 7,
 	HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
 	HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
-	HDMI_PHY_CONF0_SPARECTRL = 0x20,
+	HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
+	HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
 	HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
 	HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
 	HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
-- 
1.9.1



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

* [PATCH v15 10/12] drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare
@ 2014-12-02  7:44   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:44 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

RK3288 HDMI will not work without the spare bit of
HDMI_PHY_CONF0 enable

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c | 7 +++++++
 drivers/gpu/drm/bridge/dw_hdmi.h | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 13ace4e..961693a 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -710,6 +710,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
 			 HDMI_PHY_CONF0_ENTMDS_MASK);
 }
 
+static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
+{
+	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+			 HDMI_PHY_CONF0_SPARECTRL_OFFSET,
+			 HDMI_PHY_CONF0_SPARECTRL_MASK);
+}
+
 static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
 {
 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index baa7849..175dbc8 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -837,7 +837,8 @@ enum {
 	HDMI_PHY_CONF0_PDZ_OFFSET = 7,
 	HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
 	HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
-	HDMI_PHY_CONF0_SPARECTRL = 0x20,
+	HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
+	HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
 	HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
 	HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
 	HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
-- 
1.9.1

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

* [PATCH v15 11/12] dt-bindings: Add documentation for rockchip dw hdmi
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:44   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:44 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8:
- Add documentation for rockchip dw hdmi

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt

diff --git a/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
new file mode 100644
index 0000000..0735464
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
@@ -0,0 +1,43 @@
+Rockchip specific extensions to the Synopsys Designware HDMI
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-dw-hdmi";
+- reg: Physical base address and length of the controller's registers.
+- ddc-i2c-bus:  phandle of an I2C controller used for DDC EDID probing
+- clocks: from common clock binding: handle to hdmi clock.
+- clock-names: should be "clk" "hdcp_clk"
+- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
+- interrupts: HDMI interrupt number
+- ports: contain a port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. For
+  vopb,set the reg = <0> and set the reg = <1> for vopl.
+- reg-io-width: the width of the reg:1,4, the value should be 4 on
+  rk3288 platform
+
+Example:
+hdmi: hdmi@ff980000 {
+	compatible = "rockchip,rk3288-dw-hdmi";
+	reg = <0xff980000 0x20000>;
+	reg-io-width = <4>;
+	ddc-i2c-bus = <&i2c5>;
+	rockchip,grf = <&grf>;
+	interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+	clock-names = "clk", "hdcp_clk";
+	status = "disabled";
+	ports {
+		hdmi_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			hdmi_in_vopb: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&vopb_out_hdmi>;
+			};
+			hdmi_in_vopl: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&vopl_out_hdmi>;
+			};
+		};
+	};
+};
-- 
1.9.1



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

* [PATCH v15 11/12] dt-bindings: Add documentation for rockchip dw hdmi
@ 2014-12-02  7:44   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:44 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8:
- Add documentation for rockchip dw hdmi

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt

diff --git a/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
new file mode 100644
index 0000000..0735464
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
@@ -0,0 +1,43 @@
+Rockchip specific extensions to the Synopsys Designware HDMI
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-dw-hdmi";
+- reg: Physical base address and length of the controller's registers.
+- ddc-i2c-bus:  phandle of an I2C controller used for DDC EDID probing
+- clocks: from common clock binding: handle to hdmi clock.
+- clock-names: should be "clk" "hdcp_clk"
+- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
+- interrupts: HDMI interrupt number
+- ports: contain a port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. For
+  vopb,set the reg = <0> and set the reg = <1> for vopl.
+- reg-io-width: the width of the reg:1,4, the value should be 4 on
+  rk3288 platform
+
+Example:
+hdmi: hdmi@ff980000 {
+	compatible = "rockchip,rk3288-dw-hdmi";
+	reg = <0xff980000 0x20000>;
+	reg-io-width = <4>;
+	ddc-i2c-bus = <&i2c5>;
+	rockchip,grf = <&grf>;
+	interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+	clock-names = "clk", "hdcp_clk";
+	status = "disabled";
+	ports {
+		hdmi_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			hdmi_in_vopb: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&vopb_out_hdmi>;
+			};
+			hdmi_in_vopl: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&vopl_out_hdmi>;
+			};
+		};
+	};
+};
-- 
1.9.1

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

* [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-02  7:36 ` Andy Yan
@ 2014-12-02  7:45   ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:45 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Greg Kroah-Hartman, Grant Likely, Rob Herring, Shawn Guo,
	Josh Boyer, Sean Paul, Inki Dae, Dave Airlie, Arnd Bergmann,
	Lucas Stach, Zubair.Kakakhel, djkurtz, ykk, linux-kernel,
	dri-devel, devel, devicetree, linux-rockchip, jay.xu, Pawel Moll,
	mark.yao, Mark Rutland, vladimir_zapolskiy, Ian Campbell,
	Kumar Gala, Andy Yan

Rockchip RK3288 hdmi is compatible with dw_hdmi

this patch is depend on patch by Mark Yao Add drm
driver for Rockchip Socs

see https://lkml.org/lkml/2014/11/19/1153

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15:
- remove THIS_MODULE in platform driver

Changes in v14: None
Changes in v13: None
Changes in v12:
- add comment for the depend on patch

Changes in v11: None
Changes in v10:
- add more display mode support mpll configuration for rk3288

Changes in v9:
- move some phy configuration to platform driver

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c            |   3 +
 drivers/gpu/drm/rockchip/Kconfig            |  10 +
 drivers/gpu/drm/rockchip/Makefile           |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 354 ++++++++++++++++++++++++++++
 include/drm/bridge/dw_hdmi.h                |   1 +
 5 files changed, 369 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 961693a..8772abd 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -849,6 +849,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
+	if (hdmi->dev_type == RK3288_HDMI)
+		dw_hdmi_phy_enable_spare(hdmi, 1);
+
 	/*Wait for PHY PLL lock */
 	msec = 5;
 	do {
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 0ff6682..06371ae 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -15,3 +15,13 @@ config DRM_ROCKCHIP
 	  management to userspace. This driver does not provide
 	  2D or 3D acceleration; acceleration is performed by other
 	  IP found on the SoC.
+
+config ROCKCHIP_DW_HDMI
+        bool "Rockchip specific extensions for Synopsys DW HDMI"
+        depends on DRM_ROCKCHIP
+        select DRM_DW_HDMI
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Synopsys DesignWare HDMI driver. If you want to
+	  enable HDMI on RK3288 based SoC, you should selet this
+	  option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index b3a5193..347e65c 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -4,5 +4,5 @@
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o rockchip_drm_vop.o
-
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
new file mode 100644
index 0000000..99144f8
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define GRF_SOC_CON6                    0x025c
+#define HDMI_SEL_VOP_LIT                (1 << 4)
+
+struct rockchip_hdmi {
+	struct device *dev;
+	struct clk *clk;
+	struct clk *hdcp_clk;
+	struct regmap *regmap;
+	struct drm_encoder encoder;
+};
+
+#define to_rockchip_hdmi(x)	container_of(x, struct rockchip_hdmi, x)
+
+static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
+	{
+		27000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		36000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		40000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		54000000, {
+			{ 0x0072, 0x0001},
+			{ 0x2142, 0x0001},
+			{ 0x40a2, 0x0001},
+		},
+	}, {
+		65000000, {
+			{ 0x0072, 0x0001},
+			{ 0x2142, 0x0001},
+			{ 0x40a2, 0x0001},
+		},
+	}, {
+		66000000, {
+			{ 0x013e, 0x0003},
+			{ 0x217e, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		74250000, {
+			{ 0x0072, 0x0001},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		83500000, {
+			{ 0x0072, 0x0001},
+		},
+	}, {
+		108000000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		106500000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		146250000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		148500000, {
+			{ 0x0051, 0x0003},
+			{ 0x214c, 0x0003},
+			{ 0x4064, 0x0003}
+		},
+	}, {
+		~0UL, {
+			{ 0x00a0, 0x000a },
+			{ 0x2001, 0x000f },
+			{ 0x4002, 0x000f },
+		},
+	}
+};
+
+static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
+	/*      pixelclk    bpp8    bpp10   bpp12 */
+	{
+		40000000,  { 0x0018, 0x0018, 0x0018 },
+	}, {
+		65000000,  { 0x0028, 0x0028, 0x0028 },
+	}, {
+		66000000,  { 0x0038, 0x0038, 0x0038 },
+	}, {
+		74250000,  { 0x0028, 0x0038, 0x0038 },
+	}, {
+		83500000,  { 0x0028, 0x0038, 0x0038 },
+	}, {
+		146250000, { 0x0038, 0x0038, 0x0038 },
+	}, {
+		148500000, { 0x0000, 0x0038, 0x0038 },
+	}, {
+		~0UL,      { 0x0000, 0x0000, 0x0000},
+	}
+};
+
+static const struct dw_hdmi_sym_term rockchip_sym_term[] = {
+	/*pixelclk   symbol   term*/
+	{ 74250000,  0x8009, 0x0004 },
+	{ 148500000, 0x8029, 0x0004 },
+	{ 297000000, 0x8039, 0x0005 },
+	{ ~0UL,	     0x0000, 0x0000 }
+};
+
+static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
+{
+	struct device_node *np = hdmi->dev->of_node;
+
+	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(hdmi->regmap)) {
+		dev_err(hdmi->dev, "Unable to get rockchip,grf\n");
+		return PTR_ERR(hdmi->regmap);
+	}
+
+	hdmi->clk = devm_clk_get(hdmi->dev, "clk");
+	if (IS_ERR(hdmi->clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI clk\n");
+	       return PTR_ERR(hdmi->clk);
+	}
+
+	hdmi->hdcp_clk = devm_clk_get(hdmi->dev, "hdcp_clk");
+	if (IS_ERR(hdmi->hdcp_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI hdcp clk\n");
+		return PTR_ERR(hdmi->hdcp_clk);
+	}
+
+	return 0;
+}
+
+static enum drm_mode_status
+dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
+			    struct drm_display_mode *mode)
+{
+	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+	int pclk = mode->clock * 1000;
+	bool valid = false;
+	int i;
+
+	for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
+		if (pclk == mpll_cfg[i].mpixelclock) {
+			valid = true;
+			break;
+		}
+	}
+
+	return (valid) ? MODE_OK : MODE_BAD;
+}
+
+static struct drm_encoder_funcs dw_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static void dw_hdmi_rockchip_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool dw_hdmi_rockchip_mode_fixup(struct drm_encoder *encoder,
+					const struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void dw_hdmi_rockchip_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void dw_hdmi_rockchip_commit(struct drm_encoder *encoder)
+{
+	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+	u32 val;
+	int mux;
+
+	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+	if (mux)
+		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+	else
+		val = HDMI_SEL_VOP_LIT << 16;
+
+	regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
+	dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
+		(mux) ? "LIT" : "BIG");
+}
+
+static void dw_hdmi_rockchip_prepare(struct drm_encoder *encoder)
+{
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+}
+
+static struct drm_encoder_helper_funcs dw_hdmi_encoder_helper_funcs = {
+	.mode_fixup = dw_hdmi_rockchip_mode_fixup,
+	.mode_set = dw_hdmi_rockchip_mode_set,
+	.prepare = dw_hdmi_rockchip_prepare,
+	.commit = dw_hdmi_rockchip_commit,
+	.disable = dw_hdmi_rockchip_disable,
+};
+
+static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+	.mode_valid		= dw_hdmi_rockchip_mode_valid,
+	.mpll_cfg		= rockchip_mpll_cfg,
+	.cur_ctr		= rockchip_cur_ctr,
+	.sym_term		= rockchip_sym_term,
+	.dev_type		= RK3288_HDMI,
+};
+
+static const struct of_device_id dw_hdmi_rockchip_ids[] = {
+	{ .compatible = "rockchip,rk3288-dw-hdmi",
+	  .data = &rockchip_hdmi_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
+
+static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
+				 void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct dw_hdmi_plat_data *plat_data;
+	const struct of_device_id *match;
+	struct drm_device *drm = data;
+	struct drm_encoder *encoder;
+	struct rockchip_hdmi *hdmi;
+	int ret;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
+	plat_data = match->data;
+	hdmi->dev = &pdev->dev;
+	encoder = &hdmi->encoder;
+	platform_set_drvdata(pdev, hdmi);
+
+	ret = rockchip_hdmi_parse_dt(hdmi);
+	if (ret) {
+		dev_err(hdmi->dev, "Unable to parse OF data\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->clk);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->hdcp_clk);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+
+	drm_encoder_helper_add(encoder, &dw_hdmi_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &dw_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	return dw_hdmi_bind(dev, master, data, encoder, plat_data);
+}
+
+static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
+				    void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rockchip_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(hdmi->clk);
+	clk_disable_unprepare(hdmi->hdcp_clk);
+
+	return dw_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops dw_hdmi_rockchip_ops = {
+	.bind	= dw_hdmi_rockchip_bind,
+	.unbind	= dw_hdmi_rockchip_unbind,
+};
+
+static int dw_hdmi_rockchip_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
+}
+
+static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
+
+	return 0;
+}
+
+static struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
+	.probe  = dw_hdmi_rockchip_probe,
+	.remove = dw_hdmi_rockchip_remove,
+	.driver = {
+		.name = "dwhdmi-rockchip",
+		.of_match_table = dw_hdmi_rockchip_ids,
+	},
+};
+
+module_platform_driver(dw_hdmi_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dwhdmi-rockchip");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index fff6ae6..ca98ee0 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -22,6 +22,7 @@ enum {
 enum dw_hdmi_devtype {
 	IMX6Q_HDMI,
 	IMX6DL_HDMI,
+	RK3288_HDMI,
 };
 
 struct dw_hdmi_mpll_config {
-- 
1.9.1



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

* [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-02  7:45   ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02  7:45 UTC (permalink / raw)
  To: airlied, Philipp Zabel, heiko, fabio.estevam, rmk+kernel
  Cc: Mark Rutland, dri-devel, ykk, devel, Arnd Bergmann,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
	Sean Paul, mark.yao, Josh Boyer, Greg Kroah-Hartman,
	linux-kernel, djkurtz, Kumar Gala, Andy Yan, Shawn Guo,
	vladimir_zapolskiy, Lucas Stach

Rockchip RK3288 hdmi is compatible with dw_hdmi

this patch is depend on patch by Mark Yao Add drm
driver for Rockchip Socs

see https://lkml.org/lkml/2014/11/19/1153

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v15:
- remove THIS_MODULE in platform driver

Changes in v14: None
Changes in v13: None
Changes in v12:
- add comment for the depend on patch

Changes in v11: None
Changes in v10:
- add more display mode support mpll configuration for rk3288

Changes in v9:
- move some phy configuration to platform driver

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/bridge/dw_hdmi.c            |   3 +
 drivers/gpu/drm/rockchip/Kconfig            |  10 +
 drivers/gpu/drm/rockchip/Makefile           |   2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 354 ++++++++++++++++++++++++++++
 include/drm/bridge/dw_hdmi.h                |   1 +
 5 files changed, 369 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 961693a..8772abd 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -849,6 +849,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
 
+	if (hdmi->dev_type == RK3288_HDMI)
+		dw_hdmi_phy_enable_spare(hdmi, 1);
+
 	/*Wait for PHY PLL lock */
 	msec = 5;
 	do {
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 0ff6682..06371ae 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -15,3 +15,13 @@ config DRM_ROCKCHIP
 	  management to userspace. This driver does not provide
 	  2D or 3D acceleration; acceleration is performed by other
 	  IP found on the SoC.
+
+config ROCKCHIP_DW_HDMI
+        bool "Rockchip specific extensions for Synopsys DW HDMI"
+        depends on DRM_ROCKCHIP
+        select DRM_DW_HDMI
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Synopsys DesignWare HDMI driver. If you want to
+	  enable HDMI on RK3288 based SoC, you should selet this
+	  option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index b3a5193..347e65c 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -4,5 +4,5 @@
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o rockchip_drm_vop.o
-
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
new file mode 100644
index 0000000..99144f8
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define GRF_SOC_CON6                    0x025c
+#define HDMI_SEL_VOP_LIT                (1 << 4)
+
+struct rockchip_hdmi {
+	struct device *dev;
+	struct clk *clk;
+	struct clk *hdcp_clk;
+	struct regmap *regmap;
+	struct drm_encoder encoder;
+};
+
+#define to_rockchip_hdmi(x)	container_of(x, struct rockchip_hdmi, x)
+
+static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
+	{
+		27000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		36000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		40000000, {
+			{ 0x00b3, 0x0000},
+			{ 0x2153, 0x0000},
+			{ 0x40f3, 0x0000}
+		},
+	}, {
+		54000000, {
+			{ 0x0072, 0x0001},
+			{ 0x2142, 0x0001},
+			{ 0x40a2, 0x0001},
+		},
+	}, {
+		65000000, {
+			{ 0x0072, 0x0001},
+			{ 0x2142, 0x0001},
+			{ 0x40a2, 0x0001},
+		},
+	}, {
+		66000000, {
+			{ 0x013e, 0x0003},
+			{ 0x217e, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		74250000, {
+			{ 0x0072, 0x0001},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		83500000, {
+			{ 0x0072, 0x0001},
+		},
+	}, {
+		108000000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		106500000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		146250000, {
+			{ 0x0051, 0x0002},
+			{ 0x2145, 0x0002},
+			{ 0x4061, 0x0002}
+		},
+	}, {
+		148500000, {
+			{ 0x0051, 0x0003},
+			{ 0x214c, 0x0003},
+			{ 0x4064, 0x0003}
+		},
+	}, {
+		~0UL, {
+			{ 0x00a0, 0x000a },
+			{ 0x2001, 0x000f },
+			{ 0x4002, 0x000f },
+		},
+	}
+};
+
+static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
+	/*      pixelclk    bpp8    bpp10   bpp12 */
+	{
+		40000000,  { 0x0018, 0x0018, 0x0018 },
+	}, {
+		65000000,  { 0x0028, 0x0028, 0x0028 },
+	}, {
+		66000000,  { 0x0038, 0x0038, 0x0038 },
+	}, {
+		74250000,  { 0x0028, 0x0038, 0x0038 },
+	}, {
+		83500000,  { 0x0028, 0x0038, 0x0038 },
+	}, {
+		146250000, { 0x0038, 0x0038, 0x0038 },
+	}, {
+		148500000, { 0x0000, 0x0038, 0x0038 },
+	}, {
+		~0UL,      { 0x0000, 0x0000, 0x0000},
+	}
+};
+
+static const struct dw_hdmi_sym_term rockchip_sym_term[] = {
+	/*pixelclk   symbol   term*/
+	{ 74250000,  0x8009, 0x0004 },
+	{ 148500000, 0x8029, 0x0004 },
+	{ 297000000, 0x8039, 0x0005 },
+	{ ~0UL,	     0x0000, 0x0000 }
+};
+
+static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
+{
+	struct device_node *np = hdmi->dev->of_node;
+
+	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(hdmi->regmap)) {
+		dev_err(hdmi->dev, "Unable to get rockchip,grf\n");
+		return PTR_ERR(hdmi->regmap);
+	}
+
+	hdmi->clk = devm_clk_get(hdmi->dev, "clk");
+	if (IS_ERR(hdmi->clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI clk\n");
+	       return PTR_ERR(hdmi->clk);
+	}
+
+	hdmi->hdcp_clk = devm_clk_get(hdmi->dev, "hdcp_clk");
+	if (IS_ERR(hdmi->hdcp_clk)) {
+		dev_err(hdmi->dev, "Unable to get HDMI hdcp clk\n");
+		return PTR_ERR(hdmi->hdcp_clk);
+	}
+
+	return 0;
+}
+
+static enum drm_mode_status
+dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
+			    struct drm_display_mode *mode)
+{
+	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+	int pclk = mode->clock * 1000;
+	bool valid = false;
+	int i;
+
+	for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
+		if (pclk == mpll_cfg[i].mpixelclock) {
+			valid = true;
+			break;
+		}
+	}
+
+	return (valid) ? MODE_OK : MODE_BAD;
+}
+
+static struct drm_encoder_funcs dw_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static void dw_hdmi_rockchip_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool dw_hdmi_rockchip_mode_fixup(struct drm_encoder *encoder,
+					const struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void dw_hdmi_rockchip_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void dw_hdmi_rockchip_commit(struct drm_encoder *encoder)
+{
+	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+	u32 val;
+	int mux;
+
+	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+	if (mux)
+		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+	else
+		val = HDMI_SEL_VOP_LIT << 16;
+
+	regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
+	dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
+		(mux) ? "LIT" : "BIG");
+}
+
+static void dw_hdmi_rockchip_prepare(struct drm_encoder *encoder)
+{
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+}
+
+static struct drm_encoder_helper_funcs dw_hdmi_encoder_helper_funcs = {
+	.mode_fixup = dw_hdmi_rockchip_mode_fixup,
+	.mode_set = dw_hdmi_rockchip_mode_set,
+	.prepare = dw_hdmi_rockchip_prepare,
+	.commit = dw_hdmi_rockchip_commit,
+	.disable = dw_hdmi_rockchip_disable,
+};
+
+static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+	.mode_valid		= dw_hdmi_rockchip_mode_valid,
+	.mpll_cfg		= rockchip_mpll_cfg,
+	.cur_ctr		= rockchip_cur_ctr,
+	.sym_term		= rockchip_sym_term,
+	.dev_type		= RK3288_HDMI,
+};
+
+static const struct of_device_id dw_hdmi_rockchip_ids[] = {
+	{ .compatible = "rockchip,rk3288-dw-hdmi",
+	  .data = &rockchip_hdmi_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
+
+static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
+				 void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct dw_hdmi_plat_data *plat_data;
+	const struct of_device_id *match;
+	struct drm_device *drm = data;
+	struct drm_encoder *encoder;
+	struct rockchip_hdmi *hdmi;
+	int ret;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
+	plat_data = match->data;
+	hdmi->dev = &pdev->dev;
+	encoder = &hdmi->encoder;
+	platform_set_drvdata(pdev, hdmi);
+
+	ret = rockchip_hdmi_parse_dt(hdmi);
+	if (ret) {
+		dev_err(hdmi->dev, "Unable to parse OF data\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->clk);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(hdmi->hdcp_clk);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+
+	drm_encoder_helper_add(encoder, &dw_hdmi_encoder_helper_funcs);
+	drm_encoder_init(drm, encoder, &dw_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	return dw_hdmi_bind(dev, master, data, encoder, plat_data);
+}
+
+static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
+				    void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rockchip_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(hdmi->clk);
+	clk_disable_unprepare(hdmi->hdcp_clk);
+
+	return dw_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops dw_hdmi_rockchip_ops = {
+	.bind	= dw_hdmi_rockchip_bind,
+	.unbind	= dw_hdmi_rockchip_unbind,
+};
+
+static int dw_hdmi_rockchip_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
+}
+
+static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
+
+	return 0;
+}
+
+static struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
+	.probe  = dw_hdmi_rockchip_probe,
+	.remove = dw_hdmi_rockchip_remove,
+	.driver = {
+		.name = "dwhdmi-rockchip",
+		.of_match_table = dw_hdmi_rockchip_ids,
+	},
+};
+
+module_platform_driver(dw_hdmi_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dwhdmi-rockchip");
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index fff6ae6..ca98ee0 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -22,6 +22,7 @@ enum {
 enum dw_hdmi_devtype {
 	IMX6Q_HDMI,
 	IMX6DL_HDMI,
+	RK3288_HDMI,
 };
 
 struct dw_hdmi_mpll_config {
-- 
1.9.1

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-02  7:45   ` Andy Yan
@ 2014-12-02 10:24     ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 10:24 UTC (permalink / raw)
  To: Andy Yan
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Andy,

Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
[...]
> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
> +				 void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct dw_hdmi_plat_data *plat_data;
> +	const struct of_device_id *match;
> +	struct drm_device *drm = data;
> +	struct drm_encoder *encoder;
> +	struct rockchip_hdmi *hdmi;
> +	int ret;
> +
> +	if (!pdev->dev.of_node)
> +		return -ENODEV;
> +
> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> +	if (!hdmi)
> +		return -ENOMEM;
> +
> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
> +	plat_data = match->data;
> +	hdmi->dev = &pdev->dev;
> +	encoder = &hdmi->encoder;
> +	platform_set_drvdata(pdev, hdmi);
> +
> +	ret = rockchip_hdmi_parse_dt(hdmi);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(hdmi->clk);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
> +		return ret;
> +	}

Could we have a look at the clocks again? Basically the Rockchip clock
handling is exactly the same, except the clocks are called by other
names.

On i.MX6, according to the reference manual, the HDMI TX module has four
clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
"ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
the 32 kHz reference input can't be gated, and the "isfrclk" has its own
gate.

Does the HDMI TX implementation on Rockchip still have the separate
external sfr bus and module clock inputs? I assume that your "clk" input
is a single gate bit for bus and module clocks at the same time?
If possible, I'd prefer to find a common binding for the clocks with
some of the clocks being optional, but for that we need to know the
actual clock inputs to the HDMI TX module.

regards
Philipp


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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-02 10:24     ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 10:24 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Andy,

Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
[...]
> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
> +				 void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct dw_hdmi_plat_data *plat_data;
> +	const struct of_device_id *match;
> +	struct drm_device *drm = data;
> +	struct drm_encoder *encoder;
> +	struct rockchip_hdmi *hdmi;
> +	int ret;
> +
> +	if (!pdev->dev.of_node)
> +		return -ENODEV;
> +
> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> +	if (!hdmi)
> +		return -ENOMEM;
> +
> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
> +	plat_data = match->data;
> +	hdmi->dev = &pdev->dev;
> +	encoder = &hdmi->encoder;
> +	platform_set_drvdata(pdev, hdmi);
> +
> +	ret = rockchip_hdmi_parse_dt(hdmi);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(hdmi->clk);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
> +		return ret;
> +	}

Could we have a look at the clocks again? Basically the Rockchip clock
handling is exactly the same, except the clocks are called by other
names.

On i.MX6, according to the reference manual, the HDMI TX module has four
clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
"ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
the 32 kHz reference input can't be gated, and the "isfrclk" has its own
gate.

Does the HDMI TX implementation on Rockchip still have the separate
external sfr bus and module clock inputs? I assume that your "clk" input
is a single gate bit for bus and module clocks at the same time?
If possible, I'd prefer to find a common binding for the clocks with
some of the clocks being optional, but for that we need to know the
actual clock inputs to the HDMI TX module.

regards
Philipp

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-02 12:34       ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02 12:34 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Philipp:
On 2014年12月02日 18:24, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
> [...]
>> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
>> +				 void *data)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	const struct dw_hdmi_plat_data *plat_data;
>> +	const struct of_device_id *match;
>> +	struct drm_device *drm = data;
>> +	struct drm_encoder *encoder;
>> +	struct rockchip_hdmi *hdmi;
>> +	int ret;
>> +
>> +	if (!pdev->dev.of_node)
>> +		return -ENODEV;
>> +
>> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
>> +	if (!hdmi)
>> +		return -ENOMEM;
>> +
>> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
>> +	plat_data = match->data;
>> +	hdmi->dev = &pdev->dev;
>> +	encoder = &hdmi->encoder;
>> +	platform_set_drvdata(pdev, hdmi);
>> +
>> +	ret = rockchip_hdmi_parse_dt(hdmi);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = clk_prepare_enable(hdmi->clk);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
>> +		return ret;
>> +	}
> Could we have a look at the clocks again? Basically the Rockchip clock
> handling is exactly the same, except the clocks are called by other
> names.
>
> On i.MX6, according to the reference manual, the HDMI TX module has four
> clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
> "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
> The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
> the 32 kHz reference input can't be gated, and the "isfrclk" has its own
> gate.
>
> Does the HDMI TX implementation on Rockchip still have the separate
> external sfr bus and module clock inputs? I assume that your "clk" input
> is a single gate bit for bus and module clocks at the same time?
> If possible, I'd prefer to find a common binding for the clocks with
> some of the clocks being optional, but for that we need to know the
> actual clock inputs to the HDMI TX module.
>
> regards
> Philipp
>
     There are three  individual clock inputs on Rockchip RK3288 HDMI: 
"hdmi_ctrl_clk",
     "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible 
for different
      functions as their name described, and have their own private gate 
bit. That is
      to say, the cec_clk and hdcp_clk can all be disabled if we don't 
need hdcp and cec
      function.
      So I think it's better to make the clk control platform independent.

     Heiko, do you have any suggestions?
>
>



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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-02 12:34       ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-02 12:34 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: airlied-cv59FeDIM0c, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	djkurtz-hpIqsD4AKlfQT0dZR+AlfA, ykk-TNX95d0MmH7DzftRWevZcw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	jay.xu-TNX95d0MmH7DzftRWevZcw, Pawel Moll,
	mark.yao-TNX95d0MmH7DzftRWevZcw, Mark Rutland,
	vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA, Ian Campbell, Kuma

Hi Philipp:
On 2014年12月02日 18:24, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
> [...]
>> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
>> +				 void *data)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	const struct dw_hdmi_plat_data *plat_data;
>> +	const struct of_device_id *match;
>> +	struct drm_device *drm = data;
>> +	struct drm_encoder *encoder;
>> +	struct rockchip_hdmi *hdmi;
>> +	int ret;
>> +
>> +	if (!pdev->dev.of_node)
>> +		return -ENODEV;
>> +
>> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
>> +	if (!hdmi)
>> +		return -ENOMEM;
>> +
>> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
>> +	plat_data = match->data;
>> +	hdmi->dev = &pdev->dev;
>> +	encoder = &hdmi->encoder;
>> +	platform_set_drvdata(pdev, hdmi);
>> +
>> +	ret = rockchip_hdmi_parse_dt(hdmi);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = clk_prepare_enable(hdmi->clk);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
>> +	if (ret) {
>> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
>> +		return ret;
>> +	}
> Could we have a look at the clocks again? Basically the Rockchip clock
> handling is exactly the same, except the clocks are called by other
> names.
>
> On i.MX6, according to the reference manual, the HDMI TX module has four
> clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
> "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
> The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
> the 32 kHz reference input can't be gated, and the "isfrclk" has its own
> gate.
>
> Does the HDMI TX implementation on Rockchip still have the separate
> external sfr bus and module clock inputs? I assume that your "clk" input
> is a single gate bit for bus and module clocks at the same time?
> If possible, I'd prefer to find a common binding for the clocks with
> some of the clocks being optional, but for that we need to know the
> actual clock inputs to the HDMI TX module.
>
> regards
> Philipp
>
     There are three  individual clock inputs on Rockchip RK3288 HDMI: 
"hdmi_ctrl_clk",
     "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible 
for different
      functions as their name described, and have their own private gate 
bit. That is
      to say, the cec_clk and hdcp_clk can all be disabled if we don't 
need hdcp and cec
      function.
      So I think it's better to make the clk control platform independent.

     Heiko, do you have any suggestions?
>
>


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-02 12:34       ` Andy Yan
@ 2014-12-02 13:00         ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 13:00 UTC (permalink / raw)
  To: Andy Yan
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Andy,

Am Dienstag, den 02.12.2014, 20:34 +0800 schrieb Andy Yan:
> Hi Philipp:
> On 2014年12月02日 18:24, Philipp Zabel wrote:
> > Hi Andy,
> >
> > Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
> > [...]
> >> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
> >> +				 void *data)
> >> +{
> >> +	struct platform_device *pdev = to_platform_device(dev);
> >> +	const struct dw_hdmi_plat_data *plat_data;
> >> +	const struct of_device_id *match;
> >> +	struct drm_device *drm = data;
> >> +	struct drm_encoder *encoder;
> >> +	struct rockchip_hdmi *hdmi;
> >> +	int ret;
> >> +
> >> +	if (!pdev->dev.of_node)
> >> +		return -ENODEV;
> >> +
> >> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> >> +	if (!hdmi)
> >> +		return -ENOMEM;
> >> +
> >> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
> >> +	plat_data = match->data;
> >> +	hdmi->dev = &pdev->dev;
> >> +	encoder = &hdmi->encoder;
> >> +	platform_set_drvdata(pdev, hdmi);
> >> +
> >> +	ret = rockchip_hdmi_parse_dt(hdmi);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = clk_prepare_enable(hdmi->clk);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
> >> +		return ret;
> >> +	}
> > Could we have a look at the clocks again? Basically the Rockchip clock
> > handling is exactly the same, except the clocks are called by other
> > names.
> >
> > On i.MX6, according to the reference manual, the HDMI TX module has four
> > clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
> > "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
> > The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
> > the 32 kHz reference input can't be gated, and the "isfrclk" has its own
> > gate.
> >
> > Does the HDMI TX implementation on Rockchip still have the separate
> > external sfr bus and module clock inputs? I assume that your "clk" input
> > is a single gate bit for bus and module clocks at the same time?
> > If possible, I'd prefer to find a common binding for the clocks with
> > some of the clocks being optional, but for that we need to know the
> > actual clock inputs to the HDMI TX module.
> >
> > regards
> > Philipp
> >
>      There are three  individual clock inputs on Rockchip RK3288 HDMI: 
> "hdmi_ctrl_clk",
>      "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible 
> for different
>       functions as their name described, and have their own private gate 
> bit. That is
>       to say, the cec_clk and hdcp_clk can all be disabled if we don't 
> need hdcp and cec
>       function.
>       So I think it's better to make the clk control platform independent.

My question is not about the available gates at the SoC level, but about
the actual clock inputs from point of view of the HDMI TX IP.

It could be that the hdmi_ctrl_clk gates all inputs to the module and
bus clocks together. If so, you could just reuse "isfr" and "iahb" and
set it to the same clock. If not, we'd need to think of something else.
Unfortunately I don't have any Synopsys documentation of the HDMI TX at
that level.

regards
Philipp


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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-02 13:00         ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 13:00 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Andy,

Am Dienstag, den 02.12.2014, 20:34 +0800 schrieb Andy Yan:
> Hi Philipp:
> On 2014年12月02日 18:24, Philipp Zabel wrote:
> > Hi Andy,
> >
> > Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
> > [...]
> >> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
> >> +				 void *data)
> >> +{
> >> +	struct platform_device *pdev = to_platform_device(dev);
> >> +	const struct dw_hdmi_plat_data *plat_data;
> >> +	const struct of_device_id *match;
> >> +	struct drm_device *drm = data;
> >> +	struct drm_encoder *encoder;
> >> +	struct rockchip_hdmi *hdmi;
> >> +	int ret;
> >> +
> >> +	if (!pdev->dev.of_node)
> >> +		return -ENODEV;
> >> +
> >> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> >> +	if (!hdmi)
> >> +		return -ENOMEM;
> >> +
> >> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
> >> +	plat_data = match->data;
> >> +	hdmi->dev = &pdev->dev;
> >> +	encoder = &hdmi->encoder;
> >> +	platform_set_drvdata(pdev, hdmi);
> >> +
> >> +	ret = rockchip_hdmi_parse_dt(hdmi);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = clk_prepare_enable(hdmi->clk);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
> >> +	if (ret) {
> >> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
> >> +		return ret;
> >> +	}
> > Could we have a look at the clocks again? Basically the Rockchip clock
> > handling is exactly the same, except the clocks are called by other
> > names.
> >
> > On i.MX6, according to the reference manual, the HDMI TX module has four
> > clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
> > "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
> > The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
> > the 32 kHz reference input can't be gated, and the "isfrclk" has its own
> > gate.
> >
> > Does the HDMI TX implementation on Rockchip still have the separate
> > external sfr bus and module clock inputs? I assume that your "clk" input
> > is a single gate bit for bus and module clocks at the same time?
> > If possible, I'd prefer to find a common binding for the clocks with
> > some of the clocks being optional, but for that we need to know the
> > actual clock inputs to the HDMI TX module.
> >
> > regards
> > Philipp
> >
>      There are three  individual clock inputs on Rockchip RK3288 HDMI: 
> "hdmi_ctrl_clk",
>      "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible 
> for different
>       functions as their name described, and have their own private gate 
> bit. That is
>       to say, the cec_clk and hdcp_clk can all be disabled if we don't 
> need hdcp and cec
>       function.
>       So I think it's better to make the clk control platform independent.

My question is not about the available gates at the SoC level, but about
the actual clock inputs from point of view of the HDMI TX IP.

It could be that the hdmi_ctrl_clk gates all inputs to the module and
bus clocks together. If so, you could just reuse "isfr" and "iahb" and
set it to the same clock. If not, we'd need to think of something else.
Unfortunately I don't have any Synopsys documentation of the HDMI TX at
that level.

regards
Philipp

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-02  7:42   ` Andy Yan
@ 2014-12-02 18:23     ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 18:23 UTC (permalink / raw)
  To: Andy Yan
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Andy,

Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> new file mode 100644
> index 0000000..107c1ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> @@ -0,0 +1,40 @@
> +DesignWare HDMI bridge bindings
> +
> +Required properities:
> +- compatible: platform specific such as:
> +   * "fsl,imx6q-hdmi"
> +   * "fsl,imx6dl-hdmi"
> +   * "rockchip,rk3288-dw-hdmi"

I think we should add a common compatible value "snps,dw-hdmi-tx" here:

	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";

> +- reg: Physical base address and length of the controller's registers.
> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing

Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
master.

> +- interrupts: The HDMI interrupt number
> +
> +Optional properties
> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
> +
> +Example:
> +	hdmi: hdmi@0120000 {
> +		compatible = "fsl,imx6q-hdmi";
> +		reg = <0x00120000 0x9000>;
> +		interrupts = <0 115 0x04>;
> +		gpr = <&gpr>;
> +		clocks = <&clks 123>, <&clks 124>;
> +		clock-names = "iahb", "isfr";
> +		ddc-i2c-bus = <&i2c2>;
> +
> +		port@0 {
> +			reg = <0>;
> +
> +			hdmi_mux_0: endpoint {
> +				remote-endpoint = <&ipu1_di0_hdmi>;
> +			};
> +		};
> +
> +		port@1 {
> +			reg = <1>;
> +
> +			hdmi_mux_1: endpoint {
> +				remote-endpoint = <&ipu1_di1_hdmi>;
> +			};
> +		};
> +	};

regards
Philipp


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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-02 18:23     ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-02 18:23 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Andy,

Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> new file mode 100644
> index 0000000..107c1ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> @@ -0,0 +1,40 @@
> +DesignWare HDMI bridge bindings
> +
> +Required properities:
> +- compatible: platform specific such as:
> +   * "fsl,imx6q-hdmi"
> +   * "fsl,imx6dl-hdmi"
> +   * "rockchip,rk3288-dw-hdmi"

I think we should add a common compatible value "snps,dw-hdmi-tx" here:

	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";

> +- reg: Physical base address and length of the controller's registers.
> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing

Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
master.

> +- interrupts: The HDMI interrupt number
> +
> +Optional properties
> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
> +
> +Example:
> +	hdmi: hdmi@0120000 {
> +		compatible = "fsl,imx6q-hdmi";
> +		reg = <0x00120000 0x9000>;
> +		interrupts = <0 115 0x04>;
> +		gpr = <&gpr>;
> +		clocks = <&clks 123>, <&clks 124>;
> +		clock-names = "iahb", "isfr";
> +		ddc-i2c-bus = <&i2c2>;
> +
> +		port@0 {
> +			reg = <0>;
> +
> +			hdmi_mux_0: endpoint {
> +				remote-endpoint = <&ipu1_di0_hdmi>;
> +			};
> +		};
> +
> +		port@1 {
> +			reg = <1>;
> +
> +			hdmi_mux_1: endpoint {
> +				remote-endpoint = <&ipu1_di1_hdmi>;
> +			};
> +		};
> +	};

regards
Philipp

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-02 18:23     ` Philipp Zabel
@ 2014-12-03  0:54       ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  0:54 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach

Hi Philipp:
On 2014年12月03日 02:23, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> new file mode 100644
>> index 0000000..107c1ca
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> @@ -0,0 +1,40 @@
>> +DesignWare HDMI bridge bindings
>> +
>> +Required properities:
>> +- compatible: platform specific such as:
>> +   * "fsl,imx6q-hdmi"
>> +   * "fsl,imx6dl-hdmi"
>> +   * "rockchip,rk3288-dw-hdmi"
> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>
> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>
      How about "snps,dw-hdmi", because the driver is not only about
   hdmi tx, but also include hdmi phy.
       If we add such compatible value, do we have to implement another
    platform driver like dw_hdmi-pltfm.c with the 
compatible="snps,dw-hdmi" ,
    or just include the compatible value in dw_hdmi-imx.c and 
dw_hdmi-rockchip.c?
>> +- reg: Physical base address and length of the controller's registers.
>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> master.
>
>> +- interrupts: The HDMI interrupt number
>> +
>> +Optional properties
>> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
>> +
>> +Example:
>> +	hdmi: hdmi@0120000 {
>> +		compatible = "fsl,imx6q-hdmi";
>> +		reg = <0x00120000 0x9000>;
>> +		interrupts = <0 115 0x04>;
>> +		gpr = <&gpr>;
>> +		clocks = <&clks 123>, <&clks 124>;
>> +		clock-names = "iahb", "isfr";
>> +		ddc-i2c-bus = <&i2c2>;
>> +
>> +		port@0 {
>> +			reg = <0>;
>> +
>> +			hdmi_mux_0: endpoint {
>> +				remote-endpoint = <&ipu1_di0_hdmi>;
>> +			};
>> +		};
>> +
>> +		port@1 {
>> +			reg = <1>;
>> +
>> +			hdmi_mux_1: endpoint {
>> +				remote-endpoint = <&ipu1_di1_hdmi>;
>> +			};
>> +		};
>> +	};
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>



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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03  0:54       ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  0:54 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Philipp:
On 2014年12月03日 02:23, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> new file mode 100644
>> index 0000000..107c1ca
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> @@ -0,0 +1,40 @@
>> +DesignWare HDMI bridge bindings
>> +
>> +Required properities:
>> +- compatible: platform specific such as:
>> +   * "fsl,imx6q-hdmi"
>> +   * "fsl,imx6dl-hdmi"
>> +   * "rockchip,rk3288-dw-hdmi"
> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>
> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>
      How about "snps,dw-hdmi", because the driver is not only about
   hdmi tx, but also include hdmi phy.
       If we add such compatible value, do we have to implement another
    platform driver like dw_hdmi-pltfm.c with the 
compatible="snps,dw-hdmi" ,
    or just include the compatible value in dw_hdmi-imx.c and 
dw_hdmi-rockchip.c?
>> +- reg: Physical base address and length of the controller's registers.
>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> master.
>
>> +- interrupts: The HDMI interrupt number
>> +
>> +Optional properties
>> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
>> +
>> +Example:
>> +	hdmi: hdmi@0120000 {
>> +		compatible = "fsl,imx6q-hdmi";
>> +		reg = <0x00120000 0x9000>;
>> +		interrupts = <0 115 0x04>;
>> +		gpr = <&gpr>;
>> +		clocks = <&clks 123>, <&clks 124>;
>> +		clock-names = "iahb", "isfr";
>> +		ddc-i2c-bus = <&i2c2>;
>> +
>> +		port@0 {
>> +			reg = <0>;
>> +
>> +			hdmi_mux_0: endpoint {
>> +				remote-endpoint = <&ipu1_di0_hdmi>;
>> +			};
>> +		};
>> +
>> +		port@1 {
>> +			reg = <1>;
>> +
>> +			hdmi_mux_1: endpoint {
>> +				remote-endpoint = <&ipu1_di1_hdmi>;
>> +			};
>> +		};
>> +	};
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>


_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-03  0:54       ` Andy Yan
@ 2014-12-03  9:19         ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03  9:19 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach

Hi Andy,

Am Mittwoch, den 03.12.2014, 08:54 +0800 schrieb Andy Yan:
> >> +Required properities:
> >> +- compatible: platform specific such as:
> >> +   * "fsl,imx6q-hdmi"
> >> +   * "fsl,imx6dl-hdmi"
> >> +   * "rockchip,rk3288-dw-hdmi"
> > I think we should add a common compatible value "snps,dw-hdmi-tx" here:
> >
> > 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
> >
>       How about "snps,dw-hdmi", because the driver is not only about
>    hdmi tx, but also include hdmi phy.

Synopsys call the whole module
"DesignWare HDMI Transmitter (TX) IP Solution":

https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_tx
https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_tx

That includes the PHY. I'd prefer keeping the -tx in there to
differentiate from a possible future "snps,dw-hdmi-rx":

https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_rx
https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_rx

>        If we add such compatible value, do we have to implement another
>     platform driver like dw_hdmi-pltfm.c with the 
> compatible="snps,dw-hdmi" ,
>     or just include the compatible value in dw_hdmi-imx.c and 
> dw_hdmi-rockchip.c?

That common compatible doesn't have to be used by any driver. It's just
there to show these are the same/similar IP core.
If a common driver without any SoC specific knowledge could be written,
that one would match against the common compatible.

regards
Philipp


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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03  9:19         ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03  9:19 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Andy,

Am Mittwoch, den 03.12.2014, 08:54 +0800 schrieb Andy Yan:
> >> +Required properities:
> >> +- compatible: platform specific such as:
> >> +   * "fsl,imx6q-hdmi"
> >> +   * "fsl,imx6dl-hdmi"
> >> +   * "rockchip,rk3288-dw-hdmi"
> > I think we should add a common compatible value "snps,dw-hdmi-tx" here:
> >
> > 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
> >
>       How about "snps,dw-hdmi", because the driver is not only about
>    hdmi tx, but also include hdmi phy.

Synopsys call the whole module
"DesignWare HDMI Transmitter (TX) IP Solution":

https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_tx
https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_tx

That includes the PHY. I'd prefer keeping the -tx in there to
differentiate from a possible future "snps,dw-hdmi-rx":

https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_rx
https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_rx

>        If we add such compatible value, do we have to implement another
>     platform driver like dw_hdmi-pltfm.c with the 
> compatible="snps,dw-hdmi" ,
>     or just include the compatible value in dw_hdmi-imx.c and 
> dw_hdmi-rockchip.c?

That common compatible doesn't have to be used by any driver. It's just
there to show these are the same/similar IP core.
If a common driver without any SoC specific knowledge could be written,
that one would match against the common compatible.

regards
Philipp

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-03  9:19         ` Philipp Zabel
@ 2014-12-03  9:43           ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  9:43 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach

Hi Philipp:
On 2014年12月03日 17:19, Philipp Zabel wrote:
> Hi Andy,
>
> Am Mittwoch, den 03.12.2014, 08:54 +0800 schrieb Andy Yan:
>>>> +Required properities:
>>>> +- compatible: platform specific such as:
>>>> +   * "fsl,imx6q-hdmi"
>>>> +   * "fsl,imx6dl-hdmi"
>>>> +   * "rockchip,rk3288-dw-hdmi"
>>> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>>>
>>> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>>>
>>        How about "snps,dw-hdmi", because the driver is not only about
>>     hdmi tx, but also include hdmi phy.
> Synopsys call the whole module
> "DesignWare HDMI Transmitter (TX) IP Solution":
>
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_tx
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_tx
>
> That includes the PHY. I'd prefer keeping the -tx in there to
> differentiate from a possible future "snps,dw-hdmi-rx":
>
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_rx
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_rx

   Ok, I will add the compatible "snps, dw-hdmi-tx",
    So do I need to add this value to imx6dl.dtsi?
>>         If we add such compatible value, do we have to implement another
>>      platform driver like dw_hdmi-pltfm.c with the
>> compatible="snps,dw-hdmi" ,
>>      or just include the compatible value in dw_hdmi-imx.c and
>> dw_hdmi-rockchip.c?
> That common compatible doesn't have to be used by any driver. It's just
> there to show these are the same/similar IP core.
> If a common driver without any SoC specific knowledge could be written,
> that one would match against the common compatible.
>
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>



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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03  9:43           ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  9:43 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Philipp:
On 2014年12月03日 17:19, Philipp Zabel wrote:
> Hi Andy,
>
> Am Mittwoch, den 03.12.2014, 08:54 +0800 schrieb Andy Yan:
>>>> +Required properities:
>>>> +- compatible: platform specific such as:
>>>> +   * "fsl,imx6q-hdmi"
>>>> +   * "fsl,imx6dl-hdmi"
>>>> +   * "rockchip,rk3288-dw-hdmi"
>>> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>>>
>>> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>>>
>>        How about "snps,dw-hdmi", because the driver is not only about
>>     hdmi tx, but also include hdmi phy.
> Synopsys call the whole module
> "DesignWare HDMI Transmitter (TX) IP Solution":
>
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_tx
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_tx
>
> That includes the PHY. I'd prefer keeping the -tx in there to
> differentiate from a possible future "snps,dw-hdmi-rx":
>
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_14_csds_rx
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_hdmi_20_csds_rx

   Ok, I will add the compatible "snps, dw-hdmi-tx",
    So do I need to add this value to imx6dl.dtsi?
>>         If we add such compatible value, do we have to implement another
>>      platform driver like dw_hdmi-pltfm.c with the
>> compatible="snps,dw-hdmi" ,
>>      or just include the compatible value in dw_hdmi-imx.c and
>> dw_hdmi-rockchip.c?
> That common compatible doesn't have to be used by any driver. It's just
> there to show these are the same/similar IP core.
> If a common driver without any SoC specific knowledge could be written,
> that one would match against the common compatible.
>
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>


_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-02 18:23     ` Philipp Zabel
@ 2014-12-03  9:46       ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  9:46 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach


On 2014年12月03日 02:23, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> new file mode 100644
>> index 0000000..107c1ca
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> @@ -0,0 +1,40 @@
>> +DesignWare HDMI bridge bindings
>> +
>> +Required properities:
>> +- compatible: platform specific such as:
>> +   * "fsl,imx6q-hdmi"
>> +   * "fsl,imx6dl-hdmi"
>> +   * "rockchip,rk3288-dw-hdmi"
> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>
> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>
>> +- reg: Physical base address and length of the controller's registers.
>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> master.
     I have the same idea too, but the patch about ddc i2c master has not
  landed yet,  can we change the ddc-i2c-bus to optional  after the ddc 
i2c master
  patch land?
>> +- interrupts: The HDMI interrupt number
>> +
>> +Optional properties
>> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
>> +
>> +Example:
>> +	hdmi: hdmi@0120000 {
>> +		compatible = "fsl,imx6q-hdmi";
>> +		reg = <0x00120000 0x9000>;
>> +		interrupts = <0 115 0x04>;
>> +		gpr = <&gpr>;
>> +		clocks = <&clks 123>, <&clks 124>;
>> +		clock-names = "iahb", "isfr";
>> +		ddc-i2c-bus = <&i2c2>;
>> +
>> +		port@0 {
>> +			reg = <0>;
>> +
>> +			hdmi_mux_0: endpoint {
>> +				remote-endpoint = <&ipu1_di0_hdmi>;
>> +			};
>> +		};
>> +
>> +		port@1 {
>> +			reg = <1>;
>> +
>> +			hdmi_mux_1: endpoint {
>> +				remote-endpoint = <&ipu1_di1_hdmi>;
>> +			};
>> +		};
>> +	};
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>



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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03  9:46       ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03  9:46 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy


On 2014年12月03日 02:23, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> new file mode 100644
>> index 0000000..107c1ca
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>> @@ -0,0 +1,40 @@
>> +DesignWare HDMI bridge bindings
>> +
>> +Required properities:
>> +- compatible: platform specific such as:
>> +   * "fsl,imx6q-hdmi"
>> +   * "fsl,imx6dl-hdmi"
>> +   * "rockchip,rk3288-dw-hdmi"
> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>
> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>
>> +- reg: Physical base address and length of the controller's registers.
>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> master.
     I have the same idea too, but the patch about ddc i2c master has not
  landed yet,  can we change the ddc-i2c-bus to optional  after the ddc 
i2c master
  patch land?
>> +- interrupts: The HDMI interrupt number
>> +
>> +Optional properties
>> +- reg-io-width: the width of the reg:1,4, default set to 1 if not present
>> +
>> +Example:
>> +	hdmi: hdmi@0120000 {
>> +		compatible = "fsl,imx6q-hdmi";
>> +		reg = <0x00120000 0x9000>;
>> +		interrupts = <0 115 0x04>;
>> +		gpr = <&gpr>;
>> +		clocks = <&clks 123>, <&clks 124>;
>> +		clock-names = "iahb", "isfr";
>> +		ddc-i2c-bus = <&i2c2>;
>> +
>> +		port@0 {
>> +			reg = <0>;
>> +
>> +			hdmi_mux_0: endpoint {
>> +				remote-endpoint = <&ipu1_di0_hdmi>;
>> +			};
>> +		};
>> +
>> +		port@1 {
>> +			reg = <1>;
>> +
>> +			hdmi_mux_1: endpoint {
>> +				remote-endpoint = <&ipu1_di1_hdmi>;
>> +			};
>> +		};
>> +	};
> regards
> Philipp
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>


_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-03  9:46       ` Andy Yan
@ 2014-12-03 11:52         ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03 11:52 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach

Am Mittwoch, den 03.12.2014, 17:46 +0800 schrieb Andy Yan:
> On 2014年12月03日 02:23, Philipp Zabel wrote:
> > Hi Andy,
> >
> > Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
> >> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> >> new file mode 100644
> >> index 0000000..107c1ca
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> >> @@ -0,0 +1,40 @@
> >> +DesignWare HDMI bridge bindings
> >> +
> >> +Required properities:
> >> +- compatible: platform specific such as:
> >> +   * "fsl,imx6q-hdmi"
> >> +   * "fsl,imx6dl-hdmi"
> >> +   * "rockchip,rk3288-dw-hdmi"
> > I think we should add a common compatible value "snps,dw-hdmi-tx" here:
> >
> > 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
> >
> >> +- reg: Physical base address and length of the controller's registers.
> >> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> > Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> > master.
>      I have the same idea too, but the patch about ddc i2c master has not
>   landed yet,  can we change the ddc-i2c-bus to optional  after the ddc 
> i2c master
>   patch land?

Check out Documentation/devicetree/bindings/drm/imx/hdmi.txt, it was
already marked as optional. We can't make it required now.

regards
Philipp


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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03 11:52         ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03 11:52 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Am Mittwoch, den 03.12.2014, 17:46 +0800 schrieb Andy Yan:
> On 2014年12月03日 02:23, Philipp Zabel wrote:
> > Hi Andy,
> >
> > Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
> >> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> >> new file mode 100644
> >> index 0000000..107c1ca
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
> >> @@ -0,0 +1,40 @@
> >> +DesignWare HDMI bridge bindings
> >> +
> >> +Required properities:
> >> +- compatible: platform specific such as:
> >> +   * "fsl,imx6q-hdmi"
> >> +   * "fsl,imx6dl-hdmi"
> >> +   * "rockchip,rk3288-dw-hdmi"
> > I think we should add a common compatible value "snps,dw-hdmi-tx" here:
> >
> > 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
> >
> >> +- reg: Physical base address and length of the controller's registers.
> >> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> > Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
> > master.
>      I have the same idea too, but the patch about ddc i2c master has not
>   landed yet,  can we change the ddc-i2c-bus to optional  after the ddc 
> i2c master
>   patch land?

Check out Documentation/devicetree/bindings/drm/imx/hdmi.txt, it was
already marked as optional. We can't make it required now.

regards
Philipp

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
  2014-12-03 11:52         ` Philipp Zabel
@ 2014-12-03 11:58           ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 11:58 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy, Lucas Stach


On 2014年12月03日 19:52, Philipp Zabel wrote:
> Am Mittwoch, den 03.12.2014, 17:46 +0800 schrieb Andy Yan:
>> On 2014年12月03日 02:23, Philipp Zabel wrote:
>>> Hi Andy,
>>>
>>> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>>>> new file mode 100644
>>>> index 0000000..107c1ca
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>>>> @@ -0,0 +1,40 @@
>>>> +DesignWare HDMI bridge bindings
>>>> +
>>>> +Required properities:
>>>> +- compatible: platform specific such as:
>>>> +   * "fsl,imx6q-hdmi"
>>>> +   * "fsl,imx6dl-hdmi"
>>>> +   * "rockchip,rk3288-dw-hdmi"
>>> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>>>
>>> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>>>
>>>> +- reg: Physical base address and length of the controller's registers.
>>>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
>>> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
>>> master.
>>       I have the same idea too, but the patch about ddc i2c master has not
>>    landed yet,  can we change the ddc-i2c-bus to optional  after the ddc
>> i2c master
>>    patch land?
> Check out Documentation/devicetree/bindings/drm/imx/hdmi.txt, it was
> already marked as optional. We can't make it required now.
>
> regards
> Philipp
>
>
>
   OK, got it, thanks


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

* Re: [PATCH v15 06/12] dt-bindings: add document for dw_hdmi
@ 2014-12-03 11:58           ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 11:58 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel,
	Arnd Bergmann, linux-rockchip, Grant Likely, rmk+kernel, jay.xu,
	devicetree, Zubair.Kakakhel, Pawel Moll, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, Dave Airlie, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy


On 2014年12月03日 19:52, Philipp Zabel wrote:
> Am Mittwoch, den 03.12.2014, 17:46 +0800 schrieb Andy Yan:
>> On 2014年12月03日 02:23, Philipp Zabel wrote:
>>> Hi Andy,
>>>
>>> Am Dienstag, den 02.12.2014, 15:42 +0800 schrieb Andy Yan:
>>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>>>> new file mode 100644
>>>> index 0000000..107c1ca
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
>>>> @@ -0,0 +1,40 @@
>>>> +DesignWare HDMI bridge bindings
>>>> +
>>>> +Required properities:
>>>> +- compatible: platform specific such as:
>>>> +   * "fsl,imx6q-hdmi"
>>>> +   * "fsl,imx6dl-hdmi"
>>>> +   * "rockchip,rk3288-dw-hdmi"
>>> I think we should add a common compatible value "snps,dw-hdmi-tx" here:
>>>
>>> 	compatible = "fsl,imx6q-hdmi", "snps,dw-hdmi-tx";
>>>
>>>> +- reg: Physical base address and length of the controller's registers.
>>>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
>>> Better make ddc-i2c-bus optional, see the other thread about the ddc i2c
>>> master.
>>       I have the same idea too, but the patch about ddc i2c master has not
>>    landed yet,  can we change the ddc-i2c-bus to optional  after the ddc
>> i2c master
>>    patch land?
> Check out Documentation/devicetree/bindings/drm/imx/hdmi.txt, it was
> already marked as optional. We can't make it required now.
>
> regards
> Philipp
>
>
>
   OK, got it, thanks

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-02 13:00         ` Philipp Zabel
@ 2014-12-03 12:32           ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 12:32 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Philipp:
On 2014年12月02日 21:00, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 20:34 +0800 schrieb Andy Yan:
>> Hi Philipp:
>> On 2014年12月02日 18:24, Philipp Zabel wrote:
>>> Hi Andy,
>>>
>>> Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
>>> [...]
>>>> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
>>>> +				 void *data)
>>>> +{
>>>> +	struct platform_device *pdev = to_platform_device(dev);
>>>> +	const struct dw_hdmi_plat_data *plat_data;
>>>> +	const struct of_device_id *match;
>>>> +	struct drm_device *drm = data;
>>>> +	struct drm_encoder *encoder;
>>>> +	struct rockchip_hdmi *hdmi;
>>>> +	int ret;
>>>> +
>>>> +	if (!pdev->dev.of_node)
>>>> +		return -ENODEV;
>>>> +
>>>> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
>>>> +	if (!hdmi)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
>>>> +	plat_data = match->data;
>>>> +	hdmi->dev = &pdev->dev;
>>>> +	encoder = &hdmi->encoder;
>>>> +	platform_set_drvdata(pdev, hdmi);
>>>> +
>>>> +	ret = rockchip_hdmi_parse_dt(hdmi);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = clk_prepare_enable(hdmi->clk);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>> Could we have a look at the clocks again? Basically the Rockchip clock
>>> handling is exactly the same, except the clocks are called by other
>>> names.
>>>
>>> On i.MX6, according to the reference manual, the HDMI TX module has four
>>> clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
>>> "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
>>> The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
>>> the 32 kHz reference input can't be gated, and the "isfrclk" has its own
>>> gate.
>>>
>>> Does the HDMI TX implementation on Rockchip still have the separate
>>> external sfr bus and module clock inputs? I assume that your "clk" input
>>> is a single gate bit for bus and module clocks at the same time?
>>> If possible, I'd prefer to find a common binding for the clocks with
>>> some of the clocks being optional, but for that we need to know the
>>> actual clock inputs to the HDMI TX module.
>>>
>>> regards
>>> Philipp
>>>
>>       There are three  individual clock inputs on Rockchip RK3288 HDMI:
>> "hdmi_ctrl_clk",
>>       "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible
>> for different
>>        functions as their name described, and have their own private gate
>> bit. That is
>>        to say, the cec_clk and hdcp_clk can all be disabled if we don't
>> need hdcp and cec
>>        function.
>>        So I think it's better to make the clk control platform independent.
> My question is not about the available gates at the SoC level, but about
> the actual clock inputs from point of view of the HDMI TX IP.
>
> It could be that the hdmi_ctrl_clk gates all inputs to the module and
> bus clocks together. If so, you could just reuse "isfr" and "iahb" and
> set it to the same clock. If not, we'd need to think of something else.
> Unfortunately I don't have any Synopsys documentation of the HDMI TX at
> that level.

    After confirming with the IC designer, we finally make clear that
    Rockchip RK3288 almost use the same clock design with imx:
    clk-----iahbclk, used for hdmi module and bus
    hdcp_clk-----isfrclk, used for hdcp and i2cm
    cecclk -----cecclk, but this clk can be gated on rockchip, this is 
different with imx,
    but we don't handle the cec stuff now. So i will try to reuse the 
imx clk binds. do you
   think that is ok?
> regards
> Philipp
>
>
>
>



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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-03 12:32           ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 12:32 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Philipp:
On 2014年12月02日 21:00, Philipp Zabel wrote:
> Hi Andy,
>
> Am Dienstag, den 02.12.2014, 20:34 +0800 schrieb Andy Yan:
>> Hi Philipp:
>> On 2014年12月02日 18:24, Philipp Zabel wrote:
>>> Hi Andy,
>>>
>>> Am Dienstag, den 02.12.2014, 15:45 +0800 schrieb Andy Yan:
>>> [...]
>>>> +static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
>>>> +				 void *data)
>>>> +{
>>>> +	struct platform_device *pdev = to_platform_device(dev);
>>>> +	const struct dw_hdmi_plat_data *plat_data;
>>>> +	const struct of_device_id *match;
>>>> +	struct drm_device *drm = data;
>>>> +	struct drm_encoder *encoder;
>>>> +	struct rockchip_hdmi *hdmi;
>>>> +	int ret;
>>>> +
>>>> +	if (!pdev->dev.of_node)
>>>> +		return -ENODEV;
>>>> +
>>>> +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
>>>> +	if (!hdmi)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	match = of_match_node(dw_hdmi_rockchip_ids, pdev->dev.of_node);
>>>> +	plat_data = match->data;
>>>> +	hdmi->dev = &pdev->dev;
>>>> +	encoder = &hdmi->encoder;
>>>> +	platform_set_drvdata(pdev, hdmi);
>>>> +
>>>> +	ret = rockchip_hdmi_parse_dt(hdmi);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Unable to parse OF data\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = clk_prepare_enable(hdmi->clk);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Cannot enable HDMI clock: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = clk_prepare_enable(hdmi->hdcp_clk);
>>>> +	if (ret) {
>>>> +		dev_err(hdmi->dev, "Cannot enable HDMI hdcp clock: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>> Could we have a look at the clocks again? Basically the Rockchip clock
>>> handling is exactly the same, except the clocks are called by other
>>> names.
>>>
>>> On i.MX6, according to the reference manual, the HDMI TX module has four
>>> clock inputs: "iahbclk" (bus clock), "icecclk" (32 kHz CEC clock),
>>> "ihclk" (module clock), and "isfrclk" (27 MHz internal SFR clock).
>>> The "iahbclk" and "ihclk" are both sourced from the SoC AHB root clock,
>>> the 32 kHz reference input can't be gated, and the "isfrclk" has its own
>>> gate.
>>>
>>> Does the HDMI TX implementation on Rockchip still have the separate
>>> external sfr bus and module clock inputs? I assume that your "clk" input
>>> is a single gate bit for bus and module clocks at the same time?
>>> If possible, I'd prefer to find a common binding for the clocks with
>>> some of the clocks being optional, but for that we need to know the
>>> actual clock inputs to the HDMI TX module.
>>>
>>> regards
>>> Philipp
>>>
>>       There are three  individual clock inputs on Rockchip RK3288 HDMI:
>> "hdmi_ctrl_clk",
>>       "hdmi_cec_clk", "hdmi_hdcp_clk", the three clocks are responsible
>> for different
>>        functions as their name described, and have their own private gate
>> bit. That is
>>        to say, the cec_clk and hdcp_clk can all be disabled if we don't
>> need hdcp and cec
>>        function.
>>        So I think it's better to make the clk control platform independent.
> My question is not about the available gates at the SoC level, but about
> the actual clock inputs from point of view of the HDMI TX IP.
>
> It could be that the hdmi_ctrl_clk gates all inputs to the module and
> bus clocks together. If so, you could just reuse "isfr" and "iahb" and
> set it to the same clock. If not, we'd need to think of something else.
> Unfortunately I don't have any Synopsys documentation of the HDMI TX at
> that level.

    After confirming with the IC designer, we finally make clear that
    Rockchip RK3288 almost use the same clock design with imx:
    clk-----iahbclk, used for hdmi module and bus
    hdcp_clk-----isfrclk, used for hdcp and i2cm
    cecclk -----cecclk, but this clk can be gated on rockchip, this is 
different with imx,
    but we don't handle the cec stuff now. So i will try to reuse the 
imx clk binds. do you
   think that is ok?
> regards
> Philipp
>
>
>
>


_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-03 12:32           ` Andy Yan
@ 2014-12-03 13:09             ` Philipp Zabel
  -1 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03 13:09 UTC (permalink / raw)
  To: Andy Yan
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Andy,

Am Mittwoch, den 03.12.2014, 20:32 +0800 schrieb Andy Yan:
> > My question is not about the available gates at the SoC level, but about
> > the actual clock inputs from point of view of the HDMI TX IP.
> >
> > It could be that the hdmi_ctrl_clk gates all inputs to the module and
> > bus clocks together. If so, you could just reuse "isfr" and "iahb" and
> > set it to the same clock. If not, we'd need to think of something else.
> > Unfortunately I don't have any Synopsys documentation of the HDMI TX at
> > that level.
> 
>     After confirming with the IC designer, we finally make clear that
>     Rockchip RK3288 almost use the same clock design with imx:
>     clk-----iahbclk, used for hdmi module and bus
>     hdcp_clk-----isfrclk, used for hdcp and i2cm
>     cecclk -----cecclk, but this clk can be gated on rockchip, this is 
> different with imx,
>     but we don't handle the cec stuff now. So i will try to reuse the 
> imx clk binds. do you
>    think that is ok?

Thank you for taking the time to verify this. So we should move the
clock handling out of the soc specific parts into the common driver and
reuse the existing clock bindings ("iahb", "isfr").
I'd suggest to add the "cec" clock now to the binding document as an
optional clock, then you can already specify it in the rockchip dtsi.

regards
Philipp


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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-03 13:09             ` Philipp Zabel
  0 siblings, 0 replies; 51+ messages in thread
From: Philipp Zabel @ 2014-12-03 13:09 UTC (permalink / raw)
  To: Andy Yan
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Andy,

Am Mittwoch, den 03.12.2014, 20:32 +0800 schrieb Andy Yan:
> > My question is not about the available gates at the SoC level, but about
> > the actual clock inputs from point of view of the HDMI TX IP.
> >
> > It could be that the hdmi_ctrl_clk gates all inputs to the module and
> > bus clocks together. If so, you could just reuse "isfr" and "iahb" and
> > set it to the same clock. If not, we'd need to think of something else.
> > Unfortunately I don't have any Synopsys documentation of the HDMI TX at
> > that level.
> 
>     After confirming with the IC designer, we finally make clear that
>     Rockchip RK3288 almost use the same clock design with imx:
>     clk-----iahbclk, used for hdmi module and bus
>     hdcp_clk-----isfrclk, used for hdcp and i2cm
>     cecclk -----cecclk, but this clk can be gated on rockchip, this is 
> different with imx,
>     but we don't handle the cec stuff now. So i will try to reuse the 
> imx clk binds. do you
>    think that is ok?

Thank you for taking the time to verify this. So we should move the
clock handling out of the soc specific parts into the common driver and
reuse the existing clock bindings ("iahb", "isfr").
I'd suggest to add the "cec" clock now to the binding document as an
optional clock, then you can already specify it in the rockchip dtsi.

regards
Philipp

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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
  2014-12-03 13:09             ` Philipp Zabel
@ 2014-12-03 13:20               ` Andy Yan
  -1 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 13:20 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: airlied, heiko, fabio.estevam, rmk+kernel, Greg Kroah-Hartman,
	Grant Likely, Rob Herring, Shawn Guo, Josh Boyer, Sean Paul,
	Inki Dae, Dave Airlie, Arnd Bergmann, Lucas Stach,
	Zubair.Kakakhel, djkurtz, ykk, linux-kernel, dri-devel, devel,
	devicetree, linux-rockchip, jay.xu, Pawel Moll, mark.yao,
	Mark Rutland, vladimir_zapolskiy, Ian Campbell, Kumar Gala

Hi Philipp:
On 2014年12月03日 21:09, Philipp Zabel wrote:
> Hi Andy,
>
> Am Mittwoch, den 03.12.2014, 20:32 +0800 schrieb Andy Yan:
>>> My question is not about the available gates at the SoC level, but about
>>> the actual clock inputs from point of view of the HDMI TX IP.
>>>
>>> It could be that the hdmi_ctrl_clk gates all inputs to the module and
>>> bus clocks together. If so, you could just reuse "isfr" and "iahb" and
>>> set it to the same clock. If not, we'd need to think of something else.
>>> Unfortunately I don't have any Synopsys documentation of the HDMI TX at
>>> that level.
>>      After confirming with the IC designer, we finally make clear that
>>      Rockchip RK3288 almost use the same clock design with imx:
>>      clk-----iahbclk, used for hdmi module and bus
>>      hdcp_clk-----isfrclk, used for hdcp and i2cm
>>      cecclk -----cecclk, but this clk can be gated on rockchip, this is
>> different with imx,
>>      but we don't handle the cec stuff now. So i will try to reuse the
>> imx clk binds. do you
>>     think that is ok?
> Thank you for taking the time to verify this. So we should move the
> clock handling out of the soc specific parts into the common driver and
> reuse the existing clock bindings ("iahb", "isfr").
> I'd suggest to add the "cec" clock now to the binding document as an
> optional clock, then you can already specify it in the rockchip dtsi.
   ok
>
> regards
> Philipp
>
>
>


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

* Re: [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support
@ 2014-12-03 13:20               ` Andy Yan
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Yan @ 2014-12-03 13:20 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, heiko, airlied, dri-devel, ykk, devel, Pawel Moll,
	linux-rockchip, Grant Likely, Dave Airlie, jay.xu, devicetree,
	Zubair.Kakakhel, Arnd Bergmann, Ian Campbell, Inki Dae,
	Rob Herring, Sean Paul, rmk+kernel, mark.yao, fabio.estevam,
	Josh Boyer, Greg Kroah-Hartman, linux-kernel, djkurtz,
	Kumar Gala, Shawn Guo, vladimir_zapolskiy

Hi Philipp:
On 2014年12月03日 21:09, Philipp Zabel wrote:
> Hi Andy,
>
> Am Mittwoch, den 03.12.2014, 20:32 +0800 schrieb Andy Yan:
>>> My question is not about the available gates at the SoC level, but about
>>> the actual clock inputs from point of view of the HDMI TX IP.
>>>
>>> It could be that the hdmi_ctrl_clk gates all inputs to the module and
>>> bus clocks together. If so, you could just reuse "isfr" and "iahb" and
>>> set it to the same clock. If not, we'd need to think of something else.
>>> Unfortunately I don't have any Synopsys documentation of the HDMI TX at
>>> that level.
>>      After confirming with the IC designer, we finally make clear that
>>      Rockchip RK3288 almost use the same clock design with imx:
>>      clk-----iahbclk, used for hdmi module and bus
>>      hdcp_clk-----isfrclk, used for hdcp and i2cm
>>      cecclk -----cecclk, but this clk can be gated on rockchip, this is
>> different with imx,
>>      but we don't handle the cec stuff now. So i will try to reuse the
>> imx clk binds. do you
>>     think that is ok?
> Thank you for taking the time to verify this. So we should move the
> clock handling out of the soc specific parts into the common driver and
> reuse the existing clock bindings ("iahb", "isfr").
> I'd suggest to add the "cec" clock now to the binding document as an
> optional clock, then you can already specify it in the rockchip dtsi.
   ok
>
> regards
> Philipp
>
>
>

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

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

end of thread, other threads:[~2014-12-03 13:20 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-02  7:36 [PATCH v15 0/12] dw-hdmi: convert imx hdmi to bridge/dw_hdmi Andy Yan
2014-12-02  7:36 ` Andy Yan
2014-12-02  7:38 ` [PATCH v15 01/12] drm: imx: imx-hdmi: make checkpatch happy Andy Yan
2014-12-02  7:38   ` Andy Yan
2014-12-02  7:39 ` [PATCH v15 02/12] drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter Andy Yan
2014-12-02  7:39   ` Andy Yan
2014-12-02  7:39 ` [PATCH v15 03/12] drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode Andy Yan
2014-12-02  7:39   ` Andy Yan
2014-12-02  7:40 ` [PATCH v15 04/12] drm: imx: imx-hdmi: split phy configuration to platform driver Andy Yan
2014-12-02  7:40   ` Andy Yan
2014-12-02  7:41 ` [PATCH v15 05/12] drm: imx: imx-hdmi: move imx-hdmi to bridge/dw_hdmi Andy Yan
2014-12-02  7:41   ` Andy Yan
2014-12-02  7:42 ` [PATCH v15 06/12] dt-bindings: add document for dw_hdmi Andy Yan
2014-12-02  7:42   ` Andy Yan
2014-12-02 18:23   ` Philipp Zabel
2014-12-02 18:23     ` Philipp Zabel
2014-12-03  0:54     ` Andy Yan
2014-12-03  0:54       ` Andy Yan
2014-12-03  9:19       ` Philipp Zabel
2014-12-03  9:19         ` Philipp Zabel
2014-12-03  9:43         ` Andy Yan
2014-12-03  9:43           ` Andy Yan
2014-12-03  9:46     ` Andy Yan
2014-12-03  9:46       ` Andy Yan
2014-12-03 11:52       ` Philipp Zabel
2014-12-03 11:52         ` Philipp Zabel
2014-12-03 11:58         ` Andy Yan
2014-12-03 11:58           ` Andy Yan
2014-12-02  7:42 ` [PATCH v15 07/12] drm: bridge/dw_hdmi: add support for multi-byte register width access Andy Yan
2014-12-02  7:43 ` [PATCH v15 08/12] drm: bridge/dw_hdmi: add mode_valid support Andy Yan
2014-12-02  7:43   ` Andy Yan
2014-12-02  7:43 ` [PATCH v15 09/12] drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done Andy Yan
2014-12-02  7:43   ` Andy Yan
2014-12-02  7:44 ` [PATCH v15 10/12] drm: bridge/dw_hdmi: add function dw_hdmi_phy_enable_spare Andy Yan
2014-12-02  7:44   ` Andy Yan
2014-12-02  7:44 ` [PATCH v15 11/12] dt-bindings: Add documentation for rockchip dw hdmi Andy Yan
2014-12-02  7:44   ` Andy Yan
2014-12-02  7:45 ` [PATCH v15 12/12] drm: bridge/dw_hdmi: add rockchip rk3288 support Andy Yan
2014-12-02  7:45   ` Andy Yan
2014-12-02 10:24   ` Philipp Zabel
2014-12-02 10:24     ` Philipp Zabel
2014-12-02 12:34     ` Andy Yan
2014-12-02 12:34       ` Andy Yan
2014-12-02 13:00       ` Philipp Zabel
2014-12-02 13:00         ` Philipp Zabel
2014-12-03 12:32         ` Andy Yan
2014-12-03 12:32           ` Andy Yan
2014-12-03 13:09           ` Philipp Zabel
2014-12-03 13:09             ` Philipp Zabel
2014-12-03 13:20             ` Andy Yan
2014-12-03 13:20               ` Andy Yan

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.