blob: 435fb35a48450da83723aff2c4796ac9475ffe87 [file] [log] [blame]
Saeed Bishara651c74c2008-06-22 22:45:06 +02001/*
2 * arch/arm/mach-kirkwood/common.c
3 *
4 * Core functions for Marvell Kirkwood SoCs
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/init.h>
13#include <linux/platform_device.h>
14#include <linux/serial_8250.h>
15#include <linux/mbus.h>
16#include <linux/mv643xx_eth.h>
17#include <linux/ata_platform.h>
Lennert Buytenhek18365d12008-08-09 15:38:18 +020018#include <linux/spi/orion_spi.h>
Saeed Bishara651c74c2008-06-22 22:45:06 +020019#include <asm/page.h>
20#include <asm/timex.h>
21#include <asm/mach/map.h>
22#include <asm/mach/time.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010023#include <mach/kirkwood.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020024#include <plat/cache-feroceon-l2.h>
25#include <plat/ehci-orion.h>
Saeed Bishara09c0ed22008-06-23 04:26:07 -110026#include <plat/mv_xor.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020027#include <plat/orion_nand.h>
28#include <plat/time.h>
Saeed Bishara651c74c2008-06-22 22:45:06 +020029#include "common.h"
30
31/*****************************************************************************
32 * I/O Address Mapping
33 ****************************************************************************/
34static struct map_desc kirkwood_io_desc[] __initdata = {
35 {
36 .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
37 .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
38 .length = KIRKWOOD_PCIE_IO_SIZE,
39 .type = MT_DEVICE,
40 }, {
41 .virtual = KIRKWOOD_REGS_VIRT_BASE,
42 .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
43 .length = KIRKWOOD_REGS_SIZE,
44 .type = MT_DEVICE,
45 },
46};
47
48void __init kirkwood_map_io(void)
49{
50 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
51}
52
53
54/*****************************************************************************
55 * EHCI
56 ****************************************************************************/
57static struct orion_ehci_data kirkwood_ehci_data = {
58 .dram = &kirkwood_mbus_dram_info,
59};
60
61static u64 ehci_dmamask = 0xffffffffUL;
62
63
64/*****************************************************************************
65 * EHCI0
66 ****************************************************************************/
67static struct resource kirkwood_ehci_resources[] = {
68 {
69 .start = USB_PHYS_BASE,
70 .end = USB_PHYS_BASE + 0x0fff,
71 .flags = IORESOURCE_MEM,
72 }, {
73 .start = IRQ_KIRKWOOD_USB,
74 .end = IRQ_KIRKWOOD_USB,
75 .flags = IORESOURCE_IRQ,
76 },
77};
78
79static struct platform_device kirkwood_ehci = {
80 .name = "orion-ehci",
81 .id = 0,
82 .dev = {
83 .dma_mask = &ehci_dmamask,
84 .coherent_dma_mask = 0xffffffff,
85 .platform_data = &kirkwood_ehci_data,
86 },
87 .resource = kirkwood_ehci_resources,
88 .num_resources = ARRAY_SIZE(kirkwood_ehci_resources),
89};
90
91void __init kirkwood_ehci_init(void)
92{
93 platform_device_register(&kirkwood_ehci);
94}
95
96
97/*****************************************************************************
98 * GE00
99 ****************************************************************************/
100struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
101 .t_clk = KIRKWOOD_TCLK,
102 .dram = &kirkwood_mbus_dram_info,
103};
104
105static struct resource kirkwood_ge00_shared_resources[] = {
106 {
107 .name = "ge00 base",
108 .start = GE00_PHYS_BASE + 0x2000,
109 .end = GE00_PHYS_BASE + 0x3fff,
110 .flags = IORESOURCE_MEM,
Lennert Buytenhek144f8142008-08-26 16:04:05 +0200111 }, {
112 .name = "ge00 err irq",
113 .start = IRQ_KIRKWOOD_GE00_ERR,
114 .end = IRQ_KIRKWOOD_GE00_ERR,
115 .flags = IORESOURCE_IRQ,
Saeed Bishara651c74c2008-06-22 22:45:06 +0200116 },
117};
118
119static struct platform_device kirkwood_ge00_shared = {
120 .name = MV643XX_ETH_SHARED_NAME,
121 .id = 0,
122 .dev = {
123 .platform_data = &kirkwood_ge00_shared_data,
124 },
Lennert Buytenhek144f8142008-08-26 16:04:05 +0200125 .num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources),
Saeed Bishara651c74c2008-06-22 22:45:06 +0200126 .resource = kirkwood_ge00_shared_resources,
127};
128
129static struct resource kirkwood_ge00_resources[] = {
130 {
131 .name = "ge00 irq",
132 .start = IRQ_KIRKWOOD_GE00_SUM,
133 .end = IRQ_KIRKWOOD_GE00_SUM,
134 .flags = IORESOURCE_IRQ,
135 },
136};
137
138static struct platform_device kirkwood_ge00 = {
139 .name = MV643XX_ETH_NAME,
140 .id = 0,
141 .num_resources = 1,
142 .resource = kirkwood_ge00_resources,
143};
144
145void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
146{
147 eth_data->shared = &kirkwood_ge00_shared;
148 kirkwood_ge00.dev.platform_data = eth_data;
149
150 platform_device_register(&kirkwood_ge00_shared);
151 platform_device_register(&kirkwood_ge00);
152}
153
154
155/*****************************************************************************
156 * SoC RTC
157 ****************************************************************************/
158static struct resource kirkwood_rtc_resource = {
159 .start = RTC_PHYS_BASE,
160 .end = RTC_PHYS_BASE + SZ_16 - 1,
161 .flags = IORESOURCE_MEM,
162};
163
164void __init kirkwood_rtc_init(void)
165{
166 platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
167}
168
169
170/*****************************************************************************
171 * SATA
172 ****************************************************************************/
173static struct resource kirkwood_sata_resources[] = {
174 {
175 .name = "sata base",
176 .start = SATA_PHYS_BASE,
177 .end = SATA_PHYS_BASE + 0x5000 - 1,
178 .flags = IORESOURCE_MEM,
179 }, {
180 .name = "sata irq",
181 .start = IRQ_KIRKWOOD_SATA,
182 .end = IRQ_KIRKWOOD_SATA,
183 .flags = IORESOURCE_IRQ,
184 },
185};
186
187static struct platform_device kirkwood_sata = {
188 .name = "sata_mv",
189 .id = 0,
190 .dev = {
191 .coherent_dma_mask = 0xffffffff,
192 },
193 .num_resources = ARRAY_SIZE(kirkwood_sata_resources),
194 .resource = kirkwood_sata_resources,
195};
196
197void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
198{
199 sata_data->dram = &kirkwood_mbus_dram_info;
200 kirkwood_sata.dev.platform_data = sata_data;
201 platform_device_register(&kirkwood_sata);
202}
203
204
205/*****************************************************************************
Lennert Buytenhek18365d12008-08-09 15:38:18 +0200206 * SPI
207 ****************************************************************************/
208static struct orion_spi_info kirkwood_spi_plat_data = {
209 .tclk = KIRKWOOD_TCLK,
210};
211
212static struct resource kirkwood_spi_resources[] = {
213 {
214 .start = SPI_PHYS_BASE,
215 .end = SPI_PHYS_BASE + SZ_512 - 1,
216 .flags = IORESOURCE_MEM,
217 },
218};
219
220static struct platform_device kirkwood_spi = {
221 .name = "orion_spi",
222 .id = 0,
223 .resource = kirkwood_spi_resources,
224 .dev = {
225 .platform_data = &kirkwood_spi_plat_data,
226 },
227 .num_resources = ARRAY_SIZE(kirkwood_spi_resources),
228};
229
230void __init kirkwood_spi_init()
231{
232 platform_device_register(&kirkwood_spi);
233}
234
235
236/*****************************************************************************
Saeed Bishara651c74c2008-06-22 22:45:06 +0200237 * UART0
238 ****************************************************************************/
239static struct plat_serial8250_port kirkwood_uart0_data[] = {
240 {
241 .mapbase = UART0_PHYS_BASE,
242 .membase = (char *)UART0_VIRT_BASE,
243 .irq = IRQ_KIRKWOOD_UART_0,
244 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
245 .iotype = UPIO_MEM,
246 .regshift = 2,
247 .uartclk = KIRKWOOD_TCLK,
248 }, {
249 },
250};
251
252static struct resource kirkwood_uart0_resources[] = {
253 {
254 .start = UART0_PHYS_BASE,
255 .end = UART0_PHYS_BASE + 0xff,
256 .flags = IORESOURCE_MEM,
257 }, {
258 .start = IRQ_KIRKWOOD_UART_0,
259 .end = IRQ_KIRKWOOD_UART_0,
260 .flags = IORESOURCE_IRQ,
261 },
262};
263
264static struct platform_device kirkwood_uart0 = {
265 .name = "serial8250",
266 .id = 0,
267 .dev = {
268 .platform_data = kirkwood_uart0_data,
269 },
270 .resource = kirkwood_uart0_resources,
271 .num_resources = ARRAY_SIZE(kirkwood_uart0_resources),
272};
273
274void __init kirkwood_uart0_init(void)
275{
276 platform_device_register(&kirkwood_uart0);
277}
278
279
280/*****************************************************************************
281 * UART1
282 ****************************************************************************/
283static struct plat_serial8250_port kirkwood_uart1_data[] = {
284 {
285 .mapbase = UART1_PHYS_BASE,
286 .membase = (char *)UART1_VIRT_BASE,
287 .irq = IRQ_KIRKWOOD_UART_1,
288 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
289 .iotype = UPIO_MEM,
290 .regshift = 2,
291 .uartclk = KIRKWOOD_TCLK,
292 }, {
293 },
294};
295
296static struct resource kirkwood_uart1_resources[] = {
297 {
298 .start = UART1_PHYS_BASE,
299 .end = UART1_PHYS_BASE + 0xff,
300 .flags = IORESOURCE_MEM,
301 }, {
302 .start = IRQ_KIRKWOOD_UART_1,
303 .end = IRQ_KIRKWOOD_UART_1,
304 .flags = IORESOURCE_IRQ,
305 },
306};
307
308static struct platform_device kirkwood_uart1 = {
309 .name = "serial8250",
310 .id = 1,
311 .dev = {
312 .platform_data = kirkwood_uart1_data,
313 },
314 .resource = kirkwood_uart1_resources,
315 .num_resources = ARRAY_SIZE(kirkwood_uart1_resources),
316};
317
318void __init kirkwood_uart1_init(void)
319{
320 platform_device_register(&kirkwood_uart1);
321}
322
323
324/*****************************************************************************
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100325 * XOR
326 ****************************************************************************/
327static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = {
328 .dram = &kirkwood_mbus_dram_info,
329};
330
331static u64 kirkwood_xor_dmamask = DMA_32BIT_MASK;
332
333
334/*****************************************************************************
335 * XOR0
336 ****************************************************************************/
337static struct resource kirkwood_xor0_shared_resources[] = {
338 {
339 .name = "xor 0 low",
340 .start = XOR0_PHYS_BASE,
341 .end = XOR0_PHYS_BASE + 0xff,
342 .flags = IORESOURCE_MEM,
343 }, {
344 .name = "xor 0 high",
345 .start = XOR0_HIGH_PHYS_BASE,
346 .end = XOR0_HIGH_PHYS_BASE + 0xff,
347 .flags = IORESOURCE_MEM,
348 },
349};
350
351static struct platform_device kirkwood_xor0_shared = {
352 .name = MV_XOR_SHARED_NAME,
353 .id = 0,
354 .dev = {
355 .platform_data = &kirkwood_xor_shared_data,
356 },
357 .num_resources = ARRAY_SIZE(kirkwood_xor0_shared_resources),
358 .resource = kirkwood_xor0_shared_resources,
359};
360
361static struct resource kirkwood_xor00_resources[] = {
362 [0] = {
363 .start = IRQ_KIRKWOOD_XOR_00,
364 .end = IRQ_KIRKWOOD_XOR_00,
365 .flags = IORESOURCE_IRQ,
366 },
367};
368
369static struct mv_xor_platform_data kirkwood_xor00_data = {
370 .shared = &kirkwood_xor0_shared,
371 .hw_id = 0,
372 .pool_size = PAGE_SIZE,
373};
374
375static struct platform_device kirkwood_xor00_channel = {
376 .name = MV_XOR_NAME,
377 .id = 0,
378 .num_resources = ARRAY_SIZE(kirkwood_xor00_resources),
379 .resource = kirkwood_xor00_resources,
380 .dev = {
381 .dma_mask = &kirkwood_xor_dmamask,
382 .coherent_dma_mask = DMA_64BIT_MASK,
383 .platform_data = (void *)&kirkwood_xor00_data,
384 },
385};
386
387static struct resource kirkwood_xor01_resources[] = {
388 [0] = {
389 .start = IRQ_KIRKWOOD_XOR_01,
390 .end = IRQ_KIRKWOOD_XOR_01,
391 .flags = IORESOURCE_IRQ,
392 },
393};
394
395static struct mv_xor_platform_data kirkwood_xor01_data = {
396 .shared = &kirkwood_xor0_shared,
397 .hw_id = 1,
398 .pool_size = PAGE_SIZE,
399};
400
401static struct platform_device kirkwood_xor01_channel = {
402 .name = MV_XOR_NAME,
403 .id = 1,
404 .num_resources = ARRAY_SIZE(kirkwood_xor01_resources),
405 .resource = kirkwood_xor01_resources,
406 .dev = {
407 .dma_mask = &kirkwood_xor_dmamask,
408 .coherent_dma_mask = DMA_64BIT_MASK,
409 .platform_data = (void *)&kirkwood_xor01_data,
410 },
411};
412
413void __init kirkwood_xor0_init(void)
414{
415 platform_device_register(&kirkwood_xor0_shared);
416
417 /*
418 * two engines can't do memset simultaneously, this limitation
419 * satisfied by removing memset support from one of the engines.
420 */
421 dma_cap_set(DMA_MEMCPY, kirkwood_xor00_data.cap_mask);
422 dma_cap_set(DMA_XOR, kirkwood_xor00_data.cap_mask);
423 platform_device_register(&kirkwood_xor00_channel);
424
425 dma_cap_set(DMA_MEMCPY, kirkwood_xor01_data.cap_mask);
426 dma_cap_set(DMA_MEMSET, kirkwood_xor01_data.cap_mask);
427 dma_cap_set(DMA_XOR, kirkwood_xor01_data.cap_mask);
428 platform_device_register(&kirkwood_xor01_channel);
429}
430
431
432/*****************************************************************************
433 * XOR1
434 ****************************************************************************/
435static struct resource kirkwood_xor1_shared_resources[] = {
436 {
437 .name = "xor 1 low",
438 .start = XOR1_PHYS_BASE,
439 .end = XOR1_PHYS_BASE + 0xff,
440 .flags = IORESOURCE_MEM,
441 }, {
442 .name = "xor 1 high",
443 .start = XOR1_HIGH_PHYS_BASE,
444 .end = XOR1_HIGH_PHYS_BASE + 0xff,
445 .flags = IORESOURCE_MEM,
446 },
447};
448
449static struct platform_device kirkwood_xor1_shared = {
450 .name = MV_XOR_SHARED_NAME,
451 .id = 1,
452 .dev = {
453 .platform_data = &kirkwood_xor_shared_data,
454 },
455 .num_resources = ARRAY_SIZE(kirkwood_xor1_shared_resources),
456 .resource = kirkwood_xor1_shared_resources,
457};
458
459static struct resource kirkwood_xor10_resources[] = {
460 [0] = {
461 .start = IRQ_KIRKWOOD_XOR_10,
462 .end = IRQ_KIRKWOOD_XOR_10,
463 .flags = IORESOURCE_IRQ,
464 },
465};
466
467static struct mv_xor_platform_data kirkwood_xor10_data = {
468 .shared = &kirkwood_xor1_shared,
469 .hw_id = 0,
470 .pool_size = PAGE_SIZE,
471};
472
473static struct platform_device kirkwood_xor10_channel = {
474 .name = MV_XOR_NAME,
475 .id = 2,
476 .num_resources = ARRAY_SIZE(kirkwood_xor10_resources),
477 .resource = kirkwood_xor10_resources,
478 .dev = {
479 .dma_mask = &kirkwood_xor_dmamask,
480 .coherent_dma_mask = DMA_64BIT_MASK,
481 .platform_data = (void *)&kirkwood_xor10_data,
482 },
483};
484
485static struct resource kirkwood_xor11_resources[] = {
486 [0] = {
487 .start = IRQ_KIRKWOOD_XOR_11,
488 .end = IRQ_KIRKWOOD_XOR_11,
489 .flags = IORESOURCE_IRQ,
490 },
491};
492
493static struct mv_xor_platform_data kirkwood_xor11_data = {
494 .shared = &kirkwood_xor1_shared,
495 .hw_id = 1,
496 .pool_size = PAGE_SIZE,
497};
498
499static struct platform_device kirkwood_xor11_channel = {
500 .name = MV_XOR_NAME,
501 .id = 3,
502 .num_resources = ARRAY_SIZE(kirkwood_xor11_resources),
503 .resource = kirkwood_xor11_resources,
504 .dev = {
505 .dma_mask = &kirkwood_xor_dmamask,
506 .coherent_dma_mask = DMA_64BIT_MASK,
507 .platform_data = (void *)&kirkwood_xor11_data,
508 },
509};
510
511void __init kirkwood_xor1_init(void)
512{
513 platform_device_register(&kirkwood_xor1_shared);
514
515 /*
516 * two engines can't do memset simultaneously, this limitation
517 * satisfied by removing memset support from one of the engines.
518 */
519 dma_cap_set(DMA_MEMCPY, kirkwood_xor10_data.cap_mask);
520 dma_cap_set(DMA_XOR, kirkwood_xor10_data.cap_mask);
521 platform_device_register(&kirkwood_xor10_channel);
522
523 dma_cap_set(DMA_MEMCPY, kirkwood_xor11_data.cap_mask);
524 dma_cap_set(DMA_MEMSET, kirkwood_xor11_data.cap_mask);
525 dma_cap_set(DMA_XOR, kirkwood_xor11_data.cap_mask);
526 platform_device_register(&kirkwood_xor11_channel);
527}
528
529
530/*****************************************************************************
Saeed Bishara651c74c2008-06-22 22:45:06 +0200531 * Time handling
532 ****************************************************************************/
533static void kirkwood_timer_init(void)
534{
535 orion_time_init(IRQ_KIRKWOOD_BRIDGE, KIRKWOOD_TCLK);
536}
537
538struct sys_timer kirkwood_timer = {
539 .init = kirkwood_timer_init,
540};
541
542
543/*****************************************************************************
544 * General
545 ****************************************************************************/
546static char * __init kirkwood_id(void)
547{
548 switch (readl(DEVICE_ID) & 0x3) {
549 case 0:
550 return "88F6180";
551 case 1:
552 return "88F6192";
553 case 2:
554 return "88F6281";
555 }
556
557 return "unknown 88F6000 variant";
558}
559
Saeed Bishara13387602008-06-23 01:05:08 -1100560static int __init is_l2_writethrough(void)
561{
562 return !!(readl(L2_CONFIG_REG) & L2_WRITETHROUGH);
563}
564
Saeed Bishara651c74c2008-06-22 22:45:06 +0200565void __init kirkwood_init(void)
566{
567 printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
568 kirkwood_id(), KIRKWOOD_TCLK);
569
570 kirkwood_setup_cpu_mbus();
571
572#ifdef CONFIG_CACHE_FEROCEON_L2
Saeed Bishara13387602008-06-23 01:05:08 -1100573 feroceon_l2_init(is_l2_writethrough());
Saeed Bishara651c74c2008-06-22 22:45:06 +0200574#endif
575}