blob: 3cc2206b47b9d8d526560bd9f442e8a483e47b19 [file] [log] [blame]
stroesebe467a12003-09-12 08:42:13 +00001/*
stroese80be1db2004-12-16 18:41:27 +00002 * (C) Copyright 2001-2004
stroesebe467a12003-09-12 08:42:13 +00003 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
stroesebe467a12003-09-12 08:42:13 +00006 */
7
8#include <common.h>
Matthias Fuchs72cb5012007-12-28 17:10:42 +01009#include <asm/io.h>
stroesebe467a12003-09-12 08:42:13 +000010#include <asm/processor.h>
11#include <command.h>
12#include <malloc.h>
13
14/* ------------------------------------------------------------------------- */
15
16#if 0
17#define FPGA_DEBUG
18#endif
19
stroese80be1db2004-12-16 18:41:27 +000020extern void lxt971_no_sleep(void);
stroesebe467a12003-09-12 08:42:13 +000021
22/* fpga configuration data - gzip compressed and generated by bin2c */
23const unsigned char fpgadata[] =
24{
25#include "fpgadata.c"
26};
27
28/*
29 * include common fpga code (for esd boards)
30 */
31#include "../common/fpga.c"
32
33
stroese80be1db2004-12-16 18:41:27 +000034/* logo bitmap data - gzip compressed and generated by bin2c */
35unsigned char logo_bmp_320[] =
36{
37#include "logo_320_240_4bpp.c"
38};
39
40unsigned char logo_bmp_640[] =
41{
42#include "logo_640_480_24bpp.c"
43};
44
45
46/*
47 * include common lcd code (for esd boards)
48 */
49#include "../common/lcd.c"
50
51#include "../common/s1d13704_320_240_4bpp.h"
52#include "../common/s1d13806_320_240_4bpp.h"
53#include "../common/s1d13806_640_480_16bpp.h"
54
55
wdenkda55c6e2004-01-20 23:12:12 +000056int board_early_init_f (void)
stroesebe467a12003-09-12 08:42:13 +000057{
58 /*
59 * IRQ 0-15 405GP internally generated; active high; level sensitive
60 * IRQ 16 405GP internally generated; active low; level sensitive
61 * IRQ 17-24 RESERVED
62 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
63 * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
64 * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
65 * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
66 * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
67 * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
68 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
69 */
Stefan Roese707fd362009-09-24 09:55:50 +020070 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
71 mtdcr(UIC0ER, 0x00000000); /* disable all ints */
72 mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical*/
73 mtdcr(UIC0PR, 0xFFFFFFB5); /* set int polarities */
74 mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
75 mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority*/
76 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
stroesebe467a12003-09-12 08:42:13 +000077
78 /*
79 * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
80 */
Stefan Roese918010a2009-09-09 16:25:29 +020081 mtebc (EBC0_CFG, 0xa8400000); /* ebc always driven */
stroesebe467a12003-09-12 08:42:13 +000082
83 return 0;
84}
85
stroesebe467a12003-09-12 08:42:13 +000086int misc_init_r (void)
87{
Matthias Fuchs72cb5012007-12-28 17:10:42 +010088 unsigned char *duart0_mcr = (unsigned char *)((ulong)DUART0_BA + 4);
89 unsigned char *duart1_mcr = (unsigned char *)((ulong)DUART1_BA + 4);
90 unsigned short *lcd_contrast =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020091 (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 4);
Matthias Fuchs72cb5012007-12-28 17:10:42 +010092 unsigned short *lcd_backlight =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020093 (unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL + 6);
stroesebe467a12003-09-12 08:42:13 +000094 unsigned char *dst;
95 ulong len = sizeof(fpgadata);
96 int status;
97 int index;
98 int i;
stroese80be1db2004-12-16 18:41:27 +000099 char *str;
stroesebe467a12003-09-12 08:42:13 +0000100
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200101 dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
102 if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
stroesebe467a12003-09-12 08:42:13 +0000103 printf ("GUNZIP ERROR - must RESET board to recover\n");
104 do_reset (NULL, 0, 0, NULL);
105 }
106
107 status = fpga_boot(dst, len);
108 if (status != 0) {
109 printf("\nFPGA: Booting failed ");
110 switch (status) {
111 case ERROR_FPGA_PRG_INIT_LOW:
112 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
113 break;
114 case ERROR_FPGA_PRG_INIT_HIGH:
115 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
116 break;
117 case ERROR_FPGA_PRG_DONE:
118 printf("(Timeout: DONE not high after programming FPGA)\n ");
119 break;
120 }
121
122 /* display infos on fpgaimage */
123 index = 15;
124 for (i=0; i<4; i++) {
125 len = dst[index];
126 printf("FPGA: %s\n", &(dst[index+1]));
127 index += len+3;
128 }
129 putc ('\n');
130 /* delayed reboot */
131 for (i=20; i>0; i--) {
132 printf("Rebooting in %2d seconds \r",i);
133 for (index=0;index<1000;index++)
134 udelay(1000);
135 }
136 putc ('\n');
137 do_reset(NULL, 0, 0, NULL);
138 }
139
140 puts("FPGA: ");
141
142 /* display infos on fpgaimage */
143 index = 15;
144 for (i=0; i<4; i++) {
145 len = dst[index];
146 printf("%s ", &(dst[index+1]));
147 index += len+3;
148 }
149 putc ('\n');
150
151 free(dst);
152
153 /*
stroese80be1db2004-12-16 18:41:27 +0000154 * Reset FPGA via FPGA_INIT pin
stroesebe467a12003-09-12 08:42:13 +0000155 */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100156 out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) | FPGA_INIT); /* setup FPGA_INIT as output */
157 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~FPGA_INIT); /* reset low */
stroesebe467a12003-09-12 08:42:13 +0000158 udelay(1000); /* wait 1ms */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100159 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | FPGA_INIT); /* reset high */
stroesebe467a12003-09-12 08:42:13 +0000160 udelay(1000); /* wait 1ms */
161
162 /*
163 * Reset external DUARTs
164 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200165 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_DUART_RST); /* set reset to high */
stroesebe467a12003-09-12 08:42:13 +0000166 udelay(10); /* wait 10us */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200167 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_DUART_RST); /* set reset to low */
stroesebe467a12003-09-12 08:42:13 +0000168 udelay(1000); /* wait 1ms */
169
170 /*
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100171 * Set NAND-FLASH GPIO signals to default
172 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200173 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE));
174 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_NAND_CE);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100175
176 /*
177 * Setup EEPROM write protection
178 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200179 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_EEPROM_WP);
180 out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) | CONFIG_SYS_EEPROM_WP);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100181
182 /*
stroesebe467a12003-09-12 08:42:13 +0000183 * Enable interrupts in exar duart mcr[3]
184 */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100185 out_8(duart0_mcr, 0x08);
186 out_8(duart1_mcr, 0x08);
stroesebe467a12003-09-12 08:42:13 +0000187
188 /*
stroese80be1db2004-12-16 18:41:27 +0000189 * Init lcd interface and display logo
190 */
191 str = getenv("bd_type");
192 if (strcmp(str, "voh405_bw") == 0) {
193 lcd_setup(0, 1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200194 lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM,
stroese80be1db2004-12-16 18:41:27 +0000195 regs_13704_320_240_4bpp,
196 sizeof(regs_13704_320_240_4bpp)/sizeof(regs_13704_320_240_4bpp[0]),
197 logo_bmp_320, sizeof(logo_bmp_320));
198 } else if (strcmp(str, "voh405_bwbw") == 0) {
199 lcd_setup(0, 1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200200 lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM,
stroese80be1db2004-12-16 18:41:27 +0000201 regs_13704_320_240_4bpp,
202 sizeof(regs_13704_320_240_4bpp)/sizeof(regs_13704_320_240_4bpp[0]),
203 logo_bmp_320, sizeof(logo_bmp_320));
204 lcd_setup(1, 1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200205 lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM,
stroese80be1db2004-12-16 18:41:27 +0000206 regs_13806_320_240_4bpp,
207 sizeof(regs_13806_320_240_4bpp)/sizeof(regs_13806_320_240_4bpp[0]),
208 logo_bmp_320, sizeof(logo_bmp_320));
209 } else if (strcmp(str, "voh405_bwc") == 0) {
210 lcd_setup(0, 1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200211 lcd_init((uchar *)CONFIG_SYS_LCD_SMALL_REG, (uchar *)CONFIG_SYS_LCD_SMALL_MEM,
stroese80be1db2004-12-16 18:41:27 +0000212 regs_13704_320_240_4bpp,
213 sizeof(regs_13704_320_240_4bpp)/sizeof(regs_13704_320_240_4bpp[0]),
214 logo_bmp_320, sizeof(logo_bmp_320));
215 lcd_setup(1, 0);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200216 lcd_init((uchar *)CONFIG_SYS_LCD_BIG_REG, (uchar *)CONFIG_SYS_LCD_BIG_MEM,
stroese80be1db2004-12-16 18:41:27 +0000217 regs_13806_640_480_16bpp,
218 sizeof(regs_13806_640_480_16bpp)/sizeof(regs_13806_640_480_16bpp[0]),
219 logo_bmp_640, sizeof(logo_bmp_640));
220 } else {
221 printf("Unsupported bd_type defined (%s) -> No display configured!\n", str);
222 return 0;
223 }
224
225 /*
226 * Set invert bit in small lcd controller
227 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200228 out_8((unsigned char *)(CONFIG_SYS_LCD_SMALL_REG + 2),
229 in_8((unsigned char *)(CONFIG_SYS_LCD_SMALL_REG + 2)) | 0x01);
stroese80be1db2004-12-16 18:41:27 +0000230
231 /*
stroesebe467a12003-09-12 08:42:13 +0000232 * Set default contrast voltage on epson vga controller
233 */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100234 out_be16(lcd_contrast, 0x4646);
stroese80be1db2004-12-16 18:41:27 +0000235
236 /*
237 * Enable backlight
238 */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100239 out_be16(lcd_backlight, 0xffff);
240
241 /*
242 * Enable external I2C bus
243 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200244 out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) | CONFIG_SYS_IIC_ON);
stroesebe467a12003-09-12 08:42:13 +0000245
246 return (0);
247}
248
249
250/*
251 * Check Board Identity:
252 */
253
254int checkboard (void)
255{
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200256 char str[64];
Wolfgang Denk76af2782010-07-24 21:55:43 +0200257 int i = getenv_f("serial#", str, sizeof(str));
stroesebe467a12003-09-12 08:42:13 +0000258
259 puts ("Board: ");
260
261 if (i == -1) {
262 puts ("### No HW ID - assuming VOH405");
263 } else {
264 puts(str);
265 }
266
Wolfgang Denk76af2782010-07-24 21:55:43 +0200267 if (getenv_f("bd_type", str, sizeof(str)) != -1) {
stroese80be1db2004-12-16 18:41:27 +0000268 printf(" (%s)", str);
269 } else {
270 puts(" (Missing bd_type!)");
271 }
272
stroesebe467a12003-09-12 08:42:13 +0000273 putc ('\n');
274
stroesebe467a12003-09-12 08:42:13 +0000275 return 0;
276}
277
stroesebe467a12003-09-12 08:42:13 +0000278#ifdef CONFIG_IDE_RESET
Matthias Fuchs5dde4e22009-02-20 10:19:19 +0100279#define FPGA_MODE (CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL)
stroesebe467a12003-09-12 08:42:13 +0000280void ide_set_reset(int on)
281{
stroesebe467a12003-09-12 08:42:13 +0000282 /*
283 * Assert or deassert CompactFlash Reset Pin
284 */
285 if (on) { /* assert RESET */
Matthias Fuchs5dde4e22009-02-20 10:19:19 +0100286 out_be16((void *)FPGA_MODE,
287 in_be16((void *)FPGA_MODE) & ~CONFIG_SYS_FPGA_CTRL_CF_RESET);
stroesebe467a12003-09-12 08:42:13 +0000288 } else { /* release RESET */
Matthias Fuchs5dde4e22009-02-20 10:19:19 +0100289 out_be16((void *)FPGA_MODE,
290 in_be16((void *)FPGA_MODE) | CONFIG_SYS_FPGA_CTRL_CF_RESET);
stroesebe467a12003-09-12 08:42:13 +0000291 }
292}
293#endif /* CONFIG_IDE_RESET */
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100294
295#if defined(CONFIG_RESET_PHY_R)
296void reset_phy(void)
297{
298#ifdef CONFIG_LXT971_NO_SLEEP
299
300 /*
301 * Disable sleep mode in LXT971
302 */
303 lxt971_no_sleep();
304#endif
305}
306#endif
307
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200308#if defined(CONFIG_SYS_EEPROM_WREN)
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100309/* Input: <dev_addr> I2C address of EEPROM device to enable.
310 * <state> -1: deliver current state
311 * 0: disable write
312 * 1: enable write
313 * Returns: -1: wrong device address
314 * 0: dis-/en- able done
315 * 0/1: current state if <state> was -1.
316 */
317int eeprom_write_enable (unsigned dev_addr, int state)
318{
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200319 if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) {
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100320 return -1;
321 } else {
322 switch (state) {
323 case 1:
324 /* Enable write access, clear bit GPIO0. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200325 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_EEPROM_WP);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100326 state = 0;
327 break;
328 case 0:
329 /* Disable write access, set bit GPIO0. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200330 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_EEPROM_WP);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100331 state = 0;
332 break;
333 default:
334 /* Read current status back. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200335 state = (0 == (in_be32((void*)GPIO0_OR) & CONFIG_SYS_EEPROM_WP));
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100336 break;
337 }
338 }
339 return state;
340}
341
Wolfgang Denk6262d0212010-06-28 22:00:46 +0200342int do_eep_wren (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100343{
344 int query = argc == 1;
345 int state = 0;
346
347 if (query) {
348 /* Query write access state. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200349 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, -1);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100350 if (state < 0) {
351 puts ("Query of write access state failed.\n");
352 } else {
353 printf ("Write access for device 0x%0x is %sabled.\n",
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200354 CONFIG_SYS_I2C_EEPROM_ADDR, state ? "en" : "dis");
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100355 state = 0;
356 }
357 } else {
358 if ('0' == argv[1][0]) {
359 /* Disable write access. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200360 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 0);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100361 } else {
362 /* Enable write access. */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200363 state = eeprom_write_enable (CONFIG_SYS_I2C_EEPROM_ADDR, 1);
Matthias Fuchs72cb5012007-12-28 17:10:42 +0100364 }
365 if (state < 0) {
366 puts ("Setup of write access state failed.\n");
367 }
368 }
369
370 return state;
371}
372
373U_BOOT_CMD(eepwren, 2, 0, do_eep_wren,
Wolfgang Denkc54781c2009-05-24 17:06:54 +0200374 "Enable / disable / query EEPROM write access",
375 ""
376);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200377#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */