Commit 31306821 authored by Neil Armstrong's avatar Neil Armstrong Committed by Felipe Balbi

usb: dwc3: meson-g12a: refactor usb2 phy init

Refactor the USB2 PHY init code patch to handle the Amlogic GXL/GXM
not having the PHY mode control registers in the Glue but in the PHY
registers.

The Amlogic GXL/GXM will call phy_set_mode() instead of programming the
PHY mode control registers, thus add two new callbacks to the SoC match
data.
Reviewed-by: default avatarMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
parent 8f5bc1ec
...@@ -136,11 +136,21 @@ struct dwc3_meson_g12a_drvdata { ...@@ -136,11 +136,21 @@ struct dwc3_meson_g12a_drvdata {
const char **phy_names; const char **phy_names;
int num_phys; int num_phys;
int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base); int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base);
int (*usb2_init_phy)(struct dwc3_meson_g12a *priv, int i,
enum phy_mode mode);
int (*set_phy_mode)(struct dwc3_meson_g12a *priv, int i,
enum phy_mode mode);
}; };
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv, static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
void __iomem *base); void __iomem *base);
static int dwc3_meson_g12a_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 struct dwc3_meson_g12a_drvdata g12a_drvdata = { static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
.otg_switch_supported = true, .otg_switch_supported = true,
.clks = meson_g12a_clocks, .clks = meson_g12a_clocks,
...@@ -148,6 +158,8 @@ static struct dwc3_meson_g12a_drvdata g12a_drvdata = { ...@@ -148,6 +158,8 @@ static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
.phy_names = meson_g12a_phy_names, .phy_names = meson_g12a_phy_names,
.num_phys = ARRAY_SIZE(meson_g12a_phy_names), .num_phys = ARRAY_SIZE(meson_g12a_phy_names),
.setup_regmaps = dwc3_meson_g12a_setup_regmaps, .setup_regmaps = dwc3_meson_g12a_setup_regmaps,
.usb2_init_phy = dwc3_meson_g12a_usb2_init_phy,
.set_phy_mode = dwc3_meson_g12a_set_phy_mode,
}; };
static struct dwc3_meson_g12a_drvdata a1_drvdata = { static struct dwc3_meson_g12a_drvdata a1_drvdata = {
...@@ -157,6 +169,8 @@ static struct dwc3_meson_g12a_drvdata a1_drvdata = { ...@@ -157,6 +169,8 @@ static struct dwc3_meson_g12a_drvdata a1_drvdata = {
.phy_names = meson_a1_phy_names, .phy_names = meson_a1_phy_names,
.num_phys = ARRAY_SIZE(meson_a1_phy_names), .num_phys = ARRAY_SIZE(meson_a1_phy_names),
.setup_regmaps = dwc3_meson_g12a_setup_regmaps, .setup_regmaps = dwc3_meson_g12a_setup_regmaps,
.usb2_init_phy = dwc3_meson_g12a_usb2_init_phy,
.set_phy_mode = dwc3_meson_g12a_set_phy_mode,
}; };
struct dwc3_meson_g12a { struct dwc3_meson_g12a {
...@@ -175,8 +189,8 @@ struct dwc3_meson_g12a { ...@@ -175,8 +189,8 @@ struct dwc3_meson_g12a {
const struct dwc3_meson_g12a_drvdata *drvdata; const struct dwc3_meson_g12a_drvdata *drvdata;
}; };
static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv, static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv,
int i, enum phy_mode mode) int i, enum phy_mode mode)
{ {
if (mode == PHY_MODE_USB_HOST) if (mode == PHY_MODE_USB_HOST)
regmap_update_bits(priv->u2p_regmap[i], U2P_R0, regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
...@@ -185,11 +199,41 @@ static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv, ...@@ -185,11 +199,41 @@ static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
else else
regmap_update_bits(priv->u2p_regmap[i], U2P_R0, regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_HOST_DEVICE, 0); U2P_R0_HOST_DEVICE, 0);
return 0;
}
static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
enum phy_mode mode)
{
int ret;
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);
if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
ret = priv->drvdata->set_phy_mode(priv, i, mode);
} else
ret = priv->drvdata->set_phy_mode(priv, i,
PHY_MODE_USB_HOST);
if (ret)
return ret;
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_POWER_ON_RESET, 0);
return 0;
} }
static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv) static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
{ {
int i; int i, ret;
if (priv->otg_mode == USB_DR_MODE_PERIPHERAL) if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
priv->otg_phy_mode = PHY_MODE_USB_DEVICE; priv->otg_phy_mode = PHY_MODE_USB_DEVICE;
...@@ -203,23 +247,9 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv) ...@@ -203,23 +247,9 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
if (!strstr(priv->drvdata->phy_names[i], "usb2")) if (!strstr(priv->drvdata->phy_names[i], "usb2"))
continue; continue;
regmap_update_bits(priv->u2p_regmap[i], U2P_R0, ret = priv->drvdata->usb2_init_phy(priv, i, priv->otg_phy_mode);
U2P_R0_POWER_ON_RESET, if (ret)
U2P_R0_POWER_ON_RESET); return ret;
if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
dwc3_meson_g12a_usb2_set_mode(priv, i,
priv->otg_phy_mode);
} else
dwc3_meson_g12a_usb2_set_mode(priv, i,
PHY_MODE_USB_HOST);
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_POWER_ON_RESET, 0);
} }
return 0; return 0;
...@@ -372,7 +402,9 @@ static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv, ...@@ -372,7 +402,9 @@ static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
priv->otg_phy_mode = mode; priv->otg_phy_mode = mode;
dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode); ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, mode);
if (ret)
return ret;
dwc3_meson_g12a_usb_otg_apply_mode(priv); dwc3_meson_g12a_usb_otg_apply_mode(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment