~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/usb/dwc3/core.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * core.c - DesignWare USB3 DRD Controller Core file
 
3
 *
 
4
 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
 
5
 *
 
6
 * Authors: Felipe Balbi <balbi@ti.com>,
 
7
 *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 
8
 *
 
9
 * Redistribution and use in source and binary forms, with or without
 
10
 * modification, are permitted provided that the following conditions
 
11
 * are met:
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions, and the following disclaimer,
 
14
 *    without modification.
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in the
 
17
 *    documentation and/or other materials provided with the distribution.
 
18
 * 3. The names of the above-listed copyright holders may not be used
 
19
 *    to endorse or promote products derived from this software without
 
20
 *    specific prior written permission.
 
21
 *
 
22
 * ALTERNATIVELY, this software may be distributed under the terms of the
 
23
 * GNU General Public License ("GPL") version 2, as published by the Free
 
24
 * Software Foundation.
 
25
 *
 
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 
27
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
28
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
29
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
30
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
31
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
32
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
33
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
34
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
35
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
36
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
37
 */
 
38
 
 
39
#include <linux/module.h>
 
40
#include <linux/kernel.h>
 
41
#include <linux/slab.h>
 
42
#include <linux/spinlock.h>
 
43
#include <linux/platform_device.h>
 
44
#include <linux/pm_runtime.h>
 
45
#include <linux/interrupt.h>
 
46
#include <linux/ioport.h>
 
47
#include <linux/io.h>
 
48
#include <linux/list.h>
 
49
#include <linux/delay.h>
 
50
#include <linux/dma-mapping.h>
 
51
 
 
52
#include <linux/usb/ch9.h>
 
53
#include <linux/usb/gadget.h>
 
54
#include <linux/module.h>
 
55
 
 
56
#include "core.h"
 
57
#include "gadget.h"
 
58
#include "io.h"
 
59
 
 
60
#include "debug.h"
 
61
 
 
62
/**
 
63
 * dwc3_core_soft_reset - Issues core soft reset and PHY reset
 
64
 * @dwc: pointer to our context structure
 
65
 */
 
66
static void dwc3_core_soft_reset(struct dwc3 *dwc)
 
67
{
 
68
        u32             reg;
 
69
 
 
70
        /* Before Resetting PHY, put Core in Reset */
 
71
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 
72
        reg |= DWC3_GCTL_CORESOFTRESET;
 
73
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 
74
 
 
75
        /* Assert USB3 PHY reset */
 
76
        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
77
        reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
 
78
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
79
 
 
80
        /* Assert USB2 PHY reset */
 
81
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
82
        reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
 
83
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
84
 
 
85
        mdelay(100);
 
86
 
 
87
        /* Clear USB3 PHY reset */
 
88
        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
89
        reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
 
90
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
91
 
 
92
        /* Clear USB2 PHY reset */
 
93
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
94
        reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
 
95
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
96
 
 
97
        /* After PHYs are stable we can take Core out of reset state */
 
98
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 
99
        reg &= ~DWC3_GCTL_CORESOFTRESET;
 
100
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 
101
}
 
102
 
 
103
/**
 
104
 * dwc3_free_one_event_buffer - Frees one event buffer
 
105
 * @dwc: Pointer to our controller context structure
 
106
 * @evt: Pointer to event buffer to be freed
 
107
 */
 
108
static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
 
109
                struct dwc3_event_buffer *evt)
 
110
{
 
111
        dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
 
112
        kfree(evt);
 
113
}
 
114
 
 
115
/**
 
116
 * dwc3_alloc_one_event_buffer - Allocated one event buffer structure
 
117
 * @dwc: Pointer to our controller context structure
 
118
 * @length: size of the event buffer
 
119
 *
 
120
 * Returns a pointer to the allocated event buffer structure on succes
 
121
 * otherwise ERR_PTR(errno).
 
122
 */
 
123
static struct dwc3_event_buffer *__devinit
 
124
dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
 
