soc/amd/genoa: add I2C support

The Genoa SoC has 6 I2C controllers. In order to support those, select
SOC_AMD_COMMON_BLOCK_I2C and implement the SoC-specific functions and
data structures needed by the common AMD I2C code. Since the common AMD
I2C code also reports if the controller is enabled or not in the SSDT,
change the corresponding DSDT code to use this information. In this
patch the I2C pad control registers don't get configured by coreboot yet
and we rely on ABL already having those set up correctly which seems to
be an assumption that the reference firmware is making too. PPR #55901
Rev 0.26 was used as a reference for the I2C controllers and the GPIO
pins being used.

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: Iebc10de6ea5c6d441cff04e016dcec62405078c3
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78900
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Varshit Pandya <pandyavarshit@gmail.com>
diff --git a/src/soc/amd/genoa/i2c.c b/src/soc/amd/genoa/i2c.c
new file mode 100644
index 0000000..76c1049
--- /dev/null
+++ b/src/soc/amd/genoa/i2c.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/i2c.h>
+#include <console/console.h>
+#include <soc/i2c.h>
+#include <soc/southbridge.h>
+#include "chip.h"
+
+/* Table to switch SCL pins to outputs to initially reset the I2C peripherals */
+static const struct soc_i2c_scl_pin i2c_scl_pins[] = {
+	I2C_RESET_SCL_PIN(I2C0_SCL_PIN, GPIO_I2C0_SCL),
+	I2C_RESET_SCL_PIN(I2C1_SCL_PIN, GPIO_I2C1_SCL),
+	I2C_RESET_SCL_PIN(I2C2_SCL_PIN, GPIO_I2C2_SCL),
+	I2C_RESET_SCL_PIN(I2C3_SCL_PIN, GPIO_I2C3_SCL),
+	I2C_RESET_SCL_PIN(I2C4_SCL_PIN, GPIO_I2C4_SCL),
+	I2C_RESET_SCL_PIN(I2C5_SCL_PIN, GPIO_I2C5_SCL),
+};
+
+static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
+	{ I2C_MASTER_MODE, APU_I2C0_BASE, "I2C0" },
+	{ I2C_MASTER_MODE, APU_I2C1_BASE, "I2C1" },
+	{ I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" },
+	{ I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" },
+	{ I2C_MASTER_MODE, APU_I2C4_BASE, "I2C4" },
+	{ I2C_MASTER_MODE, APU_I2C5_BASE, "I2C5" }
+};
+
+void reset_i2c_peripherals(void)
+{
+	const struct soc_amd_genoa_config *cfg = config_of_soc();
+	struct soc_i2c_peripheral_reset_info reset_info;
+
+	reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK;
+	reset_info.i2c_scl = i2c_scl_pins;
+	reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins);
+	sb_reset_i2c_peripherals(&reset_info);
+}
+
+void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
+{
+	/* TODO: write I2C pad control registers */
+}
+
+const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)
+{
+	*num_ctrlrs = ARRAY_SIZE(i2c_ctrlr);
+	return i2c_ctrlr;
+}
+
+const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses)
+{
+	const struct soc_amd_genoa_config *config = config_of_soc();
+
+	*num_buses = ARRAY_SIZE(config->i2c);
+	return config->i2c;
+}