Fixing issues on Thinkpad Neo 14 running Linux

This article is a continuation for my previous article on setting up Linux on this specific laptop, which I've been using daily for a little over a month. My distro is Arch Linux, so this article mainly focuses on Arch Linux-related information as well as solutions.

The major problems that bother me are listed below, and fortunately, I've found solutions to all of them, which is also why I'm writing this article to share my solutions.

  • Internal microphone not working out of the box
  • Wake from sleep takes more than 10 seconds
  • External monitor cause system lag
  • CPU frequency not optimized to use the highest possible boost frequency (4.8 GHZ)

Issue 1: Internal microphone array not working out of the box

2023-07-04 update: the patch I submitted to Linux Kernel has been merged, so the laptop Thinkpad Neo14 is in the quirks list for the microphone 🎉. This means, if you are on the LTS kernel version of 6.1, or a kernel version later than 6.3, you should be able to see the microphone 'working' (you will still need to fix the pulse audio part detailed below).

This was the issue that bothered me most, I just needed it to work correctly as this is my daily driver laptop and it's important to have the microphone work correctly.

  • Root cause: I had to search all over the internet to find a proper solution for this. And what helped me in the end was this Arch Linux forum post. Based on the discussion there, the root cause seems to be my specific laptop model is not in the quirk list, and lots of people there was having this same issue. The suggested solution in that forum post is to modify the source code directly.

Solution: Modify the source code and recompile the kernel

I assume this is a big ask for most Linux user, but I will still go through what I did. I had submitted the patch to Linux kernel by the time this article is published, so hopefully when someone find this article from major search engines, this is no longer an issue.
Here is what I did:

  • Clone the Linux repo from GitHub: git clone https://github.com/torvalds/linux.git --depth 1 (the reason I added depth 1 is to save some time when cloning, I don't really need to have all the Linux history locally, and having --depth 1 will only give the most recent commit log)
  • Change the file sound/soc/amd/yc/acp6x-mach.c, adding the line detailed in the patch below to anywhere in the yc_acp_quirk_table

The following patch was exactly what I had submitted to Linux kernel, I leave it here for reference only:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
index 4406a5def..246299a17 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -171,6 +171,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
}
},
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "21EF"),
+ }
+ },
{
.driver_data = &acp6x_card,
.matches = {
  • Follow the Linux Kernel building guide for Arch Linux using Arch Build System to recompile the kernel, just remember to apply the patch using the method detailed in the guide BEFORE you started compiling.
  • Once you have installed and boot into the newly compiled kernel, you will notice your Pulse Audio profile will only have Play Hi-Fi Audio left.
  • If you are using Pulse Audio only, you will need to edit /etc/pulse/default.pa and add load-module module-udev-detect use_ucm=0
  • If you are using Pipewire, you will need to edit sudo vim /usr/share/wireplumber/main.lua.d/50-alsa-config.lua, in this file, find and replace the following line (it should be true by default):
    1
    2
    3
    -- Use UCM instead of profile when available. Can be
    -- disabled to skip trying to use the UCM profile.
    ["api.alsa.use-ucm"] = false,
    You will need to reboot again to make sure these files take effects.

Like I said in the beginning, fixing this is not trivial, but hopefully, my patch to the kernel will already fix this issue by the time someone finds and reads this article.

Issue 2: Wake from sleep takes more than 10 seconds

This was also one of the bigger issues for me. On my previous Intel laptop, the wake from sleep/suspend would take less than 5 seconds. On this machine, it would take more than 15 seconds, sometimes 20 seconds. This is getting really annoying especially because I put the laptop into sleep quite often.

  • Root cause: I'm not really sure if this is the actual cause, but this issue has something to do with a bug (?) in the kernel (?). I found the following line in the dmesg when I was looking into this issue:
    DEBUG: 2023-05-20T12:36:26,105472+12:00 nvme 0000:02:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x000d address=0x7152c000 flags=0x0000], so my assumption is that something is wrong with this AMD-Vi thingy.

Solution: Change Kernel Parameter

I don't know if this would be the correct fix, but it did solve the issue. I solved the issue by changing kernel boot parameter.

I added iommu=pt to the kernel parameter. The situation was greatly improved after reboot, the wake up time decreased to around 3 seconds.

Issue 3: External monitor cause system lag

This is likely because of my misconfigured Xorg and not likely happen to other people, but the issue I experienced was that the internal monitor will lag a lot when an external monitor is connected.

Solution: Modify Xorg configuration file

I modified the /etc/X11/xorg.conf file, here's the configuration after modification:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Section "Device"
### Available Driver options are:-
### Values: <i>: integer, <f>: float, <bool>: "True"/"False",
### <string>: "String", <freq>: "<f> Hz/kHz/MHz",
### <percent>: "<f>%"
### [arg]: arg optional
Option "DRI" "3"
#Option "ShadowPrimary" # [<bool>]
Option "TearFree" "true"
#Option "TearFree" # [<bool>]
#Option "DeleteUnusedDP12Displays" # [<bool>]
#Option "VariableRefresh" # [<bool>]
#Option "AsyncFlipSecondaries" # [<bool>]
Identifier "Card1"
Driver "amdgpu"
BusID "PCI:51:0:1"
EndSection

I changed DRI to 3, and set TearFree option to true. Once reboot, I found the issue's been resolved.

Issue 4: CPU frequency hardware limit is not using the highest possible frequency (4.8 GHZ)

This one is probably not that important, with the current frequency at 3.2 GHZ without boosting, I was able to compile the Linux kernel in 33 minutes. Given the performance of this CPU, unleashing the frequency to 4.8 GHZ will probably also be helpful.

Solution: Change kernel parameter

I changed kernel parameter again for this one.

I added an additional kernel parameter of amd_pstate=active.

On kernel 6.3+, this will set the CPU to use amd_pstate_epp, on earlier versions, this will make the system use amd_pstate as scaling driver. Note that scaling driver is different from CPU governor. If you want to use amd_pstate on 6.3 and above, you need to set amd_pstate=passive instead of active
You can verify you are indeed using the driver by running sudo cpupower --cpu all frequency-info --human, you will be able to see the driver as driver: amd_pstate_epp

References

https://bbs.archlinux.org/viewtopic.php?pid=2058087
https://wiki.archlinux.org/title/Kernel/Arch_build_system
https://wiki.archlinux.org/title/Patching_packages#Applying_patches
https://old.reddit.com/r/archlinux/comments/1381g2g/amd_pstate_epp_scaling_driver_available_with/