I moved from my Thinkpad X13 Gen1 to the new Framework 13 Pro just putting my nvme ssd in the new machine (with some groundwork done).
Disk swap 29 Sep 2026. Tuning until 24 Oct 2026. xe page-flip issue: quiet since 7.4-rc1 + BIOS 03.04 (4 Nov 2026), cause not identified. Notes, not a story.
- NVMe moved into the new laptop, no reinstall.
- Stack: LUKS2 → LVM → btrfs/snapper, systemd-boot, hibernate to a 40 GB swap LV, sway + kanshi + waybar.
- Everything identifying the system (LUKS UUID, VG name, FS UUIDs) is on the disk. Only the device-specific layer needed work.
Old: ThinkPad X13 Gen 1
- Ryzen 7 PRO 4750U, amdgpu, acpi-cpufreq
- 1920×1080, scale 1.0
- Battery 78 % health, 1389 cycles
New: Framework Laptop 13 Pro
- Core Ultra X7 358H (Panther Lake), Arc B390 (xe), intel_pstate + HWP
- 2880×1920 @ 120 Hz
- 73.1 Wh, BIOS 03.02, since 4 Nov 03.04
Preparation (on the X13)
- Intel packages installed in advance:
intel-ucode, sof-firmware, vulkan-intel, intel-media-driver, thermald. Both microcode packages stay; disk boots on either CPU.
- modprobe leftovers deleted:
i915.conf, amdgpu overdrive mask, iwlwifi tweak, thinkfan blacklists.
MODULES=() in mkinitcpio.conf (was amdgpu). Autodetect picks the hardware.
- USB wake rule: X13 PCI addresses removed, RTL8153 vendor/product line kept.
- sway:
input type:touchpad instead of a device identifier.
- NetworkManager:
interface-name= removed from ~100 Wi-Fi profiles.
- Power script: Intel branch added, tested against mocked sysfs trees.
First boot
- Boot via firmware fallback
\EFI\BOOT\BOOTX64.EFI (new NVRAM knows no systemd-boot), fallback initramfs (regular one had only X13 modules).
- No failed units, no AppArmor denials.
- RTC at 2025-01-01. NTP fixed it; early journal lines carry wrong timestamps.
| Component |
Out of the box |
| Kernel / microcode |
linux 7.2.7, intel-ucode early (0x11a → 0x11c), also from fallback initramfs |
| GPU |
xe, Arc B390 (Xe3), GuC 70.72.1, HuC 10.3.3, GSC loaded |
| VA-API |
iHD 26.2.4: AV1, HEVC, VP9 decode + encode |
| Display |
eDP-1 2880×1920, sway auto-scale 2.0 |
| Wi-Fi |
iwlwifi, CNVi 8086:e440 |
| Audio |
SOF, PipeWire sink + source, mic ok |
| Bluetooth / webcam |
controller up; /dev/video0, /dev/video1 |
| Fingerprint |
Goodix MOC via fprintd |
| EC / sensors |
cros_ec: temperatures, fan, battery via hwmon |
| Storage |
LUKS discard reaches the LVs, 40 GB swap, zswap on |
| Power |
intel_pstate + HWP, ppd with platform_profile (low-power / balanced / performance), suspend = s2idle only |
| Expansion cards |
HDMI card, USB-Ethernet RTL8153 |
Day-one changes
/etc/modules-load.d/: acpi-cpufreq out (not on intel_pstate), acpi_call out (tainted kernel for years).
- Packages removed:
thinkfan, acpi_call-dkms, xf86-video-amdgpu, radeontool. vulkan-radeon stays (steam, zed depend on it).
- Bootloader into the new NVRAM. Entries, cmdline,
resume=, mapper paths unchanged:
mkinitcpio -P # regular initramfs now has xe, iwlwifi, SOF
bootctl install # "Linux Boot Manager" into NVRAM
efibootmgr -B -b 0003 # dead Windows entries from the
efibootmgr -B -b 0004 # Framework's original SSD
thermald: installed but disabled → enabled.
- Regulatory domain:
country 00: DFS-UNSET in dmesg → WIRELESS_REGDOM="DE" in /etc/conf.d/wireless-regdom. Check: iw reg get.
- Lid is
LID0, not LID. Lid-close script globs /proc/acpi/button/lid/*/state. Old path: hibernate timer would never arm.
- Taint after cleanup: 12288, only unsigned vboxhost DKMS modules.
HiDPI
- Console: 16 px default = 240×67 characters.
FONT=latarcyrheb-sun32 (kbd) in /etc/vconsole.conf, then mkinitcpio -P; sd-vconsole embeds the font (LUKS prompt).
- sway: auto scale 2.0 = 1440×960 logical, too small.
output eDP-1 scale 1.5 = 1920×1280 logical, X13 width plus 3:2 height.
- kanshi profiles:
mode 2880x1920@120Hz … scale 1.5. External monitors at 1.0.
- swaylock:
scaling=center for the 1920×1080 lock image.
AC / battery switching
- One script,
/usr/local/bin/power-source ac|battery, one udev rule. Hardware detected from sysfs, same files on both laptops.
# /etc/udev/rules.d/61-power-source.rules (AC* matches "AC" on the X13 and "ACAD" on the Framework)
SUBSYSTEM=="power_supply", KERNEL=="AC*", ATTR{online}=="0", RUN+="/usr/local/bin/power-source battery"
SUBSYSTEM=="power_supply", KERNEL=="AC*", ATTR{online}=="1", RUN+="/usr/local/bin/power-source ac"
- Platform profile:
powerprofilesctl set power-saver / performance. On Intel, ppd also sets EPP.
- cpufreq by driver:
acpi-cpufreq (X13): boost 0/1, governor conservative/schedutil.
intel_pstate (FW13): governor stays powersave, only intel_pstate/no_turbo toggled (1 = turbo off).
- xe GPU:
/sys/class/drm/card*/device/tile*/gt*/freq0/power_profile = power_saving on battery, base on AC. Missing on amdgpu → skipped.
- Backlight: first writable
/sys/class/backlight/*, 20 % on every switch. brightnessctl fails in the udev sandbox → raw sysfs.
vm.dirty_writeback_centisecs 1500 / 500.
- Recoll indexer:
systemctl --user stop on battery, start on AC. Drop-in ConditionACPower=true for logins on battery.
- Logging:
logger -t power-source. Debug: journalctl -b -u systemd-udevd | grep power-source.
Panel refresh: 120 Hz on AC, 60 Hz on battery
Charge limit
framework_tool --charge-limit 80 as root. Stored in the EC, survives reboots, no service (unlike the ThinkPad’s sysfs threshold).
Wake sources
- Goal: only lid, power button, internal keyboard wake from suspend. No USB, Thunderbolt, dock hotplug.
- Addresses from the last column of
/proc/acpi/wakeup.
# /etc/udev/rules.d/52-usb-wakeup.rules (Framework 13 Pro, Panther Lake)
SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8153", ATTR{power/wakeup}="disabled" # dock Ethernet
SUBSYSTEM=="pci", KERNEL=="0000:00:14.0", ATTR{power/wakeup}="disabled" # XHCI: camera, fingerprint, USB-2 side of the cards
SUBSYSTEM=="pci", KERNEL=="0000:00:0d.0", ATTR{power/wakeup}="disabled" # TXHC: USB-3 side of the four USB-C ports
SUBSYSTEM=="pci", KERNEL=="0000:00:0d.2", ATTR{power/wakeup}="disabled" # TDM0 Thunderbolt NHI
SUBSYSTEM=="pci", KERNEL=="0000:00:0d.3", ATTR{power/wakeup}="disabled" # TDM1
SUBSYSTEM=="pci", KERNEL=="0000:00:07.[0-3]", ATTR{power/wakeup}="disabled" # TRP0-3 Thunderbolt root ports
- PCI
power/wakeup is a value, not a toggle like /proc/acpi/wakeup. Rule is idempotent.
- After
udevadm trigger: all eight entries *disabled. Keyboard wake works (/sys/power/pm_wakeup_irq = 1, i8042 via EC).
- Hibernate unaffected.
- Opposite case: Dell mouse 413c:3010 on the USB-A card wakes from USB autosuspend only on click →
power/control=on exception in 51-runtime-pm-exceptions.rules.
Battery tuning
- Method: unplugged, 3 min idle, usual apps open (Vivaldi, Firefox, Thunderbird, terminals).
- Package:
turbostat. System: mean of BAT1 current_now × voltage_now.
- No
Pkg%pc10 on Panther Lake in turbostat; CPU%LPI instead.
| Measurement |
System |
Package |
CPU%LPI |
| 8 Oct, before |
≈ 5.3 W |
1.14 W |
24 % |
| 9 Oct, after all changes |
4.92 W |
1.11 W |
18 % |
| 9 Oct evening, baseline for single tests |
4.11 W |
0.91 W |
24 % |
- Under 0.2 W = noise (open tabs). SoC ~1 W, rest is display and platform.
- 73.1 Wh at 80 % limit → 12 to 14 h. GPU RC6 99 %, PSR2 with selective fetch active.
Helped
- Fewer display commits (powertop: ~2.6/s
intel_atomic_commit_work): waybar cpu/memory interval 10 s, custom module 60 s with signal refresh, btop update_ms = 5000.
kernel.nmi_watchdog = 0 in 99-hardening.conf (a separate 90- file was overridden by the 99 file).
- btrfs:
nodiscard instead of discard=async on all six mounts; weekly fstrim.timer.
- xe power profile and Recoll switching (above).
- sway: screen off after 5 min instead of ~16.
inhibit_idle rule for mpv dropped; paused window blocked screen-off, mpv inhibits by itself while playing.
Tested, rejected
- intel-lpmd 0.1.0. Default config does nothing (all
*Def = -1). PowersaverDef=0 pinned user.slice and system.slice to LPE cores 12–15: CPU%LPI 0 %, package 2.16 W, system 8.94 W. Shipped Panther Lake config references CPUs 16–19, which don’t exist here. Upstream main: Panther Lake moved to mode -1, SoC power slider instead; slider already at 6 (max efficiency) via ppd power-saver. Package removed.
- HDMI card pulled: 4.11 W vs 4.14 W. Already in USB suspend.
- Panel at 40 Hz (custom mode, stable): 4.16 W, no gain. PSR2 already holds static images. EDID: LCD, VRR 30–120 Hz, dark theme saves nothing either.
adaptive_sync not tried.
- Bluetooth off: not tested, needed for headphones.
Rejected page flips on xe (EBUSY)
| Kernel |
Fresh boot |
After hibernate (S4) resume |
| 7.2.9 / 7.2.11 |
~25/min from the first minute, bursts to ~500/min; 5100–11500/day |
same |
| 6.18.58 LTS |
~2/min, no freezes |
20–100/min within 10–60 min, bursts 300–400/min, until reboot |
| 7.3.0 (v7.3, unmodified) |
~4/min, no freezes |
same pattern, ~9600 in 4 h |
| 7.4.0-rc1 + BIOS 03.04 (from 4 Nov) |
1–5/min |
no degradation in 9 cycles, baseline <3/min |
- Same userspace, displays and config across kernels. BIOS 03.02 for all rows except the last.
- Trigger on 6.18/7.3: S4 resume, persistent until reboot, 7 of 7 cycles.
- S3 (s2idle) on 7.3.x: transient. Burst of 300–2000 for 20–60 min after resume, then <1/min. Five cycles on one boot, same pattern. Suspend never heals an already degraded boot.
- Hibernate from an already degraded state: no change. swayidle disabled before hibernating (no DPMS cycle on resume): delays, does not prevent.
- DPMS off/on or output disable/enable on a degraded system: immediate burst, hundreds in 2–4 min. On a fresh boot: 4-minute burst, decays.
- Single output (external unplugged before hibernating): still 10–30/min after resume.
- Distribution: ~30 % within ±1.5 s of a pointer move between outputs (~15 % of the time), ~70 % without any output switch.
Ruled out
xe.enable_psr=0 xe.enable_dc=0 xe.enable_dsb=0, 15–24 Oct: no change in rate. enable_dsb=0 added *ERROR* Atomic update failure on pipe A 84×, otherwise never seen.
- PSR off at runtime via
i915_edp_psr_debug: no change.
- External at 60 Hz, both outputs at 60 Hz: no change (paired 10-min samples in the same degraded state: 101 at 120/75 vs 263 at 60/60).
- Software cursor
WLR_NO_HARDWARE_CURSORS=1 (cursor planes fb=0 in dri/0/state): same rate. Only the distribution changed; with the HW cursor the error was mostly on the output the pointer had just left.
- wlsunset gamma updates: no correlation. IO pressure: unrelated backup job, no correlation. Input: evdev events without gaps during freezes.
Interpretation, status
- EBUSY without kernel message: non-blocking commit meets a previous commit still pending on the same CRTC. Completion late or lost.
- Display state restored on S4 resume looks wrong, every later modeset keeps it wrong. 7.2.x: bad from boot.
- Refresh rates, PSR, DC states, DSB, HW/SW cursor, matched modes all varied without effect. Pipe-to-pipe refresh mismatch unlikely.
- Related upstream: drm/xe #9582 (PTL async flip timeout after PSR2 DEEP_SLEEP), #9253 (PTL VRR stutter, DSB poll errors). Not identical: no timeout logged here, PSR off doesn’t help.
- Report for the drm/xe tracker drafted, not filed. Attachments collected: dmesg,
journalctl -b -k, i915_display_info, both EDIDs, xe module parameters. i915_vbt read hung in the degraded state, omitted.
- Snapshot script for state captures: debugfs dumps (dmc, power domains, PSR status, display info, MST, frontbuffer),
/proc/interrupts delta over 10 s, 30 s of drm.debug=0x14, page-flip count of the last 2 min.
- Not bisected. Workaround on 6.18/7.3: suspend instead of hibernate, reboot after a hibernate.
- Counting:
journalctl -b -t sway | grep -c 'Page-flip failed'.
Since 7.4-rc1 + BIOS 03.04
- 4 Nov: BIOS 03.02 → 03.04 (16 Oct 2026) and kernel 7.4.0-rc1 (linux-mainline) in the same reboot.
- One boot, 4.5 days, 9 hibernate cycles, several dock changes: no persistent degraded state. Before: 7 of 7.
- Baseline: median 2 per minute in minutes with any error, most minutes zero. Freezes no longer noticed.
- Total still 16 200 in 4.5 days. 62 % of that in 22 minutes. Three isolated bursts account for ~10 200: 5 Nov 06:35–06:42 (2500), 7 Nov 15:46–16:07 (5400), 8 Nov 09:49–10:01 (2300). No resume or modeset before them, cause unknown.
- Load tests during the first burst hunt:
stress -c 16 for 120 s, 0 errors. ffmpeg hevc_vaapi loop for 120 s, 1 error. HandBrake rerun: not reproducible.
- Kernel or firmware: not separated. 7.3.1 + BIOS 03.04 never tested.
- Tests ended 7 Nov. Hibernate on lid close back in use. Report stays unfiled unless it returns on 7.4 final.
- Remaining stutter after hibernate was a different problem: swap-in of desktop apps. Hibernate pushes 3–4 GB into swap before writing the image. Signature: libinput lag lines and cgroup
io.pressure, page flips quiet. vm.swappiness=10 helps partly.
sysctl hardening
- Not hardware-specific, same pass. One file,
/etc/sysctl.d/99-hardening.conf. 99 wins over /usr/lib/sysctl.d/50-default.conf.
kernel.kptr_restrict = 1 # hide kernel addresses from non-root; root keeps perf/bpftrace/oops analysis
kernel.nmi_watchdog = 0 # not security: frees a perf counter, fewer interrupts
kernel.kexec_load_disabled = 1 # no other kernel at runtime; one-way until reboot, kdump unused
net.core.bpf_jit_harden = 2 # constant blinding for all BPF JIT code, also root's
fs.protected_fifos = 2 # sticky dirs: refuse O_CREAT on someone else's FIFO
fs.protected_regular = 2 # same for regular files; 2 = also group-writable sticky dirs
dev.tty.ldisc_autoload = 0 # no auto-load of line disciplines via TIOCSETD (CVE-2017-2636 class)
net.ipv4.conf.all.send_redirects = 0 # not a router
net.ipv4.conf.default.send_redirects = 0 # interfaces created later
net.ipv4.conf.*.send_redirects = 0 # interfaces that already existed; kernel evaluates "all OR interface"
- Kernel lockdown off: Arch doesn’t enforce it with Secure Boot, and it breaks hibernate.
- Apply:
sysctl --system. Check: sysctl kernel.kexec_load_disabled net.core.bpf_jit_harden kernel.nmi_watchdog.
Journal noise, no action
spd5118 20-0050: PM: dpm_run_callback(): spd5118_resume returns -6 on every resume. RAM SPD sensor slow after s2idle; only memory temperature/EEPROM reads.
ucsi_acpi USBC000:00: con3: failed to register partner alt modes (-5), unknown error 256. Known on Framework Panther Lake; USB-C and HDMI card work.
Bluetooth: hci0: Failed to send Intel_Write_DDC (-95). Controller works.
x86/CPU: Model not found in latest microcode list. Microcode is loaded.
iio-sensor-proxy: Buffer /dev/iio:device0 did not have data within 0.5s. Orientation sensor, once at start.
50-runtime-pm.rules … Could not chase sysfs attribute. USB hubs without power/control; rule skips them.
Takeaways
- Moving the disk works. Device layer: regenerate initramfs, register bootloader in NVRAM, two modules and four packages out, one hardcoded ACPI path.
- Power-management glue against sysfs, not device names. Survives the hardware change.
- HiDPI (console font, compositor scale, refresh switching) took longer than all driver work combined.
- One hardware problem cost weeks: xe page flips after hibernate. Gone with 7.4-rc1 + BIOS 03.04, cause never identified.
Schreibe einen Kommentar