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

平台:mt6582 + Android 4.4

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

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

[cpp] view plaincopy

  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。

[cpp] view plaincopy

  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函数来实现的。

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

[cpp] view plaincopy

  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 plaincopy

  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中就不用再去匹配了。

时间: 2024-10-10 17:42:44

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

另类阻止驱动加载

标 题: [分享][原创]另类阻止驱动加载 作 者: czcqq 时 间: 2010-05-04,22:27:47 链 接: http://bbs.pediy.com/showthread.php?t=112338 关于驱动的加载大概有几种方法 1 在WINDOWS下动态加载 2 在WINDOWS启动的时候加载 3 感染系统文件 对于 在WINDOWS启动的时候加载 和 感染系统文件 我们暂时不讨论,玩么只讨论动态加载 一般的加载流程,是这样的:打开服务管理器->创建服务->启动服务->

WebKit加载流程 - 概述

之前写了几篇加载流程的说明,是从下向上看,有点只见树木不见森林的感觉.经过最近一段时间的学习,有了能加以概括抽象的方法. WebKit加载流程和页面组成是直接相关的,页面就是WebKit要加载的对象.所以WebKit负责加载的类也与负责页面管理的类相对应.Apple关于WebView的说明里清楚表现了页面视图上的MVC结构: 一个页面从元素上也有其层次结构,并且和加载类对应,如下: 从页面元素上讲WebView代表了一个页面的呈现,对应一个Page. 一个Page包含一个或多个Frame,其中一

展讯平台 LCD(Mipi) 加载流程分析

stage1 阶段的详细分析参见 uboot 详细注释讲解 我们从 uboot 的 stage2 开始分析. 加载流程分析 首先是完成硬件的初始化. 函数调用流程为: u-boot64/arch/arm/board.c: board_init_r() u-boot64/common/stdio.c: stdio_init() u-boot64/common/lcd.c: drv_lcd_init() lcd_init() u-boot/drivers/video/sprdfb/sprdfb_ma

切图崽的自我修养-优化图片加载流程

前言 优化! 又是优化! 切图崽们作为整个web应用的纽带,连接着用户行为和机器性能. 而优化的最终意义,在于在这两者之间取得一个最佳的平衡点. 对于图片资源的加载来说,更是如此. 今天我们就来简单说说,项目开发中常见的图片加载优化方式. 预加载 1.遮罩大法 我们经常用jquery, jquery中$(function){})实际上是DOMContentLoaded事件完成的回调,只是完成了DOM树的构建. 诸如Css的渲染以及页面内图片等资源的下载不一定完成了.所以如果此时呈现页面,页面会非

sn9c291 驱动加载成功,mpayer无法播放

先目前将一个sn9c291+ov9712的模块驱动在fedora上加载成功,可是在使用mplayer却无法播放,不知道为何? 前后对比发现dev目录下多了video0,video1 设备节点已经出来,video1 是H264的节点 [[email protected] mplayer]# mplayer tv:// -tv driver=v4l2:width=1280:height=720:device=/dev/video1:outfmt=0x34363248 -fps 24 MPlayer

【ESXI6.0】 ESXI6.0安装时无法安装网卡驱动的解决方法及将网卡驱动加载进ISO

若安装时提示如下图所示 之后安装无法完成,会提示没有检测到网络适配器,如下图. 这时候需要将网卡驱动加载进ISO中才能在安装时候识别网卡驱动. 网卡驱动从这里下载: https://vibsdepot.v-front.de/wiki/index.php/List_of_currently_available_ESXi_packages 找到对应的型号.点击进入下一页下载. 需要使用如下工具: ESXi-Customizer-v2.7.2 http://pan.baidu.com/s/1eQ2f8

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

图片数据加载流程. Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->PhotoPage 相册集                        照片集                 某张图片 1,AlbumSetPage.java private void initializeData(Bundle data) { String mediaPath = data.getString(A

多功能PCIE交换机之八:窗口扩展和驱动加载的常见问题

结合本人在PCIE NTB/DMA最近的实际工作,总结了地址转换窗口扩展和驱动加载过程中碰到的主要问题和解决办法. 0.系统启动后看不到NTB设备 需要检查BIOS,在PCIE设置里面NTB芯片是否使能.这是因为针对不同的应用场景和客户需要,BIOS里面通常添加了Enable/Disable NTB的选项. 1.如何扩展地址转换窗口 a.确定系统要求的地址转换窗口的范围和大小: b.确保系统要求的地址转换窗口的范围和大能够被BIOS支持 c.从可用的BAR2/3和BAR4/5中选择未使用的或者可

kettle插件加载流程

kettle插件加载流程 1.前言 kettle遵循着插件机制,基于插件使得kettle整个结构非常清晰,耦合性低,移植性强,特别是对kettle进行二次开发尤其方便,根据个人了解,扩展step类型的插件比较多,具体步骤可以参考:http://blog.csdn.net/d6619309/article/details/50020977  .通过了解插件的加载流程,不仅kettle的原理有深一层的认识,还有助于在进行二次开发遇到问题的时候进行定位(例如,最近遇到个情况就是通过kettle api