1. 版本背景
- 发布时间:2011年7月21日
- LVDS支持状态:基础LVDS桥接器支持,主要通过平台特定驱动实现
- 关键里程碑 :
- DRM/KMS框架初步稳定
- OMAP、i.MX等平台LVDS驱动整合
- Panel简单时序配置支持
2. 驱动框架架构
整体架构
+---------------------+
| 用户空间 |
| DRM API (libdrm) |
+----------+----------+
|
+----------v----------+
| 内核空间 |
| DRM核心子系统 |
+----------+----------+
|
+----------v----------+
| LVDS桥接器驱动 |
| (platform-specific)|
+----------+----------+
|
+----------v----------+
| LVDS物理层 |
+---------------------+
核心组件
- DRM框架 :
drivers/gpu/drm/目录下核心实现 - 平台驱动 :
drivers/gpu/drm/omapdrm/(OMAP),drivers/gpu/drm/imx/(i.MX) - LVDS桥接器 :
drivers/gpu/drm/bridge/下的简单桥接实现 - Panel驱动 :
drivers/gpu/drm/panel/中的面板配置
3. 关键函数解析
LVDS桥接器初始化
// drivers/gpu/drm/omapdrm/omapdss/lvds.c
static int omapdss_lvds_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
struct omap_dss_device *in = dssdev->src;
int r;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
dst->src = dssdev;
dssdev->dst = dst;
return 0;
}
- 关键函数 :
connect():建立LVDS与上游设备连接enable():激活LVDS输出disable():禁用LVDS输出set_timings():配置显示时序
时序配置实现
// drivers/gpu/drm/omapdrm/omapdss/dpi.c
int dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct dpi_data *dpi = to_dpi_data(dssdev);
u32 l = 0;
l |= FLD_VAL(timings->hbp, 27, 16);
l |= FLD_VAL(timings->hfp, 11, 0);
dpi_write_reg(dpi, DPI_TIMING_H, l);
/* 垂直时序配置 */
l = 0;
l |= FLD_VAL(timings->vbp, 27, 16);
l |= FLD_VAL(timings->vfp, 11, 0);
dpi_write_reg(dpi, DPI_TIMING_V, l);
return 0;
}
- 时序参数 :
hbp(Horizontal Back Porch)hfp(Horizontal Front Porch)vbp(Vertical Back Porch)vfp(Vertical Front Porch)
4. 硬件寄存器操作
i.MX53 LVDS控制器寄存器
| 寄存器 | 地址偏移 | 功能 |
|---|---|---|
| LDB_CTRL | 0x00 | 控制LVDS通道使能 |
| LDB_CONTRAST | 0x04 | 对比度控制 |
| LDB_VIDEO_MODE | 0x08 | 视频模式配置 |
| LDB_HSYNC_WIDTH | 0x10 | 水平时钟宽度 |
| LDB_VSYNC_WIDTH | 0x14 | 垂直时钟宽度 |
寄存器配置示例
// arch/arm/mach-mx5/mx53_loco.c
static void __init imx53_lvds_init(void)
{
void __iomem *ldb_base = MX53_LDB_BASE_ADDR;
/* 使能LVDS通道 */
writel(0x1, ldb_base + LDB_CTRL);
/* 配置视频模式 */
writel((1 << 24) | (1 << 16) | (1 << 8),
ldb_base + LDB_VIDEO_MODE);
/* 配置时序 */
writel(0x40000040, ldb_base + LDB_HSYNC_WIDTH);
writel(0x10000010, ldb_base + LDB_VSYNC_WIDTH);
}
- 关键位域 :
LDB_CTRL[0]:通道0使能LDB_VIDEO_MODE[24]:数据使能极性LDB_VIDEO_MODE[16]:水平同步极性LDB_VIDEO_MODE[8]:垂直同步极性
5. 时序配置详解
时序参数计算
Total Width = Active + HFP + HBP + HSYNC
Total Height = Active + VFP + VBP + VSYNC
Pixel Clock = (Total Width × Total Height × Refresh Rate)
典型WVGA面板配置
// drivers/video/omap2/displays/panel-lgd-wvga.c
static struct omap_video_timings lgd_wvga_timings = {
.x_res = 800,
.y_res = 480,
.pixel_clock = 32000, /* kHz */
.hfp = 40,
.hbp = 60,
.hsw = 48, /* 水平同步宽度 */
.vfp = 13,
.vbp = 10,
.vsw = 3, /* 垂直同步宽度 */
.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
};
- 注意事项 :
- 时钟极性必须与面板规格匹配
- 前/后沿必须满足面板最小要求
- 像素时钟需在面板支持范围内
6. 调试技巧与工具
内核调试接口
-
debugfs路径:
/sys/kernel/debug/dri/0/sys/kernel/debug/omapdss
-
常用调试命令:
# 查看当前显示状态 cat /sys/kernel/debug/dri/0/state # 查看LVDS寄存器值 cat /sys/kernel/debug/omapdss/lvds_reg
常见调试方法
-
寄存器转储:
// drivers/gpu/drm/omapdrm/omapdss/lvds.c static void lvds_dump_regs(struct seq_file *s) { struct lvds_data *lvds = s->private; u32 l; l = readl(lvds->base + LDB_CTRL); seq_printf(s, "LDB_CTRL: %08x\n", l); /* 其他寄存器... */ } -
时序验证:使用示波器测量HSYNC/VSYNC信号
-
背光调试 :通过
/sys/class/backlight/接口控制
7. 版本差异对比
| 特性 | Linux 2.6.39 | Linux 3.0 |
|---|---|---|
| DRM/KMS架构 | 初步整合 | 更稳定 |
| LVDS桥接器 | 无统一框架 | 平台特定驱动 |
| Panel支持 | 有限 | 增加WVGA支持 |
| 时序配置 | 简单 | 增加极性控制 |
8. 实际硬件适配案例
i.MX53 LVDS适配
硬件平台:Freescale i.MX53 Quick Start Board
设备树配置:
&ldb {
status = "okay";
lvds-channel@0 {
fsl,lvds-channel = "lcdif";
status = "okay";
display = <&display0>;
};
};
&display0 {
bits-per-pixel = <24>;
display-timings {
native-mode = <&timing0>;
timing0: wvga-800x480 {
clock-frequency = <32000000>;
hactive = <800>;
vactive = <480>;
hfront-porch = <40>;
hback-porch = <60>;
hsync-len = <48>;
vfront-porch = <13>;
vback-porch = <10>;
vsync-len = <3>;
hsync-active = <1>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
9. 常见问题与解决方案
1. 屏幕无显示
-
可能原因:
- LVDS通道未使能
- 时序配置不匹配
- 电源未正确供给
-
解决方案:
# 检查寄存器状态 cat /sys/kernel/debug/omapdss/lvds_reg # 验证时序参数 dmesg | grep -i timing
2. 屏幕闪烁
- 可能原因 :
- 时钟极性不匹配
- 信号完整性问题
- 解决方案 :
- 检查
vsync_level和hsync_level - 增加LVDS线路的终端电阻
- 检查
10. 参考资料
- 内核源码:
drivers/gpu/drm/omapdrm/,arch/arm/mach-mx5/ - i.MX53参考手册:Chapter 22 - LCDIF
- OMAP4显示子系统文档:https://processors.wiki.ti.com
- DRM内核文档:GPU Driver Developer's Guide --- The Linux Kernel documentation