@ -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 ;
} ;
int board_video_skip ( void )
static int detect_hdmi ( struct display_info_t const * dev )
{
int ret ;
struct hdmi_regs * hdmi = ( struct hdmi_regs * ) HDMI_ARB_BASE_ADDR ;
return readb ( & hdmi - > phy_stat0 ) & HDMI_DVI_STAT ;
}
ret = ipuv3_fb_init ( & hdmi , 0 , IPU_PIX_FMT_RGB24 ) ;
static void do_enable_hdmi ( struct display_info_t const * dev )
{
imx_enable_hdmi_phy ( ) ;
}
if ( ret )
printf ( " HDMI cannot be configured: %d \n " , ret ) ;
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
} } } ;
imx_enable_hdmi_phy ( ) ;
return ret ;
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 ;
}
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 */