172246da4SFelipe Balbi /** 272246da4SFelipe Balbi * core.c - DesignWare USB3 DRD Controller Core file 372246da4SFelipe Balbi * 472246da4SFelipe Balbi * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com 572246da4SFelipe Balbi * 672246da4SFelipe Balbi * Authors: Felipe Balbi <balbi@ti.com>, 772246da4SFelipe Balbi * Sebastian Andrzej Siewior <bigeasy@linutronix.de> 872246da4SFelipe Balbi * 972246da4SFelipe Balbi * Redistribution and use in source and binary forms, with or without 1072246da4SFelipe Balbi * modification, are permitted provided that the following conditions 1172246da4SFelipe Balbi * are met: 1272246da4SFelipe Balbi * 1. Redistributions of source code must retain the above copyright 1372246da4SFelipe Balbi * notice, this list of conditions, and the following disclaimer, 1472246da4SFelipe Balbi * without modification. 1572246da4SFelipe Balbi * 2. Redistributions in binary form must reproduce the above copyright 1672246da4SFelipe Balbi * notice, this list of conditions and the following disclaimer in the 1772246da4SFelipe Balbi * documentation and/or other materials provided with the distribution. 1872246da4SFelipe Balbi * 3. The names of the above-listed copyright holders may not be used 1972246da4SFelipe Balbi * to endorse or promote products derived from this software without 2072246da4SFelipe Balbi * specific prior written permission. 2172246da4SFelipe Balbi * 2272246da4SFelipe Balbi * ALTERNATIVELY, this software may be distributed under the terms of the 2372246da4SFelipe Balbi * GNU General Public License ("GPL") version 2, as published by the Free 2472246da4SFelipe Balbi * Software Foundation. 2572246da4SFelipe Balbi * 2672246da4SFelipe Balbi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 2772246da4SFelipe Balbi * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2872246da4SFelipe Balbi * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2972246da4SFelipe Balbi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 3072246da4SFelipe Balbi * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 3172246da4SFelipe Balbi * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 3272246da4SFelipe Balbi * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3372246da4SFelipe Balbi * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3472246da4SFelipe Balbi * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3572246da4SFelipe Balbi * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3672246da4SFelipe Balbi * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3772246da4SFelipe Balbi */ 3872246da4SFelipe Balbi 39a72e658bSFelipe Balbi #include <linux/module.h> 4072246da4SFelipe Balbi #include <linux/kernel.h> 4172246da4SFelipe Balbi #include <linux/slab.h> 4272246da4SFelipe Balbi #include <linux/spinlock.h> 4372246da4SFelipe Balbi #include <linux/platform_device.h> 4472246da4SFelipe Balbi #include <linux/pm_runtime.h> 4572246da4SFelipe Balbi #include <linux/interrupt.h> 4672246da4SFelipe Balbi #include <linux/ioport.h> 4772246da4SFelipe Balbi #include <linux/io.h> 4872246da4SFelipe Balbi #include <linux/list.h> 4972246da4SFelipe Balbi #include <linux/delay.h> 5072246da4SFelipe Balbi #include <linux/dma-mapping.h> 5172246da4SFelipe Balbi 5272246da4SFelipe Balbi #include <linux/usb/ch9.h> 5372246da4SFelipe Balbi #include <linux/usb/gadget.h> 542204fdeeSPaul Gortmaker #include <linux/module.h> 5572246da4SFelipe Balbi 5672246da4SFelipe Balbi #include "core.h" 5772246da4SFelipe Balbi #include "gadget.h" 5872246da4SFelipe Balbi #include "io.h" 5972246da4SFelipe Balbi 6072246da4SFelipe Balbi #include "debug.h" 6172246da4SFelipe Balbi 626c167fc9SFelipe Balbi static char *maximum_speed = "super"; 636c167fc9SFelipe Balbi module_param(maximum_speed, charp, 0); 646c167fc9SFelipe Balbi MODULE_PARM_DESC(maximum_speed, "Maximum supported speed."); 656c167fc9SFelipe Balbi 66*8300dd23SFelipe Balbi /* -------------------------------------------------------------------------- */ 67*8300dd23SFelipe Balbi 68*8300dd23SFelipe Balbi #define DWC3_DEVS_POSSIBLE 32 69*8300dd23SFelipe Balbi 70*8300dd23SFelipe Balbi static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE); 71*8300dd23SFelipe Balbi 72*8300dd23SFelipe Balbi int dwc3_get_device_id(void) 73*8300dd23SFelipe Balbi { 74*8300dd23SFelipe Balbi int id; 75*8300dd23SFelipe Balbi 76*8300dd23SFelipe Balbi again: 77*8300dd23SFelipe Balbi id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE); 78*8300dd23SFelipe Balbi if (id < DWC3_DEVS_POSSIBLE) { 79*8300dd23SFelipe Balbi int old; 80*8300dd23SFelipe Balbi 81*8300dd23SFelipe Balbi old = test_and_set_bit(id, dwc3_devs); 82*8300dd23SFelipe Balbi if (old) 83*8300dd23SFelipe Balbi goto again; 84*8300dd23SFelipe Balbi } else { 85*8300dd23SFelipe Balbi pr_err("dwc3: no space for new device\n"); 86*8300dd23SFelipe Balbi id = -ENOMEM; 87*8300dd23SFelipe Balbi } 88*8300dd23SFelipe Balbi 89*8300dd23SFelipe Balbi return 0; 90*8300dd23SFelipe Balbi } 91*8300dd23SFelipe Balbi EXPORT_SYMBOL_GPL(dwc3_get_device_id); 92*8300dd23SFelipe Balbi 93*8300dd23SFelipe Balbi void dwc3_put_device_id(int id) 94*8300dd23SFelipe Balbi { 95*8300dd23SFelipe Balbi int ret; 96*8300dd23SFelipe Balbi 97*8300dd23SFelipe Balbi if (id < 0) 98*8300dd23SFelipe Balbi return; 99*8300dd23SFelipe Balbi 100*8300dd23SFelipe Balbi ret = test_bit(id, dwc3_devs); 101*8300dd23SFelipe Balbi WARN(!ret, "dwc3: ID %d not in use\n", id); 102*8300dd23SFelipe Balbi clear_bit(id, dwc3_devs); 103*8300dd23SFelipe Balbi } 104*8300dd23SFelipe Balbi EXPORT_SYMBOL_GPL(dwc3_put_device_id); 105*8300dd23SFelipe Balbi 106*8300dd23SFelipe Balbi /* -------------------------------------------------------------------------- */ 107*8300dd23SFelipe Balbi 10872246da4SFelipe Balbi /** 10972246da4SFelipe Balbi * dwc3_core_soft_reset - Issues core soft reset and PHY reset 11072246da4SFelipe Balbi * @dwc: pointer to our context structure 11172246da4SFelipe Balbi */ 11272246da4SFelipe Balbi static void dwc3_core_soft_reset(struct dwc3 *dwc) 11372246da4SFelipe Balbi { 11472246da4SFelipe Balbi u32 reg; 11572246da4SFelipe Balbi 11672246da4SFelipe Balbi /* Before Resetting PHY, put Core in Reset */ 11772246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GCTL); 11872246da4SFelipe Balbi reg |= DWC3_GCTL_CORESOFTRESET; 11972246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GCTL, reg); 12072246da4SFelipe Balbi 12172246da4SFelipe Balbi /* Assert USB3 PHY reset */ 12272246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); 12372246da4SFelipe Balbi reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; 12472246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); 12572246da4SFelipe Balbi 12672246da4SFelipe Balbi /* Assert USB2 PHY reset */ 12772246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 12872246da4SFelipe Balbi reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; 12972246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 13072246da4SFelipe Balbi 13172246da4SFelipe Balbi mdelay(100); 13272246da4SFelipe Balbi 13372246da4SFelipe Balbi /* Clear USB3 PHY reset */ 13472246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); 13572246da4SFelipe Balbi reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; 13672246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); 13772246da4SFelipe Balbi 13872246da4SFelipe Balbi /* Clear USB2 PHY reset */ 13972246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 14072246da4SFelipe Balbi reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; 14172246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 14272246da4SFelipe Balbi 14372246da4SFelipe Balbi /* After PHYs are stable we can take Core out of reset state */ 14472246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_GCTL); 14572246da4SFelipe Balbi reg &= ~DWC3_GCTL_CORESOFTRESET; 14672246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GCTL, reg); 14772246da4SFelipe Balbi } 14872246da4SFelipe Balbi 14972246da4SFelipe Balbi /** 15072246da4SFelipe Balbi * dwc3_free_one_event_buffer - Frees one event buffer 15172246da4SFelipe Balbi * @dwc: Pointer to our controller context structure 15272246da4SFelipe Balbi * @evt: Pointer to event buffer to be freed 15372246da4SFelipe Balbi */ 15472246da4SFelipe Balbi static void dwc3_free_one_event_buffer(struct dwc3 *dwc, 15572246da4SFelipe Balbi struct dwc3_event_buffer *evt) 15672246da4SFelipe Balbi { 15772246da4SFelipe Balbi dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma); 15872246da4SFelipe Balbi kfree(evt); 15972246da4SFelipe Balbi } 16072246da4SFelipe Balbi 16172246da4SFelipe Balbi /** 16272246da4SFelipe Balbi * dwc3_alloc_one_event_buffer - Allocated one event buffer structure 16372246da4SFelipe Balbi * @dwc: Pointer to our controller context structure 16472246da4SFelipe Balbi * @length: size of the event buffer 16572246da4SFelipe Balbi * 16672246da4SFelipe Balbi * Returns a pointer to the allocated event buffer structure on succes 16772246da4SFelipe Balbi * otherwise ERR_PTR(errno). 16872246da4SFelipe Balbi */ 16972246da4SFelipe Balbi static struct dwc3_event_buffer *__devinit 17072246da4SFelipe Balbi dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) 17172246da4SFelipe Balbi { 17272246da4SFelipe Balbi struct dwc3_event_buffer *evt; 17372246da4SFelipe Balbi 17472246da4SFelipe Balbi evt = kzalloc(sizeof(*evt), GFP_KERNEL); 17572246da4SFelipe Balbi if (!evt) 17672246da4SFelipe Balbi return ERR_PTR(-ENOMEM); 17772246da4SFelipe Balbi 17872246da4SFelipe Balbi evt->dwc = dwc; 17972246da4SFelipe Balbi evt->length = length; 18072246da4SFelipe Balbi evt->buf = dma_alloc_coherent(dwc->dev, length, 18172246da4SFelipe Balbi &evt->dma, GFP_KERNEL); 18272246da4SFelipe Balbi if (!evt->buf) { 18372246da4SFelipe Balbi kfree(evt); 18472246da4SFelipe Balbi return ERR_PTR(-ENOMEM); 18572246da4SFelipe Balbi } 18672246da4SFelipe Balbi 18772246da4SFelipe Balbi return evt; 18872246da4SFelipe Balbi } 18972246da4SFelipe Balbi 19072246da4SFelipe Balbi /** 19172246da4SFelipe Balbi * dwc3_free_event_buffers - frees all allocated event buffers 19272246da4SFelipe Balbi * @dwc: Pointer to our controller context structure 19372246da4SFelipe Balbi */ 19472246da4SFelipe Balbi static void dwc3_free_event_buffers(struct dwc3 *dwc) 19572246da4SFelipe Balbi { 19672246da4SFelipe Balbi struct dwc3_event_buffer *evt; 19772246da4SFelipe Balbi int i; 19872246da4SFelipe Balbi 1999f622b2aSFelipe Balbi for (i = 0; i < dwc->num_event_buffers; i++) { 20072246da4SFelipe Balbi evt = dwc->ev_buffs[i]; 20172246da4SFelipe Balbi if (evt) { 20272246da4SFelipe Balbi dwc3_free_one_event_buffer(dwc, evt); 20372246da4SFelipe Balbi dwc->ev_buffs[i] = NULL; 20472246da4SFelipe Balbi } 20572246da4SFelipe Balbi } 20672246da4SFelipe Balbi } 20772246da4SFelipe Balbi 20872246da4SFelipe Balbi /** 20972246da4SFelipe Balbi * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length 21072246da4SFelipe Balbi * @dwc: Pointer to out controller context structure 21172246da4SFelipe Balbi * @length: size of event buffer 21272246da4SFelipe Balbi * 21372246da4SFelipe Balbi * Returns 0 on success otherwise negative errno. In error the case, dwc 21472246da4SFelipe Balbi * may contain some buffers allocated but not all which were requested. 21572246da4SFelipe Balbi */ 2169f622b2aSFelipe Balbi static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) 21772246da4SFelipe Balbi { 2189f622b2aSFelipe Balbi int num; 21972246da4SFelipe Balbi int i; 22072246da4SFelipe Balbi 2219f622b2aSFelipe Balbi num = DWC3_NUM_INT(dwc->hwparams.hwparams1); 2229f622b2aSFelipe Balbi dwc->num_event_buffers = num; 2239f622b2aSFelipe Balbi 22472246da4SFelipe Balbi for (i = 0; i < num; i++) { 22572246da4SFelipe Balbi struct dwc3_event_buffer *evt; 22672246da4SFelipe Balbi 22772246da4SFelipe Balbi evt = dwc3_alloc_one_event_buffer(dwc, length); 22872246da4SFelipe Balbi if (IS_ERR(evt)) { 22972246da4SFelipe Balbi dev_err(dwc->dev, "can't allocate event buffer\n"); 23072246da4SFelipe Balbi return PTR_ERR(evt); 23172246da4SFelipe Balbi } 23272246da4SFelipe Balbi dwc->ev_buffs[i] = evt; 23372246da4SFelipe Balbi } 23472246da4SFelipe Balbi 23572246da4SFelipe Balbi return 0; 23672246da4SFelipe Balbi } 23772246da4SFelipe Balbi 23872246da4SFelipe Balbi /** 23972246da4SFelipe Balbi * dwc3_event_buffers_setup - setup our allocated event buffers 24072246da4SFelipe Balbi * @dwc: Pointer to out controller context structure 24172246da4SFelipe Balbi * 24272246da4SFelipe Balbi * Returns 0 on success otherwise negative errno. 24372246da4SFelipe Balbi */ 24472246da4SFelipe Balbi static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc) 24572246da4SFelipe Balbi { 24672246da4SFelipe Balbi struct dwc3_event_buffer *evt; 24772246da4SFelipe Balbi int n; 24872246da4SFelipe Balbi 2499f622b2aSFelipe Balbi for (n = 0; n < dwc->num_event_buffers; n++) { 25072246da4SFelipe Balbi evt = dwc->ev_buffs[n]; 25172246da4SFelipe Balbi dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n", 25272246da4SFelipe Balbi evt->buf, (unsigned long long) evt->dma, 25372246da4SFelipe Balbi evt->length); 25472246da4SFelipe Balbi 25572246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 25672246da4SFelipe Balbi lower_32_bits(evt->dma)); 25772246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 25872246da4SFelipe Balbi upper_32_bits(evt->dma)); 25972246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 26072246da4SFelipe Balbi evt->length & 0xffff); 26172246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); 26272246da4SFelipe Balbi } 26372246da4SFelipe Balbi 26472246da4SFelipe Balbi return 0; 26572246da4SFelipe Balbi } 26672246da4SFelipe Balbi 26772246da4SFelipe Balbi static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) 26872246da4SFelipe Balbi { 26972246da4SFelipe Balbi struct dwc3_event_buffer *evt; 27072246da4SFelipe Balbi int n; 27172246da4SFelipe Balbi 2729f622b2aSFelipe Balbi for (n = 0; n < dwc->num_event_buffers; n++) { 27372246da4SFelipe Balbi evt = dwc->ev_buffs[n]; 27472246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0); 27572246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0); 27672246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0); 27772246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); 27872246da4SFelipe Balbi } 27972246da4SFelipe Balbi } 28072246da4SFelipe Balbi 28126ceca97SFelipe Balbi static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc) 28226ceca97SFelipe Balbi { 28326ceca97SFelipe Balbi struct dwc3_hwparams *parms = &dwc->hwparams; 28426ceca97SFelipe Balbi 28526ceca97SFelipe Balbi parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0); 28626ceca97SFelipe Balbi parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1); 28726ceca97SFelipe Balbi parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2); 28826ceca97SFelipe Balbi parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3); 28926ceca97SFelipe Balbi parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4); 29026ceca97SFelipe Balbi parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5); 29126ceca97SFelipe Balbi parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); 29226ceca97SFelipe Balbi parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); 29326ceca97SFelipe Balbi parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); 29426ceca97SFelipe Balbi } 29526ceca97SFelipe Balbi 29672246da4SFelipe Balbi /** 29772246da4SFelipe Balbi * dwc3_core_init - Low-level initialization of DWC3 Core 29872246da4SFelipe Balbi * @dwc: Pointer to our controller context structure 29972246da4SFelipe Balbi * 30072246da4SFelipe Balbi * Returns 0 on success otherwise negative errno. 30172246da4SFelipe Balbi */ 30272246da4SFelipe Balbi static int __devinit dwc3_core_init(struct dwc3 *dwc) 30372246da4SFelipe Balbi { 30472246da4SFelipe Balbi unsigned long timeout; 30572246da4SFelipe Balbi u32 reg; 30672246da4SFelipe Balbi int ret; 30772246da4SFelipe Balbi 3087650bd74SSebastian Andrzej Siewior reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); 3097650bd74SSebastian Andrzej Siewior /* This should read as U3 followed by revision number */ 3107650bd74SSebastian Andrzej Siewior if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) { 3117650bd74SSebastian Andrzej Siewior dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); 3127650bd74SSebastian Andrzej Siewior ret = -ENODEV; 3137650bd74SSebastian Andrzej Siewior goto err0; 3147650bd74SSebastian Andrzej Siewior } 3157650bd74SSebastian Andrzej Siewior dwc->revision = reg & DWC3_GSNPSREV_MASK; 3167650bd74SSebastian Andrzej Siewior 31772246da4SFelipe Balbi dwc3_core_soft_reset(dwc); 31872246da4SFelipe Balbi 31972246da4SFelipe Balbi /* issue device SoftReset too */ 32072246da4SFelipe Balbi timeout = jiffies + msecs_to_jiffies(500); 32172246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); 32272246da4SFelipe Balbi do { 32372246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_DCTL); 32472246da4SFelipe Balbi if (!(reg & DWC3_DCTL_CSFTRST)) 32572246da4SFelipe Balbi break; 32672246da4SFelipe Balbi 32772246da4SFelipe Balbi if (time_after(jiffies, timeout)) { 32872246da4SFelipe Balbi dev_err(dwc->dev, "Reset Timed Out\n"); 32972246da4SFelipe Balbi ret = -ETIMEDOUT; 33072246da4SFelipe Balbi goto err0; 33172246da4SFelipe Balbi } 33272246da4SFelipe Balbi 33372246da4SFelipe Balbi cpu_relax(); 33472246da4SFelipe Balbi } while (true); 33572246da4SFelipe Balbi 3369f622b2aSFelipe Balbi dwc3_cache_hwparams(dwc); 3379f622b2aSFelipe Balbi 3389f622b2aSFelipe Balbi ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); 33972246da4SFelipe Balbi if (ret) { 34072246da4SFelipe Balbi dev_err(dwc->dev, "failed to allocate event buffers\n"); 34172246da4SFelipe Balbi ret = -ENOMEM; 34272246da4SFelipe Balbi goto err1; 34372246da4SFelipe Balbi } 34472246da4SFelipe Balbi 34572246da4SFelipe Balbi ret = dwc3_event_buffers_setup(dwc); 34672246da4SFelipe Balbi if (ret) { 34772246da4SFelipe Balbi dev_err(dwc->dev, "failed to setup event buffers\n"); 34872246da4SFelipe Balbi goto err1; 34972246da4SFelipe Balbi } 35072246da4SFelipe Balbi 35172246da4SFelipe Balbi return 0; 35272246da4SFelipe Balbi 35372246da4SFelipe Balbi err1: 35472246da4SFelipe Balbi dwc3_free_event_buffers(dwc); 35572246da4SFelipe Balbi 35672246da4SFelipe Balbi err0: 35772246da4SFelipe Balbi return ret; 35872246da4SFelipe Balbi } 35972246da4SFelipe Balbi 36072246da4SFelipe Balbi static void dwc3_core_exit(struct dwc3 *dwc) 36172246da4SFelipe Balbi { 36272246da4SFelipe Balbi dwc3_event_buffers_cleanup(dwc); 36372246da4SFelipe Balbi dwc3_free_event_buffers(dwc); 36472246da4SFelipe Balbi } 36572246da4SFelipe Balbi 36672246da4SFelipe Balbi #define DWC3_ALIGN_MASK (16 - 1) 36772246da4SFelipe Balbi 36872246da4SFelipe Balbi static int __devinit dwc3_probe(struct platform_device *pdev) 36972246da4SFelipe Balbi { 37072246da4SFelipe Balbi struct resource *res; 37172246da4SFelipe Balbi struct dwc3 *dwc; 3720949e99bSFelipe Balbi 37372246da4SFelipe Balbi int ret = -ENOMEM; 37472246da4SFelipe Balbi int irq; 3750949e99bSFelipe Balbi 3760949e99bSFelipe Balbi void __iomem *regs; 37772246da4SFelipe Balbi void *mem; 37872246da4SFelipe Balbi 3790949e99bSFelipe Balbi u8 mode; 3800949e99bSFelipe Balbi 38172246da4SFelipe Balbi mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); 38272246da4SFelipe Balbi if (!mem) { 38372246da4SFelipe Balbi dev_err(&pdev->dev, "not enough memory\n"); 38472246da4SFelipe Balbi goto err0; 38572246da4SFelipe Balbi } 38672246da4SFelipe Balbi dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); 38772246da4SFelipe Balbi dwc->mem = mem; 38872246da4SFelipe Balbi 38972246da4SFelipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 39072246da4SFelipe Balbi if (!res) { 39172246da4SFelipe Balbi dev_err(&pdev->dev, "missing resource\n"); 39272246da4SFelipe Balbi goto err1; 39372246da4SFelipe Balbi } 39472246da4SFelipe Balbi 395d07e8819SFelipe Balbi dwc->res = res; 396d07e8819SFelipe Balbi 39772246da4SFelipe Balbi res = request_mem_region(res->start, resource_size(res), 39872246da4SFelipe Balbi dev_name(&pdev->dev)); 39972246da4SFelipe Balbi if (!res) { 40072246da4SFelipe Balbi dev_err(&pdev->dev, "can't request mem region\n"); 40172246da4SFelipe Balbi goto err1; 40272246da4SFelipe Balbi } 40372246da4SFelipe Balbi 40472246da4SFelipe Balbi regs = ioremap(res->start, resource_size(res)); 40572246da4SFelipe Balbi if (!regs) { 40672246da4SFelipe Balbi dev_err(&pdev->dev, "ioremap failed\n"); 40772246da4SFelipe Balbi goto err2; 40872246da4SFelipe Balbi } 40972246da4SFelipe Balbi 41072246da4SFelipe Balbi irq = platform_get_irq(pdev, 0); 41172246da4SFelipe Balbi if (irq < 0) { 41272246da4SFelipe Balbi dev_err(&pdev->dev, "missing IRQ\n"); 41372246da4SFelipe Balbi goto err3; 41472246da4SFelipe Balbi } 41572246da4SFelipe Balbi 41672246da4SFelipe Balbi spin_lock_init(&dwc->lock); 41772246da4SFelipe Balbi platform_set_drvdata(pdev, dwc); 41872246da4SFelipe Balbi 41972246da4SFelipe Balbi dwc->regs = regs; 42072246da4SFelipe Balbi dwc->regs_size = resource_size(res); 42172246da4SFelipe Balbi dwc->dev = &pdev->dev; 42272246da4SFelipe Balbi dwc->irq = irq; 42372246da4SFelipe Balbi 4246c167fc9SFelipe Balbi if (!strncmp("super", maximum_speed, 5)) 4256c167fc9SFelipe Balbi dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; 4266c167fc9SFelipe Balbi else if (!strncmp("high", maximum_speed, 4)) 4276c167fc9SFelipe Balbi dwc->maximum_speed = DWC3_DCFG_HIGHSPEED; 4286c167fc9SFelipe Balbi else if (!strncmp("full", maximum_speed, 4)) 4296c167fc9SFelipe Balbi dwc->maximum_speed = DWC3_DCFG_FULLSPEED1; 4306c167fc9SFelipe Balbi else if (!strncmp("low", maximum_speed, 3)) 4316c167fc9SFelipe Balbi dwc->maximum_speed = DWC3_DCFG_LOWSPEED; 4326c167fc9SFelipe Balbi else 4336c167fc9SFelipe Balbi dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; 4346c167fc9SFelipe Balbi 43572246da4SFelipe Balbi pm_runtime_enable(&pdev->dev); 43672246da4SFelipe Balbi pm_runtime_get_sync(&pdev->dev); 43772246da4SFelipe Balbi pm_runtime_forbid(&pdev->dev); 43872246da4SFelipe Balbi 43972246da4SFelipe Balbi ret = dwc3_core_init(dwc); 44072246da4SFelipe Balbi if (ret) { 44172246da4SFelipe Balbi dev_err(&pdev->dev, "failed to initialize core\n"); 44272246da4SFelipe Balbi goto err3; 44372246da4SFelipe Balbi } 44472246da4SFelipe Balbi 4450949e99bSFelipe Balbi mode = DWC3_MODE(dwc->hwparams.hwparams0); 4460949e99bSFelipe Balbi 4470949e99bSFelipe Balbi switch (mode) { 4480949e99bSFelipe Balbi case DWC3_MODE_DEVICE: 44972246da4SFelipe Balbi ret = dwc3_gadget_init(dwc); 45072246da4SFelipe Balbi if (ret) { 4510949e99bSFelipe Balbi dev_err(&pdev->dev, "failed to initialize gadget\n"); 45272246da4SFelipe Balbi goto err4; 45372246da4SFelipe Balbi } 4540949e99bSFelipe Balbi break; 455d07e8819SFelipe Balbi case DWC3_MODE_HOST: 456d07e8819SFelipe Balbi ret = dwc3_host_init(dwc); 457d07e8819SFelipe Balbi if (ret) { 458d07e8819SFelipe Balbi dev_err(&pdev->dev, "failed to initialize host\n"); 459d07e8819SFelipe Balbi goto err4; 460d07e8819SFelipe Balbi } 461d07e8819SFelipe Balbi break; 462d07e8819SFelipe Balbi case DWC3_MODE_DRD: 463d07e8819SFelipe Balbi ret = dwc3_host_init(dwc); 464d07e8819SFelipe Balbi if (ret) { 465d07e8819SFelipe Balbi dev_err(&pdev->dev, "failed to initialize host\n"); 466d07e8819SFelipe Balbi goto err4; 467d07e8819SFelipe Balbi } 468d07e8819SFelipe Balbi 469d07e8819SFelipe Balbi ret = dwc3_gadget_init(dwc); 470d07e8819SFelipe Balbi if (ret) { 471d07e8819SFelipe Balbi dev_err(&pdev->dev, "failed to initialize gadget\n"); 472d07e8819SFelipe Balbi goto err4; 473d07e8819SFelipe Balbi } 474d07e8819SFelipe Balbi break; 4750949e99bSFelipe Balbi default: 4760949e99bSFelipe Balbi dev_err(&pdev->dev, "Unsupported mode of operation %d\n", mode); 4770949e99bSFelipe Balbi goto err4; 47872246da4SFelipe Balbi } 4790949e99bSFelipe Balbi dwc->mode = mode; 48072246da4SFelipe Balbi 48172246da4SFelipe Balbi ret = dwc3_debugfs_init(dwc); 48272246da4SFelipe Balbi if (ret) { 48372246da4SFelipe Balbi dev_err(&pdev->dev, "failed to initialize debugfs\n"); 48472246da4SFelipe Balbi goto err5; 48572246da4SFelipe Balbi } 48672246da4SFelipe Balbi 48772246da4SFelipe Balbi pm_runtime_allow(&pdev->dev); 48872246da4SFelipe Balbi 48972246da4SFelipe Balbi return 0; 49072246da4SFelipe Balbi 49172246da4SFelipe Balbi err5: 4920949e99bSFelipe Balbi switch (mode) { 4930949e99bSFelipe Balbi case DWC3_MODE_DEVICE: 49472246da4SFelipe Balbi dwc3_gadget_exit(dwc); 4950949e99bSFelipe Balbi break; 496d07e8819SFelipe Balbi case DWC3_MODE_HOST: 497d07e8819SFelipe Balbi dwc3_host_exit(dwc); 498d07e8819SFelipe Balbi break; 499d07e8819SFelipe Balbi case DWC3_MODE_DRD: 500d07e8819SFelipe Balbi dwc3_host_exit(dwc); 501d07e8819SFelipe Balbi dwc3_gadget_exit(dwc); 502d07e8819SFelipe Balbi break; 5030949e99bSFelipe Balbi default: 5040949e99bSFelipe Balbi /* do nothing */ 5050949e99bSFelipe Balbi break; 5060949e99bSFelipe Balbi } 50772246da4SFelipe Balbi 50872246da4SFelipe Balbi err4: 50972246da4SFelipe Balbi dwc3_core_exit(dwc); 51072246da4SFelipe Balbi 51172246da4SFelipe Balbi err3: 51272246da4SFelipe Balbi iounmap(regs); 51372246da4SFelipe Balbi 51472246da4SFelipe Balbi err2: 51572246da4SFelipe Balbi release_mem_region(res->start, resource_size(res)); 51672246da4SFelipe Balbi 51772246da4SFelipe Balbi err1: 51872246da4SFelipe Balbi kfree(dwc->mem); 51972246da4SFelipe Balbi 52072246da4SFelipe Balbi err0: 52172246da4SFelipe Balbi return ret; 52272246da4SFelipe Balbi } 52372246da4SFelipe Balbi 52472246da4SFelipe Balbi static int __devexit dwc3_remove(struct platform_device *pdev) 52572246da4SFelipe Balbi { 52672246da4SFelipe Balbi struct dwc3 *dwc = platform_get_drvdata(pdev); 52772246da4SFelipe Balbi struct resource *res; 52872246da4SFelipe Balbi 52972246da4SFelipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 53072246da4SFelipe Balbi 53172246da4SFelipe Balbi pm_runtime_put(&pdev->dev); 53272246da4SFelipe Balbi pm_runtime_disable(&pdev->dev); 53372246da4SFelipe Balbi 53472246da4SFelipe Balbi dwc3_debugfs_exit(dwc); 53572246da4SFelipe Balbi 5360949e99bSFelipe Balbi switch (dwc->mode) { 5370949e99bSFelipe Balbi case DWC3_MODE_DEVICE: 53872246da4SFelipe Balbi dwc3_gadget_exit(dwc); 5390949e99bSFelipe Balbi break; 540d07e8819SFelipe Balbi case DWC3_MODE_HOST: 541d07e8819SFelipe Balbi dwc3_host_exit(dwc); 542d07e8819SFelipe Balbi break; 543d07e8819SFelipe Balbi case DWC3_MODE_DRD: 544d07e8819SFelipe Balbi dwc3_host_exit(dwc); 545d07e8819SFelipe Balbi dwc3_gadget_exit(dwc); 546d07e8819SFelipe Balbi break; 5470949e99bSFelipe Balbi default: 5480949e99bSFelipe Balbi /* do nothing */ 5490949e99bSFelipe Balbi break; 5500949e99bSFelipe Balbi } 55172246da4SFelipe Balbi 55272246da4SFelipe Balbi dwc3_core_exit(dwc); 55372246da4SFelipe Balbi release_mem_region(res->start, resource_size(res)); 55472246da4SFelipe Balbi iounmap(dwc->regs); 55572246da4SFelipe Balbi kfree(dwc->mem); 55672246da4SFelipe Balbi 55772246da4SFelipe Balbi return 0; 55872246da4SFelipe Balbi } 55972246da4SFelipe Balbi 56072246da4SFelipe Balbi static struct platform_driver dwc3_driver = { 56172246da4SFelipe Balbi .probe = dwc3_probe, 56272246da4SFelipe Balbi .remove = __devexit_p(dwc3_remove), 56372246da4SFelipe Balbi .driver = { 56472246da4SFelipe Balbi .name = "dwc3", 56572246da4SFelipe Balbi }, 56672246da4SFelipe Balbi }; 56772246da4SFelipe Balbi 5687ae4fc4dSSebastian Andrzej Siewior MODULE_ALIAS("platform:dwc3"); 56972246da4SFelipe Balbi MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 57072246da4SFelipe Balbi MODULE_LICENSE("Dual BSD/GPL"); 57172246da4SFelipe Balbi MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); 57272246da4SFelipe Balbi 57372246da4SFelipe Balbi static int __devinit dwc3_init(void) 57472246da4SFelipe Balbi { 57572246da4SFelipe Balbi return platform_driver_register(&dwc3_driver); 57672246da4SFelipe Balbi } 57772246da4SFelipe Balbi module_init(dwc3_init); 57872246da4SFelipe Balbi 57972246da4SFelipe Balbi static void __exit dwc3_exit(void) 58072246da4SFelipe Balbi { 58172246da4SFelipe Balbi platform_driver_unregister(&dwc3_driver); 58272246da4SFelipe Balbi } 58372246da4SFelipe Balbi module_exit(dwc3_exit); 584