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: 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:
Neil Armstrong 2020-03-26 14:44:58 +01:00 committed by Felipe Balbi
parent 8f5bc1ec77
commit 31306821d8

View file

@ -136,11 +136,21 @@ struct dwc3_meson_g12a_drvdata {
const char **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,
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,
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 = {
.otg_switch_supported = true,
.clks = meson_g12a_clocks,
@ -148,6 +158,8 @@ static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
.phy_names = meson_g12a_phy_names,
.num_phys = ARRAY_SIZE(meson_g12a_phy_names),
.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 = {
@ -157,6 +169,8 @@ static struct dwc3_meson_g12a_drvdata a1_drvdata = {
.phy_names = meson_a1_phy_names,
.num_phys = ARRAY_SIZE(meson_a1_phy_names),
.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 {
@ -175,8 +189,8 @@ struct dwc3_meson_g12a {
const struct dwc3_meson_g12a_drvdata *drvdata;
};
static void dwc3_meson_g12a_usb2_set_mode(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)
{
if (mode == PHY_MODE_USB_HOST)
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,
else
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
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)
{
int i;
int i, ret;
if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
priv->otg_phy_mode = PHY_MODE_USB_DEVICE;
@ -203,23 +247,9 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
if (!strstr(priv->drvdata->phy_names[i], "usb2"))
continue;
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);
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);
ret = priv->drvdata->usb2_init_phy(priv, i, priv->otg_phy_mode);
if (ret)
return ret;
}
return 0;
@ -372,7 +402,9 @@ static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
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);