uzbek-plus/logs/b10/b10b3/B10B3-DESIGN.md
q 4983fe2f76 B10: finalize persistent PM8916 charging
- final persistent validation (cold2): autonomous class-A boot from cache c3732515, live cache hash re-read,
  CHARGING/FAST, USB remove/insert recovery, LTE/Wi-Fi/NCM/display PASS, 15-min stability PASS -> B10 CLOSED
- README: B7/B8/B9/B10 CLOSED, production profile (4.20 V / 450 mA / HOLD 4.05 V / full-min 4.15 V / CV 60 min /
  timer 512 min / FAULT safe clamp 4.00 V) and the four production limitations; NOTES session 38
- current tree cleaned of raw B10 run logs (monitor/dmesg/snapshot/UART excerpt/action logs/register dumps/emulator
  outputs); history (58dcb3d) not rewritten
- publication rules: tools/publish-sanitize.py and .gitignore keep B10+ logs to reports (*.md) and *-diff.txt tables
2026-10-04 19:48:10 +03:00

283 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# B10B3-DESIGN — charger supervisor + safety timer
> **Current design = section 8 (v3, CHARGE → HOLD → BATTERY → CHARGE).** Sections 2–7 (recharge-threshold model, v1/v2) are
> superseded and kept only as history; their production values (recharge 4.05 V, TERMINATED = 00/01) are withdrawn.
Date: 2026-10-03. Starting point (class A, SBL1 defaults, verified): IBAT_MAX 00 (90 mA), IBAT_SAFE 0a, CHG_CTRL 90, TCHG 80/1d (on, 120 min),
VDD_MAX/SAFE 08 (4.20 V), IBATTERM 0x105B 09 (HW termination on), COMP_OVR1 00, BOOT_DONE 00.
## 1. What stock did (facts from downstream source/binding @7f1748ce and stock DT dtb_01)
- Stock DT: `qcom,resume-soc = <99>`, no `charger-detect-eoc`, no `disable-vbatdet-based-recharge`, `tchg-mins = <232>`.
- Recharge paths (all software): (a) SOC ≤ resume-soc (99 %) while USB present → CHG_EN; (b) VBAT_DET_LO IRQ → CHG_EN; (c) USB insert → CHG_EN
(with VBAT_DET override so it charges even above VBAT_DET).
- (a) needs the stock VM-BMS SOC. Translated through the stock (generic MTP "palladium_1500mah") OCV table at 25 °C: 100 % = 4167 mV,
95 % = 4112 mV → **99 % ≈ 4.156 V OCV**. That keeps the cell practically always near 4.2 V → **rejected** per your constraint.
- (b) The LBC VBAT_DET level is not programmed by the stock driver and is not documented for PM8916 LBC (0x105D, the SMBB VBAT_DET
register in LK, reads 00 here). Its threshold is unknown → cannot be adopted as a number.
- EOC on stock was BMS-decided (HW iterm disabled). Disable = CHG_CTRL masked (bit7|bit0) → FORCE_BATT_ON (0x01); enable → CHG_ENABLE (0x80).
## 2. Proposed recharge threshold (voltage-based, VADC VBAT under load)
Our facts: post-termination idle discharge on battery ≈ 70 mV/h (B10A); VADC VBAT σ ≈ 5–7 mV, LTE TX dips up to ≈ 30 mV; load ≈ 0.15–0.2 A
→ loaded VBAT ≈ OCV − 30…40 mV (R ≈ 0.2 Ω, estimate).
| option | loaded VBAT restart | ≈ OCV | ≈ SOC on the stock generic table | time on battery after termination |
|---|---|---|---|---|
| A | 4.10 V | ≈ 4.13–4.14 V | ≈ 96–97 % | ≈ 0.5–1 h — close to "always near 4.2 V" |
| **B (recommended)** | **4.05 V** | ≈ 4.08–4.09 V | ≈ 90–91 % | ≈ 1.5–2 h |
| C | 4.00 V | ≈ 4.03–4.04 V | ≈ 83–85 % | ≈ 2.5–3 h |
Hysteresis: termination happens at the 4.20 V CV point (HW iterm); restart only after VBAT < threshold in **3 consecutive 30 s samples**
(filters TX dips). Gap 4.20 → 4.05 V = 150 mV. The generic-table SOC column is indicative only (real cell curve unknown).
## 3. Safety timer
Upstream probe writes TCHG_MAX_EN 0x1060 = 0x00 (timer off). Patch: program it like downstream `qpnp_lbc_tchg_max_set()`:
0x1060 bit7 ← 0, **0x1061 TCHG_MAX ← minutes/4 − 1**, 0x1060 bit7 ← 1. Encoding: 4…512 min in 4-min steps.
| value | 0x1061 | note |
|---|---|---|
| SBL default | 0x1d | 120 min |
| stock DT | 0x39 | 232 min |
| **proposed** | **0x7f** | **512 min = 8 h 32 min (hardware maximum)** |
Why max: at 450 mA input minus ~0.15–0.2 A board load the cell gets ≈ 0.25–0.3 A; a deep charge of a 3000 mAh cell needs > 8.5 h,
so a shorter timer would trip mid-charge. Recharge cycles (150 mV) take well under 1 h.
Expiry → CHG_FAILED (0x104A bit7). Proposed policy: supervisor goes to **FAULT**, charger disabled, logged; **no automatic restart**
(stock cleared CHG_FAILED automatically — not copied). FAULT is left only by USB re-insert or reboot. (Alternative for approval: one
automatic re-arm if VBAT < 4.0 V, then FAULT.)
Unverified: whether a CHG_EN 0→1 edge restarts the timer count (expected; will be logged).
## 4. Implementation (kernel only, no userspace register access)
- `qcom-spmi-vadc.c`: VBAT_SNS `VADC_CHAN_NO_SCALE(VBAT_SNS, 1)` → `VADC_CHAN_VOLT(VBAT_SNS, 1, SCALE_DEFAULT)` (same as VSYS) →
`in_voltage6_input` processed with the driver's own calibration (= the B10B-0 manual formula).
- `pm8916_lbc.c`:
- IIO consumer `io-channels = <&pm8916_vadc VADC_VBAT_SNS>`, `io-channel-names = "vbat"`.
- threshold from simple-battery `re-charge-voltage-microvolt` (standard battery.yaml property; this kernel's core does not parse it into
`charge_restart_voltage_uv`, so the driver reads it from the monitored-battery node itself).
- timer from new DT `qcom,charge-timeout-minutes` (default 512 if absent), programmed as in §3; no more TCHG_MAX_EN = 0.
- state machine in a delayed_work (30 s) + kicks from the existing usb_vbus IRQ:
- **NO_USB**: USBIN not valid. On removal: charger disabled (stock-style 0x01).
- **CHARGING**: CHG_CTRL 0xA0 (upstream value). If CHG_STATUS == 00 ∧ USB path 0x1308 == 01 ∧ USB valid for 2 polls
(= the state observed after real HW termination in B10A) → **TERMINATED**.
- **TERMINATED**: write disable (CHG_EN 0, FORCE_BATT_ON 1, as stock) so restart is a clean edge; poll VBAT; 3 × below threshold →
**RECHARGE** = write 0xA0 → CHARGING.
- **FAULT**: CHG_FAILED or VBAT > 4.25 V (defence) → disabled until USB re-insert/reboot.
- USB insert (and probe with USB present): always enable (edge 0→1) → CHARGING, like stock's usbin path. A class-B reboot
therefore never leaves the board on battery with USB present; the cost is one top-off per boot/insert.
- observability: charger psy `status` (Charging / Not charging / Full) + `/sys/kernel/debug/pm8916_lbc/state` (state, VBAT,
regs, counters, transitions) for the logger.
- **test-only hook (RAM image only, debugfs)**: `force_terminate` (supervisor performs its normal TERMINATED action) and
`recharge_threshold_uv` override. Not a register poke; removed/disabled for persistent integration.
- DT (b10b2 + ): charger `io-channels`, `qcom,charge-timeout-minutes = <512>`; battery `re-charge-voltage-microvolt = <chosen>`.
## 5. Test plan (RAM only, class A, USB meter in line, logger on 480s every 30 s)
Battery now ≈ 3.85 V, i.e. below every production threshold, and reaching a real termination needs hours. Therefore:
- Test 1/2 (recharge state machine, 2+ cycles): `force_terminate` at the current VBAT; set the **test** threshold to VBAT_at_terminate − 20 mV
(debugfs override, documented as test value); real discharge under controlled load (4×`yes`, ≈ 0.4 A) until VBAT < test threshold →
automatic restart without any command at that moment. Repeat ≥ 2×. Checks: meter, VADC VBAT, CHG_STATUS, CHG_CTRL, USB path, RT, temps.
- USB unplug → insert in TERMINATED and in CHARGING.
- class-B reboot from TERMINATED: `reboot` from the RAM image with RESET held → lk1st fastboot → same image again; supervisor must come up
CHARGING (or TERMINATED→RECHARGE), never "USB present, charger off, no supervision". (Warm reboots occasionally hang in SBL — R2.)
- Real HW termination: only if it happens naturally; reported separately. The production threshold is not exercised by Test 1/2
(battery below it) — reported as such.
- Abort: logger ALERT VBAT > 4.22 V or PMIC > 60 °C (operator pulls USB), driver FAULT > 4.25 V, unexpected register diff, USB/LTE/Wi-Fi instability.
## 6. Decisions (operator, 2026-10-03) and build status
- Production recharge threshold **4.05 V VADC VBAT**, 3 consecutive samples, 30 s period; no decisions from BMS-VM voltage.
- Safety timer **512 min**, timeout → latched FAULT, charging off, no automatic restart; exit only USB remove/insert or reboot.
- Test-only threshold current_VBAT − 20 mV via debugfs `test_recharge_uv` (RAM image only; not in DT/production config).
- **Open item before persistent integration:** one real hardware termination → VBAT drop → CHG_EN 0→1 → real recharge
(force_terminate proves the state machine, not the release of the hardware termination latch).
- Built, NOT loaded: patch `linux/patches/b10b3-lbc-recharge-supervisor.patch` (sha256 499a45c4…), tree src-b10b3 (hardlinked copy of src with
private copies of the 2 patched files), kernel `7.2.7-aurora-b10b3` (full build, no warnings), DTB `linux/dts/msm8916-jz08-aurora-b10b3.dts`,
image `b10/b10b3/out/aurora-b10b3.img` c3c885d5 (`build-b10b3.sh`).
- Note: upstream pm8916_lbc defines an unused `PM8916_LBC_CHGR_MAX_TIME 256`; downstream (Qualcomm) uses TCHG_MAX mask bits 6:0, max 512 min.
The driver reads TCHG_MAX back after programming 0x7f and fails probe on mismatch (timer is re-enabled before the readback).
## 7. ram1 result and REDESIGN v2 (2026-10-03)
ram1 (class-B warm reboot from B9C in its natural stop latch, RESET held → lk1st fastboot → b10b3 v1):
- probe: timer 512 min (TCHG_MAX readback 0x7f, EN 80), threshold 4.05 V; **the probe restart edge CHG_CTRL 0x21 → 0xa0 released the
latch that B9C had reached by itself** (CHG_STATUS 00 → 05, USB path 01 → 02, FAST_CHG_ON). Note: that B9C latch occurred at VBAT ≈ 3.81 V
(not a full battery), in the non-BOOT_DONE mode — cause unknown.
- USB meter 0.357 A charging. `force_terminate` wrote CHG_CTRL 0x21 (CHG_EN 0 + FORCE_BATT_ON): **meter stayed 0.358 A**, CHG_STATUS stayed 05,
FAST_CHG_ON cleared, USB path 01, VBAT not falling (3.89 → 3.92 V). → **CHG_EN = 0 does not stop the charger** on this board/mode.
Test stopped (unexpected charger state). Logs: ram1-mon.txt, ram1-actions.txt, ram1-final-state.txt, ram1/.
Redesign v2 (operator decision; diff `b10/b10b3/lbc-v1-to-v2.diff`, full patch `linux/patches/b10b3-lbc-recharge-supervisor.patch` sha256 24c6c0d7…):
- TERMINATED only from CHARGING when CHG_STATUS == 00 ∧ USB path bit1 == 0 for 2 polls (= the hardware end-of-charge latch).
**No CHG_CTRL write on entering TERMINATED**, none on USB removal, none on FAULT.
- recharge: after 3 × 30 s VADC VBAT < re-charge-voltage-microvolt → the verified sequence 0x21 → 20 ms → 0xa0.
- USB insert / probe with USB: same verified sequence (+ CHG_FAILED clear).
- FAULT (CHG_FAILED = safety-timer expiry, or VBAT > 4.25 V defence): latched, no restart, **no register write** (the hardware timer
itself stops charging; there is no verified software stop). Exit only USB re-insert or reboot.
- test hooks removed (no force_terminate, no test_recharge_uv); debugfs `state` read-only only.
- accelerated test = separate TEST-ONLY DTB `msm8916-jz08-aurora-b10b3t.dts`: battery voltage-max-design **4.00 V** → VDD_MAX 0x00
(lowest LBC step: 4000 + 25 mV·n; 3.95 V not supported), re-charge **3.94 V**. Image `b10/b10b3/out-t/aurora-b10b3t.img` dfe2fae6.
- production unchanged: DTB `msm8916-jz08-aurora-b10b3.dts` 4.20 V / 4.05 V / 450 mA / 512 min, image `b10/b10b3/out/aurora-b10b3.img` 5ba4d715
(same kernel as the test image).
- Known gap: no verified way to *stop* charging from software (only the hardware latch and the hardware timer stop it).
## 8. DESIGN v3 — CHARGE → HOLD → BATTERY → CHARGE (operator decision 2026-10-03; nothing built)
### 8.1 Use case and facts it rests on
Modem runs ≈4 h on battery, is then plugged into USB and must fully recharge; sometimes it stays on USB for a long time.
Facts (B10A, B10B-2, B10B-3 ram1/t1, EOC audit): 00/01 is a latch, not an EOC (seen at 3.83 V and ≈45 min after class A with BOOT_DONE=0);
with BOOT_DONE=1 no hardware EOC in ≈80 min CV; CHG_EN = 0 does not stop charging; verified levers = VDD_MAX, IBAT_MAX, CHG_EN 0→1 edge
(releases 00/01), timer programming. Battery 3000 mAh, 3.8 V nominal, 4.35 V max (B10 capped at 4.20 V).
**Withdrawn:** 00/01 as FULL/TERMINATED; recharge threshold 4.05 V; automatic discharge/recharge cycles; force_terminate.
### 8.2 States
| state | registers written on entry | behaviour |
|---|---|---|
| NO_USB | **none** | board on battery; charger not touched |
| CHARGING | on entry from NO_USB/probe: BOOT_DONE 0x1642 ← 0x80; VDD_MAX ← charge level (4.20 V = 0x08); IBAT_MAX checked/← 450 mA (0x04); verified restart CHG_CTRL 0x21 → 20 ms → 0xa0 (+ CHG_FAILED clear) | full charge cycle to 4.20 V on every USB insert |
| HOLD | **only VDD_MAX ← hold level (4.05 V = 0x02)**; IBAT_MAX, CHG_CTRL, timer untouched | long stay on USB; VBAT goes down to ≈4.05 V, the USB path stays working and USB powers the board (meter ≈ board load 0.15–0.20 A on the shelf); no discharge/recharge cycles |
| FAULT | **none** (logical only) | no restarts; dev_crit log; physical stop = **open blocker** |
Transitions (poll 30 s + usb_vbus IRQ kick; all decisions on calibrated VADC VBAT, never on BMS-VM):
- any → NO_USB: USBIN not valid (no write).
- NO_USB/probe → CHARGING: USBIN valid (entry writes above).
- CHARGING → HOLD: **CV criterion** held continuously for `cv-hold-minutes` (RAM test 1: 60 min; configurable, not final):
per poll "in CV" = CHG_STATUS bit1 (VDD loop) set **and** VADC VBAT ≥ `full-min-voltage` (4.15 V). Because the LBC interleaves 05/07 with 03
during CV (B10A, t1), a single poll without bit1 does not reset the timer; **two consecutive** polls without bit1, or any poll with
VBAT < 4.15 V, reset it.
- CHARGING, 00/01 latch seen (2 polls): **not FULL** — log "latch in CHARGING", verified restart edge, stay CHARGING (counter n_latch).
- HOLD → NO_USB on USB removal; NO_USB → CHARGING on insert (VDD_MAX back to 4.20 V + restart) → after hours on battery every insert recharges fully.
- HOLD, 00/01 latch seen (USB valid, 2 polls): **verified restart edge 0x21 → 20 ms → 0xa0, VDD_MAX stays at the hold level, stay HOLD**, event logged
(correction 2, 2026-10-03): with USB present the board must not silently move to battery.
- CHARGING/HOLD → FAULT: VADC VBAT > 4.25 V, or CHG_FAILED (timer) — logical latch, restart forbidden, loud log. Exit: USB re-insert or reboot.
### 8.3 Parameters (DT, charger node unless noted)
| parameter | production | source |
|---|---|---|
| charge level (VDD_MAX) | 4.20 V | battery `voltage-max-design-microvolt` (existing) |
| IBAT_MAX | 450 mA (500 mA request) | `qcom,fast-charge-safe-current` (existing) |
| hold level | 4.05 V (0x02) | new `aurora,hold-voltage-microvolt` |
| full-min voltage | 4.15 V | new `aurora,full-min-voltage-microvolt` |
| CV hold time | 60 min for the first RAM run, **not final** | new `aurora,cv-hold-minutes` |
| safety timer | 512 min (unchanged until Test B) | `qcom,charge-timeout-minutes` |
| OVP (logical FAULT) | 4.25 V | constant |
`re-charge-voltage-microvolt` is no longer used (removed from the production DT in v3).
### 8.4 Open blockers (not hidden)
1. **No verified software emergency stop.** CHG_EN = 0 does not stop the LBC. FAULT is logical only (no restarts) until a physical stop is found and
tested (candidates, each needs its own test: VDD_MAX to the 4.00 V minimum, IBAT_MAX to 90 mA, USB_SUSP 0x1347 bit0).
2. **Safety timer in HOLD** (Test B): if the hardware timer counts CV/HOLD time, a long HOLD ends with CHG_FAILED → board on battery. Production
timer strategy unchanged (512 min, enabled) until Test B.
3. 60 min CV criterion is a first guess (no current sense, no hardware EOC).
### 8.5 Test C — HOLD mechanism (first, RAM only, separate GO)
Goal: prove that lowering VDD_MAX at runtime stops the battery current, lets VBAT fall and then holds the new shelf.
- Kernel = v3 driver (states above). **Test-only DTB** (accelerated, the battery is ≈4.0 V now):
charge level **4.10 V** (VDD_MAX 0x04), hold level **4.00 V** (0x00, lowest LBC step), full-min **4.05 V**, cv-hold **5 min**, timer 512 min.
Production DTB stays 4.20 / 4.05 / 4.15 V / 60 min.
- Expected (correction 1, 2026-10-03): CHARGING (meter ≈0.35 A) → CV at 4.10 V (meter falls) → 5 min CV → HOLD: VDD_MAX 04 → 00 →
VADC VBAT goes down to the hold level, the USB path stays working (USB valid, no 00/01), and **on the shelf the meter shows the board's own load
≈0.15–0.20 A**. A sustained ≈0.01 A on the shelf = suspected USB-path cut / board on battery → not PASS.
Physical note (engineering expectation, to be observed, not a PASS criterion): VPH ≈ VBAT on this board (VADC ch6 vs ch7 differ by a few mV),
i.e. no separate power path; while VBAT is still above the new VDD_MAX the charger cannot supply the board without exceeding it, so a transient
phase with low USB input during the descent (4.10 → 4.00 V) is expected. It is logged and reported separately.
- Log every 30 s: state, VADC VBAT, CHG_STATUS, CHGR/USB/BAT RT, USB path, CHG_CTRL, VDD_MAX, IBAT_MAX, TCHG, CHG_FAILED, BOOT_DONE, temps; meter by operator.
- Checks: LTE/Wi-Fi/NCM/display alive, eMMC writes = 0, only the planned registers change (0x1040 on the HOLD transition).
- Stop: VADC > 4.15 V (test level 4.10 + margin), PMIC > 60 °C, timer disabled, unexpected register writes.
### 8.6 Test B — safety timer in HOLD (only after Test C PASS, separate GO)
Same v3 kernel, test-only DTB as Test C but `qcom,charge-timeout-minutes = 8` and cv-hold 2 min, so HOLD starts well before the timer would
expire. Observe across the 8-min mark: TCHG regs, CHG_FAILED, USB path, CHG_STATUS, VADC VBAT, meter, board power. Questions: does the timer count in
CV/HOLD; does CHG_FAILED set; does the path switch off; does the board drop to battery; would re-programming the timer on CHARGING → HOLD be safe.
STOP after the result.
**Run profile (2026-10-03, operator decision, variant A):** the battery is ≈4.00 V after Test C, so 4.10 V would leave ≈22 min of CC and the
8-min timer would expire in CHARGING, not in HOLD. This Test B run therefore uses the accelerated profile **4.05 V charge (VDD_MAX 0x02) /
4.00 V HOLD (0x00) / 4.03 V full-min / 2 min CV / 8 min timer (TCHG_MAX 0x01)**, IBAT_MAX 450 mA, same v3 kernel (driver unchanged).
DTB `msm8916-jz08-aurora-b10b3b.dts`, image `b10/b10b3/out-b/aurora-b10b3b.img` 9e66466d (only the DTB differs from Test C). Timeline t = 0 at
the driver probe (timer programming, dmesg `safety timer 8 min`). Monitor 10 s, EVDD 02/00, VMAX 4.15 V, PMIC 60 °C abort.
Preceded by a verified class-A reset (`pre-testB-classA-check.txt`, `pre-testB-classA-dump.txt`, `pre-testB-vs-baseline-diff.txt`: RTC 3 s,
no config register differs from the class-A baseline).
### 8.7 After Tests C and B
Update this design (timer strategy, FAULT stop mechanism), then one full RAM run: USB insert → CHARGING 4.20 V/450 mA → CV ≥ 4.15 V for the CV time →
HOLD 4.05 V → hours/controlled discharge without USB → USB insert → CHARGING 4.20 V. Persistent cache integration only by a separate GO.
### 8.8 Not doing now
00/01 as FULL; old recharge threshold 4.05 V; recharge cycles in HOLD; 4.35 V; > 450 mA; persistent integration; treating 60 min CV as final;
claiming a software emergency stop.
### 8.9 v3 build (2026-10-03, not loaded)
- Patch `linux/patches/b10b3-lbc-supervisor-v3.patch` (sha256 b6a74b8c…; spmi-vadc VBAT_SNS scaling + pm8916_lbc v3), v2→v3 diff `b10/b10b3/lbc-v2-to-v3.diff`;
tree src-b10b3, kernel `7.2.7-aurora-b10b3` (incremental, no warnings).
- Test C image `b10/b10b3/out-c/aurora-b10b3c.img` 5ff9dec0 (DTB `msm8916-jz08-aurora-b10b3c.dts`: 4.10 / 4.00 / 4.05 V / 5 min / 450 mA / 512 min).
- Production v3 image `b10/b10b3/out/aurora-b10b3.img` b7dc34e9 (4.20 / 4.05 / 4.15 V / 60 min) — not for loading yet.
- Driver changes v2→v3: states NO_USB/CHARGING/HOLD/FAULT; entry to CHARGING writes BOOT_DONE, VDD_MAX(charge), IBAT_MAX (only if different),
CHG_FAILED clear, restart edge; HOLD writes only VDD_MAX(hold); 00/01 in CHARGING and HOLD → restart edge (no VDD_MAX change); FAULT logical +
dev_crit; constant_charge_current writes only IBAT_MAX (under the supervisor lock, never VDD_MAX/CHG_CTRL); supervisor starts only after probe
completed (supv_ready guard against an early usb_vbus IRQ); re-charge threshold and all test hooks removed.
### 8.10 After Test C PASS (2026-10-03, operator-accepted; B10B3-TESTC-RESULT.md)
- HOLD works: after the transition VBAT goes to ≈4.00 V (test level), then USB carries the system and takes load steps; no VBAT rise.
- Corrected expectation: board consumption on USB in HOLD ≈ **0.03–0.1 A** (not 0.15–0.20 A, which included charge current).
- USB path 0x1308 = 01 alone does not mean charging is off; the latch is only **CHG_STATUS 00 + path 01**.
- Thermal margin is small: PMIC **57.9 °C** (limit 60 °C) with charging + 4×CPU load → for enclosures/heat a derating is needed
(e.g. lower IBAT_MAX above a PMIC temperature, or limit load) — to be designed, not implemented yet.
- Cosmetic: debugfs `cv_s` keeps counting in HOLD (cv_since not cleared) — fix in the next build.
- Before Test B: full class-A reset (LBC settings survive warm reboots). Test B only with a separate GO.
### 8.11 After Test B (2026-10-04, B10B3-TESTB-RESULT.md)
- Variant-A profile (4.05 / 4.00 / 4.03 V, 2 min CV, 8 min timer): HOLD at t = 153.8 s; **no CHG_FAILED in CV/HOLD up to t = 1787 s** (≈ 3.7× timer);
the USB path stayed alive after the timer mark (2×CPU load at t ≈ 22–27 min: VBAT held at 4.000 V, USB 0.08–0.10 A). A long HOLD is not ended
by the timer → blocker 8.4/2 resolved for production in the observed sense; re-programming the timer on CHARGING → HOLD is **not needed**.
- Not proven: that the timer fires at all (CC lasted ≈ 15–30 s; no positive control). The safety timer is not a verified protection; a
positive-control test (expiry in a long CC) needs its own GO. FAULT stop (8.4/1) remains open.
- Warm reboot with RESET held can end in a PMIC stage-3 reset (POFF_REASON2 STAGE3, RTC near 0) — harmless for RAM tests, note for classification.
### 8.12 After Test D (2026-10-04, B10B3-TESTD-RESULT.md) — NOT PASS / inconclusive
- Test C profile + 8-min timer: VBAT reached 4.10 V at ≈ t 300 s (battery more charged than estimated), CV criterion before the mark → by the
agreed rule not PASS. But the input current stayed at the CC level (USBIN sag unchanged, meter 0.42 A) until ≈ 8.5 min and **no CHG_FAILED**
appeared at t = 480 s or up to t ≈ 843 s. The safety timer has still never been seen to fire (Tests B, D).
- Untested explanations: timer counts only in a state with CHGR_RT FAST_CHG_ON (never set on this board), different TCHG_MAX encoding, or
restart edge at CHARGING entry. Until a positive control exists, the timer must not be counted as a protection.
- A RESET-held warm reboot regularly ends in a PMIC stage-3 reset here (0x080D = 0x80, RTC ≈ 5 s, RESET ≈ 12 s).
### 8.13 Safety timer and the two charge states (2026-10-04; T1DIAG, TESTD2, TESTD3, TESTD4 results)
- FAST_CHG_ON (CHGR RT bit5) + USB path 02 = fast charge. Entered at the restart only when VBAT (VADC at INIT) ≤ 3.896 V; at ≥ 3.930 V the LBC
charges in a non-fast state (FAST_CHG_ON 0, path 01) — independent of v2/v3 (D3 removed the only write difference; not the cause).
- TCHG counts only in fast charge: Test D4 (unchanged Test D image, entry 3.794 V) → FAST_CHG_ON 1→0, path 02→01 exactly at 8 min; **current
continued (0.41 A), CHG_FAILED never set (0x104A and RT bit6)**. The timer is therefore **not a charge-stop protection**; charging is bounded
only by VDD_MAX regulation (and the HOLD logic). Production 512-min timer stays as is (harmless), but no design element may rely on it.
- The supervisor's CHG_FAILED → FAULT path is never triggered by a TCHG expiry on this PMIC; detecting a "timer expired" event would need
FAST_CHG_ON 1→0 in CHARGING (diagnostic only).
- Open: HOLD → USB removal in v3 (one reset seen from the path-01 state); VBAT_DET threshold not documented (≈ 3.90–3.93 V observed).
- 2026-10-04 addendum: USB pull from v3 HOLD — PASS (no reset; heartbeat continuous; HOLD→NO_USB→CHARGING on re-insert). After a fresh USB
insertion the LBC entered FAST (path 02) even at 4.02 V, and the HOLD write (VDD_MAX below VBAT) ends FAST immediately (path 01).
### 8.14 Final RAM run (production profile) — B10 charging logic: RAM VALIDATED (2026-10-04, B10B3-RESULT.md)
- Production profile 4.20 / 4.05 / 4.15 V / 60 min / 450 mA / 512 min, v3 driver (no D3), RAM only: criteria 1–6 and 8–10 PASS; HOLD shelf
4.033–4.056 V for ≈ 6.3 h, USB 0.1 A on the shelf; USB pull/insert from HOLD PASS; 0 ALERT/latch/FAULT; PMIC max 45.7 °C; eMMC writes 0.
- **Warm reboot: PASS with scope limitation.** `reboot(RESTART2, "bootloader")` → lk1st fastboot without RESET (PON 0x88F[7:2]=2), no stage-3,
RTC continuous. After a warm (PS_HOLD) reboot SBL re-initialises part of the charger (IBAT_MAX 00, IBAT_SAFE 0a, CHG_CTRL 90, TCHG 1d);
the driver re-programs the production configuration at probe (VDD_MAX 4.20 V, IBAT_MAX 450 mA, CHG_CTRL 0xA0, timer 512 min, BOOT_DONE 1).
Not tested: whether VDD_MAX = 4.05 V from HOLD survives a warm reboot — not a production requirement (every boot starts a new charge cycle).
- **Withdrawn:** "charger settings survive class-B/warm reboots". Correct model: warm reboot → SBL partially re-initialises the charger →
the driver always re-programs the production configuration. (Section 8.10's "LBC settings survive warm reboots" is superseded by this.)
- Persistent cache integration only with a separate GO.
### 8.15 Cache candidate (2026-10-04, b10/b10b3/cache/B10B3-CACHE-CANDIDATE.md) — prepared, NOT written
`cache-extlinux-b10b3.img` 86869061 = B9C recipe with only the kernel (7.2.7-aurora-b10b3, v3) and production DTB replaced; emulator PASS, RAM
pretest (class A) PASS. **Blocker before persistent GO: no verified physical charge-stop actuator for FAULT; the safety timer does not stop
charging.** Proposed B10B-4 (RAM only, separate GO): USB_SUSP / IBAT_MAX min / VDD_MAX min / combination.
### 8.16 B10B-4 actuator audit (2026-10-04, B10B4-RESULT.md; RAM, TEST-ONLY hook kernel)
- USB_SUSP (0x1347 b0): NOT an actuator — only ends FAST (path 01), input 0.46 → 0.41 A, VBAT keeps rising.
- **VDD_MAX → 4.00 V: working FAULT actuator while VBAT > 4.00 V** — input 0.000 A within < 1 s, VBAT falls, board on battery, reversible
(charging resumes on VDD_MAX 08, non-fast until a USB re-insert). Below 4.00 V it caps charging at 4.00 V (not a stop).
- IBAT_MAX → 90 mA: derating only (FAST kept, reversible).
- No hard stop at any VBAT verified; VDD_MAX 0 + IBAT_MAX 0 combination untested. Integration into the driver = separate GO.
### 8.17 v4: FAULT safe clamp to 4.00 V (2026-10-04, B10B5-RESULT.md)
On FAULT entry (CHG_FAILED or VBAT > 4.25 V) v4 writes only VDD_MAX = 0x00 (+ readback, dev_crit); FAULT stays latched until USB removal or
reboot. This is a **safe clamp, not a guaranteed charge disconnect**: with VBAT > 4.00 V charging stops (USB input → 0, board on battery);
with VBAT < 4.00 V the charger may still charge up to 4.00 V. USB_SUSP is not used; IBAT_MAX is not touched in FAULT. RAM regression (TEST OVP
injection) PASS; production cache candidate `b10/b10b3/cache-v4/cache-extlinux-b10b5.img` c3732515 built, NOT written.
- 2026-10-04: production v4 RAM smoke test PASS (out-v4/aurora-b10b5.img 386502d3); cache candidate c3732515 unchanged → READY FOR PERSISTENT GO (write = separate GO).
### 8.18 PERSISTENT (2026-10-04, logs/b10/b10b5/B10-RESULT.md) — B10 CLOSED
Cache = b10b5 c3732515 (B10_CACHE_WRITE_VERIFIED, HW EDL); class-A autonomous boot validated (charger, VADC, LTE, Wi-Fi, NCM, display, USB re-insert,
15-min regression window clean). Rollback: b10/b10b5/B10-rollback.sh → B9C b9ce13c9.
- 2026-10-04 final: cold2 class-A persistent validation PASS (charger production config, USB off/on → NO_USB/CHARGING/FAST, 15-min window clean,
live cache c3732515 re-read). **B10 battery / charger / power management — CLOSED.** Production limitations: FAULT = safe clamp VDD_MAX 4.00 V
(no guaranteed hard-off below 4.00 V); safety timer does not stop charging; no thermal derating; battery contact mechanically unreliable.