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