Lenovo ThinkPad X13s

From Gentoo Wiki
(Redirected from ThinkPad X13s)
Jump to:navigation Jump to:search
This article has been flagged for not conforming to the wiki guidelines. Please help Gentoo out by starting fixing things.

The Lenovo ThinkPad X13s is an ARM64 based laptop with good support under Linux and Gentoo. Most features work flawlessly with a few still being under active development. For details on the support of each feature check this page.

This laptop isn't the fastest ever, but performs well and gets 12-16 hours of battery life under normal use conditions.

Hardware

Standard

Device Make/model Status Vendor ID / Product ID Kernel driver(s) Kernel version Notes
CPU Qualcomm Snapdragon 8cx Gen 3 Works N/A N/A 6.7.3
iGPU Qualcomm Adreno™ 690 GPU Works N/A N/A 6.7.3
SSD Micron Technology Inc 2450 NVMe SSD Works 1344:5411 nvme 6.7.3
Sound N/A Works N/A N/A 6.7.3
Wi-Fi Qualcomm Wi-Fi® 6E WCN6855 Works 17cb:1103 ath11k_pci 6.7.3
Bluetooth Qualcomm Wi-Fi® 6E WCN6855 Works 17cb:1103 N/A 6.7.3
Webcam N/A Not tested N/A N/A N/A

Detailed information

root #lscpu
Architecture:           aarch64
  CPU op-mode(s):       32-bit, 64-bit
  Byte Order:           Little Endian
CPU(s):                 8
  On-line CPU(s) list:  0-7
Vendor ID:              ARM
  Model name:           Cortex-A78C
    Model:              0
    Thread(s) per core: 1
    Core(s) per socket: 4
    Socket(s):          1
    Stepping:           r0p0
    CPU(s) scaling MHz: 100%
    CPU max MHz:        2438.3999
    CPU min MHz:        300.0000
    BogoMIPS:           38.40
    Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp uscat ilrcpc flagm
  Model name:           Cortex-X1C
    Model:              0
    Thread(s) per core: 1
    Core(s) per socket: 4
    Socket(s):          1
    Stepping:           r0p0
    CPU(s) scaling MHz: 28%
    CPU max MHz:        2995.2000
    CPU min MHz:        825.6000
    BogoMIPS:           38.40
    Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp uscat ilrcpc flagm
NUMA:                   
  NUMA node(s):         1
  NUMA node0 CPU(s):    0-7
Vulnerabilities:        
  Gather data sampling: Not affected
  Itlb multihit:        Not affected
  L1tf:                 Not affected
  Mds:                  Not affected
  Meltdown:             Not affected
  Mmio stale data:      Not affected
  Retbleed:             Not affected
  Spec rstack overflow: Not affected
  Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:           Mitigation; __user pointer sanitization
  Spectre v2:           Mitigation; CSV2, BHB
  Srbds:                Not affected
  Tsx async abort:      Not affected
root #lspci -nnk
0002:00:00.0 PCI bridge [0604]: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port [17cb:010e]
        Kernel driver in use: pcieport
0002:01:00.0 Non-Volatile memory controller [0108]: Micron Technology Inc 2450 NVMe SSD [HendrixV] (DRAM-less) [1344:5411] (rev 01)
        Subsystem: Micron Technology Inc 2450 NVMe SSD [HendrixV] (DRAM-less) [1344:0100]
        Kernel driver in use: nvme
0004:00:00.0 PCI bridge [0604]: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port [17cb:010e]
        Kernel driver in use: pcieport
0006:00:00.0 PCI bridge [0604]: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port [17cb:010e]
        Kernel driver in use: pcieport
0006:01:00.0 Network controller [0280]: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter [17cb:1103] (rev 01)
        Subsystem: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter [17cb:0108]
        Kernel driver in use: ath11k_pci
        Kernel modules: ath11k_pci
root #lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 06cb:00fc Synaptics, Inc. 
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
root #lsusb -vt
/:  Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 004: Dev 002, If 0, Class=Vendor Specific Class, Driver=[none], 12M
        ID 06cb:00fc Synaptics, Inc. 
/:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/2p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
/:  Bus 004.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 005.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
/:  Bus 006.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub

Installation

Installing Gentoo on the ThinkPad X13s is very similar to how one installs Gentoo on just about any EFI-based laptop. The main parts that need special attention are the GPU and the kernel/dtb (plus firmware blobs).

Requirements and constraints

Due to the "freshness" of all the x13s kernel and devicetree bits, the install path starts with building a kernel and creating a bootable USB stick for this device. This can either be done natively (on another arm64 device) or using a cross-compiler and qemu. Either of these methods will also require some additional hardware, either a USB-C flash drive or a small USB-C dock/hub with type-A USB ports (a USB-C ethernet adapter can also be very helpful).

Although the walk-through document uses windows boot manager, the preferred tool is efibootmgr.

The Gentoo arm64 USB image does not seem to successfully boot, but there is a custom Arch boot image that does and it has all the tools necessary to install Gentoo on it.

NOTE: For now it is necessary to cross(or native) build the initial kernel for the device (and the boot stick!!) using the WIP branches listed below in order to have the proper thermal throttling.

Options to Modify the Boot Menu

How to get the Gentoo grub install to boot by default? There are several options:

  • the walkthrough below uses the debian installer to get the grub shell, to run an EFI shell, and then use the bcfg command
  • instead, add an EFI shell to your boot stick and/or internal SSD (use the EDK2 link below and follow debian wakthrough)
  • if efi runtime is working, use efibootmgr as mentioned above
  • install refind

Note recent version of the UEFI BIOS should have a UI to edit the order of boot menu entries, but new entries cannot be created that way.

Web Resources

The install walk-through for the hacked debian installer .iso can be a helpful resource. Other related repositories and readme files may also be of interest:

Kernel

Since kernel patches are still in the patch queue/review process, the working patch set is on several branches in this repo but be sure and check for the latest branch version(s). Use one of the configs in the kernel source to start; a good choice is laptop_defconfig.

Multiple kernel branch versions are (relatively) current/available depending on needs/level of risk tolerance:

  • lenovo-x13s-linux-6.5.y
  • lenovo-x13s-linux-6.6.y
  • lenovo-x13s-linux-6.7.y

It is recommended to clone with a depth of 1 initially; the default (manual) kernel install paths work fine (see example in grub.cfg snippet).

root #cd /usr/src
root #git clone --depth 1 https://github.com/steev/linux.git -b lenovo-x13s-linux-6.7.y
root #cd linux
root #make -j9 laptop_defconfig all modules_install install dtbs_install

initrd

When generating an initrd make sure the following kernel modules are included and loaded early, to ensure the display output is working.

The list below was scraped from one of the install docs. Depending on which tools are used to generate the initrd, all or some of those might be included automatically. Note that dracut does not really provide an easy way to include an arbitrary set of firmware blobs; if the dracut initramfs doesn't work with the chosen kernel, then see below (or use genkernel instead).

Dracut

When using dracut to build the initrd, add a configuration file that looks like this:

FILE /etc/dracut.conf.d/20_thinkpad-x13s.conf
force_drivers+=" nvme phy_qcom_qmp_pcie pcie_qcom 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 "

With nothing else in the above config, a minimal but working initramfs of approx. 12 MBs can be generated via the following:

root #dracut --kver 6.6.2 -m "kernel-modules rootfs-block base"

Note the version shown above is just an example, and the argument is only required if building for a non-running kernel.

To make a somewhat larger initramfs with dracut and use the same set of firmware sub-directories used in the genkernel example requires some manual work to create an "overlay" tree, which can then be used by the one-time-only --include argument with the following config file, e.g.,

root #dracut --kver 6.7.3+ --include initrd-fw-tree / --force
FILE /etc/dracut.conf.d/20_thinkpad-x13s.conf
force_drivers+=" nvme phy_qcom_qmp_pcie pcie_qcom 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 "

dracutmodules+=" kernel-modules rootfs-block udev-rules base fs-lib shutdown "

Note that in the above command, the included path initrd-fw-tree is a local firmware directory tree (relative to the root dir) with a small subset of firmware directories and their respective contents. Create the overlay tree first using something like the following:

