Configuration for ThinkPad T14s Gen 6 (Snapdragon X Elite X1E-78-100)

The boot workarounds work well, thanks!

Another issue I’m seeing with the upgrade to unstable (latest as of yesterday): I’m getting phantom power button presses immediately on boot:

Feb 24 22:42:41 thinkpadt14sg6 systemd[1]: Starting User Login Management...
Feb 24 22:42:41 thinkpadt14sg6 systemd-logind[1037]: New seat seat0.
Feb 24 22:42:41 thinkpadt14sg6 systemd-logind[1037]: Watching system buttons on /dev/input/event0 (gpio-keys)
Feb 24 22:42:41 thinkpadt14sg6 systemd-logind[1037]: Watching system buttons on /dev/input/event2 (hid-over-i2c 04F3:000D Keyboard)
Feb 24 22:42:41 thinkpadt14sg6 systemd-logind[1037]: Watching system buttons on /dev/input/event1 (pmic_pwrkey)
Feb 24 22:42:41 thinkpadt14sg6 systemd[1]: Started User Login Management.
Feb 24 22:43:21 thinkpadt14sg6 systemd-logind[1037]: Power key pressed short.
Feb 24 22:43:21 thinkpadt14sg6 systemd-logind[1037]: Powering off...
Feb 24 22:43:21 thinkpadt14sg6 systemd-logind[1037]: System is powering down.
Feb 24 22:43:21 thinkpadt14sg6 systemd[1]: Stopping User Login Management...
Feb 24 22:43:21 thinkpadt14sg6 systemd[1]: systemd-logind.service: Deactivated successfully.
Feb 24 22:43:21 thinkpadt14sg6 systemd[1]: Stopped User Login Management.

which means it immediately shuts down, or if I boot a configuration with gdm enabled it seems to suspend or at least power down the screen. In that latter case if I press the power button the screen flashes up briefly (showing the gdm login screen) and then goes black again (presumably it’s immediately suspending), and that happens repeatedly every second time I press the button. I can see the effect of my key presses on the screen when it flashes up, so the system is still responsive to some extent.

If I boot back into my 24.11 generation I don’t see this problem at all, and nothing about power button presses appears in the logs, although I do notice the button blinks as the system finishes starting up.

Just throwing it out there in case anyone else has seen this. I couldn’t find an obvious bug report anywhere. I will try the various systemd-logind config options to ignore power button presses tomorrow to see if that helps.

I too have not read about this issue. I’m running sway on -rc kernels and gnome on linuxPackages_latest. I do have services.logind.lidSwitch = "ignore";.

Thanks, the lid switch change doesn’t help, but worth trying. I’ll do some more debugging tonight.

If it’s not a lot of trouble, would you be able to share your current NixOS configuration, so I can compare? Thanks for the help!

Sure, I’ve left out the non-relevant bits.

I’m not using separate hardware.firmware anymore as all firmware is upstream now thanks to Lenovo: qcom:x1e80100: Support for Lenovo T14s G6 Qualcomm platform - kernel/git/firmware/linux-firmware.git - Repository of firmware blobs for use with the Linux kernel and qcom:x1e80100: Support for Lenovo T14s G6 Qualcomm platform - kernel/git/firmware/linux-firmware.git - Repository of firmware blobs for use with the Linux kernel

And I’ve tuned down nix.settings.cores to 3 as with 4 cores the temperature occasionally went above 90 degrees Celsius.

Please share any remarks you have.

{ pkgs, ... }:

