1. 程式人生 > >rk3399 u-boot修改開機logo

rk3399 u-boot修改開機logo

首先分析了一下uboot啟動流程中的一部分程式碼,如下

第一部分:開機logo

1.

board_late_init							//rk33xx.c
	board/rockchip/rk33xx/rk33xx.c:238:	board_fbt_preboot();
		board_late_init						
			board_fbt_preboot();			//fastboot.c
			1.	if (gd->fdt_blob) {
						int node = fdt_path_offset(gd->fdt_blob, "/display-subsystem");//找到display-subsystem這個noded,在rk3399-android.dtsi中指定為有效。
						if (!fdt_device_is_available(gd->fdt_blob, node) || node < 0) {
				#if defined(CONFIG_LCD)
							g_is_new_display = 0;
							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();//drv_lcd_init
							}
				#else

 drv_lcd_init:

drv_lcd_init();//drv_lcd_init				//lcd.c
					lcd_init(lcd_base);		  //lcd.c
						lcd_ctrl_init(lcdbase);//rockchip_fb.c
							rk_lcdc_init(panel_info.lcdc_id);

							rk_lcdc_load_screen(&panel_info);
								........
								vop_config_timing(vop_dev, screen);//vop
									h_total = hsync_len + left_margin + x_res + right_margin;
									v_total = vsync_len + upper_margin + y_res + lower_margin;

									val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
									vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);

									val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
										V_DSP_HACT_ST(hsync_len + left_margin);
									vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
									if (screen->mode.vmode & FB_VMODE_INTERLACED) {
										/* First Field Timing */
										val = V_DSP_VS_END(vsync_len) |
											V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
													  lower_margin) + y_res + 1);
										vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);

										val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
											V_DSP_VACT_ST(vsync_len + upper_margin);
										vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
										/* Second Field Timing */
										vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
										vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
											lower_margin;
										val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
										vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
										
										vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
											lower_margin + 1;
										vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
											lower_margin + 1;
										val = V_DSP_VACT_END_F1(vact_end_f1) |
											V_DSP_VACT_ST_F1(vact_st_f1);
										vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
										vop_msk_reg(vop_dev, DSP_CTRL0,
												V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0));
										val = V_DSP_LINE_FLAG_NUM_0(lower_margin ?
														vact_end_f1 : vact_end_f1 - 1);
										val |= V_DSP_LINE_FLAG_NUM_1(lower_margin ?
														 vact_end_f1 : vact_end_f1 - 1);
										vop_msk_reg(vop_dev, LINE_FLAG, val);
									}else
										...........
									vop_vop_post_cfg(vop_dev, screen);
										.........
										post_dsp_vact_st = screen->post_dsp_sty / 2 +
													screen->mode.vsync_len +
													screen->mode.upper_margin;
										post_dsp_vact_end = post_dsp_vact_st +
													screen->post_ysize / 2;
										.........
										val = V_DSP_HACT_END_POST(post_dsp_hact_end) |
											V_DSP_HACT_ST_POST(post_dsp_hact_st);
										vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val);

										val = V_DSP_VACT_END_POST(post_dsp_vact_end) |
											V_DSP_VACT_ST_POST(post_dsp_vact_st);
								........
						lcd_clear();
						lcd_enable();

2.

2.	rockchip_display_init()
					fdt_path_offset(blob, "/display-subsystem/route"); //尋找route node.
					fdt_device_is_available //檢視route是否是okay的
					init_display_buffer //獲取fb地址
					fdt_for_each_subnode //依次解析route下的子節點,當前用的edp,所以只解析route_edp節點。
					fdt_node_offset_by_phandle //獲取connect node.
					find_crtc_node//獲取對應的ctrl node.
					rockchip_get_crtc  //根據ctrl node從g_crtc陣列中找到具體的元素,這裡compatible是"rockchip,rk3399-vop-big",在rk3399.dtsi中定義
					find_connector_node //獲取對應的connector node
					rockchip_get_connector //根據connector node從g_connector陣列中找到具體的元素,這裡compatible是"rockchip,rk3399-edp",在rk3399.dtsi中定義
					malloc(sizeof(*s)); //display相關資訊都放在struct display_state *s中
					fdt_get_string(blob, child, "logo,uboot", &s->ulogo_name);    //分別獲取uboot/kernel中的logo name以及模式
					  fdt_get_string(blob, child, "logo,kernel", &s->klogo_name);
					  fdt_get_string(blob, child, "logo,mode", &name);
					  connector_phy_init //無phy node,3368平臺需要配置。
					connector_panel_init ->
					get_panel_node //獲取edp panel node
					rockchip_get_panel //根據panel node從g_panel陣列中找到具體型號panel,因此要新增一塊新panel,那麼對應timing資訊需要新增到此陣列中
					connector_pclist_parse_dt //解析電源控制節點power_ctr,即lcd的enable以及reset gpio.
					rockchip_panel_init ->
					  panel->funcs->init ->
						panel_simple_init ->
						  panel_simple_parse_dt ->  //此函式引數解析針對mipi屏
							gpio_direction_output(enable_gpio->gpio, !!(enable_gpio->flags & OF_GPIO_ACTIVE_LOW)); //初始化之前先關屏
							rk_pwm_bl_config(0); //關背光

 3.

3.	rockchip_show_logo();
					list_for_each_entry(s, &rockchip_display_list, head) {
						s->logo.mode = s->logo_mode;
						if (load_bmp_logo(&s->logo, s->ulogo_name))//獲取圖片,提取bpp、width、height這些資訊
							printf("failed to display uboot logo\n");
						else
							display_logo(s);//display_logo
						if (load_bmp_logo(&s->logo, s->klogo_name))
							printf("failed to display kernel logo\n");
					}
				
				
					display_logo(s);//display_logo
						........
						display_init(state);
							display_get_timing(state);
								printf("Using display timing dts\n");
						........
						display_set_plane(state);
						display_enable(state);

4.

4.	lcd_standby(0);//使能
					if (enable == 0) {
					rk32_dsi_enable();

5.

5.	rk_pwm_bl_config(-1);//背光

6.修改:找一張bmp格式的圖片,替換kernel下的logo.bmp圖片即可 

第二部分:開機動畫(沒測試過)

       https://blog.csdn.net/liuyingyanhuo/article/details/81567150

參考文章:https://blog.csdn.net/ooonebook/article/details/53206623(uboot階段對dts的處理 fdt_xxx_xxx等函式說明)

                  https://blog.csdn.net/kris_fei/article/details/79003925