RK3588 MIPI转LVDS屏幕调试全流程(附完整Patch)

电子说

1.4w人已加入

描述

在嵌入式 Linux 项目中,MIPI 转 LVDS 屏幕因兼容性强、适配灵活,常被用于盒子、工业设备等场景。但调试时难免遇到 “屏幕不亮”“分辨率错乱”“驱动 bind 失败” 等问题,尤其涉及转换 IC(如 TC358775XBG)时,软硬件协同排查更需精准。本文结合实际项目案例,梳理从问题定位到功能验证的标准化步骤,并附上完整调试 Patch,帮你快速突破瓶颈。

调试调试

一、问题初始化:先搞懂“哪里错了”

调试的核心是“先定位,再动手”,盲目改配置只会浪费时间。

1. 日志抓包锁定方向

屏幕未点亮时,优先查看 DSI 相关内核日志,执行:

 

dmesg | grep dsi  # 查看DSI通道初始化报错dmesg | grep pwm  # 排查背光驱动问题

 

常见报错对应问题

•“route-dsi1: failed to get logo”:dsi1 通道配置缺失或硬件链路异常

•“pwm8: probe failed”:PWM 背光引脚复用或节点未启用

•“TC358775: command_interface is busy”:转换 IC 上电时序错误

2. 必收 “基础档案”

调试前需同步以下文件,避免无依据修改:

•开机日志(systemlog.txt):含驱动加载、硬件初始化过程

•设备树(rk3588-evb.dtsi/rk3588-evb7-v11.dtsi):本次调试核心修改文件

•硬件文档:原理图(确认 DSI 通道、PWM 引脚)、屏幕手册(1920x1080@60Hz 时序)

•关键调试命令输出:

 

# 查看显示端口状态(确认Video Port激活情况)cat /sys/kernel/debug/dri/0/summary# 查看时钟状态(验证DSI/PWM时钟是否正常)cat /sys/kernel/debug/clk/clk_summary | grep -E "dsi|pwm"

 

二、硬件链路确认:排除“物理层” 问题

MIPI 转 LVDS 的核心链路是 “DSI 信号→转换 IC→LVDS 屏幕”,硬件问题需优先排除。

1. 核心组件信息确认(对应 Patch 硬件适配)

根据硬件设计,本次调试涉及:

转换 IC:TC358775XBG(需控制上电时序)

DSI 通道:dsi1(硬件连接 dsi1,禁用 dsi0 避免冲突)

PWM 背光:PWM8 引脚(GPIO2_RK_PB1 控制转换 IC 使能)

供电:新增 vcc3v3_lcd regulator 给屏幕供电

2. 硬件功能验证

•用万用表测转换 IC 供电引脚(如 VDD3.3V),确认上电正常;

•检查引脚复用:确保 PWM8、dsi1 引脚未被 UART/GPIO 占用(参考原理图);

•背光测试:短接 PWM8 与地,观察屏幕背光是否亮起(排除背光硬件问题)。

三、设备树(DTS)配置:核心修改看这 5 处(附 Patch 代码)

DTS 是软硬件的 “桥梁”,本次 Patch 中 80% 的问题通过 DTS 修改解决,关键变更如下:

1. 禁用冲突通道,启用目标 DSI

修改文件:kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi

 

// 禁用dsi0(避免通道冲突)&dsi0 {-    tus = "okay";+    tus = "disabled";  si0_panel: panel@0 {    atus = "disabled";  // 同步禁用dsi0面板   };// 启用dsi1并配置关键参数&dsi1 {    tus = "okay";-     ckchip,lane-rate = <1100>; /*1920*1080*/+   ckchip,lane-rate = <960>;     整为900Mbps(匹配屏幕时序)       able-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;  // 转换IC使能引脚     1_panel: panel@0 {      tus = "okay";  // 启用dsi1面板    si,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST|MIPI_DSI_MODE_LPM)>;       format = ;  // RGB888格式     i,lanes  = <4>;  // 4 lane传输      时序参数(匹配屏幕手册1920x1080@60Hz)        timings1: display-timings {       1_timing0: timing0 {         k-frequency = <148500000>;  // 像素时钟148.5MHz      active = <1920>;        tive = <1080>;          -porch = <64>;          t-porch = <134>;        ck-porch = <8>;         nt-porch = <30>;        nc-len = <24>;          -len = <2>;               };     }; }; }; vsync hsy vfro vba hfron hback vac h cloc dsi disp_ // ds dsi, d sta dsi           en   // 调     ro   //ro    sta     };            st      d    sta    sta

 

