usb: dwc3: meson-g12a: add support for GXL and GXM SoCs
In order to add support for the Amlogic GXL/GXM USB Glue, this adds the corresponding : - PHY names - clock names - USB2 PHY init and mode set - regmap setup Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
This commit is contained in:
parent
df7e374581
commit
a9fc15e0fd
|
@ -101,6 +101,11 @@
|
|||
#define PHY_COUNT 3
|
||||
#define USB2_OTG_PHY 1
|
||||
|
||||
static struct clk_bulk_data meson_gxl_clocks[] = {
|
||||
{ .id = "usb_ctrl" },
|
||||
{ .id = "ddr" },
|
||||
};
|
||||
|
||||
static struct clk_bulk_data meson_g12a_clocks[] = {
|
||||
{ .id = NULL },
|
||||
};
|
||||
|
@ -111,6 +116,10 @@ static struct clk_bulk_data meson_a1_clocks[] = {
|
|||
{ .id = "xtal_usb_ctrl" },
|
||||
};
|
||||
|
||||
static const char *meson_gxm_phy_names[] = {
|
||||
"usb2-phy0", "usb2-phy1", "usb2-phy2",
|
||||
};
|
||||
|
||||
static const char *meson_g12a_phy_names[] = {
|
||||
"usb2-phy0", "usb2-phy1", "usb3-phy0",
|
||||
};
|
||||
|
@ -145,16 +154,25 @@ struct dwc3_meson_g12a_drvdata {
|
|||
int (*usb_post_init)(struct dwc3_meson_g12a *priv);
|
||||
};
|
||||
|
||||
static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv,
|
||||
void __iomem *base);
|
||||
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
|
||||
void __iomem *base);
|
||||
|
||||
static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
|
||||
enum phy_mode mode);
|
||||
enum phy_mode mode);
|
||||
static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
|
||||
enum phy_mode mode);
|
||||
|
||||
static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv,
|
||||
int i, enum phy_mode mode);
|
||||
static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv,
|
||||
int i, enum phy_mode mode);
|
||||
|
||||
static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv);
|
||||
static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv);
|
||||
|
||||
static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv);
|
||||
|
||||
/*
|
||||
* For GXL and GXM SoCs:
|
||||
|
@ -169,6 +187,34 @@ static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv);
|
|||
* reset to recover usage of the port.
|
||||
*/
|
||||
|
||||
static struct dwc3_meson_g12a_drvdata gxl_drvdata = {
|
||||
.otg_switch_supported = true,
|
||||
.otg_phy_host_port_disable = true,
|
||||
.clks = meson_gxl_clocks,
|
||||
.num_clks = ARRAY_SIZE(meson_g12a_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_gxl_usb_init,
|
||||
.usb_post_init = dwc3_meson_gxl_usb_post_init,
|
||||
};
|
||||
|
||||
static struct dwc3_meson_g12a_drvdata gxm_drvdata = {
|
||||
.otg_switch_supported = true,
|
||||
.otg_phy_host_port_disable = true,
|
||||
.clks = meson_gxl_clocks,
|
||||
.num_clks = ARRAY_SIZE(meson_g12a_clocks),
|
||||
.phy_names = meson_gxm_phy_names,
|
||||
.num_phys = ARRAY_SIZE(meson_gxm_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_gxl_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,
|
||||
|
@ -209,6 +255,21 @@ struct dwc3_meson_g12a {
|
|||
const struct dwc3_meson_g12a_drvdata *drvdata;
|
||||
};
|
||||
|
||||
static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv,
|
||||
int i, enum phy_mode mode)
|
||||
{
|
||||
return phy_set_mode(priv->phys[i], mode);
|
||||
}
|
||||
|
||||
static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
|
||||
enum phy_mode mode)
|
||||
{
|
||||
/* On GXL PHY must be started in device mode for DWC2 init */
|
||||
return priv->drvdata->set_phy_mode(priv, i,
|
||||
(i == USB2_OTG_PHY) ? PHY_MODE_USB_DEVICE
|
||||
: PHY_MODE_USB_HOST);
|
||||
}
|
||||
|
||||
static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv,
|
||||
int i, enum phy_mode mode)
|
||||
{
|
||||
|
@ -559,6 +620,18 @@ static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv,
|
||||
void __iomem *base)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
|
||||
void __iomem *base)
|
||||
{
|
||||
|
@ -599,6 +672,25 @@ static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
|
|||
return dwc3_meson_g12a_usb_init_glue(priv, priv->otg_phy_mode);
|
||||
}
|
||||
|
||||
static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv)
|
||||
{
|
||||
return dwc3_meson_g12a_usb_init_glue(priv, PHY_MODE_USB_DEVICE);
|
||||
}
|
||||
|
||||
static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY,
|
||||
priv->otg_phy_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dwc3_meson_g12a_usb_otg_apply_mode(priv, priv->otg_phy_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_meson_g12a_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct dwc3_meson_g12a *priv;
|
||||
|
@ -830,6 +922,14 @@ static const struct dev_pm_ops dwc3_meson_g12a_dev_pm_ops = {
|
|||
};
|
||||
|
||||
static const struct of_device_id dwc3_meson_g12a_match[] = {
|
||||
{
|
||||
.compatible = "amlogic,meson-gxl-usb-ctrl",
|
||||
.data = &gxl_drvdata,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,meson-gxm-usb-ctrl",
|
||||
.data = &gxm_drvdata,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,meson-g12a-usb-ctrl",
|
||||
.data = &g12a_drvdata,
|
||||
|
|
Loading…
Reference in New Issue