Clocks

NVIDIA® Jetson™ Board Support Package (BSP) supports configuring Jetson clocks and peripheral clocks through software. This topic describes how to check the clock status, get the maximum rates for clocks, and configure the clock sources for NVIDIA® Jetson AGX Orin devices.

Note

For information about available Jetson clock sources and capabilities, see the “Clock and Reset Controller” section of the Technical Reference Manual (TRM) for your Jetson processor. This section of the TRM also describes clock source multiplexers and provides descriptions of available clock sources for each component.

Linux kernel supports the common clock framework (CCF) from version 4.9. As a result:

  • All device drivers use the public CCF API defined by include/linux/clk.h and include/linux/clk-provider.h, including functions such as clk_get(), clk_enable(), devm_clk_get(), clk_prepare_enable(), clk_prepare_disable(), clk_disable(), and others, instead of device-specific APIs.

  • All clock drivers, including the Jetson custom clk driver, implement the structure clk_ops.

  • Clock sources and clocks required by devices are defined in the device tree.

  • Clocks are controlled by an R5 called the Boot and Power Management Processor. It runs RTOS software from bpmp.bin. The Linux kernel running on CCPLEX requests this software for clock programming.

The NVIDIA® Jetson™ Linux clock driver wrapper is available at nvidia/drivers/clk/tegra/.

To check clock status

On the device, enter the following command to launch debugfs and check the clock:

$ sudo -s
# cat /sys/kernel/debug/bpmp/debug/clk/clk_tree

This is a portion of the sample debugfs output that is generated when you run the command above on the NVIDIA® Jetson AGX Orin device:

clock                                                 on       rate bpmp  mrq vdd
---------------------------------------------------------------------------------
clk_m                                                  1   19200000   11    1
    actmon                                             1   19200000    2    1 vdd_core@625000
    tach0                                              1    1010526    1    1 vdd_core@625000
    ufsdev_ref                                         0   19200000    0    0
    ist                                                0   19200000    0    0
    fuse_serial                                        0   19200000    0    0
    la                                                 0   19200000    0    0
    tsense                                             1    2742858    1    0 vdd_core@625000

Overriding Default Clock Rates

The default clock rate of each component is set during system boot time and updated under control of the Jetson custom clk driver by sending requests to the BPMP to adjust the clock rate. The debugfs affords a way to override the default clock rate and set a fixed clock rate. However, you should use debugfs for debugging and experimental purposes only.

Here is an example to check the clock-specific attributes of the emc clock node under the debugfs:

# cd /sys/kernel/debug/bpmp/debug/clk
# ls emc

dvfs        flags   max_rate  mrqcount         parent       rate      state
dvfs_table  hz_off  min_rate  mrq_rate_locked  pto_counter  refcount  vdd_core

You can use these attributes to change the clock parent, clock rate, and so on.

For example, you can override the emc rate by entering these commands:

# echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/mrq_rate_locked
# echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/state
# echo 1 > /sys/kernel/debug/bpmp/debug/bwmgr/bwmgr_halt
# echo x > /sys/kernel/debug/bpmp/debug/clk/emc/rate

The x value in the third command can be any value between the min_rate and the max_rate.

Configuring GPU Clocks

With GPU DVFS enabled using the devfreq framework, GPU frequency changes based on load. You can run the GPU at a fixed frequency instead if necessary.

To run the GPU at a fixed frequency

  1. Enter one of these commands:

    • For the GPU on the Jetson AGX Orin series devices:

      # cd /sys/devices/platform/17000000.gpu/devfreq/17000000.gpu/
      
  2. List the available frequencies:

    # cat available_frequencies
    

    The command displays a list of available frequencies like this:

    306000000 408000000 510000000 612000000 714000000 816000000 918000000 1020000000 1122000000 1224000000 1300500000
    
  3. Fix the frequency.

    • To fix the frequency at the maximum supported value:

      # echo <max> > min_freq
      

      Where <max> in the maximum supported frequency. For example, to fix the frequency at the maximum supported frequency from the list in step 2:

      # echo 1377000000 > min_freq
      
    • To fix the frequency at any other supported value:

      # echo <freq> > min_freq
      # echo <freq> > max_freq
      

      Where <freq> in the desired frequency range.

      For example, to fix the frequency at 828750000:

      # echo 828750000 > min_freq
      # echo 828750000 > max_freq
      
  • Get the current frequency.

    • To get the current frequency:

      # cat cur_freq
      
  • Print the GPU load on the Jetson AGX Orin series devices:

    # cat /sys/devices/platform/17000000.gpu/load
    

The command shows the GPU load value, and the value divided by 10 represents load percentage.

Configuring VIC Clocks

Video Image Compositor (VIC) provides a set of video processing services, including geometry transform processing for lens distortion correction and temporal noise reduction. The VIC voltage and frequency are dynamically scaled to conserve power, based on utilization as measured by the activity monitor (actmon).

