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