[U-Boot] [PATCH] sunxi: H3: Add support for the host usb-phys

From: Jelle van der Waa jelle@vdwaa.nl
Add support for phy 1-3.
Signed-off-by: Jelle van der Waa jelle@vdwaa.nl [hdegoede@redhat.com: use setclrbits_le32 instead of read-modify-write] Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/usb_phy.c | 35 +++++++++++++++++++++------ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 22 +++++++++++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 8 ++++++ configs/orangepi_pc_defconfig | 1 + configs/orangepi_plus_defconfig | 1 + drivers/usb/host/ehci-sunxi.c | 14 +++++------ drivers/usb/host/ohci-sunxi.c | 18 +++++++------- include/configs/sun8i.h | 6 ++++- 8 files changed, 81 insertions(+), 24 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index 19bb5a1..6ac96cc 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -31,6 +31,9 @@ #define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) #define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0)
+#define REG_PHY_UNK_H3 0x420 +#define REG_PMU_UNK_H3 0x810 + static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus; @@ -39,19 +42,30 @@ static struct sunxi_usb_phy { int id; int init_count; int power_on_count; + int base; } sunxi_usb_phy[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, .id = 0, + .base = SUNXI_USB0_BASE, }, { .usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK, .id = 1, + .base = SUNXI_USB1_BASE, }, #if CONFIG_SUNXI_USB_PHYS >= 3 { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .id = 2, + .base = SUNXI_USB2_BASE, + }, +#endif +#if CONFIG_SUNXI_USB_PHYS >= 4 + { + .usb_rst_mask = CCM_USB_CTRL_PHY3_RST | CCM_USB_CTRL_PHY3_CLK, + .id = 3, + .base = SUNXI_USB3_BASE, } #endif }; @@ -114,6 +128,15 @@ static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, } }
+#if defined CONFIG_MACH_SUN8I_H3 +static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) +{ + if (phy->id == 0) + clrbits_le32(SUNXI_USBPHY_BASE + REG_PHY_UNK_H3, 0x01); + + clrbits_le32(phy->base + REG_PMU_UNK_H3, 0x02); +} +#else static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) { /* The following comments are machine @@ -136,16 +159,14 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy)
return; } +#endif
-static void sunxi_usb_phy_passby(int index, int enable) +static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) { unsigned long bits = 0; void *addr;
- if (index == 1) - addr = (void *)SUNXI_USB1_BASE + SUNXI_USB_PMU_IRQ_ENABLE; - else - addr = (void *)SUNXI_USB2_BASE + SUNXI_USB_PMU_IRQ_ENABLE; + addr = (void *)phy->base + SUNXI_USB_PMU_IRQ_ENABLE;
bits = SUNXI_EHCI_AHB_ICHR8_EN | SUNXI_EHCI_AHB_INCR4_BURST_EN | @@ -181,7 +202,7 @@ void sunxi_usb_phy_init(int index) sunxi_usb_phy_config(phy);
if (phy->id != 0) - sunxi_usb_phy_passby(index, SUNXI_USB_PASSBY_EN); + sunxi_usb_phy_passby(phy, SUNXI_USB_PASSBY_EN); }
void sunxi_usb_phy_exit(int index) @@ -194,7 +215,7 @@ void sunxi_usb_phy_exit(int index) return;
if (phy->id != 0) - sunxi_usb_phy_passby(index, !SUNXI_USB_PASSBY_EN); + sunxi_usb_phy_passby(phy, !SUNXI_USB_PASSBY_EN);
clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); } diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 554d858..1655f10 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -229,8 +229,18 @@ struct sunxi_ccm_reg { /* ahb_gate0 offsets */ #define AHB_GATE_OFFSET_USB_OHCI1 30 #define AHB_GATE_OFFSET_USB_OHCI0 29 +#ifdef CONFIG_MACH_SUN8I_H3 +/* + * These are EHCI1 - EHCI3 in the datasheet we call them 0 - 2 like they + * were called on older SoCs. + */ +#define AHB_GATE_OFFSET_USB_EHCI2 27 +#define AHB_GATE_OFFSET_USB_EHCI1 26 +#define AHB_GATE_OFFSET_USB_EHCI0 25 +#else #define AHB_GATE_OFFSET_USB_EHCI1 27 #define AHB_GATE_OFFSET_USB_EHCI0 26 +#endif #define AHB_GATE_OFFSET_USB0 24 #define AHB_GATE_OFFSET_MCTL 14 #define AHB_GATE_OFFSET_GMAC 17 @@ -263,13 +273,25 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY0_RST (0x1 << 0) #define CCM_USB_CTRL_PHY1_RST (0x1 << 1) #define CCM_USB_CTRL_PHY2_RST (0x1 << 2) +#define CCM_USB_CTRL_PHY3_RST (0x1 << 3) /* There is no global phy clk gate on sun6i, define as 0 */ #define CCM_USB_CTRL_PHYGATE 0 #define CCM_USB_CTRL_PHY0_CLK (0x1 << 8) #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9) #define CCM_USB_CTRL_PHY2_CLK (0x1 << 10) +#define CCM_USB_CTRL_PHY3_CLK (0x1 << 11) +#ifdef CONFIG_MACH_SUN8I_H3 +/* + * These are OHCI1 - OHCI3 in the datasheet we call them 0 - 2 like they + * were called on older SoCs. + */ +#define CCM_USB_CTRL_OHCI0_CLK (0x1 << 17) +#define CCM_USB_CTRL_OHCI1_CLK (0x1 << 18) +#define CCM_USB_CTRL_OHCI2_CLK (0x1 << 19) +#else #define CCM_USB_CTRL_OHCI0_CLK (0x1 << 16) #define CCM_USB_CTRL_OHCI1_CLK (0x1 << 17) +#endif
#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 0cdefdc..b6e11eb 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -52,10 +52,18 @@ #define SUNXI_USB2_BASE 0x01c1c000 #endif #ifdef CONFIG_SUNXI_GEN_SUN6I +#ifdef CONFIG_MACH_SUN8I_H3 +#define SUNXI_USBPHY_BASE 0x01c19000 +#define SUNXI_USB0_BASE 0x01c1a000 +#define SUNXI_USB1_BASE 0x01c1b000 +#define SUNXI_USB2_BASE 0x01c1c000 +#define SUNXI_USB3_BASE 0x01c1d000 +#else #define SUNXI_USB0_BASE 0x01c19000 #define SUNXI_USB1_BASE 0x01c1a000 #define SUNXI_USB2_BASE 0x01c1b000 #endif +#endif #define SUNXI_CSI1_BASE 0x01c1d000 #define SUNXI_TZASC_BASE 0x01c1e000 #define SUNXI_SPI3_BASE 0x01c1f000 diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig index 358caa5..254be90 100644 --- a/configs/orangepi_pc_defconfig +++ b/configs/orangepi_pc_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig index 003a9c6..958b9fc 100644 --- a/configs/orangepi_plus_defconfig +++ b/configs/orangepi_plus_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index d494ca1..4d4e190 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -35,13 +35,12 @@ static int ehci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */ - if (hccr == (void *)SUNXI_USB1_BASE) { - priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0; - priv->phy_index = 1; - } else { - priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1; - priv->phy_index = 2; - } + priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0; +#ifdef CONFIG_MACH_SUN8I_H3 + priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_OHCI0; +#endif + priv->phy_index = ((u32)hccr - SUNXI_USB1_BASE) / 0x1000 + 1; + priv->ahb_gate_mask <<= priv->phy_index - 1;
setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); #ifdef CONFIG_SUNXI_GEN_SUN6I @@ -84,6 +83,7 @@ static const struct udevice_id ehci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ehci", }, { .compatible = "allwinner,sun8i-a23-ehci", }, { .compatible = "allwinner,sun9i-a80-ehci", }, + { .compatible = "allwinner,sun8i-h3-ehci", }, { } };
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c index 6079272..2319b3c 100644 --- a/drivers/usb/host/ohci-sunxi.c +++ b/drivers/usb/host/ohci-sunxi.c @@ -37,15 +37,14 @@ static int ohci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */ - if (regs == (void *)(SUNXI_USB1_BASE + 0x400)) { - priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0; - priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK; - priv->phy_index = 1; - } else { - priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI1; - priv->usb_gate_mask = CCM_USB_CTRL_OHCI1_CLK; - priv->phy_index = 2; - } + priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0; +#ifdef CONFIG_MACH_SUN8I_H3 + priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_EHCI0; +#endif + priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK; + priv->phy_index = ((u32)regs - (SUNXI_USB1_BASE + 0x400)) / 0x1000 + 1; + priv->ahb_gate_mask <<= priv->phy_index - 1; + priv->usb_gate_mask <<= priv->phy_index - 1;
setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); setbits_le32(&ccm->usb_clk_cfg, priv->usb_gate_mask); @@ -87,6 +86,7 @@ static const struct udevice_id ohci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ohci", }, { .compatible = "allwinner,sun8i-a23-ohci", }, { .compatible = "allwinner,sun9i-a80-ohci", }, + { .compatible = "allwinner,sun8i-h3-ohci", }, { } };
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 781ff6e..7c0ab1e 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -18,7 +18,11 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif
-#define CONFIG_SUNXI_USB_PHYS 2 +#ifdef CONFIG_MACH_SUN8I_H3 + #define CONFIG_SUNXI_USB_PHYS 4 +#else + #define CONFIG_SUNXI_USB_PHYS 2 +#endif
#ifndef CONFIG_MACH_SUN8I_A83T

