[U-Boot] [PATCH v2 0/5] ti: usb (dwc3) peripheral mode fixes

Patch series enables the 2nd PHY present in DRA7 SoC so that the 2nd instance of USB DWC3 can be used in peripheral mode.
It also contains minor fixes and cleanups.
Changes from v1: Added reviewed-by and acked-by I got for the previous version
This patch series is split from [1] to contain only fixes specific to TI platforms.
[1] -> http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/229188
Kishon Vijay Abraham I (5): usb: dwc3: dwc3-omap: Use the clear register inorder to clear the interrupts ARM: DRA7: Enable clocks for USB OTGSS2 and USB PHY2 TI PHY: Add support to control 2nd USB PHY in DRA7xx/AM57xx board: ti: remove duplicate initialization of vbus_id_status include: configs: am43xx_evm: add 'usb stop' in usbboot env
arch/arm/cpu/armv7/omap5/hw_data.c | 16 +++++++++++ arch/arm/cpu/armv7/omap5/prcm-regs.c | 2 ++ arch/arm/include/asm/arch-omap5/clock.h | 3 ++ arch/arm/include/asm/omap_common.h | 2 ++ board/ti/am43xx/board.c | 2 -- board/ti/dra7xx/evm.c | 2 -- drivers/usb/dwc3/dwc3-omap.c | 46 +++++++++++++++++++------------ drivers/usb/dwc3/ti_usb_phy.c | 15 +++++++--- include/configs/am43xx_evm.h | 2 ++ 9 files changed, 64 insertions(+), 26 deletions(-)

Writing "0x00" to the USBOTGSS_IRQENABLE_SET_MISC and USBOTGSS_IRQENABLE_SET_0 doesn't disable the interrupts. Used USBOTGSS_IRQENABLE_CLR_MISC and USBOTGSS_IRQENABLE_CLR_0 instead.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Acked-by: Marek Vasut marex@denx.de Reviewed-by: Tom Rini trini@konsulko.com --- drivers/usb/dwc3/dwc3-omap.c | 46 +++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 46af109..ac9a856 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -91,6 +91,16 @@ #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL (1 << 3) #define USBOTGSS_IRQMISC_IDPULLUP_FALL (1 << 0)
+#define USBOTGSS_INTERRUPTS (USBOTGSS_IRQMISC_OEVT | \ + USBOTGSS_IRQMISC_DRVVBUS_RISE | \ + USBOTGSS_IRQMISC_CHRGVBUS_RISE | \ + USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | \ + USBOTGSS_IRQMISC_IDPULLUP_RISE | \ + USBOTGSS_IRQMISC_DRVVBUS_FALL | \ + USBOTGSS_IRQMISC_CHRGVBUS_FALL | \ + USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | \ + USBOTGSS_IRQMISC_IDPULLUP_FALL) + /* UTMI_OTG_CTRL REGISTER */ #define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5) #define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4) @@ -187,6 +197,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value) omap->irq0_offset, value); }
+static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value) +{ + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC + + omap->irqmisc_offset, value); +} + +static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value) +{ + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 - + omap->irq0_offset, value); +} + static void dwc3_omap_set_mailbox(struct dwc3_omap *omap, enum omap_dwc3_vbus_id_status status) { @@ -285,30 +307,18 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
static void dwc3_omap_enable_irqs(struct dwc3_omap *omap) { - u32 reg; - /* enable all IRQs */ - reg = USBOTGSS_IRQO_COREIRQ_ST; - dwc3_omap_write_irq0_set(omap, reg); - - reg = (USBOTGSS_IRQMISC_OEVT | - USBOTGSS_IRQMISC_DRVVBUS_RISE | - USBOTGSS_IRQMISC_CHRGVBUS_RISE | - USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | - USBOTGSS_IRQMISC_IDPULLUP_RISE | - USBOTGSS_IRQMISC_DRVVBUS_FALL | - USBOTGSS_IRQMISC_CHRGVBUS_FALL | - USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | - USBOTGSS_IRQMISC_IDPULLUP_FALL); - - dwc3_omap_write_irqmisc_set(omap, reg); + dwc3_omap_write_irq0_set(omap, USBOTGSS_IRQO_COREIRQ_ST); + + dwc3_omap_write_irqmisc_set(omap, USBOTGSS_INTERRUPTS); }
static void dwc3_omap_disable_irqs(struct dwc3_omap *omap) { /* disable all IRQs */ - dwc3_omap_write_irqmisc_set(omap, 0x00); - dwc3_omap_write_irq0_set(omap, 0x00); + dwc3_omap_write_irq0_clr(omap, USBOTGSS_IRQO_COREIRQ_ST); + + dwc3_omap_write_irqmisc_clr(omap, USBOTGSS_INTERRUPTS); }
static void dwc3_omap_map_offset(struct dwc3_omap *omap)

Enabled clocks for the second dwc3 controller and second USB PHY present in DRA7.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/cpu/armv7/omap5/hw_data.c | 16 ++++++++++++++++ arch/arm/cpu/armv7/omap5/prcm-regs.c | 2 ++ arch/arm/include/asm/arch-omap5/clock.h | 3 +++ arch/arm/include/asm/omap_common.h | 2 ++ 4 files changed, 23 insertions(+)
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c index 3a723ca..11440ac 100644 --- a/arch/arm/cpu/armv7/omap5/hw_data.c +++ b/arch/arm/cpu/armv7/omap5/hw_data.c @@ -463,6 +463,9 @@ void enable_basic_clocks(void) #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) (*prcm)->cm_l3init_ocp2scp1_clkctrl, (*prcm)->cm_l3init_usb_otg_ss1_clkctrl, +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + (*prcm)->cm_l3init_usb_otg_ss2_clkctrl, +#endif #endif 0 }; @@ -503,6 +506,19 @@ void enable_basic_clocks(void) /* Enable 32 KHz clock for dwc3 */ setbits_le32((*prcm)->cm_coreaon_usb_phy1_core_clkctrl, USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K); +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + /* Enable 960 MHz clock for dwc3 */ + setbits_le32((*prcm)->cm_l3init_usb_otg_ss2_clkctrl, + OPTFCLKEN_REFCLK960M); + + /* Enable 32 KHz clock for dwc3 */ + setbits_le32((*prcm)->cm_coreaon_usb_phy2_core_clkctrl, + USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K); + + /* Enable 60 MHz clock for USB2PHY2 */ + setbits_le32((*prcm)->cm_coreaon_l3init_60m_gfclk_clkctrl, + L3INIT_CLKCTRL_OPTFCLKEN_60M_GFCLK); +#endif #endif
/* Set the correct clock dividers for mmc */ diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c index cd51fe7..99f847b 100644 --- a/arch/arm/cpu/armv7/omap5/prcm-regs.c +++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c @@ -809,6 +809,7 @@ struct prcm_regs const dra7xx_prcm = { .cm_clkmode_dpll_gmac = 0x4a0052a8, .cm_coreaon_usb_phy1_core_clkctrl = 0x4a008640, .cm_coreaon_usb_phy2_core_clkctrl = 0x4a008688, + .cm_coreaon_l3init_60m_gfclk_clkctrl = 0x4a0086c0,
/* cm1.mpu */ .cm_mpu_mpu_clkctrl = 0x4a005320, @@ -919,6 +920,7 @@ struct prcm_regs const dra7xx_prcm = { .cm_l3init_ocp2scp1_clkctrl = 0x4a0093e0, .cm_l3init_ocp2scp3_clkctrl = 0x4a0093e8, .cm_l3init_usb_otg_ss1_clkctrl = 0x4a0093f0, + .cm_l3init_usb_otg_ss2_clkctrl = 0x4a009340,
/* cm2.l4per */ .cm_l4per_clkstctrl = 0x4a009700, diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h index f8e5630..38d50d6 100644 --- a/arch/arm/include/asm/arch-omap5/clock.h +++ b/arch/arm/include/asm/arch-omap5/clock.h @@ -172,6 +172,9 @@ /* CM_COREAON_USB_PHY_CORE_CLKCTRL */ #define USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K (1 << 8)
+/* CM_COREAON_L3INIT_60M_GFCLK_CLKCTRL */ +#define L3INIT_CLKCTRL_OPTFCLKEN_60M_GFCLK (1 << 8) + /* CM_L3INIT_USB_OTG_SS_CLKCTRL */ #define OTG_SS_CLKCTRL_MODULEMODE_HW (1 << 0) #define OPTFCLKEN_REFCLK960M (1 << 8) diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 056affc..462a9ee 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -145,6 +145,7 @@ struct prcm_regs { u32 cm_ssc_modfreqdiv_dpll_unipro; u32 cm_coreaon_usb_phy1_core_clkctrl; u32 cm_coreaon_usb_phy2_core_clkctrl; + u32 cm_coreaon_l3init_60m_gfclk_clkctrl;
/* cm2.core */ u32 cm_coreaon_bandgap_clkctrl; @@ -231,6 +232,7 @@ struct prcm_regs { u32 cm_l3init_ocp2scp1_clkctrl; u32 cm_l3init_ocp2scp3_clkctrl; u32 cm_l3init_usb_otg_ss1_clkctrl; + u32 cm_l3init_usb_otg_ss2_clkctrl;
u32 prm_irqstatus_mpu_2;

Added support to power on/power off the second USB PHY present in DRA7xx and AM57xx.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- drivers/usb/dwc3/ti_usb_phy.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/dwc3/ti_usb_phy.c b/drivers/usb/dwc3/ti_usb_phy.c index e6048eb..4159e5a 100644 --- a/drivers/usb/dwc3/ti_usb_phy.c +++ b/drivers/usb/dwc3/ti_usb_phy.c @@ -193,8 +193,11 @@ void ti_usb2_phy_power(struct ti_usb_phy *phy, int on) val = readl(phy->usb2_phy_power);
if (on) { -#ifdef CONFIG_DRA7XX - val &= ~OMAP_CTRL_DEV_PHY_PD; +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + if (phy->index == 1) + val &= ~OMAP_CTRL_USB2_PHY_PD; + else + val &= ~OMAP_CTRL_DEV_PHY_PD; #elif defined(CONFIG_AM43XX) val &= ~(AM437X_CTRL_USB2_PHY_PD | AM437X_CTRL_USB2_OTG_PD); @@ -202,8 +205,12 @@ void ti_usb2_phy_power(struct ti_usb_phy *phy, int on) AM437X_CTRL_USB2_OTGSESSEND_EN); #endif } else { -#ifdef CONFIG_DRA7XX - val |= OMAP_CTRL_DEV_PHY_PD; +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + if (phy->index == 1) + val |= OMAP_CTRL_USB2_PHY_PD; + else + val |= OMAP_CTRL_DEV_PHY_PD; + #elif defined(CONFIG_AM43XX) val &= ~(AM437X_CTRL_USB2_OTGVDET_EN | AM437X_CTRL_USB2_OTGSESSEND_EN);

vbus_id_status is initialized in board_usb_init. So remove it while creating dwc3_device objects.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- board/ti/am43xx/board.c | 2 -- board/ti/dra7xx/evm.c | 2 -- 2 files changed, 4 deletions(-)
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index d7b9e5a..1454976 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -685,7 +685,6 @@ static struct dwc3_device usb_otg_ss1 = { static struct dwc3_omap_device usb_otg_ss1_glue = { .base = (void *)USB_OTG_SS1_GLUE_BASE, .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, - .vbus_id_status = OMAP_DWC3_VBUS_VALID, .index = 0, };
@@ -704,7 +703,6 @@ static struct dwc3_device usb_otg_ss2 = { static struct dwc3_omap_device usb_otg_ss2_glue = { .base = (void *)USB_OTG_SS2_GLUE_BASE, .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, - .vbus_id_status = OMAP_DWC3_VBUS_VALID, .index = 1, };
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c index 94a1a8c..4849694 100644 --- a/board/ti/dra7xx/evm.c +++ b/board/ti/dra7xx/evm.c @@ -114,7 +114,6 @@ static struct dwc3_device usb_otg_ss1 = { static struct dwc3_omap_device usb_otg_ss1_glue = { .base = (void *)DRA7_USB_OTG_SS1_GLUE_BASE, .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, - .vbus_id_status = OMAP_DWC3_VBUS_VALID, .index = 0, };
@@ -135,7 +134,6 @@ static struct dwc3_device usb_otg_ss2 = { static struct dwc3_omap_device usb_otg_ss2_glue = { .base = (void *)DRA7_USB_OTG_SS2_GLUE_BASE, .utmi_mode = DWC3_OMAP_UTMI_MODE_SW, - .vbus_id_status = OMAP_DWC3_VBUS_VALID, .index = 1, };

The usbboot environment variable has 'usb start' command but doesn't have the corresponding 'usb stop' command. This breaks usb peripheral mode if tried after 'run usbboot' fails to load the images in usb host mode.
Fix it here by adding 'usb stop' command in usbboot env.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- include/configs/am43xx_evm.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index d148169..15fa3e3 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -292,6 +292,8 @@ "bootz ${loadaddr} - ${fdtaddr}; " \ "fi;" \ "fi\0" \ + "fi;" \ + "usb stop ${usbdev};\0" \ "findfdt="\ "if test $board_name = AM43EPOS; then " \ "setenv fdtfile am43x-epos-evm.dtb; fi; " \
participants (1)
-
Kishon Vijay Abraham I