source: SVN/rincon/u-boot/board/esd/pmc440/fpga.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 9.5 KB
Line 
1/*
2 * (C) Copyright 2007
3 * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <asm/io.h>
26#include <spartan2.h>
27#include <spartan3.h>
28#include <command.h>
29#include "fpga.h"
30#include "pmc440.h"
31
32DECLARE_GLOBAL_DATA_PTR;
33
34#if defined(CONFIG_FPGA)
35
36#define USE_SP_CODE
37
38#ifdef USE_SP_CODE
39Xilinx_Spartan3_Slave_Parallel_fns pmc440_fpga_fns = {
40        fpga_pre_config_fn,
41        fpga_pgm_fn,
42        fpga_init_fn,
43        NULL, /* err */
44        fpga_done_fn,
45        fpga_clk_fn,
46        fpga_cs_fn,
47        fpga_wr_fn,
48        NULL, /* rdata */
49        fpga_wdata_fn,
50        fpga_busy_fn,
51        fpga_abort_fn,
52        fpga_post_config_fn,
53};
54#else
55Xilinx_Spartan3_Slave_Serial_fns pmc440_fpga_fns = {
56        fpga_pre_config_fn,
57        fpga_pgm_fn,
58        fpga_clk_fn,
59        fpga_init_fn,
60        fpga_done_fn,
61        fpga_wr_fn,
62        fpga_post_config_fn,
63};
64#endif
65
66Xilinx_Spartan2_Slave_Serial_fns ngcc_fpga_fns = {
67        ngcc_fpga_pre_config_fn,
68        ngcc_fpga_pgm_fn,
69        ngcc_fpga_clk_fn,
70        ngcc_fpga_init_fn,
71        ngcc_fpga_done_fn,
72        ngcc_fpga_wr_fn,
73        ngcc_fpga_post_config_fn
74};
75
76Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
77        XILINX_XC3S1200E_DESC(
78#ifdef USE_SP_CODE
79                slave_parallel,
80#else
81                slave_serial,
82#endif
83                (void *)&pmc440_fpga_fns,
84                0),
85        XILINX_XC2S200_DESC(
86                slave_serial,
87                (void *)&ngcc_fpga_fns,
88                0)
89};
90
91
92/*
93 * Set the active-low FPGA reset signal.
94 */
95void fpga_reset(int assert)
96{
97        debug("%s:%d: RESET ", __FUNCTION__, __LINE__);
98        if (assert) {
99                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA);
100                debug("asserted\n");
101        } else {
102                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA);
103                debug("deasserted\n");
104        }
105}
106
107
108/*
109 * Initialize the SelectMap interface.  We assume that the mode and the
110 * initial state of all of the port pins have already been set!
111 */
112void fpga_serialslave_init(void)
113{
114        debug("%s:%d: Initialize serial slave interface\n", __FUNCTION__,
115              __LINE__);
116        fpga_pgm_fn(FALSE, FALSE, 0);   /* make sure program pin is inactive */
117}
118
119
120/*
121 * Set the FPGA's active-low SelectMap program line to the specified level
122 */
123int fpga_pgm_fn(int assert, int flush, int cookie)
124{
125        debug("%s:%d: FPGA PROGRAM ",
126              __FUNCTION__, __LINE__);
127
128        if (assert) {
129                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_PRG);
130                debug("asserted\n");
131        } else {
132                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_PRG);
133                debug("deasserted\n");
134        }
135        return assert;
136}
137
138
139/*
140 * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
141 * asserted (low).
142 */
143int fpga_init_fn(int cookie)
144{
145        if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_INIT)
146                return 0;
147        else
148                return 1;
149}
150
151#ifdef USE_SP_CODE
152int fpga_abort_fn(int cookie)
153{
154        return 0;
155}
156
157
158int fpga_cs_fn(int assert_cs, int flush, int cookie)
159{
160        return assert_cs;
161}
162
163
164int fpga_busy_fn(int cookie)
165{
166        return 1;
167}
168#endif
169
170
171/*
172 * Test the state of the active-high FPGA DONE pin
173 */
174int fpga_done_fn(int cookie)
175{
176        if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_DONE)
177                return 1;
178        else
179                return 0;
180}
181
182
183/*
184 * FPGA pre-configuration function. Just make sure that
185 * FPGA reset is asserted to keep the FPGA from starting up after
186 * configuration.
187 */
188int fpga_pre_config_fn(int cookie)
189{
190        debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
191        fpga_reset(TRUE);
192
193        /* release init# */
194        out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | GPIO0_FPGA_FORCEINIT);
195        /* disable PLD IOs */
196        out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_IOEN_N);
197        return 0;
198}
199
200
201/*
202 * FPGA post configuration function. Blip the FPGA reset line and then see if
203 * the FPGA appears to be running.
204 */
205int fpga_post_config_fn(int cookie)
206{
207        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
208        int rc=0;
209        char *s;
210
211        debug("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
212
213        /* enable PLD0..7 pins */
214        out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_IOEN_N);
215
216        fpga_reset(TRUE);
217        udelay (100);
218        fpga_reset(FALSE);
219        udelay (100);
220
221        FPGA_OUT32(&fpga->status, (gd->board_type << STATUS_HWREV_SHIFT) & STATUS_HWREV_MASK);
222
223        /* NGCC only: enable ledlink */
224        if ((s = getenv("bd_type")) && !strcmp(s, "ngcc"))
225                FPGA_SETBITS(&fpga->ctrla, 0x29f8c000);
226
227        return rc;
228}
229
230
231int fpga_clk_fn(int assert_clk, int flush, int cookie)
232{
233        if (assert_clk)
234                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_CLK);
235        else
236                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_CLK);
237
238        return assert_clk;
239}
240
241
242int fpga_wr_fn(int assert_write, int flush, int cookie)
243{
244        if (assert_write)
245                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA);
246        else
247                out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA);
248
249        return assert_write;
250}
251
252#ifdef USE_SP_CODE
253int fpga_wdata_fn(uchar data, int flush, int cookie)
254{
255        uchar val = data;
256        ulong or = in_be32((void*)GPIO1_OR);
257        int i = 7;
258        do {
259                /* Write data */
260                if (val & 0x80)
261                        or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA;
262                else
263                        or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA);
264
265                out_be32((void*)GPIO1_OR, or);
266
267                /* Assert the clock */
268                or |= GPIO1_FPGA_CLK;
269                out_be32((void*)GPIO1_OR, or);
270                val <<= 1;
271                i --;
272        } while (i > 0);
273
274        /* Write last data bit (the 8th clock comes from the sp_load() code */
275        if (val & 0x80)
276                or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA;
277        else
278                or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA);
279
280        out_be32((void*)GPIO1_OR, or);
281
282        return 0;
283}
284#endif
285
286#define NGCC_FPGA_PRG  CLOCK_EN
287#define NGCC_FPGA_DATA RESET_OUT
288#define NGCC_FPGA_DONE CLOCK_IN
289#define NGCC_FPGA_INIT IRIGB_R_IN
290#define NGCC_FPGA_CLK  CLOCK_OUT
291
292void ngcc_fpga_serialslave_init(void)
293{
294        debug("%s:%d: Initialize serial slave interface\n",
295              __FUNCTION__, __LINE__);
296
297        /* make sure program pin is inactive */
298        ngcc_fpga_pgm_fn (FALSE, FALSE, 0);
299}
300
301/*
302 * Set the active-low FPGA reset signal.
303 */
304void ngcc_fpga_reset(int assert)
305{
306        debug("%s:%d: RESET ", __FUNCTION__, __LINE__);
307
308        if (assert) {
309                FPGA_CLRBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N);
310                debug("asserted\n");
311        } else {
312                FPGA_SETBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N);
313                debug("deasserted\n");
314        }
315}
316
317
318/*
319 * Set the FPGA's active-low SelectMap program line to the specified level
320 */
321int ngcc_fpga_pgm_fn(int assert, int flush, int cookie)
322{
323        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
324
325        debug("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
326
327        if (assert) {
328                FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_PRG);
329                debug("asserted\n");
330        } else {
331                FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_PRG);
332                debug("deasserted\n");
333        }
334
335        return assert;
336}
337
338
339/*
340 * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
341 * asserted (low).
342 */
343int ngcc_fpga_init_fn(int cookie)
344{
345        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
346
347        debug("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
348        if (FPGA_IN32(&fpga->status) & NGCC_FPGA_INIT) {
349                debug("high\n");
350                return 0;
351        } else {
352                debug("low\n");
353                return 1;
354        }
355}
356
357
358/*
359 * Test the state of the active-high FPGA DONE pin
360 */
361int ngcc_fpga_done_fn(int cookie)
362{
363        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
364
365        debug("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
366        if (FPGA_IN32(&fpga->status) & NGCC_FPGA_DONE) {
367                debug("DONE high\n");
368                return 1;
369        } else {
370                debug("low\n");
371                return 0;
372        }
373}
374
375
376/*
377 * FPGA pre-configuration function.
378 */
379int ngcc_fpga_pre_config_fn(int cookie)
380{
381        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
382        debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
383
384        ngcc_fpga_reset(TRUE);
385        FPGA_CLRBITS(&fpga->ctrla, 0xfffffe00);
386
387        ngcc_fpga_reset(TRUE);
388        return 0;
389}
390
391
392/*
393 * FPGA post configuration function. Blip the FPGA reset line and then see if
394 * the FPGA appears to be running.
395 */
396int ngcc_fpga_post_config_fn(int cookie)
397{
398        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
399
400        debug("%s:%d: NGCC FPGA post configuration\n", __FUNCTION__, __LINE__);
401
402        udelay (100);
403        ngcc_fpga_reset(FALSE);
404
405        FPGA_SETBITS(&fpga->ctrla, 0x29f8c000);
406
407        return 0;
408}
409
410
411int ngcc_fpga_clk_fn(int assert_clk, int flush, int cookie)
412{
413        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
414
415        if (assert_clk)
416                FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_CLK);
417        else
418                FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_CLK);
419
420        return assert_clk;
421}
422
423
424int ngcc_fpga_wr_fn(int assert_write, int flush, int cookie)
425{
426        pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
427
428        if (assert_write)
429                FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_DATA);
430        else
431                FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_DATA);
432
433        return assert_write;
434}
435
436
437/*
438 * Initialize the fpga.  Return 1 on success, 0 on failure.
439 */
440int pmc440_init_fpga(void)
441{
442        char *s;
443
444        debug("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
445              __FUNCTION__, __LINE__, gd->reloc_off);
446        fpga_init(gd->reloc_off);
447
448        fpga_serialslave_init ();
449        debug("%s:%d: Adding fpga 0\n", __FUNCTION__, __LINE__);
450        fpga_add (fpga_xilinx, &fpga[0]);
451
452        /* NGCC only */
453        if ((s = getenv("bd_type")) && !strcmp(s, "ngcc")) {
454                ngcc_fpga_serialslave_init ();
455                debug("%s:%d: Adding fpga 1\n", __FUNCTION__, __LINE__);
456                fpga_add (fpga_xilinx, &fpga[1]);
457        }
458
459        return 0;
460}
461#endif /* CONFIG_FPGA */
Note: See TracBrowser for help on using the repository browser.