]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/prodrive/alpr/fpga.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / board / prodrive / alpr / fpga.c
1 /*
2  * (C) Copyright 2006
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de
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
25 /*
26  * Altera FPGA configuration support for the ALPR computer from prodrive
27  */
28
29 #include <common.h>
30 #include <altera.h>
31 #include <ACEX1K.h>
32 #include <command.h>
33 #include <asm-ppc/processor.h>
34 #include <ppc440.h>
35 #include "fpga.h"
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 #if defined(CONFIG_FPGA)
40
41 #ifdef FPGA_DEBUG
42 #define PRINTF(fmt,args...)     printf (fmt ,##args)
43 #else
44 #define PRINTF(fmt,args...)
45 #endif
46
47 static unsigned long regval;
48
49 #define SET_GPIO_REG_0(reg, bit) {                              \
50                 regval = in32(reg);                             \
51                 regval &= ~(0x80000000 >> bit);                 \
52                 out32(reg, regval);                             \
53         }
54
55 #define SET_GPIO_REG_1(reg, bit) {                              \
56                 regval = in32(reg);                             \
57                 regval |= (0x80000000 >> bit);                  \
58                 out32(reg, regval);                             \
59         }
60
61 #define SET_GPIO_0(bit)         SET_GPIO_REG_0(GPIO0_OR, bit)
62 #define SET_GPIO_1(bit)         SET_GPIO_REG_1(GPIO0_OR, bit)
63
64 #define FPGA_PRG                (0x80000000 >> CONFIG_SYS_GPIO_PROG_EN)
65 #define FPGA_CONFIG             (0x80000000 >> CONFIG_SYS_GPIO_CONFIG)
66 #define FPGA_DATA               (0x80000000 >> CONFIG_SYS_GPIO_DATA)
67 #define FPGA_CLK                (0x80000000 >> CONFIG_SYS_GPIO_CLK)
68 #define OLD_VAL                 (FPGA_PRG | FPGA_CONFIG)
69
70 #define SET_FPGA(data)          out32(GPIO0_OR, data)
71
72 #define FPGA_WRITE_1 {                                                  \
73                 SET_FPGA(OLD_VAL | 0        | FPGA_DATA);  /* set data to 1  */ \
74                 SET_FPGA(OLD_VAL | FPGA_CLK | FPGA_DATA);} /* set data to 1  */
75
76 #define FPGA_WRITE_0 {                                                  \
77                 SET_FPGA(OLD_VAL | 0        | 0        );   /* set data to 0  */ \
78                 SET_FPGA(OLD_VAL | FPGA_CLK | 0        );}  /* set data to 1  */
79
80 /* Plattforminitializations */
81 /* Here we have to set the FPGA Chain */
82 /* PROGRAM_PROG_EN      = HIGH */
83 /* PROGRAM_SEL_DPR      = LOW */
84 int fpga_pre_fn (int cookie)
85 {
86         unsigned long   reg;
87
88         reg = in32(GPIO0_IR);
89         /* Enable the FPGA Chain */
90         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_PROG_EN);
91         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_PROG_EN);
92         SET_GPIO_1(CONFIG_SYS_GPIO_PROG_EN);
93         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_SEL_DPR);
94         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_SEL_DPR);
95         SET_GPIO_0((CONFIG_SYS_GPIO_SEL_DPR));
96
97         /* initialize the GPIO Pins */
98         /* output */
99         SET_GPIO_0(CONFIG_SYS_GPIO_CLK);
100         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_CLK);
101         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CLK);
102
103         /* output */
104         SET_GPIO_0(CONFIG_SYS_GPIO_DATA);
105         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_DATA);
106         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_DATA);
107
108         /* First we set STATUS to 0 then as an input */
109         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_STATUS);
110         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_STATUS);
111         SET_GPIO_0(CONFIG_SYS_GPIO_STATUS);
112         SET_GPIO_REG_0(GPIO0_TCR, CONFIG_SYS_GPIO_STATUS);
113         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_STATUS);
114
115         /* output */
116         SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_CONFIG);
117         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CONFIG);
118         SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
119
120         /* input */
121         SET_GPIO_0(CONFIG_SYS_GPIO_CON_DON);
122         SET_GPIO_REG_0(GPIO0_TCR, CONFIG_SYS_GPIO_CON_DON);
123         SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CON_DON);
124
125         /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
126         SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
127         return FPGA_SUCCESS;
128 }
129
130 /* Set the state of CONFIG Pin */
131 int fpga_config_fn (int assert_config, int flush, int cookie)
132 {
133         if (assert_config) {
134                 SET_GPIO_1(CONFIG_SYS_GPIO_CONFIG);
135         } else {
136                 SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
137         }
138         return FPGA_SUCCESS;
139 }
140
141 /* Returns the state of STATUS Pin */
142 int fpga_status_fn (int cookie)
143 {
144         unsigned long   reg;
145
146         reg = in32(GPIO0_IR);
147         if (reg &= (0x80000000 >> CONFIG_SYS_GPIO_STATUS)) {
148                 PRINTF("STATUS = HIGH\n");
149                 return FPGA_FAIL;
150         }
151         PRINTF("STATUS = LOW\n");
152         return FPGA_SUCCESS;
153 }
154
155 /* Returns the state of CONF_DONE Pin */
156 int fpga_done_fn (int cookie)
157 {
158         unsigned long   reg;
159         reg = in32(GPIO0_IR);
160         if (reg &= (0x80000000 >> CONFIG_SYS_GPIO_CON_DON)) {
161                 PRINTF("CONF_DON = HIGH\n");
162                 return FPGA_FAIL;
163         }
164         PRINTF("CONF_DON = LOW\n");
165         return FPGA_SUCCESS;
166 }
167
168 /* writes the complete buffer to the FPGA
169    writing the complete buffer in one function is much faster,
170    then calling it for every bit */
171 int fpga_write_fn (void *buf, size_t len, int flush, int cookie)
172 {
173         size_t bytecount = 0;
174         unsigned char *data = (unsigned char *) buf;
175         unsigned char val=0;
176         int             i;
177         int len_40 = len / 40;
178
179         while (bytecount < len) {
180                 val = data[bytecount++];
181                 i = 8;
182                 do {
183                         if (val & 0x01) {
184                                 FPGA_WRITE_1;
185                         } else {
186                                 FPGA_WRITE_0;
187                         }
188                         val >>= 1;
189                         i --;
190                 } while (i > 0);
191
192 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
193                 if (bytecount % len_40 == 0) {
194                         putc ('.');             /* let them know we are alive */
195 #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
196                         if (ctrlc ())
197                                 return FPGA_FAIL;
198 #endif
199                 }
200 #endif
201         }
202         return FPGA_SUCCESS;
203 }
204
205 /* called, when programming is aborted */
206 int fpga_abort_fn (int cookie)
207 {
208         SET_GPIO_1((CONFIG_SYS_GPIO_SEL_DPR));
209         return FPGA_SUCCESS;
210 }
211
212 /* called, when programming was succesful */
213 int fpga_post_fn (int cookie)
214 {
215         return fpga_abort_fn (cookie);
216 }
217
218 /* Note that these are pointers to code that is in Flash.  They will be
219  * relocated at runtime.
220  */
221 Altera_CYC2_Passive_Serial_fns fpga_fns = {
222         fpga_pre_fn,
223         fpga_config_fn,
224         fpga_status_fn,
225         fpga_done_fn,
226         fpga_write_fn,
227         fpga_abort_fn,
228         fpga_post_fn
229 };
230
231 Altera_desc fpga[CONFIG_FPGA_COUNT] = {
232         {Altera_CYC2,
233          passive_serial,
234          Altera_EP2C35_SIZE,
235          (void *) &fpga_fns,
236          NULL,
237          0}
238 };
239
240 /*
241  * Initialize the fpga.  Return 1 on success, 0 on failure.
242  */
243 int alpr_fpga_init (void)
244 {
245         int i;
246
247         PRINTF ("%s:%d: Initialize FPGA interface\n", __FUNCTION__, __LINE__);
248         fpga_init ();
249
250         for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
251                 PRINTF ("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
252                 fpga_add (fpga_altera, &fpga[i]);
253         }
254         return 1;
255 }
256
257 #endif