rk3288 u-boot的logo显示过程

根据设备树 rockchip,uboot-logo-on = <1> 在u-boot中找到源码位置

void board_fbt_preboot(void)
		int node = fdt_path_offset(gd->fdt_blob, "/fb");
		g_logo_on_state = fdtdec_get_int(gd->fdt_blob, node, "rockchip,uboot-logo-on", 0);
		
		if (g_logo_on_state != 0) {
				lcd_enable_logo(true);
				drv_lcd_init();
					/*
					lcd_init(lcd_base);		/* LCD initialization */
					rc = stdio_register(&lcddev);
					*/
					
				#ifdef CONFIG_LCD
					if (g_logo_on_state != 0) {
						//lcd_enable_logo(true);
						//显示logo
						lcd_standby(0);
						//mdelay(100);
						/* use defaut brightness in dts */
						rk_pwm_bl_config(-1);
	
					}
				#endif
	
		}	



lcd_init(void *lcdbase) (rk3288\u-boot\common\Lcd.c)
		lcd_ctrl_init(lcdbase); (u-boot\driver\video\rockchip_fb.c)
		/*
					struct rockchip_fb *fb = &rockchip_fb;
					int ret = rk_fb_parse_dt(fb, gd->fdt_blob); //解析fb相关的fdt
							/*
							node = fdt_path_offset(blob, "/display-timings");
							//找到native-mode的值
							phandle = fdt_getprop_u32_default_node(blob, node, 0, "native-mode", -1);
							//根据native-mode对应的handler找到timing
							node = fdt_node_offset_by_phandle_node(blob, node, phandle);							
							
							开始设置pannel_info结构体
							panel_info.vl_bpix = 5;
							panel_info.lvds_ttl_en  = 0;
							panel_info.screen_type = fdtdec_get_int(blob, node, "screen-type", -1);
							panel_info.color_mode = fdtdec_get_int(blob, node, "color-mode", 0);
							panel_info.lcd_face = fdtdec_get_int(blob, node, "out-fac	
							panel_info.vl_col = fdtdec_get_int(blob, node, "hactive", 0);
							panel_info.vl_row = fdtdec_get_int(blob, node, "vactive", 0);
							panel_info.vl_width = fdtdec_get_int(blob, node, "hactive", 0);
							
							panel_info.vl_height = fdtdec_get_int(blob, node, "vactive", 0);
							panel_info.vl_freq = fdtdec_get_int(blob, node, "clock-frequency", 0);
							panel_info.vl_oep = fdtdec_get_int(blob, node, "de-active", -1);
							panel_info.vl_hsp = fdtdec_get_int(blob, node, "hsync-active", -1);
							panel_info.vl_vsp = fdtdec_get_int(blob, node, "vsync-active", -1);
							panel_info.lvds_format = fdtdec_get_int(blob, node, "lvds-format", -1);
							
							panel_info.vl_swap_rb = fdtdec_get_int(blob, node, "swap-rb", -1);
							if (panel_info.vl_swap_rb == (u_char)-1) {
							debug("Can't get swap-rb, set to 0 for default\n");
							panel_info.vl_swap_rb = 0;
							}
							
							panel_info.vl_hspw = fdtdec_get_int(blob, node, "hsync-len", 0);
							if (panel_info.vl_hspw == 0) {
							debug("Can't get hsync-len, use 10 to default\n");
							panel_info.vl_hspw = 10;
							}
							
							panel_info.vl_hfpd = fdtdec_get_int(blob, node, "hfront-porch", 0);
							panel_info.vl_hbpd = fdtdec_get_int(blob, node,	"hback-porch", 0);
							panel_info.vl_vspw = fdtdec_get_int(blob, node, "vsync-len", 0);
							panel_info.vl_vfpd = fdtdec_get_int(blob, node, "vfront-porch", 0);
							panel_info.vl_vbpd = fdtdec_get_int(blob, node, "vback-porch", 0);
							
							//查看lcdc是PRIMER:0还是EXTERN:1
							node = rk_fb_find_lcdc_node_dt(rk_fb, blob);
							panel_info.lcdc_id = rk_fb->lcdc_id;
							rk_fb_pwr_ctr_parse_dt(rk_fb, blob);
							debug("lcd timing:\n"
							      "screen_type:%d\n"
							      "lcd_face=0x%x\n"
							      "vl_col=%d\n"
							      "vl_row=%d\n"
							      "vl_freq = %d\n"
							      "lvds_format=%d\n"
							      "lcdc_id=%d\n",
							      panel_info.screen_type,
							      panel_info.lcd_face,
							      panel_info.vl_col,
							      panel_info.vl_row,
							      panel_info.vl_freq,
							      panel_info.lvds_format,
							      panel_info.lcdc_id);
							*/
							
					//设置lcdc的时钟pll_src = 0, dclk_hz = 68000000, dclk_div = 6		(panel_info.lcdc_id:0代表lcdc0,1代表lcdc1,前面设置的是主显示器lcdc0)
					panel_info.real_freq = rkclk_lcdc_clk_set(panel_info.lcdc_id,panel_info.vl_freq);
					rk_lcdc_init(panel_info.lcdc_id);	//	初始化lcdc0 panel_info.lcdc_id:0
				
					rk_lcdc_load_screen(&panel_info);	
													
						
		*/
	
	
	
