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