选项
首页首页 Skill 开发运营和 CI/CD jetson-customize-clocks

jetson-customize-clocks

NVIDIA/skills NVIDIA/skills

在刷写固件之前,通过编辑 BPMP DTB 和 nvpower.sh 文件,锁定、限制或自定义 NVIDIA Jetson 设备上 CPU、GPU 和 EMC 的时钟行为。

...展开全部
0
更新时间 2026-09-25

自定义时钟

目的

通过编辑 Linux_for_Tegra/ 下的文件,以自定义 Jetson 目标上的 CPU、GPU 和 EMC 时钟行为。涉及两个层级:

  • 位于 Linux_for_Tegra/bootloader/ ——每个时钟 max-rate-custom 上限,以及 EMC DVFS 门控(所有 SoC 上均为 bwmgr + cactmon;仅 T26x 上的 osp-controller)。
  • 位于的 nvpower.sh 文件 Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh — cpufreq / devfreq 调节器,以及(可选)在启动时写入 sysfs 的各设备最小/最大/静态速率。

常见触发条件:“锁定 CPU/GPU/EMC 频率”、“将 GPU 固定为 Fmax”、“将 EMC 固定为 MAXN”、“禁用/启用 EMC DVFS”、“禁用/启用 CPU DVFS”、“设置 CPU/GPU 最大速率”、“更改 cpufreq 调节器”。

不在范围之内:在运行中的目标设备上进行运行时时钟调优(不涉及闪存更新)、nvpmodel 电源模式编辑(请使用同级技能 /jetson-customize-nvpmodel),以及硅上限覆盖(max-rate-maxn 为只读)。

先决条件

根据 ../../context/target-platform-contract.md。 在以下情况下拒绝并重新路由:

条件 使用以下配置拒绝:
无活动配置文件,或 active: NA 路由至 /jetson-set-target 或 /jetson-init-target.
配置文件缺少 bsp_image: 阻塞 路由至 /jetson-init-image.
/Linux_for_Tegra/ 缺失 路由至 /jetson-init-image.
/Linux_for_Tegra/ 缺失或非 Git 仓库 跳转至 /jetson-init-source.

解析路径:

  • 从 bsp_image.root_path: 若存在,否则 /Image.
  • 从 source.root_path: 若存在,否则 /Source.

对于此技能而言是只读的;每次写入 (操作 1 的 BPMP DTB 和操作 2 的 nvpower.sh) 都会被归入 (覆盖跟踪器)之下。这是工作流 不变量,在 ../../context/bsp-customization-workflow.md#workflow-invariants — 手动编辑上游会悄无声息地销毁差异记录,并导致 /jetson-promote-image 该操作无效。

操作说明

  1. 解决上述先决条件(配置文件处于活动状态、已提取 BSP 映像、源覆盖跟踪器已初始化)。
  2. 从下表中选择操作。
  3. 按照链接中的操作步骤进行——操作 1(BPMP DTB)、操作 2(nvpower.sh),或同时使用 MAXN 配方。
  4. 根据每项操作的提交约定,在覆盖跟踪器中提交编辑。
  5. 使用 /jetson-promote-image → /jetson-flash-image进行部署。新的 BPMP DTB 和 nvpower.sh 将在下次启动时生效。

支持的操作

操作 编辑位置 “操作”部分
将 CPU/GPU 时钟锁定为特定频率 BPMP DTB max-rate-custom 在时钟节点上 + nvpower.sh 调速器 performance “内容编辑: max-rate-custom" + "选择该编辑项"
将EMC锁定在其初始频率(禁用EMC DVFS) BPMP DTB: bwmgr.enabled = 0, cactmon.enabled = 0,此外 /delete-node/ osp-controller 仅限 T26x “内容编辑:禁用/启用 EMC DVFS”
重新启用 EMC DVFS BPMP DTB: bwmgr.enabled = 1, cactmon.enabled = 1,恢复 osp-controller 在 T26x 上 “内容编辑:禁用/启用 EMC DVFS”
将所有参数固定为 MAXN 以进行压力测试 将上述设置与 nvpmodel MAXN 结合作为启动默认值 参见操作指南
在不锁定的情况下降低时钟的硬上限 BPMP DTB max-rate-custom 仅 “内容编辑: max-rate-custom"
在不固定最小/最大值的情况下限制设备速率 nvpower.sh 通过 sysfs 设置最小/最大值 “选择编辑项”

