TX2/L4T 32_1 (Kernel 4.9) Enable second HDMI port (and DSI port)

We have a project with a custom carrier board and multiple video outputs. Originally it was done using the L4T 28.1 BSP. With the 32.1 BSP we are having problems getting the second HDMI output to even be detected. I’m using the following dts file

tegra186-quill-hdmi-primary-p3310-1000-c03-00.dts

But I’ve enabled the second HDMI output, setting the status to “okay”

nvdisplay@15220000 {
			status = "okay";
			nvidia,dc-or-node = "/host1x/sor";
			nvidia,dc-connector = <&sor0>;
	};

The result is that there’s only one display, i.e only one /dev/fbX device, and X only reports one screen.

In the kernel messages it it shows one (disp0) detecting properly but the
other going off looking for panel config somehow. I’m not sure where
the linkage to the hdmi output is configured.

[    0.813171] tegradc 15200000.nvdisplay: disp0 connected to head0->/host1x/sor1
[    0.813501] tegradc 15200000.nvdisplay: DT parsed successfully
[    0.813544] tegradc 15200000.nvdisplay: Display dc.ffffff800b610000 registered with id=0
[    0.823710] tegradc 15200000.nvdisplay: vblank syncpt # 8 for dc 0
[    0.823742] tegradc 15200000.nvdisplay: vpulse3 syncpt # 9 for dc 0
[    0.827674] tegradc 15200000.nvdisplay: hdmi: invalid prod list prod_list_hdmi_board
[    0.827700] tegradc 15200000.nvdisplay: hdmi: tegra_hdmi_tmds_range_read(bd) failed
[    0.863802] tegradc 15200000.nvdisplay: probed
[    3.209674] tegradc 15200000.nvdisplay: fb registered
[    4.107535] tegradc 15200000.nvdisplay: hdmi: tmds rate:85478K prod-setting:prod_c_hdmi_54m_111m
[    4.117752] tegradc 15200000.nvdisplay: hdmi: get RGB quant from EDID.
[    4.124300] tegradc 15200000.nvdisplay: hdmi: get YCC quant from EDID.


[    4.145953] tegradc 15220000.nvdisplay: disp1 connected to head2->/host1x/sor
[    4.153120] tegradc 15220000.nvdisplay: tegra_dc_parse_panel_ops: panel: /host1x/sor/dp-display is not active
[    4.163045] tegradc 15220000.nvdisplay: err:-19 parsing panel_ops
[    4.283431] tegradc 15200000.nvdisplay: blank - powerdown
[    4.364092] tegradc 15200000.nvdisplay: unblank

Thanks in Advance,

Cary

According to the log, you should set hdmi-display to be enabled under sor0 and also disable the dp-display.

This part is same on both rel-28 and rel-32 release.

Ok, this helped. I also had to enable the dpaux. So my dts changes look like this

nvdisplay@15220000 {
			status = "okay";
			nvidia,dc-or-node = "/host1x/sor";
			nvidia,dc-connector = <&sor0>;
		};

		sor {
		    status = "okay";
		    nvidia,active-panel = <&sor_hdmi_display>;

		    sor_hdmi_display: hdmi-display {
			status = "okay";
		    };

		    dp-display {
			status = "disabled";
		    };
		};

		dpaux@155c0000 { 
		    status = "okay";
		};

This gets me /dev/fb0 and /dev/fb1 (and the associated entries in /sys/class/graphics), but
the X server still only sees one display. The kernel log shows some sort of internal error

