In the end I managed to get things to work. The hardware I work with has 2 sn65dsi84 DSI to LVDS bridges to make 4 LVDS channels (16 lanes) from 8 DSI lanes. This should allow to drive up to 4k LVDS displays.
I added the dsi patches from this thread: Two DSI panels displays on TX2 with Jetpack 3.2.1? - #7 by Ratbert
The DTS part to get the DSI output to work.
/* HDMI 1 (port 1) */
nvdisplay@15210000 {
status = "disabled";
win-mask = <0x0C>;
};
nvdisplay@15200000 {
nvidia,dc-or-node = "/host1x/dsi";
nvidia,dc-connector = <&dsi>;
status = "okay";
win-mask = <0x03>;
};
/* HDMI 2 (port 0) */
nvdisplay@15220000 {
status = "okay";
win-mask = <0x30>;
};
/****** DSI (LVDS 1) *************/
dsi { /* dsi@15300000 */
nvidia,dsi-controller-vs = <DSI_VS_1>;
status = "okay";
/* nvidia,active-panel = <&panel_lvds1>; */ /* single panel output */
nvidia,active-panel = <&panel_lvds_dual1>; /* ganged panel output */
panel_lvds1: panel-lvds1 {
status = "disabled";
compatible = "c,wxga-14-0";
nvidia,dsi-instance = <0>;
nvidia,dsi-n-data-lanes = <4>;
nvidia,dsi-pixel-format = <3>; /* 24 bit planar*/
nvidia,dsi-refresh-rate = <60>;
nvidia,dsi-video-data-type = <0>;
nvidia,dsi-video-clock-mode = <0>;
nvidia,dsi-video-burst-mode = <1>;
nvidia,dsi-ganged-type = <0>; /* 0= not used, 1=left/right, 2=odd/even 3=overlapped ?*/
nvidia,dsi-split-link-type= <0>; /* split link, 1=A/B) */
nvidia,dsi-ganged-swap-links = <0>;
nvidia,dsi-ganged-write-to-all-links = <0>;
nvidia,dsi-controller-vs = <1>;
nvidia,dsi-virtual-channel = <0>;
nvidia,dsi-panel-reset = <1>;
nvidia,panel-bl-pwm-gpio = <&tegra_aon_gpio TEGRA_AON_GPIO(U, 0) 1>; /* PU0 */
nvidia,dsi-ulpm-not-support = <1>;
nvidia,dsi-suspend-stop-stream-late = <1>;
nvidia,dsi-power-saving-suspend = <1>;
nvidia,default_color_space = <1>;
pwms = <&tegra_pwm1 0 40161>;
disp-default-out {
nvidia,out-type = <2>;
nvidia,out-width = <220>;
nvidia,out-height = <180>;
nvidia,out-flags = <(0 << 3)>;
nvidia,out-xres = <800>;
nvidia,out-yres = <600>;
};
display-timings {
/delete-node/ 1200x1920-32-60Hz; /*remove existing resolution*/
/* drive 2 800x600 panels as one single panel */
800x600-32-60Hz {
clock-frequency = <40000000>;
hactive = <800>;
vactive = <600>;
hfront-porch = <220>;
hback-porch = <34>;
vfront-porch = <24>;
vback-porch = <4>;
hsync-len = <13>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
nvidia,h-ref-to-sync = <1>;
nvidia,v-ref-to-sync = <11>;
};
};
};
panel_lvds_dual1: panel-lvds-dual1 {
status = "okay";
compatible = "c,wxga-14-0";
nvidia,dsi-instance = <0>;
nvidia,dsi-n-data-lanes = <8>;
nvidia,dsi-pixel-format = <3>; /* 24 bit planar*/
nvidia,dsi-refresh-rate = <60>;
nvidia,dsi-video-data-type = <0>;
nvidia,dsi-video-clock-mode = <0>;
nvidia,dsi-video-burst-mode = <1>;
nvidia,dsi-ganged-type = <1>; /* 0= not used, 1=left/right, 2=odd/even 3=overlapped ?*/
nvidia,dsi-split-link-type= <0>; /* split link, 1=A/B ) */
nvidia,dsi-ganged-swap-links = <1>;
nvidia,dsi-ganged-write-to-all-links = <0>;
nvidia,dsi-controller-vs = <1>;
nvidia,dsi-virtual-channel = <0>;
nvidia,dsi-panel-reset = <1>;
nvidia,panel-bl-pwm-gpio = <&tegra_aon_gpio TEGRA_AON_GPIO(U, 0) 1>; /* PU0 */
nvidia,dsi-ulpm-not-support = <1>;
nvidia,dsi-suspend-stop-stream-late = <1>;
nvidia,dsi-power-saving-suspend = <1>;
nvidia,default_color_space = <1>;
pwms = <&tegra_pwm1 0 40161>;
disp-default-out {
nvidia,out-type = <2>;
nvidia,out-width = <220>;
nvidia,out-height = <180>;
nvidia,out-flags = <(0 << 3)>;
nvidia,out-xres = <1600>;
nvidia,out-yres = <600>;
};
display-timings {
/delete-node/ 1200x1920-32-60Hz; /*remove existing resolution*/
/* drive 2 800x600 panels as one single panel */
1600x600-32-60Hz {
clock-frequency = <80000000>;
hactive = <1600>;
vactive = <600>;
hfront-porch = <420>;
hback-porch = <76>;
vfront-porch = <24>;
vback-porch = <4>;
hsync-len = <26>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
nvidia,h-ref-to-sync = <1>;
nvidia,v-ref-to-sync = <11>;
};
};
};
};
I used an 800x600 LVDS panel for testing. For dual output the desktop size must be double so the resolution is set to 1600x600. There also has to be room for the hsync pulses, front porch and back porch. When doubling the horizontal resolution the hsync pulses, front porch and back porch must also be made larger. Without that I get the dreaded ’ dsi: video fifo overflow’ message. And don’t forget to double the pixel clock frequency.
The next problem for me was the sn65dsi84 driver. The one that comes with the TX2 kernel is very rudimentary and requires to come up with the settings manually. I have used this chip before in a different design and the sn65dsi8x driver allows set it up using display timings. However that platform uses a DRM based video system. The TX2 doesn’t use DRM (yet) so I hacked the driver to be also usefull without DRM (added a no-drm-connect option). I’ve attached a patch to add this driver to the Tegra 32.2.1 kernel drivers. The driver should still work with DRM based video systems; there is nothing system specific in it.
The DTS tree to drive two panels looks like this:
i2c@3160000 {
sn65dsi84_1: sn65dsi84@2c {
compatible = "ti,sn65dsi83";
reg = <0x2c>;
ti,dsi-lanes = <4>;
ti,lvds-format = <0>;
ti,lvds-bpp = <24>;
ti,width-mm = <220>;
ti,height-mm = <180>;
ti,lvds-channels = <1>;
ti,always-on=<1>;
ti,no-drm-connect=<1>;
ti,reverse-lvds=<0>;
enable-gpios = <&tegra_aon_gpio TEGRA_AON_GPIO(U, 3) GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
dsi-lanes = <4>;
panel-width-mm = <220>;
panel-height-mm = <180>;
display-timings {
timing {
clock-frequency = <40000000>;
hactive = <800>;
vactive = <600>;
hfront-porch = <220>;
hback-porch = <38>;
vfront-porch = <24>;
vback-porch = <4>;
hsync-len = <13>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
};
};
port {
panel1_in: endpoint {
remote-endpoint = <&mipi_dsi_bridge_out>;
};
};
};
sn65dsi84_2: sn65dsi84@2d {
compatible = "ti,sn65dsi83";
reg = <0x2d>; /* I2C address* */
ti,dsi-lanes = <4>;
ti,lvds-format = <0>; /* 0= NS, 1=JEIDA */
ti,lvds-bpp = <24>;
ti,width-mm = <220>;
ti,height-mm = <180>;
ti,lvds-channels = <1>; /* 1=1 channel, 2=2 channels (4 lanes per channel). */
ti,always-on=<1>; /* Power up immediately and don't power down*/
ti,no-drm-connect=<1>; /* Start directly from probe function, use if the system doesn't use DRM */
ti,reverse-lvds=<1>; /* 0=normal, 1=reverse lanes and channels (mirrored PCB layout) */
ti,burst-mode= <0>; /* 0= SYNC PULSE, 1= BURST. Only for DRM mode */
enable-gpios = <&tegra_aon_gpio TEGRA_AON_GPIO(U, 3) GPIO_ACTIVE_HIGH>; /*panel power control */
enable-panel = <>; /* panel enable control */
pinctrl-names = "default";
dsi-lanes = <4>;
panel-width-mm = <220>;
panel-height-mm = <180>;
display-timings {
/* 800x600 @60Hz */
timing {
clock-frequency = <40000000>;
hactive = <800>;
vactive = <600>;
hfront-porch = <220>;
hback-porch = <38>;
vfront-porch = <24>;
vback-porch = <4>;
hsync-len = <13>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
};
};
port {
panel2_in: endpoint {
remote-endpoint = <&mipi_dsi_bridge_out>;
};
};
};
};
/* Dummy node to fullfill the requirement to have an endpoint for the sn65dsi83 driver*/
mipi_dsi_bridge {
status = “okay”;
clock-drop-level = <1>;
port@1 {
mipi_dsi_bridge_out: endpoint {
remote-endpoint = <&panel_lvds1>;
};
};
};
sn65dsi83 driver.patch.txt (32.0 KB)