blob: 5b474e4574de892cbaeb369d27fcecacc91378c3 [file] [log] [blame]
Stanislav Samsonov794d15b2008-06-22 22:45:10 +02001/*
2 * arch/arm/mach-mv78xx0/common.c
3 *
4 * Core functions for Marvell MV78xx0 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>
Riku Voipio69359942009-03-03 21:13:50 +020017#include <linux/mv643xx_i2c.h>
Stanislav Samsonov794d15b2008-06-22 22:45:10 +020018#include <linux/ata_platform.h>
Lennert Buytenhek712424f2009-02-20 02:31:58 +010019#include <linux/ethtool.h>
Stanislav Samsonov794d15b2008-06-22 22:45:10 +020020#include <asm/mach/map.h>
21#include <asm/mach/time.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010022#include <mach/mv78xx0.h>
Nicolas Pitrefdd8b072009-04-22 20:08:17 +010023#include <mach/bridge-regs.h>
Lennert Buytenhek6f088f12008-08-09 13:44:58 +020024#include <plat/cache-feroceon-l2.h>
25#include <plat/ehci-orion.h>
26#include <plat/orion_nand.h>
27#include <plat/time.h>
Andrew Lunn28a2b452011-05-15 13:32:41 +020028#include <plat/common.h>
Stanislav Samsonov794d15b2008-06-22 22:45:10 +020029#include "common.h"
30
Andrew Lunn28a2b452011-05-15 13:32:41 +020031static int get_tclk(void);
Stanislav Samsonov794d15b2008-06-22 22:45:10 +020032
33/*****************************************************************************
34 * Common bits
35 ****************************************************************************/
36int mv78xx0_core_index(void)
37{
38 u32 extra;
39
40 /*
41 * Read Extra Features register.
42 */
43 __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
44
45 return !!(extra & 0x00004000);
46}
47
48static int get_hclk(void)
49{
50 int hclk;
51
52 /*
53 * HCLK tick rate is configured by DEV_D[7:5] pins.
54 */
55 switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
56 case 0:
57 hclk = 166666667;
58 break;
59 case 1:
60 hclk = 200000000;
61 break;
62 case 2:
63 hclk = 266666667;
64 break;
65 case 3:
66 hclk = 333333333;
67 break;
68 case 4:
69 hclk = 400000000;
70 break;
71 default:
72 panic("unknown HCLK PLL setting: %.8x\n",
73 readl(SAMPLE_AT_RESET_LOW));
74 }
75
76 return hclk;
77}
78
79static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
80{
81 u32 cfg;
82
83 /*
84 * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
85 * PCLK/L2CLK by bits [19:14].
86 */
87 if (core_index == 0) {
88 cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
89 } else {
90 cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
91 }
92
93 /*
94 * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
95 * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
96 */
97 *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
98
99 /*
100 * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
101 * ratio (1, 2, 3).
102 */
103 *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
104}
105
106static int get_tclk(void)
107{
108 int tclk;
109
110 /*
111 * TCLK tick rate is configured by DEV_A[2:0] strap pins.
112 */
113 switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
114 case 1:
115 tclk = 166666667;
116 break;
117 case 3:
118 tclk = 200000000;
119 break;
120 default:
121 panic("unknown TCLK PLL setting: %.8x\n",
122 readl(SAMPLE_AT_RESET_HIGH));
123 }
124
125 return tclk;
126}
127
128
129/*****************************************************************************
130 * I/O Address Mapping
131 ****************************************************************************/
132static struct map_desc mv78xx0_io_desc[] __initdata = {
133 {
134 .virtual = MV78XX0_CORE_REGS_VIRT_BASE,
135 .pfn = 0,
136 .length = MV78XX0_CORE_REGS_SIZE,
137 .type = MT_DEVICE,
138 }, {
139 .virtual = MV78XX0_PCIE_IO_VIRT_BASE(0),
140 .pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
141 .length = MV78XX0_PCIE_IO_SIZE * 8,
142 .type = MT_DEVICE,
143 }, {
144 .virtual = MV78XX0_REGS_VIRT_BASE,
145 .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
146 .length = MV78XX0_REGS_SIZE,
147 .type = MT_DEVICE,
148 },
149};
150
151void __init mv78xx0_map_io(void)
152{
153 unsigned long phys;
154
155 /*
156 * Map the right set of per-core registers depending on
157 * which core we are running on.
158 */
159 if (mv78xx0_core_index() == 0) {
160 phys = MV78XX0_CORE0_REGS_PHYS_BASE;
161 } else {
162 phys = MV78XX0_CORE1_REGS_PHYS_BASE;
163 }
164 mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
165
166 iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
167}
168
169
170/*****************************************************************************
171 * EHCI
172 ****************************************************************************/
173static struct orion_ehci_data mv78xx0_ehci_data = {
174 .dram = &mv78xx0_mbus_dram_info,
Ronen Shitritfb6f5522008-09-17 10:08:05 +0300175 .phy_version = EHCI_PHY_NA,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200176};
177
Andrew Lunn5c602552011-05-15 13:32:40 +0200178static u64 ehci_dmamask = DMA_BIT_MASK(32);
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200179
180
181/*****************************************************************************
182 * EHCI0
183 ****************************************************************************/
184static struct resource mv78xx0_ehci0_resources[] = {
185 {
186 .start = USB0_PHYS_BASE,
Andrew Lunn5c602552011-05-15 13:32:40 +0200187 .end = USB0_PHYS_BASE + SZ_4K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200188 .flags = IORESOURCE_MEM,
189 }, {
190 .start = IRQ_MV78XX0_USB_0,
191 .end = IRQ_MV78XX0_USB_0,
192 .flags = IORESOURCE_IRQ,
193 },
194};
195
196static struct platform_device mv78xx0_ehci0 = {
197 .name = "orion-ehci",
198 .id = 0,
199 .dev = {
200 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200201 .coherent_dma_mask = DMA_BIT_MASK(32),
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200202 .platform_data = &mv78xx0_ehci_data,
203 },
204 .resource = mv78xx0_ehci0_resources,
205 .num_resources = ARRAY_SIZE(mv78xx0_ehci0_resources),
206};
207
208void __init mv78xx0_ehci0_init(void)
209{
210 platform_device_register(&mv78xx0_ehci0);
211}
212
213
214/*****************************************************************************
215 * EHCI1
216 ****************************************************************************/
217static struct resource mv78xx0_ehci1_resources[] = {
218 {
219 .start = USB1_PHYS_BASE,
Andrew Lunn5c602552011-05-15 13:32:40 +0200220 .end = USB1_PHYS_BASE + SZ_4K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200221 .flags = IORESOURCE_MEM,
222 }, {
223 .start = IRQ_MV78XX0_USB_1,
224 .end = IRQ_MV78XX0_USB_1,
225 .flags = IORESOURCE_IRQ,
226 },
227};
228
229static struct platform_device mv78xx0_ehci1 = {
230 .name = "orion-ehci",
231 .id = 1,
232 .dev = {
233 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200234 .coherent_dma_mask = DMA_BIT_MASK(32),
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200235 .platform_data = &mv78xx0_ehci_data,
236 },
237 .resource = mv78xx0_ehci1_resources,
238 .num_resources = ARRAY_SIZE(mv78xx0_ehci1_resources),
239};
240
241void __init mv78xx0_ehci1_init(void)
242{
243 platform_device_register(&mv78xx0_ehci1);
244}
245
246
247/*****************************************************************************
248 * EHCI2
249 ****************************************************************************/
250static struct resource mv78xx0_ehci2_resources[] = {
251 {
252 .start = USB2_PHYS_BASE,
Andrew Lunn5c602552011-05-15 13:32:40 +0200253 .end = USB2_PHYS_BASE + SZ_4K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200254 .flags = IORESOURCE_MEM,
255 }, {
256 .start = IRQ_MV78XX0_USB_2,
257 .end = IRQ_MV78XX0_USB_2,
258 .flags = IORESOURCE_IRQ,
259 },
260};
261
262static struct platform_device mv78xx0_ehci2 = {
263 .name = "orion-ehci",
264 .id = 2,
265 .dev = {
266 .dma_mask = &ehci_dmamask,
Andrew Lunn5c602552011-05-15 13:32:40 +0200267 .coherent_dma_mask = DMA_BIT_MASK(32),
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200268 .platform_data = &mv78xx0_ehci_data,
269 },
270 .resource = mv78xx0_ehci2_resources,
271 .num_resources = ARRAY_SIZE(mv78xx0_ehci2_resources),
272};
273
274void __init mv78xx0_ehci2_init(void)
275{
276 platform_device_register(&mv78xx0_ehci2);
277}
278
279
280/*****************************************************************************
281 * GE00
282 ****************************************************************************/
283struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
284 .t_clk = 0,
285 .dram = &mv78xx0_mbus_dram_info,
286};
287
288static struct resource mv78xx0_ge00_shared_resources[] = {
289 {
290 .name = "ge00 base",
291 .start = GE00_PHYS_BASE + 0x2000,
Andrew Lunn5c602552011-05-15 13:32:40 +0200292 .end = GE00_PHYS_BASE + SZ_16K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200293 .flags = IORESOURCE_MEM,
Lennert Buytenhek1f8081f2008-08-26 16:04:05 +0200294 }, {
295 .name = "ge err irq",
296 .start = IRQ_MV78XX0_GE_ERR,
297 .end = IRQ_MV78XX0_GE_ERR,
298 .flags = IORESOURCE_IRQ,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200299 },
300};
301
302static struct platform_device mv78xx0_ge00_shared = {
303 .name = MV643XX_ETH_SHARED_NAME,
304 .id = 0,
305 .dev = {
306 .platform_data = &mv78xx0_ge00_shared_data,
307 },
Lennert Buytenhek1f8081f2008-08-26 16:04:05 +0200308 .num_resources = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200309 .resource = mv78xx0_ge00_shared_resources,
310};
311
312static struct resource mv78xx0_ge00_resources[] = {
313 {
314 .name = "ge00 irq",
315 .start = IRQ_MV78XX0_GE00_SUM,
316 .end = IRQ_MV78XX0_GE00_SUM,
317 .flags = IORESOURCE_IRQ,
318 },
319};
320
321static struct platform_device mv78xx0_ge00 = {
322 .name = MV643XX_ETH_NAME,
323 .id = 0,
324 .num_resources = 1,
325 .resource = mv78xx0_ge00_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400326 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200327 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400328 },
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200329};
330
331void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
332{
333 eth_data->shared = &mv78xx0_ge00_shared;
334 mv78xx0_ge00.dev.platform_data = eth_data;
335
336 platform_device_register(&mv78xx0_ge00_shared);
337 platform_device_register(&mv78xx0_ge00);
338}
339
340
341/*****************************************************************************
342 * GE01
343 ****************************************************************************/
344struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
345 .t_clk = 0,
346 .dram = &mv78xx0_mbus_dram_info,
Lennert Buytenhekfc0eb9f2008-08-26 12:56:56 +0200347 .shared_smi = &mv78xx0_ge00_shared,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200348};
349
350static struct resource mv78xx0_ge01_shared_resources[] = {
351 {
352 .name = "ge01 base",
353 .start = GE01_PHYS_BASE + 0x2000,
Andrew Lunn5c602552011-05-15 13:32:40 +0200354 .end = GE01_PHYS_BASE + SZ_16K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200355 .flags = IORESOURCE_MEM,
356 },
357};
358
359static struct platform_device mv78xx0_ge01_shared = {
360 .name = MV643XX_ETH_SHARED_NAME,
361 .id = 1,
362 .dev = {
363 .platform_data = &mv78xx0_ge01_shared_data,
364 },
365 .num_resources = 1,
366 .resource = mv78xx0_ge01_shared_resources,
367};
368
369static struct resource mv78xx0_ge01_resources[] = {
370 {
371 .name = "ge01 irq",
372 .start = IRQ_MV78XX0_GE01_SUM,
373 .end = IRQ_MV78XX0_GE01_SUM,
374 .flags = IORESOURCE_IRQ,
375 },
376};
377
378static struct platform_device mv78xx0_ge01 = {
379 .name = MV643XX_ETH_NAME,
380 .id = 1,
381 .num_resources = 1,
382 .resource = mv78xx0_ge01_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400383 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200384 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400385 },
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200386};
387
388void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
389{
390 eth_data->shared = &mv78xx0_ge01_shared;
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200391 mv78xx0_ge01.dev.platform_data = eth_data;
392
393 platform_device_register(&mv78xx0_ge01_shared);
394 platform_device_register(&mv78xx0_ge01);
395}
396
397
398/*****************************************************************************
399 * GE10
400 ****************************************************************************/
401struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
402 .t_clk = 0,
403 .dram = &mv78xx0_mbus_dram_info,
Lennert Buytenhekfc0eb9f2008-08-26 12:56:56 +0200404 .shared_smi = &mv78xx0_ge00_shared,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200405};
406
407static struct resource mv78xx0_ge10_shared_resources[] = {
408 {
409 .name = "ge10 base",
410 .start = GE10_PHYS_BASE + 0x2000,
Andrew Lunn5c602552011-05-15 13:32:40 +0200411 .end = GE10_PHYS_BASE + SZ_16K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200412 .flags = IORESOURCE_MEM,
413 },
414};
415
416static struct platform_device mv78xx0_ge10_shared = {
417 .name = MV643XX_ETH_SHARED_NAME,
418 .id = 2,
419 .dev = {
420 .platform_data = &mv78xx0_ge10_shared_data,
421 },
422 .num_resources = 1,
423 .resource = mv78xx0_ge10_shared_resources,
424};
425
426static struct resource mv78xx0_ge10_resources[] = {
427 {
428 .name = "ge10 irq",
429 .start = IRQ_MV78XX0_GE10_SUM,
430 .end = IRQ_MV78XX0_GE10_SUM,
431 .flags = IORESOURCE_IRQ,
432 },
433};
434
435static struct platform_device mv78xx0_ge10 = {
436 .name = MV643XX_ETH_NAME,
437 .id = 2,
438 .num_resources = 1,
439 .resource = mv78xx0_ge10_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400440 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200441 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400442 },
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200443};
444
445void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
446{
Lennert Buytenhek712424f2009-02-20 02:31:58 +0100447 u32 dev, rev;
448
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200449 eth_data->shared = &mv78xx0_ge10_shared;
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200450 mv78xx0_ge10.dev.platform_data = eth_data;
451
Lennert Buytenhek712424f2009-02-20 02:31:58 +0100452 /*
453 * On the Z0, ge10 and ge11 are internally connected back
454 * to back, and not brought out.
455 */
456 mv78xx0_pcie_id(&dev, &rev);
457 if (dev == MV78X00_Z0_DEV_ID) {
458 eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
459 eth_data->speed = SPEED_1000;
460 eth_data->duplex = DUPLEX_FULL;
461 }
462
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200463 platform_device_register(&mv78xx0_ge10_shared);
464 platform_device_register(&mv78xx0_ge10);
465}
466
467
468/*****************************************************************************
469 * GE11
470 ****************************************************************************/
471struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
472 .t_clk = 0,
473 .dram = &mv78xx0_mbus_dram_info,
Lennert Buytenhekfc0eb9f2008-08-26 12:56:56 +0200474 .shared_smi = &mv78xx0_ge00_shared,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200475};
476
477static struct resource mv78xx0_ge11_shared_resources[] = {
478 {
479 .name = "ge11 base",
480 .start = GE11_PHYS_BASE + 0x2000,
Andrew Lunn5c602552011-05-15 13:32:40 +0200481 .end = GE11_PHYS_BASE + SZ_16K - 1,
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200482 .flags = IORESOURCE_MEM,
483 },
484};
485
486static struct platform_device mv78xx0_ge11_shared = {
487 .name = MV643XX_ETH_SHARED_NAME,
488 .id = 3,
489 .dev = {
490 .platform_data = &mv78xx0_ge11_shared_data,
491 },
492 .num_resources = 1,
493 .resource = mv78xx0_ge11_shared_resources,
494};
495
496static struct resource mv78xx0_ge11_resources[] = {
497 {
498 .name = "ge11 irq",
499 .start = IRQ_MV78XX0_GE11_SUM,
500 .end = IRQ_MV78XX0_GE11_SUM,
501 .flags = IORESOURCE_IRQ,
502 },
503};
504
505static struct platform_device mv78xx0_ge11 = {
506 .name = MV643XX_ETH_NAME,
507 .id = 3,
508 .num_resources = 1,
509 .resource = mv78xx0_ge11_resources,
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400510 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200511 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Pitrea49a0182009-05-22 16:53:40 -0400512 },
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200513};
514
515void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
516{
Lennert Buytenhek712424f2009-02-20 02:31:58 +0100517 u32 dev, rev;
518
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200519 eth_data->shared = &mv78xx0_ge11_shared;
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200520 mv78xx0_ge11.dev.platform_data = eth_data;
521
Lennert Buytenhek712424f2009-02-20 02:31:58 +0100522 /*
523 * On the Z0, ge10 and ge11 are internally connected back
524 * to back, and not brought out.
525 */
526 mv78xx0_pcie_id(&dev, &rev);
527 if (dev == MV78X00_Z0_DEV_ID) {
528 eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
529 eth_data->speed = SPEED_1000;
530 eth_data->duplex = DUPLEX_FULL;
531 }
532
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200533 platform_device_register(&mv78xx0_ge11_shared);
534 platform_device_register(&mv78xx0_ge11);
535}
536
Riku Voipio69359942009-03-03 21:13:50 +0200537/*****************************************************************************
538 * I2C bus 0
539 ****************************************************************************/
540
541static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
542 .freq_m = 8, /* assumes 166 MHz TCLK */
543 .freq_n = 3,
544 .timeout = 1000, /* Default timeout of 1 second */
545};
546
547static struct resource mv78xx0_i2c_0_resources[] = {
548 {
Riku Voipio69359942009-03-03 21:13:50 +0200549 .start = I2C_0_PHYS_BASE,
550 .end = I2C_0_PHYS_BASE + 0x1f,
551 .flags = IORESOURCE_MEM,
552 }, {
Riku Voipio69359942009-03-03 21:13:50 +0200553 .start = IRQ_MV78XX0_I2C_0,
554 .end = IRQ_MV78XX0_I2C_0,
555 .flags = IORESOURCE_IRQ,
556 },
557};
558
559
560static struct platform_device mv78xx0_i2c_0 = {
561 .name = MV64XXX_I2C_CTLR_NAME,
562 .id = 0,
563 .num_resources = ARRAY_SIZE(mv78xx0_i2c_0_resources),
564 .resource = mv78xx0_i2c_0_resources,
565 .dev = {
566 .platform_data = &mv78xx0_i2c_0_pdata,
567 },
568};
569
570/*****************************************************************************
571 * I2C bus 1
572 ****************************************************************************/
573
574static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
575 .freq_m = 8, /* assumes 166 MHz TCLK */
576 .freq_n = 3,
577 .timeout = 1000, /* Default timeout of 1 second */
578};
579
580static struct resource mv78xx0_i2c_1_resources[] = {
581 {
Riku Voipio69359942009-03-03 21:13:50 +0200582 .start = I2C_1_PHYS_BASE,
583 .end = I2C_1_PHYS_BASE + 0x1f,
584 .flags = IORESOURCE_MEM,
585 }, {
Riku Voipio69359942009-03-03 21:13:50 +0200586 .start = IRQ_MV78XX0_I2C_1,
587 .end = IRQ_MV78XX0_I2C_1,
588 .flags = IORESOURCE_IRQ,
589 },
590};
591
592
593static struct platform_device mv78xx0_i2c_1 = {
594 .name = MV64XXX_I2C_CTLR_NAME,
595 .id = 1,
596 .num_resources = ARRAY_SIZE(mv78xx0_i2c_1_resources),
597 .resource = mv78xx0_i2c_1_resources,
598 .dev = {
599 .platform_data = &mv78xx0_i2c_1_pdata,
600 },
601};
602
603void __init mv78xx0_i2c_init(void)
604{
605 platform_device_register(&mv78xx0_i2c_0);
606 platform_device_register(&mv78xx0_i2c_1);
607}
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200608
609/*****************************************************************************
610 * SATA
611 ****************************************************************************/
612static struct resource mv78xx0_sata_resources[] = {
613 {
614 .name = "sata base",
615 .start = SATA_PHYS_BASE,
616 .end = SATA_PHYS_BASE + 0x5000 - 1,
617 .flags = IORESOURCE_MEM,
618 }, {
619 .name = "sata irq",
620 .start = IRQ_MV78XX0_SATA,
621 .end = IRQ_MV78XX0_SATA,
622 .flags = IORESOURCE_IRQ,
623 },
624};
625
626static struct platform_device mv78xx0_sata = {
627 .name = "sata_mv",
628 .id = 0,
629 .dev = {
Andrew Lunn5c602552011-05-15 13:32:40 +0200630 .coherent_dma_mask = DMA_BIT_MASK(32),
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200631 },
632 .num_resources = ARRAY_SIZE(mv78xx0_sata_resources),
633 .resource = mv78xx0_sata_resources,
634};
635
636void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
637{
638 sata_data->dram = &mv78xx0_mbus_dram_info;
639 mv78xx0_sata.dev.platform_data = sata_data;
640 platform_device_register(&mv78xx0_sata);
641}
642
643
644/*****************************************************************************
645 * UART0
646 ****************************************************************************/
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200647void __init mv78xx0_uart0_init(void)
648{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200649 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
650 IRQ_MV78XX0_UART_0, get_tclk());
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200651}
652
653
654/*****************************************************************************
655 * UART1
656 ****************************************************************************/
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200657void __init mv78xx0_uart1_init(void)
658{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200659 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
660 IRQ_MV78XX0_UART_1, get_tclk());
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200661}
662
663
664/*****************************************************************************
665 * UART2
666 ****************************************************************************/
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200667void __init mv78xx0_uart2_init(void)
668{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200669 orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
670 IRQ_MV78XX0_UART_2, get_tclk());
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200671}
672
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200673/*****************************************************************************
674 * UART3
675 ****************************************************************************/
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200676void __init mv78xx0_uart3_init(void)
677{
Andrew Lunn28a2b452011-05-15 13:32:41 +0200678 orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
679 IRQ_MV78XX0_UART_3, get_tclk());
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200680}
681
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200682/*****************************************************************************
683 * Time handling
684 ****************************************************************************/
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200685void __init mv78xx0_init_early(void)
686{
687 orion_time_set_base(TIMER_VIRT_BASE);
688}
689
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200690static void mv78xx0_timer_init(void)
691{
Lennert Buytenhek4ee1f6b2010-10-15 16:50:26 +0200692 orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
693 IRQ_MV78XX0_TIMER_1, get_tclk());
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200694}
695
696struct sys_timer mv78xx0_timer = {
697 .init = mv78xx0_timer_init,
698};
699
700
701/*****************************************************************************
702 * General
703 ****************************************************************************/
Lennert Buytenhekcfdeb632009-02-20 02:31:35 +0100704static char * __init mv78xx0_id(void)
705{
706 u32 dev, rev;
707
708 mv78xx0_pcie_id(&dev, &rev);
709
710 if (dev == MV78X00_Z0_DEV_ID) {
711 if (rev == MV78X00_REV_Z0)
712 return "MV78X00-Z0";
713 else
714 return "MV78X00-Rev-Unsupported";
715 } else if (dev == MV78100_DEV_ID) {
716 if (rev == MV78100_REV_A0)
717 return "MV78100-A0";
Lennert Buytenhek662aece2009-09-30 13:02:42 -0700718 else if (rev == MV78100_REV_A1)
719 return "MV78100-A1";
Lennert Buytenhekcfdeb632009-02-20 02:31:35 +0100720 else
721 return "MV78100-Rev-Unsupported";
722 } else if (dev == MV78200_DEV_ID) {
723 if (rev == MV78100_REV_A0)
724 return "MV78200-A0";
725 else
726 return "MV78200-Rev-Unsupported";
727 } else {
728 return "Device-Unknown";
729 }
730}
731
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200732static int __init is_l2_writethrough(void)
733{
734 return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
735}
736
737void __init mv78xx0_init(void)
738{
739 int core_index;
740 int hclk;
741 int pclk;
742 int l2clk;
743 int tclk;
744
745 core_index = mv78xx0_core_index();
746 hclk = get_hclk();
747 get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
748 tclk = get_tclk();
749
Lennert Buytenhekcfdeb632009-02-20 02:31:35 +0100750 printk(KERN_INFO "%s ", mv78xx0_id());
751 printk("core #%d, ", core_index);
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200752 printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
753 printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
754 printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
755 printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
756
757 mv78xx0_setup_cpu_mbus();
758
759#ifdef CONFIG_CACHE_FEROCEON_L2
760 feroceon_l2_init(is_l2_writethrough());
761#endif
762
763 mv78xx0_ge00_shared_data.t_clk = tclk;
764 mv78xx0_ge01_shared_data.t_clk = tclk;
765 mv78xx0_ge10_shared_data.t_clk = tclk;
766 mv78xx0_ge11_shared_data.t_clk = tclk;
Stanislav Samsonov794d15b2008-06-22 22:45:10 +0200767}