Linux内核的amba lcd控制器使用clcd_panel结构体表示一个LCD屏的硬件参数:
/* include/linux/fb.h */
struct fb_videomode {
const char *name; /* optional */
u32 refresh; /* optional */
u32 xres;
u32 yres;
u32 pixclock;
u32 left_margin;
u32 right_margin;
u32 upper_margin;
u32 lower_margin;
u32 hsync_len;
u32 vsync_len;
u32 sync;
u32 vmode;
u32 flag;
};
fb_videomode各个参数的意义
Linux对LCD的抽象如下图所示:
下面研究一下fb_videomode各个成员的意义:
名称 | 在数据手册中的简称 | 中文名 | 意义 | 备注 |
name | No | 名字 | 液晶屏名字(可选) | No |
refresh | No | 刷新频率 | 刷新频率(内核中很多例子都赋值为60) | No |
xres | No | 行宽 | 每行的像素个数 | No |
yres | No | 屏幕高度 | 屏幕的行数 | No |
pixclock | No | 像素时钟 | 每个像素时钟周期的长度,单位是皮秒(10的负12次方分之1秒) | No |
left_margin | HBP (Horizontal Back Porch) | 水平后沿 | 在每行或每列的象素数据开始输出时要插入的象 素时钟周期数 | No |
right_margin | HFP (Horizontal Front Porch ) | 水平前沿 | 在每行或每列的象素结束到LCD 行时钟输出脉冲 之间的象素时钟数 | No |
upper_margin | VBP (Vertical Back Porch) | 垂直后沿 | 在垂直同步周期之后帧开头时的无效行数 | No |
lower_margin | VFP (Vertical Front Porch) | 垂直前沿 | 本帧数据输出结束到下一帧垂直同步周期开始之 前的无效行数 | No |
hsync_len | HPW (HSYNC plus width) | 行同步脉宽 | 单位:像素时钟周期 | 也有手册简称为HWH(HSYNC width) |
vsync_len | VPW (VSYNC width) | 垂直同步脉宽 | 单位:显示一行的时间th | 也有手册简称为VWH(VSYNC width) |
sync | No | 同步极性设置 | 可以根据需要设置FB_SYNC_HOR_HIGH_ACT(水平同步高电平有效)和FB_SYNC_VERT_HIGH_ACT(垂直同步高电平有效) | No |
vmode | No | No | 在内核中的大多数示例都直接置为FB_VMODE_NONINTERLACED。interlaced的意思是交错[隔行]扫描,电视中使用2:1的交错率, 即每帧分两场,垂直扫描两次,一场扫描奇数行,另一场扫描偶数行。很显然LCD目前不是这种模式。 | No |
flag | No | No | 目前没有看到用法 | No |
说明:
(1)Linux对LCD的抽象是以图像为中心的,而LCD手册则以同步信号为中心,所以内核中的left_margin是指在每一行之前(前面自然对应左边)的空闲周期数,而它对应LCD数据手册中的水平后沿(HBP Horizontal Back Porch),是指在行同步信号之后的空闲周期。参照物不同而已,但是说的是同一个东西。
(2)水平同步信号有时也成为行同步型号,垂直同步信号有人称为场同步信号。
(3)对于LCD的frambuffer抽象模型请参考内核中的文档:Documention/fb/frambuffer.txt。
(4)fb_videomode各个成员的用处是我自己参照内核代码中的include/linux/amba/clcd.h中的clcdfb_decode()函数总结的,不保证绝对正确。
Lcd屏中参数
垂直方向:
lcd控制器------------ lcd屏自身 ------------------------------- 驱动
VSPW tvpw 1<y<20 y=10 vsync_len
VBPD tvb-tvpw 23-tvpw 13 upper_margin
LINVAL tvd 480 yres
VFPD tvfp 22 lower_margin
水平方向:
HSPW thpw 1<x<40 x=20 hsync_len
HBPD thb-thpw 46-thpw 26 left_margin
HOZVAL thd 800 xres
HFPD thfp 210 right_margin
移植方式:
1. 修改自定义数据成如下: mach-smdkv210.c
static struct fb_videomode smdkv210_lcd_timing = {
.left_margin = 26, //46,
.right_margin = 210, //8,
.upper_margin = 13, //23,
.lower_margin = 22, //22,
.hsync_len = 20, //2,
.vsync_len = 10, //2,
.xres = 800,
.yres = 480,
};
2. 添加背光: smdkv210_machine_init(void)
添加以下代码:
gpio_request(S5PV210_GPD0(0),"gpd0_blacklight");
gpio_direction_output(S5PV210_GPD0(0),1);
gpio_free(S5PV210_GPD0(0));
3. 将driver/video/fbmem.c和s3c-fb.c这两层驱动编译到内核中:
在内核中:
make menuconfig
Device Drivers --->
Graphics support --->
<*> Support for frame buffer devices ---> // fbmem.c
<*> Samsung S3C framebuffer support // s3c-fb.c
Console display driver support --->
<*> Framebuffer Console support //内核启动的代码,会自动将启动logo图片放入到显存中显示
[*] Bootup logo ---> //启动logo图片
[*] Standard 224-color Linux logo (NEW)
make zImage -j2
cp -raf arch/arm/boot/uImage /tftpboot/
制作启动logo
1. jpg/bmp ---> 转换成ppm文件 (将图片转换为ppm格式,并放在内核路径下的 drivers/video/logo/ )
a, 制作ppm文件--gimp转换 (ppm图片的制作软件: 1.gtk+-2.10.13-setup 2.gimp-2.2.17-i586-setup)
b,编译进内核
logo_nexus_clut224.ppm
2. 在内核中编译一个文件: Kconfig 和 Makefile
2.1 drivers/video/logo$ vim Kconfig
30 config LOGO_NEXUS_CLUT224
31 tristate "My 224-color Nexus Logo"
32 help
33 you can choose y/n/m to build it
2.2 drivers/video/logo$ vim Makefile:
obj-$(CONFIG_LOGO_NEXUS_CLUT224) += logo_nexus_clut224.o
2.3 在启动的时候指定显示你自己做的logo
drivers/video/logo/logo.c
|
30 extern const struct linux_logo logo_nexus_clut224;
65 if (depth >= 8) {
66 #ifdef CONFIG_LOGO_NEXUS_CLUT224
67
68 logo = &logo_nexus_clut224;
69 #endif
2.4 在内核中要选择你的启动logo
make menuconfig
Device Drivers --->
Graphics support --->
--- Bootup logo
x x [ ] Standard black and white Linux logo
x x [ ] Standard 16-color Linux logo
x x [ ] Standard 224-color Linux logo
x x <*> My 224-color Nexus Logo (选择自己制作的那个)
2.5 重新编译内核:
make zImage -j2
cp -raf arch/arm/boot/uImage /tftpboot/