summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/samsung/exynos5250/cpu.h1
-rw-r--r--src/cpu/samsung/exynos5250/power.h5
-rw-r--r--src/cpu/samsung/exynos5250/usb.c110
-rw-r--r--src/cpu/samsung/exynos5250/usb.h77
-rw-r--r--src/cpu/samsung/exynos5420/cpu.h2
-rw-r--r--src/cpu/samsung/exynos5420/power.h10
-rw-r--r--src/cpu/samsung/exynos5420/usb.c129
-rw-r--r--src/cpu/samsung/exynos5420/usb.h84
-rw-r--r--src/mainboard/google/pit/mainboard.c18
-rw-r--r--src/mainboard/google/snow/mainboard.c12
10 files changed, 427 insertions, 21 deletions
diff --git a/src/cpu/samsung/exynos5250/cpu.h b/src/cpu/samsung/exynos5250/cpu.h
index 12745d3d85..85b6fae464 100644
--- a/src/cpu/samsung/exynos5250/cpu.h
+++ b/src/cpu/samsung/exynos5250/cpu.h
@@ -41,6 +41,7 @@
#define EXYNOS5_GPIO_PART2_BASE 0x11400c00 /* X00..X37 */
#define EXYNOS5_USB_DRD_XHCI_BASE 0x12000000
#define EXYNOS5_USB_DRD_PHY_BASE 0x12100000
+#define EXYNOS5_USB_DRD_DWC3_BASE 0x1200C100
#define EXYNOS5_USB_HOST_EHCI_BASE 0x12110000
#define EXYNOS5_USB_HOST_PHY_BASE 0x12130000
#define EXYNOS5_MMC_BASE 0x12200000
diff --git a/src/cpu/samsung/exynos5250/power.h b/src/cpu/samsung/exynos5250/power.h
index 293fe3b704..df68b53dbd 100644
--- a/src/cpu/samsung/exynos5250/power.h
+++ b/src/cpu/samsung/exynos5250/power.h
@@ -30,7 +30,7 @@ void power_enable_hw_thermal_trip(void);
#define MIPI_PHY1_CONTROL_ENABLE (1 << 0)
#define MIPI_PHY1_CONTROL_M_RESETN (1 << 2)
-#define POWER_USB_HOST_PHY_CTRL_EN (1 << 0)
+#define POWER_USB_PHY_CTRL_EN (1 << 0)
#define POWER_PS_HOLD_CONTROL_DATA_HIGH (1 << 8)
#define POWER_ENABLE_HW_TRIP (1UL << 31)
@@ -47,7 +47,8 @@ struct exynos5_power {
uint32_t om_stat; /* 0x0000 */
uint8_t reserved1[0x03fc];
uint32_t sw_reset; /* 0x0400 */
- uint8_t reserved2[0x0304];
+ uint8_t reserved2[0x0300];
+ uint32_t usb_drd_phy_ctrl; /* 0x0704 */
uint32_t usb_host_phy_ctrl; /* 0x0708 */
uint8_t reserved3[0x8];
uint32_t mipi_phy1_control; /* 0x0714 */
diff --git a/src/cpu/samsung/exynos5250/usb.c b/src/cpu/samsung/exynos5250/usb.c
index 521ea4da5a..76da1dd56e 100644
--- a/src/cpu/samsung/exynos5250/usb.c
+++ b/src/cpu/samsung/exynos5250/usb.c
@@ -27,13 +27,119 @@
#include "sysreg.h"
#include "usb.h"
+static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
+{
+ setbits_le32(&dwc3->ctl, 0x1 << 11); /* core soft reset */
+ setbits_le32(&dwc3->usb3pipectl, 0x1 << 31); /* PHY soft reset */
+ setbits_le32(&dwc3->usb2phycfg, 0x1 << 31); /* PHY soft reset */
+}
+
+void reset_usb_drd_dwc3()
+{
+ printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD\n");
+ reset_dwc3(exynos_usb_drd_dwc3);
+}
+
+static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
+{
+ if (!(dwc3->ctl & 0x1 << 11) ||
+ !(dwc3->usb3pipectl & 0x1 << 31) ||
+ !(dwc3->usb2phycfg & 0x1 << 31)) {
+ printk(BIOS_ERR, "DWC3 at %p not in reset (you need to call "
+ "reset_usb_drd_dwc3() first)!\n", dwc3);
+ }
+
+ /* Set relevant registers to default values (clearing all reset bits) */
+
+ writel(0x1 << 24 | /* activate PHY low power states */
+ 0x4 << 19 | /* low power delay value */
+ 0x1 << 18 | /* activate PHY low power delay */
+ 0x1 << 17 | /* enable SuperSpeed PHY suspend */
+ 0x1 << 1 | /* default Tx deemphasis value */
+ 0, &dwc3->usb3pipectl);
+
+ /* Configure PHY clock turnaround for 8-bit UTMI+, disable suspend */
+ writel(0x9 << 10 | /* PHY clock turnaround for 8-bit UTMI+ */
+ 0x1 << 8 | /* enable PHY sleep in L1 */
+ 0x1 << 6 | /* enable PHY suspend */
+ 0, &dwc3->usb2phycfg);
+
+ writel(0x5dc << 19 | /* suspend clock scale for 24MHz */
+ 0x1 << 16 | /* retry SS three times (bugfix from U-Boot) */
+ 0x1 << 12 | /* port capability HOST */
+ 0, &dwc3->ctl);
+}
+
+void setup_usb_drd_dwc3()
+{
+ setup_dwc3(exynos_usb_drd_dwc3);
+ printk(BIOS_DEBUG, "DWC3 setup for USB DRD finished\n");
+}
+
+static void setup_drd_phy(struct exynos5_usb_drd_phy *phy)
+{
+ /* Set all PHY registers to default values */
+
+ /* XHCI Version 1.0, Frame Length adjustment 30 MHz */
+ setbits_le32(&phy->linksystem, 0x1 << 27 | 0x20 << 1);
+
+ /* Disable OTG, ID0 and DRVVBUS, do not force sleep/suspend */
+ writel(1 << 6, &phy->utmi);
+
+ writel(0x88 << 23 | /* spread spectrum refclk selector */
+ 0x1 << 20 | /* enable spread spectrum */
+ 0x1 << 19 | /* enable prescaler refclk */
+ 0x68 << 11 | /* multiplier for 24MHz refclk */
+ 0x5 << 5 | /* select 24MHz refclk (weird, from U-Boot) */
+ 0x1 << 4 | /* power supply in normal operating mode */
+ 0x3 << 2 | /* use external refclk (undocumented on 5420?)*/
+ 0x1 << 1 | /* force port reset */
+ 0x1 << 0 | /* normal operating mode */
+ 0, &phy->clkrst);
+
+ writel(0x9 << 26 | /* LOS level */
+ 0x3 << 22 | /* TX VREF tune */
+ 0x1 << 20 | /* TX rise tune */
+ 0x1 << 18 | /* TX res tune */
+ 0x3 << 13 | /* TX HS X Vtune */
+ 0x3 << 9 | /* TX FS/LS tune */
+ 0x3 << 6 | /* SQRX tune */
+ 0x4 << 3 | /* OTG tune */
+ 0x4 << 0 | /* comp disc tune */
+ 0, &phy->param0);
+
+ writel(0x7f << 19 | /* reserved */
+ 0x7f << 12 | /* Tx launch amplitude */
+ 0x20 << 6 | /* Tx deemphasis 6dB */
+ 0x1c << 0 | /* Tx deemphasis 3.5dB (value from U-Boot) */
+ 0, &phy->param1);
+
+ /* disable all test features */
+ writel(0, &phy->test);
+
+ /* UTMI clock select? ("must be 0x1") */
+ writel(0x1 << 2, &phy->utmiclksel);
+
+ /* Samsung magic, undocumented (from U-Boot) */
+ writel(0x0, &phy->resume);
+
+ udelay(10);
+ clrbits_le32(&phy->clkrst, 0x1 << 1); /* deassert port reset */
+}
+
+void setup_usb_drd_phy()
+{
+ printk(BIOS_DEBUG, "Powering up USB DRD PHY\n");
+ setbits_le32(&exynos_power->usb_drd_phy_ctrl, POWER_USB_PHY_CTRL_EN);
+ setup_drd_phy(exynos_usb_drd_phy);
+}
+
void setup_usb_host_phy(int hsic_gpio)
{
unsigned int hostphy_ctrl0;
setbits_le32(&exynos_sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
- setbits_le32(&exynos_power->usb_host_phy_ctrl,
- POWER_USB_HOST_PHY_CTRL_EN);
+ setbits_le32(&exynos_power->usb_host_phy_ctrl, POWER_USB_PHY_CTRL_EN);
printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
hsic_gpio ? "with" : "without");
diff --git a/src/cpu/samsung/exynos5250/usb.h b/src/cpu/samsung/exynos5250/usb.h
index c951c1fbbb..ad617da96c 100644
--- a/src/cpu/samsung/exynos5250/usb.h
+++ b/src/cpu/samsung/exynos5250/usb.h
@@ -45,24 +45,93 @@
struct exynos5_usb_host_phy {
uint32_t usbphyctrl0;
uint32_t usbphytune0;
- uint32_t reserved1[2];
+ uint8_t reserved1[8];
uint32_t hsicphyctrl1;
uint32_t hsicphytune1;
- uint32_t reserved2[2];
+ uint8_t reserved2[8];
uint32_t hsicphyctrl2;
uint32_t hsicphytune2;
- uint32_t reserved3[2];
+ uint8_t reserved3[8];
uint32_t ehcictrl;
uint32_t ohcictrl;
uint32_t usbotgsys;
- uint32_t reserved4;
+ uint8_t reserved4[4];
uint32_t usbotgtune;
};
static struct exynos5_usb_host_phy * const exynos_usb_host_phy =
(void *)EXYNOS5_USB_HOST_PHY_BASE;
+struct exynos5_usb_drd_phy {
+ uint8_t reserved1[4];
+ uint32_t linksystem;
+ uint32_t utmi;
+ uint32_t pipe;
+ uint32_t clkrst;
+ uint32_t reg0;
+ uint32_t reg1;
+ uint32_t param0;
+ uint32_t param1;
+ uint32_t term;
+ uint32_t test;
+ uint32_t adp;
+ uint32_t utmiclksel;
+ uint32_t resume;
+ uint8_t reserved2[8];
+ uint32_t linkhcbelt;
+ uint32_t linkport;
+};
+
+static struct exynos5_usb_drd_phy * const exynos_usb_drd_phy =
+ (void *)EXYNOS5_USB_DRD_PHY_BASE;
+
+struct exynos5_usb_drd_dwc3 {
+ uint32_t sbuscfg0;
+ uint32_t sbuscfg1;
+ uint32_t txthrcfg;
+ uint32_t rxthrcfg;
+ uint32_t ctl;
+ uint32_t evten;
+ uint32_t sts;
+ uint8_t reserved0[4];
+ uint32_t snpsid;
+ uint32_t gpio;
+ uint32_t uid;
+ uint32_t uctl;
+ uint64_t buserraddr;
+ uint64_t prtbimap;
+ uint8_t reserved1[32];
+ uint32_t dbgfifospace;
+ uint32_t dbgltssm;
+ uint32_t dbglnmcc;
+ uint32_t dbgbmu;
+ uint32_t dbglspmux;
+ uint32_t dbglsp;
+ uint32_t dbgepinfo0;
+ uint32_t dbgepinfo1;
+ uint64_t prtbimap_hs;
+ uint64_t prtbimap_fs;
+ uint8_t reserved2[112];
+ uint32_t usb2phycfg;
+ uint8_t reserved3[60];
+ uint32_t usb2i2cctl;
+ uint8_t reserved4[60];
+ uint32_t usb2phyacc;
+ uint8_t reserved5[60];
+ uint32_t usb3pipectl;
+ uint8_t reserved6[60];
+};
+
+static struct exynos5_usb_drd_dwc3 * const exynos_usb_drd_dwc3 =
+ (void *)EXYNOS5_USB_DRD_DWC3_BASE;
+
/* Leave hsic_gpio at 0 to not enable HSIC. */
void setup_usb_host_phy(int hsic_gpio);
+void setup_usb_drd_phy(void);
+
+/* Call reset_ before setup_, ensure at least 100ms pass in between. */
+void reset_usb_drd_dwc3(void);
+void setup_usb_drd_dwc3(void);
+
#endif
diff --git a/src/cpu/samsung/exynos5420/cpu.h b/src/cpu/samsung/exynos5420/cpu.h
index ffc83f88e4..e3c7f1be38 100644
--- a/src/cpu/samsung/exynos5420/cpu.h
+++ b/src/cpu/samsung/exynos5420/cpu.h
@@ -39,6 +39,7 @@
#define EXYNOS5420_DMC_TZASC_0 0x10D40000
#define EXYNOS5420_DMC_TZASC_1 0x10D50000
#define EXYNOS5420_USB_DRD0_XHCI_BASE 0x12000000
+#define EXYNOS5420_USB_DRD0_DWC3_BASE 0x1200C100
#define EXYNOS5420_USB_DRD0_PHY_BASE 0x12100000
#define EXYNOS5_USB_HOST_EHCI_BASE 0x12110000
#define EXYNOS5_USB_HOST_PHY_BASE 0x12130000
@@ -46,6 +47,7 @@
#define EXYNOS5_MSHC_BASE 0x12240000
#define EXYNOS5_SROMC_BASE 0x12250000
#define EXYNOS5420_USB_DRD1_XHCI_BASE 0x12400000
+#define EXYNOS5420_USB_DRD1_DWC3_BASE 0x1240C100
#define EXYNOS5420_USB_DRD1_PHY_BASE 0x12500000
#define EXYNOS5_UART0_BASE 0x12C00000
#define EXYNOS5_UART1_BASE 0x12C10000
diff --git a/src/cpu/samsung/exynos5420/power.h b/src/cpu/samsung/exynos5420/power.h
index e65c4bd976..a89ee9dca8 100644
--- a/src/cpu/samsung/exynos5420/power.h
+++ b/src/cpu/samsung/exynos5420/power.h
@@ -30,7 +30,7 @@ void power_enable_hw_thermal_trip(void);
#define MIPI_PHY1_CONTROL_ENABLE (1 << 0)
#define MIPI_PHY1_CONTROL_M_RESETN (1 << 2)
-#define POWER_USB_HOST_PHY_CTRL_EN (1 << 0)
+#define POWER_USB_PHY_CTRL_EN (1 << 0)
#define POWER_PS_HOLD_CONTROL_DATA_HIGH (1 << 8)
#define POWER_ENABLE_HW_TRIP (1UL << 31)
@@ -47,9 +47,11 @@ struct exynos5_power {
uint32_t om_stat; /* 0x0000 */
uint8_t reserved1[0x03fc];
uint32_t sw_reset; /* 0x0400 */
- uint8_t reserved2[0x0304];
- uint32_t usb_host_phy_ctrl; /* 0x0708 */
- uint8_t reserved3[0x8];
+ uint8_t reserved2[0x0300];
+ uint32_t usb_drd0_phy_ctrl; /* 0x0704 */
+ uint32_t usb_drd1_phy_ctrl; /* 0x0708 */
+ uint32_t usb_host_phy_ctrl; /* 0x070c */
+ uint8_t reserved3[0x4];
uint32_t mipi_phy1_control; /* 0x0714 */
uint8_t reserved4[0x8];
uint32_t dptx_phy_control; /* 0x0720 */
diff --git a/src/cpu/samsung/exynos5420/usb.c b/src/cpu/samsung/exynos5420/usb.c
index 521ea4da5a..84a6f4ca4c 100644
--- a/src/cpu/samsung/exynos5420/usb.c
+++ b/src/cpu/samsung/exynos5420/usb.c
@@ -27,13 +27,138 @@
#include "sysreg.h"
#include "usb.h"
+static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
+{
+ setbits_le32(&dwc3->ctl, 0x1 << 11); /* core soft reset */
+ setbits_le32(&dwc3->usb3pipectl, 0x1 << 31); /* PHY soft reset */
+ setbits_le32(&dwc3->usb2phycfg, 0x1 << 31); /* PHY soft reset */
+}
+
+void reset_usb_drd0_dwc3()
+{
+ printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD0\n");
+ reset_dwc3(exynos_usb_drd0_dwc3);
+}
+
+void reset_usb_drd1_dwc3()
+{
+ printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD1\n");
+ reset_dwc3(exynos_usb_drd1_dwc3);
+}
+
+static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
+{
+ if (!(dwc3->ctl & 0x1 << 11) ||
+ !(dwc3->usb3pipectl & 0x1 << 31) ||
+ !(dwc3->usb2phycfg & 0x1 << 31)) {
+ printk(BIOS_ERR, "DWC3 at %p not in reset (you need to call "
+ "reset_usb_drdX_dwc3() first)!\n", dwc3);
+ }
+
+ /* Set relevant registers to default values (clearing all reset bits) */
+
+ writel(0x1 << 24 | /* activate PHY low power states */
+ 0x4 << 19 | /* low power delay value */
+ 0x1 << 18 | /* activate PHY low power delay */
+ 0x1 << 17 | /* enable SuperSpeed PHY suspend */
+ 0x1 << 1 | /* default Tx deemphasis value */
+ 0, &dwc3->usb3pipectl);
+
+ /* Configure PHY clock turnaround for 8-bit UTMI+, disable suspend */
+ writel(0x9 << 10 | /* PHY clock turnaround for 8-bit UTMI+ */
+ 0x1 << 8 | /* enable PHY sleep in L1 */
+ 0x1 << 6 | /* enable PHY suspend */
+ 0, &dwc3->usb2phycfg);
+
+ writel(0x5dc << 19 | /* suspend clock scale for 24MHz */
+ 0x1 << 16 | /* retry SS three times (bugfix from U-Boot) */
+ 0x1 << 12 | /* port capability HOST */
+ 0, &dwc3->ctl);
+}
+
+void setup_usb_drd0_dwc3()
+{
+ setup_dwc3(exynos_usb_drd0_dwc3);
+ printk(BIOS_DEBUG, "DWC3 setup for USB DRD0 finished\n");
+}
+
+void setup_usb_drd1_dwc3()
+{
+ setup_dwc3(exynos_usb_drd1_dwc3);
+ printk(BIOS_DEBUG, "DWC3 setup for USB DRD1 finished\n");
+}
+
+static void setup_drd_phy(struct exynos5_usb_drd_phy *phy)
+{
+ /* Set all PHY registers to default values */
+
+ /* XHCI Version 1.0, Frame Length adjustment 30 MHz */
+ setbits_le32(&phy->linksystem, 0x1 << 27 | 0x20 << 1);
+
+ /* Disable OTG, ID0 and DRVVBUS, do not force sleep/suspend */
+ writel(1 << 6, &phy->utmi);
+
+ writel(0x88 << 23 | /* spread spectrum refclk selector */
+ 0x1 << 20 | /* enable spread spectrum */
+ 0x1 << 19 | /* enable prescaler refclk */
+ 0x68 << 11 | /* multiplier for 24MHz refclk */
+ 0x5 << 5 | /* select 24MHz refclk (weird, from U-Boot) */
+ 0x1 << 4 | /* power supply in normal operating mode */
+ 0x3 << 2 | /* use external refclk (undocumented on 5420?)*/
+ 0x1 << 1 | /* force port reset */
+ 0x1 << 0 | /* normal operating mode */
+ 0, &phy->clkrst);
+
+ writel(0x9 << 26 | /* LOS level */
+ 0x3 << 22 | /* TX VREF tune */
+ 0x1 << 20 | /* TX rise tune */
+ 0x1 << 18 | /* TX res tune */
+ 0x3 << 13 | /* TX HS X Vtune */
+ 0x3 << 9 | /* TX FS/LS tune */
+ 0x3 << 6 | /* SQRX tune */
+ 0x4 << 3 | /* OTG tune */
+ 0x4 << 0 | /* comp disc tune */
+ 0, &phy->param0);
+
+ writel(0x7f << 19 | /* reserved */
+ 0x7f << 12 | /* Tx launch amplitude */
+ 0x20 << 6 | /* Tx deemphasis 6dB */
+ 0x1c << 0 | /* Tx deemphasis 3.5dB (value from U-Boot) */
+ 0, &phy->param1);
+
+ /* disable all test features */
+ writel(0, &phy->test);
+
+ /* UTMI clock select? ("must be 0x1") */
+ writel(0x1 << 2, &phy->utmiclksel);
+
+ /* Samsung magic, undocumented (from U-Boot) */
+ writel(0x0, &phy->resume);
+
+ udelay(10);
+ clrbits_le32(&phy->clkrst, 0x1 << 1); /* deassert port reset */
+}
+
+void setup_usb_drd0_phy()
+{
+ printk(BIOS_DEBUG, "Powering up USB DRD0 PHY\n");
+ setbits_le32(&exynos_power->usb_drd0_phy_ctrl, POWER_USB_PHY_CTRL_EN);
+ setup_drd_phy(exynos_usb_drd0_phy);
+}
+
+void setup_usb_drd1_phy()
+{
+ printk(BIOS_DEBUG, "Powering up USB DRD1 PHY\n");
+ setbits_le32(&exynos_power->usb_drd1_phy_ctrl, POWER_USB_PHY_CTRL_EN);
+ setup_drd_phy(exynos_usb_drd1_phy);
+}
+
void setup_usb_host_phy(int hsic_gpio)
{
unsigned int hostphy_ctrl0;
setbits_le32(&exynos_sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
- setbits_le32(&exynos_power->usb_host_phy_ctrl,
- POWER_USB_HOST_PHY_CTRL_EN);
+ setbits_le32(&exynos_power->usb_host_phy_ctrl, POWER_USB_PHY_CTRL_EN);
printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
hsic_gpio ? "with" : "without");
diff --git a/src/cpu/samsung/exynos5420/usb.h b/src/cpu/samsung/exynos5420/usb.h
index 7eb317c68e..b3c2a33fd6 100644
--- a/src/cpu/samsung/exynos5420/usb.h
+++ b/src/cpu/samsung/exynos5420/usb.h
@@ -45,24 +45,100 @@
struct exynos5_usb_host_phy {
uint32_t usbphyctrl0;
uint32_t usbphytune0;
- uint32_t reserved1[2];
+ uint8_t reserved1[8];
uint32_t hsicphyctrl1;
uint32_t hsicphytune1;
- uint32_t reserved2[2];
+ uint8_t reserved2[8];
uint32_t hsicphyctrl2;
uint32_t hsicphytune2;
- uint32_t reserved3[2];
+ uint8_t reserved3[8];
uint32_t ehcictrl;
uint32_t ohcictrl;
uint32_t usbotgsys;
- uint32_t reserved4;
+ uint8_t reserved4[4];
uint32_t usbotgtune;
};
static struct exynos5_usb_host_phy * const exynos_usb_host_phy =
(void *)EXYNOS5_USB_HOST_PHY_BASE;
+struct exynos5_usb_drd_phy {
+ uint8_t reserved1[4];
+ uint32_t linksystem;
+ uint32_t utmi;
+ uint32_t pipe;
+ uint32_t clkrst;
+ uint32_t reg0;
+ uint32_t reg1;
+ uint32_t param0;
+ uint32_t param1;
+ uint32_t term;
+ uint32_t test;
+ uint32_t adp;
+ uint32_t utmiclksel;
+ uint32_t resume;
+ uint8_t reserved2[8];
+ uint32_t linkhcbelt;
+ uint32_t linkport;
+};
+
+static struct exynos5_usb_drd_phy * const exynos_usb_drd0_phy =
+ (void *)EXYNOS5420_USB_DRD0_PHY_BASE;
+static struct exynos5_usb_drd_phy * const exynos_usb_drd1_phy =
+ (void *)EXYNOS5420_USB_DRD1_PHY_BASE;
+
+struct exynos5_usb_drd_dwc3 {
+ uint32_t sbuscfg0;
+ uint32_t sbuscfg1;
+ uint32_t txthrcfg;
+ uint32_t rxthrcfg;
+ uint32_t ctl;
+ uint32_t evten;
+ uint32_t sts;
+ uint8_t reserved0[4];
+ uint32_t snpsid;
+ uint32_t gpio;
+ uint32_t uid;
+ uint32_t uctl;
+ uint64_t buserraddr;
+ uint64_t prtbimap;
+ uint8_t reserved1[32];
+ uint32_t dbgfifospace;
+ uint32_t dbgltssm;
+ uint32_t dbglnmcc;
+ uint32_t dbgbmu;
+ uint32_t dbglspmux;
+ uint32_t dbglsp;
+ uint32_t dbgepinfo0;
+ uint32_t dbgepinfo1;
+ uint64_t prtbimap_hs;
+ uint64_t prtbimap_fs;
+ uint8_t reserved2[112];
+ uint32_t usb2phycfg;
+ uint8_t reserved3[60];
+ uint32_t usb2i2cctl;
+ uint8_t reserved4[60];
+ uint32_t usb2phyacc;
+ uint8_t reserved5[60];
+ uint32_t usb3pipectl;
+ uint8_t reserved6[60];
+};
+
+static struct exynos5_usb_drd_dwc3 * const exynos_usb_drd0_dwc3 =
+ (void *)EXYNOS5420_USB_DRD0_DWC3_BASE;
+static struct exynos5_usb_drd_dwc3 * const exynos_usb_drd1_dwc3 =
+ (void *)EXYNOS5420_USB_DRD1_DWC3_BASE;
+
/* Leave hsic_gpio at 0 to not enable HSIC. */
void setup_usb_host_phy(int hsic_gpio);
+void setup_usb_drd0_phy(void);
+void setup_usb_drd1_phy(void);
+
+/* Call reset_ before setup_, ensure at least 100ms pass in between. */
+void reset_usb_drd0_dwc3(void);
+void reset_usb_drd1_dwc3(void);
+void setup_usb_drd0_dwc3(void);
+void setup_usb_drd1_dwc3(void);
+
#endif
diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c
index bdf2d571b2..211160d754 100644
--- a/src/mainboard/google/pit/mainboard.c
+++ b/src/mainboard/google/pit/mainboard.c
@@ -312,9 +312,22 @@ static enum exynos5_gpio_pin usb_drd0_vbus = GPIO_H00;
static enum exynos5_gpio_pin usb_drd1_vbus = GPIO_H01;
/* static enum exynos5_gpio_pin hsic_reset_l = GPIO_X24; */
+static void prepare_usb(void)
+{
+ /* Kick these resets off early so they get at least 100ms to settle */
+ reset_usb_drd0_dwc3();
+ reset_usb_drd1_dwc3();
+}
+
static void setup_usb(void)
{
/* HSIC and USB HOST port not needed in firmware on this board */
+ setup_usb_drd0_phy();
+ setup_usb_drd1_phy();
+
+ setup_usb_drd0_dwc3();
+ setup_usb_drd1_dwc3();
+
gpio_direction_output(usb_drd0_vbus, 1);
gpio_direction_output(usb_drd1_vbus, 1);
}
@@ -401,6 +414,7 @@ static void mainboard_init(device_t dev)
void *fb_addr = (void *)(get_fb_base_kb() * KiB);
+ prepare_usb();
gpio_init();
setup_storage();
tmu_init(&exynos5420_tmu_info);
@@ -408,8 +422,6 @@ static void mainboard_init(device_t dev)
/* Clock Gating all the unused IP's to save power */
clock_gate();
- setup_usb();
-
sdmmc_vdd();
set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);
@@ -447,6 +459,8 @@ static void mainboard_init(device_t dev)
backlight_vdd();
backlight_pwm();
backlight_en();
+
+ setup_usb();
}
static void mainboard_enable(device_t dev)
diff --git a/src/mainboard/google/snow/mainboard.c b/src/mainboard/google/snow/mainboard.c
index 756dc15325..f906e534a3 100644
--- a/src/mainboard/google/snow/mainboard.c
+++ b/src/mainboard/google/snow/mainboard.c
@@ -165,9 +165,17 @@ static enum exynos5_gpio_pin usb_host_vbus = GPIO_X11;
static enum exynos5_gpio_pin usb_drd_vbus = GPIO_X27;
/* static enum exynos5_gpio_pin hsic_reset_l = GPIO_E10; */
+static void prepare_usb(void)
+{
+ /* Kick this reset off early so it gets at least 100ms to settle */
+ reset_usb_drd_dwc3();
+}
+
static void setup_usb(void)
{
/* HSIC not needed in firmware on this board */
+ setup_usb_drd_phy();
+ setup_usb_drd_dwc3();
setup_usb_host_phy(0);
gpio_direction_output(usb_host_vbus, 1);
@@ -260,6 +268,7 @@ static void mainboard_init(device_t dev)
};
void *fb_addr = (void *)(get_fb_base_kb() * KiB);
+ prepare_usb();
gpio_init();
setup_storage();
@@ -273,7 +282,6 @@ static void mainboard_init(device_t dev)
/* Disable USB3.0 PLL to save 250mW of power */
disable_usb30_pll();
- setup_usb();
sdmmc_vdd();
@@ -309,6 +317,8 @@ static void mainboard_init(device_t dev)
if (dp_tries > MAX_DP_TRIES)
printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
+ setup_usb();
+
// Uncomment to get excessive GPIO output:
// gpio_info();
}