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