MTK平台LCM驱动加载设置流程

LCM_DRIVER nt35521_hd720_dsi_vdo_boe_lcm_drv =
{
.name = “nt35521_hd720_dsi_vdo_boe”,
.set_util_funcs = lcm_set_util_funcs,
.get_params = lcm_get_params,
.init = lcm_init,
.suspend = lcm_suspend,
.resume = lcm_resume,
.compare_id = lcm_compare_id,
};

struct LCM_setting_table { 
unsigned char cmd; // 命令地址 
unsigned char count; // 寄存器值的个数 
unsigned char para_list[128]; //寄存器的值 
};

static struct LCM_setting_table lcm_initialization_setting[] = { 
{0xFF, 4, {0xAA,0x55,0xA5,0x80}}, //就是LCM_setting_table结构体的三个成员。 

mipi屏的话,MTK平台的是不同的屏只要换这个初始化设置的代码就可以跑起来的,当然有些屏ic已经有程序,不需要再从初始化里下载这段代码。只要上电时序和配置对了就可以跑起来。

效果调试最多的是调试水波纹,可以调试vcom对应的寄存器。竖的波纹好像和pll_clk有关,可以调试试一下。

初始化里的这部分延时不能少。0x11和0x29是用来下载这段代码到lcd ic的,还有其它下载模式。比如:0x10和0x28.

{0x11,  1,  {0x00}},
{REGFLAG_DELAY, 120, {}},

{0x29,  1,  {0x00}},
{REGFLAG_DELAY, 20, {}},

{REGFLAG_END_OF_TABLE, 0x00, {}},

static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = { } 
这个是睡眠设置的寄存器

static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = {}

这个是深度睡眠设置的寄存器

static void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update){}

这个是讲上面这些设置寄存器的数组push到ic里面去的函数。参数:结构体数组,个数,强制更新吧1次(我理解的)

重点内容

驱动实现部分

static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util) 

memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS)); 
}

lcm 驱动框架提供给驱动开发者的接口函数,将util复制到lcm_util。

static void lcm_get_params(LCM_PARAMS *params) 

memset(params, 0, sizeof(LCM_PARAMS)); 
params->type = LCM_TYPE_DSI;

params->width  = FRAME_WIDTH;  //宽
params->height = FRAME_HEIGHT; //高

if (LCM_DSI_CMD_MODE)
    params->dsi.mode   = CMD_MODE;
else
    params->dsi.mode   = SYNC_PULSE_VDO_MODE;
endif
// DSI
/* Command mode setting */
params->dsi.LANE_NUM                = LCM_FOUR_LANE;
params->dsi.data_format.format              = LCM_DSI_FORMAT_RGB888;

//video mode timing
    params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888;

params->dsi.vertical_sync_active                = 4; // 垂直同步信号的宽度
params->dsi.vertical_backporch              = 40;
params->dsi.vertical_frontporch             = 40;
params->dsi.vertical_active_line                = FRAME_HEIGHT;

params->dsi.horizontal_sync_active          = 4;
params->dsi.horizontal_backporch                = 82;
params->dsi.horizontal_frontporch               = 82;
params->dsi.horizontal_active_pixel         = FRAME_WIDTH;

//improve clk quality
params->dsi.PLL_CLOCK = 240; //this value must be in MTK suggested table
params->dsi.compatibility_for_nvk = 1;
params->dsi.ssc_disable = 1;

}

这个是lcm的配置部分,调试驱动必然要改的地方。 
MIPI接口:一共有三种接口:DBI(也做CPU或MCU接口)、DPI(也叫RGB接口)、DSI. 
在使用DSI接口时,目前6735支持到4条data lane,加上一条clock lane.我们采用的是DSI的

params->dsi.vertical_sync_active                = 4;
params->dsi.vertical_backporch              = 40;
params->dsi.vertical_frontporch             = 40;

params->dsi.horizontal_sync_active          = 4;
params->dsi.horizontal_backporch                = 82;
params->dsi.horizontal_frontporch               = 82;

这几个数据要看datasheet,才可以,调试的关键地方。

VSYNC:垂直同步信号(帧同步信号) , 通知LCD屏新的一帧显示
HSYNC:水平同步信号(行同步脉冲信号),代表刷新一行
VCLK:象素时钟信号(一个像素代表一个点)
VD[23:0]:LCD像素数据输出端口(RGB信号线)
VDEN:数据使能信号(TFT),代表发送数据有效

LEND:行结束信号信号,代表一行结束


上面时序图上各时钟延时参数的含义如下:(这些参数的值,LCD产生厂商会提供相应的数据手册)

VBPD(vertical back porch): 表示在一帧图像开始时,垂直同步信号以后的无效的行数,对应驱动中的upper_margin;

VFBD(vertical front  porch):表示在一帧图像结束后,垂直同步信号以前的无效的行数,对应驱动中的lower_margin;
VSPW(vertical sync pulse  width):表示垂直同步脉冲的宽度,用行数计算,对应驱动中的vsync_len;
HBPD(horizontal back porch):表示从水平同步信号开始到一行的有效数据开始之间VCLK的个数,对应驱动中的left_margin;
HFPD(horizontal front  porth):表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数,对应驱动中的right_margin;
HSPW(horizontal sync  pulse width):表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len;

params->dsi.PLL_CLOCK = 240; lcm的频率,更据实际情况改动,这个一般mtk的都会影响gps的信号强弱。

static void lcm_id_pin_handle(void) 

mt_set_gpio_pull_select(GPIO_DISP_ID0_PIN,GPIO_PULL_UP); 
mt_set_gpio_pull_select(GPIO_DISP_ID1_PIN,GPIO_PULL_DOWN); 