操作 1 — BPMP DTB 编辑

遵循 BPMP-DTB 定制协议(详见 ../../references/bsp-customization-bpmp-dtb.md中的 BPMP-DTB 定制协议。 该协议规定了具体操作流程——首次处理时进行原始导入, dtc 反编译、重新编译、合理性检查、提交。本技能 仅提供时钟相关的特定内容(即在协议的“编辑 DTS”步骤中 应编辑哪些节点和属性)。

经过编辑的 .dtb 内容将存入 /Linux_for_Tegra/ 覆盖跟踪器中。 /jetson-promote-image的通道 A 遍历 跟踪器,并将文件复制到 bsp_image。 请勿直接编辑 /Linux_for_Tegra/bootloader/——那是推广输出,而非输入。

解析 SKU 正确的 BPMP DTB

根据协议中“解析活动 BPMP DTB”一节的说明,从 BPFDTB_FILE 从活动闪存配置中读取。对于常见的Thor / 单SKU配置结构,这对应于静态 BPFDTB_FILE=... 行 , .conf 中的静态行,其值按原样即为权威值。

对于 SKU 多路复用配置模式(Orin AGX 开发套件的配置链 会根据 board_sku/board_FAB via update_flash_args_common ——参见 ../../context/bsp-customization-software-layers.md#per-board-conf-dispatch--update_flash_args_common), 请使用 board_sku= 并 board_FAB= 从活动配置文件中, 并从 BPFDTB_FILE 分派输出中的值——而非来自 每块板的静态行 .conf。对于非多路复用的配置,静态值与分派值 一致;仅当配置链有条件地覆盖时,分派才 是强制性的 BPFDTB_FILE.

列出有效最大速率(检查)

检查运行时上限的两层——参见 references/clock-control-model.md#effective-runtime-ceiling ——在确定 max-rate-custom 值之前,需检查运行时上限的两层——参见——

检查指南(BPMP 侧反编译 + grep;nvpmodel 侧在启动默认模式下使用 awk)位于 references/bpmp-dtb-clock-edits.md#inspection-cookbook.

关于 nvpmodel 层,请参见 /jetson-customize-nvpmodel.

此步骤不会改变状态——它是确定 “内容编辑: max-rate-custom 对命名时钟节点进行编辑”步骤中的编辑内容。

内容编辑: max-rate-custom 在命名时钟节点上

在协议的“编辑 DTS”步骤中,修改 命名时钟节点内的属性——切勿 lateinit. max-rate-custom 必须严格低于时钟的硬上限(max-rate-maxn 如果 已定义,否则实时 max_rate 来自同一芯片/SKU的 运行中目标)。

DTS 编辑表单、语义以及 nvpmodel ↔ BPMP 时钟节点 映射位于 references/bpmp-dtb-clock-edits.md.

随后将控制权交还给协议——其“重新编译”、“对 重新编译后的代码块进行合理性检查”、“在覆盖跟踪器中分阶段处理”以及“清理” 步骤将处理剩余部分。 根据协议规定的提交消息规范: : jetson-customize-clocks — max-rate-custom = .

内容编辑:EMC DVFS 禁用/启用

默认行为(EMC DVFS 开启)无需编辑。禁用 EMC DVFS 是一项多节点编辑操作,需在协议的同一“编辑 DTS”步骤内 进行,而非 bwmgr 开关操作:

# 编辑 范围
1 bwmgr.enabled = <0x00> 所有 SoC,必填
2 cactmon.enabled = <0x00> 所有SoC,必选
3 /delete-node/ osp-controller T26x(Thor)为必选项 — T23x(Orin)不包含此节点,请跳过

检测: dtc -I dtb -O dts | grep -c osp-controller — 零匹配 ⇒ T23x 路径。完整的 DTS 代码片段、幸存路径 的故障模式以及重新启用流程位于 references/emc-dvfs-disable.md.

在多节点编辑就位后,执行协议中的“重新编译”至“清理”步骤 。提交信息规范: : jetson-customize-clocks — EMC DVFS disable (bwmgr + cactmon[+ osp-controller]).

禁用会增加空闲功耗;仅适用于压力/性能 测试,不适用于生产环境的根文件系统。

重跑 + 幂等性

根据协议中“可重跑性”一节的规定,使用相同目标值 重跑此技能将产生无操作提交。使用不同值 重跑将重写同一属性—— git log -- $BPMP_REL 显示每次运行的历史记录。要将时钟 恢复到其 max-rate-maxn 上限,请编辑 DTS 以删除 max-rate-custom 该行并重新编译。

操作 2 — nvpower.sh 编辑

编辑 nvpower.sh,该脚本在系统启动时通过 nvpower.service 来设置 cpufreq / devfreq 调节器及其速率。

该脚本对应的文件

本操作所编辑的脚本相对路径为:

Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh

该脚本位于两个根目录下;该操作将遍历这两个目录:

角色 位置 技能是否写入?
检测 + 原始源 /Linux_for_Tegra/rootfs/etc/systemd/ 否 — 只读
叠加编辑目标 + Git 提交 /Linux_for_Tegra/rootfs/etc/systemd/ 是

后续子步骤中提到的“脚本文件”特指覆盖层 副本,位于 。该 该副本在 下文的“原始导入”步骤中仅被读取一次,此后不再被修改。

覆盖编辑配方(在编辑 nvpower.sh 之前应用)

请遵循工作流文档中的标准 “非技能编辑”流程 ——即“原始导入”与“自定义提交”的组合,两者均 受预览门控的限制。 nvpower.sh 是一个未设置 传播集的单一文件;一个原始提交 + 一个自定义提交即可覆盖 整个变更。

针对此技能的具体替换方案:

  • / 是 rootfs/etc/systemd/nvpower.sh.
  • 建议的原始导入消息: import pristine: rootfs/etc/systemd/nvpower.sh, 正文 Source: /Linux_for_Tegra/ (BSP ).
  • 建议的自定义提交头部: jetson-customize-clocks: nvpower.sh , 正文中的行例如 set_cpufreq_governor: desired_cpufreq_gov "schedutil" -> "performance".

选择编辑

函数位置(set_cpufreq_governor, set_devfreq_governor)、常用编辑方案(固定至Fmax、静态速率、最小/最大边界),以及 nvidia-l4t-init 包升级注意事项均位于 references/nvpower-sh-edits.md.

部署

覆盖层跟踪器中的自定义提交无法 自动推送到设备。部署链:

  1. /jetson-promote-image — 将覆盖层中所有受追踪的文件 复制到 /Linux_for_Tegra/。支持差异检测(跳过 字节完全相同的文件);使用 sudo cp -p 作为 rootfs/* 目标。
  2. /jetson-flash-image — 将更新后的 bsp_image 写入 设备。 nvpower.service 在下次启动时运行新脚本。
  3. (替代方案,无需刷写)将 /Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh 直接复制到运行中的目标 /etc/systemd/nvpower.sh,然后 sudo systemctl restart nvpower.service (或重启)。

编辑 /... 而不提交——或直接编辑 /... 直接编辑)对 /jetson-promote-image ,并在下次 /jetson-init-image 重新提取时会无声无息地丢失。

操作指南 — 将所有内容固定为 MAXN 以进行压力/性能测试

结合操作 1 和 2。操作 1 的 BPMP 将所有修改 集中处理于协议的一轮循环中(单次反编译 / 多节点 编辑 / 重新编译 / 提交循环——不要为同一 .dtb):

  1. BPMP DTB(“内容编辑: max-rate-custom 在指定时钟节点上”步骤内容):保留 max-rate-custom 在每个 CPU / GPU / EMC 时钟上保持未设置;移除现有 max-rate-custom 会降低上限的现有行。
  2. BPMP DTB(“内容编辑:EMC DVFS 禁用/启用”步骤内容):将 EMC 固定在其初始速率上—— bwmgr.enabled = 0, cactmon.enabled = 0,外加 /delete-node/ osp-controller 在 T26x 上(在 T23x 上跳过)。
  3. 将这两项内容编辑应用到一个“编辑 DTS”协议调用中,然后运行剩余的协议步骤(重新编译、合理性检查、涵盖这两项内容编辑的单次自定义提交)。
  4. nvpower.sh(操作 2):设置 desired_cpufreq_gov="performance" 并 desired_devfreq_gov="performance" 无条件地;移除 set_devfreq_governor中移除针对 GPU/nvjpg 的跳过设置。通过操作 2 的覆盖编辑配方(“覆盖编辑配方(在编辑 nvpower.sh 之前应用)”步骤)应用——在 rootfs 脚本上进行一个独立的覆盖跟踪器原始状态 + 定制提交对,这与 BPMP-DTB 协议的提交不同。
  5. 通过 /jetson-customize-nvpmodel ——每时钟周期 nvpmodel 上限钳位在 max-rate-maxn ,无论 BPMP DTB 内容如何。

部署 /jetson-promote-image → /jetson-flash-image 会(通过覆盖层跟踪器)获取新的 BPMP DTB 以及已编辑的 nvpower.sh (通过同一覆盖跟踪器)在下次闪存操作中生效。

限制

  • 仅限镜像构建时。所有编辑内容均位于 /Linux_for_Tegra/ ,且仅通过 /jetson-promote-image → /jetson-flash-image。实时目标调试不在本范围之内。
  • max-rate-custom 仅会降低上限。该值必须严格小于 max-rate-maxn;不支持提高硅片上限。
  • 有效上限分为两层。运行时上限为 min(BPMP cap, active-nvpmodel-mode cap)。nvpmodel 上限由 /jetson-customize-nvpmodel;本技能不会对其进行修改。
  • SoC 条件 EMC DVFS 门。禁用 EMC DVFS 需要在 T23x(bwmgr + cactmon)和 T26x(bwmgr + cactmon + delete osp-controller)。检测错误会导致未定义行为。
  • T23x的GPU上限为多节点。GPU时钟分布在 nafll_gpusys ,且每个 nafll_gpcX;该上限仅在应用于所有节点时才生效。
  • nvpower.sh 由软件包管理。它随 nvidia-l4t-init;包升级会覆盖就地编辑。长期运行的配置应优先选用 systemd 即插即用方案或同类辅助工具。
  • ODMDATA 具有优先权。当 ODMDATA 令牌覆盖某个属性时,该令牌会在闪存写入时覆盖直接的 BPMP DTS 编辑。直接的 BPMP DTS 编辑是针对未被 NVIDIA 令牌覆盖的属性的备用方案。
  • max-rate-maxn 以及lateinit均不可用。 max-rate-maxn 是芯片级上限(只读)。 lateinit 用于启动时时钟初始化,而非上限覆盖——切勿修改二者。
  • BPMP DTB 可能采用 SKU 多路复用。在复合/分发式闪存配置中(Orin AGX 开发套件链), BPFDTB_FILE 由 board_sku / board_FAB 通过 update_flash_args_common。当链路条件性地覆盖该设置时,读取静态 BPFDTB_FILE= 行是错误的;应通过分派机制进行解决。

故障排除

错误 原因 解决方案
max-rate-custom 已设置,但时钟仍会升至 max-rate-maxn T23x GPU 仅 nafll_gpusys 被限制; nafll_gpcX 分区仍以 max-rate-maxn ,并占据了有效上限。 应用相同的 max-rate-custom 到 nafll_gpusys ,并遍历所有 nafll_gpcX 由 grep -nE '^\s*nafll_gpc[0-9]+\s*:' .
EMC DVFS禁用似乎已生效,但EMC在T26x上仍会进行扩展 仅 bwmgr.enabled = <0x00> 被设置; osp-controller 该设置得以保留,并通过QoS路径重新发出频率变更指令。 添加编辑 #2 (cactmon.enabled = <0x00>) 和 #3 (/delete-node/ osp-controller) 添加到同一“编辑 DTS”步骤中。验证 osp-controller 通过 dtc -I dtb -O dts | grep -c osp-controller → 预期结果为 0。
在 T23x 上禁用 EMC DVFS 被拒绝,且针对 osp-controller T23x (Orin) BPMP DTB中不包含 osp-controller;在 T23x 上必须跳过编辑 #3。 使用 grep -c osp-controller 步骤检测SoC系列;仅当计数≥1时才应用第3步。
编辑后,BPMP 拒绝加载 DTB: max-rate-custom >= max-rate-maxn max-rate-custom 被设置为等于或高于硅上限。 降低 max-rate-custom 严格低于 max-rate-maxn。如果 max-rate-maxn 该节点中不存在该参数,请查询正在运行的目标上的实时上限: cat /sys/kernel/debug/bpmp/debug/clk//max_rate.
osp-controller 在 status = "disabled" status = "disabled" 不会将该节点从设备树中移除;BPMP 仍会遍历该节点。 用以下内容替换 /delete-node/ osp-controller; ——该节点必须不存在,BPMP 才会跳过该路径。
对 nvpower.sh 丢失后 apt upgrade nvpower.sh 归属 nvidia-l4t-init deb 包所有,并在升级时被覆盖。 对于长期运行的测试环境,请将包的编辑内容打包到 systemd 即插即用包中,或写入由 nvpower.sh,而非直接编辑 nvpower.sh 直接编辑该文件。
/jetson-promote-image 在编辑 BPMP DTB 之后,该操作将不产生任何效果 该编辑已应用到 /Linux_for_Tegra/,该文件 /jetson-promote-image的输出——而非其输入。 将该修改移至 /Linux_for_Tegra/bootloader/ (叠加追踪器),并通过 BPMP-DTB 协议提交。
上限值似乎在首次启动时生效,但在电源模式变更后会重置 当前活动的 nvpmodel 模式的每时钟周期上限被限制在 max-rate-custom. 检查两层;如果 nvpmodel 已绑定,请通过 /jetson-customize-nvpmodel。仅靠 BPMP 上限并不能作为运行时上限。

参考资料

  • ../../references/bsp-customization-bpmp-dtb.md — 标准 BPMP-DTB 定制协议(原始导入、反编译、编辑、重新编译、合理性检查、提交)。该技能的操作 1 仅为内容消费者;协议本身负责具体机制。
  • references/clock-control-model.md — 层堆栈、双上限概述、有效运行时上限公式。
  • references/bpmp-dtb-clock-edits.md — 双上限语义、DTS编辑表单、nvpmodel ↔ BPMP时钟节点映射、检查指南。
  • references/emc-dvfs-disable.md — 完整的 SoC 条件 EMC DVFS 禁用流程(含 DTS 代码片段)、检测及重新启用。
  • references/nvpower-sh-edits.md — nvpower.sh 函数位置 + 通用编辑方案 + 软件包升级注意事项。
  • /jetson-customize-nvpmodel — 相关技能:nvpmodel 功耗模式。活动模式的每时钟周期上限被限制在 BPMP DTB 上限之下。
在 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.

安装 jetson-customize-clocks

下载技能文件并将其解压到 .claude/skills/ 目录中。

下载ZIP

克隆仓库并复制技能文件到您的项目中。

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

复制 复制
快速设置: 将技能文件夹复制到 .claude/skills/ Claude 将自动检测并使用该技能
仓库 NVIDIA/skills

相关技能

Verification &amp; Quality Assurance
更新时间 2026-06-29
klingai-upgrade-migration
更新时间 2026-07-03
base44-cli
更新时间 2026-06-29
Railway CLI Management
更新时间 2026-07-02
OR