对于lcd驱动的分析主要分为三部分:
底层硬件结构浅析
framebuffer浅析
MIPI浅析
底层硬件结构浅析
1、 要使一块LCD正常的显示文字或图像,不仅需要LCD驱动器,而且还需要相应的LCD控制器。在通常情况下,生产厂商把LCD驱动器与LCD玻璃基板制作在一起,而LCD控制器则是由外部的电路来实现(平台自带),现在很多的MCU内部都集成了LCD控制器,。通过LCD控制器就可以产生LCD驱动器所需要的控制信号来控制STN/TFT屏了。
2、 Lcd控制器结构图(旨在说明原理,LCD的结构因其通信方式的不同而不同)
我们根据数据手册来描述一下LCD控制器:
a:LCD控制器由REGBANK、LCDCDMA、TIMEGEN、VIDPRCS寄存器组成;
b:REGBANK由17个可编程的寄存器组和一块256*16的调色板内存组成,它们用来配置LCD控制器的;
c:LCDCDMA是一个专用的DMA,它能自动地把在帧内存中的视频数据传送到LCD驱动器,通过使用这个DMA通道,视频数据在不需要CPU的干预的情况下显示在LCD屏上;(DMA可以实现不通过cpu直接读取内存)
d:VIDPRCS接收来自LCDCDMA的数据,将数据转换为合适的数据格式,然后通过数据端口传送视频数据到LCD驱动器;
e:TIMEGEN(脉冲发生器)由可编程的逻辑组成,他生成LCD驱动器需要的控制信号,比如VSYNC、HSYNC、VCLK和LEND等等,而这些控制信号又与REGBANK寄存器组中的LCDCON1/2/3/4/5的配置密切相关,通过不同的配置,TIMEGEN就能产生这些信号的不同形态,从而支持不同的LCD驱动器(即不同的STN/TFT屏)。
3、 常见TFT屏工作时序分析
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;
帧缓冲(framebuffer)浅析
1、 帧缓冲(framebuffer)代码结构
因为视频适配器可能基于不同的硬件体系架构,较高内核层和应用程序的实现可能会因视频卡的不同而不同,这会导致在使用不同视频卡的时需要采用不同的方案。随之而来的低可移植性和冗余的代码需要大量的投入和维护开销。帧缓冲的概念解决了这个 问题,它进行了一般化的抽象并规定编程接口,从而开发人员可以以与平台无关的方式编写应用层和较高内核层程序。因此,内核的帧缓冲接口允许应用程序与底层图形硬件的变化无关,如果应用和显示器驱动程序遵循帧缓冲接口,应用程序不用改变就可以在不同类型的视频硬件上运行。
图中fbmem.c为linux内核部分,它定义了一个统一的与userspace交互的字符设备(这里暂时把它称为file_operations),这个文件还定义了一个register_framebuffer操作(这个操作的目的是创建一个与主设备号相同的设备,例如fb0,fb1,fb2)。因为注册的设备都需要通过file_operations来实现userspace与kernel的交互,因此,register_framebuffer之前,需要填充一个fb_info来保存设备的信息,fb_info是区分fb0,fb1,fb2…的关键。
2、 fb_info的构成(只列出关键组成部分)
struct fb_info {
struct fb_var_screeninfo var; /* Current var */ 可变参数
struct fb_fix_screeninfo fix; /*Current fix */ 固定参数
struct fb_ops *fbops; //对底层硬件操作的函数指针(区别于file_operations)
};
fb_var_screeninfo主要记录用户可以修改的控制器的参 数,比如屏幕的分辨率和每个像素的比特数
fb_fix_screeninfo fix主要记录用户不可以修改的控制 器的参数,比如屏幕缓冲区的物理地址和长度等
structfb_var_screeninfo{
__u32xres; /*可见屏幕一行有多少个像素点*/
__u32 yres; /*可见屏幕一列有多少个像素点*/
__u32 xres_virtual; /*虚拟屏幕一行有多少个像素点*/
__u32 yres_virtual; /*虚拟屏幕一列有多少个像素点*/
__u32 xoffset; /*虚拟到可见屏幕之间的行偏移*/
__u32 yoffset; /*虚拟到可见屏幕之间的列偏移*/
__u32 bits_per_pixel; /*每个像素的位数即BPP*/
__u32 grayscale; /*非0时,指的是灰度*/
struct fb_bitfield red; /*fb缓存的R位域*/
struct fb_bitfield green; /*fb缓存的G位域*/
struct fb_bitfield blue; /*fb缓存的B位域*/
struct fb_bitfield transp; /*透明度*/
__u32nonstd; /* != 0 非标准像素格式*/
__u32 activate;
__u32height; /*高度*/
__u32width; /*宽度*/
__u32 accel_flags;
/*定时:除了pixclock本身外,其他的都以像素时钟为 单位*/(对应之前第一部分组后的内容)
__u32pixclock; /*像素时钟(皮秒)*/
__u32 left_margin; /*行切换,从同步到绘图之间的延迟*/
__u32right_margin; /*行切换,从绘图到同步之间的延迟*/
__u32upper_margin; /*帧切换,从同步到绘图之间的延迟*/
__u32lower_margin; /*帧切换,从绘图到同步之间的延迟*/
__u32hsync_len; /*水平同步的长度*/
__u32 vsync_len; /*垂直同步的长度*/
__u32 sync;
__u32 vmode;
__u32 rotate;
__u32reserved[5]; /*保留*/
}
structfb_fix_screeninfo{ //
charid[16]; /*字符串形式的标示符 */
unsignedlongsmem_start; /*fb缓存的开始位置 */
__u32smem_len; /*fb缓存的长度 */
__u32type; /*看FB_TYPE_* */
__u32 type_aux; /*分界*/
__u32visual; /*看FB_VISUAL_* */
__u16 xpanstep; /*如果没有硬件panning就赋值为0 */
__u16ypanstep; /*如果没有硬件panning就赋值为0 */
__u16ywrapstep; /*如果没有硬件ywrap就赋值为0 */
__u32line_length; /*一行的字节数 */
unsignedlong mmio_start; /*内存映射IO的开始位置*/
__u32mmio_len; /*内存映射IO的长度*/
__u32 accel;
__u16reserved[3]; /*保留*/
}
struct fb_ops{
struct module *owner;
//检查可变参数并进行设置
int(*fb_check_var)(struct fb_var_screeninfo*var,structfb_info*info);
//根据设置的值进行更新,使之有效
int(*fb_set_par)(struct fb_info*info);
//设置颜色寄存器
int(*fb_setcolreg)(unsigned regno,unsigned red,unsigned green,
unsigned blue,unsigned transp,struct fb_info*info);
//显示空白
int(*fb_blank)(int blank,struct fb_info *info);
//矩形填充
void(*fb_fillrect)(struct fb_info*info,conststruct fb_fillrect*rect);
//复制数据
void(*fb_copyarea)(struct fb_info*info,conststruct fb_copyarea*region);
//图形填充
void(*fb_imageblit)(struct fb_info*info,conststruct fb_image*image);
}
MIPI浅析
在android体系中,lcd使用MIPI总线来实现控制器(cpu一端)与驱动器(外设lcd屏)的通信,因此这里介绍一下MIPI协议
1、MIPI协议
MIPI是Mobile Industry Processor Interface的缩写。MIPI(移动行业处理器接口)是MIPI联盟发起的为移动应用处理器制定的开放标准。为了把移动设备内部的接口如摄像头、显示屏、基带、射频接口等标准化,从而增加设计灵活性,同时降低成本、设计复杂度、功耗和EMI。
MIPI在android体系中常见的有两种:DSI, CSI (DisplaySerialInterface, CameraSerialInterface)
DSI 定义了一个位于处理器和显示模组之间的高速串行接口。(lcd连接协议)
CSI 定义了一个位于处理器和摄像模组之间的高速串行接口。(camera连接协议)
2、DSI分层结构
DSI分四层,对应D-PHY、DSI、DCS规范、分层结构图如下:
• PHY 定义了传输媒介,输入/输出电路和和时钟和信号机制。 (物理层)
• Lane Management层:发送和收集数据流到每条lane。 (处理层—中间两层)
• Low Level protocol 层:定义了如何组帧和解析以及错误检测等。
• Application层:描述高层编码和解析数据流。 (应用层)
DSI兼容的外设支持Command或Video操作模式两种模式
• Command模式是指采用发送命令和数据到具有显示缓存的控制器。主机通过命令间接的控制外设。Command模式采用双向接口,用于发送指令,传输速率较低,精确率高
• Video模式是指从主机传输到外设采用时实象素流。这种模式只能以高速传输。为减少复杂性和节约成本,只采用Video模式的系统可能只有一个单向数据路径。用于发送帧数据,传输速率高,精确率低
D-PHY 物理描述
一个 PHY配置包括:一个时钟lane,一个或多个数据lane
• 两个Lane的 PHY配置如下图
• D-PHY的传输模式
• 低功耗(Low-Power)信号模式(用于控制):10MHz (max)
• 高速(High-Speed)信号模式(用于高速数据传输):80Mbps ~ 1Gbps/Lane
发送数据时必须低位在前,高位在后.