Dell XPS 13 2-in-1 (7390)

From Gentoo Wiki
Jump to: navigation, search

The Dell XPS 13 2-in-1 (7390, 2019) is an Intel Ice Lake (10th gen Core i processor, 10nm lithography) convertible, ultra portable laptop.

Hardware highlights

  • Up to Core i7-1065G7 CPU, 15W TDP
  • 11th Gen GPU, up to Iris Plus graphics
  • Up to 32GB of LPDDR4 RAM, clocked at 3773MHz
  • Up to 1TB NVMe SSD storage
  • Up to a 4K (3840x2400), 16:10 aspect ratio touchscreen with Wacom Active ES 2.0 Pen support
  • UEFI boot only

Hardware not working

  • Fingerprint reader (Goodix)
  • Camera (Intel IPU4)

Target setup

My personal system boots Gentoo as the only operating system (the included Windows 10 installation was wiped). Using Secure Boot and systemd-boot and full-disk (except ESP) LUKS encryption, with the sway window manager. My keyboard layout is United Kingdom (82-key).

make.conf

FILE /etc/portage/make.conf
COMMON_FLAGS="-O2 -pipe -march=icelake-client"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"

Wifi

Model is Intel (Killer Wireless) AX1650i and requires firmware from sys-kernel/linux-firmware. Because of the firmware, build the driver as a module, or include the firmware in your kernel build.

  • Wifi firmware: iwlwifi-Qu-c0-hr-b0-50.ucode
  • Bluetooth firmware intel/ibt-19-32-4.sfi, intel/ibt-19-32-4.ddc
KERNEL
[*] Networking support  --->
      [*] Wireless  --->
        [*] cfg80211 - wireless configuration API
        [*] Generic IEEE 802.11 Networking Stack (mac80211)
    Device Drivers  --->
      [*] Network device support  --->
        [*] Wireless LAN  --->
          [*] Intel devices
            <M> Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi)
              <M> Intel Wireless WiFi MVM Firmware support

Display

FILE /etc/portage/make.conf
VIDEO_CARDS="i965 intel"
USE="$USE vulkan"

You'll also need firmware from sys-kernel/linux-firmware in order to use the GPU. It is not recommended to build the GPU firmware into the kernel.

Firmware: i915/icl_dmc_ver1_09.bin

See also: Intel

Touchscreen

In kernels before 5.5, the Linux kernel may crash when loading the intel-lpss-pci module. When booting live media, pass the kernel parameter modprobe.blacklist=intel-lpss-pci. This will disable the touchscreen and pen input.

The patches to fix this are included in kernel versions after 5.5.0-rc1 and should be released into the stable 5.5.

If you're using sources from git, you can fetch the patches from the mfd tree, ib-mfd-doc-sparc-libdevres-5.5 branch

Wacom

Need to enable CONFIG_HID_WACOM and CONFIG_PINCTRL_ICELAKE to get a Wacom Active ES 2.0 pen to work.

KERNEL
Device Drivers  --->
  [*] Pin controllers  --->
    <M> Intel Ice Lake PCH pinctrl and GPIO driver
  HID support  --->
    Special HID drivers  --->
      <M> Wacom Intuos/Graphire tablet support (USB)

If using Xorg, set INPUT_DEVICES="wacom" in make.conf. In wayland, the pen is handled by libinput.

Bluetooth Buttons

Some active pens support a bluetooth to the laptop to start up applications. Currently, the bluetooth stack only reports that the device has connected and disconnected, not the type of button press (single, double, and long presses). See xf86-input-wacom "Bluetooth Button" for more info.

CODE wacom-bluetooth-pen.py
#!/usr/bin/python

import sys
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib

import subprocess

# ID of the device we care about
DEV_ID = sys.argv[1].replace(":", "_")

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

sender = "org.bluez"
adapterPath = '/org/bluez/hci0'
path = adapterPath + '/dev_' + DEV_ID
proxy = bus.get_object(sender, path)


def cb(*args, **kwargs):
    # 0: interface
    # 1: entry dict
    # 2: signature
    if args[0] != "org.bluez.Device1":
        return

    g = args[1].get
    is_connected = g("Connected")
    if isinstance(is_connected, dbus.Boolean) and is_connected:
        print("Connected...")
        # start your pen app, as a systemd user service so we only launch one
        subprocess.call('systemctl --user start mypaint.service'.split(' '))
    elif isinstance(is_connected, dbus.Boolean) and not is_connected:
        print("...Disconnected")
        # Dim the backlight
        subprocess.call('xbacklight -set 5'.split(' '))


