3 * Heiko Schocher, DENX Software Engineering, hs@denx.de
5 * SPDX-License-Identifier: GPL-2.0+
9 * Altera FPGA configuration support for the ALPR computer from prodrive
16 #include <asm/processor.h>
17 #include <asm/ppc440.h>
20 DECLARE_GLOBAL_DATA_PTR;
22 #if defined(CONFIG_FPGA)
25 #define PRINTF(fmt, args...) printf(fmt , ##args)
27 #define PRINTF(fmt, args...)
30 static unsigned long regval;
32 #define SET_GPIO_REG_0(reg, bit) do { \
34 regval &= ~(0x80000000 >> bit); \
38 #define SET_GPIO_REG_1(reg, bit) do { \
40 regval |= (0x80000000 >> bit); \
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)
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)
53 #define SET_FPGA(data) out32(GPIO0_OR, data)
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 */ \
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 */ \
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)
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));
79 /* initialize the GPIO Pins */
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);
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);
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);
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);
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);
107 /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
108 SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
112 /* Set the state of CONFIG Pin */
113 int fpga_config_fn(int assert_config, int flush, int cookie)
116 SET_GPIO_1(CONFIG_SYS_GPIO_CONFIG);
118 SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
123 /* Returns the state of STATUS Pin */
124 int fpga_status_fn(int cookie)
128 reg = in32(GPIO0_IR);
129 if (reg & (0x80000000 >> CONFIG_SYS_GPIO_STATUS)) {
130 PRINTF("STATUS = HIGH\n");
133 PRINTF("STATUS = LOW\n");
137 /* Returns the state of CONF_DONE Pin */
138 int fpga_done_fn(int cookie)
141 reg = in32(GPIO0_IR);
142 if (reg & (0x80000000 >> CONFIG_SYS_GPIO_CON_DON)) {
143 PRINTF("CONF_DON = HIGH\n");
146 PRINTF("CONF_DON = LOW\n");
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)
155 size_t bytecount = 0;
156 unsigned char *data = (unsigned char *) buf;
157 unsigned char val = 0;
159 int len_40 = len / 40;
161 while (bytecount < len) {
162 val = data[bytecount++];
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
187 /* called, when programming is aborted */
188 int fpga_abort_fn(int cookie)
190 SET_GPIO_1((CONFIG_SYS_GPIO_SEL_DPR));
194 /* called, when programming was succesful */
195 int fpga_post_fn(int cookie)
197 return fpga_abort_fn(cookie);
200 /* Note that these are pointers to code that is in Flash. They will be
201 * relocated at runtime.
203 Altera_CYC2_Passive_Serial_fns fpga_fns = {
213 Altera_desc fpga[CONFIG_FPGA_COUNT] = {
223 * Initialize the fpga. Return 1 on success, 0 on failure.
225 int alpr_fpga_init(void)
229 PRINTF("%s:%d: Initialize FPGA interface\n", __func__, __LINE__);
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]);