1、前言

在前面的文章《MSM8909中LK阶段LCM屏适配与显示流程分析(一)》,链接如下:

https://www.cnblogs.com/Cqlismy/p/12019317.html

介绍了如何使用GCDB工具生成要适配的屏幕的相关配置文件,同时,也介绍了如何在LK启动阶段中,在基于Qualcomm的LCD屏幕软件驱动框架中,修改相应的文件去适配一款屏幕,此外,该文章是"MSM8909中LK阶段LCM屏适配与显示流程分析"的第二部分,主要是分析LK启动阶段中屏幕的初始化和显示流程是怎么样的。

2、LK中屏初始化和显示流程分析

LK启动阶段中,LCM屏幕的初始化和log的显示是在aboot_init()函数中完成,调用的函数为target_display_init(),具体代码如下:

    /* Display splash screen if enabled */
#if DISPLAY_SPLASH_SCREEN
dprintf(INFO, "Display Init: Start\n");
target_display_init(device.display_panel);
dprintf(INFO, "Display Init: Done\n");
#endif

开启debug信息后,LK启动阶段中会输出如下的调试信息:

从启动的输出的调试信息,可以知道大概的初始化流程了,调用target_display_init()函数后,会通过panel_id变量的值,选择相应要初始化和显示的LCD屏幕,根据LCD屏幕的相关配置参数,去完成MSM8909芯片的mipi dsi接口的初始化,然后打开panel,进行启动log的显示。

接下来,开始对代码进行分析,对于target_display_init()函数的定义在文件:

msm8909_7./bootable/bootloader/lk/target/msm8909/target_display.c

该函数的定义如下:

void target_display_init(const char *panel_name)
{
uint32_t panel_loop = ;
uint32_t ret = ;
...
do {
target_force_cont_splash_disable(false);
ret = gcdb_display_init(panel_name, MDP_REV_305, MIPI_FB_ADDR);
if (!ret || ret == ERR_NOT_SUPPORTED) {
break;
} else {
target_force_cont_splash_disable(true);
msm_display_off();
}
} while (++panel_loop <= oem_panel_max_auto_detect_panels());
}

在这里,panel_name字符串为空串,panel的选择是通过panel_id进行选择的,在上面的代码中,可以看到,target_display_init()函数调用了gcdb_display_init()函数,该函数在文件:

msm8909_7./bootable/bootloader/lk/dev/gcdb/display/gcdb_display.c

函数的定义如下所示:

int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
{
int ret = NO_ERROR;
int pan_type; /* 通过panel_id选择屏幕,并填充panelstruct和panel.panel_info */
pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info),
&dsi_video_mode_phy_db); if (pan_type == PANEL_TYPE_DSI) { /* 判断panel是否是dsi显示接口 */
init_platform_data(); /* 初始化dsi显示模式的数据 */
if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
dprintf(CRITICAL, "DSI panel init failed!\n");
ret = ERROR;
goto error_gcdb_display_init;
} panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db;
panel.pll_clk_func = mdss_dsi_panel_clock;
panel.power_func = mdss_dsi_panel_power;
panel.pre_init_func = mdss_dsi_panel_pre_init;
panel.bl_func = mdss_dsi_bl_enable;
panel.fb.base = base;
panel.fb.width = panel.panel_info.xres;
panel.fb.height = panel.panel_info.yres;
panel.fb.stride = panel.panel_info.xres;
panel.fb.bpp = panel.panel_info.bpp;
panel.fb.format = panel.panel_info.mipi.dst_format;
} panel.fb.base = base;
panel.mdp_rev = rev; ret = msm_display_init(&panel); error_gcdb_display_init:
display_enable = ret ? : ;
return ret;
}

上面的函数调用后,调用oem_panel_select()函数来选择要初始化和显示的屏幕,在这里是通过panel_id进行选择的,而不是panel_name,oem_panel_select()函数返回panel的接口,如果为mipi dsi接口,初始化一些关于dsi平台的数据,base的显存的地址,对函数和某些成员变量赋值操作后,最后则是调用msm_display_init()函数完成最后的屏幕初始化和启动log的显示。

