高通平台MSM8916LCM模块移植(一)-bootloader部分
来源:互联网 发布:enum数据类型php 编辑:程序博客网 时间:2024/04/20 07:37
此次移植打算分成两个模块来说,bootloader部分和kernel部分。在实际的移植调试过程中也是这么分成了两个部分分别调试。
高通平台中的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 char *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_tbroadcast){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);}#endifreturn 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;}elsereturn 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部分
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
- 高通平台BootLoader的流程
- 高通平台camrea移植
- uboot移植(一)BootLoader基本概念
- 高通平台bootloader里面串口log输出配置方法
- 高通平台bootloader里面串口log输出配置方法 .
- 高通平台开机LOGO修改LK(bootloader)下实现
- 高通平台修改LK(bootloader)开机logo
- 高通平台修改LK(bootloader)开机logo
- 高通平台bootloader显示logo图片的过程
- 高通平台修改LK(bootloader)开机logo
- 高通平台msm8916修改开机logo 高通平台修改LK(bootloader)开机logo
- 高通平台工作总结(一)
- 高通平台LCD移植概述
- 高通bootloader
- 高通android bootloader
- Codeforces #288 B
- Android抗锯齿设置
- 【Darwin学习笔记】之TaskThread
- 关于MQTT-SN的开发
- SQL SERVER 2005如何建立自动备份的维护计划
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
- 找数字
- LeetCode—Largest Number
- 服务器向Android推送的相关知识和解决方案
- Atheros网卡在linux下面的配置与编译详情
- jQuery最佳实践
- The goal you specified requires a project to execute but there is no POM in 错误
- ubuntu14.04安装cuda
- java Singleton单例模式