summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@freescale.com>2015-04-29 22:28:09 -0300
committerStefano Babic <sbabic@denx.de>2015-05-15 19:20:46 +0200
commitf68a9c6b3db80f00d62963e788f8dadc0657b2b6 (patch)
tree52f134b64a48b6e2657dd1ef7a6701397214186e /board
parent8148b824492e7696a9e72bb5b715720db8fd889e (diff)
downloadu-boot-imx-f68a9c6b3db80f00d62963e788f8dadc0657b2b6.zip
u-boot-imx-f68a9c6b3db80f00d62963e788f8dadc0657b2b6.tar.gz
u-boot-imx-f68a9c6b3db80f00d62963e788f8dadc0657b2b6.tar.bz2
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 <smoch@web.de> 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 <jon.nettleton@gmail.com> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Reviewed-by: Tom Rini <trini@konsulko.com> Tested-by: Tom Rini <trini@konsulko.com> Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Reviewed-by: Tom Rini <trini@konsulko.com> Tested-by: Vagrant Cascadian <vagrant@aikidev.net>
Diffstat (limited to 'board')
-rw-r--r--board/solidrun/mx6cuboxi/mx6cuboxi.c101
1 files changed, 100 insertions, 1 deletions
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 <asm/arch/imx-regs.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mx6-pins.h>
+#include <asm/arch/mxc_hdmi.h>
#include <asm/errno.h>
#include <asm/gpio.h>
#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/video.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <miiphy.h>
@@ -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)