1 /* 2 * This file contains code to reset and initialize USB host controllers. 3 * Some of it includes work-arounds for PCI hardware and BIOS quirks. 4 * It may need to run early during booting -- before USB would normally 5 * initialize -- to ensure that Linux doesn't use any legacy modes. 6 * 7 * Copyright (c) 1999 Martin Mares <mj@ucw.cz> 8 * (and others) 9 */ 10 11 #include <linux/config.h> 12 #include <linux/types.h> 13 #include <linux/kernel.h> 14 #include <linux/pci.h> 15 #include <linux/init.h> 16 #include <linux/delay.h> 17 #include <linux/acpi.h> 18 19 20 #define UHCI_USBLEGSUP 0xc0 /* legacy support */ 21 #define UHCI_USBCMD 0 /* command register */ 22 #define UHCI_USBINTR 4 /* interrupt register */ 23 #define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ 24 #define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ 25 #define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */ 26 #define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */ 27 #define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */ 28 #define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */ 29 #define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */ 30 31 #define OHCI_CONTROL 0x04 32 #define OHCI_CMDSTATUS 0x08 33 #define OHCI_INTRSTATUS 0x0c 34 #define OHCI_INTRENABLE 0x10 35 #define OHCI_INTRDISABLE 0x14 36 #define OHCI_OCR (1 << 3) /* ownership change request */ 37 #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ 38 #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ 39 #define OHCI_INTR_OC (1 << 30) /* ownership change */ 40 41 #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ 42 #define EHCI_USBCMD 0 /* command register */ 43 #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ 44 #define EHCI_USBSTS 4 /* status register */ 45 #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ 46 #define EHCI_USBINTR 8 /* interrupt register */ 47 #define EHCI_USBLEGSUP 0 /* legacy support register */ 48 #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ 49 #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ 50 #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ 51 #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ 52 53 54 /* 55 * Make sure the controller is completely inactive, unable to 56 * generate interrupts or do DMA. 57 */ 58 void uhci_reset_hc(struct pci_dev *pdev, unsigned long base) 59 { 60 /* Turn off PIRQ enable and SMI enable. (This also turns off the 61 * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. 62 */ 63 pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC); 64 65 /* Reset the HC - this will force us to get a 66 * new notification of any already connected 67 * ports due to the virtual disconnect that it 68 * implies. 69 */ 70 outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); 71 mb(); 72 udelay(5); 73 if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET) 74 dev_warn(&pdev->dev, "HCRESET not completed yet!\n"); 75 76 /* Just to be safe, disable interrupt requests and 77 * make sure the controller is stopped. 78 */ 79 outw(0, base + UHCI_USBINTR); 80 outw(0, base + UHCI_USBCMD); 81 } 82 EXPORT_SYMBOL_GPL(uhci_reset_hc); 83 84 /* 85 * Initialize a controller that was newly discovered or has just been 86 * resumed. In either case we can't be sure of its previous state. 87 * 88 * Returns: 1 if the controller was reset, 0 otherwise. 89 */ 90 int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) 91 { 92 u16 legsup; 93 unsigned int cmd, intr; 94 95 /* 96 * When restarting a suspended controller, we expect all the 97 * settings to be the same as we left them: 98 * 99 * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; 100 * Controller is stopped and configured with EGSM set; 101 * No interrupts enabled except possibly Resume Detect. 102 * 103 * If any of these conditions are violated we do a complete reset. 104 */ 105 pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); 106 if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { 107 dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", 108 __FUNCTION__, legsup); 109 goto reset_needed; 110 } 111 112 cmd = inw(base + UHCI_USBCMD); 113 if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || 114 !(cmd & UHCI_USBCMD_EGSM)) { 115 dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", 116 __FUNCTION__, cmd); 117 goto reset_needed; 118 } 119 120 intr = inw(base + UHCI_USBINTR); 121 if (intr & (~UHCI_USBINTR_RESUME)) { 122 dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", 123 __FUNCTION__, intr); 124 goto reset_needed; 125 } 126 return 0; 127 128 reset_needed: 129 dev_dbg(&pdev->dev, "Performing full reset\n"); 130 uhci_reset_hc(pdev, base); 131 return 1; 132 } 133 EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); 134 135 static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) 136 { 137 u16 cmd; 138 return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask); 139 } 140 141 #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO) 142 #define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) 143 144 static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) 145 { 146 unsigned long base = 0; 147 int i; 148 149 if (!pio_enabled(pdev)) 150 return; 151 152 for (i = 0; i < PCI_ROM_RESOURCE; i++) 153 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { 154 base = pci_resource_start(pdev, i); 155 break; 156 } 157 158 if (base) 159 uhci_check_and_reset_hc(pdev, base); 160 } 161 162 static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) 163 { 164 return pci_resource_start(pdev, idx) && mmio_enabled(pdev); 165 } 166 167 static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) 168 { 169 void __iomem *base; 170 int wait_time; 171 u32 control; 172 173 if (!mmio_resource_enabled(pdev, 0)) 174 return; 175 176 base = ioremap_nocache(pci_resource_start(pdev, 0), 177 pci_resource_len(pdev, 0)); 178 if (base == NULL) return; 179 180 /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ 181 #ifndef __hppa__ 182 control = readl(base + OHCI_CONTROL); 183 if (control & OHCI_CTRL_IR) { 184 wait_time = 500; /* arbitrary; 5 seconds */ 185 writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); 186 writel(OHCI_OCR, base + OHCI_CMDSTATUS); 187 while (wait_time > 0 && 188 readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { 189 wait_time -= 10; 190 msleep(10); 191 } 192 if (wait_time <= 0) 193 printk(KERN_WARNING "%s %s: early BIOS handoff " 194 "failed (BIOS bug ?)\n", 195 pdev->dev.bus_id, "OHCI"); 196 197 /* reset controller, preserving RWC */ 198 writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); 199 } 200 #endif 201 202 /* 203 * disable interrupts 204 */ 205 writel(~(u32)0, base + OHCI_INTRDISABLE); 206 writel(~(u32)0, base + OHCI_INTRSTATUS); 207 208 iounmap(base); 209 } 210 211 static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) 212 { 213 int wait_time, delta; 214 void __iomem *base, *op_reg_base; 215 u32 hcc_params, val, temp; 216 u8 cap_length; 217 218 if (!mmio_resource_enabled(pdev, 0)) 219 return; 220 221 base = ioremap_nocache(pci_resource_start(pdev, 0), 222 pci_resource_len(pdev, 0)); 223 if (base == NULL) return; 224 225 cap_length = readb(base); 226 op_reg_base = base + cap_length; 227 hcc_params = readl(base + EHCI_HCC_PARAMS); 228 hcc_params = (hcc_params >> 8) & 0xff; 229 if (hcc_params) { 230 pci_read_config_dword(pdev, 231 hcc_params + EHCI_USBLEGSUP, 232 &val); 233 if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { 234 /* 235 * Ok, BIOS is in smm mode, try to hand off... 236 */ 237 pci_read_config_dword(pdev, 238 hcc_params + EHCI_USBLEGCTLSTS, 239 &temp); 240 pci_write_config_dword(pdev, 241 hcc_params + EHCI_USBLEGCTLSTS, 242 temp | EHCI_USBLEGCTLSTS_SOOE); 243 val |= EHCI_USBLEGSUP_OS; 244 pci_write_config_dword(pdev, 245 hcc_params + EHCI_USBLEGSUP, 246 val); 247 248 wait_time = 500; 249 do { 250 msleep(10); 251 wait_time -= 10; 252 pci_read_config_dword(pdev, 253 hcc_params + EHCI_USBLEGSUP, 254 &val); 255 } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); 256 if (!wait_time) { 257 /* 258 * well, possibly buggy BIOS... 259 */ 260 printk(KERN_WARNING "%s %s: early BIOS handoff " 261 "failed (BIOS bug ?)\n", 262 pdev->dev.bus_id, "EHCI"); 263 pci_write_config_dword(pdev, 264 hcc_params + EHCI_USBLEGSUP, 265 EHCI_USBLEGSUP_OS); 266 pci_write_config_dword(pdev, 267 hcc_params + EHCI_USBLEGCTLSTS, 268 0); 269 } 270 } 271 } 272 273 /* 274 * halt EHCI & disable its interrupts in any case 275 */ 276 val = readl(op_reg_base + EHCI_USBSTS); 277 if ((val & EHCI_USBSTS_HALTED) == 0) { 278 val = readl(op_reg_base + EHCI_USBCMD); 279 val &= ~EHCI_USBCMD_RUN; 280 writel(val, op_reg_base + EHCI_USBCMD); 281 282 wait_time = 2000; 283 delta = 100; 284 do { 285 writel(0x3f, op_reg_base + EHCI_USBSTS); 286 udelay(delta); 287 wait_time -= delta; 288 val = readl(op_reg_base + EHCI_USBSTS); 289 if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { 290 break; 291 } 292 } while (wait_time > 0); 293 } 294 writel(0, op_reg_base + EHCI_USBINTR); 295 writel(0x3f, op_reg_base + EHCI_USBSTS); 296 297 iounmap(base); 298 299 return; 300 } 301 302 303 304 static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) 305 { 306 if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) 307 quirk_usb_handoff_uhci(pdev); 308 else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) 309 quirk_usb_handoff_ohci(pdev); 310 else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) 311 quirk_usb_disable_ehci(pdev); 312 } 313 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); 314