lcd 显示相关的文件 ,这些后面分析 ,先怎么添加一个新的LCD驱动
./kernel-3.18/drivers/misc/mediatek/video/mt6735/videox/primary_display.c
./kernel-3.18/drivers/misc/mediatek/video/mt6735/videox/disp_lcm.c
./kernel-3.18/drivers/misc/mediatek/video/common/mtkfb.c
./kernel-3.18/drivers/misc/mediatek/video/mt6735/dispsys/ddp_dpi.c
./kernel-3.18/drivers/misc/mediatek/video/mt6735/dispsys/ddp_dsi.c
./kernel-3.18/drivers/misc/mediatek/video/mt6735/dispsys/ddp_manager.c
./kernel-3.10/drivers/misc/mediatek/videox/mt6735/mt6735m/disp_drv_platform.h
./kernel-3.18/drivers/misc/mediatek/video/mt6735/videox/mt6735m/disp_drv_platform.h
./kernel-3.18/drivers/misc/mediatek/lcm/mt65xx_lcm_list.c
一:基础知识
1.驱动IC
st7701s
nt33510
otm8108
jd9161
ili9163
hx8369
2.驱动玻璃
IVO 龙腾
CMI 奇美
CTC 声超
OTM 天马
BOE
CPT
HSD 华显
3.驱动接口
MIPI接口:
一共有三种接口:
typedef enum
{
LCM_TYPE_DBI = 0,
LCM_TYPE_DPI,
LCM_TYPE_DSI
} LCM_TYPE;
DPI(display pixel interface)(也叫RGB接口)、 params->type = LCM_TYPE_DPI;
DPI就是常说的RGB接口,采用普通的同步、时钟、信号线来传输特定数据,
采用SPI等控制线完成命令控制。(所谓的RGB接口指的是必须用BB的controller,数据必须通过点,行,帧clk等由cpu去控制数据显示到LCD上面)
DBI(display bus interface)(也做CPU或MCU接口)、(公司M8项目采用)params->type = LCM_TYPE_DBI;
DBI 也是常说的cpu接口,和DPI类似,DPI的控制和数据是分离的,DBI的控制和数据是复用的. (所谓cpu接口指的是lcd controller内置于LCD屏中)
DSI.(display serial interface) (大部分都在用)
typedef enum
{
CMD_MODE = 0,
SYNC_PULSE_VDO_MODE = 1,
SYNC_EVENT_VDO_MODE = 2,
BURST_VDO_MODE = 3
}
params->dsi.mode = CMD_MODE; /params->dsi.mode = SYNC_PULSE_VDO_MODE;
DSI是一种串行传输方式,DSI传输的数据是封装成包的。DSI分 video 模式 command 模式
DSI(video mode)和传统RGB模式类似,由BB控制持续刷新显示,LCD就不需要frame buffer。节省成本
DCS(command mode)LCD上面有一个framebuffer,有个定时控制器会从frame buffer取出数据自动刷新。省电。
4.屏的分辨率
QVGA -- 320*240 // ldpi ro.sf.lcd_density=120
VGA -- 640*480
HVGA -- 480*320 //4:3 mdpi ro.sf.lcd_density=160
wvga -- 800*480 //5:3 hdpi ro.sf.lcd_density=240
fwvga -- 854*480 //16:9 hdpi ro.sf.lcd_density=240
QHD -- 960*540 //16:9 hdpi ro.sf.lcd_density=240
hd/hd720 -- 1280*720 //标清 xhdpi ro.sf.lcd_density=320
fhd -- 1920*1080//高清 xxhdpi ro.sf.lcd_density=320
驱动中
#define FRAME_WIDTH (720)
#define FRAME_HEIGHT (1280)
5. LCD 刷新率 控制在50fps-65fps 怎么算
. 由公式计算,apk 会比 公式 低几个fps(如算出60fps,apk实测约58fps)
1 公式一: 后期实现的
1、DSI vdo mode下的数据速率data_rate的大致计算公式为:
mtk : (Data rate) = (height + vsa + vbp + vfp) * (width + 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的对数。
DSI采用的是双边采样,则clk等于数据速率的一半,也就是说一个clk周期内传送2位,所以你计算出来的值还要除以2
每线 PLL_CLOCK(clk )= Data rate/2;
2:早期 原始的
// Bit rate calculation
params->dsi.pll_div1=1; // div1=0,1,2,3;div1_real=1,2,4,4
params->dsi.pll_div2=0; // div2=0,1,2,3;div2_real=1,2,4,4
params->dsi.fbk_div =13; // fref=26MHz, fvco=fref*(fbk_div+1)*2/(div1_real*div2_real)
(26MHz * (fbk_div + 1) * 2) / (div1_real * div2_real) = (26 * 14 * 2) / (2 * 1) = 364。 Data Rate=clock * 2
二:增加新的LCD驱动
1. 修改 device/teksun/hys6737m_35_m0/ProjectConfig.mk
指定分辨率
+BOOT_LOGO = cu_fwvga
+LCM_HEIGHT = 854
+LCM_WIDTH = 480
修改vendorkernel-3.18/arch/arm/configs/hys6737m_35_m0_debug_defconfig
kernel-3.18/arch/arm/configs/hys6737m_35_m0_defconfig
指定LCM 分辨率
+CONFIG_CUSTOM_KERNEL_LCM="k801_st7701S_fwvga_dsi_vdo_cmi"
+CONFIG_LCM_HEIGHT="854"
+CONFIG_LCM_WIDTH="480"
修改vendor vendor/mediatek/proprietary/bootable/bootloader/lk/project/hys6737m_35_m0.mk
指定LCM 分辨率
+CUSTOM_LK_LCM="k801_st7701S_fwvga_dsi_vdo_cmi"
+BOOT_LOGO:=cu_fwvga
2. 添加驱动代码,放到 kernel-3.18/drivers/misc/mediatek/lcm/
vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm目录
创建文件夹 k801_st7701S_fwvga_dsi_vdo_cmi 文件夹中包含 k801_st7701S_fwvga_dsi_vdo_cmi.c、Makefile
3. 把添加驱动代码,放入LCD显示中
放入kernel
修改 kernel-3.18/drivers/misc/mediatek/lcm/mt65xx_lcm_list.h
+extern LCM_DRIVER k801_st7701S_fwvga_dsi_vdo_cmi_lcm_drv;
修改 kernel-3.18/drivers/misc/mediatek/lcm/mt65xx_lcm_list.c
+#if defined(K801_ST7701S_FWVGA_DSI_VDO_CMI)
+ &k801_st7701S_fwvga_dsi_vdo_cmi_lcm_drv,
+#endif
放入lk
修改 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm/mt65xx_lcm_list.c
+extern LCM_DRIVER k801_st7701S_fwvga_dsi_vdo_cmi_lcm_drv; //2018-10-29
+#if defined(K801_ST7701S_FWVGA_DSI_VDO_CMI)
+ &k801_st7701S_fwvga_dsi_vdo_cmi_lcm_drv,
+#endif
4. 修改驱动代码...k801_st7701S_fwvga_dsi_vdo_cmi.c
1.1 FAE 给的初始化:没C文件 那要自己加工,改成我们需要的格式
一般格式,相对高分辨率可能丢失数据
struct LCM_setting_table {
unsigned cmd;
unsigned char count;
unsigned char para_list[64];
};
static struct LCM_setting_table lcm_initialization_setting[] = {
{0xB9,3,{0xFF,0x83,0x94}},
{0xBA,6,{0x63,0x03,0x68,0x6B,0xB2,0xC0}},
...
{0xBC,1,{0X00}},
{0x11,1, {0x00}},
{REGFLAG_DELAY,120,{}},
{0x29,1, {0x00}},
{REGFLAG_DELAY,10,{}},
};
直接传
void init_lcm_registers(void)
{
unsigned int data_array[16];
data_array[0] = 0x00043902;
data_array[1] = 0x9483FFB9;
dsi_set_cmdq(data_array, 2, 1);
data_array[0] = 0x00073902;
data_array[1] = 0x680363BA;
data_array[2] = 0x00C0B26B;
dsi_set_cmdq(data_array, 3, 1);
...
data_array[0] = 0x00023902;
data_array[1] = 0x000000BC;
dsi_set_cmdq(data_array, 2, 1);
data_array[0] = 0x00110500;
dsi_set_cmdq(data_array, 1, 1);
MDELAY(120);
data_array[0] = 0x00290500;
dsi_set_cmdq(data_array, 1, 1);
MDELAY(10);
}
1.2 修改mipi通道数
params->dsi.LANE_NUM = LCM_TWO_LANE; //; -- 根据实际模组打样来配置(询问FAE得知)
//The following defined the fomat for data coming from LCD engine.
params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888; //数据格式为
-- 通常fwvga为2 hd为3/4,fhd为4(分辨率高的mipi通道数多)
-- 同为hd,3路mipi要比4路mipi的时钟高一些
1.3 屏的参数
以下为常修改值--FAE提供--可以由数据手册算出
params->dsi.vertical_sync_active = 4; //垂直同步信号的宽度
params->dsi.vertical_backporch = 16; //垂直同步信号的后沿
params->dsi.vertical_frontporch = 20; //垂直同步信号的前沿 可调节竖屏 上线白线条 ,闪屏
params->dsi.vertical_active_line = FRAME_HEIGHT;
params->dsi.horizontal_sync_active = 10;//6
params->dsi.horizontal_backporch = 78;//37
params->dsi.horizontal_frontporch = 80;//37
params->dsi.horizontal_active_pixel = FRAME_WIDTH;
params->dsi.PLL_CLOCK=180; //lcm的频率,更据实际情况改动,这个一般mtk的都会影响gps的信号强弱。
1.3 兼容
-- 系统通过读ID进行兼容,如果只配了一个屏则不读ID
-- 点亮新屏的时候,可以先不兼容,或先把读ID函数写死return 1
#define LCM_ID_NT35512 (0x5512)
static unsigned int lcm_compare_id(void)
{
return (id == LCM_ID_NT35512) ? 1 : 0; // 点新屏时可写死 return 1;
}
1.4 相同ic的lcm做兼容 - 不通模组厂的模组可以通过内置电阻不通,而使lcm的ID脚输出电压不同,把ID脚接到PMU上,lcm_compare_id()时通过PMU读取电压值,根据电压值做判断
0 - 0v
470k - 0.2~0.3v
150k - 0.7~0.8v
51k - 1.2~1.3v
1. 查看硬件原理图,可知lcm的ID脚“AUX_IN1_LCD_ID” 连接在pmu的“AUX_IN1”脚
2. 修改驱动, 主要是lcm_compare_id():
+ #define AUXADC_LCM_VOLTAGE_CHANNEL 1 // 根据原理图,lcm的ID脚接在pmu的“AUX_IN1”脚,所以是1
/* 根据mtk-online 不只屏,accdet也会用到
AUX_IN0 -- channel 0
AUX_IN1 -- channel 1
AUX_IN2 -- channel 12
AUX_IN3 -- channel 13
AUX_IN4 -- channel 14
*/
+ extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int* rawdata);
#define MIN_VOLTAGE (0)
#define MAX_VOLTAGE (100)
static unsigned int rgk_lcm_compare_id(void)
{
int data[4] = {0,0,0,0};
int lcm_vol = 0;
#ifdef AUXADC_LCM_VOLTAGE_CHANNEL
int res = 0;
int rawdata = 0;
res = IMM_GetOneChannelValue(AUXADC_LCM_VOLTAGE_CHANNEL,data,&rawdata); // 通过PMU读取电压值,根据电压值做判断
if(res < 0)
{
#ifdef BUILD_LK
printf("[adc_uboot]: get data error\n");
#endif
return 0;
}
#endif
lcm_vol = data[0]*1000+data[1]*10;
#ifdef BUILD_LK
printf("[adc_uboot]: lcm_vol= %d\n",lcm_vol);
#else
printk("[adc_kernel]: lcm_vol= 0x%x\n",lcm_vol);
#endif
return (lcm_vol>=MIN_VOLTAGE &&lcm_vol <= MAX_VOLTAGE && lcm_compare_id())? 1 : 0;
}
三:如何调整上下颠倒
修改驱动初始化数组.一般MIRROR中修改
若不支持,翻转系统:(开机logo的第一张会是倒的,需要把图片翻转)
lk:
vendor/mediatek/proprietary/bootable/bootloader/lk/project/hys6737m_35_m0.mk
MTK_LCM_PHYSICAL_ROTATION=180
kernel:
kernel-3.18/arch/arm/configs/hys6737m_35_m0_debug_defconfig
CONFIG_MTK_LCM_PHYSICAL_ROTATION="180"
system:
device/teksun/hys6737m_35_m0/ProjectConfig.mk
MTK_LCM_PHYSICAL_ROTATION=180
四:调屏问题点
1:花屏或者点不亮原因:
时钟范围超出芯片限制,可以调低试试
行扫帧扫的极性,以及时钟的极性问题,可以改下极性试试
行频和帧频没有设置好,HBP HFP VBP VFP 设置问题
信号的极性设置不对
2:屏幕抖动:
调整时钟频率
背光电压波动
设置电压时延时不够或者电压大小问题,调节VCOM
可以通过调整电压来稳定,一般调节的电压为VRL、VRH、VDV和VCM;这些电压也可以用来调节亮暗(对比度);
刷新频率设置不正确导致的闪屏
扫描方向不一致导致闪屏
IC 刷新频率与背光PWM 信号频率不匹配导致闪屏
3: 花屏
打开ESD - 打静电的时候出现花屏(按电源键休眠再唤醒才会恢复正常)。
刚开机闪屏,花屏 ,关ESD ,初始化中的ESD代码也要关,或者采用LK背光 延时打开.
五:常用调试方法:
1.查看是否有编译到
ls out/target/product/hys6737m_35_m0/obj/BOOTLOADER_OBJ/build-hys6737m_35_m0/dev/lcm/k801_st7701S_fwvga_dsi_vdo_cmi/
ls out/target/product/hys6737m_35_m0/obj/KERNEL_OBJ/drivers/misc/mediatek/lcm/k801_st7701S_fwvga_dsi_vdo_cmi/
2. 查看机器中lcm型号:
adb shell
cat /proc/cmdline //
3. 查看系统分辨率
cat /system/build.prop | grep lcd_density // 得“240”
4. 修改系统分辨率
device/teksun/hys6737m_35_m0/system.prop
ro.sf.lcd_density=240 // 240就是系统的分辨率--可以通过修改这个值(参考其他工程)