blob: 0a1c7600004e3d0b70c94177f9db429463c79971 [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 Buytenhekd323ade2008-08-29 06:55:06 +020020#include <linux/spi/orion_spi.h>
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +020021#include <net/dsa.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040022#include <asm/page.h>
23#include <asm/setup.h>
24#include <asm/timex.h>
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/time.h>
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +020028#include <mach/bridge-regs.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010029#include <mach/hardware.h>
30#include <mach/orion5x.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020031#include <plat/ehci-orion.h>
Saeed Bishara1d5a1a62008-06-16 23:25:12 -110032#include <plat/mv_xor.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020033#include <plat/orion_nand.h>
Nicolas Pitre3b937a72009-06-01 13:56:02 -040034#include <plat/orion_wdt.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020035#include <plat/time.h>
Andrew Lunn28a2b452011-05-15 13:32:41 +020036#include <plat/common.h>
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040037#include "common.h"
38
39/*****************************************************************************
40 * I/O Address Mapping
41 ****************************************************************************/
42static struct map_desc orion5x_io_desc[] __initdata = {
43 {
44 .virtual = ORION5X_REGS_VIRT_BASE,
45 .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
46 .length = ORION5X_REGS_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020047 .type = MT_DEVICE,
48 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040049 .virtual = ORION5X_PCIE_IO_VIRT_BASE,
50 .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
51 .length = ORION5X_PCIE_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020052 .type = MT_DEVICE,
53 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040054 .virtual = ORION5X_PCI_IO_VIRT_BASE,
55 .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
56 .length = ORION5X_PCI_IO_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020057 .type = MT_DEVICE,
58 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040059 .virtual = ORION5X_PCIE_WA_VIRT_BASE,
60 .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
61 .length = ORION5X_PCIE_WA_SIZE,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020062 .type = MT_DEVICE,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040063 },
64};
65
66void __init orion5x_map_io(void)
67{
68 iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
69}
70
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020071
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040072/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020073 * EHCI
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040074 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020075static struct orion_ehci_data orion5x_ehci_data = {
76 .dram = &orion5x_mbus_dram_info,
Ronen Shitritfb6f5522008-09-17 10:08:05 +030077 .phy_version = EHCI_PHY_ORION,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040078};
79
Andrew Lunn5c602552011-05-15 13:32:40 +020080static u64 ehci_dmamask = DMA_BIT_MASK(32);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040081
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040082
Lennert Buytenhek044f6c72008-04-22 05:37:12 +020083/*****************************************************************************
84 * EHCI0
85 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040086static struct resource orion5x_ehci0_resources[] = {
87 {
88 .start = ORION5X_USB0_PHYS_BASE,
Lennert Buytenhek994cab82008-04-25 16:30:21 -040089 .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040090 .flags = IORESOURCE_MEM,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +020091 }, {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040092 .start = IRQ_ORION5X_USB0_CTRL,
93 .end = IRQ_ORION5X_USB0_CTRL,
94 .flags = IORESOURCE_IRQ,
95 },
96};
97
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -040098static struct platform_device orion5x_ehci0 = {
99 .name = "orion-ehci",
100 .id = 0,
101 .dev = {
102 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200103 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400104 .platform_data = &orion5x_ehci_data,
105 },
106 .resource = orion5x_ehci0_resources,
107 .num_resources = ARRAY_SIZE(orion5x_ehci0_resources),
108};
109
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200110void __init orion5x_ehci0_init(void)
111{
112 platform_device_register(&orion5x_ehci0);
113}
114
115
116/*****************************************************************************
117 * EHCI1
118 ****************************************************************************/
119static struct resource orion5x_ehci1_resources[] = {
120 {
121 .start = ORION5X_USB1_PHYS_BASE,
122 .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
123 .flags = IORESOURCE_MEM,
124 }, {
125 .start = IRQ_ORION5X_USB1_CTRL,
126 .end = IRQ_ORION5X_USB1_CTRL,
127 .flags = IORESOURCE_IRQ,
128 },
129};
130
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400131static struct platform_device orion5x_ehci1 = {
132 .name = "orion-ehci",
133 .id = 1,
134 .dev = {
135 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200136 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400137 .platform_data = &orion5x_ehci_data,
138 },
139 .resource = orion5x_ehci1_resources,
140 .num_resources = ARRAY_SIZE(orion5x_ehci1_resources),
141};
142
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200143void __init orion5x_ehci1_init(void)
144{
145 platform_device_register(&orion5x_ehci1);
146}
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400147
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200148
149/*****************************************************************************
Andrew Lunn5c602552011-05-15 13:32:40 +0200150 * GE00
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200151 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400152void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
153{
Andrew Lunn7e3819d2011-05-15 13:32:44 +0200154 orion_ge00_init(eth_data, &orion5x_mbus_dram_info,
155 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
156 IRQ_ORION5X_ETH_ERR, orion5x_tclk);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400157}
158
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400159
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200160/*****************************************************************************
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200161 * Ethernet switch
162 ****************************************************************************/
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200163void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
164{
Andrew Lunn7e3819d2011-05-15 13:32:44 +0200165 orion_ge00_switch_init(d, irq);
Lennert Buytenhekdcf1cec2008-09-25 16:23:48 +0200166}
167
168
169/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200170 * I2C
171 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400172static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
173 .freq_m = 8, /* assumes 166 MHz TCLK */
174 .freq_n = 3,
175 .timeout = 1000, /* Default timeout of 1 second */
176};
177
178static struct resource orion5x_i2c_resources[] = {
179 {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200180 .start = I2C_PHYS_BASE,
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200181 .end = I2C_PHYS_BASE + 0x1f,
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200182 .flags = IORESOURCE_MEM,
183 }, {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200184 .start = IRQ_ORION5X_I2C,
185 .end = IRQ_ORION5X_I2C,
186 .flags = IORESOURCE_IRQ,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400187 },
188};
189
190static struct platform_device orion5x_i2c = {
191 .name = MV64XXX_I2C_CTLR_NAME,
192 .id = 0,
193 .num_resources = ARRAY_SIZE(orion5x_i2c_resources),
194 .resource = orion5x_i2c_resources,
195 .dev = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200196 .platform_data = &orion5x_i2c_pdata,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400197 },
198};
199
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200200void __init orion5x_i2c_init(void)
201{
202 platform_device_register(&orion5x_i2c);
203}
204
205
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400206/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200207 * SATA
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400208 ****************************************************************************/
209static struct resource orion5x_sata_resources[] = {
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400210 {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200211 .name = "sata base",
212 .start = ORION5X_SATA_PHYS_BASE,
213 .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
214 .flags = IORESOURCE_MEM,
215 }, {
216 .name = "sata irq",
217 .start = IRQ_ORION5X_SATA,
218 .end = IRQ_ORION5X_SATA,
219 .flags = IORESOURCE_IRQ,
220 },
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400221};
222
223static struct platform_device orion5x_sata = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200224 .name = "sata_mv",
225 .id = 0,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400226 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200227 .coherent_dma_mask = DMA_BIT_MASK(32),
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400228 },
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200229 .num_resources = ARRAY_SIZE(orion5x_sata_resources),
230 .resource = orion5x_sata_resources,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400231};
232
233void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
234{
235 sata_data->dram = &orion5x_mbus_dram_info;
236 orion5x_sata.dev.platform_data = sata_data;
237 platform_device_register(&orion5x_sata);
238}
239
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200240
241/*****************************************************************************
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200242 * SPI
243 ****************************************************************************/
244static struct orion_spi_info orion5x_spi_plat_data = {
Nicolas Pitrec0e19362008-10-19 14:18:25 -0400245 .tclk = 0,
246 .enable_clock_fix = 1,
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200247};
248
249static struct resource orion5x_spi_resources[] = {
250 {
251 .name = "spi base",
252 .start = SPI_PHYS_BASE,
253 .end = SPI_PHYS_BASE + 0x1f,
254 .flags = IORESOURCE_MEM,
255 },
256};
257
258static struct platform_device orion5x_spi = {
259 .name = "orion_spi",
260 .id = 0,
261 .dev = {
262 .platform_data = &orion5x_spi_plat_data,
263 },
264 .num_resources = ARRAY_SIZE(orion5x_spi_resources),
265 .resource = orion5x_spi_resources,
266};
267
268void __init orion5x_spi_init()
269{
270 platform_device_register(&orion5x_spi);
271}
272
273
274/*****************************************************************************
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200275 * UART0
276 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200277void __init orion5x_uart0_init(void)
278{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200279 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
280 IRQ_ORION5X_UART0, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200281}
282
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200283/*****************************************************************************
284 * UART1
285 ****************************************************************************/
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200286void __init orion5x_uart1_init(void)
287{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200288 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
289 IRQ_ORION5X_UART1, orion5x_tclk);
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200290}
291
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400292/*****************************************************************************
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100293 * XOR engine
294 ****************************************************************************/
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200295struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
296 .dram = &orion5x_mbus_dram_info,
297};
298
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100299static struct resource orion5x_xor_shared_resources[] = {
300 {
301 .name = "xor low",
302 .start = ORION5X_XOR_PHYS_BASE,
303 .end = ORION5X_XOR_PHYS_BASE + 0xff,
304 .flags = IORESOURCE_MEM,
305 }, {
306 .name = "xor high",
307 .start = ORION5X_XOR_PHYS_BASE + 0x200,
308 .end = ORION5X_XOR_PHYS_BASE + 0x2ff,
309 .flags = IORESOURCE_MEM,
310 },
311};
312
313static struct platform_device orion5x_xor_shared = {
314 .name = MV_XOR_SHARED_NAME,
315 .id = 0,
Saeed Bisharaf45964e2009-03-02 17:30:36 +0200316 .dev = {
317 .platform_data = &orion5x_xor_shared_data,
318 },
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100319 .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources),
320 .resource = orion5x_xor_shared_resources,
321};
322
Yang Hongyang284901a2009-04-06 19:01:15 -0700323static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100324
325static struct resource orion5x_xor0_resources[] = {
326 [0] = {
327 .start = IRQ_ORION5X_XOR0,
328 .end = IRQ_ORION5X_XOR0,
329 .flags = IORESOURCE_IRQ,
330 },
331};
332
333static struct mv_xor_platform_data orion5x_xor0_data = {
334 .shared = &orion5x_xor_shared,
335 .hw_id = 0,
336 .pool_size = PAGE_SIZE,
337};
338
339static struct platform_device orion5x_xor0_channel = {
340 .name = MV_XOR_NAME,
341 .id = 0,
342 .num_resources = ARRAY_SIZE(orion5x_xor0_resources),
343 .resource = orion5x_xor0_resources,
344 .dev = {
345 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700346 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800347 .platform_data = &orion5x_xor0_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100348 },
349};
350
351static struct resource orion5x_xor1_resources[] = {
352 [0] = {
353 .start = IRQ_ORION5X_XOR1,
354 .end = IRQ_ORION5X_XOR1,
355 .flags = IORESOURCE_IRQ,
356 },
357};
358
359static struct mv_xor_platform_data orion5x_xor1_data = {
360 .shared = &orion5x_xor_shared,
361 .hw_id = 1,
362 .pool_size = PAGE_SIZE,
363};
364
365static struct platform_device orion5x_xor1_channel = {
366 .name = MV_XOR_NAME,
367 .id = 1,
368 .num_resources = ARRAY_SIZE(orion5x_xor1_resources),
369 .resource = orion5x_xor1_resources,
370 .dev = {
371 .dma_mask = &orion5x_xor_dmamask,
Yang Hongyang6a355282009-04-06 19:01:13 -0700372 .coherent_dma_mask = DMA_BIT_MASK(64),
H Hartley Sweetenef4a6772010-01-29 14:56:58 -0800373 .platform_data = &orion5x_xor1_data,
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100374 },
375};
376
377void __init orion5x_xor_init(void)
378{
379 platform_device_register(&orion5x_xor_shared);
380
381 /*
382 * two engines can't do memset simultaneously, this limitation
383 * satisfied by removing memset support from one of the engines.
384 */
385 dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
386 dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
387 platform_device_register(&orion5x_xor0_channel);
388
389 dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
390 dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
391 dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
392 platform_device_register(&orion5x_xor1_channel);
393}
394
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200395static struct resource orion5x_crypto_res[] = {
396 {
397 .name = "regs",
398 .start = ORION5X_CRYPTO_PHYS_BASE,
399 .end = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
400 .flags = IORESOURCE_MEM,
401 }, {
402 .name = "sram",
403 .start = ORION5X_SRAM_PHYS_BASE,
404 .end = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
405 .flags = IORESOURCE_MEM,
406 }, {
407 .name = "crypto interrupt",
408 .start = IRQ_ORION5X_CESA,
409 .end = IRQ_ORION5X_CESA,
410 .flags = IORESOURCE_IRQ,
411 },
412};
413
414static struct platform_device orion5x_crypto_device = {
415 .name = "mv_crypto",
416 .id = -1,
417 .num_resources = ARRAY_SIZE(orion5x_crypto_res),
418 .resource = orion5x_crypto_res,
419};
420
Nicolas Pitre3fade492009-06-11 22:27:20 +0200421static int __init orion5x_crypto_init(void)
Sebastian Andrzej Siewior3a8f7442009-05-07 22:59:24 +0200422{
423 int ret;
424
425 ret = orion5x_setup_sram_win();
426 if (ret)
427 return ret;
428
429 return platform_device_register(&orion5x_crypto_device);
430}
Saeed Bishara1d5a1a62008-06-16 23:25:12 -1100431
432/*****************************************************************************
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800433 * Watchdog
434 ****************************************************************************/
Nicolas Pitre3b937a72009-06-01 13:56:02 -0400435static struct orion_wdt_platform_data orion5x_wdt_data = {
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800436 .tclk = 0,
437};
438
439static struct platform_device orion5x_wdt_device = {
Nicolas Pitre3b937a72009-06-01 13:56:02 -0400440 .name = "orion_wdt",
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800441 .id = -1,
442 .dev = {
443 .platform_data = &orion5x_wdt_data,
444 },
445 .num_resources = 0,
446};
447
448void __init orion5x_wdt_init(void)
449{
450 orion5x_wdt_data.tclk = orion5x_tclk;
451 platform_device_register(&orion5x_wdt_device);
452}
453
454
455/*****************************************************************************
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400456 * Time handling
457 ****************************************************************************/
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200458void __init orion5x_init_early(void)
459{
460 orion_time_set_base(TIMER_VIRT_BASE);
461}
462
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200463int orion5x_tclk;
464
465int __init orion5x_find_tclk(void)
466{
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200467 u32 dev, rev;
468
469 orion5x_pcie_id(&dev, &rev);
470 if (dev == MV88F6183_DEV_ID &&
471 (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
472 return 133333333;
473
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200474 return 166666667;
475}
476
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400477static void orion5x_timer_init(void)
478{
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200479 orion5x_tclk = orion5x_find_tclk();
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200480
481 orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
482 IRQ_ORION5X_BRIDGE, orion5x_tclk);
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400483}
484
485struct sys_timer orion5x_timer = {
Lennert Buytenheke7068ad2008-05-10 16:30:01 +0200486 .init = orion5x_timer_init,
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400487};
488
Lennert Buytenhek044f6c72008-04-22 05:37:12 +0200489
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400490/*****************************************************************************
491 * General
492 ****************************************************************************/
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400493/*
Lennert Buytenhekb46926b2008-04-25 16:31:32 -0400494 * Identify device ID and rev from PCIe configuration header space '0'.
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400495 */
496static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
497{
498 orion5x_pcie_id(dev, rev);
499
500 if (*dev == MV88F5281_DEV_ID) {
501 if (*rev == MV88F5281_REV_D2) {
502 *dev_name = "MV88F5281-D2";
503 } else if (*rev == MV88F5281_REV_D1) {
504 *dev_name = "MV88F5281-D1";
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200505 } else if (*rev == MV88F5281_REV_D0) {
506 *dev_name = "MV88F5281-D0";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400507 } else {
508 *dev_name = "MV88F5281-Rev-Unsupported";
509 }
510 } else if (*dev == MV88F5182_DEV_ID) {
511 if (*rev == MV88F5182_REV_A2) {
512 *dev_name = "MV88F5182-A2";
513 } else {
514 *dev_name = "MV88F5182-Rev-Unsupported";
515 }
516 } else if (*dev == MV88F5181_DEV_ID) {
517 if (*rev == MV88F5181_REV_B1) {
518 *dev_name = "MV88F5181-Rev-B1";
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200519 } else if (*rev == MV88F5181L_REV_A1) {
520 *dev_name = "MV88F5181L-Rev-A1";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400521 } else {
Lennert Buytenhekd2b2a6b2008-05-31 08:30:40 +0200522 *dev_name = "MV88F5181(L)-Rev-Unsupported";
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400523 }
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200524 } else if (*dev == MV88F6183_DEV_ID) {
525 if (*rev == MV88F6183_REV_B0) {
526 *dev_name = "MV88F6183-Rev-B0";
527 } else {
528 *dev_name = "MV88F6183-Rev-Unsupported";
529 }
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400530 } else {
531 *dev_name = "Device-Unknown";
532 }
533}
534
535void __init orion5x_init(void)
536{
537 char *dev_name;
538 u32 dev, rev;
539
540 orion5x_id(&dev, &rev, &dev_name);
Lennert Buytenhekebe35af2008-08-29 05:55:51 +0200541 printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
542
Lennert Buytenhekd323ade2008-08-29 06:55:06 +0200543 orion5x_spi_plat_data.tclk = orion5x_tclk;
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400544
545 /*
546 * Setup Orion address map
547 */
548 orion5x_setup_cpu_mbus_bridge();
Lennert Buytenhekce72e36e2008-08-09 15:17:27 +0200549
550 /*
551 * Don't issue "Wait for Interrupt" instruction if we are
552 * running on D0 5281 silicon.
553 */
554 if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
555 printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
556 disable_hlt();
557 }
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800558
559 /*
Nicolas Pitre3fade492009-06-11 22:27:20 +0200560 * The 5082/5181l/5182/6082/6082l/6183 have crypto
561 * while 5180n/5181/5281 don't have crypto.
562 */
563 if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
564 dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
565 orion5x_crypto_init();
566
567 /*
Thomas Reitmayr9e058d42009-02-24 14:59:22 -0800568 * Register watchdog driver
569 */
570 orion5x_wdt_init();
Lennert Buytenhek9dd0b192008-03-27 14:51:41 -0400571}
572
573/*
574 * Many orion-based systems have buggy bootloader implementations.
575 * This is a common fixup for bogus memory tags.
576 */
577void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t,
578 char **from, struct meminfo *meminfo)
579{
580 for (; t->hdr.size; t = tag_next(t))
581 if (t->hdr.tag == ATAG_MEM &&
582 (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
583 t->u.mem.start & ~PAGE_MASK)) {
584 printk(KERN_WARNING
585 "Clearing invalid memory bank %dKB@0x%08x\n",
586 t->u.mem.size / 1024, t->u.mem.start);
587 t->hdr.tag = 0;
588 }
589}