davinci: MMC platform support
[linux-2.6] / arch / arm / mach-davinci / devices.c
1 /*
2  * mach-davinci/devices.c
3  *
4  * DaVinci 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/dma-mapping.h>
17 #include <linux/io.h>
18
19 #include <asm/mach/map.h>
20
21 #include <mach/hardware.h>
22 #include <mach/i2c.h>
23 #include <mach/irqs.h>
24 #include <mach/cputype.h>
25 #include <mach/mux.h>
26 #include <mach/edma.h>
27 #include <mach/mmc.h>
28
29 #define DAVINCI_I2C_BASE             0x01C21000
30 #define DAVINCI_MMCSD0_BASE          0x01E10000
31 #define DM355_MMCSD0_BASE            0x01E11000
32 #define DM355_MMCSD1_BASE            0x01E00000
33
34 static struct resource i2c_resources[] = {
35         {
36                 .start          = DAVINCI_I2C_BASE,
37                 .end            = DAVINCI_I2C_BASE + 0x40,
38                 .flags          = IORESOURCE_MEM,
39         },
40         {
41                 .start          = IRQ_I2C,
42                 .flags          = IORESOURCE_IRQ,
43         },
44 };
45
46 static struct platform_device davinci_i2c_device = {
47         .name           = "i2c_davinci",
48         .id             = 1,
49         .num_resources  = ARRAY_SIZE(i2c_resources),
50         .resource       = i2c_resources,
51 };
52
53 void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
54 {
55         if (cpu_is_davinci_dm644x())
56                 davinci_cfg_reg(DM644X_I2C);
57
58         davinci_i2c_device.dev.platform_data = pdata;
59         (void) platform_device_register(&davinci_i2c_device);
60 }
61
62 #if     defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
63
64 static u64 mmcsd0_dma_mask = DMA_32BIT_MASK;
65
66 static struct resource mmcsd0_resources[] = {
67         {
68                 /* different on dm355 */
69                 .start = DAVINCI_MMCSD0_BASE,
70                 .end   = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
71                 .flags = IORESOURCE_MEM,
72         },
73         /* IRQs:  MMC/SD, then SDIO */
74         {
75                 .start = IRQ_MMCINT,
76                 .flags = IORESOURCE_IRQ,
77         }, {
78                 /* different on dm355 */
79                 .start = IRQ_SDIOINT,
80                 .flags = IORESOURCE_IRQ,
81         },
82         /* DMA channels: RX, then TX */
83         {
84                 .start = DAVINCI_DMA_MMCRXEVT,
85                 .flags = IORESOURCE_DMA,
86         }, {
87                 .start = DAVINCI_DMA_MMCTXEVT,
88                 .flags = IORESOURCE_DMA,
89         },
90 };
91
92 static struct platform_device davinci_mmcsd0_device = {
93         .name = "davinci_mmc",
94         .id = 0,
95         .dev = {
96                 .dma_mask = &mmcsd0_dma_mask,
97                 .coherent_dma_mask = DMA_32BIT_MASK,
98         },
99         .num_resources = ARRAY_SIZE(mmcsd0_resources),
100         .resource = mmcsd0_resources,
101 };
102
103 static u64 mmcsd1_dma_mask = DMA_32BIT_MASK;
104
105 static struct resource mmcsd1_resources[] = {
106         {
107                 .start = DM355_MMCSD1_BASE,
108                 .end   = DM355_MMCSD1_BASE + SZ_4K - 1,
109                 .flags = IORESOURCE_MEM,
110         },
111         /* IRQs:  MMC/SD, then SDIO */
112         {
113                 .start = IRQ_DM355_MMCINT1,
114                 .flags = IORESOURCE_IRQ,
115         }, {
116                 .start = IRQ_DM355_SDIOINT1,
117                 .flags = IORESOURCE_IRQ,
118         },
119         /* DMA channels: RX, then TX */
120         {
121                 .start = 30,    /* rx */
122                 .flags = IORESOURCE_DMA,
123         }, {
124                 .start = 31,    /* tx */
125                 .flags = IORESOURCE_DMA,
126         },
127 };
128
129 static struct platform_device davinci_mmcsd1_device = {
130         .name = "davinci_mmc",
131         .id = 1,
132         .dev = {
133                 .dma_mask = &mmcsd1_dma_mask,
134                 .coherent_dma_mask = DMA_32BIT_MASK,
135         },
136         .num_resources = ARRAY_SIZE(mmcsd1_resources),
137         .resource = mmcsd1_resources,
138 };
139
140
141 void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
142 {
143         struct platform_device  *pdev = NULL;
144
145         if (WARN_ON(cpu_is_davinci_dm646x()))
146                 return;
147
148         /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
149          * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
150          *
151          * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
152          * not handled right here ...
153          */
154         switch (module) {
155         case 1:
156                 if (!cpu_is_davinci_dm355())
157                         break;
158
159                 /* REVISIT we may not need all these pins if e.g. this
160                  * is a hard-wired SDIO device...
161                  */
162                 davinci_cfg_reg(DM355_SD1_CMD);
163                 davinci_cfg_reg(DM355_SD1_CLK);
164                 davinci_cfg_reg(DM355_SD1_DATA0);
165                 davinci_cfg_reg(DM355_SD1_DATA1);
166                 davinci_cfg_reg(DM355_SD1_DATA2);
167                 davinci_cfg_reg(DM355_SD1_DATA3);
168
169                 pdev = &davinci_mmcsd1_device;
170                 break;
171         case 0:
172                 if (cpu_is_davinci_dm355()) {
173                         mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
174                         mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
175                         mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
176
177                         /* expose all 6 MMC0 signals:  CLK, CMD, DATA[0..3] */
178                         davinci_cfg_reg(DM355_MMCSD0);
179
180                         /* enable RX EDMA */
181                         davinci_cfg_reg(DM355_EVT26_MMC0_RX);
182                 }
183
184                 else if (cpu_is_davinci_dm644x()) {
185                         /* REVISIT: should this be in board-init code? */
186                         void __iomem *base =
187                                 IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
188
189                         /* Power-on 3.3V IO cells */
190                         __raw_writel(0, base + DM64XX_VDD3P3V_PWDN);
191                         /*Set up the pull regiter for MMC */
192                         davinci_cfg_reg(DM644X_MSTK);
193                 }
194
195                 pdev = &davinci_mmcsd0_device;
196                 break;
197         }
198
199         if (WARN_ON(!pdev))
200                 return;
201
202         pdev->dev.platform_data = config;
203         platform_device_register(pdev);
204 }
205
206 #else
207
208 void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
209 {
210 }
211
212 #endif
213
214 /*-------------------------------------------------------------------------*/
215
216 static struct resource wdt_resources[] = {
217         {
218                 .start  = 0x01c21c00,
219                 .end    = 0x01c21fff,
220                 .flags  = IORESOURCE_MEM,
221         },
222 };
223
224 struct platform_device davinci_wdt_device = {
225         .name           = "watchdog",
226         .id             = -1,
227         .num_resources  = ARRAY_SIZE(wdt_resources),
228         .resource       = wdt_resources,
229 };
230
231 static void davinci_init_wdt(void)
232 {
233         platform_device_register(&davinci_wdt_device);
234 }
235
236 /*-------------------------------------------------------------------------*/
237
238 static int __init davinci_init_devices(void)
239 {
240         /* please keep these calls, and their implementations above,
241          * in alphabetical order so they're easier to sort through.
242          */
243         davinci_init_wdt();
244
245         return 0;
246 }
247 arch_initcall(davinci_init_devices);
248