root #cd /lib/firmware/
root #mkdir -p ~/initrd-fw-tree/lib/firmware/qcom
root #cp -a ./{qca,ath10k,ath11k,ath6k,RTL8192E,regulatory.db*} ~/initrd-fw-tree/lib/firmware/
root #cp -a qcom/sc8280xp ~/initrd-fw-tree/lib/firmware/qcom/

Genkernel

The primary requirements for a working initramfs (meaning one that activates the peripherals) are a handful of modules and firmware blobs. Most of the config options are up to the user, however, the required bits are shown below:

FILE /etc/genkernel.conf
# Add in early microcode support: this sets the kernel options for early microcode loading
# Possible values: empty/"no", "all", "intel", "amd"
MICROCODE=""
...
FIRMWARE="yes"
...
# Specify a comma-separated list of firmware files or directories to include,
# relative to FIRMWARE_DIR (if FIRMWARE option above is set to YES
# and ALLFIRMWARE is set to NO).
FIRMWARE_FILES="qcom/sc8280xp,qca,ath10k,ath11k,ath6k,RTL8192E,regulatory.db"
...
#AMODULES_group="module-to-include another-module"
AMODULES_nvme="nvme phy_qcom_qmp_pcie pcie_qcom 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"

Note that using ALLFIRMWARE=yes does work, however the generated initramfs is over 60 MBs compressed. The "base" config shown above should result in an initramfs file about half as big. Refer to the genkernel page for more info. The following command should work to generate just the initramfs file:

root #genkernel initramfs

Bootloader

No u-boot here, just EFI BIOS firmware and any of the usual EFI bootloaders, ie, Grub works with both install modes, as well as an EFI stub kernel. Either of these methods requires both an initramfs and the devicetree blob passed to the kernel (note: install grub with efi support and devicetree patches otherwise grub will not add devicetree to the config so it must be added manually instead).

Certain kernel parameters are required to get the system to boot and run optimally. These can be added to the default grub config as shown below.

FILE /etc/default/grub
GRUB_CMDLINE_LINUX="efi=noruntime pd_ignore_unused clk_ignore_unused arm64.nopauth"
  • pd_ignore_usused - keeps some power domains from being erroneously turned off
  • clk_ignore_unused - keeps some clocks from being erroneously turned off, this keeps the display from turning off immediately after boot
  • for pre-6.7 kernels, include pcie_aspm.policy=powersupersave to enable PCIe ASPM
  • for 6.7.0 or later kernels, efi=noruntime can be removed if the Linux boot option is enabled in the bios

If using the grub devicetree patches, then also add the following:

FILE /etc/default/grub
GRUB_DEFAULT_DTB="qcom/sc8280xp-lenovo-thinkpad-x13s.dtb"

After adding these be sure to run the following command in order to have them added to the grub config:

root #grub-mkconfig -o /boot/grub/grub.cfg

After installing a new kernel and running grub-mkconfig, if not using the patched grub from the overlay, remember to add the following line to each boot stanza in grub.cfg, using the local version, path, etc:

FILE /boot/grub/grub.cfg
devicetree	/boot/dtbs/6.3.0-rc2-x13s-r0/qcom/sc8280xp-lenovo-thinkpad-x13s.dtb

User-space

The user-space configuration consists mainly of firmware blobs (not yet in linux-firmware) and some Qualcomm-specific user-space daemons borrowed from Android. The latest a690 GPU support should be in the current mesa package(s).

  • Alarm x13s repo - WLAN/BT, GPU, Audio firmware (sys-firmware/x13s-firmware)
    • reinstall linux-firmware without the USE=savedconfig if done previously for this machine
    • use the latest non-live ebuild versions for both x13s-firmware and linux-firmware (>=linux-firmware-20231211 and >=x13s-firmware-20231030-r1)
  • qrtr - namespace daemon for net/qrtr in the Linux kernel (sys-power/qrtr-1.1)
  • pd-mapper - Qualcomm Protection Domain mapper daemon (sys-power/pd-mapper-1.0)
    • install and configure the firmware and sys-power/pd-mapper as shown below
  • audio config - ALSA UCM configuration files (media-libs/alsa-ucm-conf). The current working version is 9999 from the overlay below or master branch from upstream

