blob: d127731f47dc68aafc77edf64c763abebcb09e5f [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>
Martin Michlmayr6574e002009-03-23 19:13:21 +010017#include <linux/mv643xx_i2c.h>
Saeed Bishara651c74c2008-06-22 22:45:06 +020018#include <linux/ata_platform.h>
Nicolas Pitrefb7b2d32009-06-01 15:36:36 -040019#include <linux/mtd/nand.h>
Lennert Buytenhek18365d12008-08-09 15:38:18 +020020#include <linux/spi/orion_spi.h>
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +020021#include <net/dsa.h>
Saeed Bishara651c74c2008-06-22 22:45:06 +020022#include <asm/page.h>
23#include <asm/timex.h>
24#include <asm/mach/map.h>
25#include <asm/mach/time.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010026#include <mach/kirkwood.h>
Nicolas Pitrefdd8b072009-04-22 20:08:17 +010027#include <mach/bridge-regs.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020028#include <plat/cache-feroceon-l2.h>
29#include <plat/ehci-orion.h>
Nicolas Pitre8235ee02009-02-14 03:15:55 -050030#include <plat/mvsdio.h>
Saeed Bishara09c0ed22008-06-23 04:26:07 -110031#include <plat/mv_xor.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020032#include <plat/orion_nand.h>
33#include <plat/time.h>
Saeed Bishara651c74c2008-06-22 22:45:06 +020034#include "common.h"
35
36/*****************************************************************************
37 * I/O Address Mapping
38 ****************************************************************************/
39static struct map_desc kirkwood_io_desc[] __initdata = {
40 {
41 .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
42 .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
43 .length = KIRKWOOD_PCIE_IO_SIZE,
44 .type = MT_DEVICE,
45 }, {
46 .virtual = KIRKWOOD_REGS_VIRT_BASE,
47 .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
48 .length = KIRKWOOD_REGS_SIZE,
49 .type = MT_DEVICE,
50 },
51};
52
53void __init kirkwood_map_io(void)
54{
55 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
56}
57
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +020058/*
59 * Default clock control bits. Any bit _not_ set in this variable
60 * will be cleared from the hardware after platform devices have been
61 * registered. Some reserved bits must be set to 1.
62 */
63unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
64
Saeed Bishara651c74c2008-06-22 22:45:06 +020065
66/*****************************************************************************
67 * EHCI
68 ****************************************************************************/
69static struct orion_ehci_data kirkwood_ehci_data = {
70 .dram = &kirkwood_mbus_dram_info,
Ronen Shitritfb6f5522008-09-17 10:08:05 +030071 .phy_version = EHCI_PHY_NA,
Saeed Bishara651c74c2008-06-22 22:45:06 +020072};
73
74static u64 ehci_dmamask = 0xffffffffUL;
75
76
77/*****************************************************************************
78 * EHCI0
79 ****************************************************************************/
80static struct resource kirkwood_ehci_resources[] = {
81 {
82 .start = USB_PHYS_BASE,
83 .end = USB_PHYS_BASE + 0x0fff,
84 .flags = IORESOURCE_MEM,
85 }, {
86 .start = IRQ_KIRKWOOD_USB,
87 .end = IRQ_KIRKWOOD_USB,
88 .flags = IORESOURCE_IRQ,
89 },
90};
91
92static struct platform_device kirkwood_ehci = {
93 .name = "orion-ehci",
94 .id = 0,
95 .dev = {
96 .dma_mask = &ehci_dmamask,
97 .coherent_dma_mask = 0xffffffff,
98 .platform_data = &kirkwood_ehci_data,
99 },
100 .resource = kirkwood_ehci_resources,
101 .num_resources = ARRAY_SIZE(kirkwood_ehci_resources),
102};
103
104void __init kirkwood_ehci_init(void)
105{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200106 kirkwood_clk_ctrl |= CGC_USB0;
Saeed Bishara651c74c2008-06-22 22:45:06 +0200107 platform_device_register(&kirkwood_ehci);
108}
109
110
111/*****************************************************************************
112 * GE00
113 ****************************************************************************/
114struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
Saeed Bishara651c74c2008-06-22 22:45:06 +0200115 .dram = &kirkwood_mbus_dram_info,
116};
117
118static struct resource kirkwood_ge00_shared_resources[] = {
119 {
120 .name = "ge00 base",
121 .start = GE00_PHYS_BASE + 0x2000,
122 .end = GE00_PHYS_BASE + 0x3fff,
123 .flags = IORESOURCE_MEM,
Lennert Buytenhek144f8142008-08-26 16:04:05 +0200124 }, {
125 .name = "ge00 err irq",
126 .start = IRQ_KIRKWOOD_GE00_ERR,
127 .end = IRQ_KIRKWOOD_GE00_ERR,
128 .flags = IORESOURCE_IRQ,
Saeed Bishara651c74c2008-06-22 22:45:06 +0200129 },
130};
131
132static struct platform_device kirkwood_ge00_shared = {
133 .name = MV643XX_ETH_SHARED_NAME,
134 .id = 0,
135 .dev = {
136 .platform_data = &kirkwood_ge00_shared_data,
137 },
Lennert Buytenhek144f8142008-08-26 16:04:05 +0200138 .num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources),
Saeed Bishara651c74c2008-06-22 22:45:06 +0200139 .resource = kirkwood_ge00_shared_resources,
140};
141
142static struct resource kirkwood_ge00_resources[] = {
143 {
144 .name = "ge00 irq",
145 .start = IRQ_KIRKWOOD_GE00_SUM,
146 .end = IRQ_KIRKWOOD_GE00_SUM,
147 .flags = IORESOURCE_IRQ,
148 },
149};
150
151static struct platform_device kirkwood_ge00 = {
152 .name = MV643XX_ETH_NAME,
153 .id = 0,
154 .num_resources = 1,
155 .resource = kirkwood_ge00_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400156 .dev = {
157 .coherent_dma_mask = 0xffffffff,
158 },
Saeed Bishara651c74c2008-06-22 22:45:06 +0200159};
160
161void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
162{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200163 kirkwood_clk_ctrl |= CGC_GE0;
Saeed Bishara651c74c2008-06-22 22:45:06 +0200164 eth_data->shared = &kirkwood_ge00_shared;
165 kirkwood_ge00.dev.platform_data = eth_data;
166
167 platform_device_register(&kirkwood_ge00_shared);
168 platform_device_register(&kirkwood_ge00);
169}
170
171
172/*****************************************************************************
Ronen Shitritd15fb9e2008-10-19 23:10:14 +0200173 * GE01
174 ****************************************************************************/
175struct mv643xx_eth_shared_platform_data kirkwood_ge01_shared_data = {
176 .dram = &kirkwood_mbus_dram_info,
177 .shared_smi = &kirkwood_ge00_shared,
178};
179
180static struct resource kirkwood_ge01_shared_resources[] = {
181 {
182 .name = "ge01 base",
183 .start = GE01_PHYS_BASE + 0x2000,
184 .end = GE01_PHYS_BASE + 0x3fff,
185 .flags = IORESOURCE_MEM,
186 }, {
187 .name = "ge01 err irq",
188 .start = IRQ_KIRKWOOD_GE01_ERR,
189 .end = IRQ_KIRKWOOD_GE01_ERR,
190 .flags = IORESOURCE_IRQ,
191 },
192};
193
194static struct platform_device kirkwood_ge01_shared = {
195 .name = MV643XX_ETH_SHARED_NAME,
196 .id = 1,
197 .dev = {
198 .platform_data = &kirkwood_ge01_shared_data,
199 },
200 .num_resources = ARRAY_SIZE(kirkwood_ge01_shared_resources),
201 .resource = kirkwood_ge01_shared_resources,
202};
203
204static struct resource kirkwood_ge01_resources[] = {
205 {
206 .name = "ge01 irq",
207 .start = IRQ_KIRKWOOD_GE01_SUM,
208 .end = IRQ_KIRKWOOD_GE01_SUM,
209 .flags = IORESOURCE_IRQ,
210 },
211};
212
213static struct platform_device kirkwood_ge01 = {
214 .name = MV643XX_ETH_NAME,
215 .id = 1,
216 .num_resources = 1,
217 .resource = kirkwood_ge01_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400218 .dev = {
219 .coherent_dma_mask = 0xffffffff,
220 },
Ronen Shitritd15fb9e2008-10-19 23:10:14 +0200221};
222
223void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
224{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200225 kirkwood_clk_ctrl |= CGC_GE1;
Ronen Shitritd15fb9e2008-10-19 23:10:14 +0200226 eth_data->shared = &kirkwood_ge01_shared;
227 kirkwood_ge01.dev.platform_data = eth_data;
228
229 platform_device_register(&kirkwood_ge01_shared);
230 platform_device_register(&kirkwood_ge01);
231}
232
233
234/*****************************************************************************
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200235 * Ethernet switch
236 ****************************************************************************/
237static struct resource kirkwood_switch_resources[] = {
238 {
239 .start = 0,
240 .end = 0,
241 .flags = IORESOURCE_IRQ,
242 },
243};
244
245static struct platform_device kirkwood_switch_device = {
246 .name = "dsa",
247 .id = 0,
248 .num_resources = 0,
249 .resource = kirkwood_switch_resources,
250};
251
252void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
253{
Lennert Buytenheke84665c2009-03-20 09:52:09 +0000254 int i;
255
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200256 if (irq != NO_IRQ) {
257 kirkwood_switch_resources[0].start = irq;
258 kirkwood_switch_resources[0].end = irq;
259 kirkwood_switch_device.num_resources = 1;
260 }
261
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200262 d->netdev = &kirkwood_ge00.dev;
Lennert Buytenheke84665c2009-03-20 09:52:09 +0000263 for (i = 0; i < d->nr_chips; i++)
264 d->chip[i].mii_bus = &kirkwood_ge00_shared.dev;
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200265 kirkwood_switch_device.dev.platform_data = d;
266
267 platform_device_register(&kirkwood_switch_device);
268}
269
270
271/*****************************************************************************
Nicolas Pitrefb7b2d32009-06-01 15:36:36 -0400272 * NAND flash
273 ****************************************************************************/
274static struct resource kirkwood_nand_resource = {
275 .flags = IORESOURCE_MEM,
276 .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
277 .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
278 KIRKWOOD_NAND_MEM_SIZE - 1,
279};
280
281static struct orion_nand_data kirkwood_nand_data = {
282 .cle = 0,
283 .ale = 1,
284 .width = 8,
285};
286
287static struct platform_device kirkwood_nand_flash = {
288 .name = "orion_nand",
289 .id = -1,
290 .dev = {
291 .platform_data = &kirkwood_nand_data,
292 },
293 .resource = &kirkwood_nand_resource,
294 .num_resources = 1,
295};
296
297void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
298 int chip_delay)
299{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200300 kirkwood_clk_ctrl |= CGC_RUNIT;
Nicolas Pitrefb7b2d32009-06-01 15:36:36 -0400301 kirkwood_nand_data.parts = parts;
302 kirkwood_nand_data.nr_parts = nr_parts;
303 kirkwood_nand_data.chip_delay = chip_delay;
304 platform_device_register(&kirkwood_nand_flash);
305}
306
307
308/*****************************************************************************
Saeed Bishara651c74c2008-06-22 22:45:06 +0200309 * SoC RTC
310 ****************************************************************************/
311static struct resource kirkwood_rtc_resource = {
312 .start = RTC_PHYS_BASE,
313 .end = RTC_PHYS_BASE + SZ_16 - 1,
314 .flags = IORESOURCE_MEM,
315};
316
Nicolas Pitre5b99d532009-02-26 22:55:59 -0500317static void __init kirkwood_rtc_init(void)
Saeed Bishara651c74c2008-06-22 22:45:06 +0200318{
319 platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
320}
321
322
323/*****************************************************************************
324 * SATA
325 ****************************************************************************/
326static struct resource kirkwood_sata_resources[] = {
327 {
328 .name = "sata base",
329 .start = SATA_PHYS_BASE,
330 .end = SATA_PHYS_BASE + 0x5000 - 1,
331 .flags = IORESOURCE_MEM,
332 }, {
333 .name = "sata irq",
334 .start = IRQ_KIRKWOOD_SATA,
335 .end = IRQ_KIRKWOOD_SATA,
336 .flags = IORESOURCE_IRQ,
337 },
338};
339
340static struct platform_device kirkwood_sata = {
341 .name = "sata_mv",
342 .id = 0,
343 .dev = {
344 .coherent_dma_mask = 0xffffffff,
345 },
346 .num_resources = ARRAY_SIZE(kirkwood_sata_resources),
347 .resource = kirkwood_sata_resources,
348};
349
350void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
351{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200352 kirkwood_clk_ctrl |= CGC_SATA0;
353 if (sata_data->n_ports > 1)
354 kirkwood_clk_ctrl |= CGC_SATA1;
Saeed Bishara651c74c2008-06-22 22:45:06 +0200355 sata_data->dram = &kirkwood_mbus_dram_info;
356 kirkwood_sata.dev.platform_data = sata_data;
357 platform_device_register(&kirkwood_sata);
358}
359
360
361/*****************************************************************************
Nicolas Pitre8235ee02009-02-14 03:15:55 -0500362 * SD/SDIO/MMC
363 ****************************************************************************/
364static struct resource mvsdio_resources[] = {
365 [0] = {
366 .start = SDIO_PHYS_BASE,
367 .end = SDIO_PHYS_BASE + SZ_1K - 1,
368 .flags = IORESOURCE_MEM,
369 },
370 [1] = {
371 .start = IRQ_KIRKWOOD_SDIO,
372 .end = IRQ_KIRKWOOD_SDIO,
373 .flags = IORESOURCE_IRQ,
374 },
375};
376
377static u64 mvsdio_dmamask = 0xffffffffUL;
378
379static struct platform_device kirkwood_sdio = {
380 .name = "mvsdio",
381 .id = -1,
382 .dev = {
383 .dma_mask = &mvsdio_dmamask,
384 .coherent_dma_mask = 0xffffffff,
385 },
386 .num_resources = ARRAY_SIZE(mvsdio_resources),
387 .resource = mvsdio_resources,
388};
389
390void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
391{
392 u32 dev, rev;
393
394 kirkwood_pcie_id(&dev, &rev);
395 if (rev == 0) /* catch all Kirkwood Z0's */
396 mvsdio_data->clock = 100000000;
397 else
398 mvsdio_data->clock = 200000000;
399 mvsdio_data->dram = &kirkwood_mbus_dram_info;
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200400 kirkwood_clk_ctrl |= CGC_SDIO;
Nicolas Pitre8235ee02009-02-14 03:15:55 -0500401 kirkwood_sdio.dev.platform_data = mvsdio_data;
402 platform_device_register(&kirkwood_sdio);
403}
404
405
406/*****************************************************************************
Lennert Buytenhek18365d12008-08-09 15:38:18 +0200407 * SPI
408 ****************************************************************************/
409static struct orion_spi_info kirkwood_spi_plat_data = {
Lennert Buytenhek18365d12008-08-09 15:38:18 +0200410};
411
412static struct resource kirkwood_spi_resources[] = {
413 {
414 .start = SPI_PHYS_BASE,
415 .end = SPI_PHYS_BASE + SZ_512 - 1,
416 .flags = IORESOURCE_MEM,
417 },
418};
419
420static struct platform_device kirkwood_spi = {
421 .name = "orion_spi",
422 .id = 0,
423 .resource = kirkwood_spi_resources,
424 .dev = {
425 .platform_data = &kirkwood_spi_plat_data,
426 },
427 .num_resources = ARRAY_SIZE(kirkwood_spi_resources),
428};
429
430void __init kirkwood_spi_init()
431{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200432 kirkwood_clk_ctrl |= CGC_RUNIT;
Lennert Buytenhek18365d12008-08-09 15:38:18 +0200433 platform_device_register(&kirkwood_spi);
434}
435
436
437/*****************************************************************************
Martin Michlmayr6574e002009-03-23 19:13:21 +0100438 * I2C
439 ****************************************************************************/
440static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = {
441 .freq_m = 8, /* assumes 166 MHz TCLK */
442 .freq_n = 3,
443 .timeout = 1000, /* Default timeout of 1 second */
444};
445
446static struct resource kirkwood_i2c_resources[] = {
447 {
Martin Michlmayr6574e002009-03-23 19:13:21 +0100448 .start = I2C_PHYS_BASE,
449 .end = I2C_PHYS_BASE + 0x1f,
450 .flags = IORESOURCE_MEM,
451 }, {
Martin Michlmayr6574e002009-03-23 19:13:21 +0100452 .start = IRQ_KIRKWOOD_TWSI,
453 .end = IRQ_KIRKWOOD_TWSI,
454 .flags = IORESOURCE_IRQ,
455 },
456};
457
458static struct platform_device kirkwood_i2c = {
459 .name = MV64XXX_I2C_CTLR_NAME,
460 .id = 0,
461 .num_resources = ARRAY_SIZE(kirkwood_i2c_resources),
462 .resource = kirkwood_i2c_resources,
463 .dev = {
464 .platform_data = &kirkwood_i2c_pdata,
465 },
466};
467
468void __init kirkwood_i2c_init(void)
469{
470 platform_device_register(&kirkwood_i2c);
471}
472
473
474/*****************************************************************************
Saeed Bishara651c74c2008-06-22 22:45:06 +0200475 * UART0
476 ****************************************************************************/
477static struct plat_serial8250_port kirkwood_uart0_data[] = {
478 {
479 .mapbase = UART0_PHYS_BASE,
480 .membase = (char *)UART0_VIRT_BASE,
481 .irq = IRQ_KIRKWOOD_UART_0,
482 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
483 .iotype = UPIO_MEM,
484 .regshift = 2,
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200485 .uartclk = 0,
Saeed Bishara651c74c2008-06-22 22:45:06 +0200486 }, {
487 },
488};
489
490static struct resource kirkwood_uart0_resources[] = {
491 {
492 .start = UART0_PHYS_BASE,
493 .end = UART0_PHYS_BASE + 0xff,
494 .flags = IORESOURCE_MEM,
495 }, {
496 .start = IRQ_KIRKWOOD_UART_0,
497 .end = IRQ_KIRKWOOD_UART_0,
498 .flags = IORESOURCE_IRQ,
499 },
500};
501
502static struct platform_device kirkwood_uart0 = {
503 .name = "serial8250",
504 .id = 0,
505 .dev = {
506 .platform_data = kirkwood_uart0_data,
507 },
508 .resource = kirkwood_uart0_resources,
509 .num_resources = ARRAY_SIZE(kirkwood_uart0_resources),
510};
511
512void __init kirkwood_uart0_init(void)
513{
514 platform_device_register(&kirkwood_uart0);
515}
516
517
518/*****************************************************************************
519 * UART1
520 ****************************************************************************/
521static struct plat_serial8250_port kirkwood_uart1_data[] = {
522 {
523 .mapbase = UART1_PHYS_BASE,
524 .membase = (char *)UART1_VIRT_BASE,
525 .irq = IRQ_KIRKWOOD_UART_1,
526 .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
527 .iotype = UPIO_MEM,
528 .regshift = 2,
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200529 .uartclk = 0,
Saeed Bishara651c74c2008-06-22 22:45:06 +0200530 }, {
531 },
532};
533
534static struct resource kirkwood_uart1_resources[] = {
535 {
536 .start = UART1_PHYS_BASE,
537 .end = UART1_PHYS_BASE + 0xff,
538 .flags = IORESOURCE_MEM,
539 }, {
540 .start = IRQ_KIRKWOOD_UART_1,
541 .end = IRQ_KIRKWOOD_UART_1,
542 .flags = IORESOURCE_IRQ,
543 },
544};
545
546static struct platform_device kirkwood_uart1 = {
547 .name = "serial8250",
548 .id = 1,
549 .dev = {
550 .platform_data = kirkwood_uart1_data,
551 },
552 .resource = kirkwood_uart1_resources,
553 .num_resources = ARRAY_SIZE(kirkwood_uart1_resources),
554};
555
556void __init kirkwood_uart1_init(void)
557{
558 platform_device_register(&kirkwood_uart1);
559}
560
561
562/*****************************************************************************
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100563 * XOR
564 ****************************************************************************/
565static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = {
566 .dram = &kirkwood_mbus_dram_info,
567};
568
Yang Hongyang284901a2009-04-06 19:01:15 -0700569static u64 kirkwood_xor_dmamask = DMA_BIT_MASK(32);
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100570
571
572/*****************************************************************************
573 * XOR0
574 ****************************************************************************/
575static struct resource kirkwood_xor0_shared_resources[] = {
576 {
577 .name = "xor 0 low",
578 .start = XOR0_PHYS_BASE,
579 .end = XOR0_PHYS_BASE + 0xff,
580 .flags = IORESOURCE_MEM,
581 }, {
582 .name = "xor 0 high",
583 .start = XOR0_HIGH_PHYS_BASE,
584 .end = XOR0_HIGH_PHYS_BASE + 0xff,
585 .flags = IORESOURCE_MEM,
586 },
587};
588
589static struct platform_device kirkwood_xor0_shared = {
590 .name = MV_XOR_SHARED_NAME,
591 .id = 0,
592 .dev = {
593 .platform_data = &kirkwood_xor_shared_data,
594 },
595 .num_resources = ARRAY_SIZE(kirkwood_xor0_shared_resources),
596 .resource = kirkwood_xor0_shared_resources,
597};
598
599static struct resource kirkwood_xor00_resources[] = {
600 [0] = {
601 .start = IRQ_KIRKWOOD_XOR_00,
602 .end = IRQ_KIRKWOOD_XOR_00,
603 .flags = IORESOURCE_IRQ,
604 },
605};
606
607static struct mv_xor_platform_data kirkwood_xor00_data = {
608 .shared = &kirkwood_xor0_shared,
609 .hw_id = 0,
610 .pool_size = PAGE_SIZE,
611};
612
613static struct platform_device kirkwood_xor00_channel = {
614 .name = MV_XOR_NAME,
615 .id = 0,
616 .num_resources = ARRAY_SIZE(kirkwood_xor00_resources),
617 .resource = kirkwood_xor00_resources,
618 .dev = {
619 .dma_mask = &kirkwood_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700620 .coherent_dma_mask = DMA_BIT_MASK(64),
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100621 .platform_data = (void *)&kirkwood_xor00_data,
622 },
623};
624
625static struct resource kirkwood_xor01_resources[] = {
626 [0] = {
627 .start = IRQ_KIRKWOOD_XOR_01,
628 .end = IRQ_KIRKWOOD_XOR_01,
629 .flags = IORESOURCE_IRQ,
630 },
631};
632
633static struct mv_xor_platform_data kirkwood_xor01_data = {
634 .shared = &kirkwood_xor0_shared,
635 .hw_id = 1,
636 .pool_size = PAGE_SIZE,
637};
638
639static struct platform_device kirkwood_xor01_channel = {
640 .name = MV_XOR_NAME,
641 .id = 1,
642 .num_resources = ARRAY_SIZE(kirkwood_xor01_resources),
643 .resource = kirkwood_xor01_resources,
644 .dev = {
645 .dma_mask = &kirkwood_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700646 .coherent_dma_mask = DMA_BIT_MASK(64),
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100647 .platform_data = (void *)&kirkwood_xor01_data,
648 },
649};
650
Nicolas Pitre5b99d532009-02-26 22:55:59 -0500651static void __init kirkwood_xor0_init(void)
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100652{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200653 kirkwood_clk_ctrl |= CGC_XOR0;
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100654 platform_device_register(&kirkwood_xor0_shared);
655
656 /*
657 * two engines can't do memset simultaneously, this limitation
658 * satisfied by removing memset support from one of the engines.
659 */
660 dma_cap_set(DMA_MEMCPY, kirkwood_xor00_data.cap_mask);
661 dma_cap_set(DMA_XOR, kirkwood_xor00_data.cap_mask);
662 platform_device_register(&kirkwood_xor00_channel);
663
664 dma_cap_set(DMA_MEMCPY, kirkwood_xor01_data.cap_mask);
665 dma_cap_set(DMA_MEMSET, kirkwood_xor01_data.cap_mask);
666 dma_cap_set(DMA_XOR, kirkwood_xor01_data.cap_mask);
667 platform_device_register(&kirkwood_xor01_channel);
668}
669
670
671/*****************************************************************************
672 * XOR1
673 ****************************************************************************/
674static struct resource kirkwood_xor1_shared_resources[] = {
675 {
676 .name = "xor 1 low",
677 .start = XOR1_PHYS_BASE,
678 .end = XOR1_PHYS_BASE + 0xff,
679 .flags = IORESOURCE_MEM,
680 }, {
681 .name = "xor 1 high",
682 .start = XOR1_HIGH_PHYS_BASE,
683 .end = XOR1_HIGH_PHYS_BASE + 0xff,
684 .flags = IORESOURCE_MEM,
685 },
686};
687
688static struct platform_device kirkwood_xor1_shared = {
689 .name = MV_XOR_SHARED_NAME,
690 .id = 1,
691 .dev = {
692 .platform_data = &kirkwood_xor_shared_data,
693 },
694 .num_resources = ARRAY_SIZE(kirkwood_xor1_shared_resources),
695 .resource = kirkwood_xor1_shared_resources,
696};
697
698static struct resource kirkwood_xor10_resources[] = {
699 [0] = {
700 .start = IRQ_KIRKWOOD_XOR_10,
701 .end = IRQ_KIRKWOOD_XOR_10,
702 .flags = IORESOURCE_IRQ,
703 },
704};
705
706static struct mv_xor_platform_data kirkwood_xor10_data = {
707 .shared = &kirkwood_xor1_shared,
708 .hw_id = 0,
709 .pool_size = PAGE_SIZE,
710};
711
712static struct platform_device kirkwood_xor10_channel = {
713 .name = MV_XOR_NAME,
714 .id = 2,
715 .num_resources = ARRAY_SIZE(kirkwood_xor10_resources),
716 .resource = kirkwood_xor10_resources,
717 .dev = {
718 .dma_mask = &kirkwood_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700719 .coherent_dma_mask = DMA_BIT_MASK(64),
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100720 .platform_data = (void *)&kirkwood_xor10_data,
721 },
722};
723
724static struct resource kirkwood_xor11_resources[] = {
725 [0] = {
726 .start = IRQ_KIRKWOOD_XOR_11,
727 .end = IRQ_KIRKWOOD_XOR_11,
728 .flags = IORESOURCE_IRQ,
729 },
730};
731
732static struct mv_xor_platform_data kirkwood_xor11_data = {
733 .shared = &kirkwood_xor1_shared,
734 .hw_id = 1,
735 .pool_size = PAGE_SIZE,
736};
737
738static struct platform_device kirkwood_xor11_channel = {
739 .name = MV_XOR_NAME,
740 .id = 3,
741 .num_resources = ARRAY_SIZE(kirkwood_xor11_resources),
742 .resource = kirkwood_xor11_resources,
743 .dev = {
744 .dma_mask = &kirkwood_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700745 .coherent_dma_mask = DMA_BIT_MASK(64),
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100746 .platform_data = (void *)&kirkwood_xor11_data,
747 },
748};
749
Nicolas Pitre5b99d532009-02-26 22:55:59 -0500750static void __init kirkwood_xor1_init(void)
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100751{
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200752 kirkwood_clk_ctrl |= CGC_XOR1;
Saeed Bishara09c0ed22008-06-23 04:26:07 -1100753 platform_device_register(&kirkwood_xor1_shared);
754
755 /*
756 * two engines can't do memset simultaneously, this limitation
757 * satisfied by removing memset support from one of the engines.
758 */
759 dma_cap_set(DMA_MEMCPY, kirkwood_xor10_data.cap_mask);
760 dma_cap_set(DMA_XOR, kirkwood_xor10_data.cap_mask);
761 platform_device_register(&kirkwood_xor10_channel);
762
763 dma_cap_set(DMA_MEMCPY, kirkwood_xor11_data.cap_mask);
764 dma_cap_set(DMA_MEMSET, kirkwood_xor11_data.cap_mask);
765 dma_cap_set(DMA_XOR, kirkwood_xor11_data.cap_mask);
766 platform_device_register(&kirkwood_xor11_channel);
767}
768
769
770/*****************************************************************************
Saeed Bishara651c74c2008-06-22 22:45:06 +0200771 * Time handling
772 ****************************************************************************/
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200773int kirkwood_tclk;
774
775int __init kirkwood_find_tclk(void)
776{
Ronen Shitritb2b3dc22008-09-15 10:40:35 +0300777 u32 dev, rev;
778
779 kirkwood_pcie_id(&dev, &rev);
780 if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0)
781 return 200000000;
782
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200783 return 166666667;
784}
785
Saeed Bishara651c74c2008-06-22 22:45:06 +0200786static void kirkwood_timer_init(void)
787{
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200788 kirkwood_tclk = kirkwood_find_tclk();
789 orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
Saeed Bishara651c74c2008-06-22 22:45:06 +0200790}
791
792struct sys_timer kirkwood_timer = {
793 .init = kirkwood_timer_init,
794};
795
796
797/*****************************************************************************
798 * General
799 ****************************************************************************/
Ronen Shitritb2b3dc22008-09-15 10:40:35 +0300800/*
801 * Identify device ID and revision.
802 */
Saeed Bishara651c74c2008-06-22 22:45:06 +0200803static char * __init kirkwood_id(void)
804{
Ronen Shitritb2b3dc22008-09-15 10:40:35 +0300805 u32 dev, rev;
Saeed Bishara651c74c2008-06-22 22:45:06 +0200806
Ronen Shitritb2b3dc22008-09-15 10:40:35 +0300807 kirkwood_pcie_id(&dev, &rev);
808
809 if (dev == MV88F6281_DEV_ID) {
810 if (rev == MV88F6281_REV_Z0)
811 return "MV88F6281-Z0";
812 else if (rev == MV88F6281_REV_A0)
813 return "MV88F6281-A0";
814 else
815 return "MV88F6281-Rev-Unsupported";
816 } else if (dev == MV88F6192_DEV_ID) {
817 if (rev == MV88F6192_REV_Z0)
818 return "MV88F6192-Z0";
819 else if (rev == MV88F6192_REV_A0)
820 return "MV88F6192-A0";
821 else
822 return "MV88F6192-Rev-Unsupported";
823 } else if (dev == MV88F6180_DEV_ID) {
824 if (rev == MV88F6180_REV_A0)
825 return "MV88F6180-Rev-A0";
826 else
827 return "MV88F6180-Rev-Unsupported";
828 } else {
829 return "Device-Unknown";
830 }
Saeed Bishara651c74c2008-06-22 22:45:06 +0200831}
832
Ronen Shitrit4360bb42008-09-23 15:28:10 +0300833static void __init kirkwood_l2_init(void)
Saeed Bishara13387602008-06-23 01:05:08 -1100834{
Ronen Shitrit4360bb42008-09-23 15:28:10 +0300835#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
836 writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
837 feroceon_l2_init(1);
838#else
839 writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
840 feroceon_l2_init(0);
841#endif
Saeed Bishara13387602008-06-23 01:05:08 -1100842}
843
Saeed Bishara651c74c2008-06-22 22:45:06 +0200844void __init kirkwood_init(void)
845{
846 printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200847 kirkwood_id(), kirkwood_tclk);
848 kirkwood_ge00_shared_data.t_clk = kirkwood_tclk;
Nicolas Pitre13731d12009-01-06 23:02:08 +0100849 kirkwood_ge01_shared_data.t_clk = kirkwood_tclk;
Ronen Shitrit79d4dd72008-09-15 00:56:38 +0200850 kirkwood_spi_plat_data.tclk = kirkwood_tclk;
851 kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
852 kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
Saeed Bishara651c74c2008-06-22 22:45:06 +0200853
854 kirkwood_setup_cpu_mbus();
855
856#ifdef CONFIG_CACHE_FEROCEON_L2
Ronen Shitrit4360bb42008-09-23 15:28:10 +0300857 kirkwood_l2_init();
Saeed Bishara651c74c2008-06-22 22:45:06 +0200858#endif
Nicolas Pitre5b99d532009-02-26 22:55:59 -0500859
860 /* internal devices that every board has */
861 kirkwood_rtc_init();
862 kirkwood_xor0_init();
863 kirkwood_xor1_init();
Saeed Bishara651c74c2008-06-22 22:45:06 +0200864}
Rabeeh Khourye8b2b7b2009-03-22 17:30:32 +0200865
866static int __init kirkwood_clock_gate(void)
867{
868 unsigned int curr = readl(CLOCK_GATING_CTRL);
869
870 printk(KERN_DEBUG "Gating clock of unused units\n");
871 printk(KERN_DEBUG "before: 0x%08x\n", curr);
872
873 /* Make sure those units are accessible */
874 writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0, CLOCK_GATING_CTRL);
875
876 /* For SATA: first shutdown the phy */
877 if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
878 /* Disable PLL and IVREF */
879 writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
880 /* Disable PHY */
881 writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
882 }
883 if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
884 /* Disable PLL and IVREF */
885 writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
886 /* Disable PHY */
887 writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
888 }
889
890 /* For PCIe: first shutdown the phy */
891 if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
892 writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
893 while (1)
894 if (readl(PCIE_STATUS) & 0x1)
895 break;
896 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
897 }
898
899 /* Now gate clock the required units */
900 writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
901 printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
902
903 return 0;
904}
905late_initcall(kirkwood_clock_gate);