From b06862b9d8ea7046287ac84589210ef16a1afc0d Mon Sep 17 00:00:00 2001
From: Bin Meng <bmeng.cn@gmail.com>
Date: Thu, 3 Sep 2015 05:37:27 -0700
Subject: [PATCH] x86: quark: Add USB PHY initialization support

USB PHY needs to be properly initialized per Quark firmware writer
guide, otherwise the EHCI controller on Quark SoC won't work.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
 arch/x86/cpu/quark/quark.c              | 41 +++++++++++++++++++++++++
 arch/x86/include/asm/arch-quark/quark.h |  8 +++++
 2 files changed, 49 insertions(+)

diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index dda3c7c7fc..637c370e81 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -125,6 +125,44 @@ static void quark_pcie_early_init(void)
 	msg_port_io_write(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1, pcie_cfg);
 }
 
+static void quark_usb_early_init(void)
+{
+	u32 usb;
+
+	/* The sequence below comes from Quark firmware writer guide */
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_GLOBAL_PORT);
+	usb &= ~(1 << 1);
+	usb |= ((1 << 6) | (1 << 7));
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_GLOBAL_PORT, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_COMPBG);
+	usb &= ~((1 << 8) | (1 << 9));
+	usb |= ((1 << 7) | (1 << 10));
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_COMPBG, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2);
+	usb |= (1 << 29);
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL1);
+	usb |= (1 << 1);
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL1, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL1);
+	usb &= ~((1 << 3) | (1 << 4) | (1 << 5));
+	usb |= (1 << 6);
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL1, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2);
+	usb &= ~(1 << 29);
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb);
+
+	usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2);
+	usb |= (1 << 24);
+	msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb);
+}
+
 static void quark_enable_legacy_seg(void)
 {
 	u32 hmisc2;
@@ -164,6 +202,9 @@ int arch_cpu_init(void)
 	 */
 	quark_pcie_early_init();
 
+	/* Initialize USB2 PHY */
+	quark_usb_early_init();
+
 	/* Turn on legacy segments (A/B/E/F) decode to system RAM */
 	quark_enable_legacy_seg();
 
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index aad7fbe883..5d81976998 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -12,6 +12,7 @@
 #define MSG_PORT_HOST_BRIDGE	0x03
 #define MSG_PORT_RMU		0x04
 #define MSG_PORT_MEM_MGR	0x05
+#define MSG_PORT_USB_AFE	0x14
 #define MSG_PORT_PCIE_AFE	0x16
 #define MSG_PORT_SOC_UNIT	0x31
 
@@ -49,6 +50,13 @@
 #define ESRAM_BLK_CTRL		0x82
 #define ESRAM_BLOCK_MODE	0x10000000
 
+/* Port 0x14: USB2 AFE Unit Port Registers */
+
+#define USB2_GLOBAL_PORT	0x4001
+#define USB2_PLL1		0x7f02
+#define USB2_PLL2		0x7f03
+#define USB2_COMPBG		0x7f04
+
 /* Port 0x16: PCIe AFE Unit Port Registers */
 
 #define PCIE_RXPICTRL0_L0	0x2080
-- 
2.39.5