- LBC supervisor v1..v4 (linux/patches/b10b3-lbc-supervisor-v3.patch + b10/b10b3/lbc-v3-to-v4-fault-clamp.diff): CHARGING 4.20 V/450 mA -> HOLD 4.05 V after 60 min CV -> battery -> new cycle on USB insert; FAULT = VDD_MAX 4.00 V clamp - RAM tests C/B/D/D2/D3/D4 (safety timer only ends fast charge), B10B-4 actuator audit (VDD_MAX works, USB_SUSP does not), B10B-5 FAULT clamp regression, production run, warm reboot via PON reboot reason - cache = B10B-5 c3732515 (HW EDL write, readback + full partition verify), class-A persistent validation - test-only hooks/images are not part of the production kernel; images with the AP PSK are not published
147 lines
14 KiB
Markdown
147 lines
14 KiB
Markdown
# B10A-RESULT — battery / charger / power-management audit (read-only)
|
||
|
||
Date: 2026-10-03. Board: Aurora JZ08AU-XPA-7J-R3, running the operational baseline (aboot lk1st-b9l `15208dbb`,
|
||
cache B9C `b9ce13c9`, kernel `7.2.7-aurora-b9c #9`), USB connected to 480s, boot = class B (PON_REASON1 = USB_CHG).
|
||
Nothing was changed: no build, no eMMC/cache write, no PMIC/regulator/GPIO writes, no ADC conversion trigger, no reboot.
|
||
Live data = sysfs/debugfs reads + PM8916 regmap debugfs reads (`b10/b10a/b10a-probe.sh`, `b10a-trend.sh`, `b10a-pm.sh`).
|
||
|
||
Raw data: `b10/b10a/b10a-live1.txt` (full dump), `b10/b10a/b10a-trend1.txt` (30 s trend). Stock sources:
|
||
`android/power_supply.txt`, `dt/dtb_01.dts`, `partitions/{boot,aboot,sbl1}.bin`.
|
||
|
||
## Main findings
|
||
|
||
1. **Hardware: PM8916 internal linear charger (LBC) + PM8916 VM-BMS (voltage-mode fuel gauge, no coulomb counter).**
|
||
No external charger/gauge IC (stock DT has no I²C charger/gauge; `CHG_OPTION 0x1008 = 0x80` = PMIC charger in use).
|
||
Upstream Linux 7.2 has drivers for both: `CHARGER_PM8916_LBC` (`qcom,pm8916-lbc`) and `BATTERY_PM8916_BMS_VM`
|
||
(`qcom,pm8916-bms-vm`); both nodes exist in `pm8916.dtsi` with `status = "disabled"`. Neither is built today.
|
||
2. **Today nobody manages charging in Linux.** `/sys/class/power_supply` is empty, IIO=n (no VADC, no PMIC temp-alarm
|
||
thermal zone). The charger runs on whatever SBL1/PMIC defaults leave in the registers:
|
||
CHG_EN = 1, VDD_MAX = 4.200 V, **IBAT_MAX = 90 mA (field = 0, the minimum)**, IBAT_SAFE = 990 mA,
|
||
safety timer ON (raw 0x1d), battery present, battery temp OK, USBIN valid.
|
||
3. **SBL1 `batt_voltage≈4.2 V` is not a state-of-charge indicator.** With USB present the LBC is in CV at VDD_MAX, so the
|
||
reading is clamped at ≈4.19–4.20 V. Boots where SBL1 ran before USB was attached (R2 T3C/T4A, R3A: battery first)
|
||
show 3.99–4.10 V. Stock era (Android charging at 411 mA, SoC 24 %) showed 3.86–3.97 V.
|
||
The memory note "batt_voltage ~4.2 V, so low charge is not the cause" (R2) therefore rests on a CV-clamped value.
|
||
4. **Battery voltage is flat under Linux load:** BMS FIFO = 14702±1 LSB over the whole trend, i.e. the charger holds CV.
|
||
Either the board's load is below what the LBC delivers, or the 90 mA field does not limit total output as assumed.
|
||
This cannot be resolved read-only (no current sense in VM-BMS) → needs a USB power meter (see next steps).
|
||
5. **USB gadget declares `MaxPower = 2 mA`** (configfs `c.1/MaxPower 2`, bmAttributes 0x80). Stock Android reported
|
||
`usb CURRENT_MAX = 500000`. A strict host/hub may limit the port; our board draws far more than 2 mA.
|
||
6. Power management (CPU): `psci_idle` cpuidle with WFI + `cpu-sleep-0` (heavily used), menu governor;
|
||
cpufreq schedutil 200/400/800/998.4 MHz; all 4 CPUs online; system suspend = s2idle only (not used).
|
||
Thermal: tsens zones 43–45 °C; no PMIC die-temp zone (needs IIO + spmi-vadc).
|
||
|
||
## Table
|
||
|
||
| Item | Stock (Android 3.10, stock LK) | Current (lk1st-b9l + Linux 7.2.7-b9c) | Status |
|
||
|---|---|---|---|
|
||
| Charger HW | PM8916 LBC `qcom,qpnp-linear-charger` (CHGR 0x1000, BAT_IF 0x1200, USB_CHGPTH 0x1300, MISC 0x1600) | same HW, no driver (`CHARGER_PM8916_LBC` not set, DT node disabled) | **Unmanaged** (SBL1/PMIC defaults) |
|
||
| Charge voltage | `vddmax-mv` = `vddsafe-mv` = 4200 | VDD_MAX 0x08 = 4200 mV, VDD_SAFE 0x08 = 4200 mV | Same |
|
||
| Charge current | `ibatsafe-ma` 1440; thermal mitigation 1440/720/630/0; runtime = min(USB current_max 500, …); Android showed −411.6 mA (charging) | IBAT_MAX 0x00 = 90 mA; IBAT_SAFE 0x0a = 990 mA | **Lower than stock** (field decode per upstream driver: 90 mA + 90 mA·n) |
|
||
| Input min (VIN_MIN) | `vinmin-mv` 4308 | VIN_MIN is 0x1047 = 0x04 = 4308 mV (corrected in B10A-DRIVER-AUDIT; 0x1043 = 0x86 is something else) | Same as stock |
|
||
| Safety timer | `tchg-mins` 232 | TCHG_MAX_EN 0x80, TCHG_MAX raw 0x1d | Enabled (value differs) |
|
||
| Temperature (JEITA) | cool 10.0 °C / warm 45.0 °C; 4100 mV + 360 mA in cool/warm; hot 25 % / cold 80 % BTC thresholds | BAT_IF RT temp_ok = 1; BTC regs 0x1248–0x124a = 0a 81 c0 | HW BTC active, no SW JEITA |
|
||
| Battery presence | `batt-pres` IRQ | BAT_IF 0x1208 = 0x83 (present), RT bat_pres = 1 | OK |
|
||
| Termination / resume | `chg-term-ua` 100 mA, `resume-soc` 99 %, `report-charger-eoc` | CHGR RT: chg_done 0, fast_chg 0, vbat_det_lo 1; CHG_STATUS 0x1009 = 0x03 | Open (no SW EOC/resume logic) |
|
||
| Fuel gauge | `qcom,qpnp-vm-bms` + userspace `vm_bms` daemon; battery `palladium_1500mah` (generic Qualcomm MTP profile, batt-id 75 kΩ), cutoff 3.4 V, max 4.2 V | VM-BMS HW enabled (EN 0x4046 = 0x80, MODE 0x0a normal, FIFO len 5, S1/S2 10/7); no driver | **No SoC in Linux** |
|
||
| VBAT (BMS FIFO) | — | raw 14702 (stable); upstream ×300 µV ⇒ 4.41 V (implausible, > VDD_MAX); if CV = 4.200 V ⇒ ≈285.7 µV/LSB | **Scale unverified** (hypothesis; needs a reference) |
|
||
| BMS OCV reg (0x406a) | — | raw 0x37ff = 14335 (low byte 0xff suspicious) ⇒ 4.30 V (×300) / 4.095 V (×285.7) | Unreliable |
|
||
| VADC | `qcom,qpnp-vadc` with vbat_sns, vph_pwr, usb_in, die/chg temp, batt_therm, batt_id, xo_therm, pa_therm0 | IIO=n; last conversion left by SBL1: CH 0x06 (VBAT_SNS) data 0x9826 | **No ADC in Linux** |
|
||
| USB/VBUS detect | `msm_otg` + `usbin_valid` IRQ | extcon `usb-detect@1300` USB=1; USB_CHGPTH RT usbin_valid = 1, coarse_det = 1; UDC configured, high-speed | OK |
|
||
| USB current declared | power_supply usb CURRENT_MAX 500 mA | gadget MaxPower 2 mA | **Mismatch** |
|
||
| Charger mode boot | stock LK: cold boot + PON USB_CHG + no KPDPWR ⇒ `androidboot.mode=charger` ⇒ `/charger` + `healthd -n` + `vm_bms` | lk1st boots Linux unconditionally (no charger-screen); B9L splash | Different by design |
|
||
| SBL1 | `pm_sbl_chg` (CHG_App_LUT, VBATT/USB_IN/BATT_ID/BATT_THERM), prints `batt_voltage` | same SBL1 (unchanged) | Reference |
|
||
| PON / power-off | — | PON_REASON1 0x10 (USB_CHG), POFF2 0x80d = 0x20 (UVLO, latched after power cuts — see R2) | Known |
|
||
| Coin cell (0x2800) | — | COIN EN 0x2846 = 0x80, VSET 0x01, RSET 0x00 | Enabled; presence of a backup cell unknown (RTC resets on class A ⇒ probably none) |
|
||
| CPU idle/freq | — | psci_idle WFI + cpu-sleep-0, schedutil 200–998 MHz | OK |
|
||
| Thermal | `pm8916_tz`, `bms`, `battery`, tsens | tsens only (5 zones, 43–45 °C) | PMIC/battery temp missing |
|
||
|
||
## SBL1 `batt_voltage` history (from logs/uart)
|
||
|
||
| Period | Chain / power-on | batt_voltage (mV) |
|
||
|---|---|---|
|
||
| 2026-09-29 | stock chain, Android charging 411 mA | 3857–3975 |
|
||
| 2026-09-30 → 10-03 | lk1st + Linux, USB present at SBL1 | 4147–4202 (mostly 4186–4201) |
|
||
| 2026-10-02 R2 T3C/T4A, R3A | battery first, USB later (class A tests) | 3990–4101 |
|
||
|
||
## Open questions (need the operator)
|
||
|
||
1. Battery: real capacity/chemistry/label (stock DT profile is the generic `palladium_1500mah`); is there a thermistor
|
||
(BAT_IF temp_ok = 1 suggests BTC sees a valid value) and a batt-id resistor?
|
||
2. Actual current from USB: a USB power meter between 480s and the board (idle LTE, LTE traffic, Wi-Fi AP) would show
|
||
whether the board is net-charging or discharging with IBAT_MAX = 90 mA.
|
||
3. VBAT reference: one multimeter reading on the battery terminals would calibrate the BMS FIFO scale.
|
||
|
||
## Next step (proposal, needs GO)
|
||
|
||
B10B (RAM-only, like B8B/B9B): kernel = b9c + `IIO` + `QCOM_SPMI_VADC` + `QCOM_SPMI_TEMP_ALARM` + `BATTERY_PM8916_BMS_VM`
|
||
+ `CHARGER_PM8916_LBC`; DT enables `pm8916_bms`/`pm8916_charger` with a conservative `monitored-battery`
|
||
(4.2 V, constant-charge current ≤ 500 mA, safe values from stock DT) and `pm8916_vadc`. Note: the LBC driver writes
|
||
VDD_MAX/IBAT_MAX/TCHG at probe — that is a PMIC write and needs its own GO; an even safer first step is
|
||
B10B-0 = VADC + temp-alarm + BMS only (BMS probe also writes its FIFO/interval/EN registers), charger untouched.
|
||
USB gadget MaxPower → 500 mA is a separate tiny change for the next image.
|
||
|
||
## Incident during the audit: board died at uptime ≈2148.7 s — RESOLVED: operator unplugged USB to insert a USB power meter
|
||
|
||
- UART (`logs/uart/b9l-bootcold1-20261003-020146.raw` on 480s, tail saved as `b10/b10a/b10a-death-uart-tail.txt`) stops
|
||
**mid-line** at 02:38:11 MSK (board epoch 1790984291), inside normal ModemManager debug output. No panic/oops/thermal/reset text,
|
||
no SBL1 restart afterwards → abrupt power loss or a hard hang, not a kernel crash with a message.
|
||
- USB NCM (18d1:d001) disappeared from 480s at the same time; no re-enumeration (no SBL/lk/fastboot) afterwards.
|
||
- The read-only trend was sleeping at that moment: last register read ≈uptime 2129 s, next due ≈2159 s (death ≈20 s after a read).
|
||
The same reads had run 11 times before, and a full 3328-register dump earlier. The reads are therefore an unlikely cause,
|
||
but it cannot be fully excluded.
|
||
- Only 3 of the 12 trend samples survived (the rest were in board RAM). Logger on 480s still running.
|
||
- Fits the open "flaky battery contact / UVLO" issue (R2, B9C cold1 "battery dropped") and the unmanaged charger state (IBAT_MAX 90 mA).
|
||
Needs the operator: what does the board show (display/backlight on?), is the battery seated, is USB still powered?
|
||
|
||
**Resolution:** the operator confirmed the power loss was intentional (USB unplugged to insert a USB power meter). Not a board fault; the register reads are cleared.
|
||
|
||
## Follow-up with a USB power meter (operator, 2026-10-03 02:45–03:01)
|
||
|
||
- Boot 02:44 (class A, RTC 3 s): meter 4.90–4.98 V, **0.15–0.20 A** idle (LTE + Wi-Fi AP + display); max 0.41 A seen
|
||
(the 0.024 A "min" was during manual replug; the meter shows max, not min). → 90 mA in IBAT_MAX does NOT cap USB input.
|
||
- Boot 02:53 (class B, RTC 533 s), CPU-load test `b10/b10a/b10a-load.sh` (20 s idle, 60 s 4×`yes`, 30 s idle; CPU 998 MHz, tsens 44→71 °C, no throttling):
|
||
**meter stayed at 0.01 A the whole time** — the board ran from the battery. BMS FIFO (raw): idle 14554 → load 14324/14308 → recovering 14498
|
||
(≈ −65…−70 mV under load at the 285.7 µV/LSB hypothesis). Data: `b10a-load3.txt` (`b10a-load2.txt` = same test, debugfs not mounted → no regs).
|
||
- Register diff vs the first dump (`b10a-live2.txt` vs `b10a-live1.txt`): **CHG_STATUS 0x1009 03 → 00**, **USB_CHGPTH 0x1308 02 → 01**,
|
||
PON 0x807 88→c8, 0x80d 20→00; CHG_CTRL (0x90), IBAT_MAX, VDD_MAX, RT statuses (chg 01, bat 03, usb 03) unchanged; extcon USB=1, UDC configured.
|
||
→ **USB is valid and CHG_EN = 1, but the LBC is currently not charging and not supplying the load.**
|
||
Hypothesis (unproven): LBC is in its post-"done"/maintenance state and waits for VBAT to fall below the resume (VBAT_DET) threshold;
|
||
without a Linux driver nothing restarts charging. Bits of 0x1009/0x1308 are not decoded (no downstream source here).
|
||
|
||
## 30-min read-only monitor (03:03:52–03:34, `b10/b10a/b10a-mon.sh`, data `b10a-mon1.txt`)
|
||
|
||
31 samples, 60 s apart, uptime 630→2431 s, idle (LTE + Wi-Fi AP + display), operator watching the meter (≈0.01 A).
|
||
- **Nothing in the charger changed:** CHG_STATUS 0x1009..0x100b = `00 00 43`, CHGR RT 0x1010 = 01, CHG_CTRL 0x90, VDD_MAX 0x08,
|
||
IBAT_MAX 0x00, USB 0x1308/0x1309 = `01 90`, USB RT 0x1310 = 03, BAT_IF RT 0x1210 = 03 in all 31 samples. OCV reg constant 14376.
|
||
- **BMS FIFO falls linearly: 14530 → 14410 (−120 LSB / 30 min)** ≈ −34 mV/30 min (≈ −70 mV/h at 285.7 µV/LSB; scale unverified).
|
||
No step up, i.e. **the LBC did not resume charging by itself** within 30 min while VBAT went from ≈4.15 to ≈4.12 V.
|
||
- Consequence: in this state the board runs from the battery with USB plugged; it will eventually hit the cutoff/UVLO.
|
||
Charging was active (meter 0.15–0.20 A) in the 02:02 and 02:44 boots and stopped after the manual replug before the 02:51/02:53 boots.
|
||
What exactly puts the LBC into this state (replug sequence? charge-done latch?) and what the resume threshold is remains open.
|
||
|
||
## Variant 1: full PMIC reset (operator, 03:57–03:59): charging restored
|
||
|
||
Operator: USB off, battery out ≥90 s, battery in, then USB through the meter. Boot 03:59:27 = **class A** (RTC 3 s), SBL1 batt_voltage=4165.
|
||
Meter: max 0.41 A while the kernel boots. Registers at uptime 45 s (`b10a-classA1.txt`): **CHG_STATUS 0x1009 = 05**, **USB 0x1308 = 02 90**,
|
||
RT 01/03/03, CTRL 0x90, VDD_MAX 0x08, IBAT_MAX 0x00; BMS OCV reg 14090 (≈4.03 V at 285.7 µV/LSB, taken at battery-only power-up).
|
||
→ The "stuck, not charging" state lives in the PMIC retained domain: class B boots kept it, a full POR cleared it.
|
||
Observed states: 0x1308 = 02 when charging, 01 when stuck (USB valid); 0x1009 = 03 (CV at 4.2 V, boot 02:02), 05 (now, below CV), 00 (stuck). Bit meaning not decoded.
|
||
|
||
## 60-min monitor while charging (04:01:08–05:02, `b10a-mon2.txt`): the LBC stops by itself after the CV phase
|
||
|
||
| uptime (s) | CHG_STATUS | 0x1308 | FIFO (raw) | meter | phase |
|
||
|---|---|---|---|---|---|
|
||
| 100–760 | 05 | 02 | 14484 → 14699 rising | ≈0.41 A | CC / input-limited |
|
||
| 760–1360 | 05 | 02 | frozen 14685–14699 (no FIFO updates) | — | — |
|
||
| 1360–2622 | 03 (sporadic 07/05) | 02 | 14667 → 14683, flat | ≈0.2 A, falling | CV at 4.2 V, taper |
|
||
| **2622→2682** (≈04:44, ~45 min after power-on) | **00** | **01** | step 14682 → 14538 (−144), then −4…−5 per min | **0.01 A** | **charger off, board on battery** |
|
||
|
||
- Nobody touched the board. CHGR RT stayed 01 (no chg_done/chg_fail RT bit), USB RT 03, BAT RT 03, CTRL 0x90 throughout.
|
||
- The −144 LSB step is the CV source disappearing (≈ −41 mV at 285.7 µV/LSB); afterwards the same linear discharge as in the 30-min monitor.
|
||
- **Conclusion:** after the CV taper the LBC ends the charge cycle autonomously (charge-done/termination) and switches the whole USB path off,
|
||
so the load moves to the battery. The 0x1009=00 / 0x1308=01 state from the 03:03 monitor is this same post-termination state, not a replug artefact.
|
||
With no Linux driver nothing re-enables charging; in the 30-min monitor VBAT fell ≈30 mV without any hardware resume.
|
||
Hypothesis: the downstream qpnp-linear-charger handled resume in software (vbat-det-lo IRQ → re-enable), so on stock the
|
||
charger was restarted by the kernel. To be checked against the downstream source and the upstream pm8916_lbc before B10B.
|
||
- Charge cycle: from class-A power-on (OCV ≈4.03 V) to termination ≈45 min.
|