rk3399 u-boot修改開機logo
阿新 • • 發佈:2018-12-06
首先分析了一下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等函式說明)