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