RK3399-新老MIPI屏兼容问题

背景

  • Platform: RK3399
  • OS: Android7.1.2
  • Kernel: v4.4.103

项目经常会遇到屏供应商屏幕停产,驱动IC升级等问题,如果产品已经量产或出货,软件上就需要考虑新旧屏幕的兼容问题,避免维护多套软件代码。
这里我们遇到了MIPI屏升级驱动IC的情况。

分析

主要思路就是初始化屏幕之前,先读取驱动IC的ID,然后通过不同的ID去使用DTS里面的不同初始化参数,也可以通过读取不同的ID来加载不同的DTS。此方式主要适用于兼容的驱动IC之间,除了初始化参数不同之外,其他参数基本相同的情形。

RK3399的MIPI屏采用的是DRM,panel-simple驱动
需注意的是uboot和内核里面都需要同步修改。

解决

主要路径及文件:

  • kernel:
    路径:kernel/drivers/gpu/drm
    相关文件:panel-simple.c-->drm_mipi_dsi.c->dw-mipi-dsi.c

  • uboot:
    路径:u-boot/drivers/video
    相关文件:rockchip_dsi_panel.c -> rockchip_mipi_dsi.c->rockchip-dw-mipi-dsi

kernel部分修改

panel-simple.c文件修改:

  1. panel_simple_enable函数中添加
    读取ID操作及根据ID发送不同的初始化代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    +	/*---- modify start 2020.5.7----*/
    + /// new/old MIPI LCD, read ID DCh
    + //mipi_dsi_generic_read(dsi, );
    + err = mipi_dsi_dcs_read(dsi, 0xDC, &mipi_id3, sizeof(mipi_id3));
    + if (err <= 0) {
    + dev_err(&dsi->dev, "mipi_dsi_dcs_read ID ,error=%d!!\n", err);
    + return err;
    }
    + DBG("mipi_dsi_dcs_read ID=%x\n", mipi_id3);
    +
    + if(mipi_id3 == 0x04) //new LCD
    + {
    + if (p->on_cmds_new) {
    + err = panel_simple_dsi_send_cmds(p, p->on_cmds_new);
    + if (err)
    + dev_err(p->dev, "failed to send new on cmds\n");
    + }
    + }
    + else if(mipi_id3 == 0xff)
    + {
    + if (p->on_cmds) {
    + err = panel_simple_dsi_send_cmds(p, p->on_cmds);
    + if (err)
    + dev_err(p->dev, "failed to send on cmds\n");
    + }
    + }
    + /*---- modify end 2020.5.7----*/

需要注意读取ID的时机和位置
需要确认dw-mipi-dsi.c中是否支持DCS读操作(MIPI_DSI_DCS_READ),以前的老版本好像是不支持的,需要更新代码

  1. panel_simple_dsi_probe添加获取不同屏的初始化代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    +	data = of_get_property(dsi->dev.of_node, "panel-init-sequence-new", &len);
    + if (data) {
    + panel->on_cmds_new = devm_kzalloc(&dsi->dev,
    + sizeof(*panel->on_cmds_new),
    + GFP_KERNEL);
    + if (!panel->on_cmds_new)
    + return -ENOMEM;
    + err = panel_simple_dsi_parse_dcs_cmds(&dsi->dev, data, len,
    + panel->on_cmds_new);
    + if (err) {
    + dev_err(&dsi->dev, "failed to parse panel init sequence new\n");
    + return err;
    + }
    + }
    + /*---- modify end 2020.5.13----*/
    + data = of_get_property(dsi->dev.of_node, "panel-init-sequence-old", &len);

uboot部分修改

同kernel类似

扩展

  • MIPI Generic和DCS指令的区别:
    在读/写指令时,Generic指令 是不区分 Index 和 parameter 的,而 DCS 会默认把 data0 作为Index 然后计算 parameter 数目
    mipi_dsi_generic_read/mipi_dsi_generic_write
    mipi_dsi_dcs_read/mipi_dsi_dcs_write/mipi_dsi_dcs_write_buffer

  • DCS commands
    命令的前面三个字节分别表示命令类型、延时和命令净荷长度。从第四个字节开始表示命令的有效 payload

  • 模式
    video mode和command mode
    MIPI_DSI_MODE_LPM MIPI_DSI_MODE_EOT_PACKET
    MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_LPM

  • 硬件排查:

  1. 检查各种供电电压及电平
    VCCIO的电平与reset的电平
  2. 上电时序
    reset的时序,en和reset引脚的控制
  3. cmd发送是否成功,看打印,
  4. 信号完整性
    时钟数据是否有波形,降低时钟试试

https://blog.csdn.net/kris_fei/article/details/79073705
https://blog.csdn.net/kris_fei/article/details/79003925
https://blog.csdn.net/kris_fei/article/details/79099111

Donate comment here