This is an old revision of the document!
Table of Contents
DDR Frequency Switching on RK3588 (LPDDR5)
This page documents how to change the DDR frequency on RK3588 platforms (as shipped by the rkbin DDR init blob) and records the observed LPDDR5-6400 / 3200 MHz operation on ampere (CoolPi CM5 GenBook, 32 GB LPDDR5).
Source material: the public
DDR_FREQUENCY_TABLE.md
in the rk3588-ddr-analysis repo. Reverse-engineered DFS entry point
is tracked in the memory note project_rk3588_ddr_dfs_entry.md.
<WRAP round important>
Flashing a bad DDR blob bricks boot. Recovery requires putting the
board into maskrom mode and reflashing over USB. Always keep a known-good
blob image handy before experimenting. A dedicated MASKROM recovery page does
not yet exist on this wiki — TODO: create megabitchip:maskrom_recovery.
</WRAP>
1. Stock frequencies per rkbin version
Official Rockchip blobs
| Version | LP4 Freq | LP5 Freq | LP5 Data Rate | LP5 BW/ch | Status |
|---|---|---|---|---|---|
| v1.09 | 2112 MHz | 2736 MHz | 5472 MT/s | 10.9 GB/s | Oldest available |
| v1.10–v1.14 | 2112 MHz | 2736 MHz | 5472 MT/s | 10.9 GB/s | Iterative fixes |
| v1.15 | 2112 MHz | 2736 MHz | 5472 MT/s | 10.9 GB/s | Last 2736 blob |
| v1.16 | 2112 MHz | 2400 MHz | 4800 MT/s | 9.6 GB/s | 2736 dropped |
| v1.17–v1.19 | 2112 MHz | 2400 MHz | 4800 MT/s | 9.6 GB/s | Current |
| v1.19 (cons.) | 1848 MHz | 2112 MHz | 4224 MT/s | 8.4 GB/s | Conservative |
Community-achieved (rkddr / DT overlay)
| LP5 Freq | Data Rate | BW/ch | Source | Stability |
|---|---|---|---|---|
| 2112 MHz | 4224 MT/s | 8.4 GB/s | Official conservative | Rock solid |
| 2400 MHz | 4800 MT/s | 9.6 GB/s | Official default | Stable |
| 2736 MHz | 5472 MT/s | 10.9 GB/s | Old official (v1.15) | Dropped by Rockchip |
| 3200 MHz | 6400 MT/s | 12.8 GB/s | Community (hbiyik rkddr) | Works with SK Hynix rated modules |
2. How to switch — four mechanisms, increasing risk
2.1 Swap the whole rkbin blob version (lowest risk)
The simplest approach: pick a pre-built blob and use it verbatim.
- v1.09 – v1.15 → 2736 MHz LP5
- v1.16+ → 2400 MHz LP5
- v1.19 conservative → 2112 MHz LP5
Drop the chosen rk3588_ddr_*.bin into rkbin/bin/rk35/ and rebuild
idbloader.img. No byte-level editing needed.
2.2 ''rkddr'' TUI (hbiyik)
https://github.com/hbiyik/rkddr — a TUI that edits DDR blob parameters (frequency, ODT, drive strength) directly on the board and writes the modified blob back into the IDB (eMMC / SPI flash). This is the documented path to the 3200 MHz community setting.
2.3 ''ddrbin_tool'' (Rockchip official)
Shipped in rkbin/tools/. Official configurator for frequency, channel
config, ODT, drive strength. Operates on a blob file before flashing.
2.4 Manual byte patch (highest risk)
The code is identical across all frequency variants — only timing parameter bytes differ.
LP5 timing word, 32-bit little-endian:
| LP5 Frequency | Timing Value | Blob Offset |
|---|---|---|
| 2112 MHz | 0x00216840 | 0x11BF4 (v1.19) |
| 2400 MHz | 0x00216960 | 0x11BF4 (v1.19) |
| 2736 MHz | 0x00210AB0 | 0x10F64 (v1.15) |
LP4 timing word:
| LP4 Frequency | Timing Value | Blob Offset |
|---|---|---|
| 1848 MHz | 0x00210738 | 0x11B8C (v1.19) |
| 2112 MHz | 0x00210840 | 0x11B8C (v1.19) |
Six bytes in the data section — get them wrong and the board does not complete DDR training.
3. DVFS entry point
The TPL blob trains six frequency steps (main + five alternatives) and
writes the pre-trained results to PMU GRF OS registers for the Linux
side to consume. Runtime DDR frequency transitions (DVFS) are dispatched
through the vector at blob+0x34 → FUN_10978, invoked by the M0
coprocessor under BL31 on a DVFS event.
Caveat on ampere: the current mainline kernel on ampere has no DMC
devfreq driver wired, so FUN_10978 is dormant at runtime —
whatever frequency the blob sets at boot is the steady-state frequency.
Backlink: memory note project_rk3588_ddr_dfs_entry.md.
4. Observed 3200 MHz operation (ampere)
<WRAP round tip> User-reported state from Markus, not a machine-probed capture. The machine is offline at the time of writing; bench readouts below are placeholders to be filled on the next bench-on session. </WRAP>
Setup: ampere (CoolPi CM5 GenBook, RK3588, 32 GB LPDDR5). The blob was
reconfigured via the community rkddr TUI to LPDDR5-6400 (3200 MHz
clock, 6400 MT/s, ~12.8 GB/s per channel). Ampere boots and runs in
steady daily use at this setting.
Why it works: LPDDR5-6400 is the JEDEC ceiling for LPDDR5 (LPDDR5X
extends beyond but is not populated on RK3588). Ampere's DRAM is SK Hynix
LPDDR5, rated for the 6400 MT/s grade per JEDEC. The combination of
(a) rated modules and (b) community-tuned timings from rkddr is the
documented path to this clock.
To flesh out next bench session
- Exact DRAM part number —
sudo dmidecode -t memory(or decode the SPD/JEDEC ID from DT if dmidecode is sparse on this platform). dmesg | grep -iE “ddr|dram|lpddr”at boot —[dmesg: pending bench-on session]cat /sys/bus/platform/drivers/rockchip-dmc/dmc/devfreq/dmc/available_frequencies—[pending; may return ENOENT since DMC devfreq is not wired on mainline]…/devfreq/dmc/cur_freqreadback —[pending]stressapptestruntime hours at 3200 MHz —[pending]
5. Safety notes
- Flashing a bad DDR blob bricks boot. Recovery = maskrom + USB reflash of
idbloader.img. Keep the previous workingidbloader.imgon a USB stick. - Thermals matter. 3200 MHz LP5 raises per-channel bandwidth ~33 % over the 2400 MHz default; check SoC/DRAM temps under sustained load before calling it stable.
- SK Hynix vs. Samsung vs. Micron. SK Hynix LPDDR5 is rated 6400 MT/s; Samsung varies (5500–6400); Micron typically caps at 5500. Do not blindly apply ampere's settings to a different board without checking the module.
- Mainline kernel has no DMC devfreq on ampere — so there is no runtime safety net that drops to a lower step if the high-frequency step becomes unstable. The boot frequency is the only frequency.
See also
- rk3588-ddr-analysis repo — the analysis this page summarises
- hbiyik/rkddr — community TUI for DDR blob parameters
- TODO:
megabitchip:maskrom_recovery(not yet created) — recovery procedure when a bad blob blocks boot
