import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / arm / mach-at91rm9200 / core.c
1 /*
2  * linux/arch/arm/mach-at91rm9200/core.c
3  *
4  *  Copyright (c) 2003 SAN People
5  *  Copyright (c) 2003 ATMEL
6  *  Copyright (c) Rick Bronson
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <linux/config.h>
24 #include <linux/types.h>
25 #include <linux/init.h>
26 #include <linux/mm.h>
27
28 #include <asm/hardware.h>
29 #include <asm/setup.h>
30 #include <asm/mach-types.h>
31 #include <asm/irq.h>
32
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35 #include <asm/mach/irq.h>
36
37 #include <asm/arch/hardware.h>
38
39 /*
40  * System peripheral registers mapped at virtual address.
41  */
42 AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS;
43
44 static struct map_desc at91rm9200_io_desc[] __initdata = {
45         /* virtual,             physical,          length,   domain,    r, w, c, b */
46         { AT91C_VA_BASE_SYS,    AT91C_BASE_SYS,    SZ_4K,    DOMAIN_IO, 0, 1, 0, 0},
47         { AT91C_VA_BASE_SPI,    AT91C_BASE_SPI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
48         { AT91C_VA_BASE_SSC2,   AT91C_BASE_SSC2,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
49         { AT91C_VA_BASE_SSC1,   AT91C_BASE_SSC1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
50         { AT91C_VA_BASE_SSC0,   AT91C_BASE_SSC0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
51         { AT91C_VA_BASE_US3,    AT91C_BASE_US3,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
52         { AT91C_VA_BASE_US2,    AT91C_BASE_US2,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
53         { AT91C_VA_BASE_US1,    AT91C_BASE_US1,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
54         { AT91C_VA_BASE_US0,    AT91C_BASE_US0,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
55         { AT91C_VA_BASE_EMAC,   AT91C_BASE_EMAC,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
56         { AT91C_VA_BASE_TWI,    AT91C_BASE_TWI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
57         { AT91C_VA_BASE_MCI,    AT91C_BASE_MCI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
58         { AT91C_VA_BASE_UDP,    AT91C_BASE_UDP,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
59         { AT91C_VA_BASE_TCB1,   AT91C_BASE_TCB1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
60         { AT91C_VA_BASE_TCB0,   AT91C_BASE_TCB0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
61         LAST_DESC
62 };
63
64 /* Interrupt configuration */
65 static AT91_REG at91rm9200_irq_smr[] __initdata = {
66         (AT91_SMR_FIQ),         /* FIQ */
67         (AT91_SMR_SYS),         /* System Peripherals */
68         (AT91_SMR_PIOA),        /* PIO A */
69         (AT91_SMR_PIOB),        /* PIO B */
70         (AT91_SMR_PIOC),        /* PIO C */
71         (AT91_SMR_PIOD),        /* PIO D */
72         (AT91_SMR_US0),         /* USART 0 */
73         (AT91_SMR_US1),         /* USART 1 */
74         (AT91_SMR_US2),         /* USART 2 */
75         (AT91_SMR_US3),         /* USART 3 */
76         (AT91_SMR_MCI),         /* Multimedia Card */
77         (AT91_SMR_UDP),         /* USB Device */
78         (AT91_SMR_TWI),         /* Two-wire interface */
79         (AT91_SMR_SPI),         /* SPI */
80         (AT91_SMR_SSC0),        /* Sync Serial 0 */
81         (AT91_SMR_SSC1),        /* Sync Serial 1 */
82         (AT91_SMR_SSC2),        /* Sync Serial 2 */
83         (AT91_SMR_TC0),         /* TC 0 */
84         (AT91_SMR_TC1),         /* TC 1 */
85         (AT91_SMR_TC2),         /* TC 2 */
86         (AT91_SMR_TC3),         /* TC 3 */
87         (AT91_SMR_TC4),         /* TC 4 */
88         (AT91_SMR_TC5),         /* TC 5 */
89         (AT91_SMR_UHP),         /* USB Host */
90         (AT91_SMR_EMAC),        /* Ethernet */
91         (AT91_SMR_IRQ0),        /* IRQ 0 */
92         (AT91_SMR_IRQ1),        /* IRQ 1 */
93         (AT91_SMR_IRQ2),        /* IRQ 2 */
94         (AT91_SMR_IRQ3),        /* IRQ 3 */
95         (AT91_SMR_IRQ4),        /* IRQ 4 */
96         (AT91_SMR_IRQ5),        /* IRQ 5 */
97         (AT91_SMR_IRQ6)         /* IRQ 6 */
98 };
99
100 /* Architecture-specific fixups */
101 static void __init at91rm9200_fixup(struct machine_desc *desc, struct param_struct *unused,
102                  char **cmdline, struct meminfo *mi)
103 {
104 #ifdef CONFIG_BLK_DEV_INITRD
105         ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
106         setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
107 //      setup_initrd(0xc0100000, 3*1024*1024);
108 #endif
109 }
110
111 extern void at91_register_uart(int idx, int port);
112
113 void __init at91rm9200_map_io(void)
114 {
115         int serial[AT91C_NR_UART] = AT91C_UART_MAP;
116         int i;
117
118         iotable_init(at91rm9200_io_desc);
119
120         /* Register UARTs */
121         for (i = 0; i < AT91C_NR_UART; i++) {
122                 if (serial[i] >= 0)
123                         at91_register_uart(i, serial[i]);
124         }
125 }
126
127 static void at91rm9200_mask_irq(unsigned int irq)
128 {
129         /* Disable interrupt on AIC */
130         AT91_SYS->AIC_IDCR =  1 << irq;
131 }
132
133 static void at91rm9200_unmask_irq(unsigned int irq)
134 {
135         /* Enable interrupt on AIC */
136         AT91_SYS->AIC_IECR =  1 << irq;
137 }
138
139 void __init at91rm9200_init_irq(void)
140 {
141         unsigned int i;
142
143         /*
144          * The IVR is used by macro get_irqnr_and_base to read and verify.
145          * The irq number is NR_IRQS when a spurious interrupt has occured.
146          */
147         for (i = 0; i < NR_IRQS; i++) {
148                 /* Put irq number in Source Vector Register: */
149                 AT91_SYS->AIC_SVR[i] = i;
150                 /* Store the Source Mode Register as defined in table above */
151                 AT91_SYS->AIC_SMR[i] = at91rm9200_irq_smr[i];
152
153                 irq_desc[i].valid       = 1;
154                 irq_desc[i].mask_ack    = at91rm9200_mask_irq;
155                 irq_desc[i].mask        = at91rm9200_mask_irq;
156                 irq_desc[i].unmask      = at91rm9200_unmask_irq;
157
158                 /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
159                 if (i < 8)
160                         AT91_SYS->AIC_EOICR = AT91_SYS->AIC_EOICR;
161         }
162
163         /* Spurious Interrupt ID in Spurious Vector Register is NR_IRQS
164          * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
165          */
166         AT91_SYS->AIC_SPU = NR_IRQS;
167
168         /* No debugging in AIC: Debug (Protect) Control Register */
169         AT91_SYS->AIC_DCR = 0;
170
171         /* Disable and clear all interrupts initially */
172         AT91_SYS->AIC_IDCR = 0xFFFFFFFF;
173         AT91_SYS->AIC_ICCR = 0xFFFFFFFF;
174 }
175
176 MACHINE_START(AT91RM9200, "ATMEL AT91RM9200")
177         MAINTAINER("SAN People / ATMEL")
178         BOOT_MEM(AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS)
179         BOOT_PARAMS(AT91_SDRAM_BASE + 0x100)
180         FIXUP(at91rm9200_fixup)
181         MAPIO(at91rm9200_map_io)
182         INITIRQ(at91rm9200_init_irq)
183 MACHINE_END