125
{
 
126
        struct dwc3_event_buffer        *evt;
 
127
 
 
128
        evt = kzalloc(sizeof(*evt), GFP_KERNEL);
 
129
        if (!evt)
 
130
                return ERR_PTR(-ENOMEM);
 
131
 
 
132
        evt->dwc        = dwc;
 
133
        evt->length     = length;
 
134
        evt->buf        = dma_alloc_coherent(dwc->dev, length,
 
135
                        &evt->dma, GFP_KERNEL);
 
136
        if (!evt->buf) {
 
137
                kfree(evt);
 
138
                return ERR_PTR(-ENOMEM);
 
139
        }
 
140
 
 
141
        return evt;
 
142
}
 
143
 
 
144
/**
 
145
 * dwc3_free_event_buffers - frees all allocated event buffers
 
146
 * @dwc: Pointer to our controller context structure
 
147
 */
 
148
static void dwc3_free_event_buffers(struct dwc3 *dwc)
 
149
{
 
150
        struct dwc3_event_buffer        *evt;
 
151
        int i;
 
152
 
 
153
        for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
 
154
                evt = dwc->ev_buffs[i];
 
155
                if (evt) {
 
156
                        dwc3_free_one_event_buffer(dwc, evt);
 
157
                        dwc->ev_buffs[i] = NULL;
 
158
                }
 
159
        }
 
160
}
 
161
 
 
162
/**
 
163
 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
 
164
 * @dwc: Pointer to out controller context structure
 
165
 * @num: number of event buffers to allocate
 
166
 * @length: size of event buffer
 
167
 *
 
168
 * Returns 0 on success otherwise negative errno. In error the case, dwc
 
169
 * may contain some buffers allocated but not all which were requested.
 
170
 */
 
171
static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num,
 
172
                unsigned length)
 
173
{
 
174
        int                     i;
 
175
 
 
176
        for (i = 0; i < num; i++) {
 
177
                struct dwc3_event_buffer        *evt;
 
178
 
 
179
                evt = dwc3_alloc_one_event_buffer(dwc, length);
 
180
                if (IS_ERR(evt)) {
 
181
                        dev_err(dwc->dev, "can't allocate event buffer\n");
 
182
                        return PTR_ERR(evt);
 
183
                }
 
184
                dwc->ev_buffs[i] = evt;
 
185
        }
 
186
 
 
187
        return 0;
 
188
}
 
189
 
 
190
/**
 
191
 * dwc3_event_buffers_setup - setup our allocated event buffers
 
192
 * @dwc: Pointer to out controller context structure
 
193
 *
 
194
 * Returns 0 on success otherwise negative errno.
 
195
 */
 
196
static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
 
197
{
 
198
        struct dwc3_event_buffer        *evt;
 
199
        int                             n;
 
200
 
 
201
        for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
 
202
                evt = dwc->ev_buffs[n];
 
203
                dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
 
204
                                evt->buf, (unsigned long long) evt->dma,
 
205
                                evt->length);
 
206
 
 
207
                dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
 
208
                                lower_32_bits(evt->dma));
 
209
                dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
 
210
                                upper_32_bits(evt->dma));
 
211
                dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
 
212
                                evt->length & 0xffff);
 
213
                dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
 
214
        }
 
215
 
 
216
        return 0;
 
217
}
 
218
 
 
219
static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 
220
{
 
221
        struct dwc3_event_buffer        *evt;
 
222
        int                             n;
 
223
 
 
224
        for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
 
225
                evt = dwc->ev_buffs[n];
 
226
                dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
 
227
                dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
 
228
                dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);
 
229
                dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
 
230
        }
 
231
}
 
232
 
 
233
static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
 
234
{
 
235
        struct dwc3_hwparams    *parms = &dwc->hwparams;
 
236
 
 
237
        parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
 
238
        parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
 
239
        parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
 
240
        parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
 
241
        parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
 
242
        parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
 
243
        parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
 
244
        parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
 
245
        parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 
246
}
 
247
 
 
248
/**
 
249
 * dwc3_core_init - Low-level initialization of DWC3 Core
 
250
 * @dwc: Pointer to our controller context structure
 
251
 *
 
252
 * Returns 0 on success otherwise negative errno.
 
253
 */
 
254
static int __devinit dwc3_core_init(struct dwc3 *dwc)
 
