MIPI (Mobile Industry Processor Interface) is an open standard for mobile application processors initiated by the MIPI Consortium. The DSI (Display Serial Interface) defines a high-speed serial interface between the processor and the display module. Currently MIPI DSI is standard on most SOCs, and the RK3399 has two DSIs on it, one of which is pinned out by Tinker board 2. This article uses YYT_MIPI7LCD_2203 as an example to introduce how to use the MIPI DSI interface under Debian on tinker board 2s. In addition, screens adapted to mobile application processors usually come with touch functionality, which is also described in this article.
To customize the Debian firmware for the MIPI-DSI interface touch screen, the following preparations need to be made first
The modified Debian firmware needs to be burned with Rockchip's burn tool. You cannot use balena-etcher to burn it.
Among the Debian firmware I used the one below, this one can be directly burned with the Rexchip burn tool, debugging is more convenient, if you are using other firmware, you can use the dd command to directly burn a partition instead.
No matter which firmware is used, the whole debian system needs to be burned into Tinker board 2 first, and the MIPI-DSI interface touch screen only needs to be modified in the kernel part, but not in other parts.
The following will introduce the adaptation method of MIPI-DSI interface and the adaptation method of I2C touch function respectively
In addition to the Tinkerboard 2/2S and touch screen, it is recommended to prepare a high-power power supply, the power supply should be 12V 2A, the screen power should be provided by the motherboard, and the power quality should be better, otherwise it will interfere with the screen display.
When you buy YYT MIPI7 LCD 2203, it comes with an adapter board, which is defined as follows
Then you need to wire, in the above diagram has marked the interface above the adapter board, which
The wiring diagram is as follows
Touch reset/Touch interrupt/TCON power/TCON enable pin can be selected according to the actual situation, this is just to give a reference
Whether you download the source code through github or netbook, you need at least two directories, kernel and prebuilts, the former is the kernel source code directory, the latter is the cross-compiler directory, these two folders must be in the same folder, otherwise it can not be compiled
If the reader wants to modify it directly and does not want to understand how it works, they can skip the following section and go directly to the relevant source code download and replacement instructions section.
A brief introduction to the current RK3399 display framework. The current Debian uses the Linux DRM framework for display, and the display path in the DRM framework is as follows
Several components in the diagram
Framebuffer: the display memory, which is used by embedded systems as part of the memory
CRTC: display controller, in the RK3399 platform is the SOC internal VOP, the RK3399 contains two VOP;
Encoder: output converter, refers to RGB, LVDS, DSI, eDP, HDMI, CVBS, VGA and other display interfaces, it is essentially an encoder that encodes the signal provided by the CRTC into the signal required by the corresponding display interface.
Connector: refers to the interface part of the interaction between encoder and panel.
Panel: various specific screens
Therefore, to drive a DSI screen, there are three parts that need to be configured, including the VOP, the DSI controller, and the parameters of the screen.
First, turn on vopb and vopl, set the clock and MMU
&vopb {
//turn on vopb's function
status = "okay";
//specify the vopb clock, the VOP clock-parents for HDMI must be specified as PLL_VPLL
assigned-clocks = <&cru DCLK_VOP0_DIV>;
assigned-clock-parents = <&cru PLL_VPLL>;
support-multi-area;
};
//enable mmu
&vopb_mmu {
status = "okay";
};
&vopl {
//enable vopl
status = "okay";
//assign vopl clocks, no HDMI VOP clock-parents with PLL_CPLL
assigned-clocks = <&cru DCLK_VOP1_DIV>;
assigned-clock-parents = <&cru PLL_CPLL>;
support-multi-area;
};
//enable mmu
&vopl_mmu {
status = "okay";
};
Then you need to set the binding relationship between vop and display interface, take DSI+HDMI as an example
// vopl bind to dsi
&dsi_in_vopl {
status = "okay";
};
&dsi_in_vopb {
status = "disabled";
};
// vopb bind to hdmi
&hdmi_in_vopb {
status = "okay";
};
&hdmi_in_vopl {
status = "disabled";
};
Modify the configuration of DSI and panel. Where the panel configuration is referenced from the smartfire wiki, http://wiki.smartfire.cn/Tinkerboard2/lcd
&dsi {
status = "okay";
// Configure the frequency of each lane of dsi, generally tearing, streaks, etc. can be adjusted to improve this value
//If this value is not configured, the DSI driver will automatically calculate
rockchip,lane-rate = <500>;
panel@0 {
// the specific parameters of the screen, the screen using the dsi interface whose properties must be simple-panel-dsi
compatible = "simple-panel-dsi";
reg = <0>;
//backlight, even if the backlight adjustment function is not enabled, this property must be configured, and the node of backlight must be valid
// otherwise the driver will fail to load
backlight = <&backlight>;
// enable pin, if enable is connected to a gpio, this attribute must be set
enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
//These can be filled out according to the specifications
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>;
// The following timing parameters are according to the wiki above
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 active control
vsync-active = <0>; //vsync active control
de-active = <1>; //DEN active control
pixelclk-active = <0>; //dclk active control
};
};
//This ports is the panel, this port should be bound with the corresponding port of dsi
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi: endpoint {
remote-endpoint = <&dsi_out_panel>;
};
};
};
};
//this ports is dsi, this port should be bound to the port of the target panel
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
dsi_out_panel: endpoint {
remote-endpoint = <&panel_in_dsi>;
};
};
};
};
In addition to the device tree, the DSI driver and panel driver also need to be modified, because asus in order to adapt to other screens, modified the original code of Rockchip SDK, so to replace the original code back to rk, you can directly download at the end of the article
Here, the MIPI-DSI part of the modification is complete
The touch chip for the 7" screen is GT911, which is the touch chip of Huitian Technology and supports 7-8" screen with up to 5 touch points. The kernel comes with its driver, the path is drivers/input/touchscreen/gt9xx. kernel config should set CONFIG_TOUCHSCREEN_GT9XX to Y. The default config file is already configured, no need to modify it.
Then the device tree needs to add gt911 under i2c8 as follows
&i2c8 {
goodix_ts@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>; // can also fill 0x14
touch-gpio = <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>; //interrupt IO
reset-gpio = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>; //reset IO
max-x = <1024>; //x-directional resolution
max-y = <600>; //y-directional resolution
tp-size = <911>; //related to the configuration selected in the source code
status = "okay";
};
};
The GT911 can switch its I2C address to one of 0x5d and 0x14 by configuring the interrupt pin and reset pin level sequence at power up, this is designed to resolve I2C conflicts, you can choose either one here
touch-gpio is the interrupt pin, reset-gpio is the reset pin, configuration and hardware wiring consistent
max-x and max-y are the maximum values in the x and y directions respectively, which can be filled in according to the screen resolution.
tp-size corresponds to the selection of the touch profile in the source code, here fill in 911
There are several points in the source code that need to be modified. Find gt9xx.c in the gt9xx directory.
Here set gtp_change_x2y to false, do not exchange x and y coordinates reported values
Then find gt9xx_cfg.h and change the configuration file. The configuration file can be obtained from the source code download in the next chapter, download the whole gt911 directory and it will be inside, the file name is GT911_Config_20220510_094105.cfg
Here is a brief mention of how the GT911 works. the GT911 register address starts from 0x8047 to 0x8100, a total of 186 bytes, for the GT911 configuration file. the function of some registers in the datasheet is described as follows
The values of these registers are strongly correlated with the external screen, the lamination of the touch chip, the wiring, etc. Generally, the screen manufacturer will provide this information and then put these values into a cfg file. Here is a general look at the source code
In gt9xx_cfg.h, assign 186 bytes from GT911_Config_20220510_094105.cfg to the array gtp_dat_gt11
Then in gt9xx.c, memcpy the contents of this gtp_dat_gt11 to the array named config, and then during initialization, the contents of the array named config will be written to the register starting with 0x8047. This is the flow of config file download
replace the file drivers/gpu/drm/rockchip/dw-mipi-dsi.c
Replace the file drivers/gpu/drm/panel/panel-simple.c
Replace file arch/arm64/boot/dts/rockchip/rk3399-tinker_board_2.dts
replace file arch/arm64/boot/dts/rockchip/rk3399-tinker_board_2.dtsi
Unzip and replace the folder drivers/input/touchscreen/gt9xx Note that the entire folder is given 777 permissions after replacement.
If the replacement does not take effect, please check if the source file is modified earlier than the .o output file, according to gcc's compilation rules, this case will not be recompiled
If you have downloaded the full version of the SDK from the debian source code Baidu disk download link above, you can replace the source code as described in the previous section, the kernel source code is in the kernel directory inside the sdk, as follows
In addition, asus currently uses the dtbo mechanism, when compiling the system, several dtbo files with other screen adaptations will be generated in the oem directory, these dtbo will overlay the device tree, resulting in the previous section for the device tree changes fail, so you can refer to the following patch, modify device/rockchip/ tinker_board_2
After replacing it, execute it in the sdk directory
. /build.sh
will generate the firmware, which is located in rockdev/update.img
Burning reference the following section, first make the development board into maskrom mode
Then burn as shown in the following figure
Modify and compile as above, and after downloading to the board, check the serial port log
This log shows the dsi clock and resolution, which means the dsi controller has been working, the dsi controller has been bound to the drm framework, the dsi controller and the panel have been bound, and when outputting this log, some images will be displayed on the screen in general
This log means that the touch is working properly
The final result is as follows
In addition, if you connect a dual screen to debian, you can display it differently, but you can't touch it differently, that is, there is only one touch, so if you connect DSI and HDMI at the same time, be careful to choose the current operating screen
If the user is using other screens, you can directly find the supplier to get the screen parameters and touch profile, touch profile directly replace the configuration in gt9xx, and screen parameters directly fill in the device tree