blob: e3e043c0004c0554e1033293d69e1725ebd1379f [file] [log] [blame]
Saeed Bisharaedabd382009-08-06 15:12:43 +03001/*
2 * arch/arm/mach-dove/common.c
3 *
4 * Core functions for Marvell Dove 88AP510 System On Chip
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/pci.h>
16#include <linux/serial_8250.h>
17#include <linux/clk.h>
18#include <linux/mbus.h>
Saeed Bisharaedabd382009-08-06 15:12:43 +030019#include <linux/ata_platform.h>
Andrew Lunn5c602552011-05-15 13:32:40 +020020#include <linux/serial_8250.h>
Saeed Bisharaedabd382009-08-06 15:12:43 +030021#include <linux/gpio.h>
22#include <asm/page.h>
23#include <asm/setup.h>
24#include <asm/timex.h>
Lennert Buytenhek573a6522009-11-24 19:33:52 +020025#include <asm/hardware/cache-tauros2.h>
Saeed Bisharaedabd382009-08-06 15:12:43 +030026#include <asm/mach/map.h>
27#include <asm/mach/time.h>
28#include <asm/mach/pci.h>
29#include <mach/dove.h>
30#include <mach/bridge-regs.h>
31#include <asm/mach/arch.h>
32#include <linux/irq.h>
33#include <plat/mv_xor.h>
34#include <plat/ehci-orion.h>
35#include <plat/time.h>
Andrew Lunn28a2b452011-05-15 13:32:41 +020036#include <plat/common.h>
Saeed Bisharaedabd382009-08-06 15:12:43 +030037#include "common.h"
38
Andrew Lunn28a2b452011-05-15 13:32:41 +020039static int get_tclk(void);
40
Saeed Bisharaedabd382009-08-06 15:12:43 +030041/*****************************************************************************
42 * I/O Address Mapping
43 ****************************************************************************/
44static struct map_desc dove_io_desc[] __initdata = {
45 {
46 .virtual = DOVE_SB_REGS_VIRT_BASE,
47 .pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
48 .length = DOVE_SB_REGS_SIZE,
49 .type = MT_DEVICE,
50 }, {
51 .virtual = DOVE_NB_REGS_VIRT_BASE,
52 .pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
53 .length = DOVE_NB_REGS_SIZE,
54 .type = MT_DEVICE,
55 }, {
56 .virtual = DOVE_PCIE0_IO_VIRT_BASE,
57 .pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
58 .length = DOVE_PCIE0_IO_SIZE,
59 .type = MT_DEVICE,
60 }, {
61 .virtual = DOVE_PCIE1_IO_VIRT_BASE,
62 .pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
63 .length = DOVE_PCIE1_IO_SIZE,
64 .type = MT_DEVICE,
65 },
66};
67
68void __init dove_map_io(void)
69{
70 iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
71}
72
73/*****************************************************************************
74 * EHCI
75 ****************************************************************************/
76static struct orion_ehci_data dove_ehci_data = {
77 .dram = &dove_mbus_dram_info,
78 .phy_version = EHCI_PHY_NA,
79};
80
81static u64 ehci_dmamask = DMA_BIT_MASK(32);
82
83/*****************************************************************************
84 * EHCI0
85 ****************************************************************************/
86static struct resource dove_ehci0_resources[] = {
87 {
88 .start = DOVE_USB0_PHYS_BASE,
89 .end = DOVE_USB0_PHYS_BASE + SZ_4K - 1,
90 .flags = IORESOURCE_MEM,
91 }, {
92 .start = IRQ_DOVE_USB0,
93 .end = IRQ_DOVE_USB0,
94 .flags = IORESOURCE_IRQ,
95 },
96};
97
98static struct platform_device dove_ehci0 = {
99 .name = "orion-ehci",
100 .id = 0,
101 .dev = {
102 .dma_mask = &ehci_dmamask,
103 .coherent_dma_mask = DMA_BIT_MASK(32),
104 .platform_data = &dove_ehci_data,
105 },
106 .resource = dove_ehci0_resources,
107 .num_resources = ARRAY_SIZE(dove_ehci0_resources),
108};
109
110void __init dove_ehci0_init(void)
111{
112 platform_device_register(&dove_ehci0);
113}
114
115/*****************************************************************************
116 * EHCI1
117 ****************************************************************************/
118static struct resource dove_ehci1_resources[] = {
119 {
120 .start = DOVE_USB1_PHYS_BASE,
121 .end = DOVE_USB1_PHYS_BASE + SZ_4K - 1,
122 .flags = IORESOURCE_MEM,
123 }, {
124 .start = IRQ_DOVE_USB1,
125 .end = IRQ_DOVE_USB1,
126 .flags = IORESOURCE_IRQ,
127 },
128};
129
130static struct platform_device dove_ehci1 = {
131 .name = "orion-ehci",
132 .id = 1,
133 .dev = {
134 .dma_mask = &ehci_dmamask,
135 .coherent_dma_mask = DMA_BIT_MASK(32),
136 .platform_data = &dove_ehci_data,
137 },
138 .resource = dove_ehci1_resources,
139 .num_resources = ARRAY_SIZE(dove_ehci1_resources),
140};
141
142void __init dove_ehci1_init(void)
143{
144 platform_device_register(&dove_ehci1);
145}
146
147/*****************************************************************************
148 * GE00
149 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300150void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
151{
Andrew Lunn7e3819d2011-05-15 13:32:44 +0200152 orion_ge00_init(eth_data, &dove_mbus_dram_info,
153 DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
154 0, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300155}
156
157/*****************************************************************************
158 * SoC RTC
159 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300160void __init dove_rtc_init(void)
161{
Andrew Lunnf6eaccb2011-05-15 13:32:42 +0200162 orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);
Saeed Bisharaedabd382009-08-06 15:12:43 +0300163}
164
165/*****************************************************************************
166 * SATA
167 ****************************************************************************/
168static struct resource dove_sata_resources[] = {
169 {
170 .name = "sata base",
171 .start = DOVE_SATA_PHYS_BASE,
172 .end = DOVE_SATA_PHYS_BASE + 0x5000 - 1,
173 .flags = IORESOURCE_MEM,
174 }, {
175 .name = "sata irq",
176 .start = IRQ_DOVE_SATA,
177 .end = IRQ_DOVE_SATA,
178 .flags = IORESOURCE_IRQ,
179 },
180};
181
182static struct platform_device dove_sata = {
183 .name = "sata_mv",
184 .id = 0,
185 .dev = {
186 .coherent_dma_mask = DMA_BIT_MASK(32),
187 },
188 .num_resources = ARRAY_SIZE(dove_sata_resources),
189 .resource = dove_sata_resources,
190};
191
192void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
193{
194 sata_data->dram = &dove_mbus_dram_info;
195 dove_sata.dev.platform_data = sata_data;
196 platform_device_register(&dove_sata);
197}
198
199/*****************************************************************************
200 * UART0
201 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300202void __init dove_uart0_init(void)
203{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200204 orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE,
205 IRQ_DOVE_UART_0, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300206}
207
208/*****************************************************************************
209 * UART1
210 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300211void __init dove_uart1_init(void)
212{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200213 orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
214 IRQ_DOVE_UART_1, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300215}
216
217/*****************************************************************************
218 * UART2
219 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300220void __init dove_uart2_init(void)
221{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200222 orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
223 IRQ_DOVE_UART_2, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300224}
225
226/*****************************************************************************
227 * UART3
228 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300229void __init dove_uart3_init(void)
230{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200231 orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
232 IRQ_DOVE_UART_3, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300233}
234
235/*****************************************************************************
Andrew Lunn980f9f62011-05-15 13:32:46 +0200236 * SPI
Saeed Bisharaedabd382009-08-06 15:12:43 +0300237 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300238void __init dove_spi0_init(void)
239{
Andrew Lunn980f9f62011-05-15 13:32:46 +0200240 orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300241}
242
Saeed Bisharaedabd382009-08-06 15:12:43 +0300243void __init dove_spi1_init(void)
244{
Andrew Lunn980f9f62011-05-15 13:32:46 +0200245 orion_spi_init(DOVE_SPI1_PHYS_BASE, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300246}
247
248/*****************************************************************************
249 * I2C
250 ****************************************************************************/
Saeed Bisharaedabd382009-08-06 15:12:43 +0300251void __init dove_i2c_init(void)
252{
Andrew Lunnaac7ffa2011-05-15 13:32:45 +0200253 orion_i2c_init(DOVE_I2C_PHYS_BASE, IRQ_DOVE_I2C, 10);
Saeed Bisharaedabd382009-08-06 15:12:43 +0300254}
255
256/*****************************************************************************
257 * Time handling
258 ****************************************************************************/
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200259void __init dove_init_early(void)
260{
261 orion_time_set_base(TIMER_VIRT_BASE);
262}
263
Saeed Bisharaedabd382009-08-06 15:12:43 +0300264static int get_tclk(void)
265{
266 /* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
267 return 166666667;
268}
269
270static void dove_timer_init(void)
271{
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200272 orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
273 IRQ_DOVE_BRIDGE, get_tclk());
Saeed Bisharaedabd382009-08-06 15:12:43 +0300274}
275
276struct sys_timer dove_timer = {
277 .init = dove_timer_init,
278};
279
280/*****************************************************************************
281 * XOR
282 ****************************************************************************/
283static struct mv_xor_platform_shared_data dove_xor_shared_data = {
284 .dram = &dove_mbus_dram_info,
285};
286
287/*****************************************************************************
288 * XOR 0
289 ****************************************************************************/
290static u64 dove_xor0_dmamask = DMA_BIT_MASK(32);
291
292static struct resource dove_xor0_shared_resources[] = {
293 {
294 .name = "xor 0 low",
295 .start = DOVE_XOR0_PHYS_BASE,
296 .end = DOVE_XOR0_PHYS_BASE + 0xff,
297 .flags = IORESOURCE_MEM,
298 }, {
299 .name = "xor 0 high",
300 .start = DOVE_XOR0_HIGH_PHYS_BASE,
301 .end = DOVE_XOR0_HIGH_PHYS_BASE + 0xff,
302 .flags = IORESOURCE_MEM,
303 },
304};
305
306static struct platform_device dove_xor0_shared = {
307 .name = MV_XOR_SHARED_NAME,
308 .id = 0,
309 .dev = {
310 .platform_data = &dove_xor_shared_data,
311 },
312 .num_resources = ARRAY_SIZE(dove_xor0_shared_resources),
313 .resource = dove_xor0_shared_resources,
314};
315
316static struct resource dove_xor00_resources[] = {
317 [0] = {
318 .start = IRQ_DOVE_XOR_00,
319 .end = IRQ_DOVE_XOR_00,
320 .flags = IORESOURCE_IRQ,
321 },
322};
323
324static struct mv_xor_platform_data dove_xor00_data = {
325 .shared = &dove_xor0_shared,
326 .hw_id = 0,
327 .pool_size = PAGE_SIZE,
328};
329
330static struct platform_device dove_xor00_channel = {
331 .name = MV_XOR_NAME,
332 .id = 0,
333 .num_resources = ARRAY_SIZE(dove_xor00_resources),
334 .resource = dove_xor00_resources,
335 .dev = {
336 .dma_mask = &dove_xor0_dmamask,
337 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweeten639b9be2010-01-29 15:30:53 -0700338 .platform_data = &dove_xor00_data,
Saeed Bisharaedabd382009-08-06 15:12:43 +0300339 },
340};
341
342static struct resource dove_xor01_resources[] = {
343 [0] = {
344 .start = IRQ_DOVE_XOR_01,
345 .end = IRQ_DOVE_XOR_01,
346 .flags = IORESOURCE_IRQ,
347 },
348};
349
350static struct mv_xor_platform_data dove_xor01_data = {
351 .shared = &dove_xor0_shared,
352 .hw_id = 1,
353 .pool_size = PAGE_SIZE,
354};
355
356static struct platform_device dove_xor01_channel = {
357 .name = MV_XOR_NAME,
358 .id = 1,
359 .num_resources = ARRAY_SIZE(dove_xor01_resources),
360 .resource = dove_xor01_resources,
361 .dev = {
362 .dma_mask = &dove_xor0_dmamask,
363 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweeten639b9be2010-01-29 15:30:53 -0700364 .platform_data = &dove_xor01_data,
Saeed Bisharaedabd382009-08-06 15:12:43 +0300365 },
366};
367
368void __init dove_xor0_init(void)
369{
370 platform_device_register(&dove_xor0_shared);
371
372 /*
373 * two engines can't do memset simultaneously, this limitation
374 * satisfied by removing memset support from one of the engines.
375 */
376 dma_cap_set(DMA_MEMCPY, dove_xor00_data.cap_mask);
377 dma_cap_set(DMA_XOR, dove_xor00_data.cap_mask);
378 platform_device_register(&dove_xor00_channel);
379
380 dma_cap_set(DMA_MEMCPY, dove_xor01_data.cap_mask);
381 dma_cap_set(DMA_MEMSET, dove_xor01_data.cap_mask);
382 dma_cap_set(DMA_XOR, dove_xor01_data.cap_mask);
383 platform_device_register(&dove_xor01_channel);
384}
385
386/*****************************************************************************
387 * XOR 1
388 ****************************************************************************/
389static u64 dove_xor1_dmamask = DMA_BIT_MASK(32);
390
391static struct resource dove_xor1_shared_resources[] = {
392 {
393 .name = "xor 0 low",
394 .start = DOVE_XOR1_PHYS_BASE,
395 .end = DOVE_XOR1_PHYS_BASE + 0xff,
396 .flags = IORESOURCE_MEM,
397 }, {
398 .name = "xor 0 high",
399 .start = DOVE_XOR1_HIGH_PHYS_BASE,
400 .end = DOVE_XOR1_HIGH_PHYS_BASE + 0xff,
401 .flags = IORESOURCE_MEM,
402 },
403};
404
405static struct platform_device dove_xor1_shared = {
406 .name = MV_XOR_SHARED_NAME,
407 .id = 1,
408 .dev = {
409 .platform_data = &dove_xor_shared_data,
410 },
411 .num_resources = ARRAY_SIZE(dove_xor1_shared_resources),
412 .resource = dove_xor1_shared_resources,
413};
414
415static struct resource dove_xor10_resources[] = {
416 [0] = {
417 .start = IRQ_DOVE_XOR_10,
418 .end = IRQ_DOVE_XOR_10,
419 .flags = IORESOURCE_IRQ,
420 },
421};
422
423static struct mv_xor_platform_data dove_xor10_data = {
424 .shared = &dove_xor1_shared,
425 .hw_id = 0,
426 .pool_size = PAGE_SIZE,
427};
428
429static struct platform_device dove_xor10_channel = {
430 .name = MV_XOR_NAME,
431 .id = 2,
432 .num_resources = ARRAY_SIZE(dove_xor10_resources),
433 .resource = dove_xor10_resources,
434 .dev = {
435 .dma_mask = &dove_xor1_dmamask,
436 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweeten639b9be2010-01-29 15:30:53 -0700437 .platform_data = &dove_xor10_data,
Saeed Bisharaedabd382009-08-06 15:12:43 +0300438 },
439};
440
441static struct resource dove_xor11_resources[] = {
442 [0] = {
443 .start = IRQ_DOVE_XOR_11,
444 .end = IRQ_DOVE_XOR_11,
445 .flags = IORESOURCE_IRQ,
446 },
447};
448
449static struct mv_xor_platform_data dove_xor11_data = {
450 .shared = &dove_xor1_shared,
451 .hw_id = 1,
452 .pool_size = PAGE_SIZE,
453};
454
455static struct platform_device dove_xor11_channel = {
456 .name = MV_XOR_NAME,
457 .id = 3,
458 .num_resources = ARRAY_SIZE(dove_xor11_resources),
459 .resource = dove_xor11_resources,
460 .dev = {
461 .dma_mask = &dove_xor1_dmamask,
462 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweeten639b9be2010-01-29 15:30:53 -0700463 .platform_data = &dove_xor11_data,
Saeed Bisharaedabd382009-08-06 15:12:43 +0300464 },
465};
466
467void __init dove_xor1_init(void)
468{
469 platform_device_register(&dove_xor1_shared);
470
471 /*
472 * two engines can't do memset simultaneously, this limitation
473 * satisfied by removing memset support from one of the engines.
474 */
475 dma_cap_set(DMA_MEMCPY, dove_xor10_data.cap_mask);
476 dma_cap_set(DMA_XOR, dove_xor10_data.cap_mask);
477 platform_device_register(&dove_xor10_channel);
478
479 dma_cap_set(DMA_MEMCPY, dove_xor11_data.cap_mask);
480 dma_cap_set(DMA_MEMSET, dove_xor11_data.cap_mask);
481 dma_cap_set(DMA_XOR, dove_xor11_data.cap_mask);
482 platform_device_register(&dove_xor11_channel);
483}
484
Saeed Bishara16bc90a2010-05-06 16:12:06 +0300485/*****************************************************************************
486 * SDIO
487 ****************************************************************************/
488static u64 sdio_dmamask = DMA_BIT_MASK(32);
489
490static struct resource dove_sdio0_resources[] = {
491 {
492 .start = DOVE_SDIO0_PHYS_BASE,
493 .end = DOVE_SDIO0_PHYS_BASE + 0xff,
494 .flags = IORESOURCE_MEM,
495 }, {
496 .start = IRQ_DOVE_SDIO0,
497 .end = IRQ_DOVE_SDIO0,
498 .flags = IORESOURCE_IRQ,
499 },
500};
501
502static struct platform_device dove_sdio0 = {
Mike Rapoport930e2fe2010-10-28 21:23:53 +0200503 .name = "sdhci-dove",
Saeed Bishara16bc90a2010-05-06 16:12:06 +0300504 .id = 0,
505 .dev = {
506 .dma_mask = &sdio_dmamask,
507 .coherent_dma_mask = DMA_BIT_MASK(32),
508 },
509 .resource = dove_sdio0_resources,
510 .num_resources = ARRAY_SIZE(dove_sdio0_resources),
511};
512
513void __init dove_sdio0_init(void)
514{
515 platform_device_register(&dove_sdio0);
516}
517
518static struct resource dove_sdio1_resources[] = {
519 {
520 .start = DOVE_SDIO1_PHYS_BASE,
521 .end = DOVE_SDIO1_PHYS_BASE + 0xff,
522 .flags = IORESOURCE_MEM,
523 }, {
524 .start = IRQ_DOVE_SDIO1,
525 .end = IRQ_DOVE_SDIO1,
526 .flags = IORESOURCE_IRQ,
527 },
528};
529
530static struct platform_device dove_sdio1 = {
Mike Rapoport930e2fe2010-10-28 21:23:53 +0200531 .name = "sdhci-dove",
Saeed Bishara16bc90a2010-05-06 16:12:06 +0300532 .id = 1,
533 .dev = {
534 .dma_mask = &sdio_dmamask,
535 .coherent_dma_mask = DMA_BIT_MASK(32),
536 },
537 .resource = dove_sdio1_resources,
538 .num_resources = ARRAY_SIZE(dove_sdio1_resources),
539};
540
541void __init dove_sdio1_init(void)
542{
543 platform_device_register(&dove_sdio1);
544}
545
Saeed Bisharaedabd382009-08-06 15:12:43 +0300546void __init dove_init(void)
547{
548 int tclk;
549
550 tclk = get_tclk();
551
552 printk(KERN_INFO "Dove 88AP510 SoC, ");
553 printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
554
Lennert Buytenhek573a6522009-11-24 19:33:52 +0200555#ifdef CONFIG_CACHE_TAUROS2
556 tauros2_init();
557#endif
Saeed Bisharaedabd382009-08-06 15:12:43 +0300558 dove_setup_cpu_mbus();
559
Saeed Bisharaedabd382009-08-06 15:12:43 +0300560 /* internal devices that every board has */
561 dove_rtc_init();
562 dove_xor0_init();
563 dove_xor1_init();
564}