高通移植mipi LCD的过程LK代码
lk部分:(实现LCD兼容)
1. 函数定位
aboot_init()
来到target_display_init()
;
这就是高通原生lk LCD 兼容的关键所在。至于你需要兼容多少LCD 就在while()设置了,具体代码就不跟下去了。
然后根据target中的不同文件来判断是否进入哪一个函数来处理:
target_display_init()
函数里有很重要函数就是gcdb_display_init()
;
如果平台支持屏幕最大个数自动检测,msm8953支持兼容两个屏。(GCDB:Global Component Database全局组件数据库);
gcdb_display_init初始化pll_clk_func、power_func、bl_func等功能(指明相应的函数指针),初始化好之后就调用msm_display_init()函数。
在msm_display_init()里先Turn on panel,再Turn on backlight;
panel.power_func = mdss_dsi_panel_power; //turn on panel
panel.bl_func = mdss_dsi_bl_enable; //turn on backlight
函数指向相应的函数中去;
2. 打开lcd
/* Turn on panel */
1. 调用mdss_dsi_panel_power()中的regulator_enable()给L2、L6、L17供电
if (pdata->power_func)
ret = pdata->power_func(1, &(panel->panel_info));
2. 调用mdss_dsi_mipi_dfps_config函数:
if (pdata->dfps_func)
ret = pdata->dfps_func(&(panel->panel_info));
3. 调用mdss_dsi_panel_clock()
调用calculate_clock_config(pinfo)
计算时钟配置和调用target_panel_clock(enable, pinfo)
配置目标panel的时钟。
4. 分配并设置帧缓存:
msm_fb_alloc(&(panel->fb))
和fbcon_setup(&(panel->fb))
为帧缓冲器(frame buffer)分配内存。
5. 获取logo图片:
调用fetch_image_from_partition()
从splash分区获取lk logo图片,如果splash分区没有满足要求的数据,就显示默认的logo。
6. DSI转HDMI:
if ((panel->dsi2HDMI_config) && (panel->panel_info.has_bridge_chip))
ret = panel->dsi2HDMI_config(&(panel->panel_info));
7. msm_display_config()函数:
7.1 mdss_dsi_phy_init()
mdss_dsi_phy_init(&mipi_pinfo,MIPI_DSI0_BASE, DSI0_PHY_BASE);
if(pinfo->mipi.dual_dsi)
如果有两个MIPI DSI接口MIPI_DSI0和MIPI_DSI1就调用两次mdss_dsi_phy_init(),msm8909只有MIPI_DSI0,MSM8994等有两个DSI接口。
mdss_dsi_phy_init(&mipi_pinfo,MIPI_DSI1_BASE, DSI1_PHY_BASE);
7.2 ret = mdss_dsi_host_init(mipi, mipi->dual_dsi, mipi->broadcast);
初始化DSI接口的host控制器。
7.3 调用if (panel->pre_init_func) {}函数:
static int mdss_dsi_panel_pre_init(void)
{
intret = NO_ERROR;
if(panelstruct.paneldata->panel_lp11_init) {
ret= mdss_dsi_panel_reset(1);
if(ret) {
dprintf(CRITICAL,"panel reset failed\n");
returnret;
}
}
if(panelstruct.paneldata->panel_init_delay)
udelay(panelstruct.paneldata->panel_init_delay);
dprintf(SPEW,"Panel pre init done\n");
returnret;
}
因为panelstruct.paneldata->panel_lp11_init
在init_panel_data()
函数赋值为1,所以调用mdss_dsi_panel_reset()
根据reset时序来复位panel。
8. ret = msm_display_on();
主要部分:
case MIPI_VIDEO_PANEL:
dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");
ret = mdp_dsi_video_on(pinfo);
if (ret)
goto msm_display_on_out;
ret = mdss_dsi_post_on(panel);
if (ret)
goto msm_display_on_out;
ret = mipi_dsi_on(pinfo);
if (ret)
goto msm_display_on_out;
break;
8.1 调用mdp_dsi_video_on()使能DSI VIDEO
8.2 mdss_dsi_post_on()使用初始化命令来初始化panel
8.3 mipi_dsi_on()
9. 打开背光:
/* Turn on backlight */
if (pdata->bl_func)
ret = pdata->bl_func(1);
3. 增加一个panel需要做的事:
1、在gcdb_display_init()函数中有一个函数oem_panel_select()函数:
(这个函数需要做的工作是:主要是识别不同IC,赋值给参数panel_id,panel_id的使用在同一文件中的 init_panel_data()函数中。)
pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info),
&dsi_video_mode_phy_db);
2、uint32_t hw_id = board_hardware_id();
//判断是高通哪一款平台,这里不需要看,hw_id是不需要管的,因为在下面语句中会直接跳到init_panel_data函数中来
3、在oem_panel_select()函数中需要根据你的hw_id来确定使用哪一款的LCD;
panel_override_id = panel_name_to_id(supp_panels,
ARRAY_SIZE(supp_panels), panel_name);
supp_panels是struct panel_list,如果要增加一个panel就需要在这里增加一个supp_panels,例如:
static struct panel_list supp_panels[] = {
{"truly_1080p_video", TRULY_1080P_VIDEO_PANEL},
{"truly_1080p_cmd", TRULY_1080P_CMD_PANEL},
{"r69006_1080p_video", R69006_1080P_VIDEO_PANEL},
{"r69006_1080p_cmd", R69006_1080P_CMD_PANEL},
{"truly_wuxga_video", TRULY_WUXGA_VIDEO_PANEL},
{"nt35523_720p_video", NT35523_720P_VIDEO_PANEL},
{"a914_nhd_video", A914_NHD_VIDEO_PANEL},
};
4、在这个枚举中也需要增加相应的panel:
/*---------------------------------------------------------------------------*/
enum {
TRULY_1080P_VIDEO_PANEL,
TRULY_1080P_CMD_PANEL,
R69006_1080P_VIDEO_PANEL,
R69006_1080P_CMD_PANEL,
TRULY_WUXGA_VIDEO_PANEL,
NT35523_720P_VIDEO_PANEL,
A914_NHD_VIDEO_PANEL,
UNKNOWN_PANEL
};
if (panel_name) {
panel_override_id = panel_name_to_id(supp_panels,
ARRAY_SIZE(supp_panels), panel_name);
if (panel_override_id < 0) {
dprintf(CRITICAL, "Not able to search the panel:%s\n",
panel_name + strspn(panel_name, " "));
} else if (panel_override_id < UNKNOWN_PANEL) {
/* panel override using fastboot oem command */
panel_id = panel_override_id;
dprintf(INFO, "OEM panel override:%s\n",
panel_name + strspn(panel_name, " "));
goto panel_init;
}
}
……
panel_init:
/*
* Update all data structures after 'panel_init' label. Only panel
* selection is supposed to happen before that.
*/
pinfo->pipe_type = MDSS_MDP_PIPE_TYPE_RGB;
return init_panel_data(panelstruct, pinfo, phy_db);
确保能直接跳到panel_init
函数中来;
5、同样来到init_panel_data()函数中来:
在这里也需要增加一个panel:(当然了,要增加相应的头文件#include "include/panel_a914_nhd_video.h"
这个头文件是LCM供应商给的文件,一般来说都要自己根据时序图来参照)
case TRULY_WUXGA_VIDEO_PANEL:
panelstruct->paneldata = &truly_wuxga_video_panel_data;
panelstruct->paneldata->panel_with_enable_gpio = 1;
panelstruct->panelres = &truly_wuxga_video_panel_res;
panelstruct->color = &truly_wuxga_video_color;
panelstruct->videopanel = &truly_wuxga_video_video_panel;
panelstruct->commandpanel = &truly_wuxga_video_command_panel;
panelstruct->state = &truly_wuxga_video_state;
panelstruct->laneconfig = &truly_wuxga_video_lane_config;
panelstruct->paneltiminginfo
= &truly_wuxga_video_timing_info;
panelstruct->panelresetseq
= &truly_wuxga_video_panel_reset_seq;
panelstruct->backlightinfo = &truly_wuxga_video_backlight;
pinfo->mipi.panel_on_cmds
= truly_wuxga_video_on_command;
pinfo->mipi.num_of_panel_on_cmds
= TRULY_WUXGA_VIDEO_ON_COMMAND;
pinfo->mipi.panel_off_cmds
= truly_wuxga_video_off_command;
pinfo->mipi.num_of_panel_off_cmds
= TRULY_WUXGA_VIDEO_OFF_COMMAND;
memcpy(phy_db->timing,
truly_wuxga_14nm_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t));
pinfo->dfps.panel_dfps = truly_wuxga_video_dfps;
pinfo->mipi.signature = TRULY_WUXGA_VIDEO_SIGNATURE;
break;
case A914_NHD_VIDEO_PANEL:
panelstruct->paneldata = &a914_nhd_video_panel_data;
panelstruct->panelres = &a914_nhd_video_panel_res;
panelstruct->color = &a914_nhd_video_color;
panelstruct->videopanel = &a914_nhd_video_video_panel;
panelstruct->commandpanel = &a914_nhd_video_command_panel;
panelstruct->state = &a914_nhd_video_state;
panelstruct->laneconfig = &a914_nhd_video_lane_config;
panelstruct->paneltiminginfo
= &a914_nhd_video_timing_info;
panelstruct->panelresetseq
= &a914_nhd_video_panel_reset_seq;
panelstruct->backlightinfo = &a914_nhd_video_backlight;
pinfo->mipi.panel_on_cmds
= a914_nhd_video_on_command;
pinfo->mipi.num_of_panel_on_cmds
= A914_NHD_VIDEO_ON_COMMAND;
pinfo->mipi.panel_off_cmds
= a914_nhd_video_off_command;
pinfo->mipi.num_of_panel_off_cmds
= A914_NHD_VIDEO_OFF_COMMAND;
memcpy(phy_db->timing,
a914_nhd_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t));
pinfo->mipi.signature = A914_NHD_VIDEO_SIGNATURE;
break;
6、调整背光:
在gcdb_display_init()
函数中有一个函数指针mdss_dsi_bl_enable
:
这个函数是用来调整背光的和使能背光的,通过PWM来作用:(具体要看原理图)
static int mdss_dsi_bl_enable(uint8_t enable)
{
int ret = NO_ERROR;
ret = panel_backlight_ctrl(enable);
if (ret)
dprintf(CRITICAL, "Backlight %s failed\n", enable ? "enable" :
"disable");
return ret;
}
static uint32_t panel_backlight_ctrl(uint8_t enable)
{
uint32_t ret = NO_ERROR;
if (panelstruct.backlightinfo)
ret = target_backlight_ctrl(panelstruct.backlightinfo, enable);
return ret;
}
所以bootloader的背光是通过target_backlight_ctrl()
控制的,找到该项目的这个函数修改:
wled_backlight_ctrl
;
7、更改LCD的参数:
LCD的一些参数:
VBPD(verticalback porch)
:表示在一帧图像开始时,垂直同步信号以后的无效的行数。
VFPD(verticalfront porch)
:表示在一帧图像结束后,垂直同步信号以前的无效的行数。
VSPW(verticalsync pulse width)
:表示垂直同步脉冲的宽度,用行数计算。
HBPD(horizontal back porch)
:表示从水平同步信号开始到一行的有效数据开始之间的VCL的个数。
HFPD(horizontal front porch)
:表示一行的有效数据结束到下一个水平同步信号开始 之间的VCLK的个数。
HSPW(horizontalsync pulse width)
:表示水平同步信号的宽度,用VCLK计算。
高通移植mipi LCD的过程LK代码的更多相关文章
- 高通安卓调试LCD几方面总结
来公司上班现在已经整整一个月了,蔽人不才,能力有限,学习进度缓慢,不过也是有一点点的收获与心得,在这里写出来与大家分享,养成良好的记录习惯也免得后忘记. 不啰嗦了,开入正题.来公司一个月左右的时间,主 ...
- 高通 android平台LCD驱动分析
目前手机芯片厂家提供的源码里包含整个LCD驱动框架,一般厂家会定义一个xxx_fb.c的源文件,注册一个平台设备和平台驱动,在驱动的probe函数中来调用register_framebuffer(), ...
- 【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
- 高通 MSM8K bootloader : SBL1 .
一. MSM8K Boot Flow 图1: 高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974.MSM8916.MSM8994等,会有微小区别. 从上图,可以看 ...
- 高通 MSM8K bootloader之一: SBL1
MSM8K Boot Flow 转自:http://www.cnblogs.com/liang123/p/6325257.html http://blog.csdn.net/F ...
- 高通平台msm8909 LK 实现LCD 兼容
前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...
- 高通平台 lcd driver 调试小结
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
此次移植打算分成两个模块来说,bootloader部分和kernel部分.在实际的移植调试过程中也是这么分成了两个部分分别调试. 高通平台中的bootloader叫做LK(Little Kernel, ...
- 高通平台MSM8916LCM模块移植(一)-bootloader部分【转】
本文转载自:http://www.mobile-open.com/2016/970947.html 高通平台中的bootloader叫做LK(Little Kernel,对于LCM来说LK部分相当重要 ...
随机推荐
- SOA和微服务架构的区别
微服务架构强调的第一个重点就是业务系统需要彻底的组件化和服务化,原有的单个业务系统会拆分为多个可以独立开发,设计,运行和运维的小应用.这些小应用之间通过服务完成交互和集成.每个小应用从前端web ui ...
- MVC笔记--特性路由
物性路由:将路由和控制器放在一起,这样更简单方便,还可以处理复杂的路由场景 传统路由:集中.强制.基于代码风格来定义的. 每个MVC应用程序都需要路由来定义自己的处理请求方式,路由是MVC是应用程序的 ...
- 基于Flume的日志收集系统方案参考
前言 本文将简单介绍两种基于Flume的日志收集系统可能的架构方案,可根据不同的实际场景参考使用. 方案一 示例图如下: 说明: 每个日志源(http上报.日志文件等)对应一个Agent-c用于收集对 ...
- 浅谈如何使用Netty开发高性能的RPC服务器
如何使用Netty进行RPC服务器的开发,技术原理涉及如下:1.定义RPC请求消息.应答消息结构,里面要包括RPC的接口定义模块,如远程调用的类名.方法名.参数结构.参数值等信息. 2.服务端初始化的 ...
- MySQL修改表、字段、库的字符集及字符集说明
修改数据库字符集: ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [COLLATE ...]; 把表默认的字符集和所有字符列( ...
- 为springboot项目添加springboot-admin监控
我们知道spring-boot-actuator暴露了大量统计和监控信息的端点,spring-boot-admin 就是为此提供的监控项目. 先来看看大概会提供什么样的功能 从图中可以看出,主要内容都 ...
- sql多条件查询语句
如上图:三个文本可选项,那sql语句怎么写呢? 1.首先获取三个文本的值分别为Name,Age,Sex. 2.string sql="select * from 表 where 1=1&qu ...
- C#微信公众号开发--微信事件交互
前言 一切准备工作就绪时就先实现一个关注公众号后向客户端推送一条消息.关注后推送消息需要一个get请求.一个post请求,get请求主要是为了向微信服务器验证,post请求主要就是处理微信消息了. 调 ...
- JWT的相关讲解
原文链接: http://www.cnblogs.com/chenwolong/p/Token.html
- .Net敏捷开发框架6.1.6.2版本,联系QQ:6539471
演示地址:www.fishcmonkey.com .NET敏捷开发框架 6.1.6.2 版本发布 新增手机流程-我的流程(可查看流程进度和表单内容) 新增手机流程-待办任务(可查看流程进度和表单内容, ...