From f68a9c6b3db80f00d62963e788f8dadc0657b2b6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 29 Apr 2015 22:28:09 -0300 Subject: mx6cuboxi: Add HDMI output support Add HDMI output using PLL5 as the source for the IPU clocks, and accurate VESA timings. These settings are based on the patch from Soeren Moch submitted for the tbs2910 mx6 based board. It allows the display to work properly at 1024x768@60. This should make the hdmi output signal compatible with most if not all modern displays. Signed-off-by: Jon Nettleton Signed-off-by: Fabio Estevam Reviewed-by: Tom Rini Tested-by: Tom Rini Signed-off-by: Rabeeh Khoury Signed-off-by: Fabio Estevam Reviewed-by: Tom Rini Tested-by: Vagrant Cascadian --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 101 ++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) (limited to 'board/solidrun') diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index d3a32c1..eab92f1 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -18,9 +18,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -159,10 +161,107 @@ int board_eth_init(bd_t *bis) return cpu_eth_init(bis); } +#ifdef CONFIG_VIDEO_IPUV3 +static void do_enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +struct display_info_t const displays[] = { + { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = do_enable_hdmi, + .mode = { + .name = "HDMI", + /* 1024x768@60Hz (VESA)*/ + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15384, + .left_margin = 160, + .right_margin = 24, + .upper_margin = 29, + .lower_margin = 3, + .hsync_len = 136, + .vsync_len = 6, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED + } + } +}; + +size_t display_count = ARRAY_SIZE(displays); + +static int setup_display(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + int reg; + int timeout = 100000; + + enable_ipu_clock(); + imx_setup_hdmi(); + + /* set video pll to 455MHz (24MHz * (37+11/12) / 2) */ + setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN); + + reg = readl(&ccm->analog_pll_video); + reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT; + reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(37); + reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT; + reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1); + writel(reg, &ccm->analog_pll_video); + + writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num); + writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom); + + reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN; + writel(reg, &ccm->analog_pll_video); + + while (timeout--) + if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK) + break; + if (timeout < 0) { + printf("Warning: video pll lock timeout!\n"); + return -ETIMEDOUT; + } + + reg = readl(&ccm->analog_pll_video); + reg |= BM_ANADIG_PLL_VIDEO_ENABLE; + reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS; + writel(reg, &ccm->analog_pll_video); + + /* gate ipu1_di0_clk */ + clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK); + + /* select video_pll clock / 7 for ipu1_di0_clk -> 65MHz pixclock */ + reg = readl(&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 |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET) | + (6 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) | + (0 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); + writel(reg, &ccm->chsccdr); + + /* enable ipu1_di0_clk */ + setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK); + + return 0; +} +#endif /* CONFIG_VIDEO_IPUV3 */ + int board_early_init_f(void) { + int ret = 0; setup_iomux_uart(); - return 0; + +#ifdef CONFIG_VIDEO_IPUV3 + ret = setup_display(); +#endif + return ret; } int board_init(void) -- cgit v1.1