John Zhao has uploaded this change for review. ( https://review.coreboot.org/27746
Change subject: soc/intel/apollolake: Force USB-C into host mode ......................................................................
soc/intel/apollolake: Force USB-C into host mode
When USB OTG is set, GLK FSP enables xHCI SW ID pin and configures USB-C as device mode. Force USB-C into host mode.
BUG=b:111623911 TEST=Verified that USB-C being host mode once USB OTG is set.
Change-Id: Iaca3d25a1159f922b743963cbc508d8defa7b6ff Signed-off-by: John Zhao john.zhao@intel.com --- M src/soc/intel/apollolake/chip.c M src/soc/intel/apollolake/chip.h 2 files changed, 46 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/46/27746/1
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index 081bba3..347a8e1 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -49,6 +49,8 @@ #include <soc/cpu.h> #include <soc/pm.h> #include <soc/systemagent.h> +#include <security/vboot/vboot_common.h> +#include <timer.h>
#include "chip.h"
@@ -666,6 +668,42 @@ * security. */ drop_privilege_all(); + + /* + * When USB OTG is set, GLK FSP enables xHCI SW ID pin and configures + * USB-C as device mode. Force USB-C into host mode. + */ + if (IS_ENABLED(CONFIG_SOC_INTEL_GLK) && vboot_can_enable_udc()) { + uint32_t *cfg0; + uint32_t *cfg1; + const struct resource *res; + uint32_t reg; + struct stopwatch sw; + struct device *xhci_dev = PCH_DEV_XHCI; + + printk(BIOS_INFO, "Putting xHCI port 0 into host mode.\n"); + res = find_resource(xhci_dev, PCI_BASE_ADDRESS_0); + cfg0 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG0); + cfg1 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG1); + reg = read32(cfg0); + if (reg && SW_IDPIN_EN_MASK) { + reg &= ~SW_IDPIN_MASK; + reg |= SW_IDPIN_HOST; + } + write32(cfg0, reg); + + stopwatch_init_msecs_expire(&sw, 10); + /* Wait for the host mode status bit. */ + while ((read32(cfg1) & DRD_MODE_MASK) != DRD_MODE_HOST) { + if (stopwatch_expired(&sw)) { + printk(BIOS_INFO, "Timed out waiting for host mode.\n"); + break; + } + } + + printk(BIOS_INFO, "xHCI port 0 host switch over took %lu ms\n", + stopwatch_duration_msecs(&sw)); + } } }
diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h index 61ddeda..508965c 100644 --- a/src/soc/intel/apollolake/chip.h +++ b/src/soc/intel/apollolake/chip.h @@ -33,6 +33,14 @@ #define MAX_PCIE_PORTS 6 #define CLKREQ_DISABLED 0xf
+#define DUAL_ROLE_CFG0 0x80d8 +#define SW_IDPIN_EN_MASK (1 << 21) +#define SW_IDPIN_MASK (1 << 20) +#define SW_IDPIN_HOST (0 << 20) +#define DUAL_ROLE_CFG1 0x80dc +#define DRD_MODE_MASK (1 << 29) +#define DRD_MODE_HOST (1 << 29) + enum pnp_settings { PNP_PERF, PNP_POWER,