johnfanv2 / LenovoLegionLinux

Driver and tools for controlling Lenovo Legion laptops in Linux including fan control and power mode.
https://github.com/johnfanv2/LenovoLegionLinux
GNU General Public License v2.0
1.56k stars 56 forks source link

Legion S7 16ARHA7: Module fails to load on F37 #11

Closed tonky closed 1 year ago

tonky commented 1 year ago

Hello John, and thank you for the good work you're doing!

Can't load the module on my S7, but i'm ready to provide all the info you need.

LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc ❯ make
make -C /lib/modules/6.1.6-200.fc37.x86_64/build M=/home/tonky/projects/LenovoLegionLinux/kernel_module modules make[1]: Entering directory '/usr/src/kernels/6.1.6-200.fc37.x86_64' make[1]: Leaving directory '/usr/src/kernels/6.1.6-200.fc37.x86_64'

❯ sudo make reloadmodule [...] [126675.495248] legion_laptop: loading out-of-tree module taints kernel. [126675.495305] legion_laptop: module verification failed: signature and/or required key missing - tainting kernel [126675.495928] legion_laptop 0.1 starts loading [126675.495930] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82UG; DMI_BIOS_VERSION:KFCN32WW [126675.495980] legion PNP0C09:00: legion_laptop platform driver 0.1 probing [126675.495981] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82UG; DMI_BIOS_VERSION:KFCN32WW [126675.495982] legion PNP0C09:00: is_denied: 0; is_allowed: 0 [126675.495983] legion PNP0C09:00: Module not useable for this laptop because it is not in allowlist. Notify maintainer if you want to add your device or force load with param force. [126675.495984] legion PNP0C09:00: legion_laptop not loaded for this device [126675.496014] legion: probe of PNP0C09:00 failed with error -12

❯ uname -a Linux fedora 6.1.6-200.fc37.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Jan 14 16:55:06 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

top of lshw:

fedora
    description: Notebook
    product: 82UG (LENOVO_MT_82UG_BU_idea_FM_Legion S7 16ARHA7)
    vendor: LENOVO
    version: Legion S7 16ARHA7
    serial: PF46VJ2P
    width: 64 bits
    capabilities: smbios-3.4.0 dmi-3.4.0 smp vsyscall32
    configuration: administrator_password=disabled boot=normal chassis=notebook family=Legion S7 16ARHA7 frontpanel_password=disabled keyboard_password=disabled power-on_pass
word=disabled sku=LENOVO_MT_82UG_BU_idea_FM_Legion S7 16ARHA7 uuid=F7DB42E0-5845-ED11-80F3-9C2DCDA28A9E
  *-core
       description: Motherboard
       product: LNVNB161216
       vendor: LENOVO
       physical id: 0
       version: NO DPK
       serial: PF46VJ2P
       slot: Base Board Chassis Location
     *-firmware
          description: BIOS
          vendor: LENOVO
          physical id: 0
          version: KFCN32WW
          date: 09/29/2022
          size: 128KiB
          capacity: 32MiB
          capabilities: pci upgrade shadowing cdboot bootselect edd int13floppynec int13floppytoshiba int13floppy360 int13floppy1200 int13floppy720 int13floppy2880 int9keyboard int10video acpi usb biosbootspecification uefi
     *-cpu
          description: CPU
          product: AMD Ryzen 9 6900HX with Radeon Graphics
          vendor: Advanced Micro Devices [AMD]
          physical id: 4
          bus info: cpu@0
          version: AMD Ryzen 9 6900HX with Radeon Graphics
          serial: Unknown
          slot: FP7
johnfanv2 commented 1 year ago

Thanks for getting in contact and testing it on your laptop!

Your model is very new and not yet in the list of compatible models. You can try it anyhow. Try to pull the code again. I just added a new make command. After pulling please run:

sudo make forcereloadmodule

This will force to load the module even if your model is not added to the compatible models yet. Then try to do the tests to check if everything is working. Please report back, then I can add your laptop series to the list of working models.

If it does not work, I could try to talk to the controller by using ACPI/WMI. This is only available in newer models.

tonky commented 1 year ago

Thanks for the quick answer and potential workaround!

But judging by dmesg output i'm missing some matching configuration?

LenovoLegionLinux/kernel_module on  main via C v12.2.1-gcc 
❯ sudo make forcereloadmodule
[...]
[258265.465108] legion_laptop 0.1 starts unloading
[258265.465137] legion_laptop 0.1 unloaded
[258265.480998] legion_laptop 0.1 starts loading
[258265.481000] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82UG; DMI_BIOS_VERSION:KFCN32WW
[258265.481043] legion PNP0C09:00: legion_laptop platform driver 0.1 probing
[258265.481044] Read identifying information: DMI_SYS_VENDOR: LENOVO; DMI_PRODUCT_NAME: 82UG; DMI_BIOS_VERSION:KFCN32WW
[258265.481046] legion PNP0C09:00: is_denied: 0; is_allowed: 0
[258265.481046] legion PNP0C09:00: legion_laptop is forced to load.
[258265.481047] legion PNP0C09:00: legion_laptop is forced to load and would otherwise be not loaded
[258265.481048] legion PNP0C09:00: No matching configuration found
[258265.481048] legion PNP0C09:00: legion_laptop not loaded for this device
[258265.481077] legion: probe of PNP0C09:00 failed with error -12
johnfanv2 commented 1 year ago

Thanks for the quick answer and potential workaround!

But judging by dmesg output i'm missing some matching configuration?

Thanks for the output. There was a bug when forcing the load for an unknown model. I pushed a new version that hopefully :smile: fixes it.

Please run after pulling:

make
sudo make forcereloadmodule
tonky commented 1 year ago

Holy macaroni, it actually works!

Thank you so much John, now my laptop is silent with light load(for some reason default Lenovo RPM is noisy 2500 when just idling).

This is so awesome! Can i buy you a beer somehow? :)

For some reason the curve point seems too high for the temperature(id 5, 1300 rpm, for 45-50C?), but that's such a minor detail compared to silent machine that i got now!

legion_hwmon-isa-0000
Adapter: ISA adapter
Fan 1:           1355 RPM
Fan 2:           1349 RPM
CPU Temperature:  +49.0°C
GPU Temperature:  +51.0°C
IC Temperature:   +45.0°C

[root@fedora hwmon8]# cat /sys/kernel/debug/legion/fancurve
EC Chip ID: 8227
EC Chip Version: 2a4
legion_laptop version: 0.1
legion_laptop features: fancurve powermode platformprofile platformprofilenotify minifancurve
minifancurve on cool: error
lock fan controller: false
enable maximumfanspeed: false
enable maximumfanspeed status: 0
fan curve current point id: 5
fan curve points size: 10
Current fan curve in UEFI
rpm1|rpm2|acceleration|deceleration|cpu_min_temp|cpu_max_temp|gpu_min_temp|gpu_max_temp|ic_min_temp|ic_max_temp
0   0   5   4   0   50  0   50  0   50
800 800 5   4   50  55  50  60  50  55
1000    1000    5   4   55  60  60  70  55  60
1100    1100    4   3   61  65  60  70  60  65
1200    1200    2   2   66  70  70  80  60  65
1300    1300    2   2   71  75  70  80  60  65
1800    1800    2   2   76  79  80  90  60  65
2300    2300    2   2   80  89  80  90  60  65
3000    3000    2   2   90  94  80  90  70  80
3600    3600    2   2   95  99  90  99  80  90
johnfanv2 commented 1 year ago

Great. I just added your model/BIOS to the list of compatible models. You can now use it normally with forcereloadmodule.

What do you mean by "For some reason the curve point seems too high for the temperature(id 5, 1300 rpm, for 45-50C?)" ? Is the value different from the value you have set?

Could you also check if the other functions (power mode, mini fan curve, locking fan controller) work?

tonky commented 1 year ago

Is the value different from the value you have set?

In the lm-sensors output above you can see that CPU, GPU and IC temperature are about 50C.

Given the provided fan curve table, I would expect the fan curve point to be not higher than 1(fans at 800). But it's actually 5(fans at 1300).

Great. I just added your model/BIOS to the list of compatible models. You can now use it normally with forcereloadmodule.

