]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
fa6667fe GU |
2 | /***************************************************************************/ |
3 | ||
4 | /* | |
5 | * nettel.c -- startup code support for the NETtel boards | |
6 | * | |
7 | * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) | |
8 | */ | |
9 | ||
10 | /***************************************************************************/ | |
11 | ||
12 | #include <linux/kernel.h> | |
13 | #include <linux/param.h> | |
14 | #include <linux/init.h> | |
15 | #include <linux/io.h> | |
16 | #include <linux/platform_device.h> | |
17 | #include <asm/coldfire.h> | |
18 | #include <asm/mcfsim.h> | |
19 | #include <asm/nettel.h> | |
20 | ||
21 | /***************************************************************************/ | |
22 | ||
23 | /* | |
24 | * Define the IO and interrupt resources of the 2 SMC9196 interfaces. | |
25 | */ | |
26 | #define NETTEL_SMC0_ADDR 0x30600300 | |
27 | #define NETTEL_SMC0_IRQ 29 | |
28 | ||
29 | #define NETTEL_SMC1_ADDR 0x30600000 | |
30 | #define NETTEL_SMC1_IRQ 27 | |
31 | ||
32 | /* | |
33 | * We need some access into the SMC9196 registers. Define those registers | |
34 | * we will need here (including the smc91x.h doesn't seem to give us these | |
35 | * in a simple form). | |
36 | */ | |
37 | #define SMC91xx_BANKSELECT 14 | |
38 | #define SMC91xx_BASEADDR 2 | |
39 | #define SMC91xx_BASEMAC 4 | |
40 | ||
41 | /***************************************************************************/ | |
42 | ||
43 | static struct resource nettel_smc91x_0_resources[] = { | |
44 | { | |
45 | .start = NETTEL_SMC0_ADDR, | |
46 | .end = NETTEL_SMC0_ADDR + 0x20, | |
47 | .flags = IORESOURCE_MEM, | |
48 | }, | |
49 | { | |
50 | .start = NETTEL_SMC0_IRQ, | |
51 | .end = NETTEL_SMC0_IRQ, | |
52 | .flags = IORESOURCE_IRQ, | |
53 | }, | |
54 | }; | |
55 | ||
56 | static struct resource nettel_smc91x_1_resources[] = { | |
57 | { | |
58 | .start = NETTEL_SMC1_ADDR, | |
59 | .end = NETTEL_SMC1_ADDR + 0x20, | |
60 | .flags = IORESOURCE_MEM, | |
61 | }, | |
62 | { | |
63 | .start = NETTEL_SMC1_IRQ, | |
64 | .end = NETTEL_SMC1_IRQ, | |
65 | .flags = IORESOURCE_IRQ, | |
66 | }, | |
67 | }; | |
68 | ||
69 | static struct platform_device nettel_smc91x[] = { | |
70 | { | |
71 | .name = "smc91x", | |
72 | .id = 0, | |
73 | .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources), | |
74 | .resource = nettel_smc91x_0_resources, | |
75 | }, | |
76 | { | |
77 | .name = "smc91x", | |
78 | .id = 1, | |
79 | .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources), | |
80 | .resource = nettel_smc91x_1_resources, | |
81 | }, | |
82 | }; | |
83 | ||
84 | static struct platform_device *nettel_devices[] __initdata = { | |
85 | &nettel_smc91x[0], | |
86 | &nettel_smc91x[1], | |
87 | }; | |
88 | ||
89 | /***************************************************************************/ | |
90 | ||
91 | static u8 nettel_macdefault[] __initdata = { | |
92 | 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01, | |
93 | }; | |
94 | ||
95 | /* | |
96 | * Set flash contained MAC address into SMC9196 core. Make sure the flash | |
97 | * MAC address is sane, and not an empty flash. If no good use the Moreton | |
98 | * Bay default MAC address instead. | |
99 | */ | |
100 | ||
101 | static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr) | |
102 | { | |
103 | u16 *macp; | |
104 | ||
105 | macp = (u16 *) flashaddr; | |
106 | if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff)) | |
107 | macp = (u16 *) &nettel_macdefault[0]; | |
108 | ||
109 | writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); | |
110 | writew(macp[0], ioaddr + SMC91xx_BASEMAC); | |
111 | writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2); | |
112 | writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4); | |
113 | } | |
114 | ||
115 | /***************************************************************************/ | |
116 | ||
117 | /* | |
118 | * Re-map the address space of at least one of the SMC ethernet | |
119 | * parts. Both parts power up decoding the same address, so we | |
120 | * need to move one of them first, before doing anything else. | |
121 | */ | |
122 | ||
123 | static void __init nettel_smc91x_init(void) | |
124 | { | |
1419ea3b | 125 | writew(0x00ec, MCFSIM_PADDR); |
fa6667fe GU |
126 | mcf_setppdata(0, 0x0080); |
127 | writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); | |
128 | writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR); | |
129 | mcf_setppdata(0x0080, 0); | |
130 | ||
131 | /* Set correct chip select timing for SMC9196 accesses */ | |
1419ea3b | 132 | writew(0x1180, MCFSIM_CSCR3); |
fa6667fe GU |
133 | |
134 | /* Set the SMC interrupts to be auto-vectored */ | |
135 | mcf_autovector(NETTEL_SMC0_IRQ); | |
136 | mcf_autovector(NETTEL_SMC1_IRQ); | |
137 | ||
138 | /* Set MAC addresses from flash for both interfaces */ | |
139 | nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000); | |
140 | nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006); | |
141 | } | |
142 | ||
143 | /***************************************************************************/ | |
144 | ||
145 | static int __init init_nettel(void) | |
146 | { | |
147 | nettel_smc91x_init(); | |
148 | platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices)); | |
149 | return 0; | |
150 | } | |
151 | ||
152 | arch_initcall(init_nettel); | |
153 | ||
154 | /***************************************************************************/ |