高通平台bootloader显示logo图片的过程

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 的中心基准值,可以改变图片的显示位置。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值