baytrail: implement baytrail technical advisory 556192
This is the implementation of TA 556192
It's for errata USB Device May Not be Detected at System
Power-On
Please see more details in TA 556192
BUG=none
BRANCH=firmware-rambi-5216.B
TEST=boot ok on rambi. need more validation on it
Change-Id: I55dd6807a026b9d0d6595f65384bb0e7c9cad20c
Signed-off-by: Kane Chen <kane.chen@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/651811
Reviewed-by: YH Lin <yueherngl@chromium.org>
diff --git a/src/soc/intel/baytrail/baytrail/iosf.h b/src/soc/intel/baytrail/baytrail/iosf.h
index 9da86f5..c4ecc61 100644
--- a/src/soc/intel/baytrail/baytrail/iosf.h
+++ b/src/soc/intel/baytrail/baytrail/iosf.h
@@ -227,6 +227,9 @@
# define DTR0_SPEED_1333 0x02
# define DTR0_SPEED_1600 0x03
+#define PMSTS 0xc
+# define PMSTS_WRO_MASK 0x100
+# define PMSTS_DISR_MASK 0x0
/*
* PUNIT Registers
*/
diff --git a/src/soc/intel/baytrail/baytrail/ramstage.h b/src/soc/intel/baytrail/baytrail/ramstage.h
index a8b5fdc..c935d5a 100644
--- a/src/soc/intel/baytrail/baytrail/ramstage.h
+++ b/src/soc/intel/baytrail/baytrail/ramstage.h
@@ -36,6 +36,7 @@
#endif
void baytrail_init_scc(void);
void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index);
+void byt_usb_wa(void);
extern struct pci_operations soc_pci_ops;
diff --git a/src/soc/intel/baytrail/ehci.c b/src/soc/intel/baytrail/ehci.c
index d4e2986..0af66b6 100644
--- a/src/soc/intel/baytrail/ehci.c
+++ b/src/soc/intel/baytrail/ehci.c
@@ -31,6 +31,8 @@
#include <baytrail/pmc.h>
#include <baytrail/ramstage.h>
#include <baytrail/ehci.h>
+#include <baytrail/xhci.h>
+#include <baytrail/iosf.h>
#include "chip.h"
@@ -123,6 +125,83 @@
reg_script_run(usb2_phy_script);
}
+void byt_usb_wa(void)
+{
+ u8 i;
+ u32 orig, per_port;
+
+ static const struct reg_script \
+ usb_workaround_script[BYTM_USB2_PORT_COUNT][8] = {
+ {
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4113, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4123, 0x7f13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4123, 0x13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4123, 0x4011),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4113, 0x108),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4113, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4113, 0x0),
+ REG_SCRIPT_END
+ },
+ {
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4213, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4223, 0x7f13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4223, 0x13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4223, 0x4011),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4213, 0x108),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4213, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4213, 0x0),
+ REG_SCRIPT_END
+ },
+ {
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4313, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4323, 0x7f13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4323, 0x13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4323, 0x4011),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4313, 0x108),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4313, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4313, 0x0),
+ REG_SCRIPT_END
+ },
+ {
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4413, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4423, 0x7f13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4423, 0x13),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4423, 0x4011),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4413, 0x108),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4413, 0x8),
+ REG_IOSF_WRITE(IOSF_PORT_USBPHY, 0x4413, 0x0),
+ REG_SCRIPT_END
+ }
+ };
+
+ if (acpi_slp_type == 3 || \
+ (iosf_dunit_read(PMSTS) & PMSTS_WRO_MASK) > 0) {
+ printk(BIOS_DEBUG, "warm reset/S3 resume detected \
+ , skip USB WA \n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "Start USB WA for BYT\n");
+ for (i = 0; i < BYTM_USB2_PORT_COUNT; i++) {
+ /*
+ * The below reg_script_run is for steps 1 ~ 7 in the Tech Advisory
+ * for each port
+ */
+ reg_script_run(usb_workaround_script[i]);
+
+ /*
+ * The below programing is for steps 8 ~ 12 in the Tech Advisory
+ * for each port
+ */
+ per_port = 0x4126 + i * 0x100;
+ orig = iosf_usbphy_read(per_port);
+ iosf_usbphy_write(per_port, 0x1c);
+ iosf_usbphy_write(per_port, 0x0);
+ iosf_usbphy_write(per_port, 0x11c);
+ iosf_usbphy_write(per_port, orig);
+ }
+}
+
static void ehci_init(device_t dev)
{
struct soc_intel_baytrail_config *config = dev->chip_info;
diff --git a/src/soc/intel/baytrail/ramstage.c b/src/soc/intel/baytrail/ramstage.c
index fcaf41f..82c25f1 100644
--- a/src/soc/intel/baytrail/ramstage.c
+++ b/src/soc/intel/baytrail/ramstage.c
@@ -217,4 +217,7 @@
setup_soc_gpios(gpio_config, config->enable_xdp_tap);
baytrail_init_scc();
+
+ /* Execute Tech Advisory 556192 */
+ byt_usb_wa();
}