]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/blob - arch/arm/mach-omap2/usb-fs.c
ARM: OMAP: AM33XX: Remove autoidle regs
[sitara-epos/sitara-epos-kernel.git] / arch / arm / mach-omap2 / usb-fs.c
1 /*
2  * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
3  *
4  * Copyright (C) 2004 Texas Instruments, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/types.h>
24 #include <linux/errno.h>
25 #include <linux/init.h>
26 #include <linux/platform_device.h>
27 #include <linux/clk.h>
28 #include <linux/err.h>
30 #include <asm/irq.h>
32 #include <plat/usb.h>
33 #include <plat/board.h>
35 #include "control.h"
36 #include "mux.h"
38 #define INT_USB_IRQ_GEN         INT_24XX_USB_IRQ_GEN
39 #define INT_USB_IRQ_NISO        INT_24XX_USB_IRQ_NISO
40 #define INT_USB_IRQ_ISO         INT_24XX_USB_IRQ_ISO
41 #define INT_USB_IRQ_HGEN        INT_24XX_USB_IRQ_HGEN
42 #define INT_USB_IRQ_OTG         INT_24XX_USB_IRQ_OTG
44 #if defined(CONFIG_ARCH_OMAP2)
46 #ifdef  CONFIG_USB_GADGET_OMAP
48 static struct resource udc_resources[] = {
49         /* order is significant! */
50         {               /* registers */
51                 .start          = UDC_BASE,
52                 .end            = UDC_BASE + 0xff,
53                 .flags          = IORESOURCE_MEM,
54         }, {            /* general IRQ */
55                 .start          = INT_USB_IRQ_GEN,
56                 .flags          = IORESOURCE_IRQ,
57         }, {            /* PIO IRQ */
58                 .start          = INT_USB_IRQ_NISO,
59                 .flags          = IORESOURCE_IRQ,
60         }, {            /* SOF IRQ */
61                 .start          = INT_USB_IRQ_ISO,
62                 .flags          = IORESOURCE_IRQ,
63         },
64 };
66 static u64 udc_dmamask = ~(u32)0;
68 static struct platform_device udc_device = {
69         .name           = "omap_udc",
70         .id             = -1,
71         .dev = {
72                 .dma_mask               = &udc_dmamask,
73                 .coherent_dma_mask      = 0xffffffff,
74         },
75         .num_resources  = ARRAY_SIZE(udc_resources),
76         .resource       = udc_resources,
77 };
79 static inline void udc_device_init(struct omap_usb_config *pdata)
80 {
81         pdata->udc_device = &udc_device;
82 }
84 #else
86 static inline void udc_device_init(struct omap_usb_config *pdata)
87 {
88 }
90 #endif
92 #if     defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
94 /* The dmamask must be set for OHCI to work */
95 static u64 ohci_dmamask = ~(u32)0;
97 static struct resource ohci_resources[] = {
98         {
99                 .start  = OMAP_OHCI_BASE,
100                 .end    = OMAP_OHCI_BASE + 0xff,
101                 .flags  = IORESOURCE_MEM,
102         },
103         {
104                 .start  = INT_USB_IRQ_HGEN,
105                 .flags  = IORESOURCE_IRQ,
106         },
107 };
109 static struct platform_device ohci_device = {
110         .name                   = "ohci",
111         .id                     = -1,
112         .dev = {
113                 .dma_mask               = &ohci_dmamask,
114                 .coherent_dma_mask      = 0xffffffff,
115         },
116         .num_resources  = ARRAY_SIZE(ohci_resources),
117         .resource               = ohci_resources,
118 };
120 static inline void ohci_device_init(struct omap_usb_config *pdata)
122         pdata->ohci_device = &ohci_device;
125 #else
127 static inline void ohci_device_init(struct omap_usb_config *pdata)
131 #endif
133 #if     defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
135 static struct resource otg_resources[] = {
136         /* order is significant! */
137         {
138                 .start          = OTG_BASE,
139                 .end            = OTG_BASE + 0xff,
140                 .flags          = IORESOURCE_MEM,
141         }, {
142                 .start          = INT_USB_IRQ_OTG,
143                 .flags          = IORESOURCE_IRQ,
144         },
145 };
147 static struct platform_device otg_device = {
148         .name           = "omap_otg",
149         .id             = -1,
150         .num_resources  = ARRAY_SIZE(otg_resources),
151         .resource       = otg_resources,
152 };
154 static inline void otg_device_init(struct omap_usb_config *pdata)
156         pdata->otg_device = &otg_device;
159 #else
161 static inline void otg_device_init(struct omap_usb_config *pdata)
165 #endif
167 static void omap2_usb_devconf_clear(u8 port, u32 mask)
169         u32 r;
171         r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
172         r &= ~USBTXWRMODEI(port, mask);
173         omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
176 static void omap2_usb_devconf_set(u8 port, u32 mask)
178         u32 r;
180         r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
181         r |= USBTXWRMODEI(port, mask);
182         omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
185 static void omap2_usb2_disable_5pinbitll(void)
187         u32 r;
189         r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
190         r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI);
191         omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
194 static void omap2_usb2_enable_5pinunitll(void)
196         u32 r;
198         r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
199         r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI;
200         omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
203 static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device)
205         u32     syscon1 = 0;
207         omap2_usb_devconf_clear(0, USB_BIDIR_TLL);
209         if (nwires == 0)
210                 return 0;
212         if (is_device)
213                 omap_mux_init_signal("usb0_puen", 0);
215         omap_mux_init_signal("usb0_dat", 0);
216         omap_mux_init_signal("usb0_txen", 0);
217         omap_mux_init_signal("usb0_se0", 0);
218         if (nwires != 3)
219                 omap_mux_init_signal("usb0_rcv", 0);
221         switch (nwires) {
222         case 3:
223                 syscon1 = 2;
224                 omap2_usb_devconf_set(0, USB_BIDIR);
225                 break;
226         case 4:
227                 syscon1 = 1;
228                 omap2_usb_devconf_set(0, USB_BIDIR);
229                 break;
230         case 6:
231                 syscon1 = 3;
232                 omap_mux_init_signal("usb0_vp", 0);
233                 omap_mux_init_signal("usb0_vm", 0);
234                 omap2_usb_devconf_set(0, USB_UNIDIR);
235                 break;
236         default:
237                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
238                         0, nwires);
239         }
241         return syscon1 << 16;
244 static u32 __init omap2_usb1_init(unsigned nwires)
246         u32     syscon1 = 0;
248         omap2_usb_devconf_clear(1, USB_BIDIR_TLL);
250         if (nwires == 0)
251                 return 0;
253         /* NOTE:  board-specific code must set up pin muxing for usb1,
254          * since each signal could come out on either of two balls.
255          */
257         switch (nwires) {
258         case 2:
259                 /* NOTE: board-specific code must override this setting if
260                  * this TLL link is not using DP/DM
261                  */
262                 syscon1 = 1;
263                 omap2_usb_devconf_set(1, USB_BIDIR_TLL);
264                 break;
265         case 3:
266                 syscon1 = 2;
267                 omap2_usb_devconf_set(1, USB_BIDIR);
268                 break;
269         case 4:
270                 syscon1 = 1;
271                 omap2_usb_devconf_set(1, USB_BIDIR);
272                 break;
273         case 6:
274         default:
275                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
276                         1, nwires);
277         }
279         return syscon1 << 20;
282 static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup)
284         u32     syscon1 = 0;
286         omap2_usb2_disable_5pinbitll();
287         alt_pingroup = 0;
289         /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
290         if (alt_pingroup || nwires == 0)
291                 return 0;
293         omap_mux_init_signal("usb2_dat", 0);
294         omap_mux_init_signal("usb2_se0", 0);
295         if (nwires > 2)
296                 omap_mux_init_signal("usb2_txen", 0);
297         if (nwires > 3)
298                 omap_mux_init_signal("usb2_rcv", 0);
300         switch (nwires) {
301         case 2:
302                 /* NOTE: board-specific code must override this setting if
303                  * this TLL link is not using DP/DM
304                  */
305                 syscon1 = 1;
306                 omap2_usb_devconf_set(2, USB_BIDIR_TLL);
307                 break;
308         case 3:
309                 syscon1 = 2;
310                 omap2_usb_devconf_set(2, USB_BIDIR);
311                 break;
312         case 4:
313                 syscon1 = 1;
314                 omap2_usb_devconf_set(2, USB_BIDIR);
315                 break;
316         case 5:
317                 /* NOTE: board-specific code must mux this setting depending
318                  * on TLL link using DP/DM.  Something must also
319                  * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
320                  * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0
321                  * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0
322                  */
324                 syscon1 = 3;
325                 omap2_usb2_enable_5pinunitll();
326                 break;
327         case 6:
328         default:
329                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
330                         2, nwires);
331         }
333         return syscon1 << 24;
336 void __init omap2_usbfs_init(struct omap_usb_config *pdata)
338         struct clk *ick;
340         if (!cpu_is_omap24xx())
341                 return;
343         ick = clk_get(NULL, "usb_l4_ick");
344         if (IS_ERR(ick))
345                 return;
347         clk_enable(ick);
348         pdata->usb0_init = omap2_usb0_init;
349         pdata->usb1_init = omap2_usb1_init;
350         pdata->usb2_init = omap2_usb2_init;
351         udc_device_init(pdata);
352         ohci_device_init(pdata);
353         otg_device_init(pdata);
354         omap_otg_init(pdata);
355         clk_disable(ick);
356         clk_put(ick);
359 #endif