高通821平台LCD调试实例之LK部分流程讲解
gcdb_display_init ()主要的初始化代码如下:在该函数中有一个重要的函数就是oem_panel_select(),该函数就是根据你的hw_id确定使用哪一款LCD,hw_id这个是在高通的私有代码中传过来的。另外一个比较重要的函数是msm_display_init(&panel),这个函数将oem_panel_select中获得到的信息进行初始化动作,因此有必要首先需要分析oem_panel_select这个函数体的功能。
pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), &dsi_video_mode_phy_db); dsi_panel_init(&(panel.panel_info), &panelstruct) panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db; panel.pll_clk_func = mdss_dsi_panel_clock; panel.dfps_func = mdss_dsi_mipi_dfps_config; panel.power_func = mdss_dsi_panel_power; panel.pre_init_func = mdss_dsi_panel_pre_init; panel.bl_func = mdss_dsi_bl_enable; panel.dsi2HDMI_config = mdss_dsi2HDMI_config; /* * If dfps enabled, reserve fb memory to store pll * codes and pass pll codes values to kernel. */ if (panel.panel_info.dfps.panel_dfps.enabled) { panel.panel_info.dfps.dfps_fb_base = base; base += DFPS_PLL_CODES_SIZE; dprintf(SPEW, "dfps base=0x%p,d, fb_base=0x%p!\n", panel.panel_info.dfps.dfps_fb_base, base); } panel.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; ret = msm_display_init(&panel);
指定panel_id =TIANMA_2K_VIDEO_PANEL,这个是实际选择屏起作用的选项
switch (hw_id) { case HW_PLATFORM_MTP: case HW_PLATFORM_FLUID: case HW_PLATFORM_SURF: #if DISPLAY_AUO_SPLITDSI_VIDEO_PANEL panel_id = JDI_FHD_VIDEO_PANEL; #elif DISPLAY_SAMSUNG_FHD_VIDEO_PANEL panel_id = SAMSUNG_FHD_VIDEO_PANEL; #elif DISPLAY_TIANMA_FHD_VIDEO_PANEL panel_id = TIANMA_FHD_VIDEO_PANEL; #elif DISPLAY_TIANMA_2K_VIDEO_PANEL panel_id = TIANMA_2K_VIDEO_PANEL; #endif break;
然后会调用init_panel_data根据panel_id 来执行对应的初始化动作,初始化中获得的屏参数来源于
bootable/bootloader/lk/dev/gcdb/display/include/panel_tianma_2k_video.h,该头文件是按照panel.h为参考格式填充,具体参数由屏厂商提供。
case TIANMA_2K_VIDEO_PANEL: pan_type = PANEL_TYPE_DSI; pinfo->lcd_reg_en = 0; panelstruct->paneldata = &tianma_2k_dualdsi_video_panel_data; panelstruct->panelres = &tianma_2k_dualdsi_video_panel_res; panelstruct->color = &tianma_2k_dualdsi_video_color; panelstruct->videopanel= &tianma_2k_dualdsi_video_video_panel; panelstruct->commandpanel = &tianma_2k_dualdsi_video_command_panel; panelstruct->state = &tianma_2k_dualdsi_video_state; panelstruct->laneconfig= &tianma_2k_dualdsi_video_lane_config; panelstruct->paneltiminginfo = &tianma_2k_dualdsi_video_timing_info; panelstruct->panelresetseq = &tianma_2k_dualdsi_video_reset_seq; panelstruct->backlightinfo = &tianma_2k_dualdsi_video_backlight; pinfo->labibb = &tianma_2k_dualdsi_video_labibb; pinfo->mipi.panel_on_cmds = tianma_2k_dualdsi_video_on_command; pinfo->mipi.num_of_panel_on_cmds = TIANMA_2K_DUALDSI_VIDEO_ON_COMMAND; pinfo->mipi.panel_off_cmds = tianma_2k_dualdsi_video_off_command; pinfo->mipi.num_of_panel_off_cmds = TIANMA_2K_DUALDSI_VIDEO_OFF_COMMAND; memcpy(phy_db->timing, tianma_2k_dualdsi_thulium_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t)); pinfo->mipi.tx_eot_append = true; /* * remove DUAL_PIPE_FLAG because on this target for this panel, * it will be added based on one of the selected configurations. */ panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG; panelstruct->config = &tianma_2k_dualdsi_video_config0; if (oem_data) { switch (oem_data->cfg_num[0]) { case -1: /* default */ case 0: panelstruct->config = &tianma_2k_dualdsi_video_config0; break; case 1: panelstruct->config = &tianma_2k_dualdsi_video_config1; break; default: dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n", oem_data->cfg_num[0]); panelstruct->config = &tianma_2k_dualdsi_video_config0; } //oem_data->swap_dsi_ctrl = 1; // use swap } pinfo->lm_split[0] = panelstruct->config->lm_split[0]; pinfo->lm_split[1] = panelstruct->config->lm_split[1]; pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc; break;