Jetson Xavier platform specific configurations

Hard-Coding Kernel Display Boot Mode for HDMI

The Linux kernel boot logs and text-mode login prompt fails to display on some monitors due to a known fbconsole pixel clock calculation issue. To workaround this issue, support has been to specify exact Mode timings in Device Tree for HDMI.

Affected HDMI monitors include:

  • Acer S277HK

  • Dell 24-inch 4K monitor

  • Viewsonic VP2780

  • ASUS MX27UQ

  • Samsung 8500 UHD TV

  • NEC MultiSync LCD2070VX

  • LG Flatron W2246

  • ASUS VW220TE

NVIDIA has packaged a utility to update the kernel DTB file to work around this issue. To update kernel DTB file, complete the steps in the next section.

Update Kernel DTB file

  1. Navigate to kernel directory at:

    <top>/Linux_for_Tegra/kernel
    
  2. To update the DTB, run the following commands:

    $ ./nv-enable-hard-coded-kernel-boot-display-mode.sh
    $ dtb/tegra194-p2888-0001-p2822-0000.dtb
    
  3. Flash the system.

After successful boot, fbconsole displays in the specified mode. The default display mode is 720x480p@60Hz CEA.

The DTB file is at:

kernel/dtb/tegra194-p2888-0001-p2822-0000.dtb

Specifying a Non-Default Mode

  1. Open the utility in your preferred editor.

  2. In the properties array, update the values to the left of the ‘:’ (colon) for each of the mode parameters.

  3. Save the utility script and exit the editor.

  4. Execute the utility again by completing the steps in Update Kernel DTB file.

Guidelines

  • Any known working mode on the given Monitor/TV can be specified instead of the 720x480p mode.

  • If the nvidia,fbcon-default-mode node already exists, the script might print an error message. It is safe to ignore this message.

  • By default, the HDMI is mapped to SOR1 on both the platforms. If it is updated to SOR0, ensure that the node path is also updated and assigned to the fbcon_node variable in the script.

nvimp_util: A Tool for Calculating Memory Bandwidth for a Particular Display Configuration (IMP)

Is Mode Possible (IMP) is an algorithm that can be used to determine:

  • With the bandwidth constraints, whether a proposed display configuration is possible.

  • If the configuration is possible, the expected bandwidth values that must be programmed into the hardware to support this configuration

Display configuration loosely refers to the state of all active heads, windows, and cursors.

Several factors can impact IMP, such as the maximum downscaling factor for each active window, the surface dimensions of each window, the raster timings on a particular head and so on. IMP takes all of these factors into account.

nvimp_util is an offline utility that lets you input a display configuration through the command line and run IMP on it. If IMP passes, the utility outputs bandwidth values that you can specify in a device tree to support the display configuration. This topic explains how to use nvimp_util to run IMP and how to program device tree accordingly.

You must have sudo permissions to run this tool.

Command Line Options

Command line options for nvimp_util fall into two main categories: - Per-head - Per-window.

The following tables describe these options:

Required per-head options
Option name Description Value
--head <n>

-h <n>

Specifies physical display ID of a head. All other per-head options apply to this head. Integer

NVIDIA® Jetson AGX Xavier™ series: [0, 3]

--pclkMHz <fp>

-p <fpK>

Pixel clock value in megahertz for the head. Floating point
--h_active <n>

-a <n>

Horizontal active raster width in pixels. Integer
--v_active <n>

-b <n>

Vertical active raster height in lines. Integer
--h_blank <n>

-A <n>

Total horizontal line blanking in pixels. Integer
--v_blank <n>

-B <n>

Total vertical blanking in lines. Integer


Optional per-head options
Option name Description Value
--cursor_active <b>

-C <b>

Indicates whether the head’s hardware cursor is active. Integer

Zero (FALSE) or non-zero (TRUE)

Default is FALSE

--output_lut_enable <b>

-l <b> (lower case L)

Indicates whether the head’s OLUT (Output Lookup Table) is enabled. Integer