Awesome, thanks!

Could you also check if the other functions (power mode, mini fan curve, locking fan controller) work?

Will do a bit later and report back.

tonky commented 1 year ago

I couldn't test GUI features, since F37 doesn't ship Qt5, but Qt6. here's what i tested from CLI:

  1. minifancurve don't seem to work:

    # echo 1 > minifancurve 
    # cat minifancurve 
    cat: minifancurve: Operation not permitted

    also you can see the minifancurve on cool: error in the /sys/kernel/debug/legion/fancurve output.

  2. Power profiles - work! Changing them in applet does the same as Fn+Q, with switching button color etc.

  3. Locking and unlocking fan - works

johnfanv2 commented 1 year ago
  1. I didn't know that now Qt6 is standard. I will have to check if Qt6 is standard in other distros and change to it.
  2. Minifancurve is only in some models. If your model does not change its fan curve on its own (so called mini fan curve), then everything should work fine. If you observer that it changes on its own to a small fan curve, please notify me.
  3. Great!
  4. Good.
  5. If you still observer, the problem that the wrong fan speed/point id is chosen, maybe the following will help:
    • cpu_min_temp, cpu_max_temp, gpu_min_temp, gpu_max_temp, ic_min_temp, ic_max_temp should increase from step to step if below 127. max_temp should be 127 in the last point.
    • cpu_min_temp of one point should be lower than cpu_max_temp of the point before I am not sure if this is needed, but I have seen that in all stock fan curves.
johnfanv2 commented 1 year ago

The install instructions for Fedora were wrong. PyQt5 is available, so the GUI should work. I updated the README with the correct package names.

tonky commented 1 year ago

Ah, so PyQt5 is some sort of the metapackage or alias.

Thanks, now it's useable(after commending out the minifancurve file read, as it was giving the error below)

Yeah, everything else seems to work, including disable touchpad and Fn lock toggles.

As for fan speeds - i've applied your suggestions(min/max overlap, max_temp of 127), but still it mostly sticks to fan curve point 6(althogh i saw it dip lower on long idle!)

For example here, given temperatures, i'd expect point to be 3, with fans on 700, but it's 6 and 1200 instead.

Adapter: ISA adapter
Fan 1:           1247 RPM
Fan 2:           1247 RPM
CPU Temperature:  +52.0°C
GPU Temperature:  +57.0°C
IC Temperature:   +52.0°C

rpm1|rpm2|acceleration|deceleration|cpu_min_temp|cpu_max_temp|gpu_min_temp|gpu_max_temp|ic_min_temp|ic_max_temp
0   0   5   2   0   31  0   31  0   36
500 500 5   2   30  46  30  46  35  41
600 600 4   2   45  51  45  51  40  46
700 700 3   2   50  66  50  66  45  61
800 800 3   2   65  71  65  71  60  66
900 900 2   2   70  76  70  76  65  71
1200    1200    2   2   75  81  75  81  70  76
1800    1800    2   2   80  86  80  86  75  81
2600    2600    2   2   85  96  85  96  80  86
3600    3600    2   2   95  127 95  127 85  127
❯ sudo python/legion_linux/legion_gui.py  
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
Traceback (most recent call last):
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion_gui.py", line 375, in <module>
    main()
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion_gui.py", line 344, in main
    contr.init(read_from_hw=not do_not_excpect_hwmon)
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion_gui.py", line 42, in init
    self.model.read_fancurve_from_hw()
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion.py", line 375, in read_fancurve_from_hw
    self.fan_curve = self.fancurve_io.read_fan_curve()
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion.py", line 305, in read_fan_curve
    fancurve.enable_minifancurve = self.get_minifancuve()
                                   ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion.py", line 266, in get_minifancuve
    invalue = self._read_file(file_path)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tonky/projects/LenovoLegionLinux/python/legion_linux/legion.py", line 152, in _read_file
    return int(filepointer.read())
               ^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 1] Operation not permitted
johnfanv2 commented 1 year ago

@tonky I patched the python program, so it should start without mini fan curve.

I will think about the problem that it does not choose the correct point. Does it work if you do not change the fan curve but just load the module, read out the fan curve, but do not change it?