blob: 7f9b24550597888c342b9cb5e9b66ec63cbd75b6 [file] [log] [blame]
Michael Jones84d7a012011-11-04 13:53:44 -04001/*
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 *
Wolfgang Denk1a459662013-07-08 09:37:19 +020010 * SPDX-License-Identifier: GPL-2.0+
Michael Jones84d7a012011-11-04 13:53:44 -040011 */
12
13#include <common.h>
14#include <ACEX1K.h>
15#include <command.h>
16#include <asm/gpio.h>
Michael Jonesbb4d4642013-02-07 23:53:37 +000017#include <linux/byteorder/generic.h>
Michael Jones84d7a012011-11-04 13:53:44 -040018#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
26Altera_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
36Altera_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
59DECLARE_GLOBAL_DATA_PTR;
60
61/* return FPGA_SUCCESS on success, else FPGA_FAIL
62 */
63int 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
116int fpga_null_fn(int cookie)
117{
118 return 0;
119}
120
121int 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
133int 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
155int 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
172static 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
192int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie)
193{
194 unsigned char *data = (unsigned char *) buf;
195 int i;
Michael Jonesbb4d4642013-02-07 23:53:37 +0000196 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 }
Michael Jones84d7a012011-11-04 13:53:44 -0400207
208 fpga_debug("fpga_wr: buf %p / size %d\n", buf, len);
Michael Jonesbb4d4642013-02-07 23:53:37 +0000209 for (i = headerlen; i < len; i++)
Michael Jones84d7a012011-11-04 13:53:44 -0400210 _write_fpga(data[i]);
211 fpga_debug("-%s\n", __func__);
212
213 return FPGA_SUCCESS;
214}