For more information about VIC, see the “Video Image Compositor” section in the Technical Reference Manual (TRM) for your Jetson processor.

VIC Dynamic Voltage and Frequency Scaling

VIC actmon is a hardware block which monitors VIC active cycles in a fixed time window. It works with the wmark_active devfreq governor to perform dynamic voltage and frequency scaling (DVFS) operations for VIC.

wmark_active tries to keep the current load (the ratio of VIC active cycle to total cycle, scaled to [0, 1000]) within a certain percentage range. It sets upper and lower bounds for the current load. When current load goes outside these bounds, VIC actmon raises an interrupt which causes wmark_active to raise the VIC frequency, reducing the current load, or lower the frequency, increasing it.

The control logic in wmark_active is:

  1. Compute the current load:

    \(\text{cur}{r\_ load}_{} = \ \frac{\text{VIC}\ \text{active}\ \text{cycle}}{\text{VIC}\ \text{total}\ \text{cycle}\ @\text{current}\ \text{frequency}}*1000\)

  2. If (freq_boost_en && curr_load >= load_max):

    \(curr\_ ideal\_ freq = \ F_{\max}\)

    else:

    \(curr\_ ideal\_ freq = \ \frac{curr\_ load}{load\_ target}*curr\_ freq\)

    \(\text{av}{g\_ target\_ freq}_{\text{current}} = \ \frac{\text{smooth}}{\text{smooth}\ + \ 1}*\text{av}{g\_ target\_ freq}_{\text{previous}} + \ \frac{1}{\text{smooth}\ + \ 1}*\text{cur}{r\_ ideal\_ freq}_{}\)

    Where:

    • curr_load is the current load.

    • freq_boost_en is a knob which enables or disables the frequency boost feature.

    • Fmax is the maximum possible VIC frequency.

    • load_max is the frequency boost threshold. Its range is [0, 1000]. wmark_active boosts the VIC frequency to Fmax when load_level exceeds this threshold.

    • load_target (the load target) is the value of curr_load that wmark_active tries to maintain.

    • curr_freq is the current VIC frequency, in hertz.

    • curr_ideal_freq is the VIC frequency, in hertz, that would yield a curr_load value of load_target under current instantaneous operating conditions.

    • avg_target_freq is the moving average of the target frequency, in hertz. It is used to avoid abrupt changes in curr_freq when it is recalculated. This property is described more fully in To customize VIC DVFS with control knobs.

Select the first available frequency step that is greater than or equal to avg_target_freqcurrent.

Sysfs Paths for DVFS Control

This section describes the use of several knobs that control the operation of VIC DVFS.

Pathnames of Sysfs Nodes for DVFS Control

The sysfs nodes that control VIC knobs are located in a pair of directories whose locations are device-dependent. The descriptions that follow use these placeholders to represent those directories:

  • For NVIDIA® Jetson AGX Orin family series:

    • <knobpath> represents /sys/devices/platform/bus@0/13e00000.host1x/15340000.vic.

    • <knobpath_devfreq> represents /sys/devices/platform/bus@0/13e00000.host1x/15340000.vic/devfreq/15340000.vic

In the following procedures, replace these placeholders with the appropriate pathnames for your Jetson device.

VIC DVFS Control Terminology

Many of the control knobs concern the current load and the load target. The default load target is 700, i.e. wmark_active tries to keep the VIC active cycle at 70% of the current VIC frequency.

A lower load target makes VIC frequency scaling more aggressive, because the VIC frequency scales up to Fmax when the VIC active cycle exceeds (load target / 1000) × Fmax.

To enable or disable VIC DVFS

VIC DVFS is enabled by default. You can disable VIC DVFS by changing the underlying devfreq governor to userspace governor for the VIC engine.

Here is an example to change the devfreq governor of the VIC engine:

$ echo <gov> > <knobpath_devfreq>/governor

Where <gov> is the name of the VIC devfreq governor to be used:

  • To enable VIC DVFS, type wmark_active for the <gov>

  • To disable VIC DVFS, type userspace for the <gov>

