最近在RK3576平台上调试一块新的MIPI屏幕S8001280B1060B-32LB时遇到了一个典型问题:开发板厂商提供的设备树配置与新版屏幕不兼容。我使用的是野火LubanCat3开发板,搭配Buildroot 2024.02系统环境,而官方只提供了Debian/Ubuntu的支持。更棘手的是,官方代码中的屏幕驱动已经是旧版,而我手头的是新版屏幕。
这种情况在嵌入式开发中很常见——硬件迭代速度往往快于软件支持。幸运的是,经过检查发现硬件引脚定义没有变化,只是屏幕时序参数需要调整,这意味着我们不需要重写整个驱动,只需针对性地修改设备树配置即可。
在开始修改前,我们需要明确几个关键原则:
本次修改主要涉及两个部分:
背光部分因为硬件引脚未变,且原厂驱动已经完善,我们只需要在设备树中添加相应的PWM背光配置即可。屏幕时序则需要根据厂家提供的新参数进行全面调整。
在设备树根节点下添加backlight节点:
dts复制/ {
backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm1_6ch_2 0 25000 0>;
brightness-levels = <
0 20 20 21 21 22 22 23
// ... 中间省略多行 ...
248 249 250 251 252 253 254 255
>;
default-brightness-level = <200>;
};
};
关键参数说明:
pwms: 指定使用的PWM控制器和通道brightness-levels: 亮度等级曲线,实现非线性调节default-brightness-level: 默认亮度值启用对应的PWM控制器并设置引脚复用:
dts复制&pwm1_6ch_2 {
status = "okay";
pinctrl-0 = <&pwm1m1_ch2>;
};
这个配置依赖于内核中已经定义的PWM控制器:
dts复制pwm1_6ch_2: pwm@2add2000 {
compatible = "rockchip,rk3576-pwm";
reg = <0x0 0x2add2000 0x0 0x1000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm1m0_ch2>;
clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>, <&cru CLK_OSC_PWM1>;
clock-names = "pwm", "pclk", "osc";
status = "disabled";
};
在pinctrl文件中找到对应的引脚定义:
dts复制pwm1m0_ch2: pwm1m0-ch2 {
rockchip,pins =
/* pwm1_ch2_m0 */
<0 RK_PB6 12 &pcfg_pull_none>;
};
根据屏幕规格书,我们需要配置以下关键参数:
code复制params->dsi.vertical_sync_active=4
params->dsi.vertical_backporch=8
params->dsi.vertical_frontporch=30
params->dsi.horizontal_sync_active=20
params->dsi.horizontal_backporch=20
params->dsi.horizontal_frontporch=40
params->dsi.PLL_CLOCK=419
在dsi节点下添加display-timings配置:
dts复制disp_timings0: display-timings {
native-mode = <&dsi_timing0>;
dsi_timing0: timing0 {
clock-frequency = <69801600>;
hactive = <800>;
vactive = <1280>;
hsync-len = <20>;
hback-porch = <20>;
hfront-porch = <40>;
vsync-len = <4>;
vback-porch = <8>;
vfront-porch = <30>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
屏幕初始化需要通过一系列DCS命令完成:
dts复制panel-init-sequence = [
// 初始化命令序列
15 00 02 E0 00
15 00 02 E1 93
15 00 02 E2 65
15 00 02 E3 F8
15 00 02 80 03
// ... 后续省略多行 ...
15 05 02 29 00
];
每个命令的格式为:<延迟ms> <命令长度> <命令数据...>
项目中还需要配置UART10用于调试输出:
dts复制&uart10 {
pinctrl-names = "default";
pinctrl-0 = <&uart10m1_xfer>;
status = "okay";
};
对应的引脚复用配置:
dts复制uart10m1_xfer: uart10m1-xfer {
rockchip,pins =
/* uart10_rx_m1 */
<1 RK_PD1 9 &pcfg_pull_up>,
/* uart10_tx_m1 */
<1 RK_PD0 9 &pcfg_pull_up>;
};
触摸屏通过I2C2接口连接:
dts复制&i2c2 {
pinctrl-names = "default";
pinctrl-0 = <&i2c2m0_xfer>;
status = "okay";
gt911_dsi: gt911@5d {
status = "okay";
compatible = "goodix,gt911";
reg = <0x5d>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PD0 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio0 RK_PD1 GPIO_ACTIVE_LOW>;
irq-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&tp0_irq>;
touchscreen-inverted-x = <1>;
touchscreen-swapped-x-y = <1>;
};
};
dts复制&pinctrl {
dsi {
tp0_irq: tp0-irq {
rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
在修改内核代码时,强烈建议使用Git进行版本管理:
bash复制# 查看修改状态
git status
# 添加修改文件
git add rk3576-lubancat-3.dts rk3576-lubancat-3-S8001280B1060B.dtsi
# 提交修改
git commit -m "add dts"
# 查看提交历史
git log
根据本次实践经验,总结出设备树修改的五个关键步骤:
可能原因:
排查步骤:
可能原因:
解决方案:
bash复制# 在内核目录下执行
make ARCH=arm64 dtbs
将生成的dtb文件复制到boot分区:
bash复制cp arch/arm64/boot/dts/rockchip/rk3576-lubancat-3.dtb /boot/
在实际操作中,我发现设备树修改虽然看似复杂,但只要遵循一定的方法论,就能大大降低调试难度。以下是一些个人建议:
对于RK3576这类复杂SoC,建议在修改前先充分阅读《Rockchip DRM Display Driver Development Guide》等官方文档,理解其显示子系统的架构和工作原理。