On Wed, Aug 9, 2023 at 10:40 AM Xu Yang <xu.yang_2@xxxxxxx> wrote: > > Some NXP processors using ChipIdea USB IP have a bug when frame babble is > detected. > > Issue description: > In USB camera test, our controller is host in HS mode. In ISOC IN, when > device sends data across the micro frame, it causes the babble in host > controller. This will clear the PE bit. In spec, it also requires to set > the PEC bit and then set the PCI bit. Without the PCI interrupt, the > software does not know the PE is cleared. > > This will add a flag CI_HDRC_HAS_PORTSC_PEC_MISSED to some impacted > platform datas. And the ehci host driver will assert PEC by SW when > specific conditions are satisfied. > > Signed-off-by: Xu Yang <xu.yang_2@xxxxxxx> > Acked-by: Peter Chen <peter.chen@xxxxxxxxxx> Peter > --- > Changes in v2: > - no change > --- > drivers/usb/chipidea/ci.h | 1 + > drivers/usb/chipidea/ci_hdrc_imx.c | 4 +++- > drivers/usb/chipidea/core.c | 2 ++ > drivers/usb/chipidea/host.c | 1 + > include/linux/usb/chipidea.h | 1 + > 5 files changed, 8 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h > index d262b9df7b3d..d9bb3d3f026e 100644 > --- a/drivers/usb/chipidea/ci.h > +++ b/drivers/usb/chipidea/ci.h > @@ -257,6 +257,7 @@ struct ci_hdrc { > bool id_event; > bool b_sess_valid_event; > bool imx28_write_fix; > + bool has_portsc_pec_bug; > bool supports_runtime_pm; > bool in_lpm; > bool wakeup_int; > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c > index 772bbdade994..e28bb2f2612d 100644 > --- a/drivers/usb/chipidea/ci_hdrc_imx.c > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c > @@ -68,11 +68,13 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = { > > static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { > .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | > + CI_HDRC_HAS_PORTSC_PEC_MISSED | > CI_HDRC_PMQOS, > }; > > static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { > - .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, > + .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | > + CI_HDRC_HAS_PORTSC_PEC_MISSED, > }; > > static const struct of_device_id ci_hdrc_imx_dt_ids[] = { > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c > index 6e1196b53253..7ac39a281b8c 100644 > --- a/drivers/usb/chipidea/core.c > +++ b/drivers/usb/chipidea/core.c > @@ -1044,6 +1044,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) > CI_HDRC_IMX28_WRITE_FIX); > ci->supports_runtime_pm = !!(ci->platdata->flags & > CI_HDRC_SUPPORTS_RUNTIME_PM); > + ci->has_portsc_pec_bug = !!(ci->platdata->flags & > + CI_HDRC_HAS_PORTSC_PEC_MISSED); > platform_set_drvdata(pdev, ci); > > ret = hw_device_init(ci, base); > diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c > index ebe7400243b1..08af26b762a2 100644 > --- a/drivers/usb/chipidea/host.c > +++ b/drivers/usb/chipidea/host.c > @@ -151,6 +151,7 @@ static int host_start(struct ci_hdrc *ci) > ehci->has_hostpc = ci->hw_bank.lpm; > ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; > ehci->imx28_write_fix = ci->imx28_write_fix; > + ehci->has_ci_pec_bug = ci->has_portsc_pec_bug; > > priv = (struct ehci_ci_priv *)ehci->priv; > priv->reg_vbus = NULL; > diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h > index ee38835ed77c..0b4f2d5faa08 100644 > --- a/include/linux/usb/chipidea.h > +++ b/include/linux/usb/chipidea.h > @@ -63,6 +63,7 @@ struct ci_hdrc_platform_data { > #define CI_HDRC_IMX_IS_HSIC BIT(14) > #define CI_HDRC_PMQOS BIT(15) > #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) > +#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) > enum usb_dr_mode dr_mode; > #define CI_HDRC_CONTROLLER_RESET_EVENT 0 > #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 > -- > 2.34.1 >