soc/amd: introduce and use get_uvolts_from_vid for SVI2 and SVI3

Instead of implementing the conversion from the raw serial voltage ID
value to the voltage in microvolts in every SoC, introduce the
SOC_AMD_COMMON_BLOCK_SVI[2,3] Kconfig options for the SoC to select the
correct version, implement get_uvolts_from_vid for both cases and only
include the selected implementation in the build.

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: I344641217e6e4654fd281d434b88e346e0482f57
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73995
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig
index 046fd23..dbb628b 100644
--- a/src/soc/amd/cezanne/Kconfig
+++ b/src/soc/amd/cezanne/Kconfig
@@ -63,6 +63,7 @@
 	select SOC_AMD_COMMON_BLOCK_SMU
 	select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY
 	select SOC_AMD_COMMON_BLOCK_SPI
+	select SOC_AMD_COMMON_BLOCK_SVI2
 	select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H
 	select SOC_AMD_COMMON_BLOCK_UART
 	select SOC_AMD_COMMON_BLOCK_UCODE
diff --git a/src/soc/amd/cezanne/acpi.c b/src/soc/amd/cezanne/acpi.c
index 43ed7fe..cebdf7c5 100644
--- a/src/soc/amd/cezanne/acpi.c
+++ b/src/soc/amd/cezanne/acpi.c
@@ -146,13 +146,7 @@
 	current_divisor = pstate_reg.idd_div;
 
 	/* Voltage */
-	if ((core_vid >= 0xF8) && (core_vid <= 0xFF)) {
-		/* Voltage off for VID codes 0xF8 to 0xFF */
-		voltage_in_uvolts = 0;
-	} else {
-		voltage_in_uvolts = SERIAL_VID_2_MAX_MICROVOLTS -
-					(SERIAL_VID_2_DECODE_MICROVOLTS * core_vid);
-	}
+	voltage_in_uvolts = get_uvolts_from_vid(core_vid);
 
 	/* Power in mW */
 	power_in_mw = (voltage_in_uvolts) / 10 * current_value_amps;
diff --git a/src/soc/amd/cezanne/include/soc/msr.h b/src/soc/amd/cezanne/include/soc/msr.h
index fdbe47e..79ebc7ee 100644
--- a/src/soc/amd/cezanne/include/soc/msr.h
+++ b/src/soc/amd/cezanne/include/soc/msr.h
@@ -22,10 +22,6 @@
 #define PSTATE_DEF_FREQ_DIV_MAX		0x3E
 #define PSTATE_DEF_CORE_FREQ_BASE	25
 
-/* Value defined in Serial VID Interface 2.0 spec (#48022, NDA only) */
-#define  SERIAL_VID_2_DECODE_MICROVOLTS	6250
-#define  SERIAL_VID_2_MAX_MICROVOLTS	1550000L
-
 #define MSR_CPPC_CAPABILITY_1				0xc00102b0
 #define SHIFT_CPPC_CAPABILITY_1_HIGHEST_PERF		24
 #define SHIFT_CPPC_CAPABILITY_1_NOMINAL_PERF		16
diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig
index f7583e7..5dc846b 100644
--- a/src/soc/amd/common/block/cpu/Kconfig
+++ b/src/soc/amd/common/block/cpu/Kconfig
@@ -66,6 +66,18 @@
 	  Add common SMM relocation, finalization and handler functionality to
 	  the build.
 
+config SOC_AMD_COMMON_BLOCK_SVI2
+	bool
+	help
+	  Select this option is the SoC uses the serial VID 2 standard for
+	  encoding the voltage it requests from the VRM.
+
+config SOC_AMD_COMMON_BLOCK_SVI3
+	bool
+	help
+	  Select this option is the SoC uses the serial VID 3 standard for
+	  encoding the voltage it requests from the VRM.
+
 config SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H
 	bool
 	select COLLECT_TIMESTAMPS_NO_TSC # selected use SoC-specific timestamp function
diff --git a/src/soc/amd/common/block/cpu/Makefile.inc b/src/soc/amd/common/block/cpu/Makefile.inc
index bd9e8ff..055341e 100644
--- a/src/soc/amd/common/block/cpu/Makefile.inc
+++ b/src/soc/amd/common/block/cpu/Makefile.inc
@@ -4,6 +4,9 @@
 romstage-y += cpu.c
 ramstage-y += cpu.c
 
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_SVI2) += svi2.c
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_SVI3) += svi3.c
+
 ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_UCODE),y)
 define add-ucode-as-cbfs
 cbfs-files-y += cpu_microcode_$(2).bin
