MIPI(移动行业处理器接口)是Mobile Industry Processor Interface的缩写。MIPI(移动行业处理器接口)是MIPI联盟发起的为移动应用处理器制定的开放标准。其中 DSI(Display Serial Interface)定义了一个位于处理器和显示模组之间的高速串行接口。目前MIPI DSI是大多数SOC上面的标配。RK3399上面有两组DSI,Tinker board 2将其中一组DSI引出。本文以YYT_MIPI7LCD_2203为例介绍如何在tinker board 2s的Debian下面使用MIPI DSI接口。另外,与移动应用处理器适配的屏幕通常会带有触摸功能,本文也一并介绍。
要针对 MIPI-DSI接口触摸屏 定制Debian固件,需要先进行如下准备工作
修改好的Debian固件需要用瑞芯微烧录工具烧录。不能使用balena-etcher烧录。
其中Debian固件笔者用的是下图的这个,这个可以直接用瑞芯微烧录工具烧录,调试起来较为方便,如果使用的是其他固件,可以用dd命令直接烧录某个分区以替代。
无论用哪个固件,需要先把整个debian系统烧录到Tinker board 2里面,适配 MIPI-DSI接口触摸屏 只需要修改内核部分,其他部分不需要修改。
下面将分别介绍MIPI-DSI接口的适配方法和I2C触摸功能的适配方法
除了Tinkerboard 2/2S以及触摸屏之外,建议准备个大功率的电源,电源要用12V 2A的,不然带不动屏幕,屏幕电源要由主板提供,且电源质量要比较好,不然会干扰屏幕显示。
在购买YYT MIPI7 LCD 2203的时候,会附带一个转接板,其定义如下
然后需要接线,在上图中已经标明了转接板上面的接口,其中
接线的图如下
触摸复位 触摸中断 TCON电源 TCON使能脚 可以根据实际情况另外选择,此处只是给出一种参考
无论通过github还是网盘下载源码,都至少需要kernel和prebuilts两个目录,前者是内核源码目录,后者是交叉编译器目录,这两个文件夹必须在同一文件夹下,否则无法编译
如果读者希望直接修改,并不想了解其原理,可以略过下面的部分,直接看 相关源码下载与替换说明 章节。
简单介绍一下目前 RK3399的显示框架。目前的Debian采用的都是Linux DRM框架进行显示,在DRM框架中,其显示通路如下图所示
图中的几个组成部分
Framebuffer:显存,嵌入式系统使用的是内存的一部分
CRTC:显示控制器,在RK3399平台是SOC 内部VOP,RK3399里面包含两个VOP;
Encoder:输出转换器,指RGB、LVDS、DSI、eDP、HDMI、CVBS、VGA 等显示接口,它本质就是一个编码器,将CRTC提供过来的信号编码为对应显示接口需要的信号。
Connector:连接器,指encoder 和panel 之间交互的接口部分;
Panel:各种具体的屏幕
因此,要驱动DSI屏幕,有三个部分需要配置,包括VOP,DSI控制器,屏幕的参数。
首先开启vopb与vopl,设置时钟与MMU
&vopb {
//打开vopb的功能
status = "okay";
//指定vopb的时钟,接HDMI的那个VOP clock-parents必须指定为PLL_VPLL
assigned-clocks = <&cru DCLK_VOP0_DIV>;
assigned-clock-parents = <&cru PLL_VPLL>;
support-multi-area;
};
//启用mmu
&vopb_mmu {
status = "okay";
};
&vopl {
//打开vopl的功能
status = "okay";
//指定vopl的时钟,不接HDMI的VOP clock-parents用PLL_CPLL
assigned-clocks = <&cru DCLK_VOP1_DIV>;
assigned-clock-parents = <&cru PLL_CPLL>;
support-multi-area;
};
//启用mmu
&vopl_mmu {
status = "okay";
};
然后需要设置vop与显示接口之间的绑定关系,以DSI+HDMI为例
// vopl绑定到dsi
&dsi_in_vopl {
status = "okay";
};
&dsi_in_vopb {
status = "disabled";
};
// vopb绑定到hdmi
&hdmi_in_vopb {
status = "okay";
};
&hdmi_in_vopl {
status = "disabled";
};
修改DSI和panel的配置。其中panel的配置,是参考风火轮的wiki, http://wiki.smartfire.cn/Tinkerboard2/lcd
&dsi {
status = "okay";
//配置dsi每个lane的频率,一般出现花屏,条纹等可以调整这个值改善
//如果这个值不配置,DSI驱动会自动计算
rockchip,lane-rate = <500>;
panel@0 {
//屏幕的具体参数,使用dsi接口的屏幕其属性必须是simple-panel-dsi
compatible = "simple-panel-dsi";
reg = <0>;
//背光,即使不启用背光调节功能,这个属性也必须配置,且backlight的节点必须是有效的
//否则驱动会加载失败
backlight = <&backlight>;
//使能脚,如果enable 接到一个gpio,这个属性必须设置
enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
//这些根据规格书填写即可
bpc = <8>;
bus-format = <0x100a>;
width-mm = <476>;
height-mm = <267>;
dsi,flags = <3>;
dsi,format = <0>;
dsi,lanes = <4>;
//屏幕初始化序列,屏厂会提供
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
];
display-timings {
native-mode = <&timing2>;
//下面timing的参数按wiki上面的
timing2: timing2 {
clock-frequency = <52000000>; //DCLK
hactive = <1024>; //hactive
vactive = <600>; //vactive
hfront-porch = <160>; //hfp
hback-porch = <160>; //hbp
hsync-len = <10>; //hsa
vfront-porch = <12>; //vfp
vsync-len = <1>; //vsa
vback-porch = <23>; //vbp
hsync-active = <0>; //hync 极性控制 置 1 反转极性
vsync-active = <0>; //vsync 极性控制 置 1 反转极性
de-active = <1>; //DEN 极性控制
pixelclk-active = <0>; //dclk 极性控制
};
};
//这个ports是panel的,这个port要和dsi对应的port绑定
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi: endpoint {
remote-endpoint = <&dsi_out_panel>;
};
};
};
};
//这个ports是dsi的,这个port要和目标panel的port绑定
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
dsi_out_panel: endpoint {
remote-endpoint = <&panel_in_dsi>;
};
};
};
};
除了设备树之外,DSI的驱动和panel的驱动也需要修改,因为asus为了适配其他的屏幕,修改过rk原始的代码,所以要更换回rk原始的代码,可以直接在文末下载
到这里,MIPI-DSI部分的修改就完成了
7寸屏幕的触摸芯片为GT911,这是汇顶科技的触摸芯片,支持7-8寸屏,最多5点触摸。内核自带其驱动,路径为drivers/input/touchscreen/gt9xx。内核config要将CONFIG_TOUCHSCREEN_GT9XX设置为Y。默认的config文件已经配置好,不需要修改
然后设备树需要将gt911加入i2c8下,如下
&i2c8 {
goodix_ts@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>; //也可以填0x14
touch-gpio = <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>; //中断IO
reset-gpio = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>; //复位IO
max-x = <1024>; //x方向解析度
max-y = <600>; //y方向解析度
tp-size = <911>; //与源码中选择的配置相关
status = "okay";
};
};
通过配置GT911上电时中断脚和复位脚电平时序,可以切换其I2C地址为0x5d和0x14的其中之一,这一设计是为了解决I2C冲突,这里可以任选一个
touch-gpio是中断脚,reset-gpio是复位脚,配置和硬件接线一致
max-x和max-y分别是x方向和y方向最大值,按屏的分辨率填写即可
tp-size对应的是源码中触摸配置文件的选择,这里填911
源码中有几个点需要修改一下。在gt9xx目录中找到gt9xx.c,
这里将gtp_change_x2y设置为false,不交换x和y的坐标上报值
然后找到gt9xx_cfg.h,将配置文件换掉,配置文件可以从下一章的源码下载中获取,将整个gt911目录下载下来里面就有,文件名为GT911_Config_20220510_094105.cfg
这里简单提一下GT911的工作原理。GT911的寄存器地址从0x8047开始,到0x8100,总共186个字节,为GT911的配置文件,datasheet中部分寄存器的功能说明如下
完整版本的可以直接查阅GT911 datasheet。这些寄存器的值与外屏,触摸芯片的贴合,接线等强相关,一般屏厂会提供这些信息,然后将这些值放到一个cfg文件中。下面可以大致看下其源码
在gt9xx_cfg.h中,将GT911_Config_20220510_094105.cfg中186个字节赋值给数组gtp_dat_gt11
然后在gt9xx.c中,将这个gtp_dat_gt11中的内容memcpy到名为config的数组中,然后在初始化的时候,会将名为config的数组内容写入到0x8047开头的寄存器中。这就是配置文件下载的流程
替换文件 drivers/gpu/drm/rockchip/dw-mipi-dsi.c
替换文件 drivers/gpu/drm/panel/panel-simple.c
替换文件 arch/arm64/boot/dts/rockchip/rk3399-tinker_board_2.dts
替换文件 arch/arm64/boot/dts/rockchip/rk3399-tinker_board_2.dtsi
解压后替换文件夹 drivers/input/touchscreen/gt9xx 注意替换之后整个文件夹给777权限
如果替换之后没有生效,请检查源文件修改的时间是不是早于.o输出文件的修改时间,按gcc的编译规则,这种情况是不会重新编译的
如果用户在上方的 debian源码百度盘下载 链接处下载了完整版本的SDK,此时可以按照上一章节的方法替换源码,内核源码在sdk里面的kernel目录,如下图
此外,目前asus使用了dtbo机制,编译系统的时候,会生成若干个适配了其他屏幕的dtbo文件在oem目录下,这些dtbo会对设备树进行overlay操作,导致上一章节针对设备树的修改失效,因此可以参考下面的patch,修改device/rockchip/tinker_board_2下面的编译脚本
替换之后,在sdk目录下执行
./build.sh
会生成固件,固件位于 rockdev/update.img
烧录参考下面的章节,先使开发板进入maskrom模式
然后按照下图的方式进行烧录
按上述方式修改并编译,下载到板上之后,注意查看串口的log
这个log里面显示dsi的时钟及分辨率,说明dsi控制器已经工作,dsi控制器已经绑定到drm框架中,dsi控制器和panel已经绑定,且输出这个log的时候,一般屏幕上面会显示一些图像
这个log说明触摸已经能正常工作
最终显示的效果如下
另外说明一下,目前debian上面如果接双屏,虽然能异显,但是不能异触,就是触摸只有一个,所以,如果同时接DSI和HDMI时,要注意选择当前操作的屏幕
如果用户使用的是其他的屏幕,可以直接找供应商拿到屏幕参数和触摸配置文件,触摸配置文件直接替换gt9xx中的配置,而屏参直接填入设备树