diff options
-rw-r--r-- | board/compulab/cm_t3517/cm_t3517.c | 4 | ||||
-rw-r--r-- | drivers/usb/musb-new/musb_core.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb-new/musb_uboot.c | 12 | ||||
-rw-r--r-- | drivers/usb/musb-new/pic32.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb-new/sunxi.c | 107 | ||||
-rw-r--r-- | include/linux/usb/musb.h | 4 |
6 files changed, 80 insertions, 54 deletions
diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c index 09cb27def0..668bb7631a 100644 --- a/board/compulab/cm_t3517/cm_t3517.c +++ b/board/compulab/cm_t3517/cm_t3517.c @@ -74,8 +74,8 @@ static void cm_t3517_musb_init(void) CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN | CONF2_DATPOL); - if (musb_register(&cm_t3517_musb_pdata, &cm_t3517_musb_board_data, - (void *)AM35XX_IPSS_USBOTGSS_BASE)) + if (!musb_register(&cm_t3517_musb_pdata, &cm_t3517_musb_board_data, + (void *)AM35XX_IPSS_USBOTGSS_BASE)) printf("Failed initializing AM35x MUSB!\n"); } #else diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c index 8fec6f38ad..afea9fbcef 100644 --- a/drivers/usb/musb-new/musb_core.c +++ b/drivers/usb/musb-new/musb_core.c @@ -1007,6 +1007,7 @@ void musb_stop(struct musb *musb) * - ... */ musb_platform_try_idle(musb, 0); + musb_platform_exit(musb); } #ifndef __UBOOT__ diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index 2b04fbd046..2bf918eab4 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -419,8 +419,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) } #endif /* CONFIG_USB_MUSB_GADGET */ -int musb_register(struct musb_hdrc_platform_data *plat, void *bdata, - void *ctl_regs) +struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata, + void *ctl_regs) { struct musb **musbp; @@ -436,14 +436,14 @@ int musb_register(struct musb_hdrc_platform_data *plat, void *bdata, break; #endif default: - return -EINVAL; + return ERR_PTR(-EINVAL); } *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs); - if (!*musbp) { + if (IS_ERR(*musbp)) { printf("Failed to init the controller\n"); - return -EIO; + return ERR_CAST(*musbp); } - return 0; + return *musbp; } diff --git a/drivers/usb/musb-new/pic32.c b/drivers/usb/musb-new/pic32.c index f04719d7af..3a19900e21 100644 --- a/drivers/usb/musb-new/pic32.c +++ b/drivers/usb/musb-new/pic32.c @@ -251,9 +251,11 @@ static int musb_usb_probe(struct udevice *dev) ret = musb_lowlevel_init(mdata); #else pic32_musb_plat.mode = MUSB_PERIPHERAL; - ret = musb_register(&pic32_musb_plat, &pdata->dev, mregs); + mdata->host = musb_register(&pic32_musb_plat, &pdata->dev, mregs); + if (!mdata->host) + return -EIO; #endif - if (ret == 0) + if ((ret == 0) && mdata->host) printf("PIC32 MUSB OTG\n"); return ret; diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 08de9c69c7..6cf9826cda 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -76,18 +76,23 @@ * From usbc/usbc.c ******************************************************************************/ +#define OFF_SUN6I_AHB_RESET0 0x2c0 + struct sunxi_musb_config { struct musb_hdrc_config *config; + bool has_reset; u8 rst_bit; u8 clkgate_bit; + u32 off_reset0; }; struct sunxi_glue { struct musb_host_data mdata; struct sunxi_ccm_reg *ccm; + u32 *reg_reset0; struct sunxi_musb_config *cfg; struct device dev; - struct phy *phy; + struct phy phy; }; #define to_sunxi_glue(d) container_of(d, struct sunxi_glue, dev) @@ -235,19 +240,19 @@ static int sunxi_musb_enable(struct musb *musb) musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0); if (is_host_enabled(musb)) { - ret = sun4i_usb_phy_vbus_detect(glue->phy); + ret = sun4i_usb_phy_vbus_detect(&glue->phy); if (ret == 1) { printf("A charger is plugged into the OTG: "); return -ENODEV; } - ret = sun4i_usb_phy_id_detect(glue->phy); + ret = sun4i_usb_phy_id_detect(&glue->phy); if (ret == 1) { printf("No host cable detected: "); return -ENODEV; } - ret = generic_phy_power_on(glue->phy); + ret = generic_phy_power_on(&glue->phy); if (ret) { pr_err("failed to power on USB PHY\n"); return ret; @@ -271,7 +276,7 @@ static void sunxi_musb_disable(struct musb *musb) return; if (is_host_enabled(musb)) { - ret = generic_phy_power_off(glue->phy); + ret = generic_phy_power_off(&glue->phy); if (ret) { pr_err("failed to power off USB PHY\n"); return; @@ -291,7 +296,7 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); - ret = generic_phy_init(glue->phy); + ret = generic_phy_init(&glue->phy); if (ret) { pr_err("failed to init USB PHY\n"); return ret; @@ -303,12 +308,12 @@ static int sunxi_musb_init(struct musb *musb) if (glue->cfg->clkgate_bit) setbits_le32(&glue->ccm->ahb_gate0, BIT(glue->cfg->clkgate_bit)); -#ifdef CONFIG_SUNXI_GEN_SUN6I - setbits_le32(&glue->ccm->ahb_reset0_cfg, BIT(AHB_GATE_OFFSET_USB0)); + + if (glue->cfg->has_reset) + setbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0)); + if (glue->cfg->rst_bit) - setbits_le32(&glue->ccm->ahb_reset0_cfg, - BIT(glue->cfg->rst_bit)); -#endif + setbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit)); USBC_ConfigFIFO_Base(); USBC_EnableDpDmPullUp(musb->mregs); @@ -326,22 +331,50 @@ static int sunxi_musb_init(struct musb *musb) return 0; } +static int sunxi_musb_exit(struct musb *musb) +{ + struct sunxi_glue *glue = to_sunxi_glue(musb->controller); + int ret = 0; + + if (generic_phy_valid(&glue->phy)) { + ret = generic_phy_exit(&glue->phy); + if (ret) { + dev_err(dev, "failed to power off usb phy\n"); + return ret; + } + } + + if (glue->cfg->has_reset) + clrbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0)); + + if (glue->cfg->rst_bit) + clrbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit)); + + clrbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0)); + if (glue->cfg->clkgate_bit) + clrbits_le32(&glue->ccm->ahb_gate0, + BIT(glue->cfg->clkgate_bit)); + + return 0; +} + static void sunxi_musb_pre_root_reset_end(struct musb *musb) { struct sunxi_glue *glue = to_sunxi_glue(musb->controller); - sun4i_usb_phy_set_squelch_detect(glue->phy, false); + sun4i_usb_phy_set_squelch_detect(&glue->phy, false); } static void sunxi_musb_post_root_reset_end(struct musb *musb) { struct sunxi_glue *glue = to_sunxi_glue(musb->controller); - sun4i_usb_phy_set_squelch_detect(glue->phy, true); + sun4i_usb_phy_set_squelch_detect(&glue->phy, true); } static const struct musb_platform_ops sunxi_musb_ops = { .init = sunxi_musb_init, + .exit = sunxi_musb_exit, .enable = sunxi_musb_enable, .disable = sunxi_musb_disable, .pre_root_reset_end = sunxi_musb_pre_root_reset_end, @@ -405,7 +438,6 @@ static int musb_usb_probe(struct udevice *dev) struct usb_bus_priv *priv = dev_get_uclass_priv(dev); struct musb_hdrc_platform_data pdata; void *base = dev_read_addr_ptr(dev); - struct phy phy; int ret; if (!base) @@ -419,13 +451,14 @@ static int musb_usb_probe(struct udevice *dev) if (IS_ERR(glue->ccm)) return PTR_ERR(glue->ccm); - ret = generic_phy_get_by_name(dev, "usb", &phy); + glue->reg_reset0 = (void *)glue->ccm + glue->cfg->off_reset0; + + ret = generic_phy_get_by_name(dev, "usb", &glue->phy); if (ret) { pr_err("failed to get usb PHY\n"); return ret; } - glue->phy = &phy; priv->desc_before_addr = true; memset(&pdata, 0, sizeof(pdata)); @@ -444,9 +477,11 @@ static int musb_usb_probe(struct udevice *dev) printf("Allwinner mUSB OTG (Host)\n"); #else pdata.mode = MUSB_PERIPHERAL; - ret = musb_register(&pdata, &glue->dev, base); - if (!ret) - printf("Allwinner mUSB OTG (Peripheral)\n"); + host->host = musb_register(&pdata, &glue->dev, base); + if (!host->host) + return -EIO; + + printf("Allwinner mUSB OTG (Peripheral)\n"); #endif return ret; @@ -456,29 +491,8 @@ static int musb_usb_remove(struct udevice *dev) { struct sunxi_glue *glue = dev_get_priv(dev); struct musb_host_data *host = &glue->mdata; - int ret; - - if (generic_phy_valid(glue->phy)) { - ret = generic_phy_exit(glue->phy); - if (ret) { - pr_err("failed to exit %s USB PHY\n", dev->name); - return ret; - } - } musb_stop(host->host); - -#ifdef CONFIG_SUNXI_GEN_SUN6I - clrbits_le32(&glue->ccm->ahb_reset0_cfg, BIT(AHB_GATE_OFFSET_USB0)); - if (glue->cfg->rst_bit) - clrbits_le32(&glue->ccm->ahb_reset0_cfg, - BIT(glue->cfg->rst_bit)); -#endif - clrbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0)); - if (glue->cfg->clkgate_bit) - clrbits_le32(&glue->ccm->ahb_gate0, - BIT(glue->cfg->clkgate_bit)); - free(host->host); host->host = NULL; @@ -487,21 +501,30 @@ static int musb_usb_remove(struct udevice *dev) static const struct sunxi_musb_config sun4i_a10_cfg = { .config = &musb_config, + .has_reset = false, +}; + +static const struct sunxi_musb_config sun6i_a31_cfg = { + .config = &musb_config, + .has_reset = true, + .off_reset0 = OFF_SUN6I_AHB_RESET0, }; static const struct sunxi_musb_config sun8i_h3_cfg = { .config = &musb_config_h3, + .has_reset = true, .rst_bit = 23, .clkgate_bit = 23, + .off_reset0 = OFF_SUN6I_AHB_RESET0, }; static const struct udevice_id sunxi_musb_ids[] = { { .compatible = "allwinner,sun4i-a10-musb", .data = (ulong)&sun4i_a10_cfg }, { .compatible = "allwinner,sun6i-a31-musb", - .data = (ulong)&sun4i_a10_cfg }, + .data = (ulong)&sun6i_a31_cfg }, { .compatible = "allwinner,sun8i-a33-musb", - .data = (ulong)&sun4i_a10_cfg }, + .data = (ulong)&sun6i_a31_cfg }, { .compatible = "allwinner,sun8i-h3-musb", .data = (ulong)&sun8i_h3_cfg }, { } diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 9104414cf0..a31ce67a81 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -150,7 +150,7 @@ extern int tusb6010_platform_retime(unsigned is_refclk); /* * U-Boot specfic stuff */ -int musb_register(struct musb_hdrc_platform_data *plat, void *bdata, - void *ctl_regs); +struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata, + void *ctl_regs); #endif /* __LINUX_USB_MUSB_H */ |