zzby0 opened a new pull request, #19741:
URL: https://github.com/apache/nuttx/pull/19741

   ## Summary
   
   This PR introduces a **device frequency scaling (devfreq) framework** for
   NuttX, providing generic dynamic voltage and frequency scaling (DVFS)
   infrastructure for any clock-scalable device (CPU, GPU, memory bus, DSP, 
etc.).
   
   Unlike a single system-wide CPU policy, devfreq manages any number of
   independent devices, each registered by name with its own frequency table and
   governor.
   
   **Architecture** — the framework separates policy from mechanism:
   
   - A **lower half** (`struct devfreq_driver_s`) is provided by the platform: 
an
     ascending frequency table plus `target_index`/`get_frequency` callbacks. 
The
     lower half is only ever told "go to table entry N".
   - Two independent forces resolve the frequency:
     - **QoS requests** — each requester installs a `[min, max]` window; the
       framework aggregates all windows (highest `min`, lowest `max`) into a 
single
       clamp. When windows do not intersect, the driver's `conflict_policy`
       (`PREFER_HIGH` / `PREFER_LOW`) decides the winner.
     - **Governors** — `performance` (top of window), `powersave` (bottom of
       window), and `ondemand` (load-driven scaling).
   - The resolved frequency is snapped to a real table entry and applied through
     the lower half.
   
   **Components:**
   
   - Core framework (`drivers/devfreq/devfreq.c`) — registration, table
     validation, QoS resolution, governor dispatch, suspend/resume, change
     notifier chain.
   - Governors: `performance`, `powersave`, `ondemand`.
   - QoS constraint engine (`devfreq_qos.c`) built on a priority-sorted list
     (`include/nuttx/plist.h`).
   - procfs interface (`/proc/devfreq/<name>`) — read frequency table / current
     frequency / governor / QoS list; write to install a frequency constraint
     from user space.
   - Public API (`include/nuttx/devfreq.h`) and documentation
     (`Documentation/.../special/devfreq.rst`).
   
   ## Impact
   
   - **New feature**: adds the devfreq framework. Entirely opt-in — gated behind
     `CONFIG_DEVFREQ` (default `n`); no effect on existing configurations.
   - **Build**: new `drivers/devfreq/` subsystem wired into `drivers/Kconfig`,
     `drivers/Makefile`, and `CMakeLists.txt`.
   - **User space**: when `CONFIG_DEVFREQ_PROCFS` is set, exposes
     `/proc/devfreq/<name>` (read status/table, write `<min> <max>` in kHz to
     constrain, `0 0` to clear). Requires `CONFIG_FS_PROCFS`; auto-selects
     `CONFIG_FS_PROCFS_REGISTER`.
   - **New config options**: `CONFIG_DEVFREQ`, `CONFIG_DEVFREQ_PROCFS`,
     `CONFIG_DEVFREQ_PROCFS_QOS`, `CONFIG_DEVFREQ_GOV_ONDEMAND`,
     `CONFIG_DEVFREQ_SAMPLE_RATE`, `CONFIG_DEVFREQ_LOAD_THRESHOLD`.
   - **New header**: `include/nuttx/plist.h` (priority-sorted list, 
header-only),
     a dependency of the QoS engine.
   - **Hardware**: no impact unless a platform registers a lower-half driver.
   - **Documentation**: new page under
     `Documentation/components/drivers/special/`.
   - **Compatibility**: no changes to existing APIs; no regressions expected.
   
   ## Testing
   
   ### Host & Targets
   
   | Item          | Detail                                                    |
   | ------------- | --------------------------------------------------------- |
   | Host OS       | Linux x86_64 (Ubuntu)                                     |
   | Toolchains    | host `gcc` 13.4.0 (sim), `arm-none-eabi-gcc` 10.3.1 (arm) |
   | NuttX / apps  | apache/master                                             |
   | Real hardware | BES2800bp, ARMv8-M Cortex-M55                             |
   
   `tools/checkpatch.sh` passes on all commits.
   
   ### Build Verification
   
   | Arch          | Config             | devfreq options              | Result 
                  |
   | ------------- | ------------------ | ---------------------------- | 
------------------------ |
   | sim (x86_64)  | `sim:nsh`          | DEVFREQ + PROCFS + PROCFS_QOS | `LD 
nuttx` OK, 0 warnings |
   | arm (Cortex-A7) | `qemu-armv7a:nsh` | DEVFREQ + PROCFS + PROCFS_QOS | `LD 
nuttx` OK, 0 warnings |
   
   ### Runtime Functional Test — Simulator
   
   A temporary dummy lower-half driver (table `200000 400000 600000 800000` kHz)
   was registered as `/proc/devfreq/test` to exercise the framework end to end
   (scaffolding removed after testing).
   
   **performance governor** (selects the top of the resolved window):
   
   ```
   nsh> cat /proc/devfreq/test
    governor:    performance
    cur_freq:    800000
    freq_table:  200000 400000 600000 800000
   
   nsh> echo '0 400000'      > /proc/devfreq/test   # cap: max=400000
   test_devfreq: target_index=1 freq=400000         # -> cur_freq 400000
   
   nsh> echo '600000 800000' > /proc/devfreq/test   # floor honoured
   test_devfreq: target_index=3 freq=800000         # -> cur_freq 800000
   
   nsh> echo '200000 600000' > /proc/devfreq/test   # window [200000,600000]
   test_devfreq: target_index=2 freq=600000         # -> top-in-window 600000
   
   nsh> echo '0 0'           > /proc/devfreq/test   # clear QoS
   test_devfreq: target_index=3 freq=800000         # -> restores 800000
   
   nsh> echo '800000 200000' > /proc/devfreq/test   # invalid min>max
                                                    # -> write returns -EINVAL, 
no change
   ```
   
   **powersave governor** (selects the bottom of the resolved window):
   
   ```
   nsh> cat /proc/devfreq/test
   test_devfreq: target_index=0 freq=200000         # default -> lowest 200000
    governor:    powersave
    cur_freq:    200000
   
   nsh> echo '400000 800000' > /proc/devfreq/test   # window [400000,800000]
   test_devfreq: target_index=1 freq=400000         # -> bottom-in-window 400000
   ```
   
   ### Runtime Functional Test — Real Hardware (BES2800bp, Cortex-M55)
   
   The framework was also validated on real silicon driving the CPU clock 
through
   a platform CPU devfreq lower half (`/proc/devfreq/cpu`, table
   `32 26000 52000 104000 208000 320000` kHz, performance governor). The 
lower-half
   CPU driver is board/downstream code and is not part of this PR.
   
   **Scenario 1 — Concurrent QoS requests with conflicting windows.**
   Two requests are installed: one caps at `208000`, another pins
   `[320000, 320000]`. The windows do not intersect (aggregate min `320000` >
   aggregate max `208000`), so the driver's `conflict_policy` resolves it — here
   the higher frequency wins and the CPU runs at 320 MHz:
   
   ```
   ap> cat /proc/devfreq/cpu
    devfreq:     cpu
    governor:    performance
    cur_freq:    320000
    suspended:   False
    freq_table:  32 26000 52000 104000 208000 320000
    qos_list(min, max, backtrace):
    0, 208000,
    320000, 320000,
   ```
   
   **Scenario 2 — Updating a QoS request re-resolves and changes the real 
clock.**
   The `[320000, 320000]` request is updated to `[208000, 208000]` via procfs. 
The
   windows now intersect at `208000`, and the CPU frequency drops to 208 MHz on
   hardware:
   
   ```
   ap> echo "208000 208000" > /proc/devfreq/cpu
   
   ap> cat /proc/devfreq/cpu
    devfreq:     cpu
    governor:    performance
    cur_freq:    208000
    suspended:   False
    freq_table:  32 26000 52000 104000 208000 320000
    qos_list(min, max, backtrace):
    0, 208000,
    208000, 208000,
   ```
   
   ### Coverage Summary
   
   Verified across simulator and hardware: device registration, procfs 
read/write,
   QoS `[min, max]` aggregation (upper cap and lower floor), multi-requester
   conflict resolution via `conflict_policy`, governor selection (performance =
   top-of-window, powersave = bottom-of-window), QoS clear, invalid-input
   rejection, and lower-half `target_index` / `get_frequency` invocation with a
   real frequency change on Cortex-M55.
   
   ### Documentation
   
   `Documentation/components/drivers/special/devfreq.rst` renders correctly via
   `make html`.
   
   ### Notes
   
   All temporary test scaffolding (the sim dummy driver) was reverted after
   testing and is not part of this PR.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to