[    4.230506] tegradc 15220000.nvdisplay: disp1 connected to head2->/host1x/sor
[    4.241723] tegradc 15220000.nvdisplay: DT parsed successfully
[    4.247592] tegradc 15220000.nvdisplay: Display dc.ffffff800bc60000 registered with id=1
[    4.255922] tegradc 15220000.nvdisplay: vblank syncpt # 11 for dc 2
[    4.262208] tegradc 15220000.nvdisplay: vpulse3 syncpt # 12 for dc 2
[    4.270950] tegradc 15220000.nvdisplay: hdmi: invalid prod list prod_list_hdmi_board
[    4.278727] tegradc 15220000.nvdisplay: hdmi: tegra_hdmi_tmds_range_read(bd) failed
[    4.320456] tegradc 15220000.nvdisplay: probed
[    4.334665] tegradc 15220000.nvdisplay: fb registered
[    4.358562] tegradc 15220000.nvdisplay: hdmi: tmds rate:85478K prod-setting:prod_c_hdmi_54m_111m
[    4.367461] tegradc 15200000.nvdisplay: blank - powerdown
[    4.368756] tegradc 15220000.nvdisplay: hdmi: get RGB quant from EDID.
[    4.368760] tegradc 15220000.nvdisplay: hdmi: get YCC quant from EDID.
[    4.437841] tegradc 15200000.nvdisplay: unblank
[    4.443650] tegradc 15200000.nvdisplay: hdmi: tmds rate:148500K prod-setting:prod_c_hdmi_111m_223m
[    4.444986] tegradc 15200000.nvdisplay: hdmi: get RGB quant from EDID.
[    4.445009] tegradc 15200000.nvdisplay: hdmi: get YCC quant from EDID.
[    7.742374] tegradc 15220000.nvdisplay: blank - powerdown
[    7.769138] extcon-disp-state external-connection:disp-state: cable 46 state 0
[    7.769140] Extcon AUX0(HDMI) disable
[    7.790049] tegra_nvdisp_handle_pd_disable: Powergated Head2 pd
[    7.790131] ignoring invalid window 0 request
[    7.790132] ------------[ cut here ]------------
[    7.790145] WARNING: CPU: 2 PID: 725 at /dvs/git/dirty/git-master_linux/kernel/nvidia/drivers/video/tegra/dc/window.c:1044 tegra_dc_update_windows+0x304/0x540
[    7.790148] Modules linked in:
[    7.790156] CPU: 2 PID: 725 Comm: kworker/2:1 Not tainted 4.9.140-tegra #1
[    7.790157] Hardware name: quill (DT)
[    7.790182] Workqueue: events tegra_hdmi_hpd_worker
[    7.790184] task: ffffffc1eb375400 task.stack: ffffffc1eb2b0000
[    7.790187] PC is at tegra_dc_update_windows+0x304/0x540
[    7.790190] LR is at tegra_dc_update_windows+0x304/0x540
[    7.790211] pc : [<ffffff80085d5084>] lr : [<ffffff80085d5084>] pstate: 40400045
[    7.790217] sp : ffffffc1eb2b3900
[    7.790226] x29: ffffffc1eb2b3900 x28: 0000000000000000 
[    7.790230] x27: 0000000000000020 x26: 0000000000000000 
[    7.790233] x25: 0000000000000001 x24: 0000000000000000 
[    7.790241] x23: ffffffc1eb2b39c8 x22: 0000000000000001 
[    7.790253] x21: ffffffc1eb422060 x20: ffffffc1e5470000 
[    7.790256] x19: 0000000000000000 x18: 0000000000000001 
[    7.790259] x17: 0000000000000000 x16: 0000000000000000 
[    7.790267] x15: ffffffffffffffff x14: ffffff800a104240 
[    7.790275] x13: ffffff800a103e79 x12: 0000000000000040 
[    7.790278] x11: 0000000000000003 x10: 0000000000000100 
[    7.790286] x9 : 0000000000000012 x8 : 7365757165722030 
[    7.790293] x7 : 0000000000000021 x6 : ffffff800a103141 
[    7.790301] x5 : 00ffffffffffffff x4 : 0000000000000000 
[    7.790304] x3 : 0000000000000000 x2 : 0000000000000000 
[    7.790311] x1 : ffffffc1eb375400 x0 : 0000000000000021 
[    7.790324] ---[ end trace 1e40c9ebcdb5baec ]---
[    7.790327] Call trace:
[    7.790332] [<ffffff80085d5084>] tegra_dc_update_windows+0x304/0x540
[    7.790341] [<ffffff800866f46c>] tegra_fb_pan_display+0xcc/0x100
[    7.790346] [<ffffff800851a2ac>] fb_pan_display+0x9c/0x120
[    7.790350] [<ffffff800851a658>] fb_set_var+0x148/0x398
[    7.790354] [<ffffff800866fde8>] tegra_fbcon_set_fb_mode+0x70/0xa0
[    7.790358] [<ffffff800866ffc4>] tegra_fb_update_monspecs+0x1ac/0x2d8
[    7.790361] [<ffffff80086267c8>] tegra_hdmi_hotplug_notify+0x70/0xd0
[    7.790364] [<ffffff8008628180>] tegra_hdmi_edid_eld_setup+0x168/0x248
[    7.790368] [<ffffff8008629e68>] tegra_hdmi_hpd_worker+0x138/0x2f8
[    7.790374] [<ffffff80080d4f3c>] process_one_work+0x1e4/0x4b0
[    7.790378] [<ffffff80080d5258>] worker_thread+0x50/0x4c8
[    7.790381] [<ffffff80080dbee4>] kthread+0xec/0xf0
[    7.790386] [<ffffff8008083850>] ret_from_fork+0x10/0x40
[    7.790393] tegradc 15220000.nvdisplay: unblank
[    7.790505] tegra_nvdisp_handle_pd_enable: Unpowergated Head2 pd
[    7.790766] Parent Clock set for DC plld3
[    7.793452] tegradc 15220000.nvdisplay: hdmi: tmds rate:85500K prod-setting:prod_c_hdmi_54m_111m
[    7.794792] tegradc 15220000.nvdisplay: hdmi: get RGB quant from EDID.
[    7.794798] tegradc 15220000.nvdisplay: hdmi: get YCC quant from EDID.
[    7.798392] extcon-disp-state external-connection:disp-state: cable 46 state 1
[    7.798394] Extcon AUX0(HDMI) enable
[    8.185668] tegradc 15200000.nvdisplay: hdmi: plugged
[    8.206333] tegradc 15220000.nvdisplay: hdmi: plugged