2. 启用 PWM 背光与屏幕供电

修改文件:kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi

 

// 新增屏幕3.3V供电regulatorvcc3v3_lcd: vcc3v3-lcd {    patible = "regulator-fixed";      ator-name = "vcc3v3_lcd";    -supply = <&vcc_3v3_s0>;  // 依赖主3.3V电源};// 启用PWM8背光引脚&pwm8 {     trl-0 = <&pwm8m1_pins>;  // 绑定PWM8引脚   atus = "okay";  // 解决背光不亮问题};// 配置显示路由(dsi1对应vp3)&route_dsi1 {-  tatus = "disabled";+    tus = "okay";      ct = <&vp3_out_dsi1>;  // 绑定Video Port3};// 禁用HDMI避免显示冲突(调试阶段)&hdmi0_in_vp0 {-      s = "okay";+  tatus = "disabled";};      s  statu  conne    sta      s     st   pinc    vin  regul    com

 

3. DTS 修改验证

编译后通过以下命令确认配置生效:

 

# 反编译dtb查看配置dtc -I dtb -O dts arch/arm64/boot/dts/rockchip/rk3588-evb.dtb > check.dts# 检查关键节点是否存在grep -E "dsi1.*okay|pwm8.*okay|vcc3v3_lcd" check.dts

 

四、驱动代码修改:解决转换 IC 控制与时钟匹配(附 Patch)

驱动层主要解决“转换 IC 上电时序”“时钟计算错误”“DCS 指令下发验证” 三大问题,核心修改如下:

1. 转换 IC 上电时序控制

修改文件:kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c

新增转换 IC 电源控制函数,确保上电顺序符合手册要求(先使能、再复位):

 

// 转换IC上电函数(enable→复位拉低→拉高→拉低)static void dsi_external_bradge_power_on(struct dw_mipi_dsi2 *dsi){   intk("debug_lvds_test: %sn", __FUNCTION__);    if (dsi->enable_gpio) {        gpiod_direction_output(dsi->enable_gpio, 1);  // 使能转换IC        usleep_range(1000, 2000);  // 延时1-2ms    }    if (dsi->reset_gpio) {        gpiod_direction_output(dsi->reset_gpio, 0);  // 复位拉低        usleep_range(1000, 2000);        gpiod_direction_output(dsi->reset_gpio, 1);  // 复位拉高        usleep_range(1000, 2000);        gpiod_direction_output(dsi->reset_gpio, 0);  // 复位稳定        usleep_range(1000, 2000);    }}// 转换IC下电函数static void dsi_external_bradge_power_down(struct dw_mipi_dsi2 *dsi){  rintk("debug_lvds_test: %sn", __FUNCTION__);    if (dsi->reset_gpio) {        gpiod_direction_output(dsi->reset_gpio, 1);        usleep_range(1000, 2000);    }    if (dsi->enable_gpio) {        gpiod_direction_output(dsi->enable_gpio, 0);        usleep_range(1000, 2000);    }}// 在编码器使能/禁用时调用电源控制static void dw_mipi_dsi2_encoder_enable(struct drm_encoder *encoder){     external_bradge_power_on(dsi2);  // 使能时上电    ... 原有初始化逻辑}static void dw_mipi_dsi2_encoder_disable(struct drm_encoder *encoder){  si_external_bradge_power_down(dsi2);  // 禁用时下电    ... 原有销毁逻辑}     //      d     //   dsi_      p     pr

 

2. 时钟计算修正(解决信号不稳定)

修改文件:kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c

调整 DSI 逃逸时钟分频,匹配转换 IC 要求:

 

static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2){    ... 原有配置     20MHz分频改为10MHz,避免时钟过高导致转换IC异常 */-      lk_div = DIV_ROUND_UP(sys_clk, 20 * 2);+    _clk_div = DIV_ROUND_UP(sys_clk, 10 * 2);   l |= PHY_LPTX_CLK_DIV(esc_clk_div);    ... 原有配置}     //     va    esc  esc_c   /* 原     //

 

3. DCS 指令下发验证

修改文件:u-boot/drivers/video/drm/rockchip_panel.c

添加打印确认 DCS 指令是否成功发送(排查 “屏幕亮但无显示” 问题):

 

static void panel_simple_prepare(struct rockchip_panel *panel){+    ntf("xsc panel_simple_prepare: 开始发送DCS指令n");    ... 原有逻辑      lat->on_cmds) {    t = rockchip_panel_send_dsi_cmds(dsi, plat->on_cmds);      ret)     intf("failed to send on cmds: %dn", ret);+      +        f("succed to send on cmds: %dn", ret);  // 指令成功打印        . 原有逻辑}  // ..      }                print          else                   pr          if (            re  if (p     //    pri

 

五、U-Boot 阶段适配(附 Patch)

启动阶段需提前初始化转换 IC 电源,避免 Linux 阶段初始化滞后:

修改文件:u-boot/drivers/video/drm/dw_mipi_dsi2.c

 

// 新增U-Boot阶段电源控制static void rockchip_dsi_external_bridge_power_on(struct dw_mipi_dsi2 *dsi){      t dw_mipi_dsi2 *priv = dev_get_priv(dsi->dev);   _gpio_set_value(&priv->enable_gpio, 1);  // 使能转换IC    lay(1000);    gpio_set_value(&priv->reset_gpio, 0);  // 复位拉低   elay(1000);   _gpio_set_value(&priv->reset_gpio, 1);  // 复位拉高        udelay(1000);        dm_gpio_set_value(&priv->reset_gpio, 0);  // 复位稳定}// 准备阶段调用电源控制static int dw_mipi_dsi2_connector_prepare(struct rockchip_connector *conn,                                          struct display_state *state){+        rockchip_dsi_external_bridge_power_on(dsi2);  // U-Boot阶段上电        // ... 原有逻辑}     dm     ud    dm_    ude     dm  struc

 

六、功能验证:3 步确认调试结果

1.背光验证:开机后观察屏幕背光是否亮起(PWM8 配置生效);

2.彩条测试:执行modetest -M rockchip -s 224@115:1920x1080,屏幕显示彩条说明信号正常;

3.日志验证:查看dmesg无 DSI/PWM 报错,cat /sys/kernel/debug/dri/0/summary显示“dsi1 connected”。

七、Patch 核心修改总结

模块 修改内容 解决问题
DTS(dsi) 禁用 dsi0、启用 dsi1 + 时序配置 通道冲突、分辨率错乱
DTS(电源) 新增 vcc3v3_lcd、启用 PWM8 屏幕供电不足、背光不亮
驱动(电源) 新增转换 IC 上电时序函数 转换 IC 初始化失败
驱动(时钟) 调整 DSI 逃逸时钟分频 信号不稳定、屏幕闪烁
U-Boot 启动阶段电源控制 Linux 阶段初始化滞后

调试

结语

MIPI 转 LVDS 调试的核心是 “分层排查”:先排除硬件供电 / 连接问题,再通过 DTS 匹配硬件配置,最后通过驱动解决时序 / 控制问题。本文附上的完整 Patch 覆盖了从启动到运行的全流程适配,你可根据实际硬件调整引脚、时钟、时序等参数。

若调试中遇到“彩条正常但应用无显示”“双显冲突” 等问题,欢迎在评论区留言,我们一起完善调试指南~

以下是完整patch,有需要自取(获取指令后台获取)

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
jf_88971412 04-10
0 回复 举报
这个资料怎么获取 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分