从target_display_init开始
void target_display_init(const char *panel_name)
{
struct oem_panel_data oem;
int32_t ret = 0;
uint32_t panel_loop = 0;
set_panel_cmd_string(panel_name);
oem = mdss_dsi_get_oem_data();
if (!strcmp(oem.panel, NO_PANEL_CONFIG)
|| !strcmp(oem.panel, SIM_VIDEO_PANEL)
|| !strcmp(oem.panel, SIM_DUALDSI_VIDEO_PANEL)
|| !strcmp(oem.panel, SIM_CMD_PANEL)
|| !strcmp(oem.panel, SIM_DUALDSI_CMD_PANEL)
|| oem.skip) {
dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
oem.panel);
oem.cont_splash = false;
}
/* skip splash screen completely not just cont splash */
if (!strcmp(oem.panel, DISABLE_PANEL_CONFIG)) {
dprintf(INFO, "%s: disable splash screen \n",
__func__);
return;
}
do {
target_force_cont_splash_disable(false);
ret = gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR);
if (!ret || ret == ERR_NOT_SUPPORTED) {
break;
} else {
target_force_cont_splash_disable(true);
msm_display_off();
}
} while (++panel_loop <= oem_panel_max_auto_detect_panels());
if (!oem.cont_splash) {
dprintf(INFO, "Forcing continuous splash disable\n");
target_force_cont_splash_disable(true);
}
}
int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
{
int ret = NO_ERROR;
int pan_type;
dsi_video_mode_phy_db.pll_type = DSI_PLL_TYPE_28NM;
panel.panel_info.disable_wled_labibb = false;
pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), --------------1
&dsi_video_mode_phy_db); // oem_panel_select()函数去选择要使用那一款LCD屏,并根据对应屏的panel-xxx.h中的各个结构体填充至panelstruct,panel.panel_info 和 dsi_video_mode_phy_db 中,并返回panel_type为 PANEL_TYPE_DSI
if (pan_type == PANEL_TYPE_DSI) {
if (update_dsi_display_config())
goto error_gcdb_display_init;
target_dsi_phy_config(&dsi_video_mode_phy_db); // 继续填充 dsi_video_mode_phy_db中的strength,regulator 和 laneCfg
mdss_dsi_check_swap_status(); // 交换目标面板,使用适合的时钟,如果panel_dest为DISPLAY_1,则更改为DISPLAY_2(dsi_controller = "dsi:1:"),如果不为DISPLAY_1,则更改为 DISPLAY_1(dsi_controller = "dsi:0:")
mdss_dsi_set_pll_src(); // 设置时钟
if (dsi_panel_init(&(panel.panel_info), &panelstruct)) { // 将panel_struc中和其他函数指针赋予panel.panel_info
dprintf(CRITICAL, "DSI panel init failed!\n");
ret = ERROR;
goto error_gcdb_display_init;
}
panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db; // 将填充好的dsi_video_mode_phy_db赋予panel
panel.pll_clk_func = mdss_dsi_panel_clock;
panel.dfps_func = mdss_dsi_mipi_dfps_config;
panel.power_func = mdss_dsi_panel_power; // 赋值屏的电源函数 ----------2
panel.pre_init_func = mdss_dsi_panel_pre_init;
panel.bl_func = mdss_dsi_bl_enable; // 使能屏的背光函数---------------------3
panel.dsi2HDMI_config = mdss_dsi2HDMI_config;
/*
* Reserve fb memory to store pll codes and pass
* pll codes values to kernel.
*/
panel.panel_info.dfps.dfps_fb_base = base;
base += DFPS_PLL_CODES_SIZE;
panel.fb.base = base;
dprintf(SPEW, "dfps base=0x%p,d, fb_base=0x%p!\n",
panel.panel_info.dfps.dfps_fb_base, base);
panel.fb.width = panel.panel_info.xres;
panel.fb.height = panel.panel_info.yres;
panel.fb.stride = panel.panel_info.xres;
panel.fb.bpp = panel.panel_info.bpp;
panel.fb.format = panel.panel_info.mipi.dst_format;
} else if (pan_type == PANEL_TYPE_EDP) {
mdss_edp_panel_init(&(panel.panel_info));
/* prepare func is set up at edp_panel_init */
panel.clk_func = mdss_edp_panel_clock;
panel.power_func = mdss_edp_panel_power;
panel.bl_func = mdss_edp_bl_enable;
panel.fb.format = FB_FORMAT_RGB888;
} else if (pan_type == PANEL_TYPE_SPI) {
panel.panel_info.xres = panelstruct.panelres->panel_width;
panel.panel_info.yres = panelstruct.panelres->panel_height;
panel.panel_info.bpp = panelstruct.color->color_format;
panel.power_func = mdss_spi_panel_power;
panel.bl_func = mdss_spi_bl_enable;
panel.fb.base = base;
panel.fb.width = panel.panel_info.xres;
panel.fb.height = panel.panel_info.yres;
panel.fb.bpp = panel.panel_info.bpp;
panel.fb.format = FB_FORMAT_RGB565;
panel.panel_info.type = SPI_