Zero (FALSE) or non-zero (TRUE)

Default is FALSE

--output_lut_size <n>

-g <n>

Specifies the number of entries in the OLUT.

Use only if ``output_lut_enable`` is TRUE.

Integer

257 or 1025

No default

Note

Per-window options may be omitted completely. The required options must all be specified if the --window option (optional, in the subsequent table) is present.

Required per-window options
Option name Description Value
--sizeInX <n>

-X <n>

Input width of the window in pixels.

Required if e is specified.

Integer
--sizeInY <n>

-y <n>

NO if "window" is specified

The input height of the window in lines.

Integer
--sizeOutX <n>

-X <n>

NO if "window" is specified

Output width of the window in pixels.

Integer

[1, h_active]

--sizeOutY <n>

-Y <n>

NO if "window" is specified

Output height of the window in lines.

Integer

[1, v_active]


Optional per-window options
Option name Description Value
--window <n>

-W <n>

Specifies the physical ID of the hardware window.

Applies to the corresponding "head" argument since a window is always owned by a head.

Required if any other per-window switches are specified. All other per-window switches apply to this window.

Integer

[0, 5]

No default

--format <str>

-f <str>

Input color format of the window's surface. String

Value must be one of:

  • FORMAT_420_PLANAR_10_12_BIT
  • FORMAT_420_SEMI_PLANAR_10_12_BIT
  • FORMAT_422_SEMI_PLANAR_10_12_BIT
  • FORMAT_422R_SEMI_PLANAR_10_12_BIT
  • FORMAT_444_PLANAR_10_12_BIT
  • FORMAT_444_SEMI_PLANAR_10_12_BIT
  • FORMAT_1BPP_PACKED
  • FORMAT_2BPP_PACKED
  • FORMAT_4BPP_PACKED
  • FORMAT_8BPP_PACKED
  • FORMAT_420_PLANAR
  • FORMAT_420_SEMI_PLANAR
  • FORMAT_422_PACKED
  • FORMAT_422_SEMI_PLANAR
  • FORMAT_422R_SEMI_PLANAR
  • FORMAT_444_PLANAR
  • FORMAT_444_SEMI_PLANAR
Default is FORMAT_4BPP_PACKED.
--surface <str>

-g <str>

Describes memory layout of the window's surface. String

Value must be one of:

  • PITCH
  • BLOCKLINEAR
Default is PITCH.
--pointOutX <n>

-i <n>

Output X-coordinate of the window's upper left corner in the active raster. Integer

[0, (h_active‒1)]

Default is 0

--pointOutY <n>

-J <n>

Output Y-coordinate of the window's upper left corner in the active raster. Integer

[0, (v_active‒1)]

Default is 0

--pointInX <n>

-i <n>

Input X-coordinate of the surface fetch offset; 0 to fetch the entire surface. Integer

[0, (sizeInX‒1)]

Default is 0

--pointInY <n>

-j <n>

Input Y-coordinate of the surface fetch offset; 0 to fetch the entire surface. Integer

[0, (sizeInY‒1)]

Default is 0

--rotation <b>

-r <b>

Specifies whether hardware SCAN_COLUMN rotation is enabled for this window. Integer

Zero (FALSE) or non-zero (TRUE)

Default is FALSE

--compression <b>

-z <b>

Specifies whether to apply CDE compression to a window's surface. Integer

Zero (false) or non-zero (true); default is zero

Applies to: Jetson TX2 series only


Other options
Option name Description Value
--help

-H

Lists available command-line arguments with a short description of each. n/a
--version

-V

Displays the version number of nvimp_util.

Multi-Head/Multi-Window Input Configurations

nvimp_util allows you to specify input configurations that contain multiple active display heads and/or windows. All arguments that immediately follow a --head or --window option apply to that head or window.

For example, suppose you want to specify an input configuration with the following head-to-window mapping:

  • HEAD0: WINDOW0, WINDOW1

  • HEAD1: WINDOW2, WINDOW3

  • HEAD2: WINDOW4, WINDOW5

