blob: 310de50e1bb97feccd04b2f3d42b302339b66bd9 [file] [log] [blame]
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -04001/*
2 * arch/arm/mach-orion5x/common.c
3 *
4 * Core functions for Marvell Orion 5x SoCs
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/serial_8250.h>
17#include <linux/mbus.h>
18#include <linux/mv643xx_eth.h>
19#include <linux/mv643xx_i2c.h>
20#include <linux/ata_platform.h>
Lennert Buytenhekd323ade2008-08-29 06:55:06 +020021#include <linux/spi/orion_spi.h>
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +020022#include <net/dsa.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040023#include <asm/page.h>
24#include <asm/setup.h>
25#include <asm/timex.h>
26#include <asm/mach/arch.h>
27#include <asm/mach/map.h>
28#include <asm/mach/time.h>
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +020029#include <mach/bridge-regs.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010030#include <mach/hardware.h>
31#include <mach/orion5x.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020032#include <plat/ehci-orion.h>
Saeed Bishara1d5a1a62008-06-16 23:25:12 -110033#include <plat/mv_xor.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020034#include <plat/orion_nand.h>
Nicolas Pitre3b937a7db2009-06-01 13:56:02 -040035#include <plat/orion_wdt.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020036#include <plat/time.h>
Andrew Lunn28a2b452011-05-15 13:32:41 +020037#include <plat/common.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040038#include "common.h"
39
40/*****************************************************************************
41 * I/O Address Mapping
42 ****************************************************************************/
43static struct map_desc orion5x_io_desc[] __initdata = {
44 {
45 .virtual = ORION5X_REGS_VIRT_BASE,
46 .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
47 .length = ORION5X_REGS_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020048 .type = MT_DEVICE,
49 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040050 .virtual = ORION5X_PCIE_IO_VIRT_BASE,
51 .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
52 .length = ORION5X_PCIE_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020053 .type = MT_DEVICE,
54 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040055 .virtual = ORION5X_PCI_IO_VIRT_BASE,
56 .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
57 .length = ORION5X_PCI_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020058 .type = MT_DEVICE,
59 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040060 .virtual = ORION5X_PCIE_WA_VIRT_BASE,
61 .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
62 .length = ORION5X_PCIE_WA_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020063 .type = MT_DEVICE,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040064 },
65};
66
67void __init orion5x_map_io(void)
68{
69 iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
70}
71
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020072
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040073/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020074 * EHCI
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040075 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020076static struct orion_ehci_data orion5x_ehci_data = {
77 .dram = &orion5x_mbus_dram_info,
Ronen Shitritfb6f5522008-09-17 10:08:05 +030078 .phy_version = EHCI_PHY_ORION,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040079};
80
Andrew Lunn5c602552011-05-15 13:32:40 +020081static u64 ehci_dmamask = DMA_BIT_MASK(32);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040082
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040083
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020084/*****************************************************************************
85 * EHCI0
86 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040087static struct resource orion5x_ehci0_resources[] = {
88 {
89 .start = ORION5X_USB0_PHYS_BASE,
Lennert Buytenhek994cab82008-04-25 16:30:21 -040090 .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040091 .flags = IORESOURCE_MEM,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020092 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040093 .start = IRQ_ORION5X_USB0_CTRL,
94 .end = IRQ_ORION5X_USB0_CTRL,
95 .flags = IORESOURCE_IRQ,
96 },
97};
98
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040099static struct platform_device orion5x_ehci0 = {
100 .name = "orion-ehci",
101 .id = 0,
102 .dev = {
103 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200104 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400105 .platform_data = &orion5x_ehci_data,
106 },
107 .resource = orion5x_ehci0_resources,
108 .num_resources = ARRAY_SIZE(orion5x_ehci0_resources),
109};
110
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200111void __init orion5x_ehci0_init(void)
112{
113 platform_device_register(&orion5x_ehci0);
114}
115
116
117/*****************************************************************************
118 * EHCI1
119 ****************************************************************************/
120static struct resource orion5x_ehci1_resources[] = {
121 {
122 .start = ORION5X_USB1_PHYS_BASE,
123 .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
124 .flags = IORESOURCE_MEM,
125 }, {
126 .start = IRQ_ORION5X_USB1_CTRL,
127 .end = IRQ_ORION5X_USB1_CTRL,
128 .flags = IORESOURCE_IRQ,
129 },
130};
131
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400132static struct platform_device orion5x_ehci1 = {
133 .name = "orion-ehci",
134 .id = 1,
135 .dev = {
136 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200137 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400138 .platform_data = &orion5x_ehci_data,
139 },
140 .resource = orion5x_ehci1_resources,
141 .num_resources = ARRAY_SIZE(orion5x_ehci1_resources),
142};
143
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200144void __init orion5x_ehci1_init(void)
145{
146 platform_device_register(&orion5x_ehci1);
147}
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400148
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200149
150/*****************************************************************************
Andrew Lunn5c602552011-05-15 13:32:40 +0200151 * GE00
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200152 ****************************************************************************/
Andrew Lunn5c602552011-05-15 13:32:40 +0200153struct mv643xx_eth_shared_platform_data orion5x_ge00_shared_data = {
Lennert Buytenhekd236f5a2008-04-26 14:48:11 -0400154 .dram = &orion5x_mbus_dram_info,
155};
156
Andrew Lunn5c602552011-05-15 13:32:40 +0200157static struct resource orion5x_ge00_shared_resources[] = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400158 {
159 .start = ORION5X_ETH_PHYS_BASE + 0x2000,
Andrew Lunn5c602552011-05-15 13:32:40 +0200160 .end = ORION5X_ETH_PHYS_BASE + SZ_16K - 1,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400161 .flags = IORESOURCE_MEM,
Lennert Buytenhekeeff6d82008-08-26 16:01:21 +0200162 }, {
163 .start = IRQ_ORION5X_ETH_ERR,
164 .end = IRQ_ORION5X_ETH_ERR,
165 .flags = IORESOURCE_IRQ,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400166 },
167};
168
Andrew Lunn5c602552011-05-15 13:32:40 +0200169static struct platform_device orion5x_ge00_shared = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400170 .name = MV643XX_ETH_SHARED_NAME,
171 .id = 0,
Lennert Buytenhekd236f5a2008-04-26 14:48:11 -0400172 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200173 .platform_data = &orion5x_ge00_shared_data,
Lennert Buytenhekd236f5a2008-04-26 14:48:11 -0400174 },
Andrew Lunn5c602552011-05-15 13:32:40 +0200175 .num_resources = ARRAY_SIZE(orion5x_ge00_shared_resources),
176 .resource = orion5x_ge00_shared_resources,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400177};
178
Andrew Lunn5c602552011-05-15 13:32:40 +0200179static struct resource orion5x_ge00_resources[] = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400180 {
181 .name = "eth irq",
182 .start = IRQ_ORION5X_ETH_SUM,
183 .end = IRQ_ORION5X_ETH_SUM,
184 .flags = IORESOURCE_IRQ,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200185 },
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400186};
187
188static struct platform_device orion5x_eth = {
189 .name = MV643XX_ETH_NAME,
190 .id = 0,
191 .num_resources = 1,
Andrew Lunn5c602552011-05-15 13:32:40 +0200192 .resource = orion5x_ge00_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400193 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200194 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400195 },
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400196};
197
198void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
199{
Andrew Lunn5c602552011-05-15 13:32:40 +0200200 eth_data->shared = &orion5x_ge00_shared;
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400201 orion5x_eth.dev.platform_data = eth_data;
Lennert Buytenhekfa3959f2008-04-24 01:27:02 +0200202
Andrew Lunn5c602552011-05-15 13:32:40 +0200203 platform_device_register(&orion5x_ge00_shared);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400204 platform_device_register(&orion5x_eth);
205}
206
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400207
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200208/*****************************************************************************
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200209 * Ethernet switch
210 ****************************************************************************/
211static struct resource orion5x_switch_resources[] = {
212 {
213 .start = 0,
214 .end = 0,
215 .flags = IORESOURCE_IRQ,
216 },
217};
218
219static struct platform_device orion5x_switch_device = {
220 .name = "dsa",
221 .id = 0,
222 .num_resources = 0,
223 .resource = orion5x_switch_resources,
224};
225
226void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
227{
Lennert Buytenheke84665c2009-03-20 09:52:09 +0000228 int i;
229
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200230 if (irq != NO_IRQ) {
231 orion5x_switch_resources[0].start = irq;
232 orion5x_switch_resources[0].end = irq;
233 orion5x_switch_device.num_resources = 1;
234 }
235
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200236 d->netdev = &orion5x_eth.dev;
Lennert Buytenheke84665c2009-03-20 09:52:09 +0000237 for (i = 0; i < d->nr_chips; i++)
Andrew Lunn5c602552011-05-15 13:32:40 +0200238 d->chip[i].mii_bus = &orion5x_ge00_shared.dev;
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200239 orion5x_switch_device.dev.platform_data = d;
240
241 platform_device_register(&orion5x_switch_device);
242}
243
244
245/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200246 * I2C
247 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400248static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
249 .freq_m = 8, /* assumes 166 MHz TCLK */
250 .freq_n = 3,
251 .timeout = 1000, /* Default timeout of 1 second */
252};
253
254static struct resource orion5x_i2c_resources[] = {
255 {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200256 .start = I2C_PHYS_BASE,
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200257 .end = I2C_PHYS_BASE + 0x1f,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200258 .flags = IORESOURCE_MEM,
259 }, {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200260 .start = IRQ_ORION5X_I2C,
261 .end = IRQ_ORION5X_I2C,
262 .flags = IORESOURCE_IRQ,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400263 },
264};
265
266static struct platform_device orion5x_i2c = {
267 .name = MV64XXX_I2C_CTLR_NAME,
268 .id = 0,
269 .num_resources = ARRAY_SIZE(orion5x_i2c_resources),
270 .resource = orion5x_i2c_resources,
271 .dev = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200272 .platform_data = &orion5x_i2c_pdata,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400273 },
274};
275
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200276void __init orion5x_i2c_init(void)
277{
278 platform_device_register(&orion5x_i2c);
279}
280
281
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400282/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200283 * SATA
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400284 ****************************************************************************/
285static struct resource orion5x_sata_resources[] = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400286 {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200287 .name = "sata base",
288 .start = ORION5X_SATA_PHYS_BASE,
289 .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
290 .flags = IORESOURCE_MEM,
291 }, {
292 .name = "sata irq",
293 .start = IRQ_ORION5X_SATA,
294 .end = IRQ_ORION5X_SATA,
295 .flags = IORESOURCE_IRQ,
296 },
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400297};
298
299static struct platform_device orion5x_sata = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200300 .name = "sata_mv",
301 .id = 0,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400302 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200303 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400304 },
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200305 .num_resources = ARRAY_SIZE(orion5x_sata_resources),
306 .resource = orion5x_sata_resources,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400307};
308
309void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
310{
311 sata_data->dram = &orion5x_mbus_dram_info;
312 orion5x_sata.dev.platform_data = sata_data;
313 platform_device_register(&orion5x_sata);
314}
315
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200316
317/*****************************************************************************
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200318 * SPI
319 ****************************************************************************/
320static struct orion_spi_info orion5x_spi_plat_data = {
Nicolas Pitrec0e19362008-10-19 14:18:25 -0400321 .tclk = 0,
322 .enable_clock_fix = 1,
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200323};
324
325static struct resource orion5x_spi_resources[] = {
326 {
327 .name = "spi base",
328 .start = SPI_PHYS_BASE,
329 .end = SPI_PHYS_BASE + 0x1f,
330 .flags = IORESOURCE_MEM,
331 },
332};
333
334static struct platform_device orion5x_spi = {
335 .name = "orion_spi",
336 .id = 0,
337 .dev = {
338 .platform_data = &orion5x_spi_plat_data,
339 },
340 .num_resources = ARRAY_SIZE(orion5x_spi_resources),
341 .resource = orion5x_spi_resources,
342};
343
344void __init orion5x_spi_init()
345{
346 platform_device_register(&orion5x_spi);
347}
348
349
350/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200351 * UART0
352 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200353void __init orion5x_uart0_init(void)
354{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200355 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
356 IRQ_ORION5X_UART0, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200357}
358
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200359/*****************************************************************************
360 * UART1
361 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200362void __init orion5x_uart1_init(void)
363{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200364 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
365 IRQ_ORION5X_UART1, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200366}
367
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400368/*****************************************************************************
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100369 * XOR engine
370 ****************************************************************************/
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200371struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
372 .dram = &orion5x_mbus_dram_info,
373};
374
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100375static struct resource orion5x_xor_shared_resources[] = {
376 {
377 .name = "xor low",
378 .start = ORION5X_XOR_PHYS_BASE,
379 .end = ORION5X_XOR_PHYS_BASE + 0xff,
380 .flags = IORESOURCE_MEM,
381 }, {
382 .name = "xor high",
383 .start = ORION5X_XOR_PHYS_BASE + 0x200,
384 .end = ORION5X_XOR_PHYS_BASE + 0x2ff,
385 .flags = IORESOURCE_MEM,
386 },
387};
388
389static struct platform_device orion5x_xor_shared = {
390 .name = MV_XOR_SHARED_NAME,
391 .id = 0,
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200392 .dev = {
393 .platform_data = &orion5x_xor_shared_data,
394 },
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100395 .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources),
396 .resource = orion5x_xor_shared_resources,
397};
398
Yang Hongyang284901a2009-04-06 19:01:15 -0700399static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100400
401static struct resource orion5x_xor0_resources[] = {
402 [0] = {
403 .start = IRQ_ORION5X_XOR0,
404 .end = IRQ_ORION5X_XOR0,
405 .flags = IORESOURCE_IRQ,
406 },
407};
408
409static struct mv_xor_platform_data orion5x_xor0_data = {
410 .shared = &orion5x_xor_shared,
411 .hw_id = 0,
412 .pool_size = PAGE_SIZE,
413};
414
415static struct platform_device orion5x_xor0_channel = {
416 .name = MV_XOR_NAME,
417 .id = 0,
418 .num_resources = ARRAY_SIZE(orion5x_xor0_resources),
419 .resource = orion5x_xor0_resources,
420 .dev = {
421 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700422 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800423 .platform_data = &orion5x_xor0_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100424 },
425};
426
427static struct resource orion5x_xor1_resources[] = {
428 [0] = {
429 .start = IRQ_ORION5X_XOR1,
430 .end = IRQ_ORION5X_XOR1,
431 .flags = IORESOURCE_IRQ,
432 },
433};
434
435static struct mv_xor_platform_data orion5x_xor1_data = {
436 .shared = &orion5x_xor_shared,
437 .hw_id = 1,
438 .pool_size = PAGE_SIZE,
439};
440
441static struct platform_device orion5x_xor1_channel = {
442 .name = MV_XOR_NAME,
443 .id = 1,
444 .num_resources = ARRAY_SIZE(orion5x_xor1_resources),
445 .resource = orion5x_xor1_resources,
446 .dev = {
447 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700448 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800449 .platform_data = &orion5x_xor1_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100450 },
451};
452
453void __init orion5x_xor_init(void)
454{
455 platform_device_register(&orion5x_xor_shared);
456
457 /*
458 * two engines can't do memset simultaneously, this limitation
459 * satisfied by removing memset support from one of the engines.
460 */
461 dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
462 dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
463 platform_device_register(&orion5x_xor0_channel);
464
465 dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
466 dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
467 dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
468 platform_device_register(&orion5x_xor1_channel);
469}
470
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200471static struct resource orion5x_crypto_res[] = {
472 {
473 .name = "regs",
474 .start = ORION5X_CRYPTO_PHYS_BASE,
475 .end = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
476 .flags = IORESOURCE_MEM,
477 }, {
478 .name = "sram",
479 .start = ORION5X_SRAM_PHYS_BASE,
480 .end = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
481 .flags = IORESOURCE_MEM,
482 }, {
483 .name = "crypto interrupt",
484 .start = IRQ_ORION5X_CESA,
485 .end = IRQ_ORION5X_CESA,
486 .flags = IORESOURCE_IRQ,
487 },
488};
489
490static struct platform_device orion5x_crypto_device = {
491 .name = "mv_crypto",
492 .id = -1,
493 .num_resources = ARRAY_SIZE(orion5x_crypto_res),
494 .resource = orion5x_crypto_res,
495};
496
Nicolas Pitre3fade492009-06-11 22:27:20 +0200497static int __init orion5x_crypto_init(void)
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200498{
499 int ret;
500
501 ret = orion5x_setup_sram_win();
502 if (ret)
503 return ret;
504
505 return platform_device_register(&orion5x_crypto_device);
506}
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100507
508/*****************************************************************************
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800509 * Watchdog
510 ****************************************************************************/
Nicolas Pitre3b937a7db2009-06-01 13:56:02 -0400511static struct orion_wdt_platform_data orion5x_wdt_data = {
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800512 .tclk = 0,
513};
514
515static struct platform_device orion5x_wdt_device = {
Nicolas Pitre3b937a7db2009-06-01 13:56:02 -0400516 .name = "orion_wdt",
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800517 .id = -1,
518 .dev = {
519 .platform_data = &orion5x_wdt_data,
520 },
521 .num_resources = 0,
522};
523
524void __init orion5x_wdt_init(void)
525{
526 orion5x_wdt_data.tclk = orion5x_tclk;
527 platform_device_register(&orion5x_wdt_device);
528}
529
530
531/*****************************************************************************
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400532 * Time handling
533 ****************************************************************************/
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200534void __init orion5x_init_early(void)
535{
536 orion_time_set_base(TIMER_VIRT_BASE);
537}
538
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200539int orion5x_tclk;
540
541int __init orion5x_find_tclk(void)
542{
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200543 u32 dev, rev;
544
545 orion5x_pcie_id(&dev, &rev);
546 if (dev == MV88F6183_DEV_ID &&
547 (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
548 return 133333333;
549
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200550 return 166666667;
551}
552
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400553static void orion5x_timer_init(void)
554{
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200555 orion5x_tclk = orion5x_find_tclk();
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200556
557 orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
558 IRQ_ORION5X_BRIDGE, orion5x_tclk);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400559}
560
561struct sys_timer orion5x_timer = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200562 .init = orion5x_timer_init,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400563};
564
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200565
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400566/*****************************************************************************
567 * General
568 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400569/*
Lennert Buytenhekb46926b2008-04-25 16:31:32 -0400570 * Identify device ID and rev from PCIe configuration header space '0'.
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400571 */
572static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
573{
574 orion5x_pcie_id(dev, rev);
575
576 if (*dev == MV88F5281_DEV_ID) {
577 if (*rev == MV88F5281_REV_D2) {
578 *dev_name = "MV88F5281-D2";
579 } else if (*rev == MV88F5281_REV_D1) {
580 *dev_name = "MV88F5281-D1";
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200581 } else if (*rev == MV88F5281_REV_D0) {
582 *dev_name = "MV88F5281-D0";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400583 } else {
584 *dev_name = "MV88F5281-Rev-Unsupported";
585 }
586 } else if (*dev == MV88F5182_DEV_ID) {
587 if (*rev == MV88F5182_REV_A2) {
588 *dev_name = "MV88F5182-A2";
589 } else {
590 *dev_name = "MV88F5182-Rev-Unsupported";
591 }
592 } else if (*dev == MV88F5181_DEV_ID) {
593 if (*rev == MV88F5181_REV_B1) {
594 *dev_name = "MV88F5181-Rev-B1";
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200595 } else if (*rev == MV88F5181L_REV_A1) {
596 *dev_name = "MV88F5181L-Rev-A1";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400597 } else {
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200598 *dev_name = "MV88F5181(L)-Rev-Unsupported";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400599 }
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200600 } else if (*dev == MV88F6183_DEV_ID) {
601 if (*rev == MV88F6183_REV_B0) {
602 *dev_name = "MV88F6183-Rev-B0";
603 } else {
604 *dev_name = "MV88F6183-Rev-Unsupported";
605 }
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400606 } else {
607 *dev_name = "Device-Unknown";
608 }
609}
610
611void __init orion5x_init(void)
612{
613 char *dev_name;
614 u32 dev, rev;
615
616 orion5x_id(&dev, &rev, &dev_name);
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200617 printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
618
Andrew Lunn5c602552011-05-15 13:32:40 +0200619 orion5x_ge00_shared_data.t_clk = orion5x_tclk;
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200620 orion5x_spi_plat_data.tclk = orion5x_tclk;
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400621
622 /*
623 * Setup Orion address map
624 */
625 orion5x_setup_cpu_mbus_bridge();
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200626
627 /*
628 * Don't issue "Wait for Interrupt" instruction if we are
629 * running on D0 5281 silicon.
630 */
631 if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
632 printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
633 disable_hlt();
634 }
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800635
636 /*
Nicolas Pitre3fade492009-06-11 22:27:20 +0200637 * The 5082/5181l/5182/6082/6082l/6183 have crypto
638 * while 5180n/5181/5281 don't have crypto.
639 */
640 if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
641 dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
642 orion5x_crypto_init();
643
644 /*
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800645 * Register watchdog driver
646 */
647 orion5x_wdt_init();
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400648}
649
650/*
651 * Many orion-based systems have buggy bootloader implementations.
652 * This is a common fixup for bogus memory tags.
653 */
654void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t,
655 char **from, struct meminfo *meminfo)
656{
657 for (; t->hdr.size; t = tag_next(t))
658 if (t->hdr.tag == ATAG_MEM &&
659 (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
660 t->u.mem.start & ~PAGE_MASK)) {
661 printk(KERN_WARNING
662 "Clearing invalid memory bank %dKB@0x%08x\n",
663 t->u.mem.size / 1024, t->u.mem.start);
664 t->hdr.tag = 0;
665 }
666}