255
{
 
256
        unsigned long           timeout;
 
257
        u32                     reg;
 
258
        int                     ret;
 
259
 
 
260
        reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
 
261
        /* This should read as U3 followed by revision number */
 
262
        if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
 
263
                dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
 
264
                ret = -ENODEV;
 
265
                goto err0;
 
266
        }
 
267
        dwc->revision = reg;
 
268
 
 
269
        dwc3_core_soft_reset(dwc);
 
270
 
 
271
        /* issue device SoftReset too */
 
272
        timeout = jiffies + msecs_to_jiffies(500);
 
273
        dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
 
274
        do {
 
275
                reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 
276
                if (!(reg & DWC3_DCTL_CSFTRST))
 
277
                        break;
 
278
 
 
279
                if (time_after(jiffies, timeout)) {
 
280
                        dev_err(dwc->dev, "Reset Timed Out\n");
 
281
                        ret = -ETIMEDOUT;
 
282
                        goto err0;
 
283
                }
 
284
 
 
285
                cpu_relax();
 
286
        } while (true);
 
287
 
 
288
        ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM,
 
289
                        DWC3_EVENT_BUFFERS_SIZE);
 
290
        if (ret) {
 
291
                dev_err(dwc->dev, "failed to allocate event buffers\n");
 
292
                ret = -ENOMEM;
 
293
                goto err1;
 
294
        }
 
295
 
 
296
        ret = dwc3_event_buffers_setup(dwc);
 
297
        if (ret) {
 
298
                dev_err(dwc->dev, "failed to setup event buffers\n");
 
299
                goto err1;
 
300
        }
 
301
 
 
302
        dwc3_cache_hwparams(dwc);
 
303
 
 
304
        return 0;
 
305
 
 
306
err1:
 
307
        dwc3_free_event_buffers(dwc);
 
308
 
 
309
err0:
 
310
        return ret;
 
311
}
 
312
 
 
313
static void dwc3_core_exit(struct dwc3 *dwc)
 
314
{
 
315
        dwc3_event_buffers_cleanup(dwc);
 
316
        dwc3_free_event_buffers(dwc);
 
317
}
 
318
 
 
319
#define DWC3_ALIGN_MASK         (16 - 1)
 
320
 
 
321
static int __devinit dwc3_probe(struct platform_device *pdev)
 
322
{
 
323
        const struct platform_device_id *id = platform_get_device_id(pdev);
 
324
        struct resource         *res;
 
325
        struct dwc3             *dwc;
 
326
        void __iomem            *regs;
 
327
        unsigned int            features = id->driver_data;
 
328
        int                     ret = -ENOMEM;
 
329
        int                     irq;
 
330
        void                    *mem;
 
331
 
 
332
        mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
 
333
        if (!mem) {
 
334
                dev_err(&pdev->dev, "not enough memory\n");
 
335
                goto err0;
 
336
        }
 
337
        dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
 
338
        dwc->mem = mem;
 
339
 
 
340
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
341
        if (!res) {
 
342
                dev_err(&pdev->dev, "missing resource\n");
 
343
                goto err1;
 
344
        }
 
345
 
 
346
        res = request_mem_region(res->start, resource_size(res),
 
347
                        dev_name(&pdev->dev));
 
348
        if (!res) {
 
349
                dev_err(&pdev->dev, "can't request mem region\n");
 
350
                goto err1;
 
351
        }
 
352
 
 
353
        regs = ioremap(res->start, resource_size(res));
 
354
        if (!regs) {
 
355
                dev_err(&pdev->dev, "ioremap failed\n");
 
356
                goto err2;
 
357
        }
 
358
 
 
359
        irq = platform_get_irq(pdev, 0);
 
360
        if (irq < 0) {
 
361
                dev_err(&pdev->dev, "missing IRQ\n");
 
362
                goto err3;
 
363
        }
 
364
 
 
365
        spin_lock_init(&dwc->lock);
 
366
        platform_set_drvdata(pdev, dwc);
 
367
 
 
368
        dwc->regs       = regs;
 
369
        dwc->regs_size  = resource_size(res);
 
370
        dwc->dev        = &pdev->dev;
 
371
        dwc->irq        = irq;
 
372
 
 
373
        pm_runtime_enable(&pdev->dev);
 
374
        pm_runtime_get_sync(&pdev->dev);
 
375
        pm_runtime_forbid(&pdev->dev);
 
376
 
 
377
        ret = dwc3_core_init(dwc);
 
378
        if (ret) {
 
379
                dev_err(&pdev->dev, "failed to initialize core\n");
 
380
                goto err3;
 
381
        }
 
382
 
 
383
        if (features & DWC3_HAS_PERIPHERAL) {
 
384
                ret = dwc3_gadget_init(dwc);
 
385
                if (ret) {
 
386
                        dev_err(&pdev->dev, "failed to initialized gadget\n");
 
387
                        goto err4;
 
388
                }
 
389
        }
 
390
 
 
391
        ret = dwc3_debugfs_init(dwc);
 
392
        if (ret) {
 
393
                dev_err(&pdev->dev, "failed to initialize debugfs\n");
 
394
                goto err5;
 
395
        }
 
396
 
 
397
        pm_runtime_allow(&pdev->dev);
 
398
 
 
399
        return 0;
 
400
 
 
401
err5:
 
402
        if (features & DWC3_HAS_PERIPHERAL)
 
403
                dwc3_gadget_exit(dwc);
 
404
 
 
405
err4:
 
406
        dwc3_core_exit(dwc);
 
407
 
 
408
err3:
 
409
        iounmap(regs);
 
410
 
 
411
err2:
 
412
        release_mem_region(res->start, resource_size(res));
 
413
 
 
414
err1:
 
415
        kfree(dwc->mem);
 
416
 
 
417
err0:
 
418
        return ret;
 
419
}
 
