浅谈瑞芯微RK3588的MIPI屏Linux驱动移植

1,701 阅读8分钟

【原创声明】:本文系原创作品,谢绝任何形式的未经授权的转载。如需转载,请先私信联系我获取许可,谢谢合作!

MIPI协议简介

MIPI(Mobile Industry Processor Interface)协议是由 MIPI 联盟制定的一系列高速串行通信标准,主要用于移动设备及嵌入式系统中的数据传输,涵盖摄像头、显示屏、存储、传感器等多个领域。其目标是提供高效、低功耗、低引脚数的接口标准,以满足现代移动设备对高速数据传输的需求。

屏幕移植概述

Linux 驱动中移植MIPI屏幕主要有两种方式:

  1. 编写DTS文件
  2. 基于DRM Panel框架编写C语言代码

我们着重聊一下在Rockchip平台下的DTS移植方式。

屏幕核心参数

首先在移植之前,我们需要熟读屏幕的Datasheet,重点关注如下参数

  1. 屏幕分辨率
  • Hactive 水平有效区域,即屏幕的 宽度像素数
  • Vactive 垂直有效区域,即屏幕的 高度像素数
  1. 屏幕的Data Lanes
  2. 屏幕背光(OLED屏为自发光,此参数可以忽略)
  3. Refresh Rate 刷新率,屏幕每秒刷新的次数,通常是 60Hz、90Hz、120Hz 等
  4. 屏幕的像素参数
  • HFP: Horizon Front Porch 行前消隐
  • HBP: Horizon Back Porch 行后消隐
  • VFP: Vertical Front Porch 垂直前消隐
  • VBP: Vertical Back Porch 垂直后消隐
  • HSYNC:Horizontal Sync Length 行同步信号持续时间
  • VSYNC: Vertical Sync Period 垂直同步信号持续时间
  • Pixel_clk: Pixel Clock:表示 每秒传输的像素数量

Display_timing.png

  1. 初始化序列 & 关闭序列,

屏幕序列是主控芯片通过MIPI-D0数据线发送给屏幕的一组数据,从而控制屏幕。

  • 初始化序列:用于设置屏幕参数并点亮屏幕

这段序列一般是在初始化时序执行完成后发送。

  • 关闭序列:用于在系统休眠或关机时关闭屏幕
  1. 像素数据格式,每个像素的颜色存储方式,例如:RGB888、RGB565等

RK3588S 详细配置

屏幕sequence序列

通过MIPI-D0数据线向屏幕发送sequence序列,从而操纵屏幕进行参数的设置。

我们需要将屏幕厂商提供的屏幕sequence序列“翻译”成针对RK3588S平台的字节序列,填写到DTS文件中。

初始化sequence序列

panel-init-sequence,设置相关值,点亮屏幕

panel-init-sequence = [ 
        15 00 02 80 ac
        15 00 02 81 b8
        15 00 02 82 09
        15 00 02 83 78
        15 00 02 84 7f
        15 00 02 85 bb
        15 00 02 86 70
];
关闭sequence序列

panel-exit-sequence,设置相关值,关闭屏幕

panel-exit-sequence = [ 
       05 00 01 28
       05 00 01 10
];

引脚定义

在初始化&关闭序列之前,我们需要针对屏幕的上电或下电、Enable或Disable、Reset 通过GPIO引脚进行控制,从而满足屏幕的时序要求。这就需要在前期电路设计时,要充分考虑当前屏幕需要几个GPIO引脚进行控制。要特别注意的是,有些屏幕需要分别控制多路电压上电,这时需要多路GPIO来完成上电功能。例如:一些屏幕的负电压需要在正电压上电前间隔一段时间上电。

我们先来看看使能引脚和Reset引脚 enable-gpios 用于定义用来使能屏幕的GPIO引脚,和使能所需电平。

这段代码的含义是,用GPIO1_B5这个引脚进行使能,并且是一直保持低电平使能。 enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>;

reset-gpios 用于定义用来Reset屏幕的GPIO引脚,和使能所需电平。

这段代码的含义是,用GPIO1_B4这个引脚进行重启,并且是Reset是低电平有效。 reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;

