高通平台MSM8916LCM模块移植(一)-bootloader部分【转】
本文转载自:http://www.mobile-open.com/2016/970947.html
高通平台中的bootloader叫做LK(Little Kernel,对于LCM来说LK部分相当重要,它不仅要负责开机部分的LCD显示任务,还要负责传参给kernel的LCM驱动,指导kernel选择合适的LCM参数。
1、LK中LCM启动流程
2、oem_panel_select()
- /********************************************************
- *Name: oem_panel_select
- *Function: selection different lcm panel
- *Description: 1)This func will be roaded twice,first time use default value
- second time depend on lk_lcd_id value match correct branch.
- *Author: Jerry.peng
- *********************************************************/
- bool oem_panel_select(const charchar *panel_name, struct panel_struct *panelstruct,
- struct msm_panel_info *pinfo,
- struct mdss_dsi_phy_ctrl *phy_db)
- {
- uint32_t soc_version = board_soc_version();
- uint32_t gpio_state = 0;
- gpio_tlmm_config(LCM_GPIO_DETECT, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_ENABLE);<span style="color:#33ff33;"> </span><span style="color:#009900;">//这个主要是硬件检测lcd_id引脚,用来区分同一IC不同模组厂屏</span>
- mdelay(10);
- gpio_state = gpio_status(LCM_GPIO_DETECT);
- dprintf(CRITICAL, "[PHC]:oem_panel.c soc_version = 0X%x value,gpio_state=%d\n",soc_version,gpio_state);
- if(0x6089 == lk_lcd_id || 0xFFFF == lk_lcd_id){ <span style="color:#009900;"> //lk_lcd_id 是自己设定的一个全局变量,赋值在mipi_dsi.c文件中</span>
- if(gpio_state){ <span style="color:#009900;">//这个是同一个IC,不同模组厂的情况,由之前说的lcd_id引脚来判定</span>
- panel_id = ILI9806E_WVGA_VIDEO_HONGTAO_PANEL;
- dprintf(CRITICAL,"[PHC]: ILI9806E hongtao panel choosed\n");
- } else {
- panel_id = ILI9806E_WVGA_VIDEO_HAIFEI_PANEL;
- dprintf(CRITICAL,"[PHC]: ILI9806E haifei panel choosed\n");
- }
- }
- else if(0x8018 == lk_lcd_id){ <span style="background-color: rgb(255, 255, 255);"><span style="color:#009900;">//此处为IC(OTM8019)的情况</span></span>
- if(gpio_state){
- panel_id = OTM8019_WVGA_VIDEO_SUXIAN_PANEL;
- dprintf(CRITICAL,"[PHC]: otm8019 panel choosed\n");
- } else {
- panel_id = OTM8019_WVGA_VIDEO_HAOSHITONG_PANEL;
- dprintf(CRITICAL,"[PHC]: otm8018b panel choosed\n");
- }
- }
- else if (0x3551 == lk_lcd_id){ <span style="font-family: Arial, Helvetica, sans-serif;"><span style="color:#009900;">//此处为IC(NT35512S)的情况</span></span>
- panel_id = NT35512S_WVGA_VIDEO_HAIFEI_PANEL;
- dprintf(CRITICAL,"[PHC]: NT35512S haifei panel choosed\n");
- }
- panel_init:
- pinfo->pipe_type = MDSS_MDP_PIPE_TYPE_RGB;
- return init_panel_data(panelstruct, pinfo, phy_db);
- }
3、mdss_dsi_initialize()
mdss_dsi_initialize() 在文件Android/bootable/bootloader/lk/platform/msm_shared/mipi_dsi.c 中
在 mipi_dsi.c 文件开始先申明全局变量 lk_lcd_id
- uint32_t lk_lcd_id = 0xFFFF;
- /*****************************************************************
- *Name: mdss_dsi_panel_initialize
- *Function: Read LCM id & send lcm config
- *Descritpion: 1/ soc_version use for identify T3F project
- 2/ lcm_id_retry usr for identify 2 lane or 4lane mipi
- *******************************************************************/
- int mdss_dsi_panel_initialize(struct mipi_dsi_panel_config *pinfo, uint32_t
- broadcast)
- {
- int status = 0;
- #if (DISPLAY_TYPE_MDSS == 1)
- <span style="background-color: rgb(255, 255, 255);"><span style="color:#cc33cc;"> if (0xffff == lk_lcd_id ){ </span><span style="color:#009900;">//洋红色这部分代码是自己添加的和上面函数所说的oem_panel_select()配合使用</span><span style="color:#cc33cc;">
- lk_lcd_id = read_panel_id(); </span><span style="color:#009900;"> //此为读ID的函数调用处</span><span style="color:#cc33cc;">
- target_force_cont_splash_disable(true);
- msm_display_off();
- target_force_cont_splash_disable(false);
- target_display_init(NULL); </span><span style="color:#009900;">//从上面流程图看以看出,这个是屏初始化的开始函数,相当于第二次初始化屏幕</span><span style="color:#cc33cc;">
- return 1;
- }</span></span>
- if (pinfo->panel_cmds) {
- if (broadcast) {
- status = mdss_dual_dsi_cmds_tx(pinfo->panel_cmds,
- pinfo->num_of_panel_cmds);
- } else {
- status = mipi_dsi_cmds_tx(pinfo->panel_cmds,
- pinfo->num_of_panel_cmds);
- if (!status && target_panel_auto_detect_enabled())
- status =
- mdss_dsi_read_panel_signature(pinfo->signature);
- }
- dprintf(CRITICAL,"[PHC]: status=%d\n",status);
- }
- #endif
- return status;
- }
4、read_panel_id()
read_panel_id()为读取LCM ID的函数,里面包括读取各中IC函数,详细看下面代码。
- <pre name="code" class="cpp">/*****************************************************************
- *Name: read_panel_id
- *Function: Read LCM id
- *Descritpion: 1/ lcm_id_retry usr for identify 2 lane or 4lane mipi
- 2/ lcm_id_retry == 0 means 2 lane
- *Author: Jerry.peng
- *******************************************************************/
- uint32_t read_panel_id(void)
- {
- uint32_t lcd_id = 0xffff;
- <span style="white-space:pre"> </span>if( mdss_dsi_read_ili9806e_id() )
- <span style="white-space:pre"> </span>lcd_id = 0x6089; /* panel ic is ili9806e */
- <span style="white-space:pre"> </span>else if( mdss_dsi_read_otm8018b_id())
- <span style="white-space:pre"> </span>lcd_id = 0x8018; /* panel ic is otm8018b */
- <span style="white-space:pre"> </span>else if( mdss_dsi_read_nt35512s_id() )
- <span style="white-space:pre"> </span>lcd_id = 0x3551; /* panel ic is nt35512s */
- if(lcd_id == 0xffff){
- lcd_id = 0x1283;
- dprintf(CRITICAL,"[PHC]: no panel id readed use default \n");
- return lcd_id;
- }
不同IC的读取ID的函数都大同小异,我这里就用ili9806e这颗IC来举例:
- <pre name="code" class="cpp">static struct mipi_dsi_cmd apex_ili9806e_panel_set_cmd[] = {
- {sizeof(apex_ili9806e_cmd0), apex_ili9806e_cmd0},
- };
- static char apex_ili9806e_panel_set_pkt_size[4] = {0x08, 0x00, 0x37, 0x80};
- static struct mipi_dsi_cmd apex_ili9806e_panel_set_pkt_size_cmd[] = {
- {sizeof(apex_ili9806e_panel_set_pkt_size), apex_ili9806e_panel_set_pkt_size},};
- static char apex_ili9806e_panel_manufacture_id[4] = {0x00, 0x00, 0x06, 0xA0};
- static struct mipi_dsi_cmd apex_ili9806e_panel_manufacture_id_cmd[] = {
- {sizeof(apex_ili9806e_panel_manufacture_id), apex_ili9806e_panel_manufacture_id},};
- <pre name="code" class="cpp">static bool mdss_dsi_read_ili9806e_id(void)
- {
- char rec_buf[24];
- char *rp = rec_buf;
- uint32_t *lp,temp,ret, data = 0;
- ret = mipi_dsi_cmds_tx(apex_ili9806e_panel_set_cmd, ARRAY_SIZE(apex_ili9806e_panel_set_cmd));
- mdelay(10);
- ret = mipi_dsi_cmds_tx(apex_ili9806e_panel_set_pkt_size_cmd, ARRAY_SIZE(apex_ili9806e_panel_set_pkt_size_cmd));
- mdelay(10);
- ret = mipi_dsi_cmds_tx(apex_ili9806e_panel_manufacture_id_cmd, ARRAY_SIZE(apex_ili9806e_panel_manufacture_id_cmd));
- mdelay(10);
- if(ret == 1)
- lcm_id_retry += 1;
- mipi_dsi_cmds_rx(&rp, 3);
- lp = (uint32_t *)rp;
- data = (uint32_t)*lp;
- data = ntohl(data);
- data = data & 0xFF;
- dprintf(CRITICAL,"[PHC]: ili9806e id: 0x%x\n", data);
- if(data == 0x98) {
- lcm_id_retry = 0;
- return true;
- }
- else
- return false;
- }
到此,整个lk中LCM兼容和移植的主体部分就已经完成了,剩下就是填LCM参数进.h文件,这里再对整个流程进行一个补充整理。
首先解释下为什么不用高通默认的兼容方法,因为高通默认的兼容需要用到各种硬件id,平台id,这些都是在SBL中设定的,修改起来麻烦,而且可以兼容的屏幕个数有限,我上面所说的这种方法加上我拓展的一些代码,已经可以兼容十多块屏幕。
整个兼容方法的思路是,在LCM进行第一遍初始化的时候,什么都不变,但进行到mipi_dsi.c文件中的mdss_dsi_initialize()函数的时候,回去读当前使用的LCM IC 的id
,如果和默认的屏幕id一样,则不进行第二次初始化,若不一样,则重新初始化,这个时候全局变量lk_lcd_id已经被赋值,当第二遍初始化到了oem_panel.c文件的oem_panel_select()函数中,函数根据lk_lcd_id的值来匹配正确的屏幕变量。匹配完成之后继续未完成的屏幕初始化,至此整个流程走完,屏幕点亮!
文章介绍完毕,如有错误欢迎大家指正~
高通平台MSM8916LCM模块移植(一)-bootloader部分【转】的更多相关文章
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
此次移植打算分成两个模块来说,bootloader部分和kernel部分.在实际的移植调试过程中也是这么分成了两个部分分别调试. 高通平台中的bootloader叫做LK(Little Kernel, ...
- 高通平台的bootloader过程【转】
====================基本知识=======================LK是(L)ittle (K)ernel的缩写.高通平台android普遍采用LK作为其bootloade ...
- 高通平台Bootloader启动流程【转】
本文转载自:http://blog.csdn.net/fang_first/article/details/49615631 ====================基本知识============= ...
- 【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
- 高通平台 lcd driver 调试小结
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
- 高通、猎户机型Android典型bootloader分析
1.bootloader是什么? 简单地说,bootloader 就是在操作系统内核运行之前运行的一段小程序.通过这段小程序,我们可以初始化硬件设备.建立内存空间的映射图,从而将系统的软硬件环境带到一 ...
- 高通平台msm8909 LK 实现LCD 兼容
前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...
- [修改高通平台WIFI MAC 地址] & [adb over wifi]
[修改高通平台WIFI MAC 地址]fccmd --helpfccmd startfccmd getwifimacfccmd setwifimac 74:AC:5F:F5:D7:40 [adb ov ...
- android 6.0 高通平台sensor 工作机制及流程(原创)
最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...
随机推荐
- PHP制作姓名、学号。爱好等窗口
if (radioButton1.Checked == true) textBox2.Text = 姓名: + textBox1.Text + 性别: + radi ...
- mongo 过滤查询条件后分组、排序
描述:最近业主有这么一个需求,根据集合中 时间段进行过滤,过滤的时间时间段为日期类型字符串,需要根据某一日期进行截取后.进行分组,排序 概述题目:根据createTime时间段做查询,然后以 天进行分 ...
- 【BZOJ1880】[Sdoi2009]Elaxia的路线 最短路+DP
[BZOJ1880][Sdoi2009]Elaxia的路线 Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起 ...
- Flow Problem(最大流模板)
Flow Problem Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tota ...
- 通知url必须为直接可访问的url,不能携带参数 异步接收微信支付结果通知的回调地址 不能携带参数。 回调地址后是否可以加自定义参数 同步回调地址 异步回调地址 return_url和notify_url的区别
[微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7 通知url必须为直接可访问的 ...
- Error: unable to connect to node rabbit@10: nodedown 修改hostname后异常
https://blog.csdn.net/witsmakemen/article/details/22651365 [root@d bin]# rabbitmqctl start_appStarti ...
- TGraphicControl(自绘就2步,直接自绘自己,不需要调用VCL框架提供的函数重绘所有子控件,也不需要自己来提供PaintWindow函数让管理框架来调用)与TControl关键属性方法速记(Repaint要求父控件执行详细代码来重绘自己,还是直接要求Invalidate无效后Update刷新父控件,就看透明不透明这个属性,因为计算显示的区域有所不同)
TGraphicControl = class(TControl) private FCanvas: TCanvas; procedure WMPaint(var Message: TWMPaint) ...
- 外部导入js(javascript)文件方法
<script src="myScript.js"></script>
- 用户(user)和用户组(group)相关的配置文件、命令或目录;
1.与用户(user)和用户组(group)相关的配置文件: 1)与用户(user)相关的配置文件:/etc/passwd 注:用户(user)的配置文件:/etc/shadow 注:用户(user) ...
- Ubuntu出现Authentication failure(认证失败)的解决方法(转)
当我们想在刚安装的Linux系统启动某些服务或者想进入root用户时提示认证失败或者权限不够时,原因是刚安装Ubuntu后,root用户默认是未激活的,不允许登录,也不允许使用su命令到转到root用 ...