diff options
Diffstat (limited to 'arch/arm/mach-lh7a40x/arch-lpd7a40x.c')
-rw-r--r-- | arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 200 |
1 files changed, 140 insertions, 60 deletions
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index 12e23277c5ea..c0e6854289f1 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c | |||
@@ -23,6 +23,28 @@ | |||
23 | 23 | ||
24 | #include "common.h" | 24 | #include "common.h" |
25 | 25 | ||
26 | #define CPLD_INT_NETHERNET (1<<0) | ||
27 | #define CPLD_INTMASK_ETHERNET (1<<2) | ||
28 | #if defined (CONFIG_MACH_LPD7A400) | ||
29 | # define CPLD_INT_NTOUCH (1<<1) | ||
30 | # define CPLD_INTMASK_TOUCH (1<<3) | ||
31 | # define CPLD_INT_PEN (1<<4) | ||
32 | # define CPLD_INTMASK_PEN (1<<4) | ||
33 | # define CPLD_INT_PIRQ (1<<4) | ||
34 | #endif | ||
35 | #define CPLD_INTMASK_CPLD (1<<7) | ||
36 | #define CPLD_INT_CPLD (1<<6) | ||
37 | |||
38 | #define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */ | ||
39 | #define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */ | ||
40 | #define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */ | ||
41 | #define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */ | ||
42 | #define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */ | ||
43 | #define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */ | ||
44 | #define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */ | ||
45 | #define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */ | ||
46 | |||
47 | |||
26 | static struct resource smc91x_resources[] = { | 48 | static struct resource smc91x_resources[] = { |
27 | [0] = { | 49 | [0] = { |
28 | .start = CPLD00_PHYS, | 50 | .start = CPLD00_PHYS, |
@@ -48,12 +70,12 @@ static struct platform_device smc91x_device = { | |||
48 | static struct resource lh7a40x_usbclient_resources[] = { | 70 | static struct resource lh7a40x_usbclient_resources[] = { |
49 | [0] = { | 71 | [0] = { |
50 | .start = USB_PHYS, | 72 | .start = USB_PHYS, |
51 | .end = (USB_PHYS + 0xFF), | 73 | .end = (USB_PHYS + PAGE_SIZE), |
52 | .flags = IORESOURCE_MEM, | 74 | .flags = IORESOURCE_MEM, |
53 | }, | 75 | }, |
54 | [1] = { | 76 | [1] = { |
55 | .start = IRQ_USBINTR, | 77 | .start = IRQ_USB, |
56 | .end = IRQ_USBINTR, | 78 | .end = IRQ_USB, |
57 | .flags = IORESOURCE_IRQ, | 79 | .flags = IORESOURCE_IRQ, |
58 | }, | 80 | }, |
59 | }; | 81 | }; |
@@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = { | |||
61 | static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; | 83 | static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; |
62 | 84 | ||
63 | static struct platform_device lh7a40x_usbclient_device = { | 85 | static struct platform_device lh7a40x_usbclient_device = { |
64 | .name = "lh7a40x_udc", | 86 | // .name = "lh7a40x_udc", |
87 | .name = "lh7-udc", | ||
65 | .id = 0, | 88 | .id = 0, |
66 | .dev = { | 89 | .dev = { |
67 | .dma_mask = &lh7a40x_usbclient_dma_mask, | 90 | .dma_mask = &lh7a40x_usbclient_dma_mask, |
@@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = { | |||
101 | 124 | ||
102 | #endif | 125 | #endif |
103 | 126 | ||
104 | static struct platform_device *lpd7a40x_devs[] __initdata = { | 127 | static struct platform_device* lpd7a40x_devs[] __initdata = { |
105 | &smc91x_device, | 128 | &smc91x_device, |
106 | &lh7a40x_usbclient_device, | 129 | &lh7a40x_usbclient_device, |
107 | #if defined (CONFIG_ARCH_LH7A404) | 130 | #if defined (CONFIG_ARCH_LH7A404) |
@@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void); | |||
113 | 136 | ||
114 | static void __init lpd7a40x_init (void) | 137 | static void __init lpd7a40x_init (void) |
115 | { | 138 | { |
116 | CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */ | 139 | #if defined (CONFIG_MACH_LPD7A400) |
140 | CPLD_CONTROL |= 0 | ||
141 | | CPLD_CONTROL_SWINT /* Disable software interrupt */ | ||
142 | | CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */ | ||
117 | CPLD_CONTROL &= ~(0 | 143 | CPLD_CONTROL &= ~(0 |
118 | | (1<<1) /* Disable LCD */ | 144 | | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */ |
119 | | (1<<0) /* Enable WLAN */ | 145 | | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */ |
120 | ); | 146 | ); |
147 | #endif | ||
148 | |||
149 | #if defined (CONFIG_MACH_LPD7A404) | ||
150 | CPLD_CONTROL &= ~(0 | ||
151 | | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */ | ||
152 | ); | ||
153 | #endif | ||
121 | 154 | ||
122 | platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); | 155 | platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); |
156 | #if defined (CONFIG_FB_ARMCLCD) | ||
157 | lh7a40x_clcd_init (); | ||
158 | #endif | ||
123 | } | 159 | } |
124 | 160 | ||
125 | static void lh7a40x_ack_cpld_irq (u32 irq) | 161 | static void lh7a40x_ack_cpld_irq (u32 irq) |
126 | { | 162 | { |
127 | /* CPLD doesn't have ack capability */ | 163 | /* CPLD doesn't have ack capability, but some devices may */ |
164 | |||
165 | #if defined (CPLD_INTMASK_TOUCH) | ||
166 | /* The touch control *must* mask the the interrupt because the | ||
167 | * interrupt bit is read by the driver to determine if the pen | ||
168 | * is still down. */ | ||
169 | if (irq == IRQ_TOUCH) | ||
170 | CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH; | ||
171 | #endif | ||
128 | } | 172 | } |
129 | 173 | ||
130 | static void lh7a40x_mask_cpld_irq (u32 irq) | 174 | static void lh7a40x_mask_cpld_irq (u32 irq) |
131 | { | 175 | { |
132 | switch (irq) { | 176 | switch (irq) { |
133 | case IRQ_LPD7A40X_ETH_INT: | 177 | case IRQ_LPD7A40X_ETH_INT: |
134 | CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; | 178 | CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET; |
135 | break; | 179 | break; |
136 | case IRQ_LPD7A400_TS: | 180 | #if defined (IRQ_TOUCH) |
137 | CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; | 181 | case IRQ_TOUCH: |
182 | CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH; | ||
138 | break; | 183 | break; |
184 | #endif | ||
139 | } | 185 | } |
140 | } | 186 | } |
141 | 187 | ||
@@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq) | |||
143 | { | 189 | { |
144 | switch (irq) { | 190 | switch (irq) { |
145 | case IRQ_LPD7A40X_ETH_INT: | 191 | case IRQ_LPD7A40X_ETH_INT: |
146 | CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; | 192 | CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET; |
147 | break; | 193 | break; |
148 | case IRQ_LPD7A400_TS: | 194 | #if defined (IRQ_TOUCH) |
149 | CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; | 195 | case IRQ_TOUCH: |
196 | CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH; | ||
150 | break; | 197 | break; |
198 | #endif | ||
151 | } | 199 | } |
152 | } | 200 | } |
153 | 201 | ||
@@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, | |||
164 | 212 | ||
165 | desc->chip->ack (irq); | 213 | desc->chip->ack (irq); |
166 | 214 | ||
167 | if ((mask & 0x1) == 0) /* WLAN */ | 215 | if ((mask & (1<<0)) == 0) /* WLAN */ |
168 | IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); | 216 | IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); |
169 | 217 | ||
170 | if ((mask & 0x2) == 0) /* Touch */ | 218 | #if defined (IRQ_TOUCH) |
171 | IRQ_DISPATCH (IRQ_LPD7A400_TS); | 219 | if ((mask & (1<<1)) == 0) /* Touch */ |
220 | IRQ_DISPATCH (IRQ_TOUCH); | ||
221 | #endif | ||
172 | 222 | ||
173 | desc->chip->unmask (irq); /* Level-triggered need this */ | 223 | desc->chip->unmask (irq); /* Level-triggered need this */ |
174 | } | 224 | } |
@@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void) | |||
204 | 254 | ||
205 | /* Then, configure CPLD interrupt */ | 255 | /* Then, configure CPLD interrupt */ |
206 | 256 | ||
207 | CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */ | 257 | /* Disable all CPLD interrupts */ |
258 | #if defined (CONFIG_MACH_LPD7A400) | ||
259 | CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN | ||
260 | | CPLD_INTMASK_ETHERNET; | ||
261 | /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong | ||
262 | and 4 is uncefined. */ | ||
263 | // (1<<7)|(1<<4)|(1<<3)|(1<<2); | ||
264 | #endif | ||
265 | #if defined (CONFIG_MACH_LPD7A404) | ||
266 | CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET; | ||
267 | /* *** FIXME: don't know why we need 6 and 5, neither is defined. */ | ||
268 | // (1<<6)|(1<<5)|(1<<3); | ||
269 | #endif | ||
208 | GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ | 270 | GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ |
209 | GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ | 271 | GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */ |
210 | GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ | 272 | GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ |
211 | barrier (); | 273 | barrier (); |
212 | GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ | 274 | GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ |
@@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void) | |||
216 | for (irq = IRQ_BOARD_START; | 278 | for (irq = IRQ_BOARD_START; |
217 | irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { | 279 | irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { |
218 | set_irq_chip (irq, &lpd7a40x_cpld_chip); | 280 | set_irq_chip (irq, &lpd7a40x_cpld_chip); |
219 | set_irq_handler (irq, do_edge_IRQ); | 281 | set_irq_handler (irq, do_level_IRQ); |
220 | set_irq_flags (irq, IRQF_VALID); | 282 | set_irq_flags (irq, IRQF_VALID); |
221 | } | 283 | } |
222 | 284 | ||
@@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void) | |||
226 | lpd7a40x_cpld_handler); | 288 | lpd7a40x_cpld_handler); |
227 | } | 289 | } |
228 | 290 | ||
229 | static struct map_desc lpd7a400_io_desc[] __initdata = { | 291 | static struct map_desc lpd7a40x_io_desc[] __initdata = { |
230 | { | 292 | { |
231 | .virtual = IO_VIRT, | 293 | .virtual = IO_VIRT, |
232 | .pfn = __phys_to_pfn(IO_PHYS), | 294 | .pfn = __phys_to_pfn(IO_PHYS), |
233 | .length = IO_SIZE, | 295 | .length = IO_SIZE, |
234 | .type = MT_DEVICE | 296 | .type = MT_DEVICE |
235 | }, { /* Mapping added to work around chip select problems */ | 297 | }, |
298 | { /* Mapping added to work around chip select problems */ | ||
236 | .virtual = IOBARRIER_VIRT, | 299 | .virtual = IOBARRIER_VIRT, |
237 | .pfn = __phys_to_pfn(IOBARRIER_PHYS), | 300 | .pfn = __phys_to_pfn(IOBARRIER_PHYS), |
238 | .length = IOBARRIER_SIZE, | 301 | .length = IOBARRIER_SIZE, |
239 | .type = MT_DEVICE | 302 | .type = MT_DEVICE |
240 | }, { | 303 | }, |
304 | { | ||
241 | .virtual = CF_VIRT, | 305 | .virtual = CF_VIRT, |
242 | .pfn = __phys_to_pfn(CF_PHYS), | 306 | .pfn = __phys_to_pfn(CF_PHYS), |
243 | .length = CF_SIZE, | 307 | .length = CF_SIZE, |
244 | .type = MT_DEVICE | 308 | .type = MT_DEVICE |
245 | }, { | 309 | }, |
310 | { | ||
246 | .virtual = CPLD02_VIRT, | 311 | .virtual = CPLD02_VIRT, |
247 | .pfn = __phys_to_pfn(CPLD02_PHYS), | 312 | .pfn = __phys_to_pfn(CPLD02_PHYS), |
248 | .length = CPLD02_SIZE, | 313 | .length = CPLD02_SIZE, |
249 | .type = MT_DEVICE | 314 | .type = MT_DEVICE |
250 | }, { | 315 | }, |
316 | { | ||
251 | .virtual = CPLD06_VIRT, | 317 | .virtual = CPLD06_VIRT, |
252 | .pfn = __phys_to_pfn(CPLD06_PHYS), | 318 | .pfn = __phys_to_pfn(CPLD06_PHYS), |
253 | .length = CPLD06_SIZE, | 319 | .length = CPLD06_SIZE, |
320 | .type = MT_DEVICE | ||
321 | }, | ||
322 | { | ||
323 | .virtual = CPLD08_VIRT, | ||
324 | .pfn = __phys_to_pfn(CPLD08_PHYS), | ||
325 | .length = CPLD08_SIZE, | ||
254 | .type = MT_DEVICE | 326 | .type = MT_DEVICE |
255 | }, { | 327 | }, |
328 | { | ||
256 | .virtual = CPLD08_VIRT, | 329 | .virtual = CPLD08_VIRT, |
257 | .pfn = __phys_to_pfn(CPLD08_PHYS), | 330 | .pfn = __phys_to_pfn(CPLD08_PHYS), |
258 | .length = CPLD08_SIZE, | 331 | .length = CPLD08_SIZE, |
259 | .type = MT_DEVICE | 332 | .type = MT_DEVICE |
260 | }, { | 333 | }, |
334 | { | ||
335 | .virtual = CPLD0A_VIRT, | ||
336 | .pfn = __phys_to_pfn(CPLD0A_PHYS), | ||
337 | .length = CPLD0A_SIZE, | ||
338 | .type = MT_DEVICE | ||
339 | }, | ||
340 | { | ||
261 | .virtual = CPLD0C_VIRT, | 341 | .virtual = CPLD0C_VIRT, |
262 | .pfn = __phys_to_pfn(CPLD0C_PHYS), | 342 | .pfn = __phys_to_pfn(CPLD0C_PHYS), |
263 | .length = CPLD0C_SIZE, | 343 | .length = CPLD0C_SIZE, |
264 | .type = MT_DEVICE | 344 | .type = MT_DEVICE |
265 | }, { | 345 | }, |
346 | { | ||
266 | .virtual = CPLD0E_VIRT, | 347 | .virtual = CPLD0E_VIRT, |
267 | .pfn = __phys_to_pfn(CPLD0E_PHYS), | 348 | .pfn = __phys_to_pfn(CPLD0E_PHYS), |
268 | .length = CPLD0E_SIZE, | 349 | .length = CPLD0E_SIZE, |
269 | .type = MT_DEVICE | 350 | .type = MT_DEVICE |
270 | }, { | 351 | }, |
352 | { | ||
271 | .virtual = CPLD10_VIRT, | 353 | .virtual = CPLD10_VIRT, |
272 | .pfn = __phys_to_pfn(CPLD10_PHYS), | 354 | .pfn = __phys_to_pfn(CPLD10_PHYS), |
273 | .length = CPLD10_SIZE, | 355 | .length = CPLD10_SIZE, |
274 | .type = MT_DEVICE | 356 | .type = MT_DEVICE |
275 | }, { | 357 | }, |
358 | { | ||
276 | .virtual = CPLD12_VIRT, | 359 | .virtual = CPLD12_VIRT, |
277 | .pfn = __phys_to_pfn(CPLD12_PHYS), | 360 | .pfn = __phys_to_pfn(CPLD12_PHYS), |
278 | .length = CPLD12_SIZE, | 361 | .length = CPLD12_SIZE, |
279 | .type = MT_DEVICE | 362 | .type = MT_DEVICE |
280 | }, { | 363 | }, |
364 | { | ||
281 | .virtual = CPLD14_VIRT, | 365 | .virtual = CPLD14_VIRT, |
282 | .pfn = __phys_to_pfn(CPLD14_PHYS), | 366 | .pfn = __phys_to_pfn(CPLD14_PHYS), |
283 | .length = CPLD14_SIZE, | 367 | .length = CPLD14_SIZE, |
284 | .type = MT_DEVICE | 368 | .type = MT_DEVICE |
285 | }, { | 369 | }, |
370 | { | ||
286 | .virtual = CPLD16_VIRT, | 371 | .virtual = CPLD16_VIRT, |
287 | .pfn = __phys_to_pfn(CPLD16_PHYS), | 372 | .pfn = __phys_to_pfn(CPLD16_PHYS), |
288 | .length = CPLD16_SIZE, | 373 | .length = CPLD16_SIZE, |
289 | .type = MT_DEVICE | 374 | .type = MT_DEVICE |
290 | }, { | 375 | }, |
376 | { | ||
291 | .virtual = CPLD18_VIRT, | 377 | .virtual = CPLD18_VIRT, |
292 | .pfn = __phys_to_pfn(CPLD18_PHYS), | 378 | .pfn = __phys_to_pfn(CPLD18_PHYS), |
293 | .length = CPLD18_SIZE, | 379 | .length = CPLD18_SIZE, |
294 | .type = MT_DEVICE | 380 | .type = MT_DEVICE |
295 | }, { | 381 | }, |
382 | { | ||
296 | .virtual = CPLD1A_VIRT, | 383 | .virtual = CPLD1A_VIRT, |
297 | .pfn = __phys_to_pfn(CPLD1A_PHYS), | 384 | .pfn = __phys_to_pfn(CPLD1A_PHYS), |
298 | .length = CPLD1A_SIZE, | 385 | .length = CPLD1A_SIZE, |
299 | .type = MT_DEVICE | 386 | .type = MT_DEVICE |
300 | }, | 387 | }, |
301 | /* This mapping is redundant since the smc driver performs another. */ | ||
302 | /* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */ | ||
303 | }; | 388 | }; |
304 | 389 | ||
305 | void __init | 390 | void __init |
306 | lpd7a400_map_io(void) | 391 | lpd7a40x_map_io(void) |
307 | { | 392 | { |
308 | iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc)); | 393 | iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc)); |
309 | |||
310 | /* Fixup (improve) Static Memory Controller settings */ | ||
311 | SMC_BCR0 = 0x200039af; /* Boot Flash */ | ||
312 | SMC_BCR6 = 0x1000fbe0; /* CPLD */ | ||
313 | SMC_BCR7 = 0x1000b2c2; /* Compact Flash */ | ||
314 | } | 394 | } |
315 | 395 | ||
316 | #ifdef CONFIG_MACH_LPD7A400 | 396 | #ifdef CONFIG_MACH_LPD7A400 |
@@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") | |||
320 | .phys_io = 0x80000000, | 400 | .phys_io = 0x80000000, |
321 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, | 401 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, |
322 | .boot_params = 0xc0000100, | 402 | .boot_params = 0xc0000100, |
323 | .map_io = lpd7a400_map_io, | 403 | .map_io = lpd7a40x_map_io, |
324 | .init_irq = lh7a400_init_irq, | 404 | .init_irq = lh7a400_init_irq, |
325 | .timer = &lh7a40x_timer, | 405 | .timer = &lh7a40x_timer, |
326 | .init_machine = lpd7a40x_init, | 406 | .init_machine = lpd7a40x_init, |
@@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") | |||
335 | .phys_io = 0x80000000, | 415 | .phys_io = 0x80000000, |
336 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, | 416 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, |
337 | .boot_params = 0xc0000100, | 417 | .boot_params = 0xc0000100, |
338 | .map_io = lpd7a400_map_io, | 418 | .map_io = lpd7a40x_map_io, |
339 | .init_irq = lh7a404_init_irq, | 419 | .init_irq = lh7a404_init_irq, |
340 | .timer = &lh7a40x_timer, | 420 | .timer = &lh7a40x_timer, |
341 | .init_machine = lpd7a40x_init, | 421 | .init_machine = lpd7a40x_init, |