ARM: davinci: Make __clk_{enable,disable} functions public
[linux-2.6-block.git] / arch / arm / mach-davinci / usb-da8xx.c
CommitLineData
86cad160
DL
1/*
2 * DA8xx USB
3 */
0004b02a
DL
4#include <linux/clk.h>
5#include <linux/delay.h>
86cad160
DL
6#include <linux/dma-mapping.h>
7#include <linux/init.h>
0004b02a 8#include <linux/mfd/da8xx-cfgchip.h>
9b504750 9#include <linux/phy/phy.h>
86cad160
DL
10#include <linux/platform_data/usb-davinci.h>
11#include <linux/platform_device.h>
12#include <linux/usb/musb.h>
13
0004b02a 14#include <mach/clock.h>
86cad160
DL
15#include <mach/common.h>
16#include <mach/cputype.h>
17#include <mach/da8xx.h>
18#include <mach/irqs.h>
19
0004b02a
DL
20#include "clock.h"
21
86cad160
DL
22#define DA8XX_USB0_BASE 0x01e00000
23#define DA8XX_USB1_BASE 0x01e25000
24
9b504750
DL
25static struct platform_device da8xx_usb_phy = {
26 .name = "da8xx-usb-phy",
27 .id = -1,
0004b02a
DL
28 .dev = {
29 /*
30 * Setting init_name so that clock lookup will work in
31 * da8xx_register_usb11_phy_clk() even if this device is not
32 * registered yet.
33 */
34 .init_name = "da8xx-usb-phy",
35 },
9b504750
DL
36};
37
38int __init da8xx_register_usb_phy(void)
39{
40 return platform_device_register(&da8xx_usb_phy);
41}
42
86cad160
DL
43static struct musb_hdrc_config musb_config = {
44 .multipoint = true,
45 .num_eps = 5,
46 .ram_bits = 10,
47};
48
49static struct musb_hdrc_platform_data usb_data = {
50 /* OTG requires a Mini-AB connector */
51 .mode = MUSB_OTG,
52 .clock = "usb20",
53 .config = &musb_config,
54};
55
56static struct resource da8xx_usb20_resources[] = {
57 {
58 .start = DA8XX_USB0_BASE,
59 .end = DA8XX_USB0_BASE + SZ_64K - 1,
60 .flags = IORESOURCE_MEM,
61 },
62 {
63 .start = IRQ_DA8XX_USB_INT,
64 .flags = IORESOURCE_IRQ,
65 .name = "mc",
66 },
67};
68
69static u64 usb_dmamask = DMA_BIT_MASK(32);
70
0004b02a 71static struct platform_device da8xx_usb20_dev = {
86cad160
DL
72 .name = "musb-da8xx",
73 .id = -1,
74 .dev = {
0004b02a
DL
75 /*
76 * Setting init_name so that clock lookup will work in
77 * usb20_phy_clk_enable() even if this device is not registered.
78 */
79 .init_name = "musb-da8xx",
86cad160
DL
80 .platform_data = &usb_data,
81 .dma_mask = &usb_dmamask,
82 .coherent_dma_mask = DMA_BIT_MASK(32),
83 },
84 .resource = da8xx_usb20_resources,
85 .num_resources = ARRAY_SIZE(da8xx_usb20_resources),
86};
87
88int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
89{
90 usb_data.power = mA > 510 ? 255 : mA / 2;
91 usb_data.potpgt = (potpgt + 1) / 2;
92
0004b02a 93 return platform_device_register(&da8xx_usb20_dev);
86cad160
DL
94}
95
86cad160
DL
96static struct resource da8xx_usb11_resources[] = {
97 [0] = {
98 .start = DA8XX_USB1_BASE,
99 .end = DA8XX_USB1_BASE + SZ_4K - 1,
100 .flags = IORESOURCE_MEM,
101 },
102 [1] = {
103 .start = IRQ_DA8XX_IRQN,
104 .end = IRQ_DA8XX_IRQN,
105 .flags = IORESOURCE_IRQ,
106 },
107};
108
109static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
110
111static struct platform_device da8xx_usb11_device = {
8439a1d7
AH
112 .name = "ohci-da8xx",
113 .id = -1,
86cad160
DL
114 .dev = {
115 .dma_mask = &da8xx_usb11_dma_mask,
116 .coherent_dma_mask = DMA_BIT_MASK(32),
117 },
118 .num_resources = ARRAY_SIZE(da8xx_usb11_resources),
119 .resource = da8xx_usb11_resources,
120};
121
122int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
123{
124 da8xx_usb11_device.dev.platform_data = pdata;
125 return platform_device_register(&da8xx_usb11_device);
126}
0004b02a
DL
127
128static struct clk usb_refclkin = {
129 .name = "usb_refclkin",
130 .set_rate = davinci_simple_set_rate,
131};
132
133static struct clk_lookup usb_refclkin_lookup =
134 CLK(NULL, "usb_refclkin", &usb_refclkin);
135
136/**
137 * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
138 *
139 * @rate: The clock rate in Hz
140 *
141 * This clock is only needed if the board provides an external USB_REFCLKIN
142 * signal, in which case it will be used as the parent of usb20_phy_clk and/or
143 * usb11_phy_clk.
144 */
145int __init da8xx_register_usb_refclkin(int rate)
146{
147 int ret;
148
149 usb_refclkin.rate = rate;
150 ret = clk_register(&usb_refclkin);
151 if (ret)
152 return ret;
153
154 clkdev_add(&usb_refclkin_lookup);
155
156 return 0;
157}
158
159static void usb20_phy_clk_enable(struct clk *clk)
160{
161 struct clk *usb20_clk;
162 int err;
163 u32 val;
164 u32 timeout = 500000; /* 500 msec */
165
166 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
167
168 usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
169 if (IS_ERR(usb20_clk)) {
170 pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
171 return;
172 }
173
174 /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
175 err = clk_prepare_enable(usb20_clk);
176 if (err) {
177 pr_err("failed to enable usb20 clk: %d\n", err);
178 clk_put(usb20_clk);
179 return;
180 }
181
182 /*
183 * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
184 * host may use the PLL clock without USB 2.0 OTG being used.
185 */
186 val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
187 val |= CFGCHIP2_PHY_PLLON;
188
189 writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
190
191 while (--timeout) {
192 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
193 if (val & CFGCHIP2_PHYCLKGD)
194 goto done;
195 udelay(1);
196 }
197
198 pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
199done:
200 clk_disable_unprepare(usb20_clk);
201 clk_put(usb20_clk);
202}
203
204static void usb20_phy_clk_disable(struct clk *clk)
205{
206 u32 val;
207
208 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
209 val |= CFGCHIP2_PHYPWRDN;
210 writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
211}
212
213static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
214{
215 u32 val;
216
217 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
218
219 /* Set the mux depending on the parent clock. */
220 if (parent == &usb_refclkin) {
221 val &= ~CFGCHIP2_USB2PHYCLKMUX;
222 } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
223 val |= CFGCHIP2_USB2PHYCLKMUX;
224 } else {
225 pr_err("Bad parent on USB 2.0 PHY clock\n");
226 return -EINVAL;
227 }
228
229 /* reference frequency also comes from parent clock */
230 val &= ~CFGCHIP2_REFFREQ_MASK;
231 switch (clk_get_rate(parent)) {
232 case 12000000:
233 val |= CFGCHIP2_REFFREQ_12MHZ;
234 break;
235 case 13000000:
236 val |= CFGCHIP2_REFFREQ_13MHZ;
237 break;
238 case 19200000:
239 val |= CFGCHIP2_REFFREQ_19_2MHZ;
240 break;
241 case 20000000:
242 val |= CFGCHIP2_REFFREQ_20MHZ;
243 break;
244 case 24000000:
245 val |= CFGCHIP2_REFFREQ_24MHZ;
246 break;
247 case 26000000:
248 val |= CFGCHIP2_REFFREQ_26MHZ;
249 break;
250 case 38400000:
251 val |= CFGCHIP2_REFFREQ_38_4MHZ;
252 break;
253 case 40000000:
254 val |= CFGCHIP2_REFFREQ_40MHZ;
255 break;
256 case 48000000:
257 val |= CFGCHIP2_REFFREQ_48MHZ;
258 break;
259 default:
260 pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
261 return -EINVAL;
262 }
263
264 writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
265
266 return 0;
267}
268
269static struct clk usb20_phy_clk = {
270 .name = "usb20_phy",
271 .clk_enable = usb20_phy_clk_enable,
272 .clk_disable = usb20_phy_clk_disable,
273 .set_parent = usb20_phy_clk_set_parent,
274};
275
276static struct clk_lookup usb20_phy_clk_lookup =
277 CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
278
279/**
280 * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
281 *
282 * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
283 * or "pll0_aux" if false.
284 */
285int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
286{
287 struct clk *parent;
288 int ret = 0;
289
290 parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
291 if (IS_ERR(parent))
292 return PTR_ERR(parent);
293
294 usb20_phy_clk.parent = parent;
295 ret = clk_register(&usb20_phy_clk);
296 if (!ret)
297 clkdev_add(&usb20_phy_clk_lookup);
298
299 clk_put(parent);
300
301 return ret;
302}
303
304static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
305{
306 u32 val;
307
308 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
309
310 /* Set the USB 1.1 PHY clock mux based on the parent clock. */
311 if (parent == &usb20_phy_clk) {
312 val &= ~CFGCHIP2_USB1PHYCLKMUX;
313 } else if (parent == &usb_refclkin) {
314 val |= CFGCHIP2_USB1PHYCLKMUX;
315 } else {
316 pr_err("Bad parent on USB 1.1 PHY clock\n");
317 return -EINVAL;
318 }
319
320 writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
321
322 return 0;
323}
324
325static struct clk usb11_phy_clk = {
326 .name = "usb11_phy",
327 .set_parent = usb11_phy_clk_set_parent,
328};
329
330static struct clk_lookup usb11_phy_clk_lookup =
331 CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
332
333/**
334 * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
335 *
336 * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
337 * or "usb20_phy" if false.
338 */
339int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
340{
341 struct clk *parent;
342 int ret = 0;
343
344 if (use_usb_refclkin)
345 parent = clk_get(NULL, "usb_refclkin");
346 else
347 parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
348 if (IS_ERR(parent))
349 return PTR_ERR(parent);
350
351 usb11_phy_clk.parent = parent;
352 ret = clk_register(&usb11_phy_clk);
353 if (!ret)
354 clkdev_add(&usb11_phy_clk_lookup);
355
356 clk_put(parent);
357
358 return ret;
359}