平台: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\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. disp_dump_lcm_parameters(lcm_params);
  12. return TRUE;
  13. }

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

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("\t\t[fail]\n");

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\n", lcm_count);
  6. printk("[LCM Auto Detect], try to find driver for [%s]\n",
  7. (lcm_name==NULL)?"unknown":lcm_name);
  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_index = 0;
  15. printk("[LCM Specified]\t[%s]\n", (lcm->name==NULL)?"unknown":lcm->name);
  16. isLCMFound = true;
  17. goto done;
  18. }
  19. else
  20. {
  21. int i;
  22. for(i = 0;i < lcm_count;i++)
  23. {
  24. lcm = lcm_driver_list[i];
  25. printk("[LCM Auto Detect] [%d] - [%s]\t", i, (lcm->name==NULL)?"unknown":lcm->name);
  26. lcm->set_util_funcs(&lcm_utils);
  27. memset((void*)&s_lcm_params, 0, sizeof(LCM_PARAMS));
  28. lcm->get_params(&s_lcm_params);
  29. disphal_init_ctrl_if();
  30. LCD_Set_DrivingCurrent(&s_lcm_params);
  31. LCD_Init_IO_pad(&s_lcm_params);
  32. if(lcm_name != NULL)
  33. {
  34. if(!strcmp(lcm_name,lcm->name))
  35. {
  36. printk("\t\t[success]\n");
  37. *lcm_index = i;
  38. isLCMFound = true;
  39. goto done;
  40. }
  41. else
  42. {
  43. printk("\t\t[fail]\n");
  44. }
  45. }
  46. else
  47. {
  48. if(LCM_TYPE_DSI == lcm_params->type)
  49. {
  50. init_dsi(FALSE);
  51. }
  52. if(lcm->compare_id != NULL && lcm->compare_id())
  53. {
  54. printk("\t\t[success]\n");
  55. isLCMFound = true;
  56. *lcm_index = i;
  57. goto done;
  58. }
  59. else
  60. {
  61. if(LCM_TYPE_DSI == lcm_params->type)
  62. DSI_Deinit();
  63. printk("\t\t[fail]\n");
  64. }
  65. }
  66. }
  67. }
  68. done:
  69. if (isLCMFound)
  70. {
  71. memset((void*)&s_lcm_params, 0, sizeof(LCM_PARAMS));
  72. lcm->get_params(&s_lcm_params);
  73. return lcm;
  74. }
  75. else
  76. return NULL;
  77. }

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

lcm=1-hx8389b_qhd_dsi_vdo

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

mtk lcm驱动加载流程 (转载)的更多相关文章

  1. android源码解析(十七)-->Activity布局加载流程

    版权声明:本文为博主原创文章,未经博主允许不得转载. 好吧,终于要开始讲讲Activity的布局加载流程了,大家都知道在Android体系中Activity扮演了一个界面展示的角色,这也是它与andr ...

  2. Cocos Creator 资源加载流程剖析【一】——cc.loader与加载管线

    这系列文章会对Cocos Creator的资源加载和管理进行深入的剖析.主要包含以下内容: cc.loader与加载管线 Download部分 Load部分 额外流程(MD5 Pipe) 从编辑器到运 ...

  3. java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现

    注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...

  4. Dubbo 配置的加载流程

    配置加载流程 在SpringBoot应用启动阶段,Dubbo的读取配置遵循以下原则 Dubbo支持了多层级的配置,按照预先定义的优先级自动实现配置之间的覆盖,最终所有的配置汇总到数据总线URL后,驱动 ...

  5. angular源码分析:angular的整个加载流程

    在前面,我们讲了angular的目录结构.JQLite以及依赖注入的实现,在这一期中我们将重点分析angular的整个框架的加载流程. 一.从源代码的编译顺序开始 下面是我们在目录结构哪一期理出的an ...

  6. 老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

      最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者 ...

  7. (DT系列四)驱动加载中, 如何取得device tree中的属性

    本文以At91rm9200平台为例,从源码实现的角度来分析驱动加载时,Device tree的属性是如何取得的.一:系统级初始化DT_MACHINE_START 主要是定义"struct m ...

  8. 【转】(DT系列四)驱动加载中, 如何取得device tree中的属性

    原文网址:http://www.cnblogs.com/biglucky/p/4057488.html 本文以At91rm9200平台为例,从源码实现的角度来分析驱动加载时,Device tree的属 ...

  9. Android5.1图库Gallery2代码分析数据加载流程

    图片数据加载流程. Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->Photo ...

随机推荐

  1. MD5加密,Base64加密/解密,AES加密/解密

    1.从github上下载GTMBase64-master和AESCrypt-ObjC-master导入工程,如下图所示. 2.使用前的配置及注意事项: (1) 在build phases中的GTMBa ...

  2. Mootools插件-闪烁的标题

    转自:http://www.cnblogs.com/see7di/archive/2012/10/09/2716024.html 回想起来,我已经好久没有写点啥了,尤其是关于Mootools方面的东西 ...

  3. hdwiki中插件开发指南

    插件就是为了满足个性化需求按照HDWiki插件开发规范编写的可插拔程序,虽然可以直接对HDWiki进行二次开发实现插件同样的功能,但是这样做势必影响到系统的升级和稳定性. 采用插件的方式,可以随时进行 ...

  4. java UUID

    UUID是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符.UUID具有以下涵义: 经由一定的算法机器生成 为了保证 ...

  5. css3 简单动画

    <script> <!-- var x,y,n=0,ny=0,rotINT,rotYINT function rotateDIV() { x=document.getElementB ...

  6. poj2888 Magic Bracelet

    给你一个正n(<10^9)边形和m(<10)种色料,要求给正n边形顶点染色并且规定k组颜色对不能相邻, 输入保证n与mod互质,计数染色总方案数(绕图形中心旋转后相同的方案算一种)对mod ...

  7. 如何修改配置以修复ThinkPad 小红帽滚轮失效?

    本人使用ThinkPad X1 Carbon超级本,由于近期安装了遨游浏览器(Maxthon),发现其总体体验还是不错,但是在本机器上有个明显的Bug:就是小红帽的滚轮不管用. 由于就查了网上相关资料 ...

  8. UML类图几种关系的总结(转)

    原文:http://gjhappyyy.iteye.com/blog/1422515 在UML类图中,常见的有以下几种关系: 泛化(Generalization),  实现(Realization), ...

  9. U3D UGUI学习4 - Text

    1.对应NGUI的四种文字显示模式 Shrink Content 对应NGUI第一种模式     勾选Best Fit 但似乎有一个Bug,文字过多的时候会爆框.解决方法是改变Line Spacing ...

  10. 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解

    http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...