diff --git a/src/soc/amd/common/block/cpu/svi2.c b/src/soc/amd/common/block/cpu/svi2.c
new file mode 100644
index 0000000..0a41b78
--- /dev/null
+++ b/src/soc/amd/common/block/cpu/svi2.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/cpu.h>
+#include <types.h>
+
+/* Value defined in Serial VID Interface 2.0 spec (#48022, NDA only) */
+#define  SERIAL_VID_2_DECODE_MICROVOLTS	6250
+#define  SERIAL_VID_2_MAX_MICROVOLTS	1550000L
+
+uint32_t get_uvolts_from_vid(uint16_t core_vid)
+{
+	if ((core_vid >= 0xF8) && (core_vid <= 0xFF)) {
+		/* Voltage off for VID codes 0xF8 to 0xFF */
+		return 0;
+	} else {
+		return SERIAL_VID_2_MAX_MICROVOLTS -
+			(SERIAL_VID_2_DECODE_MICROVOLTS * core_vid);
+	}
+}
diff --git a/src/soc/amd/common/block/cpu/svi3.c b/src/soc/amd/common/block/cpu/svi3.c
new file mode 100644
index 0000000..35a4a78
--- /dev/null
+++ b/src/soc/amd/common/block/cpu/svi3.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/cpu.h>
+#include <types.h>
+
+/* Value defined in Serial VID Interface 3.0 spec (#56413, NDA only) */
+#define  SERIAL_VID_3_DECODE_MICROVOLTS	5000
+#define  SERIAL_VID_3_BASE_MICROVOLTS	245000L
+
+uint32_t get_uvolts_from_vid(uint16_t core_vid)
+{
+	if (core_vid == 0x00) {
+		/* Voltage off for VID code 0x00 */
+		return 0;
+	} else {
+		return SERIAL_VID_3_BASE_MICROVOLTS +
+			(SERIAL_VID_3_DECODE_MICROVOLTS * core_vid);
+	}
+}
diff --git a/src/soc/amd/common/block/include/amdblocks/cpu.h b/src/soc/amd/common/block/include/amdblocks/cpu.h
index 3501b22..cbce028 100644
--- a/src/soc/amd/common/block/include/amdblocks/cpu.h
+++ b/src/soc/amd/common/block/include/amdblocks/cpu.h
@@ -16,6 +16,7 @@
 
 union pstate_msr; /* proper definition is in soc/msr.h */
 
+uint32_t get_uvolts_from_vid(uint16_t core_vid);
 uint32_t get_pstate_core_freq(union pstate_msr pstate_reg);
 uint32_t get_pstate_core_power(union pstate_msr pstate_reg);
 const acpi_cstate_t *get_cstate_config_data(size_t *size);
diff --git a/src/soc/amd/glinda/Kconfig b/src/soc/amd/glinda/Kconfig
index 3ffee09..5e9b7f9 100644
--- a/src/soc/amd/glinda/Kconfig
+++ b/src/soc/amd/glinda/Kconfig
@@ -69,6 +69,7 @@
 	select SOC_AMD_COMMON_BLOCK_SMU			# TODO: Check if this is still correct
 	select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY	# TODO: Check if this is still correct
 	select SOC_AMD_COMMON_BLOCK_SPI			# TODO: Check if this is still correct
+	select SOC_AMD_COMMON_BLOCK_SVI3
 	select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H	# FIXME: This is likely incompatible
 	select SOC_AMD_COMMON_BLOCK_UART		# TODO: Check if this is still correct
 	select SOC_AMD_COMMON_BLOCK_UCODE		# TODO: Check if this is still correct
diff --git a/src/soc/amd/glinda/acpi.c b/src/soc/amd/glinda/acpi.c
index 37349c1..b9ea0eb 100644
--- a/src/soc/amd/glinda/acpi.c
+++ b/src/soc/amd/glinda/acpi.c
@@ -123,13 +123,7 @@
 	current_divisor = pstate_reg.idd_div;
 
 	/* Voltage */
