User Tools

Site Tools


megabitchip:pinetab2_ddr

DDR Frequency Switching on PineTab2 / RK3566 (LPDDR4)

This page documents how to change the DDR frequency on the Pine64 PineTab2 v2.0 (Rockchip RK3566, 8 GB LPDDR4 as 2x 4 GB) by swapping the rkbin TPL DDR-init blob, and records the production-stable 1332 MT/s operation observed on ohm (mfritsche's PineTab2 v2.0).

Sibling page: DDR frequency switching on RK3588 (LPDDR5) — same methodology framework, RK3588-/LPDDR5-specific blobs and offsets. Read both if you are working across the family.

<WRAP round important> Flashing a bad DDR blob bricks boot. Recovery requires either booting from an SD card with a known-good idbloader.img (PineTab2 boots SD before eMMC) or putting the tablet into MASKROM mode and reflashing over USB from a host machine. A dedicated MASKROM-recovery page does not yet exist on this wiki — TODO: create megabitchip:maskrom_recovery (both the RK3588 and RK3566/PineTab2 mechanisms differ — PineTab2 has a dedicated MASKROM hardware switch, unlike the PinePhone and earlier Pine64 devices which rely on shorting a flash pin). </WRAP>

1. Stock and observed frequencies

Stock

The danctnix uboot-pinetab2 package (version 2026.04-4 at time of writing) ships with rk3566_ddr_1056MHz_v1.23.bin:

Blob DPLL Data Rate BW/ch Status
rk3566_ddr_1056MHz_v1.23.bin 528 MHz 1056 MT/s ~4.2 GB/s danctnix default

Verified upgrade

Blob DPLL Data Rate BW/ch Status
rk3568_ddr_1332MHz_v1.23.bin 666 MHz 1332 MT/s ~5.3 GB/s VERIFIED stable on ohm

+26 % memory bandwidth vs. stock, currently running on ohm. Validation: 50+ minutes of memtester 4G 1 with all 10+ completed patterns clean (Stuck Address, Random Value, Compare XOR/SUB/MUL/DIV/OR/AND, Sequential Increment, Solid Bits, partial Block Sequential), no EDAC / MCE / kernel panic in dmesg.

Hardware ceiling

1332 MT/s is the documented ceiling for this silicon. Both rk3568_ddr_1560MHz_v1.23.bin and rk3568_ddr_1560MHz_D4_LP4_4x_eyescan_v1.23.bin were tested with structurally-validated SPL packaging (see §4) and do not train on RK3566 — ohm fails to boot, no recovery without MASKROM. Do not waste a session on 1560.

2. Available rkbin v1.23 blobs for RK3566

From ~/src/rkbin/bin/rk35/ on ohm (and on a clone of rockchip-linux/rkbin):

Blob Rate Notes
rk3566_ddr_528MHz_ultra_v1.10.bin 528 MT/s very low
rk3566_ddr_780MHz_ultra_v1.10.bin 780 MT/s low
rk3566_ddr_920MHz_ultra_v1.10.bin 920 MT/s older
rk3566_ddr_920MHz_v1.23.bin 920 MT/s v1.23 conservative
rk3566_ddr_1056MHz_ultra_v1.20.bin 1056 MT/s alt
rk3566_ddr_1056MHz_v1.23.bin 1056 MT/s danctnix default
rk3568_ddr_920MHz_v1.23.bin 920 MT/s RK3568 cross-blob, works on RK3566
rk3568_ddr_1056MHz_v1.23.bin 1056 MT/s RK3568 cross-blob
rk3568_ddr_1332MHz_v1.23.bin 1332 MT/s VERIFIED on PineTab2 — recommended
rk3568_ddr_1560MHz_v1.23.bin 1560 MT/s does NOT train on RK3566 silicon
rk3568_ddr_1560MHz_D4_LP4_4x_eyescan_v1.23.bin 1560 MT/s does NOT train (eyescan variant tried)

The rk3568_ blobs work on RK3566 because the two SoCs share their DDR controller IP; the rkbin RK3568 toolchain happens to ship the higher frequency points the RK3566 line does not.

3. Build recipe (mkimage -T rksd)

The danctnix idbloader.img is a Rockchip RKSD container with two parts: the DDR init blob (TPL, 4 KB scrambled header + payload) and the SPL (U-Boot SPL stage). To switch frequency, repack the same SPL with a different DDR blob.

DDR=~/src/rkbin/bin/rk35/rk3568_ddr_1332MHz_v1.23.bin   # or 1056/920/780/528 etc.
SPL=~/ohm-recovery/uboot-spl-correct.bin                # extracted from danctnix
                                                        # idbloader.img with skip=61440
mkimage -n rk3568 -T rksd -d $DDR:$SPL \
        ~/ohm-recovery/idbloader-1332-FIXED.img

The -n rk3568 name argument is correct even on RK3566 — the rkbin TPL key matches the RK3568 line. The output is bit-for-bit consumable by the BootROM the same way the danctnix idbloader.img is.

4. Critical SPL-extraction gotcha

<WRAP round important> The dd skip= for extracting the SPL from danctnix idbloader.img must be exactly 61440 (= sector 120 × 512), NOT 63488.

Sector 120 is recorded in the RKNS header at byte 0xd0 of the danctnix idbloader.img. Naively assuming a 4-sector pad-up of the DDR region (which would land at 63488) silently truncates the SPL by 2 KB, and the resulting idbloader.img bricks on flash — looking exactly like a DDR-training failure at the device. </WRAP>

Validation procedure

To prove that a freshly-extracted SPL + your packaging recipe are structurally sound before risking a frequency change, build a 1056 variant with the same SPL+recipe and confirm:

md5sum ~/ohm-recovery/idbloader-1056-FIXED.img
# must equal: ceb4d3fdfb7252e0815d24694e9043b4   (the danctnix golden)

If the md5 matches, the SPL extraction and mkimage recipe are correct, and only the DDR portion can fail at the device. If the md5 does not match, the SPL is wrong — fix the extraction first; do not flash. This is the procedure that retroactively explained ohm's 1560 MT/s bricking as a genuine DDR-training failure (and not an SPL truncation), because the parallel 1056-FIXED build matched the danctnix golden md5 byte-for-byte.

5. Flash procedure (eMMC, danctnix layout)

Two raw offsets in the pre-GPT region (GPT starts at sector 65536):

Component eMMC sector Byte offset
idbloader.img 64 32 KB
u-boot.itb 16384 8 MB

Path A — boot-from-SD (safest)

  1. Write the new idbloader-<TARGET>-FIXED.img to a danctnix-bootable SD card's sector 64.
  2. Insert SD into PineTab2, power on. The PineTab2 BootROM tries SD before eMMC, so a bad DDR blob on SD cannot brick the device — just remove the SD and the eMMC keeps booting.
  3. If SD boots successfully, you have validated the blob on this physical hardware. Now mirror to eMMC (Path B).

Path B — direct eMMC write from a running ohm

sudo dd if=~/ohm-recovery/idbloader-1332-FIXED.img \
        of=/dev/mmcblk0 bs=512 seek=64 count=420 conv=fsync
sudo cp ~/ohm-recovery/idbloader-1332-FIXED.img /boot/idbloader.img
sudo sync
sudo reboot

The /boot/idbloader.img copy keeps initramfs-rebuild / kernel-package hooks consistent with the on-disk raw region.

Failure mode for Path B = MASKROM + meitner. Do not skip Path A on the first build of a frequency you have not previously verified.

6. Recovery procedures

6.1 SD-boot recovery (preferred)

From a danctnix-bootable SD on ohm:

sudo dd if=/path/to/idbloader-1056-FIXED.img \
        of=/dev/mmcblk0 bs=512 seek=64 count=420 conv=fsync
sudo cp /path/to/idbloader-1056-FIXED.img /boot/idbloader.img
sudo sync
sudo reboot

Remove the SD before reboot completes so the device boots from the freshly-rewritten eMMC.

6.2 MASKROM + rkdeveloptool from meitner (flaky)

  1. Trigger MASKROM via the dedicated MASKROM hardware switch on the PineTab2. (This is the one significant divergence from PinePhone / earlier Pine64 devices, which rely on shorting a flash pin or holding a button — note this clearly when documenting recovery for future readers.)
  2. On meitner, build rockchip-linux/rkdeveloptool from master. The prebuilt rkdeveloptool 1.32 has trouble with NEWIDB v1.23 blobs — the wl step succeeds maybe half the time. Be prepared to retry.
  3. Push the loader and write the idbloader:
# On meitner, with PineTab2 in MASKROM connected over USB-C:
rkdeveloptool db MiniLoaderAll.bin
# wait ~15-20 s for USB-MSC to come up
rkdeveloptool wl 64 idbloader.img
rkdeveloptool rd 0

MiniLoaderAll.bin is the Pine64-supplied loader from pine64.org.

7. Runtime DVFS

Mainline kernel does NOT have a DMC devfreq driver wired for the PineTab2 DT. Whatever frequency the TPL programs at boot is the steady-state frequency. There is no runtime scaling and no runtime safety net that would drop to a lower step if the chosen frequency becomes unstable. Treat the boot blob as the only frequency the system will ever see.

8. Safety notes

  • Always run the §4 md5 validation. A mis-extracted SPL fails identically to a mis-trained DDR — you will misdiagnose for hours otherwise.
  • Always do Path A (SD boot) before Path B (direct eMMC) for any frequency you have not previously verified on the specific physical device.
  • 1332 is the ceiling. Do not retry 1560 expecting a different result on PineTab2 silicon.
  • No DMC devfreq on mainline = boot frequency is forever. No kernel-side fallback if a marginal blob is silently flaky under thermal stress months later.
  • Thermals matter. 1332 MT/s raises per-channel bandwidth ~26 % over the 1056 MT/s default; sustained-load temps should be checked before declaring stable in a hot ambient.

See also

megabitchip/pinetab2_ddr.txt · Last modified: by markus_fritsche