]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/devices.c
14537ffd8af3a4e2953ad8acde6dc739bee85462
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / devices.c
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
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/io.h>
17 #include <linux/clk.h>
18
19 #include <mach/hardware.h>
20 #include <asm/mach-types.h>
21 #include <asm/mach/map.h>
22
23 #include <mach/control.h>
24 #include <mach/tc.h>
25 #include <mach/board.h>
26 #include <mach/mux.h>
27 #include <mach/gpio.h>
28 #include <mach/eac.h>
29 #include <mach/mmc.h>
30
31 #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
32
33 #define MBOX_REG_SIZE   0x120
34
35 static struct resource omap2_mbox_resources[] = {
36         {
37                 .start          = OMAP24XX_MAILBOX_BASE,
38                 .end            = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
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
51 static 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
63 static struct platform_device mbox_device = {
64         .name           = "omap2-mailbox",
65         .id             = -1,
66 };
67
68 static inline void omap_init_mbox(void)
69 {
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         }
80         platform_device_register(&mbox_device);
81 }
82 #else
83 static inline void omap_init_mbox(void) { }
84 #endif /* CONFIG_OMAP_MBOX_FWK */
85
86 #if defined(CONFIG_OMAP_STI)
87
88 #if defined(CONFIG_ARCH_OMAP2)
89
90 #define OMAP2_STI_BASE          0x48068000
91 #define OMAP2_STI_CHANNEL_BASE  0x54000000
92 #define OMAP2_STI_IRQ           4
93
94 static 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 };
110 #elif defined(CONFIG_ARCH_OMAP3)
111
112 #define OMAP3_SDTI_BASE         0x54500000
113 #define OMAP3_SDTI_CHANNEL_BASE 0x54600000
114
115 static 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
129
130 static struct platform_device sti_device = {
131         .name           = "sti",
132         .id             = -1,
133         .num_resources  = ARRAY_SIZE(sti_resources),
134         .resource       = sti_resources,
135 };
136
137 static inline void omap_init_sti(void)
138 {
139         platform_device_register(&sti_device);
140 }
141 #else
142 static inline void omap_init_sti(void) {}
143 #endif
144
145 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
146
147 #include <mach/mcspi.h>
148
149 #define OMAP2_MCSPI1_BASE               0x48098000
150 #define OMAP2_MCSPI2_BASE               0x4809a000
151 #define OMAP2_MCSPI3_BASE               0x480b8000
152 #define OMAP2_MCSPI4_BASE               0x480ba000
153
154 static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
155         .num_cs         = 4,
156 };
157
158 static struct resource omap2_mcspi1_resources[] = {
159         {
160                 .start          = OMAP2_MCSPI1_BASE,
161                 .end            = OMAP2_MCSPI1_BASE + 0xff,
162                 .flags          = IORESOURCE_MEM,
163         },
164 };
165
166 static struct platform_device omap2_mcspi1 = {
167         .name           = "omap2_mcspi",
168         .id             = 1,
169         .num_resources  = ARRAY_SIZE(omap2_mcspi1_resources),
170         .resource       = omap2_mcspi1_resources,
171         .dev            = {
172                 .platform_data = &omap2_mcspi1_config,
173         },
174 };
175
176 static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
177         .num_cs         = 2,
178 };
179
180 static struct resource omap2_mcspi2_resources[] = {
181         {
182                 .start          = OMAP2_MCSPI2_BASE,
183                 .end            = OMAP2_MCSPI2_BASE + 0xff,
184                 .flags          = IORESOURCE_MEM,
185         },
186 };
187
188 static struct platform_device omap2_mcspi2 = {
189         .name           = "omap2_mcspi",
190         .id             = 2,
191         .num_resources  = ARRAY_SIZE(omap2_mcspi2_resources),
192         .resource       = omap2_mcspi2_resources,
193         .dev            = {
194                 .platform_data = &omap2_mcspi2_config,
195         },
196 };
197
198 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
199 static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
200         .num_cs         = 2,
201 };
202
203 static struct resource omap2_mcspi3_resources[] = {
204         {
205         .start          = OMAP2_MCSPI3_BASE,
206         .end            = OMAP2_MCSPI3_BASE + 0xff,
207         .flags          = IORESOURCE_MEM,
208         },
209 };
210
211 static 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
223 static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
224         .num_cs         = 1,
225 };
226
227 static struct resource omap2_mcspi4_resources[] = {
228         {
229                 .start          = OMAP2_MCSPI4_BASE,
230                 .end            = OMAP2_MCSPI4_BASE + 0xff,
231                 .flags          = IORESOURCE_MEM,
232         },
233 };
234
235 static 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
246 static void omap_init_mcspi(void)
247 {
248         platform_device_register(&omap2_mcspi1);
249         platform_device_register(&omap2_mcspi2);
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
256 }
257
258 #else
259 static inline void omap_init_mcspi(void) {}
260 #endif
261
262 #ifdef CONFIG_SND_OMAP24XX_EAC
263
264 #define OMAP2_EAC_BASE                  0x48090000
265
266 static struct resource omap2_eac_resources[] = {
267         {
268                 .start          = OMAP2_EAC_BASE,
269                 .end            = OMAP2_EAC_BASE + 0x109,
270                 .flags          = IORESOURCE_MEM,
271         },
272 };
273
274 static 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
284 void 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
291 void omap_init_eac(struct eac_platform_data *pdata) {}
292 #endif
293
294 #ifdef CONFIG_OMAP_SHA1_MD5
295 static 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
307 static 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
314 static void omap_init_sha1_md5(void)
315 {
316         platform_device_register(&sha1_md5_device);
317 }
318 #else
319 static inline void omap_init_sha1_md5(void) { }
320 #endif
321
322 /*-------------------------------------------------------------------------*/
323
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
331 static 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  **/
349 static 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
404 static inline void omap_hsmmc_reset(void) {}
405 #endif
406
407 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
408         defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
409
410 static 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);
420                 if (mmc_controller->slots[0].wires == 4) {
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
441 void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
442                         int nr_controllers)
443 {
444         int i;
445         char *name;
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
475                 if (cpu_is_omap2420()) {
476                         size = OMAP2420_MMC_SIZE;
477                         name = "mmci-omap";
478                 } else {
479                         size = HSMMC_SIZE;
480                         name = "mmci-omap-hs";
481                 }
482                 omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
483         };
484 }
485
486 #endif
487
488 /*-------------------------------------------------------------------------*/
489
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
494 static 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 };
505 static 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 };
514 static inline void omap_hdq_init(void)
515 {
516         (void) platform_device_register(&omap_hdq_dev);
517 }
518 #else
519 static inline void omap_hdq_init(void) {}
520 #endif
521
522 /*-------------------------------------------------------------------------*/
523
524 static 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          */
529         omap_hsmmc_reset();
530         omap_init_mbox();
531         omap_init_mcspi();
532         omap_hdq_init();
533         omap_init_sti();
534         omap_init_sha1_md5();
535
536         return 0;
537 }
538 arch_initcall(omap2_init_devices);