From ca7463c9d795d7c43621c8c5ac1faf870deec47c Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 6 Dec 2016 00:00:55 +0100 Subject: [PATCH] imx6: icorem6: Add framebuffer support Add IPUv3 framebuffer support for Engicam i.CoreM6 qdl board. Cc: Anatolij Gustschin Cc: Stefano Babic Cc: Matteo Lisi Cc: Michael Trimarchi Signed-off-by: Jagan Teki --- board/engicam/icorem6/icorem6.c | 113 +++++++++++++++++++++++++++++++++++ configs/imx6qdl_icore_mmc_defconfig | 3 + configs/imx6qdl_icore_nand_defconfig | 3 + include/configs/imx6qdl_icore.h | 12 ++++ 4 files changed, 131 insertions(+) diff --git a/board/engicam/icorem6/icorem6.c b/board/engicam/icorem6/icorem6.c index 587775e..171ec45 100644 --- a/board/engicam/icorem6/icorem6.c +++ b/board/engicam/icorem6/icorem6.c @@ -18,6 +18,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -90,6 +91,113 @@ static void setup_gpmi_nand(void) } #endif +#if defined(CONFIG_VIDEO_IPUV3) +static iomux_v3_cfg_t const rgb_pads[] = { + IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK), + IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15), + IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), + IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), + IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00), + IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01), + IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02), + IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03), + IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04), + IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05), + IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06), + IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07), + IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08), + IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09), + IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10), + IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11), + IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12), + IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13), + IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14), + IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15), + IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16), + IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17), +}; + +static void enable_rgb(struct display_info_t const *dev) +{ + SETUP_IOMUX_PADS(rgb_pads); +} + +struct display_info_t const displays[] = { + { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB666, + .detect = NULL, + .enable = enable_rgb, + .mode = { + .name = "Amp-WD", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = 30000, + .left_margin = 30, + .right_margin = 30, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 64, + .vsync_len = 20, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED + } + }, +}; + +size_t display_count = ARRAY_SIZE(displays); + +static void setup_display(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + int reg; + + enable_ipu_clock(); + + /* Turn on LDB0,IPU,IPU DI0 clocks */ + reg = __raw_readl(&mxc_ccm->CCGR3); + reg |= (MXC_CCM_CCGR3_LDB_DI0_MASK | 0xffff); + writel(reg, &mxc_ccm->CCGR3); + + /* set LDB0, LDB1 clk select to 011/011 */ + reg = readl(&mxc_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK | + MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); + reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) | + (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->cs2cdr); + + reg = readl(&mxc_ccm->cscmr2); + reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; + writel(reg, &mxc_ccm->cscmr2); + + reg = readl(&mxc_ccm->chsccdr); + reg |= (CHSCCDR_CLK_SEL_LDB_DI0 << + MXC_CCM_CHSCCDR_IPU1_DI0_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 | + IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG | + IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT | + IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG | + IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT | + IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED | + IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; + writel(reg, &iomux->gpr[2]); + + reg = readl(&iomux->gpr[3]); + reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK) | + (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 << + IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); + writel(reg, &iomux->gpr[3]); +} +#endif /* CONFIG_VIDEO_IPUV3 */ + int board_early_init_f(void) { SETUP_IOMUX_PADS(uart4_pads); @@ -105,6 +213,11 @@ int board_init(void) #ifdef CONFIG_NAND_MXS setup_gpmi_nand(); #endif + +#ifdef CONFIG_VIDEO_IPUV3 + setup_display(); +#endif + return 0; } diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig index 31f40b4..6fa85de 100644 --- a/configs/imx6qdl_icore_mmc_defconfig +++ b/configs/imx6qdl_icore_mmc_defconfig @@ -33,6 +33,9 @@ CONFIG_MXC_UART=y CONFIG_IMX_THERMAL=y CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y +CONFIG_VIDEO=y +CONFIG_VIDEO_IPUV3=y +CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y diff --git a/configs/imx6qdl_icore_nand_defconfig b/configs/imx6qdl_icore_nand_defconfig index 3410e4c..b32eea9 100644 --- a/configs/imx6qdl_icore_nand_defconfig +++ b/configs/imx6qdl_icore_nand_defconfig @@ -29,6 +29,9 @@ CONFIG_IMX_THERMAL=y # CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y +CONFIG_VIDEO=y +CONFIG_VIDEO_IPUV3=y +CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y diff --git a/include/configs/imx6qdl_icore.h b/include/configs/imx6qdl_icore.h index f8a1263..70e74ba 100644 --- a/include/configs/imx6qdl_icore.h +++ b/include/configs/imx6qdl_icore.h @@ -149,6 +149,18 @@ # define CONFIG_PHY_SMSC #endif +/* Framebuffer */ +#ifdef CONFIG_VIDEO_IPUV3 +# define CONFIG_IPUV3_CLK 260000000 +# define CONFIG_IMX_VIDEO_SKIP + +# define CONFIG_SPLASH_SCREEN +# define CONFIG_BMP_16BPP +# define CONFIG_VIDEO_BMP_RLE8 +# define CONFIG_VIDEO_LOGO +# define CONFIG_VIDEO_BMP_LOGO +#endif + /* SPL */ #ifdef CONFIG_SPL # ifdef CONFIG_NAND_MXS