proxy.connect_to_signal("PropertiesChanged", cb)

try:
    loop = GLib.MainLoop()
    loop.run()
except KeyboardInterrupt:
    loop.quit()
CODE systemd/user/wacom-bluetooth-pen@.service
[Unit]
Description=Watch for Wacom Pen BlueTooth connections

[Service]
Type=simple
Restart=on-failure
ExecStart=/path/to/wacom-bluetooth-pen.py %I

[Install]
WantedBy=bluetooth.target
CODE systemd/user/mypaint.service
[Unit]
Description=MyPaint drawing software

[Service]
Type=simple
ExecStart=/usr/bin/mypaint

(Almost) Flicker-free boot

sys-boot/plymouth-9999 supports flicker-free boot, but with a couple of noticeable flickers. Set the plymouth theme to bgrt. The i915.fastboot=1 parameter is not required.

root #echo '=sys-boot/plymouth-9999 **' >> /etc/portage/package.accept_keywords
root #emerge =plymouth-9999
root #plymouth-set-default-theme bgrt

Intel GVT

Currently iGVT-g is not supported by the i915 driver for Ice Lake. Other modes (iGVT-d, iGVT-s) have not been tested. The developers have indicated that Ice Lake would be supported in the future.

Feature request: https://github.com/intel/gvt-linux/issues/126

Experimental GuC/HuC

Since iGVT is disabled, it may be possible to get the performance/power-saving benefits of GuC/HuC since it would otherwise be incompatible with iGVT.

Set i915.enable_guc=-1 in your kernel command line to enable GuC/HuC firmware loading.

Firmware files: i915/icl_guc_33.0.0.bin, i915/icl_huc_ver8_4_3238.bin

VA-API

Set USE="vaapi" in make.conf and run:

root #emerge --ask x11-libs/libva-intel-media-driver

See bug#692244 if libva-intel-media-driver has compile errors.

Then set vaapi to use the intel-media-driver, instead of the regular intel-driver:

FILE /etc/env.d/11libva-media-driver
LIBVA_DRIVER_NAME=iHD

Applications like mpv, vlc and ffmpeg can then use hardware acceleration via vaapi. Check that the GPU is being used for video with igt-gpu-tools' intel_gpu_top. Browsers don't appear to take advantage of hardware acceleration.

Disable keyboard in tablet/tent/stand mode

KERNEL
Device Drivers  --->
      HID support  --->
        Intel ISH HID support  --->
          <M> Intel Integrated Sensor Hub
  <M> Industrial I/O support  --->
    Accelerometers  --->
      <M> HID Accelerometers 3D

Other sensors are available (e.g. Ambient Light Sensor, Gyroscope, Inclination and Rotation) in the system, they are not required to disable the keyboard in tablet mode.

Automatic rotation

You can use rot8 or iio-sensor-proxy to automatically rotate your screen. Note, these apps will rotate your screen even in laptop mode, when you may not want it to.

Finger and Pen rotates with screen

Rotating the screen won't automatically rotate the touch and pen input.

Add this to your sway config to fix touch (the pen/"tablet_tool" has issues when rotated, see below):

FILE ~/.config/sway/config
input type:touch map_to_output eDP-1
# input type:tablet_tool map_to_output eDP-1 # has issues, see below

Issue: Wacom Pen jitter

If the screen has been rotated 90 degrees, you cannot draw straight vertical or horizontal lines with a pen. There isn't a workaround yet.

Sway issue: https://github.com/swaywm/sway/issues/4613

Secure Boot

app-crypt/efitools' efi-updatevar can update the 4 secure boot variables when in setup mode. When in user mode, I copied the public databases onto the ESP and loaded them through the UEFI Setup GUI. Tip: systemctl reboot --firmware-setup reboots directly to setup without having to press the Setup key on boot (F2).

Signed UEFI executable by dracut

Once your Secure Boot keys are in /etc/efikeys, pop the following into a dracut configuration file:

FILE /etc/dracut.conf.d/uefi-secureboot.conf
uefi_stub="/usr/lib/systemd/boot/efi/linuxx64.efi.stub"
uefi_secureboot_cert="/etc/efikeys/db.crt"
uefi_secureboot_key="/etc/efikeys/db.key"

