option
MaisonMaison Skill DevOps et CI/CD jetson-customize-clocks

jetson-customize-clocks

NVIDIA/skills NVIDIA/skills

Verrouillez, limitez ou personnalisez le comportement des horloges du CPU, du GPU et de l'EMC sur les appareils NVIDIA Jetson en modifiant le fichier BPMP DTB et le script nvpower.sh avant la mise à jour du firmware.

...Développer tout
0
Heure mise à jour 25 septembre 2026

Personnaliser les horloges

Objectif

Personnaliser le comportement des horloges CPU, GPU et EMC sur une cible Jetson en modifiant les fichiers situés sous Linux_for_Tegra/ avant de flasher l’image. Deux niveaux sont concernés :

  • Le DTB BPMP situé à l’adresse Linux_for_Tegra/bootloader/ — les max-rate-custom , ainsi que la porte DVFS EMC (bwmgr + cactmon sur tous les SoC ; osp-controller sur le T26x uniquement).
  • nvpower.sh à Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh — les régulateurs cpufreq / devfreq et (en option) les fréquences minimales / maximales / statiques par périphérique écrites dans sysfs au démarrage.

Déclencheurs courants : «verrouiller la fréquence du CPU/GPU/EMC », « fixer le GPU à Fmax », « fixer l’EMC à MAXN », « désactiver/activer le DVFS de l’EMC », « désactiver/activer le DVFS du CPU », « définir la fréquence maximale du CPU/GPU », « changer de régulateur cpufreq ».

Hors du champ d’application : réglage de l’horloge en temps réel sur une cible active (sans étape de flash), modifications du mode d’alimentation via nvpmodel (utilisez la compétence sœur /jetson-customize-nvpmodel) et les contournements de la limite matérielle (max-rate-maxn en lecture seule).

Prérequis

Définir le profil actif conformément à ../../context/target-platform-contract.md. Refuser et rediriger dans les cas suivants :

Condition Refuser avec
Aucun profil actif, ou active: NA Acheminer vers /jetson-set-target ou /jetson-init-target.
Le profil ne contient pas bsp_image: bloc Itinéraire vers /jetson-init-image.
/Linux_for_Tegra/ manquant Chemin vers /jetson-init-image.
/Linux_for_Tegra/ manquant ou n'est pas un dépôt Git Chemin d'accès à /jetson-init-source.

Résolution des chemins :

  • à partir de bsp_image.root_path: si présent, sinon /Image.
  • à partir de source.root_path: si présent, sinon /Source.

est en lecture seule pour cette compétence ; chaque écriture (le DTB BPMP de l'opération 1 et celui de l'opération 2 nvpower.sh) aboutit sous (le suivi des superpositions). Il s’agit de l’invariance du flux de travail dans ../../context/bsp-customization-workflow.md#workflow-invariants — l’édition manuelle en amont détruit silencieusement la piste de différences et génère /jetson-promote-image une opération nulle.

Instructions

  1. Remplissez les conditions préalables ci-dessus (profil actif, image BSP extraite, suiveur de superposition source initialisé).
  2. Choisissez l’opération dans le tableau ci-dessous.
  3. Suivez la section de procédure correspondante — Opération 1 (DTB BPMP), Opération 2 (nvpower.sh), ou la recette MAXN pour les deux.
  4. Validez la modification dans le suivi des superpositions conformément à la convention de validation propre à chaque opération.
  5. Déployez avec /jetson-promote-image → /jetson-flash-image. Le nouveau DTB BPMP et nvpower.sh prendront effet au prochain démarrage.

Opérations prises en charge

Opération Emplacement de la modification Section « Procédure »
Verrouiller la fréquence d’un CPU / GPU à une valeur spécifique BPMP DTB max-rate-custom sur le nœud d'horloge + nvpower.sh régulateur performance « Modification du contenu : max-rate-custom» + « Sélectionner la modification »
Verrouiller l’EMC à son taux d’initialisation (désactiver le DVFS de l’EMC) DTB BPMP : bwmgr.enabled = 0, cactmon.enabled = 0, plus /delete-node/ osp-controller sur T26x uniquement « Modification du contenu : désactivation / activation de l'EMC DVFS »
Réactiver le DVFS EMC DTB BPMP : bwmgr.enabled = 1, cactmon.enabled = 1, restaurer osp-controller sur T26x « Modification du contenu : désactivation / activation du DVFS EMC »
Régler tous les paramètres sur MAXN pour les tests de résistance Combiner ce qui précède + nvpmodel MAXN comme valeur par défaut au démarrage voir la recette
Abaisser la limite maximale d'une fréquence d'horloge sans verrouillage DTB BPMP max-rate-custom uniquement « Modification du contenu : max-rate-custom"
Limiter la fréquence d’un périphérique sans verrouiller nvpower.sh min/max via sysfs « Sélectionner la modification »

Opération 1 — Modifications du DTB BPMP

Suivez le protocole de personnalisation du DTB BPMP décrit dans ../../references/bsp-customization-bpmp-dtb.md. Le protocole définit les mécanismes : importation à l’état vierge lors de la première intervention, dtc décompilation, recompilation, vérification de cohérence, validation. Cette compétence ne fournit que le contenu spécifique à l’horloge (quels nœuds et propriétés modifier lors de l’étape « Modifier le DTS » du protocole).