To customize VIC DVFS with control knobs

  • The block_window control knob defines the shortest period between VIC frequency scaling operations, in microseconds. VIC actmon skips frequency scaling if the last VIC frequency scaling operation was performed less than block_window microseconds ago.

    To set block_window, enter the command:

    $ echo <period> > <knobpath>/block_window
    

    Where <period> is the block_window value to set.

  • The load_target control knob sets the VIC load target. To set the load_target, enter the command:

    $ echo <target> > <knobpath>/load_target
    

    Where <target> is the load target to set. The value range for the <target> is between 0 and 1000.

  • The freq_boost_en control knob enables or disables the frequency boost feature. If frequency boost is enabled, wmark_active boosts the VIC frequency to Fmax when the VIC load level exceeds the frequency boost threshold (set by the load_max control knob, below).

    To enable or disable frequency boost, enter the command:

    $ echo <b> > <knobpath>/freq_boost_en
    

    Where <b> is 1 to enable frequency boost, or 0 to disable it.

  • The load_max control knob sets the frequency boost threshold. wmark_active boosts the VIC frequency to Fmax when the VIC load level exceeds the frequency boost threshold. Its range is [0, 1000]. Its default value is 900.

    Note that wmark_active boosts the VIC frequency only if freq_boost_en (above) is enabled.

    To set the frequency boost threshold, enter the command:

    $ echo <max> > <knobpath>/load_max
    

    Where <max> is the frequency boost threshold to set.

  • curr_ideal_freq is the VIC frequency, in hertz, that would yield a curr_load value of load_target under current instantaneous operating conditions.

  • avg_target_freq is the average target frequency, in hertz. That is, it is a moving average of the target frequency, in hertz.

    The smooth knob adjusts the weights that avg_target_freqprevious and curr_ideal_freq are given in adjusting the value of avg_target_freq toward the target frequency:

    \({\text{avg}\_\text{target}\_\text{freq}}_{\text{current}} = \ \frac{\text{smooth}}{\text{smooth}\ + \ 1}*{\text{avg}\_\text{target}\_\text{freq}}_{\text{previous}}\ + \ \frac{1}{\text{smooth}\ + \ 1}*\text{curr}\_\text{ideal}\_\text{freq}\)

    If smooth is 0, the weight of avg_target_freqprevious is 0% and the weight of curr_ideal_freq is 100%, so avg_target_freqcurrent is set to curr_ideal_freq each time it is adjusted.

    To set smooth, enter the command:

    $ echo <value> > <knobpath>/smooth
    

    Where <value> is the value to set.

Setting the Static VIC Frequency

For debugging or power/performance evaluation, you may want to set the VIC frequency to a fixed value. You can set the static VIC frequency directly if you disable VIC DVFS.

To set the static VIC frequency

  1. Disable VIC runtime power management (PM) suspend. This forces the VIC hardware block into a power-on state so that you can configure the VIC frequency with commands:

    $ echo on > <knobpath>/power/control
    
  2. Read the runtime status:

    $ cat <knobpath>/power/runtime_status
    

    The command should display a runtime status of active.

  3. Disable VIC DVFS:

    $ echo userspace > <knobpath_devfreq>/governor
    
  4. Check the available VIC frequency settings:

    $ cat <knobpath_devfreq>/available_frequencies
    

    The command lists the available frequencies like this:

    115200000 128000000 140800000 153600000 166400000 179200000 192000000 204800000 217600000 230400000 243200000 256000000 268800000 281600000 294400000 307200000 320000000 332800000 345600000 358400000 371200000 384000000 396800000 409600000 422400000 435200000 448000000 460800000 473600000 486400000 499200000 512000000 524800000 537600000 550400000 563200000 576000000 588800000 601600000 614400000 627200000 640000000 652800000 665600000 678400000 691200000 704000000 716800000 729600000
    
  5. Choose one of the available frequencies, and set the VIC maximum frequency and the VIC frequency to that value:

    $ echo <frequency> > <knobpath_devfreq>/max_freq
    $ echo <frequency> > <knobpath_devfreq>/userspace/set_freq
    
  6. Enable VIC runtime PM suspend:

    $ echo auto > <knobpath>/power/control
    

Configuring Clocks

In general, each block or module has a dedicated clock source register. For detailed information about a given register, see your Jetson device’s Technical Reference Manual for information about CLK_RST_CONTROLLER_CLK_SOURCE_<module_name>.

Clock source registers provide clock source selection and clock divider control for the module. The divider is typically 8 bits: 7 integer bits and 1 fractional bit (U7.1).

To change clock configurations in the kernel device driver module

  1. Declare the clocks in the device tree. For example, for mttcan, clocks can be declared like this:

    clocks = <&bpmp TEGRA234_CLK_CAN1_CORE>,
            <&bpmp TEGRA234_CLK_CAN1_HOST>,
            <&bpmp TEGRA234_CLK_CAN1>,
            <&bpmp TEGRA234_CLK_PLLAON>;
    clock-names = "can_core", "can_host","can","pllaon";
    
  2. Use devm_clk_get() to obtain the desired clock source using clock-names.

  3. Use clk_get_parent() to obtain the parent clock for the desired clock.

  4. Use clk_set_parent() to select the specified clock source for the target clock.

  5. Use clk_set_rate() to set the frequency of the target clock.

    The divider is calculated automatically according to the target rate. Successful clock frequency settings must meet use one of the available dividers of that module and the frequency of the clock source.

  6. Use clk_round_rate() to get the exact clock frequency that can be configured from the current clock source.

  7. Use clk_prepare_enable(), or clk_prepare() and clk_enable(), to enable the clock. You can use clk_prepare() instead of clk_enable() to enable a clock if the operation may sleep.