这个防止漏电的

static void lcm_init(void) 

//enable VSP & VSN 
lcm_util.set_gpio_out(GPIO_LCD_BIAS_ENP_PIN, GPIO_OUT_ONE); 
lcm_util.set_gpio_out(GPIO_LCD_BIAS_ENN_PIN, GPIO_OUT_ONE); 
msleep(50); 
//reset high to low to high 
lcm_util.set_gpio_out(GPIO_DISP_LRSTB_PIN, GPIO_OUT_ONE); 
mdelay(5); 
lcm_util.set_gpio_out(GPIO_DISP_LRSTB_PIN, GPIO_OUT_ZERO); 
mdelay(5); 
lcm_util.set_gpio_out(GPIO_DISP_LRSTB_PIN, GPIO_OUT_ONE); 
msleep(10);

lcm_id_pin_handle();

push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1);  

// when phone initial , config output high, enable backlight drv chip 
lcm_util.set_gpio_out(GPIO_LCD_DRV_EN_PIN, GPIO_OUT_ONE);

LCD_DEBUG("uboot:boe_nt35521_lcm_init\n");

//只要是初始化的上电时序,reset脚1 0 1(高低高),vsp和vsn,背光使能。mipi的屏都是一样的。
 

 

Mt65xx_lcm_list.c 函数中通过lcm_driver_list调用到lcm模组驱动函数。

Disp_lcm.c文件中通过disp_lcm_probe函数来调用lcm_driver_list数组,

Primary_display.c文件中通过primary_display_init函数调用
disp_lcm_probe(lcm_name, LCM_INTERFACE_NOTDEFINED)

在mtkfb.c文件中通过mtkfb_probe函数调用
primary_display_init(mtkfb_find_lcm_driver(), lcd_fps);

通过数据结构platform_driver挂接的到platform总线上

 

遇到一些问题的处理方法
   1、开机时背光亮了屏幕黑屏:
     a、mipi的lane数量有没有配置对、核对硬件原理图
     b、核对屏初始化参数是否跟供应商提供的一致,有时候自己改错了
     c、测量屏的2.8V供电是否有,复位引脚gpio有没有配置对,必要时用示波器测量时序
     d、查看一下开机串口log,有没有屏相关的报错
     e、换一块主板或者换个屏试试
     f、找负责硬件原理图设计的人员也帮忙看看,实在解决不了再找FAE协助,有可能要修改屏初始化参数
      或porch参数

   2、开机时花屏:
     a、检查一下logo配置是否正确,查看logo原始图片分辨率对不对
     b、检查代码中分辨率设置对不对
     c、很多时候是需要FAE协助修改屏初始化参数

   3、闪屏、白屏、有条纹、竖线、颜色不对等效果问题:
     a、先去查看供电、复位时序是否正常
     b、有时候需要调整mipi时钟频率(lcm_get_params函数中的PLL_CLOCK)或者porch参数
     c、一般是需要FAE协助修改屏初始化参数
     d、有时候出现闪屏需要用到屏幕录像来对比分析,命令是adb shell screenrecord /sdcard/record.mp4
————————————————

计算DSI数据速率的方式,以及如何配置时钟clk的方式 [SOLUTION] 1、DSI vdo mode下的数据速率data_rate的计算公式为: 
Data rate= (width+VSA+VBP+VFP)*(height+HSA+HBP+HFP)* total_bit_per_pixel*frame_per_second/total_lane_num

 

2、DSI cmd mode下的数据速率data_rate的计算公式为: 
Data rate= width*height*1.2* total_bit_per_pixel*frame_per_second/total_lane_num


参数注释: 
data_rate : 表示的是数据速率 
width,height  :屏幕分辨率 
VSA VBP VFP :DSI vdo mode的vertical porch配置参数 
HSA HBP HFP :DSI vdo mode的horizontal porch配置参数 
total_bit_per_pixel :表示的是一个pixel需要用几个bit来表示,比如RGB565的话就是16个bit 
frame_per_second :就是我们通常看到的fps,叫做帧率,表示每秒发送多少个帧,一般是60帧每秒 
total_lane_num :表示的是data lane的对数。

 

3、DSI采用的是双边采样,则clk等于数据速率的一半,因此: clk=data_rate/2 
有两种配置clk的方式,第一种方式配置四个参数得到,第二种配置方式直接配置频率,建议采用第二种。 
第一种方式:
    params->dsi.pll_div1   = ;  //配置范围为0,1,2,3的时候,对应的div1_real等于1,2,4,4     params->dsi.pll_div2   = ;  //配置范围为0,1,2,3的时候,对应的div2_real等于1,2,4,4     params->dsi.fbk_div   = ;  //范围 0..63     params->dsi.fbk_sel   = ;  //配置范围为0,1,2,3的时候,对应的fbk_sel_real等于1,2,4,4            输出频率=26MHz*fbk_div*(2*fbk_sel_real)/(div1_real*div2_real) 第二种方式: 
    params->dsi.PLL_CLOCK = LCM_DSI_6589_PLL_CLOCK_234;//这里举例89平台,使用一个宏,表示配置的clk等于234MHz。但是在89之后的平台,使用直接配置一个频率数字的方式,比如234,表示234MHZ)

 

4、在lcm porting过程中,这些参数都定义在lcm_drv.h文件中的LCM_DSI_PARAMS结构体中,随着平台的发展,或许有所不同,但是基本原理都是一致的,如何配置clk的大小,请先根据自己的帧率、像素格式、porch值、屏的分辨率、data lane对数等计算出data_rate,然后计算出clk。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部