Then when updating your kernel, run (replace where necessary):

root #make modules_install
root #dracut --uefi --kernel-image arch/x86/boot/bzImage --kernel-cmdline "$cmdline" -f /path/to/output.efi $kernel_version

TPM2

OpenSSL engine

Emerge app-crypt/tpm2-tss-engine to use the TPM as an OpenSSL engine. To use the tpm resource manager as an unprivileged user, add the user to the tss group.

user $openssl engine -t -c tpm2tss
user $tpm2tss-genkey myTpmKey.keyfile
user $openssl req -engine tpm2tss -keyform engine -new -x509 -nodes -sha256 -days 365 -key myTpmKey.keyfile -out self-signed-cert.crt

Optional configuration

The engine should not require further configuration, but if you need to you can add the following configuration to /etc/ssl/openssl.cnf and modify to taste.

FILE /etc/ssl/openssl.cnf
[default]
openssl_conf = openssl_init

[openssl_init]
engines = engine_section

[engine_section]
tpm2tss = tpm2tss_section

[tpm2tss_section]
engine_id = tpm2tss
dynamic_path = /usr/lib64/engines-1.1/libtpm2tss.so

TOTP measured boot

root #emerge tpm2-totp --autounmask --autounmask-write
root #dispatch-conf
root #emerge app-crypt/tpm2-totp

If using dracut and plymouth, you'll want a tpm2-totp version greater than 0.2.0, which isn't in the tree, as it contains a ready-to-use dracut module. tpm2-totp-0.2.0 wants a library called tctildr, which is part of tpm2-tss-2.3.0, which is also not in the tree. See its pull request.

Add the tpm2-totp module to dracut's config files:

FILE /etc/dracut.conf.d/tpm2-totp.conf
add_dracutmodules+="tpm2-totp"

By default tpm2-totp uses PCR banks 0, 2, 4 and 6. PCR4 contains a hash of the kernel binary you are running, which will change on every kernel update. If you update often, this will cause the TOTP to break each time. Check your PCR banks with app-crypt/tpm2-tools' tpm2_pcrlist. Adjust which PCR banks are used with the tpm2-totp generate -p flag.

PCR bank (Suspected) Use
0 UEFI code
1 UEFI config
2 unknown, identical to PCR3
3 unknown, identical to PCR2
4 (EFI binary hash)
5 unknown
6 unknown
7 (combined hash of the PK+KEK+db(+dbx) databases)
8 kernel command line
9 None (zeros)
10 Unknown use (in concert with IMA)

Sleep

By default, closing the lid will activate S2 sleep (s2idle), which uses a lot of battery while asleep (~20% overnight).

You can try S3/deep sleep by writing deep into /sys/power/mem_sleep and try suspending again, however there may be issues with the internal display or the touchscreen failing to work on resume. Try disabling BIOS Setup -> POST Behaviour -> "Sign of Life" -> "Early Dell Logo Display".

Discover which sleep modes are available to the system:

FILE /sys/power/disk
[platform] shutdown reboot suspend test_resume
FILE /sys/power/mem_sleep
[s2idle] deep
FILE /sys/power/state
freeze mem disk

Check the defaults in /etc/systemd/sleep.conf.

For instance, it's really easy to press the power button when holding in tablet mode, so I selected 's2idle'/'freeze' for the power key (I repurposed hybrid sleep for it). I then use S3 suspend-to-RAM (deep sleep) on lid close, after which a short timeout to suspend-to-disk (S4), to do a full resume through the bootloader:

FILE /etc/systemd/sleep.conf
[Sleep]
HybridSleepState=freeze

SuspendState=mem
HibernateState=disk
HibernateMode=platform
HibernateDelaySec=5m
FILE /etc/systemd/logind.conf
[Login]
HandlePowerKey=hybrid-sleep
HandleLidSwitch=suspend-then-hibernate
FILE /etc/kernel/cmdline
... mem_sleep_default=deep

Note, when the power button is pressed and the system goes into s2idle, it still responds to the lid closing and going into suspend.

Read more about kernel sleep states

LUKS/resume timeout

If you use hibernation with encrypted swap (with dracut/systemd, but maybe other systems too), the systemd-hibernate-resume service will time out after 90 seconds, and entering your password after that will cause hibernation data loss. Upcoming systemd versions will contain a patch that increases the timeout to infinity, but it'd rather turn the laptop off to save battery power.

