]>
Commit | Line | Data |
---|---|---|
b318262a SR |
1 | /* |
2 | * (C) Copyright 2001-2003 | |
3 | * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | #include <asm/processor.h> | |
bd84ee4c | 26 | #include <asm/io.h> |
b318262a SR |
27 | #include <command.h> |
28 | #include <malloc.h> | |
29 | ||
b318262a SR |
30 | |
31 | #if 0 | |
32 | #define FPGA_DEBUG | |
33 | #endif | |
34 | ||
bd84ee4c MF |
35 | DECLARE_GLOBAL_DATA_PTR; |
36 | ||
b318262a | 37 | extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
12537cc5 | 38 | extern void lxt971_no_sleep(void); |
b318262a SR |
39 | |
40 | /* fpga configuration data - gzip compressed and generated by bin2c */ | |
41 | const unsigned char fpgadata[] = | |
42 | { | |
43 | #include "fpgadata.c" | |
44 | }; | |
45 | ||
46 | /* | |
47 | * include common fpga code (for esd boards) | |
48 | */ | |
49 | #include "../common/fpga.c" | |
50 | ||
51 | ||
12537cc5 SR |
52 | /* |
53 | * include common auto-update code (for esd boards) | |
54 | */ | |
55 | #include "../common/auto_update.h" | |
56 | ||
57 | au_image_t au_image[] = { | |
58 | {"plu405/preinst.img", 0, -1, AU_SCRIPT}, | |
59 | {"plu405/u-boot.img", 0xfffc0000, 0x00040000, AU_FIRMWARE}, | |
fe126d8b | 60 | {"plu405/pImage_${bd_type}", 0x00000000, 0x00100000, AU_NAND}, |
12537cc5 SR |
61 | {"plu405/pImage.initrd", 0x00100000, 0x00200000, AU_NAND}, |
62 | {"plu405/yaffsmt2.img", 0x00300000, 0x01c00000, AU_NAND}, | |
63 | {"plu405/postinst.img", 0, 0, AU_SCRIPT}, | |
64 | }; | |
65 | ||
66 | int N_AU_IMAGES = (sizeof(au_image) / sizeof(au_image[0])); | |
67 | ||
b318262a | 68 | /* Prototypes */ |
eedcd078 | 69 | int gunzip(void *, int, unsigned char *, unsigned long *); |
b318262a | 70 | |
c837dcb1 | 71 | int board_early_init_f (void) |
b318262a SR |
72 | { |
73 | /* | |
74 | * IRQ 0-15 405GP internally generated; active high; level sensitive | |
75 | * IRQ 16 405GP internally generated; active low; level sensitive | |
76 | * IRQ 17-24 RESERVED | |
77 | * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive | |
78 | * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive | |
79 | * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive | |
80 | * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive | |
81 | * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive | |
82 | * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive | |
83 | * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive | |
84 | */ | |
85 | mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ | |
86 | mtdcr(uicer, 0x00000000); /* disable all ints */ | |
87 | mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ | |
88 | mtdcr(uicpr, 0xFFFFFF99); /* set int polarities */ | |
89 | mtdcr(uictr, 0x10000000); /* set int trigger levels */ | |
40e43e3b | 90 | mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest prio */ |
b318262a SR |
91 | mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ |
92 | ||
93 | /* | |
40e43e3b MF |
94 | * EBC Configuration Register: set ready timeout to |
95 | * 512 ebc-clks -> ca. 15 us | |
b318262a SR |
96 | */ |
97 | mtebc (epcr, 0xa8400000); /* ebc always driven */ | |
98 | ||
99 | return 0; | |
100 | } | |
101 | ||
b318262a SR |
102 | int misc_init_r (void) |
103 | { | |
f6e0f1f6 MF |
104 | unsigned char *duart0_mcr = (unsigned char *)((ulong)DUART0_BA + 4); |
105 | unsigned char *duart1_mcr = (unsigned char *)((ulong)DUART1_BA + 4); | |
b318262a SR |
106 | unsigned char *dst; |
107 | ulong len = sizeof(fpgadata); | |
108 | int status; | |
109 | int index; | |
110 | int i; | |
111 | ||
bd84ee4c MF |
112 | /* adjust flash start and offset */ |
113 | gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; | |
114 | gd->bd->bi_flashoffset = 0; | |
115 | ||
6d0f6bcf JCPV |
116 | dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE); |
117 | if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) { | |
b318262a SR |
118 | printf ("GUNZIP ERROR - must RESET board to recover\n"); |
119 | do_reset (NULL, 0, 0, NULL); | |
120 | } | |
121 | ||
122 | status = fpga_boot(dst, len); | |
123 | if (status != 0) { | |
124 | printf("\nFPGA: Booting failed "); | |
125 | switch (status) { | |
126 | case ERROR_FPGA_PRG_INIT_LOW: | |
40e43e3b MF |
127 | printf("(Timeout: INIT not low " |
128 | "after asserting PROGRAM*)\n"); | |
b318262a SR |
129 | break; |
130 | case ERROR_FPGA_PRG_INIT_HIGH: | |
40e43e3b MF |
131 | printf("(Timeout: INIT not high " |
132 | "after deasserting PROGRAM*)\n"); | |
b318262a SR |
133 | break; |
134 | case ERROR_FPGA_PRG_DONE: | |
40e43e3b MF |
135 | printf("(Timeout: DONE not high " |
136 | "after programming FPGA)\n"); | |
b318262a SR |
137 | break; |
138 | } | |
139 | ||
140 | /* display infos on fpgaimage */ | |
141 | index = 15; | |
142 | for (i=0; i<4; i++) { | |
143 | len = dst[index]; | |
144 | printf("FPGA: %s\n", &(dst[index+1])); | |
145 | index += len+3; | |
146 | } | |
147 | putc ('\n'); | |
148 | /* delayed reboot */ | |
149 | for (i=20; i>0; i--) { | |
150 | printf("Rebooting in %2d seconds \r",i); | |
151 | for (index=0;index<1000;index++) | |
152 | udelay(1000); | |
153 | } | |
154 | putc ('\n'); | |
155 | do_reset(NULL, 0, 0, NULL); | |
156 | } | |
157 | ||
158 | puts("FPGA: "); | |
159 | ||
160 | /* display infos on fpgaimage */ | |
161 | index = 15; | |
162 | for (i=0; i<4; i++) { | |
163 | len = dst[index]; | |
164 | printf("%s ", &(dst[index+1])); | |
165 | index += len+3; | |
166 | } | |
167 | putc ('\n'); | |
168 | ||
169 | free(dst); | |
170 | ||
171 | /* | |
172 | * Reset FPGA via FPGA_DATA pin | |
173 | */ | |
174 | SET_FPGA(FPGA_PRG | FPGA_CLK); | |
175 | udelay(1000); /* wait 1ms */ | |
176 | SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); | |
177 | udelay(1000); /* wait 1ms */ | |
178 | ||
179 | /* | |
180 | * Reset external DUARTs | |
181 | */ | |
6d0f6bcf | 182 | out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_DUART_RST); |
40e43e3b | 183 | udelay(10); |
6d0f6bcf | 184 | out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_DUART_RST); |
40e43e3b | 185 | udelay(1000); |
b318262a | 186 | |
f6e0f1f6 MF |
187 | /* |
188 | * Set NAND-FLASH GPIO signals to default | |
189 | */ | |
40e43e3b | 190 | out_be32((void*)GPIO0_OR, |
6d0f6bcf JCPV |
191 | in_be32((void*)GPIO0_OR) & ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE)); |
192 | out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_NAND_CE); | |
f6e0f1f6 MF |
193 | |
194 | /* | |
195 | * Setup EEPROM write protection | |
196 | */ | |
6d0f6bcf JCPV |
197 | out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_EEPROM_WP); |
198 | out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) | CONFIG_SYS_EEPROM_WP); | |
f6e0f1f6 | 199 | |
b318262a SR |
200 | /* |
201 | * Enable interrupts in exar duart mcr[3] | |
202 | */ | |
f6e0f1f6 MF |
203 | out_8(duart0_mcr, 0x08); |
204 | out_8(duart1_mcr, 0x08); | |
b318262a SR |
205 | |
206 | return (0); | |
207 | } | |
208 | ||
b318262a SR |
209 | /* |
210 | * Check Board Identity: | |
211 | */ | |
b318262a SR |
212 | int checkboard (void) |
213 | { | |
77ddac94 | 214 | char str[64]; |
b318262a SR |
215 | int i = getenv_r ("serial#", str, sizeof(str)); |
216 | ||
217 | puts ("Board: "); | |
218 | ||
219 | if (i == -1) { | |
220 | puts ("### No HW ID - assuming PLU405"); | |
221 | } else { | |
222 | puts(str); | |
223 | } | |
224 | ||
225 | putc ('\n'); | |
b318262a SR |
226 | return 0; |
227 | } | |
228 | ||
b318262a SR |
229 | #ifdef CONFIG_IDE_RESET |
230 | void ide_set_reset(int on) | |
231 | { | |
232 | volatile unsigned short *fpga_mode = | |
6d0f6bcf | 233 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL); |
b318262a SR |
234 | |
235 | /* | |
236 | * Assert or deassert CompactFlash Reset Pin | |
237 | */ | |
238 | if (on) { /* assert RESET */ | |
6d0f6bcf | 239 | *fpga_mode &= ~(CONFIG_SYS_FPGA_CTRL_CF_RESET); |
b318262a | 240 | } else { /* release RESET */ |
6d0f6bcf | 241 | *fpga_mode |= CONFIG_SYS_FPGA_CTRL_CF_RESET; |
b318262a SR |
242 | } |
243 | } | |
244 | #endif /* CONFIG_IDE_RESET */ | |
245 | ||
f9fc6a58 MF |
246 | void reset_phy(void) |
247 | { | |
248 | #ifdef CONFIG_LXT971_NO_SLEEP | |
249 | ||
250 | /* | |
251 | * Disable sleep mode in LXT971 | |
252 | */ | |
253 | lxt971_no_sleep(); | |
254 | #endif | |
255 | } | |
f6e0f1f6 | 256 | |
6d0f6bcf | 257 | #if defined(CONFIG_SYS_EEPROM_WREN) |
f6e0f1f6 MF |
258 | /* Input: <dev_addr> I2C address of EEPROM device to enable. |
259 | * <state> -1: deliver current state | |
260 | * 0: disable write | |
261 | * 1: enable write | |
262 | * Returns: -1: wrong device address | |
263 | * 0: dis-/en- able done | |
264 | * 0/1: current state if <state> was -1. | |
265 | */ | |
266 | int eeprom_write_enable (unsigned dev_addr, int state) | |
267 | { | |
6d0f6bcf | 268 | if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) { |
f6e0f1f6 MF |
269 | return -1; |
270 | } else { | |
271 | switch (state) { | |
272 | case 1: | |
273 | /* Enable write access, clear bit GPIO0. */ | |
40e43e3b | 274 | out_be32((void*)GPIO0_OR, |
6d0f6bcf | 275 | in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_EEPROM_WP); |
f6e0f1f6 MF |
276 | state = 0; |
277 | break; | |
278 | case 0: | |
279 | /* Disable write access, set bit GPIO0. */ | |
40e43e3b | 280 | out_be32((void*)GPIO0_OR, |
6d0f6bcf | 281 | in_be32((void*)GPIO0_OR) | CONFIG_SYS_EEPROM_WP); |
f6e0f1f6 MF |
282 | state = 0; |
283 | break; | |
284 | default: | |
285 | /* Read current status back. */ | |
40e43e3b | 286 | state = (0 == (in_be32((void*)GPIO0_OR) & |
6d0f6bcf | 287 | CONFIG_SYS_EEPROM_WP)); |
f6e0f1f6 MF |
288 | break; |
289 | } | |
290 | } | |
291 | return state; | |
292 | } | |
293 | ||
294 | int do_eep_wren (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
295 | { | |
296 | int query = argc == 1; | |
297 | int state = 0; | |
298 | ||
299 | if (query) { | |
300 | /* Query write access state. */ | |
6d0f6bcf | 301 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, -1); |
f6e0f1f6 MF |
302 | if (state < 0) { |
303 | puts ("Query of write access state failed.\n"); | |
304 | } else { | |
305 | printf ("Write access for device 0x%0x is %sabled.\n", | |
6d0f6bcf | 306 | CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis"); |
f6e0f1f6 MF |
307 | state = 0; |
308 | } | |
309 | } else { | |
310 | if ('0' == argv[1][0]) { | |
311 | /* Disable write access. */ | |
6d0f6bcf | 312 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 0); |
f6e0f1f6 MF |
313 | } else { |
314 | /* Enable write access. */ | |
6d0f6bcf | 315 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 1); |
f6e0f1f6 MF |
316 | } |
317 | if (state < 0) { | |
318 | puts ("Setup of write access state failed.\n"); | |
319 | } | |
320 | } | |
321 | ||
322 | return state; | |
323 | } | |
324 | ||
325 | U_BOOT_CMD(eepwren, 2, 0, do_eep_wren, | |
326 | "eepwren - Enable / disable / query EEPROM write access\n", | |
327 | NULL); | |
6d0f6bcf | 328 | #endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */ |