前言
代码环境:
Android P
今天想记录和分享的是MTK平台LCM的兼容,当然,在学习兼容原理的时候肯定需要大概知道lcm的加载流程,于是借鉴前辈们的经验(文章最后会贴上参考的文章),浅显的去学习了一下,LCM方面深入的知识以后有机会再慢慢研究,保持一颗学习的心~
LK阶段
lcm大概加载流程
kmain() -> platform_init() -> mt_disp_init() -> primary_display_init() -> disp_lcm_probe()
1、文件路径:vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c
调用kmain()函数。
/* called from crt0.S */
void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE;
void kmain(void)
{
/*省略部分代码*/
/*创建并唤醒‘bootstrap2’线程*/
thread_t *thread_bs2 = thread_create("bootstrap2", &bootstrap2, NULL,DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
if (thread_bs2)
thread_resume(thread_bs2);
else {
dprintf(CRITICAL, "Error: Cannot create bootstrap2 thread!\n");
assert(0);
}
/*省略部分代码*/
}
static int bootstrap2(void *arg)
{
/*省略部分代码*/
// initialize the rest of the platform
dprintf(SPEW, "initializing platform\n");
platform_init(); //执行plattform_init函数
/*省略部分代码*/
}
2、文件路径:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/platform.c
调用platform_init()函数。
void platform_init(void)
{
/*省略部分代码*/
mt_disp_init((void *)g_fb_base);
/*省略部分代码*/
}
3、文件路径:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/mt_disp_drv.c
调用mt_disp_init()函数。
void mt_disp_init(void *lcdbase)
{
/*省略部分代码*/
primary_display_init(NULL);
/*省略部分代码*/
}
vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm/mt65xx_lcm_list.c
4、文件路径:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/primary_display.c
调用primary_display_init()函数。
int primary_display_init(char *lcm_name)
{
/**/
if (pgc->plcm == NULL)
pgc->plcm = disp_lcm_probe( lcm_name, LCM_INTERFACE_NOTDEFINED);
...
lcm_param = disp_lcm_get_params(pgc->plcm); //获取lcm参数
...
disp_lcm_init(pgc->plcm); //初始lcm;
4.1、文件路径:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/disp_lcm.c
调用disp_lcm_probe()函数。
// if lcm handle already probed, should return lcm handle directly
disp_lcm_handle* disp_lcm_probe(char* plcm_name, LCM_INTERFACE_ID lcm_id)
{
..........
LCM_DRIVER *lcm_drv = NULL; //LCM_DRIVER :操作函数结构体
LCM_PARAMS *lcm_param = NULL; //LCM_PARAMS lcm参数结构体
disp_lcm_handle *plcm = NULL; //该函数的返回值
if (_lcm_count() == 0) {
//该函数会返回lcm驱动的个数,后面会解析。
DISPERR("no lcm driver defined in linux kernel driver\n");
return NULL;
} else if (_lcm_count() == 1) {
//表示如果驱动个数为1,默认采用该驱动(我的理解,不知道是否正确)
lcm_drv = lcm_driver_list[0];
isLCMFound = true; //isLCMFound :表示是否找到可使用驱动的变量
}else{
//如果lcm驱动个数大于1个,那么就会循环去判断lcm_driver_list列表里面的lcm驱动和硬件是否匹配
// in lk, plcm_name should always be NULL
if (plcm_name == NULL) {
//在LK阶段,disp_lcm_probe传递进来的参数:plcm_name,永远为NULL。
int i = 0;
disp_path_handle handle = NULL; //定义disp_path_handle 结构体变量handle;
disp_lcm_handle hlcm; //定义disp_lcm_handle 结构体变量hlcm;
disp_lcm_handle *plcm = &hlcm; //将hlcm的地址赋给plcm指针;
LCM_PARAMS hlcm_param