blob: 0869ca0718be26dd4721802b43e7d04ba70eddb0 [file] [log] [blame]
wdenk232fe0b2003-09-02 22:48:03 +00001/*
2 * (C) Copyright 2001-2003
3 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
4 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk232fe0b2003-09-02 22:48:03 +00007 */
8
9#include <common.h>
10#include <asm/processor.h>
11#include <command.h>
12
13/* ------------------------------------------------------------------------- */
14
15#ifdef FPGA_DEBUG
16#define DBG(x...) printf(x)
17#else
18#define DBG(x...)
19#endif /* DEBUG */
20
21#define MAX_ONES 226
22
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020023#ifdef CONFIG_SYS_FPGA_PRG
24# define FPGA_PRG CONFIG_SYS_FPGA_PRG /* FPGA program pin (ppc output)*/
25# define FPGA_CLK CONFIG_SYS_FPGA_CLK /* FPGA clk pin (ppc output) */
26# define FPGA_DATA CONFIG_SYS_FPGA_DATA /* FPGA data pin (ppc output) */
27# define FPGA_DONE CONFIG_SYS_FPGA_DONE /* FPGA done pin (ppc input) */
28# define FPGA_INIT CONFIG_SYS_FPGA_INIT /* FPGA init pin (ppc input) */
wdenk232fe0b2003-09-02 22:48:03 +000029#else
30# define FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
31# define FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
32# define FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
33# define FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */
34# define FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */
35#endif
36
37#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */
38#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */
39#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */
40
41#define SET_FPGA(data) out32(GPIO0_OR, data)
42
43#define FPGA_WRITE_1 { \
wdenk9c53f402003-10-15 23:53:47 +000044 SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
45 SET_FPGA(FPGA_PRG | FPGA_DATA); /* set data to 1 */ \
46 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \
47 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
wdenk232fe0b2003-09-02 22:48:03 +000048
49#define FPGA_WRITE_0 { \
wdenk9c53f402003-10-15 23:53:47 +000050 SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
51 SET_FPGA(FPGA_PRG); /* set data to 0 */ \
52 SET_FPGA(FPGA_PRG | FPGA_CLK); /* set clock to 1 */ \
53 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
wdenk232fe0b2003-09-02 22:48:03 +000054
55#if 0
56static int fpga_boot (unsigned char *fpgadata, int size)
57{
58 int i, index, len;
59 int count;
60
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020061#ifdef CONFIG_SYS_FPGA_SPARTAN2
wdenk232fe0b2003-09-02 22:48:03 +000062 int j;
63#else
64 unsigned char b;
65 int bit;
66#endif
67
68 /* display infos on fpgaimage */
69 index = 15;
70 for (i = 0; i < 4; i++) {
71 len = fpgadata[index];
72 DBG ("FPGA: %s\n", &(fpgadata[index + 1]));
73 index += len + 3;
74 }
75
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020076#ifdef CONFIG_SYS_FPGA_SPARTAN2
wdenk232fe0b2003-09-02 22:48:03 +000077 /* search for preamble 0xFFFFFFFF */
78 while (1) {
79 if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
80 && (fpgadata[index + 2] == 0xff)
81 && (fpgadata[index + 3] == 0xff))
82 break; /* preamble found */
83 else
84 index++;
85 }
86#else
87 /* search for preamble 0xFF2X */
88 for (index = 0; index < size - 1; index++) {
89 if ((fpgadata[index] == 0xff)
90 && ((fpgadata[index + 1] & 0xf0) == 0x30))
91 break;
92 }
93 index += 2;
94#endif
95
96 DBG ("FPGA: configdata starts at position 0x%x\n", index);
97 DBG ("FPGA: length of fpga-data %d\n", size - index);
98
99 /*
100 * Setup port pins for fpga programming
101 */
102 out32 (GPIO0_ODR, 0x00000000); /* no open drain pins */
103 out32 (GPIO0_TCR, in32 (GPIO0_TCR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */
104 out32 (GPIO0_OR, in32 (GPIO0_OR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set pins to high */
105
106 DBG ("%s, ",
107 ((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
108 DBG ("%s\n",
109 ((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
110
111 /*
112 * Init fpga by asserting and deasserting PROGRAM*
113 */
114 SET_FPGA (FPGA_CLK | FPGA_DATA);
115
116 /* Wait for FPGA init line low */
117 count = 0;
118 while (in32 (GPIO0_IR) & FPGA_INIT) {
119 udelay (1000); /* wait 1ms */
120 /* Check for timeout - 100us max, so use 3ms */
121 if (count++ > 3) {
122 DBG ("FPGA: Booting failed!\n");
123 return ERROR_FPGA_PRG_INIT_LOW;
124 }
125 }
126
127 DBG ("%s, ",
128 ((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
129 DBG ("%s\n",
130 ((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
131
132 /* deassert PROGRAM* */
133 SET_FPGA (FPGA_PRG | FPGA_CLK | FPGA_DATA);
134
135 /* Wait for FPGA end of init period . */
136 count = 0;
137 while (!(in32 (GPIO0_IR) & FPGA_INIT)) {
138 udelay (1000); /* wait 1ms */
139 /* Check for timeout */
140 if (count++ > 3) {
141 DBG ("FPGA: Booting failed!\n");
142 return ERROR_FPGA_PRG_INIT_HIGH;
143 }
144 }
145
146 DBG ("%s, ",
147 ((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
148 DBG ("%s\n",
149 ((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
150
151 DBG ("write configuration data into fpga\n");
152 /* write configuration-data into fpga... */
153
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200154#ifdef CONFIG_SYS_FPGA_SPARTAN2
wdenk232fe0b2003-09-02 22:48:03 +0000155 /*
156 * Load uncompressed image into fpga
157 */
158 for (i = index; i < size; i++) {
159 for (j = 0; j < 8; j++) {
160 if ((fpgadata[i] & 0x80) == 0x80) {
161 FPGA_WRITE_1;
162 } else {
163 FPGA_WRITE_0;
164 }
165 fpgadata[i] <<= 1;
166 }
167 }
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200168#else /* ! CONFIG_SYS_FPGA_SPARTAN2 */
wdenk232fe0b2003-09-02 22:48:03 +0000169 /* send 0xff 0x20 */
170 FPGA_WRITE_1;
171 FPGA_WRITE_1;
172 FPGA_WRITE_1;
173 FPGA_WRITE_1;
174 FPGA_WRITE_1;
175 FPGA_WRITE_1;
176 FPGA_WRITE_1;
177 FPGA_WRITE_1;
178 FPGA_WRITE_0;
179 FPGA_WRITE_0;
180 FPGA_WRITE_1;
181 FPGA_WRITE_0;
182 FPGA_WRITE_0;
183 FPGA_WRITE_0;
184 FPGA_WRITE_0;
185 FPGA_WRITE_0;
186
187 /*
188 ** Bit_DeCompression
189 ** Code 1 .. maxOnes : n '1's followed by '0'
190 ** maxOnes + 1 .. maxOnes + 1 : n - 1 '1's no '0'
191 ** maxOnes + 2 .. 254 : n - (maxOnes + 2) '0's followed by '1'
192 ** 255 : '1'
193 */
194
195 for (i = index; i < size; i++) {
196 b = fpgadata[i];
197 if ((b >= 1) && (b <= MAX_ONES)) {
198 for (bit = 0; bit < b; bit++) {
199 FPGA_WRITE_1;
200 }
201 FPGA_WRITE_0;
202 } else if (b == (MAX_ONES + 1)) {
203 for (bit = 1; bit < b; bit++) {
204 FPGA_WRITE_1;
205 }
206 } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
207 for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
208 FPGA_WRITE_0;
209 }
210 FPGA_WRITE_1;
211 } else if (b == 255) {
212 FPGA_WRITE_1;
213 }
214 }
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200215#endif /* CONFIG_SYS_FPGA_SPARTAN2 */
wdenk232fe0b2003-09-02 22:48:03 +0000216
217 DBG ("%s, ",
218 ((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
219 DBG ("%s\n",
220 ((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
221
222 /*
223 * Check if fpga's DONE signal - correctly booted ?
224 */
225
226 /* Wait for FPGA end of programming period . */
227 count = 0;
228 while (!(in32 (GPIO0_IR) & FPGA_DONE)) {
229 udelay (1000); /* wait 1ms */
230 /* Check for timeout */
231 if (count++ > 3) {
232 DBG ("FPGA: Booting failed!\n");
233 return ERROR_FPGA_PRG_DONE;
234 }
235 }
236
237 DBG ("FPGA: Booting successful!\n");
238 return 0;
239}
240#endif /* 0 */