-	if (core_vid == 0x00) {
-		/* Voltage off for VID code 0x00 */
-		voltage_in_uvolts = 0;
-	} else {
-		voltage_in_uvolts = SERIAL_VID_3_BASE_MICROVOLTS +
-					(SERIAL_VID_3_DECODE_MICROVOLTS * core_vid);
-	}
+	voltage_in_uvolts = get_uvolts_from_vid(core_vid);
 
 	/* Power in mW */
 	power_in_mw = (voltage_in_uvolts) / 10 * current_value_amps;
diff --git a/src/soc/amd/glinda/include/soc/msr.h b/src/soc/amd/glinda/include/soc/msr.h
index 7b68897..ad4d9d0 100644
--- a/src/soc/amd/glinda/include/soc/msr.h
+++ b/src/soc/amd/glinda/include/soc/msr.h
@@ -22,10 +22,6 @@
 
 #define PSTATE_DEF_CORE_FREQ_BASE	5
 
-/* Value defined in Serial VID Interface 3.0 spec (#56413, NDA only) */
-#define  SERIAL_VID_3_DECODE_MICROVOLTS	5000
-#define  SERIAL_VID_3_BASE_MICROVOLTS	245000L
-
 #define MSR_CPPC_CAPABILITY_1				0xc00102b0
 #define SHIFT_CPPC_CAPABILITY_1_HIGHEST_PERF		24
 #define SHIFT_CPPC_CAPABILITY_1_NOMINAL_PERF		16
diff --git a/src/soc/amd/mendocino/Kconfig b/src/soc/amd/mendocino/Kconfig
index 737a8db..2df289f 100644
--- a/src/soc/amd/mendocino/Kconfig
+++ b/src/soc/amd/mendocino/Kconfig
@@ -71,6 +71,7 @@
 	select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY
 	select SOC_AMD_COMMON_BLOCK_SPI
 	select SOC_AMD_COMMON_BLOCK_STB
+	select SOC_AMD_COMMON_BLOCK_SVI3
 	select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H
 	select SOC_AMD_COMMON_BLOCK_UART
 	select SOC_AMD_COMMON_BLOCK_UCODE
diff --git a/src/soc/amd/mendocino/acpi.c b/src/soc/amd/mendocino/acpi.c
index f6a95bf..0574ba7 100644
--- a/src/soc/amd/mendocino/acpi.c
+++ b/src/soc/amd/mendocino/acpi.c
@@ -148,13 +148,7 @@
 	current_divisor = pstate_reg.idd_div;
 
 	/* Voltage */
-	if (core_vid == 0x00) {
-		/* Voltage off for VID code 0x00 */
-		voltage_in_uvolts = 0;
-	} else {
-		voltage_in_uvolts = SERIAL_VID_3_BASE_MICROVOLTS +
-					(SERIAL_VID_3_DECODE_MICROVOLTS * core_vid);
-	}
+	voltage_in_uvolts = get_uvolts_from_vid(core_vid);
 
 	/* Power in mW */
 	power_in_mw = (voltage_in_uvolts) / 10 * current_value_amps;
diff --git a/src/soc/amd/mendocino/include/soc/msr.h b/src/soc/amd/mendocino/include/soc/msr.h
index cb03425..b83997a 100644
--- a/src/soc/amd/mendocino/include/soc/msr.h
+++ b/src/soc/amd/mendocino/include/soc/msr.h
@@ -23,10 +23,6 @@
 #define PSTATE_DEF_FREQ_DIV_MAX		0x3E
 #define PSTATE_DEF_CORE_FREQ_BASE	25
 
-/* Value defined in Serial VID Interface 3.0 spec (#56413, NDA only) */
-#define  SERIAL_VID_3_DECODE_MICROVOLTS	5000
-#define  SERIAL_VID_3_BASE_MICROVOLTS	245000L
-
 #define MSR_CPPC_CAPABILITY_1				0xc00102b0
 #define SHIFT_CPPC_CAPABILITY_1_HIGHEST_PERF		24
 #define SHIFT_CPPC_CAPABILITY_1_NOMINAL_PERF		16
diff --git a/src/soc/amd/phoenix/Kconfig b/src/soc/amd/phoenix/Kconfig
index cb54306..96a287c 100644
--- a/src/soc/amd/phoenix/Kconfig
+++ b/src/soc/amd/phoenix/Kconfig
@@ -69,6 +69,7 @@
 	select SOC_AMD_COMMON_BLOCK_SMU
 	select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY
 	select SOC_AMD_COMMON_BLOCK_SPI
