summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoff Levand <geoff@infradead.org>2011-11-22 18:33:45 -0800
committerGeoff Levand <geoff@infradead.org>2011-12-08 09:38:53 -0800
commit9187bef2fa395e85d5e22c4792b553d98410ccd6 (patch)
tree4b5c7bcecca9cabf00da1050a4bbe405352d4d70
parent876e0df902c726408c84b75dab673a90fd492e1d (diff)
usb: PS3 EHCI HC reset work-around
PS3 EHCI HC errata fix 316 - The PS3 EHCI HC will reset its internal INSNREGXX setup regs back to the chip default values on Host Controller Reset (CMD_RESET) or Light Host Controller Reset (CMD_LRESET). The work-around for this is for the HC driver to re-initialise these regs when ever the HC is reset. Adds a new helper routine ps3_ehci_setup_insnreg() which is called from ps3_ehci_hc_reset(). Signed-off-by: Geoff Levand <geoff@infradead.org> Acked-by: Alan Stern <stern@rowland.harvard.edu>
-rw-r--r--drivers/usb/host/ehci-ps3.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 2dc32da75cfc..a20e496eb479 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -21,6 +21,34 @@
#include <asm/firmware.h>
#include <asm/ps3.h>
+static void ps3_ehci_setup_insnreg(struct ehci_hcd *ehci)
+{
+ /* PS3 HC internal setup register offsets. */
+
+ enum ps3_ehci_hc_insnreg {
+ ps3_ehci_hc_insnreg01 = 0x084,
+ ps3_ehci_hc_insnreg02 = 0x088,
+ ps3_ehci_hc_insnreg03 = 0x08c,
+ };
+
+ /* PS3 EHCI HC errata fix 316 - The PS3 EHCI HC will reset its
+ * internal INSNREGXX setup regs back to the chip default values
+ * on Host Controller Reset (CMD_RESET) or Light Host Controller
+ * Reset (CMD_LRESET). The work-around for this is for the HC
+ * driver to re-initialise these regs when ever the HC is reset.
+ */
+
+ /* Set burst transfer counts to 256 out, 32 in. */
+
+ writel_be(0x01000020, (void __iomem *)ehci->regs +
+ ps3_ehci_hc_insnreg01);
+
+ /* Enable burst transfer counts. */
+
+ writel_be(0x00000001, (void __iomem *)ehci->regs +
+ ps3_ehci_hc_insnreg03);
+}
+
static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
{
int result;
@@ -49,6 +77,8 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
ehci_reset(ehci);
+ ps3_ehci_setup_insnreg(ehci);
+
return result;
}