一、Linux LCD驱动简介
先来回顾一下裸机的时候 LCD 驱动是怎么编写的,裸机 LCD 驱动编写流程如下:
①、初始化 I.MX6U 的 eLCDIF 控制器,重点是 LCD 屏幕宽(width)、高(height)、hspw、
hbp、hfp、vspw、vbp 和 vfp 等信息。
②、初始化 LCD 像素时钟。
③、设置 RGBLCD 显存。
④、应用程序直接通过操作显存来操作 LCD,实现在 LCD 上显示字符、图片等信息。
在 Linux 中应用程序最终也是通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片
等信息。在裸机中我们可以随意的分配显存,但是在 Linux 系统中内存的管理很严格,显存是
需要申请的,不是你想用就能用的。而且因为虚拟内存的存在,驱动程序设置的显存和应用程
序访问的显存要是同一片物理内存。
为了解决上述问题,Framebuffer 诞生了, Framebuffer 翻译过来就是帧缓冲,简称 fb,因
此大家在以后的 Linux 学习中见到"Framebuffer"或者"fb"的话第一反应应该想到 RGBLCD
或者显示设备。fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一
个 fb 设备,当我们编写好 LCD 驱动以后会生成一个名为/dev/fbX(X=0~n)的设备,应用程序通
过访问/dev/fbX 这个设备就可以访问 LCD。NXP 官方的 Linux 内核默认已经开启了 LCD 驱动,
因此我们是可以看到/dev/fb0 这样一个设备,如图 59.1.1.1 所示:

fb 的 file_operations 操作集定义在 drivers/video/fbdev/core/fbmem.c 文件
中,如下所示:
cpp
1495 static const struct file_operations fb_fops = {
1496 .owner = THIS_MODULE,
1497 .read = fb_read,
1498 .write = fb_write,
1499 .unlocked_ioctl = fb_ioctl,
1500 #ifdef CONFIG_COMPAT
1501 .compat_ioctl = fb_compat_ioctl,
1502 #endif
1503 .mmap = fb_mmap,
1504 .open = fb_open,
1505 .release = fb_release,
1506 #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
1507 .get_unmapped_area = get_fb_unmapped_area,
1508 #endif
1509 #ifdef CONFIG_FB_DEFERRED_IO
1510 .fsync = fb_deferred_io_fsync,
1511 #endif
1512 .llseek = default_llseek,
1513 };
二、LCD设备树驱动修改
1、IO配置
cpp
1 pinctrl_lcdif_dat: lcdifdatgrp {
2 fsl,pins = <
3 MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
4 MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
5 MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
6 MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
7 MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
8 MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
9 MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
10 MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
11 MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
12 MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
13 MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
14 MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
15 MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
16 MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
17 MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
18 MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
19 MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
20 MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
21 MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
22 MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
23 MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
24 MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
25 MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
26 MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
27 >;
28 };
29
30 pinctrl_lcdif_ctrl: lcdifctrlgrp {
31 fsl,pins = <
32 MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
33 MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
34 MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
35 MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
36 >;
37 pinctrl_pwm1: pwm1grp {
38 fsl,pins = <
39 MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
40 >;
41 };
2**、LCD屏幕参数节点信息修改**
cpp
1 &lcdif {
2 pinctrl-names = "default";
3 pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */
4 &pinctrl_lcdif_ctrl>;
5 display = <&display0>;
6 status = "okay";
7
8 display0: display { /* LCD 属性信息 */
9 bits-per-pixel = <24>; /* 一个像素占用 24bit */
10 bus-width = <24>; /* 总线宽度 */
11
12 display-timings {
13 native-mode = <&timing0>; /* 时序信息 */
14 timing0: timing0 {
15 clock-frequency = <51200000>;/* LCD 像素时钟,单位 Hz */
16 hactive = <1024>; /* LCD X 轴像素个数 */
17 vactive = <600>; /* LCD Y 轴像素个数 */
18 hfront-porch = <160>; /* LCD hfp 参数 */
19 hback-porch = <140>; /* LCD hbp 参数 */
20 hsync-len = <20>; /* LCD hspw 参数 */
21 vback-porch = <20>; /* LCD vbp 参数 */
22 vfront-porch = <12>; /* LCD vfp 参数 */
23 vsync-len = <3>; /* LCD vspw 参数 */
24
25 hsync-active = <0>; /* hsync 数据线极性 */
26 vsync-active = <0>; /* vsync 数据线极性 */
27 de-active = <1>; /* de 数据线极性 */
28 pixelclk-active = <0>; /* clk 数据线先极性 */
29 };
30 };
31 };
32 };
3**、LCD屏幕背光节点信息**
cpp
1 pinctrl_pwm1: pwm1grp {
2 fsl,pins = <
3 MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
4 >;
5 };
三、编译验证LCD
设备树编译
make dtbs
将编译生成的设备树文件拷贝到~/linux/tftboot
使能linux logo显示


使用新编译的linux内核文件重启开发板

四、使能LCD作为控制台
1**、设置uboot中的****bootargs**
cpp
setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.3:
/home/zipeng/linux/nfs/rootfs ip=192.168.1.2:192.168.1.3:192.168.1.1:255.255.255.0::eth0:
off'
这里我们设置了两遍 console,第一次设置 console=tty1,
也就是设置 LCD 屏幕为控制台,第二遍又设置 console=ttymxc0,115200,也就是设置串口也作
为控制台。相当于我们打开了两个 console。
2**、修改****/etc/inittab****文件**
打开开发板根文件系统里面的/etc/inittab文件,在里面添加这一句:
tty1::askfirst:-/bin/sh

3、重启Limux开发板
可以看到这会linux内核启动的时候会在LCD屏打印信息


执行echo hello linux > /dev/tty1 可以看到LCD屏幕上打印对应信息
