aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/momentum/ocelot_c/Makefile2
-rw-r--r--arch/mips/momentum/ocelot_c/platform.c201
-rw-r--r--arch/mips/momentum/ocelot_c/prom.c58
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c121
4 files changed, 202 insertions, 180 deletions
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
index 94802b4db472..d69161aa1675 100644
--- a/arch/mips/momentum/ocelot_c/Makefile
+++ b/arch/mips/momentum/ocelot_c/Makefile
@@ -2,7 +2,7 @@
2# Makefile for Momentum Computer's Ocelot-C and -CS boards. 2# Makefile for Momentum Computer's Ocelot-C and -CS boards.
3# 3#
4 4
5obj-y += cpci-irq.o irq.o prom.o reset.o \ 5obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \
6 setup.o uart-irq.o 6 setup.o uart-irq.o
7 7
8obj-$(CONFIG_KGDB) += dbg_io.o 8obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
new file mode 100644
index 000000000000..6c495b2f1560
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -0,0 +1,201 @@
1#include <linux/delay.h>
2#include <linux/if_ether.h>
3#include <linux/ioport.h>
4#include <linux/mv643xx.h>
5#include <linux/platform_device.h>
6
7#include "ocelot_c_fpga.h"
8
9#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
10
11static struct resource mv643xx_eth_shared_resources[] = {
12 [0] = {
13 .name = "ethernet shared base",
14 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
15 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
16 MV643XX_ETH_SHARED_REGS_SIZE - 1,
17 .flags = IORESOURCE_MEM,
18 },
19};
20
21static struct platform_device mv643xx_eth_shared_device = {
22 .name = MV643XX_ETH_SHARED_NAME,
23 .id = 0,
24 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
25 .resource = mv643xx_eth_shared_resources,
26};
27
28#define MV_SRAM_BASE 0xfe000000UL
29#define MV_SRAM_SIZE (256 * 1024)
30
31#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
32#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
33
34#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
35#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
36
37#define MV64x60_IRQ_ETH_0 48
38#define MV64x60_IRQ_ETH_1 49
39
40#ifdef CONFIG_MV643XX_ETH_0
41
42static struct resource mv64x60_eth0_resources[] = {
43 [0] = {
44 .name = "eth0 irq",
45 .start = MV64x60_IRQ_ETH_0,
46 .end = MV64x60_IRQ_ETH_0,
47 .flags = IORESOURCE_IRQ,
48 },
49};
50
51static char eth0_mac_addr[ETH_ALEN];
52
53static struct mv643xx_eth_platform_data eth0_pd = {
54 .mac_addr = eth0_mac_addr,
55
56 .tx_sram_addr = MV_SRAM_BASE_ETH0,
57 .tx_sram_size = MV_SRAM_TXRING_SIZE,
58 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
59
60 .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
61 .rx_sram_size = MV_SRAM_RXRING_SIZE,
62 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
63};
64
65static struct platform_device eth0_device = {
66 .name = MV643XX_ETH_NAME,
67 .id = 0,
68 .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
69 .resource = mv64x60_eth0_resources,
70 .dev = {
71 .platform_data = &eth0_pd,
72 },
73};
74#endif /* CONFIG_MV643XX_ETH_0 */
75
76#ifdef CONFIG_MV643XX_ETH_1
77
78static struct resource mv64x60_eth1_resources[] = {
79 [0] = {
80 .name = "eth1 irq",
81 .start = MV64x60_IRQ_ETH_1,
82 .end = MV64x60_IRQ_ETH_1,
83 .flags = IORESOURCE_IRQ,
84 },
85};
86
87static char eth1_mac_addr[ETH_ALEN];
88
89static struct mv643xx_eth_platform_data eth1_pd = {
90 .mac_addr = eth1_mac_addr,
91
92 .tx_sram_addr = MV_SRAM_BASE_ETH1,
93 .tx_sram_size = MV_SRAM_TXRING_SIZE,
94 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
95
96 .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
97 .rx_sram_size = MV_SRAM_RXRING_SIZE,
98 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
99};
100
101static struct platform_device eth1_device = {
102 .name = MV643XX_ETH_NAME,
103 .id = 1,
104 .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
105 .resource = mv64x60_eth1_resources,
106 .dev = {
107 .platform_data = &eth1_pd,
108 },
109};
110#endif /* CONFIG_MV643XX_ETH_1 */
111
112static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
113 &mv643xx_eth_shared_device,
114#ifdef CONFIG_MV643XX_ETH_0
115 &eth0_device,
116#endif
117#ifdef CONFIG_MV643XX_ETH_1
118 &eth1_device,
119#endif
120 /* The third port is not wired up on the Ocelot C */
121};
122
123static u8 __init exchange_bit(u8 val, u8 cs)
124{
125 /* place the data */
126 OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
127 udelay(1);
128
129 /* turn the clock on */
130 OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
131 udelay(1);
132
133 /* turn the clock off and read-strobe */
134 OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
135
136 /* return the data */
137 return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
138}
139
140static void __init get_mac(char dest[6])
141{
142 u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
143 int i,j;
144
145 for (i = 0; i < 12; i++)
146 exchange_bit(read_opcode[i], 1);
147
148 for (j = 0; j < 6; j++) {
149 dest[j] = 0;
150 for (i = 0; i < 8; i++) {
151 dest[j] <<= 1;
152 dest[j] |= exchange_bit(0, 1);
153 }
154 }
155
156 /* turn off CS */
157 exchange_bit(0,0);
158}
159
160/*
161 * Copy and increment ethernet MAC address by a small value.
162 *
163 * This is useful for systems where the only one MAC address is stored in
164 * non-volatile memory for multiple ports.
165 */
166static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
167 unsigned int add)
168{
169 int i;
170
171 BUG_ON(add >= 256);
172
173 for (i = ETH_ALEN; i >= 0; i--) {
174 dst[i] = src[i] + add;
175 add = dst[i] < src[i]; /* compute carry */
176 }
177
178 WARN_ON(add);
179}
180
181static int __init mv643xx_eth_add_pds(void)
182{
183 unsigned char mac[ETH_ALEN];
184 int ret;
185
186 get_mac(mac);
187#ifdef CONFIG_MV643XX_ETH_0
188 eth_mac_add(eth1_mac_addr, mac, 0);
189#endif
190#ifdef CONFIG_MV643XX_ETH_1
191 eth_mac_add(eth1_mac_addr, mac, 1);
192#endif
193 ret = platform_add_devices(mv643xx_eth_pd_devs,
194 ARRAY_SIZE(mv643xx_eth_pd_devs));
195
196 return ret;
197}
198
199device_initcall(mv643xx_eth_add_pds);
200
201#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c
index 1f67728d6a49..d0b77e101d74 100644
--- a/arch/mips/momentum/ocelot_c/prom.c
+++ b/arch/mips/momentum/ocelot_c/prom.c
@@ -31,10 +31,6 @@ struct callvectors* debug_vectors;
31extern unsigned long marvell_base; 31extern unsigned long marvell_base;
32extern unsigned int cpu_clock; 32extern unsigned int cpu_clock;
33 33
34#ifdef CONFIG_MV643XX_ETH
35extern unsigned char prom_mac_addr_base[6];
36#endif
37
38const char *get_system_type(void) 34const char *get_system_type(void)
39{ 35{
40#ifdef CONFIG_CPU_SR71000 36#ifdef CONFIG_CPU_SR71000
@@ -44,55 +40,6 @@ const char *get_system_type(void)
44#endif 40#endif
45} 41}
46 42
47#ifdef CONFIG_MV643XX_ETH
48static void burn_clocks(void)
49{
50 int i;
51
52 /* this loop should burn at least 1us -- this should be plenty */
53 for (i = 0; i < 0x10000; i++)
54 ;
55}
56
57static u8 exchange_bit(u8 val, u8 cs)
58{
59 /* place the data */
60 OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
61 burn_clocks();
62
63 /* turn the clock on */
64 OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
65 burn_clocks();
66
67 /* turn the clock off and read-strobe */
68 OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
69
70 /* return the data */
71 return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
72}
73
74void get_mac(char dest[6])
75{
76 u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
77 int i,j;
78
79 for (i = 0; i < 12; i++)
80 exchange_bit(read_opcode[i], 1);
81
82 for (j = 0; j < 6; j++) {
83 dest[j] = 0;
84 for (i = 0; i < 8; i++) {
85 dest[j] <<= 1;
86 dest[j] |= exchange_bit(0, 1);
87 }
88 }
89
90 /* turn off CS */
91 exchange_bit(0,0);
92}
93#endif
94
95
96#ifdef CONFIG_64BIT 43#ifdef CONFIG_64BIT
97 44
98unsigned long signext(unsigned long addr) 45unsigned long signext(unsigned long addr)
@@ -226,11 +173,6 @@ void __init prom_init(void)
226 mips_machgroup = MACH_GROUP_MOMENCO; 173 mips_machgroup = MACH_GROUP_MOMENCO;
227 mips_machtype = MACH_MOMENCO_OCELOT_C; 174 mips_machtype = MACH_MOMENCO_OCELOT_C;
228 175
229#ifdef CONFIG_MV643XX_ETH
230 /* get the base MAC address for on-board ethernet ports */
231 get_mac(prom_mac_addr_base);
232#endif
233
234#ifndef CONFIG_64BIT 176#ifndef CONFIG_64BIT
235 debug_vectors->printf("Booting Linux kernel...\n"); 177 debug_vectors->printf("Booting Linux kernel...\n");
236#endif 178#endif
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index b0e82a097f7e..0b6b2338cfb4 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -50,7 +50,6 @@
50#include <linux/sched.h> 50#include <linux/sched.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/pci.h> 52#include <linux/pci.h>
53#include <linux/platform_device.h>
54#include <linux/pm.h> 53#include <linux/pm.h>
55#include <linux/timex.h> 54#include <linux/timex.h>
56#include <linux/vmalloc.h> 55#include <linux/vmalloc.h>
@@ -361,123 +360,3 @@ static int io_base_ioremap(void)
361} 360}
362 361
363module_init(io_base_ioremap); 362module_init(io_base_ioremap);
364
365#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
366
367static struct resource mv643xx_eth_shared_resources[] = {
368 [0] = {
369 .name = "ethernet shared base",
370 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
371 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
372 MV643XX_ETH_SHARED_REGS_SIZE - 1,
373 .flags = IORESOURCE_MEM,
374 },
375};
376
377static struct platform_device mv643xx_eth_shared_device = {
378 .name = MV643XX_ETH_SHARED_NAME,
379 .id = 0,
380 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
381 .resource = mv643xx_eth_shared_resources,
382};
383
384#define MV_SRAM_BASE 0xfe000000UL
385#define MV_SRAM_SIZE (256 * 1024)
386
387#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
388#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
389
390#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
391#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
392
393#define MV64x60_IRQ_ETH_0 48
394#define MV64x60_IRQ_ETH_1 49
395
396#ifdef CONFIG_MV643XX_ETH_0
397
398static struct resource mv64x60_eth0_resources[] = {
399 [0] = {
400 .name = "eth0 irq",
401 .start = MV64x60_IRQ_ETH_0,
402 .end = MV64x60_IRQ_ETH_0,
403 .flags = IORESOURCE_IRQ,
404 },
405};
406
407static struct mv643xx_eth_platform_data eth0_pd = {
408 .tx_sram_addr = MV_SRAM_BASE_ETH0,
409 .tx_sram_size = MV_SRAM_TXRING_SIZE,
410 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
411
412 .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
413 .rx_sram_size = MV_SRAM_RXRING_SIZE,
414 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
415};
416
417static struct platform_device eth0_device = {
418 .name = MV643XX_ETH_NAME,
419 .id = 0,
420 .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
421 .resource = mv64x60_eth0_resources,
422 .dev = {
423 .platform_data = &eth0_pd,
424 },
425};
426#endif /* CONFIG_MV643XX_ETH_0 */
427
428#ifdef CONFIG_MV643XX_ETH_1
429
430static struct resource mv64x60_eth1_resources[] = {
431 [0] = {
432 .name = "eth1 irq",
433 .start = MV64x60_IRQ_ETH_1,
434 .end = MV64x60_IRQ_ETH_1,
435 .flags = IORESOURCE_IRQ,
436 },
437};
438
439static struct mv643xx_eth_platform_data eth1_pd = {
440 .tx_sram_addr = MV_SRAM_BASE_ETH1,
441 .tx_sram_size = MV_SRAM_TXRING_SIZE,
442 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
443
444 .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
445 .rx_sram_size = MV_SRAM_RXRING_SIZE,
446 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
447};
448
449static struct platform_device eth1_device = {
450 .name = MV643XX_ETH_NAME,
451 .id = 1,
452 .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
453 .resource = mv64x60_eth1_resources,
454 .dev = {
455 .platform_data = &eth1_pd,
456 },
457};
458#endif /* CONFIG_MV643XX_ETH_1 */
459
460static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
461 &mv643xx_eth_shared_device,
462#ifdef CONFIG_MV643XX_ETH_0
463 &eth0_device,
464#endif
465#ifdef CONFIG_MV643XX_ETH_1
466 &eth1_device,
467#endif
468 /* The third port is not wired up on the Ocelot C */
469};
470
471int mv643xx_eth_add_pds(void)
472{
473 int ret;
474
475 ret = platform_add_devices(mv643xx_eth_pd_devs,
476 ARRAY_SIZE(mv643xx_eth_pd_devs));
477
478 return ret;
479}
480
481device_initcall(mv643xx_eth_add_pds);
482
483#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */