Skip to content

RK3566: add DDR devfreq driver#2423

Open
aenertia wants to merge 1 commit intoROCKNIX:nextfrom
aenertia:nert-next/rk3566-dmc
Open

RK3566: add DDR devfreq driver#2423
aenertia wants to merge 1 commit intoROCKNIX:nextfrom
aenertia:nert-next/rk3566-dmc

Conversation

@aenertia
Copy link
Copy Markdown
Contributor

@aenertia aenertia commented Mar 14, 2026

RK3566: add DDR devfreq driver for RK356x
Add dynamic DDR frequency scaling (devfreq) for all RK3566/RK3568
devices. The DMC driver reads DDR utilization from the DFI hardware
monitor and adjusts memory frequency via ATF shared-memory commands,
reducing idle power draw while scaling up under load.

Depends on: nert-next/rkbin-bump (BL31 v1.45) #2425

Kernel patches:
1011 — DFI devfreq-event: PM suspend/resume ops for DDRMON
1012 — rk3568-dmc devfreq driver (BSP V2 SIP, MCU-based DCF)
1013 — DMC node + OPP table in rk356x-base.dtsi
OPPs: 324/528/780/920/1056 MHz (ATF disables untrained)
1014 — Enable DMC on Anbernic RGxx3 (Generic)
1015 — Enable DMC on Powkiddy X55
1016 — CPU energy model (cpu1-3) + thermal sustainable-power
1017 — Enable DMC on Powkiddy RK2023 (shared with RG353 boards)

Device tree (ROCKNIX-maintained):

  • rk3568-anbernic-rg-ds.dts: DMC enable with center-supply

Kernel config:

  • CONFIG_ARM_RK3568_DMC_DEVFREQ=y
  • CONFIG_CPU_IDLE_GOV_TEO=y

Platform quirk (010-governors):

  • Export DMC_FREQ sysfs path for frequency scripts
  • Activate TEO CPU idle governor at boot

Coverage: all 14 RK3566/RK3568 device DTBs via rk356x-base.dtsi
shared nodes. Per-board patches enable DMC where center-supply is
defined. 920 MHz OPP added for RK3568 boards (e.g. RGDS) where ATF
trains FSPs that differ from the standard RK3566 set.

Power Impact: dev (no DMC) vs dmc — R analysis

All data from FNB58 USB-PD inline power meter, paired measurements.

CPU Power at Stock Voltage (performance gov, W)

CPU MHz dev dmc Delta
408 2.556 2.580 +0.024
600 2.738 2.758 +0.020
816 2.932 2.953 +0.021
1104 3.756 3.740 -0.016
1416 5.149 5.153 +0.005
1608 6.553 6.920 +0.367

Paired t-test (n=6): mean diff -0.070W, p=0.293
Result: NOT SIGNIFICANT — DMC is power-neutral for CPU workloads.

CPU Power at UV-L3 (performance gov, W)

CPU MHz dev dmc Delta
408 2.438 2.431 -0.006
600 2.599 2.607 +0.007
816 2.778 2.786 +0.008
1104 3.195 3.184 -0.011
1416 3.484 3.467 -0.017
1608 3.784 3.751 -0.033
1800 4.069 4.027 -0.042

Paired t-test (n=7): mean diff +0.014W, p=0.109
Result: NOT SIGNIFICANT — all deltas within ±1%.

7z LZMA (RGDS, 4 threads)

Governor Compress MIPS Decompress MIPS
performance 1217 4125
ondemand 1212 4187
schedutil 1207 4183

All governors within <1% — DMC does not degrade throughput.

TEO + DMC Final Statistics (RGDS)

cpu-sleep entries: 96,014
cpu-sleep total time: 133.2 seconds
DMC total transitions: 544
DMC time at 920 MHz under load: 989s

Tested on RG353P (Generic) and RGDS (Specific):

  • DMC active with simple_ondemand, 50ms polling
  • DDR scales 324↔528↔920 MHz under load (RGDS)
  • DDR scales 324↔528↔780↔1056 MHz under load (RG353P)
  • TEO idle governor active, cpu-sleep state registered
  • Zero GPU PM warnings

Thanks to zetarancio for the initial DMC patchset that informed this
work. Thanks to sydarn for testing and review feedback, and to
macromorgan (Chris Morgan) for the idle-states DTS patch (1001) and
RGDS DDR timing data that identified the 920 MHz FSP.

@aenertia
Copy link
Copy Markdown
Contributor Author

@sydarn
Copy link
Copy Markdown
Contributor

sydarn commented Mar 14, 2026

Please split out rkbin update in a separate PR.

Add dynamic DDR frequency scaling (devfreq) for all RK3566/RK3568
devices. The DMC driver reads DDR utilization from the DFI hardware
monitor and adjusts memory frequency via ATF shared-memory commands,
reducing idle power draw while scaling up under load.

Depends on: nert-next/rkbin-bump (BL31 v1.45)

Kernel patches:
  1011 — DFI devfreq-event: PM suspend/resume ops for DDRMON
  1012 — rk3568-dmc devfreq driver (BSP V2 SIP, MCU-based DCF)
  1013 — DMC node + OPP table in rk356x-base.dtsi
         OPPs: 324/528/780/920/1056 MHz (ATF disables untrained)
  1014 — Enable DMC on Anbernic RGxx3 (Generic)
  1015 — Enable DMC on Powkiddy X55
  1016 — CPU energy model (cpu1-3) + thermal sustainable-power
  1017 — Enable DMC on Powkiddy RK2023 (shared with RG353 boards)

