Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Arm laptop project

The Arm laptop project

What would it take to run mainline Linux on an Arm laptop built for Windows? That was the question Linaro set out to answer in a project funded by Arm. A bit more than a year later, the Lenovo ThinkPad X13s can now be used as a daily driver while running mainline Linux without any out-of-tree patches on top.

This talk will give an overview of how this project came about; discuss some of the difficulties encountered, how they were addressed and what remains to be done; and provide a summary of the current status of the Arm laptop project.

Johan HOVOLD

Kernel Recipes
PRO

October 12, 2023
Tweet

More Decks by Kernel Recipes

Other Decks in Programming

Transcript

  1. The Arm laptop project
    Johan Hovold
    Hovold Consulting AB
    Kernel Recipes, Paris
    25 September 2023

    View Slide

  2. Introduction
    • Windows on Arm (WoA)
    • Laptops built on (Qualcomm) 64-bit Arm SoCs
    • Quiet and power efficient
    • Non-standard boot chain
    • Customised OS

    View Slide

  3. Introduction
    • Windows on Arm (WoA)
    • Laptops built on (Qualcomm) 64-bit Arm SoCs
    • Quiet and power efficient
    • Non-standard boot chain
    • Customised OS
    • What would it take to run Linux on them?

    View Slide

  4. Project overview
    • Linaro project
    • Funded by Arm and Qualcomm
    • Hardware from Qualcomm and Lenovo
    • Proof-of-concept: Mainline Linux on Arm laptop (built for Windows)
    • How far could we get?

    View Slide

  5. People
    • Johan Hovold
    • Bj¨
    orn Andersson
    • Linaro’s Qualcomm landing team
    • Building on work done by Qualcomm, Linaro and many others

    View Slide

  6. Talk outline
    • Background
    • Status
    • Work in progress
    • Open issues
    • Setup instructions
    • Distro support

    View Slide

  7. Previous work
    • Linaro and Arm collaboration
    • Try to get Linux to boot on WoA laptops
    • ASUS NovaGo TP370QL
    • HP Envy x2
    • Lenovo Mixx 630
    • Lenovo Yoga C630
    • Enable basic features
    • Investigate options for distro support (e.g. ACPI vs DT)
    • https://github.com/aarch64-laptops/
    • #aarch64-laptops on OFTC

    View Slide

  8. Lenovo ThinkPad X13s
    • Snapdragon 8xc Gen3 Compute (sc8280xp)
    • 13.3” FHD (1920x1200) display
    • 32 GB LPDDR4 (up to)
    • 1 TB NVMe SSD (up to)
    • Adreno 690 GPU
    • 2 speakers, 2 microphones, headphone jack
    • 5 MP camera
    • Wi-Fi 6E (802.11ax)
    • Bluetooth 5.1
    • 5G modem (optional)
    • 2 x USB-C 3.2 Gen 2
    • 49.5 Wh battery

    View Slide

  9. Boot firmware
    • Qualcomm and Windows on Arm
    • UEFI
    • Runtime services not available after boot (e.g. EFI variables)
    • ACPI vs DT
    • Supporting Qualcomm’s non-standard ACPI not feasible
    • DtbLoader.efi
    • Ship devicetree blob with UEFI firmware
    • Allows for generic distro installers
    • Hypervisor
    • UEFI and Linux starts in EL1
    • No virtualisation

    View Slide

  10. Work outline
    • Feature implementation and mainlining
    • Reverse engineering
    • Refactoring (technical debt)
    • Firmware requests
    • Bug fixing
    • Patch review
    • Patch tracking
    • Work-in-progress (WIP) branches
    • Support (#aarch64-laptops)

    View Slide

  11. WIP branches
    • Important fixes and features under development
    • Minimal johan defconfig
    • Rebased on RC kernels
    • Several regressions found and fixed early
    • Example: IRQ software resend in 6.5-rc1
    • 41 branches so far, latest:
    • https://github.com/jhovold/linux/tree/wip/sc8280xp-v6.6-rc2
    • Announced on #aarch64-laptops
    • Testing by early adopters
    • Repackaged with distro config (e.g. by steev)
    • Base for distro images (e.g. Ubuntu)

    View Slide

  12. Device firmware
    • Use Windows firmware files for bringup
    • Work with Lenovo and Qualcomm to get firmware released
    • Wi-Fi board file not compatible with ath11k firmware
    • Took one year to get calibration data released
    • Everything but video acceleration now in linux-firmware.git

    View Slide

  13. Mainline feature support
    • 6.0
    • Backlight
    • CPUfreq
    • Keyboard
    • Remoteproc
    • Touchpad
    • Touchscreen
    • USB
    • Watchdog
    • 6.1
    • System suspend
    • 6.2
    • Modem
    • NVMe SSD
    • PCIe (x4)
    • Thermal sensors
    • 6.3
    • Battery
    • External display
    • Internal display (*)
    • 6.4
    • Bluetooth
    • IOMMU (**)
    • RTC
    • Touchpad (alternate)
    • Wi-Fi
    • 6.5
    • Audio
    • GPU
    • USB-C orientation switching

    View Slide

  14. Work in progress
    • Camera
    • Raw sensor data
    • Software processing (e.g. debayering)
    • EFI variables1 (merged for 6.7)
    • Maximilian Luz
    • Fingerprint reader1
    • Video acceleration1
    • USB-C muxing (4-lane DisplayPort)
    • Performance optimisation (e.g. better memory bus scaling)
    • Power consumption
    1Supported in WIP branches

    View Slide

  15. Power consumption
    • Idle: 3.2 W (15 h)2
    • Suspend: 1.7 W (29 h)
    • Suspend to idle
    • Not yet hitting deepest low-power state
    2Backlight at 66%, PCIe ASPM, Xorg, Wi-Fi

    View Slide

  16. Audio
    • Speakers, microphones, headphone jack and DisplayPort working in 6.5
    • Late fix for speaker and headphone distortion
    • Kernel, topology and UCM files need to be updated in lock step
    • Known issues
    • Pops and clicks (partial fix in WIP branch)
    • Microphone distortion

    View Slide

  17. GPU
    • Adreno 690 support in Linux 6.5 and Mesa 23.1
    • Rob Clark
    • Important fix in Mesa 23.1.4 (Firefox crash)
    • Extracted a690 GMU firmware not (yet) in linux-firmware
    • Driver will use a660 GMU firmware in 6.6 (and 6.5.3)
    • Use symlink before 6.5.3
    # ln -s a660_gmu.bin a690_gmu.bin

    View Slide

  18. Bluetooth
    • Unique device address (BD ADDR) stored externally
    • Need details from Qualcomm (or reverse engineer)
    • No support in bluetoothd for setting custom or random address
    • https://github.com/bluez/bluez/issues/107
    • Must be set manually (or using systemd service) for now
    • Similar problem with Wi-Fi MAC address
    • Falls back to random address
    # btmgmt --index 0 public -addr 00:11:22:33:44:55

    View Slide

  19. Remote processors
    • Qualcomm protection-domain mapper daemon (pd-mapper)
    • https://github.com/andersson/pd-mapper
    • Reads configuration shipped with remoteproc firmware
    • Tells remote processors which services to start
    • Tells kernel where to find services
    • Audio
    • Battery
    • USB-C Alternate Mode
    • Battery may not charge if pd-mapper not running
    • Depends on Qualcomm IPC Router name service (qrtr-ns)
    • https://github.com/andersson/qrtr
    • Functionality should be moved to kernel and devicetree

    View Slide

  20. Second-source devices
    • X13s comes with one of two touchpad controllers
    • Boot firmware should determine which one is populated
    • Update the devicetree accordingly

    View Slide

  21. Touchpad devicetree
    &i2c21 {
    touchpad@15 {
    compatible = "hid -over -i2c";
    reg = <0x15 >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "disabled";
    };
    touchpad@2c {
    compatible = "hid -over -i2c";
    reg = <0x2c >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "disabled";
    };
    };

    View Slide

  22. Touchpad devicetree
    &i2c21 {
    touchpad@15 {
    compatible = "hid -over -i2c";
    reg = <0x15 >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "disabled";
    };
    touchpad@2c {
    compatible = "hid -over -i2c";
    reg = <0x2c >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "okay";
    };
    };

    View Slide

  23. Second-source devices (cont.)
    • X13s firmware does not support this
    • Linux needs to probe both touchpads
    • HID driver already checks if a device is present
    • Used for optionally populated devices (e.g. the X13s touchscreen)

    View Slide

  24. HID driver probe
    int i2c_hid_core_probe (struct i2c_client *client , ...)
    {
    ...
    i2c_hid_core_power_up ();
    /* Make sure there is something at this address */
    ret = i2c_smbus_read_byte (client);
    if (ret < 0) {
    i2c_hid_core_power_down ();
    return -ENODEV;
    }
    hid = hid_allocate_device ();
    ...
    hid_add_device (hid);
    return 0;
    }

    View Slide

  25. Touchpad devicetree
    &i2c21 {
    touchpad@15 {
    compatible = "hid -over -i2c";
    reg = <0x15 >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "okay";
    };
    touchpad@2c {
    compatible = "hid -over -i2c";
    reg = <0x2c >;
    interrupts = <182 IRQ_TYPE_LEVEL_LOW >;
    vdd -supply = <&vreg_3p3 >;
    status = "okay";
    };
    };

    View Slide

  26. Asynchronous probe woes
    • Devices can be probed in parallel

    View Slide

  27. Asynchronous probe woes
    • Devices can be probed in parallel
    • Interrupt mapping race in IRQ core
    • Affects all shared interrupts
    • Two mappings for the same interrupt line
    • Touchpad interrupts dismissed as spurious
    • Irqdomain locking fixes merged in 6.4

    View Slide

  28. Asynchronous probe woes
    • Devices can be probed in parallel
    • Interrupt mapping race in IRQ core
    • Affects all shared interrupts
    • Two mappings for the same interrupt line
    • Touchpad interrupts dismissed as spurious
    • Irqdomain locking fixes merged in 6.4
    • ”Shared” resources claimed temporarily
    • Check existence before acquiring resources
    • Interrupt regression in 6.6-rc1
    • Problem: A reset GPIO can not be shared

    View Slide

  29. Asynchronous probe woes
    • Devices can be probed in parallel
    • Interrupt mapping race in IRQ core
    • Affects all shared interrupts
    • Two mappings for the same interrupt line
    • Touchpad interrupts dismissed as spurious
    • Irqdomain locking fixes merged in 6.4
    • ”Shared” resources claimed temporarily
    • Check existence before acquiring resources
    • Interrupt regression in 6.6-rc1
    • Problem: A reset GPIO can not be shared
    • Some resources claimed before HID driver probes
    • Move pin configuration to parent bus node (hack)
    • Or allow sharing?

    View Slide

  30. Asynchronous probe woes
    • Devices can be probed in parallel
    • Interrupt mapping race in IRQ core
    • Affects all shared interrupts
    • Two mappings for the same interrupt line
    • Touchpad interrupts dismissed as spurious
    • Irqdomain locking fixes merged in 6.4
    • ”Shared” resources claimed temporarily
    • Check existence before acquiring resources
    • Interrupt regression in 6.6-rc1
    • Problem: A reset GPIO can not be shared
    • Some resources claimed before HID driver probes
    • Move pin configuration to parent bus node (hack)
    • Or allow sharing?
    • Extend devicetree specification?
    • Mark devices as mutually exclusive
    • Force sequential probe

    View Slide

  31. Bootloader handover
    • Resources may have been (left) enabled by boot firmware
    • Clocks
    • Regulators
    • Power domains
    • Interconnects
    • Handover should be seamless (e.g. EFI framebuffer)
    • Disable any resources not needed to save power

    View Slide

  32. Handover problems
    • Unused clocks and power domains disabled at late init
    • Breaks display handover when display driver built as module
    • Workaround: clk ignore unused and pd ignore unused
    • Ignoring wastes power
    • Fails to disable unused clocks for modular clock drivers

    View Slide

  33. Handover problems
    • Unused clocks and power domains disabled at late init
    • Breaks display handover when display driver built as module
    • Workaround: clk ignore unused and pd ignore unused
    • Ignoring wastes power
    • Fails to disable unused clocks for modular clock drivers
    • Unused regulators disabled 30 seconds after late init
    • Breaks early console unless display driver in initramfs
    • Example: Rescue shell or full-disk encryption

    View Slide

  34. Handover problems
    • Unused clocks and power domains disabled at late init
    • Breaks display handover when display driver built as module
    • Workaround: clk ignore unused and pd ignore unused
    • Ignoring wastes power
    • Fails to disable unused clocks for modular clock drivers
    • Unused regulators disabled 30 seconds after late init
    • Breaks early console unless display driver in initramfs
    • Example: Rescue shell or full-disk encryption
    • Interconnect state synced when all consumers’ drivers are bound
    • Power state left at maximum if driver fails to probe
    • Example: Firmware missing (video acceleration)
    • Example: Driver disabled

    View Slide

  35. Disabling unused resources
    • Need common mechanism for disabling unused resources
    • Could be built on device links and sync-state mechanism, which triggers when all
    consumers’ drivers are bound
    • Also need timer for consumers that fail to probe?
    • Timer extended when a driver is bound (cf. deferred probe)
    • Trigger state sync on expiry
    • Problem: Need to pause timer in rescue shell
    • Alternative: User space triggers sync when booted
    • Use existing state synced sysfs interface?

    View Slide

  36. Future work
    • Camera ISP
    • Bluetooth BD ADDR and Wi-Fi MAC address
    • Hibernation
    • Keyboard special keys (e.g. mic mute)
    • Thermal throttling, non-CPU (e.g. GPU, DSP, charger, radio)
    • Trusted Platform Module (TPM)
    • USB Power Delivery (USB-PD)
    • Virtualisation

    View Slide

  37. Future work
    • Camera ISP
    • Bluetooth BD ADDR and Wi-Fi MAC address
    • Hibernation
    • Keyboard special keys (e.g. mic mute)
    • Thermal throttling, non-CPU (e.g. GPU, DSP, charger, radio)
    • Trusted Platform Module (TPM)
    • USB Power Delivery (USB-PD)
    • Virtualisation

    View Slide

  38. Getting started with X13s
    • Linux 6.5 (mainline or WIP)
    • https://github.com/jhovold/linux/tree/wip/sc8280xp-v6.5
    • make johan defconfig
    • linux-firmware-20230919
    • ln -s a660 gmu.bin a690 gmu.bin
    • qcvss8280.mbn (with WIP branch)
    • alsa-ucm-conf 1.2.10 + volume fixes
    • https://github.com/alsa-project/alsa-ucm-conf/pull/335
    • Mesa 23.1.4
    • Qualcomm pd-mapper and qrtr-ns daemons
    • https://github.com/andersson/pd-mapper
    • https://github.com/andersson/qrtr

    View Slide

  39. Kernel command line
    • clk ignore unused (generic issue)
    • pd ignore unused (generic issue)
    • arm64.nopauth (firmware bug)
    • efi=noruntime (firmware bug)
    • iommu.passthrough=0 iommu.strict=0 (USB throughput)
    • pcie aspm.policy=powersupersave (PCIe ASPM)

    View Slide

  40. Initramfs
    • Modules needed to boot
    • nvme, phy qcom qmp pcie, pcie qcom
    • Modules needed for early console (optional)
    • i2c hid of, i2c qcom geni
    • leds qcom lpg, pwm bl
    • qrtr, pmic glink altmode, gpio sbu mux, phy qcom qmp combo
    • panel edp, msm, phy qcom edp
    • Depends on config
    • Documented in commit message for johan defconfig
    • Missing display dependency can break EFI framebuffer

    View Slide

  41. Distro support
    • https://launchpad.net/~ubuntu-concept/+archive/ubuntu/x13s
    • https://fedoraproject.org/wiki/Thinkpad_X13s
    • https://wiki.debian.org/InstallingDebianOn/Thinkpad/X13s

    View Slide

  42. Summary
    • Lenovo ThinkPad X13s well supported by mainline Linux 6.5
    • More features under way (e.g. camera)
    • Working on improving suspend power consumption

    View Slide

  43. Wiki
    • For updated status, known issues and other resources, see:
    • https://github.com/jhovold/linux/wiki/X13s

    View Slide

  44. View Slide