420
 
 
421
static int __devexit dwc3_remove(struct platform_device *pdev)
 
422
{
 
423
        const struct platform_device_id *id = platform_get_device_id(pdev);
 
424
        struct dwc3     *dwc = platform_get_drvdata(pdev);
 
425
        struct resource *res;
 
426
        unsigned int    features = id->driver_data;
 
427
 
 
428
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
429
 
 
430
        pm_runtime_put(&pdev->dev);
 
431
        pm_runtime_disable(&pdev->dev);
 
432
 
 
433
        dwc3_debugfs_exit(dwc);
 
434
 
 
435
        if (features & DWC3_HAS_PERIPHERAL)
 
436
                dwc3_gadget_exit(dwc);
 
437
 
 
438
        dwc3_core_exit(dwc);
 
439
        release_mem_region(res->start, resource_size(res));
 
440
        iounmap(dwc->regs);
 
441
        kfree(dwc->mem);
 
442
 
 
443
        return 0;
 
444
}
 
445
 
 
446
static const struct platform_device_id dwc3_id_table[] __devinitconst = {
 
447
        {
 
448
                .name   = "dwc3-omap",
 
449
                .driver_data = (DWC3_HAS_PERIPHERAL
 
450
                        | DWC3_HAS_XHCI
 
451
                        | DWC3_HAS_OTG),
 
452
        },
 
453
        {
 
454
                .name   = "dwc3-pci",
 
455
                .driver_data = DWC3_HAS_PERIPHERAL,
 
456
        },
 
457
        {  },   /* Terminating Entry */
 
458
};
 
459
MODULE_DEVICE_TABLE(platform, dwc3_id_table);
 
460
 
 
461
static struct platform_driver dwc3_driver = {
 
462
        .probe          = dwc3_probe,
 
463
        .remove         = __devexit_p(dwc3_remove),
 
464
        .driver         = {
 
465
                .name   = "dwc3",
 
466
        },
 
467
        .id_table       = dwc3_id_table,
 
468
};
 
469
 
 
470
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
 
471
MODULE_LICENSE("Dual BSD/GPL");
 
472
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
 
473
 
 
474
static int __devinit dwc3_init(void)
 
475
{
 
476
        return platform_driver_register(&dwc3_driver);
 
477
}
 
478
module_init(dwc3_init);
 
479
 
 
480
static void __exit dwc3_exit(void)
 
481
{
 
482
        platform_driver_unregister(&dwc3_driver);
 
483
}
 
484
module_exit(dwc3_exit);