Brandon Breitenstein has uploaded this change for review.

View Change

WIP: drivers/intel/usb4/mux_retimer: Enable retimer FW upgrade mux interaction

In order to update the BB retimers for usb4/tbt they need to be turned on and in
a specific mode. This DSM allows for the use of an EC RAM Byte to get the current
state of each port and wether or not it has a retimer. It also allows Kernel to
issue a state for the retimer to be put into for firmware updates.

Change-Id: I768cfb56790049c231173b0ea0f8e08fe6b64b93
Signed-off-by: Brandon Breitenstein <brandon.breitenstein@intel.com>
---
A src/drivers/intel/usb4/mux_retimer/Kconfig
A src/drivers/intel/usb4/mux_retimer/Makefile.inc
A src/drivers/intel/usb4/mux_retimer/mux_retimer.c
M src/ec/google/chromeec/acpi/emem.asl
M src/mainboard/google/volteer/Kconfig
5 files changed, 119 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/30/48630/1
diff --git a/src/drivers/intel/usb4/mux_retimer/Kconfig b/src/drivers/intel/usb4/mux_retimer/Kconfig
new file mode 100644
index 0000000..d5dc3f9
--- /dev/null
+++ b/src/drivers/intel/usb4/mux_retimer/Kconfig
@@ -0,0 +1,6 @@
+config DRIVERS_INTEL_USB4_MUX_RETIMER
+ bool
+ depends on HAVE_ACPI_TABLES
+ help
+ The mux retimer driver is required when synchronization is needed
+ between the EC and Kernel on the retimer upgrade path for BB retimer
diff --git a/src/drivers/intel/usb4/mux_retimer/Makefile.inc b/src/drivers/intel/usb4/mux_retimer/Makefile.inc
new file mode 100644
index 0000000..bca87fc
--- /dev/null
+++ b/src/drivers/intel/usb4/mux_retimer/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_INTEL_USB4_MUX_RETIMER) += mux_retimer.c
diff --git a/src/drivers/intel/usb4/mux_retimer/mux_retimer.c b/src/drivers/intel/usb4/mux_retimer/mux_retimer.c
new file mode 100644
index 0000000..de538e2
--- /dev/null
+++ b/src/drivers/intel/usb4/mux_retimer/mux_retimer.c
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpigen.h>
+#include <acpi/acpi_device.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <gpio.h>
+#include <string.h>
+
+/* Unique ID for the Mux Retimer Upgrade _DSM. */
+#define INTEL_USB4_MUX_RETIMER_DSM_UUID "5e7fb958-b2c5-49dc-90b9-f95b1275e824"
+
+/*
+ * Arg0: UUID
+ * Arg1: Revision ID (set to 1)
+ * Arg2: Function Index
+ * 0: Query command implemented
+ * 1: Query current MUX state and ports with retimers
+ * 2: Set MUX state for retimer upgrade
+ * Arg3: A package containing parameters for the function specified by the UUID
+ * revision ID and function index.
+ * Function 2: Value to set EC RAM
+ */
+
+static void usb4_mux_cb_standard_query(void *arg)
+{
+ /*
+ * ToInteger (Arg1, Local2)
+ * If (Local2 == 1) {
+ * Return(Buffer() {0x07})
+ * }
+ * Return (Buffer() {0x01})
+ */
+ acpigen_write_to_integer(ARG1_OP, LOCAL2_OP);
+
+ /* Revision 1 supports 2 Functions beyond the standard query */
+ acpigen_write_if_lequal_op_int(LOCAL2_OP, 1);
+ acpigen_write_return_singleton_buffer(0x07);
+ acpigen_pop_len(); /* If */
+
+ /* Other revisions support no additional functions */
+ acpigen_write_return_singleton_buffer(0);
+}
+
+static void usb4_mux_cb_get_mux_state(void *arg)
+{
+ /*
+ * // Read Mux Retimer info from EC RAM
+ * Return RFWU
+ */
+ acpigen_write_return_namestr("RFWU");
+}
+
+static void usb4_mux_cb_set_mux_state(void *arg)
+{
+ /*
+ * // Get argument for on/off from Arg3[0]
+ * Local0 = DeRefOf (Arg3[0])
+ */
+ acpigen_get_package_op_element(ARG3_OP, 0, LOCAL0_OP);
+
+ /*
+ * // write the EC RAM for Retimer Upgrade
+ * RFWU = LOCAL0
+ */
+ acpigen_write_name_byte("RFWU", LOCAL0_OP);
+
+ /* Return (Zero) */
+ acpigen_write_return_integer(0);
+}
+
+static void (*usb4_mux_callbacks[3])(void *) = {
+ usb4_mux_cb_standard_query, /* Function 0 */
+ usb4_mux_cb_get_mux_state, /* Function 1 */
+ usb4_mux_cb_set_mux_state, /* Function 2 */
+};
+
+static void usb4_mux_fill_ssdt(const struct device *dev)
+{
+ const char *scope = acpi_device_scope(dev);
+
+ if (!scope)
+ return;
+
+ /* Write the _DSM that toggles ack with provided GPIO. */
+ acpigen_write_scope(scope);
+ acpigen_write_dsm(INTEL_USB4_MUX_RETIMER_DSM_UUID, usb4_mux_callbacks,
+ ARRAY_SIZE(usb4_mux_callbacks), NULL);
+ acpigen_pop_len(); /* Scope */
+
+ printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
+ dev_path(dev));
+}
+
+static struct device_operations usb4_mux_dev_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_fill_ssdt = usb4_mux_fill_ssdt,
+};
+
+static void usb4_mux_retimer_enable(struct device *dev)
+{
+ dev->ops = &usb4_mux_dev_ops;
+}
+
+struct chip_operations drivers_intel_usb4_mux_ops = {
+ CHIP_NAME("Intel USB4 Mux Retimer Upgrade")
+ .enable_dev = usb4_mux_retimer_enable
+};
diff --git a/src/ec/google/chromeec/acpi/emem.asl b/src/ec/google/chromeec/acpi/emem.asl
index 2a556ed..ee50796 100644
--- a/src/ec/google/chromeec/acpi/emem.asl
+++ b/src/ec/google/chromeec/acpi/emem.asl
@@ -18,7 +18,7 @@
FAN0, 16, // Fan Speed 0
Offset (0x24),
BTVR, 8, // Battery structure version
-Offset (0x30),
+RFWU, 8, // Retimer FW Update
LIDS, 1, // Lid Switch State
PBTN, 1, // Power Button Pressed
WPDI, 1, // Write Protect Disabled
diff --git a/src/mainboard/google/volteer/Kconfig b/src/mainboard/google/volteer/Kconfig
index c776ba1..5e185a7 100644
--- a/src/mainboard/google/volteer/Kconfig
+++ b/src/mainboard/google/volteer/Kconfig
@@ -12,6 +12,7 @@
select DRIVERS_INTEL_USB4_RETIMER
select DRIVERS_I2C_MAX98373
select DRIVERS_INTEL_SOUNDWIRE
+ select DRIVERS_INTEL_USB4_MUX_RETIMER
select DRIVERS_SPI_ACPI
select DRIVERS_SOUNDWIRE_ALC5682
select DRIVERS_SOUNDWIRE_MAX98373

To view, visit change 48630. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I768cfb56790049c231173b0ea0f8e08fe6b64b93
Gerrit-Change-Number: 48630
Gerrit-PatchSet: 1
Gerrit-Owner: Brandon Breitenstein <brandon.breitenstein@intel.com>
Gerrit-MessageType: newchange