rename CFG_ macros to CONFIG_SYS
[platform/kernel/u-boot.git] / drivers / usb / usb_ohci.c
index 829bbca..c1aac33 100644 (file)
@@ -53,6 +53,9 @@
 
 #if defined(CONFIG_PCI_OHCI)
 # include <pci.h>
+#if !defined(CONFIG_PCI_OHCI_DEVNO)
+#define CONFIG_PCI_OHCI_DEVNO  0
+#endif
 #endif
 
 #include <malloc.h>
 #if defined(CONFIG_ARM920T) || \
     defined(CONFIG_S3C2400) || \
     defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C6400) || \
     defined(CONFIG_440EP) || \
     defined(CONFIG_PCI_OHCI) || \
     defined(CONFIG_MPC5200) || \
-    defined(CFG_OHCI_USE_NPS)
+    defined(CONFIG_SYS_OHCI_USE_NPS)
 # define OHCI_USE_NPS          /* force NoPowerSwitching mode */
 #endif
 
 /*
  * e.g. PCI controllers need this
  */
-#ifdef CFG_OHCI_SWAP_REG_ACCESS
-# define readl(a) __swap_32(*((vu_long *)(a)))
-# define writel(a, b) (*((vu_long *)(b)) = __swap_32((vu_long)a))
+#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS
+# define readl(a) __swap_32(*((volatile u32 *)(a)))
+# define writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a))
 #else
-# define readl(a) (*((vu_long *)(a)))
-# define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
-#endif /* CFG_OHCI_SWAP_REG_ACCESS */
+# define readl(a) (*((volatile u32 *)(a)))
+# define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
+#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
 
 #define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
 
@@ -105,26 +109,33 @@ static struct pci_device_id ohci_pci_ids[] = {
 };
 #endif
 
+#ifdef CONFIG_PCI_EHCI_DEVNO
+static struct pci_device_id ehci_pci_ids[] = {
+       {0x1131, 0x1562},       /* Philips 1562 PCI EHCI module ids */
+       /* Please add supported PCI EHCI controller ids here */
+       {0, 0}
+};
+#endif
+
 #ifdef DEBUG
 #define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
 #else
 #define dbg(format, arg...) do {} while(0)
 #endif /* DEBUG */
 #define err(format, arg...) printf("ERROR: " format "\n", ## arg)
-#undef SHOW_INFO
 #ifdef SHOW_INFO
 #define info(format, arg...) printf("INFO: " format "\n", ## arg)
 #else
 #define info(format, arg...) do {} while(0)
 #endif
 
-#ifdef CFG_OHCI_BE_CONTROLLER
+#ifdef CONFIG_SYS_OHCI_BE_CONTROLLER
 # define m16_swap(x) cpu_to_be16(x)
 # define m32_swap(x) cpu_to_be32(x)
 #else
 # define m16_swap(x) cpu_to_le16(x)
 # define m32_swap(x) cpu_to_le32(x)
-#endif /* CFG_OHCI_BE_CONTROLLER */
+#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */
 
 /* global ohci_t */
 static ohci_t gohci;
@@ -139,28 +150,14 @@ int got_rhsc;
 /* device which was disconnected */
 struct usb_device *devgone;
 
-/*-------------------------------------------------------------------------*/
-
-/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
- * The erratum (#4) description is incorrect.  AMD's workaround waits
- * till some bits (mostly reserved) are clear; ok for all revs.
- */
-#define OHCI_QUIRK_AMD756 0xabcd
-#define read_roothub(hc, register, mask) ({ \
-       u32 temp = readl (&hc->regs->roothub.register); \
-       if (hc->flags & OHCI_QUIRK_AMD756) \
-               while (temp & mask) \
-                       temp = readl (&hc->regs->roothub.register); \
-       temp; })
-
-static u32 roothub_a (struct ohci *hc)
-       { return read_roothub (hc, a, 0xfc0fe000); }
+static inline u32 roothub_a (struct ohci *hc)
+       { return readl (&hc->regs->roothub.a); }
 static inline u32 roothub_b (struct ohci *hc)
        { return readl (&hc->regs->roothub.b); }
 static inline u32 roothub_status (struct ohci *hc)
        { return readl (&hc->regs->roothub.status); }
-static u32 roothub_portstatus (struct ohci *hc, int i)
-       { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+static inline u32 roothub_portstatus (struct ohci *hc, int i)
+       { return readl (&hc->regs->roothub.portstatus[i]); }
 
 /* forward declaration */
 static int hc_interrupt (void);
@@ -1233,9 +1230,9 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe
        }
 
        bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
