1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 基于msm8916移植lcd流程--LK

基于msm8916移植lcd流程--LK

时间:2021-02-15 21:25:29

相关推荐

基于msm8916移植lcd流程--LK

插一小句,别介意哈,公众号:二校五叔

本篇先不讲解lcd代码在kernel和lk中的流程,讲解基于msm8916,移植ILI9881C型号的lcd

首先要准备一下东西:屏IC 规格书,初始化代码,硬件原理图

屏IC 规格书—>获得时序等数据

初始化代码 —>获得初始化屏幕ic的命令,用于编写屏的.h文件(lk)和.dtsi文件(kernel)

硬件原理图 —>获得打开背光、reset等有关电源的引脚,在代码中拉高拉低

首先从规格书中可以获得以下一些信息:

得到的信息如下:

水平脉冲宽度(qcom,mdss-dsi-h-pulse-width,Hsync)为30

水平后沿值(qcom,mdss-dsi-h-back-porch,HBP)为30

水平前沿值(qcom,mdss-dsi-h-front-porch,HFP)为38

面板宽度(qcom,mdss-dsi-panel-width,HAdr)为720

垂直脉冲宽度(qcom,mdss-dsi-v-pulse-width,Vsync)为6

垂直后沿值(qcom,mdss-dsi-v-back-porch,VBP)为8

垂直前沿值(qcom,mdss-dsi-v-front-porch,VFP)为10

面板高度(qcom,mdss-dsi-panel-height,VAdr)为1280

一、在LK中移植LCD

1.首先要准备好LCD的.h文件

因为ILI9881C型号的lcd在高通的推荐供应商列表中,所以可以在高通官网中找到类似的patch,里面有相关的.h代码,仿照来合成需要的.h文件。

在这个.h文件中,需要修改的地方有如下:

static struct panel_resolution cpt_claa053wd41_3xb_ili9881_720p_video_panel_res = {

720, 1280, 38, 30, 30, 0, 10, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0

};

这个结构体包含了显示屏的许多参数,在Panel.h中可以找到其结构体如下:

typedef struct panel_resolution{uint16_t panel_width;uint16_t panel_height;uint16_t hfront_porch;uint16_t hback_porch;uint16_t hpulse_width;uint16_t hsync_skew;uint16_t vfront_porch;uint16_t vback_porch;uint16_t vpulse_width;uint16_t hleft_border;uint16_t hright_border;uint16_t vtop_border;uint16_t vbottom_border;uint16_t hactive_res;uint16_t vactive_res;uint16_t invert_data_polarity;uint16_t invert_vsync_polarity;uint16_t invert_hsync_polarity;};

根据屏的信息,把数据填入相应的位置。(上面结构体是改好的)

static const uint32_t cpt_claa053wd41_3xb_ili9881_720p_video_timings[] = {

0x80, 0x20, 0x11, 0x00, 0x3C, 0x38, 0x1A, 0x20, 0x13, 0x03, 0x04, 0x00

};

指定面板 PHY 定时设置的长度为 12 的数组。这组数据一般是根据计算得到,在这里我使用的是以前项目使用的数据。

static struct panel_timing cpt_claa053wd41_3xb_ili9881_720p_video_timing_info = {

0, 4, 0x04, 0x1b

};

0x04是指qcom,mdss-dsi-t-clk-post,指定模式切换后的字节时钟周期。

0x1b是指 qcom,mdss-dsi-t-clk-pre,指定模式切换前的字节时钟周期。

这两个数据都是沿用上一个项目的数据。

static struct panel_reset_sequence cpt_claa053wd41_3xb_ili9881_720p_video_reset_seq = {

{1, 0, 1, }, {50, 20, 50, }, 2

};

对应的结构体如下:

