Message ID | 1517156391-11353-16-git-send-email-jagan@amarulasolutions.com |
---|---|
State | Changes Requested |
Delegated to: | Marek Vasut |
Headers | show |
Series | musb: sunxi: Add OTG-Peripheral support for Allwineer H3/H5/A64 | expand |
On 01/28/2018 05:19 PM, Jagan Teki wrote: > Allwinner V3/H3/H5/A64 have PHY0 dual_route, where routing happens > through EHCI/OHCI or through MUSB based id_det. id_det can be 0 and > 1 for Host and Peripheral dr_modes and it can be gpio value for OTG. > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > Cc: Marek Vasut <marex@denx.de> > --- > arch/arm/include/asm/arch-sunxi/usb_phy.h | 1 + > arch/arm/mach-sunxi/usb_phy.c | 20 ++++++++++++++++++++ > drivers/usb/musb-new/sunxi.c | 7 +++++++ > 3 files changed, 28 insertions(+) > > diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h > index 5a9cacb..e546e03 100644 > --- a/arch/arm/include/asm/arch-sunxi/usb_phy.h > +++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h > @@ -19,3 +19,4 @@ void sunxi_usb_phy_power_off(int index); > int sunxi_usb_phy_vbus_detect(int index); > int sunxi_usb_phy_id_detect(int index); > void sunxi_usb_phy_enable_squelch_detect(int index, int enable); > +void sunxi_usb_phy0_reroute(int id_det); > diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c > index a81425d..93340c7 100644 > --- a/arch/arm/mach-sunxi/usb_phy.c > +++ b/arch/arm/mach-sunxi/usb_phy.c > @@ -28,6 +28,8 @@ > #else > #define SUNXI_USB_CSR 0x410 > #endif > +#define REG_PHY_OTGCTL 0x420 > +#define OTGCTL_ROUTE_MUSB BIT(0) > > #define SUNXI_USB_PMU_IRQ_ENABLE 0x800 > #define SUNXI_USB_PASSBY_EN 1 > @@ -332,6 +334,24 @@ int sunxi_usb_phy_id_detect(int index) > return gpio_get_value(phy->gpio_id_det); > } > > +#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) || \ > + defined(CONFIG_MACH_SUN8I_V3S) > +void sunxi_usb_phy0_reroute(int id_det) Is this supposed to be bool mode ? Also, ifdefs ... use DT. > +{ > + u32 regval; > + > + regval = readl(SUNXI_USB0_BASE + REG_PHY_OTGCTL); > + if (id_det == 0) { > + /* Host mode. Route phy0 to EHCI/OHCI */ > + regval &= ~OTGCTL_ROUTE_MUSB; > + } else { > + /* Peripheral mode. Route phy0 to MUSB */ > + regval |= OTGCTL_ROUTE_MUSB; > + } > + writel(regval, SUNXI_USB0_BASE + REG_PHY_OTGCTL); > +} > +#endif > + > int sunxi_usb_phy_probe(void) > { > struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; > diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c > index d02e083..c64c551 100644 > --- a/drivers/usb/musb-new/sunxi.c > +++ b/drivers/usb/musb-new/sunxi.c > @@ -272,6 +272,13 @@ static int sunxi_musb_init(struct musb *musb) > #endif > > sunxi_usb_phy_init(0); > +#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) || \ > + defined(CONFIG_MACH_SUN8I_V3S) > + if (is_host_enabled(musb)) > + sunxi_usb_phy0_reroute(0); > + else > + sunxi_usb_phy0_reroute(1); > +#endif > > USBC_ConfigFIFO_Base(); > USBC_EnableDpDmPullUp(musb->mregs); >
diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h index 5a9cacb..e546e03 100644 --- a/arch/arm/include/asm/arch-sunxi/usb_phy.h +++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h @@ -19,3 +19,4 @@ void sunxi_usb_phy_power_off(int index); int sunxi_usb_phy_vbus_detect(int index); int sunxi_usb_phy_id_detect(int index); void sunxi_usb_phy_enable_squelch_detect(int index, int enable); +void sunxi_usb_phy0_reroute(int id_det); diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c index a81425d..93340c7 100644 --- a/arch/arm/mach-sunxi/usb_phy.c +++ b/arch/arm/mach-sunxi/usb_phy.c @@ -28,6 +28,8 @@ #else #define SUNXI_USB_CSR 0x410 #endif +#define REG_PHY_OTGCTL 0x420 +#define OTGCTL_ROUTE_MUSB BIT(0) #define SUNXI_USB_PMU_IRQ_ENABLE 0x800 #define SUNXI_USB_PASSBY_EN 1 @@ -332,6 +334,24 @@ int sunxi_usb_phy_id_detect(int index) return gpio_get_value(phy->gpio_id_det); } +#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) || \ + defined(CONFIG_MACH_SUN8I_V3S) +void sunxi_usb_phy0_reroute(int id_det) +{ + u32 regval; + + regval = readl(SUNXI_USB0_BASE + REG_PHY_OTGCTL); + if (id_det == 0) { + /* Host mode. Route phy0 to EHCI/OHCI */ + regval &= ~OTGCTL_ROUTE_MUSB; + } else { + /* Peripheral mode. Route phy0 to MUSB */ + regval |= OTGCTL_ROUTE_MUSB; + } + writel(regval, SUNXI_USB0_BASE + REG_PHY_OTGCTL); +} +#endif + int sunxi_usb_phy_probe(void) { struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index d02e083..c64c551 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -272,6 +272,13 @@ static int sunxi_musb_init(struct musb *musb) #endif sunxi_usb_phy_init(0); +#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) || \ + defined(CONFIG_MACH_SUN8I_V3S) + if (is_host_enabled(musb)) + sunxi_usb_phy0_reroute(0); + else + sunxi_usb_phy0_reroute(1); +#endif USBC_ConfigFIFO_Base(); USBC_EnableDpDmPullUp(musb->mregs);
Allwinner V3/H3/H5/A64 have PHY0 dual_route, where routing happens through EHCI/OHCI or through MUSB based id_det. id_det can be 0 and 1 for Host and Peripheral dr_modes and it can be gpio value for OTG. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Cc: Marek Vasut <marex@denx.de> --- arch/arm/include/asm/arch-sunxi/usb_phy.h | 1 + arch/arm/mach-sunxi/usb_phy.c | 20 ++++++++++++++++++++ drivers/usb/musb-new/sunxi.c | 7 +++++++ 3 files changed, 28 insertions(+)