屏的启动流程

2019-04-14 20:09发布

. 屏的启动流程 取的代码为:
svn+ssh://svn@10.20.30.18/svn-repos/mtk6735m-aly/trunk/pb3.2.0
使用的屏为:
lcd: HL_5093D,
IC: ILI9806E,
size: 5.0寸,
Resolution:480*854,
亮屏修改与增加的文件为:
LK:
新建 pb3.2.0ootableootloaderlkdevlcmWZP_FW_ILI9806E WZP_FW_ILI9806E.c
主要实现
LCM_DRIVER WZP_FW_ILI9806E_drv =
{
.name = “WZP_FW_ILI9806E_drv”,
.set_util_funcs = wzp_lcm_set_util_funcs,
.get_params = wzp_lcm_get_params, //屏的相关参数
.init = wzp_lcm_init, //屏的初始化函数
.suspend = wzp_lcm_suspend, //屏的睡眠函数(在Kernel中调用)
.resume = wzp_lcm_resume, //屏的睡眠唤醒函数(在Kernel中调用)
.compare_id = wzp_lcm_compare_id, //多个屏驱动的比较函数
}; 新建 pb3.2.0ootableootloaderlkdevlcmWZP_FW_ILI9806E Makefile
新增行obj-y += WZP_FW_ILI9806E.o 修改pb3.2.0ootableootloaderlkdevlcm mt65xx_lcm_list.c (新增一行extern LCM_DRIVER WZP_FW_ILI9806E_drv; 在LCM_DRIVER* lcm_driver_list[] 中新增 #if defined(WZP_FW_ILI9806E)
&WZP_FW_ILI9806E_drv,
#endif 修改 pb3.2.0ootableootloaderlkproject ali6735_35gt_a_l1.mk (在文件中这一行增加CUSTOM_LK_LCM=“WZP_FW_ILI9806E jd9161ba_fwvga_vdo hx8389b_qhd_dsi_vdo otm8018b_dsi_vdo”) Kernel:
新建pb3.2.0kernel-3.10driversmiscmediateklcmWZP_FW_ILI9806EWZP_FW_ILI9806E.c
新建pb3.2.0kernel-3.10driversmiscmediateklcmWZP_FW_ILI9806E Makefile
修改pb3.2.0kernel-3.10driversmiscmediateklcmmt65xx_lcm_list.c
修改pb3.2.0kernel-3.10archarmconfigsali6735_35gt_a_l1_debug_defconfig
(在文件中这一行增加CONFIG_CUSTOM_KERNEL_LCM=“WZP_FW_ILI9806E lcm_common jd9161ba_fwvga_vdo hx8389b_qhd_dsi_vdo otm8018b_dsi_vdo”) 在LK中初始化,并显示手机第一屏:
Lk指(pb3.2.0/bootable/bootloader/lk),lk启动代码从main.c开始
Main.c (lk/kernel/main.c)
static int bootstrap2(void *arg)
{

platform_init(); //跳转到Platform.c
} Platform.c (lk/platform/mt6735/platform.c) void platform_init(void) //这个函数完成部分硬件的初始化,如震动马达、nand、背光、屏 { … g_fb_size = mt_disp_get_vram_size();//屏的初始化从这里开始,跳到
Mt_disp_drv.c
// g_fb_base为内存的地址,作为屏的显存frame buffer,
} Mt_disp_drv.c (lk/platform/mt6735/Mt_disp_drv.c) UINT32 mt_disp_get_vram_size(void) {
return DISP_GetVRamSize();//跳转到primary_display.c
} Primary_display.c (lk/platform/mt6735/Primary_display.c)
unsigned int DISP_GetVRamSize(void)
{
static UINT32 vramSize = 0;
if (0 == vramSize)
{
vramSize = DISP_GetFBRamSize();//跳转

}
跳转到这个函数:
UINT32 DISP_GetFBRamSize(void)
{
return ALIGN_TO(DISP_GetScreenWidth(), MTK_FB_ALIGNMENT) * DISP_GetScreenHeight() * ((DISP_GetScreenBpp() + 7) >> 3) * DISP_GetPages();
}
跳转到这个函数:
UINT32 DISP_GetScreenWidth(void)
{
return primary_display_get_width();
}
跳转到这个函数:
int primary_display_get_width(void)
{
if(pgc->plcm == NULL)
{
pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);
DISPMSG(“lcm handle is null, after probe:0x%08x ”,pgc->plcm);
if(pgc->plcm == NULL)//跳转到Disp_lcm.c
return 0;
}

} Disp_lcm.c (lk/platform/mt6735/Disp_lcm.c)
disp_lcm_handle* disp_lcm_probe(char* plcm_name, LCM_INTERFACE_ID lcm_id)
{ //寻找匹配的屏的驱动

if(_lcm_count() == 0) //确定mt65xx_lcm_list.c中定义的屏驱动的个数
{
DISPERR(“no lcm driver defined in linux kernel driver ”);
return NULL;
}
else
{
// in lk, plcm_name should always be NULL
if(plcm_name == NULL) //LK默认没有name,Kernel中为mtkfb
{
int i = 0;
disp_path_handle handle = NULL;
disp_lcm_handle hlcm;
disp_lcm_handle *plcm = &hlcm;
LCM_PARAMS hlcm_param; for(i=0;i<_lcm_count();i++) //遍历mt65xx_lcm_list.c中的屏驱动,寻找匹配的 { memset((void*)&hlcm, 0, sizeof(disp_lcm_handle)); memset((void*)&hlcm_param, 0, sizeof(LCM_PARAMS)); lcm_drv= lcm_driver_list[i]; //调用WZP_FW_ILI9806E.c或其它 的用户定义的驱动函数
lcm_drv->get_params(&hlcm_param);
plcm->drv = lcm_drv;
plcm->params = &hlcm_param;
plcm->lcm_if_id = plcm->params->lcm_if;
DISPMSG(“we will check lcm: %s ”, lcm_drv->name);
if(lcm_id == LCM_INTERFACE_NOTDEFINED ||(lcm_id != LCM_INTERFACE_NOTDEFINED && plcm->lcm_if_id == lcm_id))
{
handle = _display_interface_path_init(plcm);//获取到驱动后,执行
屏的初始化
if(handle == NULL)
{
DISPERR("_display_interface_path_init returns NULL ");
goto FAIL;
} if(lcm_drv->init_power) { lcm_drv->init_power(); } if(lcm_drv->compare_id != NULL) { if(lcm_drv->compare_id() != 0)//多驱动时,比较ID匹配屏驱动 { isLCMFound = true;//如果ID匹配,则找到驱动,退出循环 _display_interface_path_deinit(handle); break; } } _display_interface_path_deinit(handle);//如果没找到匹配的驱动,则消 除屏相关初始化,再次开始循环遍历
}
} if(isLCMFound == false)//如果遍历完毕没匹配到合适的,默认使用第一个 { DISPERR("we have checked all lcm driver, but no lcm found "); lcm_drv = lcm_driver_list[0]; isLCMFound = true; } } else { int i = 0; for(i=0;i<_lcm_count();i++) { lcm_drv = lcm_driver_list[i]; if(!strcmp(lcm_drv->name, plcm_name)) { isLCMFound = true; break; } } } } } 至此,LK中屏初始化完成,可以正常显示画面,
Platform.c (lk/platform/mt6735/platform.c)
void platform_init(void)
{

mt_disp_init((void *)g_fb_base);//初始化完成后继续往下执行
mt_disp_fill_rect(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT, 0x0);//显示黑 {MOD}画面
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); //刷新屏显示画面

} 在LK启动完成后,将初始化相关参数保存入command_line中,供Kernel中调用。