exynos5: Refactor board-specific parts out of USB PHY code

This patch moves around some of the existing Exynos5 USB 2.0 PHY code
to make it cleaner in preparation of the 3.0 PHYs. It moves the VBUS
GPIOs (which are completely board-specific) into the mainboard code and
makes sure to only initialize PHYs on the boards that actually need
them. It also removes the USB 3.0 PLL hack that was needed on Snow from
the Pit and Kirby boards (which do not have that PLL anymore).

BUG=chrome-os-partner:21969
TEST=Manual

Change-Id: Ia35f47a765acff60481f0907f7448ec4f78e0937
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/66887
Reviewed-by: Stefan Reinauer <reinauer@google.com>
diff --git a/src/cpu/samsung/exynos5250/cpu.c b/src/cpu/samsung/exynos5250/cpu.c
index d66d98e..3646c2a 100644
--- a/src/cpu/samsung/exynos5250/cpu.c
+++ b/src/cpu/samsung/exynos5250/cpu.c
@@ -30,7 +30,6 @@
 #include "dp-core.h"
 #include "cpu.h"
 #include "clk.h"
-#include "usb.h"
 #include "chip.h"
 
 static unsigned int cpu_id;
@@ -153,8 +152,6 @@
 {
 	printk(BIOS_INFO, "CPU:   S5P%X @ %ldMHz\n",
 			cpu_id, get_arm_clk() / (1024*1024));
-
-	usb_init(dev);
 }
 
 static void cpu_noop(device_t dev)
diff --git a/src/cpu/samsung/exynos5250/cpu.h b/src/cpu/samsung/exynos5250/cpu.h
index f4ab3ed..4cc9391 100644
--- a/src/cpu/samsung/exynos5250/cpu.h
+++ b/src/cpu/samsung/exynos5250/cpu.h
@@ -44,9 +44,10 @@
 #define EXYNOS5_DMC_CTRL_BASE		0x10DD0000
 #define EXYNOS5_GPIO_PART1_BASE		0x11400000	/* A00..Y67 */
 #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_HOST_EHCI_BASE	0x12110000
-#define EXYNOS5_USBPHY_BASE		0x12130000
-#define EXYNOS5_USBOTG_BASE		0x12140000
+#define EXYNOS5_USB_HOST_PHY_BASE	0x12130000
 
 #define EXYNOS5_MMC_BASE		0x12200000
 #define EXYNOS5_MSHC_BASE		0x12240000
@@ -117,8 +118,9 @@
 #define samsung_get_base_swreset() ((struct exynos5_swreset *)EXYNOS5_SWRESET)
 #define samsung_get_base_sysreg() ((struct exynos5_sysreg *)EXYNOS5_SYSREG_BASE)
 #define samsung_get_base_uart() ((struct exynos5_uart *)EXYNOS5_UART_BASE)
-#define samsung_get_base_usb_phy() ((struct exynos5_usb_phy *)EXYNOS5_USBPHY_BASE)
-#define samsung_get_base_usb_otg() ((struct exynos5_usb_otg *)EXYNOS5_USBOTG_BASE)
+#define samsung_get_base_usb_drd_phy() ((struct exynos5_usb_drd_phy *)EXYNOS5_USB_DRD_PHY_BASE)
+#define samsung_get_base_usb_host_phy() ((struct exynos5_usb_host_phy *)EXYNOS5_USB_HOST_PHY_BASE)
+#define samsung_get_base_usb_host_otg() ((struct exynos5_usb_host_otg *)EXYNOS5_USB_HOST_OTG_BASE)
 #define samsung_get_base_watchdog() ((struct exynos5_watchdog *)EXYNOS5_WATCHDOG_BASE)
 #define samsung_get_base_power() ((struct exynos5_power *)EXYNOS5_POWER_BASE)
 #define samsung_get_base_i2s() ((struct exynos5_i2s *)EXYNOS5_I2S_BASE)