Hi,
On Wed, Feb 10, 2016 at 5:25 PM, Hans de Goede hdegoede@redhat.com wrote:
From: Jelle van der Waa jelle@vdwaa.nl
Add support for phy 1-3.
Signed-off-by: Jelle van der Waa jelle@vdwaa.nl [hdegoede@redhat.com: use setclrbits_le32 instead of read-modify-write] Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/usb_phy.c | 35 +++++++++++++++++++++------ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 22 +++++++++++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 8 ++++++ configs/orangepi_pc_defconfig | 1 + configs/orangepi_plus_defconfig | 1 + drivers/usb/host/ehci-sunxi.c | 14 +++++------ drivers/usb/host/ohci-sunxi.c | 18 +++++++------- include/configs/sun8i.h | 6 ++++- 8 files changed, 81 insertions(+), 24 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index 19bb5a1..6ac96cc 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -31,6 +31,9 @@ #define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) #define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0)
+#define REG_PHY_UNK_H3 0x420 +#define REG_PMU_UNK_H3 0x810
static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus; @@ -39,19 +42,30 @@ static struct sunxi_usb_phy { int id; int init_count; int power_on_count;
int base;
} sunxi_usb_phy[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, .id = 0,
.base = SUNXI_USB0_BASE, }, { .usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK, .id = 1,
.base = SUNXI_USB1_BASE, },
#if CONFIG_SUNXI_USB_PHYS >= 3 { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .id = 2,
.base = SUNXI_USB2_BASE,
},
+#endif +#if CONFIG_SUNXI_USB_PHYS >= 4
{
.usb_rst_mask = CCM_USB_CTRL_PHY3_RST | CCM_USB_CTRL_PHY3_CLK,
.id = 3,
.base = SUNXI_USB3_BASE, }
#endif }; @@ -114,6 +128,15 @@ static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, } }
+#if defined CONFIG_MACH_SUN8I_H3 +static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) +{
if (phy->id == 0)
clrbits_le32(SUNXI_USBPHY_BASE + REG_PHY_UNK_H3, 0x01);
clrbits_le32(phy->base + REG_PMU_UNK_H3, 0x02);
+} +#else static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) { /* The following comments are machine @@ -136,16 +159,14 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy)
return;
} +#endif
-static void sunxi_usb_phy_passby(int index, int enable) +static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) { unsigned long bits = 0; void *addr;
if (index == 1)
addr = (void *)SUNXI_USB1_BASE + SUNXI_USB_PMU_IRQ_ENABLE;
else
addr = (void *)SUNXI_USB2_BASE + SUNXI_USB_PMU_IRQ_ENABLE;
addr = (void *)phy->base + SUNXI_USB_PMU_IRQ_ENABLE;
I'd suggest moving this into struct sunxi_usb_phy itself, i.e. have sunxi_usb_phy record the phy register base, instead of the whole usb controller block, kind of like what we have for the kernel sun4i-a10-usb-phy bindings. This would help with moving the phy driver to device model / DT. But it would add more modifications. It's up to you though.
bits = SUNXI_EHCI_AHB_ICHR8_EN | SUNXI_EHCI_AHB_INCR4_BURST_EN |
@@ -181,7 +202,7 @@ void sunxi_usb_phy_init(int index) sunxi_usb_phy_config(phy);
if (phy->id != 0)
sunxi_usb_phy_passby(index, SUNXI_USB_PASSBY_EN);
sunxi_usb_phy_passby(phy, SUNXI_USB_PASSBY_EN);
}
void sunxi_usb_phy_exit(int index) @@ -194,7 +215,7 @@ void sunxi_usb_phy_exit(int index) return;
if (phy->id != 0)
sunxi_usb_phy_passby(index, !SUNXI_USB_PASSBY_EN);
sunxi_usb_phy_passby(phy, !SUNXI_USB_PASSBY_EN); clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask);
} diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 554d858..1655f10 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -229,8 +229,18 @@ struct sunxi_ccm_reg { /* ahb_gate0 offsets */ #define AHB_GATE_OFFSET_USB_OHCI1 30 #define AHB_GATE_OFFSET_USB_OHCI0 29 +#ifdef CONFIG_MACH_SUN8I_H3 +/*
- These are EHCI1 - EHCI3 in the datasheet we call them 0 - 2 like they
- were called on older SoCs.
- */
Maybe mention EHCI0 / OHCI0 are for USB OTG? Helps explain the difference.
+#define AHB_GATE_OFFSET_USB_EHCI2 27 +#define AHB_GATE_OFFSET_USB_EHCI1 26 +#define AHB_GATE_OFFSET_USB_EHCI0 25 +#else #define AHB_GATE_OFFSET_USB_EHCI1 27 #define AHB_GATE_OFFSET_USB_EHCI0 26 +#endif #define AHB_GATE_OFFSET_USB0 24 #define AHB_GATE_OFFSET_MCTL 14 #define AHB_GATE_OFFSET_GMAC 17 @@ -263,13 +273,25 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY0_RST (0x1 << 0) #define CCM_USB_CTRL_PHY1_RST (0x1 << 1) #define CCM_USB_CTRL_PHY2_RST (0x1 << 2) +#define CCM_USB_CTRL_PHY3_RST (0x1 << 3) /* There is no global phy clk gate on sun6i, define as 0 */ #define CCM_USB_CTRL_PHYGATE 0 #define CCM_USB_CTRL_PHY0_CLK (0x1 << 8) #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9) #define CCM_USB_CTRL_PHY2_CLK (0x1 << 10) +#define CCM_USB_CTRL_PHY3_CLK (0x1 << 11) +#ifdef CONFIG_MACH_SUN8I_H3 +/*
- These are OHCI1 - OHCI3 in the datasheet we call them 0 - 2 like they
- were called on older SoCs.
Same here.
- */
+#define CCM_USB_CTRL_OHCI0_CLK (0x1 << 17) +#define CCM_USB_CTRL_OHCI1_CLK (0x1 << 18) +#define CCM_USB_CTRL_OHCI2_CLK (0x1 << 19) +#else #define CCM_USB_CTRL_OHCI0_CLK (0x1 << 16) #define CCM_USB_CTRL_OHCI1_CLK (0x1 << 17) +#endif
#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 0cdefdc..b6e11eb 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -52,10 +52,18 @@ #define SUNXI_USB2_BASE 0x01c1c000 #endif #ifdef CONFIG_SUNXI_GEN_SUN6I +#ifdef CONFIG_MACH_SUN8I_H3 +#define SUNXI_USBPHY_BASE 0x01c19000 +#define SUNXI_USB0_BASE 0x01c1a000 +#define SUNXI_USB1_BASE 0x01c1b000 +#define SUNXI_USB2_BASE 0x01c1c000 +#define SUNXI_USB3_BASE 0x01c1d000 +#else #define SUNXI_USB0_BASE 0x01c19000 #define SUNXI_USB1_BASE 0x01c1a000 #define SUNXI_USB2_BASE 0x01c1b000 #endif +#endif #define SUNXI_CSI1_BASE 0x01c1d000 #define SUNXI_TZASC_BASE 0x01c1e000 #define SUNXI_SPI3_BASE 0x01c1f000 diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig index 358caa5..254be90 100644 --- a/configs/orangepi_pc_defconfig +++ b/configs/orangepi_pc_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig index 003a9c6..958b9fc 100644 --- a/configs/orangepi_plus_defconfig +++ b/configs/orangepi_plus_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index d494ca1..4d4e190 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -35,13 +35,12 @@ static int ehci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */
if (hccr == (void *)SUNXI_USB1_BASE) {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0;
priv->phy_index = 1;
} else {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1;
priv->phy_index = 2;
}
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0;
+#ifdef CONFIG_MACH_SUN8I_H3
priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_OHCI0;
+#endif
priv->phy_index = ((u32)hccr - SUNXI_USB1_BASE) / 0x1000 + 1;
priv->ahb_gate_mask <<= priv->phy_index - 1; setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask);
#ifdef CONFIG_SUNXI_GEN_SUN6I @@ -84,6 +83,7 @@ static const struct udevice_id ehci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ehci", }, { .compatible = "allwinner,sun8i-a23-ehci", }, { .compatible = "allwinner,sun9i-a80-ehci", },
{ .compatible = "allwinner,sun8i-h3-ehci", },
Suggest sorting these by family first.
{ }
};
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c index 6079272..2319b3c 100644 --- a/drivers/usb/host/ohci-sunxi.c +++ b/drivers/usb/host/ohci-sunxi.c @@ -37,15 +37,14 @@ static int ohci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */
if (regs == (void *)(SUNXI_USB1_BASE + 0x400)) {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0;
priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK;
priv->phy_index = 1;
} else {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI1;
priv->usb_gate_mask = CCM_USB_CTRL_OHCI1_CLK;
priv->phy_index = 2;
}
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0;
+#ifdef CONFIG_MACH_SUN8I_H3
priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_EHCI0;
+#endif
priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK;
priv->phy_index = ((u32)regs - (SUNXI_USB1_BASE + 0x400)) / 0x1000 + 1;
priv->ahb_gate_mask <<= priv->phy_index - 1;
priv->usb_gate_mask <<= priv->phy_index - 1; setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); setbits_le32(&ccm->usb_clk_cfg, priv->usb_gate_mask);
@@ -87,6 +86,7 @@ static const struct udevice_id ohci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ohci", }, { .compatible = "allwinner,sun8i-a23-ohci", }, { .compatible = "allwinner,sun9i-a80-ohci", },
{ .compatible = "allwinner,sun8i-h3-ohci", },
And these.
FYI, I've some WIP patches for A83T USB, which I'll rebase. They still need some work and testing.
Regards ChenYu
{ }
};
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 781ff6e..7c0ab1e 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -18,7 +18,11 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif
-#define CONFIG_SUNXI_USB_PHYS 2 +#ifdef CONFIG_MACH_SUN8I_H3
#define CONFIG_SUNXI_USB_PHYS 4
+#else
#define CONFIG_SUNXI_USB_PHYS 2
+#endif
#ifndef CONFIG_MACH_SUN8I_A83T
2.5.0
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi,
On 02/14/2016 08:45 AM, Chen-Yu Tsai wrote:
Hi,
On Wed, Feb 10, 2016 at 5:25 PM, Hans de Goede hdegoede@redhat.com wrote:
From: Jelle van der Waa jelle@vdwaa.nl
Add support for phy 1-3.
Signed-off-by: Jelle van der Waa jelle@vdwaa.nl [hdegoede@redhat.com: use setclrbits_le32 instead of read-modify-write] Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/usb_phy.c | 35 +++++++++++++++++++++------ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 22 +++++++++++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 8 ++++++ configs/orangepi_pc_defconfig | 1 + configs/orangepi_plus_defconfig | 1 + drivers/usb/host/ehci-sunxi.c | 14 +++++------ drivers/usb/host/ohci-sunxi.c | 18 +++++++------- include/configs/sun8i.h | 6 ++++- 8 files changed, 81 insertions(+), 24 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index 19bb5a1..6ac96cc 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -31,6 +31,9 @@ #define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) #define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0)
+#define REG_PHY_UNK_H3 0x420 +#define REG_PMU_UNK_H3 0x810
- static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus;
@@ -39,19 +42,30 @@ static struct sunxi_usb_phy { int id; int init_count; int power_on_count;
} sunxi_usb_phy[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, .id = 0,int base;
.base = SUNXI_USB0_BASE, }, { .usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK, .id = 1,
#if CONFIG_SUNXI_USB_PHYS >= 3 { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .id = 2,.base = SUNXI_USB1_BASE, },
.base = SUNXI_USB2_BASE,
},
+#endif +#if CONFIG_SUNXI_USB_PHYS >= 4
{
.usb_rst_mask = CCM_USB_CTRL_PHY3_RST | CCM_USB_CTRL_PHY3_CLK,
.id = 3,
#endif };.base = SUNXI_USB3_BASE, }
@@ -114,6 +128,15 @@ static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, } }
+#if defined CONFIG_MACH_SUN8I_H3 +static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) +{
if (phy->id == 0)
clrbits_le32(SUNXI_USBPHY_BASE + REG_PHY_UNK_H3, 0x01);
clrbits_le32(phy->base + REG_PMU_UNK_H3, 0x02);
+} +#else static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) { /* The following comments are machine @@ -136,16 +159,14 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy)
return;
} +#endif
-static void sunxi_usb_phy_passby(int index, int enable) +static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) { unsigned long bits = 0; void *addr;
if (index == 1)
addr = (void *)SUNXI_USB1_BASE + SUNXI_USB_PMU_IRQ_ENABLE;
else
addr = (void *)SUNXI_USB2_BASE + SUNXI_USB_PMU_IRQ_ENABLE;
addr = (void *)phy->base + SUNXI_USB_PMU_IRQ_ENABLE;
I'd suggest moving this into struct sunxi_usb_phy itself, i.e. have sunxi_usb_phy record the phy register base, instead of the whole usb controller block, kind of like what we have for the kernel sun4i-a10-usb-phy bindings. This would help with moving the phy driver to device model / DT. But it would add more modifications. It's up to you though.
I think its best to keep this as is for now.
bits = SUNXI_EHCI_AHB_ICHR8_EN |
SUNXI_EHCI_AHB_INCR4_BURST_EN |
@@ -181,7 +202,7 @@ void sunxi_usb_phy_init(int index) sunxi_usb_phy_config(phy);
if (phy->id != 0)
sunxi_usb_phy_passby(index, SUNXI_USB_PASSBY_EN);
sunxi_usb_phy_passby(phy, SUNXI_USB_PASSBY_EN);
}
void sunxi_usb_phy_exit(int index)
@@ -194,7 +215,7 @@ void sunxi_usb_phy_exit(int index) return;
if (phy->id != 0)
sunxi_usb_phy_passby(index, !SUNXI_USB_PASSBY_EN);
sunxi_usb_phy_passby(phy, !SUNXI_USB_PASSBY_EN); clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask);
}
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 554d858..1655f10 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -229,8 +229,18 @@ struct sunxi_ccm_reg { /* ahb_gate0 offsets */ #define AHB_GATE_OFFSET_USB_OHCI1 30 #define AHB_GATE_OFFSET_USB_OHCI0 29 +#ifdef CONFIG_MACH_SUN8I_H3 +/*
- These are EHCI1 - EHCI3 in the datasheet we call them 0 - 2 like they
- were called on older SoCs.
- */
Maybe mention EHCI0 / OHCI0 are for USB OTG? Helps explain the difference.
Good idea, fixed.
+#define AHB_GATE_OFFSET_USB_EHCI2 27 +#define AHB_GATE_OFFSET_USB_EHCI1 26 +#define AHB_GATE_OFFSET_USB_EHCI0 25 +#else #define AHB_GATE_OFFSET_USB_EHCI1 27 #define AHB_GATE_OFFSET_USB_EHCI0 26 +#endif #define AHB_GATE_OFFSET_USB0 24 #define AHB_GATE_OFFSET_MCTL 14 #define AHB_GATE_OFFSET_GMAC 17 @@ -263,13 +273,25 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY0_RST (0x1 << 0) #define CCM_USB_CTRL_PHY1_RST (0x1 << 1) #define CCM_USB_CTRL_PHY2_RST (0x1 << 2) +#define CCM_USB_CTRL_PHY3_RST (0x1 << 3) /* There is no global phy clk gate on sun6i, define as 0 */ #define CCM_USB_CTRL_PHYGATE 0 #define CCM_USB_CTRL_PHY0_CLK (0x1 << 8) #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9) #define CCM_USB_CTRL_PHY2_CLK (0x1 << 10) +#define CCM_USB_CTRL_PHY3_CLK (0x1 << 11) +#ifdef CONFIG_MACH_SUN8I_H3 +/*
- These are OHCI1 - OHCI3 in the datasheet we call them 0 - 2 like they
- were called on older SoCs.
Same here.
- */
+#define CCM_USB_CTRL_OHCI0_CLK (0x1 << 17) +#define CCM_USB_CTRL_OHCI1_CLK (0x1 << 18) +#define CCM_USB_CTRL_OHCI2_CLK (0x1 << 19) +#else #define CCM_USB_CTRL_OHCI0_CLK (0x1 << 16) #define CCM_USB_CTRL_OHCI1_CLK (0x1 << 17) +#endif
#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 0cdefdc..b6e11eb 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -52,10 +52,18 @@ #define SUNXI_USB2_BASE 0x01c1c000 #endif #ifdef CONFIG_SUNXI_GEN_SUN6I +#ifdef CONFIG_MACH_SUN8I_H3 +#define SUNXI_USBPHY_BASE 0x01c19000 +#define SUNXI_USB0_BASE 0x01c1a000 +#define SUNXI_USB1_BASE 0x01c1b000 +#define SUNXI_USB2_BASE 0x01c1c000 +#define SUNXI_USB3_BASE 0x01c1d000 +#else #define SUNXI_USB0_BASE 0x01c19000 #define SUNXI_USB1_BASE 0x01c1a000 #define SUNXI_USB2_BASE 0x01c1b000 #endif +#endif #define SUNXI_CSI1_BASE 0x01c1d000 #define SUNXI_TZASC_BASE 0x01c1e000 #define SUNXI_SPI3_BASE 0x01c1f000 diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig index 358caa5..254be90 100644 --- a/configs/orangepi_pc_defconfig +++ b/configs/orangepi_pc_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig index 003a9c6..958b9fc 100644 --- a/configs/orangepi_plus_defconfig +++ b/configs/orangepi_plus_defconfig @@ -12,3 +12,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_USB_EHCI_HCD=y diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index d494ca1..4d4e190 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -35,13 +35,12 @@ static int ehci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */
if (hccr == (void *)SUNXI_USB1_BASE) {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0;
priv->phy_index = 1;
} else {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1;
priv->phy_index = 2;
}
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0;
+#ifdef CONFIG_MACH_SUN8I_H3
priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_OHCI0;
+#endif
priv->phy_index = ((u32)hccr - SUNXI_USB1_BASE) / 0x1000 + 1;
priv->ahb_gate_mask <<= priv->phy_index - 1; setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask);
#ifdef CONFIG_SUNXI_GEN_SUN6I
@@ -84,6 +83,7 @@ static const struct udevice_id ehci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ehci", }, { .compatible = "allwinner,sun8i-a23-ehci", }, { .compatible = "allwinner,sun9i-a80-ehci", },
{ .compatible = "allwinner,sun8i-h3-ehci", },
Suggest sorting these by family first.
Ack, fixed.
{ }
};
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c index 6079272..2319b3c 100644 --- a/drivers/usb/host/ohci-sunxi.c +++ b/drivers/usb/host/ohci-sunxi.c @@ -37,15 +37,14 @@ static int ohci_usb_probe(struct udevice *dev) * This should go away once we've moved to the driver model for * clocks resp. phys. */
if (regs == (void *)(SUNXI_USB1_BASE + 0x400)) {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0;
priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK;
priv->phy_index = 1;
} else {
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI1;
priv->usb_gate_mask = CCM_USB_CTRL_OHCI1_CLK;
priv->phy_index = 2;
}
priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0;
+#ifdef CONFIG_MACH_SUN8I_H3
priv->ahb_gate_mask |= 1 << AHB_GATE_OFFSET_USB_EHCI0;
+#endif
priv->usb_gate_mask = CCM_USB_CTRL_OHCI0_CLK;
priv->phy_index = ((u32)regs - (SUNXI_USB1_BASE + 0x400)) / 0x1000 + 1;
priv->ahb_gate_mask <<= priv->phy_index - 1;
priv->usb_gate_mask <<= priv->phy_index - 1; setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); setbits_le32(&ccm->usb_clk_cfg, priv->usb_gate_mask);
@@ -87,6 +86,7 @@ static const struct udevice_id ohci_usb_ids[] = { { .compatible = "allwinner,sun7i-a20-ohci", }, { .compatible = "allwinner,sun8i-a23-ohci", }, { .compatible = "allwinner,sun9i-a80-ohci", },
{ .compatible = "allwinner,sun8i-h3-ohci", },
And these.
FYI, I've some WIP patches for A83T USB, which I'll rebase. They still need some work and testing.
Cool.
Regards,
Hans
participants (2)
-
Chen-Yu Tsai
-
Hans de Goede