A UEFI firmware update is strongly recommended for general use of the laptop - the initial 1.13 version devices seem to ship with contains multiple bugs that can result in bricking the laptop: Reddit thread discussing the issue; another Reddit thread discussing a different bricking issue.
The latest version, v1.35, is highly recommended. All information on this page assumes the latest firmware.
Both the HDMI port and DisplayPort outputs created when using either a USB-C adapter or Thunderbolt dock are wired to the Nvidia dGPU.
A BIOS setting can be used to disable the integrated GPU, and run everything on the dedicated Nvidia card. The dedicated GPU cannot be disabled through firmware, so enabling runtime power management in some form is highly recommended when using the iGPU.
CPU thermal throttling
This laptop is affected by a CPU throttling bug when using Linux.
Basically, the laptop's firmware uses an implementation of Intel's Dynamic Platform and Thermal Framework (DPTF) that does not work with Linux. While newer generations of ThinkPads have gotten a BIOS update to fix this, a Lenovo employee confirmed that older affected Thinkpads (including T580, T480, T480s, X1C6, P1G1 and X1E1) will not get the fix.
A stress test usingindicates that the CPU is limited to 38W/80C at boot, resulting in a sustained all-core frequency of around 2850 MHz on the i7-8750H.
Fix using reverse-engineered DPTF implementation
Starting with kernel 5.12, the work-in-progress can be utilized by installing and enabling, which will attempt to make use of the firmware's adaptive performance policy.
Unfortunately, the current implementation does not appear to help much on this laptop. While the CPU's limit is raised to 45W/83C, the all-core frequency is erratic, resulting in only a marginal performance improvement.
Fix using dptfxtract and manual DPTF profile setting
Another option, which does result in full performance, is to extract the DPTF tables and use them in combination with a manual change of the DPTF profile.
Configuring thermald to use extracted dptf tables
First, make sureis installed. Next, use Intel's proprietary AUR tool to extract the DPTF tables:
This will populate
/etc/thermald/ with multiple configuration files of the form
thermal-conf.xml.*, each of which represents a converted DPTF table.
The tool also creates a copy of each of these files in the current working directory, so you may want to remove those:
# rm thermal-conf.xml.*
The thermald service file shipped with Arch Linux enables adaptive mode by default. In order to use the extracted tables we have to override it.
Create the necessary directory if it does not exist already:
# mkdir -p /etc/systemd/system/thermald.service.d
Then create the following file:
[Service] ExecStart= ExecStart=/usr/bin/thermald --systemd --dbus-enable
Afterwards, reload the systemd manager configuration and enable thermald.
Selecting the appropriate configuration
/etc/thermald/is not recommended as it may result in your laptop running out of spec!
Out of all the generated configuration files, thermald will use
thermal-conf.xml.auto by default. You can try any of the other configurations by adding the
--config-file flag to the
override.conf created earlier.
The default configuration file already unlocks full performance. A stress test indicates that the CPU is now limited to 45W/95C, resulting in a sustained all-core frequency of around 3300 MHz on the i7-8750H.
Manually setting a DPTF profile to prevent temporary re-throttling
The setup above is not perfect, every time the CPU temperature trips over 80C the laptop's embedded controller (EC) will re-throttle the CPU for a few seconds.
This issue can be fixed, without 'fighting the EC', by manually setting the adaptive performance DPTF profile using the following script:
#!/bin/bash # Script that enables the adaptive performance DPTF profile, if available. # Check for super user privileges. if (( $EUID != 0 )); then echo "ERROR: script requires super user privileges. Exiting!" exit 1 fi # from: https://github.com/torvalds/linux/blob/master/drivers/thermal/intel/int340x_thermal/int3400_thermal.c adaptive_performance_uuid='63BE270F-1C11-48FD-A6F7-3AF253FF3E2D' # Check if the adaptive performance profile is supported. available_uuids=$(cat /sys/devices/platform/INT3400:00/uuids/available_uuids) if [[ $available_uuids != *$adaptive_performance_uuid* ]]; then echo "ERROR: adaptive performance profile not supported. Exiting!" exit 1 fi # Find the INT3400 Thermal driver. INT3400=$(grep INT3400 /sys/class/thermal/thermal_zone*/type | grep Thermal | sed '/\/sys\/class\/thermal\/thermal_zone/ s/\/type.*//') if [[ "$INT3400" == '' ]]; then echo "ERROR: unable to find the INT3400 thermal driver. Exiting!" exit 1 fi # Temporarily disable the INT3400 thermal driver. echo 'disabled' > "$INT3400"/mode if [[ $(cat "$INT3400"/mode) != 'disabled' ]]; then echo "ERROR: unable to disable the INT3400 thermal driver. Exiting!" exit 1 fi # Enable the adaptive performance profile. echo "$adaptive_performance_uuid" > /sys/devices/platform/INT3400:00/uuids/current_uuid current_uuid=$(cat /sys/devices/platform/INT3400:00/uuids/current_uuid) if [[ "$current_uuid" != "$adaptive_performance_uuid" ]]; then echo "ERROR: unable to set the adaptive performance profile. Exiting!" exit 1 fi # Re-enable the INT3400 thermal driver. echo 'enabled' > "$INT3400"/mode if [[ $(cat "$INT3400"/mode) != 'enabled' ]]; then echo "ERROR: unable to re-enable the INT3400 thermal driver. Exiting!" exit 1 fi echo "Successfully set the adaptive performance DPTF profile."
Save the script somewhere and create a systemd service for it:
[Unit] Description=Set Intel DPTF policy to adaptive performance [Service] Type=oneshot ExecStart=/path/to/script/set_dptf_adaptive.sh [Install] WantedBy=default.target
Do not forget to replace
/path/to/script/ in the service file.
Finally, reload the systemd manager configuration and enable the service.
Disabling BDPROCHOT to prevent throttling on battery
- After this fix the laptop may run hotter than is comfortable when using it on your lap or similar positions.
- Disabling BDPROCHOT can be considered a 'nuclear option' in terms of power management. Use at your own risk!
The laptop's performance on battery is far below expectations when using Linux. The cause appears to be something called 'lap mode' (documented by Lenovo, here).
Basically, when unplugged, the laptop will by default assume that it is being used on the user's lap. And since Linux has no working DPTF implementation to tell the the laptop otherwise, it will always assume it is being used the user's lap. Consequently, In order to keep the laptop base at a 'skin friendly' temperature, the laptop's EC throttles the CPU with BDPROCHOT (BiDirectional PROCessor HOT) when one of many thermal sensors trips a predetermined value. Effectively this will keep the CPU at around 70C max while simultaneously preventing the fans from properly spinning up. A repeated on-again off-again all-core stress test causes the CPU to throttle as low as 800 MHz.
Since there is currently no known way to disable 'lap mode', the only path to full performance on battery is to disable BDPROCHOT altogether. This can be done using the following script:
#!/bin/bash # Script that unsets the BDPROCHOT-bit on some Intel CPUs. # Check for super user privileges. if (( $EUID != 0 )); then echo "ERROR: script requires super user privileges. Exiting!" exit 1 fi # Enable writing to model-specific registers of the CPU. modprobe msr # Get current state of the CPU power-related bits (in base-10). flags=$(rdmsr 0x1FC -d) # Check if BDPROCHOT-bit is already unset. if [[ $(("$flags" & 0x00000001)) == 0 ]]; then echo "INFO: BDPROCHOT-bit is already unset. Exiting!" exit 0 fi # Unset BRPROCHOT-bit. wrmsr -a 0x1FC $(("$flags" & 0xfffffffe)) # Check if we were successful. flags=$(rdmsr 0x1FC -d) if [[ $(("$flags" & 0x00000001)) == 1 ]]; then echo "ERROR: unable to unset BDPROCHOT-bit. Exiting!" exit 1 fi echo "Successfully disabled BDPROCHOT."
Save the script somewhere and create a systemd service for it:
[Unit] Description=Disable BDPROCHOT [Service] Type=oneshot ExecStart=/path/to/script/bdprochot_disable.sh [Install] WantedBy=default.target
A suspend/resume-cycle will cause the EC to re-set the BDPROCHOT-bit.
Create the following file (and make it executable) to run the script on resume:
#!/bin/sh case "$1" in post) /path/to/script/bdprochot_disable.sh ;; esac
Do not forget to replace
/path/to/script/ in both files.
Finally, reload the systemd manager configuration, enable the service and reboot.
The CPU's performance on battery should now be roughly equal as when plugged in.
Microphone noise reduction
PulseAudio's PulseAudio#Microphone echo/noise cancellation can be used to reduce the amount of microphone noise by adding the following to
### Enable Echo/Noise-Cancellation load-module module-echo-cancel use_master_format=1 aec_method=webrtc aec_args="beamforming=1 mic_geometry=-0.0257,0,0,0.0257,0,0" source_name=echoCancel_source sink_name=echoCancel_sink set-default-source echoCancel_source set-default-sink echoCancel_sink
The above mic_geometry is specific to the X1 Extreme.
The module-filter-heuristics and module-filter-apply modules can sometimes result in adding additional noise, so the lines that enable them should be commented out:
#load-module module-filter-heuristics #load-module module-filter-apply
Bad sound quality may also result from audio clipping, which can occur if "Internal Mic Boost" is larger than zero in alsamixer.
A reverse engineering effort is ongoing here, and an experimental driver is available on the AUR as AUR.
Upstream libfprint bug is tracked here.