安卓屏幕驱动移植

2019-07-13 02:21发布

 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(颜 {MOD}),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-porch、mdss-dsi-h-front-porch、mdss-dsi-h-pulse-width、mdss-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