blob: f9412a21ebd5ac541d57a0bff76e5429a4bc74c7 [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/*
2 * (C) Copyright 2006
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
4 *
5 * (C) Copyright 2001-2004
6 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
7 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
8 *
9 * See file CREDITS for list of people who contributed to this
10 * project.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27
28#include <common.h>
29#include <asm/processor.h>
30#include <command.h>
31
32/* ------------------------------------------------------------------------- */
33
34#ifdef FPGA_DEBUG
35#define DBG(x...) printf(x)
36#else
37#define DBG(x...)
38#endif /* DEBUG */
39
40#define FPGA_PRG CFG_FPGA_PRG /* FPGA program pin (cpu output)*/
41#define FPGA_CLK CFG_FPGA_CLK /* FPGA clk pin (cpu output) */
42#define FPGA_DATA CFG_FPGA_DATA /* FPGA data pin (cpu output) */
43#define FPGA_DONE CFG_FPGA_DONE /* FPGA done pin (cpu input) */
44#define FPGA_INIT CFG_FPGA_INIT /* FPGA init pin (cpu input) */
45
46#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */
47#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */
48#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */
49
50#ifndef OLD_VAL
51# define OLD_VAL 0
52#endif
53
54#if 0 /* test-only */
55#define FPGA_WRITE_1 { \
56 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set clock to 0 */ \
57 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set data to 1 */ \
58 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \
59 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
60
61#define FPGA_WRITE_0 { \
62 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set clock to 0 */ \
63 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | 0 ); /* set data to 0 */ \
64 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | 0 ); /* set clock to 1 */ \
65 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
66#else
67#define FPGA_WRITE_1 { \
68 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | FPGA_DATA); /* set data to 1 */ \
69 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
70
71#define FPGA_WRITE_0 { \
72 SET_FPGA(OLD_VAL | FPGA_PRG | 0 | 0 ); /* set data to 0 */ \
73 SET_FPGA(OLD_VAL | FPGA_PRG | FPGA_CLK | 0 );} /* set data to 1 */
74#endif
75
76static int fpga_boot(unsigned char *fpgadata, int size)
77{
78 int i,index,len;
79 int count;
80 int j;
81
82 /* display infos on fpgaimage */
83 index = 15;
84 for (i=0; i<4; i++) {
85 len = fpgadata[index];
86 DBG("FPGA: %s\n", &(fpgadata[index+1]));
87 index += len+3;
88 }
89
90 /* search for preamble 0xFFFFFFFF */
91 while (1) {
92 if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
93 (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
94 break; /* preamble found */
95 else
96 index++;
97 }
98
99 DBG("FPGA: configdata starts at position 0x%x\n",index);
100 DBG("FPGA: length of fpga-data %d\n", size-index);
101
102 /*
103 * Setup port pins for fpga programming
104 */
105 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set pins to high */
106
107 DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
108 DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
109
110 /*
111 * Init fpga by asserting and deasserting PROGRAM*
112 */
113 SET_FPGA(0 | FPGA_CLK | FPGA_DATA); /* set prog active */
114
115 /* Wait for FPGA init line low */
116 count = 0;
117 while (FPGA_INIT_STATE) {
118 udelay(1000); /* wait 1ms */
119 /* Check for timeout - 100us max, so use 3ms */
120 if (count++ > 3) {
121 DBG("FPGA: Booting failed!\n");
122 return ERROR_FPGA_PRG_INIT_LOW;
123 }
124 }
125
126 DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
127 DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
128
129 /* deassert PROGRAM* */
130 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set prog inactive */
131
132 /* Wait for FPGA end of init period . */
133 count = 0;
134 while (!(FPGA_INIT_STATE)) {
135 udelay(1000); /* wait 1ms */
136 /* Check for timeout */
137 if (count++ > 3) {
138 DBG("FPGA: Booting failed!\n");
139 return ERROR_FPGA_PRG_INIT_HIGH;
140 }
141 }
142
143 DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
144 DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
145
146 DBG("write configuration data into fpga\n");
147 /* write configuration-data into fpga... */
148
149 /*
150 * Load uncompressed image into fpga
151 */
152 for (i=index; i<size; i++) {
153 for (j=0; j<8; j++) {
154 if ((fpgadata[i] & 0x80) == 0x80) {
155 FPGA_WRITE_1;
156 } else {
157 FPGA_WRITE_0;
158 }
159 fpgadata[i] <<= 1;
160 }
161 }
162
163 DBG("%s, ",(FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE" );
164 DBG("%s\n",(FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT" );
165
166 /*
167 * Check if fpga's DONE signal - correctly booted ?
168 */
169
170 /* Wait for FPGA end of programming period . */
171 count = 0;
172 while (!(FPGA_DONE_STATE)) {
173 udelay(1000); /* wait 1ms */
174 /* Check for timeout */
175 if (count++ > 3) {
176 DBG("FPGA: Booting failed!\n");
177 return ERROR_FPGA_PRG_DONE;
178 }
179 }
180
181 DBG("FPGA: Booting successful!\n");
182 return 0;
183}