CSDN仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2018/07/19/RK3288——LCD裸机/#more
在RK3288平台上,采用裸机实现LVDS和MIPI接口的LCD显示。
1.常见的LCD显示接口
在之前写的Exynos4412——LCD驱动里,使用的RGB接口。
除了RGB接口,如今市面上主流的还有LVDS、MIPI、eDP接口。
接口 | 分辨率 | 接口电平 | 说明 |
---|---|---|---|
RGB | 800x480以下 | TTL | 几乎所有的SOC都支持RGB接口; 在小屏、低端设备中广泛使用; |
LVDS | 1024x768及以上 | 差分信号 | 中高端的SOC大多数都集成,也可通过转换芯片将RGB转成LVDS输出; 在大屏,中高端平板、笔记本中使用; |
MIPI | 1080P以下 | 差分信号 | 大多数中高端的SOC都集成,也可通过转换芯片实现; 手机平台的标准接口,在手机中广泛使用; |
eDP | 1080P以上 | 差分信号 | 高端SOC中集成,相对比较新的规范; 支持超高分辨率,有取代LVDS的趋势; |
各接口示意图如下:
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/1.jpg)
- RGB接口:RGB接口也叫TTL(
Transistor Transistor Logic
)接口,它是唯一一个采用TTL电平的LCD接口。如果数据接口R、G、B都只使用0~5共6x3根数据线,即为18bit RGB接口,如果R、G、B都使用0~7共8x3根数据线,即称为24bit RGB接口;它的详细介绍,可以参考前面的Exynos4412——LCD驱动; - LVDS接口:LVDS(
Low Voltage Differential Signaling
),即一种采用低压差分信号技术的LCD接口,克服了TTL电平方式传输宽带高码率数据时功耗大、EMI电磁干扰大等缺点;如果数据接口只使用LVDS_D0~D2这三组数据线,就是6bit 模式;如果使用LVDS_D0~D3这四组数据线,就是8bit 模式; - MIPI接口:MIPI(
Mobile Industry Processor Interface
),为了推进手机应用处理器接口的标准化而产生的。MIPI是一系列接口的总称,MIPI下应用比较多的是DSI(Display Serial Interface
)和CSI(Camera Serial Interface
),分别针对显示屏应用和摄像头应用。这里的MIPI接口,实质上指的是DSI接口; - eDP接口:eDP(
Embedded Display Port
),主要用于将视频源连接到显示设备(如计算机显示器),还可以传输音频,USB和其他形式的数据;该部分目前资料较少,RK3288芯片手册该部分寄存器都没给,属于保密范围,暂时没法研究;
2.LVDS
2.1 分析过程
先理一下分析的思路:
- 1.首先需要一个RK3288的开发板(这里使用的是Firefly生产的AIO-3288J),且带有LVDS接口的屏,且提供的资料能够让屏亮起来;
- 2.根据提供资料、源码,重头编译一下源码,包括U-boot、Kernel、Android等(编译Android可能需要设置交换分区);
- 3.编译完成后,将生成的镜像文件烧录至开发板,验证是否可用;
- 4.可用后,就有了显示部分的源码,先从设备树文件夹入手,查看生成了哪些dtb文件,即表示对应的dts被使用了,再找到对应的dts文件,找到lcd、screen、blacklinght、lvds等关键词的部分;
- 5.得出RK3288的LVDS至少和VOP(lcdc)、lvds、screen、blacklinght这四个部分有关,再利用设备树
compatible
与内核匹配和源码若使用都会生成.o
这两个特性,找到对应部分的内核源码; - 6.修改内核源码,重新编译烧录,观察现象;比如,找到内核源码中lvds相关部分,屏蔽掉
lvds_en()
这一明显关键的函数后,发现开发板开机后,启动内核屏幕仍然会出现logo,因此推测U-boot也做了LVDS的相关初始化,内核中的lvds_en()
可能用于后续锁屏等屏幕的开闭; - 7.屏蔽多个关键函数,发现除去背光函数对屏幕显示有影响外,其它的关键函数的屏蔽,对开始显示logo都没影响;
- 8.在U-boot中,直接操作寄存器使能背光,同时屏蔽进入内核的代码,发现进入U-boot即可显示logo,因此U-boot里肯定有完整的LVDS显示的操作,内核就暂时不用管了;
- 9.以U-boot中
lcdc_init()
、lvds_en()
等为核心突破口,先打印出该部分的寄存器操作值,再屏蔽掉该部分代码,自己直接向寄存器写值,重新烧录,查看logo是否仍显示;如果logo存在,则表示自己直接操作该部分寄存器成功; - 10.以此类推,逐渐屏蔽源码,改为自己直接操作寄存器,最后按照源码的函数调用顺序,依次操作寄存器,单独生成bin文件,测试显示成功即可;
- 11.查阅相关寄存器,分析、注释;
对LVDS接口的LCD显示分析如下:
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/2.jpg)
对LVDS接口的LCD操作框架总结如下:
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/3.jpg)
这其中有两个值得一提的点:
- 1.核心板上有个电源IC,需要通过I2C设置电源IC的输出,提供给显示模块,如果没有设置,屏幕是不会有显示的;
- 2.屏幕参数的设置,用到了前面1.3LCD显示原理的知识:
//hspw+hbp+col+hfp:8+8+800+48=848
VOP_BIG_DSP_HTOTAL_HS_END = ((8<<0) | (848<<16)); //0:HS_PW 16:HTOTAL
VOP_BIG_DSP_HACT_ST_END = ((816<<0) | (16<<16)); //0:COL_END 16:COL_START
//vspw+vbp+row+vfp:4+11+1280+32=1312
VOP_BIG_DSP_VTOTAL_VS_END = ((4<<0) | (1312<<16));//0:VS_PW 16:VTOTAL
VOP_BIG_DSP_VACT_ST_END = ((1295<<0) | (15<<16)); //0:ROW_END 16:ROW_START
VOP_BIG_POST_DSP_HACT_INFO = ((816<<0) | (16<<16)); //0:COL_END 16:COL_START
VOP_BIG_POST_DSP_VACT_INFO = ((1295<<0) | (15<<16)); //0:ROW_END 16:ROW_START
在水平方向,由HSYNC(hspw)+HBP+Active weigth(col)+HFP=Total weigth(HTOTAL)
,再根据LCD的手册,取合适的值,填入寄存器对应位;
比如,VOP_BIG_DSP_HTOTAL_HS_END的低16位填入HSYNC(hspw)
值,高16位填入Total weigth(HTOTAL)
;VOP_BIG_DSP_HACT_ST_END低16位填入HSYNC(hspw)+HBP+Active weigth(col)
的值,高16位填入HSYNC(hspw)+HBP
的值;都是吻合LCD的显示原理的。
2.2 源码及效果
源码见Github。
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/4.gif)
3.MIPI
3.1 分析过程
先理一下分析的思路:
- 1.首先需要一个带有MIPI屏的RK3288的开发板,Firefly生产的AIO-3288J的MIPI屏已经停产,也没找到兼容的,因此又去弄了一个带MIPI屏的RK3288开发板(荣品生产的king3288);
- 2.根据提供的资料,编译源码,下载,烧录、测试;
- 3.有了前面的经验,猜测开机LOGO显示的代码在U-Boot中,注释掉U-Boot中
common/cmd_bootrk.c
里的//do_bootm_linux(0, 0, NULL, &images);
,使其不能引导内核,重新编译U-Boot,下载,发现有LOGO显示,证明U-Boot里有MIPI屏显示操作; - 4.依旧是找到LOGO显示的相关代码,修改,编译,烧写,观察现象,最终得到独立的MIPI屏显示相关代码;
对MIPI接口的LCD显示分析如下:
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/4.jpg)
MIPI部分的代码比LVDS感觉要乱一些,主要是因为在结构体里定义了函数,使用Source Insight
分析代码时,没那么方便,涉及到了三个结构体如下,分别是VOP、MIPI接口、面板的相关操作:
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/5.jpg)
这其中有两个值得一提的点:
- 1.它们的PMIC使用的同一款,且配置一样,直接就可以用之前的代码;
- 2.不能直接读出所有配置的寄存器,然后对比,因为实测有些寄存器操作后,需要一个等待时间(需要读取另一个寄存器判断),才能进行下一个寄存器的操作,就可能出现源码和自己代码的寄存器值都一样,但实际效果不一样;
3.2 源码及效果
源码见Github。
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/180719/6.gif)
4.心得
- 1.熟悉了如果从驱动中提取出裸机代码,看清了对寄存器的实质操作,有利于理解整个流程;
- 2.无论是何种接口的LCD,都有共性,比如都需要向buf写数据,且告诉对应寄存器;针对RK3288,都使用VOP对buf数据处理,然后再通过不同的接口发送出去,都需要根据LCD面板来设置时间参数;