1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.com.
*
* (C) Copyright 2011
* Andre Schwarz, Matrix Vision GmbH, andre.schwarz@matrix-vision.de
* Michael Jones, Matrix Vision GmbH, michael.jones@matrix-vision.de
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <ACEX1K.h>
#include <command.h>
#include <asm/gpio.h>
#include <linux/byteorder/generic.h>
#include "fpga.h"
#ifdef FPGA_DEBUG
#define fpga_debug(fmt, args...) printf("%s: "fmt, __func__, ##args)
#else
#define fpga_debug(fmt, args...)
#endif
Altera_CYC2_Passive_Serial_fns altera_fns = {
fpga_null_fn, /* Altera_pre_fn */
fpga_config_fn,
fpga_status_fn,
fpga_done_fn,
fpga_wr_fn,
fpga_null_fn,
fpga_null_fn,
};
Altera_desc cyclone2 = {
Altera_CYC2,
fast_passive_parallel,
Altera_EP3C5_SIZE,
(void *) &altera_fns,
NULL,
0
};
#define GPIO_RESET 43
#define GPIO_DCLK 65
#define GPIO_nSTATUS 157
#define GPIO_CONF_DONE 158
#define GPIO_nCONFIG 159
#define GPIO_DATA0 54
#define GPIO_DATA1 55
#define GPIO_DATA2 56
#define GPIO_DATA3 57
#define GPIO_DATA4 58
#define GPIO_DATA5 60
#define GPIO_DATA6 61
#define GPIO_DATA7 62
DECLARE_GLOBAL_DATA_PTR;
/* return FPGA_SUCCESS on success, else FPGA_FAIL
*/
int mvblx_init_fpga(void)
{
fpga_debug("Initializing FPGA interface\n");
fpga_init();
fpga_add(fpga_altera, &cyclone2);
if (gpio_request(GPIO_DCLK, "dclk") ||
gpio_request(GPIO_nSTATUS, "nStatus") ||
#ifndef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
gpio_request(GPIO_CONF_DONE, "conf_done") ||
#endif
gpio_request(GPIO_nCONFIG, "nConfig") ||
gpio_request(GPIO_DATA0, "data0") ||
gpio_request(GPIO_DATA1, "data1") ||
gpio_request(GPIO_DATA2, "data2") ||
gpio_request(GPIO_DATA3, "data3") ||
gpio_request(GPIO_DATA4, "data4") ||
gpio_request(GPIO_DATA5, "data5") ||
gpio_request(GPIO_DATA6, "data6") ||
gpio_request(GPIO_DATA7, "data7")) {
printf("%s: error requesting GPIOs.", __func__);
return FPGA_FAIL;
}
/* set up outputs */
gpio_direction_output(GPIO_DCLK, 0);
gpio_direction_output(GPIO_nCONFIG, 0);
gpio_direction_output(GPIO_DATA0, 0);
gpio_direction_output(GPIO_DATA1, 0);
gpio_direction_output(GPIO_DATA2, 0);
gpio_direction_output(GPIO_DATA3, 0);
gpio_direction_output(GPIO_DATA4, 0);
gpio_direction_output(GPIO_DATA5, 0);
gpio_direction_output(GPIO_DATA6, 0);
gpio_direction_output(GPIO_DATA7, 0);
/* NB omap_free_gpio() resets to an input, so we can't
* free ie. nCONFIG, or else the FPGA would reset
* Q: presumably gpio_free() has the same effect?
*/
/* set up inputs */
gpio_direction_input(GPIO_nSTATUS);
#ifndef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
gpio_direction_input(GPIO_CONF_DONE);
#endif
fpga_config_fn(0, 1, 0);
udelay(60);
return FPGA_SUCCESS;
}
int fpga_null_fn(int cookie)
{
return 0;
}
int fpga_config_fn(int assert, int flush, int cookie)
{
fpga_debug("SET config : %s=%d\n", assert ? "low" : "high", assert);
if (flush) {
gpio_set_value(GPIO_nCONFIG, !assert);
udelay(1);
gpio_set_value(GPIO_nCONFIG, assert);
}
return assert;
}
int fpga_done_fn(int cookie)
{
int result = 0;
/* since revA of BLX, we will not get this signal. */
udelay(10);
#ifdef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
fpga_debug("not waiting for CONF_DONE.");
result = 1;
#else
fpga_debug("CONF_DONE check ... ");
if (gpio_get_value(GPIO_CONF_DONE)) {
fpga_debug("high\n");
result = 1;
} else
fpga_debug("low\n");
gpio_free(GPIO_CONF_DONE);
#endif
return result;
}
int fpga_status_fn(int cookie)
{
int result = 0;
fpga_debug("STATUS check ... ");
result = gpio_get_value(GPIO_nSTATUS);
if (result < 0)
fpga_debug("error\n");
else if (result > 0)
fpga_debug("high\n");
else
fpga_debug("low\n");
return result;
}
static inline int _write_fpga(u8 byte)
{
gpio_set_value(GPIO_DATA0, byte & 0x01);
gpio_set_value(GPIO_DATA1, (byte >> 1) & 0x01);
gpio_set_value(GPIO_DATA2, (byte >> 2) & 0x01);
gpio_set_value(GPIO_DATA3, (byte >> 3) & 0x01);
gpio_set_value(GPIO_DATA4, (byte >> 4) & 0x01);
gpio_set_value(GPIO_DATA5, (byte >> 5) & 0x01);
gpio_set_value(GPIO_DATA6, (byte >> 6) & 0x01);
gpio_set_value(GPIO_DATA7, (byte >> 7) & 0x01);
/* clock */
gpio_set_value(GPIO_DCLK, 1);
udelay(1);
gpio_set_value(GPIO_DCLK, 0);
udelay(1);
return 0;
}
int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie)
{
unsigned char *data = (unsigned char *) buf;
int i;
int headerlen = len - cyclone2.size;
if (headerlen < 0)
return FPGA_FAIL;
else if (headerlen == sizeof(uint32_t)) {
const unsigned int fpgavers_len = 11; /* '0x' + 8 hex digits + \0 */
char fpgavers_str[fpgavers_len];
snprintf(fpgavers_str, fpgavers_len, "0x%08x",
be32_to_cpup((uint32_t*)data));
setenv("fpgavers", fpgavers_str);
}
fpga_debug("fpga_wr: buf %p / size %d\n", buf, len);
for (i = headerlen; i < len; i++)
_write_fpga(data[i]);
fpga_debug("-%s\n", __func__);
return FPGA_SUCCESS;
}
|