summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Wawrzynczak <twawrzynczak@chromium.org>2020-05-14 10:23:19 -0600
committerDuncan Laurie <dlaurie@chromium.org>2020-05-26 20:51:32 +0000
commite184e39e2ed9ac3f76d2c4f2cc830e335a216e45 (patch)
treee4388384481781e0d55bc82e8c4c1bd9b3e286cb
parent7f00dba33beb65e0380ed4b3194102083630b2f4 (diff)
drivers/intel/pmc_mux/con: Add new PMC MUX & CON chip drivers
The Tiger Lake PMC device has a MUX device which is expected to be exposed in ACPI tables. The MUX device simply has a _HID and _DDN. The CON devices link the USB-2 and USB-3 port numbers (from SoC point of view) to the physical connector. They also have orientation options for the sideband (SBU) and USB High Speed signals (HSL), meaning that they can be fixed (i.e, another device besides the SoC controls the orientation, and effectively the SoC is following only CC1 or CC2 orientation), or they can follow the CC lines. BUG=b:151646486 TEST=Tested with next patch in series (see TEST line there) Change-Id: I8b5f275907601960410459aa669e257b80ff3dc2 Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Signed-off-by: John Zhao <john.zhao@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40862 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--src/drivers/intel/pmc_mux/Kconfig7
-rw-r--r--src/drivers/intel/pmc_mux/Makefile.inc2
-rw-r--r--src/drivers/intel/pmc_mux/chip.h9
-rw-r--r--src/drivers/intel/pmc_mux/con/Makefile.inc1
-rw-r--r--src/drivers/intel/pmc_mux/con/chip.h26
-rw-r--r--src/drivers/intel/pmc_mux/con/con.c83
-rw-r--r--src/drivers/intel/pmc_mux/mux.c42
7 files changed, 170 insertions, 0 deletions
diff --git a/src/drivers/intel/pmc_mux/Kconfig b/src/drivers/intel/pmc_mux/Kconfig
new file mode 100644
index 0000000000..24eb1a19d3
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/Kconfig
@@ -0,0 +1,7 @@
+config DRIVERS_INTEL_PMC
+ bool
+ default n
+ depends on HAVE_ACPI_TABLES
+ help
+ When enabled, driver/intel/pmc_mux will add support for mux
+ configuration of USB Type-C ports via the SoC's muxes.
diff --git a/src/drivers/intel/pmc_mux/Makefile.inc b/src/drivers/intel/pmc_mux/Makefile.inc
new file mode 100644
index 0000000000..f27f01444b
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/Makefile.inc
@@ -0,0 +1,2 @@
+subdirs-y += con
+ramstage-$(CONFIG_DRIVERS_INTEL_PMC) += mux.c
diff --git a/src/drivers/intel/pmc_mux/chip.h b/src/drivers/intel/pmc_mux/chip.h
new file mode 100644
index 0000000000..dcca2a3ecc
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/chip.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __DRIVERS_INTEL_PMC_MUX_H__
+#define __DRIVERS_INTEL_PMC_MUX_H__
+
+struct drivers_intel_pmc_mux_config {
+};
+
+#endif /* __DRIVERS_INTEL_PMC_MUX_H__ */
diff --git a/src/drivers/intel/pmc_mux/con/Makefile.inc b/src/drivers/intel/pmc_mux/con/Makefile.inc
new file mode 100644
index 0000000000..213e8fc7ec
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/con/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_INTEL_PMC) += con.c
diff --git a/src/drivers/intel/pmc_mux/con/chip.h b/src/drivers/intel/pmc_mux/con/chip.h
new file mode 100644
index 0000000000..02d018a2e9
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/con/chip.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __DRIVERS_INTEL_PMC_MUX_CON_H__
+#define __DRIVERS_INTEL_PMC_MUX_CON_H__
+
+enum typec_orientation {
+ /* The orientation of the signal follows the orientation of the CC lines. */
+ TYPEC_ORIENTATION_FOLLOW_CC = 0,
+ /* The orientation of the signal is fixed to follow CC1 */
+ TYPEC_ORIENTATION_NORMAL,
+ /* The orientation of the signal is fixed to follow CC2 */
+ TYPEC_ORIENTATION_REVERSE,
+};
+
+struct drivers_intel_pmc_mux_con_config {
+ /* 1-based port numbers (from SoC point of view) */
+ int usb2_port_number;
+ /* 1-based port numbers (from SoC point of view) */
+ int usb3_port_number;
+ /* Orientation of the sideband signals (SBU) */
+ enum typec_orientation sbu_orientation;
+ /* Orientation of the High Speed lines */
+ enum typec_orientation hsl_orientation;
+};
+
+#endif /* __DRIVERS_INTEL_PMC_MUX_CON_H__ */
diff --git a/src/drivers/intel/pmc_mux/con/con.c b/src/drivers/intel/pmc_mux/con/con.c
new file mode 100644
index 0000000000..08c38e8875
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/con/con.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpigen.h>
+#include <console/console.h>
+#include <intelblocks/acpi.h>
+#include "chip.h"
+
+static const char *con_acpi_name(const struct device *dev)
+{
+ static char name[5];
+ snprintf(name, sizeof(name), "CON%1X", dev->path.generic.id);
+ return name;
+}
+
+static const char *orientation_to_str(enum typec_orientation ori)
+{
+ switch (ori) {
+ case TYPEC_ORIENTATION_NORMAL:
+ return "normal";
+ case TYPEC_ORIENTATION_REVERSE:
+ return "reverse";
+ case TYPEC_ORIENTATION_FOLLOW_CC: /* Intentional fallthrough */
+ default:
+ return "";
+ }
+}
+
+static void con_fill_ssdt(const struct device *dev)
+{
+ struct drivers_intel_pmc_mux_con_config *config = dev->chip_info;
+ struct acpi_dp *dsd;
+
+ if (!dev->enabled)
+ return;
+
+ /* Reference the existing scope and write CONx device */
+ acpigen_write_scope(acpi_device_scope(dev));
+ acpigen_write_device(acpi_device_name(dev));
+
+ acpigen_write_name_integer("_ADR", dev->path.generic.id);
+
+ /* _DSD, Device-Specific Data */
+ dsd = acpi_dp_new_table("_DSD");
+ acpi_dp_add_integer(dsd, "usb2-port-number", config->usb2_port_number);
+ acpi_dp_add_integer(dsd, "usb3-port-number", config->usb3_port_number);
+
+ /*
+ * The kernel assumes that these Type-C signals (SBUs and HSLs) follow the CC lines,
+ * unless they are explicitly called out otherwise.
+ */
+ if (config->sbu_orientation != TYPEC_ORIENTATION_FOLLOW_CC)
+ acpi_dp_add_string(dsd, "sbu-orientation",
+ orientation_to_str(config->sbu_orientation));
+
+ if (config->hsl_orientation != TYPEC_ORIENTATION_FOLLOW_CC)
+ acpi_dp_add_string(dsd, "hsl-orientation",
+ orientation_to_str(config->hsl_orientation));
+
+ acpi_dp_write(dsd);
+
+ acpigen_pop_len(); /* CONx Device */
+ 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 con_dev_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_name = con_acpi_name,
+ .acpi_fill_ssdt = con_fill_ssdt,
+};
+
+static void con_enable(struct device *dev)
+{
+ dev->ops = &con_dev_ops;
+}
+
+struct chip_operations drivers_intel_pmc_mux_con_ops = {
+ CHIP_NAME("Intel PMC MUX CON Driver")
+ .enable_dev = con_enable,
+};
diff --git a/src/drivers/intel/pmc_mux/mux.c b/src/drivers/intel/pmc_mux/mux.c
new file mode 100644
index 0000000000..29ed1a9603
--- /dev/null
+++ b/src/drivers/intel/pmc_mux/mux.c
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <acpi/acpigen.h>
+#include <device/device.h>
+#include "chip.h"
+
+#define TGL_PMC_MUX_HID "INTC105C"
+
+static const char *mux_acpi_name(const struct device *dev)
+{
+ return "MUX";
+}
+
+static void mux_fill_ssdt(const struct device *dev)
+{
+ acpigen_write_scope(acpi_device_scope(dev));
+ acpigen_write_device(acpi_device_name(dev));
+
+ acpigen_write_name_string("_HID", TGL_PMC_MUX_HID);
+ acpigen_write_name_string("_DDN", dev->chip_ops->name);
+
+ acpigen_pop_len(); /* Device */
+ acpigen_pop_len(); /* Scope */
+}
+
+static struct device_operations mux_dev_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_name = mux_acpi_name,
+ .acpi_fill_ssdt = mux_fill_ssdt,
+ .scan_bus = scan_static_bus,
+};
+
+static void mux_enable(struct device *dev)
+{
+ dev->ops = &mux_dev_ops;
+}
+
+struct chip_operations drivers_intel_pmc_mux_ops = {
+ CHIP_NAME("Intel PMC MUX Driver")
+ .enable_dev = mux_enable,
+};