Patchwork [U-Boot,1/2] mx6: Factor out common HDMI setup code

login
register
mail settings
Submitter Pardeep Kumar Singla
Date July 12, 2013, 10:21 p.m.
Message ID <1373667683-14368-1-git-send-email-b45784@freescale.com>
Download mbox | patch
Permalink /patch/258815/
State Superseded
Delegated to: Stefano Babic
Headers show

Comments

Pardeep Kumar Singla - July 12, 2013, 10:21 p.m.
Instead of duplicating HDMI setup code for every mx6 board, factor out the common code

Signed-off-by: Pardeep Kumar Singla <b45784@freescale.com>
---
 arch/arm/cpu/armv7/mx6/soc.c                  |   51 ++++++++++++++
 arch/arm/include/asm/arch-mx6/mxc_hdmi.h      |    6 ++
 arch/arm/include/asm/arch-mx6/sys_proto.h     |   13 ++++
 board/boundary/nitrogen6x/nitrogen6x.c        |   57 +---------------
 board/freescale/mx6qsabrelite/mx6qsabrelite.c |   60 ++--------------
 board/wandboard/wandboard.c                   |   91 ++++++-------------------
 include/configs/mx6qsabrelite.h               |    8 ++-
 include/configs/nitrogen6x.h                  |    2 +-
 include/configs/wandboard.h                   |    1 +
 9 files changed, 106 insertions(+), 183 deletions(-)
Eric Nelson - July 14, 2013, 3:43 p.m.
Hi Pardeep,

On 07/12/2013 03:21 PM, Pardeep Kumar Singla wrote:
> Instead of duplicating HDMI setup code for every mx6 board, factor out the common code
>
> Signed-off-by: Pardeep Kumar Singla <b45784@freescale.com>
> ---
>   arch/arm/cpu/armv7/mx6/soc.c                  |   51 ++++++++++++++
>   arch/arm/include/asm/arch-mx6/mxc_hdmi.h      |    6 ++
>   arch/arm/include/asm/arch-mx6/sys_proto.h     |   13 ++++
>   board/boundary/nitrogen6x/nitrogen6x.c        |   57 +---------------
>   board/freescale/mx6qsabrelite/mx6qsabrelite.c |   60 ++--------------
>   board/wandboard/wandboard.c                   |   91 ++++++-------------------
>   include/configs/mx6qsabrelite.h               |    8 ++-
>   include/configs/nitrogen6x.h                  |    2 +-
>   include/configs/wandboard.h                   |    1 +
>   9 files changed, 106 insertions(+), 183 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
> index fc436fb..6e79310 100644
> --- a/arch/arm/cpu/armv7/mx6/soc.c
> +++ b/arch/arm/cpu/armv7/mx6/soc.c
> @@ -32,6 +32,8 @@
>   #include <asm/imx-common/boot_mode.h>
>   #include <asm/imx-common/dma.h>
>   #include <stdbool.h>
> +#include <asm/arch/mxc_hdmi.h>
> +#include <asm/arch/crm_regs.h>
>
>   struct scu_regs {
>   	u32	ctrl;
> @@ -228,3 +230,52 @@ const struct boot_mode soc_boot_modes[] = {
>   void s_init(void)
>   {
>   }
> +
> +#ifdef CONFIG_IMX_HDMI
> +void imx_enable_hdmi_phy(struct display_info_t const *dev)
> +{

The only reason this has a dev parameter is so it can be used by
auto-detect code.

It should be kept out of this code to make the interface clearer.

Boards that support auto-detect (mx6qsabrelite/nitrogen6x)
can wrap it.

> +	struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
> +	u8 reg;
> +	reg = readb(&hdmi->phy_conf0);
> +	reg |= HDMI_PHY_CONF0_PDZ_MASK;
> +	writeb(reg, &hdmi->phy_conf0);
> +	udelay(3000);
> +	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
> +	writeb(reg, &hdmi->phy_conf0);
> +	udelay(3000);
> +	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
> +	writeb(reg, &hdmi->phy_conf0);
> +	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
> +}
> +
> +void imx_setup_hdmi(void)
> +{
> +	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +	struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
> +	int reg;
> +
> +	/* Turn on IPU clock */
> +	reg = readl(&mxc_ccm->CCGR3);
> +	reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
> +	writel(reg, &mxc_ccm->CCGR3);
> +
> +	/* Turn on HDMI PHY clock */
> +	reg = readl(&mxc_ccm->CCGR2);
> +	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
> +		 MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
> +	writel(reg, &mxc_ccm->CCGR2);
> +	 /* clear HDMI PHY reset */
> +	 writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);


There's a lot of policy in this register write and some of it isn't
really HDMI-specific (LDB clock selects). I'd recommend keeping
that in board-specific code:

> +	reg = readl(&mxc_ccm->chsccdr);
> +	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
> +		 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
> +		 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
> +	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
> +		 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)|
> +		 (CHSCCDR_PODF_DIVIDE_BY_3
> +		 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
> +		 |(CHSCCDR_IPU_PRE_CLK_540M_PFD
> +		 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
> +	writel(reg, &mxc_ccm->chsccdr);
> +}
> +#endif
> diff --git a/arch/arm/include/asm/arch-mx6/mxc_hdmi.h b/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
> index 9dccb3f..9e2074b 100644
> --- a/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
> +++ b/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
> @@ -21,6 +21,12 @@
>   #ifndef __MXC_HDMI_H__
>   #define __MXC_HDMI_H__
>
> +#ifdef CONFIG_IMX_HDMI
> +#include<asm/arch/sys_proto.h>
> +void imx_enable_hdmi_phy(struct display_info_t const *dev);
> +void imx_setup_hdmi(void);
> +#endif
> +
>   /*
>    * Hdmi controller registers
>    */
> diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
> index 38e4e51..9fb539b 100644
> --- a/arch/arm/include/asm/arch-mx6/sys_proto.h
> +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
> @@ -25,6 +25,9 @@
>   #define _SYS_PROTO_H_
>
>   #include <asm/imx-common/regs-common.h>
> +#include<linux/list.h>
> +#include <linux/fb.h>
> +#include <i2c.h>
>
>   #define MXC_CPU_MX51		0x51
>   #define MXC_CPU_MX53		0x53
> @@ -34,6 +37,16 @@
>   #define MXC_CPU_MX6Q		0x63
>
>   #define is_soc_rev(rev)	((get_cpu_rev() & 0xFF) - rev)

This is specific to a couple of boards, and not mx6-specific:

> +
> +struct display_info_t {
> +	int        bus;
> +	int        addr;
> +	int        pixfmt;
> +	int        (*detect)(struct display_info_t const *dev);
> +	void        (*enable)(struct display_info_t const *dev);
> +	struct        fb_videomode mode;
> +};
> +

>   u32 get_cpu_rev(void);
>   const char *get_imx_type(u32 imxtype);
>   unsigned imx_ddr_size(void);
> diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c
> index 8f0f9b8..d97d47a 100644
> --- a/board/boundary/nitrogen6x/nitrogen6x.c
> +++ b/board/boundary/nitrogen6x/nitrogen6x.c
> @@ -464,40 +464,12 @@ static iomux_v3_cfg_t const rgb_pads[] = {
>   	MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
>   };
>
>  <snip>
>
> -static void enable_hdmi(struct display_info_t const *dev)
> -{

static void do_enable_hdmi(struct display_info_t const *dev)
{
	return enable_hdmi();
}

Regards,


Eric

Patch

diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index fc436fb..6e79310 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -32,6 +32,8 @@ 
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/dma.h>
 #include <stdbool.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <asm/arch/crm_regs.h>
 
 struct scu_regs {
 	u32	ctrl;
@@ -228,3 +230,52 @@  const struct boot_mode soc_boot_modes[] = {
 void s_init(void)
 {
 }
+
+#ifdef CONFIG_IMX_HDMI
+void imx_enable_hdmi_phy(struct display_info_t const *dev)
+{
+	struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+	u8 reg;
+	reg = readb(&hdmi->phy_conf0);
+	reg |= HDMI_PHY_CONF0_PDZ_MASK;
+	writeb(reg, &hdmi->phy_conf0);
+	udelay(3000);
+	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
+	writeb(reg, &hdmi->phy_conf0);
+	udelay(3000);
+	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
+	writeb(reg, &hdmi->phy_conf0);
+	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
+}
+
+void imx_setup_hdmi(void)
+{
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+	int reg;
+
+	/* Turn on IPU clock */
+	reg = readl(&mxc_ccm->CCGR3);
+	reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
+	writel(reg, &mxc_ccm->CCGR3);
+
+	/* Turn on HDMI PHY clock */
+	reg = readl(&mxc_ccm->CCGR2);
+	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
+		 MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
+	writel(reg, &mxc_ccm->CCGR2);
+	 /* clear HDMI PHY reset */
+	 writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
+	reg = readl(&mxc_ccm->chsccdr);
+	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
+		 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
+		 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
+	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+		 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)|
+		 (CHSCCDR_PODF_DIVIDE_BY_3
+		 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
+		 |(CHSCCDR_IPU_PRE_CLK_540M_PFD
+		 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+	writel(reg, &mxc_ccm->chsccdr);
+}
+#endif
diff --git a/arch/arm/include/asm/arch-mx6/mxc_hdmi.h b/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
index 9dccb3f..9e2074b 100644
--- a/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
+++ b/arch/arm/include/asm/arch-mx6/mxc_hdmi.h
@@ -21,6 +21,12 @@ 
 #ifndef __MXC_HDMI_H__
 #define __MXC_HDMI_H__
 
+#ifdef CONFIG_IMX_HDMI
+#include<asm/arch/sys_proto.h>
+void imx_enable_hdmi_phy(struct display_info_t const *dev);
+void imx_setup_hdmi(void);
+#endif
+
 /*
  * Hdmi controller registers
  */
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 38e4e51..9fb539b 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -25,6 +25,9 @@ 
 #define _SYS_PROTO_H_
 
 #include <asm/imx-common/regs-common.h>
+#include<linux/list.h>
+#include <linux/fb.h>
+#include <i2c.h>
 
 #define MXC_CPU_MX51		0x51
 #define MXC_CPU_MX53		0x53
@@ -34,6 +37,16 @@ 
 #define MXC_CPU_MX6Q		0x63
 
 #define is_soc_rev(rev)	((get_cpu_rev() & 0xFF) - rev)
+
+struct display_info_t {
+	int        bus;
+	int        addr;
+	int        pixfmt;
+	int        (*detect)(struct display_info_t const *dev);
+	void        (*enable)(struct display_info_t const *dev);
+	struct        fb_videomode mode;
+};
+
 u32 get_cpu_rev(void);
 const char *get_imx_type(u32 imxtype);
 unsigned imx_ddr_size(void);
diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c
index 8f0f9b8..d97d47a 100644
--- a/board/boundary/nitrogen6x/nitrogen6x.c
+++ b/board/boundary/nitrogen6x/nitrogen6x.c
@@ -464,40 +464,12 @@  static iomux_v3_cfg_t const rgb_pads[] = {
 	MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
 };
 
-struct display_info_t {
-	int	bus;
-	int	addr;
-	int	pixfmt;
-	int	(*detect)(struct display_info_t const *dev);
-	void	(*enable)(struct display_info_t const *dev);
-	struct	fb_videomode mode;
-};
-
-
 static int detect_hdmi(struct display_info_t const *dev)
 {
 	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 	return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
 }
 
-static void enable_hdmi(struct display_info_t const *dev)
-{
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-	u8 reg;
-	printf("%s: setup HDMI monitor\n", __func__);
-	reg = readb(&hdmi->phy_conf0);
-	reg |= HDMI_PHY_CONF0_PDZ_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
-}
-
 static int detect_i2c(struct display_info_t const *dev)
 {
 	return ((0 == i2c_set_bus_num(dev->bus))
@@ -528,7 +500,7 @@  static struct display_info_t const displays[] = {{
 	.addr	= 0,
 	.pixfmt	= IPU_PIX_FMT_RGB24,
 	.detect	= detect_hdmi,
-	.enable	= enable_hdmi,
+	.enable	= imx_enable_hdmi_phy,
 	.mode	= {
 		.name           = "HDMI",
 		.refresh        = 60,
@@ -653,25 +625,14 @@  static void setup_display(void)
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-
 	int reg;
 
+	imx_setup_hdmi();
 	/* Turn on LDB0,IPU,IPU DI0 clocks */
 	reg = __raw_readl(&mxc_ccm->CCGR3);
-	reg |=   MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
-		|MXC_CCM_CCGR3_LDB_DI0_MASK;
+	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
 	writel(reg, &mxc_ccm->CCGR3);
 
-	/* Turn on HDMI PHY clock */
-	reg = __raw_readl(&mxc_ccm->CCGR2);
-	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
-	       |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
-	writel(reg, &mxc_ccm->CCGR2);
-
-	/* clear HDMI PHY reset */
-	writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
-
 	/* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
 	writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
 	writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
@@ -688,18 +649,6 @@  static void setup_display(void)
 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
 	writel(reg, &mxc_ccm->cscmr2);
 
-	reg = readl(&mxc_ccm->chsccdr);
-	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
-		|MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
-		|MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
-	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
-	      |(CHSCCDR_PODF_DIVIDE_BY_3
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
-	      |(CHSCCDR_IPU_PRE_CLK_540M_PFD
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
-	writel(reg, &mxc_ccm->chsccdr);
-
 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 	     |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
 	     |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
index 862bc30..21b6bb6 100644
--- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
@@ -42,7 +42,7 @@ 
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/mxc_hdmi.h>
 #include <i2c.h>
-
+#include<asm/arch/sys_proto.h>
 DECLARE_GLOBAL_DATA_PTR;
 
 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
@@ -436,40 +436,12 @@  static iomux_v3_cfg_t const rgb_pads[] = {
 	MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
 };
 
-struct display_info_t {
-	int	bus;
-	int	addr;
-	int	pixfmt;
-	int	(*detect)(struct display_info_t const *dev);
-	void	(*enable)(struct display_info_t const *dev);
-	struct	fb_videomode mode;
-};
-
-
 static int detect_hdmi(struct display_info_t const *dev)
 {
 	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 	return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
 }
 
-static void enable_hdmi(struct display_info_t const *dev)
-{
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-	u8 reg;
-	printf("%s: setup HDMI monitor\n", __func__);
-	reg = readb(&hdmi->phy_conf0);
-	reg |= HDMI_PHY_CONF0_PDZ_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
-}
-
 static int detect_i2c(struct display_info_t const *dev)
 {
 	return ((0 == i2c_set_bus_num(dev->bus))
@@ -500,7 +472,7 @@  static struct display_info_t const displays[] = {{
 	.addr	= 0,
 	.pixfmt	= IPU_PIX_FMT_RGB24,
 	.detect	= detect_hdmi,
-	.enable	= enable_hdmi,
+	.enable	= imx_enable_hdmi_phy,
 	.mode	= {
 		.name           = "HDMI",
 		.refresh        = 60,
@@ -625,25 +597,15 @@  static void setup_display(void)
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-
 	int reg;
 
+	imx_setup_hdmi();
+
 	/* Turn on LDB0,IPU,IPU DI0 clocks */
 	reg = __raw_readl(&mxc_ccm->CCGR3);
-	reg |=   MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
-		|MXC_CCM_CCGR3_LDB_DI0_MASK;
+	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
 	writel(reg, &mxc_ccm->CCGR3);
 
-	/* Turn on HDMI PHY clock */
-	reg = __raw_readl(&mxc_ccm->CCGR2);
-	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
-	       |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
-	writel(reg, &mxc_ccm->CCGR2);
-
-	/* clear HDMI PHY reset */
-	writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
-
 	/* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
 	writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
 	writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
@@ -660,18 +622,6 @@  static void setup_display(void)
 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
 	writel(reg, &mxc_ccm->cscmr2);
 
-	reg = readl(&mxc_ccm->chsccdr);
-	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
-		|MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
-		|MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
-	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
-	      |(CHSCCDR_PODF_DIVIDE_BY_3
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
-	      |(CHSCCDR_IPU_PRE_CLK_540M_PFD
-		<<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
-	writel(reg, &mxc_ccm->chsccdr);
-
 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 	     |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
 	     |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c
index 43c02ac..4957303 100644
--- a/board/wandboard/wandboard.c
+++ b/board/wandboard/wandboard.c
@@ -28,7 +28,6 @@ 
 #include <miiphy.h>
 #include <netdev.h>
 #include <linux/fb.h>
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
@@ -211,85 +210,37 @@  int board_phy_config(struct phy_device *phydev)
 }
 
 #if defined(CONFIG_VIDEO_IPUV3)
-static void enable_hdmi(void)
-{
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-	u8 reg;
-	reg = readb(&hdmi->phy_conf0);
-	reg |= HDMI_PHY_CONF0_PDZ_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	udelay(3000);
-	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
-	writeb(reg, &hdmi->phy_conf0);
-	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
-}
-
-static struct fb_videomode const hdmi = {
-	.name           = "HDMI",
-	.refresh        = 60,
-	.xres           = 1024,
-	.yres           = 768,
-	.pixclock       = 15385,
-	.left_margin    = 220,
-	.right_margin   = 40,
-	.upper_margin   = 21,
-	.lower_margin   = 7,
-	.hsync_len      = 60,
-	.vsync_len      = 10,
-	.sync           = FB_SYNC_EXT,
-	.vmode          = FB_VMODE_NONINTERLACED
-};
+static struct display_info_t const displays = {
+	.pixfmt = IPU_PIX_FMT_RGB24,
+	.enable = imx_enable_hdmi_phy,
+	.mode   = {
+		.name           = "HDMI",
+		.refresh        = 60,
+		.xres           = 1024,
+		.yres           = 768,
+		.pixclock       = 15385,
+		.left_margin    = 220,
+		.right_margin   = 40,
+		.upper_margin   = 21,
+		.lower_margin   = 7,
+		.hsync_len      = 60,
+		.vsync_len      = 10,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} };
 
 int board_video_skip(void)
 {
 	int ret;
 
-	ret = ipuv3_fb_init(&hdmi, 0, IPU_PIX_FMT_RGB24);
+	ret = ipuv3_fb_init(&displays.mode, 0, displays.pixfmt);
 
 	if (ret)
 		printf("HDMI cannot be configured: %d\n", ret);
-
-	enable_hdmi();
+	displays.enable(&displays);
 
 	return ret;
 }
-
-static void setup_display(void)
-{
-	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
-	struct hdmi_regs *hdmi	= (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-	int reg;
-
-	/* Turn on IPU clock */
-	reg = readl(&mxc_ccm->CCGR3);
-	reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
-	writel(reg, &mxc_ccm->CCGR3);
-
-	/* Turn on HDMI PHY clock */
-	reg = readl(&mxc_ccm->CCGR2);
-	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
-		| MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
-	writel(reg, &mxc_ccm->CCGR2);
-
-	/* clear HDMI PHY reset */
-	writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
-
-	reg = readl(&mxc_ccm->chsccdr);
-	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
-		| MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
-		| MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
-	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
-		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
-	      | (CHSCCDR_PODF_DIVIDE_BY_3
-		<< MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
-	      | (CHSCCDR_IPU_PRE_CLK_540M_PFD
-		<< MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
-	writel(reg, &mxc_ccm->chsccdr);
-}
 #endif /* CONFIG_VIDEO_IPUV3 */
 
 int board_eth_init(bd_t *bis)
@@ -309,7 +260,7 @@  int board_early_init_f(void)
 {
 	setup_iomux_uart();
 #if defined(CONFIG_VIDEO_IPUV3)
-	setup_display();
+	imx_setup_hdmi();
 #endif
 	return 0;
 }
diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h
index c7db81d..4549f24 100644
--- a/include/configs/mx6qsabrelite.h
+++ b/include/configs/mx6qsabrelite.h
@@ -26,6 +26,7 @@ 
 #define CONFIG_MX6Q
 
 #include "mx6_common.h"
+#include<asm/sizes.h>
 
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
@@ -35,14 +36,14 @@ 
 #include <asm/arch/imx-regs.h>
 #include <asm/imx-common/gpio.h>
 
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN          (10 * SZ_1M)
+
 #define CONFIG_CMDLINE_TAG
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 #define CONFIG_REVISION_TAG
 
-/* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(10 * 1024 * 1024)
-
 #define CONFIG_BOARD_EARLY_INIT_F
 #define CONFIG_MISC_INIT_R
 #define CONFIG_MXC_GPIO
@@ -141,6 +142,7 @@ 
 #define CONFIG_BMP_16BPP
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_IPUV3_CLK 260000000
+#define CONFIG_IMX_HDMI
 
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index 74df66c..5a4d06e 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -154,7 +154,7 @@ 
 #define CONFIG_IPUV3_CLK 260000000
 #define CONFIG_CMD_HDMIDETECT
 #define CONFIG_CONSOLE_MUX
-
+#define CONFIG_IMX_HDMI
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
 #define CONFIG_CONS_INDEX	       1
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index ee6bf21..9282e23 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -100,6 +100,7 @@ 
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_VIDEO_BMP_LOGO
 #define CONFIG_IPUV3_CLK 260000000
+#define CONFIG_IMX_HDMI
 
 #if defined(CONFIG_MX6DL)
 #define CONFIG_DEFAULT_FDT_FILE		"imx6dl-wandboard.dtb"