aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/dwc3-meson-g12a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3/dwc3-meson-g12a.c')
-rw-r--r--drivers/usb/dwc3/dwc3-meson-g12a.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index 88b75b5a039c..417e05381b5d 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -116,23 +116,24 @@ static struct clk_bulk_data meson_a1_clocks[] = {
{ .id = "xtal_usb_ctrl" },
};
-static const char *meson_gxm_phy_names[] = {
+static const char * const meson_gxm_phy_names[] = {
"usb2-phy0", "usb2-phy1", "usb2-phy2",
};
-static const char *meson_g12a_phy_names[] = {
+static const char * const meson_g12a_phy_names[] = {
"usb2-phy0", "usb2-phy1", "usb3-phy0",
};
/*
* Amlogic A1 has a single physical PHY, in slot 1, but still has the
* two U2 PHY controls register blocks like G12A.
+ * AXG has the similar scheme, thus needs the same tweak.
* Handling the first PHY on slot 1 would need a large amount of code
* changes, and the current management is generic enough to handle it
* correctly when only the "usb2-phy1" phy is specified on-par with the
* DT bindings.
*/
-static const char *meson_a1_phy_names[] = {
+static const char * const meson_a1_phy_names[] = {
"usb2-phy0", "usb2-phy1"
};
@@ -143,7 +144,7 @@ struct dwc3_meson_g12a_drvdata {
bool otg_phy_host_port_disable;
struct clk_bulk_data *clks;
int num_clks;
- const char **phy_names;
+ const char * const *phy_names;
int num_phys;
int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base);
int (*usb2_init_phy)(struct dwc3_meson_g12a *priv, int i,
@@ -215,6 +216,19 @@ static struct dwc3_meson_g12a_drvdata gxm_drvdata = {
.usb_post_init = dwc3_meson_gxl_usb_post_init,
};
+static struct dwc3_meson_g12a_drvdata axg_drvdata = {
+ .otg_switch_supported = true,
+ .clks = meson_gxl_clocks,
+ .num_clks = ARRAY_SIZE(meson_gxl_clocks),
+ .phy_names = meson_a1_phy_names,
+ .num_phys = ARRAY_SIZE(meson_a1_phy_names),
+ .setup_regmaps = dwc3_meson_gxl_setup_regmaps,
+ .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy,
+ .set_phy_mode = dwc3_meson_gxl_set_phy_mode,
+ .usb_init = dwc3_meson_g12a_usb_init,
+ .usb_post_init = dwc3_meson_gxl_usb_post_init,
+};
+
static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
.otg_switch_supported = true,
.clks = meson_g12a_clocks,
@@ -520,11 +534,7 @@ static int dwc3_meson_g12a_role_set(struct usb_role_switch *sw,
return 0;
if (priv->drvdata->otg_phy_host_port_disable)
- dev_warn_once(priv->dev, "Manual OTG switch is broken on this "\
- "SoC, when manual switching from "\
- "Host to device, DWC3 controller "\
- "will need to be resetted in order "\
- "to recover usage of the Host port");
+ dev_warn_once(priv->dev, "Broken manual OTG switch\n");
return dwc3_meson_g12a_otg_mode_set(priv, mode);
}
@@ -626,10 +636,7 @@ static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv,
/* GXL controls the PHY mode in the PHY registers unlike G12A */
priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, base,
&phy_meson_g12a_usb_glue_regmap_conf);
- if (IS_ERR(priv->usb_glue_regmap))
- return PTR_ERR(priv->usb_glue_regmap);
-
- return 0;
+ return PTR_ERR_OR_ZERO(priv->usb_glue_regmap);
}
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
@@ -737,13 +744,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
goto err_disable_clks;
}
- ret = reset_control_deassert(priv->reset);
+ ret = reset_control_reset(priv->reset);
if (ret)
- goto err_assert_reset;
+ goto err_disable_clks;
ret = dwc3_meson_g12a_get_phys(priv);
if (ret)
- goto err_assert_reset;
+ goto err_disable_clks;
ret = priv->drvdata->setup_regmaps(priv, base);
if (ret)
@@ -752,7 +759,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
if (priv->vbus) {
ret = regulator_enable(priv->vbus);
if (ret)
- goto err_assert_reset;
+ goto err_disable_clks;
}
/* Get dr_mode */
@@ -765,13 +772,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
ret = priv->drvdata->usb_init(priv);
if (ret)
- goto err_assert_reset;
+ goto err_disable_clks;
/* Init PHYs */
for (i = 0 ; i < PHY_COUNT ; ++i) {
ret = phy_init(priv->phys[i]);
if (ret)
- goto err_assert_reset;
+ goto err_disable_clks;
}
/* Set PHY Power */
@@ -809,9 +816,6 @@ err_phys_exit:
for (i = 0 ; i < PHY_COUNT ; ++i)
phy_exit(priv->phys[i]);
-err_assert_reset:
- reset_control_assert(priv->reset);
-
err_disable_clks:
clk_bulk_disable_unprepare(priv->drvdata->num_clks,
priv->drvdata->clks);
@@ -909,8 +913,8 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
return ret;
}
- if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
- ret = regulator_enable(priv->vbus);
+ if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
+ ret = regulator_enable(priv->vbus);
if (ret)
return ret;
}
@@ -934,6 +938,10 @@ static const struct of_device_id dwc3_meson_g12a_match[] = {
.data = &gxm_drvdata,
},
{
+ .compatible = "amlogic,meson-axg-usb-ctrl",
+ .data = &axg_drvdata,
+ },
+ {
.compatible = "amlogic,meson-g12a-usb-ctrl",
.data = &g12a_drvdata,
},