diff options
Diffstat (limited to 'arch/mips/momentum/ocelot_3/prom.c')
-rw-r--r-- | arch/mips/momentum/ocelot_3/prom.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c new file mode 100644 index 000000000000..89c17a0c0bed --- /dev/null +++ b/arch/mips/momentum/ocelot_3/prom.c | |||
@@ -0,0 +1,248 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Louis Hamilton, Red Hat, Inc. | ||
6 | * hamilton@redhat.com [MIPS64 modifications] | ||
7 | * | ||
8 | * Copyright 2004 PMC-Sierra | ||
9 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | ||
10 | * | ||
11 | * Based on Ocelot Linux port, which is | ||
12 | * Copyright 2001 MontaVista Software Inc. | ||
13 | * Author: jsun@mvista.com or jsun@junsun.net | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License as published by the | ||
17 | * Free Software Foundation; either version 2 of the License, or (at your | ||
18 | * option) any later version. | ||
19 | * | ||
20 | * Copyright (C) 2004 MontaVista Software Inc. | ||
21 | * Author: Manish Lachwani, mlachwani@mvista.com | ||
22 | * | ||
23 | */ | ||
24 | #include <linux/config.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/bootmem.h> | ||
27 | #include <linux/mv643xx.h> | ||
28 | |||
29 | #include <asm/addrspace.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/pmon.h> | ||
32 | #include "ocelot_3_fpga.h" | ||
33 | |||
34 | struct callvectors* debug_vectors; | ||
35 | extern unsigned long marvell_base; | ||
36 | extern unsigned long cpu_clock; | ||
37 | |||
38 | #ifdef CONFIG_MV643XX_ETH | ||
39 | extern unsigned char prom_mac_addr_base[6]; | ||
40 | #endif | ||
41 | |||
42 | const char *get_system_type(void) | ||
43 | { | ||
44 | return "Momentum Ocelot-3"; | ||
45 | } | ||
46 | |||
47 | #ifdef CONFIG_MV643XX_ETH | ||
48 | 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 | |||
57 | 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 | |||
74 | void 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_MIPS64 | ||
97 | |||
98 | unsigned long signext(unsigned long addr) | ||
99 | { | ||
100 | addr &= 0xffffffff; | ||
101 | return (unsigned long)((int)addr); | ||
102 | } | ||
103 | |||
104 | void *get_arg(unsigned long args, int arc) | ||
105 | { | ||
106 | unsigned long ul; | ||
107 | unsigned char *puc, uc; | ||
108 | |||
109 | args += (arc * 4); | ||
110 | ul = (unsigned long)signext(args); | ||
111 | puc = (unsigned char *)ul; | ||
112 | if (puc == 0) | ||
113 | return (void *)0; | ||
114 | |||
115 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
116 | uc = *puc++; | ||
117 | ul = (unsigned long)uc; | ||
118 | uc = *puc++; | ||
119 | ul |= (((unsigned long)uc) << 8); | ||
120 | uc = *puc++; | ||
121 | ul |= (((unsigned long)uc) << 16); | ||
122 | uc = *puc++; | ||
123 | ul |= (((unsigned long)uc) << 24); | ||
124 | #else /* CONFIG_CPU_LITTLE_ENDIAN */ | ||
125 | uc = *puc++; | ||
126 | ul = ((unsigned long)uc) << 24; | ||
127 | uc = *puc++; | ||
128 | ul |= (((unsigned long)uc) << 16); | ||
129 | uc = *puc++; | ||
130 | ul |= (((unsigned long)uc) << 8); | ||
131 | uc = *puc++; | ||
132 | ul |= ((unsigned long)uc); | ||
133 | #endif /* CONFIG_CPU_LITTLE_ENDIAN */ | ||
134 | ul = signext(ul); | ||
135 | return (void *)ul; | ||
136 | } | ||
137 | |||
138 | char *arg64(unsigned long addrin, int arg_index) | ||
139 | { | ||
140 | unsigned long args; | ||
141 | char *p; | ||
142 | |||
143 | args = signext(addrin); | ||
144 | p = (char *)get_arg(args, arg_index); | ||
145 | |||
146 | return p; | ||
147 | } | ||
148 | #endif /* CONFIG_MIPS64 */ | ||
149 | |||
150 | void __init prom_init(void) | ||
151 | { | ||
152 | int argc = fw_arg0; | ||
153 | char **arg = (char **) fw_arg1; | ||
154 | char **env = (char **) fw_arg2; | ||
155 | struct callvectors *cv = (struct callvectors *) fw_arg3; | ||
156 | int i; | ||
157 | |||
158 | #ifdef CONFIG_MIPS64 | ||
159 | char *ptr; | ||
160 | printk("prom_init - MIPS64\n"); | ||
161 | |||
162 | /* save the PROM vectors for debugging use */ | ||
163 | debug_vectors = (struct callvectors *)signext((unsigned long)cv); | ||
164 | |||
165 | /* arg[0] is "g", the rest is boot parameters */ | ||
166 | arcs_cmdline[0] = '\0'; | ||
167 | |||
168 | for (i = 1; i < argc; i++) { | ||
169 | ptr = (char *)arg64((unsigned long)arg, i); | ||
170 | if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= | ||
171 | sizeof(arcs_cmdline)) | ||
172 | break; | ||
173 | strcat(arcs_cmdline, ptr); | ||
174 | strcat(arcs_cmdline, " "); | ||
175 | } | ||
176 | i = 0; | ||
177 | |||
178 | while (1) { | ||
179 | ptr = (char *)arg64((unsigned long)env, i); | ||
180 | if (! ptr) | ||
181 | break; | ||
182 | |||
183 | if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { | ||
184 | marvell_base = simple_strtol(ptr + strlen("gtbase="), | ||
185 | NULL, 16); | ||
186 | |||
187 | if ((marvell_base & 0xffffffff00000000) == 0) | ||
188 | marvell_base |= 0xffffffff00000000; | ||
189 | |||
190 | printk("marvell_base set to 0x%016lx\n", marvell_base); | ||
191 | } | ||
192 | if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { | ||
193 | cpu_clock = simple_strtol(ptr + strlen("cpuclock="), | ||
194 | NULL, 10); | ||
195 | printk("cpu_clock set to %d\n", cpu_clock); | ||
196 | } | ||
197 | i++; | ||
198 | } | ||
199 | printk("arcs_cmdline: %s\n", arcs_cmdline); | ||
200 | |||
201 | #else /* CONFIG_MIPS64 */ | ||
202 | |||
203 | /* save the PROM vectors for debugging use */ | ||
204 | debug_vectors = cv; | ||
205 | |||
206 | /* arg[0] is "g", the rest is boot parameters */ | ||
207 | arcs_cmdline[0] = '\0'; | ||
208 | for (i = 1; i < argc; i++) { | ||
209 | if (strlen(arcs_cmdline) + strlen(arg[i] + 1) | ||
210 | >= sizeof(arcs_cmdline)) | ||
211 | break; | ||
212 | strcat(arcs_cmdline, arg[i]); | ||
213 | strcat(arcs_cmdline, " "); | ||
214 | } | ||
215 | |||
216 | while (*env) { | ||
217 | if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { | ||
218 | marvell_base = simple_strtol(*env + strlen("gtbase="), | ||
219 | NULL, 16); | ||
220 | } | ||
221 | if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { | ||
222 | cpu_clock = simple_strtol(*env + strlen("cpuclock="), | ||
223 | NULL, 10); | ||
224 | } | ||
225 | env++; | ||
226 | } | ||
227 | #endif /* CONFIG_MIPS64 */ | ||
228 | |||
229 | mips_machgroup = MACH_GROUP_MOMENCO; | ||
230 | mips_machtype = MACH_MOMENCO_OCELOT_3; | ||
231 | |||
232 | #ifdef CONFIG_MV643XX_ETH | ||
233 | /* get the base MAC address for on-board ethernet ports */ | ||
234 | get_mac(prom_mac_addr_base); | ||
235 | #endif | ||
236 | |||
237 | #ifndef CONFIG_MIPS64 | ||
238 | debug_vectors->printf("Booting Linux kernel...\n"); | ||
239 | #endif | ||
240 | } | ||
241 | |||
242 | void __init prom_free_prom_memory(void) | ||
243 | { | ||
244 | } | ||
245 | |||
246 | void __init prom_fixup_mem_map(unsigned long start, unsigned long end) | ||
247 | { | ||
248 | } | ||