panel是一个静态的全局变量,为struct msm_fb_panel_data类型,该结构体的定义如下所示:

struct msm_fb_panel_data {
struct msm_panel_info panel_info; /* 描述panel的数据结构 */
struct fbcon_config fb;
int mdp_rev;
int rotate; /* function entry chain */ /* 与msm底层寄存器操作相关函数API */
int (*power_func) (int enable, struct msm_panel_info *);
int (*clk_func) (int enable);
int (*bl_func) (int enable);
int (*pll_clk_func) (int enable, struct msm_panel_info *);
int (*post_power_func)(int enable);
int (*pre_init_func)(void);
};

该结构体中,比较重要的成员为panel_info,它描述了我们LCD屏幕相关的配置信息,还要一系列函数指针,在oem_panel_select()函数中完成了对该结构的函数指针初始化,是与SoC底层寄存器操作相关的API函数:

panel.pll_clk_func = mdss_dsi_panel_clock;   /* panel时钟控制相关*/
panel.power_func = mdss_dsi_panel_power;    /* 电源相关 */
panel.pre_init_func = mdss_dsi_panel_pre_init;   /* 预初始化 */
panel.bl_func = mdss_dsi_bl_enable;   /* panel背光灯使能函数 */

对于上面列出的函数的实现,就不贴了,本文只描述LK阶段中LCM屏幕初始化和显示流程,有兴趣可以自己琢磨源码实现。

最后,则是调用msm_display_init()函数完成LCM屏幕的初始化和log显示,该函数的定义在文件:

msm8909_7./bootable/bootloader/lk/platform/msm_shared/display.c

简化后的函数的定义如下所示:

int msm_display_init(struct msm_fb_panel_data *pdata)
{
int ret = NO_ERROR; panel = pdata;
if (!panel) {
ret = ERR_INVALID_ARGS;
goto msm_display_init_out;
} /* Turn on panel */
if (pdata->power_func) /* 开启panel的电源 */
ret = pdata->power_func(, &(panel->panel_info));
if (ret)
goto msm_display_init_out; /* Enable clock */
if (pdata->clk_func) /* 将dsi时钟使能 */
ret = pdata->clk_func(); ret = msm_fb_alloc(&(panel->fb)); /* 分配显存 */
if (ret)
goto msm_display_init_out; ret = msm_display_config(); /* 显示配置 */
if (ret)
goto msm_display_init_out; fbcon_setup(&(panel->fb));
display_image_on_screen(); /* 启动log载入并显示 */
ret = msm_display_on();
if (ret)
goto msm_display_init_out; /* Turn on backlight */
if (pdata->bl_func) /* 开启背光灯 */
ret = pdata->bl_func();
if (ret)
goto msm_display_init_out; msm_display_init_out:
return ret;
}

从注释中,可以很清楚地知道了流程,msm_display_init()函数,其实就是调用了全局变量panel填充的底层函数API接口,dsi接口初始化完成后,会将启动log图片复制到显示缓存,最后,背光灯打开后,我们就能看到了启动log图片了,这就是LK启动阶段中LCM屏幕的初始化和显示流程了。

3、小结

接下来,总结一下函数的调用过程,如下:

target_display_init()
|
gcdb_display_init()
|
oem_panel_select() /* 根据panel_id选择屏幕 */
|
init_platform_data() /* 初始化dsi接口 */
|
dsi_panel_init()
|
msm_display_init()
|
power_func() /* panel电源开启 */
|
clk_func() /* dis时钟开启 */
|
display_image_on_screen() /* 载入log并显示 */
|
msm_display_on()
|
bl_func() /* 开启panel的背光灯 */

本文,主要简单介绍了MSM8909中Android系统的LK启动阶段中LCM屏幕的初始化和显示流程。

