irusanov/ZenStates-Core

ZenStates for linux

Opened this issue ยท 22 comments

First of all, thanks for all the work and updates on this tool.

I'm submitting the issue here since
https://github.com/irusanov/ZenStates-Linux
doesn't have an option to submit an issue.

I was trying to use the zenstates-linux and tried P-state and oc-enable modes but none of these do anything in realtime even though the response says it's applied. The processor is a Threadripper 3970X, so it's a matisse?

Hi,

I haven't touched such a system, but in theory it should work, unless it is locked by the motherboard bios.
P-States don't work on newer generations and this feature is useless.

You have 2 modes:

  • auto
  • manual overclock (which works with a static frequency)

You can also tune the limits in auto mode.
When in manual OC mode, the only options available are the --oc-frequency and --oc-vid
--oc-frequency is in MHz units (integer, in 25MHz steps), so you will need to enter e.g. 3800.
--oc-vid is in VID (HEX number 0x0 - 0xFE range), lowest number 0x0 results in 1.55V. The higher you go with VID number, the target voltage gets lower.

You should also get some monitoring software to see if they have changed.
Have you checked if the (max) frequency changes when you enable --oc-enable?

I should find time to work on this, it could be much better...

@irusanov see below. 3600 MHz is set in BIOS btw. The p-states values might not be stock (as I had played with it before) but the manual oc mode doesn't reflect changes applied even though it says successful.

lscpu | grep MHz CPU MHz: 3600.080 CPU max MHz: 3600.0000 CPU min MHz: 2200.0000

python3 /root/git_repos/ZenStates-Linux/zenstates.py --no-gui -l

CPUs: 1
CPUID: 00830F10
Package Type: 7
P0 - Enabled - FID = 88 - DID = 8 - VID = 5A - Ratio = 34.00 - vCore = 0.98750
P1 - Enabled - FID = 96 - DID = A - VID = 60 - Ratio = 30.00 - vCore = 0.95000
P2 - Enabled - FID = 90 - DID = C - VID = 70 - Ratio = 24.00 - vCore = 0.85000
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Enabled
C6 State - Core - Enabled

python3 /root/git_repos/ZenStates-Linux/zenstates.py --no-gui --oc-enable --oc-vid 5A --oc-frequency 3500

CPUs: 1
CPUID: 00830F10
Package Type: 7
Enable OC Mode
Set OC VID to 5A
Set OC frequency to 3500MHz

lscpu | grep MHz
CPU MHz: 3600.074 CPU max MHz: 3600.0000 CPU min MHz: 2200.0000

Ignore the P-States, they are not updated and not used. Newer CPUs use hw P-States internally.
I will check if lscpu shows correct frequency on my system, might be a display issue if it reads it from e.g. P-State.
If so, one workaround would be to also update the P-State0, which will not have any effect, but just for display.

CPUs: 1
CPUID: 00830F10
Package Type: 7
Enable OC Mode
Set OC VID to 5A
Set OC frequency to 3500MHz

So I changed p0 to reflect the oc frequency that I applied previously but the frequency still hovers at 3600

CPUs: 1
CPUID: 00830F10
Package Type: 7
P0 - Enabled - FID = 8C - DID = 8 - VID = 5A - Ratio = 35.00 - vCore = 0.98750
P1 - Enabled - FID = 96 - DID = A - VID = 60 - Ratio = 30.00 - vCore = 0.95000
P2 - Enabled - FID = 90 - DID = C - VID = 70 - Ratio = 24.00 - vCore = 0.85000
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Enabled
C6 State - Core - Enabled

Appreciate your help so far.

I can confirm lscpu doesn't show the frequency. Even when in OC mode, the frequency is not really fixed, cores drop to what seems to be lowest active P-State2.
Even if you "disable" all P-States nothing happens and they are not respected

~/ZenStates-Linux$ sudo python3 zenstates.py --no-gui -l
CPUs: 1
CPUID: 00A20F10
Package Type: 2
P0 - Disabled
P1 - Disabled
P2 - Disabled
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Enabled
C6 State - Core - Disabled

The OC frequency is set though. You can watch for changes every second with
watch -n1 "lscpu | grep MHz"
or even every 100ms
watch -n.1 "lscpu | grep MHz"

You will see the frequency jumps to the required one. You can also run some benchmark like blender to see if it stays at 3500.
Let me know if this works.
Otherwise, you can probably use some monitoring tool like ryzen monitor, but it requires a kernel module to be installed.

PS: Currently, you have to supply the --oc-enable swith every time you want to change the --oc-frequency or --oc-vid
Example
sudo python3 zenstates.py --no-gui --oc-enable --oc-frequency 3500

It's always possible that it doesn't work for you though, as it seems you do everything correctly :/

I have also pushed a WIP branch with all the changes I had laying around, but I doubt it would make a difference:
https://github.com/irusanov/ZenStates-Linux/tree/WIP

Uff, I think the problem is it uses the "Rome ES" code, while this is Castle Peak. That's why it is not working.
I have pushed a workaround in the WIP branch. Retail CastlePeak is the same as Matisse and Vermeer.

Uff, I think the problem is it uses the "Rome ES" code, while this is Castle Peak. That's why it is not working. I have pushed a workaround in the WIP branch

Yes. it's the CPUID issue. the WIP branch works great.