Device tree (ROCKNIX-maintained):
  - rk3568-anbernic-rg-ds.dts: DMC enable with center-supply

Kernel config:
  - CONFIG_ARM_RK3568_DMC_DEVFREQ=y
  - CONFIG_CPU_IDLE_GOV_TEO=y

Platform quirk (010-governors):
  - Export DMC_FREQ sysfs path for frequency scripts
  - Activate TEO CPU idle governor at boot

Coverage: all 14 RK3566/RK3568 device DTBs via rk356x-base.dtsi
shared nodes. Per-board patches enable DMC where center-supply is
defined. 920 MHz OPP added for RK3568 boards (e.g. RGDS) where ATF
trains FSPs that differ from the standard RK3566 set.

## Power Impact: dev (no DMC) vs dmc — R analysis

All data from FNB58 USB-PD inline power meter, paired measurements.

### CPU Power at Stock Voltage (performance gov, W)

| CPU MHz | dev    | dmc    | Delta   |
|---------|--------|--------|---------|
| 408     | 2.556  | 2.580  | +0.024  |
| 600     | 2.738  | 2.758  | +0.020  |
| 816     | 2.932  | 2.953  | +0.021  |
| 1104    | 3.756  | 3.740  | -0.016  |
| 1416    | 5.149  | 5.153  | +0.005  |
| 1608    | 6.553  | 6.920  | +0.367  |

Paired t-test (n=6): mean diff -0.070W, p=0.293
Result: NOT SIGNIFICANT — DMC is power-neutral for CPU workloads.

### CPU Power at UV-L3 (performance gov, W)

| CPU MHz | dev    | dmc    | Delta   |
|---------|--------|--------|---------|
| 408     | 2.438  | 2.431  | -0.006  |
| 600     | 2.599  | 2.607  | +0.007  |
| 816     | 2.778  | 2.786  | +0.008  |
| 1104    | 3.195  | 3.184  | -0.011  |
| 1416    | 3.484  | 3.467  | -0.017  |
| 1608    | 3.784  | 3.751  | -0.033  |
| 1800    | 4.069  | 4.027  | -0.042  |

Paired t-test (n=7): mean diff +0.014W, p=0.109
Result: NOT SIGNIFICANT — all deltas within ±1%.

### 7z LZMA (RGDS, 4 threads)

| Governor    | Compress MIPS | Decompress MIPS |
|-------------|---------------|-----------------|
| performance | 1217          | 4125            |
| ondemand    | 1212          | 4187            |
| schedutil   | 1207          | 4183            |

All governors within <1% — DMC does not degrade throughput.

### TEO + DMC Final Statistics (RGDS)

  cpu-sleep entries: 96,014
  cpu-sleep total time: 133.2 seconds
  DMC total transitions: 544
  DMC time at 920 MHz under load: 989s

Tested on RG353P (Generic) and RGDS (Specific):
  - DMC active with simple_ondemand, 50ms polling
  - DDR scales 324↔528↔920 MHz under load (RGDS)
  - DDR scales 324↔528↔780↔1056 MHz under load (RG353P)
  - TEO idle governor active, cpu-sleep state registered
  - Zero GPU PM warnings

Thanks to zetarancio for the initial DMC patchset that informed this
work. Thanks to sydarn for testing and review feedback, and to
macromorgan (Chris Morgan) for the idle-states DTS patch (1001) and
RGDS DDR timing data that identified the 920 MHz FSP.
@aenertia aenertia force-pushed the nert-next/rk3566-dmc branch from f6c27bd to da4b8d7 Compare March 14, 2026 11:42
aenertia added a commit to aenertia/distribution that referenced this pull request Mar 14, 2026
  - rkbin bumped to ef49d0c2 (fixes ddrbin_tool → ddrbin_tool.py)
  - BL31 v1.44 → v1.45 for both Generic and Specific images

BL31 v1.45 is a safe upgrade validated on RG353P (Generic) and
RGDS (Specific). Required for DMC devfreq support (PR ROCKNIX#2423).
@aenertia
Copy link
Copy Markdown
Contributor Author

@aenertia aenertia changed the title RK3566: add DDR devfreq driver and bump BL31 firmware RK3566: add DDR devfreq driver Mar 14, 2026
aenertia added a commit to aenertia/distribution that referenced this pull request Mar 15, 2026
Bump rkbin to ef49d0c2 for RK3566 only (fixes ddrbin_tool →
ddrbin_tool.py rename). Other devices keep the existing version
(7c35e21a) to avoid breaking blob references (e.g. RK3588
rk3588_bl31_v1.47.elf does not exist in the newer rkbin).

BL31 v1.44 → v1.45 for both Generic and Specific u-boot images.
BL31 v1.45 validated on RG353P (Generic) and RGDS (Specific).
Required for DMC devfreq support (PR ROCKNIX#2423).

post_unpack() auto-detects whether ddrbin_tool is a Python script
(.py) or native binary, supporting both rkbin versions for the
RK3326 UART5 TPL tuning.
@aenertia
Copy link
Copy Markdown
Contributor Author

Can we get this merged? I have been running this for several weeks now with 6.18/6.19 and 7.0-rc4 kernels and it's working as expected on all three devices I have tested without any problems. Ideally this needs a schedutils/teo switch in default scheduler to really shine. But I see no reason why it can't be merged by itself. Perf govts peg both to max and it's the current state of per emu govts anyway in -next so potential for regression is minimal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants