Background#
Recently, I wanted to find a 5-inch MIPI screen with a resolution of 1080P and touch capability for an embedded project. After searching on Taobao, I found a suitable and inexpensive 5.5-inch screen module priced at about 95 yuan each. To further reduce costs, I started to consider whether there were cheaper alternatives, and began to think about utilizing smartphone screens. Before the era of full screens, 5.5 inches and 1080P were the mainstream configurations for smartphones, so there should be quite a few options available. Due to the large inventory, the prices of screen modules might also be advantageous. I have long been envious of the screens from old smartphones; although these screens come from outdated devices, their display quality often far exceeds that of typical embedded screen modules, so it would be great if I could make use of them.
However, not every smartphone screen can be easily used. The core obstacle to lighting up a smartphone screen lies in the lack of information. Unlike standalone finished screen modules that generally provide specifications and initialization data, smartphone screens often do not have publicly available hardware and software information. To drive a smartphone screen, two major challenges must be addressed:
First, on the hardware side, it is necessary to know the model and pin definitions of the screen connector to correctly connect power and signals. Although it is theoretically possible to trace the lines from the densely packed pins of the display control IC to the connector, there are experts who can do this, but the engineering effort is quite substantial. A more convenient approach is to obtain the repair schematic of the phone; thanks to the large smartphone repair market, many models' schematics can be found online or in some repair tools. From the schematic, the interface definitions of the screen connector can be directly found, and even the connector model.
On the software side, it is necessary to know the initialization sequence and timing of the screen. This can generally be extracted from the phone's firmware. For devices on the Qualcomm platform, the timing and initialization sequence can be obtained from the device tree (see the device tree extraction section in the Yunxi Box article). This process does not require actually owning a device; as long as there is a flashing package, extraction can generally be performed. Some special devices are supported by the open-source community, such as the relatively active project postmarketOS. For such devices, we can directly obtain the required screen information from the open-source code repository.
So I decided to look for an easy target to see if I could find a device with a suitable screen that also has hardware schematics and software source code. After searching the supported device list of postmarketOS, I finally narrowed it down to the Xiaomi 5X (xiaomi-tissot) and Redmi 5 Plus (xiaomi-vince), whose screen modules are priced around 40 yuan on Taobao. I also compared the two screens:
The Xiaomi 5X screen is 5.5 inches, 1080x1920 (16:9), 403 PPI, and has a 68% NTSC color gamut. Its module uses GFF full lamination, bonding the touch layer to the upper glass cover with optical glue. The process is simple but thick, and the visual effect is slightly inferior; when the screen is not lit, it also appears not purely black.
The Redmi 5 Plus screen is 5.99 inches, 1080x2160 (18:9), 403 PPI, and has an 84% NTSC color gamut. The same screen is also used in the Xiaomi 6X and Redmi 5 Plus. Its module employs Incell full lamination technology, where the touch unit is integrated with the LCM, making the module thinner and the visual effect very transparent.
Since I do not need the three navigation keys of Android, it is very tempting to exchange a similar module size for a larger display area and achieve a certain degree of "full-screen" effect, making the Redmi 5 Plus undoubtedly the better choice. However, the RV1126 SoC I plan to use is rated in the datasheet to support a maximum resolution of 1920x1080, so it is uncertain whether it can drive a 2160x1080 screen. Therefore, I purchased both screens and planned to test them; if the Redmi 5 Plus screen cannot be perfectly compatible, I will have to settle for the Xiaomi 5X screen as a fallback.
Hardware#
After analyzing the schematic, I found that the screen interface definitions of the Xiaomi 5X (top) and Redmi 5 Plus (bottom) are very similar, but the connectors used are different. The Xiaomi 5X uses the BM23PF0.8-40DS-0.35V(880) connector with a pin pitch of 0.35mm; the Redmi 5 Plus uses the BM20B(0.8)-40DS-0.4V(51) connector with a pitch of 0.4mm. Both have the same number of pins but different pitches, making them incompatible.
Based on the schematic, I made an adapter board that, on one hand, performs signal conversion, connecting the screen's MIPI-DSI signals, I2C signals, and other control IO to a connector compatible with the Yibaina EB-RV1126-DC-201 development board. On the other hand, it includes the necessary power circuits, using the 3.3V power provided by the development board to generate the high voltage required for backlight, the positive and negative voltages required for the LCD, and the 1.8V IO voltage not directly provided by the development board.
After completing the soldering of the adapter board and connecting both screens to the adapter board, the hardware is ready, and I can start operating the touch screen in software.
Software#
The Rockchip_DRM_Panel_Porting_Guide explains the general operation of driving MIPI-DSI screens. It utilizes the panel-simple-dsi
driver in the Linux kernel, which allows for the omission of the trouble of adding a separate driver for general screens, as it can be completed by modifying the device tree.
Configuring panel-simple-dsi
requires providing two core pieces of information:
- Initialization sequence (panel-init-sequence): This includes a series of initialization commands, each of which follows the rule that each command consists of a header and a data payload, both represented in hexadecimal. The header contains 3 bytes, defining the data type (Data Type), delay after sending (Delay, ms), and payload length (Payload Length). The data starting from the fourth byte represents a payload of length Payload Length. The Data Types include the following:
- 0x05: DCS Short WRITE. no parameters;
- 0x15: DCS Short WRITE. 1 parameter;
- 0x39: DCS Long Write/write LUT Command;
- 0x03: Generic Short WRITE, no parameters;
- 0x13: Generic Short WRITE. 1 parameter;
- 0x23: Generic Short WRITE, 2 parameters;
- 0x29: Generic Long Write;
- Display timings (display-timings): Defines various timing parameters during the screen refresh process, requiring complete knowledge of each of the following parts:
- Htotal = Hactive + Hfront-porch + HSync + Hback-porch
- Vtotal = Vactive + Vfront-porch + VSync + Vback-porch
- pixel-clock = Htotal × Vtotal × frame rate
For the Xiaomi 5X and Redmi 5 Plus, which have good community support, the compatible driver names for the screens can be found in the lk2nd device tree of the msm8953-mainline
project, and the specific screen driver can be found in the kernel code.
For example, for the Xiaomi 5X, the screen and corresponding compatible driver can be found in the lk2nd/dts/msm8953-xiaomi-vince.dts at main · msm8953-mainline/lk2nd device tree. In fact, as listed below, the same model of phone may involve screens from multiple suppliers, and the screen driver IC and touch solutions may differ, resulting in multiple entries. Normally, it is necessary to determine the screen solution based on the LCD_ID pin of the screen module or by reading specific registers via MIPI-DSI to perform different initializations. However, since this is only a test for one screen, I chose the simplest manual trial and error approach.
panel {
compatible = "xiaomi,vince-panel";
qcom,mdss_dsi_td4310_fhdplus_video_e7 {
compatible = "xiaomi,td4310-fhdplus-e7";
touchscreen-compatible = "syna,rmi4-i2c";
// touchscreen-compatible = "novatek,nt36525-i2c";
};
// ...
qcom,mdss_dsi_nt36672_csot_fhdplus_video_e7 {
compatible = "xiaomi,nt36672-csot-fhdplus-e7";
touchscreen-compatible = "syna,rmi4-i2c";
// touchscreen-compatible = "novatek,nt36525-i2c";
};
};
Taking one of the models xiaomi,nt36672-tianma-fhdplus-e7
as an example, the corresponding driver code can be found at linux/drivers/gpu/drm/panel/msm8953-generated/panel-xiaomi-nt36672-tianma-fhdplus-e7.c at 6.12/main · msm8953-mainline/linux. The task is to extract the information from the code and fill it into the corresponding device tree node of panel-simple-dsi
in the correct format. After filling it out, it looks like this:
&dsi {
status = "okay";
rockchip,lane-rate = <1000>;
dsi_panel: panel@0 {
status = "okay";
compatible = "simple-panel-dsi";
reg = <0>;
reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&dsi_rst_gpio>;
backlight = <&backlight>;
reset-delay-ms = <200>;
enable-delay-ms = <100>;
prepare-delay-ms = <20>;
unprepare-delay-ms = <20>;
disable-delay-ms = <20>;
init-delay-ms = <120>;
dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
dsi,format = <MIPI_DSI_FMT_RGB888>;
dsi,lanes = <4>;
/* Based on panel-xiaomi-nt36672-tianma-fhdplus-e7.c/nt36672_tianmaplus_e7_on() function */
panel-init-sequence = [
// DCS Short Write
05 78 01 11
// Generic Short Write
13 00 02 B0 04
// Generic Short Write
13 00 02 D6 01
// Generic Long Write
29 00 27 C7 00 19 28 3b 4a 55 6d 7d 8a 96 48 54 62 76 7f 8b 99 a4 b2 00 19 28 3b 4a 55 6d 7d 8a 96 48 54 62 76 7f 8b 99 a4 b2
// Generic Long Write
29 00 38 C8 03 00 01 03 ff fe 00 00 fe 01 fd f7 00 00 01 ff fb f2 00 00 01 03 01 ec 00 00 fe 01 fd f5 00 00 01 fe fa fe 00 00 01 03 ff fe 00 00 fe 01 fd ec 00 00 fe 01 fb d3 00
// DCS Long Write
39 00 03 51 ff 00
// DCS Short Write
15 00 02 53 24
// DCS Short Write
15 00 02 55 00
// DCS Short Write
15 00 02 35 00
// DCS Short Write
05 14 01 29
];
/* panel-exit-sequence */
panel-exit-sequence = [
05 14 01 28
05 78 01 10
];
disp_timings1: display-timings {
native-mode = <&dsi_timing0>;
dsi_timing0: timing0 {
clock-frequency = <148500000>;// (480+50+60+10)*(800+20+34+2)*60
hactive = <1080>;
hfront-porch = <108>;
hback-porch = <12>;
hsync-len = <60>;
vactive = <1920>;
vfront-porch = <166>;
vback-porch = <84>;
vsync-len = <33>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
swap-rb = <0>;
swap-rg = <0>;
swap-gb = <0>;
};
};
// ...
};
In addition, the backlight boost IC requires a PWM signal for enable and dimming control. The hardware is already connected, and it is only necessary to configure a pwm-backlight
generic driver node in the device tree, which has also been referenced in the above dsi node.
backlight: backlight {
compatible = "pwm-backlight";
brightness-levels = <0 1 2 3 ... 255>;
default-brightness-level = <200>;
pwms = <&pwm7 0 25000 0>; // PWM7, 25kHz
};
Testing#
After flashing the kernel image with the new device tree, I can enter the terminal and use modetest -M rockchip -s 83@69:1080x1920
for testing.
The biggest fear when lighting up a screen is a pitch-black display, as incorrect software or hardware connections can lead to the same result. Unfortunately, during the initial test, I tried various initialization sequences, but the screen remained pitch black and unresponsive. The Rockchip_DRM_Panel_Porting_Guide also provides a troubleshooting method, which allows checking whether the communication link is functioning properly through MIPI-DSI read operations. By adding read commands to the panel-simple driver, I could observe whether errors occurred during reading and whether the mode changed at startup. Testing revealed that only by continuously pressing the flex cable onto the PCB connector could I read correctly; it turned out to be a low-level error of poor soldering. The pitch of these connectors is tight, and the pad size is very small, which may also be due to the pads and solder mask openings being too small, making soldering quite difficult. After repeated attempts, I barely managed to solder it securely. Once this issue was resolved, the screen lit up smoothly.
Final Effect#
The Xiaomi 5X screen can display normally, and both the test images and video playback work well, achieving the expected effect.
As expected, the Redmi 5 Plus screen cannot display perfectly due to the limitations of the RV1126. If vactive
is directly configured to 2160 in the device tree, the driver has logic to compare the width and height with the maximum capabilities of the hardware during the probe
phase, and exceeding the maximum capability of 1920 prevents initialization. Even if this check logic is removed to bypass the check and force initialization, the displayed content is completely garbled. A barely usable method is to reduce vactive
to the hardware-supported 1920 and allocate the extra 240 to other timing parts. This way, the screen can normally display the 1080x1920 area, but there are 1080x240 areas that cannot display correctly.
Conclusion#
Through this experience, it can be seen that lighting up a smartphone screen is sometimes not difficult, provided there is support from hardware and software information (whether shared online or reverse-engineered). With most smartphone screens using the universal MIPI-DSI protocol, the vast majority of screens from phones with repair schematics and open firmware have great potential for reuse, making them a feasible and economical solution for amateur embedded projects.
An interesting example is the "universal" screen testers in the smartphone repair industry, which can test a vast array of mobile device screens by swapping different flex cables and configurations. I am quite curious about how they obtain the timing and initialization sequences for a large number of devices. Do they figure out the driver IC model and then apply public data, or do they capture and reverse-engineer the low-speed initialization sequences of DSI using a logic analyzer?
Finally, the screens used this time are from products nearly 8 years old. Today's smartphone screens have made significant progress; even LCD screens like the Redmi Note 11T Pro have higher screen-to-body ratios, higher refresh rates, and wider color gamuts, not to mention stronger OLEDs. I hope to challenge some newer smartphone screens in the future. Additionally, another area worth researching is how to use open-source tools like ArgyllCMS to calibrate screens in an embedded Linux environment, thus achieving a certain level of professional color management for the content displayed on these screens.