本文共 6819 字,大约阅读时间需要 22 分钟。
platform: mtk8937
以下为开机后调用关系:
根据不同的平台,这个函数所在的文件不同; 我们项目属于msm8952系列;
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_CMD_PANEL) || oem.skip) { dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n", oem.panel); 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; pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), &dsi_video_mode_phy_db); 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); mdss_dsi_check_swap_status(); mdss_dsi_set_pll_src(); if (dsi_panel_init(&(panel.panel_info), &panelstruct)) { 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; 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; /* * 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 { dprintf(CRITICAL, "Target panel init not found!\n"); ret = ERR_NOT_SUPPORTED; goto error_gcdb_display_init; } panel.fb.base = base; panel.mdp_rev = rev; ret = msm_display_init(&panel);error_gcdb_display_init: display_enable = ret ? 0 : 1; return ret;}再调用下面函数: // 配置lcd.
int msm_display_init(struct msm_fb_panel_data *pdata){ int ret = NO_ERROR; panel = pdata; if (!panel) { ret = ERR_INVALID_ARGS; goto msm_display_init_out; } /* Turn on panel */ if (pdata->power_func) ret = pdata->power_func(1, &(panel->panel_info)); if (ret) goto msm_display_init_out; if (pdata->dfps_func) ret = pdata->dfps_func(&(panel->panel_info)); /* Enable clock */ if (pdata->clk_func) ret = pdata->clk_func(1, &(panel->panel_info)); if (ret) goto msm_display_init_out; /* Read specifications from panel if available. * If further clocks should be enabled, they can be enabled * using pll_clk_func */ if (pdata->update_panel_info) ret = pdata->update_panel_info(); if (ret) goto msm_display_init_out; /* Enabled for auto PLL calculation or to enable * additional clocks */ if (pdata->pll_clk_func) ret = pdata->pll_clk_func(1, &(panel->panel_info)); if (ret) goto msm_display_init_out; /* pinfo prepare */ if (pdata->panel_info.prepare) { /* this is for edp which pinfo derived from edid */ ret = pdata->panel_info.prepare(); 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; } if (ret) goto msm_display_init_out; ret = msm_fb_alloc(&(panel->fb)); if (ret) goto msm_display_init_out; fbcon_setup(&(panel->fb)); display_image_on_screen(); if ((panel->dsi2HDMI_config) && (panel->panel_info.has_bridge_chip)) ret = panel->dsi2HDMI_config(&(panel->panel_info)); if (ret) goto msm_display_init_out; ret = msm_display_config(); if (ret) goto msm_display_init_out; ret = msm_display_on(); if (ret) goto msm_display_init_out; if (pdata->post_power_func) ret = pdata->post_power_func(1); if (ret) goto msm_display_init_out; /* Turn on backlight */ if (pdata->bl_func) ret = pdata->bl_func(1); if (ret) goto msm_display_init_out;msm_display_init_out: return ret;}再调用,下面函数;
void display_image_on_screen(void){#if DISPLAY_TYPE_MIPI int fetch_image_from_partition(); dprintf(INFO, "display_image_on_screen-1\n"); if (fetch_image_from_partition() < 0) { display_default_image_on_screen(); } else { /* data has been put into the right place */ fbcon_flush(); }#else display_default_image_on_screen();#endif}再调用显示logo函数:
void display_default_image_on_screen(void){ unsigned i = 0; unsigned total_x; unsigned total_y; unsigned bytes_per_bpp; unsigned image_base;#if DISPLAY_TYPE_MIPI char *image = NULL;#endif if (!config) { dprintf(CRITICAL,"NULL configuration, image cannot be displayed\n"); return; } fbcon_clear(); // clear screen with Black color total_x = config->width; total_y = config->height; bytes_per_bpp = ((config->bpp) / 8); image_base = ((((total_y/2) - (SPLASH_IMAGE_HEIGHT / 2) - 1) * (config->width)) + (total_x/2 - (SPLASH_IMAGE_WIDTH / 2)));#if DISPLAY_TYPE_MIPI#if ENABLE_WBC image = (pm_appsbl_charging_in_progress() ? image_batt888 : imageBuffer_rgb888);#else image = imageBuffer_rgb888;#endif if (bytes_per_bpp == 3) { for (i = 0; i < SPLASH_IMAGE_HEIGHT; i++) { memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp), image + (i * SPLASH_IMAGE_WIDTH * bytes_per_bpp), SPLASH_IMAGE_WIDTH * bytes_per_bpp); } } fbcon_flush();#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE if(is_cmd_mode_enabled()) mipi_dsi_cmd_mode_trigger();#endif#else if (bytes_per_bpp == 2) { for (i = 0; i < SPLASH_IMAGE_HEIGHT; i++) { memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp), imageBuffer + (i * SPLASH_IMAGE_WIDTH * bytes_per_bpp), SPLASH_IMAGE_WIDTH * bytes_per_bpp); } } fbcon_flush();#endif}在以上函数中,fbcon_clear() 是清屏。
fbcon_clear(); // clear screen with Black color
config->width; // screen total width
config->height // screen total high
image_base // 显示的screen的中心基准。
改变这个image_base 的中心基准值,可以改变图片的显示位置。
转载地址:http://osngi.baihongyu.com/