OMAP3 SRF: Generic shared resource f/w
[linux-ginger.git] / arch / arm / mach-omap2 / usb-musb.c
blobf5364b850e1ccb1ebec1d5b436b68270deca7928
1 /*
2 * linux/arch/arm/mach-omap2/usb-musb.c
4 * This file will contain the board specific details for the
5 * MENTOR USB OTG controller on OMAP3430
7 * Copyright (C) 2007-2008 Texas Instruments
8 * Copyright (C) 2008 Nokia Corporation
9 * Author: Vikram Pandita
11 * Generalization by:
12 * Felipe Balbi <felipe.balbi@nokia.com>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
19 #include <linux/types.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
22 #include <linux/platform_device.h>
23 #include <linux/clk.h>
24 #include <linux/dma-mapping.h>
25 #include <linux/io.h>
27 #include <linux/usb/musb.h>
29 #include <asm/sizes.h>
31 #include <mach/hardware.h>
32 #include <mach/irqs.h>
33 #include <plat/mux.h>
34 #include <plat/usb.h>
36 #define OTG_SYSCONFIG 0x404
37 #define OTG_SYSC_SOFTRESET BIT(1)
38 #define OTG_SYSSTATUS 0x408
39 #define OTG_SYSS_RESETDONE BIT(0)
41 static struct platform_device dummy_pdev = {
42 .dev = {
43 .bus = &platform_bus_type,
47 static void __init usb_musb_pm_init(void)
49 void __iomem *otg_base;
50 struct clk *otg_clk;
51 struct device *dev = &dummy_pdev.dev;
53 if (!cpu_is_omap34xx())
54 return;
56 otg_base = ioremap(OMAP34XX_HSUSB_OTG_BASE, SZ_4K);
57 if (WARN_ON(!otg_base))
58 return;
60 dev_set_name(dev, "musb_hdrc");
61 otg_clk = clk_get(dev, "ick");
63 if (otg_clk && clk_enable(otg_clk)) {
64 printk(KERN_WARNING
65 "%s: Unable to enable clocks for MUSB, "
66 "cannot reset.\n", __func__);
67 } else {
68 /* Reset OTG controller. After reset, it will be in
69 * force-idle, force-standby mode. */
70 __raw_writel(OTG_SYSC_SOFTRESET, otg_base + OTG_SYSCONFIG);
72 while (!(OTG_SYSS_RESETDONE &
73 __raw_readl(otg_base + OTG_SYSSTATUS)))
74 cpu_relax();
77 if (otg_clk) {
78 clk_disable(otg_clk);
79 clk_put(otg_clk);
82 iounmap(otg_base);
85 #ifdef CONFIG_USB_MUSB_SOC
87 static struct resource musb_resources[] = {
88 [0] = { /* start and end set dynamically */
89 .flags = IORESOURCE_MEM,
91 [1] = { /* general IRQ */
92 .start = INT_243X_HS_USB_MC,
93 .flags = IORESOURCE_IRQ,
95 [2] = { /* DMA IRQ */
96 .start = INT_243X_HS_USB_DMA,
97 .flags = IORESOURCE_IRQ,
101 static int clk_on;
103 static int musb_set_clock(struct clk *clk, int state)
105 if (state) {
106 if (clk_on > 0)
107 return -ENODEV;
109 clk_enable(clk);
110 clk_on = 1;
111 } else {
112 if (clk_on == 0)
113 return -ENODEV;
115 clk_disable(clk);
116 clk_on = 0;
119 return 0;
122 static struct musb_hdrc_eps_bits musb_eps[] = {
123 { "ep1_tx", 10, },
124 { "ep1_rx", 10, },
125 { "ep2_tx", 9, },
126 { "ep2_rx", 9, },
127 { "ep3_tx", 3, },
128 { "ep3_rx", 3, },
129 { "ep4_tx", 3, },
130 { "ep4_rx", 3, },
131 { "ep5_tx", 3, },
132 { "ep5_rx", 3, },
133 { "ep6_tx", 3, },
134 { "ep6_rx", 3, },
135 { "ep7_tx", 3, },
136 { "ep7_rx", 3, },
137 { "ep8_tx", 2, },
138 { "ep8_rx", 2, },
139 { "ep9_tx", 2, },
140 { "ep9_rx", 2, },
141 { "ep10_tx", 2, },
142 { "ep10_rx", 2, },
143 { "ep11_tx", 2, },
144 { "ep11_rx", 2, },
145 { "ep12_tx", 2, },
146 { "ep12_rx", 2, },
147 { "ep13_tx", 2, },
148 { "ep13_rx", 2, },
149 { "ep14_tx", 2, },
150 { "ep14_rx", 2, },
151 { "ep15_tx", 2, },
152 { "ep15_rx", 2, },
155 static struct musb_hdrc_config musb_config = {
156 .multipoint = 1,
157 .dyn_fifo = 1,
158 .soft_con = 1,
159 .dma = 1,
160 .num_eps = 16,
161 .dma_channels = 7,
162 .dma_req_chan = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
163 .ram_bits = 12,
164 .eps_bits = musb_eps,
167 static struct musb_hdrc_platform_data musb_plat = {
168 #ifdef CONFIG_USB_MUSB_OTG
169 .mode = MUSB_OTG,
170 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
171 .mode = MUSB_HOST,
172 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
173 .mode = MUSB_PERIPHERAL,
174 #endif
175 /* .clock is set dynamically */
176 .set_clock = musb_set_clock,
177 .config = &musb_config,
179 /* REVISIT charge pump on TWL4030 can supply up to
180 * 100 mA ... but this value is board-specific, like
181 * "mode", and should be passed to usb_musb_init().
183 .power = 50, /* up to 100 mA */
186 static u64 musb_dmamask = DMA_BIT_MASK(32);
188 static struct platform_device musb_device = {
189 .name = "musb_hdrc",
190 .id = -1,
191 .dev = {
192 .dma_mask = &musb_dmamask,
193 .coherent_dma_mask = DMA_BIT_MASK(32),
194 .platform_data = &musb_plat,
196 .num_resources = ARRAY_SIZE(musb_resources),
197 .resource = musb_resources,
200 void __init usb_musb_init(void)
202 if (cpu_is_omap243x())
203 musb_resources[0].start = OMAP243X_HS_BASE;
204 else
205 musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
206 musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
209 * REVISIT: This line can be removed once all the platforms using
210 * musb_core.c have been converted to use use clkdev.
212 musb_plat.clock = "ick";
214 if (platform_device_register(&musb_device) < 0) {
215 printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
216 return;
219 usb_musb_pm_init();
222 #else
223 void __init usb_musb_init(void)
225 usb_musb_pm_init();
227 #endif /* CONFIG_USB_MUSB_SOC */