struct lcdc_device {
	int node;
	int id;
	int soc_type;
	int dft_win; 				/*default win for display*/
	int regsbak[REG_LEN];
	int regs;				/*1:standby,0:wrok*/
	struct rk_screen *screen;
};
		
int rk_lcdc_init(int lcdc_id)
{
	struct lcdc_device *lcdc_dev = &rk32_lcdc;
	u32 msk, val;

	lcdc_dev->soc_type = gd->arch.chiptype;
	lcdc_dev->id = lcdc_id;



	rk32_lcdc_parse_dt(lcdc_dev, gd->fdt_blob);
			/*
			设置lcdc_dev->reg = 0xff930000,	lcdc_dev->dft_win =order % 10;
			*/


	grf_writel(1<<16, GRF_IO_VSEL); /*LCDCIOdomain 3.3 Vvoltageselectio*/

	msk = m_AUTO_GATING_EN | m_STANDBY_EN | m_DMA_STOP | m_MMU_EN;
	val =  v_AUTO_GATING_EN(1) | v_STANDBY_EN(0) |	v_DMA_STOP(0) | v_MMU_EN(0);
	lcdc_msk_reg(lcdc_dev, SYS_CTRL, msk, val);
	msk = m_DSP_LAYER3_SEL | m_DSP_LAYER2_SEL|	m_DSP_LAYER1_SEL | m_DSP_LAYER0_SEL;
	val = v_DSP_LAYER3_SEL(3) | v_DSP_LAYER2_SEL(2) |	v_DSP_LAYER1_SEL(1) | v_DSP_LAYER0_SEL(0);
	lcdc_msk_reg(lcdc_dev, DSP_CTRL1, msk, val);
	lcdc_cfg_done(lcdc_dev);

	return 0;
}
	
/* Screen description 
*type:LVDS,RGB,MIPI,MCU
*lvds_fromat:lvds data format,set it if the screen is lvds
*face:thi display output face,18bit,24bit,etc
*ft: the time need to display one frame time
*/
struct rk_screen {
	u16 type;
	u16 lvds_format; 
	u16 face;
	u16 color_mode;
	u8 lcdc_id;   
	u8 screen_id; 
	struct fb_videomode mode;
	u32 post_dsp_stx;
	u32 post_dsp_sty;
	u32 post_xsize;
	u32 post_ysize;
	u16 x_mirror;
	u16 y_mirror;
	int interlace;
	int pixelrepeat; //For 480i/576i format, pixel is repeated twice.
	u16 width;
	u16 height;
	u8  ft;
	int *dsp_lut;
	int *cabc_lut;

	u8 hdmi_resolution;
	u8 mcu_wrperiod;
	u8 mcu_usefmk;
	u8 mcu_frmrate;

	u8 pin_hsync;
	u8 pin_vsync;
	u8 pin_den;
	u8 pin_dclk;

	/* Swap rule */
	u8 swap_gb;
	u8 swap_rg;
	u8 swap_rb;
	u8 swap_delta;
	u8 swap_dumy;
	


	int xpos;  //horizontal display start position on the sceen ,then can be changed by application
	int ypos;
	int xsize; //horizontal and vertical display size on he screen,they can be changed by application
	int ysize;
	struct rk_screen *ext_screen;
	struct overscan overscan;
	/* Operation function*/
	int (*init)(void);
	int (*standby)(u8 enable);
	int (*refresh)(u8 arg);
	int (*scandir)(u16 dir);
	int (*disparea)(u8 area);
	int (*sscreen_get)(struct rk_screen *screen, u8 resolution);
	int (*sscreen_set)(struct rk_screen *screen, bool type);
};
		

	
			


