• mtk lcm驱动加载流程 (转载)


    平台:mt6582 + Android 4.4

    前面就说过,在mtk代码中支持屏是可兼容的,通过调用驱动中的compare_id函数来匹配驱动和屏,这里来细看一下代码。

    1. LK部分(mediatek/platform/mt6582/lk/disp_drv.c)

    1. OOL DISP_DetectDevice(void)  
    2. {  
    3.     //LCD_STATUS ret;  
    4.     DISP_LOG("shi=>%s, %d ", __func__, __LINE__);  
    5.     lcm_drv = disp_drv_get_lcm_driver(NULL);  
    6.     if (NULL == lcm_drv)  
    7.     {  
    8.         printk("%s, disp_drv_get_lcm_driver() returns NULL ", __func__);  
    9.         return FALSE;  
    10.     }  
    11.   
    12.     disp_dump_lcm_parameters(lcm_params);  
    13.   
    14.     return TRUE;  
    15. }  

    在DISP_DetectDevice函数中调用了disp_drv_get_lcm_driver。

    1. const LCM_DRIVER *disp_drv_get_lcm_driver(const char *lcm_name)  
    2. {  
    3.     LCM_DRIVER *lcm = NULL;  
    4.     printk("[LCM Auto Detect], we have %d lcm drivers built in ", lcm_count);  
    5.     printk("[LCM Auto Detect], try to find driver for [%s] ",   
    6.             (lcm_name==NULL)?"unknown":lcm_name);  
    7.   
    8.     if(lcm_count ==1)  
    9.     {  
    10.         // we need to verify whether the lcm is connected  
    11.         // even there is only one lcm type defined  
    12.         lcm = lcm_driver_list[0];  
    13.         lcm->set_util_funcs(&lcm_utils);  
    14.         lcm->get_params(&s_lcm_params);  
    15.         u4IndexOfLCMList = 0;  
    16.   
    17.         lcm_params = &s_lcm_params;  
    18.         lcm_drv = lcm;  
    19. /* 
    20.         disp_drv_init_ctrl_if(); 
    21.         disp_drv_set_driving_current(lcm_params); 
    22.         disp_drv_init_io_pad(lcm_params); 
    23.  
    24.         if(lcm_drv->compare_id) 
    25.         { 
    26.             if(LCM_TYPE_DSI == lcm_params->type){ 
    27.                 init_dsi(FALSE); 
    28.             } 
    29.  
    30.             if(lcm_drv->compare_id() == TRUE) 
    31.             { 
    32.                 printk("[LCM Specified] compare id success "); 
    33.                 isLCMFound = TRUE; 
    34.             } 
    35.             else 
    36.             { 
    37.                 printk("[LCM Specified] compare id fail "); 
    38.                 printk("%s, lcm is not connected ", __func__); 
    39.  
    40.                 if(LCM_TYPE_DSI == lcm_params->type) 
    41.                     DSI_Deinit(); 
    42.             } 
    43.         } 
    44.         else 
    45. */  
    46.         {  
    47.             isLCMFound = TRUE;  
    48.         }  
    49.   
    50.         printk("[LCM Specified] [%s] ", (lcm->name==NULL)?"unknown":lcm->name);  
    51.   
    52.         goto done;  
    53.     }  
    54.     else  
    55.     {  
    56.         unsigned int i;  
    57.   
    58.         for(i = 0;i < lcm_count;i++)  
    59.         {  
    60.             lcm_params = &s_lcm_params;  
    61.             lcm = lcm_driver_list[i];  
    62.   
    63.             printk("[LCM Auto Detect] [%d] - [%s] ", i, (lcm->name==NULL)?"unknown":lcm->name);  
    64.   
    65.             lcm->set_util_funcs(&lcm_utils);  
    66.             memset((void*)lcm_params, 0, sizeof(LCM_PARAMS));  
    67.             lcm->get_params(lcm_params);  
    68.   
    69.             disp_drv_init_ctrl_if();  
    70.             disp_drv_set_driving_current(lcm_params);  
    71.             disp_drv_init_io_pad(lcm_params);  
    72.   
    73.             if(lcm_name != NULL)  
    74.             {  
    75.                 if(!strcmp(lcm_name,lcm->name))  
    76.                 {  
    77.                     printk(" [success] ");  
    78.                     isLCMFound = TRUE;  
    79.                                    u4IndexOfLCMList = i;  
    80.                     lcm_drv = lcm;  
    81.   
    82.                     goto done;  
    83.                 }  
    84.                 else  
    85.                 {  
    86.                     printk(" [fail] ");  
    87.                 }  
    88.             }  
    89.             else   
    90.             {  
    91.                 if(LCM_TYPE_DSI == lcm_params->type){  
    92.                     init_dsi(FALSE);  
    93.                     MASKREG32(DSI_BASE + 0x10, 0x2, 0x2);  
    94.                 }  
    95.   
    96.                 if(lcm->compare_id != NULL && lcm->compare_id())  
    97.                 {  
    98.                     printk(" [success] ");  
    99.                     isLCMFound = TRUE;  
    100.                     lcm_drv = lcm;  
    101.                                    u4IndexOfLCMList = i;  
    102.                     goto done;  
    103.                 }  
    104.                 else  
    105.                 {  
    106.                   
    107.                     lcm_drv = lcm;  
    108.                     if(LCM_TYPE_DSI == lcm_params->type){  
    109.                         DSI_Deinit();  
    110.                         DSI_PHY_clk_switch(false);  
    111.                     }  
    112.                     printk(" [fail] ");  
    113.                 }  
    114.             }  
    115.         }  
    116.     }  
    117. done:  
    118.   
    119.       
    120.     if(LCM_TYPE_DSI == lcm_params->type)  
    121.     {  
    122.         int ret = 0;  
    123.         unsigned int data_array[3];  
    124.         char buffer[4];  
    125.         init_dsi(FALSE);  
    126.         MASKREG32(DSI_BASE + 0x10, 0x2, 0x2);  
    127.   
    128.     data_array[0] = 0x00043700;  
    129.     DSI_set_cmdq(data_array, 1, 1);  
    130.   
    131.         ret = DSI_dcs_read_lcm_reg_v2(0x0A, &buffer,1);  
    132.         if(ret == 0)  
    133.         {  
    134.             isLCMConnected = 0;  
    135.             printk("lcm is not connected ");  
    136.         }  
    137.         else  
    138.         {  
    139.             isLCMConnected = 1;  
    140.             printk("lcm is connected ");  
    141.         }  
    142.           
    143.         DSI_Deinit();  
    144.     }  
    145.       
    146.     return lcm_drv;  
    147. }  

    lcm_count变量是通过mt65xx_lcm_list.c中的lcm_driver_list计算得来的,如果在ProjectConfig.mk中只配置了一个屏,那么lcm_count值就为1,否则就不会1。

    如果lcm_count值为1,那么直接获取lcm_driver_list这个数组的第一个元素并把它赋值给一个全局变量lcm_drv,调用屏相关的 set_util_funcs和get_params函数,所以如果只有一个屏驱动话,那是很简单的,也不用去匹配,直接拿来用就是了。

    如果lcm_count值不为1呢,也就是有多个屏驱动呢,那么来看看是如何匹配的。
    首先是for循环,依次遍历lcm_driver_list这个数组,如果lcm_name这个变量不为NULL,那么直接匹配lcm_name和屏驱动 中的name字段是否相同,如果匹配成功,也就找到了相应的屏驱动,但是需要注意的是在LK中,这个变量值是为空的,有 DISP_DetectDevice函数为证,所以说LK中肯定不会走这部分代码。那么是接下来的else部分,在else代码中,首先是判断屏驱动中的 compare_id是否为空,如果不空的话,还会调用compare_id函数来匹配屏和驱动,如果两者都满足,那说明找到了合适的驱动,否则继续循 环。所以匹配屏和驱动还是靠驱动中的compare_id函数来实现的。

    注意:这里会有一个问题,如果是多个屏驱动的话,当前面都没有匹配成功的话,将使用最后一个屏驱动,请看代码:

    1. lcm_drv = lcm;  
    2. if(LCM_TYPE_DSI == lcm_params->type){  
    3.     DSI_Deinit();  
    4.     DSI_PHY_clk_switch(false);  
    5. }  
    6. printk(" [fail] ");  


    2. kernel部分(mediatek/platform/mt6582/kernel/drivers/video/disp_hal.c)
    LK部分代码看完了,那么再来看kernel部分。

    1. const LCM_DRIVER *disphal_get_lcm_driver(const char *lcm_name, unsigned int *lcm_index)  
    2. {  
    3.     LCM_DRIVER *lcm = NULL;  
    4.     bool isLCMFound = false;  
    5.     printk("[LCM Auto Detect], we have %d lcm drivers built in ", lcm_count);  
    6.     printk("[LCM Auto Detect], try to find driver for [%s] ",   
    7.         (lcm_name==NULL)?"unknown":lcm_name);  
    8.   
    9.     if(lcm_count == 1)  
    10.     {  
    11.         // we need to verify whether the lcm is connected  
    12.         // even there is only one lcm type defined  
    13.         lcm = lcm_driver_list[0];  
    14.         lcm->set_util_funcs(&lcm_utils);  
    15.         *lcm_index = 0;  
    16.         printk("[LCM Specified] [%s] ", (lcm->name==NULL)?"unknown":lcm->name);  
    17.         isLCMFound = true;  
    18.         goto done;  
    19.     }  
    20.     else  
    21.     {  
    22.         int i;  
    23.         for(i = 0;i < lcm_count;i++)  
    24.         {  
    25.             lcm = lcm_driver_list[i];  
    26.             printk("[LCM Auto Detect] [%d] - [%s] ", i, (lcm->name==NULL)?"unknown":lcm->name);  
    27.             lcm->set_util_funcs(&lcm_utils);  
    28.             memset((void*)&s_lcm_params, 0, sizeof(LCM_PARAMS));  
    29.             lcm->get_params(&s_lcm_params);  
    30.   
    31.             disphal_init_ctrl_if();  
    32.             LCD_Set_DrivingCurrent(&s_lcm_params);  
    33.             LCD_Init_IO_pad(&s_lcm_params);  
    34.   
    35.             if(lcm_name != NULL)  
    36.             {  
    37.                 if(!strcmp(lcm_name,lcm->name))  
    38.                 {  
    39.                     printk(" [success] ");  
    40.                     *lcm_index = i;  
    41.                     isLCMFound = true;  
    42.                     goto done;  
    43.                 }  
    44.                 else  
    45.                 {  
    46.                     printk(" [fail] ");  
    47.                 }  
    48.             }  
    49.             else   
    50.             {  
    51.                 if(LCM_TYPE_DSI == lcm_params->type)  
    52.                 {  
    53.                     init_dsi(FALSE);  
    54.                 }  
    55.   
    56.                 if(lcm->compare_id != NULL && lcm->compare_id())  
    57.                 {  
    58.                     printk(" [success] ");  
    59.                     isLCMFound = true;  
    60.                     *lcm_index = i;  
    61.                     goto done;  
    62.                 }  
    63.                 else  
    64.                 {  
    65.                     if(LCM_TYPE_DSI == lcm_params->type)  
    66.                         DSI_Deinit();  
    67.                     printk(" [fail] ");  
    68.                 }  
    69.             }  
    70.         }  
    71.     }  
    72. done:  
    73.     if (isLCMFound)  
    74.     {  
    75.         memset((void*)&s_lcm_params, 0, sizeof(LCM_PARAMS));  
    76.         lcm->get_params(&s_lcm_params);  
    77.         return lcm;  
    78.     }  
    79.     else  
    80.         return NULL;  
    81. }  

    注意,同LK部分不同的是,LK会给kernel传递一个命令行参数,而这个参数中就有可能包括屏的驱动,例如:

    lcm=1-hx8389b_qhd_dsi_vdo

    这部分代码其实同LK的差不多,只是参数lcm_name字段就有可能不为空,即在LK中已经找到了合适的屏驱动,kernel中就不用再去匹配了。

  • 相关阅读:
    前台加请求头token,后台接收
    MD5加密工具类
    SpringBoot实现请求拦截(@Aspect切面类和自定义拦截器)
    Swagger2添加统一header-token
    idea + groovy + mybatis 自动生成 Dao、mappings 和 实体类
    JAVA算法编程题50题及答案
    Python 1基础语法一(注释、行与缩进、多行语句、空行和代码组)
    ENVI 安装
    Python之GUI编程(Tkinter))
    Python 0(安装及初步使用+学习资源推荐)
  • 原文地址:https://www.cnblogs.com/reality-soul/p/4637099.html
Copyright © 2020-2023  润新知