aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 22:52:28 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:48 -0400
commit66d4eadd8d067269ea8fead1a50fe87c2979a80d (patch)
treeb0324868818058161e528bd194f6888456924fd4 /drivers/usb/host/xhci-hcd.c
parent74c6874199af98e602bb7c5fb1beb9cffda98729 (diff)
USB: xhci: BIOS handoff and HW initialization.
Add PCI initialization code to take control of the xHCI host controller away from the BIOS, halt, and reset the host controller. The xHCI spec says that BIOSes must give up the host controller within 5 seconds. Add some host controller glue functions to handle hardware initialization and memory allocation for the host controller. The current xHCI prototypes use PCI interrupts, but the xHCI spec requires MSI-X interrupts. Add code to support MSI-X interrupts, but use the PCI interrupts for now. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
new file mode 100644
index 000000000000..64fcc22e9d59
--- /dev/null
+++ b/drivers/usb/host/xhci-hcd.c
@@ -0,0 +1,377 @@
1/*
2 * xHCI host controller driver
3 *
4 * Copyright (C) 2008 Intel Corp.
5 *
6 * Author: Sarah Sharp
7 * Some code borrowed from the Linux EHCI driver.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/irq.h>
24#include <linux/module.h>
25
26#include "xhci.h"
27
28#define DRIVER_AUTHOR "Sarah Sharp"
29#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
30
31/* TODO: copied from ehci-hcd.c - can this be refactored? */
32/*
33 * handshake - spin reading hc until handshake completes or fails
34 * @ptr: address of hc register to be read
35 * @mask: bits to look at in result of read
36 * @done: value of those bits when handshake succeeds
37 * @usec: timeout in microseconds
38 *
39 * Returns negative errno, or zero on success
40 *
41 * Success happens when the "mask" bits have the specified value (hardware
42 * handshake done). There are two failure modes: "usec" have passed (major
43 * hardware flakeout), or the register reads as all-ones (hardware removed).
44 */
45static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
46 u32 mask, u32 done, int usec)
47{
48 u32 result;
49
50 do {
51 result = xhci_readl(xhci, ptr);
52 if (result == ~(u32)0) /* card removed */
53 return -ENODEV;
54 result &= mask;
55 if (result == done)
56 return 0;
57 udelay(1);
58 usec--;
59 } while (usec > 0);
60 return -ETIMEDOUT;
61}
62
63/*
64 * Force HC into halt state.
65 *
66 * Disable any IRQs and clear the run/stop bit.
67 * HC will complete any current and actively pipelined transactions, and
68 * should halt within 16 microframes of the run/stop bit being cleared.
69 * Read HC Halted bit in the status register to see when the HC is finished.
70 * XXX: shouldn't we set HC_STATE_HALT here somewhere?
71 */
72int xhci_halt(struct xhci_hcd *xhci)
73{
74 u32 halted;
75 u32 cmd;
76 u32 mask;
77
78 xhci_dbg(xhci, "// Halt the HC\n");
79 /* Disable all interrupts from the host controller */
80 mask = ~(XHCI_IRQS);
81 halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
82 if (!halted)
83 mask &= ~CMD_RUN;
84
85 cmd = xhci_readl(xhci, &xhci->op_regs->command);
86 cmd &= mask;
87 xhci_writel(xhci, cmd, &xhci->op_regs->command);
88
89 return handshake(xhci, &xhci->op_regs->status,
90 STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
91}
92
93/*
94 * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
95 *
96 * This resets pipelines, timers, counters, state machines, etc.
97 * Transactions will be terminated immediately, and operational registers
98 * will be set to their defaults.
99 */
100int xhci_reset(struct xhci_hcd *xhci)
101{
102 u32 command;
103 u32 state;
104
105 state = xhci_readl(xhci, &xhci->op_regs->status);
106 BUG_ON((state & STS_HALT) == 0);
107
108 xhci_dbg(xhci, "// Reset the HC\n");
109 command = xhci_readl(xhci, &xhci->op_regs->command);
110 command |= CMD_RESET;
111 xhci_writel(xhci, command, &xhci->op_regs->command);
112 /* XXX: Why does EHCI set this here? Shouldn't other code do this? */
113 xhci_to_hcd(xhci)->state = HC_STATE_HALT;
114
115 return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
116}
117
118/*
119 * Stop the HC from processing the endpoint queues.
120 */
121static void xhci_quiesce(struct xhci_hcd *xhci)
122{
123 /*
124 * Queues are per endpoint, so we need to disable an endpoint or slot.
125 *
126 * To disable a slot, we need to insert a disable slot command on the
127 * command ring and ring the doorbell. This will also free any internal
128 * resources associated with the slot (which might not be what we want).
129 *
130 * A Release Endpoint command sounds better - doesn't free internal HC
131 * memory, but removes the endpoints from the schedule and releases the
132 * bandwidth, disables the doorbells, and clears the endpoint enable
133 * flag. Usually used prior to a set interface command.
134 *
135 * TODO: Implement after command ring code is done.
136 */
137 BUG_ON(!HC_IS_RUNNING(xhci_to_hcd(xhci)->state));
138 xhci_dbg(xhci, "Finished quiescing -- code not written yet\n");
139}
140
141#if 0
142/* Set up MSI-X table for entry 0 (may claim other entries later) */
143static int xhci_setup_msix(struct xhci_hcd *xhci)
144{
145 int ret;
146 struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
147
148 xhci->msix_count = 0;
149 /* XXX: did I do this right? ixgbe does kcalloc for more than one */
150 xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL);
151 if (!xhci->msix_entries) {
152 xhci_err(xhci, "Failed to allocate MSI-X entries\n");
153 return -ENOMEM;
154 }
155 xhci->msix_entries[0].entry = 0;
156
157 ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
158 if (ret) {
159 xhci_err(xhci, "Failed to enable MSI-X\n");
160 goto free_entries;
161 }
162
163 /*
164 * Pass the xhci pointer value as the request_irq "cookie".
165 * If more irqs are added, this will need to be unique for each one.
166 */
167 ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0,
168 "xHCI", xhci_to_hcd(xhci));
169 if (ret) {
170 xhci_err(xhci, "Failed to allocate MSI-X interrupt\n");
171 goto disable_msix;
172 }
173 xhci_dbg(xhci, "Finished setting up MSI-X\n");
174 return 0;
175
176disable_msix:
177 pci_disable_msix(pdev);
178free_entries:
179 kfree(xhci->msix_entries);
180 xhci->msix_entries = NULL;
181 return ret;
182}
183
184/* XXX: code duplication; can xhci_setup_msix call this? */
185/* Free any IRQs and disable MSI-X */
186static void xhci_cleanup_msix(struct xhci_hcd *xhci)
187{
188 struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
189 if (!xhci->msix_entries)
190 return;
191
192 free_irq(xhci->msix_entries[0].vector, xhci);
193 pci_disable_msix(pdev);
194 kfree(xhci->msix_entries);
195 xhci->msix_entries = NULL;
196 xhci_dbg(xhci, "Finished cleaning up MSI-X\n");
197}
198#endif
199
200/*
201 * Initialize memory for HCD and xHC (one-time init).
202 *
203 * Program the PAGESIZE register, initialize the device context array, create
204 * device contexts (?), set up a command ring segment (or two?), create event
205 * ring (one for now).
206 */
207int xhci_init(struct usb_hcd *hcd)
208{
209 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
210 int retval = 0;
211
212 xhci_dbg(xhci, "xhci_init\n");
213 spin_lock_init(&xhci->lock);
214 retval = xhci_mem_init(xhci, GFP_KERNEL);
215 xhci_dbg(xhci, "Finished xhci_init\n");
216
217 return retval;
218}
219
220/*
221 * Start the HC after it was halted.
222 *
223 * This function is called by the USB core when the HC driver is added.
224 * Its opposite is xhci_stop().
225 *
226 * xhci_init() must be called once before this function can be called.
227 * Reset the HC, enable device slot contexts, program DCBAAP, and
228 * set command ring pointer and event ring pointer.
229 *
230 * Setup MSI-X vectors and enable interrupts.
231 */
232int xhci_run(struct usb_hcd *hcd)
233{
234 u32 temp;
235 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
236 xhci_dbg(xhci, "xhci_run\n");
237
238#if 0 /* FIXME: MSI not setup yet */
239 /* Do this at the very last minute */
240 ret = xhci_setup_msix(xhci);
241 if (!ret)
242 return ret;
243
244 return -ENOSYS;
245#endif
246 xhci_dbg(xhci, "// Set the interrupt modulation register\n");
247 temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
248 temp &= 0xffff;
249 temp |= (u32) 160;
250 xhci_writel(xhci, temp, &xhci->ir_set->irq_control);
251
252 /* Set the HCD state before we enable the irqs */
253 hcd->state = HC_STATE_RUNNING;
254 temp = xhci_readl(xhci, &xhci->op_regs->command);
255 temp |= (CMD_EIE);
256 xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n",
257 temp);
258 xhci_writel(xhci, temp, &xhci->op_regs->command);
259
260 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
261 xhci_dbg(xhci, "// Enabling event ring interrupter 0x%x"
262 " by writing 0x%x to irq_pending\n",
263 (unsigned int) xhci->ir_set,
264 (unsigned int) ER_IRQ_ENABLE(temp));
265 xhci_writel(xhci, ER_IRQ_ENABLE(temp),
266 &xhci->ir_set->irq_pending);
267 xhci_print_ir_set(xhci, xhci->ir_set, 0);
268
269 temp = xhci_readl(xhci, &xhci->op_regs->command);
270 temp |= (CMD_RUN);
271 xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
272 temp);
273 xhci_writel(xhci, temp, &xhci->op_regs->command);
274 /* Flush PCI posted writes */
275 temp = xhci_readl(xhci, &xhci->op_regs->command);
276 xhci_dbg(xhci, "// @%x = 0x%x\n",
277 (unsigned int) &xhci->op_regs->command, temp);
278
279 xhci_dbg(xhci, "Finished xhci_run\n");
280 return 0;
281}
282
283/*
284 * Stop xHCI driver.
285 *
286 * This function is called by the USB core when the HC driver is removed.
287 * Its opposite is xhci_run().
288 *
289 * Disable device contexts, disable IRQs, and quiesce the HC.
290 * Reset the HC, finish any completed transactions, and cleanup memory.
291 */
292void xhci_stop(struct usb_hcd *hcd)
293{
294 u32 temp;
295 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
296
297 spin_lock_irq(&xhci->lock);
298 if (HC_IS_RUNNING(hcd->state))
299 xhci_quiesce(xhci);
300 xhci_halt(xhci);
301 xhci_reset(xhci);
302 spin_unlock_irq(&xhci->lock);
303
304#if 0 /* No MSI yet */
305 xhci_cleanup_msix(xhci);
306#endif
307 xhci_dbg(xhci, "// Disabling event ring interrupts\n");
308 temp = xhci_readl(xhci, &xhci->op_regs->status);
309 xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
310 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
311 xhci_writel(xhci, ER_IRQ_DISABLE(temp),
312 &xhci->ir_set->irq_pending);
313 xhci_print_ir_set(xhci, xhci->ir_set, 0);
314
315 xhci_dbg(xhci, "cleaning up memory\n");
316 xhci_mem_cleanup(xhci);
317 xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
318 xhci_readl(xhci, &xhci->op_regs->status));
319}
320
321/*
322 * Shutdown HC (not bus-specific)
323 *
324 * This is called when the machine is rebooting or halting. We assume that the
325 * machine will be powered off, and the HC's internal state will be reset.
326 * Don't bother to free memory.
327 */
328void xhci_shutdown(struct usb_hcd *hcd)
329{
330 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
331
332 spin_lock_irq(&xhci->lock);
333 xhci_halt(xhci);
334 spin_unlock_irq(&xhci->lock);
335
336#if 0
337 xhci_cleanup_msix(xhci);
338#endif
339
340 xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
341 xhci_readl(xhci, &xhci->op_regs->status));
342}
343
344int xhci_get_frame(struct usb_hcd *hcd)
345{
346 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
347 /* EHCI mods by the periodic size. Why? */
348 return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3;
349}
350
351MODULE_DESCRIPTION(DRIVER_DESC);
352MODULE_AUTHOR(DRIVER_AUTHOR);
353MODULE_LICENSE("GPL");
354
355static int __init xhci_hcd_init(void)
356{
357#ifdef CONFIG_PCI
358 int retval = 0;
359
360 retval = xhci_register_pci();
361
362 if (retval < 0) {
363 printk(KERN_DEBUG "Problem registering PCI driver.");
364 return retval;
365 }
366#endif
367 return 0;
368}
369module_init(xhci_hcd_init);
370
371static void __exit xhci_hcd_cleanup(void)
372{
373#ifdef CONFIG_PCI
374 xhci_unregister_pci();
375#endif
376}
377module_exit(xhci_hcd_cleanup);