Re: [PATCH v2 2/2] usb: chipidea: add workaround for chipidea PEC bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux