AnsweredAssumed Answered

Low frequency screens initialization in U-boot for splash screen

Question asked by Alexandr Spivac on Jun 27, 2018
Latest reply on Jun 28, 2018 by igorpadykov

Hellow

 

I am using "i.MX6Q" SOM 

I make some modifications in u-boot

I am using version v2015.04 

 

I have to initialize screens in U-boot and put a splash screen on them.

I added support for small screens. Derived clock from PLL2 PFD0  to pll5. Added configuration for dividers of pll5 in board code file. Added support of pll5 clock to "ipu_common.c" code file and put this clock to ldb_clk[0].rate and ldb_clk[1].rate Some code of this:

 

static unsigned long get_pll5_clk_rate(void)
{
struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
int reg;
int post_div_select = 1;
int div_select;
int num;
int denum;
unsigned long ret;

reg = readl(&ccm->analog_pll_video);
//post_div_select = reg & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT >> BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
switch ((reg & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT) >> BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT) {
case 0:
post_div_select = 4;
break;
case 1:
post_div_select = 2;
break;
case 2:
post_div_select = 1;
break;
default:
break;
}
div_select = reg & BM_ANADIG_PLL_VIDEO_DIV_SELECT;
reg = readl(&ccm->analog_pll_video_num);
num = reg & BM_ANADIG_PLL_VIDEO_NUM_A;
if ( num & (1<<29) ) num |= 0xC0000000;
reg = readl(&ccm->analog_pll_video_denom);
denum = reg & BM_ANADIG_PLL_VIDEO_DENOM_B;
ret = ( unsigned long ) (24000000.0*((float)div_select+(float)num/(float)denum)/(float)post_div_select);
#ifdef DEBUG
debug("Function %s post_div_select = %d\n", __func__, post_div_select);
debug("Function %s div_select = %d\n", __func__, div_select);
debug("Function %s num = %d\n", __func__, num);
debug("Function %s denum = %d\n", __func__, denum);
//debug("Function %s divider = %9.6f\n", __func__, divider);
debug("Function %s pll5 clock = %lu\n", __func__, ret);
#endif
return ( ret );
}

 

in int ipu_probe(void)

ldb_clk[0].rate = get_pll5_clk_rate()/7;
ldb_clk[1].rate = ldb_clk[0].rate;

 

I successfully initialize this my screens and have a splash screen :

 

struct display_info_t const displays[] = {{
.bus = -1, 
.addr = 0, 
.pixfmt = IPU_PIX_FMT_RGB24, 
.detect = detect_display_board_obc,
.enable = enable_lvds_obc, 
.mode = {
.name = "HVGA-OBC",
.refresh = 60,
.xres = 480,
.yres = 272,
.pixclock = MHZ2PS(9), 
.left_margin = 2, 
.right_margin = 2, 
.upper_margin = 2, 
.lower_margin = 2, 
.hsync_len = 41,
.vsync_len = 10, 
.sync = FB_SYNC_EXT , 
.vmode = FB_VMODE_NONINTERLACED 
} }, {
.bus = 0, 
.addr = -1, 
.pixfmt = IPU_PIX_FMT_RGB24, 
.detect = detect_display_board_vt600,
.enable = enable_lvds_vt600, 
.mode = {
.name = "WVGA-VT600",
.refresh = 60, 
.xres = 800,
.yres = 480,
.pixclock = MHZ2PS(30), 
.left_margin = 88, 
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 13, 
.hsync_len = 48, 
.vsync_len = 3,
.sync = FB_SYNC_EXT,
.vmode = FB_VMODE_NONINTERLACED
} } };

 

After some resets of u-boot in some cases screen not initialized properly and screen white with color lines.

U-boot copy kernel and device tree to ram and hang.

After some debugging, I founded an endless loop in the file "ipu_disp.c" :

do {
reg = __raw_readl(IPUIRQ_2_STATREG(irq));
} while (!(reg & IPUIRQ_2_MASK(irq)));

 

I understand that initialization was not properly but cannot find what cause this.

 

Someone can help me?

 All Regards,

Alex

Outcomes