Hi Marek, Thank you for the patch.
On lun., juin 17, 2024 at 19:36, Marek Vasut <marek.vasut+rene...@mailbox.org> wrote: > The current init operation also sets the PHY into USB host mode. > Split the mode configuration into set_mode callback instead and > implement support for device and OTG modes as well. > > The OTG mode performs auto-detection and selects either host or > device mode. In case the OTG mode is configured, submode field > can be used to select full PHY (re)initialization or only mode > auto-detection. The full (re)initialization is only necessary > once, on start up. > > Since the OTG mode may enable IRQ generation in the PHY, disable > that IRQ generation in the exit callback again. > > Signed-off-by: Marek Vasut <marek.vasut+rene...@mailbox.org> Reviewed-by: Mattijs Korpershoek <mkorpersh...@baylibre.com> > --- > Cc: Caleb Connolly <caleb.conno...@linaro.org> > Cc: Fabio Estevam <feste...@gmail.com> > Cc: Fabrice Gasnier <fabrice.gasn...@foss.st.com> > Cc: Jonas Karlman <jo...@kwiboo.se> > Cc: Mathieu Othacehe <othac...@gnu.org> > Cc: Mattijs Korpershoek <mkorpersh...@baylibre.com> > Cc: Neil Armstrong <neil.armstr...@linaro.org> > Cc: Nishanth Menon <n...@ti.com> > Cc: Nobuhiro Iwamatsu <iwama...@nigauri.org> > Cc: Sean Anderson <sean...@gmail.com> > Cc: Simon Glass <s...@chromium.org> > Cc: Sumit Garg <sumit.g...@linaro.org> > Cc: Tim Harvey <thar...@gateworks.com> > Cc: Tom Rini <tr...@konsulko.com> > Cc: Xavier Drudis Ferran <xdru...@tinet.cat> > Cc: u-boot-q...@groups.io > Cc: u-boot@lists.denx.de > --- > V2: No change > --- > drivers/phy/phy-rcar-gen3.c | 90 ++++++++++++++++++++++++++++++++++--- > 1 file changed, 85 insertions(+), 5 deletions(-) > > diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c > index 7c292cae0e2..b278f995f37 100644 > --- a/drivers/phy/phy-rcar-gen3.c > +++ b/drivers/phy/phy-rcar-gen3.c > @@ -8,6 +8,7 @@ > #include <clk.h> > #include <div64.h> > #include <dm.h> > +#include <dm/device_compat.h> > #include <fdtdec.h> > #include <generic-phy.h> > #include <malloc.h> > @@ -31,8 +32,13 @@ > #define USB2_LINECTRL1 0x610 > #define USB2_ADPCTRL 0x630 > > +/* INT_ENABLE */ > +#define USB2_INT_ENABLE_UCOM_INTEN BIT(3) > +#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) > +#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) > + > /* USBCTR */ > -#define USB2_USBCTR_PLL_RST BIT(1) > +#define USB2_USBCTR_PLL_RST BIT(1) > > /* SPD_RSM_TIMSET */ > #define USB2_SPD_RSM_TIMSET_INIT 0x014e029b > @@ -43,11 +49,23 @@ > /* COMMCTRL */ > #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode > */ > > +/* OBINTSTA and OBINTEN */ > +#define USB2_OBINT_SESSVLDCHG BIT(12) > +#define USB2_OBINT_IDDIGCHG BIT(11) > + > +/* VBCTRL */ > +#define USB2_VBCTRL_DRVVBUSSEL BIT(8) > + > /* LINECTRL1 */ > +#define USB2_LINECTRL1_DPRPD_EN BIT(19) > #define USB2_LINECTRL1_DP_RPD BIT(18) > +#define USB2_LINECTRL1_DMRPD_EN BIT(17) > #define USB2_LINECTRL1_DM_RPD BIT(16) > > /* ADPCTRL */ > +#define USB2_ADPCTRL_OTGSESSVLD BIT(20) > +#define USB2_ADPCTRL_IDDIG BIT(19) > +#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is > enabled */ > #define USB2_ADPCTRL_DRVVBUS BIT(4) > > struct rcar_gen3_phy { > @@ -65,12 +83,14 @@ static int rcar_gen3_phy_phy_init(struct phy *phy) > writel(USB2_SPD_RSM_TIMSET_INIT, priv->regs + USB2_SPD_RSM_TIMSET); > writel(USB2_OC_TIMSET_INIT, priv->regs + USB2_OC_TIMSET); > > - setbits_le32(priv->regs + USB2_LINECTRL1, > - USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD); > + return 0; > +} > > - clrbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI); > +static int rcar_gen3_phy_phy_exit(struct phy *phy) > +{ > + struct rcar_gen3_phy *priv = dev_get_priv(phy->dev); > > - setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS); > + writel(0, priv->regs + USB2_INT_ENABLE); > > return 0; > } > @@ -102,10 +122,70 @@ static int rcar_gen3_phy_phy_power_off(struct phy *phy) > return regulator_set_enable(priv->vbus_supply, false); > } > > +static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode, > + int submode) > +{ > + const u32 adpdevmask = USB2_ADPCTRL_IDDIG | USB2_ADPCTRL_OTGSESSVLD; > + struct rcar_gen3_phy *priv = dev_get_priv(phy->dev); > + u32 adpctrl; > + > + if (mode == PHY_MODE_USB_OTG) { > + if (submode) { > + /* OTG submode is used as initialization indicator */ > + writel(USB2_INT_ENABLE_UCOM_INTEN | > + USB2_INT_ENABLE_USBH_INTB_EN | > + USB2_INT_ENABLE_USBH_INTA_EN, > + priv->regs + USB2_INT_ENABLE); > + setbits_le32(priv->regs + USB2_VBCTRL, > + USB2_VBCTRL_DRVVBUSSEL); > + writel(USB2_OBINT_SESSVLDCHG | USB2_OBINT_IDDIGCHG, > + priv->regs + USB2_OBINTSTA); > + setbits_le32(priv->regs + USB2_OBINTEN, > + USB2_OBINT_SESSVLDCHG | > + USB2_OBINT_IDDIGCHG); > + setbits_le32(priv->regs + USB2_ADPCTRL, > + USB2_ADPCTRL_IDPULLUP); > + clrsetbits_le32(priv->regs + USB2_LINECTRL1, > + USB2_LINECTRL1_DP_RPD | > + USB2_LINECTRL1_DM_RPD | > + USB2_LINECTRL1_DPRPD_EN | > + USB2_LINECTRL1_DMRPD_EN, > + USB2_LINECTRL1_DPRPD_EN | > + USB2_LINECTRL1_DMRPD_EN); > + } > + > + adpctrl = readl(priv->regs + USB2_ADPCTRL); > + if ((adpctrl & adpdevmask) == adpdevmask) > + mode = PHY_MODE_USB_DEVICE; > + else > + mode = PHY_MODE_USB_HOST; > + } > + > + if (mode == PHY_MODE_USB_HOST) { > + clrbits_le32(priv->regs + USB2_COMMCTRL, > USB2_COMMCTRL_OTG_PERI); > + setbits_le32(priv->regs + USB2_LINECTRL1, > + USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD); > + setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS); > + } else if (mode == PHY_MODE_USB_DEVICE) { > + setbits_le32(priv->regs + USB2_COMMCTRL, > USB2_COMMCTRL_OTG_PERI); > + clrsetbits_le32(priv->regs + USB2_LINECTRL1, > + USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD, > + USB2_LINECTRL1_DM_RPD); > + clrbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS); > + } else { > + dev_err(phy->dev, "Unknown mode %d\n", mode); > + return -EINVAL; > + } > + > + return 0; > +} > + > static const struct phy_ops rcar_gen3_phy_phy_ops = { > .init = rcar_gen3_phy_phy_init, > + .exit = rcar_gen3_phy_phy_exit, > .power_on = rcar_gen3_phy_phy_power_on, > .power_off = rcar_gen3_phy_phy_power_off, > + .set_mode = rcar_gen3_phy_phy_set_mode, > }; > > static int rcar_gen3_phy_probe(struct udevice *dev) > -- > 2.43.0