This mostly changes the company name from ATG to TDI (TransDimension), but it also updates initialization and split ISO support for that part's integrated transaction translator. Please merge.
- Dave
This patch updates support for the TDI EHCI controller, which is mostly used on non-PCI systems: - Correctly initialize the latest chip, which has both host (EHCI) and peripheral modes. - Initialize split isochronous transfers to use the integrated TT. Most of the patch, by volume, just changes the company name from ARC to TDI in the source code; TransDimension bought ARC's peripheral connectivity business. From: Craig Nadler <[EMAIL PROTECTED]> Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- 1.10/drivers/usb/host/Kconfig 2004-12-06 10:45:04 -08:00 +++ edited/drivers/usb/host/Kconfig 2005-02-04 17:49:28 -08:00 @@ -65,7 +65,7 @@ controller is needed. It's safe to say "y" even if your controller doesn't support this feature. - This supports the EHCI implementation from ARC International. + This supports the EHCI implementation from TransDimension Inc. config USB_OHCI_HCD tristate "OHCI HCD support" --- 1.100/drivers/usb/host/ehci-hcd.c 2005-01-14 16:01:56 -08:00 +++ edited/drivers/usb/host/ehci-hcd.c 2005-02-05 17:38:45 -08:00 @@ -191,9 +191,22 @@ return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); } +/* put TDI/ARC silicon into EHCI mode */ +static void tdi_reset (struct ehci_hcd *ehci) +{ + u32 __iomem *reg_ptr; + u32 tmp; + + reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); + tmp = readl (reg_ptr); + tmp |= 0x3; + writel (tmp, reg_ptr); +} + /* reset a non-running (STS_HALT == 1) controller */ static int ehci_reset (struct ehci_hcd *ehci) { + int retval; u32 command = readl (&ehci->regs->command); command |= CMD_RESET; @@ -201,7 +214,15 @@ writel (command, &ehci->regs->command); ehci_to_hcd(ehci)->state = USB_STATE_HALT; ehci->next_statechange = jiffies; - return handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); + retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); + + if (retval) + return retval; + + if (ehci_is_TDI(ehci)) + tdi_reset (ehci); + + return retval; } /* idle the controller (from running) */ @@ -346,11 +367,20 @@ if (hcd->self.controller->bus == &pci_bus_type) { struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - /* AMD8111 EHCI doesn't work, according to AMD errata */ - if ((pdev->vendor == PCI_VENDOR_ID_AMD) - && (pdev->device == 0x7463)) { - ehci_info (ehci, "ignoring AMD8111 (errata)\n"); - return -EIO; + switch (pdev->vendor) { + case PCI_VENDOR_ID_TDI: + if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { + ehci->is_tdi_rh_tt = 1; + tdi_reset (ehci); + } + break; + case PCI_VENDOR_ID_AMD: + /* AMD8111 EHCI doesn't work, according to AMD errata */ + if (pdev->device == 0x7463) { + ehci_info (ehci, "ignoring AMD8111 (errata)\n"); + return -EIO; + } + break; } temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); @@ -380,6 +410,8 @@ ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); return -EIO; } + if (ehci_is_TDI(ehci)) + ehci_reset (ehci); #endif /* cache this readonly data; minimize PCI reads */ @@ -460,15 +492,6 @@ /* help hc dma work well with cachelines */ pci_set_mwi (pdev); - - /* chip-specific init */ - switch (pdev->vendor) { - case PCI_VENDOR_ID_ARC: - if (pdev->device == PCI_DEVICE_ID_ARC_EHCI) - ehci->is_arc_rh_tt = 1; - break; - } - } #endif --- 1.25/drivers/usb/host/ehci-hub.c 2005-01-07 20:55:36 -08:00 +++ edited/drivers/usb/host/ehci-hub.c 2005-02-04 17:49:28 -08:00 @@ -178,7 +178,7 @@ if (!(port_status & PORT_PE)) { /* with integrated TT, there's nobody to hand it to! */ - if (ehci_is_ARC(ehci)) { + if (ehci_is_TDI(ehci)) { ehci_dbg (ehci, "Failed to enable port %d on root hub TT\n", index+1); @@ -517,7 +517,7 @@ * transaction translator built in. */ if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT - && !ehci_is_ARC(ehci) + && !ehci_is_TDI(ehci) && PORT_USB11 (temp)) { ehci_dbg (ehci, "port %d low speed --> companion\n", --- 1.62/drivers/usb/host/ehci-q.c 2005-02-04 15:51:52 -08:00 +++ edited/drivers/usb/host/ehci-q.c 2005-02-04 17:49:53 -08:00 @@ -198,7 +198,7 @@ && urb->dev->tt && !usb_pipeint (urb->pipe) && ((token & QTD_STS_MMF) != 0 || QTD_CERR(token) == 0) - && (!ehci_is_ARC(ehci) + && (!ehci_is_TDI(ehci) || urb->dev->tt->hub != ehci_to_hcd(ehci)->self.root_hub)) { #ifdef DEBUG @@ -713,10 +713,10 @@ info2 |= (EHCI_TUNE_MULT_TT << 30); info2 |= urb->dev->ttport << 23; - /* set the address of the TT; for ARC's integrated + /* set the address of the TT; for TDI's integrated * root hub tt, leave it zeroed. */ - if (!ehci_is_ARC(ehci) + if (!ehci_is_TDI(ehci) || urb->dev->tt->hub != ehci_to_hcd(ehci)->self.root_hub) info2 |= urb->dev->tt->hub->devnum << 16; --- 1.42/drivers/usb/host/ehci-sched.c 2005-02-04 15:51:52 -08:00 +++ edited/drivers/usb/host/ehci-sched.c 2005-02-05 17:24:11 -08:00 @@ -650,6 +650,7 @@ static void iso_stream_init ( + struct ehci_hcd *ehci, struct ehci_iso_stream *stream, struct usb_device *dev, int pipe, @@ -701,7 +702,10 @@ u32 addr; addr = dev->ttport << 24; - addr |= dev->tt->hub->devnum << 16; + if (!ehci_is_TDI(ehci) + || (dev->tt->hub != + ehci_to_hcd(ehci)->self.root_hub)) + addr |= dev->tt->hub->devnum << 16; addr |= epnum << 8; addr |= dev->devnum; stream->usecs = HS_USECS_ISO (maxp); @@ -819,7 +823,7 @@ /* dev->ep owns the initial refcount */ ep->hcpriv = stream; stream->ep = ep; - iso_stream_init(stream, urb->dev, urb->pipe, + iso_stream_init(ehci, stream, urb->dev, urb->pipe, urb->interval); } --- 1.46/drivers/usb/host/ehci.h 2004-11-30 01:43:30 -08:00 +++ edited/drivers/usb/host/ehci.h 2005-02-05 17:37:30 -08:00 @@ -82,7 +82,7 @@ unsigned long next_statechange; u32 command; - unsigned is_arc_rh_tt:1; /* ARC roothub with TT */ + unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ /* glue to PCI and HCD framework */ struct ehci_caps __iomem *caps; @@ -599,13 +599,13 @@ * needed (mostly in root hub code). */ -#define ehci_is_ARC(e) ((e)->is_arc_rh_tt) +#define ehci_is_TDI(e) ((e)->is_tdi_rh_tt) /* Returns the speed of a device attached to a port on the root hub. */ static inline unsigned int ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) { - if (ehci_is_ARC(ehci)) { + if (ehci_is_TDI(ehci)) { switch ((portsc>>26)&3) { case 0: return 0; @@ -621,7 +621,7 @@ #else -#define ehci_is_ARC(e) (0) +#define ehci_is_TDI(e) (0) #define ehci_port_speed(ehci, portsc) (1<<USB_PORT_FEAT_HIGHSPEED) #endif --- 1.172/include/linux/pci_ids.h 2005-02-04 15:51:53 -08:00 +++ edited/include/linux/pci_ids.h 2005-02-04 17:49:28 -08:00 @@ -2034,8 +2034,8 @@ #define PCI_VENDOR_ID_TOPSPIN 0x1867 -#define PCI_VENDOR_ID_ARC 0x192E -#define PCI_DEVICE_ID_ARC_EHCI 0x0101 +#define PCI_VENDOR_ID_TDI 0x192E +#define PCI_DEVICE_ID_TDI_EHCI 0x0101 #define PCI_VENDOR_ID_SYMPHONY 0x1c1c #define PCI_DEVICE_ID_SYMPHONY_101 0x0001