+	select SOC_AMD_COMMON_BLOCK_SVI3
 	select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H
 	select SOC_AMD_COMMON_BLOCK_UART
 	select SOC_AMD_COMMON_BLOCK_UCODE
diff --git a/src/soc/amd/phoenix/acpi.c b/src/soc/amd/phoenix/acpi.c
index e3996ba..e147e88 100644
--- a/src/soc/amd/phoenix/acpi.c
+++ b/src/soc/amd/phoenix/acpi.c
@@ -149,13 +149,7 @@
 	current_divisor = pstate_reg.idd_div;
 
 	/* Voltage */
-	if (core_vid == 0x00) {
-		/* Voltage off for VID code 0x00 */
-		voltage_in_uvolts = 0;
-	} else {
-		voltage_in_uvolts = SERIAL_VID_3_BASE_MICROVOLTS +
-					(SERIAL_VID_3_DECODE_MICROVOLTS * core_vid);
-	}
+	voltage_in_uvolts = get_uvolts_from_vid(core_vid);
 
 	/* Power in mW */
 	power_in_mw = (voltage_in_uvolts) / 10 * current_value_amps;
diff --git a/src/soc/amd/phoenix/include/soc/msr.h b/src/soc/amd/phoenix/include/soc/msr.h
index 8eee068..173ee09 100644
--- a/src/soc/amd/phoenix/include/soc/msr.h
+++ b/src/soc/amd/phoenix/include/soc/msr.h
@@ -25,10 +25,6 @@
 #define PSTATE_DEF_FREQ_DIV_MAX		0x3E
 #define PSTATE_DEF_CORE_FREQ_BASE	25
 
-/* Value defined in Serial VID Interface 3.0 spec (#56413, NDA only) */
-#define  SERIAL_VID_3_DECODE_MICROVOLTS	5000
-#define  SERIAL_VID_3_BASE_MICROVOLTS	245000L
-
 #define MSR_CPPC_CAPABILITY_1				0xc00102b0
 #define SHIFT_CPPC_CAPABILITY_1_HIGHEST_PERF		24
 #define SHIFT_CPPC_CAPABILITY_1_NOMINAL_PERF		16
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index 325a65a..746b4fb 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -59,6 +59,7 @@
 	select SOC_AMD_COMMON_BLOCK_SMU
 	select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY
 	select SOC_AMD_COMMON_BLOCK_SPI
+	select SOC_AMD_COMMON_BLOCK_SVI2
 	select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H
 	select SOC_AMD_COMMON_BLOCK_UART
 	select SOC_AMD_COMMON_BLOCK_UCODE
diff --git a/src/soc/amd/picasso/acpi.c b/src/soc/amd/picasso/acpi.c
index b7d954d..d1232e3 100644
--- a/src/soc/amd/picasso/acpi.c
+++ b/src/soc/amd/picasso/acpi.c
@@ -150,13 +150,7 @@
 	current_divisor = pstate_reg.idd_div;
 
 	/* Voltage */
-	if ((core_vid >= 0xF8) && (core_vid <= 0xFF)) {
-		/* Voltage off for VID codes 0xF8 to 0xFF */
-		voltage_in_uvolts = 0;
-	} else {
-		voltage_in_uvolts = SERIAL_VID_2_MAX_MICROVOLTS -
-					(SERIAL_VID_2_DECODE_MICROVOLTS * core_vid);
-	}
+	voltage_in_uvolts = get_uvolts_from_vid(core_vid);
 
 	/* Power in mW */
 	power_in_mw = (voltage_in_uvolts) / 10 * current_value_amps;
diff --git a/src/soc/amd/picasso/include/soc/msr.h b/src/soc/amd/picasso/include/soc/msr.h
index 2f02372..0747b84 100644
--- a/src/soc/amd/picasso/include/soc/msr.h
+++ b/src/soc/amd/picasso/include/soc/msr.h
@@ -26,8 +26,4 @@
 #define PSTATE_DEF_FREQ_DIV_MAX		0x3E
 #define PSTATE_DEF_CORE_FREQ_BASE	25
 
-/* Value defined in Serial VID Interface 2.0 spec (#48022, NDA only) */
-#define  SERIAL_VID_2_DECODE_MICROVOLTS	6250
-#define  SERIAL_VID_2_MAX_MICROVOLTS	1550000L
-
 #endif /* AMD_PICASSO_MSR_H */