diff --git a/POLL_SITE_MAP.md b/POLL_SITE_MAP.md index b5deddc..8158df3 100644 --- a/POLL_SITE_MAP.md +++ b/POLL_SITE_MAP.md @@ -79,3 +79,62 @@ the blob waits on before continuing. Worth its own trace. the "operating_mode" mapping for sites 2/4/5/7. - Special-case site 10 in the bisection plan — it's not a normal PHY poll and may need different treatment. + +## Update 2026-04-15 evening — TRM §2.4.3 mined + +Sibling research went back into the TRM and found **§2.4.3 Registers +Summary For DDRPHY** which I'd missed. That section names almost every +low-offset poll we'd labelled `(RE)`: + +| old guess | TRM actual | confidence | +|---|---|---| +| PHY + 0x110 `(RE)` — `F000F000` trigger | **`DDRPHY_CAL_RD_VWML0`** (Read Valid Window Margin Left Code 0) | TRM HIGH | +| PHY + 0x120 `(RE)` — step-complete bit | **`DDRPHY_CAL_RD_VWMR0`** (Read Valid Window Margin Right Code 0) | TRM HIGH | +| PHY + 0x160 `(RE)` — CFG_B 0x30003 | **`DDRPHY_CAL_CON5`** (Calibration Control 5: wrtrn_cyc_mode / wrtrn_cyc_en / wrtrn_cyc_th) | TRM HIGH | +| PHY + 0x684 "CalBusy" | **`DDRPHY_PRBS_CON0`** — PRBS training control (our CalBusy guess was wrong) | TRM HIGH | +| PHY + 0xa24 "DFI ready" | **`DDRPHY_SCHD_TRAIN_CON0`** — master training scheduler, full bit layout documented | **TRM extremely high** | +| PHY + 0xb88 "shadow" | **`DDRPHY_DQSDUTY_CON2`** — DQS rise-duty monitor (DCM/DCA debug) | TRM HIGH | +| PHY + 0x118, 0x154, 0x184 | TRM gaps (reserved) — still RE. Likely per-slice shadow / handshake FSMs | RE | + +### Big picture + +- **SCHD_TRAIN_CON0 @ +0xa24 is the master controller.** Writing to + it with the right bit combination selects a training type (CBT, + WrLvl, GT, Rd, Wr), enables per-rank bits, and sets the `phy_train_en` + bit. Polling `[1] phy_train_done` tells you when it's finished. **Four + of our poll sites (8, 9, possibly 11) are almost certainly polling + this bit.** +- The `0x30003` / `0x30000` pattern in d328 writes to `CAL_CON5`, not + `SCHD_TRAIN_CON0` — so it configures write-training cycle mode, not + the master scheduler. Initial sibling hypothesis of "DVFS gate + training" was incorrect on second reading. + +### Training sequence now mapped to poll sites + +Per TRM §2.6.x "Training Procedure": + +1. Power ramp / PLL lock / clock config +2. DFI init: `DDRCTL_DFIMISC.dfi_init_start=1`, poll `DDRCTL_DFISTAT.dfi_init_complete` — **site 3 is here** +3. ZQ calibration: `ZQ_CON0.zq_manual_str`, poll `ZQ_CON1.zq_done` +4. MDLL lock +5. Scheduler enable (`LP_CON0.ctrl_scheduler_en`) +6. Training loop, all via `SCHD_TRAIN_CON0`: + - CBT (Command Bus Training) + - Write Leveling + - Gate Training + - Read DQ Training → results land in `CAL_RD_VWMC0/VWML0/VWMR0` + - Write DQ Training → results in `CAL_WR_VWMC0/VWML0/VWMR0` + - PRBS Training (LPDDR5 high-speed) + - DQS Duty-cycle monitoring + +Our 16 poll sites are scattered across steps 2, 5 (scheduler-en state), +and the six training sub-steps in step 6. + +### Open items + +- **+0x118 / +0x154 / +0x184 remain TRM-reserved** — training engine + private FSMs. No way to name these from docs; dynamic tracing on + real hardware (with UART or JTAG) is the remaining path. +- CSDN LPDDR5 series (DDR Study blog) turned out to cover JEDEC-layer + protocol only; no register-level help. Useful background for training + phase names but not for our RE. diff --git a/rk3588_regs_annotated.h b/rk3588_regs_annotated.h index e9e92ca..cd992e8 100644 --- a/rk3588_regs_annotated.h +++ b/rk3588_regs_annotated.h @@ -122,3 +122,69 @@ /* The large-offset polls (0xb88, 0xa24, 0x684) in the early-cluster * functions are also DWC PUB; semantic guesses in BUG_ANALYSIS.md. */ + +/* ===================================================================== + * TRM §2.4.3 "Registers Summary For DDRPHY" — confirmed 2026-04-15 + * (sibling research surfaced this section of the TRM we'd missed). + * All offsets are within a per-channel DDRPHY Operational Base. + * ===================================================================== + */ + +#define DDRPHY_CAL_RD_VWML0 0x0110 /* Calibration Read Valid Window + Margin Left Code 0 (TRM HIGH) */ +/* +0x118 : TRM-reserved in the register summary. RE: per-slice "window + * valid" or shadow register; the blob reads [31:28] as per-slice done + * flags. Private training-engine FSM register. */ +#define DDRPHY_CAL_RD_VWMR0 0x0120 /* Calibration Read Valid Window + Margin Right Code 0 (TRM HIGH) */ +/* +0x154 : TRM-reserved. RE: accompanies CAL_CON5 in d328; likely a + * per-slice write-training trigger or training-engine shadow. */ +#define DDRPHY_CAL_CON5 0x0160 /* Calibration Control Register 5: + [10] binary_en (TBD) + [9:2] wrtrn_cyc_th (write training cycle threshold) + [1] wrtrn_cyc_en (write training cycle delay enable) + [0] wrtrn_cyc_mode (1=low freq 500MHz-1GHz, 0=matched edges) + (TRM HIGH) */ +/* +0x184 : TRM-reserved. RE: DFI phyupd / update-request handshake + * (pattern matches — wait non-zero, then wait zero). */ +#define DDRPHY_PRBS_CON0 0x0684 /* PRBS Training Control Register 0 + (our old "CalBusy" guess was wrong) + LPDDR5 high-speed PRBS pattern + training start/done (TRM HIGH) */ +#define DDRPHY_SCHD_TRAIN_CON0 0x0A24 /* **Master training scheduler** + [0] phy_train_en (start) + [1] phy_train_done (RO, completion) + [2] phy_cbt_en + [3] phy_wrlvl_en + [4] phy_gttrn_en (gate leveling) + [5] phy_rdtrn_en (read training) + [6] phy_wrtrn_en (write training) + [7] phy_wlcal_en + [9:8] phy_wrlvl_rank_en + [11:10] phy_gttrn_rank_en + [13:12] phy_rdtrn_rank_en + [15:14] phy_wrtrn_rank_en + [17:16] dvfs_gttrn_en + [19:18] dvfs_wrtrn_en + [21:20] periodic_gttrn_en + [23:22] periodic_wrtrn_en + (TRM EXTREMELY HIGH) */ +#define DDRPHY_DQSDUTY_CON2 0x0B88 /* DQS Rise-Duty rank1 DS0 — + duty-cycle monitor for DCM/DCA + (our old "UctShadow" guess wrong) + (TRM HIGH) */ + +/* ------------------------------------------------------------------- + * Semantic re-interpretation of FUN_0000d328 (train_phy_block): + * Writes 0x30003 to CAL_CON5 (+0x160): + * bit[0] wrtrn_cyc_mode=1 (low-freq edge mode) + * bit[1] wrtrn_cyc_en=1 (write training cycle delay enabled) + * bits[17:16] are in the RESERVED range of CAL_CON5 — no-op there. + * So d328 enables write-training cycle mode, waits for handshake, + * then clears (writes 0x30000 ≈ bits[17:16] — clears the [1:0] bits + * effectively). + * + * NOT "DVFS gate training" as initial sibling hypothesis; d328 is + * actually WRITE TRAINING setup/teardown (configuring the cycle + * mode, not the master scheduler). + * ------------------------------------------------------------------- */