git: 0e6e1f14f0a7 - main - hwpstate_amd: add amd pstate for zen5

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 16 Jan 2025 14:25:53 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=0e6e1f14f0a7cfabec38106e41cb2f7a39363e55

commit 0e6e1f14f0a7cfabec38106e41cb2f7a39363e55
Author:     SHENGYI HONG <aokblast@FreeBSD.org>
AuthorDate: 2024-12-09 03:18:18 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-16 14:25:45 +0000

    hwpstate_amd: add amd pstate for zen5
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D47985
---
 sys/x86/cpufreq/hwpstate_amd.c | 62 +++++++++++++++++++++++++++++++-----------
 1 file 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;