{
  boot = {
    initrd.kernelModules = [
      "nvme"
      "f2fs"
    ];
    kernelPackages =
      let
        kernel_pkg =
          { buildLinux, ... }@args:
          buildLinux (
            args
            // {
              ignoreConfigErrors = true;
              src = builtins.fetchTarball {
                url = "https://git.kernel.org/torvalds/t/linux-6.14-rc4.tar.gz";
                sha256 = "sha256:04nndjy8jspwmklr1ymcmhxpsg1rxyhbnllrzvr2qyrvxa81lh9p";
              };
              version = "6.14.0-rc4";
            }
            // (args.argsOverride or { })
          );
        kernel = pkgs.callPackage kernel_pkg { };
      in
      pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
    kernelParams = [
      "clk_ignore_unused"
      "pd_ignore_unused"
      "mem=31G"
    ];
    kernelPatches = [
      {
        extraConfig = ''
          TYPEC y
          PHY_QCOM_QMP y
          QCOM_CLK_RPM y
          MFD_QCOM_RPM y
          REGULATOR_QCOM_RPM y
          PHY_QCOM_QMP_PCIE y
          CLK_X1E80100_CAMCC y
        '';
        name = "snapdragon-config";
        patch = null;
      }
    ];
    loader = {
      efi.canTouchEfiVariables = true;
      systemd-boot = {
        enable = true;
        configurationLimit = 16;
      };
    };
  };

  hardware = {
    deviceTree = {
      enable = true;
      name = "qcom/x1e78100-lenovo-thinkpad-t14s.dtb";
    };
    enableRedistributableFirmware = true;
    graphics = {
      enable = true;
    };
  };

  networking = {
    dhcpcd.enable = false;
    networkmanager = {
      enable = true;
      wifi.backend = "iwd";
    };
    wireless = {
      iwd = {
        settings = {
          General = {
            ControlPortOverNL80211 = false;
          };
        };
      };
    };
    useDHCP = false;
    useNetworkd = true;
  };

  nix = {
    settings = {
      cores = 3;
    };
  };

  nixpkgs.hostPlatform = "aarch64-linux";

  powerManagement.cpuFreqGovernor = "powersave";

  systemd = {
    network = {
      enable = true;
      networks = {
        wlan0 = {
          DHCP = "yes";
          matchConfig = {
            Name = "wlan0";
          };
        };
      };
    };
  };
}

Finally getting back to this, thanks for sharing the config. I think I reproduced your config pretty much exactly (including the kernel), but I’m still having issues on unstable. I’ll look into it further.

Out of interest, could you share which commit of nixpkgs you’re using? I’m using ba487dbc9d04e0634c64e3b1f0d25839a0a68246 FWIW.

EDIT: To clarify ‘issues’, it boots, I see various boot status messages fly past, and then end up with a blank unresponsive screen (regardless of whether I have a window system enabled). I don’t see anything obvious in journalctl (the power key thing I saw before was a red herring I think, I was confused by the system time being wrong!). Pressing the power key shuts it down successfully, but the usual things (e.g. ctrl-alt-f* to switch ttys) don’t work.

Update: it turns out everything is responsive, it’s just the screen is blank. I can log in with the root password and type reboot and it’ll reboot. So I’m guessing it’s a problem with GPU initialization. Booting with nomodeset doesn’t seem to help.

Mine goes blank for about 10 seconds before tty login/password appear. This is with sway, which I start at the command line (and is installed with home-manager).

But gnome works as well:

{
  services = {
    xserver = {
      enable = true;
      desktopManager = {
        gnome = {
          enable = true;
        };
      };
      displayManager = {
        gdm = {
          enable = true;
          autoSuspend = false;
        };
      };
    };
  };
}

Can you compare your journalctl -b -g 'adreno|drm' with mine?