The nvimp_util command line looks like this (where “…” represents other options):

# nvimp_util --head 0 --window 0 ... --window 1 ... \
             --head 1 --window 2 ... --window 3 ... \
             --head 2 --window 4 ... --window 5 ...

Output Values

nvimp_util outputs bandwidth values calculated by IMP. These values must be programmed into hardware to support the proposed display configuration.

Output values can be divided into three categories: - System - Per-window - Per-cursor. System values apply to the display as a whole. Per-window values apply to a specific window and Per-cursor values apply to a specific cursor.

The following tables list the output values, with a brief description of each:

System output values
Value name Description
nvidia,total_disp_bw_with_catchup Total required ISO bandwidth for display, including the catchup factor.

The catchup factor is added as a margin to cover events that can disrupt the instantaneous bandwidth allocated to display (e.g., DVFS).

nvidia,total_disp_bw_without_catchup Total required ISO bandwidth for display, *not* including the catchup factor.
nvidia,disp_emc_floor EMC floor required to satisfy various MC latency allowance constraints.
nvidia,disp_min_hubclk Minimum required hubclk rate. The hubclk is the main interface clock used by isohub. Isohub is the hardware unit that fetches surfaces from DRAM, buffers them, and drains them to the nvdisplay pipeline.
nvidia,total_win_fetch_slots Aggregate number of fetch slots allocated to all active windows. Think of a fetch slot as a time slot allocated for a window or cursor pipe to fetch from DRAM. Each window pipe is assigned its own number of fetch slots, as described below.
nvidia,total_cursor_fetch_slots Aggregate number of fetch slots allocated to all active cursors. Each individual cursor pipe is assigned its own number of fetch slots, as described below.


Window output values
Value name Description
nvidia,win_fetch_meter_slots Number of fetch slots allocated to each active window pipe.
nvidia,win_dvfs_watermark_values Specifies DVFS watermark values for each active window pipe. If the current amount of buffering is above the watermark threshold, the display hardware allows the Memory Controller (MC) to schedule a DVFS event if necessary.
nvidia,win_pipe_meter_values Amount of metering that must be applied on the window precomp side. This effectively controls the rate at which pixels flow from isohub to precomp. An unsigned fixed point (U8.8) value.
nvidia,win_mempool_buffer_entries Number of mempool buffering entries allocated to the window. Each mempool entry is 128 bytes wide.
nvidia,win_thread_groups Specifies the thread group assigned to the window. Each thread group can potentially contain a different number of threads. The number of threads controls which semi-planar/planar input formats are supported, as well as whether hardware rotation can be done in combination with certain input formats.


Cursor output values
Value name Description
nvidia,cursor_fetch_meter_slots Number of fetch slots allocated to each active cursor pipe.
nvidia,cursor_dvfs_watermark_values Specifies DVFS watermark values for each active cursor pipe. If the current amount of buffering is above the watermark threshold, the display hardware allows the Memory Controller (MC) to schedule a DVFS event if necessary.
nvidia,cursor_pipe_meter_values Amount of metering that must be applied on the window precomp side. This effectively controls the rate at which pixels flow from isohub to precomp. An unsigned fixed point (U8.8) value.
nvidia,cursor_mempool_buffer_entries Number of mempool buffering entries allocated to the cursor. Each mempool entry is 128 bytes wide.

Device Tree Configuration

nvimp_util prints the output values described above to the console. These values must then be programmed into a device tree. The Jetson display driver reads the values from device tree on boot and programs them into the hardware.

For example, suppose that you run this nvimp_util command:

# nvimp_util -h 0 -p 100 -a 480 -b 640 -A 128 -B 505 -l 1 -g 257 -C 1 \
             -W 1 -f FORMAT_4BPP_PACKED -s BLOCKLINEAR -x 640 -y 480 -X 640 -Y 480 -i 0 -j 0 -I 0 -J 0 -r 1 -z 1 \
             -h 2 -p 74.25 -a 1280 -b 720 -A 370 -B 30 -l 1 -g 257 -C 1 \
             -W 5 -f FORMAT_4BPP_PACKED -s BLOCKLINEAR -x 1280 -y 720 -X 1280 -Y 720 -i 0 -j 0 -I 0 -J 0 -r 0 -z 1 \
             -W 2 -f FORMAT_1BPP_PACKED -s BLOCKLINEAR -x 1280 -y 720 -X 1280 -Y 720 -i 0 -j 0 -I 0 -J 0 -r 1 -z 0

The program displays this output:

Input parameters:

Head: 0
pclkMHz: 100
h_active: 480
v_active: 640
h_blank: 128
v_blank: 505
output_lut_enable: 1
output_lut_size: 257
cursor_active: 1

Window: 1
color_format: FORMAT_4BPP_PACKED
surface_format: BLOCKLINEAR
sizeInX: 640
sizeInY: 480
sizeOutX: 640
sizeOutY: 480
pointInX: 0
pointInY: 0
pointOutX: 0
pointOutY: 0
rotation: 1
compression: 1

Head: 2
pclkMHz: 74.25
h_active: 1280
v_active: 720
h_blank: 370
v_blank: 30
output_lut_enable: 1
output_lut_size: 257
cursor_active: 1

Window: 5
color_format: FORMAT_4BPP_PACKED
surface_format: BLOCKLINEAR
sizeInX: 1280
sizeInY: 720
sizeOutX: 1280
sizeOutY: 720
pointInX: 0
pointInY: 0
pointOutX: 0
pointOutY: 0
rotation: 0
compression: 1

Window: 2
color_format: FORMAT_1BPP_PACKED
surface_format: BLOCKLINEAR
sizeInX: 1280
sizeInY: 720
sizeOutX: 1280
sizeOutY: 720
pointInX: 0
pointInY: 0
pointOutX: 0
pointOutY: 0
rotation: 1
compression: 0

\*******Input parameters parsing done******\

Number of Windows = 3

Window 1 is attached to Head 0

Window 5 is attached to Head 2

Window 2 is attached to Head 2


Number of Cursors = 2

Cursor 0 is attached to Head 0

Cursor 1 is attached to Head 2


Number of Heads = 2


Requested mode is possible!

Add following values in device tree:

/* Global settings */
nvidia,total_disp_bw_with_catchup = <0 1497231>;
nvidia,total_disp_bw_without_catchup = <0 1361119>;
nvidia,disp_emc_floor = <0 102000000>;
nvidia,disp_min_hubclk = <0 28073088>;
nvidia,total_win_fetch_slots = /bits/ 16 <15>;
nvidia,total_cursor_fetch_slots = /bits/ 16 <8>;

/* Window settings */
nvidia,imp_win_mapping = /bits/ 8 <1 5 2 >;
nvidia,win_fetch_meter_slots = /bits/ 16 <15 8 2 >;
nvidia,win_dvfs_watermark_values = <0 28274 0 16893 0 26794 >;
nvidia,win_pipe_meter_values = <256 256 256 >;
nvidia,win_mempool_buffer_entries = <0 2399 0 1269 0 280 >;
nvidia,win_thread_groups = /bits/ 8 <-1 -1 0 >;

/* Cursor settings */
nvidia,imp_head_mapping = /bits/ 8 <0 2 >;
nvidia,cursor_fetch_meter_slots = /bits/ 16 <15 5 >;
nvidia,cursor_dvfs_watermark_values = <0 9135 0 2762 >;
nvidia,cursor_pipe_meter_values = <256 256 >;
nvidia,cursor_mempool_buffer_entries = <0 798 0 241 >;

Note

Although the nvimp_util output shows values for the compression, that setting is not implemented on T194 platforms, and is ignored.