It’s not clear why this error is happening.

Any ideas?

Thanks,

Cary

[    7.790131] ignoring invalid window 0 request

Could you share what is your “win-mask” field now? Please tell us the values from 3 heads.

There are totally 6 windows on TX2 and shared by 3 heads display. If you assign nothing to specific head, then that head cannot work. Also, if you assign same window to different head simultaneously, then it should crash too.

Thanks, this is helpful.

I seem to have been able to set the win-mask and nvidia,fb-win values to eliminate errors
during the dt parsing for the display (I enabled debug messages in drivers/video/tegra/dc/of_dc.c).
We have a dsi output that’s disabled for now.

Device tree customizations:

nvdisplay@15200000 {
			status = "okay";
			win-mask = <0x03>;
			nvidia,fb-win = <0>;
			nvidia,dc-or-node = "/host1x/sor1";
			nvidia,dc-connector = <&sor1>;
		};
		nvdisplay@15210000 {
			status = "disabled";
			win-mask = <0x30>;
			nvidia,fb-win = <4>;
			nvidia,dc-or-node = "/host1x/dsi";
			nvidia,dc-connector = <&dsi>;
		};
		nvdisplay@15220000 {
			status = "okay";
			win-mask = <0x0C>;
			nvidia,fb-win = <2>;
			nvidia,dc-or-node = "/host1x/sor";
			nvidia,dc-connector = <&sor0>;
		};

dmesg:

[    0.896820] OF_DC_LOG: valid_heads 3
[    0.898099] OF_DC_LOG: dc controller index 0
[    0.898130] tegradc 15200000.nvdisplay: disp0 connected to head0->/host1x/sor1
[    0.898188] OF_DC_LOG: fb bpp 32
[    0.898210] OF_DC_LOG: fb flip on probe
[    0.898252] OF_DC_LOG: dc flag 1
[    0.898288] OF_DC_LOG: out_dcc bus 3
[    0.898339] OF_DC_LOG: default_out flag 2
[    0.898358] OF_DC_LOG: tegra dc align msb
[    0.898377] OF_DC_LOG: tegra order red to blue
[    0.898397] OF_DC_LOG: parent clk plld2
[    0.898417] OF_DC_LOG: framebuffer xres 4096
[    0.898435] OF_DC_LOG: framebuffer yres 2160
[    0.898459] OF_DC_LOG: fb window Index 0
[    0.898498] OF_DC_LOG: win mask 0x3
[    0.898518] OF_DC_LOG: cmu enable 1
[    0.898538] tegradc 15200000.nvdisplay: DT parsed successfully
[    0.898610] tegradc 15200000.nvdisplay: Display dc.ffffff800b610000 registered with id=0
[    0.908059] tegradc 15200000.nvdisplay: vblank syncpt # 8 for dc 0
[    0.908089] tegradc 15200000.nvdisplay: vpulse3 syncpt # 9 for dc 0
[    0.913495] tegradc 15200000.nvdisplay: hdmi: invalid prod list prod_list_hdmi_board
[    0.913535] tegradc 15200000.nvdisplay: hdmi: tegra_hdmi_tmds_range_read(bd) failed
[    0.949924] tegradc 15200000.nvdisplay: probed
[    4.205954] tegradc 15200000.nvdisplay: fb registered
[    4.239754] tegradc 15200000.nvdisplay: hdmi: tmds rate:148500K prod-setting:prod_c_hdmi_111m_223m
[    4.250139] tegradc 15200000.nvdisplay: hdmi: get RGB quant from EDID.
[    4.256690] tegradc 15200000.nvdisplay: hdmi: get YCC quant from EDID.
[    4.278237] OF_DC_LOG: dc controller index 2
[    4.282526] tegradc 15220000.nvdisplay: disp1 connected to head2->/host1x/sor
[    4.289695] OF_DC_LOG: fb bpp 32
[    4.292939] OF_DC_LOG: fb flip on probe
[    4.300734] OF_DC_LOG: dc flag 1
[    4.303993] OF_DC_LOG: out_dcc bus 5
[    4.307586] OF_DC_LOG: default_out flag 2
[    4.311607] OF_DC_LOG: tegra dc align msb
[    4.315634] OF_DC_LOG: tegra order red to blue
[    4.320090] OF_DC_LOG: parent clk plld3
[    4.323948] OF_DC_LOG: framebuffer xres 4096
[    4.328229] OF_DC_LOG: framebuffer yres 2160
[    4.332527] OF_DC_LOG: fb window Index 2
[    4.336457] OF_DC_LOG: win mask 0xc
[    4.339954] OF_DC_LOG: emc clk rate 300000000
[    4.344316] OF_DC_LOG: cmu enable 1
[    4.347802] tegradc 15220000.nvdisplay: DT parsed successfully
[    4.353664] tegradc 15220000.nvdisplay: Display dc.ffffff800bc60000 registered with id=1
[    4.361997] tegradc 15220000.nvdisplay: vblank syncpt # 11 for dc 2
[    4.368286] tegradc 15220000.nvdisplay: vpulse3 syncpt # 12 for dc 2
[    4.376976] tegradc 15220000.nvdisplay: hdmi: invalid prod list prod_list_hdmi_board
[    4.384816] tegradc 15220000.nvdisplay: hdmi: tegra_hdmi_tmds_range_read(bd) failed
[    4.407284] tegradc 15220000.nvdisplay: probed
[    4.420294] tegradc 15220000.nvdisplay: fb registered
[    4.425813] tegradc 15200000.nvdisplay: blank - powerdown
[    4.503555] tegradc 15200000.nvdisplay: unblank
[    4.512873] tegradc 15200000.nvdisplay: hdmi: tmds rate:148500K prod-setting:prod_c_hdmi_111m_223m
[    4.514399] tegradc 15200000.nvdisplay: hdmi: get RGB quant from EDID.
[    4.514425] tegradc 15200000.nvdisplay: hdmi: get YCC quant from EDID.
[    7.757246] tegradc 15200000.nvdisplay: hdmi: plugged
[  106.055244] tegradc 15200000.nvdisplay: blank - powerdown
[  106.122099] tegradc 15200000.nvdisplay: unblank
[  106.129542] tegradc 15200000.nvdisplay: hdmi: tmds rate:148500K prod-setting:prod_c_hdmi_111m_223m
[  106.130963] tegradc 15200000.nvdisplay: hdmi: get RGB quant from EDID.

Now I get two frame buffers, however The X server won’t start.

Xorg -verbose
...
(II) NVIDIA dlloader X Driver  32.1.0  Release Build  (integ_stage_rel)  (buildbrain@mobile-u64-2988)  Wed Mar 13 00:27:33 PDT 2019
(II) NVIDIA Unified Driver for all Supported NVIDIA GPUs
(WW) Falling back to old probe method for NVIDIA
(II) Loading /usr/lib/xorg/modules/libfb.so
(II) Module fb: vendor="X.Org Foundation"
        compiled for 1.19.6, module version = 1.0.0
(II) Loading /usr/lib/xorg/modules/libwfb.so
(II) Module wfb: vendor="X.Org Foundation"
        compiled for 1.19.6, module version = 1.0.0
(WW) VGA arbiter: cannot open kernel arbiter, no multi-card support
(II) NVIDIA(0): Creating default Display subsection in Screen section
        "Default Screen Section" for depth/fbbpp 24/32
(==) NVIDIA(0): Depth 24, (==) framebuffer bpp 32
(==) NVIDIA(0): RGB weight 888
(==) NVIDIA(0): Default visual is TrueColor
(==) NVIDIA(0): Using gamma correction (1.0, 1.0, 1.0)
(DB) xf86MergeOutputClassOptions unsupported bus type 0
(**) NVIDIA(0): Enabling 2D acceleration
(II) Loading /usr/lib/xorg/modules/extensions/libglxserver_nvidia.so
(II) Module glxserver_nvidia: vendor="NVIDIA Corporation"
        compiled for 4.0.2, module version = 1.0.0
