uzbek-plus/logs/b10/b10a/B10A-RESULT.md
q 58dcb3d121 B10: battery charging — PM8916 LBC supervisor v4 (CHARGE/HOLD, FAULT safe clamp to 4.00 V) and persistent B10B-5 cache
- 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
2026-10-04 19:00:27 +03:00

14 KiB
Raw Blame History

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.