mx6sabresd: Add LVDS splash screen support
mx6sabresd boards can be connected to a Hannstar XGA LVDS panel. Add support for displaying U-boot splashscreen on it. By default, HDMI splash is selected. In order to use splash via LVDS, do the following in the U-boot prompt: setenv panel Hannstar-XGA save and reboot. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
This commit is contained in:
		
							parent
							
								
									7b8657e2bd
								
							
						
					
					
						commit
						d9b8946035
					
				| 
						 | 
				
			
			@ -234,47 +234,171 @@ int board_phy_config(struct phy_device *phydev)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_VIDEO_IPUV3)
 | 
			
		||||
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
 | 
			
		||||
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_DVI_STAT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_enable_hdmi(struct display_info_t const *dev)
 | 
			
		||||
{
 | 
			
		||||
	imx_enable_hdmi_phy();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void enable_lvds(struct display_info_t const *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct iomuxc *iomux = (struct iomuxc *)
 | 
			
		||||
				IOMUXC_BASE_ADDR;
 | 
			
		||||
	u32 reg = readl(&iomux->gpr[2]);
 | 
			
		||||
	reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT |
 | 
			
		||||
	       IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT;
 | 
			
		||||
	writel(reg, &iomux->gpr[2]);
 | 
			
		||||
}
 | 
			
		||||
static 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",
 | 
			
		||||
		.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
 | 
			
		||||
} }, {
 | 
			
		||||
	.bus	= -1,
 | 
			
		||||
	.addr	= 0,
 | 
			
		||||
	.pixfmt	= IPU_PIX_FMT_LVDS666,
 | 
			
		||||
	.detect	= NULL,
 | 
			
		||||
	.enable	= enable_lvds,
 | 
			
		||||
	.mode	= {
 | 
			
		||||
		.name           = "Hannstar-XGA",
 | 
			
		||||
		.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 i;
 | 
			
		||||
	int ret;
 | 
			
		||||
	char const *panel = getenv("panel");
 | 
			
		||||
	if (!panel) {
 | 
			
		||||
		for (i = 0; i < ARRAY_SIZE(displays); i++) {
 | 
			
		||||
			struct display_info_t const *dev = displays+i;
 | 
			
		||||
			if (dev->detect(dev)) {
 | 
			
		||||
				panel = dev->mode.name;
 | 
			
		||||
				printf("auto-detected panel %s\n", panel);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!panel) {
 | 
			
		||||
			panel = displays[0].mode.name;
 | 
			
		||||
			printf("No panel detected: default to %s\n", panel);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		for (i = 0; i < ARRAY_SIZE(displays); i++) {
 | 
			
		||||
			if (!strcmp(panel, displays[i].mode.name))
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (i < ARRAY_SIZE(displays)) {
 | 
			
		||||
		ret = ipuv3_fb_init(&displays[i].mode, 0,
 | 
			
		||||
				    displays[i].pixfmt);
 | 
			
		||||
		if (!ret) {
 | 
			
		||||
			displays[i].enable(displays+i);
 | 
			
		||||
			printf("Display: %s (%ux%u)\n",
 | 
			
		||||
			       displays[i].mode.name,
 | 
			
		||||
			       displays[i].mode.xres,
 | 
			
		||||
			       displays[i].mode.yres);
 | 
			
		||||
		} else
 | 
			
		||||
			printf("LCD %s cannot be configured: %d\n",
 | 
			
		||||
			       displays[i].mode.name, ret);
 | 
			
		||||
	} else {
 | 
			
		||||
		printf("unsupported panel %s\n", panel);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = ipuv3_fb_init(&hdmi, 0, IPU_PIX_FMT_RGB24);
 | 
			
		||||
 | 
			
		||||
	if (ret)
 | 
			
		||||
		printf("HDMI cannot be configured: %d\n", ret);
 | 
			
		||||
 | 
			
		||||
	imx_enable_hdmi_phy();
 | 
			
		||||
	return ret;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
	imx_setup_hdmi();
 | 
			
		||||
 | 
			
		||||
	/* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
 | 
			
		||||
	reg = __raw_readl(&mxc_ccm->CCGR3);
 | 
			
		||||
	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
 | 
			
		||||
	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 | MXC_CCM_CSCMR2_LDB_DI1_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);
 | 
			
		||||
	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 | 
			
		||||
		<< MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
 | 
			
		||||
	writel(reg, &mxc_ccm->chsccdr);
 | 
			
		||||
 | 
			
		||||
	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 | 
			
		||||
	     | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
 | 
			
		||||
	     | 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_CH0_MODE_DISABLED
 | 
			
		||||
	     | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
 | 
			
		||||
	writel(reg, &iomux->gpr[2]);
 | 
			
		||||
 | 
			
		||||
	reg = readl(&iomux->gpr[3]);
 | 
			
		||||
	reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
 | 
			
		||||
			| IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
 | 
			
		||||
	    | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 | 
			
		||||
	       << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
 | 
			
		||||
	writel(reg, &iomux->gpr[3]);
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_VIDEO_IPUV3 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue