高通平台lk下调屏小结

    在lk下调试屏幕,可先了解下lk的代码流程,方便接下来的调试。这里以msm8996平台为例,描述lk的代码结构。

bootable/bootloader/lk/kernel/maic.c

/* called from crt0.S */
void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE;
void kmain(void)
{
	// get us into some sort of thread context
	thread_init_early();

	// early arch stuff
	arch_early_init();

	// do any super early platform initialization
	platform_early_init();

	// do any super early target initialization
	target_early_init();

	dprintf(INFO, "welcome to lk\n\n");
	bs_set_timestamp(BS_BL_START);

	// deal with any static constructors
	dprintf(SPEW, "calling constructors\n");
	call_constructors();

	// bring up the kernel heap
	dprintf(SPEW, "initializing heap\n");
	heap_init();

	__stack_chk_guard_setup();

	// initialize the threading system
	dprintf(SPEW, "initializing threads\n");
	thread_init();

	// initialize the dpc system
	dprintf(SPEW, "initializing dpc\n");
	dpc_init();

	// initialize kernel timers
	dprintf(SPEW, "initializing timers\n");
	timer_init();

#if (!ENABLE_NANDWRITE)
	// create a thread to complete system initialization
	dprintf(SPEW, "creating bootstrap completion thread\n");
	thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));

	// enable interrupts
	exit_critical_section();

	// become the idle thread
	thread_become_idle();
#else
        bootstrap_nandwrite();
#endif
}

bootstrap2

static int bootstrap2(void *arg)
{
	dprintf(SPEW, "top of bootstrap2()\n");

	arch_init();

	// XXX put this somewhere else
#if WITH_LIB_BIO
	bio_init();
#endif
#if WITH_LIB_FS
	fs_init();
#endif

	// initialize the rest of the platform
	dprintf(SPEW, "initializing platform\n");
	platform_init();

	// initialize the target
	dprintf(SPEW, "initializing target\n");
	target_init();

	dprintf(SPEW, "calling apps_init()\n");
	apps_init();

	return 0;
}

apps_init中调用了bootable/bootloader/lk/app/aboot/aboot.c

void aboot_init(const struct app_descriptor *app)
{
	unsigned reboot_mode = 0;

	/* Setup page size information for nv storage */
	if (target_is_emmc_boot())
	{
		page_size = mmc_page_size();
		page_mask = page_size - 1;
	}
	else
	{
		page_size = flash_page_size();
		page_mask = page_size - 1;
	}

	ASSERT((MEMBASE + MEMSIZE) > MEMBASE);

	read_device_info(&device);
	read_allow_oem_unlock(&device);

	/* Display splash screen if enabled */
#if DISPLAY_SPLASH_SCREEN
#if NO_ALARM_DISPLAY
	if (!check_alarm_boot()) {
#endif
		dprintf(SPEW, "Display Init: Start\n");
#if DISPLAY_HDMI_PRIMARY
	if (!strlen(device.display_panel))
		strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
			sizeof(device.display_panel));
#endif
#if ENABLE_WBC
		/* Wait if the display shutdown is in progress */
		while(pm_app_display_shutdown_in_prgs());
		if (!pm_appsbl_display_init_done())
			target_display_init(device.display_panel);
		else
			display_image_on_screen();
#else
		target_display_init(device.display_panel);
#endif
		dprintf(SPEW, "Display Init: Done\n");
#if NO_ALARM_DISPLAY
	}
#endif
#endif

	target_serialno((unsigned char *) sn_buf);
	dprintf(SPEW,"serial number: %s\n",sn_buf);

	memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);

	/*
	 * Check power off reason if user force reset,
	 * if yes phone will do normal boot.
	 */
	if (is_user_force_reset())
		goto normal_boot;

	/* Check if we should do something other than booting up */
	if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
	{
		dprintf(ALWAYS,"dload mode key sequence detected\n");
		if (set_download_mode(EMERGENCY_DLOAD))
		{
			dprintf(CRITICAL,"dload mode not supported by target\n");
		}
		else
		{
			reboot_device(DLOAD);
			dprintf(CRITICAL,"Failed to reboot into dload mode\n");
		}
		boot_into_fastboot = true;
	}
	if (!boot_into_fastboot)
	{
		if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
			boot_into_recovery = 1;
		if (!boot_into_recovery &&
			(keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
			boot_into_fastboot = true;
	}
	#if NO_KEYPAD_DRIVER
	if (fastboot_trigger())
		boot_into_fastboot = true;
	#endif

#if USE_PON_REBOOT_REG
	reboot_mode = check_hard_reboot_mode();
#else
	reboot_mode = check_reboot_mode();
#endif
	if (reboot_mode == RECOVERY_MODE)
	{
		boot_into_recovery = 1;
	}
	else if(reboot_mode == FASTBOOT_MODE)
	{
		boot_into_fastboot = true;
	}
	else if(reboot_mode == ALARM_BOOT)
	{
		boot_reason_alarm = true;
	}
#if VERIFIED_BOOT
#if !VBOOT_MOTA
	else if (reboot_mode == DM_VERITY_ENFORCING)
	{
		device.verity_mode = 1;
		write_device_info(&device);
	}
	else if (reboot_mode == DM_VERITY_LOGGING)
	{
		device.verity_mode = 0;
		write_device_info(&device);
	}
	else if (reboot_mode == DM_VERITY_KEYSCLEAR)
	{
		if(send_delete_keys_to_tz())
			ASSERT(0);
	}
#endif
#endif

normal_boot:
	if (!boot_into_fastboot)
	{
		if (target_is_emmc_boot())
		{
			if(emmc_recovery_init())
				dprintf(ALWAYS,"error in emmc_recovery_init\n");
			if(target_use_signed_kernel())
			{
				if((device.is_unlocked) || (device.is_tampered))
				{
				#ifdef TZ_TAMPER_FUSE
					set_tamper_fuse_cmd();
				#endif
				#if USE_PCOM_SECBOOT
					set_tamper_flag(device.is_tampered);
				#endif
				}
			}

			boot_linux_from_mmc();
		}
		else
		{
			recovery_init();
	#if USE_PCOM_SECBOOT
		if((device.is_unlocked) || (device.is_tampered))
			set_tamper_flag(device.is_tampered);
	#endif
			boot_linux_from_flash();
		}
		dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
			"to fastboot mode.\n");
	}

	/* We are here means regular boot did not happen. Start fastboot. */

	/* register aboot specific fastboot commands */
	aboot_fastboot_register_commands();

	/* dump partition table for debug info */
	partition_dump();

	/* initialize and start fastboot */
	fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
#if FBCON_DISPLAY_MSG
	display_fastboot_menu_thread();
#endif
}
重点关注下target_display_init(device.display_panel),这里进行屏幕的初始化。

