转自: https://blog.csdn.net/zhahaobing2017/article/details/52951159

android屏幕启动流程

点亮一个新屏幕,下面以8909-x26的屏幕为例。

启动引导部分:

一、添加对应的.h文件

首先添加一个.h头文件,命名为panel_ili9806e_fwvga_hsd_helitai_x26_video.h,该文件放在路径/bootable/bootloader/lk/dev/gcdb/include/下面。因为这里包含了各种型号的屏幕的头文件,也就是初始化代码,并且放在了启动引导目录。根据命名,知道该屏幕的IC(芯片)是ili9806e,屏幕分辨率是fwvga,玻璃是HSD,模组厂是helitai(合力泰)。

屏幕工作的关键是芯片、玻璃、模组厂!

在头文件里面会对屏幕进行初始化,如backlight(背光),lane(通道),color(颜色),timing_information(定时)等。

/*---------------------------------------------------------------------------*/

/* Backlight setting                                                         */

/*---------------------------------------------------------------------------*/

static struct backlight ili9806e_fwvga_hsd_helitai_x26_video_backlight = {

1, 1, 4095, 100, 1, "PMIC_8941"

};

/*---------------------------------------------------------------------------*/

/* Lane configuration                                                        */

/*---------------------------------------------------------------------------*/

static struct lane_configuration ili9806e_fwvga_hsd_helitai_x26_video_lane_config = {

2, 1, 1, 1, 0, 0, 0

};

/*---------------------------------------------------------------------------*/

/* Panel color information                                                   */

/*---------------------------------------------------------------------------*/

static struct color_info ili9806e_fwvga_hsd_helitai_x26_video_color = {

24, 0, 0xff, 0, 0, 0

};

static char ili9806e_fwvga_hsd_helitai_x26_video_on_cmd0[] = {

0x06, 0x00, 0x39, 0xC0,

0xFF, 0xFF, 0x98, 0x06,

0x04, 0x01, 0xFF, 0xFF,

};

......

二、oem_penel.c文件添加自己的新屏幕(路径:bootable/bootloader/lk/target/msm8909_x26_q1/

(1).首先添加屏幕初始化的头文件”panel_ili9806e_fwvga_hsd_helitai_x26_video.h“,即:

#include “include/panel_ili9806e_fwvga_hsd_helitai_x26_video.h”.

(2).在枚举类型中添加自己的新屏幕:

其中该枚举类型在文件mipi_panel_reg_id.h中(路径:./bootable/bootloader/lk/platform/msm_shared/include/

enum {

......

ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL,//add your panel.

UNKNOWN_PANEL

};

(3).在函数init_panel_data()中,添加自己的板子的case语句,即新屏幕的数据初始化。

case ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL:

panelstruct->paneldata          = &ili9806e_fwvga_hsd_helitai_x26_video_panel_data;

panelstruct->panelres           = &ili9806e_fwvga_hsd_helitai_x26_video_panel_res;

panelstruct->color              = &ili9806e_fwvga_hsd_helitai_x26_video_color;

panelstruct->videopanel         = &ili9806e_fwvga_hsd_helitai_x26_video_video_panel;

panelstruct->commandpanel       = &ili9806e_fwvga_hsd_helitai_x26_video_command_panel;

panelstruct->state              = &ili9806e_fwvga_hsd_helitai_x26_video_state;

panelstruct->laneconfig         = &ili9806e_fwvga_hsd_helitai_x26_video_lane_config;

panelstruct->paneltiminginfo    = &ili9806e_fwvga_hsd_helitai_x26_video_timing_info;

panelstruct->panelresetseq      = &ili9806e_fwvga_hsd_helitai_x26_video_reset_seq;

panelstruct->backlightinfo      = &ili9806e_fwvga_hsd_helitai_x26_video_backlight;

pinfo->mipi.panel_cmds          = ili9806e_fwvga_hsd_helitai_x26_video_on_command;

pinfo->mipi.num_of_panel_cmds   = ARRAY_SIZE(ili9806e_fwvga_hsd_helitai_x26_video_on_command);

memcpy(phy_db->timing,ili9806e_fwvga_hsd_helitai_x26_video_timings, TIMING_SIZE);

pinfo->mipi.signature = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_SIGNATURE;

break;

(4).在函数oem_panel_select()中,必须让控制板的id选择自己新添加的,否则,开机屏幕不亮。

case HW_PLATFORM_QRD:

if (lcm_gpio_id == 1) {

panel_id = ILI9806E_FWVGA_HSD_HUASHI_VIDEO_PANEL;

} else {

panel_id = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL;//add your panel

}

break;

到此,lk(little kernel)部分,屏幕相关的工作就完成了!

程序执行流程:

(1)当按下开机键,程序自然就是从main函数开始执行,不过main是C 语言的叫法。(具体可以参见BIOS过程)。

(2)程序运行到APP_START(aboot)

.init = aboot_init,

APP_END

就会调用aboot_init()函数。aboot意为“引导”。

(2)引导的时候自然有屏幕的启动和初始化,aboot_init()函数调用target_display_init()函数,条件是DISPLAY_SPLASH_SCREEN为1。

(3)在函数target_display_init()最后,ret = gcdb_display_init();程序自然跳转到函数gcdb_display_init()

(4)在gcdb_display_init中首先调用oem_panel_select()函数,然后又跳转到oem_panel_select函数。

hw_id的值由board_hardware_id()返回,返回了11,然后进入qrd路线。107行知lcm_gpio_id=0,所以在else分支(lcm_gpio_id =0)下添加自己的屏幕,即将panel_id设置为ILI9806E_FWVGA_HSD_HELITAI_x26

_VIDEO_PANEL.(panel_id = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL)。

(5)oem_panel_select()函数最后return init_panel_data(),程序进入init_panel_data(),

(6)在init_panel_data()中已经添加了自己的case语句,根据第109行,Func:oem_panel_select panel_id = 17 ,说明,已经选择了添加的新屏幕来初始化,因为枚举变量中自己新添加的屏幕(ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL)刚好是第17个。这样panel_ili9806e_fwvga_hsd_helitai_x26_video.h文件参数全部用到。最后返回pan_type.

(7)程序继续在oem_panel_select()中,也返回pan_type,然后退出oem_panel_select()函数。回到gcdb_display_init()中,接收了pan_type,所以日志117行打印出pan_type是PANEL_TYPE_DSI。

(8)在gcdb_display_init中自然初始化DSI下的项目,如:

panel.fb.width,

panel.fb.height,

panel.fb.stride,

panel.fb.bpp

...

(9)第117行,display_enable = 1,ret = 0;gcdb_display_init()返回,说明屏幕bootloader部分完成,新屏幕可用,成功返回0.然后回到函数target_display_init()。

(10)第118行, in function:target_display_init,line:350,ret = 0.说明 target_display_init函数也成功结束。

(11)到此开机中屏幕的点亮结束了。

编译bootloader: make aboot -j6

烧写bootloader: fastboot flash aboot emmc_appsboot.mbn

附log:

......

106 [1450][1450]#mipi_get_lcm_pin_id().pin[8]_status = 0

107 ------ Func:oem_panel_select lcm_gpio_id = 0 ----------

108 hw_id = 11

109 -Func:oem_panel_select    panel_id = 17 -------

110 in function:gcdb_display_init,line:379,panel_type is PANEL_TYPE_DSI

111 in function:gcdb_display_init,line:386,panel init successfully!

112 [1540][1540] Config MIPI_VIDEO_PANEL.

113 [1690][1690] Panic Lut0 la90000 Lut1 ff Robest 0

114 [1700][1700] Turn on MIPI_VIDEO_PANEL.

115 [1720][1720] Video lane tested successfully

116 in function:gcdb_display_init,line:419,panel_type is PANEL_TYPE_DSI

117 display_enable = 1,ret = 0

118 in function:target_display_init,line:350,ret = 0

......

内核部分:

三、 (1)在路径kernel/arch/arm/boot/dts/msm8909_x26_q1下添加内核配置文件: dsi-panel-ili9806e-fwvga-hsd-helitai-x26-video.dtsi.

该文件是屏幕的配置文件,屏幕休眠唤醒时会走此文件。配置项目包括:

mdss-dsi-h-back-porchmdss-dsi-h-front-porchmdss-dsi-h-pulse-widthmdss-dsi-h-sync-skew等。

具体可参考文件:kernel/Documentation/devicetree/bindings/fb

其中在文件开头有一变量 dsi_ili9806e_fwvga_hsd_hlt_x26_vid,其值必须和启动引导部分的结构体ili9806e_fwvga_hsd_helitai_x26_video_panel_data的第一个成员相同。

引导部分和内核相关联就是这个panel_node_id, 这样屏幕待机之后唤醒就会找到引导时候的初始化屏幕路线。引导部分和内核部分的桥梁就是panel_node_id(变量dsi_ili9806e_fwvga_hsd_hlt_x26_vid), 他写进cmd-line,最后传给内核。

(2)在文件msm8909-mdss-panels.dtsi添加头文件:

即添加一行代码:#include "dsi-panel-ili9806e-fwvga-hsd-helitai-x26-video.dtsi"

其中该文件是屏幕的配置文件

(3)添加自己的屏幕(注意语法,不要漏掉分号):

&dsi_ili9806e_fwvga_hsd_hlt_x26_vid {

       qcom,cont-splash-enabled;

};

(4)将id设置为自己的id,这一步很重要,否则,开机屏幕正常,但是一旦休眠,再次唤醒手机,手机就是白屏,因为,唤醒虽然走的是开机的初始化路线,但是在这里却进入了另一种型号的屏幕了!

&mdss_dsi0 {

/*qcom,dsi-pref-prim-pan = <&dsi_ili9806e_fwvga_video>;*/

qcom,dsi-pref-prim-pan = <&dsi_ili9806e_fwvga_hsd_hlt_x26_vid>;//在这一行改为自己的屏幕

pinctrl-names = "mdss_default", "mdss_sleep";

  ......

};

到此,内核部分修改完成!

编译:make bootimage -j6

烧写: sudo fastboot flash boot boot.img

标签: aosp

添加新评论