Rock 3A DSI ST7701

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!

Hi, @Maxim_45637288, you can refer to this sitronix,st7701.yaml.

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>;

may like this,


st7701:st7701@0 {
	compatible = "techstar,ts8550b";
	... ...

	port {
		dsi1_out_port: endpoint {
		remote-endpoint = <&dsi1_out_port>;
		};
           };
	... ...
};

        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.

&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.

https://github.com/torvalds/linux/blob/feffde684ac29a3b7aec82d2df850fbdbdee55e4/drivers/gpu/drm/panel/Makefile#L89

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?

yes, the driver is enabled.

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

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?

/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”;
};

please try this

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