bootable/bootloader/lk/target/msm8996/target_display.c

void target_display_init(const char *panel_name)
{
	struct oem_panel_data oem;

	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);
		return;
	} else if ((!strcmp(oem.panel, HDMI_PANEL_NAME)) || \
		((!strlen(oem.panel)) && ((board_hardware_id() == HW_PLATFORM_SBC) ||
		(platform_is_apq8096_mediabox())))) {
		dprintf(INFO, "%s: HDMI is primary\n", __func__);
		mdss_hdmi_display_init(MDP_REV_50, (void *) HDMI_FB_ADDR);
		return;
	}

	if (gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR)) {
		target_force_cont_splash_disable(true);
		msm_display_off();
	}

	if (!oem.cont_splash) {
		dprintf(INFO, "Forcing continuous splash disable\n");
		target_force_cont_splash_disable(true);
	}
}
gcdb_display_init调用pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), &dsi_video_mode_phy_db),选择具体的屏幕

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;
		/*
		 * 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;
	} 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;
}
bootable/bootloader/lk/target/msm8996/oem_panel.c,找不到面板会根据平台有一个默认的屏幕配置。
int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
			struct msm_panel_info *pinfo,
			struct mdss_dsi_phy_ctrl *phy_db)
{
	uint32_t hw_id = board_hardware_id();
	int32_t panel_override_id;
	uint32_t ret = 0;

	phy_db->pll_type = DSI_PLL_TYPE_THULIUM;
	pinfo->has_bridge_chip = false;

	if (panel_name) {
		panel_override_id = panel_name_to_id(supp_panels,
				ARRAY_SIZE(supp_panels), panel_name);

		if (panel_override_id < 0) {
			dprintf(CRITICAL, "Not able to search the panel:%s\n",
					 panel_name);
		} else if (panel_override_id < UNKNOWN_PANEL) {
			/* panel override using fastboot oem command */
			panel_id = panel_override_id;

			dprintf(INFO, "OEM panel override:%s\n",
					panel_name);
			goto panel_init;
		}
	}

	switch (hw_id) {
	case HW_PLATFORM_MTP:
		panel_id = NT35596_1080P_VIDEO_PANEL;
       		break;
	case HW_PLATFORM_FLUID:
	case HW_PLATFORM_SURF:
		panel_id = SHARP_WQXGA_DUALDSI_VIDEO_PANEL;
		break;
	case HW_PLATFORM_QRD:
		panel_id = R69007_WQXGA_CMD_PANEL;
		break;
	case HW_PLATFORM_LIQUID:
		panel_id = JDI_4K_DUALDSI_VIDEO_NOFBC_PANEL;
		break;
	case HW_PLATFORM_DRAGON:
		panel_id = TRULY_FWVGA_VIDEO_PANEL;
		break;
	case HW_PLATFORM_ADP:
		panel_id = ADV7533_720P_VIDEO_PANEL;
		pinfo->has_bridge_chip = true;
		break;
	default:
		dprintf(CRITICAL, "Display not enabled for %d HW type\n"
					, hw_id);
		return PANEL_TYPE_UNKNOWN;
	}

panel_init:
	if (pinfo->has_bridge_chip) {        //i2c通信部分,如果该屏幕需要进行i2c初始化
		ret = oem_panel_bridge_chip_init(pinfo);
		if (ret) {
			dprintf(CRITICAL, "Error in initializing bridge chip\n");
			return ret;
		}
	}
	return init_panel_data(panelstruct, pinfo, phy_db);
}

        这里可以修改高通原有的屏幕参数,也可以自己新建一款屏幕。在bootable/bootloader/lk/dev/gcdb/display/include

有具体的屏幕参数。

           我们只需适配自己的屏幕,基本上就可以在lk下正常显示了(屏幕的参数最好仔细确认,因为平台的差异会导致屏幕的参数有细微的变化)。







  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值