欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

屏的启动流程

程序员文章站 2022-06-05 17:36:37
...

.

屏的启动流程

取的代码为:
svn+ssh://[email protected]/svn-repos/mtk6735m-aly/trunk/pb3.2.0
使用的屏为:
lcd: HL_5093D,
IC: ILI9806E,
size: 5.0寸,
Resolution:480*854,
亮屏修改与增加的文件为:
LK:
新建 pb3.2.0\bootable\bootloader\lk\dev\lcm\WZP_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.0\bootable\bootloader\lk\dev\lcm\WZP_FW_ILI9806E\ Makefile
新增行obj-y += WZP_FW_ILI9806E.o

修改pb3.2.0\bootable\bootloader\lk\dev\lcm\ 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.0\bootable\bootloader\lk\project\ ali6735_35gt_a_l1.mk

(在文件中这一行增加CUSTOM_LK_LCM=“WZP_FW_ILI9806E jd9161ba_fwvga_vdo hx8389b_qhd_dsi_vdo otm8018b_dsi_vdo”)

Kernel:
新建pb3.2.0\kernel-3.10\drivers\misc\mediatek\lcm\WZP_FW_ILI9806E\WZP_FW_ILI9806E.c
新建pb3.2.0\kernel-3.10\drivers\misc\mediatek\lcm\WZP_FW_ILI9806E\ Makefile
修改pb3.2.0\kernel-3.10\drivers\misc\mediatek\lcm\mt65xx_lcm_list.c
修改pb3.2.0\kernel-3.10\arch\arm\configs\ali6735_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\n”,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\n”);
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\n”, 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\n");
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\n");
			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);//显示黑色画面
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); //刷新屏显示画面

}

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

相关标签: 驱动