PageRenderTime 30ms CodeModel.GetById 15ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/board/esd/plu405/plu405.c

https://gitlab.com/veo-labs/u-boot
C | 345 lines | 222 code | 41 blank | 82 comment | 28 complexity | c5570b4891d7046f88b8ab8d5c93bdff MD5 | raw file
  1/*
  2 * (C) Copyright 2001-2003
  3 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
  4 *
  5 * SPDX-License-Identifier:	GPL-2.0+
  6 */
  7
  8#include <common.h>
  9#include <asm/processor.h>
 10#include <asm/io.h>
 11#include <command.h>
 12#include <malloc.h>
 13#include <sja1000.h>
 14
 15#undef FPGA_DEBUG
 16
 17DECLARE_GLOBAL_DATA_PTR;
 18
 19extern void lxt971_no_sleep(void);
 20
 21/* fpga configuration data - gzip compressed and generated by bin2c */
 22const unsigned char fpgadata[] =
 23{
 24#include "fpgadata.c"
 25};
 26
 27/*
 28 * include common fpga code (for esd boards)
 29 */
 30#include "../common/fpga.c"
 31
 32/*
 33 * generate a short spike on the CAN tx line
 34 * to bring the couplers in sync
 35 */
 36void init_coupler(u32 addr)
 37{
 38	struct sja1000_basic_s *ctrl = (struct sja1000_basic_s *)addr;
 39
 40	/* reset */
 41	out_8(&ctrl->cr, CR_RR);
 42
 43	/* dominant */
 44	out_8(&ctrl->btr0, 0x00); /* btr setup is required */
 45	out_8(&ctrl->btr1, 0x14); /* we use 1Mbit/s */
 46	out_8(&ctrl->oc, OC_TP1 | OC_TN1 | OC_POL1 |
 47	      OC_TP0 | OC_TN0 | OC_POL0 | OC_MODE1);
 48	out_8(&ctrl->cr, 0x00);
 49
 50	/* delay */
 51	in_8(&ctrl->cr);
 52	in_8(&ctrl->cr);
 53	in_8(&ctrl->cr);
 54	in_8(&ctrl->cr);
 55
 56	/* reset */
 57	out_8(&ctrl->cr, CR_RR);
 58}
 59
 60int board_early_init_f(void)
 61{
 62	/*
 63	 * IRQ 0-15  405GP internally generated; active high; level sensitive
 64	 * IRQ 16    405GP internally generated; active low; level sensitive
 65	 * IRQ 17-24 RESERVED
 66	 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
 67	 * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
 68	 * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
 69	 * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
 70	 * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
 71	 * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
 72	 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
 73	 */
 74	mtdcr(UIC0SR, 0xFFFFFFFF);       /* clear all ints */
 75	mtdcr(UIC0ER, 0x00000000);       /* disable all ints */
 76	mtdcr(UIC0CR, 0x00000000);       /* set all to be non-critical*/
 77	mtdcr(UIC0PR, 0xFFFFFF99);       /* set int polarities */
 78	mtdcr(UIC0TR, 0x10000000);       /* set int trigger levels */
 79	mtdcr(UIC0VCR, 0x00000001);      /* set vect base=0,INT0 highest prio */
 80	mtdcr(UIC0SR, 0xFFFFFFFF);       /* clear all ints */
 81
 82	/*
 83	 * EBC Configuration Register: set ready timeout to
 84	 * 512 ebc-clks -> ca. 15 us
 85	 */
 86	mtebc(EBC0_CFG, 0xa8400000); /* ebc always driven */
 87
 88	return 0;
 89}
 90
 91int misc_init_r(void)
 92{
 93	unsigned char *dst;
 94	unsigned char fctr;
 95	ulong len = sizeof(fpgadata);
 96	int status;
 97	int index;
 98	int i;
 99
100	/* adjust flash start and offset */
101	gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
102	gd->bd->bi_flashoffset = 0;
103
104	dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
105	if (gunzip(dst, CONFIG_SYS_FPGA_MAX_SIZE,
106		   (uchar *)fpgadata, &len) != 0) {
107		printf("GUNZIP ERROR - must RESET board to recover\n");
108		do_reset(NULL, 0, 0, NULL);
109	}
110
111	status = fpga_boot(dst, len);
112	if (status != 0) {
113		printf("\nFPGA: Booting failed ");
114		switch (status) {
115		case ERROR_FPGA_PRG_INIT_LOW:
116			printf("(Timeout: INIT not low "
117			       "after asserting PROGRAM*)\n");
118			break;
119		case ERROR_FPGA_PRG_INIT_HIGH:
120			printf("(Timeout: INIT not high "
121			       "after deasserting PROGRAM*)\n");
122			break;
123		case ERROR_FPGA_PRG_DONE:
124			printf("(Timeout: DONE not high "
125			       "after programming FPGA)\n");
126			break;
127		}
128
129		/* display infos on fpgaimage */
130		index = 15;
131		for (i=0; i<4; i++) {
132			len = dst[index];
133			printf("FPGA: %s\n", &(dst[index+1]));
134			index += len+3;
135		}
136		putc ('\n');
137		/* delayed reboot */
138		for (i=20; i>0; i--) {
139			printf("Rebooting in %2d seconds \r",i);
140			for (index=0;index<1000;index++)
141				udelay(1000);
142		}
143		putc('\n');
144		do_reset(NULL, 0, 0, NULL);
145	}
146
147	puts("FPGA:  ");
148
149	/* display infos on fpgaimage */
150	index = 15;
151	for (i=0; i<4; i++) {
152		len = dst[index];
153		printf("%s ", &(dst[index+1]));
154		index += len+3;
155	}
156	putc('\n');
157
158	free(dst);
159
160	/*
161	 * Reset FPGA via FPGA_DATA pin
162	 */
163	SET_FPGA(FPGA_PRG | FPGA_CLK);
164	udelay(1000); /* wait 1ms */
165	SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
166	udelay(1000); /* wait 1ms */
167
168	/*
169	 * Reset external DUARTs
170	 */
171	out_be32((void*)GPIO0_OR,
172		 in_be32((void*)GPIO0_OR) | CONFIG_SYS_DUART_RST);
173	udelay(10);
174	out_be32((void*)GPIO0_OR,
175		 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_DUART_RST);
176	udelay(1000);
177
178	/*
179	 * Set NAND-FLASH GPIO signals to default
180	 */
181	out_be32((void*)GPIO0_OR,
182		 in_be32((void*)GPIO0_OR) &
183		 ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE));
184	out_be32((void*)GPIO0_OR,
185		 in_be32((void*)GPIO0_OR) | CONFIG_SYS_NAND_CE);
186
187	/*
188	 * Setup EEPROM write protection
189	 */
190	out_be32((void*)GPIO0_OR,
191		 in_be32((void*)GPIO0_OR) | CONFIG_SYS_EEPROM_WP);
192	out_be32((void*)GPIO0_TCR,
193		 in_be32((void*)GPIO0_TCR) | CONFIG_SYS_EEPROM_WP);
194
195	/*
196	 * Enable interrupts in exar duart mcr[3]
197	 */
198	out_8((void *)DUART0_BA + 4, 0x08);
199	out_8((void *)DUART1_BA + 4, 0x08);
200
201	/*
202	 * Enable auto RS485 mode in 2nd external uart
203	 */
204	out_8((void *)DUART1_BA + 3, 0xbf); /* write LCR */
205	fctr = in_8((void *)DUART1_BA + 1); /* read FCTR */
206	fctr |= 0x08;                       /* enable RS485 mode */
207	out_8((void *)DUART1_BA + 1, fctr); /* write FCTR */
208	out_8((void *)DUART1_BA + 3, 0);    /* write LCR */
209
210	/*
211	 * Init magnetic couplers
212	 */
213	if (!getenv("noinitcoupler")) {
214		init_coupler(CAN0_BA);
215		init_coupler(CAN1_BA);
216	}
217	return 0;
218}
219
220/*
221 * Check Board Identity:
222 */
223int checkboard(void)
224{
225	char str[64];
226	int i = getenv_f("serial#", str, sizeof(str));
227
228	puts("Board: ");
229
230	if (i == -1)
231		puts("### No HW ID - assuming PLU405");
232	else
233		puts(str);
234
235	putc('\n');
236	return 0;
237}
238
239#ifdef CONFIG_IDE_RESET
240#define FPGA_CTRL (CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL)
241void ide_set_reset(int on)
242{
243	/*
244	 * Assert or deassert CompactFlash Reset Pin
245	 */
246	if (on) {		/* assert RESET */
247		out_be16((void *)FPGA_CTRL,
248			 in_be16((void *)FPGA_CTRL) &
249			 ~CONFIG_SYS_FPGA_CTRL_CF_RESET);
250	} else {		/* release RESET */
251		out_be16((void *)FPGA_CTRL,
252			 in_be16((void *)FPGA_CTRL) |
253			 CONFIG_SYS_FPGA_CTRL_CF_RESET);
254	}
255}
256#endif /* CONFIG_IDE_RESET */
257
258void reset_phy(void)
259{
260#ifdef CONFIG_LXT971_NO_SLEEP
261
262	/*
263	 * Disable sleep mode in LXT971
264	 */
265	lxt971_no_sleep();
266#endif
267}
268
269#if defined(CONFIG_SYS_EEPROM_WREN)
270/* Input: <dev_addr>  I2C address of EEPROM device to enable.
271 *	       <state> -1: deliver current state
272 *			0: disable write
273 *			1: enable write
274 *  Returns:	       -1: wrong device address
275 *			0: dis-/en- able done
276 *		      0/1: current state if <state> was -1.
277 */
278int eeprom_write_enable(unsigned dev_addr, int state)
279{
280	if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) {
281		return -1;
282	} else {
283		switch (state) {
284		case 1:
285			/* Enable write access, clear bit GPIO0. */
286			out_be32((void*)GPIO0_OR,
287				 in_be32((void*)GPIO0_OR) &
288				 ~CONFIG_SYS_EEPROM_WP);
289			state = 0;
290			break;
291		case 0:
292			/* Disable write access, set bit GPIO0. */
293			out_be32((void*)GPIO0_OR,
294				 in_be32((void*)GPIO0_OR) |
295				 CONFIG_SYS_EEPROM_WP);
296			state = 0;
297			break;
298		default:
299			/* Read current status back. */
300			state = ((in_be32((void*)GPIO0_OR) &
301				       CONFIG_SYS_EEPROM_WP) == 0);
302			break;
303		}
304	}
305	return state;
306}
307
308int do_eep_wren(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
309{
310	int query = argc == 1;
311	int state = 0;
312
313	if (query) {
314		/* Query write access state. */
315		state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, -1);
316		if (state < 0) {
317			puts("Query of write access state failed.\n");
318		} else {
319			printf("Write access for device 0x%0x is %sabled.\n",
320			       CONFIG_SYS_I2C_EEPROM_ADDR,
321			       state ? "en" : "dis");
322			state = 0;
323		}
324	} else {
325		if (argv[1][0] == '0') {
326			/* Disable write access. */
327			state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR,
328						    0);
329		} else {
330			/* Enable write access. */
331			state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR,
332						    1);
333		}
334		if (state < 0)
335			puts("Setup of write access state failed.\n");
336	}
337
338	return state;
339}
340
341U_BOOT_CMD(eepwren,	2,	0,	do_eep_wren,
342	"Enable / disable / query EEPROM write access",
343	""
344);
345#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */