Hardware/Framework/Laptop 16: Difference between revisions
No edit summary |
Mention systemd bug resulting in idle-suspend loop |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 18: | Line 18: | ||
|x86_64-linux | |x86_64-linux | ||
|- | |- | ||
!colspan="2" class="title"|7040 Series | !colspan="2" class="title"|AMD Ryzen 7040 Series | ||
|- | |||
!Maintainer | |||
|- | |||
!colspan="2" class="title"|AMD Ryzen AI 300 Series | |||
|- | |- | ||
!Maintainer | !Maintainer | ||
| Line 25: | Line 29: | ||
</div> | </div> | ||
The Framework Laptop 16 is a configurable, upgradeable, and repairable laptop made by | The Framework Laptop 16 is a configurable, upgradeable, and repairable laptop made by Framework. | ||
== Status == | == Status == | ||
The device boots NixOS. | The device boots NixOS and works well with a recent kernel and the appropriate nixos-hardware module for your CPU generation. | ||
== Known issues == | == Known issues == | ||
[[Category: Incomplete]] | [[Category: Incomplete]] | ||
The device still has a couple of hardware quirks (see below). | The device still has a couple of hardware quirks (see below). | ||
[[Linux kernel|Using the latest kernel]] will fix some issues. Also read configuration hints in this article. | [[Linux kernel|Using the latest kernel]] will fix some issues. Also read configuration hints in this article. | ||
=== Double suspend after GNOME automatic/idle suspend (systemd v258 regression) === | |||
Some users have reported a "double suspend" / "suspend loop" on Framework Laptop 16 (notably with GNOME and the NVIDIA dGPU module): after the machine suspends due to *automatic idle suspend* and is resumed, it may suspend again ~20-30 seconds later (sometimes repeating multiple times). Manual suspend and lid-close suspend may still behave normally. | |||
Upstream tracking: | |||
* https://github.com/systemd/systemd/issues/40078 | |||
* https://github.com/systemd/systemd/issues/39259 | |||
==== Workaround 1: add a post-resume sleep inhibitor ==== | |||
Add this snippet to configuration.nix: | |||
<syntaxhighlight lang="nix"> | |||
systemd.services.inhibit-sleep-after-resume = { | |||
description = "Temporary sleep inhibitor after resume (workaround for double-suspend)"; | |||
wantedBy = [ "post-resume.target" ]; | |||
after = [ "post-resume.target" ]; | |||
serviceConfig.Type = "oneshot"; | |||
script = '' | |||
${pkgs.systemd}/bin/systemd-inhibit \ | |||
--mode=block \ | |||
--what=sleep:idle \ | |||
--why="Workaround: avoid immediate second suspend after resume" \ | |||
${pkgs.coreutils}/bin/sleep 60 | |||
''; | |||
}; | |||
</syntaxhighlight> | |||
==== Workaround 2: disable GNOME idle-suspend (low risk; lid-close suspend still works) ==== | |||
===== Quick (imperative) test ===== | |||
Disable idle suspend on AC power: | |||
<syntaxhighlight lang="sh"> | |||
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing' | |||
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 0 | |||
</syntaxhighlight> | |||
Optionally also disable it on battery: | |||
<syntaxhighlight lang="sh"> | |||
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing' | |||
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout 0 | |||
</syntaxhighlight> | |||
===== Declarative configuration (recommended) ===== | |||
<syntaxhighlight lang="nix"> | |||
{ lib, ... }: | |||
{ | |||
# Declaratively set GNOME dconf defaults. | |||
programs.dconf.enable = true; | |||
programs.dconf.profiles.user.databases = [ | |||
{ | |||
settings = { | |||
"org/gnome/settings-daemon/plugins/power" = { | |||
# Disable idle-suspend on AC power (keeps lid-close suspend behavior): | |||
sleep-inactive-ac-type = "nothing"; | |||
sleep-inactive-ac-timeout = lib.gvariant.mkUint32 0; | |||
# Optional: also disable idle-suspend on battery: | |||
# sleep-inactive-battery-type = "nothing"; | |||
# sleep-inactive-battery-timeout = lib.gvariant.mkUint32 0; | |||
}; | |||
}; | |||
} | |||
]; | |||
} | |||
</syntaxhighlight> | |||
After applying, log out and log back in (or reboot) to ensure GNOME picks up the updated settings. | |||
==== Workaround 3: pin nixpkgs to pre-systemd-v258 for the affected machine (higher impact) ==== | |||
If you prefer to keep GNOME idle-suspend enabled, another workaround is to pin the affected system to a nixpkgs revision before systemd v258 landed. | |||
* Commit that introduced systemd v258: https://github.com/NixOS/nixpkgs/commit/70ca21d3c4982d7f95e48688d02cd9ef6b1347f5 | |||
* Latest pre-v258 commit (pre-merge parent): https://github.com/NixOS/nixpkgs/commit/d3736636ac39ed678e557977b65d620ca75142d0. | |||
== Configuration == | == Configuration == | ||
Framework specific NixOS hardware | Framework-specific NixOS hardware configuration is bundled within the [https://github.com/NixOS/nixos-hardware nixos-hardware] project. | ||
=== AMD 7040 Series === | === AMD Ryzen 7040 Series === | ||
It is recommended to use [https://search.nixos.org/options?query=power-profiles-daemon power-profiles-daemon] over <code>tlp</code> for the AMD | It is recommended to use [https://search.nixos.org/options?query=power-profiles-daemon power-profiles-daemon] over <code>tlp</code> for the AMD Framework. | ||
* NixOS Hardware module for flakes: <code>nixos-hardware.nixosModules.framework-16-7040-amd</code> | * NixOS Hardware module for flakes: <code>nixos-hardware.nixosModules.framework-16-7040-amd</code> | ||
* NixOS Hardware module for channels: <code><nixos-hardware/framework/16-inch/7040-amd></code> | * NixOS Hardware module for channels: <code><nixos-hardware/framework/16-inch/7040-amd></code> | ||
=== Fix | === AMD Ryzen AI 300 Series === | ||
[https://docs.kernel.org/gpu/amdgpu/module-parameters.html?highlight=abmlevel Active Backlight Management] is used to reduce [https://community.frame.work/t/solved-color-issues-in-linux-6-9/52158/34 battery power consumption] | |||
* NixOS Hardware module for flakes: <code>nixos-hardware.nixosModules.framework-16-amd-ai-300-series</code> | |||
* NixOS Hardware module for channels: <code><nixos-hardware/framework/16-inch/amd-ai-300-series></code> | |||
==== NVIDIA dGPU module (RTX 5070 etc.) ==== | |||
If you have the NVIDIA dGPU module, prefer the maintained nixos-hardware NVIDIA submodule (it enables hybrid graphics with PRIME offload and provides <code>nvidia-offload <command></code>): | |||
* NixOS Hardware module for flakes: <code>nixos-hardware.nixosModules.framework-16-amd-ai-300-series-nvidia</code> | |||
* NixOS Hardware module for channels: <code><nixos-hardware/framework/16-inch/amd-ai-300-series/nvidia></code> | |||
'''IMPORTANT:''' You MUST override the PRIME PCI bus IDs for your specific system. Framework 16’s modular design means bus IDs can vary depending on installed expansion cards and NVMe drives. | |||
Example override: | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
# In your system configuration: | |||
hardware.nvidia.prime = { | |||
# Replace these values with your own system's IDs: | |||
amdgpuBusId = "PCI:XXX:YY:Z"; | |||
nvidiaBusId = "PCI:AAA:BB:C"; | |||
}; | |||
} | |||
</syntaxhighlight> | |||
Find PCI IDs: | |||
<syntaxhighlight lang="sh"> | |||
$ nix-shell -p pciutils --run 'lspci | grep -E "VGA|3D|Display"' | |||
</syntaxhighlight> | |||
Convert the hex bus/device numbers to decimal and format as <code>PCI:<bus>:<device>:<function></code>. | |||
Example: <code>c1:00.0</code> → <code>PCI:193:0:0</code>. | |||
Quick helper (optional): | |||
<syntaxhighlight lang="sh"> | |||
# Replace BDF with the lspci value like c1:00.0 | |||
BDF="c1:00.0" | |||
BUS="${BDF%%:*}"; REST="${BDF#*:}" | |||
DEV="${REST%%.*}"; FUN="${REST#*.}" | |||
printf 'PCI:%d:%d:%d\n' "$((16#$BUS))" "$((16#$DEV))" "$FUN" | |||
</syntaxhighlight> | |||
Validation (hybrid/offload): | |||
<syntaxhighlight lang="sh"> | |||
# Default: should show AMD iGPU | |||
nix-shell -p mesa-demos --run 'glxinfo -B | grep -E "OpenGL vendor|OpenGL renderer"' | |||
# Offload: should show NVIDIA dGPU | |||
nix-shell -p mesa-demos --run 'nvidia-offload glxinfo -B | grep -E "OpenGL vendor|OpenGL renderer"' | |||
# Idle power check: should become "suspended" when idle | |||
cat /sys/bus/pci/devices/0000:??:??.?/power/runtime_status | |||
</syntaxhighlight> | |||
Note: <code>nvidia-smi</code> can wake the GPU, so it is not a reliable “is the GPU sleeping?” probe. | |||
=== Fix color accuracy in Power Saving modes === | |||
[https://docs.kernel.org/gpu/amdgpu/module-parameters.html?highlight=abmlevel Active Backlight Management] is used to reduce [https://community.frame.work/t/solved-color-issues-in-linux-6-9/52158/34 battery power consumption], which can cause the colors of the screen to be inaccurate. | |||
Some desktop environments may already be able to modify this setting. | Some desktop environments may already be able to modify this setting. | ||
To disable it add the kernel parameter: | To disable it add the kernel parameter: | ||
<syntaxhighlight lang="nix"> | |||
boot.kernelParams = [ "amdgpu.abmlevel=0" ]; | |||
</syntaxhighlight> | |||
=== Prevent wake up in backpack === | === Prevent wake up in backpack === | ||
Putting your Framework in a backpack can cause it to wake up due to the screen flexing onto the keyboard. While this is not resolved in | |||
Putting your Framework in a backpack can cause it to wake up due to the screen flexing onto the keyboard. While this is not resolved in firmware, you can work around this issue with a udev rule. | |||
If you are also importing <code>nixos-hardware</code>, prefer merging (e.g. <code>lib.mkAfter</code>) rather than overwriting <code>services.udev.extraRules</code>, since nixos-hardware may install its own udev rules. | |||
<syntaxhighlight lang="nix"> | |||
{ lib, ... }: | |||
{ | |||
services.udev.extraRules = lib.mkAfter '' | |||
SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0012", ATTR{power/wakeup}="disabled", ATTR{driver/1-1.1.1.4/power/wakeup}="disabled" | |||
SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0014", ATTR{power/wakeup}="disabled", ATTR{driver/1-1.1.1.4/power/wakeup}="disabled" | |||
''; | |||
} | |||
</syntaxhighlight> | |||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ | ||
| Line 73: | Line 237: | ||
|Backlit keyboard ISO | |Backlit keyboard ISO | ||
|32ac 0018 | |32ac 0018 | ||
|- | |||
|Other devices | |||
|Use <code>lsusb</code> to find Vendor/Product IDs | |||
|} | |} | ||
This does not prevent the trackpad from waking up the device | This does not prevent the trackpad from waking up the device; this however seems to happen less in a backpack. | ||
=== BIOS configuration === | |||
Enable [https://guides.frame.work/Guide/Ubuntu+22.04+LTS+Installation+on+the+Framework+Laptop+16/306?lang=en#s1974 Linux Audio Compatibility] in the BIOS to improve speaker audio quality. | |||
[https://guides.frame.work/Guide/Ubuntu+22.04+LTS+Installation+on+the+Framework+Laptop+16/306?lang=en#s1974 | |||
== Useful utilities == | |||
Framework provides and the community maintains utilities that help manage Framework hardware. | |||
* <code>framework-tool</code> provides libraries and tools to interact with Framework-specific features. | |||
* Input modules (LED matrix / numpad) can be controlled with tools such as <code>inputmodule-control</code>. | |||
To enable input module support (if installed), set: | |||
<syntaxhighlight lang="nix"> | |||
inputmodule.enable = true; | |||
</syntaxhighlight> | |||
Example (LED matrix clock): | |||
<syntaxhighlight lang="sh"> | |||
# Serial device is often /dev/ttyACM0 (or ttyACM1 if you have two modules) | |||
inputmodule-control --serial-dev /dev/ttyACM0 led-matrix --clock | |||
</syntaxhighlight> | |||
== External resources == | == External resources == | ||
There is [https://community.frame.work/t/nixos-on-the-framework-laptop-16/46743 a NixOS thread on the Framework forum], where you can find additional help, guidance and example configurations. | |||
There is [https://community.frame.work/t/nixos-on-the-framework-laptop-16/46743 a NixOS thread on the Framework forum], where you can find additional help, guidance, and example configurations. | |||