blob: 3133f942733a6d586ec09e4a273bd15886fdfe02 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
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
20DECLARE_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
30static 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 */
69int 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 */
113int 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 */
124int 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 */
138int 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 */
153int 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 */
188int 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 */
195int 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 */
203Altera_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
213Altera_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 */
225int 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