./zenstates.py --no-gui --oc-enable --oc-frequency 3500 --oc-vid 58
CPUs: 1
CPUID: 0x00A20F10
Model: 0x21 (33)
Package Type: 0x2
Enable OC Mode
Set OC VID to 58
Set OC frequency to 3500MHz

it picked up the changes correctly now with oc frequency.
lscpu does display correct clocks as long as we keep the updates to milliseconds or so.
But I was monitoring using so it should be correct
watch -n0.1 "grep \"^[c]pu MHz\" /proc/cpuinfo"'

Cool, it was an overlook from my side, this should have been the first thing to check.
Will try to find some time to finish the WIP branch - I'm going to use model instead of cpuid as in the Core dll and also update other supported CPUs.

Thanks for your patience :d

hold on a minute. I jumped the gun in excitement. I was use WIP on 5950X which obviously worked before as well.
On this one (3970X) I get the below error.
File "/root/git_repos/ZenStates-Linux/zenstates.py", line 389 if _pkgtype == 7 and _cpuid not 0x00830F10: # Rome ES ^ SyntaxError: invalid syntax
should be !=

fixed it and it works now.

CPUs: 1
CPUID: 0x00830F10
Model: 0x31 (49)
Package Type: 0x7
Enable OC Mode
Set OC VID to 5A
Set OC frequency to 3500MHz
root@trx40:~/git_repos/ZenStates-Linux# python3 /root/git_repos/ZenStates-Linux/zenstates.py --no-gui --oc-enable --oc-vid 5A --oc-frequency 3400
CPUs: 1
CPUID: 0x00830F10
Model: 0x31 (49)
Package Type: 0x7
Enable OC Mode
Set OC VID to 5A
Set OC frequency to 3400MHz

yes, try
if _pkgtype == 7 and _cpuid != 0x00830F10

yes, try if _pkgtype == 7 and _cpuid != 0x00830F10

Yup. already done so and it works :)

I also force-pushed it. Glad it finally works :)

Hey, I was also looking into using ZenStates on Linux and bumped into ryzen_smu which can also read and write to the SMU.

Right now I'm looking at your code for ZenStates and I have a question about this line in GetPsmMarginSingleCore:

result.args[0] = coreMask & 0xfff00000;

My goal is to set PsmMargin, but I first need to figure out what it is actually set to before I just blindly write wrong values here. I need to write this coremask to /sys/kernel/ryzen_smu_drv/smu_args before sending 0x35. I could just write the assumed value with 0x36 but I like to verify what I'm doing.

What values does coreMask take?

Like 0x01000000 would be the second core? Does this account for SMT or just physical cores? Or do I need to write a mask based on the core_id , core_complex and/or ccd_id?

I basically just want to read the current PsmMargin and then set it to -30 for all cores, I assume it is going to be eight cores for the 5800X3D.

edit:

I just realized that the value I'm trying to read here is probably already zero!

printf '%0*x' 48 0 | fold -w 2 | tac | tr -d '\n' | xxd -r -p | sudo tee /sys/kernel/ryzen_smu_drv/smu_args && printf '\x36' | sudo tee /sys/kernel/ryzen_smu_drv/mp1_smu_cmd

Sets it to zero on all cores, I'm not sure what the correct values should look like for negative numbers. I tried "1e0010000000000000000000000000000000000000000000" for "-30" but that put the CPU in super slow mode :D

Ok this idiot figured it out e2ffffffffffffff00000000000000000000000000000000 is the correct value for -30.

You can just dot a negative number into the command I posted to set the offset!

printf '%0*x' 48 -30 | fold -w 2 | tac | tr -d '\n' | xxd -r -p | sudo tee /sys/kernel/ryzen_smu_drv/smu_args && printf '\x36' | sudo tee /sys/kernel/ryzen_smu_drv/mp1_smu_cmd

@sfjuocekr

I'm still working on it, slowly, but you can check:

https://github.com/mann1x/ryzen_monitor_ng

It should work also on the 3D, a lot of SMU commands are already implemented and can be changed via command line.

But you need to use v0.1.4 of my version of ryzen_smu:

https://gitlab.com/mann1x/ryzen_smu/-/tree/9a9499f519c4ba2e5ab985275edafeee4da66a2f

@sfjuocekr For PSM margin I have an utility function which might give you an idea how to set it.

https://github.com/irusanov/ZenStates-Core/blob/master/Utils.cs#L101

the parameter is 16bit only, for -30 it would be 0xffe2
0x100000 - 0x1e

As for cores, you have to account for the ccx as well. CoreMask is used for the get and set command for a single core and I also have a helper for it:

public uint MakeCoreMask(uint core = 0, uint ccd = 0, uint ccx = 0)

((ccd << 4 | ccx % ccxInCcd & 0xF) << 4 | core % coresInCcx & 0xF) << 20

For Zen3 and Zen4 you only have the ccx and core parameter.

Yea, I was kind of tired last night and got put off by these lines and failed to get my math right:

int offset = margin < 0 ? 0x100000 : 0;
return Convert.ToUInt32(offset + margin) & 0xffff;

Maybe ZenStates-Linux could include these or maybe instead of yet another monitoring utility with extra functionality we could get our heads together and make some dedicated control utility out of it (zenctl?) that uses libsmu from ryzen_smu.

Yes, I agree that would be the best - to join forces and make one application which would be the alternative of RyzenMaster, but for Linux. I will add these in ZenStates-Linux at some point, but have no ETA. I had GTK3 GUI in the works, but also unfinished.

What about Uno?

https://platform.uno/