Add this to your kernel command line to power off the laptop at the 90 second mark:

FILE /etc/kernel/cmdline
rd.emergency=poweroff rd.timeout=90 rd.shell=0

See also: Bug report & systemd-hibernate-resume pull request

USB-C PD charging

Plugging in a USB-C PD battery may not do the right thing (i.e. the laptop charges the battery) without the Type-C UCSI driver.

KERNEL
Device Drivers  --->
  [*] USB support  --->
    <M> USB Type-C Support  --->
      <M> USB Type-C Connector System Software Interface driver
        <M> UCSI ACPI Interface Driver

The driver exposes /sys/class/typec which configures the ports to pull power, and it can be further configured as a power source or sink.

Dell SMBios tools

KERNEL
Device Drivers  --->
  [*] X86 Platform Specific Device Drivers  --->
    <M> Dell Systems Management Base Driver
    <M>   Dell SMBIOS driver
    <M>    Dell SMBIOS driver WMI backend
    <M>    Dell Laptop Extras
root #emerge libsmbios[python]

Fan Thermal Profile

root #smbios-thermal-ctl -i
Libsmbios version : 2.4.2
smbios-thermal-ctl version : 2.4.2

 Print all the Available Thermal Information of your system:
-------------------------------------------------------------------

Supported Thermal Modes:
	 Balanced
	 Cool Bottom
	 Quiet
	 Performance

Supported Active Acoustic Controller (AAC) modes:

Supported AAC Configuration type:
	Global (AAC enable/disable applies to all supported USTT modes)
root #smbios-thermal-ctl -g
smbios-thermal-ctl -g
Helper function to Get current Thermal Mode settings

 Print Current Status of Thermal Information:
-------------------------------------------------------------------

Current Thermal Modes:
	 Quiet

Current Active Acoustic Controller (AAC) Mode:
	 AAC mode Disabled

Current Active Acoustic Controller (AAC) Mode:
	Global (AAC enable/disable applies to all supported USTT modes)

Current Fan Failure Mode:

It's pretty self-explanatory except that the 'Cool Bottom' (with a space) mode should be passed as 'cool-bottom' (with a dash):

root #smbios-thermal-ctl --set-thermal-mode=cool-bottom
Helper function to Set Thermal Mode
Thermal Information Set successfully to: cool-bottom

Filtered calls

You may get some errors while running the smbios tools:

root #smbios-token-ctl
ERROR: Could not execute SMI.

Common problems are:

    -- 'SMM Mitigations' is enabled in BIOS setup.
        Run kernel 4.15 or later with
        dell-smbios-wmi enabled.
         or
        Disable 'SMM mitigations' in BIOS setup.

    -- Insufficient permissions to perform operation.
       Try running as a more privileged account.
          Linux  : run as 'root' user
          Windows: run as 'administrator' user

    -- dell-smbios-wmi driver not loaded
       Try loading the dell-smbios-wmi driver
          Linux : modprobe dell-smbios-wmi

    -- Call filtered by Linux kernel
       Some functionality is natively supported
       by the Linux kernel

    -- dcdbas device driver not loaded.
       Try loading the dcdbas driver
          Linux  : modprobe dcdbas

Check dmesg for 'Invalid call'. These calls are filtered by the dell-smbios driver. For some tools, like smbios-token-ctl, the filtered calls can be blacklisted so that the tool can continue running (skipping those filtered calls).

intel-undervolt

All but the 'System Agent' can be undervolted. I experienced GPU glitches below -40mV, and the Tjunction offset goes down to -40°C (100°C-40°C=60°C).

root #emerge --ask sys-power/intel-undervolt
FILE /etc/intel-undervolt.conf
undervolt 0 'CPU' -80
undervolt 1 'GPU' -40
undervolt 2 'CPU Cache' -80
undervolt 3 'System Agent' 0
undervolt 4 'Analog I/O' -80
power package 15/0.002:disabled 10/600
tjoffset -40
hwphint force load:multi:4.0 power balance_power

The intel-undervolt.service will re-apply itself after suspend and hibernation, but not on suspend-then-hibernate. Add this to your service override:

FILE /etc/systemd/system/intel-undervolt.service.d/override.conf
[Unit]
After=suspend-then-hibernate.target

[Install]
WantedBy=suspend-then-hibernate.target

See also