blob: c26e6dbe489b0a55d9c33a86f355000310475a21 [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>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040018#include <linux/mv643xx_i2c.h>
19#include <linux/ata_platform.h>
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +020020#include <net/dsa.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040021#include <asm/page.h>
22#include <asm/setup.h>
23#include <asm/timex.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26#include <asm/mach/time.h>
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +020027#include <mach/bridge-regs.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010028#include <mach/hardware.h>
29#include <mach/orion5x.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020030#include <plat/ehci-orion.h>
Saeed Bishara1d5a1a62008-06-16 23:25:12 -110031#include <plat/mv_xor.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020032#include <plat/orion_nand.h>
33#include <plat/time.h>
Andrew Lunn28a2b452011-05-15 13:32:41 +020034#include <plat/common.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040035#include "common.h"
36
37/*****************************************************************************
38 * I/O Address Mapping
39 ****************************************************************************/
40static struct map_desc orion5x_io_desc[] __initdata = {
41 {
42 .virtual = ORION5X_REGS_VIRT_BASE,
43 .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
44 .length = ORION5X_REGS_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020045 .type = MT_DEVICE,
46 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040047 .virtual = ORION5X_PCIE_IO_VIRT_BASE,
48 .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
49 .length = ORION5X_PCIE_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020050 .type = MT_DEVICE,
51 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040052 .virtual = ORION5X_PCI_IO_VIRT_BASE,
53 .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
54 .length = ORION5X_PCI_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020055 .type = MT_DEVICE,
56 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040057 .virtual = ORION5X_PCIE_WA_VIRT_BASE,
58 .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
59 .length = ORION5X_PCIE_WA_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020060 .type = MT_DEVICE,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040061 },
62};
63
64void __init orion5x_map_io(void)
65{
66 iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
67}
68
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020069
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040070/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020071 * EHCI
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040072 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020073static struct orion_ehci_data orion5x_ehci_data = {
74 .dram = &orion5x_mbus_dram_info,
Ronen Shitritfb6f5522008-09-17 10:08:05 +030075 .phy_version = EHCI_PHY_ORION,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040076};
77
Andrew Lunn5c602552011-05-15 13:32:40 +020078static u64 ehci_dmamask = DMA_BIT_MASK(32);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040079
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040080
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020081/*****************************************************************************
82 * EHCI0
83 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040084static struct resource orion5x_ehci0_resources[] = {
85 {
86 .start = ORION5X_USB0_PHYS_BASE,
Lennert Buytenhek994cab82008-04-25 16:30:21 -040087 .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040088 .flags = IORESOURCE_MEM,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020089 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040090 .start = IRQ_ORION5X_USB0_CTRL,
91 .end = IRQ_ORION5X_USB0_CTRL,
92 .flags = IORESOURCE_IRQ,
93 },
94};
95
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040096static struct platform_device orion5x_ehci0 = {
97 .name = "orion-ehci",
98 .id = 0,
99 .dev = {
100 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200101 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400102 .platform_data = &orion5x_ehci_data,
103 },
104 .resource = orion5x_ehci0_resources,
105 .num_resources = ARRAY_SIZE(orion5x_ehci0_resources),
106};
107
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200108void __init orion5x_ehci0_init(void)
109{
110 platform_device_register(&orion5x_ehci0);
111}
112
113
114/*****************************************************************************
115 * EHCI1
116 ****************************************************************************/
117static struct resource orion5x_ehci1_resources[] = {
118 {
119 .start = ORION5X_USB1_PHYS_BASE,
120 .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
121 .flags = IORESOURCE_MEM,
122 }, {
123 .start = IRQ_ORION5X_USB1_CTRL,
124 .end = IRQ_ORION5X_USB1_CTRL,
125 .flags = IORESOURCE_IRQ,
126 },
127};
128
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400129static struct platform_device orion5x_ehci1 = {
130 .name = "orion-ehci",
131 .id = 1,
132 .dev = {
133 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200134 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400135 .platform_data = &orion5x_ehci_data,
136 },
137 .resource = orion5x_ehci1_resources,
138 .num_resources = ARRAY_SIZE(orion5x_ehci1_resources),
139};
140
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200141void __init orion5x_ehci1_init(void)
142{
143 platform_device_register(&orion5x_ehci1);
144}
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400145
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200146
147/*****************************************************************************
Andrew Lunn5c602552011-05-15 13:32:40 +0200148 * GE00
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200149 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400150void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
151{
Andrew Lunn7e3819d2011-05-15 13:32:44 +0200152 orion_ge00_init(eth_data, &orion5x_mbus_dram_info,
153 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
154 IRQ_ORION5X_ETH_ERR, orion5x_tclk);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400155}
156
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400157
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200158/*****************************************************************************
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200159 * Ethernet switch
160 ****************************************************************************/
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200161void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
162{
Andrew Lunn7e3819d2011-05-15 13:32:44 +0200163 orion_ge00_switch_init(d, irq);
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200164}
165
166
167/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200168 * I2C
169 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200170void __init orion5x_i2c_init(void)
171{
Andrew Lunnaac7ffa2011-05-15 13:32:45 +0200172 orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8);
173
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200174}
175
176
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400177/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200178 * SATA
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400179 ****************************************************************************/
180static struct resource orion5x_sata_resources[] = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400181 {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200182 .name = "sata base",
183 .start = ORION5X_SATA_PHYS_BASE,
184 .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
185 .flags = IORESOURCE_MEM,
186 }, {
187 .name = "sata irq",
188 .start = IRQ_ORION5X_SATA,
189 .end = IRQ_ORION5X_SATA,
190 .flags = IORESOURCE_IRQ,
191 },
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400192};
193
194static struct platform_device orion5x_sata = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200195 .name = "sata_mv",
196 .id = 0,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400197 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200198 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400199 },
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200200 .num_resources = ARRAY_SIZE(orion5x_sata_resources),
201 .resource = orion5x_sata_resources,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400202};
203
204void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
205{
206 sata_data->dram = &orion5x_mbus_dram_info;
207 orion5x_sata.dev.platform_data = sata_data;
208 platform_device_register(&orion5x_sata);
209}
210
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200211
212/*****************************************************************************
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200213 * SPI
214 ****************************************************************************/
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200215void __init orion5x_spi_init()
216{
Andrew Lunn980f9f62011-05-15 13:32:46 +0200217 orion_spi_init(SPI_PHYS_BASE, orion5x_tclk);
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200218}
219
220
221/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200222 * UART0
223 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200224void __init orion5x_uart0_init(void)
225{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200226 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
227 IRQ_ORION5X_UART0, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200228}
229
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200230/*****************************************************************************
231 * UART1
232 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200233void __init orion5x_uart1_init(void)
234{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200235 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
236 IRQ_ORION5X_UART1, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200237}
238
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400239/*****************************************************************************
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100240 * XOR engine
241 ****************************************************************************/
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200242struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
243 .dram = &orion5x_mbus_dram_info,
244};
245
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100246static struct resource orion5x_xor_shared_resources[] = {
247 {
248 .name = "xor low",
249 .start = ORION5X_XOR_PHYS_BASE,
250 .end = ORION5X_XOR_PHYS_BASE + 0xff,
251 .flags = IORESOURCE_MEM,
252 }, {
253 .name = "xor high",
254 .start = ORION5X_XOR_PHYS_BASE + 0x200,
255 .end = ORION5X_XOR_PHYS_BASE + 0x2ff,
256 .flags = IORESOURCE_MEM,
257 },
258};
259
260static struct platform_device orion5x_xor_shared = {
261 .name = MV_XOR_SHARED_NAME,
262 .id = 0,
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200263 .dev = {
264 .platform_data = &orion5x_xor_shared_data,
265 },
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100266 .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources),
267 .resource = orion5x_xor_shared_resources,
268};
269
Yang Hongyang284901a2009-04-06 19:01:15 -0700270static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100271
272static struct resource orion5x_xor0_resources[] = {
273 [0] = {
274 .start = IRQ_ORION5X_XOR0,
275 .end = IRQ_ORION5X_XOR0,
276 .flags = IORESOURCE_IRQ,
277 },
278};
279
280static struct mv_xor_platform_data orion5x_xor0_data = {
281 .shared = &orion5x_xor_shared,
282 .hw_id = 0,
283 .pool_size = PAGE_SIZE,
284};
285
286static struct platform_device orion5x_xor0_channel = {
287 .name = MV_XOR_NAME,
288 .id = 0,
289 .num_resources = ARRAY_SIZE(orion5x_xor0_resources),
290 .resource = orion5x_xor0_resources,
291 .dev = {
292 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700293 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800294 .platform_data = &orion5x_xor0_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100295 },
296};
297
298static struct resource orion5x_xor1_resources[] = {
299 [0] = {
300 .start = IRQ_ORION5X_XOR1,
301 .end = IRQ_ORION5X_XOR1,
302 .flags = IORESOURCE_IRQ,
303 },
304};
305
306static struct mv_xor_platform_data orion5x_xor1_data = {
307 .shared = &orion5x_xor_shared,
308 .hw_id = 1,
309 .pool_size = PAGE_SIZE,
310};
311
312static struct platform_device orion5x_xor1_channel = {
313 .name = MV_XOR_NAME,
314 .id = 1,
315 .num_resources = ARRAY_SIZE(orion5x_xor1_resources),
316 .resource = orion5x_xor1_resources,
317 .dev = {
318 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700319 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800320 .platform_data = &orion5x_xor1_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100321 },
322};
323
324void __init orion5x_xor_init(void)
325{
326 platform_device_register(&orion5x_xor_shared);
327
328 /*
329 * two engines can't do memset simultaneously, this limitation
330 * satisfied by removing memset support from one of the engines.
331 */
332 dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
333 dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
334 platform_device_register(&orion5x_xor0_channel);
335
336 dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
337 dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
338 dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
339 platform_device_register(&orion5x_xor1_channel);
340}
341
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200342static struct resource orion5x_crypto_res[] = {
343 {
344 .name = "regs",
345 .start = ORION5X_CRYPTO_PHYS_BASE,
346 .end = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
347 .flags = IORESOURCE_MEM,
348 }, {
349 .name = "sram",
350 .start = ORION5X_SRAM_PHYS_BASE,
351 .end = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
352 .flags = IORESOURCE_MEM,
353 }, {
354 .name = "crypto interrupt",
355 .start = IRQ_ORION5X_CESA,
356 .end = IRQ_ORION5X_CESA,
357 .flags = IORESOURCE_IRQ,
358 },
359};
360
361static struct platform_device orion5x_crypto_device = {
362 .name = "mv_crypto",
363 .id = -1,
364 .num_resources = ARRAY_SIZE(orion5x_crypto_res),
365 .resource = orion5x_crypto_res,
366};
367
Nicolas Pitre3fade492009-06-11 22:27:20 +0200368static int __init orion5x_crypto_init(void)
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200369{
370 int ret;
371
372 ret = orion5x_setup_sram_win();
373 if (ret)
374 return ret;
375
376 return platform_device_register(&orion5x_crypto_device);
377}
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100378
379/*****************************************************************************
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800380 * Watchdog
381 ****************************************************************************/
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800382void __init orion5x_wdt_init(void)
383{
Andrew Lunn5e00d372011-05-15 13:32:47 +0200384 orion_wdt_init(orion5x_tclk);
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800385}
386
387
388/*****************************************************************************
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400389 * Time handling
390 ****************************************************************************/
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200391void __init orion5x_init_early(void)
392{
393 orion_time_set_base(TIMER_VIRT_BASE);
394}
395
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200396int orion5x_tclk;
397
398int __init orion5x_find_tclk(void)
399{
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200400 u32 dev, rev;
401
402 orion5x_pcie_id(&dev, &rev);
403 if (dev == MV88F6183_DEV_ID &&
404 (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
405 return 133333333;
406
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200407 return 166666667;
408}
409
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400410static void orion5x_timer_init(void)
411{
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200412 orion5x_tclk = orion5x_find_tclk();
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200413
414 orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
415 IRQ_ORION5X_BRIDGE, orion5x_tclk);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400416}
417
418struct sys_timer orion5x_timer = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200419 .init = orion5x_timer_init,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400420};
421
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200422
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400423/*****************************************************************************
424 * General
425 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400426/*
Lennert Buytenhekb46926b2008-04-25 16:31:32 -0400427 * Identify device ID and rev from PCIe configuration header space '0'.
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400428 */
429static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
430{
431 orion5x_pcie_id(dev, rev);
432
433 if (*dev == MV88F5281_DEV_ID) {
434 if (*rev == MV88F5281_REV_D2) {
435 *dev_name = "MV88F5281-D2";
436 } else if (*rev == MV88F5281_REV_D1) {
437 *dev_name = "MV88F5281-D1";
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200438 } else if (*rev == MV88F5281_REV_D0) {
439 *dev_name = "MV88F5281-D0";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400440 } else {
441 *dev_name = "MV88F5281-Rev-Unsupported";
442 }
443 } else if (*dev == MV88F5182_DEV_ID) {
444 if (*rev == MV88F5182_REV_A2) {
445 *dev_name = "MV88F5182-A2";
446 } else {
447 *dev_name = "MV88F5182-Rev-Unsupported";
448 }
449 } else if (*dev == MV88F5181_DEV_ID) {
450 if (*rev == MV88F5181_REV_B1) {
451 *dev_name = "MV88F5181-Rev-B1";
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200452 } else if (*rev == MV88F5181L_REV_A1) {
453 *dev_name = "MV88F5181L-Rev-A1";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400454 } else {
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200455 *dev_name = "MV88F5181(L)-Rev-Unsupported";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400456 }
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200457 } else if (*dev == MV88F6183_DEV_ID) {
458 if (*rev == MV88F6183_REV_B0) {
459 *dev_name = "MV88F6183-Rev-B0";
460 } else {
461 *dev_name = "MV88F6183-Rev-Unsupported";
462 }
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400463 } else {
464 *dev_name = "Device-Unknown";
465 }
466}
467
468void __init orion5x_init(void)
469{
470 char *dev_name;
471 u32 dev, rev;
472
473 orion5x_id(&dev, &rev, &dev_name);
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200474 printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
475
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400476 /*
477 * Setup Orion address map
478 */
479 orion5x_setup_cpu_mbus_bridge();
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200480
481 /*
482 * Don't issue "Wait for Interrupt" instruction if we are
483 * running on D0 5281 silicon.
484 */
485 if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
486 printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
487 disable_hlt();
488 }
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800489
490 /*
Nicolas Pitre3fade492009-06-11 22:27:20 +0200491 * The 5082/5181l/5182/6082/6082l/6183 have crypto
492 * while 5180n/5181/5281 don't have crypto.
493 */
494 if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
495 dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
496 orion5x_crypto_init();
497
498 /*
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800499 * Register watchdog driver
500 */
501 orion5x_wdt_init();
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400502}
503
504/*
505 * Many orion-based systems have buggy bootloader implementations.
506 * This is a common fixup for bogus memory tags.
507 */
508void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t,
509 char **from, struct meminfo *meminfo)
510{
511 for (; t->hdr.size; t = tag_next(t))
512 if (t->hdr.tag == ATAG_MEM &&
513 (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
514 t->u.mem.start & ~PAGE_MASK)) {
515 printk(KERN_WARNING
516 "Clearing invalid memory bank %dKB@0x%08x\n",
517 t->u.mem.size / 1024, t->u.mem.start);
518 t->hdr.tag = 0;
519 }
520}