RK 平台 MIPI 点屏注意事项
2019-10-14
关键字:rk3288 MIPI 点屏
rk 平台关于 MIPI 屏幕的点屏流程已经非常完善了,基本上只要确定了硬件没问题、接线没问题、屏幕没问题,再稍稍配置一下 dtsi 里的参数就可以的了。
MIPI 点屏流程大致可以概括为以下几步:
1、确认硬件环境;
2、确认相关接口管脚;
3、配置屏幕背光 dts;
4、配置 MIPI 屏幕参数;
5、屏幕显示效果调校。
1、确认硬件环境
确认硬件环境这个活理论上来说是由硬件人员来提供保证的,大多数软件人员都不懂这块的知识,只能相信他人。但他人毕竟是他人,你无法保证他人不会犯迷糊,所以有的时候身为软件人员,要和硬件打交道的话,会很痛苦。
言归正传,所谓确认硬件环境,无非就是要确认以下几点信息:
1、MIPI 排线接口电路正确;
2、板端接口到屏端接口的走线正确;
3、供电符合要求。
保证了以上三点就可以开始软件点屏了。
2、确认相关接口管脚
这个是要根据板端原理图来确认哪些引脚是接到我们要点的屏幕上去的。
例如,通常 rk 的芯片都会有多组视频信号输送接口,如 lcd0 ~ lcdx。我们要找到属于我们的那个管脚。
还要找到控制背光开关的管脚。由于背光电流强度是由 pwm 来决定的,所以还要再确认好是哪组 pwm 用于控制我们要点的屏幕。
3、配置屏幕背光 dts
直接修改 kernel 的 dts 文件即可。
不同板端所使用的 dts 文件通常不一致,所以这步要自行确认自己使用的是哪一个文件。不过这个文件通常都位于以下目录中:
./kernel/arch/arm/boot/dts/
在你的 dts 文件中,主要是要找到 backlight 节点,然后再配置 pwm 与 gpio 信息,如下所示:
backlight { compatible = "pwm-backlight"; pwms = <&pwm2 0 25000>; brightness-levels = < ... >; default-brightness-level = <200>; enable-gpios = <&gpio7 GPIO_C6 GPIO_ACTIVE_HIGH>; };
其次再将对应的 pwm 节点置为可用状态:
&pwm2 { status = "okay"; };
然后可以关注一下以下节点配置,它表明了这个屏幕的参数被记载的节点名称,后续初始化屏幕时就会去这里指定的节点里查找信息:
&rk_screen { display-timings = <&disp_timings>; };
最后是将输送视频信号的相关功能置为开启状态,这个需要参考原理图才能决定填哪个了:
&lcdc0 { status = "okay"; rockchip,mirror = <NO_MIRROR>;
... }
4、配置MIPI屏幕参数
这一步就是配置上一步中提到的 display-timins = <&disp_timings>; 的信息了。
通常这个节点的信息会独立保存在一个文件后缀为 dtsi 的文件中。它在配置好以后是通过前面的 dts 文件 include 进来使用的。
这个 dtsi 文件中的信息主要有以下四种节点:
1、disp_mipi_init: mipi_dsi_init 节点;
2、disp_timings: display-timings 节点;
3、disp_mipi_power_ctr: mipi_power_ctr 节点;
4、disp_mipi_init_cmds: screen-on-cmds 节点。
disp_mipi_init: mipi_dsi_init
这个节点一般记载有以下信息:
disp_mipi_init: mipi_dsi_init{ compatible = "rockchip,mipi_dsi_init"; rockchip,screen_init = <1>; rockchip,dsi_lane = <4>; rockchip,dsi_hs_clk = <600>; rockchip,mipi_dsi_num = <1>; };
screen_init 参数表示这块屏幕是否需要做初始化操作。通常 MIPI 屏幕都是要做的,置 1 表示需要,置 0 表示不需要。
dsi_lane 表示屏幕用于传输信息的通道数量。这个要根据屏幕规格书业确认,例如:
这就表示这块 MIPI 屏幕有 4 组数据线,所以填 4 就好。
dsi_hs_clk 表示总时钟数,单位为 MHZ。
mipi_dsi_num 一般填 1 就好。
disp_timings: display-timings
这个节点中的内容关乎于屏幕的参数信息。它的结构如下示例所示:
disp_timings: display-timings { native-mode = <&timing0>; compatible = "rockchip,display-timings"; timing0: timing0 { screen-type = <SCREEN_MIPI>; out-face = <OUT_P666>; clock-frequency = <50000000>; hactive = <800>; vactive = <1280>; hback-porch = <32>; hfront-porch = <32>; vback-porch = <32>; vfront-porch = <22>; hsync-len = <4>; vsync-len = <4>; hsync-active = <0>; vsync-active = <0>; de-active = <0>; pixelclk-active = <0>; swap-rb = <0>; swap-rg = <0>; swap-gb = <0>; }; };
这个节点的信息含义不作过多解释,这里仅关注如何填值。
这块节点的信息基本要从屏幕规格书中来。
screen_type 可填的值有:SCREEN_MIPI , SCREEN_DUAL_MIPI。
out-face 可填的值有:OUT_P565 , OUT_P666 , OUT_P888。
后面的信息就要查阅屏幕规格书,通常可以找到 INPUT_SIGNAL_TIMING 章节,其中通常会记载有类似信息:
clock-frequency 就是上图中的 DCLK frequency 中的数据。这些表格中,我们一般取 Typ 列的值来使用。
hactive 与 vactive 就是屏幕分辨率,这个信息对应于上图表中的 Horizontal Display Area 与 Vertical Display Area。
hback-porch 对应于 Hs Back Porch。
hfront-porch 对应于 Hs Front Porch。
vback-porch 对应于 Vs Back Porch。
vfront-porch 对应于 Vs Front Porch。
hsync-len 对应于Hs pulse width。
vsync-len 对应于 VS Pulse Width。
通常填好这几个参数就可以了。
disp_mipi_power_ctr: mipi_power_ctr
这个节点记载 MIPI 屏幕的重置脚与使能脚的信息。根据实际情况配置即可。
disp_mipi_power_ctr: mipi_power_ctr { compatible = "rockchip,mipi_power_ctr"; mipi_lcd_rst:mipi_lcd_rst{ compatible = "rockchip,lcd_rst"; rockchip,gpios = <&gpio7 GPIO_B4 GPIO_ACTIVE_HIGH>; rockchip,delay = <100>; }; mipi_lcd_en:mipi_lcd_en { compatible = "rockchip,lcd_en"; rockchip,gpios = <&gpio0 GPIO_A2 GPIO_ACTIVE_HIGH>; rockchip,delay = <100>; }; };
disp_mipi_init_cmds: screen-on-cmds
这个节点中记载的是屏幕的初始化指令。指令内容通常需要厂家提供。厂家给过来的指令有可能不是直接适配到 RK 平台的,需要做转换。
那如何转换呢?我这里直接援引某位大神博客(https://blog.csdn.net/sdkdlwk/article/details/78698494)中的内容了,如下图所示:
我这里需要额外强调一点:0x29 和 0x39 是有区别的,不可通用,如果你发现自己的指令内容没有错,但就是点不起来,那么可以尝试一下更改 0x29 系或 0x39 系看看效果。
5、屏幕显示效果调校
如果按照上面的配置能正常显示自然是最好,但也不能排除仍然无法显示,或者是显示的效果不好的。这种情况就需要调校上一步中的参数信息了。
首先是屏幕初始化指令,指令一定要正确,这里说的正确除了指令内容正确外还得保证指令成功写了出去。有些屏幕它的单条初始化指令是很长的,而 RK 默认的单条指令长度又有限制,当指令内容过长时,就会导致段错误的发生,直接引起无法开机。
如何解决这个问题呢?答案是增大系统中保存指令的空间。在哪里改?在 uboot 中。
./u-boot/drivers/video/screen/lcd_mipi.c
在这份代码中会去解析 dtsi 中的指令,并存于一个数组中,直接将数组长度增大即可,如下图所示:
当然,不敢保证所有人的代码结构都和笔者的是一样的,如果你的代码中并没有这样一个数组,那么还可以改这个结构体:
./u-boot/drivers/video/transmitter/mipi.dsi.h
在这个头文件中有一个结构体 struct dcs_cmd,将它里面的 cmds 数组的长度更改一下即可:
如果改了这个仍然不起效果,那可能你的代码是被改动过的。这个时候就需要自行跟踪源码,看看它究竟把这些初始化指令保存到哪里去的。一般直接跟踪上面提到的 lcd_mipi.c 中的 rk_mipi_screen_init_dt 函数就可以的了。
其次是时钟信息。时钟不正确会导致显示不出来内容或者颜色有偏差。这里说的时钟包含:rockchip,dsi_hs_clk 与 clock-frequency。尤其是 dsi_hs_clk 节点,它代表总时钟,clock-frequency 代表单通道的时钟,因此前者时钟总是要比后者时钟大。关于这个关系的确定,我再贴上另一个大神博客(https://blog.csdn.net/u012715694/article/details/51751006)中的内容,如下图所示:
最后还得关注下disp_timins 节点中的信息,它们也是会直接影响到显示效果的:
实在不行的话,就用最笨的办法,一个一个去调去试,看看哪个出来的效果最好。当然,如果你有专业的理论知识可以直接计算出来,那就最好不过了。笔者很遗憾,笔者没有!