MSM8909中LK阶段LCM屏适配与显示流程分析(二)的更多相关文章

  1. MSM8909中LK阶段LCM屏适配与显示流程分析(一)

    1.前言 在驱动开发中,我们往往需要适配一些新的屏幕或者调试一些屏幕的参数等,对于Qualcomm的MSM8909这款SoC,当启动Android系统时,会有一个LK阶段,该阶段用来启动Linux内核 ...

  2. Android中的跨进程通信方法实例及特点分析(二):ContentProvider

    1.ContentProvider简单介绍 在Android中有些数据(如通讯录.音频.视频文件等)是要供非常多应用程序使用的.为了更好地对外提供数据.Android系统给我们提供了Content P ...

  3. iOS 横竖屏适配 笔记

    研究消息转发机制 已经一周多了,但是 还是没整理出博客, 还是先写一个 项目中遇到的 横竖屏适配问题. // 开启自动转屏 - (BOOL)shouldAutorotate { return YES; ...

  4. mtk lk阶段的lcm流程

    一.lk进入kmain() 1. vendor/mediatek/proprietary/bootable/bootloader/lk/arch/arm/srt0.S bl kmain 二.初始化lk ...

  5. 移动端H5页面高清多屏适配方案

    背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿. 对于移动端开发而言,为了做到页面高清的效果,视觉稿的规范 ...

  6. Phonegap之ios对iPhone6和Plus的闪屏适配 -- xmTan

    故事的发生起于,由于老板强烈要求app在iPhone6和5有一样的工具栏,然后前端妹子用@media为iPhone6和Plus做了样式适配.然后问题来了,竟然奇葩的发现@media样式只对iPhone ...

  7. webapp:移动端高清、多屏适配方案(zz)

    来源: http://sentsin.com/web/1212.html 移动端高清.多屏适配方案 背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉 ...

  8. 解惑好文:移动端H5页面高清多屏适配方案 (转)

    转自:http://mobile.51cto.com/web-484304.htm https://github.com/amfe/lib-flexible/blob/master/src/makeg ...

  9. 移动端高清、多屏适配方案 [来源:http://div.io/topic/1092]

    Lovesueee 发布于 8 月前 移动端高清.多屏适配方案 背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视 ...

随机推荐

  1. 基于python的selenium常用操作方法(1)

    1 selenium定位方法    Selenium提供了8种定位方式. ·         id ·         name ·         class name ·         tag ...

  2. COMP2521: Assignment

    COMP2521: Assignment 2Social Network AnalysisA notice on the class web page will be posted after eac ...

  3. ASP.NET 数据绑定

    控件绑定数据源控件手动方式: DataSourceID = 数据源控件名称下拉框绑定 A.设置Datasource B.DataTextField="name"' //显示的值 C ...

  4. java Integer中隐藏的细节魔鬼!来自面试官的三轮暴击!

    1 第一波暴击!!! 程序员比较实在,一般会说: 那就先上代码 package com.example.demo; public class TestInteger { public static v ...

  5. Elasticsearch Query DSL 语言介绍

    目录 0. 引言 1. 组合查询 2. 全文搜索 2.1 Match 2.2 Match Phase 2.3 Multi Match 2.4 Query String 2.5 Simple Query ...

  6. PHP作用域和文件夹操作

    1.作用域      1.1变量作用域      1.全局变量:在函数外面       2.局部变量:在函数里面,默认情况下,函数内部是不会访问函数外部的变量       3.超全局变量:可以在函数内 ...

  7. MySqlBulkLoader 中文乱码

    MySQL驱动:MySqlConnector GitHub地址:https://github.com/mysql-net/MySqlConnector.git 文档地址:https://mysql-n ...

  8. Windows下Django项目搭建流程

    1.创建虚拟环境 virtualenv test 2.进入虚拟环境 source ./项目名/Scripts/activate 3.创建项目 django-admin startproject 项目名 ...

  9. UITableView总结

    .协议介绍 UITableViewDataSource() UITableViewDelegate(常用) .刷新 下拉刷新: 上拉刷新 .搜索 .重用 自定义cell 不使用重用方法 注册Cell ...

  10. WC 个人项目 ( node.js 实现 )

    基于 node.js 的 wordCounter 个人项目 GitHub 项目地址:https://github.com/KofeChen/node.js-WordCounter 实现功能: 能够匹配 ...