Skip to content

Commit

Permalink
usb: chipidea: add workaround for chipidea PEC bug
Browse files Browse the repository at this point in the history
[ Upstream commit 12e6ac6 ]

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@nxp.com>
Link: https://lore.kernel.org/r/20230809024432.535160-2-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Xu Yang authored and gregkh committed Sep 23, 2023
1 parent ba3df8c commit 205dd46
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/usb/chipidea/ci.h
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/chipidea/ci_hdrc_imx.c
Expand Up @@ -67,11 +67,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[] = {
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/chipidea/core.c
Expand Up @@ -1045,6 +1045,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);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/chipidea/host.c
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/chipidea.h
Expand Up @@ -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
Expand Down

0 comments on commit 205dd46

Please sign in to comment.