hirschmann / nbfc

NoteBook FanControl
Other
2.9k stars 487 forks source link

Making a config for Lenovo Ideapad Y700-15ISK #526

Closed erkexzcx closed 4 years ago

erkexzcx commented 6 years ago

Hi,

I am trying to figure out correct registers for fan controls and manual controls on Lenovo Ideapad Y700-15ISK. It has 2 fans and they seem to be linked with each other (see 0x53 register below).

There are 2 registers 0x06 and 0xFE which corresponds to actual fans speeds. In extracted DSDT code they are named as FANS ("Fan Speed" - probably for fan 1 speed) and FA2S ("Fan 2 Speed" - probably for fan 2 speed).

Sometimes, changing register 0x53 actually affects both fan speeds. This register looks like it outputs temperature, which is respected by fans. After fresh boot - changing it affects fan speeds, but after some load - it's being overridden and has no effect on fan speeds. It has different values from fan speeds, so it's not a fan speed target value. Setting it to 0 does not stop fans completely - I have a feeling that fans corresponds to GPU temperature at the same time.

In conclusion, I think I need to locate registers to somehow enable manual control (or disable EC automatic control) in order to proceed further, unfortunately - I had no luck identifying them.

@hirschmann - I see you uploaded Lenovo Ideapad 7105.xml configuration file. Can I have some DSDT code examples related to Lenovo laptops? Or any other Lenovo laptops manufactured at around ~2015-2016 DSDT codes? There are no data sheets available, DSDT and ec-probing is the only way to locate something, but I am currently don't know where to look at. :/

I am also attaching my DSDT code: DSDT.txt Any chance that someone could look at it and help me identify manual control or fan speed control registers?

erkexzcx commented 6 years ago

Some more information that might help:

dsdt variables with register locations.txt Some ec-probing and identified registers.txt

erkexzcx commented 6 years ago

@hirschmann You don't mind sharing Lenovo laptops from around ~2015-2016 DSDT tables? They might help for analysis.

hirschmann commented 6 years ago

I didn't write the Lenovo Ideapad 710S config. I just uploaded it, because it was sent to me by mail. Look at the author tag: https://github.com/hirschmann/nbfc/blob/f45d28291251b83a914d5b82019d62bbd34683a5/Configs/Lenovo%20Ideapad%20710S.xml#L4

I have put some datasheets and other documents in my onedrive, though. Maybe they can be useful: https://1drv.ms/f/s!AjbOVawzvTRsg0LQHhnEquRHA8Uj

erkexzcx commented 6 years ago

Sharing some more analysis and findings.

lenovo-ideapad-y700-disassembly-26

Both fans seem to be linked, but we have 2 separate EC registers providing fan speed values for each fan separatelly (read only):

FAN 0xFE (254): MAX - 0x25 (37) MIN - 0x00 (0)

FAN 0x06 (6): MAX - 0x28 (40) MIN - 0x00 (0)

To have some manual control or to be able to completely stop both fans, we can actually manipulate the mechanism which adjusts the fan speed according to multiple temperature readings. The mechanism checks the temperatures at registers 0xB0 (176), 0x56 (86) and 0x53 (83) and accordingly sets the fan speed.

My approach was to spam registers 176 and 86 with zeroes (so temperature seems to be 0 all the time) and just use register 83 for manual control and the result was this config - https://pastebin.com/fggB00vL

I will be further analyzing and searching for the ways to improve the config for this laptop, but for a reference that's all I have at the moment.

Note that there is also few other interesting variables in DSDT, which I will also test in the future:

AUTO, 1, 0x0D // Mode? FCHG, 1, 0x0E // Fan change?

MODE, 1, 0xAB // Mode? INIT, 1, 0xAD // Initialise? FAN1, 1, 0xAE // true/false for fan1? FAN2, 1, 0xAF // true/false for fan2? FAOK, 1, 0xB0 // fan OK? SDTE, 8, 0xB2 // spindown something? SPDN, 4, 0xB3 // spindown? FNUM, 4, 0xB4 // fan num?

erkexzcx commented 6 years ago

So after endless hours of debugging, analyzing and hacking, I've came with this config: https://pastebin.com/X7aVWWqE

When NVidia GPU is in use - the config seems to be no longer working. Disabling it and enabling it seem to help, but it's still not working as expected.

I am not sure if I am going to spend any more time on this particular laptop. Leaving config for someone's else investigations :) And not making pull request, since it works, but not quite in a useful way.

erkexzcx commented 6 years ago

also there was a moment when fans literally started to spin both at speed of 49 (0x31) for a moment and laptop turned off. I've never seen fan speed of this laptop reaching more than 40 in all testings.

If someone manages to get manual control working - that would be amazing!

arthurprs commented 6 years ago

There is some similarity with #521 (1 fan only). In that notebook I can't make it stop "fighting" the awful control from Lenovo.

I tried to copy what you did (write 0 to 86) but it didn't help.

erkexzcx commented 6 years ago

Hi arthurprs,

Probe ec registers with CPU intensive app (and ensure that NVIDIA is not in use - there is applet from nvidia control panel to see what apps use nvidia GPU):

ec-probe monitor -i 1 --clearly

Identify which registers contain temperatures (they will frequently change if you have CPU load) + they contain actual temperatures, just in hexademical. Try to spam these temperature registers with zeroes just like I did with register 86.

arthurprs commented 6 years ago

Interesting idea to write to the temperature register (in addition to the fan controller). I'll take a look

erkexzcx commented 6 years ago

As per my older comment, the mechanism seem to read multiple temperature registers and adjust the fan speed according to the highest value of them all. It works something like that, so this is why I decided to spam register 86 with zero and use register 83 to spam it with temperature which is being used by mechanism to set fan speed. And my config works, not perfectly, but works.

Both 83 and 86 seem to be temperature read-only registers. I just use them to manipulate fan speed.

Another important thing - if nvidia GPU is in use, then the config does not seem to work for me, so you need to use ec-probe tool to identify what register, to what value from what value it changes when NVidia GPU is powered on and when it's powered off. Switch it off - check registers. Switch it on - check registers again. Do it multiple times to identify what changes. If you are still struggling to understand what I mean - check Optimus technology:

Optimus Technology is a hybrid graphics implementation without a hardware multiplexer. The integrated GPU manages the display while the dedicated GPU manages the most demanding rendering and ships the work to the integrated GPU to be displayed. When the laptop is running on battery supply, the dedicated GPU is turned off to save power and prolong the battery life.

How to enable tray icon to check if nvidia is powered on (in use) or powered off (not in use):

There is a tray icon you can enable in the Nvidia Control Panel that shows when a application is using your discrete GPU. In the Nvidia CP, goto Desktop -> Display GPU Activity Icon in Notification Area.

Please report any findings - they might help me too :)

nQ8hzkZw commented 6 years ago

Hi erkexzcx,

There is a topic on Lenovo forums with similar problem. I posted some of my findings in that topic. For example, the INIT flag in 0xAB (171) register. Value 0x08 written to the 0xAB register disables the fan controller.

I tried writing zeros to the temperature registers but it has no effect on my Y720 (Lenovo Y720 has the same EC registers as Y700).

The script I used for the test: #!/bin/bash while true; do mono ec-probe.exe write 176 0 mono ec-probe.exe write 86 0 mono ec-probe.exe write 83 0 done

With "ec-probe.exe monitor" I see a brief moments when all temperature registers have 0. But the fans speed does not change. Am I doing something wrong? Are you able to stop the fans completely by writing to the temperature registers?

erkexzcx commented 6 years ago

Mentioning #316

I did spent so much time on it and just figured it out that this is technically not possible:


OperationRegion (EMMP, SystemMemory, 0xFF00D400, 0xFF) Field (ERAM, ByteAcc, Lock, Preserve) { Offset (0x01), VDAT, 8, VSTA, 8, Offset (0x06), FANS, 8,


Anyway, we are not giving up with reverse engineering. @hirschmann - I believe you should update https://github.com/hirschmann/nbfc/wiki/Analyze-your-notebook%27s-DSDT accordingly just to save community time trying to figure out what is not technically possible :)

erkexzcx commented 6 years ago

Hi nQ8hzkZw,

Since you are on Linux, this is a bit tricky for you:

  1. Using ec-probe write to in a script to spam register with desired value is not an option. How much it takes for this command to execute? Maybe 300-1000 ms while you need to spam register every like 100-300ms instead. So this is not an option neither for you, neither for me. Please remember this when looking at below step 7.
  2. You do not have graphical config editor. I both use Arch Linux on my Asus UX430UQ and Windows (on this laptop, owned by my gf), and it's the way easier to investigate it on Windows :)

However, I will mention steps for Windows, but you can easily reuse them on Linux:

  1. Go to nvidia control panel and select preferred processor - integrated graphics. This way you ensure that no app uses nvidia on startup (i've seen once that windows notes used it :D )
  2. Have this enabled. This way you ensure that no app uses nvidia and it's powered off:

image

image

  1. Disable any NBFC profiles on startup. Either set to read-only, or disable. Do not give any control to NBFC.

  2. Hold power off button for a 10 seconds, so it's forcibly powered off. This way you reset all registers.

  3. Boot up, open PowerShell terminal with admin rights and see if fan changes after you write this:

ec-probe.exe write 0x53 255

After like 0-15 seconds fans should start spinning at full speed.

  1. Write this:

ec-probe.exe write 0x53 0

See if fans should start spinning slower (but does not completely stop). You might also validate fan speeds using registers 0x06 and 0xFE.

  1. If this happens - congratulations, you have the same controlling mechanism as mine's. Now, if you think about why it does not stop, but just spins slower - you are right, there must be at least 2 temperature sensors which are being used to determine fan speed - this (0x53) and something else.

After some investigation, I realized that the second sensor is located at register 0x56 and if you spam it with zeroes - you can use 0x53 to literally manipulate fan speed mechanism. This is why I ended up with this config: https://pastebin.com/X7aVWWqE (yes, it is capable of fully stopping fans).

Now few things to consider:

  1. I don't know why, but on startup 0x53 is not being overriden by anything.
  2. If you put some cpu/gpu load - 0x53 is being overriden. Maybe check for that "flag" which causes 0x53 to be overriden?
  3. If you run any app under NVidia - my created config seem to no longer work. If you turn off the NVidia program - config still no longer works or works like after few minutes. The fan speed is literally seem to be stuck and won't change, even on very high GPU/CPU temps. If you disable NBFC - fans starts working again as usual. Maybe registers 0x56 or 0x53 has something to do with it?

Hope my investigation is helpful.

erkexzcx commented 6 years ago

Also I noticed that when NVidia GPU is powered off (being used), the register 0xBD changes to 0x80 and when GPU is not in use, it's set to 0x00.

When GPU is in use, register 0xB4 reports actual NVidia GPU temperature. When GPU is not in use - it is no longer updated and shows last temperature before GPU was turned off (so literally anything).

Unfortunately, these registers did not help me at all, so I just share what I discovered.

erkexzcx commented 6 years ago

Help needed. Anyone using Lenovo ideapad computers (expect Y700 and Y720) - please share their decompiled DSDT.

erkexzcx commented 6 years ago

Looks like fan control interesting registers are always +-5 numbers away from each other, according to other lenovo ideapad laptops. Maybe this helps a bit.

Lenovo Ideapad 500S-14ISK.xml Read register: 149 Write register: 148 Manual fan control register: 147

Lenovo Ideapad 710S.xml Read register: 149 Write register: 148 Manual fan control register: 147 and 150

Lenovo Ideapad 710S.xml Read register: 149 Write register: 148 Manual fan control register: 147 and 150

Lenovo Ideapad U330p.xml Read register: 146 Write register: 146 Manual fan control register: 144

nQ8hzkZw commented 6 years ago

@erkexzcx, Thanks for the detailed answer. You are right, the ec-probe write command takes a long time (~290 ms, according to the time command in Linux). I reduced the delay by running multiple instances of ec-probe write command. At this time I spammed these registers with zeroes for a longer time:

0x06: 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,13,13,13,13,13
0x0D: 1E,1E,1E,1E,1E,1F,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1E,1F,1F,1F,1F,1F,1F,1F,1F,1F,1F,20,1F,1F,1F,1F,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,1F
0x0E: 1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1D,1E,1E,1E,1E,1F,1F,1F,1F,1F,1F,1F,20,20,20,20,20,20,21,21,21,21,20,20,20,20,20,20,20,1F,1F,1F,1F,1F,1F,1F,1F,1E
0x53: 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,FF,FF,FF,FF,FF,FF,FF,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
0x56: 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,00,29,00,00,00,00,00,00,00,00,00,00,00,00,00,30,00,00,00,00,00,00,00,00,30,27,26,26,25,25,25,25,25,24,24,24,24,24,23,23,23,23,23,23
0xB0: 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,28,2A,2C,00,00,00,00,00,00,00,00,00,00,00,30,00,00,00,00,00,00,30,31,00,00,27,26,26,25,25,25,25,25,24,24,24,24,24,23,23,23,23,24,23
0xC6: 9A,9A,9A,9A,9A,9A,9A,9A,9B,9A,9A,9A,9A,9A,9A,9B,9B,9A,9A,9A,9A,9A,9A,9A,9A,9A,9B,9B,9A,9A,9A,9A,99,9A,9B,9A,9B,9A,9A,9A,9A,9A,9A,9B,9B,9A,9A,9A,9A,9A,9A,9A,9A,9A,9A,9A,9A,9A,9A
0xFE: 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,10,10,10,10,10

Unfortunately, writing to register 0x53 has no effect on my system. It seems that the fans control mechanisms on the Y700 and Y720 are not identical.

GeographicCone commented 6 years ago

Hi @erkexzcx!

I saw your post on the Lenovo forums. This is all very interesting. I've also been looking into fan control on the Y700. A summary of what I found out:

  1. Fan control by writing to the EC registers could be possible by spoofing temperature readings
  2. However, fan speed is not directly related to any particular temperature but determined by a more sophisticated algorithm, the behavior of which also depends on whether the dGPU is in use (offset 0xBD == 0x80 if true, 0x00 otherwise)
  3. Actual fine-grained fan control can be achieved by writing to \\.\EnergyDrv (an interface provided by the Lenovo Power Management driver)
  4. A Lenovo utility that provides a "dust extraction" routine comes with a complete library for all this, which can be reverse engineered: https://forums.lenovo.com/t5/Gaming-Laptops/Reducing-fans-noise-on-Lenovo-Legion-laptops/m-p/4125653#M17900

I see you delved very deep into (1), and it must have taken a lot of effort. I'd suggest though, for best results with fan control on these laptops (the same solution is likely to work with Y510p, Y520, Y720, etc. as well), it'd be most productive to allocate any resources towards (4). I believe the time investment in either solution is comparable but only with the latter would it be possible to make the fans do exactly what we want, while with the former we'd always be constrained by the inputs to the original algorithm.

(The library has other uses too such as battery control, and somebody has already figured out how to use a Bluetooth toggle inside it too, so the possibilities extend beyond just fan control.)

Towards (4), the first steps should be reproducing the "dust extraction" without the utility. I posted some more details about it here: https://github.com/hirschmann/nbfc/issues/419#issuecomment-402506162

TL;DR: If anyone wants to get involved with this, I'd suggest to: (1) download the utility linked above, (2) figure out how it does its "dust extraction" and (3) write a very simple program in your favorite language that does exactly the same (say, C or Python).

Then the library can be studied further and the program expanded accordingly. Once a working solution is found, it could perhaps be integrated into NBFC. It's probably going to be more and more laptops using this kind of fan control in the future (for the record, the EC on this laptop is an ITE IT8371; this might help in identifying other laptops this is also applicable to).

Meanwhile, I hope @hirschmann can forgive me for bringing all this here as even though it's technically out of the scope of NBFC at the moment, this feels like the most natural place to discuss all things related to fan control.

GeographicCone commented 6 years ago

For the record, I also started out the way @erkexzcx did: by looking at config files made for other Lenovo laptops. I did a comparison of all of them (this was back in June, things may have changed since). I'll share it here for completeness, maybe it helps in figuring out solutions for other Lenovo models:

== Config Comparison ==

Model          Read  Min     Max  |  Write Min     Max  |    Rst  |  Ext         Val
-- Group 1: Read 0x06, Write 0xB0 or 0x5? --
IP 500S-13ISK  0x06                  0xB0    0 ...  44         -
IP 510s        0x06   22 ...  41     0xB0   35 ...  90         0
U31-70         0x06                  0xB0    0 ...  44         -
Y 510          0x06   20 ...  41     0xB0   38 ...  90         0
Y 710          0x06    0 ...  59     0xB0   22 ...  80         0
Y 3 14         0x06                  0x56    0 ...  80         0
Y 11s          0x56                  0x57    0 ...  80
IP Y580        0x06    0 ...  35     0x5F    0 ...  95         -
-- Group 2: Read 0x95, Write 0x94, Set 0x93 to 20 --
IP 500S-14ISK  0x95                  0x94  116 ... 255       116     0x93         20
IP 710s        0x95                  0x94   72 ... 255        72     0x93, 0x96   20
TP E520        0x95                  0x94  175 ... 100       100     0x93         20
U41-70         0x95                  0x94  255 ... 116       116     0x93         20
V580           0x95                  0x94  255 ... 100         4     0x93         20
-- Group 3: Outliers --
IP U330p       0x92w                 0x92w 768 ... 257     65535     0x90          0
Y 2 13         0xAB                  0xAB    0 ...   8         8
Y 13 2191      0xF2, 0xF3            <--   255 ...   1         0     # Left & Right Fans
-- Group 4: ThinkPads Except Badge-Engineered (Not Applicable) --
TP Helix       0x47                  0x47    0 ...   7       128
TP T430s       0x47                  0x47    0 ...   7       128
TP T540p       0x47                  0x47    0 ...   7       128
TP X121e       0x47                  0x47    0 ...   7       128
TP X230        0x47                  0x47    0 ...   7       128

# Legend

Read   Hex  ReadRegister
- Min  Dec  MinSpeedValueRead
- Max  Dec  MaxSpeedValueRead
Write  Hex  WriteRegister
- Min  Dec  MinSpeedValue
- Max  Dec  MaxSpeedValue
Rst    Dec  FanSpeedResetValue
Ext    Hex  [RegisterWriteConfiguration:] Register
- Val  Dec  [RegisterWriteConfiguration:] Value

w - Word

And, as for the EC registers, I made an .irw information file with the identifiers for all of them pulled from DSDT (the entries reference SystemMemory but it mirrors the data in the EC), alongside some other sources and guesswork. Here's an overview of all the EC registers based on what I found out:

y700 ec overview

The table is color-coded as follows:

And the complete file is attached below. It can be viewed as plain text, or loaded into RwEverything:

rweverything ec information

EC_Y700.irw.txt

erkexzcx commented 6 years ago

Thank you guys for investigation and comments. I did not expect such amount of activity on this laptop or Lenovo laptops in overall regarding fan control.

Thanks, @GeographicCone for providing some light. I will for sure double check this once I have some spare time.

@nQ8hzkZw - the register 0xAB changed from 0x00 to 0x08 also disables fan controlling mechanism for Y700 model.

You know what? I will try to set up a script overnight to bruteforce all values from 0 to 255 on 0xAB with 15sec intervals after changing 0xAB, putting number (e.g. 0x30) to registers like 0x07 or 0xFF, wait another 15seconds and monitor if fan speed has changed. Something like that. I think it's worth trying :)

MODE, 1, 0xAB // Mode? INIT, 1, 0xAD // Initialise? FAN1, 1, 0xAE // true/false for fan1? FAN2, 1, 0xAF // true/false for fan2? FAOK, 1, 0xB0 // fan OK? SDTE, 8, 0xB2 // spindown something? SPDN, 4, 0xB3 // spindown? FNUM, 4, 0xB4 // fan num?

So these are interesting variables - I gotta keep digging on them, maybe they will be my next targets for bruteforce :)

erkexzcx commented 6 years ago

It's strange that 0xFE represents fan speed, and not 0xFF. Maybe 0xFF is reserved for writing fan speed of 0xFE? Also I did change something (for sure 0xAB, but not sure about 0xFF) and my laptop suddenly powered off itself and turned on again. I will keep investigating and will update in a day or two :+1:

Going back to my previous comments - maybe we have even higher fan speeds, but they are locked down?

also there was a moment when fans literally started to spin both at speed of 49 (0x31) for a moment and laptop turned off. I've never seen fan speed of this laptop reaching more than 40 in all testings.

Note about other lenovo models - the next register is usually for writting fan speed, so I assume similarily is in our laptop:

0xFE for reading 0xFF for writting, but I believe we need to find a "flag" to enable this.

this is just what I would like to believe :D

nQ8hzkZw commented 6 years ago

I did similar bruteforcing some time ago. Be careful with 0xBD register. I think it is responsible for overheating protection. One bit (values 0x80 or 0x40) in that register turns on the fans at full speed. If you set two bits (I don't remember which ones), the notebook suddenly shuts down.

EDIT: CPU frequency is locked at 800 MHz when changing value from 0x00 to 0x04 in 0xC1 register.

erkexzcx commented 6 years ago

Thanks for the info.

Bruteforcing 0xAB (values from 0 to 255), waiting 15sec., changing 0xFE and 0xFF values to 37, waiting for another 15sec - did not change value of 0xFE (fan speed.).

Will do some more bruteforcing & research with other registers as well.

GeographicCone commented 6 years ago

@erkexzcx

Yeah, bit 3 (INIT) is set at 0xAB when the "dust extraction" starts, so this could be some sort of manual override toggle for the fans.

@nQ8hzkZw:

Be careful with 0xBD register. I think it is responsible for overheating protection.

Offset 0xBD is described in the DSDT as GATY. Most likely this stands for "Graphics Adapter Type." It changes to 0x80 when nVidia GPU is in use, otherwise it is 0x00.

The fan control algorithm takes it into account whether the GPU is running, and behaves differently even though the temperatures didn't change. This is why I believe reverse engineering the library will be necessary to control the fans reliably.

If you make a change to the EC that violates some sort of internal consistency check: (1) the fans will start running at full speed, (2) the computer will power itself off after a couple of seconds. I first noticed this by accidentally flashing a saved RwEverything dump back into the EC.


Also note that the minimum interval for ec-probe is 1 second, which misses a lot of changes. RwEverything can be set to refresh much more often. Then it can be seen that a lot more is actually going on in the EC registers than what would be apparent from running ec-probe monitor.

DavidGretzschel commented 6 years ago

@erkexzcx @GeographicCone I tried erkexzcx's config with the Y720-15IKB. I couldn't ensure that the Nvidia Card stayed out of the picture, no matter what I did, so I disabled it in 'Device Manager'. Turns out, it's necessary to run an external monitor. The config sadly doesn't run any quieter. I'll check what I can learn tomorrow with RWEverything and the DustExtraction-Tool.

DavidGretzschel commented 6 years ago

I only see 'smart power-saving hard disk', no 'fan dust extraction' option available. I tried version 7.0.3.4 and 7.0.3.9. image

GeographicCone commented 6 years ago

@davidermined

I only see 'smart power-saving hard disk', no 'fan dust extraction' option available. I tried version 7.0.3.4 and 7.0.3.9.

Interesting. For the record, this is what it should look like (on your screenshot, there is even the space for it):

Energy Management - Dust Extraction

The kernel driver provides the service these utilities all connect to. One thing I can think of is that they could be competing for access to the same device.

You might be the first person to try running this on the Y720, so it's possible the utility no longer works but I think it's unlikely given how similar this laptop is to the Y700.

It could also happen if the MTM (Machine Type Model) or some of the other OEM strings are messed up but I think it's the least likely explanation, just mentioning it for completeness.

erkexzcx commented 6 years ago

Hey look what I see on my Y700:

image

So after turning it on and turning it off (dust removal), I see these changes:

untitled

0x01: 00,      03,      00,      03,00,03
0x06: 16,      32,31,   0C,16,   31,   31
0x0E: 20,                     1F,      1F
0x56: 1E,            1D,               1D
0x88: E0,   00,E0,                     E0
0x8A: C3,   00,C3,                     C3
0xAB: 00,      08,      00,      08,   08
0xB0: 1E,            1D,1E,   1D,      1E
0xC6: 40,42,41,      43,41,      40,41,41
0xFE: 1C,12,   32,31,   2C,25,1D,31,   31

0xAB changes accordingly - value 0x08 indeed disables fan control mechanism and 0x00 enables it back. Great - now I have to figure out if any of these registers allow me to have any fan control.

EDIT: Tried messing with 0x01 and 0xAB registers - not able to control fan in any way. :/

erkexzcx commented 6 years ago

register 0x01 seem to have different values during tests: 0x01, 0x02, 0x03, 0x05 and once seen 0xC1. I believe we also need to bruteforce this register with script.

0xAB seem to only have 0x08 value to disable fan control and 0x00 to enable.

arthurprs commented 6 years ago

Did you try setting both? (0xAB set to 0x08 and 0x01 to 0x03)

erkexzcx commented 6 years ago

Of course I did - nothing changes. If 0x06 and 0xFE are only for readings, then the dust removal tool only changes 0xAB and 0x01 registers. I am currently running a bruteforce script against 0x01 while having 0xAB set to 0x08. Trying to change registers 0x05, 0x06, 0x07, 0xFE, 0xFF, 0xAE and 0xAF.

DavidGretzschel commented 6 years ago

So... I've been wondering about the 'Intel 100 series C230 chipset Thermal Subsystem' that is shown in my device manager. Reading up on it's documentation in 7.1.1 it seems to have two 'usages': 1: send temperatures in half degrees, 2: send interrupts after temperature trip points have been reached.

From the documentation alone it's not clear, if enabled, it either always does both, does one or the other, or the functions are selectable. With my Graphics card on, my RW-table I can identify two registers, which seem to be showing temperature data, but those are unlikely to be in half degrees, because the values are too low for that (and there's two of them, anyway)*. Do we definitely know if the Intel Thermal Subsystem plays no role at all (from the documentation it's implied, that it can be disabled, which would seem sensible, as it has rather terrible accuracy (see 7.1.3), but then again, that might just be a cause of the terrible, observed behaviour)? Kinda scared to just disable it, bcs. I don't know if that action has bricking potential (though, I can be convinced by some authorative sounding "No, it won't. This is fine."). I think it might be possible, that the chipset doesn't use function 1, but measures the temperature anyway and sends out interrupts with function 2, based on that. I wish the doc was less ambiguous there.

Another thing, I noticed in the documentation is on 30.7 the line saying "Both SMLink0 and SMLINK1 support up to 1Mhz." In 7.4.1 it also says, that the chipset can use the SMLink 1 or the eSPI interface for thermal reporting. In If that's a common enough value for a temperature probe to send an update, then it would be hard to outspam it with a measly signal every 10ms, wouldn't it? But as @erkexzcx seems to have some success with spamming false temperature data, it might also point to the chipset not being involved or at least not using SMLink1?

Is the chipset entirely the wrong tree to bark up for some obvious reason, I'm oblivious to and everybody knows this, already? If not, do we all use the same chipset?

*The values that are in the right range to be temperatures (and that respond to extreme cooling by going down) are 0x56 and 0xB0. I also noticed, that the fans reach a tolerable noise level at around 35 degrees or so (don't remember exactly, but any realistic light usage will push the temperatures up enough to trigger the annoying fans**), so maybe spamming 0 degrees might be overkill. Another weird thing is, that the chipset has a an accuracy specified for the range of -10 to 30 degrees, but no way of sending minus-degree values, instead opting to send values of up to 254 degrees (7.1.4)(0xFF/255 is reserved for booting up/no sensor data yet), well above any trip point (though this might be an inconsistency in the documentation, because they might confusingly refer to half degrees here).

**a silly analogy came to mind: The temperature is Justin Bieber, who is admittedly somewhat hot, but his true hotness is vastly overrated by his annoying, constantly screaming fans, the True Beliebers. The problem thus is the Lenovo BelieberGate.

@GeographicCone I had Nerve Center and the Yoga energy management program on. I'll uninstall Yoga and disable Sense and then try after reinstalling the program.

image 100-series-chipset-datasheet-vol-1.pdf

DavidGretzschel commented 6 years ago

@GeographicCone Killed NerveCenter from TrayIcon. Tried to kill all the .exe . Invalid query every time. Guess that means, they were already dead? "sc query acpivpc" doesn't produce output (don't know if it's supposed to). Still no dust extraction after reinstall. Battery shows is about the same as Windows tray icon, but it updates a bit slower, I think. It correctly registers, if it's charging or not. Could you check, if I somehow screwed up the commands in PowerShell?

image

DavidGretzschel commented 6 years ago

I have made a video of the EC, where I turned ExtremeCooling on and off. Together with the DSDT.txt I might discover some things about the 720.

The protocol was (not exact values): 1 min off 3 min on a couple times: 20 sec on/ 20 sec off many times: 5 sec on/5 sec off many more time: 1 sec on/off

@GeographicCone Is that approach a good start for creating an .irw-table, like you did? Could you also upload your DSDT, so I can better understand, how you interpret it? (I'll of course, compare with yours and hope, that it has the same structure/is shifted)

Link to the video, if anyone wants to try, as well. https://files.fm/u/pbmfpveg

DSDT.txt

DavidGretzschel commented 6 years ago

@erkexzcx so my temperature and fan speed registers are the same. Which I could have noticed earlier, if I'd read more carefully and looked at them first, instead of discovering them on my own. Oh well.

erkexzcx commented 6 years ago

@davidermined so you were able to stop fans completelly by using my previously provided config? :)

DavidGretzschel commented 6 years ago

No, not that. I've already tried that. But I know a little bit more what I'm doing and will test it again, now. Maybe I missed a step.

erkexzcx commented 6 years ago

Well, for my register 0x53 setting to 0xFF or anything higher than 85 (in decimal) puts fans at "max" speed (40 in decimal).

Also, 0x53 looka to be temperature sensor and I don't accuratelly remember how I discovered. I think i used furmark app to put some GPU load (most effective way to spin fans) and therefore I noticed it. Maybe it's similar in your set-up - try to find it the same way like I did. Note that when doing it my nvidia was in use.

And yeah - 0x53 is not changing after boot, it's just start to change a bit later or after giving computer some load. I can't confirm how to make it "change", but as I stated earlier - try to find if such register exists on your set-up. It might just have different location in EC :)

DavidGretzschel commented 6 years ago

Ok, still not working. I can't exactly turn off the Graphics Card (no software off switch), but I made it prefer processor for stuff in the NVidia control panel. The indicator applet in the tray doesn't show any programs using the card. The task manager confirms that. Is that, what you did, to ensure it's really off or do you have some kind of software-off (in that case, I'd disconnect it in device manager again).

I am on the latest BIOS for my machine, it's possible they locked down the access? This might have happened even across generations, so even downgrading the BIOS might not work, but I will try it, if I've got no better approach.

The profile should be put to target speed 0%, I'm assuming (tried auto and some others as well with no effect either)?

DavidGretzschel commented 6 years ago

Ohh.. maybe I should have explained better before about what I did. Extreme Cooling is a Lenovo NerveSense feature, that spins the fans to it's maximum for heavy gaming sessions. I guess, I just quietly assumed, everyone had that feature. The registers were easy to discover with Extreme Cooling. Temperature goes down, Fan Spinners go up.

So.... is the whole point of the Dust Extraction protocol to get the fans spinning as fast as possible, as well? (I never asked myself exactly what the Dust Extraction actually does....) 'Cause if so, then I don't need it. Extreme Cooling would do the same.

DavidGretzschel commented 6 years ago

I didn't notice that 0x53 wasn't changing. It always changed with the temperature, when I looked at it. 0xFF being the default would be consistent however with it being the Chipset Thermal Subsystem, therefore specifically the processor's temperature probe. 0xFF is the processor's way of telling to the system, that it's not measuring yet. Thus it's very likely that the chipset's thermal probe is being used.

The system might be going at max speed in that case, because for all it knows, the processor could be on fire. My fans also spin at max-speed when booting, but as soon as I see the windows screen, they calm down to normal annoying levels.

Your system is about 2 to 3 years older, so maybe that's some progress they've made in the meantime.

erkexzcx commented 6 years ago

0x06 register and 0xFE shows 0 as expected if fans are not spinning. If you put heavy GPU load and by doing it get fans running as fast as possible - you won't see 0x06 reaching more than 40 (0x28) and 0xFE reaching more than 37 (0x25).

By using dust-removal tool, fans are being spinned at 49-50 (0x31-0x32) speed** for short period of times (spins for about minute, ~10 sec pause and repeat that several times). So if your mentioned extreme cooling software spins fans at about 49-50, then I believe you don't even need dust removal software to test it :)

**If you look at DSDT:

                        If (LEqual (Arg1, 0x09))
                        {
                            Store (^^PCI0.LPCB.EC0.FA2S, Local0)
                            Multiply (Local0, 0x64, Local0)
                            Return (Local0)
                        }

these numbers seem to be multiplied by 0x64 which means 100 in decimal and I think this is how RPM speed is actually generated (e.g. 40 means 4000 RPM)

DavidGretzschel commented 6 years ago

My 0x06 and 0xFE registers show up to 0x29 (41), even. So I'm glad that's settled.

I looked at the reviews for our laptops each: https://www.notebookcheck.net/Lenovo-Ideapad-Y700-15ISK-80NW-Notebook-Review.155878.0.html#toc-emissions

https://www.notebookcheck.net/Lenovo-Legion-Y720-7700HQ-Full-HD-GTX-1060-Laptop-Review.218710.0.html#toc-emissions

(mine isn't quite right, as I have the i5 version, but that's the closes I could get)

For your model, they say it's supposed to be inaudible on PowerSaver and integrated graphics. Is it? Could you compare the decibel level with a phone app?

DavidGretzschel commented 6 years ago

Okay, I wont reach 50, but I don't even know, if my fans could even go that fast. There's a speed difference, that's the point. [all this constant switching between reading decimal and hex is really confusing] 4000 rpm sounds about right for a laptop fan. Not sure if that spec is listed, anywhere to confirm.

erkexzcx commented 6 years ago

So moving back to the drawing board, nobody seem to find any solution to manually control the fan speed.

Lenovo power management software is capable of controlling fan speed by putting it to max (more than laptop itself spins on highest temps), but yet this is not a fan control. It just shows that software somehow can control fans.

For Y700 - proof that my above given in pastebin profile can control fan speed: https://drive.google.com/file/d/1XbcEnNUxMZ8S6DPoSDIGn3KSMMm6eH1g/view?usp=drivesdk

So I don't see this thread going any further - it's just does not work. Leaving this issue open until github closes its platform, the world ends or someone finally reverse engineer and figure it out the way to control fan speed.

DavidGretzschel commented 6 years ago

@erkexzcx @GeographicCone After 'nightfever' mentioned that the y920 had fan temperatures and possibly even control in the Nerve Center and 'Agatio' mentioned that some intel-dll looked promising in the same forum thread, I installed the y920 version of Nerve Center for my y720 (after getting rid of the original y720 version of it). https://forums.lenovo.com/t5/Gaming-Laptops/Lenovo-Y720-fans-too-sensitive/td-p/3983693

It didn't give me any more options, but after I searched in C:\Program Files\Lenovo\Nerve Center\ I found among many other .dll files: FanManagerPlugin.dll and IntelOverclockingSDK.dll FanManagerPlugin is mostly Gibberish/unreadable characters, but in IntelOverclockingSDK.dll with Notepad+ and just searching for 'temp' alone yields 381 hits. The second occurence is already promising with similar xml-like entries around it:

Range Automatic Minimum Fan Speed % The Minimum Fan Speed represents the power that will be applied to the fan controller when the temperature of the associated zone is below the Minimum Temperature for that zone.

Not quite sure how to properly edit these and what would happen, if I did, but these do look rather lovely and convenient. Anyone interested in exploring these or helping me do it? I uploaded the /bin/x64 folder, where many of those dll-files are. x64.zip

DavidGretzschel commented 6 years ago

I don't know, if I had these to begin with in my y720 Nerve Center installation. Or if it even was actually a different installer for the y920-Nerve Center.

likeMyCoffee commented 6 years ago

Hello all, I'm the unlucky owner of a Lenovo Yoga 520-14IKB with crappy noisy fan :'(

I believe I have found some good information. Checking out https://github.com/coreboot/coreboot/blob/master/src/ec/compal/ene932/acpi/ec.asl gives possibly some more info on the registers.

Small snippet shows two thermal shutdown temperatures which are 0x64 in my EC which is 100C. This means that this is close if not equal to the EC we are dealing with.

It also gives info on the registers and might help us....

Offset(0xA7 to 0xA8), OSTT, 8, // OS Throttling Temp OSST, 8, // OS Shutdown Temp

(Offset 0xAB) MODE, 1, // Mode(0=Local, 1=Remote) ,2, // Reserve INIT, 1, // INITOK(0/1=Controlled by OS/EC) FAN1, 1, // FAN1 Active FAN2, 1, // FAN2 Active FANT, 1, // FAN Speed Time OK (FAOK) SKNM, 1, // Skin Mode (0/1 = Skin Address 90/92)

(Offset 0xAC) SDTM, 8, // Shutdown Thermal Temperature

(Offset 0xB0 to 0xB6) CTMP, 8, // Current CPU Temperature CTML, 8, // CPU local temperature SKTA, 8, // Skin Temperature A SKTB, 8, // GPU Temperature SKTC, 8, // Skin Temperature C , 8, // Reserved NTMP, 8, // North Bridge Diode Temp

github-actions[bot] commented 4 years ago

This issue is stale because it has been open more than 180 days with no activity. If nobody comments within 7 days, this issue will be closed

mmhobi commented 4 years ago

0xBD= 0x80 sets to match GPU need (I believe), setting it to =0x40 forces extreme cooling. https://gitlab.com/OdinTdh/extremecooling4linux/-/blob/master/ec4Linux.py more searching around, Lenovo nerve-sense for Y720 (730? 700? i dont remember) does not use 0xBD, instead it sets 0x39 to 1, which I believe turns on manual control. From there there's 2 more registers that are changed by nerve-sense but unwritable normally (but I believe 0x39=1 enables writing to them, didn't check).

nervesense extreme on overrides 0xBD=0x00/0x80, and 0xBD=0x40 overrides nervesense extreme off

Heres the datasheet for what I believe is the ec we're all rocking: https://gofile.io/d/AoYkZ0 (thanks https://github.com/hirschmann/nbfc/issues/707) Fron the openboot file there is a register i saw change from 01 and 11 which would match up with

    FSSN, 4,        // Fan Speed Step Number                ; ADh.0-3
                        // 00 : Fan Off
                        // 01 : Fan On Speed 1
                        // 10 : Fan On Speed 2
                        // 11 : Fan On Speed 3

when I have time I'll look into it more, but my logic goes, 0xBD to 0 (80 enables gpu monitor?), 0x39 to 1, and then FSSN to whatever. I tried reverse engineering the nerversense but it kept crashing when running with a debugger. I'll try some more later.