Hardware/Framework/Laptop 16: Difference between revisions

Adding hint for audio compatibility bios configuration
Atvor (talk | contribs)
Mention systemd bug resulting in idle-suspend loop
 
(15 intermediate revisions by 10 users not shown)
Line 10: Line 10:
|-
|-
!Manufacturer
!Manufacturer
|Framework
|[[Hardware/Framework|Framework]]
|-
!Support
|[https://knowledgebase.frame.work/framework-component-linux-support-matrix-B1gwmFtPgg components]
|-
|-
!Architecture
!Architecture
|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
|-
|-
!Status
|maybe supported
|}
|}
</div>
</div>


The Framework Laptop 16 is a configurable, upgradeable, and repairable laptop made by the Framework company.
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 options are bundled within the nixos-hardware project.
Framework-specific NixOS hardware configuration is bundled within the [https://github.com/NixOS/nixos-hardware nixos-hardware] project.
 
=== 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 Framework.
 
* 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>
 
=== AMD Ryzen AI 300 Series ===
 
* 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 &lt;command&gt;</code>):


=== AMD 7040 Series ===
* 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>


It is recommended to use [https://search.nixos.org/options?channel=23.11&show=services.power-profiles-daemon.enable power-profiles-daemon] over <code>tlp</code> for the AMD framework.
'''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.


=== Touchpad Palm Rejection ===
Example override:
The Framework 16 keyboard is treated as an external USB device by libinput causing the touchpad to stay enabled when typing.


Fix sourced from here: [https://community.frame.work/t/nixos-on-the-framework-laptop-16/46743/162 community.frame.work] by: [https://community.frame.work/u/sumiflow/summary @sumiflow]
<syntaxhighlight lang="nix">
environment.etc = {
{
<nowiki> </nowiki> "libinput/local-overrides.quirks".text = <nowiki>''</nowiki>
  # In your system configuration:
<nowiki> </nowiki>   [Keyboard]
  hardware.nvidia.prime = {
<nowiki> </nowiki>   MatchUdevType=keyboard
    # Replace these values with your own system's IDs:
<nowiki> </nowiki>  MatchName=Framework Laptop 16 Keyboard Module - ANSI Keyboard
    amdgpuBusId = "PCI:XXX:YY:Z";
<nowiki> </nowiki>  AttrKeyboardIntegration=internal
    nvidiaBusId = "PCI:AAA:BB:C";
<nowiki> </nowiki> <nowiki>''</nowiki>;
  };
};
}
</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:&lt;bus&gt;:&lt;device&gt;:&lt;function&gt;</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.
 
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 Firmware, you can workaround this issue with a udev rule:
services.udev.extraRules = <nowiki>''</nowiki>
<nowiki> </nowiki>  ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0012", ATTR{power/wakeup}="disabled", ATTR{driver/1-1.1.1.4/power/wakeup}="disabled"
<nowiki> </nowiki>  ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0014", ATTR{power/wakeup}="disabled", ATTR{driver/1-1.1.1.4/power/wakeup}="disabled"
<nowiki>''</nowiki>;
The Product and Vendor IDs can be found using lsusb.


This does not prevent the trackpad from waking up the device. This however seems to happen less in a 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 firmware, you can work around this issue with a udev rule.


=== Bios Configuration ===
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.
[https://guides.frame.work/Guide/Ubuntu+22.04+LTS+Installation+on+the+Framework+Laptop+16/306?lang=en#s1974 Enable Linux Audio Compatibility in the bios] to improve speaker audio quality.
 
<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"
|+
!Product
!Vendor and Product ID
|-
|RGB Macropad
|32ac 0013
|-
|Backlit keyboard ISO
|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 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.
 
== 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.