aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSHENGYI HONG <aokblast@FreeBSD.org>2024-12-09 03:18:18 +0000
committerMark Johnston <markj@FreeBSD.org>2025-01-16 14:25:45 +0000
commit0e6e1f14f0a7cfabec38106e41cb2f7a39363e55 (patch)
tree7befa8b60d67e46fe1303bbf8998b85fe6bb4ddb
parent621569254cd0b0639488aa5d7b8143cef7c90a18 (diff)
hwpstate_amd: add amd pstate for zen5
Reviewed by: markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D47985
-rw-r--r--sys/x86/cpufreq/hwpstate_amd.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/sys/x86/cpufreq/hwpstate_amd.c b/sys/x86/cpufreq/hwpstate_amd.c
index 5a2ff7611228..a9305e571ece 100644
--- a/sys/x86/cpufreq/hwpstate_amd.c
+++ b/sys/x86/cpufreq/hwpstate_amd.c
@@ -43,6 +43,8 @@
* 31116 Rev 3.20 February 04, 2009
* BIOS and Kernel Developer's Guide(BKDG) for AMD Family 11h Processors
* 41256 Rev 3.00 - July 07, 2008
+ * Processor Programming Reference (PPR) for AMD Family 1Ah Model 02h,
+ * Revision C1 Processors Volume 1 of 7 - Sep 29, 2024
*/
#include <sys/param.h>
@@ -88,6 +90,8 @@
#define AMD_17H_CUR_DID(msr) (((msr) >> 8) & 0x3F)
#define AMD_17H_CUR_FID(msr) ((msr) & 0xFF)
+#define AMD_1AH_CUR_FID(msr) ((msr) & 0xFFF)
+
#define HWPSTATE_DEBUG(dev, msg...) \
do { \
if (hwpstate_verbose) \
@@ -163,6 +167,23 @@ static driver_t hwpstate_driver = {
DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, 0, 0);
+static int
+hwpstate_amd_iscale(int val, int div)
+{
+ switch (div) {
+ case 3: /* divide by 1000 */
+ val /= 10;
+ case 2: /* divide by 100 */
+ val /= 10;
+ case 1: /* divide by 10 */
+ val /= 10;
+ case 0: /* divide by 1 */
+ ;
+ }
+
+ return (val);
+}
+
/*
* Go to Px-state on all cpus, considering the limit register (if so
* configured).
@@ -462,13 +483,30 @@ hwpstate_get_info_from_msr(device_t dev)
case 0x17:
case 0x18:
case 0x19:
- did = AMD_17H_CUR_DID(msr);
- if (did == 0) {
- HWPSTATE_DEBUG(dev, "unexpected did: 0\n");
- did = 1;
+ case 0x1A:
+ /* calculate freq */
+ if (family == 0x1A) {
+ fid = AMD_1AH_CUR_FID(msr);
+ /* 1Ah CPU don't use a divisor */
+ hwpstate_set[i].freq = fid;
+ if (fid > 0x0f)
+ hwpstate_set[i].freq *= 5;
+ else {
+ HWPSTATE_DEBUG(dev,
+ "unexpected fid: %d\n", fid);
+ return (ENXIO);
+ }
+ } else {
+ did = AMD_17H_CUR_DID(msr);
+ if (did == 0) {
+ HWPSTATE_DEBUG(dev,
+ "unexpected did: 0\n");
+ did = 1;
+ }
+ fid = AMD_17H_CUR_FID(msr);
+ hwpstate_set[i].freq = (200 * fid) / did;
}
- fid = AMD_17H_CUR_FID(msr);
- hwpstate_set[i].freq = (200 * fid) / did;
+
/* Vid step is 6.25mV, so scale by 100. */
hwpstate_set[i].volts =
(155000 - (625 * AMD_17H_CUR_VID(msr))) / 100;
@@ -479,16 +517,8 @@ hwpstate_get_info_from_msr(device_t dev)
* section 2.5.2.1.6.
*/
hwpstate_set[i].power = AMD_17H_CUR_IDD(msr) * 1000;
- switch (AMD_17H_CUR_IDIV(msr)) {
- case 3: /* divide by 1000 */
- hwpstate_set[i].power /= 10;
- case 2: /* divide by 100 */
- hwpstate_set[i].power /= 10;
- case 1: /* divide by 10 */
- hwpstate_set[i].power /= 10;
- case 0: /* divide by 1 */
- ;
- }
+ hwpstate_set[i].power = hwpstate_amd_iscale(
+ hwpstate_set[i].power, AMD_17H_CUR_IDIV(msr));
hwpstate_set[i].power *= hwpstate_set[i].volts;
/* Milli amps * milli volts to milli watts. */
hwpstate_set[i].power /= 1000;