diff mbox

[U-Boot,v4,1/1] tegra: usb: Fix device enumeration problem of USB1

Message ID 4B9C9637D5087840A465BDCB251780E9E2D6EDA3E6@HKMAIL02.nvidia.com
State Superseded
Headers show

Commit Message

Jim Lin June 21, 2012, 3:24 a.m. UTC
A known hardware issue of USB1 port where bit 1 (connect status
change) of PORTSC register will be set after issuing Port Reset
(like "usb reset" in u-boot command line).
This will be treated as an error and stops later device enumeration.

Therefore we clear that bit after Port Reset in order to proceed
later device enumeration.

Signed-off-by: Jim Lin <jilin@nvidia.com>
---
To reproduce this issue, you can modify board .dts file to set
as the following to build u-boot binary.
"
 usb0 = "/usb@c5000000";
 usb1 = "/usb@c5008000";
"
Install device on USB1 port (address at 0xc5000000).
And run "usb reset" in u-boot console to enumerate device.

Before adding this patch, we could see problem every time.
After adding, tried 10 times of "usb reset", "usb tree", "usb stop"
, without seeing issue.

Changes in v4:
- Add comment to describe replacing weak function ehci_powerup_fixup of ehci-hcd.c
- Remove using variable my_reg

Changes in v3:
- Move patch for USB1 controller into ehci_powerup_fixup of ehci-tegra.c
- Update copyright year to 2012

Changes in v2:
- Change config name
- Add a callback function at the end of ehci_submit_root() function

 drivers/usb/host/ehci-tegra.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

Comments

Stephen Warren June 21, 2012, 5:41 a.m. UTC | #1
On 06/20/2012 09:24 PM, Jim Lin wrote:
> A known hardware issue of USB1 port where bit 1 (connect status
> change) of PORTSC register will be set after issuing Port Reset
> (like "usb reset" in u-boot command line).
> This will be treated as an error and stops later device enumeration.
> 
> Therefore we clear that bit after Port Reset in order to proceed
> later device enumeration.
> 
> Signed-off-by: Jim Lin <jilin@nvidia.com>

Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Marek Vasut June 21, 2012, 10:16 a.m. UTC | #2
Dear Jim Lin,

> A known hardware issue of USB1 port where bit 1 (connect status
> change) of PORTSC register will be set after issuing Port Reset
> (like "usb reset" in u-boot command line).
> This will be treated as an error and stops later device enumeration.
> 
> Therefore we clear that bit after Port Reset in order to proceed
> later device enumeration.
> 
> Signed-off-by: Jim Lin <jilin@nvidia.com>
> ---
> To reproduce this issue, you can modify board .dts file to set
> as the following to build u-boot binary.
> "
>  usb0 = "/usb@c5000000";
>  usb1 = "/usb@c5008000";
> "
> Install device on USB1 port (address at 0xc5000000).
> And run "usb reset" in u-boot console to enumerate device.
> 
> Before adding this patch, we could see problem every time.
> After adding, tried 10 times of "usb reset", "usb tree", "usb stop"
> , without seeing issue.
> 
> Changes in v4:
> - Add comment to describe replacing weak function ehci_powerup_fixup of
> ehci-hcd.c - Remove using variable my_reg
> 
> Changes in v3:
> - Move patch for USB1 controller into ehci_powerup_fixup of ehci-tegra.c
> - Update copyright year to 2012
> 
> Changes in v2:
> - Change config name
> - Add a callback function at the end of ehci_submit_root() function
> 
>  drivers/usb/host/ehci-tegra.c |   18 +++++++++++++++++-
>  1 files changed, 17 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
> index a7e105b..6646d3a 100644
> --- a/drivers/usb/host/ehci-tegra.c
> +++ b/drivers/usb/host/ehci-tegra.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2009 NVIDIA Corporation
> + * Copyright (c) 2009-2012 NVIDIA Corporation
>   *
>   * See file CREDITS for list of people who contributed to this
>   * project.
> @@ -29,6 +29,22 @@
>  #include <asm/errno.h>
>  #include <asm/arch/usb.h>
> 
> +/*
> + * A known hardware issue where Connect Status Change bit of PORTSC
> register + * of USB1 controller will be set after Port Reset.
> + * We have to clear it in order for later device enumeration to proceed.
> + * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
> + * in "ehci-hcd.c".
> + */
> +void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)

So it was even enough to use the already preinstalled callback? :-)

> +{
> +	mdelay(50);
> +	if (((u32) status_reg & 0xFFFFC000) != TEGRA_USB1_BASE)

What's this magic number here?

> +		return;
> +	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
> +	if (ehci_readl(status_reg) & EHCI_PS_CSC)
> +		*reg |= EHCI_PS_CSC;

writel()

> +}
> 
>  /*
>   * Create the appropriate control structures to manage

Best regards,
Marek Vasut
Jim Lin June 21, 2012, 10:42 a.m. UTC | #3
>From: Marek Vasut [mailto:marek.vasut@gmail.com] 
>Sent: Thursday, June 21, 2012 6:16 PM
>> --- a/drivers/usb/host/ehci-tegra.c
>> +++ b/drivers/usb/host/ehci-tegra.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Copyright (c) 2009 NVIDIA Corporation
>> + * Copyright (c) 2009-2012 NVIDIA Corporation
>>   *
>>   * See file CREDITS for list of people who contributed to this
>>   * project.
>> @@ -29,6 +29,22 @@
>>  #include <asm/errno.h>
>>  #include <asm/arch/usb.h>
>> 
>> +/*
>> + * A known hardware issue where Connect Status Change bit of PORTSC
>> register + * of USB1 controller will be set after Port Reset.
>> + * We have to clear it in order for later device enumeration to proceed.
>> + * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
>> + * in "ehci-hcd.c".
>> + */
>> +void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
>
>So it was even enough to use the already preinstalled callback? :-)

Yes.

>> +{
>> +	mdelay(50);
>> +	if (((u32) status_reg & 0xFFFFC000) != TEGRA_USB1_BASE)
>
>What's this magic number here?

Address Mask value, any suggestion?

>> +		return;
> +	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
>> +	if (ehci_readl(status_reg) & EHCI_PS_CSC)
>> +		*reg |= EHCI_PS_CSC;
>
>writel()

The real IO write (ehci_writel) is done in ehci-hcd.c after calling of ehci_powerup_fixup.
Any suggestion?
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
Marek Vasut June 21, 2012, 4:57 p.m. UTC | #4
Dear Jim Lin,

> >From: Marek Vasut [mailto:marek.vasut@gmail.com]
> >Sent: Thursday, June 21, 2012 6:16 PM
> >
> >> --- a/drivers/usb/host/ehci-tegra.c
> >> +++ b/drivers/usb/host/ehci-tegra.c
> >> @@ -1,5 +1,5 @@
> >> 
> >>  /*
> >> 
> >> - * Copyright (c) 2009 NVIDIA Corporation
> >> + * Copyright (c) 2009-2012 NVIDIA Corporation
> >> 
> >>   *
> >>   * See file CREDITS for list of people who contributed to this
> >>   * project.
> >> 
> >> @@ -29,6 +29,22 @@
> >> 
> >>  #include <asm/errno.h>
> >>  #include <asm/arch/usb.h>
> >> 
> >> +/*
> >> + * A known hardware issue where Connect Status Change bit of PORTSC
> >> register + * of USB1 controller will be set after Port Reset.
> >> + * We have to clear it in order for later device enumeration to
> >> proceed. + * This ehci_powerup_fixup overrides the weak function
> >> ehci_powerup_fixup + * in "ehci-hcd.c".
> >> + */
> >> +void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
> >
> >So it was even enough to use the already preinstalled callback? :-)
> 
> Yes.
> 
> >> +{
> >> +	mdelay(50);
> >> +	if (((u32) status_reg & 0xFFFFC000) != TEGRA_USB1_BASE)
> >
> >What's this magic number here?
> 
> Address Mask value, any suggestion?

I wonder ... either comment or #define it somewhere, the later is favorable.

> 
> >> +		return;
> > 
> > +	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
> > 
> >> +	if (ehci_readl(status_reg) & EHCI_PS_CSC)
> >> +		*reg |= EHCI_PS_CSC;
> >
> >writel()
> 
> The real IO write (ehci_writel) is done in ehci-hcd.c after calling of
> ehci_powerup_fixup. Any suggestion?

Good, leave it at that.

> ---------------------------------------------------------------------------
> -------- This email message is for the sole use of the intended
> recipient(s) and may contain confidential information.  Any unauthorized
> review, use, disclosure or distribution is prohibited.  If you are not the
> intended recipient, please contact the sender by reply email and destroy
> all copies of the original message.
> ---------------------------------------------------------------------------
> --------

^^ The above is nvidia bullshit, please remove it, it doesn't make sense here.

Best regards,
Marek Vasut
diff mbox

Patch

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index a7e105b..6646d3a 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -1,5 +1,5 @@ 
 /*
- * Copyright (c) 2009 NVIDIA Corporation
+ * Copyright (c) 2009-2012 NVIDIA Corporation
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -29,6 +29,22 @@ 
 #include <asm/errno.h>
 #include <asm/arch/usb.h>
 
+/*
+ * A known hardware issue where Connect Status Change bit of PORTSC register
+ * of USB1 controller will be set after Port Reset.
+ * We have to clear it in order for later device enumeration to proceed.
+ * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
+ * in "ehci-hcd.c".
+ */
+void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+{
+	mdelay(50);
+	if (((u32) status_reg & 0xFFFFC000) != TEGRA_USB1_BASE)
+		return;
+	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
+	if (ehci_readl(status_reg) & EHCI_PS_CSC)
+		*reg |= EHCI_PS_CSC;
+}
 
 /*
  * Create the appropriate control structures to manage