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, leading me to think about utilizing smartphone screens. Before the era of full screens, 5.5 inches and 1080P were mainstream configurations for smartphones, so there should be quite a few options available. Given the large inventory, the prices of screen modules might also be advantageous. I have long been envious of the screens from old phones; 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 they could be utilized.
However, not every smartphone screen can be easily used; the core obstacle to lighting up a smartphone screen is the lack of information. Unlike standalone finished screen modules that generally provide specifications and initialization data directly, smartphone screens often lack 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 workload is quite substantial. A more convenient approach is to obtain the repair schematic of the phone; thanks to the vast smartphone repair market, schematics for many models can be found online or in some repair tools. From the schematic, one can directly find the interface definitions of the screen connector and even the connector model.
On the software side, it is necessary to know the screen's initialization sequence and timing. This information 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 article on Yunxi Box). 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.
Therefore, I decided to look for a soft target and see if I could find a device with a suitable screen that also had hardware schematics and software source code available. After searching through 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 already 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 color gamut of 68% NTSC. 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; even when the screen is not lit, it appears less pure black.
The Redmi 5 Plus screen is 5.99 inches, 1080x2160 (18:9), 403 PPI, and has a color gamut of 84% NTSC. 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, resulting in a thinner module with a very transparent visual effect.
Since I do not need the three Android navigation keys, it is very tempting to exchange a similar module size for a larger display area and achieve a certain degree of "full-screen" effect; the Redmi 5 Plus is 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 whether it can drive a 2160x1080 screen is questionable. Therefore, I purchased both screens, planning 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 close, 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 the pitches are different, making them incompatible.
Based on the schematic, I created an adapter board that serves to connect the screen's MIPI-DSI signals, I2C signals, and other control IO to a connector compatible with the EasyBiner EB-RV1126-DC-201 development board. Additionally, the board includes the necessary power circuits, utilizing the 3.3V power provided by the development board to generate the high voltage required for backlight, the positive and negative voltages needed for the LCD, and the 1.8V IO voltage not directly provided by the development board.
With the adapter board soldered and both screens connected to it, the hardware is now ready, and I can start working on the software to drive the screen.
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 hassle of adding a separate driver for general screens; the driver can be completed simply 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 Type includes the following categories:
- 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): This 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 well-supported Xiaomi 5X and Redmi 5 Plus, the compatible driver names for the screens can be found in the lk2nd device tree of the msm8953-mainline
project, and the specific screen drivers can be found in the kernel code.
For example, for the Xiaomi 5X, the screen and corresponding compatible driver can be found in the device tree at lk2nd/dts/msm8953-xiaomi-vince.dts at main · msm8953-mainline/lk2nd. 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. Once filled 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>;
};
};
// ...
};
Additionally, the backlight boost IC requires a PWM signal for enable and dimming control. The hardware has already been connected; it is only necessary to configure a generic driver node for pwm-backlight
in the device tree, and the above dsi node has already referenced this backlight 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 with no response. The Rockchip_DRM_Panel_Porting_Guide also provides a troubleshooting method, allowing one to check if the communication link is normal by performing read operations via MIPI-DSI. By adding read commands to the panel-simple driver, one can observe during startup whether there are any read errors and if the mode changes. Testing revealed that only when I pressed down hard on the flex cable to the PCB connector could it read correctly; it turned out to be a low-level error due to poor soldering. These connector pitches are tight, and the solder pads are 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 very smoothly.
Final Effect#
The Xiaomi 5X screen can display normally, with test images and video playback functioning as expected.
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 during the probe
phase that compares the width and height with the maximum capabilities of the hardware; exceeding the maximum capability of 1920 prevents initialization. Even if this check logic is removed and initialization is forced, the displayed content becomes completely garbled. A workaround is to reduce vactive
to the supported 1920 and allocate the excess 240 to other parts of the timing. This way, the screen can normally display the 1080x1920 area, but the 1080x240 area cannot display properly.
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 documentation (whether shared online or reverse-engineered). With most smartphone screens using the universal MIPI-DSI protocol, the vast majority of smartphone screens that have repair schematics and open firmware possess 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 so many 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 utilize open-source tools like ArgyllCMS for color calibration in an embedded Linux environment, enabling a certain degree of professional color management for the content displayed on these screens to ensure color accuracy.