Kernel driver mpq8646¶
Supported chips:
MPS MPQ8646
Prefix: ‘mpq8646’
- Author:
Vincent Jardin <vjardin@free.fr>
Chip-identity¶
Support the boards that are designed with the MPS MPQ8646 probed thanks to``MFR_MODEL`` register.
This driver targets the MPQ8646 silicon specifically.
Description¶
The MPQ8646 is a fully integrated, PMBus-compatible, high-frequency, synchronous buck converter. It offers a compact solution that achieves up high Amps output current per phase, with excellent load and line regulation over a wide input supply range. The chip operates at high efficiency over a wide output current load range.
The PMBus interface provides converter configurations and key parameters monitoring.
The device adopts MPS’s proprietary multi-phase digital constant-on-time (MCOT) control, which provides fast transient response and eases loop stabilization. The MCOT scheme also allows multiple devices or channels to be connected in parallel with excellent current sharing and phase interleaving for high-current applications.
Fully integrated protection features include over-current protection (OCP), over-voltage protection (OVP), under-voltage protection (UVP), and over-temperature protection (OTP).
This device is compliant with:
PMBus rev 1.3 interface.
The driver exports the following attributes via the ‘sysfs’ files for input voltage:
in1_input
in1_label
in1_max
in1_max_alarm
in1_min
in1_min_alarm
in1_crit
in1_crit_alarm
The driver provides the following attributes for output voltage:
in2_input
in2_label
in2_alarm
in2_max
in2_max_alarm
in2_min
in2_min_alarm
in2_crit
in2_crit_alarm
in2_lcrit
in2_lcrit_alarm
The driver provides the following attributes for output current:
curr1_input
curr1_label
curr1_max
curr1_max_alarm
curr1_crit
curr1_crit_alarm
The driver provides the following attributes for temperature:
temp1_input
temp1_max
temp1_max_alarm
temp1_crit
temp1_crit_alarm
Alarm acknowledgment¶
The hwmon-class inX_alarm/currX_alarm/tempX_alarm files are
read-only in pmbus_core. The driver exposes the standard
PMBUS_VIRT_RESET_*_HISTORY virtual-register channel for fault
acknowledgment: writing 1 to inX_reset_history /
currX_reset_history / tempX_reset_history sends the chip a
CLEAR_FAULTS (0x03) Send-Byte, which clears the latched
STATUS_WORD / STATUS_VOUT / STATUS_IOUT /
STATUS_INPUT / STATUS_TEMPERATURE bits the chip is currently
exposing.
The MPS-specific NVM post-mortem register
PROTECTION_LAST (0xFB) is not cleared by this path; it can be read
(decoded) via the protection_last debugfs entry described below.
Regulator framework integration¶
When CONFIG_REGULATOR=y is set, the chip is
exposed under /sys/class/regulator/ and accepts the standard
regulator framework operations:
regulator_enable()/regulator_disable()->OPERATION(0x01)regulator_set_voltage()->VOUT_COMMAND(0x21)regulator_get_voltage()->READ_VOUT(0x8B)regulator_is_enabled()->OPERATIONbit-decode
The single regulator descriptor is named "vout" (page 0). For a
multi-page configuration the descriptor table can be extended in
the driver.
In-driver alarm-poll fallback¶
On boards where the chip’s SMBALERT# pin is unavailable to the
SoC, pmbus_core::pmbus_irq_setup cannot deliver SMBALERT-driven
poll(POLLPRI) wakes or udev change@... events on the
inX_alarm files. The driver provides a delayed_work-based
polling fallback that
periodically invokes the pmbus core fault check,
pmbus_check_and_notify_faults(), which sends the notifications and
then clears the latched faults, exactly like the SMBALERT#
interrupt path. The frequency of polling is tunable:
/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/alarm_poll_interval_ms
The default is 1000 ms.
Set it to 0 to disable. The worker self-suppresses
when client->irq != 0 (i.e. when DT supplies an
interrupts = <...> property on the regulator node), so adding
SMBALERT# wiring is a zero-driver-change uplift on a future
board rev.
MPS post-mortem (PROTECTION_LAST)¶
The MPQ8646 silicon keeps a single 16-bit NVM-backed record of the
last protection event in PROTECTION_LAST (0xFB). It survives
chip power/reset. The following debugfs entries expose it:
/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/protection_last (RO)
/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/status_decoded (RO)
protection_last decodes the 16-bit value based on the datasheet
fault names (INIT_FAULT, NVM_CRC_ERROR, NVM_FAULT,
OC_PHASE_FAULT, OTP_SELF_FAULT, SWITCH_PRD_FAULT,
VIN_OV_FAULT, VOUT_OV_FAULT, VOUT_UV_FAULT,
OC_TOT_FAULT, VIN_UVLO_FAULT, DRMOS_OTP).
status_decoded reads STATUS_WORD (0x79) and renders the
16 bits with MPS-extension labels (bit12 = NVM_SUMMARY,
bit8 = WATCH_DOG, bit0 = DRMOS_FAULT) instead of the
PMBus 1.3 spec generic names.
NVMEM snapshot¶
When CONFIG_NVMEM=y is set, the chip’s NVM-backed
observability registers are exposed as a single 16-byte read-only
nvmem_device at /sys/bus/nvmem/devices/<i2c-name>/nvmem.
Layout (little-endian for 16-bit fields, zero-fill on per-entry read
failure and for the reserved tail):
offset 0..1 PROTECTION_LAST (0xFB) word
offset 2..3 MFR_RETRY_TIMES (0xF4) word
offset 4..5 MFR_CONFIG_ID (0xC0) word
offset 6..7 MFR_VBOOT_CFG (0xFC) word
offset 8 MFR_SILICON_REV (0xC3) byte
offset 9..15 reserved (zero)
Suitable for single-cat post-mortem capture by a fleet daemon.
Diagnostics and introspection¶
When CONFIG_DEBUG_FS=y is set, the driver adds a read-only
decode surface to the client’s pmbus debugfs directory,
/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/.
The driver intentionally exposes no raw register poke/peek debugfs;
use i2c-dev (i2cget/i2cset/i2ctransfer) for that.
Identity / observability (read-only):
File |
PMBus / MFR cmd |
Description |
|---|---|---|
|
0xC0 (word) |
board / SKU NVM identifier |
|
0xC1 (word) |
NVM image revision (PART_RECOG + config code rev fields) |
|
0xC3 (byte) |
die revision |
|
0xF4 (word) |
per-fault-class recovery-mode
configuration (NOT a retry
count). Four 4-bit fields
[15:12]=OTP, [11:8]=VOUT_OV,
[7:4]=VOUT_UV, [3:0]=OCP.
Each field: 0x0=latch-off,
0x1..0xE=retry N times then
latch off, 0xF=hiccup
(retry indefinitely). The
chip exposes no in-NVM
retry-event counter; track
transitions externally if
needed (poll
|
|
0xFC (word) |
ADDR/VBOOT latched at POR |
Timing / UVLO knobs (read-only):
File |
PMBus cmd |
Description |
|---|---|---|
|
0x35 (word) |
UVLO turn-on threshold |
|
0x36 (word) |
UVLO turn-off threshold |
|
0x60 (word) |
soft-start delay |
|
0x61 (word) |
soft-start ramp time |
|
0x64 (word) |
soft-stop delay |
|
0x65 (word) |
soft-stop ramp time |
The only writable entry is alarm_poll_interval_ms (the alarm-poll
worker cadence, see above), it is driver-local and never touches the
chip.
Unsafe provisioning¶
Available only when CONFIG_SENSORS_MPQ8646_DEBUG_UNSAFE=y
(default n, it is for boards bring up only). They WRITE to the regulator.
On many designs the MPQ8646 powers the main CPU core rail, so a wrong write can
brown out the board or persist a bad setpoint into finite-cycle NVM.
WARNING: Some wrong register writes can and likely will physically damage or
destroy the chip and/or the board. An explicit warning banner is printed at probe
time when this option is enabled.
File |
PMBus / MFR cmd |
Description |
|---|---|---|
|
0x15 |
STORE_USER_ALL Send-Byte (commit RAM config to NVM) |
|
0x16 |
RESTORE_USER_ALL Send-Byte (revert RAM to last-NVM image) |
|
0x08 |
CLEAR_LAST_FAULT Send-Byte |
|
-- |
gated CLEAR_LAST_FAULT, see below |
|
0x02 (byte) |
PMBus vs CTRL-pin on/off source + active polarity |
|
0x25 (word) |
margin-high VOUT setpoint |
|
0x26 (word) |
margin-low VOUT setpoint |
|
0xEE (word) |
programmable PMBus write-lock |
|
0xC2 (word) |
user-programmable product revision |
clear_protection_last writes CLEAR_LAST_FAULT (0x08) Send-Byte.
The chip silently no-ops unless MFR_CFG_EXT (0xF5) bit[6] is set.
clear_protection_last_force performs the unlock with the following
six-step dancing:
read
WRITE_PROTECT(0x10) andMFR_CFG_EXT(0xF5) for restoreclear
WRITE_PROTECTif setset
MFR_CFG_EXTbit[6] = 1, preserving other bitssend
CLEAR_LAST_FAULT(0x08)restore
MFR_CFG_EXT(with retry to handle the chip’s undocumented post-NVM-write busy window)restore
WRITE_PROTECT
Devicetree¶
The driver uses compatible = "mps,mpq8646". There are some few optional
properties:
mps,vout-fb-divider-ratio-permille: it writesVOUT_SCALE_LOOP(0x29) at probe to compensate for an external resistor divider in the VOUT feedback path. The valid range is 11-bit.interrupts = <...>: if the board routes the chip’sSMBALERT#pin to a SoC GPIO, declaring it here lights uppmbus_core::pmbus_irq_setupand disables the in-driver alarm-poll fallback