]>
Commit | Line | Data |
---|---|---|
1f54ce6d SR |
1 | /* |
2 | * (C) Copyright 2001-2004 | |
3 | * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com | |
4 | * | |
98f4a3df SR |
5 | * (C) Copyright 2005 |
6 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
7 | * | |
bd84ee4c | 8 | * (C) Copyright 2006-2007 |
48a05a51 SR |
9 | * Matthias Fuchs, esd GmbH, matthias.fuchs@esd-electronics.com |
10 | * | |
1f54ce6d SR |
11 | * See file CREDITS for list of people who contributed to this |
12 | * project. | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU General Public License as | |
16 | * published by the Free Software Foundation; either version 2 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, write to the Free Software | |
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
27 | * MA 02111-1307 USA | |
28 | */ | |
29 | ||
30 | #include <common.h> | |
31 | #include <asm/processor.h> | |
32 | #include <command.h> | |
33 | #include <malloc.h> | |
98f4a3df SR |
34 | #include <pci.h> |
35 | #include <sm501.h> | |
36 | ||
d87080b7 WD |
37 | DECLARE_GLOBAL_DATA_PTR; |
38 | ||
98f4a3df SR |
39 | #ifdef CONFIG_VIDEO_SM501 |
40 | ||
41 | #define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ | |
42 | (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) | |
43 | ||
44 | #ifdef CONFIG_VIDEO_SM501_8BPP | |
45 | #error CONFIG_VIDEO_SM501_8BPP not supported. | |
46 | #endif /* CONFIG_VIDEO_SM501_8BPP */ | |
47 | ||
48 | #ifdef CONFIG_VIDEO_SM501_16BPP | |
49 | #define BPP 16 | |
50 | ||
51 | /* | |
52 | * 800x600 display B084SN03: PCLK = 40MHz | |
53 | * => 2*PCLK = 80MHz | |
54 | * 336/4 = 84MHz | |
55 | * => PCLK = 84MHz | |
56 | */ | |
57 | static const SMI_REGS init_regs_800x600 [] = | |
58 | { | |
59 | #if 1 /* test-only */ | |
60 | {0x0005c, SWAP32(0xffffffff)}, /* set endianess to big endian */ | |
61 | #else | |
62 | {0x0005c, SWAP32(0x00000000)}, /* set endianess to little endian */ | |
63 | #endif | |
64 | {0x00004, SWAP32(0x00000000)}, | |
65 | /* clocks for pm1... */ | |
66 | {0x00048, SWAP32(0x00021807)}, | |
67 | {0x0004C, SWAP32(0x221a0a01)}, | |
68 | {0x00054, SWAP32(0x00000001)}, | |
69 | /* clocks for pm0... */ | |
70 | {0x00040, SWAP32(0x00021807)}, | |
71 | {0x00044, SWAP32(0x221a0a01)}, | |
72 | {0x00054, SWAP32(0x00000000)}, | |
48a05a51 SR |
73 | /* GPIO */ |
74 | {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */ | |
98f4a3df SR |
75 | /* panel control regs... */ |
76 | {0x80000, SWAP32(0x0f013105)}, /* panel display control: 16-bit RGB 5:6:5 mode */ | |
77 | {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */ | |
48a05a51 | 78 | {0x8000C, SWAP32(0x00010000)}, /* panel fb address */ |
98f4a3df SR |
79 | {0x80010, SWAP32(0x06400640)}, /* panel fb offset/window width */ |
80 | {0x80014, SWAP32(0x03200000)}, /* panel fb width (0x320=800) */ | |
81 | {0x80018, SWAP32(0x02580000)}, /* panel fb height (0x258=600) */ | |
82 | {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */ | |
83 | {0x80020, SWAP32(0x02580320)}, /* panel plane br location */ | |
84 | {0x80024, SWAP32(0x041f031f)}, /* panel horizontal total */ | |
85 | {0x80028, SWAP32(0x00800347)}, /* panel horizontal sync */ | |
86 | {0x8002C, SWAP32(0x02730257)}, /* panel vertical total */ | |
87 | {0x80030, SWAP32(0x00040258)}, /* panel vertical sync */ | |
88 | {0x80200, SWAP32(0x00010000)}, /* crt display control */ | |
89 | {0, 0} | |
90 | }; | |
91 | ||
92 | /* | |
93 | * 1024x768 display G150XG02: PCLK = 65MHz | |
94 | * => 2*PCLK = 130MHz | |
95 | * 288/2 = 144MHz | |
96 | * => PCLK = 72MHz | |
97 | */ | |
98 | static const SMI_REGS init_regs_1024x768 [] = | |
99 | { | |
100 | {0x00004, SWAP32(0x00000000)}, | |
101 | /* clocks for pm1... */ | |
102 | {0x00048, SWAP32(0x00021807)}, | |
103 | {0x0004C, SWAP32(0x011a0a01)}, | |
104 | {0x00054, SWAP32(0x00000001)}, | |
105 | /* clocks for pm0... */ | |
106 | {0x00040, SWAP32(0x00021807)}, | |
107 | {0x00044, SWAP32(0x011a0a01)}, | |
108 | {0x00054, SWAP32(0x00000000)}, | |
48a05a51 SR |
109 | /* GPIO */ |
110 | {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */ | |
98f4a3df SR |
111 | /* panel control regs... */ |
112 | {0x80000, SWAP32(0x0f013105)}, /* panel display control: 16-bit RGB 5:6:5 mode */ | |
113 | {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */ | |
48a05a51 | 114 | {0x8000C, SWAP32(0x00010000)}, /* panel fb address */ |
98f4a3df SR |
115 | {0x80010, SWAP32(0x08000800)}, /* panel fb offset/window width */ |
116 | {0x80014, SWAP32(0x04000000)}, /* panel fb width (0x400=1024) */ | |
117 | {0x80018, SWAP32(0x03000000)}, /* panel fb height (0x300=768) */ | |
118 | {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */ | |
119 | {0x80020, SWAP32(0x03000400)}, /* panel plane br location */ | |
120 | {0x80024, SWAP32(0x053f03ff)}, /* panel horizontal total */ | |
121 | {0x80028, SWAP32(0x0140040f)}, /* panel horizontal sync */ | |
122 | {0x8002C, SWAP32(0x032502ff)}, /* panel vertical total */ | |
123 | {0x80030, SWAP32(0x00260301)}, /* panel vertical sync */ | |
124 | {0x80200, SWAP32(0x00010000)}, /* crt display control */ | |
125 | {0, 0} | |
126 | }; | |
1f54ce6d | 127 | |
98f4a3df SR |
128 | #endif /* CONFIG_VIDEO_SM501_16BPP */ |
129 | ||
130 | #ifdef CONFIG_VIDEO_SM501_32BPP | |
131 | #define BPP 32 | |
132 | ||
133 | /* | |
134 | * 800x600 display B084SN03: PCLK = 40MHz | |
135 | * => 2*PCLK = 80MHz | |
136 | * 336/4 = 84MHz | |
137 | * => PCLK = 84MHz | |
138 | */ | |
139 | static const SMI_REGS init_regs_800x600 [] = | |
140 | { | |
141 | #if 0 /* test-only */ | |
142 | {0x0005c, SWAP32(0xffffffff)}, /* set endianess to big endian */ | |
143 | #else | |
144 | {0x0005c, SWAP32(0x00000000)}, /* set endianess to little endian */ | |
145 | #endif | |
146 | {0x00004, SWAP32(0x00000000)}, | |
147 | /* clocks for pm1... */ | |
148 | {0x00048, SWAP32(0x00021807)}, | |
149 | {0x0004C, SWAP32(0x221a0a01)}, | |
150 | {0x00054, SWAP32(0x00000001)}, | |
151 | /* clocks for pm0... */ | |
152 | {0x00040, SWAP32(0x00021807)}, | |
153 | {0x00044, SWAP32(0x221a0a01)}, | |
154 | {0x00054, SWAP32(0x00000000)}, | |
48a05a51 SR |
155 | /* GPIO */ |
156 | {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */ | |
98f4a3df SR |
157 | /* panel control regs... */ |
158 | {0x80000, SWAP32(0x0f013106)}, /* panel display control: 32-bit RGB 8:8:8 mode */ | |
159 | {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */ | |
48a05a51 | 160 | {0x8000C, SWAP32(0x00010000)}, /* panel fb address */ |
98f4a3df SR |
161 | {0x80010, SWAP32(0x0c800c80)}, /* panel fb offset/window width */ |
162 | {0x80014, SWAP32(0x03200000)}, /* panel fb width (0x320=800) */ | |
163 | {0x80018, SWAP32(0x02580000)}, /* panel fb height (0x258=600) */ | |
164 | {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */ | |
165 | {0x80020, SWAP32(0x02580320)}, /* panel plane br location */ | |
166 | {0x80024, SWAP32(0x041f031f)}, /* panel horizontal total */ | |
167 | {0x80028, SWAP32(0x00800347)}, /* panel horizontal sync */ | |
168 | {0x8002C, SWAP32(0x02730257)}, /* panel vertical total */ | |
169 | {0x80030, SWAP32(0x00040258)}, /* panel vertical sync */ | |
170 | {0x80200, SWAP32(0x00010000)}, /* crt display control */ | |
171 | {0, 0} | |
172 | }; | |
173 | ||
174 | /* | |
175 | * 1024x768 display G150XG02: PCLK = 65MHz | |
176 | * => 2*PCLK = 130MHz | |
177 | * 288/2 = 144MHz | |
178 | * => PCLK = 72MHz | |
179 | */ | |
180 | static const SMI_REGS init_regs_1024x768 [] = | |
181 | { | |
182 | {0x00004, SWAP32(0x00000000)}, | |
183 | /* clocks for pm1... */ | |
184 | {0x00048, SWAP32(0x00021807)}, | |
185 | {0x0004C, SWAP32(0x011a0a01)}, | |
186 | {0x00054, SWAP32(0x00000001)}, | |
187 | /* clocks for pm0... */ | |
188 | {0x00040, SWAP32(0x00021807)}, | |
189 | {0x00044, SWAP32(0x011a0a01)}, | |
190 | {0x00054, SWAP32(0x00000000)}, | |
48a05a51 SR |
191 | /* GPIO */ |
192 | {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */ | |
98f4a3df SR |
193 | /* panel control regs... */ |
194 | {0x80000, SWAP32(0x0f013106)}, /* panel display control: 32-bit RGB 8:8:8 mode */ | |
195 | {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */ | |
48a05a51 | 196 | {0x8000C, SWAP32(0x00010000)}, /* panel fb address */ |
98f4a3df SR |
197 | {0x80010, SWAP32(0x10001000)}, /* panel fb offset/window width */ |
198 | {0x80014, SWAP32(0x04000000)}, /* panel fb width (0x400=1024) */ | |
199 | {0x80018, SWAP32(0x03000000)}, /* panel fb height (0x300=768) */ | |
200 | {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */ | |
201 | {0x80020, SWAP32(0x03000400)}, /* panel plane br location */ | |
202 | {0x80024, SWAP32(0x053f03ff)}, /* panel horizontal total */ | |
203 | {0x80028, SWAP32(0x0140040f)}, /* panel horizontal sync */ | |
204 | {0x8002C, SWAP32(0x032502ff)}, /* panel vertical total */ | |
205 | {0x80030, SWAP32(0x00260301)}, /* panel vertical sync */ | |
206 | {0x80200, SWAP32(0x00010000)}, /* crt display control */ | |
207 | {0, 0} | |
208 | }; | |
209 | ||
210 | #endif /* CONFIG_VIDEO_SM501_32BPP */ | |
211 | ||
212 | #endif /* CONFIG_VIDEO_SM501 */ | |
1f54ce6d SR |
213 | |
214 | #if 0 | |
215 | #define FPGA_DEBUG | |
216 | #endif | |
217 | ||
218 | extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | |
219 | extern void lxt971_no_sleep(void); | |
220 | ||
221 | /* fpga configuration data - gzip compressed and generated by bin2c */ | |
222 | const unsigned char fpgadata[] = | |
223 | { | |
224 | #include "fpgadata.c" | |
225 | }; | |
226 | ||
227 | /* | |
228 | * include common fpga code (for esd boards) | |
229 | */ | |
230 | #include "../common/fpga.c" | |
231 | ||
232 | ||
233 | /* Prototypes */ | |
234 | int gunzip(void *, int, unsigned char *, unsigned long *); | |
235 | ||
236 | ||
237 | /* logo bitmap data - gzip compressed and generated by bin2c */ | |
238 | unsigned char logo_bmp_320[] = | |
239 | { | |
240 | #include "logo_320_240_4bpp.c" | |
241 | }; | |
242 | ||
243 | unsigned char logo_bmp_320_8bpp[] = | |
244 | { | |
245 | #include "logo_320_240_8bpp.c" | |
246 | }; | |
247 | ||
248 | unsigned char logo_bmp_640[] = | |
249 | { | |
250 | #include "logo_640_480_24bpp.c" | |
251 | }; | |
252 | ||
253 | unsigned char logo_bmp_1024[] = | |
254 | { | |
255 | #include "logo_1024_768_8bpp.c" | |
256 | }; | |
257 | ||
258 | ||
259 | /* | |
260 | * include common lcd code (for esd boards) | |
261 | */ | |
262 | #include "../common/lcd.c" | |
263 | ||
264 | #include "../common/s1d13704_320_240_4bpp.h" | |
265 | #include "../common/s1d13705_320_240_8bpp.h" | |
266 | #include "../common/s1d13806_640_480_16bpp.h" | |
267 | #include "../common/s1d13806_1024_768_8bpp.h" | |
268 | ||
269 | ||
270 | /* | |
271 | * include common auto-update code (for esd boards) | |
272 | */ | |
273 | #include "../common/auto_update.h" | |
274 | ||
275 | au_image_t au_image[] = { | |
276 | {"hh405/preinst.img", 0, -1, AU_SCRIPT}, | |
277 | {"hh405/u-boot.img", 0xfff80000, 0x00080000, AU_FIRMWARE}, | |
fe126d8b | 278 | {"hh405/pImage_${bd_type}", 0x00000000, 0x00100000, AU_NAND}, |
1f54ce6d SR |
279 | {"hh405/pImage.initrd", 0x00100000, 0x00200000, AU_NAND}, |
280 | {"hh405/yaffsmt2.img", 0x00300000, 0x01c00000, AU_NAND}, | |
281 | {"hh405/postinst.img", 0, 0, AU_SCRIPT}, | |
282 | }; | |
283 | ||
284 | int N_AU_IMAGES = (sizeof(au_image) / sizeof(au_image[0])); | |
285 | ||
286 | ||
48a05a51 SR |
287 | /* |
288 | * Get version of HH405 board from GPIO's | |
289 | */ | |
1f54ce6d SR |
290 | int board_revision(void) |
291 | { | |
292 | unsigned long osrh_reg; | |
293 | unsigned long isr1h_reg; | |
294 | unsigned long tcr_reg; | |
295 | unsigned long value; | |
296 | ||
1f54ce6d SR |
297 | /* |
298 | * Setup GPIO pins (BLAST/GPIO0 and GPIO9 as GPIO) | |
299 | */ | |
300 | osrh_reg = in32(GPIO0_OSRH); | |
301 | isr1h_reg = in32(GPIO0_ISR1H); | |
302 | tcr_reg = in32(GPIO0_TCR); | |
303 | out32(GPIO0_OSRH, osrh_reg & ~0xC0003000); /* output select */ | |
304 | out32(GPIO0_ISR1H, isr1h_reg | 0xC0003000); /* input select */ | |
305 | out32(GPIO0_TCR, tcr_reg & ~0x80400000); /* select input */ | |
306 | ||
307 | udelay(1000); /* wait some time before reading input */ | |
308 | value = in32(GPIO0_IR) & 0x80400000; /* get config bits */ | |
309 | ||
310 | /* | |
311 | * Restore GPIO settings | |
312 | */ | |
313 | out32(GPIO0_OSRH, osrh_reg); /* output select */ | |
314 | out32(GPIO0_ISR1H, isr1h_reg); /* input select */ | |
315 | out32(GPIO0_TCR, tcr_reg); /* enable output driver for outputs */ | |
316 | ||
317 | if (value & 0x80000000) { | |
318 | /* Revision 1.0 or 1.1 detected */ | |
48a05a51 | 319 | return 1; |
1f54ce6d SR |
320 | } else { |
321 | if (value & 0x00400000) { | |
98f4a3df | 322 | /* unused */ |
48a05a51 | 323 | return 3; |
1f54ce6d | 324 | } else { |
48a05a51 | 325 | return 2; |
1f54ce6d SR |
326 | } |
327 | } | |
328 | } | |
329 | ||
330 | ||
331 | int board_early_init_f (void) | |
332 | { | |
333 | /* | |
334 | * IRQ 0-15 405GP internally generated; active high; level sensitive | |
335 | * IRQ 16 405GP internally generated; active low; level sensitive | |
336 | * IRQ 17-24 RESERVED | |
337 | * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive | |
338 | * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive | |
339 | * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive | |
340 | * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive | |
341 | * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive | |
342 | * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive | |
343 | * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive | |
344 | */ | |
345 | mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ | |
346 | mtdcr(uicer, 0x00000000); /* disable all ints */ | |
347 | mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ | |
6d0f6bcf | 348 | mtdcr(uicpr, CONFIG_SYS_UIC0_POLARITY);/* set int polarities */ |
1f54ce6d SR |
349 | mtdcr(uictr, 0x10000000); /* set int trigger levels */ |
350 | mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/ | |
351 | mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ | |
352 | ||
353 | /* | |
354 | * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us | |
355 | */ | |
356 | mtebc (epcr, 0xa8400000); /* ebc always driven */ | |
357 | ||
358 | return 0; | |
359 | } | |
360 | ||
48a05a51 SR |
361 | int cf_enable(void) |
362 | { | |
48a05a51 SR |
363 | int i; |
364 | ||
365 | volatile unsigned short *fpga_ctrl = | |
6d0f6bcf | 366 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL); |
48a05a51 | 367 | volatile unsigned short *fpga_status = |
6d0f6bcf | 368 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 2); |
48a05a51 SR |
369 | |
370 | if (gd->board_type >= 2) { | |
6d0f6bcf JCPV |
371 | if (*fpga_status & CONFIG_SYS_FPGA_STATUS_CF_DETECT) { |
372 | if (!(*fpga_ctrl & CONFIG_SYS_FPGA_CTRL_CF_BUS_EN)) { | |
373 | *fpga_ctrl &= ~CONFIG_SYS_FPGA_CTRL_CF_PWRN; | |
48a05a51 SR |
374 | |
375 | for (i=0; i<300; i++) | |
376 | udelay(1000); | |
377 | ||
6d0f6bcf | 378 | *fpga_ctrl |= CONFIG_SYS_FPGA_CTRL_CF_BUS_EN; |
48a05a51 SR |
379 | |
380 | for (i=0; i<20; i++) | |
381 | udelay(1000); | |
382 | } | |
383 | } else { | |
6d0f6bcf JCPV |
384 | *fpga_ctrl &= ~CONFIG_SYS_FPGA_CTRL_CF_BUS_EN; |
385 | *fpga_ctrl |= CONFIG_SYS_FPGA_CTRL_CF_PWRN; | |
48a05a51 SR |
386 | } |
387 | } | |
388 | ||
389 | return 0; | |
390 | } | |
1f54ce6d SR |
391 | |
392 | int misc_init_r (void) | |
393 | { | |
1f54ce6d | 394 | volatile unsigned short *fpga_ctrl = |
6d0f6bcf | 395 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL); |
1f54ce6d | 396 | volatile unsigned short *lcd_contrast = |
6d0f6bcf | 397 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 4); |
1f54ce6d | 398 | volatile unsigned short *lcd_backlight = |
6d0f6bcf | 399 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 6); |
1f54ce6d SR |
400 | unsigned char *dst; |
401 | ulong len = sizeof(fpgadata); | |
402 | int status; | |
403 | int index; | |
404 | int i; | |
405 | char *str; | |
406 | unsigned long contrast0 = 0xffffffff; | |
407 | ||
6d0f6bcf JCPV |
408 | dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE); |
409 | if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) { | |
1f54ce6d SR |
410 | printf ("GUNZIP ERROR - must RESET board to recover\n"); |
411 | do_reset (NULL, 0, 0, NULL); | |
412 | } | |
413 | ||
414 | status = fpga_boot(dst, len); | |
415 | if (status != 0) { | |
416 | printf("\nFPGA: Booting failed "); | |
417 | switch (status) { | |
418 | case ERROR_FPGA_PRG_INIT_LOW: | |
419 | printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); | |
420 | break; | |
421 | case ERROR_FPGA_PRG_INIT_HIGH: | |
422 | printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); | |
423 | break; | |
424 | case ERROR_FPGA_PRG_DONE: | |
425 | printf("(Timeout: DONE not high after programming FPGA)\n "); | |
426 | break; | |
427 | } | |
428 | ||
429 | /* display infos on fpgaimage */ | |
430 | index = 15; | |
431 | for (i=0; i<4; i++) { | |
432 | len = dst[index]; | |
433 | printf("FPGA: %s\n", &(dst[index+1])); | |
434 | index += len+3; | |
435 | } | |
436 | putc ('\n'); | |
437 | /* delayed reboot */ | |
438 | for (i=20; i>0; i--) { | |
439 | printf("Rebooting in %2d seconds \r",i); | |
440 | for (index=0;index<1000;index++) | |
441 | udelay(1000); | |
442 | } | |
443 | putc ('\n'); | |
444 | do_reset(NULL, 0, 0, NULL); | |
445 | } | |
446 | ||
447 | puts("FPGA: "); | |
448 | ||
449 | /* display infos on fpgaimage */ | |
450 | index = 15; | |
451 | for (i=0; i<4; i++) { | |
452 | len = dst[index]; | |
453 | printf("%s ", &(dst[index+1])); | |
454 | index += len+3; | |
455 | } | |
456 | putc ('\n'); | |
457 | ||
458 | free(dst); | |
459 | ||
460 | /* | |
461 | * Reset FPGA via FPGA_INIT pin | |
462 | */ | |
463 | out32(GPIO0_TCR, in32(GPIO0_TCR) | FPGA_INIT); /* setup FPGA_INIT as output */ | |
464 | out32(GPIO0_OR, in32(GPIO0_OR) & ~FPGA_INIT); /* reset low */ | |
465 | udelay(1000); /* wait 1ms */ | |
466 | out32(GPIO0_OR, in32(GPIO0_OR) | FPGA_INIT); /* reset high */ | |
467 | udelay(1000); /* wait 1ms */ | |
468 | ||
469 | /* | |
470 | * Write Board revision into FPGA | |
471 | */ | |
472 | *fpga_ctrl |= gd->board_type & 0x0003; | |
1f54ce6d | 473 | |
53677ef1 | 474 | /* |
98f4a3df SR |
475 | * Setup and enable EEPROM write protection |
476 | */ | |
6d0f6bcf | 477 | out32(GPIO0_OR, in32(GPIO0_OR) | CONFIG_SYS_EEPROM_WP); |
98f4a3df | 478 | |
1f54ce6d SR |
479 | /* |
480 | * Reset touch-screen controller | |
481 | */ | |
6d0f6bcf | 482 | out32(GPIO0_OR, in32(GPIO0_OR) & ~CONFIG_SYS_TOUCH_RST); |
1f54ce6d | 483 | udelay(1000); |
6d0f6bcf | 484 | out32(GPIO0_OR, in32(GPIO0_OR) | CONFIG_SYS_TOUCH_RST); |
1f54ce6d | 485 | |
efe2a4d5 WD |
486 | /* |
487 | * Enable power on PS/2 interface (with reset) | |
488 | */ | |
6d0f6bcf | 489 | *fpga_ctrl &= ~(CONFIG_SYS_FPGA_CTRL_PS2_PWR); |
efe2a4d5 WD |
490 | for (i=0;i<500;i++) |
491 | udelay(1000); | |
6d0f6bcf | 492 | *fpga_ctrl |= (CONFIG_SYS_FPGA_CTRL_PS2_PWR); |
1f54ce6d SR |
493 | |
494 | /* | |
495 | * Get contrast value from environment variable | |
496 | */ | |
497 | str = getenv("contrast0"); | |
498 | if (str) { | |
499 | contrast0 = simple_strtol(str, NULL, 16); | |
500 | if (contrast0 > 255) { | |
501 | printf("ERROR: contrast0 value too high (0x%lx)!\n", contrast0); | |
48a05a51 | 502 | contrast0 = 0xffffffff; |
1f54ce6d SR |
503 | } |
504 | } | |
505 | ||
506 | /* | |
507 | * Init lcd interface and display logo | |
508 | */ | |
98f4a3df | 509 | |
1f54ce6d SR |
510 | str = getenv("bd_type"); |
511 | if (strcmp(str, "ppc230") == 0) { | |
512 | /* | |
513 | * Switch backlight on | |
514 | */ | |
6d0f6bcf | 515 | *fpga_ctrl |= CONFIG_SYS_FPGA_CTRL_VGA0_BL; |
1f54ce6d SR |
516 | *lcd_backlight = 0x0000; |
517 | ||
518 | lcd_setup(1, 0); | |
6d0f6bcf | 519 | lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM, |
1f54ce6d SR |
520 | regs_13806_1024_768_8bpp, |
521 | sizeof(regs_13806_1024_768_8bpp)/sizeof(regs_13806_1024_768_8bpp[0]), | |
522 | logo_bmp_1024, sizeof(logo_bmp_1024)); | |
523 | } else if (strcmp(str, "ppc220") == 0) { | |
524 | /* | |
525 | * Switch backlight on | |
526 | */ | |
6d0f6bcf | 527 | *fpga_ctrl &= ~CONFIG_SYS_FPGA_CTRL_VGA0_BL; |
1f54ce6d SR |
528 | *lcd_backlight = 0x0000; |
529 | ||
530 | lcd_setup(1, 0); | |
6d0f6bcf | 531 | lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM, |
1f54ce6d SR |
532 | regs_13806_640_480_16bpp, |
533 | sizeof(regs_13806_640_480_16bpp)/sizeof(regs_13806_640_480_16bpp[0]), | |
534 | logo_bmp_640, sizeof(logo_bmp_640)); | |
535 | } else if (strcmp(str, "ppc215") == 0) { | |
536 | /* | |
537 | * Set default display contrast voltage | |
538 | */ | |
539 | if (contrast0 == 0xffffffff) { | |
540 | *lcd_contrast = 0x0082; | |
541 | } else { | |
542 | *lcd_contrast = contrast0; | |
543 | } | |
544 | *lcd_backlight = 0xffff; | |
545 | /* | |
546 | * Switch backlight on | |
547 | */ | |
6d0f6bcf | 548 | *fpga_ctrl |= CONFIG_SYS_FPGA_CTRL_VGA0_BL | CONFIG_SYS_FPGA_CTRL_VGA0_BL_MODE; |
1f54ce6d SR |
549 | /* |
550 | * Set lcd clock (small epson) | |
551 | */ | |
552 | *fpga_ctrl |= LCD_CLK_06250; | |
553 | udelay(100); /* wait for 100 us */ | |
554 | ||
555 | lcd_setup(0, 1); | |
6d0f6bcf | 556 | lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM, |
1f54ce6d SR |
557 | regs_13705_320_240_8bpp, |
558 | sizeof(regs_13705_320_240_8bpp)/sizeof(regs_13705_320_240_8bpp[0]), | |
559 | logo_bmp_320_8bpp, sizeof(logo_bmp_320_8bpp)); | |
560 | } else if (strcmp(str, "ppc210") == 0) { | |
561 | /* | |
562 | * Set default display contrast voltage | |
563 | */ | |
564 | if (contrast0 == 0xffffffff) { | |
565 | *lcd_contrast = 0x0060; | |
566 | } else { | |
567 | *lcd_contrast = contrast0; | |
568 | } | |
569 | *lcd_backlight = 0xffff; | |
570 | /* | |
571 | * Switch backlight on | |
572 | */ | |
6d0f6bcf | 573 | *fpga_ctrl |= CONFIG_SYS_FPGA_CTRL_VGA0_BL | CONFIG_SYS_FPGA_CTRL_VGA0_BL_MODE; |
1f54ce6d | 574 | /* |
48a05a51 | 575 | * Set lcd clock (small epson), enable 1-wire interface |
1f54ce6d | 576 | */ |
6d0f6bcf | 577 | *fpga_ctrl |= LCD_CLK_08330 | CONFIG_SYS_FPGA_CTRL_OW_ENABLE; |
1f54ce6d SR |
578 | |
579 | lcd_setup(0, 1); | |
6d0f6bcf | 580 | lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM, |
1f54ce6d SR |
581 | regs_13704_320_240_4bpp, |
582 | sizeof(regs_13704_320_240_4bpp)/sizeof(regs_13704_320_240_4bpp[0]), | |
583 | logo_bmp_320, sizeof(logo_bmp_320)); | |
2c7b2ab5 | 584 | #ifdef CONFIG_VIDEO_SM501 |
1f54ce6d | 585 | } else { |
2c7b2ab5 SR |
586 | pci_dev_t devbusfn; |
587 | ||
98f4a3df SR |
588 | /* |
589 | * Is SM501 connected (ppc221/ppc231)? | |
590 | */ | |
591 | devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0); | |
592 | if (devbusfn != -1) { | |
593 | puts("VGA: SM501 with 8 MB "); | |
594 | if (strcmp(str, "ppc221") == 0) { | |
595 | printf("(800*600, %dbpp)\n", BPP); | |
48a05a51 | 596 | *lcd_backlight = 0x002d; /* max. allowed brightness */ |
98f4a3df SR |
597 | } else if (strcmp(str, "ppc231") == 0) { |
598 | printf("(1024*768, %dbpp)\n", BPP); | |
48a05a51 | 599 | *lcd_backlight = 0x0000; |
98f4a3df SR |
600 | } else { |
601 | printf("Unsupported bd_type defined (%s) -> No display configured!\n", str); | |
602 | return 0; | |
603 | } | |
604 | } else { | |
605 | printf("Unsupported bd_type defined (%s) -> No display configured!\n", str); | |
606 | return 0; | |
607 | } | |
2c7b2ab5 | 608 | #endif /* CONFIG_VIDEO_SM501 */ |
1f54ce6d SR |
609 | } |
610 | ||
48a05a51 SR |
611 | cf_enable(); |
612 | ||
1f54ce6d SR |
613 | return (0); |
614 | } | |
615 | ||
616 | ||
617 | /* | |
618 | * Check Board Identity: | |
619 | */ | |
620 | ||
621 | int checkboard (void) | |
622 | { | |
18c5e64c | 623 | char str[64]; |
1f54ce6d SR |
624 | int i = getenv_r ("serial#", str, sizeof(str)); |
625 | ||
626 | puts ("Board: "); | |
627 | ||
628 | if (i == -1) { | |
629 | puts ("### No HW ID - assuming HH405"); | |
630 | } else { | |
631 | puts(str); | |
632 | } | |
633 | ||
634 | if (getenv_r("bd_type", str, sizeof(str)) != -1) { | |
635 | printf(" (%s", str); | |
636 | } else { | |
637 | puts(" (Missing bd_type!"); | |
638 | } | |
639 | ||
640 | gd->board_type = board_revision(); | |
48a05a51 | 641 | printf(", Rev %ld.x)\n", gd->board_type); |
1f54ce6d SR |
642 | |
643 | return 0; | |
644 | } | |
645 | ||
1f54ce6d SR |
646 | #ifdef CONFIG_IDE_RESET |
647 | void ide_set_reset(int on) | |
648 | { | |
649 | volatile unsigned short *fpga_mode = | |
6d0f6bcf | 650 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL); |
48a05a51 | 651 | volatile unsigned short *fpga_status = |
6d0f6bcf | 652 | (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 2); |
1f54ce6d | 653 | |
6d0f6bcf | 654 | if (((gd->board_type >= 2) && (*fpga_status & CONFIG_SYS_FPGA_STATUS_CF_DETECT)) || |
48a05a51 SR |
655 | (gd->board_type < 2)) { |
656 | /* | |
657 | * Assert or deassert CompactFlash Reset Pin | |
658 | */ | |
659 | if (on) { /* assert RESET */ | |
660 | cf_enable(); | |
6d0f6bcf | 661 | *fpga_mode &= ~(CONFIG_SYS_FPGA_CTRL_CF_RESET); |
48a05a51 | 662 | } else { /* release RESET */ |
6d0f6bcf | 663 | *fpga_mode |= CONFIG_SYS_FPGA_CTRL_CF_RESET; |
48a05a51 | 664 | } |
1f54ce6d SR |
665 | } |
666 | } | |
667 | #endif /* CONFIG_IDE_RESET */ | |
668 | ||
669 | ||
6d0f6bcf | 670 | #if defined(CONFIG_SYS_EEPROM_WREN) |
98f4a3df SR |
671 | /* Input: <dev_addr> I2C address of EEPROM device to enable. |
672 | * <state> -1: deliver current state | |
673 | * 0: disable write | |
674 | * 1: enable write | |
675 | * Returns: -1: wrong device address | |
676 | * 0: dis-/en- able done | |
677 | * 0/1: current state if <state> was -1. | |
678 | */ | |
679 | int eeprom_write_enable (unsigned dev_addr, int state) | |
680 | { | |
6d0f6bcf | 681 | if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) { |
98f4a3df SR |
682 | return -1; |
683 | } else { | |
684 | switch (state) { | |
685 | case 1: | |
686 | /* Enable write access, clear bit GPIO_SINT2. */ | |
6d0f6bcf | 687 | out32(GPIO0_OR, in32(GPIO0_OR) & ~CONFIG_SYS_EEPROM_WP); |
98f4a3df SR |
688 | state = 0; |
689 | break; | |
690 | case 0: | |
691 | /* Disable write access, set bit GPIO_SINT2. */ | |
6d0f6bcf | 692 | out32(GPIO0_OR, in32(GPIO0_OR) | CONFIG_SYS_EEPROM_WP); |
98f4a3df SR |
693 | state = 0; |
694 | break; | |
695 | default: | |
696 | /* Read current status back. */ | |
6d0f6bcf | 697 | state = (0 == (in32(GPIO0_OR) & CONFIG_SYS_EEPROM_WP)); |
98f4a3df SR |
698 | break; |
699 | } | |
700 | } | |
701 | return state; | |
702 | } | |
703 | ||
704 | int do_eep_wren (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
705 | { | |
706 | int query = argc == 1; | |
707 | int state = 0; | |
708 | ||
709 | if (query) { | |
710 | /* Query write access state. */ | |
6d0f6bcf | 711 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, -1); |
98f4a3df SR |
712 | if (state < 0) { |
713 | puts ("Query of write access state failed.\n"); | |
714 | } else { | |
715 | printf ("Write access for device 0x%0x is %sabled.\n", | |
6d0f6bcf | 716 | CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis"); |
98f4a3df SR |
717 | state = 0; |
718 | } | |
719 | } else { | |
720 | if ('0' == argv[1][0]) { | |
721 | /* Disable write access. */ | |
6d0f6bcf | 722 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 0); |
98f4a3df SR |
723 | } else { |
724 | /* Enable write access. */ | |
6d0f6bcf | 725 | state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 1); |
98f4a3df SR |
726 | } |
727 | if (state < 0) { | |
728 | puts ("Setup of write access state failed.\n"); | |
729 | } | |
730 | } | |
731 | ||
732 | return state; | |
733 | } | |
734 | ||
735 | U_BOOT_CMD(eepwren, 2, 0, do_eep_wren, | |
2fb2604d | 736 | "Enable / disable / query EEPROM write access", |
98f4a3df | 737 | NULL); |
6d0f6bcf | 738 | #endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */ |
98f4a3df SR |
739 | |
740 | ||
741 | #ifdef CONFIG_VIDEO_SM501 | |
742 | #ifdef CONFIG_CONSOLE_EXTRA_INFO | |
743 | /* | |
744 | * Return text to be printed besides the logo. | |
745 | */ | |
746 | void video_get_info_str (int line_number, char *info) | |
747 | { | |
98f4a3df SR |
748 | char str[64]; |
749 | char str2[64]; | |
750 | int i = getenv_r("serial#", str2, sizeof(str)); | |
751 | ||
752 | if (line_number == 1) { | |
753 | sprintf(str, " Board: "); | |
754 | ||
755 | if (i == -1) { | |
756 | strcat(str, "### No HW ID - assuming HH405"); | |
757 | } else { | |
758 | strcat(str, str2); | |
759 | } | |
760 | ||
761 | if (getenv_r("bd_type", str2, sizeof(str2)) != -1) { | |
762 | strcat(str, " ("); | |
763 | strcat(str, str2); | |
764 | } else { | |
765 | strcat(str, " (Missing bd_type!"); | |
766 | } | |
767 | ||
48a05a51 | 768 | sprintf(str2, ", Rev %ld.x)", gd->board_type); |
98f4a3df SR |
769 | strcat(str, str2); |
770 | strcpy(info, str); | |
771 | } else { | |
772 | info [0] = '\0'; | |
773 | } | |
774 | } | |
775 | #endif /* CONFIG_CONSOLE_EXTRA_INFO */ | |
776 | ||
777 | /* | |
778 | * Returns SM501 register base address. First thing called in the driver. | |
779 | */ | |
780 | unsigned int board_video_init (void) | |
781 | { | |
782 | pci_dev_t devbusfn; | |
783 | u32 addr; | |
784 | ||
785 | /* | |
786 | * Is SM501 connected (ppc221/ppc231)? | |
787 | */ | |
788 | devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0); | |
789 | if (devbusfn != -1) { | |
790 | pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, (u32 *)&addr); | |
791 | return (addr & 0xfffffffe); | |
792 | } | |
793 | ||
794 | return 0; | |
795 | } | |
796 | ||
797 | /* | |
798 | * Returns SM501 framebuffer address | |
799 | */ | |
800 | unsigned int board_video_get_fb (void) | |
801 | { | |
802 | pci_dev_t devbusfn; | |
803 | u32 addr; | |
804 | ||
805 | /* | |
806 | * Is SM501 connected (ppc221/ppc231)? | |
807 | */ | |
808 | devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0); | |
809 | if (devbusfn != -1) { | |
810 | pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, (u32 *)&addr); | |
48a05a51 SR |
811 | addr &= 0xfffffffe; |
812 | #ifdef CONFIG_VIDEO_SM501_FBMEM_OFFSET | |
813 | addr += CONFIG_VIDEO_SM501_FBMEM_OFFSET; | |
814 | #endif | |
815 | return addr; | |
98f4a3df SR |
816 | } |
817 | ||
818 | return 0; | |
819 | } | |
820 | ||
821 | /* | |
822 | * Called after initializing the SM501 and before clearing the screen. | |
823 | */ | |
824 | void board_validate_screen (unsigned int base) | |
825 | { | |
826 | } | |
827 | ||
828 | /* | |
829 | * Return a pointer to the initialization sequence. | |
830 | */ | |
831 | const SMI_REGS *board_get_regs (void) | |
832 | { | |
833 | char *str; | |
834 | ||
835 | str = getenv("bd_type"); | |
836 | if (strcmp(str, "ppc221") == 0) { | |
837 | return init_regs_800x600; | |
838 | } else { | |
839 | return init_regs_1024x768; | |
840 | } | |
841 | } | |
842 | ||
843 | int board_get_width (void) | |
844 | { | |
845 | char *str; | |
846 | ||
847 | str = getenv("bd_type"); | |
848 | if (strcmp(str, "ppc221") == 0) { | |
849 | return 800; | |
850 | } else { | |
851 | return 1024; | |
852 | } | |
853 | } | |
854 | ||
855 | int board_get_height (void) | |
856 | { | |
857 | char *str; | |
858 | ||
859 | str = getenv("bd_type"); | |
860 | if (strcmp(str, "ppc221") == 0) { | |
861 | return 600; | |
862 | } else { | |
863 | return 768; | |
864 | } | |
865 | } | |
866 | ||
867 | #endif /* CONFIG_VIDEO_SM501 */ | |
48a05a51 SR |
868 | |
869 | ||
870 | void reset_phy(void) | |
871 | { | |
872 | #ifdef CONFIG_LXT971_NO_SLEEP | |
873 | ||
874 | /* | |
875 | * Disable sleep mode in LXT971 | |
876 | */ | |
877 | lxt971_no_sleep(); | |
878 | #endif | |
879 | } |