kernel: simple-framebuffer simple-framebuffer.0: [drm] Registered 1 planes with drm panic
kernel: [drm] Initialized simpledrm 1.0.0 for simple-framebuffer.0 on minor 0
kernel: simple-framebuffer simple-framebuffer.0: [drm] fb0: simpledrmdrmfb frame buffer device
systemd[1]: Starting Load Kernel Module drm...
systemd[1]: modprobe@drm.service: Deactivated successfully.
systemd[1]: Finished Load Kernel Module drm.
kernel: adreno 3d00000.gpu: Adding to iommu group 3
kernel: WARNING: CPU: 0 PID: 586 at drivers/gpu/drm/panel/panel-edp.c:814 panel_edp_probe+0x3f8/0x580 [panel_edp]
kernel: Modules linked in: panel_edp(+) mousedev snd_q6apm(+) joydev hid_multitouch nls_iso8859_1 nls_cp437 apr rpmsg_ctrl fastrpc rpmsg_char qrtr_smd i2c_hid_of i2c_hid phy_nxp_ptn3222 qcom_pd_mapper ucsi_glink pmic_glink_altmode typec_ucsi qcom_battmgr qcom_edac aux_hpd_bridge ath12k(+) msm polyval_ce polyval_generic phy_qcom_eusb2_repeater sm4_ce_gcm sm4_ce_ccm sm4_ce sm4_ce_cipher sm4 nvmem_qcom_spmi_sdam qcom_pon sm3_ce sm3 qcom_spmi_temp_alarm sha3_ce mac80211 ocmem gpu_sched sha512_ce drm_exec snd_soc_x1e80100 sha512_arm64 i2c_qcom_geni drm_dp_aux_bus phy_qcom_qmp_combo snd_soc_qcom_sdw snd_soc_qcom_common drm_display_helper aux_bridge phy_qcom_edp mhi cec pinctrl_sm8550_lpass_lpi dispcc_x1e80100 libarc4 pinctrl_lpass_lpi phy_qcom_qmp_usb phy_qcom_snps_eusb2 qcom_stats qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcom_sysmon snd_soc_lpass_va_macro snd_soc_lpass_rx_macro lpasscc_sc8280xp snd_soc_lpass_wsa_macro snd_soc_lpass_tx_macro qcom_common snd_soc_lpass_macro_common qcom_glink_smem soundwire_qcom
kernel:  dp_aux_ep_probe+0x3c/0x138 [drm_dp_aux_bus]
kernel:  __dp_aux_dp_driver_register+0x2c/0x58 [drm_dp_aux_bus]
kernel: adreno 3d00000.gpu: supply vdd not found, using dummy regulator
kernel: adreno 3d00000.gpu: supply vddcx not found, using dummy regulator
kernel: [drm:dpu_kms_hw_init:1156] dpu hardware revision:0x90020000
kernel: [drm] Initialized msm 1.12.0 for ae01000.display-controller on minor 1
kernel: msm_dpu ae01000.display-controller: [drm:adreno_request_fw [msm]] loaded qcom/gen70500_sqe.fw from new location
kernel: msm_dpu ae01000.display-controller: [drm:adreno_request_fw [msm]] loaded qcom/gen70500_gmu.bin from new location
kernel: [drm] Loaded GMU firmware v4.3.17
kernel: msm_dpu ae01000.display-controller: [drm] fb0: msmdrmfb frame buffer device

Tracking nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; I’m currently at:

    "nixpkgs": {
      "locked": {
        "lastModified": 1740791350,
        "narHash": "sha256-igS2Z4tVw5W/x3lCZeeadt0vcU9fxtetZ/RyrqsCRQ0=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "199169a2135e6b864a888e89a2ace345703c025d",
        "type": "github"
      },

Thanks very much @ookhoi . Using the same commit made no difference. Here’s the difference in the logs (my broken one is left (<), yours is right (>)):

< kernel: adreno 3d00000.gpu: Adding to iommu group 4
< kernel: WARNING: CPU: 9 PID: 768 at drivers/gpu/drm/panel/panel-edp.c:814 panel_edp_probe+0x3f8/0x580 [panel_edp]
< kernel: Modules linked in: snd_q6apm(+) apr panel_edp(+) joydev mousedev hid_multitouch rpmsg_ctrl fastrpc rpmsg_char qrtr_smd i2c_hid_of phy_nxp_ptn3222 i2c_hid qcom_pd_mapper ucsi_glink pmic_glink_altmode qcom_battmgr aux_hpd_bridge typec_ucsi qcom_edac msm ath12k(+) polyval_ce polyval_generic sm4_ce_gcm sm4_ce_ccm sm4_ce sm4_ce_cipher sm4 sm3_ce sm3 sha3_ce phy_qcom_eusb2_repeater qcom_pon nvmem_qcom_spmi_sdam sha512_ce qcom_spmi_temp_alarm mac80211 ocmem sha512_arm64 gpu_sched i2c_qcom_geni snd_soc_x1e80100 drm_exec snd_soc_qcom_sdw phy_qcom_qmp_combo snd_soc_qcom_common qcom_stats aux_bridge drm_dp_aux_bus drm_display_helper dispcc_x1e80100 phy_qcom_edp phy_qcom_qmp_usb cec pinctrl_sm8550_lpass_lpi qcom_q6v5_pas snd_soc_lpass_rx_macro mhi phy_qcom_snps_eusb2 pinctrl_lpass_lpi soundwire_qcom snd_soc_lpass_wsa_macro snd_soc_lpass_tx_macro libarc4 snd_soc_lpass_va_macro gpucc_x1e80100 lpasscc_sc8280xp qcom_pil_info qcom_q6v5 slimbus snd_soc_lpass_macro_common qcom_sysmon qcom_common qcom_glink_smem qrtr
< kernel: dp_aux_ep_probe+0x3c/0x138 [drm_dp_aux_bus]
< kernel: __dp_aux_dp_driver_register+0x2c/0x58 [drm_dp_aux_bus]
---
> kernel: adreno 3d00000.gpu: Adding to iommu group 3
> kernel: WARNING: CPU: 0 PID: 586 at drivers/gpu/drm/panel/panel-edp.c:814 panel_edp_probe+0x3f8/0x580 [panel_edp]
> kernel: Modules linked in: panel_edp(+) mousedev snd_q6apm(+) joydev hid_multitouch nls_iso8859_1 nls_cp437 apr rpmsg_ctrl fastrpc rpmsg_char qrtr_smd i2c_hid_of i2c_hid phy_nxp_ptn3222 qcom_pd_mapper ucsi_glink pmic_glink_altmode typec_ucsi qcom_battmgr qcom_edac aux_hpd_bridge ath12k(+) msm polyval_ce polyval_generic phy_qcom_eusb2_repeater sm4_ce_gcm sm4_ce_ccm sm4_ce sm4_ce_cipher sm4 nvmem_qcom_spmi_sdam qcom_pon sm3_ce sm3 qcom_spmi_temp_alarm sha3_ce mac80211 ocmem gpu_sched sha512_ce drm_exec snd_soc_x1e80100 sha512_arm64 i2c_qcom_geni drm_dp_aux_bus phy_qcom_qmp_combo snd_soc_qcom_sdw snd_soc_qcom_common drm_display_helper aux_bridge phy_qcom_edp mhi cec pinctrl_sm8550_lpass_lpi dispcc_x1e80100 libarc4 pinctrl_lpass_lpi phy_qcom_qmp_usb phy_qcom_snps_eusb2 qcom_stats qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcom_sysmon snd_soc_lpass_va_macro snd_soc_lpass_rx_macro lpasscc_sc8280xp snd_soc_lpass_wsa_macro snd_soc_lpass_tx_macro qcom_common snd_soc_lpass_macro_common qcom_glink_smem soundwire_qcom
> kernel:  dp_aux_ep_probe+0x3c/0x138 [drm_dp_aux_bus]
> kernel:  __dp_aux_dp_driver_register+0x2c/0x58 [drm_dp_aux_bus]

I don’t see much of a difference apart from the iommu group being different. I will play with some of the other settings you sent later on. Thanks so much!

Could it be yours has an oled display? If yes, it could be brightness maybe? Mine are lcd.

Yes I had the same thought about brightness, but I didn’t think about the OLED vs LCD wrinkle. Mine is OLED, so that definitely sounds like a lead (just pressing the brightness controls doesn’t do anything, of course). There are a bunch of references to OLED brightness being broken in the kernel/dtbs at various points, but I’m now using the same kernel in both the working and the broken case.

Since it happens later in boot, it feels like it’s something that systemd is starting that’s causing the issue. I’ve tried disabling a few obvious services to no avail. Unfortunately systemd.confirm_spawn=true seems to crash the system, because otherwise that would be really useful to debug.

Anyhow, I’ll keep hacking away at it, thanks for the help!

I narrowed it down a bit further: the screen appears to go blank after systemd-udevd starts (if I add a delay to the start of that unit, the screen remains active until after the delay expires). I’ve taken a look at the difference between the udev rules on the two systems and they look pretty similar, and doing udevadm info --attribute-walk --path=/sys/class/drm/card1 looks similar (not exactly the same, the newer systemd seems to have more information). I’ll keep looking!

1 Like

It turns out a patch is needed to make OLED brightness work. It’s not clear why it only affects unstable for me and not 24.11. Ubuntu have a hack in their kernel tree at the moment, and there is an upstream patch series to separate out the device trees for LCD vs OLED and fix it properly. See Ubuntu 24.10 Concept ♥️ Snapdragon X Elite - #701 by tobhe - Ubuntu Architectures - Ubuntu Community Hub

Thanks for the help!

EDIT: FYI @ookhoi I’m using the ubuntu kernel now and it seems to be working well:

src = pkgs.fetchgit {
  url = "https://git.launchpad.net/~ubuntu-concept/ubuntu/+source/linux/+git/oracular";
  rev = "01934ace84b4bb3dbdc888ad4d5d3bec8ceb4068";
  sha256 = "sha256-O/FMWI2veqTq0gv6WAXO9hczlokJhHyo1YBaRNVk0ZM=";
};
version = "6.14.0-rc4";
2 Likes