The values displayed above in the Global settings, Window settings, and Cursor settings sections must be copied to a device tree. Two groups of nodes are involved:

  • /host1x/disp_imp_table

    This node contains groups of IMP settings that have been calculated for certain configurations.

    The num_settings property specifies the number of IMP setting groups contained within the node.

  • /host1x/disp_imp_table/disp_imp_settings_<n>

    This is a group of nodes; <n> is a number that corresponds to the order in which each node appears under /host1x/disp_imp_table. That is, <n> is 0 for the first node, 1 for the second and so on.

    Each disp_imp_settings_<n> node contains the IMP output settings that must be programmed for a specific input configuration. The device tree property names are the same as the corresponding parameter names that nvimp_util writes to the console.

    The window and cursor device tree properties each specify an array of values (one value per window or per cursor). Use the nvidia,imp_win_mapping and nvidia,imp_head_mapping properties to explicitly specify which window(s) or cursor(s) the node applies to.

    The following device tree properties operate on 64-bit numbers:

    • nvidia,total_disp_bw_with_catchup

    • nvidia,total_disp_bw_without_catchup

    • nvidia,disp_emc_floor

    • nvidia,disp_min_hubclk

    • nvidia,win_dvfs_watermark_values

    • nvidia,win_mempool_buffer_entries

    • nvidia,cursor_dvfs_watermark_values

    • nvidia,cursor_mempool_buffer_entries

There are two simple approaches that you can use to copy the values to a device tree:

  • Edit the SoC-level IMP device tree settings directly.

    • NVIDIA Jetson AGX Xavier series: The SoC-level IMP device tree source file may be found at:

      $TOP/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc/tegra194-soc-disp-imp.dtsi
      

    To copy your values over, delete or comment out the existing disp_imp_table node and add your own.

  • Create your own DTSI fragment with the appropriate disp_imp_table node.

    • Jetson AGX Xavier series: Insert your fragment into tegra194-soc-base.dtsi. Comment out the #include at the top for the generic tegra194-soc-disp-imp.dtsi file.

This is what the corresponding device tree entry will look like for the above example:

/ {
    host1x {
        disp_imp_table: disp_imp_table {
            status = "okay";
            num_settings = <1>;
            disp_imp_settings_0 {

                /* Global settings */
                nvidia,total_disp_bw_with_catchup = <0 1497231>;
                nvidia,total_disp_bw_without_catchup = <0 1361119>;
                nvidia,disp_emc_floor = <0 102000000>;
                nvidia,disp_min_hubclk = <0 28073088>;
                nvidia,total_win_fetch_slots = /bits/ 16 <15>;
                nvidia,total_cursor_fetch_slots = /bits/ 16 <8>;

                /* Window settings */
                nvidia,imp_win_mapping = /bits/ 8 <1 5 2 >;
                nvidia,win_fetch_meter_slots = /bits/ 16 <15 8 2 >;
                nvidia,win_dvfs_watermark_values = <0 28274 0 16893 0 26794 >;
                nvidia,win_pipe_meter_values = <256 256 256 >;
                nvidia,win_mempool_buffer_entries = <0 2399 0 1269 0 280 >;
                nvidia,win_thread_groups = /bits/ 8 <-1 -1 0 >;

                /* Cursor settings */
                nvidia,imp_head_mapping = /bits/ 8 <0 2 >;
                nvidia,cursor_fetch_meter_slots = /bits/ 16 <15 5 >;
                nvidia,cursor_dvfs_watermark_values = <0 9135 0 2762 >;
                nvidia,cursor_pipe_meter_values = <256 256 >;
                nvidia,cursor_mempool_buffer_entries = <0 798 0 241 >;
            };
        };
    };
};

After you update the DTS, rebuild it and flash the new DTB blob onto the device.

Limitations with Seamless Display

Seamless Display (display initialization by bootloader) is enabled on HDMI & DP for Jetson Xavier series in the current release with below limitations.

Seamless Display limited to Head0