初始化时序

  1. 通过power-supply配置进行上电
  2. enable-gpios进行使能
  3. Delayprepare-delay-ms时间,准备进行Reset操作
  4. 设置reset-gpiosReset管脚(根据电平拉低或拉高)
  5. Delayreset-delay-ms时间,保持Reset状态
  6. 恢复reset-gpiosReset管脚
  7. Delayinit-delay-ms,准备发送初始化序列
  8. 通过MIPI-D0数据线发送 [初始化sequence序列](#### 初始化sequence序列)
  9. Delayenable-delay-ms时间,准备点亮背光
  10. 点亮背光

U-boot rockchip_panel_probe 读取DTS的配置 panel_simple_prepare 执行 第1步到第7步 rockchip_panel_send_dsi_cmds 执行 第8步 panel_simple_enable 执行 第9步到第10步

初始化&关闭的时序

关闭时序

  1. 关闭背光
  2. Delay disable-delay-ms,准备发送关闭序列
  3. 通过MIPI-D0数据线发送 [关闭sequence序列](#### 关闭sequence序列)
  4. 设置reset-gpios管脚并保持复位状态
  5. 设置enable-gpios为Disable
  6. 下电
  7. Delayunprepare-delay-ms

U-boot panel_simple_disable 执行第1、2步 panel_simple_unprepare 执行 第3步到第7步

屏幕参数

下面我们来看一下DTS中屏幕相关的配置参数:

hactive 水平分辨率 vactive 垂直分辨率 hfront-porch 行前消隐 hback-porch 行后消隐 hsync-len 行同步信号持续时间 vfront-porch 垂直前消隐 vback-porch 垂直后消隐 vsync-len 垂直同步信号持续时间 clock-frequency 时钟屏率,单位Hz,计算公式如下:

clock_frequency=(HActive+HFP+HBP+HSYNC)×(VActive+VFP+vVBP+VSYNC)×Refresh_Rateclock\_frequency=(HActive + HFP + HBP + HSYNC) \times (VActive + VFP + vVBP + VSYNC) \times Refresh\_Rate

dsi,format 屏幕像素数据格式,通常设置为MIPI_DSI_FMT_RGB888,当然需要根据屏幕的属性来设置,可选项有:MIPI_DSI_FMT_RGB666MIPI_DSI_FMT_RGB666_PACKEDMIPI_DSI_FMT_RGB565

dsi,flags DSI2工作模式,通常设置为<(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>,下面我们来一一梳理对应的含义: - MIPI_DSI_MODE_VIDEO 视频模式,该模式下,系统会持续向屏幕发送像素数据,通常用于实时渲染。 - MIPI_DSI_MODE_VIDEO_BURST 视频突发传输模式,在此模式下数据会被分成多个突发(Burst)传输,数据发送完成后,接收方会确认接收完毕,再继续传输下一块数据。这种模式通常用于减少低频传输的延迟提高效率,也可以减少功耗。 - MIPI_DSI_MODE_LPM 低功耗模式,允许DSI接口在不传输数据时进入低功耗状态。 - MIPI_DSI_MODE_EOT_PACKET EOT(End of Transmission)。DSI接口会在每次传输结束时发送一个EOT数据包,从而标志着数据传输的结束,帮助屏幕控制器更高效的管理数据流。 dsi,lanes 屏幕支持的MIPI data通道数,MIPI接口通过多个差分对传输数据,每个差分对称为一个数据通道(Lane),数据通道越多,总带宽越高,可支持更高分辨率或更快刷新率。

常见数据通道数:

通道数典型应用场景带宽能力(示例)
1 Lane低分辨率显示屏(如小型智能手表屏幕)适用于 480x800@60Hz 等低需求场景。
2 Lanes中端手机屏幕、低分辨率摄像头支持 1080p@60Hz 显示或 8MP 摄像头。
4 Lanes高端手机/平板屏幕、高分辨率摄像头支持 4K@60Hz 显示或 12MP+ 摄像头。
8 Lanes专业显示设备、超高速摄像头用于 8K 显示或高速工业相机。

其他参数

status 当前屏幕是否使能,有两种取值:"okay" "disabled" power-supply 电源管理相关设置。 pinctrl-0 设置用于Reset和Enable的GPIO引脚定义,类似于enable-gpiosreset-gpios使用前的声明

lcd_rst_gpio: lcd-rst-gpio {
        rockchip,pins = 
        <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>,
        <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
};

backlight 背光引用,compatible = "pwm-backlight"类型,用于控制背光的亮暗。

route_dsi0 U-Boot 和 Kernel开机logo

    - `status`  功能是否使能,两种取值:"okay"、"disabled"
    - `connect` 显示在哪一路通道,例如 `<&vp2_out_dsi0>` 对应VP2通道 DSI-0设备
    - `logo,uboot` U-Boot启动阶段显示的图片,只支持8bit,16bit,24bit、32bit的BMP图片
    - `logo,kernel` Linux Kernel启动阶段显示的图片,只支持8bit,16bit,24bit、32bit的BMP图片
    - `logo,mode` 显示模式,两种取值:居中显示"center",全屏显示"fullscreen"

&route_dsi0 {
        status = "okay";
        connect = <&vp2_out_dsi0>;
        logo,uboot = "logo_uboot.bmp";
        logo,kernel = "logo_kernel.bmp";
        logo,mode = "center";
};

uboot_logo.jpg

dsiX_in_vpY 用于表示VP(Video Processor,视频处理器) 和 DSI(Display Serial Interface,显示串行接口)的连接关系,X的取值可以是1、2,而Y的取值可以是1、2、3,但是一路VP只能绑定一个DSI通道。

DSI和VP连接关系

例如:下面的这段代码将DSI-0映射到了VP2,并同时禁止了DSI-0到VP3的映射

&dsi0_in_vp2 {
        status = "okay";
};

&dsi0_in_vp3 {
        status = "disabled";
};

参考资料

本篇文章以风火轮-MIPI 7寸LCD(Q7030TM16441BA0)为例。

  • [1] Rockchip RK3588 MIPI-DSI2软件开发指南

  • [2] Linux Kernel: drivers/gpu/drm/panel/panel-simple.c

  • [3] U-Boot: drivers/video/drm/rockchip_panel.c