In-progress ebuilds for the above can be found in the embedded overlay. Be sure to install and activate the overlay before installing an actual desktop, eg, Gnome or XFCE. Manually installing sys-firmware/x13s-firmware and sys-power/pd-mapper along with one of the big desktops should pull in all the required bits.

To configure bluetooth and the Qualcomm user-space bits:

root #emerge linux-firmware x13s-firmware -v --ask
root #emerge sys-power/pd-mapper -v --ask

Edit /etc/conf.d/bdaddr and change the last 3 octets

root #rc-update del bluetooth
root #rc-update add bdaddr
root #rc-update add pd-mapper
root #openrc

Post-install

These devices are generally "new" enough to need BIOS firmware updates, which can be obtained from the Lenovo support page. If the device no longer has the vendor-installed OS, follow the steps here to create a bootable USB stick for updating the BIOS firmware. Selecting the USB disk from the (BIOS) Boot Menu will automatically launch the EFI firmware installer.

Possibly some configuration nits may also need to be addressed; feel free to add your own here.

Audio

In order to get audio working install PipeWire with PulseAudio emulation

  1. Install media-video/pipewire with pipewire-alsa and sound-server USE flags enabled
  2. Install media-video/wireplumber
  3. Install media-sound/pulseaudio with -daemon USE flag disabled
  4. Globally enable the pulseaudio USE flag in make.conf so that applications will use the PulseAudio API to talk to PipeWire
  5. Add your user to the pipewire group
root #usermod -aG pipewire larry

If running a minimalist desktop that does not take advantage of autostart files, add the gentoo-pipewire-launcher command to the .xinitrc file:

user $nohup gentoo-pipewire-launcher restart &

There are some audio glitches when using Firefox with PipeWire on the x13s. To fix these, either switch to PulseAudio or decrease the max-quantum as a workaround:

user $pw-metadata -n settings 0 clock.max-quantum 1024

Video Acceleration

Working video acceleration requires the qcvss8280.mbn firmware blob. Due to legal issues this is not yet included in the sys-kernel/linux-firmware packgae. Either copy it from the windows partition or download it from Lenovo's website. It's in the GPU driver package. The file can be extracted after unpacking with innoextract:

user $innoextract n3hdr19w.exe
  1. Place the qcvss8280.mbn file in the /lib/firmware/qcom/sc8280xp/LENOVO/21BX/ directory.
  2. Enable VIDEO_CARDS="freedreno"
  3. Enable USE="vulkan zink"
  4. Recompile everything necessary
  5. Add your user to the video group
FILE /etc/portage/make.conf
USE="vulkan zink"
VIDEO_CARDS="freedreno"
root #emerge -uDavN @world
root #usermod -aG video larry

This should make video acceleration work and allow a few hours extra battery life.

Troubleshooting

f0 respawning

With a default arm64 system, error messages like this may appear both on the default TTY and in the system log:

Id "f0" respawning too fast: disabled for 5 minutes

To get rid of those, edit the inittab at /etc/inittab and remove or comment out the last line, that looks something like this:

FILE /etc/inittab
# Architecture specific features
f0:12345:respawn:/sbin/agetty 9600 ttyAMA0 vt100

Then, restart the system.

Clock loses time on reboot

The default configuration may not assume a builtin RTC with a battery, so check the following config and go ahead and treat this device like a real laptop (NTP use is completely optional).

FILE /etc/conf.d/hwclock
clock_hctosys="YES"
clock_systohc="YES"

MAC Address changes on reboot

For some reason the MAC address of the wireless card changes every time the system is rebooted. This can be frustrating if using Static DHCP or MAC FIltering on the local network. In order to fix this, add a udev rule to set the MAC address. Simply fill in the X's with the desired MAC address:

FILE /etc/udev/rules.d/99-wifi-mac.rules
ACTION=="add", SUBSYSTEM=="net", KERNELS=="0006:01:00.0", RUN+="/bin/ip link set dev $name address XX:XX:XX:XX:XX:XX"

External resources