Hi there,
I’m trying to get a DSI display to work with a ROCK 3A board. My display uses the Sitronix ST7701 driver.
I added the driver to the kernel and wrote the necessary device tree sources (DTS). However, I’m running into some issues, and the console is showing the following errors.
Could you help me identify the mistakes in my DTS?
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dsi1>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
port {
dsi1_out_port: endpoint {
remote-endpoint = <&panel_dsi_in>;
};
};
st7701:st7701@0 {
compatible = "techstar,ts8550b";
reg = <0x0>;
status = "okay";
// label = "test_display";
// VCC-supply = <&vcc_3v3>;
// IOVCC-supply = <&vcc_3v3>;
reset-gpios = <&gpio1 24 0>;
// prepare-delay-ms = <2>;
// reset-delay-ms = <1>;
// init-delay-ms = <20>;
// enable-delay-ms = <120>;
// disable-delay-ms = <50>;
// unprepare-delay-ms = <20>;
// 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 = <2>;
panel-init-sequence = [
39 00 06 FF 77 01 00 00 13
39 00 02 EF 08
39 00 06 FF 77 01 00 00 10
39 00 03 C0 63 00
39 00 03 C1 10 02
39 00 03 C2 31 02
39 00 02 CC 10
39 00 11 B0 C0 0C 92 0C 10 05 02 0D 07 21 04 53 11 6A 32 1F
39 00 11 B1 C0 87 CF 0C 10 06 00 03 08 1D 06 54 12 E6 EC 0F
39 00 06 FF 77 01 00 00 11
39 00 02 B0 5D
39 00 02 B1 62
39 00 02 B2 82
39 00 02 B3 80
39 00 02 B5 42
39 00 02 B7 85
39 00 02 B8 20
39 00 02 C0 09
39 00 02 C1 78
39 00 02 C2 78
39 00 02 D0 88
39 FF 02 EE 42
39 00 04 E0 00 00 02
39 00 0C E1 04 A0 06 A0 05 A0 07 A0 00 44 44
39 00 0D E2 00 00 33 33 01 A0 00 00 01 A0 00 00
39 00 05 E3 00 00 33 33
39 00 03 E4 44 44
39 00 11 E5 0C 30 A0 A0 0E 32 A0 A0 08 2C A0 A0 0A 2E A0 A0
39 00 05 E6 00 00 33 33
39 00 03 E7 44 44
39 00 11 E8 0D 31 A0 A0 0F 33 A0 A0 09 2D A0 A0 0B 2F A0 A0
39 00 08 EB 00 01 E4 E4 44 88 00
39 00 11 ED FF F5 47 6F 0B A1 A2 BF FB 2A 1A B0 F6 74 5F FF
39 00 07 EF 08 08 08 40 3F 64
39 00 06 FF 77 01 00 00 13
39 00 03 E8 00 0E
39 00 06 FF 77 01 00 00 00
39 FF 01 11
39 00 06 FF 77 01 00 00 13
39 FF 03 E8 00 0C
39 00 03 E8 00 00
39 00 06 FF 77 01 00 00 00
39 00 02 3A 50
39 FF 01 29
];
display-timings {
native-mode = <&timing0>;
timing0: timing-0 {
clock-frequency = <30000000>;
hactive = <540>;
vactive = <960>;
hfront-porch = <20>;
hback-porch = <20>;
hsync-len = <20>;
vfront-porch = <20>;
vback-porch = <20>;
vsync-len = <20>;
};
};
port {
panel_dsi_in: endpoint {
remote-endpoint = <&dsi1_out_port>;
};
};
};
};
};
fragment@1 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <0xffffffff>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@4 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@5 {
target = <0xffffffff>;
__overlay__ {
status = "disabled";
};
};
__fixups__ {
video_phy1 = "/fragment@1:target:0";
dsi1_in_vp0 = "/fragment@2:target:0";
dsi1_in_vp1 = "/fragment@3:target:0";
route_dsi1 = "/fragment@4:target:0";
hdmi = "/fragment@5:target:0";
};
};
It seems I’m having trouble properly using ports, endpoints, and remote-endpoints. At the moment, I’m using fragments like these:
port {
dsi1_out_port: endpoint {
remote-endpoint = <&panel_dsi_in>;
};
};
and
port {
panel_dsi_in: endpoint {
remote-endpoint = <&dsi1_out_port>;
};
};
But I don’t think these are correct. Additionally, I don’t see a link in /sys/firmware/devicetree/base/symbols to the new driver. I’m not sure if that’s normal or if there’s an issue.
Any pointers would be greatly appreciated!
Nasca
December 4, 2024, 1:51am
2
Nasca
December 4, 2024, 1:54am
3
The port might need to be located under the st7701 node.
Thank you very much for your answer,
can you describe in a little more detail what you mean.
I looked at the document in the link and used it.
I tried to do it like this, but it didn’t help
panel_dsi_in: endpoint {
remote-endpoint = <&dsi1_in_vp1>;
Nasca
December 4, 2024, 8:00am
5
may like this,
st7701:st7701@0 {
compatible = "techstar,ts8550b";
... ...
port {
dsi1_out_port: endpoint {
remote-endpoint = <&dsi1_out_port>;
};
};
... ...
};
Nasca
December 4, 2024, 8:01am
6
port {
dsi1_out_port: endpoint {
remote-endpoint = <&panel_dsi_in>;
};
};
delete it first, and please show me the log then.
I deleted this port,
now the commands
dmesg | grep mipi and
dmesg | grep dsi do not output anything.
Nasca
December 4, 2024, 8:44am
8
&dsi1 {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
st7701:st7701@0 {
compatible = "techstar,ts8550b", "sitronix,st7701";
reg = <0x0>;
status = "okay";
... ...
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi1: endpoint {
remote-endpoint = <&dsi1_out_panel>;
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
dsi1_out_panel: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_dsi1>;
};
};
};
};
};
please try this, and before that make sure that you have enabled the driver of st7701.
I checked it like this, is it normal?
grep SITRONIX_ST7701 /boot/config-$(uname -r)
dmesg | grep st7701
CONFIG_DRM_PANEL_SITRONIX_ST7701=y
do i leave this port remote?
Nasca
December 4, 2024, 9:22am
12
yes, the driver is enabled.
Nasca
December 4, 2024, 9:25am
13
sorry, can you descript it in detail ?
sorry, i wanted to say when i use the code you suggested, i should leave this port deleted
Nasca
December 4, 2024, 10:09am
15
you can use my code first.
&dsi1 {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
st7701:st7701@0 {
compatible = "techstar,ts8550b", "sitronix,st7701";
reg = <0x0>;
status = "okay";
... ...
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi1: endpoint {
remote-endpoint = <&dsi1_out_panel>;
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
dsi1_out_panel: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_dsi1>;
};
};
};
};
};
&video_phy1 {
status = "okay";
};
&dsi1_in_vp0 {
status = "disabled";
};
&dsi1_in_vp1 {
status = "okay";
};
&route_dsi1 {
status = "okay";
};
delete your ports, use my two ports above, then fill the other properties.
when compiling I get this error:
rk356x-4-3inch-screen-28-53.dts:50.17-64.26: ERROR (duplicate_node_names): /fragment@0/overlay /st7701@0/ports: Duplicate node name
ERROR: Input tree has errors, aborting (use -f to force output)
line 50 is here
};
ports {
**#address-cells = <1>;**
#size-cells = <0>;
port@1 {
I also wanted to ask why you don’t use fragments in your listing?
Nasca
December 4, 2024, 11:45am
17
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
metadata {
title = “Enable ST7701”;
compatible = “radxa,rock-3a”;
category = “display”;
exclusive = “dsi1”;
description = “Enable ST7701.”;
};
};
&dsi1 {
status = “okay”;
#address-cells = <1>;
#size-cells = <0>;
st7701:st7701@0 {
compatible = "techstar,ts8550b", "sitronix,st7701";
reg = <0x0>;
status = "okay";
label = "test_display";
// VCC-supply = <&vcc_3v3>;
// IOVCC-supply = <&vcc_3v3>;
reset-gpios = <&gpio1 24 0>;
// prepare-delay-ms = <2>;
// reset-delay-ms = <1>;
// init-delay-ms = <20>;
// enable-delay-ms = <120>;
// disable-delay-ms = <50>;
// unprepare-delay-ms = <20>;
// 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 = <2>;
panel-init-sequence = [
39 00 06 FF 77 01 00 00 13
39 00 02 EF 08
39 00 06 FF 77 01 00 00 10
39 00 03 C0 63 00
39 00 03 C1 10 02
39 00 03 C2 31 02
39 00 02 CC 10
39 00 11 B0 C0 0C 92 0C 10 05 02 0D 07 21 04 53 11 6A 32 1F
39 00 11 B1 C0 87 CF 0C 10 06 00 03 08 1D 06 54 12 E6 EC 0F
39 00 06 FF 77 01 00 00 11
39 00 02 B0 5D
39 00 02 B1 62
39 00 02 B2 82
39 00 02 B3 80
39 00 02 B5 42
39 00 02 B7 85
39 00 02 B8 20
39 00 02 C0 09
39 00 02 C1 78
39 00 02 C2 78
39 00 02 D0 88
39 FF 02 EE 42
39 00 04 E0 00 00 02
39 00 0C E1 04 A0 06 A0 05 A0 07 A0 00 44 44
39 00 0D E2 00 00 33 33 01 A0 00 00 01 A0 00 00
39 00 05 E3 00 00 33 33
39 00 03 E4 44 44
39 00 11 E5 0C 30 A0 A0 0E 32 A0 A0 08 2C A0 A0 0A 2E A0 A0
39 00 05 E6 00 00 33 33
39 00 03 E7 44 44
39 00 11 E8 0D 31 A0 A0 0F 33 A0 A0 09 2D A0 A0 0B 2F A0 A0
39 00 08 EB 00 01 E4 E4 44 88 00
39 00 11 ED FF F5 47 6F 0B A1 A2 BF FB 2A 1A B0 F6 74 5F FF
39 00 07 EF 08 08 08 40 3F 64
39 00 06 FF 77 01 00 00 13
39 00 03 E8 00 0E
39 00 06 FF 77 01 00 00 00
39 FF 01 11
39 00 06 FF 77 01 00 00 13
39 FF 03 E8 00 0C
39 00 03 E8 00 00
39 00 06 FF 77 01 00 00 00
39 00 02 3A 50
39 FF 01 29
];
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi1: endpoint {
remote-endpoint = <&dsi1_out_panel>;
};
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
dsi1_out_panel: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_dsi1>;
};
};
};
};
&video_phy1 {
status = “okay”;
};
&dsi1_in_vp0 {
status = “disabled”;
};
&dsi1_in_vp1 {
status = “okay”;
};
&route_dsi1 {
status = “okay”;
};
Nasca
December 4, 2024, 11:47am
19
for overlay dts code style, you can refer to radxa-overlay
Thank you for your help.
Your example, as it is, doesn’t compile for me.
For some reason, the compiler throws an error if the DTS is written without fragment@.
Additionally, compilation errors occur when there’s a #include , and the DTS also fails to compile if it contains dsi-formats or dsi-flags.
It also doesn’t compile if I specify a node directly instead of using the target = <0xffffffff>; construct.
Nevertheless, your assistance was helpful, and I managed to create this DTS.
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dsi1>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
dsi1_out_panel: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_dsi1>;
};
};
};
st7701:st7701@0 {
compatible = "techstar,ts8550b", "sitronix, st7701";
reg = <0x0>;
status = "okay";
// label = "test_display";
// VCC-supply = <&vcc_3v3>;
// IOVCC-supply = <&vcc_3v3>;
reset-gpios = <&gpio1 24 0>;
// prepare-delay-ms = <2>;
// reset-delay-ms = <1>;
// init-delay-ms = <20>;
// enable-delay-ms = <120>;
// disable-delay-ms = <50>;
// unprepare-delay-ms = <20>;
// 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 = <2>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_dsi1: endpoint {
remote-endpoint = <&dsi1_out_panel>;
};
};
};
};
};
};
fragment@1 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <0xffffffff>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@4 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
connect = <&vp1_out_dsi1>;
};
};
fragment@5 {
target = <0xffffffff>;
__overlay__ {
status = "disabled";
};
};
fragment@6 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
fragment@7 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
};
};
__fixups__ {
video_phy1 = "/fragment@1:target:0";
dsi1_in_vp0 = "/fragment@2:target:0";
dsi1_in_vp1 = "/fragment@3:target:0";
route_dsi1 = "/fragment@4:target:0";
hdmi = "/fragment@5:target:0";
vop_mmu = "/fragment@6:target:0";
vop = "/fragment@7:target:0";
};
};
Now the MIPI log looks like this:
[ 9.712463] rockchip-drm display-subsystem: bound fe070000.dsi (ops 0xffffffc0091f83e8)
[ 9.714567] dw_mipi_dsi_rockchip_host_attach+0x34/0xbc
[ 9.714577] dw_mipi_dsi_host_attach+0xd4/0xe0
[ 9.714586] mipi_dsi_attach+0x30/0x44
[ 9.714597] st7701_dsi_probe+0x15c/0x160
[ 9.714606] mipi_dsi_drv_probe+0x24/0x30
[ 9.714685] mipi_dsi_driver_register_full+0x64/0x70
[ 9.714698] st7701_dsi_driver_init+0x24/0x30
However, the DRM log contains the following errors, and the screen remains black. Could you please suggest where I could go from here?
[ 9.714087] [drm:__drm_atomic_state_free] Freeing atomic state 00000000cb4bca7f
[ 9.714201] WARNING: CPU: 0 PID: 1 at drivers/gpu/drm/drm_mode_config.c:617 drm_mode_config_validate+0x16c/0x20c
[ 9.714256] pc : drm_mode_config_validate+0x16c/0x20c
[ 9.714266] lr : drm_mode_config_validate+0x16c/0x20c
[ 9.714504] drm_mode_config_validate+0x16c/0x20c
[ 9.714515] drm_dev_register+0x38/0x1e8
[ 9.714525] rockchip_drm_bind+0x6dc/0x740
[ 9.714129] Bogus possible_crtcs: [ENCODER:113:DSI-113] possible_crtcs=0x0 (full crtc mask=0x1)
[ 9.714201] WARNING: CPU: 0 PID: 1 at drivers/gpu/drm/drm_mode_config.c:617 drm_mode_config_validate+0x16c/0x20c
[ 9.714208] Modules linked in:
[ 9.714229] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.160-rockchip-rk356x #1.0.8
[ 9.714235] Hardware name: Rockchip RK3566 OPi 3B (DT)
[ 9.714245] pstate: 60c00009 (nZCv daif +PAN +UAO -TCO BTYPE=--)
[ 9.714256] pc : drm_mode_config_validate+0x16c/0x20c
[ 9.714266] lr : drm_mode_config_validate+0x16c/0x20c