Message ID | 7407d9e557bfce2a5541fd002d36c15a041c0cc2.1748461536.git.dan.carpenter@linaro.org |
---|---|
State | New |
Headers | show |
Series | usb: chipidea: Add support for s32g2 and s32g3 | expand |
On Wed, May 28, 2025 at 10:57:27PM +0300, Dan Carpenter wrote: > From: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com> > > Enable USB driver for s32g2. > > Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com> > Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> > --- > drivers/usb/chipidea/ci_hdrc_imx.c | 6 +++ > drivers/usb/chipidea/usbmisc_imx.c | 69 ++++++++++++++++++++++++++++++ > 2 files changed, 75 insertions(+) > > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c > index 780f4d151345..ce207f8566d5 100644 > --- a/drivers/usb/chipidea/ci_hdrc_imx.c > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0+ > /* > * Copyright 2012 Freescale Semiconductor, Inc. > + * Copyright 2020 NXP 2025? Frank > * Copyright (C) 2012 Marek Vasut <marex@denx.de> > * on behalf of DENX Software Engineering GmbH > */ > @@ -78,6 +79,10 @@ static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { > CI_HDRC_HAS_PORTSC_PEC_MISSED, > }; > > +static const struct ci_hdrc_imx_platform_flag s32g_usb_data = { > + .flags = CI_HDRC_DISABLE_HOST_STREAMING, > +}; > + > static const struct of_device_id ci_hdrc_imx_dt_ids[] = { > { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, > { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, > @@ -89,6 +94,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = { > { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, > { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data}, > { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data}, > + { .compatible = "nxp,s32g2-usb", .data = &s32g_usb_data}, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); > diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c > index 95759a4ec60c..43098a150e83 100644 > --- a/drivers/usb/chipidea/usbmisc_imx.c > +++ b/drivers/usb/chipidea/usbmisc_imx.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0+ > /* > * Copyright 2012 Freescale Semiconductor, Inc. > + * Copyright 2020 NXP > */ > > #include <linux/module.h> > @@ -158,6 +159,18 @@ > /* Flags for 'struct imx_usbmisc' */ > #define REINIT_DURING_RESUME BIT(1) > > +#define S32G_WAKEUP_IE BIT(0) > +#define S32G_CORE_IE BIT(1) > +#define S32G_PWRFLTEN BIT(7) > +#define S32G_WAKEUPCTRL BIT(10) > +#define S32G_WAKEUPEN BIT(11) > + > +/* Workaround errata ERR050474 (handle packages that aren't 4 byte aligned) */ > +#define S32G_UCMALLBE BIT(15) > + > +#define S32G_WAKEUP_BITS (S32G_WAKEUP_IE | S32G_CORE_IE | S32G_WAKEUPEN | \ > + S32G_WAKEUPCTRL) > + > struct usbmisc_ops { > /* It's called once when probe a usb device */ > int (*init)(struct imx_usbmisc_data *data); > @@ -618,6 +631,52 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data) > return 0; > } > > +static int usbmisc_s32g_set_wakeup(struct imx_usbmisc_data *data, bool enabled) > +{ > + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > + unsigned long flags; > + u32 reg; > + > + spin_lock_irqsave(&usbmisc->lock, flags); > + > + reg = readl(usbmisc->base); > + if (enabled) > + reg |= S32G_WAKEUP_BITS; > + else > + reg &= ~S32G_WAKEUP_BITS; > + > + writel(reg, usbmisc->base); > + spin_unlock_irqrestore(&usbmisc->lock, flags); > + > + return 0; > +} > + > +static int usbmisc_s32g_init(struct imx_usbmisc_data *data, u32 extra_flags) > +{ > + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > + unsigned long flags; > + u32 reg; > + > + spin_lock_irqsave(&usbmisc->lock, flags); > + > + reg = readl(usbmisc->base); > + > + reg |= S32G_PWRFLTEN; > + reg |= extra_flags; > + > + writel(reg, usbmisc->base); > + > + spin_unlock_irqrestore(&usbmisc->lock, flags); > + usbmisc_s32g_set_wakeup(data, false); > + > + return 0; > +} > + > +static int usbmisc_s32g2_init(struct imx_usbmisc_data *data) > +{ > + return usbmisc_s32g_init(data, S32G_UCMALLBE); > +} > + > static int usbmisc_imx7d_set_wakeup > (struct imx_usbmisc_data *data, bool enabled) > { > @@ -1135,6 +1194,12 @@ static const struct usbmisc_ops imx95_usbmisc_ops = { > .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, > }; > > +static const struct usbmisc_ops s32g2_usbmisc_ops = { > + .init = usbmisc_s32g2_init, > + .set_wakeup = usbmisc_s32g_set_wakeup, > + .flags = REINIT_DURING_RESUME, > +}; > + > static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) > { > struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > @@ -1363,6 +1428,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { > .compatible = "fsl,imx95-usbmisc", > .data = &imx95_usbmisc_ops, > }, > + { > + .compatible = "nxp,s32g2-usbmisc", > + .data = &s32g2_usbmisc_ops, > + }, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); > -- > 2.47.2 >
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 780f4d151345..ce207f8566d5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2020 NXP * Copyright (C) 2012 Marek Vasut <marex@denx.de> * on behalf of DENX Software Engineering GmbH */ @@ -78,6 +79,10 @@ static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { CI_HDRC_HAS_PORTSC_PEC_MISSED, }; +static const struct ci_hdrc_imx_platform_flag s32g_usb_data = { + .flags = CI_HDRC_DISABLE_HOST_STREAMING, +}; + static const struct of_device_id ci_hdrc_imx_dt_ids[] = { { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, @@ -89,6 +94,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = { { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data}, { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data}, + { .compatible = "nxp,s32g2-usb", .data = &s32g_usb_data}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 95759a4ec60c..43098a150e83 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2020 NXP */ #include <linux/module.h> @@ -158,6 +159,18 @@ /* Flags for 'struct imx_usbmisc' */ #define REINIT_DURING_RESUME BIT(1) +#define S32G_WAKEUP_IE BIT(0) +#define S32G_CORE_IE BIT(1) +#define S32G_PWRFLTEN BIT(7) +#define S32G_WAKEUPCTRL BIT(10) +#define S32G_WAKEUPEN BIT(11) + +/* Workaround errata ERR050474 (handle packages that aren't 4 byte aligned) */ +#define S32G_UCMALLBE BIT(15) + +#define S32G_WAKEUP_BITS (S32G_WAKEUP_IE | S32G_CORE_IE | S32G_WAKEUPEN | \ + S32G_WAKEUPCTRL) + struct usbmisc_ops { /* It's called once when probe a usb device */ int (*init)(struct imx_usbmisc_data *data); @@ -618,6 +631,52 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data) return 0; } +static int usbmisc_s32g_set_wakeup(struct imx_usbmisc_data *data, bool enabled) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&usbmisc->lock, flags); + + reg = readl(usbmisc->base); + if (enabled) + reg |= S32G_WAKEUP_BITS; + else + reg &= ~S32G_WAKEUP_BITS; + + writel(reg, usbmisc->base); + spin_unlock_irqrestore(&usbmisc->lock, flags); + + return 0; +} + +static int usbmisc_s32g_init(struct imx_usbmisc_data *data, u32 extra_flags) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&usbmisc->lock, flags); + + reg = readl(usbmisc->base); + + reg |= S32G_PWRFLTEN; + reg |= extra_flags; + + writel(reg, usbmisc->base); + + spin_unlock_irqrestore(&usbmisc->lock, flags); + usbmisc_s32g_set_wakeup(data, false); + + return 0; +} + +static int usbmisc_s32g2_init(struct imx_usbmisc_data *data) +{ + return usbmisc_s32g_init(data, S32G_UCMALLBE); +} + static int usbmisc_imx7d_set_wakeup (struct imx_usbmisc_data *data, bool enabled) { @@ -1135,6 +1194,12 @@ static const struct usbmisc_ops imx95_usbmisc_ops = { .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, }; +static const struct usbmisc_ops s32g2_usbmisc_ops = { + .init = usbmisc_s32g2_init, + .set_wakeup = usbmisc_s32g_set_wakeup, + .flags = REINIT_DURING_RESUME, +}; + static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); @@ -1363,6 +1428,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { .compatible = "fsl,imx95-usbmisc", .data = &imx95_usbmisc_ops, }, + { + .compatible = "nxp,s32g2-usbmisc", + .data = &s32g2_usbmisc_ops, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);