Les .dtb se retrouve dans le /Linux_for_Tegra/ suivi des superpositions. /jetson-promote-imageLe canal A parcourt le tracker et copie le fichier dans bsp_image. Ne modifiez pas directement « /Linux_for_Tegra/bootloader/» : il s’agit de la sortie de la promotion, et non d’une entrée.

Résoudre le DTB BPMP avec le SKU correct

Conformément à la section « Résolution du DTB BPMP actif » du protocole, lisez BPFDTB_FILE à partir de la configuration Flash active. Pour les configurations courantes Thor / à SKU unique, il s’agit de la ligne statique BPFDTB_FILE=... ligne dans la configuration par carte .conf et dont la valeur fait autorité telle quelle.

Pour les configurations à multiplexage de SKU (chaîne de configuration du kit de développement Orin AGX qui sélectionne un DTB BPMP différent par board_sku/board_FAB via update_flash_args_common — voir ../../context/bsp-customization-software-layers.md#per-board-conf-dispatch--update_flash_args_common), parcourez la chaîne de répartition avec board_sku= et board_FAB= à partir du profil actif, puis lisez BPFDTB_FILE à partir de la sortie de répartition — et non à partir de la ligne statique de la configuration propre à la carte .conf. Les valeurs statiques et celles issues de la répartition coïncident pour les configurations non multiplexées ; la répartition n’est obligatoire que lorsque la chaîne de configuration remplace conditionnellement BPFDTB_FILE.

Liste des débits maximaux effectifs (inspection)

Inspecter les deux couches du plafond d’exécution — voir references/clock-control-model.md#effective-runtime-ceiling — avant de déterminer une max-rate-custom valeur.

Le guide d’inspection (décompilation côté BPMP + grep ; awk côté nvpmodel sur le mode par défaut au démarrage) se trouve dans references/bpmp-dtb-clock-edits.md#inspection-cookbook.

Pour la couche nvpmodel, voir /jetson-customize-nvpmodel.

Cette étape ne modifie pas l’état — il s’agit d’une condition préalable au dimensionnement de la modification dans l’étape « Modification du contenu : max-rate-custom sur un nœud d’horloge nommé ».

Modification du contenu : max-rate-custom sur un nœud d’horloge nommé

Au cours de l’étape « Modifier le DTS » du protocole, modifiez la propriété à l’intérieur du nœud d’horloge nommé — celle-ci lateinit. max-rate-custom doit être strictement inférieure au plafond fixe de l’horloge (max-rate-maxn si elle est définie ; sinon, la fréquence en temps réel max_rate provenant d’une cible en fonctionnement de la même puce / SKU).

Le formulaire d’édition du DTS, la sémantique et le mappage nvpmodel ↔ nœud d’horloge BPMP se trouvent dans references/bpmp-dtb-clock-edits.md.

Rendez ensuite le contrôle au protocole — ses étapes « Recompiler », « Vérification de cohérence du blob recompilé », « Placer dans le traqueur de superposition » et « Nettoyage » se chargent du reste. Convention de message de validation selon le protocole : : jetson-customize-clocks — max-rate-custom = .

Modification du contenu : activation / désactivation de l’EMC DVFS

Le comportement par défaut (EMC DVFS activé) ne nécessite aucune modification. La désactivation d’EMC DVFS est une modification multi-nœuds appliquée au sein de la même étape « Modifier le DTS » du protocole, et non une bwmgr commutation :

# Modification Portée
1 bwmgr.enabled = <0x00> Tous les SoC, obligatoire
2 cactmon.enabled = <0x00> Tous les SoC, obligatoire
3 /delete-node/ osp-controller T26x (Thor) obligatoire — T23x (Orin) ne dispose pas d’un tel nœud, ignorer

Détection : dtc -I dtb -O dts | grep -c osp-controller — zéro résultat ⇒ chemin T23x. Les extraits DTS complets, les modes de défaillance des chemins de secours et la procédure de réactivation se trouvent dans references/emc-dvfs-disable.md.

Appliquez les étapes du protocole allant de « Recompile » à « Cleanup » une fois que la modification multi-nœuds est en place. Convention relative au message de validation : : jetson-customize-clocks — EMC DVFS disable (bwmgr + cactmon[+ osp-controller]).

La désactivation augmente la consommation en veille ; destinée aux tests de charge / de performances, et non aux systèmes de fichiers racine de production.

Réexécution + idempotence

Conformément à la section « Re-runnability » du protocole, la réexécution de cette compétence avec la même valeur cible produit une validation sans effet. La réexécution avec une valeur différente réécrit la même propriété — git log -- $BPMP_REL ce qui permet de visualiser l’historique par exécution. Pour ramener une horloge à son max-rate-maxn plafond, modifiez le DTS pour supprimer la max-rate-custom ligne et recompilez.

Opération 2 — Modifications de nvpower.sh

Modifications nvpower.sh, qui s’exécute au démarrage via nvpower.service pour définir les régulateurs et les fréquences cpufreq / devfreq.

Le fichier de script

Le script modifié par cette opération a le chemin relatif suivant :

Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh

Il se trouve dans deux répertoires racines ; l’opération parcourt les deux :

Rôle Emplacement La compétence écrit-elle ?
Détection + source intacte /Linux_for_Tegra/rootfs/etc/systemd/ non — lecture seule
Modification de la cible de superposition + commit Git /Linux_for_Tegra/rootfs/etc/systemd/ oui

Les sous-étapes suivantes font référence au fichier par script pour désigner la superposition copiée sous . La copie est lue une seule fois lors de l'étape « pristine-import » ci-dessous, puis n'est plus jamais modifiée.

Recette de modification de l’overlay (à appliquer avant de modifier nvpower.sh)

Suivez la recette canonique de modifications hors compétence dans la documentation du workflow — paire « importation pristine » + « commit de personnalisation », toutes deux soumises au contrôle de prévisualisation. nvpower.sh Il s’agit d’un fichier unique sans ensemble de propagation ; un commit « pristine » + un commit de personnalisation couvrent l’intégralité de la modification.

Substitutions concrètes pour cette compétence :

  • / est rootfs/etc/systemd/nvpower.sh.
  • Message suggéré pour l’importation « pristine » : import pristine: rootfs/etc/systemd/nvpower.sh, corps Source: /Linux_for_Tegra/ (BSP ).
  • En-tête suggéré pour le commit de personnalisation : jetson-customize-clocks: nvpower.sh , lignes de corps telles que set_cpufreq_governor: desired_cpufreq_gov "schedutil" -> "performance".

Choisissez l'emplacement de la

Emplacements des fonctions (set_cpufreq_governor, set_devfreq_governor), les recettes d’édition courantes (fixation à Fmax, taux statique, limites min/max) et les nvidia-l4t-init mise en garde concernant la mise à niveau du package se trouvent dans references/nvpower-sh-edits.md.

Deploy

Le commit de personnalisation dans le tracker de superposition n'atteint pas l'appareil de lui-même. La chaîne de déploiement :

  1. /jetson-promote-image — copie chaque fichier suivi de la superposition dans /Linux_for_Tegra/. Prise en charge des différences (ignore les bytes identiques) ; utilise sudo cp -p pour les rootfs/* destinations.
  2. /jetson-flash-image — flashe la version mise à jour bsp_image sur le périphérique. nvpower.service exécute le nouveau script au prochain démarrage.
  3. (Autre méthode, sans flashage) Copier /Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh directement dans le répertoire /etc/systemd/nvpower.sh, puis sudo systemctl restart nvpower.service (ou redémarrez).

Modification /... sans valider — ou l'édition /... directement — n’a aucun effet sur /jetson-promote-image et est perdu sans avertissement lors de la prochaine /jetson-init-image ré-extraction.

Astuce — fixez tout à MAXN pour les tests de charge / de performances

Combine les opérations 1 et 2. Le BPMP de l’opération 1 traite l’ensemble du flux en un seul cycle du protocole (un seul cycle de décompilation / modification multi-nœuds / recompilation / validation — ne pas effectuer deux allers-retours dans le protocole pour le même .dtb):

  1. DTB BPMP (le contenu de l’étape « Modification du contenu : max-rate-custom sur un nœud d’horloge nommé ») : laissez max-rate-custom désactivé sur chaque horloge CPU / GPU / EMC ; supprimez les max-rate-custom lignes existantes qui abaissent le plafond.
  2. DTB du BPMP (contenu de l’étape « Modification du contenu : désactivation / activation du DVFS EMC ») : verrouiller l’EMC à sa fréquence d’initialisation — bwmgr.enabled = 0, cactmon.enabled = 0, plus /delete-node/ osp-controller sur T26x (ignorer sur T23x).
  3. Appliquez les deux modifications de contenu au sein d’un seul appel du protocole « Modifier le DTS », puis exécutez les étapes restantes du protocole (recompilation, vérification de cohérence, validation unique de la personnalisation couvrant les deux modifications de contenu).
  4. nvpower.sh (Opération 2) : définissez desired_cpufreq_gov="performance" et desired_devfreq_gov="performance" sans condition ; supprimez le saut GPU/nvjpg dans set_devfreq_governor. Application via la recette de modification par superposition de l’opération 2 (l’étape « Recette de modification par superposition (à appliquer avant de modifier nvpower.sh) ») — une paire distincte de commit « pristine » + personnalisation du script du système de fichiers racine (rootfs) via le suivi des superpositions, distincte du commit du protocole BPMP-DTB.
  5. Définir le mode nvpmodel par défaut au démarrage sur MAXN via /jetson-customize-nvpmodel — les limites de nvpmodel par cycle d’horloge sont fixées en dessous de max-rate-maxn quel que soit le contenu du DTB BPMP.

Déployer /jetson-promote-image → /jetson-flash-image récupère le nouveau DTB BPMP (via le suivi des superpositions) et le fichier nvpower.sh (via ce même suivi des superpositions) lors de la prochaine écriture sur la mémoire flash.

Limitations

  • Uniquement au moment de la création de l’image. Toutes les modifications sont intégrées sous /Linux_for_Tegra/ et ne parviennent à l’appareil que via /jetson-promote-image → /jetson-flash-image. Le réglage en temps réel n’est pas pris en charge.
  • max-rate-custom ne fait qu’abaisser le plafond. Il doit être strictement inférieur à max-rate-maxn; l’augmentation de la limite maximale du circuit intégré n’est pas prise en charge.
  • Le plafond effectif comporte deux niveaux. Le plafond d’exécution est min(BPMP cap, active-nvpmodel-mode cap). Le plafond nvpmodel appartient à /jetson-customize-nvpmodel; cette compétence ne le modifie pas.
  • Porte EMC DVFS conditionnelle au SoC. La désactivation de l’EMC DVFS nécessite de modifier des ensembles de nœuds différents sur les T23x (bwmgr + cactmon) par rapport aux T26x (bwmgr + cactmon + suppression osp-controller). Une détection erronée entraîne un comportement indéfini.
  • La limite du GPU sur les T23x est multi-nœuds. La fréquence d'horloge du GPU est répartie entre nafll_gpusys et chaque nafll_gpcX; la limite ne s’applique que lorsqu’elle est appliquée à l’ensemble de ces nœuds.
  • nvpower.sh est géré par le paquet. Il est fourni dans nvidia-l4t-init; les mises à jour du paquet écrasent les modifications effectuées sur place. Les configurations à long terme devraient privilégier une solution de remplacement systemd ou un utilitaire associé.
  • ODMDATA l’emporte. Lorsqu’un jeton ODMDATA couvre une propriété, il remplace les modifications directes du DTS BPMP au moment de la mise à jour de la mémoire flash. Les modifications directes du DTS BPMP constituent la solution de secours pour les propriétés non couvertes par un jeton NVIDIA.
  • max-rate-maxn et lateinit sont hors limites. max-rate-maxn est la limite matérielle (en lecture seule). lateinit est destiné à l’initialisation de l’horloge au démarrage, et non au contournement de la limite maximale — ne modifiez jamais l’un ou l’autre.
  • Le DTB BPMP peut être multiplexé par SKU. Sur les configurations de flash composées / distribuées (chaîne du kit de développement Orin AGX), BPFDTB_FILE est sélectionné par board_sku / board_FAB via update_flash_args_common. La lecture de la ligne statique BPFDTB_FILE= est erronée lorsque la chaîne la remplace de manière conditionnelle ; résolvez le problème via la répartition à la place.

Dépannage

Erreur Cause Solution
max-rate-custom définie, mais la fréquence d’horloge continue d’augmenter jusqu’à max-rate-maxn sur le GPU T23x Seule nafll_gpusys a été plafonnée ; les nafll_gpcX partitions fonctionnent toujours à max-rate-maxn et dominent le plafond effectif. Appliquez la même max-rate-custom à nafll_gpusys et à chaque nafll_gpcX nœud répertorié par grep -nE '^\s*nafll_gpc[0-9]+\s*:' .
La désactivation de l'EMC DVFS semble s'appliquer, mais l'EMC continue de s'adapter sur le T26x Seule bwmgr.enabled = <0x00> a été défini ; osp-controller il persiste et réémet les modifications de fréquence via le chemin QoS. Ajouter les modifications n° 2 (cactmon.enabled = <0x00>) et n° 3 (/delete-node/ osp-controller) dans la même étape « Modifier le DTS ». Vérifiez osp-controller via dtc -I dtb -O dts | grep -c osp-controller → résultat attendu : 0.
La désactivation de l’EMC DVFS a été rejetée sur le T23x avec le message « nœud introuvable » pour les osp-controller T23x (Orin) : les DTB BPMP ne contiennent pas osp-controller; la modification n° 3 doit être ignorée sur T23x. Détecter la famille de SoC à l’aide de l’ grep -c osp-controller étape ; n’appliquer la modification n° 3 que lorsque le nombre est ≥ 1.
BPMP refuse de charger la DTB après modification : max-rate-custom >= max-rate-maxn max-rate-custom a été défini à une valeur égale ou supérieure au plafond de la puce. Réduire max-rate-custom strictement en dessous max-rate-maxn. Si max-rate-maxn est absent du nœud, interroger la limite en temps réel sur une cible en cours d’exécution : cat /sys/kernel/debug/bpmp/debug/clk//max_rate.
osp-controller réapparaît après status = "disabled" status = "disabled" ne supprime pas le nœud de l’arborescence des périphériques ; le BPMP continue de le parcourir. Remplacer par /delete-node/ osp-controller; — le nœud ne doit pas exister pour que le BPMP ignore le chemin.
Modifications apportées à nvpower.sh perdu après apt upgrade nvpower.sh est géré par le nvidia-l4t-init deb et sont écrasées lors de la mise à jour. Pour les configurations de test à long terme, intégrez les modifications dans un fichier « drop-in » systemd ou dans un fichier d’aide fréreux référencé par nvpower.sh, plutôt que de modifier nvpower.sh directement dans le fichier.
/jetson-promote-image n'a aucun effet après la modification du DTB BPMP La modification a été appliquée à /Linux_for_Tegra/, qui correspond à /jetson-promote-imagela sortie de — et non à son entrée. Déplacez la modification vers /Linux_for_Tegra/bootloader/ (le tracker de superposition) et validez via le protocole BPMP-DTB.
La limite semble s'appliquer au premier démarrage, puis se réinitialise après un changement de mode d'alimentation La limite par cycle d’horloge du mode nvpmodel actif est plafonnée en dessous de max-rate-custom. Inspectez les deux couches ; si nvpmodel est contraignant, augmentez (ou supprimez) la limite nvpmodel via /jetson-customize-nvpmodel. La limite BPMP seule ne constitue pas le plafond d'exécution.

Références

  • ../../references/bsp-customization-bpmp-dtb.md — protocole canonique de personnalisation BPMP-DTB (importation à l’état vierge, décompilation, modification, recompilation, vérification de cohérence, validation). L’opération n° 1 de cette compétence se limite à la consommation de contenu ; le protocole gère les mécanismes.
  • references/clock-control-model.md — pile de couches, aperçu des deux plafonds, formule du plafond d’exécution effectif.
  • references/bpmp-dtb-clock-edits.md — Sémantique des deux plafonds, formulaire d’édition DTS, mappage nvpmodel ↔ nœud d’horloge BPMP, guide pratique d’inspection.
  • references/emc-dvfs-disable.md — Procédure complète de désactivation EMC DVFS conditionnelle au SoC avec extraits DTS, détection et réactivation.
  • references/nvpower-sh-edits.md — nvpower.sh Emplacements des fonctions + recettes d’édition courantes + mise en garde concernant la mise à niveau des paquets.
  • /jetson-customize-nvpmodel — Compétence connexe : modes de consommation d’énergie nvpmodel. Le plafond par cycle d’horloge du mode actif est limité en dessous du plafond DTB du BPMP.
Voir sur GitHub
---
name: jetson-customize-clocks
description: Lock, cap, or customize CPU, GPU, and EMC clock behavior on NVIDIA Jetson devices by editing BPMP DTB and nvpower.sh before flashing.
license: Apache-2.0
---

# Customize Clocks

## Purpose

Customize CPU, GPU, and EMC clock behavior on a Jetson target by editing files under `Linux_for_Tegra/` before flashing the image. Two layers are in scope:

- The **BPMP DTB** at `Linux_for_Tegra/bootloader/<BPFDTB_FILE>` — per-clock `max-rate-custom` ceilings, plus the EMC DVFS gate (bwmgr + cactmon on all SoCs; osp-controller on T26x only).
- **nvpower.sh** at `Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh` — cpufreq / devfreq governors and (optionally) per-device min / max / static rates written to sysfs at boot.

Common triggers: "lock CPU/GPU/EMC frequency", "pin GPU to Fmax", "pin EMC to MAXN", "disable/enable EMC DVFS", "disable/enable CPU DVFS", "set CPU/GPU max rate", "change cpufreq governor".

Out of scope: runtime clock tuning on a live target (no flash step), nvpmodel power-mode edits (use the sibling skill `/jetson-customize-nvpmodel`), and silicon-ceiling overrides (`max-rate-maxn` is read-only).

## Prerequisites

Resolve the active profile per
[`../../context/target-platform-contract.md`](../../context/target-platform-contract.md).
Refuse and route in these cases:

| Condition | Refuse with |
|---|---|
| No active profile, or `active: NA` | Route to `/jetson-set-target` or `/jetson-init-target`. |
| Profile lacks `bsp_image:` block | Route to `/jetson-init-image`. |
| `<bsp_image.root_path>/Linux_for_Tegra/` missing | Route to `/jetson-init-image`. |
| `<source.root_path>/Linux_for_Tegra/` missing or not a git repo | Route to `/jetson-init-source`. |

Resolve paths:

- `<bsp_image.root_path>` from `bsp_image.root_path:` if present, else `<workspace>/Image`.
- `<source.root_path>` from `source.root_path:` if present, else `<workspace>/Source`.

`<bsp_image.root_path>` is **read-only** for this skill; every write
(Operation 1's BPMP DTB and Operation 2's `nvpower.sh`) lands under
`<source.root_path>` (the overlay tracker). This is the workflow
invariant in
[`../../context/bsp-customization-workflow.md#workflow-invariants`](../../context/bsp-customization-workflow.md#workflow-invariants) —
hand-editing upstream silently destroys the diff trail and makes
`/jetson-promote-image` a noop.

## Instructions

1. Resolve the prerequisites above (active profile, BSP image extracted, source overlay tracker initialized).
2. Pick the operation from the table below.
3. Follow the linked procedure section — Operation 1 (BPMP DTB), Operation 2 (`nvpower.sh`), or the MAXN recipe for both.
4. Commit the edit inside the overlay tracker per each Operation's commit convention.
5. Deploy with `/jetson-promote-image` → `/jetson-flash-image`. The new BPMP DTB and `nvpower.sh` take effect on the next boot.

### Supported operations

| Operation | Where the edit lives | Procedure section |
|---|---|---|
| Lock a CPU / GPU clock to a specific rate | BPMP DTB `max-rate-custom` on the clock node + `nvpower.sh` governor `performance` | "Content edit: `max-rate-custom`" + "Pick the edit" |
| Lock EMC at its init rate (disable EMC DVFS) | BPMP DTB: `bwmgr.enabled = 0`, `cactmon.enabled = 0`, plus `/delete-node/ osp-controller` on T26x only | "Content edit: EMC DVFS disable / enable" |
| Re-enable EMC DVFS | BPMP DTB: `bwmgr.enabled = 1`, `cactmon.enabled = 1`, restore `osp-controller` on T26x | "Content edit: EMC DVFS disable / enable" |
| Pin everything to MAXN for stress runs | Combine the above + nvpmodel MAXN as boot default | see Recipe |
| Lower a clock's hard ceiling without locking | BPMP DTB `max-rate-custom` only | "Content edit: `max-rate-custom`" |
| Bound a device's rate without pinning | `nvpower.sh` min/max via sysfs | "Pick the edit" |

## Operation 1 — BPMP DTB edits

Follow the BPMP-DTB customization protocol in
[`../../references/bsp-customization-bpmp-dtb.md`](../../references/bsp-customization-bpmp-dtb.md).
The protocol owns the mechanics — pristine import on first touch,
`dtc` decompile, recompile, sanity-check, commit. This skill
supplies only the **clock-specific content** (which nodes and
properties to edit during the protocol's "Edit the DTS" step).

The edited `.dtb` lands in the `<source.root_path>/Linux_for_Tegra/`
overlay tracker. `/jetson-promote-image`'s channel A walks the
tracker and copies the file into `bsp_image`. **Do not edit
`<bsp_image.root_path>/Linux_for_Tegra/bootloader/<bpmp-dtb>`
directly** — that's the promote output, not an input.

### Resolve the SKU-correct BPMP DTB

Per the protocol's "Resolving the active BPMP DTB" section, read
`BPFDTB_FILE` from the active flash conf. For the common Thor /
single-SKU conf shapes this is the static `BPFDTB_FILE=...` line
in the per-board `.conf` and the value is authoritative as-is.

For **SKU-multiplexed conf shapes** (Orin AGX devkit conf chain
that selects a different BPMP DTB per `board_sku`/`board_FAB`
via `update_flash_args_common` — see
[`../../context/bsp-customization-software-layers.md#per-board-conf-dispatch--update_flash_args_common`](../../context/bsp-customization-software-layers.md#per-board-conf-dispatch--update_flash_args_common)),
walk the dispatch chain with `board_sku=<module.sku>` and
`board_FAB=<module.revision or empty>` from the active profile,
and read `BPFDTB_FILE` from the dispatch output — **not** from
the static line of the per-board `.conf`. Static and dispatched
values match for non-multiplexed confs; the dispatch is
mandatory only when the conf chain conditionally overrides
`BPFDTB_FILE`.

### List effective max rates (inspection)

Inspect both layers of the runtime ceiling — see [`references/clock-control-model.md#effective-runtime-ceiling`](references/clock-control-model.md#effective-runtime-ceiling) — before deciding on a `max-rate-custom` value.

Inspection cookbook (BPMP-side decompile + grep; nvpmodel-side awk over the boot default mode) is in [`references/bpmp-dtb-clock-edits.md#inspection-cookbook`](references/bpmp-dtb-clock-edits.md#inspection-cookbook).

For the nvpmodel layer see [`/jetson-customize-nvpmodel`](../jetson-customize-nvpmodel/SKILL.md).

This step does not mutate state — it's a precondition for sizing
the edit in the "Content edit: `max-rate-custom` on a named clock node" step.

### Content edit: `max-rate-custom` on a named clock node

During the "Edit the DTS" step of the protocol, modify the property
inside the named clock node — never `lateinit`. `max-rate-custom`
must be strictly below the clock's hard cap (`max-rate-maxn` if
defined, otherwise the live `max_rate` from a running target of
the same chip / SKU).

DTS edit form, semantics, and the nvpmodel ↔ BPMP clock-node
mapping live in [`references/bpmp-dtb-clock-edits.md`](references/bpmp-dtb-clock-edits.md).

Then hand control back to the protocol — its "Recompile", "Sanity-check
the recompiled blob", "Stage in the overlay tracker", and "Cleanup"
steps cover the rest.
Commit-message convention per the protocol:
`<BPMP_BASENAME>: jetson-customize-clocks — <clock-node> max-rate-custom = <value>`.

### Content edit: EMC DVFS disable / enable

Default behavior (EMC DVFS on) requires no edit. Disabling EMC
DVFS is a **multi-node edit** applied inside the same "Edit the DTS" step of
the protocol, **not** a `bwmgr` toggle:

| # | Edit | Scope |
|---|---|---|
| 1 | `bwmgr.enabled = <0x00>` | All SoCs, mandatory |
| 2 | `cactmon.enabled = <0x00>` | All SoCs, mandatory |
| 3 | `/delete-node/ osp-controller` | **T26x (Thor) mandatory** — T23x (Orin) has no such node, skip |

Detection: `dtc -I dtb -O dts <bpmp-dtb> | grep -c osp-controller`
— zero hits ⇒ T23x path. Full DTS snippets, the surviving-paths
failure modes, and the re-enable procedure are in
[`references/emc-dvfs-disable.md`](references/emc-dvfs-disable.md).

Apply the protocol's "Recompile" through "Cleanup" steps once the multi-node edit is in
place. Commit-message convention:
`<BPMP_BASENAME>: jetson-customize-clocks — EMC DVFS disable (bwmgr + cactmon[+ osp-controller])`.

Disabling raises idle power; intended for stress / performance
tests, not production rootfs.

### Re-run + idempotency

Per the protocol's "Re-runnability" section, re-running this
skill with the same target value produces a no-op commit. Re-
running with a different value rewrites the same property — `git
log -- $BPMP_REL` shows the per-run history. To return a clock
to its `max-rate-maxn` ceiling, edit the DTS to remove the
`max-rate-custom` line and recompile.

## Operation 2 — nvpower.sh edits

Edits `nvpower.sh`, which runs at boot via `nvpower.service` to set
cpufreq / devfreq governors and rates.

### The per-script file

The script this Operation edits has the relative path:

```
Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh
```

It lives in **two** roots; the Operation walks both:

| Role | Location | Skill writes? |
|---|---|---|
| Detection + pristine source | `<bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/systemd/` | no — read-only |
| Overlay edit target + git commit | `<source.root_path>/Linux_for_Tegra/rootfs/etc/systemd/` | yes |

Subsequent sub-steps refer to **the per-script file** to mean the overlay
copy under `<source.root_path>`. The `<bsp_image.root_path>` copy is read
once during the pristine-import step below, then never touched again.

### Overlay edit recipe (apply before editing nvpower.sh)

Follow the canonical
[Off-skill edits recipe](../../context/bsp-customization-workflow.md#off-skill-edits)
in the workflow doc — pristine import + customization commit pair, both
gated by the preview gate. `nvpower.sh` is a single file with no
propagation set; one pristine commit + one customization commit covers
the entire change.

Concrete substitutions for this skill:

- `<rel>/<file>` is `rootfs/etc/systemd/nvpower.sh`.
- Suggested pristine-import message:
  `import pristine: rootfs/etc/systemd/nvpower.sh`,
  body `Source: <bsp_image.root_path>/Linux_for_Tegra/ (BSP <bsp_image.version>)`.
- Suggested customization-commit header:
  `jetson-customize-clocks: nvpower.sh <summary>`,
  body lines like `set_cpufreq_governor: desired_cpufreq_gov "schedutil" -> "performance"`.

### Pick the edit

Function locations (`set_cpufreq_governor`, `set_devfreq_governor`), common-edit recipes (pin to Fmax, static rate, min/max bounds), and the `nvidia-l4t-init` package-upgrade caveat live in [`references/nvpower-sh-edits.md`](references/nvpower-sh-edits.md).

### Deploy

The customization commit in the overlay tracker does not reach the device
on its own. The Deploy chain:

1. **`/jetson-promote-image`** — copies every tracked file in the overlay
   into `<bsp_image.root_path>/Linux_for_Tegra/`. Diff-aware (skip
   byte-identical); uses `sudo cp -p` for `rootfs/*` destinations.
2. **`/jetson-flash-image`** — flashes the updated `bsp_image` to the
   device. `nvpower.service` runs the new script on the next boot.
3. (Alternate, no flash) Copy `<source.root_path>/Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh`
   directly to the running target's `/etc/systemd/nvpower.sh`, then
   `sudo systemctl restart nvpower.service` (or reboot).

Editing `<source.root_path>/...` without committing — or editing
`<bsp_image.root_path>/...` directly — does nothing for `/jetson-promote-image`
and is silently lost on the next `/jetson-init-image` re-extract.

## Recipe — pin everything to MAXN for stress / performance runs

Combines Operations 1 + 2. Operation 1's BPMP edits all flow
through one round of the protocol (a single decompile / multi-node
edit / recompile / commit cycle — don't round-trip the protocol
twice for the same `.dtb`):

1. **BPMP DTB** (the "Content edit: `max-rate-custom` on a named clock node" step content): leave `max-rate-custom` unset on every CPU / GPU / EMC clock; remove existing `max-rate-custom` lines that lower the ceiling.
2. **BPMP DTB** (the "Content edit: EMC DVFS disable / enable" step content): pin EMC at its init rate — `bwmgr.enabled = 0`, `cactmon.enabled = 0`, plus `/delete-node/ osp-controller` on T26x (skip on T23x).
3. Apply both content edits inside one protocol "Edit the DTS" invocation, then run the remaining protocol steps (recompile, sanity-check, single customization commit covering both content edits).
4. **nvpower.sh** (Operation 2): set `desired_cpufreq_gov="performance"` and `desired_devfreq_gov="performance"` unconditionally; remove the GPU/nvjpg skip in `set_devfreq_governor`. Applies via Operation 2's overlay edit recipe (the "Overlay edit recipe (apply before editing nvpower.sh)" step) — a separate overlay-tracker pristine + customization commit pair on the rootfs script, distinct from the BPMP-DTB protocol's commit.
5. Set the boot-default nvpmodel mode to MAXN via [`/jetson-customize-nvpmodel`](../jetson-customize-nvpmodel/SKILL.md) — the per-clock nvpmodel cap clamps below `max-rate-maxn` regardless of BPMP DTB content.

Deploy [`/jetson-promote-image`](../jetson-promote-image/SKILL.md) → [`/jetson-flash-image`](../jetson-flash-image/SKILL.md) picks up the new BPMP DTB (via the overlay tracker) and the edited `nvpower.sh` (via the same overlay tracker) on the next flash.

## Limitations

- **Image-build-time only.** All edits land under `<source.root_path>/Linux_for_Tegra/` and reach the device only via `/jetson-promote-image` → `/jetson-flash-image`. Live-target tuning is out of scope.
- **`max-rate-custom` only lowers the ceiling.** It must be strictly below `max-rate-maxn`; raising the silicon cap is not supported.
- **Effective ceiling is two-layer.** The runtime ceiling is `min(BPMP cap, active-nvpmodel-mode cap)`. The nvpmodel cap is owned by `/jetson-customize-nvpmodel`; this skill does not edit it.
- **SoC-conditional EMC DVFS gate.** Disabling EMC DVFS requires editing different node sets on T23x (bwmgr + cactmon) vs T26x (bwmgr + cactmon + delete `osp-controller`). Mis-detection produces undefined behavior.
- **T23x GPU cap is multi-node.** The GPU clock is split across `nafll_gpusys` and every `nafll_gpcX`; the cap binds only when applied to all of them.
- **`nvpower.sh` is package-managed.** It ships in `nvidia-l4t-init`; package upgrades clobber in-place edits. Long-lived setups should prefer a systemd drop-in or sibling helper.
- **ODMDATA wins.** When an ODMDATA token covers a property, the token overrides direct BPMP DTS edits at flash time. Direct BPMP DTS edits are the fallback for properties no NVIDIA token reaches.
- **`max-rate-maxn` and `lateinit` are off-limits.** `max-rate-maxn` is the silicon ceiling (read-only). `lateinit` is for boot-time clock init, not ceiling overrides — never touch either.
- **BPMP DTB may be SKU-multiplexed.** On compound / dispatched flash confs (Orin AGX devkit chain), `BPFDTB_FILE` is selected by `board_sku` / `board_FAB` via `update_flash_args_common`. Reading the static `BPFDTB_FILE=` line is wrong when the chain conditionally overrides it; resolve via the dispatch instead.

## Troubleshooting

| Error | Cause | Solution |
|---|---|---|
| `max-rate-custom` set but clock still ramps to `max-rate-maxn` on T23x GPU | Only `nafll_gpusys` was capped; the `nafll_gpcX` partitions still run at `max-rate-maxn` and dominate the effective ceiling. | Apply the same `max-rate-custom` to `nafll_gpusys` **and** every `nafll_gpcX` node enumerated by `grep -nE '^\s*nafll_gpc[0-9]+\s*:' <decompiled.dts>`. |
| EMC DVFS disable appears to apply but EMC still scales on T26x | Only `bwmgr.enabled = <0x00>` was set; `osp-controller` survives and re-issues frequency changes via the QoS path. | Add edits #2 (`cactmon.enabled = <0x00>`) and #3 (`/delete-node/ osp-controller`) inside the same "Edit the DTS" step. Verify `osp-controller` via `dtc -I dtb -O dts <bpmp-dtb> \| grep -c osp-controller` → expect 0. |
| EMC DVFS disable rejected on T23x with "node not found" for `osp-controller` | T23x (Orin) BPMP DTBs do not contain `osp-controller`; edit #3 must be skipped on T23x. | Detect SoC family with the `grep -c osp-controller` step; only apply #3 when the count is ≥1. |
| BPMP refuses to load DTB after edit: `max-rate-custom >= max-rate-maxn` | `max-rate-custom` was set to or above the silicon ceiling. | Lower `max-rate-custom` strictly below `max-rate-maxn`. If `max-rate-maxn` is absent from the node, query the live cap on a running target: `cat /sys/kernel/debug/bpmp/debug/clk/<clock>/max_rate`. |
| `osp-controller` re-appears after `status = "disabled"` | `status = "disabled"` does not remove the node from the device tree; BPMP still walks it. | Replace with `/delete-node/ osp-controller;` — the node must not exist for BPMP to skip the path. |
| Edits to `nvpower.sh` lost after `apt upgrade` | `nvpower.sh` is owned by the `nvidia-l4t-init` deb and gets overwritten on upgrade. | For long-lived test setups, package edits into a systemd drop-in or a sibling helper file referenced by `nvpower.sh`, rather than editing `nvpower.sh` in place. |
| `/jetson-promote-image` is a no-op after editing the BPMP DTB | The edit was applied to `<bsp_image.root_path>/Linux_for_Tegra/`, which is `/jetson-promote-image`'s output — not its input. | Move the edit to `<source.root_path>/Linux_for_Tegra/bootloader/<BPFDTB_FILE>` (the overlay tracker) and commit through the BPMP-DTB protocol. |
| Cap appears to apply on first boot then resets after a power-mode change | The active nvpmodel mode's per-clock cap clamps below `max-rate-custom`. | Inspect both layers; if nvpmodel is binding, raise (or remove) the nvpmodel cap via `/jetson-customize-nvpmodel`. The BPMP cap alone is not the runtime ceiling. |

## References

- [`../../references/bsp-customization-bpmp-dtb.md`](../../references/bsp-customization-bpmp-dtb.md) — canonical BPMP-DTB customization protocol (pristine import, decompile, edit, recompile, sanity-check, commit). Operation 1 of this skill is a content-only consumer; the protocol owns the mechanics.
- [`references/clock-control-model.md`](references/clock-control-model.md) — layer stack, two-ceilings overview, effective-runtime-ceiling formula.
- [`references/bpmp-dtb-clock-edits.md`](references/bpmp-dtb-clock-edits.md) — two-ceilings semantics, DTS edit form, nvpmodel ↔ BPMP clock-node mapping, inspection cookbook.
- [`references/emc-dvfs-disable.md`](references/emc-dvfs-disable.md) — full SoC-conditional EMC DVFS disable procedure with DTS snippets, detection, re-enable.
- [`references/nvpower-sh-edits.md`](references/nvpower-sh-edits.md) — `nvpower.sh` function locations + common-edit recipes + package-upgrade caveat.
- [`/jetson-customize-nvpmodel`](../jetson-customize-nvpmodel/SKILL.md) — sibling skill: nvpmodel power modes. The active mode's per-clock cap clamps below the BPMP DTB cap.

Installer jetson-customize-clocks

Téléchargez et décompressez les fichiers de compétences dans votre répertoire .claude/skills/.

Télécharger le ZIP

Clonez le dépôt et copiez les fichiers de compétence dans votre projet.

git clone https://github.com/NVIDIA/skills/tree/main/skills/jetson-customize-clocks # Copy SKILL.md to your .claude/skills/ directory

Copier Copier
Configuration rapide: Copiez le dossier de la compétence dans .claude/skills/ Claude détectera automatiquement la compétence et l'utilisera
Dépôt NVIDIA/skills

Compétences similaires

Verification &amp; Quality Assurance
Heure mise à jour 29 juin 2026
klingai-upgrade-migration
Heure mise à jour 3 juillet 2026
base44-cli
Heure mise à jour 29 juin 2026
Railway CLI Management
Heure mise à jour 2 juillet 2026
OR