(II) NVIDIA GLX Module  32.1.0  Release Build  (integ_stage_rel)  (buildbrain@mobile-u64-2988)  Wed Mar 13 00:25:11 PDT 2019
(EE) NVIDIA(GPU-0): Failed to initialize the NVIDIA graphics device!
(EE) NVIDIA(0): Failing initialization of X screen 0
(II) Unloading glxserver_nvidia
(EE) Screen(s) found, but none have a usable configuration.
(EE) 
Fatal server error:
(EE) no screens found(EE) 
(EE)

Two questions:

a) What should the “win-mask” and “nvidia,fb-win” values be for each nvdisplay entry?
We want to be able to run X and one nvoverlaysink on each display, so each display
needs 2 connections to the frame buffer. I think this is what win-mask is for, but I don’t
understand what nvidia,fb-win means or should be set to.

b) Why wouldn’t the X driver start? What configurations would make it mis-operate?

Thanks in advance,

Cary

  1. In general, you don’t need to modify nvidia,fb-win. Only need to change the value of win-mask.

The rule to change win mask is:

There are 6 windows as A~F. If you want to assign window A/B/C to head0, then you assign ABC as 1s and remaining as 0s.

ABCDEF
111000 → This value is 0x38.

And if you want to assign DEF to head2

ABCDEF
000111 → This value is 0x7.

  1. I am not sure about current status. If you don’t have X enabled, how did you know you have 2 framebuffers? Also, for the X error, could you share the result of lsmod?

HDMI 1,2 are working now, thanks.

It appears as if the nvidia,win-mask entry for nvdisplay@15220000 was not set.
I compared to an earlier L4T 28 system, and copied the value (5) to use. I still
am not sure what this actually means.

Currently I am allocating two windows per display head.

I was checking for frame buffers looking for either /dev/fb?, or looking in /sys/class/graphics.

As for the Xorg startup problem, I believe this could have been a missing package or driver
or something. I re-installed the L4T32 rootfs and kernel from scratch and the problem
starting Xorg was resolved. It is possible, however, that it was caused by using the
tegra186-quill-p3310-1000-a00-00-base.dts file as a starting point rather thant
the *c00-00-base.dts file. Not 100% sure.

Here’s the dts I’m using that enables both hdmi.

/* Base device tree from L4T */


#include "tegra186-quill-p3310-1000-a00-00-base.dts"

/* Enable second HDMI */

/ {
        nvidia,dtsfilename = __FILE__;

	/* Note each head has two 'windows' (dma channels?) into the frame buffer */

        host1x {
		/* DSI */
                nvdisplay@15200000 {
			status = "disabled";
			win-mask = <0x03>;
                };

		/* HDMI-1 */
                nvdisplay@15210000 {
			status = "okay";
			win-mask = <0x0C>;
                };

		/* HDMI-2 */
                nvdisplay@15220000 {
			status = "okay";
			win-mask = <0x30>;
			nvidia,fb-win = <0x05>;  /* missing from L4T 32_1 */
                };

		/* Needed to be enabled for HDMI-2 */
		sor {
		    status = "okay";
		    nvidia,active-panel = <&sor_hdmi_display>;

		    sor_hdmi_display: hdmi-display {
			status = "okay";
		    };

		    dp-display {
			status = "okay";
		    };
		};

		dpaux@155c0000 { 
		    status = "okay";
		}; 

	};

};

Next step is to enable the third video out using the DSI output circuit.

Thanks for your help.

Cary

You could refer to TX2 TRM chapter “Display Controller” → 24.3.1 overview to understand how these hardware windows work.

In brief,

  1. tegra is able to supports up to 3 heads display so you could see fb0/fb1/fb2 under /dev if all three nvdisplay are enabled.

  2. For each fb, you need assign at least one surface to it for rendering.

  3. What is the benefit if I assign many windows to single head?
    For some usecase like “nvoverlaysink” in gstreamer, it can directly draw something to different windows. You may notice that there is no gpu usage when rendering something directly to nvoverlaysink. That means if I want to get better performance, I could leverage those windows.

However, if you only have 1 window on head, you need a window manager like lightdm or gdm and compositor to help you gather all the surfaces you want to render, compose them into one surface through GPU and draw it on the screen.

If you are familiar with Linux DRM, then those windows are the “planes” in drm API.