power: supply: macsmc: support charge_behaviour on newer SMC firmware#435
power: supply: macsmc: support charge_behaviour on newer SMC firmware#435IntegralPilot wants to merge 17 commits intoAsahiLinux:bits/110-smcfrom
Conversation
Apple Silicon Macs (M1, etc.) have an RTC that is part of the PMU IC, but most of the PMU functionality is abstracted out by the SMC. An additional RTC offset stored inside NVMEM is required to compute the current date/time. Reviewed-by: Mark Kettenis <kettenis@openbsd.org> Reviewed-by: Neal Gompa <neal@gompa.dev> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: James Calligeros <jcalligeros99@gmail.com> Reviewd-by: Mark Kettenis <kettenis@openbsd.org>
Apple Silicon devices integrate a vast array of sensors, monitoring current, power, temperature, and voltage across almost every part of the system. The sensors themselves are all connected to the System Management Controller (SMC). The SMC firmware exposes the data reported by these sensors via its standard FourCC-based key-value API. The SMC is also responsible for monitoring and controlling any fans connected to the system, exposing them in the same way. For reasons known only to Apple, each device exposes its sensors with an almost totally unique set of keys. This is true even for devices which share an SoC. An M1 Mac mini, for example, will report its core temperatures on different keys to an M1 MacBook Pro. Worse still, the SMC does not provide a way to enumerate the available keys at runtime, nor do the keys follow any sort of reasonable or consistent naming rules that could be used to deduce their purpose. We must therefore know which keys are present on any given device, and which function they serve, ahead of time. Add a schema so that we can describe the available sensors for a given Apple Silicon device in the Devicetree. Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: James Calligeros <jcalligeros99@gmail.com> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Apple Silicon Macs (M1, etc.) have an RTC that is part of the PMU IC, but most of the PMU functionality is abstracted out by the SMC. On T600x machines, the RTC counter must be accessed via the SMC to get full functionality, and it seems likely that future machines will move towards making SMC handle all RTC functionality. The SMC RTC counter access is implemented on all current machines as of the time of this writing, on firmware 12.x. However, the RTC offset (needed to set the time) is still only accessible via direct PMU access. To handle this, we expose the RTC offset as an NVMEM cell from the SPMI PMU device node, and this driver consumes that cell and uses it to compute/set the current time. Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: Hector Martin <marcan@marcan.st> Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Add the new SMC RTC function to the mfd device Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
When using the _SMC_KEY macro in switch/case statements, GCC 15.2.1 errors out with 'case label does not reduce to an integer constant'. Introduce a new __SMC_KEY macro that can be used instead. Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
The System Management Controller on Apple Silicon devices is responsible for integrating and exposing the data reported by the vast array of hardware monitoring sensors present on these devices. It is also responsible for fan control, and allows users to manually set fan speeds if they so desire. Add a hwmon driver to expose current, power, temperature, and voltage monitoring sensors, as well as fan speed monitoring and control via the SMC on Apple Silicon devices. The SMC firmware has no consistency between devices, even when they share an SoC. The FourCC keys used to access sensors are almost random. An M1 Mac mini will have different FourCCs for its CPU core temperature sensors to an M1 MacBook Pro, for example. For this reason, the valid sensors for a given device are specified in a child of the SMC Devicetree node. The driver uses this information to determine which sensors to make available at runtime. Reviewed-by: Neal Gompa <neal@gompa.dev> Co-developed-by: Janne Grunau <j@jannau.net> Signed-off-by: James Calligeros <jcalligeros99@gmail.com> Acked-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Janne Grunau <j@jannau.net>
Add the SMC hwmon functionality to the mfd device Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
This driver implements power button and lid switch support for Apple Mac devices using SMC controllers driven by the macsmc driver. In addition to basic input support, this also responds to the final shutdown warning (when the power button is held down long enough) by doing an emergency kernel poweroff. This allows the NVMe controller to be cleanly shut down, which prevents data loss for in-cache data. Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: Hector Martin <marcan@marcan.st> Co-developed-by: Sven Peter <sven@kernel.org> Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Add the new SMC input function to the mfd device Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
…ttons/lid Signed-off-by: Janne Grunau <j@jannau.net>
MFD will probe sub devices declared with MFD_CELL_OF() even without match on the device tree compatible. macsmc-reboot depends on nvmem provided via device tree. Fail probe() with -ENODEV if this information is missing. Signed-off-by: Janne Grunau <j@jannau.net>
This driver implements support for battery stats on top of the macsmc framework, to support Apple M1 Mac machines. power: supply: macsmc_power: Add cycle count and health props power: supply: macsmc_power: Add present prop power: supply: macsmc_power: Add more props, rework others power: supply: macsmc_power: Use BUIC instead of BRSC for charge power: supply: macsmc_power: Turn off OBC flags if macOS left them on power: supply: macsmc_power: Add AC power supply power: supply: macsmc_power: Add critical level shutdown & misc events power: supply: macsmc_power: Add CHWA charge thresholds This is a hardcoded charge threshold feature present in firmware 13.0 or newer. Userspace settings are rounded to one of the two possible behaviors. power: supply: macsmc_power: Report available charge_behaviours The generic handling if charge_behaviours in the power_supply core requires power_supply_desc.charge_behaviours to be set. power: supply: macsmc_power: Add more properties Report more voltages from the battery, and also fudge energy numbers from charge numbers. This way userspace doesn't try to convert on its own (and gets it very wrong). power: supply: macsmc_power: Add CHLS charge thresholds Since macOS Sequoia firmware, CHLS replaced CHWA and now allows an arbitrary end charge threshold to be configured. Prefer CHWA over CHLS since the SMC firmware from iBoot-10151.1.1 (macOS 14.0) is not compatible with our CHGLS usage. It was working with the SMC firmware from iBoot-10151.121.1 (macOS 14.5). power: supply: macsmc_power: Remove CSIL Gone in Sequoia firmware. power: supply: macsmc_power: Report not charging for CHLS thresholds If a CHLS charge threshold is configured and the current SoC is above the start threshold report a busy BMS as not charging. power: supply: macsmc_power: Report only supported properties The SMC firmware in macOS 15.4 dropped "AC-i" and "AC-n" (and all keys with lower case last letter) without obvious replacement. Stop reporting VOLTAGE_NOW / INPUT_CURRENT_LIMIT if "AC-n" is not present. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Co-developed-by: Thomas Weißschuh <linux@weissschuh.net> Signed-off-by: Janne Grunau <j@jannau.net> Co-developed-by: Janne Grunau <j@jannau.net> Co-authored-by: Joey Gouly <joey.gouly@arm.com> Signed-off-by: Hector Martin <marcan@marcan.st>
power: supply: macsmc_power: Log power data on button presses This helps catch s2idle power stats, since we get early data when the system resumes due to a power button press. Signed-off-by: Hector Martin <marcan@marcan.st>
Signed-off-by: Janne Grunau <j@jannau.net>
Hard wakeup events are required to wake from s2idle. The comment in [1] to always send wakeup events is correct though. To combine both requirements use pm_wakeup_dev_event() and evaluate the previous conditions for calling pm_wakeup_hard_event() as hard parameters. The remark about always reporting KEY_POWER is only partially correct though. (Some) User space handles that indeed correctly but a system offering a agetty login prompt shuts down immediately after waking from s2idle. 1: https://lore.kernel.org/all/qffp7kadq3xojla5k6f5pr37irgytqfsqvabr6ydvulxnkcgnn@bv5mrraxrhhe/ Signed-off-by: Janne Grunau <j@jannau.net>
Signed-off-by: Janne Grunau <j@jannau.net>
|
Oh sorry just realised there's an unrelated 2-line whitespace change in |
Newer Apple SMC firmware (found on M3 devices and updated M1/M2) has removed the legacy `CH0C` (Inhibit Charge) and `CH0I` (Force Discharge) keys. Reading these missing keys results in -EIO (-5) errors, causing the `charge_behaviour` sysfs property to fail completely. This patch adds support for the new `CHTE` key used for charge inhibition on these devices. For now, it seems that `auto` and `inhibit-charge` are the only possible behaviours to set using this new key, however further macOS tracing may reveal additional behaviour states in future. Changes: 1. Detects the presence of `CHTE`, `CH0C`, and `CH0I` during probe. 2. Only exposes `force_discharge` capability if `CH0I` is actually present. 3. Implements read/write support for `CHTE` using raw byte buffers (this is to avoid endianness issues with the kernel's u32 helpers) Fully backwards compatible with both old and new firmwares. Tested on M3 with new firmware. Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>
49a85dd to
aee3b28
Compare
|
Just moved a comment to a more logical place. |
|
thanks a ton for looking into this issue! i upgraded MacOS earlier today and was extremely disappointed to find out about this regression. this patch does fix the |
|
Thank you for testing this out! I can't reproduce the |
|
somehow the error seems to be gone now. i did find out that i was loading the wrong device trees due to a minor corner case in my distro's kernel install hooks, but i haven't fixed the issue and yet the empty read on either way, it seems to be working fine now. thanks again for looking into this! |
|
Tested on 16-inch M2 Pro 2023. Before applying this patch, setting the charge threshold is flaky, and there are a lot of the following logs: These are all gone now. Thanks for working on this! |
|
I sent this driver upstream, including this and other improvements: https://lore.kernel.org/asahi/20260105-b4-macsmc-power-v1-0-62954c42a555@gmail.com, though it will probably take several weeks of review, then several weeks for it to land here, so I'll leave this open in case anyone wants just the charge_behaviour patch so optimised charging works, though feel free to close if it's better to wait for upstream. Happy to help, it was fun reverse engineering to find out how to fix this. |
Newer Apple SMC firmware (found on M3 devices and updated M1/M2) has removed the legacy
CH0C(Inhibit Charge) andCH0I(Force Discharge) keys. Reading these missing keys results in -EIO (-5) errors, causing thecharge_behavioursysfs property to fail completely.This patch adds support for the new
CHTEkey used for charge inhibition on these devices.For now, it seems that
autoandinhibit-chargeare the only possible behaviours to set using this new key, however further macOS tracing may reveal additional behaviour states in future.Changes:
CHTE,CH0C, andCH0Iduring probe.force_dischargecapability ifCH0Iis actually present.CHTEusing raw byte buffers (this is to avoid endianness issues with the kernel's u32 helpers)Fully backwards compatible with both old and new firmwares. Tested on M3 with new firmware.