MIPS: Alchemy: MMC for DB1100
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / mips / alchemy / devboards / db1000.c
1 /*
2  * DBAu1000/1500/1100 board support
3  *
4  * Copyright 2000, 2008 MontaVista Software Inc.
5  * Author: MontaVista Software, Inc. <source@mvista.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include <linux/dma-mapping.h>
23 #include <linux/gpio.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/leds.h>
27 #include <linux/mmc/host.h>
28 #include <linux/module.h>
29 #include <linux/platform_device.h>
30 #include <linux/pm.h>
31 #include <asm/mach-au1x00/au1000.h>
32 #include <asm/mach-au1x00/au1000_dma.h>
33 #include <asm/mach-au1x00/au1100_mmc.h>
34 #include <asm/mach-db1x00/bcsr.h>
35 #include <asm/reboot.h>
36 #include <prom.h>
37 #include "platform.h"
38
39 #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
40
41 struct pci_dev;
42
43 static const char *board_type_str(void)
44 {
45         switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
46         case BCSR_WHOAMI_DB1000:
47                 return "DB1000";
48         case BCSR_WHOAMI_DB1500:
49                 return "DB1500";
50         case BCSR_WHOAMI_DB1100:
51                 return "DB1100";
52         default:
53                 return "(unknown)";
54         }
55 }
56
57 const char *get_system_type(void)
58 {
59         return board_type_str();
60 }
61
62 void __init board_setup(void)
63 {
64         /* initialize board register space */
65         bcsr_init(DB1000_BCSR_PHYS_ADDR,
66                   DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
67
68         printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str());
69
70 #if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR)
71         {
72                 u32 pin_func;
73
74                 /* Set IRFIRSEL instead of GPIO15 */
75                 pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
76                 au_writel(pin_func, SYS_PINFUNC);
77                 /* Power off until the driver is in use */
78                 bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
79                          BCSR_RESETS_IRDA_MODE_OFF);
80         }
81 #endif
82         bcsr_write(BCSR_PCMCIA, 0);     /* turn off PCMCIA power */
83
84         /* Enable GPIO[31:0] inputs */
85         alchemy_gpio1_input_enable();
86 }
87
88
89 static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
90 {
91         if ((slot < 12) || (slot > 13) || pin == 0)
92                 return -1;
93         if (slot == 12)
94                 return (pin == 1) ? AU1500_PCI_INTA : 0xff;
95         if (slot == 13) {
96                 switch (pin) {
97                 case 1: return AU1500_PCI_INTA;
98                 case 2: return AU1500_PCI_INTB;
99                 case 3: return AU1500_PCI_INTC;
100                 case 4: return AU1500_PCI_INTD;
101                 }
102         }
103         return -1;
104 }
105
106 static struct resource alchemy_pci_host_res[] = {
107         [0] = {
108                 .start  = AU1500_PCI_PHYS_ADDR,
109                 .end    = AU1500_PCI_PHYS_ADDR + 0xfff,
110                 .flags  = IORESOURCE_MEM,
111         },
112 };
113
114 static struct alchemy_pci_platdata db1500_pci_pd = {
115         .board_map_irq  = db1500_map_pci_irq,
116 };
117
118 static struct platform_device db1500_pci_host_dev = {
119         .dev.platform_data = &db1500_pci_pd,
120         .name           = "alchemy-pci",
121         .id             = 0,
122         .num_resources  = ARRAY_SIZE(alchemy_pci_host_res),
123         .resource       = alchemy_pci_host_res,
124 };
125
126 static int __init db1500_pci_init(void)
127 {
128         if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500)
129                 return platform_device_register(&db1500_pci_host_dev);
130         return 0;
131 }
132 /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
133 arch_initcall(db1500_pci_init);
134
135
136 static struct resource au1100_lcd_resources[] = {
137         [0] = {
138                 .start  = AU1100_LCD_PHYS_ADDR,
139                 .end    = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
140                 .flags  = IORESOURCE_MEM,
141         },
142         [1] = {
143                 .start  = AU1100_LCD_INT,
144                 .end    = AU1100_LCD_INT,
145                 .flags  = IORESOURCE_IRQ,
146         }
147 };
148
149 static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
150
151 static struct platform_device au1100_lcd_device = {
152         .name           = "au1100-lcd",
153         .id             = 0,
154         .dev = {
155                 .dma_mask               = &au1100_lcd_dmamask,
156                 .coherent_dma_mask      = DMA_BIT_MASK(32),
157         },
158         .num_resources  = ARRAY_SIZE(au1100_lcd_resources),
159         .resource       = au1100_lcd_resources,
160 };
161
162 static struct resource alchemy_ac97c_res[] = {
163         [0] = {
164                 .start  = AU1000_AC97_PHYS_ADDR,
165                 .end    = AU1000_AC97_PHYS_ADDR + 0xfff,
166                 .flags  = IORESOURCE_MEM,
167         },
168         [1] = {
169                 .start  = DMA_ID_AC97C_TX,
170                 .end    = DMA_ID_AC97C_TX,
171                 .flags  = IORESOURCE_DMA,
172         },
173         [2] = {
174                 .start  = DMA_ID_AC97C_RX,
175                 .end    = DMA_ID_AC97C_RX,
176                 .flags  = IORESOURCE_DMA,
177         },
178 };
179
180 static struct platform_device alchemy_ac97c_dev = {
181         .name           = "alchemy-ac97c",
182         .id             = -1,
183         .resource       = alchemy_ac97c_res,
184         .num_resources  = ARRAY_SIZE(alchemy_ac97c_res),
185 };
186
187 static struct platform_device alchemy_ac97c_dma_dev = {
188         .name           = "alchemy-pcm-dma",
189         .id             = 0,
190 };
191
192 static struct platform_device db1x00_codec_dev = {
193         .name           = "ac97-codec",
194         .id             = -1,
195 };
196
197 static struct platform_device db1x00_audio_dev = {
198         .name           = "db1000-audio",
199 };
200
201 /******************************************************************************/
202
203 static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
204 {
205         void (*mmc_cd)(struct mmc_host *, unsigned long);
206         /* link against CONFIG_MMC=m */
207         mmc_cd = symbol_get(mmc_detect_change);
208         mmc_cd(ptr, msecs_to_jiffies(500));
209         symbol_put(mmc_detect_change);
210
211         return IRQ_HANDLED;
212 }
213
214 static int db1100_mmc_cd_setup(void *mmc_host, int en)
215 {
216         int ret = 0;
217
218         if (en) {
219                 irq_set_irq_type(AU1100_GPIO19_INT, IRQ_TYPE_EDGE_BOTH);
220                 ret = request_irq(AU1100_GPIO19_INT, db1100_mmc_cd, 0,
221                                   "sd0_cd", mmc_host);
222         } else
223                 free_irq(AU1100_GPIO19_INT, mmc_host);
224         return ret;
225 }
226
227 static int db1100_mmc1_cd_setup(void *mmc_host, int en)
228 {
229         int ret = 0;
230
231         if (en) {
232                 irq_set_irq_type(AU1100_GPIO20_INT, IRQ_TYPE_EDGE_BOTH);
233                 ret = request_irq(AU1100_GPIO20_INT, db1100_mmc_cd, 0,
234                                   "sd1_cd", mmc_host);
235         } else
236                 free_irq(AU1100_GPIO20_INT, mmc_host);
237         return ret;
238 }
239
240 static int db1100_mmc_card_readonly(void *mmc_host)
241 {
242         /* testing suggests that this bit is inverted */
243         return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1;
244 }
245
246 static int db1100_mmc_card_inserted(void *mmc_host)
247 {
248         return !alchemy_gpio_get_value(19);
249 }
250
251 static void db1100_mmc_set_power(void *mmc_host, int state)
252 {
253         if (state) {
254                 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
255                 msleep(400);    /* stabilization time */
256         } else
257                 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
258 }
259
260 static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
261 {
262         if (b != LED_OFF)
263                 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
264         else
265                 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
266 }
267
268 static struct led_classdev db1100_mmc_led = {
269         .brightness_set = db1100_mmcled_set,
270 };
271
272 static int db1100_mmc1_card_readonly(void *mmc_host)
273 {
274         return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0;
275 }
276
277 static int db1100_mmc1_card_inserted(void *mmc_host)
278 {
279         return !alchemy_gpio_get_value(20);
280 }
281
282 static void db1100_mmc1_set_power(void *mmc_host, int state)
283 {
284         if (state) {
285                 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
286                 msleep(400);    /* stabilization time */
287         } else
288                 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
289 }
290
291 static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
292 {
293         if (b != LED_OFF)
294                 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
295         else
296                 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
297 }
298
299 static struct led_classdev db1100_mmc1_led = {
300         .brightness_set = db1100_mmc1led_set,
301 };
302
303 static struct au1xmmc_platform_data db1100_mmc_platdata[2] = {
304         [0] = {
305                 .cd_setup       = db1100_mmc_cd_setup,
306                 .set_power      = db1100_mmc_set_power,
307                 .card_inserted  = db1100_mmc_card_inserted,
308                 .card_readonly  = db1100_mmc_card_readonly,
309                 .led            = &db1100_mmc_led,
310         },
311         [1] = {
312                 .cd_setup       = db1100_mmc1_cd_setup,
313                 .set_power      = db1100_mmc1_set_power,
314                 .card_inserted  = db1100_mmc1_card_inserted,
315                 .card_readonly  = db1100_mmc1_card_readonly,
316                 .led            = &db1100_mmc1_led,
317         },
318 };
319
320 static struct resource au1100_mmc0_resources[] = {
321         [0] = {
322                 .start  = AU1100_SD0_PHYS_ADDR,
323                 .end    = AU1100_SD0_PHYS_ADDR + 0xfff,
324                 .flags  = IORESOURCE_MEM,
325         },
326         [1] = {
327                 .start  = AU1100_SD_INT,
328                 .end    = AU1100_SD_INT,
329                 .flags  = IORESOURCE_IRQ,
330         },
331         [2] = {
332                 .start  = DMA_ID_SD0_TX,
333                 .end    = DMA_ID_SD0_TX,
334                 .flags  = IORESOURCE_DMA,
335         },
336         [3] = {
337                 .start  = DMA_ID_SD0_RX,
338                 .end    = DMA_ID_SD0_RX,
339                 .flags  = IORESOURCE_DMA,
340         }
341 };
342
343 static u64 au1xxx_mmc_dmamask =  DMA_BIT_MASK(32);
344
345 static struct platform_device db1100_mmc0_dev = {
346         .name           = "au1xxx-mmc",
347         .id             = 0,
348         .dev = {
349                 .dma_mask               = &au1xxx_mmc_dmamask,
350                 .coherent_dma_mask      = DMA_BIT_MASK(32),
351                 .platform_data          = &db1100_mmc_platdata[0],
352         },
353         .num_resources  = ARRAY_SIZE(au1100_mmc0_resources),
354         .resource       = au1100_mmc0_resources,
355 };
356
357 static struct resource au1100_mmc1_res[] = {
358         [0] = {
359                 .start  = AU1100_SD1_PHYS_ADDR,
360                 .end    = AU1100_SD1_PHYS_ADDR + 0xfff,
361                 .flags  = IORESOURCE_MEM,
362         },
363         [1] = {
364                 .start  = AU1100_SD_INT,
365                 .end    = AU1100_SD_INT,
366                 .flags  = IORESOURCE_IRQ,
367         },
368         [2] = {
369                 .start  = DMA_ID_SD1_TX,
370                 .end    = DMA_ID_SD1_TX,
371                 .flags  = IORESOURCE_DMA,
372         },
373         [3] = {
374                 .start  = DMA_ID_SD1_RX,
375                 .end    = DMA_ID_SD1_RX,
376                 .flags  = IORESOURCE_DMA,
377         }
378 };
379
380 static struct platform_device db1100_mmc1_dev = {
381         .name           = "au1xxx-mmc",
382         .id             = 1,
383         .dev = {
384                 .dma_mask               = &au1xxx_mmc_dmamask,
385                 .coherent_dma_mask      = DMA_BIT_MASK(32),
386                 .platform_data          = &db1100_mmc_platdata[1],
387         },
388         .num_resources  = ARRAY_SIZE(au1100_mmc1_res),
389         .resource       = au1100_mmc1_res,
390 };
391
392
393 static struct platform_device *db1x00_devs[] = {
394         &db1x00_codec_dev,
395         &alchemy_ac97c_dma_dev,
396         &alchemy_ac97c_dev,
397         &db1x00_audio_dev,
398 };
399
400 static struct platform_device *db1100_devs[] = {
401         &au1100_lcd_device,
402         &db1100_mmc0_dev,
403         &db1100_mmc1_dev,
404 };
405
406 static int __init db1000_dev_init(void)
407 {
408         int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
409         int c0, c1, d0, d1, s0, s1;
410
411         if (board == BCSR_WHOAMI_DB1500) {
412                 c0 = AU1500_GPIO2_INT;
413                 c1 = AU1500_GPIO5_INT;
414                 d0 = AU1500_GPIO0_INT;
415                 d1 = AU1500_GPIO3_INT;
416                 s0 = AU1500_GPIO1_INT;
417                 s1 = AU1500_GPIO4_INT;
418         } else if (board == BCSR_WHOAMI_DB1100) {
419                 c0 = AU1100_GPIO2_INT;
420                 c1 = AU1100_GPIO5_INT;
421                 d0 = AU1100_GPIO0_INT;
422                 d1 = AU1100_GPIO3_INT;
423                 s0 = AU1100_GPIO1_INT;
424                 s1 = AU1100_GPIO4_INT;
425
426                 gpio_direction_input(19);       /* sd0 cd# */
427                 gpio_direction_input(20);       /* sd1 cd# */
428
429                 platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
430         } else if (board == BCSR_WHOAMI_DB1000) {
431                 c0 = AU1000_GPIO2_INT;
432                 c1 = AU1000_GPIO5_INT;
433                 d0 = AU1000_GPIO0_INT;
434                 d1 = AU1000_GPIO3_INT;
435                 s0 = AU1000_GPIO1_INT;
436                 s1 = AU1000_GPIO4_INT;
437         } else
438                 return 0; /* unknown board, no further dev setup to do */
439
440         irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH);
441         irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
442         irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
443         irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
444         irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
445         irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
446
447         db1x_register_pcmcia_socket(
448                 AU1000_PCMCIA_ATTR_PHYS_ADDR,
449                 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
450                 AU1000_PCMCIA_MEM_PHYS_ADDR,
451                 AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
452                 AU1000_PCMCIA_IO_PHYS_ADDR,
453                 AU1000_PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
454                 c0, d0, /*s0*/0, 0, 0);
455
456         db1x_register_pcmcia_socket(
457                 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
458                 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
459                 AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004000000,
460                 AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
461                 AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004000000,
462                 AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
463                 c1, d1, /*s1*/0, 0, 1);
464
465         platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
466         db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED);
467         return 0;
468 }
469 device_initcall(db1000_dev_init);