]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/matrix_vision/mvblx/fpga.c
Merge git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / board / matrix_vision / mvblx / fpga.c
1 /*
2  * (C) Copyright 2002
3  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4  * Keith Outwater, keith_outwater@mvis.com.
5  *
6  * (C) Copyright 2011
7  * Andre Schwarz, Matrix Vision GmbH, andre.schwarz@matrix-vision.de
8  * Michael Jones, Matrix Vision GmbH, michael.jones@matrix-vision.de
9  *
10  * SPDX-License-Identifier:     GPL-2.0+
11  */
12
13 #include <common.h>
14 #include <ACEX1K.h>
15 #include <command.h>
16 #include <asm/gpio.h>
17 #include <linux/byteorder/generic.h>
18 #include "fpga.h"
19
20 #ifdef FPGA_DEBUG
21 #define fpga_debug(fmt, args...)      printf("%s: "fmt, __func__, ##args)
22 #else
23 #define fpga_debug(fmt, args...)
24 #endif
25
26 Altera_CYC2_Passive_Serial_fns altera_fns = {
27         fpga_null_fn,   /* Altera_pre_fn */
28         fpga_config_fn,
29         fpga_status_fn,
30         fpga_done_fn,
31         fpga_wr_fn,
32         fpga_null_fn,
33         fpga_null_fn,
34 };
35
36 Altera_desc cyclone2 = {
37         Altera_CYC2,
38         fast_passive_parallel,
39         Altera_EP3C5_SIZE,
40         (void *) &altera_fns,
41         NULL,
42         0
43 };
44
45 #define GPIO_RESET              43
46 #define GPIO_DCLK               65
47 #define GPIO_nSTATUS    157
48 #define GPIO_CONF_DONE  158
49 #define GPIO_nCONFIG    159
50 #define GPIO_DATA0              54
51 #define GPIO_DATA1              55
52 #define GPIO_DATA2              56
53 #define GPIO_DATA3              57
54 #define GPIO_DATA4              58
55 #define GPIO_DATA5              60
56 #define GPIO_DATA6              61
57 #define GPIO_DATA7              62
58
59 DECLARE_GLOBAL_DATA_PTR;
60
61 /* return FPGA_SUCCESS on success, else FPGA_FAIL
62  */
63 int mvblx_init_fpga(void)
64 {
65         fpga_debug("Initializing FPGA interface\n");
66         fpga_init();
67         fpga_add(fpga_altera, &cyclone2);
68
69         if (gpio_request(GPIO_DCLK, "dclk") ||
70                         gpio_request(GPIO_nSTATUS, "nStatus") ||
71 #ifndef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
72                         gpio_request(GPIO_CONF_DONE, "conf_done") ||
73 #endif
74                         gpio_request(GPIO_nCONFIG, "nConfig") ||
75                         gpio_request(GPIO_DATA0, "data0") ||
76                         gpio_request(GPIO_DATA1, "data1") ||
77                         gpio_request(GPIO_DATA2, "data2") ||
78                         gpio_request(GPIO_DATA3, "data3") ||
79                         gpio_request(GPIO_DATA4, "data4") ||
80                         gpio_request(GPIO_DATA5, "data5") ||
81                         gpio_request(GPIO_DATA6, "data6") ||
82                         gpio_request(GPIO_DATA7, "data7")) {
83                 printf("%s: error requesting GPIOs.", __func__);
84                 return FPGA_FAIL;
85         }
86
87         /* set up outputs */
88         gpio_direction_output(GPIO_DCLK,  0);
89         gpio_direction_output(GPIO_nCONFIG, 0);
90         gpio_direction_output(GPIO_DATA0, 0);
91         gpio_direction_output(GPIO_DATA1, 0);
92         gpio_direction_output(GPIO_DATA2, 0);
93         gpio_direction_output(GPIO_DATA3, 0);
94         gpio_direction_output(GPIO_DATA4, 0);
95         gpio_direction_output(GPIO_DATA5, 0);
96         gpio_direction_output(GPIO_DATA6, 0);
97         gpio_direction_output(GPIO_DATA7, 0);
98
99         /* NB omap_free_gpio() resets to an input, so we can't
100          * free ie. nCONFIG, or else the FPGA would reset
101          * Q: presumably gpio_free() has the same effect?
102          */
103
104         /* set up inputs */
105         gpio_direction_input(GPIO_nSTATUS);
106 #ifndef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
107         gpio_direction_input(GPIO_CONF_DONE);
108 #endif
109
110         fpga_config_fn(0, 1, 0);
111         udelay(60);
112
113         return FPGA_SUCCESS;
114 }
115
116 int fpga_null_fn(int cookie)
117 {
118         return 0;
119 }
120
121 int fpga_config_fn(int assert, int flush, int cookie)
122 {
123         fpga_debug("SET config : %s=%d\n", assert ? "low" : "high", assert);
124         if (flush) {
125                 gpio_set_value(GPIO_nCONFIG, !assert);
126                 udelay(1);
127                 gpio_set_value(GPIO_nCONFIG, assert);
128         }
129
130         return assert;
131 }
132
133 int fpga_done_fn(int cookie)
134 {
135         int result = 0;
136
137         /* since revA of BLX, we will not get this signal. */
138         udelay(10);
139 #ifdef CONFIG_SYS_FPGA_DONT_USE_CONF_DONE
140         fpga_debug("not waiting for CONF_DONE.");
141         result = 1;
142 #else
143         fpga_debug("CONF_DONE check ... ");
144         if (gpio_get_value(GPIO_CONF_DONE))  {
145                 fpga_debug("high\n");
146                 result = 1;
147         } else
148                 fpga_debug("low\n");
149         gpio_free(GPIO_CONF_DONE);
150 #endif
151
152         return result;
153 }
154
155 int fpga_status_fn(int cookie)
156 {
157         int result = 0;
158         fpga_debug("STATUS check ... ");
159
160         result = gpio_get_value(GPIO_nSTATUS);
161
162         if (result < 0)
163                 fpga_debug("error\n");
164         else if (result > 0)
165                 fpga_debug("high\n");
166         else
167                 fpga_debug("low\n");
168
169         return result;
170 }
171
172 static inline int _write_fpga(u8 byte)
173 {
174         gpio_set_value(GPIO_DATA0, byte & 0x01);
175         gpio_set_value(GPIO_DATA1, (byte >> 1) & 0x01);
176         gpio_set_value(GPIO_DATA2, (byte >> 2) & 0x01);
177         gpio_set_value(GPIO_DATA3, (byte >> 3) & 0x01);
178         gpio_set_value(GPIO_DATA4, (byte >> 4) & 0x01);
179         gpio_set_value(GPIO_DATA5, (byte >> 5) & 0x01);
180         gpio_set_value(GPIO_DATA6, (byte >> 6) & 0x01);
181         gpio_set_value(GPIO_DATA7, (byte >> 7) & 0x01);
182
183         /* clock */
184         gpio_set_value(GPIO_DCLK, 1);
185         udelay(1);
186         gpio_set_value(GPIO_DCLK, 0);
187         udelay(1);
188
189         return 0;
190 }
191
192 int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie)
193 {
194         unsigned char *data = (unsigned char *) buf;
195         int i;
196         int headerlen = len - cyclone2.size;
197
198         if (headerlen < 0)
199                 return FPGA_FAIL;
200         else if (headerlen == sizeof(uint32_t)) {
201                 const unsigned int fpgavers_len = 11; /* '0x' + 8 hex digits + \0 */
202                 char fpgavers_str[fpgavers_len];
203                 snprintf(fpgavers_str, fpgavers_len, "0x%08x",
204                                 be32_to_cpup((uint32_t*)data));
205                 setenv("fpgavers", fpgavers_str);
206         }
207
208         fpga_debug("fpga_wr: buf %p / size %d\n", buf, len);
209         for (i = headerlen; i < len; i++)
210                 _write_fpga(data[i]);
211         fpga_debug("-%s\n", __func__);
212
213         return FPGA_SUCCESS;
214 }