git: b44b64eeff1d - stable/13 - hwpstate_amd: calculate power if P-state info comes from MSR

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 26 Jun 2023 19:52:31 UTC
The branch stable/13 has been updated by markj:

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

commit b44b64eeff1dac47fe0c0922a471b9785c27d266
Author:     Johannes Totz <jo@bruelltuete.com>
AuthorDate: 2023-06-12 16:00:15 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-06-26 19:52:08 +0000

    hwpstate_amd: calculate power if P-state info comes from MSR
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D40140
    
    (cherry picked from commit e74dd9577fb00518834a1bf07fad8c1d4c978d7a)
---
 sys/x86/cpufreq/hwpstate_amd.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/sys/x86/cpufreq/hwpstate_amd.c b/sys/x86/cpufreq/hwpstate_amd.c
index 3193cbd908cc..3760b40ad397 100644
--- a/sys/x86/cpufreq/hwpstate_amd.c
+++ b/sys/x86/cpufreq/hwpstate_amd.c
@@ -85,6 +85,8 @@ __FBSDID("$FreeBSD$");
 #define	AMD_10H_11H_CUR_DID(msr)		(((msr) >> 6) & 0x07)
 #define	AMD_10H_11H_CUR_FID(msr)		((msr) & 0x3F)
 
+#define	AMD_17H_CUR_IDIV(msr)			(((msr) >> 30) & 0x03)
+#define	AMD_17H_CUR_IDD(msr)			(((msr) >> 22) & 0xFF)
 #define	AMD_17H_CUR_VID(msr)			(((msr) >> 14) & 0xFF)
 #define	AMD_17H_CUR_DID(msr)			(((msr) >> 8) & 0x3F)
 #define	AMD_17H_CUR_FID(msr)			((msr) & 0xFF)
@@ -447,6 +449,9 @@ hwpstate_get_info_from_msr(device_t dev)
 		did = AMD_10H_11H_CUR_DID(msr);
 		fid = AMD_10H_11H_CUR_FID(msr);
 
+		hwpstate_set[i].volts = CPUFREQ_VAL_UNKNOWN;
+		hwpstate_set[i].power = CPUFREQ_VAL_UNKNOWN;
+		hwpstate_set[i].lat = CPUFREQ_VAL_UNKNOWN;
 		/* Convert fid/did to frequency. */
 		switch (family) {
 		case 0x11:
@@ -467,6 +472,29 @@ hwpstate_get_info_from_msr(device_t dev)
 			}
 			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;
+			/*
+			 * Calculate current first.
+			 * This equation is mentioned in
+			 * "BKDG for AMD Family 15h Models 70h-7fh Processors",
+			 * 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_set[i].volts;
+			/* Milli amps * milli volts to milli watts. */
+			hwpstate_set[i].power /= 1000;
 			break;
 		default:
 			HWPSTATE_DEBUG(dev, "get_info_from_msr: %s family"
@@ -476,10 +504,6 @@ hwpstate_get_info_from_msr(device_t dev)
 			return (ENXIO);
 		}
 		hwpstate_set[i].pstate_id = i;
-		/* There was volts calculation, but deleted it. */
-		hwpstate_set[i].volts = CPUFREQ_VAL_UNKNOWN;
-		hwpstate_set[i].power = CPUFREQ_VAL_UNKNOWN;
-		hwpstate_set[i].lat = CPUFREQ_VAL_UNKNOWN;
 	}
 	return (0);
 }