int rk_lcdc_load_screen(vidinfo_t *vid)
{
	struct lcdc_device *lcdc_dev = &rk32_lcdc;
	struct rk_screen *screen =  lcdc_dev->screen;
	int face = 0;
	u32 msk, val;
	
	//用前面设置的panel_info给rk_screen赋值
	rk_fb_vidinfo_to_screen(vid, screen); 
  if (vid->screen_type == SCREEN_RGB ||
		   vid->screen_type == SCREEN_LVDS ||
		   vid->screen_type == SCREEN_DUAL_LVDS) {
		msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
			m_HDMI_OUT_EN | m_RGB_OUT_EN;
		val = v_RGB_OUT_EN(1);
	}
	lcdc_msk_reg(lcdc_dev, SYS_CTRL, msk, val);

	msk = m_DSP_BLACK_EN | m_DSP_BLANK_EN | m_DSP_OUT_ZERO |
		m_DSP_DCLK_POL | m_DSP_DEN_POL | m_DSP_VSYNC_POL |
		m_DSP_HSYNC_POL;
	val = v_DSP_BLACK_EN(0) | v_DSP_BLANK_EN(0) | v_DSP_OUT_ZERO(0) |
		v_DSP_DCLK_POL(vid->vl_clkp) | v_DSP_DEN_POL(vid->vl_oep) |
		v_DSP_VSYNC_POL(vid->vl_vsp) | v_DSP_HSYNC_POL(vid->vl_hsp);
	lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val);
	
	
	switch (vid->lcd_face) {
	...
	...
	case OUT_D888_P666:
		face = OUT_P888;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
			m_DITHER_DOWN_SEL;
		val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
			v_DITHER_DOWN_SEL(1);
		break;
	}
	
	lcdc_msk_reg(lcdc_dev, DSP_CTRL1, msk, val);

	msk = m_DSP_RG_SWAP | m_DSP_RB_SWAP | m_DSP_DELTA_SWAP |
		m_DSP_FIELD_POL | m_DSP_DUMMY_SWAP | m_DSP_BG_SWAP |
		m_DSP_OUT_MODE;
	val = v_DSP_RG_SWAP(0) | v_DSP_RB_SWAP(vid->vl_swap_rb) |
		v_DSP_DELTA_SWAP(0) | v_DSP_DUMMY_SWAP(0) |
		v_DSP_FIELD_POL(0) | v_DSP_BG_SWAP(0) |
		v_DSP_OUT_MODE(face);
	lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val);
	lcdc_writel(lcdc_dev, DSP_BG, 0);
	val = v_DSP_HS_PW(vid->vl_hspw) | v_DSP_HTOTAL(vid->vl_hspw +
		vid->vl_hbpd + vid->vl_col + vid->vl_hfpd);
	lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
	val = v_DSP_HACT_END(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) |
		v_DSP_HACT_ST(vid->vl_hspw + vid->vl_hbpd);
	lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
	val = v_DSP_VTOTAL(vid->vl_vspw + vid->vl_vbpd +
		vid->vl_row + vid->vl_vfpd) | v_DSP_VS_PW(vid->vl_vspw);
	lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
	val = v_DSP_VACT_END(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)|
		v_DSP_VACT_ST(vid->vl_vspw + vid->vl_vbpd);
	lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
	val = v_DSP_HACT_END_POST(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) |
		v_DSP_HACT_ST_POST(vid->vl_hspw + vid->vl_hbpd);
	lcdc_writel(lcdc_dev, POST_DSP_HACT_INFO, val);
	val = v_DSP_HACT_END_POST(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)|
	      v_DSP_HACT_ST_POST(vid->vl_vspw + vid->vl_vbpd);
	lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO, val);
	lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO_F1, 0);
	lcdc_writel(lcdc_dev, POST_RESERVED, 0x10001000);
	lcdc_writel(lcdc_dev, MCU_CTRL, 0);

	msk = m_DSP_LINE_FLAG_NUM | m_LINE_FLAG_INTR_EN;
	val = v_DSP_LINE_FLAG_NUM(vid->vl_vspw + vid->vl_vbpd + vid->vl_row) |
	      v_LINE_FLAG_INTR_EN(0);
	lcdc_msk_reg(lcdc_dev, INTR_CTRL0, msk, val);
	lcdc_cfg_done(lcdc_dev);
	
	if ((vid->screen_type == SCREEN_LVDS) ||
	    (vid->screen_type == SCREEN_DUAL_LVDS) ||
	    (vid->screen_type == SCREEN_RGB)) {
		rk32_lvds_en(vid);
	}

	return 0;
}
		
		
/* Enable LCD and DIGITAL OUT in DSS */
void rk_lcdc_standby(int enable)
{
	struct lcdc_device *lcdc_dev = &rk32_lcdc;

	lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
		     v_STANDBY_EN(enable ? 1 : 0));
		     
			/*
			#define v_STANDBY_EN(x)      		(((x)&1)<<22)
			*/	     
	lcdc_cfg_done(lcdc_dev);
}	
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值