Display is initialized by bootloader to display a splash screen on connected monitors as soon as possible during boot-up. However there is a known stability issue when bootloader enables the display on second and third display heads.

To avoid this stability issue, bootloader display initialization on second and third heads (depending on the number of display heads supported on a platform) has been disabled in this release. Hence, splash screen will show up only on the monitor connected to first head (head0). On Jetson Xavier AGX series and Jetson Xavier NX series, HDMI output is mapped to head0 by default. Hence, splash screen would come up only if a HDMI monitor is connected during boot.

If the use case requires splash screen on DP instead of HDMI, swap the HDMI SOR mapped to head0 with a DP SOR.

  1. Example - For Jetson Xavier AGX:

  • head0 -> sor2 -> HDMI

  • head1 -> sor0 -> DP

  • head2 -> sor1 -> DP

Swap HDMI and DP SORs assigned to “nvidia,dc-connector” property under head0 and head1 in <TOP>/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2822-disp.dtsi:

diff --git a/common/tegra194-p2822-disp.dtsi b/common/tegra194-p2822-disp.dtsi
index 188e64f..d37c103 100644
--- a/common/tegra194-p2822-disp.dtsi
+++ b/common/tegra194-p2822-disp.dtsi
@@ -32,7 +32,7 @@
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
win-mask = <0x3>;
nvidia,fb-win = <0>;
-  nvidia,dc-connector = <&sor2>;
+  nvidia,dc-connector = <&sor0>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
avdd_hdmi-supply = <&p2888_spmic_sd0>; /* 1v0 */
avdd_hdmi_pll-supply = <&p2888_spmic_sd1>; /* 1v8 */
@@ -46,7 +46,7 @@
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
win-mask = <0xC>;
nvidia,fb-win = <2>;
-  nvidia,dc-connector = <&sor0>;
+  nvidia,dc-connector = <&sor2>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
vdd-dp-pwr-supply = <&p2888_spmic_sd0>;
avdd-dp-pll-supply = <&p2888_spmic_sd1>;
  1. Example - For Jetson Xavier NX:

  • head0 -> sor1 -> HDMI

  • head1 -> sor0 -> DP

Swap HDMI and DP SORs assigned to “nvidia,dc-connector” property under head0 and head1 in <TOP>/hardware/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-disp.dtsi:

diff --git a/common/tegra194-p3509-disp.dtsi b/common/tegra194-p3509-disp.dtsi
index f93b99a..15c7ad0 100644
--- a/common/tegra194-p3509-disp.dtsi
+++ b/common/tegra194-p3509-disp.dtsi
@@ -33,7 +33,7 @@
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
win-mask = <0x7>;
nvidia,fb-win = <0>;
-  nvidia,dc-connector = <&sor1>;
+  nvidia,dc-connector = <&sor0>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
avdd_hdmi-supply = <&p3668_spmic_sd0>; /* 1v0 */
avdd_hdmi_pll-supply = <&p3668_spmic_sd1>; /* 1v8 */
@@ -47,7 +47,7 @@
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
win-mask = <0x38>;
nvidia,fb-win = <3>;
-  nvidia,dc-connector = <&sor0>;
+  nvidia,dc-connector = <&sor1>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
vdd-dp-pwr-supply = <&p3668_spmic_sd0>;
avdd-dp-pll-supply = <&p3668_spmic_sd1>;

Seamless Display limitation for DP ALT-Mode (DP over USB-C)

Bootloader display driver polls for 1msec to detect if the HPD has been asserted by the Display Port sink. This polling duration is found to be sufficient for native DP connectors. However different DP ALT-mode downstream devices that are connected on Jetson Xavier AGX (cables, adapters, hubs and so on) might incur variable amounts of latency before they trigger the handshake process needed to drive DP over USB-C port. Since this delay is non-deterministic, increasing polling duration is not guaranteed to address the variations issue and could inadvertently increase the boot time. Due to this limitation, user may observe some inconsistent behavior for seamless display over DP ALT-mode.