driver/intel/pmc_mux/conn: Add type-c port info to cbmem

This change adds type-c port information for USB type-c ports to cbmem.

BUG=b:149830546
TEST='emerge-volteer coreboot chromeos-bootimage', flash and boot
volteer2 to kernel, log in and check cbmem for type-c info exported to
the payload:
  localhost ~ # cbmem -c | grep type-c
  added type-c port0 info to cbmem: usb2:9 usb3:1 sbu:0 data:0
  added type-c port1 info to cbmem: usb2:4 usb3:2 sbu:1 data:0

Change-Id: Ic56a1ad1b617e3af000664147d21165e6ea3a742
Signed-off-by: Nick Vaccaro <nvaccaro@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57345
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
diff --git a/src/drivers/intel/pmc_mux/conn/conn.c b/src/drivers/intel/pmc_mux/conn/conn.c
index 7a622c8..caff166 100644
--- a/src/drivers/intel/pmc_mux/conn/conn.c
+++ b/src/drivers/intel/pmc_mux/conn/conn.c
@@ -2,11 +2,73 @@
 
 #include <acpi/acpigen.h>
 #include <boot/coreboot_tables.h>
+#include <cbmem.h>
 #include <console/console.h>
 #include <intelblocks/acpi.h>
 
 #include "chip.h"
 
+/* Number of registered connectors */
+static size_t total_conn_count;
+
+static void conn_init(struct device *dev)
+{
+	total_conn_count++;
+}
+
+static struct type_c_info *conn_get_cbmem_buffer(void)
+{
+	struct type_c_info *info;
+	size_t size;
+
+	info = cbmem_find(CBMEM_ID_TYPE_C_INFO);
+	if (info)
+		return info;
+
+	size = sizeof(struct type_c_info) + total_conn_count * sizeof(struct type_c_port_info);
+	info = cbmem_add(CBMEM_ID_TYPE_C_INFO, size);
+
+	if (!info)
+		return NULL;
+
+	memset(info, 0, size);
+	return info;
+}
+
+static void conn_write_cbmem_entry(struct device *dev)
+{
+	const struct drivers_intel_pmc_mux_conn_config *config = dev->chip_info;
+	struct type_c_port_info *port_info;
+	struct type_c_info *info;
+	size_t count;
+
+	/*
+	 * Do not re-run this code on resume as the cbmem data is populated on boot-up
+	 * (non-S3 path) and stays intact across S3 suspend/resume.
+	 */
+	if (acpi_is_wakeup_s3())
+		return;
+
+	info = conn_get_cbmem_buffer();
+	if (!info || (info->port_count >= total_conn_count)) {
+		printk(BIOS_ERR, "ERROR: No space for Type-C port info!\n");
+		return;
+	}
+
+	count = info->port_count;
+	port_info = &info->port_info[count];
+	port_info->usb2_port_number = config->usb2_port_number;
+	port_info->usb3_port_number = config->usb3_port_number;
+	port_info->sbu_orientation = config->sbu_orientation;
+	port_info->data_orientation = config->hsl_orientation;
+
+	printk(BIOS_INFO, "added type-c port%ld info to cbmem: usb2:%d usb3:%d sbu:%d data:%d\n",
+			count, port_info->usb2_port_number, port_info->usb3_port_number,
+			port_info->sbu_orientation, port_info->data_orientation);
+
+	info->port_count++;
+}
+
 static const char *conn_acpi_name(const struct device *dev)
 {
 	static char name[5];
@@ -76,6 +138,8 @@
 	.set_resources	= noop_set_resources,
 	.acpi_name	= conn_acpi_name,
 	.acpi_fill_ssdt	= conn_fill_ssdt,
+	.init		= conn_init,
+	.final		= conn_write_cbmem_entry,
 };
 
 static void conn_enable(struct device *dev)