-       wValue        = cpu_to_le16 (cmd->value);
-       wIndex        = cpu_to_le16 (cmd->index);
-       wLength       = cpu_to_le16 (cmd->length);
+       wValue        = le16_to_cpu (cmd->value);
+       wIndex        = le16_to_cpu (cmd->index);
+       wLength       = le16_to_cpu (cmd->length);
 
        info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
                dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
@@ -1583,11 +1580,38 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 static int hc_reset (ohci_t *ohci)
 {
+#ifdef CONFIG_PCI_EHCI_DEVNO
+       pci_dev_t pdev;
+#endif
        int timeout = 30;
        int smm_timeout = 50; /* 0,5 sec */
 
        dbg("%s\n", __FUNCTION__);
 
+#ifdef CONFIG_PCI_EHCI_DEVNO
+       /*
+        *  Some multi-function controllers (e.g. ISP1562) allow root hub
+        * resetting via EHCI registers only.
+        */
+       pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVNO);
+       if (pdev != -1) {
+               u32 base;
+               int timeout = 1000;
+
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
+               writel (readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET,
+                       base + EHCI_USBCMD_OFF);
+
+               while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) {
+                       if (timeout-- <= 0) {
+                               printf("USB RootHub reset timed out!");
+                               break;
+                       }
+                       udelay(1);
+               }
+       } else
+               printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO);
+#endif
        if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
                writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
                info("USB HC TakeOver from SMM");
@@ -1795,13 +1819,13 @@ int usb_lowlevel_init(void)
        pci_dev_t pdev;
 #endif
 
-#ifdef CFG_USB_OHCI_CPU_INIT
+#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
        /* cpu dependant init */
        if(usb_cpu_init())
                return -1;
 #endif
 
-#ifdef CFG_USB_OHCI_BOARD_INIT
+#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
        /*  board dependant init */
        if(usb_board_init())
                return -1;
@@ -1833,7 +1857,7 @@ int usb_lowlevel_init(void)
        gohci.sleeping = 0;
        gohci.irq = -1;
 #ifdef CONFIG_PCI_OHCI
-       pdev = pci_find_devices(ohci_pci_ids, 0);
+       pdev = pci_find_devices(ohci_pci_ids, CONFIG_PCI_OHCI_DEVNO);
 
        if (pdev != -1) {
                u16 vid, did;
@@ -1849,21 +1873,21 @@ int usb_lowlevel_init(void)
        } else
                return -1;
 #else
-       gohci.regs = (struct ohci_regs *)CFG_USB_OHCI_REGS_BASE;
+       gohci.regs = (struct ohci_regs *)CONFIG_SYS_USB_OHCI_REGS_BASE;
 #endif
 
        gohci.flags = 0;
-       gohci.slot_name = CFG_USB_OHCI_SLOT_NAME;
+       gohci.slot_name = CONFIG_SYS_USB_OHCI_SLOT_NAME;
 
        if (hc_reset (&gohci) < 0) {
                hc_release_ohci (&gohci);
                err ("can't reset usb-%s", gohci.slot_name);
-#ifdef CFG_USB_OHCI_BOARD_INIT
+#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
                /* board dependant cleanup */
                usb_board_init_fail();
 #endif
 
-#ifdef CFG_USB_OHCI_CPU_INIT
+#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
                /* cpu dependant cleanup */
                usb_cpu_init_fail();
 #endif
@@ -1877,12 +1901,12 @@ int usb_lowlevel_init(void)
                err ("can't start usb-%s", gohci.slot_name);
                hc_release_ohci (&gohci);
                /* Initialization failed */
-#ifdef CFG_USB_OHCI_BOARD_INIT
+#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
                /* board dependant cleanup */
                usb_board_stop();
 #endif
 
-#ifdef CFG_USB_OHCI_CPU_INIT
+#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
                /* cpu dependant cleanup */
                usb_cpu_stop();
 #endif
@@ -1908,18 +1932,20 @@ int usb_lowlevel_stop(void)
        /* call hc_release_ohci() here ? */
        hc_reset (&gohci);
 
-#ifdef CFG_USB_OHCI_BOARD_INIT
+#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
        /* board dependant cleanup */
        if(usb_board_stop())
                return -1;
 #endif
 
-#ifdef CFG_USB_OHCI_CPU_INIT
+#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
        /* cpu dependant cleanup */
        if(usb_cpu_stop())
                return -1;
 #endif
-
+       /* This driver is no longer initialised. It needs a new low-level
+        * init (board/cpu) before it can be used again. */
+       ohci_inited = 0;
        return 0;
 }
 #endif /* CONFIG_USB_OHCI_NEW */