typedef struct panel_reset_sequence {//引脚的状态,数据对应的含义分别为,拉低,拉高,拉低uint8_t pin_state[TOTAL_RESET_GPIO_CTRL]; //拉高、拉低的状态持续的时间,分别为50、20和50毫秒uint32_t sleep[TOTAL_RESET_GPIO_CTRL];//pin脚的两个方向uint8_t pin_direction;};

看产品规格书可以获得此数据:

只要符合图片的值就可以了

static struct backlight cpt_claa053wd41_3xb_ili9881_720p_video_backlight = {

1, 1, 255, 100, 2, “BL_PWM”

};

对应的结构体如下:

typedef struct backlight {uint16_t bl_interface_type;uint16_t bl_min_level;uint16_t bl_max_level; //背光的最大值为255uint16_t bl_step;uint16_t bl_pmic_controltype;char*bl_pmic_model; //背光的模式为PWM模式};

最麻烦的是,利用厂家的初始化代码合成.h文件的以下结构体(一般厂商会直接给合成后的,这次没有):

首先看一下厂家给的初始化代码:

Generic_Long_Write_3P(0xFF,0x98,0x81,0x03);Generic_Short_Write_1P(0x01,0x00);Generic_Short_Write_1P(0x02,0x00);...Generic_Short_Write_1P(0x35,0x00);Generic_Short_Write_NP(0x11);Delay(120);Generic_Short_Write_NP(0x29); // Display OnDelay(20);

根据下载的patch中的例子,可以模仿有:

static char cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd0[] = {0x04, 0x00, 0x39, 0xC0, //0x04, 0x00--有效字节为四个,0x39--表示写,0xC0--ECC校验0xFF, 0x98, 0x81, 0x03, //0xFF, 0x98,0x81, 0x03--有效数据};static char cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd1[] = {0x02, 0x00, 0x39, 0xC0,//0x02, 0x00--两个有效字节0x01, 0x00, 0xFF, 0xFF,//0x01, 0x00--有效数据 0xFF, 0xFF--crc校验};...static char cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd192[] = {0x11, 0x00, 0x05, 0x80 //最后两个命令有点不一样,0x11--有效数据};static char cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd193[] = {0x29, 0x00, 0x05, 0x80 //0x29};static struct mipi_dsi_cmd cpt_claa053wd41_3xb_ili9881_720p_video_on_command[] = {{0x8, cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd0, 0x00},{0x8, cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd1, 0x00},...{0x4, cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd192, 0x78},//0x78为延迟时间,十进制为120{0x4, cpt_claa053wd41_3xb_ili9881_720p_video_on_cmd193, 0x00}};#define CPT_CLAA053WD41_3XB_ILI9881_720P_VIDEO_ON_COMMAND 194

mipi_dsi_cmd对应的结构体如下:

struct mipi_dsi_cmd {int size; //大小char *payload; //命令int wait; //等待时间uint8_t cmds_post_tg;};

从中可以看出,每一条命令写入一个cpt_claa053wd41_3xb_ili9881_720p_video_on_cmdx[]中,最后在汇总到static struct mipi_dsi_cmd结构体中。

至此,.h文件完成了。

2.接下来的步骤是使得lk代码可以调用这个.h文件

在display.h中的枚举类型中,添加这个屏

enum {JDI_1080P_VIDEO_PANEL,...XXX_PANEL,UNKNOWN_PANEL};

在bootable/bootloader/lk/target/msm8916/oem_panel.c中

首先,添加头文件#include “include/xxx.h” —>上一步的头文件

接着在屏列表信息中添加新屏:

static struct panel_list supp_panels[] = {{"jdi_1080p_video", JDI_1080P_VIDEO_PANEL},...{"xxx_video", XXX_PANEL},};//屏列表结构体struct panel_list {char name[MAX_PANEL_ID_LEN];uint32_t id;};

在进入oem_panel_select函数中,事先要知道hw_id是什么,switch后进入相应的分支,进行如下赋值:

panel_id = XXX_PANEL;

在init_panel_data函数中,利用switch (panel_id),找到相应的地方,给panelstruct结构体赋值

//panelstruct结构体typedef struct panel_struct{struct panel_config *paneldata;struct panel_resolution*panelres;struct color_info *color;struct videopanel_info*videopanel;struct commandpanel_info *commandpanel;struct command_state *state;struct lane_configuration *laneconfig;struct panel_timing *paneltiminginfo;struct panel_reset_sequence *panelresetseq;struct backlight *backlightinfo;struct fb_compression fbcinfo;};

//赋值的代码,case XXX_PANEL:panelstruct->paneldata = &XXX_video_panel_data;panelstruct->panelres= &XXX_video_panel_res;panelstruct->color = &XXX_video_color;panelstruct->videopanel = &XXX_video_video_panel;panelstruct->commandpanel = &XXX_video_command_panel;panelstruct->state = &XXX_video_state;panelstruct->laneconfig = &XXX_video_lane_config;panelstruct->paneltiminginfo= &XXX_video_timing_info;panelstruct->panelresetseq= &XXX_video_reset_seq;panelstruct->backlightinfo = &XXX_video_backlight;pinfo->mipi.panel_cmds= XXX_video_on_command;pinfo->mipi.num_of_panel_cmds= XXX_VIDEO_ON_COMMAND;memcpy(phy_db->timing,XXX_video_timings, TIMING_SIZE);break;

至此.h文件的信息就可以被代码使用了

3.根据原理图,在代码某处拉高引脚

从中可以看出,要拉高的引脚为GPIO_24和GPIO_25,分别为点亮背光和reset引脚

在bootable\bootloader\lk\target\msm8916\target_display.c中,

int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,struct msm_panel_info *pinfo){...//在Display.h中定义为24号引脚gpio_tlmm_config(vdd_enable_gpio.pin_id, 0,vdd_enable_gpio.pin_direction, vdd_enable_gpio.pin_pull,vdd_enable_gpio.pin_strength,vdd_enable_gpio.pin_state);gpio_set_dir(vdd_enable_gpio.pin_id, 2); //拉高//在Display.h中定义为25号引脚gpio_tlmm_config(reset_gpio.pin_id, 0,reset_gpio.pin_direction, reset_gpio.pin_pull,reset_gpio.pin_strength, reset_gpio.pin_state);gpio_set_dir(reset_gpio.pin_id, 2);//拉高...}

display.h中定义了显示屏相关的引脚,和一些相关的宏以及配置信息

panel.h中定义了显示屏代码中相关的结构体

4.注意

有些屏的稳压器tps系列的,需要手动拉高引脚,例如97号引脚

在新的代码中添加显示屏,一般要在bootable/bootloader/lk/platform/msm8916/中添加和初始化相关i2c的接口,需要改变的文件为(一般可以仿照前后代码写):gpio.c、iomap.h、msm8916-clock.c

5.完成,下篇讲解在kernel中添加显示屏

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。