mtk lcm驱动加载流程

来源:互联网 发布:坎巴拉太空计划 mac 编辑:程序博客网 时间:2024/05/09 10:22

http://blog.csdn.net/mcgrady_tracy/article/details/42427517

平台:mt6582 + Android 4.4

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

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

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. OOL DISP_DetectDevice(void)  
  2. {  
  3.     //LCD_STATUS ret;  
  4.     DISP_LOG("shi=>%s, %d\n", __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\n", __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。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  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\n", lcm_count);  
  5.     printk("[LCM Auto Detect], try to find driver for [%s]\n",   
  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\n"); 
  33.                 isLCMFound = TRUE; 
  34.             } 
  35.             else 
  36.             { 
  37.                 printk("[LCM Specified] compare id fail\n"); 
  38.                 printk("%s, lcm is not connected\n", __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]\t[%s]\n", (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]\t", 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("\t\t[success]\n");  
  78.                     isLCMFound = TRUE;  
  79.                                    u4IndexOfLCMList = i;  
  80.                     lcm_drv = lcm;  
  81.   
  82.                     goto done;  
  83.                 }  
  84.                 else  
  85.                 {  
  86.                     printk("\t\t[fail]\n");  
  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("\t\t[success]\n");  
  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("\t\t[fail]\n");  
  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\n");  
  136.         }  
  137.         else  
  138.         {  
  139.             isLCMConnected = 1;  
  140.             printk("lcm is connected\n");  
  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函数来实现的。

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

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

2. kernel部分(mediatek/platform/mt6582/kernel/drivers/video/disp_hal.c)
LK部分代码看完了,那么再来看kernel部分。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  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\n", lcm_count);  
  6.     printk("[LCM Auto Detect], try to find driver for [%s]\n",   
  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]\t[%s]\n", (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]\t", 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("\t\t[success]\n");  
  40.                     *lcm_index = i;  
  41.                     isLCMFound = true;  
  42.                     goto done;  
  43.                 }  
  44.                 else  
  45.                 {  
  46.                     printk("\t\t[fail]\n");  
  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("\t\t[success]\n");  
  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("\t\t[fail]\n");  
  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中就不用再去匹配了。
0 0
原创粉丝点击