[U-Boot] [PATCH v3.2 14/58] musb-new: sunxi: Use CLK and RESET support

Now clock and reset drivers are available for respective SoC's so use clk and reset ops on musb driver.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v3.2: - add has_reset bool in existing driver data Changes for v3.1: - droped unused variables - add flags for checking reset require or not - handle clk and reset errors properly
drivers/usb/musb-new/sunxi.c | 101 ++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 32 deletions(-)
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 9f71b84fd1..6d92cf83b1 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -16,9 +16,11 @@ * This file is part of the Inventra Controller Driver for Linux. */ #include <common.h> +#include <clk.h> #include <dm.h> #include <generic-phy.h> #include <phy-sun4i-usb.h> +#include <reset.h> #include <asm/arch/cpu.h> #include <asm/arch/clock.h> #include <asm/arch/gpio.h> @@ -72,22 +74,26 @@ #define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1 #define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0
+/* flags */ +#define SUNXI_MUSB_FL_HAS_RESET 0 + /****************************************************************************** * From usbc/usbc.c ******************************************************************************/
struct sunxi_musb_config { struct musb_hdrc_config *config; - u8 rst_bit; - u8 clkgate_bit; + bool has_reset; };
struct sunxi_glue { struct musb_host_data mdata; - struct sunxi_ccm_reg *ccm; struct sunxi_musb_config *cfg; struct device dev; struct phy phy; + struct clk clk; + struct reset_ctl rst; + unsigned long flags; }; #define to_sunxi_glue(d) container_of(d, struct sunxi_glue, dev)
@@ -291,25 +297,28 @@ static int sunxi_musb_init(struct musb *musb)
pr_debug("%s():\n", __func__);
+ ret = clk_enable(&glue->clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + + if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) { + ret = reset_deassert(&glue->rst); + if (ret) { + dev_err(dev, "failed to deassert reset\n"); + goto err_clk; + } + } + ret = generic_phy_init(&glue->phy); if (ret) { pr_err("failed to init USB PHY\n"); - return ret; + goto err_rst; }
musb->isr = sunxi_musb_interrupt;
- setbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0)); - 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->rst_bit) - setbits_le32(&glue->ccm->ahb_reset0_cfg, - BIT(glue->cfg->rst_bit)); -#endif - USBC_ConfigFIFO_Base(); USBC_EnableDpDmPullUp(musb->mregs); USBC_EnableIdPullUp(musb->mregs); @@ -324,6 +333,13 @@ static int sunxi_musb_init(struct musb *musb) USBC_ForceVbusValidToHigh(musb->mregs);
return 0; + +err_rst: + if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) + reset_assert(&glue->rst); +err_clk: + clk_disable(&glue->clk); + return ret; }
static int sunxi_musb_exit(struct musb *musb) @@ -339,16 +355,19 @@ static int sunxi_musb_exit(struct musb *musb) } }
-#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)); + if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) { + ret = reset_assert(&glue->rst); + if (ret) { + dev_err(dev, "failed to deassert reset\n"); + return ret; + } + } + + ret = clk_disable(&glue->clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + }
return 0; } @@ -442,9 +461,22 @@ static int musb_usb_probe(struct udevice *dev) if (!glue->cfg) return -EINVAL;
- glue->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - if (IS_ERR(glue->ccm)) - return PTR_ERR(glue->ccm); + if (glue->cfg->has_reset) + test_and_set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags); + + ret = clk_get_by_index(dev, 0, &glue->clk); + if (ret) { + dev_err(dev, "failed to get clock\n"); + return ret; + } + + if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) { + ret = reset_get_by_index(dev, 0, &glue->rst); + if (ret) { + dev_err(dev, "failed to get reset\n"); + return ret; + } + }
ret = generic_phy_get_by_name(dev, "usb", &glue->phy); if (ret) { @@ -495,21 +527,26 @@ 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, };
static const struct sunxi_musb_config sun8i_h3_cfg = { .config = &musb_config_h3, - .rst_bit = 23, - .clkgate_bit = 23, + .has_reset = true, };
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 }, { }

Hi,
On Mon, Aug 20, 2018 at 10:02:31PM +0530, Jagan Teki wrote:
- glue->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
- if (IS_ERR(glue->ccm))
return PTR_ERR(glue->ccm);
- if (glue->cfg->has_reset)
test_and_set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
I'm not sure why the flag is needed here. It's completely redundant with the boolean you're testing to set that flag.
Maxime

On Wed, Aug 22, 2018 at 9:24 PM, Maxime Ripard maxime.ripard@bootlin.com wrote:
Hi,
On Mon, Aug 20, 2018 at 10:02:31PM +0530, Jagan Teki wrote:
glue->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
if (IS_ERR(glue->ccm))
return PTR_ERR(glue->ccm);
if (glue->cfg->has_reset)
test_and_set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
I'm not sure why the flag is needed here. It's completely redundant with the boolean you're testing to set that flag.
Since the reset is optional, set the flag for reset required SoC's instead of using reset_get_by_index_optional

On Wed, Aug 22, 2018 at 09:33:27PM +0530, Jagan Teki wrote:
On Wed, Aug 22, 2018 at 9:24 PM, Maxime Ripard maxime.ripard@bootlin.com wrote:
Hi,
On Mon, Aug 20, 2018 at 10:02:31PM +0530, Jagan Teki wrote:
glue->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
if (IS_ERR(glue->ccm))
return PTR_ERR(glue->ccm);
if (glue->cfg->has_reset)
test_and_set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
I'm not sure why the flag is needed here. It's completely redundant with the boolean you're testing to set that flag.
Since the reset is optional, set the flag for reset required SoC's instead of using reset_get_by_index_optional
Yeah, I understood the intent, but you can remove the flag and use glue->cfg->has_reset.
Maxime
participants (2)
-
Jagan Teki
-
Maxime Ripard