blob: e9d2d36c1b2b861899a242bb9e5e414e894c6e31 [file] [log] [blame]
stroese1f54ce62004-12-16 18:23:14 +00001/*
2 * (C) Copyright 2001-2004
3 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4 *
Stefan Roese98f4a3d2005-09-22 09:04:17 +02005 * (C) Copyright 2005
6 * Stefan Roese, DENX Software Engineering, sr@denx.de.
7 *
Matthias Fuchsbd84ee42007-07-09 10:10:06 +02008 * (C) Copyright 2006-2007
Stefan Roese48a05a52006-02-07 16:51:04 +01009 * Matthias Fuchs, esd GmbH, matthias.fuchs@esd-electronics.com
10 *
stroese1f54ce62004-12-16 18:23:14 +000011 * 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>
Matthias Fuchsbb57ad42009-02-20 10:19:19 +010032#include <asm/io.h>
stroese1f54ce62004-12-16 18:23:14 +000033#include <command.h>
34#include <malloc.h>
Stefan Roese98f4a3d2005-09-22 09:04:17 +020035#include <pci.h>
36#include <sm501.h>
stroese1f54ce62004-12-16 18:23:14 +000037
Wolfgang Denkd87080b2006-03-31 18:32:53 +020038DECLARE_GLOBAL_DATA_PTR;
39
Matthias Fuchsbb57ad42009-02-20 10:19:19 +010040/* FPGA internal regs */
41#define FPGA_CTRL ((u16 *)(CONFIG_SYS_FPGA_BASE_ADDR + 0x000))
42#define FPGA_STATUS ((u16 *)(CONFIG_SYS_FPGA_BASE_ADDR + 0x002))
43#define FPGA_CTR ((u16 *)(CONFIG_SYS_FPGA_BASE_ADDR + 0x004))
44#define FPGA_BL ((u16 *)(CONFIG_SYS_FPGA_BASE_ADDR + 0x006))
45
46/* FPGA Control Reg */
47#define FPGA_CTRL_REV0 0x0001
48#define FPGA_CTRL_REV1 0x0002
49#define FPGA_CTRL_VGA0_BL 0x0004
50#define FPGA_CTRL_VGA0_BL_MODE 0x0008
51#define FPGA_CTRL_CF_RESET 0x0040
52#define FPGA_CTRL_PS2_PWR 0x0080
53#define FPGA_CTRL_CF_PWRN 0x0100 /* low active */
54#define FPGA_CTRL_CF_BUS_EN 0x0200
55#define FPGA_CTRL_LCD_CLK 0x7000 /* mask for lcd clock */
56#define FPGA_CTRL_OW_ENABLE 0x8000
57
58#define FPGA_STATUS_CF_DETECT 0x8000
59
Stefan Roese98f4a3d2005-09-22 09:04:17 +020060#ifdef CONFIG_VIDEO_SM501
61
62#define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
63 (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
64
65#ifdef CONFIG_VIDEO_SM501_8BPP
66#error CONFIG_VIDEO_SM501_8BPP not supported.
67#endif /* CONFIG_VIDEO_SM501_8BPP */
68
69#ifdef CONFIG_VIDEO_SM501_16BPP
70#define BPP 16
71
72/*
73 * 800x600 display B084SN03: PCLK = 40MHz
74 * => 2*PCLK = 80MHz
75 * 336/4 = 84MHz
76 * => PCLK = 84MHz
77 */
78static const SMI_REGS init_regs_800x600 [] =
79{
80#if 1 /* test-only */
81 {0x0005c, SWAP32(0xffffffff)}, /* set endianess to big endian */
82#else
83 {0x0005c, SWAP32(0x00000000)}, /* set endianess to little endian */
84#endif
85 {0x00004, SWAP32(0x00000000)},
86 /* clocks for pm1... */
87 {0x00048, SWAP32(0x00021807)},
88 {0x0004C, SWAP32(0x221a0a01)},
89 {0x00054, SWAP32(0x00000001)},
90 /* clocks for pm0... */
91 {0x00040, SWAP32(0x00021807)},
92 {0x00044, SWAP32(0x221a0a01)},
93 {0x00054, SWAP32(0x00000000)},
Stefan Roese48a05a52006-02-07 16:51:04 +010094 /* GPIO */
95 {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */
Stefan Roese98f4a3d2005-09-22 09:04:17 +020096 /* panel control regs... */
97 {0x80000, SWAP32(0x0f013105)}, /* panel display control: 16-bit RGB 5:6:5 mode */
98 {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */
Stefan Roese48a05a52006-02-07 16:51:04 +010099 {0x8000C, SWAP32(0x00010000)}, /* panel fb address */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200100 {0x80010, SWAP32(0x06400640)}, /* panel fb offset/window width */
101 {0x80014, SWAP32(0x03200000)}, /* panel fb width (0x320=800) */
102 {0x80018, SWAP32(0x02580000)}, /* panel fb height (0x258=600) */
103 {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */
104 {0x80020, SWAP32(0x02580320)}, /* panel plane br location */
105 {0x80024, SWAP32(0x041f031f)}, /* panel horizontal total */
106 {0x80028, SWAP32(0x00800347)}, /* panel horizontal sync */
107 {0x8002C, SWAP32(0x02730257)}, /* panel vertical total */
108 {0x80030, SWAP32(0x00040258)}, /* panel vertical sync */
109 {0x80200, SWAP32(0x00010000)}, /* crt display control */
110 {0, 0}
111};
112
113/*
114 * 1024x768 display G150XG02: PCLK = 65MHz
115 * => 2*PCLK = 130MHz
116 * 288/2 = 144MHz
117 * => PCLK = 72MHz
118 */
119static const SMI_REGS init_regs_1024x768 [] =
120{
121 {0x00004, SWAP32(0x00000000)},
122 /* clocks for pm1... */
123 {0x00048, SWAP32(0x00021807)},
124 {0x0004C, SWAP32(0x011a0a01)},
125 {0x00054, SWAP32(0x00000001)},
126 /* clocks for pm0... */
127 {0x00040, SWAP32(0x00021807)},
128 {0x00044, SWAP32(0x011a0a01)},
129 {0x00054, SWAP32(0x00000000)},
Stefan Roese48a05a52006-02-07 16:51:04 +0100130 /* GPIO */
131 {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200132 /* panel control regs... */
133 {0x80000, SWAP32(0x0f013105)}, /* panel display control: 16-bit RGB 5:6:5 mode */
134 {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */
Stefan Roese48a05a52006-02-07 16:51:04 +0100135 {0x8000C, SWAP32(0x00010000)}, /* panel fb address */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200136 {0x80010, SWAP32(0x08000800)}, /* panel fb offset/window width */
137 {0x80014, SWAP32(0x04000000)}, /* panel fb width (0x400=1024) */
138 {0x80018, SWAP32(0x03000000)}, /* panel fb height (0x300=768) */
139 {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */
140 {0x80020, SWAP32(0x03000400)}, /* panel plane br location */
141 {0x80024, SWAP32(0x053f03ff)}, /* panel horizontal total */
142 {0x80028, SWAP32(0x0140040f)}, /* panel horizontal sync */
143 {0x8002C, SWAP32(0x032502ff)}, /* panel vertical total */
144 {0x80030, SWAP32(0x00260301)}, /* panel vertical sync */
145 {0x80200, SWAP32(0x00010000)}, /* crt display control */
146 {0, 0}
147};
148
149#endif /* CONFIG_VIDEO_SM501_16BPP */
150
151#ifdef CONFIG_VIDEO_SM501_32BPP
152#define BPP 32
153
154/*
155 * 800x600 display B084SN03: PCLK = 40MHz
156 * => 2*PCLK = 80MHz
157 * 336/4 = 84MHz
158 * => PCLK = 84MHz
159 */
160static const SMI_REGS init_regs_800x600 [] =
161{
162#if 0 /* test-only */
163 {0x0005c, SWAP32(0xffffffff)}, /* set endianess to big endian */
164#else
165 {0x0005c, SWAP32(0x00000000)}, /* set endianess to little endian */
166#endif
167 {0x00004, SWAP32(0x00000000)},
168 /* clocks for pm1... */
169 {0x00048, SWAP32(0x00021807)},
170 {0x0004C, SWAP32(0x221a0a01)},
171 {0x00054, SWAP32(0x00000001)},
172 /* clocks for pm0... */
173 {0x00040, SWAP32(0x00021807)},
174 {0x00044, SWAP32(0x221a0a01)},
175 {0x00054, SWAP32(0x00000000)},
Stefan Roese48a05a52006-02-07 16:51:04 +0100176 /* GPIO */
177 {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200178 /* panel control regs... */
179 {0x80000, SWAP32(0x0f013106)}, /* panel display control: 32-bit RGB 8:8:8 mode */
180 {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */
Stefan Roese48a05a52006-02-07 16:51:04 +0100181 {0x8000C, SWAP32(0x00010000)}, /* panel fb address */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200182 {0x80010, SWAP32(0x0c800c80)}, /* panel fb offset/window width */
183 {0x80014, SWAP32(0x03200000)}, /* panel fb width (0x320=800) */
184 {0x80018, SWAP32(0x02580000)}, /* panel fb height (0x258=600) */
185 {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */
186 {0x80020, SWAP32(0x02580320)}, /* panel plane br location */
187 {0x80024, SWAP32(0x041f031f)}, /* panel horizontal total */
188 {0x80028, SWAP32(0x00800347)}, /* panel horizontal sync */
189 {0x8002C, SWAP32(0x02730257)}, /* panel vertical total */
190 {0x80030, SWAP32(0x00040258)}, /* panel vertical sync */
191 {0x80200, SWAP32(0x00010000)}, /* crt display control */
192 {0, 0}
193};
194
195/*
196 * 1024x768 display G150XG02: PCLK = 65MHz
197 * => 2*PCLK = 130MHz
198 * 288/2 = 144MHz
199 * => PCLK = 72MHz
200 */
201static const SMI_REGS init_regs_1024x768 [] =
202{
203 {0x00004, SWAP32(0x00000000)},
204 /* clocks for pm1... */
205 {0x00048, SWAP32(0x00021807)},
206 {0x0004C, SWAP32(0x011a0a01)},
207 {0x00054, SWAP32(0x00000001)},
208 /* clocks for pm0... */
209 {0x00040, SWAP32(0x00021807)},
210 {0x00044, SWAP32(0x011a0a01)},
211 {0x00054, SWAP32(0x00000000)},
Stefan Roese48a05a52006-02-07 16:51:04 +0100212 /* GPIO */
213 {0x1000c, SWAP32(0xfffffff0)}, /* GPIO32..63 direction */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200214 /* panel control regs... */
215 {0x80000, SWAP32(0x0f013106)}, /* panel display control: 32-bit RGB 8:8:8 mode */
216 {0x80004, SWAP32(0xc428bb17)}, /* panel panning control ??? */
Stefan Roese48a05a52006-02-07 16:51:04 +0100217 {0x8000C, SWAP32(0x00010000)}, /* panel fb address */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200218 {0x80010, SWAP32(0x10001000)}, /* panel fb offset/window width */
219 {0x80014, SWAP32(0x04000000)}, /* panel fb width (0x400=1024) */
220 {0x80018, SWAP32(0x03000000)}, /* panel fb height (0x300=768) */
221 {0x8001C, SWAP32(0x00000000)}, /* panel plane tl location */
222 {0x80020, SWAP32(0x03000400)}, /* panel plane br location */
223 {0x80024, SWAP32(0x053f03ff)}, /* panel horizontal total */
224 {0x80028, SWAP32(0x0140040f)}, /* panel horizontal sync */
225 {0x8002C, SWAP32(0x032502ff)}, /* panel vertical total */
226 {0x80030, SWAP32(0x00260301)}, /* panel vertical sync */
227 {0x80200, SWAP32(0x00010000)}, /* crt display control */
228 {0, 0}
229};
230
231#endif /* CONFIG_VIDEO_SM501_32BPP */
232
233#endif /* CONFIG_VIDEO_SM501 */
stroese1f54ce62004-12-16 18:23:14 +0000234
235#if 0
236#define FPGA_DEBUG
237#endif
238
stroese1f54ce62004-12-16 18:23:14 +0000239extern void lxt971_no_sleep(void);
240
241/* fpga configuration data - gzip compressed and generated by bin2c */
242const unsigned char fpgadata[] =
243{
244#include "fpgadata.c"
245};
246
247/*
248 * include common fpga code (for esd boards)
249 */
250#include "../common/fpga.c"
251
252
stroese1f54ce62004-12-16 18:23:14 +0000253/* logo bitmap data - gzip compressed and generated by bin2c */
254unsigned char logo_bmp_320[] =
255{
256#include "logo_320_240_4bpp.c"
257};
258
259unsigned char logo_bmp_320_8bpp[] =
260{
261#include "logo_320_240_8bpp.c"
262};
263
264unsigned char logo_bmp_640[] =
265{
266#include "logo_640_480_24bpp.c"
267};
268
269unsigned char logo_bmp_1024[] =
270{
271#include "logo_1024_768_8bpp.c"
272};
273
274
275/*
276 * include common lcd code (for esd boards)
277 */
278#include "../common/lcd.c"
279
280#include "../common/s1d13704_320_240_4bpp.h"
281#include "../common/s1d13705_320_240_8bpp.h"
282#include "../common/s1d13806_640_480_16bpp.h"
283#include "../common/s1d13806_1024_768_8bpp.h"
284
285
286/*
287 * include common auto-update code (for esd boards)
288 */
289#include "../common/auto_update.h"
290
291au_image_t au_image[] = {
292 {"hh405/preinst.img", 0, -1, AU_SCRIPT},
293 {"hh405/u-boot.img", 0xfff80000, 0x00080000, AU_FIRMWARE},
Wolfgang Denkfe126d82005-11-20 21:40:11 +0100294 {"hh405/pImage_${bd_type}", 0x00000000, 0x00100000, AU_NAND},
stroese1f54ce62004-12-16 18:23:14 +0000295 {"hh405/pImage.initrd", 0x00100000, 0x00200000, AU_NAND},
296 {"hh405/yaffsmt2.img", 0x00300000, 0x01c00000, AU_NAND},
297 {"hh405/postinst.img", 0, 0, AU_SCRIPT},
298};
299
300int N_AU_IMAGES = (sizeof(au_image) / sizeof(au_image[0]));
301
302
Stefan Roese48a05a52006-02-07 16:51:04 +0100303/*
304 * Get version of HH405 board from GPIO's
305 */
stroese1f54ce62004-12-16 18:23:14 +0000306int board_revision(void)
307{
308 unsigned long osrh_reg;
309 unsigned long isr1h_reg;
310 unsigned long tcr_reg;
311 unsigned long value;
312
313 /*
stroese1f54ce62004-12-16 18:23:14 +0000314 * Setup GPIO pins (BLAST/GPIO0 and GPIO9 as GPIO)
315 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100316 osrh_reg = in_be32((void *)GPIO0_OSRH);
317 isr1h_reg = in_be32((void *)GPIO0_ISR1H);
318 tcr_reg = in_be32((void *)GPIO0_TCR);
319 out_be32((void *)GPIO0_OSRH, osrh_reg & ~0xC0003000); /* output select */
320 out_be32((void *)GPIO0_ISR1H, isr1h_reg | 0xC0003000); /* input select */
321 out_be32((void *)GPIO0_TCR, tcr_reg & ~0x80400000); /* select input */
stroese1f54ce62004-12-16 18:23:14 +0000322
323 udelay(1000); /* wait some time before reading input */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100324 value = in_be32((void *)GPIO0_IR) & 0x80400000; /* get config bits */
stroese1f54ce62004-12-16 18:23:14 +0000325
326 /*
327 * Restore GPIO settings
328 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100329 out_be32((void *)GPIO0_OSRH, osrh_reg); /* output select */
330 out_be32((void *)GPIO0_ISR1H, isr1h_reg); /* input select */
331 out_be32((void *)GPIO0_TCR, tcr_reg); /* enable output driver for outputs */
stroese1f54ce62004-12-16 18:23:14 +0000332
333 if (value & 0x80000000) {
334 /* Revision 1.0 or 1.1 detected */
Stefan Roese48a05a52006-02-07 16:51:04 +0100335 return 1;
stroese1f54ce62004-12-16 18:23:14 +0000336 } else {
337 if (value & 0x00400000) {
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200338 /* unused */
Stefan Roese48a05a52006-02-07 16:51:04 +0100339 return 3;
stroese1f54ce62004-12-16 18:23:14 +0000340 } else {
Stefan Roese48a05a52006-02-07 16:51:04 +0100341 return 2;
stroese1f54ce62004-12-16 18:23:14 +0000342 }
343 }
344}
345
346
347int board_early_init_f (void)
348{
349 /*
350 * IRQ 0-15 405GP internally generated; active high; level sensitive
351 * IRQ 16 405GP internally generated; active low; level sensitive
352 * IRQ 17-24 RESERVED
353 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
354 * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
355 * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
356 * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
357 * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
358 * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
359 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
360 */
Stefan Roese952e7762009-09-24 09:55:50 +0200361 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
362 mtdcr(UIC0ER, 0x00000000); /* disable all ints */
363 mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical*/
364 mtdcr(UIC0PR, CONFIG_SYS_UIC0_POLARITY);/* set int polarities */
365 mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
366 mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority*/
367 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
stroese1f54ce62004-12-16 18:23:14 +0000368
369 /*
370 * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
371 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200372 mtebc(EBC0_CFG, 0xa8400000); /* ebc always driven */
stroese1f54ce62004-12-16 18:23:14 +0000373
374 return 0;
375}
376
Stefan Roese48a05a52006-02-07 16:51:04 +0100377int cf_enable(void)
378{
Stefan Roese48a05a52006-02-07 16:51:04 +0100379 int i;
380
Stefan Roese48a05a52006-02-07 16:51:04 +0100381 if (gd->board_type >= 2) {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100382 if (in_be16(FPGA_STATUS) & FPGA_STATUS_CF_DETECT) {
383 if (!(in_be16(FPGA_CTRL) & FPGA_CTRL_CF_BUS_EN)) {
384 out_be16(FPGA_CTRL,
385 in_be16(FPGA_CTRL) & ~FPGA_CTRL_CF_PWRN);
Stefan Roese48a05a52006-02-07 16:51:04 +0100386
387 for (i=0; i<300; i++)
388 udelay(1000);
389
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100390 out_be16(FPGA_CTRL,
391 in_be16(FPGA_CTRL) | FPGA_CTRL_CF_BUS_EN);
Stefan Roese48a05a52006-02-07 16:51:04 +0100392
393 for (i=0; i<20; i++)
394 udelay(1000);
395 }
396 } else {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100397 out_be16(FPGA_CTRL,
398 in_be16(FPGA_CTRL) & ~FPGA_CTRL_CF_BUS_EN);
399 out_be16(FPGA_CTRL,
400 in_be16(FPGA_CTRL) | FPGA_CTRL_CF_PWRN);
Stefan Roese48a05a52006-02-07 16:51:04 +0100401 }
402 }
403
404 return 0;
405}
stroese1f54ce62004-12-16 18:23:14 +0000406
407int misc_init_r (void)
408{
stroese1f54ce62004-12-16 18:23:14 +0000409 unsigned char *dst;
410 ulong len = sizeof(fpgadata);
411 int status;
412 int index;
413 int i;
414 char *str;
415 unsigned long contrast0 = 0xffffffff;
416
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200417 dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
418 if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
stroese1f54ce62004-12-16 18:23:14 +0000419 printf ("GUNZIP ERROR - must RESET board to recover\n");
420 do_reset (NULL, 0, 0, NULL);
421 }
422
423 status = fpga_boot(dst, len);
424 if (status != 0) {
425 printf("\nFPGA: Booting failed ");
426 switch (status) {
427 case ERROR_FPGA_PRG_INIT_LOW:
428 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
429 break;
430 case ERROR_FPGA_PRG_INIT_HIGH:
431 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
432 break;
433 case ERROR_FPGA_PRG_DONE:
434 printf("(Timeout: DONE not high after programming FPGA)\n ");
435 break;
436 }
437
438 /* display infos on fpgaimage */
439 index = 15;
440 for (i=0; i<4; i++) {
441 len = dst[index];
442 printf("FPGA: %s\n", &(dst[index+1]));
443 index += len+3;
444 }
445 putc ('\n');
446 /* delayed reboot */
447 for (i=20; i>0; i--) {
448 printf("Rebooting in %2d seconds \r",i);
449 for (index=0;index<1000;index++)
450 udelay(1000);
451 }
452 putc ('\n');
453 do_reset(NULL, 0, 0, NULL);
454 }
455
456 puts("FPGA: ");
457
458 /* display infos on fpgaimage */
459 index = 15;
460 for (i=0; i<4; i++) {
461 len = dst[index];
462 printf("%s ", &(dst[index+1]));
463 index += len+3;
464 }
465 putc ('\n');
466
467 free(dst);
468
469 /*
470 * Reset FPGA via FPGA_INIT pin
471 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100472 /* setup FPGA_INIT as output */
473 out_be32((void *)GPIO0_TCR,
474 in_be32((void *)GPIO0_TCR) | FPGA_INIT);
475 out_be32((void *)GPIO0_OR,
476 in_be32((void *)GPIO0_OR) & ~FPGA_INIT); /* reset low */
stroese1f54ce62004-12-16 18:23:14 +0000477 udelay(1000); /* wait 1ms */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100478 out_be32((void *)GPIO0_OR,
479 in_be32((void *)GPIO0_OR) | FPGA_INIT); /* reset high */
stroese1f54ce62004-12-16 18:23:14 +0000480 udelay(1000); /* wait 1ms */
481
482 /*
483 * Write Board revision into FPGA
484 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100485 out_be16(FPGA_CTRL, in_be16(FPGA_CTRL) | (gd->board_type & 0x0003));
stroese1f54ce62004-12-16 18:23:14 +0000486
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200487 /*
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200488 * Setup and enable EEPROM write protection
489 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100490 out_be32((void *)GPIO0_OR,
491 in_be32((void *)GPIO0_OR) | CONFIG_SYS_EEPROM_WP);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200492
stroese1f54ce62004-12-16 18:23:14 +0000493 /*
stroese1f54ce62004-12-16 18:23:14 +0000494 * Reset touch-screen controller
495 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100496 out_be32((void *)GPIO0_OR,
497 in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_TOUCH_RST);
stroese1f54ce62004-12-16 18:23:14 +0000498 udelay(1000);
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100499 out_be32((void *)GPIO0_OR,
500 in_be32((void *)GPIO0_OR) | CONFIG_SYS_TOUCH_RST);
stroese1f54ce62004-12-16 18:23:14 +0000501
wdenkefe2a4d2004-12-16 21:44:03 +0000502 /*
503 * Enable power on PS/2 interface (with reset)
504 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100505 out_be16(FPGA_CTRL, in_be16(FPGA_CTRL) & ~FPGA_CTRL_PS2_PWR);
wdenkefe2a4d2004-12-16 21:44:03 +0000506 for (i=0;i<500;i++)
507 udelay(1000);
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100508 out_be16(FPGA_CTRL, in_be16(FPGA_CTRL) | FPGA_CTRL_PS2_PWR);
stroese1f54ce62004-12-16 18:23:14 +0000509
510 /*
511 * Get contrast value from environment variable
512 */
513 str = getenv("contrast0");
514 if (str) {
515 contrast0 = simple_strtol(str, NULL, 16);
516 if (contrast0 > 255) {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100517 printf("ERROR: contrast0 value too high (0x%lx)!\n",
518 contrast0);
Stefan Roese48a05a52006-02-07 16:51:04 +0100519 contrast0 = 0xffffffff;
stroese1f54ce62004-12-16 18:23:14 +0000520 }
521 }
522
523 /*
524 * Init lcd interface and display logo
525 */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200526
stroese1f54ce62004-12-16 18:23:14 +0000527 str = getenv("bd_type");
528 if (strcmp(str, "ppc230") == 0) {
529 /*
530 * Switch backlight on
531 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100532 out_be16(FPGA_CTRL,
533 in_be16(FPGA_CTRL) | FPGA_CTRL_VGA0_BL);
534 out_be16(FPGA_BL, 0x0000);
stroese1f54ce62004-12-16 18:23:14 +0000535
536 lcd_setup(1, 0);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200537 lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM,
stroese1f54ce62004-12-16 18:23:14 +0000538 regs_13806_1024_768_8bpp,
539 sizeof(regs_13806_1024_768_8bpp)/sizeof(regs_13806_1024_768_8bpp[0]),
540 logo_bmp_1024, sizeof(logo_bmp_1024));
541 } else if (strcmp(str, "ppc220") == 0) {
542 /*
543 * Switch backlight on
544 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100545 out_be16(FPGA_CTRL,
546 in_be16(FPGA_CTRL) & ~FPGA_CTRL_VGA0_BL);
547 out_be16(FPGA_BL, 0x0000);
stroese1f54ce62004-12-16 18:23:14 +0000548
549 lcd_setup(1, 0);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200550 lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM,
stroese1f54ce62004-12-16 18:23:14 +0000551 regs_13806_640_480_16bpp,
552 sizeof(regs_13806_640_480_16bpp)/sizeof(regs_13806_640_480_16bpp[0]),
553 logo_bmp_640, sizeof(logo_bmp_640));
554 } else if (strcmp(str, "ppc215") == 0) {
555 /*
556 * Set default display contrast voltage
557 */
558 if (contrast0 == 0xffffffff) {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100559 out_be16(FPGA_CTR, 0x0082);
stroese1f54ce62004-12-16 18:23:14 +0000560 } else {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100561 out_be16(FPGA_CTR, contrast0);
stroese1f54ce62004-12-16 18:23:14 +0000562 }
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100563 out_be16(FPGA_BL, 0xffff);
stroese1f54ce62004-12-16 18:23:14 +0000564 /*
565 * Switch backlight on
566 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100567 out_be16(FPGA_CTRL,
568 in_be16(FPGA_CTRL) |
569 FPGA_CTRL_VGA0_BL |
570 FPGA_CTRL_VGA0_BL_MODE);
stroese1f54ce62004-12-16 18:23:14 +0000571 /*
572 * Set lcd clock (small epson)
573 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100574 out_be16(FPGA_CTRL, in_be16(FPGA_CTRL) | LCD_CLK_06250);
stroese1f54ce62004-12-16 18:23:14 +0000575 udelay(100); /* wait for 100 us */
576
577 lcd_setup(0, 1);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200578 lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM,
stroese1f54ce62004-12-16 18:23:14 +0000579 regs_13705_320_240_8bpp,
580 sizeof(regs_13705_320_240_8bpp)/sizeof(regs_13705_320_240_8bpp[0]),
581 logo_bmp_320_8bpp, sizeof(logo_bmp_320_8bpp));
582 } else if (strcmp(str, "ppc210") == 0) {
583 /*
584 * Set default display contrast voltage
585 */
586 if (contrast0 == 0xffffffff) {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100587 out_be16(FPGA_CTR, 0x0060);
stroese1f54ce62004-12-16 18:23:14 +0000588 } else {
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100589 out_be16(FPGA_CTR, contrast0);
stroese1f54ce62004-12-16 18:23:14 +0000590 }
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100591 out_be16(FPGA_BL, 0xffff);
stroese1f54ce62004-12-16 18:23:14 +0000592 /*
593 * Switch backlight on
594 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100595 out_be16(FPGA_CTRL,
596 in_be16(FPGA_CTRL) |
597 FPGA_CTRL_VGA0_BL |
598 FPGA_CTRL_VGA0_BL_MODE);
stroese1f54ce62004-12-16 18:23:14 +0000599 /*
Stefan Roese48a05a52006-02-07 16:51:04 +0100600 * Set lcd clock (small epson), enable 1-wire interface
stroese1f54ce62004-12-16 18:23:14 +0000601 */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100602 out_be16(FPGA_CTRL,
603 in_be16(FPGA_CTRL) |
604 LCD_CLK_08330 |
605 FPGA_CTRL_OW_ENABLE);
stroese1f54ce62004-12-16 18:23:14 +0000606
607 lcd_setup(0, 1);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200608 lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM,
stroese1f54ce62004-12-16 18:23:14 +0000609 regs_13704_320_240_4bpp,
610 sizeof(regs_13704_320_240_4bpp)/sizeof(regs_13704_320_240_4bpp[0]),
611 logo_bmp_320, sizeof(logo_bmp_320));
Stefan Roese2c7b2ab2005-09-30 16:41:12 +0200612#ifdef CONFIG_VIDEO_SM501
stroese1f54ce62004-12-16 18:23:14 +0000613 } else {
Stefan Roese2c7b2ab2005-09-30 16:41:12 +0200614 pci_dev_t devbusfn;
615
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200616 /*
617 * Is SM501 connected (ppc221/ppc231)?
618 */
619 devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0);
620 if (devbusfn != -1) {
621 puts("VGA: SM501 with 8 MB ");
622 if (strcmp(str, "ppc221") == 0) {
623 printf("(800*600, %dbpp)\n", BPP);
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100624 out_be16(FPGA_BL, 0x002d); /* max. allowed brightness */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200625 } else if (strcmp(str, "ppc231") == 0) {
626 printf("(1024*768, %dbpp)\n", BPP);
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100627 out_be16(FPGA_BL, 0x0000);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200628 } else {
629 printf("Unsupported bd_type defined (%s) -> No display configured!\n", str);
630 return 0;
631 }
632 } else {
633 printf("Unsupported bd_type defined (%s) -> No display configured!\n", str);
634 return 0;
635 }
Stefan Roese2c7b2ab2005-09-30 16:41:12 +0200636#endif /* CONFIG_VIDEO_SM501 */
stroese1f54ce62004-12-16 18:23:14 +0000637 }
638
Stefan Roese48a05a52006-02-07 16:51:04 +0100639 cf_enable();
640
stroese1f54ce62004-12-16 18:23:14 +0000641 return (0);
642}
643
644
645/*
646 * Check Board Identity:
647 */
648
649int checkboard (void)
650{
Stefan Roese18c5e642006-01-18 20:06:44 +0100651 char str[64];
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200652 int i = getenv_f("serial#", str, sizeof(str));
stroese1f54ce62004-12-16 18:23:14 +0000653
654 puts ("Board: ");
655
656 if (i == -1) {
657 puts ("### No HW ID - assuming HH405");
658 } else {
659 puts(str);
660 }
661
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200662 if (getenv_f("bd_type", str, sizeof(str)) != -1) {
stroese1f54ce62004-12-16 18:23:14 +0000663 printf(" (%s", str);
664 } else {
665 puts(" (Missing bd_type!");
666 }
667
668 gd->board_type = board_revision();
Stefan Roese48a05a52006-02-07 16:51:04 +0100669 printf(", Rev %ld.x)\n", gd->board_type);
stroese1f54ce62004-12-16 18:23:14 +0000670
671 return 0;
672}
673
stroese1f54ce62004-12-16 18:23:14 +0000674#ifdef CONFIG_IDE_RESET
675void ide_set_reset(int on)
676{
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100677 if (((gd->board_type >= 2) &&
678 (in_be16(FPGA_STATUS) & FPGA_STATUS_CF_DETECT)) ||
Stefan Roese48a05a52006-02-07 16:51:04 +0100679 (gd->board_type < 2)) {
680 /*
681 * Assert or deassert CompactFlash Reset Pin
682 */
683 if (on) { /* assert RESET */
684 cf_enable();
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100685 out_be16(FPGA_CTRL,
686 in_be16(FPGA_CTRL) &
687 ~FPGA_CTRL_CF_RESET);
Stefan Roese48a05a52006-02-07 16:51:04 +0100688 } else { /* release RESET */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100689 out_be16(FPGA_CTRL,
690 in_be16(FPGA_CTRL) |
691 FPGA_CTRL_CF_RESET);
Stefan Roese48a05a52006-02-07 16:51:04 +0100692 }
stroese1f54ce62004-12-16 18:23:14 +0000693 }
694}
695#endif /* CONFIG_IDE_RESET */
696
697
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200698#if defined(CONFIG_SYS_EEPROM_WREN)
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200699/* Input: <dev_addr> I2C address of EEPROM device to enable.
700 * <state> -1: deliver current state
701 * 0: disable write
702 * 1: enable write
703 * Returns: -1: wrong device address
704 * 0: dis-/en- able done
705 * 0/1: current state if <state> was -1.
706 */
707int eeprom_write_enable (unsigned dev_addr, int state)
708{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200709 if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) {
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200710 return -1;
711 } else {
712 switch (state) {
713 case 1:
714 /* Enable write access, clear bit GPIO_SINT2. */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100715 out_be32((void *)GPIO0_OR,
716 in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_EEPROM_WP);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200717 state = 0;
718 break;
719 case 0:
720 /* Disable write access, set bit GPIO_SINT2. */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100721 out_be32((void *)GPIO0_OR,
722 in_be32((void *)GPIO0_OR) | CONFIG_SYS_EEPROM_WP);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200723 state = 0;
724 break;
725 default:
726 /* Read current status back. */
Matthias Fuchsbb57ad42009-02-20 10:19:19 +0100727 state = (0 == (in_be32((void *)GPIO0_OR) &
728 CONFIG_SYS_EEPROM_WP));
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200729 break;
730 }
731 }
732 return state;
733}
734
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200735int do_eep_wren (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200736{
737 int query = argc == 1;
738 int state = 0;
739
740 if (query) {
741 /* Query write access state. */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200742 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, -1);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200743 if (state < 0) {
744 puts ("Query of write access state failed.\n");
745 } else {
746 printf ("Write access for device 0x%0x is %sabled.\n",
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200747 CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis");
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200748 state = 0;
749 }
750 } else {
751 if ('0' == argv[1][0]) {
752 /* Disable write access. */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200753 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 0);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200754 } else {
755 /* Enable write access. */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200756 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 1);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200757 }
758 if (state < 0) {
759 puts ("Setup of write access state failed.\n");
760 }
761 }
762
763 return state;
764}
765
766U_BOOT_CMD(eepwren, 2, 0, do_eep_wren,
Wolfgang Denka89c33d2009-05-24 17:06:54 +0200767 "Enable / disable / query EEPROM write access",
768 ""
769);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200770#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200771
772
773#ifdef CONFIG_VIDEO_SM501
774#ifdef CONFIG_CONSOLE_EXTRA_INFO
775/*
776 * Return text to be printed besides the logo.
777 */
778void video_get_info_str (int line_number, char *info)
779{
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200780 char str[64];
781 char str2[64];
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200782 int i = getenv_f("serial#", str2, sizeof(str));
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200783
784 if (line_number == 1) {
785 sprintf(str, " Board: ");
786
787 if (i == -1) {
788 strcat(str, "### No HW ID - assuming HH405");
789 } else {
790 strcat(str, str2);
791 }
792
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200793 if (getenv_f("bd_type", str2, sizeof(str2)) != -1) {
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200794 strcat(str, " (");
795 strcat(str, str2);
796 } else {
797 strcat(str, " (Missing bd_type!");
798 }
799
Stefan Roese48a05a52006-02-07 16:51:04 +0100800 sprintf(str2, ", Rev %ld.x)", gd->board_type);
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200801 strcat(str, str2);
802 strcpy(info, str);
803 } else {
804 info [0] = '\0';
805 }
806}
807#endif /* CONFIG_CONSOLE_EXTRA_INFO */
808
809/*
810 * Returns SM501 register base address. First thing called in the driver.
811 */
812unsigned int board_video_init (void)
813{
814 pci_dev_t devbusfn;
815 u32 addr;
816
817 /*
818 * Is SM501 connected (ppc221/ppc231)?
819 */
820 devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0);
821 if (devbusfn != -1) {
822 pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, (u32 *)&addr);
823 return (addr & 0xfffffffe);
824 }
825
826 return 0;
827}
828
829/*
830 * Returns SM501 framebuffer address
831 */
832unsigned int board_video_get_fb (void)
833{
834 pci_dev_t devbusfn;
835 u32 addr;
836
837 /*
838 * Is SM501 connected (ppc221/ppc231)?
839 */
840 devbusfn = pci_find_device(PCI_VENDOR_SM, PCI_DEVICE_SM501, 0);
841 if (devbusfn != -1) {
842 pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, (u32 *)&addr);
Stefan Roese48a05a52006-02-07 16:51:04 +0100843 addr &= 0xfffffffe;
844#ifdef CONFIG_VIDEO_SM501_FBMEM_OFFSET
845 addr += CONFIG_VIDEO_SM501_FBMEM_OFFSET;
846#endif
847 return addr;
Stefan Roese98f4a3d2005-09-22 09:04:17 +0200848 }
849
850 return 0;
851}
852
853/*
854 * Called after initializing the SM501 and before clearing the screen.
855 */
856void board_validate_screen (unsigned int base)
857{
858}
859
860/*
861 * Return a pointer to the initialization sequence.
862 */
863const SMI_REGS *board_get_regs (void)
864{
865 char *str;
866
867 str = getenv("bd_type");
868 if (strcmp(str, "ppc221") == 0) {
869 return init_regs_800x600;
870 } else {
871 return init_regs_1024x768;
872 }
873}
874
875int board_get_width (void)
876{
877 char *str;
878
879 str = getenv("bd_type");
880 if (strcmp(str, "ppc221") == 0) {
881 return 800;
882 } else {
883 return 1024;
884 }
885}
886
887int board_get_height (void)
888{
889 char *str;
890
891 str = getenv("bd_type");
892 if (strcmp(str, "ppc221") == 0) {
893 return 600;
894 } else {
895 return 768;
896 }
897}
898
899#endif /* CONFIG_VIDEO_SM501 */
Stefan Roese48a05a52006-02-07 16:51:04 +0100900
901
902void reset_phy(void)
903{
904#ifdef CONFIG_LXT971_NO_SLEEP
905
906 /*
907 * Disable sleep mode in LXT971
908 */
909 lxt971_no_sleep();
910#endif
911}