ARM: OMAP3: mmc-twl4030 allow arbitrary slot names, v3
[deliverable/linux.git] / arch / arm / mach-omap2 / devices.c
CommitLineData
1dbae815
TL
1/*
2 * linux/arch/arm/mach-omap2/devices.c
3 *
4 * OMAP2 platform device setup/initialization
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
1dbae815
TL
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
fced80c7 16#include <linux/io.h>
917fa280 17#include <linux/clk.h>
1dbae815 18
a09e64fb 19#include <mach/hardware.h>
1dbae815
TL
20#include <asm/mach-types.h>
21#include <asm/mach/map.h>
22
90c62bf0 23#include <mach/control.h>
a09e64fb
RK
24#include <mach/tc.h>
25#include <mach/board.h>
26#include <mach/mux.h>
27#include <mach/gpio.h>
646e3ed1 28#include <mach/eac.h>
d8874665 29#include <mach/mmc.h>
1dbae815 30
6c20a683 31#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
c40fae95 32
6c20a683
HD
33#define MBOX_REG_SIZE 0x120
34
35static struct resource omap2_mbox_resources[] = {
c40fae95 36 {
6c20a683
HD
37 .start = OMAP24XX_MAILBOX_BASE,
38 .end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
c40fae95
TL
39 .flags = IORESOURCE_MEM,
40 },
41 {
42 .start = INT_24XX_MAIL_U0_MPU,
43 .flags = IORESOURCE_IRQ,
44 },
45 {
46 .start = INT_24XX_MAIL_U3_MPU,
47 .flags = IORESOURCE_IRQ,
48 },
49};
50
6c20a683
HD
51static struct resource omap3_mbox_resources[] = {
52 {
53 .start = OMAP34XX_MAILBOX_BASE,
54 .end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
55 .flags = IORESOURCE_MEM,
56 },
57 {
58 .start = INT_24XX_MAIL_U0_MPU,
59 .flags = IORESOURCE_IRQ,
60 },
61};
62
c40fae95 63static struct platform_device mbox_device = {
da8cfe03 64 .name = "omap2-mailbox",
c40fae95 65 .id = -1,
c40fae95
TL
66};
67
68static inline void omap_init_mbox(void)
69{
6c20a683
HD
70 if (cpu_is_omap2420()) {
71 mbox_device.num_resources = ARRAY_SIZE(omap2_mbox_resources);
72 mbox_device.resource = omap2_mbox_resources;
73 } else if (cpu_is_omap3430()) {
74 mbox_device.num_resources = ARRAY_SIZE(omap3_mbox_resources);
75 mbox_device.resource = omap3_mbox_resources;
76 } else {
77 pr_err("%s: platform not supported\n", __func__);
78 return;
79 }
c40fae95
TL
80 platform_device_register(&mbox_device);
81}
82#else
83static inline void omap_init_mbox(void) { }
6c20a683 84#endif /* CONFIG_OMAP_MBOX_FWK */
c40fae95 85
9b6553cd
TL
86#if defined(CONFIG_OMAP_STI)
87
646e3ed1
TL
88#if defined(CONFIG_ARCH_OMAP2)
89
90#define OMAP2_STI_BASE 0x48068000
9b6553cd
TL
91#define OMAP2_STI_CHANNEL_BASE 0x54000000
92#define OMAP2_STI_IRQ 4
93
94static struct resource sti_resources[] = {
95 {
96 .start = OMAP2_STI_BASE,
97 .end = OMAP2_STI_BASE + 0x7ff,
98 .flags = IORESOURCE_MEM,
99 },
100 {
101 .start = OMAP2_STI_CHANNEL_BASE,
102 .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
103 .flags = IORESOURCE_MEM,
104 },
105 {
106 .start = OMAP2_STI_IRQ,
107 .flags = IORESOURCE_IRQ,
108 }
109};
646e3ed1
TL
110#elif defined(CONFIG_ARCH_OMAP3)
111
112#define OMAP3_SDTI_BASE 0x54500000
113#define OMAP3_SDTI_CHANNEL_BASE 0x54600000
114
115static struct resource sti_resources[] = {
116 {
117 .start = OMAP3_SDTI_BASE,
118 .end = OMAP3_SDTI_BASE + 0xFFF,
119 .flags = IORESOURCE_MEM,
120 },
121 {
122 .start = OMAP3_SDTI_CHANNEL_BASE,
123 .end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1,
124 .flags = IORESOURCE_MEM,
125 }
126};
127
128#endif
9b6553cd
TL
129
130static struct platform_device sti_device = {
131 .name = "sti",
132 .id = -1,
9b6553cd
TL
133 .num_resources = ARRAY_SIZE(sti_resources),
134 .resource = sti_resources,
135};
136
137static inline void omap_init_sti(void)
138{
139 platform_device_register(&sti_device);
140}
141#else
142static inline void omap_init_sti(void) {}
143#endif
144
646e3ed1 145#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
ed7eb9d9 146
a09e64fb 147#include <mach/mcspi.h>
ed7eb9d9
JY
148
149#define OMAP2_MCSPI1_BASE 0x48098000
150#define OMAP2_MCSPI2_BASE 0x4809a000
646e3ed1
TL
151#define OMAP2_MCSPI3_BASE 0x480b8000
152#define OMAP2_MCSPI4_BASE 0x480ba000
ed7eb9d9 153
ed7eb9d9 154static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
ed7eb9d9
JY
155 .num_cs = 4,
156};
157
c40fae95
TL
158static struct resource omap2_mcspi1_resources[] = {
159 {
160 .start = OMAP2_MCSPI1_BASE,
161 .end = OMAP2_MCSPI1_BASE + 0xff,
162 .flags = IORESOURCE_MEM,
163 },
164};
165
646e3ed1 166static struct platform_device omap2_mcspi1 = {
ed7eb9d9
JY
167 .name = "omap2_mcspi",
168 .id = 1,
c40fae95
TL
169 .num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
170 .resource = omap2_mcspi1_resources,
ed7eb9d9
JY
171 .dev = {
172 .platform_data = &omap2_mcspi1_config,
173 },
174};
175
176static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
ed7eb9d9
JY
177 .num_cs = 2,
178};
179
c40fae95
TL
180static struct resource omap2_mcspi2_resources[] = {
181 {
182 .start = OMAP2_MCSPI2_BASE,
183 .end = OMAP2_MCSPI2_BASE + 0xff,
184 .flags = IORESOURCE_MEM,
185 },
186};
187
646e3ed1 188static struct platform_device omap2_mcspi2 = {
ed7eb9d9
JY
189 .name = "omap2_mcspi",
190 .id = 2,
c40fae95
TL
191 .num_resources = ARRAY_SIZE(omap2_mcspi2_resources),
192 .resource = omap2_mcspi2_resources,
ed7eb9d9
JY
193 .dev = {
194 .platform_data = &omap2_mcspi2_config,
195 },
196};
197
646e3ed1
TL
198#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
199static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
200 .num_cs = 2,
201};
202
203static struct resource omap2_mcspi3_resources[] = {
204 {
205 .start = OMAP2_MCSPI3_BASE,
206 .end = OMAP2_MCSPI3_BASE + 0xff,
207 .flags = IORESOURCE_MEM,
208 },
209};
210
211static struct platform_device omap2_mcspi3 = {
212 .name = "omap2_mcspi",
213 .id = 3,
214 .num_resources = ARRAY_SIZE(omap2_mcspi3_resources),
215 .resource = omap2_mcspi3_resources,
216 .dev = {
217 .platform_data = &omap2_mcspi3_config,
218 },
219};
220#endif
221
222#ifdef CONFIG_ARCH_OMAP3
223static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
224 .num_cs = 1,
225};
226
227static struct resource omap2_mcspi4_resources[] = {
228 {
229 .start = OMAP2_MCSPI4_BASE,
230 .end = OMAP2_MCSPI4_BASE + 0xff,
231 .flags = IORESOURCE_MEM,
232 },
233};
234
235static struct platform_device omap2_mcspi4 = {
236 .name = "omap2_mcspi",
237 .id = 4,
238 .num_resources = ARRAY_SIZE(omap2_mcspi4_resources),
239 .resource = omap2_mcspi4_resources,
240 .dev = {
241 .platform_data = &omap2_mcspi4_config,
242 },
243};
244#endif
245
ed7eb9d9
JY
246static void omap_init_mcspi(void)
247{
248 platform_device_register(&omap2_mcspi1);
249 platform_device_register(&omap2_mcspi2);
646e3ed1
TL
250#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
251 platform_device_register(&omap2_mcspi3);
252#endif
253#ifdef CONFIG_ARCH_OMAP3
254 platform_device_register(&omap2_mcspi4);
255#endif
ed7eb9d9
JY
256}
257
258#else
259static inline void omap_init_mcspi(void) {}
260#endif
261
646e3ed1
TL
262#ifdef CONFIG_SND_OMAP24XX_EAC
263
264#define OMAP2_EAC_BASE 0x48090000
265
266static struct resource omap2_eac_resources[] = {
267 {
268 .start = OMAP2_EAC_BASE,
269 .end = OMAP2_EAC_BASE + 0x109,
270 .flags = IORESOURCE_MEM,
271 },
272};
273
274static struct platform_device omap2_eac_device = {
275 .name = "omap24xx-eac",
276 .id = -1,
277 .num_resources = ARRAY_SIZE(omap2_eac_resources),
278 .resource = omap2_eac_resources,
279 .dev = {
280 .platform_data = NULL,
281 },
282};
283
284void omap_init_eac(struct eac_platform_data *pdata)
285{
286 omap2_eac_device.dev.platform_data = pdata;
287 platform_device_register(&omap2_eac_device);
288}
289
290#else
291void omap_init_eac(struct eac_platform_data *pdata) {}
292#endif
293
294#ifdef CONFIG_OMAP_SHA1_MD5
295static struct resource sha1_md5_resources[] = {
296 {
297 .start = OMAP24XX_SEC_SHA1MD5_BASE,
298 .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
299 .flags = IORESOURCE_MEM,
300 },
301 {
302 .start = INT_24XX_SHA1MD5,
303 .flags = IORESOURCE_IRQ,
304 }
305};
306
307static struct platform_device sha1_md5_device = {
308 .name = "OMAP SHA1/MD5",
309 .id = -1,
310 .num_resources = ARRAY_SIZE(sha1_md5_resources),
311 .resource = sha1_md5_resources,
312};
313
314static void omap_init_sha1_md5(void)
315{
316 platform_device_register(&sha1_md5_device);
317}
318#else
319static inline void omap_init_sha1_md5(void) { }
320#endif
321
d8874665
TL
322/*-------------------------------------------------------------------------*/
323
917fa280
KH
324#ifdef CONFIG_ARCH_OMAP3
325
326#define MMCHS_SYSCONFIG 0x0010
327#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
328#define MMCHS_SYSSTATUS 0x0014
329#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
330
331static struct platform_device dummy_pdev = {
332 .dev = {
333 .bus = &platform_bus_type,
334 },
335};
336
337/**
338 * omap_hsmmc_reset() - Full reset of each HS-MMC controller
339 *
340 * Ensure that each MMC controller is fully reset. Controllers
341 * left in an unknown state (by bootloader) may prevent retention
342 * or OFF-mode. This is especially important in cases where the
343 * MMC driver is not enabled, _or_ built as a module.
344 *
345 * In order for reset to work, interface, functional and debounce
346 * clocks must be enabled. The debounce clock comes from func_32k_clk
347 * and is not under SW control, so we only enable i- and f-clocks.
348 **/
349static void __init omap_hsmmc_reset(void)
350{
351 u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
352 OMAP24XX_NR_MMC;
353
354 for (i = 0; i < nr_controllers; i++) {
355 u32 v, base = 0;
356 struct clk *iclk, *fclk;
357 struct device *dev = &dummy_pdev.dev;
358
359 switch (i) {
360 case 0:
361 base = OMAP2_MMC1_BASE;
362 break;
363 case 1:
364 base = OMAP2_MMC2_BASE;
365 break;
366 case 2:
367 base = OMAP3_MMC3_BASE;
368 break;
369 }
370
371 dummy_pdev.id = i;
372 iclk = clk_get(dev, "mmchs_ick");
373 if (iclk && clk_enable(iclk))
374 iclk = NULL;
375
376 fclk = clk_get(dev, "mmchs_fck");
377 if (fclk && clk_enable(fclk))
378 fclk = NULL;
379
380 if (!iclk || !fclk) {
381 printk(KERN_WARNING
382 "%s: Unable to enable clocks for MMC%d, "
383 "cannot reset.\n", __func__, i);
384 break;
385 }
386
387 omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
388 v = omap_readl(base + MMCHS_SYSSTATUS);
389 while (!(omap_readl(base + MMCHS_SYSSTATUS) &
390 MMCHS_SYSSTATUS_RESETDONE))
391 cpu_relax();
392
393 if (fclk) {
394 clk_disable(fclk);
395 clk_put(fclk);
396 }
397 if (iclk) {
398 clk_disable(iclk);
399 clk_put(iclk);
400 }
401 }
402}
403#else
404static inline void omap_hsmmc_reset(void) {}
405#endif
406
d8874665
TL
407#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
408 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
409
410static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
411 int controller_nr)
412{
413 if (cpu_is_omap2420() && controller_nr == 0) {
414 omap_cfg_reg(H18_24XX_MMC_CMD);
415 omap_cfg_reg(H15_24XX_MMC_CLKI);
416 omap_cfg_reg(G19_24XX_MMC_CLKO);
417 omap_cfg_reg(F20_24XX_MMC_DAT0);
418 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
419 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
90c62bf0 420 if (mmc_controller->slots[0].wires == 4) {
d8874665
TL
421 omap_cfg_reg(H14_24XX_MMC_DAT1);
422 omap_cfg_reg(E19_24XX_MMC_DAT2);
423 omap_cfg_reg(D19_24XX_MMC_DAT3);
424 omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
425 omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
426 omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
427 }
428
429 /*
430 * Use internal loop-back in MMC/SDIO Module Input Clock
431 * selection
432 */
433 if (mmc_controller->slots[0].internal_clock) {
434 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
435 v |= (1 << 24);
436 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
437 }
438 }
439}
440
441void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
442 int nr_controllers)
443{
444 int i;
0dffb5c5 445 char *name;
d8874665
TL
446
447 for (i = 0; i < nr_controllers; i++) {
448 unsigned long base, size;
449 unsigned int irq = 0;
450
451 if (!mmc_data[i])
452 continue;
453
454 omap2_mmc_mux(mmc_data[i], i);
455
456 switch (i) {
457 case 0:
458 base = OMAP2_MMC1_BASE;
459 irq = INT_24XX_MMC_IRQ;
460 break;
461 case 1:
462 base = OMAP2_MMC2_BASE;
463 irq = INT_24XX_MMC2_IRQ;
464 break;
465 case 2:
466 if (!cpu_is_omap34xx())
467 return;
468 base = OMAP3_MMC3_BASE;
469 irq = INT_34XX_MMC3_IRQ;
470 break;
471 default:
472 continue;
473 }
474
0dffb5c5 475 if (cpu_is_omap2420()) {
d8874665 476 size = OMAP2420_MMC_SIZE;
0dffb5c5
TL
477 name = "mmci-omap";
478 } else {
d8874665 479 size = HSMMC_SIZE;
0dffb5c5
TL
480 name = "mmci-omap-hs";
481 }
482 omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
d8874665
TL
483 };
484}
485
486#endif
487
488/*-------------------------------------------------------------------------*/
489
646e3ed1
TL
490#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
491#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
492#define OMAP_HDQ_BASE 0x480B2000
493#endif
494static struct resource omap_hdq_resources[] = {
495 {
496 .start = OMAP_HDQ_BASE,
497 .end = OMAP_HDQ_BASE + 0x1C,
498 .flags = IORESOURCE_MEM,
499 },
500 {
501 .start = INT_24XX_HDQ_IRQ,
502 .flags = IORESOURCE_IRQ,
503 },
504};
505static struct platform_device omap_hdq_dev = {
506 .name = "omap_hdq",
507 .id = 0,
508 .dev = {
509 .platform_data = NULL,
510 },
511 .num_resources = ARRAY_SIZE(omap_hdq_resources),
512 .resource = omap_hdq_resources,
513};
514static inline void omap_hdq_init(void)
515{
516 (void) platform_device_register(&omap_hdq_dev);
517}
518#else
519static inline void omap_hdq_init(void) {}
520#endif
521
1dbae815
TL
522/*-------------------------------------------------------------------------*/
523
524static int __init omap2_init_devices(void)
525{
526 /* please keep these calls, and their implementations above,
527 * in alphabetical order so they're easier to sort through.
528 */
917fa280 529 omap_hsmmc_reset();
c40fae95 530 omap_init_mbox();
ed7eb9d9 531 omap_init_mcspi();
646e3ed1 532 omap_hdq_init();
9b6553cd 533 omap_init_sti();
646e3ed1 534 omap_init_sha1_md5();
1dbae815
TL
535
536 return 0;
537}
538arch_initcall(omap2_init_devices);
This page took 0.312996 seconds and 5 git commands to generate.