
The A83T has 3 USB PHYs: 1 for USB OTG, 1 for standard USB 1.1/2.0 host, 1 for USB HSIC.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/sunxi/usb_phy.c | 48 ++++++++++++++++++++++++++++++++++++++ include/configs/sun8i.h | 2 ++ 2 files changed, 50 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index 0749fbd..4ac532a 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -34,6 +34,16 @@ #define REG_PHY_UNK_H3 0x420 #define REG_PMU_UNK_H3 0x810
+/* A83T specific control bits for PHY0 */ +#define SUNXI_PHY_CTL_VBUSVLDEXT BIT(5) +#define SUNXI_PHY_CTL_SIDDQ BIT(3) + +/* A83T HSIC specific bits */ +#define SUNXI_EHCI_HS_FORCE BIT(20) +#define SUNXI_EHCI_CONNECT_DET BIT(17) +#define SUNXI_EHCI_CONNECT_INT BIT(16) +#define SUNXI_EHCI_HSIC BIT(1) + static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus; @@ -55,6 +65,14 @@ static struct sunxi_usb_phy { .base = SUNXI_USB1_BASE, }, #if CONFIG_SUNXI_USB_PHYS >= 3 +#ifdef CONFIG_MACH_SUN8I_A83T + { + .usb_rst_mask = CCM_USB_CTRL_HSIC_RST | CCM_USB_CTRL_HSIC_CLK | + CCM_USB_CTRL_12M_CLK, + .id = 2, + .base = SUNXI_USB2_BASE, + } +#else { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .id = 2, @@ -68,6 +86,7 @@ static struct sunxi_usb_phy { .base = SUNXI_USB3_BASE, } #endif +#endif };
static int get_vbus_gpio(int index) @@ -97,6 +116,7 @@ static int get_id_detect_gpio(int index) return -EINVAL; }
+#ifndef CONFIG_MACH_SUN8I_A83T static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, int data, int len) { @@ -161,6 +181,7 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) return; } #endif +#endif
static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) { @@ -174,6 +195,13 @@ static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) SUNXI_EHCI_AHB_INCRX_ALIGN_EN | SUNXI_EHCI_ULPI_BYPASS_EN;
+#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 2) + bits |= SUNXI_EHCI_HS_FORCE | + SUNXI_EHCI_CONNECT_INT | + SUNXI_EHCI_HSIC; +#endif + if (enable) setbits_le32(addr, bits); else @@ -184,9 +212,11 @@ static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable)
void sunxi_usb_phy_enable_squelch_detect(int index, int enable) { +#ifndef CONFIG_MACH_SUN8I_A83T struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
usb_phy_write(phy, 0x3c, enable ? 0 : 2, 2); +#endif }
void sunxi_usb_phy_init(int index) @@ -200,10 +230,21 @@ void sunxi_usb_phy_init(int index)
setbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask);
+#ifndef CONFIG_MACH_SUN8I_A83T sunxi_usb_phy_config(phy); +#endif
if (phy->id != 0) sunxi_usb_phy_passby(phy, SUNXI_USB_PASSBY_EN); + +#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 0) { + setbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_VBUSVLDEXT); + clrbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_SIDDQ); + } +#endif }
void sunxi_usb_phy_exit(int index) @@ -218,6 +259,13 @@ void sunxi_usb_phy_exit(int index) if (phy->id != 0) sunxi_usb_phy_passby(phy, !SUNXI_USB_PASSBY_EN);
+#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 0) { + setbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_SIDDQ); + } +#endif + clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); }
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 7c0ab1e..eb5db4e 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -20,6 +20,8 @@
#ifdef CONFIG_MACH_SUN8I_H3 #define CONFIG_SUNXI_USB_PHYS 4 +#elif defined CONFIG_MACH_SUN8I_A83T + #define CONFIG_SUNXI_USB_PHYS 3 #else #define CONFIG_SUNXI_USB_PHYS 2 #endif