amdctl
amdctl copied to clipboard
Ryzen 2500U CpuFID is higher than limited, inaccurate frequency calculation
Hello @kevinlekiller, this time I'm writing you because of a Ryzen mobile APU. Please look at the default values are used for P0, modifying the fid value to something high at the line 125 is enough. However this time I couln't find the BKDG document for fam17h. It would be hard to guess the value. I have some desktop 1st and 2nd gen Ryzens at home, I can check those too. `# amdctl -g -c 1 Voltage ID encodings: SVI (serial) Detected CPU model 11h, from family 17h with 8 CPU cores.
Core 1 | P-State Limits (non-turbo): Highest: 1 ; Lowest 3 | Current P-State: 3 Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower 0 1 100 10 53 20.00x 2000MHz 1219mV 20 10 30.00A 36.56W 1 1 102 12 96 17.00x 1600MHz 950mV 17 10 27.00A 25.65W 2 1 50 12 120 8.33x 800MHz 800mV 16 10 26.00A 20.80W 3 0 0 0 88 -nanx 0MHz 1000mV 0 10 10.00A 10.00W Northbridge: No P-States on AMD17H Northbridge.`
Apart from that the minimum freq is around 750MHz with this settings. Do you have any ideas what should we do?
Best regards
I think I got the info from the register reference, the FID register address is listed on page 130.
When I tested with a 2700x and a 2400g a few years back the numbers looked odd, especially P-State 3 like yours, I didn't look into it however since the motherboards those were in allowed proper over/under clocking unlike mobile CPU's like your 2500U.
Perhaps the way Zen calculates the CPU frequency is different than what the math which is currently used.
Looking at the commit, here's how tha math is done CpuFid && CpuDid ? (int) ((CpuFid / CpuDid) * REFCLK * 2) : 0;
So with P-State 2 you have a FID of 50, a DID of 12 and REFCLCK is usually 100: (50 / 12) = 4.16666666667 * 100 * 2 = 833.33, which doesn't match the 800 oddly, but like you wrote it shows 750 so something obviously is off.
Maybe the REFCLK changes on Zen?
The information in the DID section is complex, I don't understand it all:
CpuDfsId: core divisor ID. Read-write. Reset: XXXXXXb. Specifies the core frequency divisor; see CpuFid. For values [1Ah:08h], 1/8th integer divide steps supported down to VCO/3.25 (Note, L3/L2 fifo logic related to 4-cycle data heads-up requires core to be 1/3 of L3 frequency or higher). For values [30h:1Ch], 1/4th integer divide steps supported down to VCO/6 (DID[0] should zero if DID[5:0]>1Ah). (Note, core and L3 frequencies below 400MHz are not supported by the architecture). Core supports DID up to 30h, but L3 must be 2Ch (VCO/5.5) or less.
From what I can understand, DID can be max 48 and the clock speed can't be less than 400MHz.
I don't think that AMD is playing with the reference clock by default. It might has some changes between 97-103 MHz, but this architecture has a fine grain P-state modification algorithm, IMHO this is why there is a higher ranger for the CpuFID value. I tried the highest value and it seems to be the CpuFID is maximized at 128.
I checked on a 2500g, with default settings the fid shows up to 144:
Core 0 | P-State Limits (non-turbo): Highest: 1 ; Lowest 3 | Current P-State: 2
Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower
0 1 144 8 16 36.00x 3600MHz 1450mV 36 10 46.00A 66.70W
1 1 138 12 92 23.00x 2300MHz 975mV 23 10 33.00A 32.17W
2 1 128 16 108 16.00x 1600MHz 875mV 16 10 26.00A 22.75W
3 0 0 0 88 -nanx 0MHz 1000mV 0 10 10.00A 10.00W
Can't change the settings on it since it's not my CPU.
Perhaps for now a limit of 192 on Fid could be set, since we don't know what the max is?
I found this doing a search, but I doubt that's the max.
https://hardforum.b-cdn.net/data/attachment-files/2017/03/76381_PStateCalc.png
I found exactly the same, I just forgot to add here. I'll test the new version later this week, thanks!
v0.3
# ./amdctl03 -g -c 0
Voltage ID encodings: SVI (serial)
Detected CPU model 11h, from family 17h with 8 CPU cores.
Core 0 | P-State Limits (non-turbo): Highest: 1 ; Lowest 3 | Current P-State: 3
Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower
0 1 100 10 80 20.00x 2000MHz 1050mV 20 10 30.00A 31.50W
1 1 86 12 104 14.33x 1400MHz 900mV 17 10 27.00A 24.30W
2 1 50 12 124 8.33x 800MHz 775mV 16 10 26.00A 20.15W
3 0 0 0 88 -nanx 0MHz 1000mV 0 10 10.00A 10.00W
Northbridge:
No P-States on AMD17H Northbridge.
v0.4
# ./amdctl04 -g -c 0
Voltage ID encodings: SVI (serial)
Detected CPU model 11h, from family 17h with 8 CPU cores.
Core 0 | P-State Limits (non-turbo): Highest: 1 ; Lowest 3 | Current P-State: 3
Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower
0 1 100 10 80 20.00x 2000MHz 1050mV 20 10 30.00A 31.50W
1 1 86 12 104 14.33x 1433MHz 900mV 17 10 27.00A 24.30W
2 1 50 12 124 8.33x 833MHz 775mV 16 10 26.00A 20.15W
3 0 0 0 88 -nanx 0MHz 1000mV 0 10 10.00A 10.00W
Northbridge:
No P-States on AMD17H Northbridge.
$ grep MHz /proc/cpuinfo
cpu MHz : 731.757
cpu MHz : 731.851
cpu MHz : 731.671
cpu MHz : 731.115
cpu MHz : 731.069
cpu MHz : 732.010
cpu MHz : 731.687
cpu MHz : 731.420
Looks great, the calculated frequencies are aligned with the multiplier. However it's still different from the one which the cpuinfo reports.
$ sudo ./amdctl05 -g -c 0
Voltage ID encodings: SVI (serial)
Detected CPU model 11h, from family 17h with 8 CPU cores.
Core 0 | P-State Limits (non-turbo): Highest: 1 ; Lowest 3 | Current P-State: 3
Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower
0 1 100 10 80 20.00x 2000MHz 1050mV 20 10 30.00A 31.50W
1 1 86 12 104 14.33x 1433MHz 900mV 17 10 27.00A 24.30W
2 1 53 12 124 8.83x 883MHz 775mV 16 10 26.00A 20.15W
3 0 0 0 88 -nanx 0MHz 1000mV 0 10 10.00A 10.00W
Northbridge:
No P-States on AMD17H Northbridge.
$ grep MHz /proc/cpuinfo
cpu MHz : 798.075
cpu MHz : 798.403
cpu MHz : 798.448
cpu MHz : 796.839
cpu MHz : 798.253
cpu MHz : 796.768
cpu MHz : 798.152
cpu MHz : 797.55
I think that's because of "SenseMI", which is why there are so few power states on Zen CPU's.
Precision Boost, part of SenseMI, there are 4 P-States that the OS can use, but the CPU has other P-States (thought it said 1000's, but it's 25MHz spacing I read somewhere else) it can apply over or under those 4 P-States: https://images.anandtech.com/doci/11170/AMD%20Ryzen%20Tech%20Day%20-%20Architecture%20Keynote-24%20-%20Copy.jpg
I think the fine grade P-states are important in case of using them as intermediate P-states, which are limited between the minimal and maximal values as reference.
That makes sense, although it's odd it says the current P-State is 3, when it would make more sense for it to be 2.
Edit: I think it's because pre Zen the state in used is incremented? I don't have access to pre-zen anymore unfortunately.
Now it shows the correct P-State in use on the 2400g at least:
Detected CPU model 11h, from family 17h with 8 CPU cores.
Core 1 | P-State Limits (non-turbo): Highest: 0 ; Lowest 2 | Current P-State: 0
Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower
0 1 144 8 16 36.00x 3600MHz 1450mV 36 10 46.00A 66.70W
1 1 138 12 92 23.00x 2300MHz 975mV 23 10 33.00A 32.17W
2 1 128 16 108 16.00x 1600MHz 875mV 16 10 26.00A 22.75W
cat /proc/cpuinfo | grep MHz
cpu MHz : 1600.000
cpu MHz : 1600.000
cpu MHz : 1600.000
cpu MHz : 1600.000
cpu MHz : 3600.000
cpu MHz : 1590.908
cpu MHz : 1600.000
cpu MHz : 1545.487
Also matches the info from cpupower:
cpupower frequency-info
analyzing CPU 0:
driver: acpi-cpufreq
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: Cannot determine or is not supported.
hardware limits: 1.60 GHz - 3.60 GHz
available frequency steps: 3.60 GHz, 2.30 GHz, 1.60 GHz
I might be wrong about my previous post, it looks Current P-State is inversed?
sudo ./amdctl -g && i=0; for m in $(grep -Po "MHz[\s:]+\d+" /proc/cpuinfo | grep -o [0-9]*); do echo "Core $i $m MHz"; ((++i)); done
If I run that with some cores at max frequency it looks like it's inversed.
The AMD PDF says:
CurPstate: current P-state. Read,Error-on-write,Volatile. Reset: XXXb. This field provides the frequency component of the current non-boosted P-state of the core (regardless of the source of the P-state change, including Core::X86::Msr::PStateCtl[PstateCmd]. 0=P0, 1=P1, etc. The value of this field is updated when the COF transitions to a new value associated with a P-state
Which is confusing. ("the frequency component ")
The lowest P-state is definitely fine as is. I assume, the calculation is wrong somehow.
Yeah, I'm assuming it has to do with the description of CpuDfsId
, it would require an extra function to read or write to those specific bit ranges which should then read the correct value, by reading the "base" bit range, it shows the default P-State value, while reading those other bit ranges show the actual current value, I'll have to do some testing to figure out how it works exactly.