diff --git a/src/cpu/samsung/exynos5250/power.c b/src/cpu/samsung/exynos5250/power.c
index 029efc9..be055e3 100644
--- a/src/cpu/samsung/exynos5250/power.c
+++ b/src/cpu/samsung/exynos5250/power.c
@@ -24,7 +24,6 @@
 #include <arch/hlt.h>
 #include "cpu.h"
 #include "power.h"
-#include "sysreg.h"
 
 static void ps_hold_setup(void)
 {
@@ -65,36 +64,6 @@
 	setbits_le32(&power->dptx_phy_control, DPTX_PHY_ENABLE);
 }
 
-void power_enable_usb_phy(void)
-{
-	struct exynos5_sysreg *sysreg =
-		samsung_get_base_sysreg();
-	struct exynos5_power *power =
-		samsung_get_base_power();
-	unsigned int phy_cfg;
-
-	/* Setting USB20PHY_CONFIG register to USB 2.0 HOST link */
-	phy_cfg = readl(&sysreg->usb20_phy_cfg);
-	if (phy_cfg & USB20_PHY_CFG_EN) {
-		printk(BIOS_DEBUG, "USB 2.0 HOST link already selected\n");
-	} else {
-		phy_cfg |= USB20_PHY_CFG_EN;
-		writel(phy_cfg, &sysreg->usb20_phy_cfg);
-	}
-
-	/* Enabling USBHOST_PHY */
-	setbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
-}
-
-void power_disable_usb_phy(void)
-{
-	struct exynos5_power *power =
-		samsung_get_base_power();
-
-	/* Disabling USBHost_PHY */
-	clrbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
-}
-
 void power_enable_hw_thermal_trip(void)
 {
 	struct exynos5_power *power =
diff --git a/src/cpu/samsung/exynos5250/power.h b/src/cpu/samsung/exynos5250/power.h
index 5483d92..2b57e18 100644
--- a/src/cpu/samsung/exynos5250/power.h
+++ b/src/cpu/samsung/exynos5250/power.h
@@ -73,9 +73,6 @@
 /* Enable DPTX PHY */
 void power_enable_dp_phy(void);
 
-void power_enable_usb_phy(void);
-void power_disable_usb_phy(void);
-
 /* Initialize the pmic voltages to power up the system */
 int power_init(void);
 
diff --git a/src/cpu/samsung/exynos5250/usb.c b/src/cpu/samsung/exynos5250/usb.c
index 5084707..9e990a1 100644
--- a/src/cpu/samsung/exynos5250/usb.c
+++ b/src/cpu/samsung/exynos5250/usb.c
@@ -18,75 +18,72 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <delay.h>
+#include <arch/io.h>
 #include <console/console.h>
 #include <device/device.h>
-#include <arch/io.h>
-#include <delay.h>
+#include "cpu.h"
 #include "gpio.h"
 #include "power.h"
-#include "cpu.h"
+#include "sysreg.h"
 #include "usb.h"
-#include "chip.h"
 
-/* Enable VBUS */
-static int usb_vbus_init(int vbus_gpio)
-{
-	/* Enable VBUS power switch */
-	gpio_direction_output(GPIO_X11, 1);
-	/* VBUS turn ON time */
-	mdelay(3);
-
-	return 0;
-}
-
-/* Setup the EHCI host controller. */
-
-static void setup_usb_phy(struct usb_phy *usb, int hsic_gpio)
+void setup_usb_host_phy(int hsic_gpio)
 {
 	unsigned int hostphy_ctrl0;
+	struct exynos5_sysreg *sysreg = samsung_get_base_sysreg();
+	struct exynos5_power *power = samsung_get_base_power();
+	struct exynos5_usb_host_phy *phy = samsung_get_base_usb_host_phy();
 
-	power_enable_usb_phy();
+	setbits_le32(&sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
+	setbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
 
-	/* Setting up host and device simultaneously */
-	hostphy_ctrl0 = readl(&usb->usbphyctrl0);
-	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK | HOST_CTRL0_COMMONON_N |
+	printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
+			hsic_gpio ? "with" : "without");
+
+	hostphy_ctrl0 = readl(&phy->usbphyctrl0);
+	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK |
+			   HOST_CTRL0_COMMONON_N |
 			   /* HOST Phy setting */
 			   HOST_CTRL0_PHYSWRST |
 			   HOST_CTRL0_PHYSWRSTALL |
 			   HOST_CTRL0_SIDDQ |
 			   HOST_CTRL0_FORCESUSPEND |
 			   HOST_CTRL0_FORCESLEEP);
-	hostphy_ctrl0 |= (	/* Setting up the ref freq */
-				 CLK_24MHZ << 16 |
-				 /* HOST Phy setting */
-				 HOST_CTRL0_LINKSWRST |
-				 HOST_CTRL0_UTMISWRST);
-	writel(hostphy_ctrl0, &usb->usbphyctrl0);
+	hostphy_ctrl0 |= (/* Setting up the ref freq */
+			  CLK_24MHZ << 16 |
+			  /* HOST Phy setting */
+			  HOST_CTRL0_LINKSWRST |
+			  HOST_CTRL0_UTMISWRST);
+	writel(hostphy_ctrl0, &phy->usbphyctrl0);
 	udelay(10);
-	clrbits_le32(&usb->usbphyctrl0,
-		     HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+	clrbits_le32(&phy->usbphyctrl0,
+		     HOST_CTRL0_LINKSWRST |
+		     HOST_CTRL0_UTMISWRST);
 	udelay(20);
 
 	/* EHCI Ctrl setting */
-	setbits_le32(&usb->ehcictrl,
+	setbits_le32(&phy->ehcictrl,
 		     EHCICTRL_ENAINCRXALIGN |
 		     EHCICTRL_ENAINCR4 |
-		     EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
+		     EHCICTRL_ENAINCR8 |
+		     EHCICTRL_ENAINCR16);
 
 	/* HSIC USB Hub initialization. */
-	// FIXME board specific?
-	gpio_direction_output(hsic_gpio, 0);
-	udelay(100);
-	gpio_direction_output(hsic_gpio, 1);
-	udelay(5000);
+	if (hsic_gpio) {
+		gpio_direction_output(hsic_gpio, 0);
+		udelay(100);
+		gpio_direction_output(hsic_gpio, 1);
+		udelay(5000);
 
-	clrbits_le32(&usb->hsicphyctrl1,
-		     HOST_CTRL0_SIDDQ |
-		     HOST_CTRL0_FORCESLEEP |
-		     HOST_CTRL0_FORCESUSPEND);
-	setbits_le32(&usb->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
-	udelay(10);
-	clrbits_le32(&usb->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+		clrbits_le32(&phy->hsicphyctrl1,
+			     HOST_CTRL0_SIDDQ |
+			     HOST_CTRL0_FORCESLEEP |
+			     HOST_CTRL0_FORCESUSPEND);
+		setbits_le32(&phy->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+		udelay(10);
+		clrbits_le32(&phy->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+	}
 
 	/* At this point we need to wait for 50ms before talking to
 	 * the USB controller (PHY clock and power setup time)
@@ -94,13 +91,3 @@
 	 * will have passed.
 	 */
 }
-
-void usb_init(device_t dev)
-{
-	struct usb_phy *usb;
-	struct cpu_samsung_exynos5250_config *conf = dev->chip_info;
-
-	usb_vbus_init(conf->usb_vbus_gpio);
-	usb = (struct usb_phy *) samsung_get_base_usb_phy();
-	setup_usb_phy(usb, conf->usb_hsic_gpio);
-}
diff --git a/src/cpu/samsung/exynos5250/usb.h b/src/cpu/samsung/exynos5250/usb.h
index 45a7b53..c963436 100644
--- a/src/cpu/samsung/exynos5250/usb.h
+++ b/src/cpu/samsung/exynos5250/usb.h
@@ -40,7 +40,7 @@
 #define EHCICTRL_ENAINCR16                      (1 << 26)
 
 /* Register map for PHY control */
-struct usb_phy {
+struct exynos5_usb_host_phy {
         uint32_t usbphyctrl0;
         uint32_t usbphytune0;
         uint32_t reserved1[2];
@@ -57,6 +57,7 @@
         uint32_t usbotgtune;
 };
 
-void usb_init(device_t dev);
+/* Leave hsic_gpio at 0 to not enable HSIC. */
+void setup_usb_host_phy(int hsic_gpio);
 
 #endif
diff --git a/src/cpu/samsung/exynos5420/cpu.c b/src/cpu/samsung/exynos5420/cpu.c
index bd140d0..98bd493 100644
--- a/src/cpu/samsung/exynos5420/cpu.c
+++ b/src/cpu/samsung/exynos5420/cpu.c
@@ -30,7 +30,6 @@
 #include "fimd.h"
 #include "cpu.h"
 #include "clk.h"
-#include "usb.h"
 #include "chip.h"
 
 #include <ec/google/chromeec/ec.h>
@@ -181,8 +180,6 @@
 {
 	printk(BIOS_INFO, "CPU:   S5P%X @ %ldMHz\n",
 			cpu_id, get_arm_clk() / 1000000);
-
-	usb_init(dev);
 }
 
 static void cpu_noop(device_t dev)
diff --git a/src/cpu/samsung/exynos5420/cpu.h b/src/cpu/samsung/exynos5420/cpu.h
index 44b3464..472b6aa 100644
--- a/src/cpu/samsung/exynos5420/cpu.h
+++ b/src/cpu/samsung/exynos5420/cpu.h
@@ -118,11 +118,14 @@
 #define EXYNOS5420_DMC_DREXI_1		0x10C30000
 #define EXYNOS5420_DMC_TZASC_0		0x10D40000
 #define EXYNOS5420_DMC_TZASC_1		0x10D50000
-#define EXYNOS5420_USB_HOST_XHCI_BASE	0x12000000
-#define EXYNOS5420_USB3PHY_BASE		0x12100000
+#define EXYNOS5420_USB_DRD0_XHCI_BASE	0x12000000
+#define EXYNOS5420_USB_DRD0_PHY_BASE	0x12100000
 #define EXYNOS5420_USB_HOST_EHCI_BASE	0x12110000
+#define EXYNOS5420_USB_HOST_PHY_BASE	0x12130000
 #define EXYNOS5420_MMC_BASE		0x12200000
 #define EXYNOS5420_SROMC_BASE		0x12250000
+#define EXYNOS5420_USB_DRD1_XHCI_BASE	0x12400000
+#define EXYNOS5420_USB_DRD1_PHY_BASE	0x12500000
 #define EXYNOS5420_UART_BASE		0x12C00000
 #define EXYNOS5420_I2C_BASE		0x12C60000
 #define EXYNOS5420_I2C_8910_BASE	0x12E00000
@@ -138,8 +141,7 @@
 #define EXYNOS5420_DP_BASE		0x145B0000
 #define EXYNOS5420_INF_REG_BASE		0x10040800
 
-#define EXYNOS5420_USBPHY_BASE		DEVICE_NOT_AVAILABLE
-#define EXYNOS5420_USBOTG_BASE		DEVICE_NOT_AVAILABLE
+
 #define EXYNOS5420_FIMD_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS5420_ADC_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS5420_MODEM_BASE		DEVICE_NOT_AVAILABLE
@@ -194,8 +196,8 @@
 #define samsung_get_base_swreset() ((struct exynos5_swreset *)EXYNOS5_SWRESET)
 #define samsung_get_base_sysreg() ((struct exynos5_sysreg *)EXYNOS5_SYSREG_BASE)
 #define samsung_get_base_uart() ((struct exynos5_uart *)EXYNOS5_UART_BASE)
-#define samsung_get_base_usb_phy() ((struct exynos5_usb_phy *)EXYNOS5_USBPHY_BASE)
-#define samsung_get_base_usb_otg() ((struct exynos5_usb_otg *)EXYNOS5_USBOTG_BASE)
+#define samsung_get_base_usb_host_phy() ((struct exynos5_usb_host_phy *)EXYNOS5420_USB_HOST_PHY_BASE)
+#define samsung_get_base_usb_host_otg() ((struct exynos5_usb_host_otg *)EXYNOS5420_USB_HOST_OTG_BASE)
 #define samsung_get_base_watchdog() ((struct exynos5_watchdog *)EXYNOS5_WATCHDOG_BASE)
 #define samsung_get_base_power() ((struct exynos5_power *)EXYNOS5_POWER_BASE)
 #define samsung_get_base_i2s() ((struct exynos5_i2s *)EXYNOS5_I2S_BASE)
diff --git a/src/cpu/samsung/exynos5420/power.c b/src/cpu/samsung/exynos5420/power.c
index 3215462..8496d8f 100644
--- a/src/cpu/samsung/exynos5420/power.c
+++ b/src/cpu/samsung/exynos5420/power.c
@@ -26,7 +26,6 @@
 #include "dmc.h"
 #include "power.h"
 #include "setup.h"
-#include "sysreg.h"
 
 void ps_hold_setup(void)
 {
@@ -67,36 +66,6 @@
 	setbits_le32(&power->dptx_phy_control, EXYNOS_DP_PHY_ENABLE);
 }
 
-void power_enable_usb_phy(void)
-{
-	struct exynos5_sysreg *sysreg =
-		samsung_get_base_sysreg();
-	struct exynos5_power *power =
-		samsung_get_base_power();
-	unsigned int phy_cfg;
-
-	/* Setting USB20PHY_CONFIG register to USB 2.0 HOST link */
-	phy_cfg = readl(&sysreg->usb20_phy_cfg);
-	if (phy_cfg & USB20_PHY_CFG_EN) {
-		printk(BIOS_DEBUG, "USB 2.0 HOST link already selected\n");
-	} else {
-		phy_cfg |= USB20_PHY_CFG_EN;
-		writel(phy_cfg, &sysreg->usb20_phy_cfg);
-	}
-
-	/* Enabling USBHOST_PHY */
-	setbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
-}
-
-void power_disable_usb_phy(void)
-{
-	struct exynos5_power *power =
-		samsung_get_base_power();
-
-	/* Disabling USBHost_PHY */
-	clrbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
-}
-
 void power_enable_hw_thermal_trip(void)
 {
 	struct exynos5_power *power =
diff --git a/src/cpu/samsung/exynos5420/power.h b/src/cpu/samsung/exynos5420/power.h
index 4efc84e..29d3d14 100644
--- a/src/cpu/samsung/exynos5420/power.h
+++ b/src/cpu/samsung/exynos5420/power.h
@@ -73,9 +73,6 @@
 /* Enable DPTX PHY */
 void power_enable_dp_phy(void);
 
-void power_enable_usb_phy(void);
-void power_disable_usb_phy(void);
-
 /* Initialize the pmic voltages to power up the system */
 int power_init(void);
 
diff --git a/src/cpu/samsung/exynos5420/usb.c b/src/cpu/samsung/exynos5420/usb.c
index 6e79ef1..9e990a1 100644
--- a/src/cpu/samsung/exynos5420/usb.c
+++ b/src/cpu/samsung/exynos5420/usb.c
@@ -18,75 +18,72 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <delay.h>
+#include <arch/io.h>
 #include <console/console.h>
 #include <device/device.h>
-#include <arch/io.h>
-#include <delay.h>
+#include "cpu.h"
 #include "gpio.h"
 #include "power.h"
-#include "cpu.h"
+#include "sysreg.h"
 #include "usb.h"
-#include "chip.h"
 
-/* Enable VBUS */
-static int usb_vbus_init(int vbus_gpio)
-{
-	/* Enable VBUS power switch */
-	gpio_direction_output(GPIO_X11, 1);
-	/* VBUS turn ON time */
-	mdelay(3);
-
-	return 0;
-}
-
-/* Setup the EHCI host controller. */
-
-static void setup_usb_phy(struct usb_phy *usb, int hsic_gpio)
+void setup_usb_host_phy(int hsic_gpio)
 {
 	unsigned int hostphy_ctrl0;
+	struct exynos5_sysreg *sysreg = samsung_get_base_sysreg();
+	struct exynos5_power *power = samsung_get_base_power();
+	struct exynos5_usb_host_phy *phy = samsung_get_base_usb_host_phy();
 
-	power_enable_usb_phy();
+	setbits_le32(&sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
+	setbits_le32(&power->usb_host_phy_ctrl, POWER_USB_HOST_PHY_CTRL_EN);
 
-	/* Setting up host and device simultaneously */
-	hostphy_ctrl0 = readl(&usb->usbphyctrl0);
-	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK | HOST_CTRL0_COMMONON_N |
+	printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
+			hsic_gpio ? "with" : "without");
+
+	hostphy_ctrl0 = readl(&phy->usbphyctrl0);
+	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK |
+			   HOST_CTRL0_COMMONON_N |
 			   /* HOST Phy setting */
 			   HOST_CTRL0_PHYSWRST |
 			   HOST_CTRL0_PHYSWRSTALL |
 			   HOST_CTRL0_SIDDQ |
 			   HOST_CTRL0_FORCESUSPEND |
 			   HOST_CTRL0_FORCESLEEP);
-	hostphy_ctrl0 |= (	/* Setting up the ref freq */
-				 CLK_24MHZ << 16 |
-				 /* HOST Phy setting */
-				 HOST_CTRL0_LINKSWRST |
-				 HOST_CTRL0_UTMISWRST);
-	writel(hostphy_ctrl0, &usb->usbphyctrl0);
+	hostphy_ctrl0 |= (/* Setting up the ref freq */
+			  CLK_24MHZ << 16 |
+			  /* HOST Phy setting */
+			  HOST_CTRL0_LINKSWRST |
+			  HOST_CTRL0_UTMISWRST);
+	writel(hostphy_ctrl0, &phy->usbphyctrl0);
 	udelay(10);
-	clrbits_le32(&usb->usbphyctrl0,
-		     HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+	clrbits_le32(&phy->usbphyctrl0,
+		     HOST_CTRL0_LINKSWRST |
+		     HOST_CTRL0_UTMISWRST);
 	udelay(20);
 
 	/* EHCI Ctrl setting */
-	setbits_le32(&usb->ehcictrl,
+	setbits_le32(&phy->ehcictrl,
 		     EHCICTRL_ENAINCRXALIGN |
 		     EHCICTRL_ENAINCR4 |
-		     EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
+		     EHCICTRL_ENAINCR8 |
+		     EHCICTRL_ENAINCR16);
 
 	/* HSIC USB Hub initialization. */
-	// FIXME board specific?
-	gpio_direction_output(hsic_gpio, 0);
-	udelay(100);
-	gpio_direction_output(hsic_gpio, 1);
-	udelay(5000);
+	if (hsic_gpio) {
+		gpio_direction_output(hsic_gpio, 0);
+		udelay(100);
+		gpio_direction_output(hsic_gpio, 1);
+		udelay(5000);
 
-	clrbits_le32(&usb->hsicphyctrl1,
-		     HOST_CTRL0_SIDDQ |
-		     HOST_CTRL0_FORCESLEEP |
-		     HOST_CTRL0_FORCESUSPEND);
-	setbits_le32(&usb->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
-	udelay(10);
-	clrbits_le32(&usb->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+		clrbits_le32(&phy->hsicphyctrl1,
+			     HOST_CTRL0_SIDDQ |
+			     HOST_CTRL0_FORCESLEEP |
+			     HOST_CTRL0_FORCESUSPEND);
+		setbits_le32(&phy->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+		udelay(10);
+		clrbits_le32(&phy->hsicphyctrl1, HOST_CTRL0_PHYSWRST);
+	}
 
 	/* At this point we need to wait for 50ms before talking to
 	 * the USB controller (PHY clock and power setup time)
@@ -94,13 +91,3 @@
 	 * will have passed.
 	 */
 }
-
-void usb_init(device_t dev)
-{
-	struct usb_phy *usb;
-	struct cpu_samsung_exynos5420_config *conf = dev->chip_info;
-
-	usb_vbus_init(conf->usb_vbus_gpio);
-	usb = (struct usb_phy *) samsung_get_base_usb_phy();
-	setup_usb_phy(usb, conf->usb_hsic_gpio);
-}
diff --git a/src/cpu/samsung/exynos5420/usb.h b/src/cpu/samsung/exynos5420/usb.h
index 1b7d635..7837eb2 100644
--- a/src/cpu/samsung/exynos5420/usb.h
+++ b/src/cpu/samsung/exynos5420/usb.h
@@ -40,7 +40,7 @@
 #define EHCICTRL_ENAINCR16                      (1 << 26)
 
 /* Register map for PHY control */
-struct usb_phy {
+struct exynos5_usb_host_phy {
         uint32_t usbphyctrl0;
         uint32_t usbphytune0;
         uint32_t reserved1[2];
@@ -57,6 +57,7 @@
         uint32_t usbotgtune;
 };
 
-void usb_init(device_t dev);
+/* Leave hsic_gpio at 0 to not enable HSIC. */
+void setup_usb_host_phy(int hsic_gpio);
 
 #endif
diff --git a/src/mainboard/google/kirby/devicetree.cb b/src/mainboard/google/kirby/devicetree.cb
index 2c9e668..0a8a8ca 100644
--- a/src/mainboard/google/kirby/devicetree.cb
+++ b/src/mainboard/google/kirby/devicetree.cb
@@ -30,6 +30,4 @@
 	register "left_margin" = "80"
 	register "right_margin" = "48"
 	register "hsync" = "32"
-	register "usb_vbus_gpio" = "GPIO_X11"
-	register "usb_hsic_gpio" = "GPIO_E10"
 end
diff --git a/src/mainboard/google/kirby/mainboard.c b/src/mainboard/google/kirby/mainboard.c
index 4d5dd1a..a479061 100644
--- a/src/mainboard/google/kirby/mainboard.c
+++ b/src/mainboard/google/kirby/mainboard.c
@@ -36,6 +36,7 @@
 #include <cpu/samsung/exynos5420/i2c.h>
 #include <cpu/samsung/exynos5420/dp.h>
 #include <cpu/samsung/exynos5420/fimd.h>
+#include <cpu/samsung/exynos5420/usb.h>
 #include <drivers/parade/ps8625/ps8625.h>
 #include <ec/google/chromeec/ec.h>
 #include <stdlib.h>
@@ -296,7 +297,17 @@
 	udelay(LCD_T6_DELAY_MS * 1000);
 }
 
+static enum exynos5_gpio_pin usb_drd_vbus = GPIO_H00;
 
+static void setup_usb(void)
+{
+	/* USB HOST port not needed in firmware, HSIC not stuffed */
+	/* TODO: remove (set up 2.0 PHY only to help early bring-up) */
+	setup_usb_host_phy(0);
+
+	/* Kirby has a single VBUS GPIO for both DRDs to save IO-board pins */
+	gpio_direction_output(usb_drd_vbus, 1);
+}
 
 static struct edp_video_info dp_video_info = {
 	.master_mode = 0,
@@ -313,16 +324,6 @@
 #define EXYNOS5420_DP1_BASE	0x145b0000
 #define MAX_DP_TRIES	5
 
-/*
- * This function disables the USB3.0 PLL to save power
- */
-static void disable_usb30_pll(void)
-{
-	enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
-
-	gpio_direction_output(usb3_pll_l, 0);
-}
-
 static void setup_storage(void)
 {
 	/* MMC0: Fixed, 8 bit mode, connected with GPIO. */
@@ -371,8 +372,7 @@
 	/* Clock Gating all the unused IP's to save power */
 	clock_gate();
 
-	/* Disable USB3.0 PLL to save 250mW of power */
-	disable_usb30_pll();
+	setup_usb();
 
 	set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);
 
diff --git a/src/mainboard/google/pit/devicetree.cb b/src/mainboard/google/pit/devicetree.cb
index 0c687c4..3b6cdb9 100644
--- a/src/mainboard/google/pit/devicetree.cb
+++ b/src/mainboard/google/pit/devicetree.cb
@@ -30,6 +30,4 @@
 	register "left_margin" = "80"
 	register "right_margin" = "48"
 	register "hsync" = "32"
-	register "usb_vbus_gpio" = "GPIO_X11"
-	register "usb_hsic_gpio" = "GPIO_E10"
 end
diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c
index 5f6faa2..f85cf00 100644
--- a/src/mainboard/google/pit/mainboard.c
+++ b/src/mainboard/google/pit/mainboard.c
@@ -36,6 +36,7 @@
 #include <cpu/samsung/exynos5420/i2c.h>
 #include <cpu/samsung/exynos5420/dp.h>
 #include <cpu/samsung/exynos5420/fimd.h>
+#include <cpu/samsung/exynos5420/usb.h>
 #include <drivers/parade/ps8625/ps8625.h>
 #include <ec/google/chromeec/ec.h>
 #include <stdlib.h>
@@ -303,7 +304,16 @@
 	gpio_direction_output(bl_en, 1);
 }
 
+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 setup_usb(void)
+{
+	/* HSIC and USB HOST port not needed in firmware on this board */
+	gpio_direction_output(usb_drd0_vbus, 1);
+	gpio_direction_output(usb_drd1_vbus, 1);
+}
 
 static struct edp_video_info dp_video_info = {
 	.master_mode = 0,
@@ -320,16 +330,6 @@
 #define EXYNOS5420_DP1_BASE	0x145b0000
 #define MAX_DP_TRIES	5
 
-/*
- * This function disables the USB3.0 PLL to save power
- */
-static void disable_usb30_pll(void)
-{
-	enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
-
-	gpio_direction_output(usb3_pll_l, 0);
-}
-
 static void setup_storage(void)
 {
 	/* MMC0: Fixed, 8 bit mode, connected with GPIO. */
@@ -405,8 +405,7 @@
 	/* Clock Gating all the unused IP's to save power */
 	clock_gate();
 
-	/* Disable USB3.0 PLL to save 250mW of power */
-	disable_usb30_pll();
+	setup_usb();
 
 	sdmmc_vdd();
 
diff --git a/src/mainboard/google/snow/devicetree.cb b/src/mainboard/google/snow/devicetree.cb
index 34aa4e6..c14f374 100644
--- a/src/mainboard/google/snow/devicetree.cb
+++ b/src/mainboard/google/snow/devicetree.cb
@@ -30,6 +30,4 @@
 	register "left_margin" = "80"
 	register "right_margin" = "48"
 	register "hsync" = "32"
-	register "usb_vbus_gpio" = "GPIO_X11"
-	register "usb_hsic_gpio" = "GPIO_E10"
 end
diff --git a/src/mainboard/google/snow/mainboard.c b/src/mainboard/google/snow/mainboard.c
index 23119c9..3167a14 100644
--- a/src/mainboard/google/snow/mainboard.c
+++ b/src/mainboard/google/snow/mainboard.c
@@ -35,6 +35,7 @@
 #include <cpu/samsung/exynos5250/power.h>
 #include <cpu/samsung/exynos5250/i2c.h>
 #include <cpu/samsung/exynos5250/dp-core.h>
+#include <cpu/samsung/exynos5250/usb.h>
 
 #include "exynos5250.h"
 
@@ -156,6 +157,19 @@
 	tps65090_fet_enable(TPS65090_BUS, FET4_CTRL);
 }
 
+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 setup_usb(void)
+{
+	/* HSIC not needed in firmware on this board */
+	setup_usb_host_phy(0);
+
+	gpio_direction_output(usb_host_vbus, 1);
+	gpio_direction_output(usb_drd_vbus, 1);
+}
+
 //static struct video_info smdk5250_dp_config = {
 static struct video_info dp_video_info = {
 	/* FIXME: fix video_info struct to use const for name */
@@ -256,6 +270,7 @@
 
 	/* Disable USB3.0 PLL to save 250mW of power */
 	disable_usb30_pll();
+	setup_usb();
 
 	sdmmc_vdd();