Work on the Surface Pro 12in continued and is now consolidated in a single repository:
Everything here is superseded by it, and a great deal has been learned since this snapshot (2026-07-14). Notably, all of the following now work and are documented there:
- EL2 + KVM, with the
tcblaunch.exeversion pitfall spelled out — the single factor that decides whether Secure Launch works at all- Internal Wi-Fi at EL2 — the cause was a PCIe SMMUv3 left at
status = "reserved"in the device tree, plus the false-negative test that hid it for days- Audio at EL2 — DSPs started before
ExitBootServices, then attached by the kernel instead of started- Boot brought from 30 s to 9 s, with each remaining console warning identified
- the annotated EL1→EL2 device-tree diff, and the systemd units carrying the workarounds
Please open issues and follow the work there. Thanks for reading.
Running Arch Linux ARM on the Microsoft Surface Pro 12" (1st Ed, Snapdragon) — SoC Snapdragon X Plus 8-core, x1p42100, ARM64 — a device with no upstream kernel support at the time this work began.
This builds directly on Harrison Vanderbyl's surface-pro-12-inch-linux (device tree + firmware groundwork). None of this exists without that work — thank you.
Status snapshot: 2026-07-14. The device runs as an internal dual-boot (Windows + Arch Linux ARM) with working internal display, KDE Plasma, GPU acceleration, hardware video codec, audio, and Wi-Fi.
| Component | State | Notes |
|---|---|---|
| Boot | ✅ | Custom linux-next kernel, GRUB (arm64-efi), internal dual-boot |
| Internal display (eDP) | ✅ | KDE Plasma / Wayland. Non-fatal panel-edp probe warning remains |
| GPU 3D accel | ✅ | Adreno X1-45 — OpenGL 4.6 (freedreno) + Vulkan 1.4 (turnip), Mesa 26.1 |
| HW video codec | ✅ | Decode + encode via V4L2 after supplying one firmware blob (see Fixes) |
| Audio | ✅ | Card + ADSP up, headset jack detected; topology now in linux-firmware |
| Wi-Fi | ✅ | ath12k / WCN7850 (FastConnect 7800), wpa_supplicant |
| Battery | ✅ | Gauge works via energy_* / UPower (percentage + health). charge_*/capacity return ENODATA — known upstream regression, no desktop impact |
| Suspend / resume | ❌ | Snapdragon does not resume — sleep targets masked (see Stability) |
| Surface HID (cover / sensors) | unexpected descriptor length warnings |
- SoC: Snapdragon X Plus 8-core,
x1p42100, ARM64 - GPU: Adreno X1-45 (freedreno / turnip)
- Wi-Fi/BT: Qualcomm FastConnect 7800 / WCN7850 (PCI subsystem
00ab:1414) - Audio:
X1P42100-Microsoft-Surface-Pro-12in(AudioReach / q6apm) - Internal storage: KIOXIA UFS ~477 GB (shared with Windows)
- linux-next, reference build
7.1.0-next-20260626, compiled withx1p42100support absent from stable kernels:CLK_X1P42100_GPUCC/CAMCC/VIDEOCC,CLK_X1E80100_GCC/DISPCC,PINCTRL_X1E80100built in;DRM_MSM,ATH12Kas modules. - DTB from Harrison Vanderbyl's repo (SP12 board not yet upstream), loaded by GRUB (
devicetree). - Heads-up: mainline Linux 7.2 integrates the SP12 DTS — once it lands, the custom DTB and home-compiled kernel should become unnecessary.
Linux root lives on an internal ext4 partition alongside Windows. GRUB (arm64-efi, standalone BOOTAA64.EFI on the ESP) loads /boot/Image + initramfs + DTB. Earlier iterations booted from USB (SanDisk key, then Ventoy vdisk, then USB SSD) before moving to the internal disk for reliability — see CHANGELOG.md.
The iris video codec requires qcvss8380_pa.mbn, which is not shipped in linux-firmware. Without it, dmesg spams Direct firmware load ... failed with error -2 and the codec never initializes.
Extract it from the Windows driver store (dual-boot users have it locally):
Windows/System32/DriverStore/FileRepository/qcdx8380.inf_arm64_*/qcvss8380_pa.mbn
Copy it to:
/lib/firmware/qcom/x1p42100/Microsoft/Surface12/qcvss8380_pa.mbn
If several driver versions are present, pick the one whose qcdxkmbase8380.bin matches (md5) the graphics firmware already installed on the Linux side, to keep the DX firmware set consistent.
- Do NOT blacklist
qcom_iris— blacklisting freezes boot viasync_state. Supplying the firmware is the correct fix. - After reboot you get
/dev/video0(decoder) +/dev/video1(encoder). Use them via V4L2 mem2mem:mpv --hwdec=v4l2m2m,ffmpeg -hwaccel v4l2m2m. - Note: VA-API is not the Adreno path. The
vaInitialize failedwarning in Electron/Chromium apps is harmless — video accel goes through V4L2.
The AudioReach topology X1P42100-Microsoft-Surface-Pro-12in-tplg.bin now ships in linux-firmware under qcom/x1e80100/. The ADSP firmware qcadsp8380.mbn lives under qcom/x1p42100/Microsoft/Surface12/. With both present, the card comes up (q6apm), the headset jack is detected, and PipeWire routes normally.
- Battery
charge_*sysfs return ENODATA and nocapacityfile — a known regression in recent qcom-x1e kernels. No desktop impact: UPower derives percentage and health fromenergy_*(which report correctly).cycle_count,voltage_max_designand the manufacture date are firmware placeholders. Charge-limit control andstate_of_healthare landing upstream. panel-edpprobe warning (drivers/gpu/drm/panel/panel-edp.c) — non-fatal; display works.- Surface HID descriptor warnings — cover / sensors.
- No suspend/resume — masked (see below).
- No resume from suspend on Snapdragon → mask
sleep/suspend/hibernate/hybrid-sleeptargets and set logindIdleAction=ignore,HandleLidSwitch=ignore. - Fragile USB controller under heavy load: avoid sustained I/O between two USB SSDs simultaneously (locks the bus);
usbcore.autosuspend=-1keeps USB storage from dropping (-EIO/ ext4 corruption). - Updating with
pacman -Syu: holdlinux-aarch64,systemd,mesa,vulkan-freedreno(plusmkinitcpio,linux-firmware*) inIgnorePkg, and add--ignore vulkan-mesa-implicit-layersat upgrade time, so the whole Mesa/Vulkan userspace stays on one version — a partial upgrade that bumps only part of the stack can destabilise the Adreno/turnip GPU. The custom/boot/Image+ DTB are not package-managed, so they survive upgrades untouched. - Auto-mounting a shared NTFS partition (dual-boot data): add it to
/etc/fstabwithnofail,x-systemd.automountthroughntfs-3g(the custom kernel has no in-treentfs3), so a dirty/hibernated volume can never block or delay boot.
- Harrison Vanderbyl —
surface-pro-12-inch-linux: the device tree + firmware groundwork this is built on. - Arch Linux ARM · linux-next · Mesa (freedreno / turnip) · the aarch64-laptops community.
GPL-2.0 — see LICENSE. The kernel .config and device tree derive from the Linux kernel (GPL-2.0); the helper scripts and documentation are released under the same license for consistency.