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>
This commit is contained in:
Tim Wawrzynczak 2020-05-14 10:23:19 -06:00 committed by Duncan Laurie
parent 7f00dba33b
commit e184e39e2e
7 changed files with 170 additions and 0 deletions

View File

@ -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.

View File

@ -0,0 +1,2 @@
subdirs-y += con
ramstage-$(CONFIG_DRIVERS_INTEL_PMC) += mux.c

View File

@ -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__ */

View File

@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_INTEL_PMC) += con.c

View File

@ -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__ */

View File

@ -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,
};

View File

@ -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,
};