LCD 驱动实验教程
——疯壳·嵌入式平板开发
下图来源于文档 3128_sdk_a02_20170325.pdf 中第 19 页。
图一、从原理图可以看出 LCD 是采用 mipi 接口和 cpu 相连的。
图1
第二节 LCD 驱动框架及实现
在 linux 内核中,显示相关的驱动称为 fb(framebuffer)驱动。在 RK31XX 的平台上,为了尽可能的复用代码,fb 驱动被分为 fb 框架相关的部分、LCDC 控制器相关的部分、LCD 屏幕相关的部分、LCD 电源操作相关的板级配置部分。 a.fb 框架相关的代码
drivers/video/fbmem.c
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h
include/linux/rk_screen.h
这部分代码实现是fb 相关的框架,不涉及具体的硬件操作,所有的LCDC 驱动共用。其中 fbmem.c 为 linux 内核原生代码,他向上提供和用户空间交互的接口(open、read、write、ioctl 等),向下联系平台相关的 fb 驱动 rk_fb.c。
b.LCDC 相关的代码
drivers/video/rockchip/lcdc/rk312x_lcdc.c
这部分代码和具体的 LCDC 控制器相关。
c.LCD 屏幕配置相关代码
drivers/video/rockchip/screen/rk_screen.c
rk_screen.c 是屏幕配置文件的共用代码,重点介绍如下接口。 set_lcd_info:屏幕参数配置接口,所有的屏幕都会用到
get_fb_size:根据屏幕的分辨率计算需要分配多大的 fb 空间,对于三 buffer,计算公式为 X*Y*4*3,双 buffer 计算公式为 X*Y*4*2,目前我们都使用三 buffer。
建议每个项目相关的人员都要看下 rk_screen.c 中相关接口的实现,以方便开发中遇到的 debug 问题。
第三节 实验代码 --- 快速判断 RGB 颜色是否有颠倒
在有些项目上,由于 LCD 屏幕自身原因或者硬件连接原因,会导致 RGB 颜色出现颠倒, 比如 R 和 G 反了、或者 R 和 B 反了、或者 B 和 G 反了,导致显示颜色出现异常。这种情况可以通过软件配置进行纠正。首先,要判断出哪两种颜色反掉了,方法如下:通过RK 系统中自带的 IO 命令向 FB 里面写单元色红色(0x00ff0000)、绿色(0x0000ff00)、蓝色(0x000000ff)看对应的显示效果,就可以判断是哪两种颜色反掉了。具体方法如 下:
(1)在串口里面执行 stop 命令(需要 root 权限),这样 Android 不再进行屏幕更新,以免影响测试。
(2)然后查询 LCDC 寄存器,获取当前 FB 地址:因为 RK 采用三 buffer 的方式,这里有可能存在地址不一样的情况,所以执行 io 命令前尽量先敲如下命令看下地址是什么。
图2
用 io 命令依次向该地址写入 RGB 单元色数据,看屏幕对应的显示情况:
io -w -4 -l 0x3e8000 0x90fe8000 0x00ff0000 红色
io -w -4 -l 0x3e8000 0x90fe8000 0x0000ff00 绿色
io -w -4 -l 0x3e8000 0x90fe8000 0x000000ff 蓝色
注意-l 参数后面跟的是写入数据的长度,这里都是满屏写入,我使用的设备的屏幕分辨率为 1280*800,因此一帧数据的长度为 1280*800*4 = 0x3e8000。正常情况下,依次在串口中输入上面三个命令,屏幕上依次显示红、绿、蓝三种颜色,如果显示的某种颜色 不对,比如写入红色,屏幕上显示的却是蓝色,如果 R 和 B 反了,则应该在屏幕驱动中#define SWAP_RB 1,对 RB 进行交换。如果向 FB 里面写入 RGB 中任意一种的单元色屏而屏幕显示的图像不是这三个单元色中的任意一种,那就有可能是屏幕有问题,或者 硬件设计有问题,或者中间的转换芯片比如 LVDS 有问题,或者 LVDS_FORMAT 设置的不对。
第四节 实验现象
为什么敲入了屏幕全部变红色命令(io -w -4 -l 0x3e8000 0x90fe8000 0x00ff0000),屏幕并没有任何反应? --- IOMMU(input/output memory management unit),Device 的IOMMU 类似于 CPU 的 MMU。
首先因为设备默认打开了 iommu 功能,所以操作时候有可能操作的地址就不是真实的物理地址,而是虚拟地址。这样就和 io 命令冲突了,io 命令是必须操作物理地址的。修改如下,DTS 中增加如下选项:
&lcdc {
status = "okay";
backlight = <&backlight>;
rockchip,iommu-enabled = <0>;
......
图3