1 /*-
2 * Copyright (c) 2017 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 /*
32 * Intel Arria 10 FPGA Manager.
33 * Chapter 4, Arria 10 Hard Processor System Technical Reference Manual.
34 * Chapter A, FPGA Reconfiguration.
35 */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/bus.h>
43 #include <sys/kernel.h>
44 #include <sys/module.h>
45 #include <sys/malloc.h>
46 #include <sys/rman.h>
47 #include <sys/timeet.h>
48 #include <sys/timetc.h>
49 #include <sys/conf.h>
50 #include <sys/uio.h>
51
52 #include <dev/ofw/openfirm.h>
53 #include <dev/ofw/ofw_bus.h>
54 #include <dev/ofw/ofw_bus_subr.h>
55
56 #include <machine/bus.h>
57 #include <machine/cpu.h>
58 #include <machine/intr.h>
59
60 #include <arm/altera/socfpga/socfpga_common.h>
61
62 #define FPGAMGR_DCLKCNT 0x8 /* DCLK Count Register */
63 #define FPGAMGR_DCLKSTAT 0xC /* DCLK Status Register */
64 #define FPGAMGR_GPO 0x10 /* General-Purpose Output Register */
65 #define FPGAMGR_GPI 0x14 /* General-Purpose Input Register */
66 #define FPGAMGR_MISCI 0x18 /* Miscellaneous Input Register */
67 #define IMGCFG_CTRL_00 0x70
68 #define S2F_CONDONE_OE (1 << 24)
69 #define S2F_NSTATUS_OE (1 << 16)
70 #define CTRL_00_NCONFIG (1 << 8)
71 #define CTRL_00_NENABLE_CONDONE (1 << 2)
72 #define CTRL_00_NENABLE_NSTATUS (1 << 1)
73 #define CTRL_00_NENABLE_NCONFIG (1 << 0)
74 #define IMGCFG_CTRL_01 0x74
75 #define CTRL_01_S2F_NCE (1 << 24)
76 #define CTRL_01_S2F_PR_REQUEST (1 << 16)
77 #define CTRL_01_S2F_NENABLE_CONFIG (1 << 0)
78 #define IMGCFG_CTRL_02 0x78
79 #define CTRL_02_CDRATIO_S 16
80 #define CTRL_02_CDRATIO_M (0x3 << CTRL_02_CDRATIO_S)
81 #define CTRL_02_CFGWIDTH_16 (0 << 24)
82 #define CTRL_02_CFGWIDTH_32 (1 << 24)
83 #define CTRL_02_EN_CFG_DATA (1 << 8)
84 #define CTRL_02_EN_CFG_CTRL (1 << 0)
85 #define IMGCFG_STAT 0x80
86 #define F2S_PR_ERROR (1 << 11)
87 #define F2S_PR_DONE (1 << 10)
88 #define F2S_PR_READY (1 << 9)
89 #define F2S_MSEL_S 16
90 #define F2S_MSEL_M (0x7 << F2S_MSEL_S)
91 #define MSEL_PASSIVE_FAST 0
92 #define MSEL_PASSIVE_SLOW 1
93 #define F2S_NCONFIG_PIN (1 << 12)
94 #define F2S_CONDONE_OE (1 << 7)
95 #define F2S_NSTATUS_PIN (1 << 4)
96 #define F2S_CONDONE_PIN (1 << 6)
97 #define F2S_USERMODE (1 << 2)
98
99 struct fpgamgr_a10_softc {
100 struct resource *res[2];
101 bus_space_tag_t bst_data;
102 bus_space_handle_t bsh_data;
103 struct cdev *mgr_cdev;
104 device_t dev;
105 };
106
107 static struct resource_spec fpgamgr_a10_spec[] = {
108 { SYS_RES_MEMORY, 0, RF_ACTIVE },
109 { SYS_RES_MEMORY, 1, RF_ACTIVE },
110 { -1, 0 }
111 };
112
113 static int
114 fpga_wait_dclk_pulses(struct fpgamgr_a10_softc *sc, int npulses)
115 {
116 int tout;
117
118 /* Clear done bit, if any */
119 if (READ4(sc, FPGAMGR_DCLKSTAT) != 0)
120 WRITE4(sc, FPGAMGR_DCLKSTAT, 0x1);
121
122 /* Request DCLK pulses */
123 WRITE4(sc, FPGAMGR_DCLKCNT, npulses);
124
125 /* Wait finish */
126 tout = 1000;
127 while (tout > 0) {
128 if (READ4(sc, FPGAMGR_DCLKSTAT) == 1) {
129 WRITE4(sc, FPGAMGR_DCLKSTAT, 0x1);
130 break;
131 }
132 tout--;
133 DELAY(10);
134 }
135 if (tout == 0) {
136 device_printf(sc->dev,
137 "Error: dclkpulses wait timeout\n");
138 return (1);
139 }
140
141 return (0);
142 }
143
144 static int
145 fpga_open(struct cdev *dev, int flags __unused,
146 int fmt __unused, struct thread *td __unused)
147 {
148 struct fpgamgr_a10_softc *sc;
149 int tout;
150 int msel;
151 int reg;
152
153 sc = dev->si_drv1;
154
155 /* Step 1 */
156 reg = READ4(sc, IMGCFG_STAT);
157 if ((reg & F2S_USERMODE) == 0) {
158 device_printf(sc->dev, "Error: invalid mode\n");
159 return (ENXIO);
160 };
161
162 /* Step 2 */
163 reg = READ4(sc, IMGCFG_STAT);
164 msel = (reg & F2S_MSEL_M) >> F2S_MSEL_S;
165 if ((msel != MSEL_PASSIVE_FAST) && \
166 (msel != MSEL_PASSIVE_SLOW)) {
167 device_printf(sc->dev,
168 "Error: invalid msel %d\n", msel);
169 return (ENXIO);
170 };
171
172 /*
173 * Step 3.
174 * TODO: add support for compressed, encrypted images.
175 */
176 reg = READ4(sc, IMGCFG_CTRL_02);
177 reg &= ~(CTRL_02_CDRATIO_M);
178 WRITE4(sc, IMGCFG_CTRL_02, reg);
179
180 reg = READ4(sc, IMGCFG_CTRL_02);
181 reg &= ~CTRL_02_CFGWIDTH_32;
182 WRITE4(sc, IMGCFG_CTRL_02, reg);
183
184 /* Step 4. a */
185 reg = READ4(sc, IMGCFG_CTRL_01);
186 reg &= ~CTRL_01_S2F_PR_REQUEST;
187 WRITE4(sc, IMGCFG_CTRL_01, reg);
188
189 reg = READ4(sc, IMGCFG_CTRL_00);
190 reg |= CTRL_00_NCONFIG;
191 WRITE4(sc, IMGCFG_CTRL_00, reg);
192
193 /* b */
194 reg = READ4(sc, IMGCFG_CTRL_01);
195 reg &= ~CTRL_01_S2F_NCE;
196 WRITE4(sc, IMGCFG_CTRL_01, reg);
197
198 /* c */
199 reg = READ4(sc, IMGCFG_CTRL_02);
200 reg |= CTRL_02_EN_CFG_CTRL;
201 WRITE4(sc, IMGCFG_CTRL_02, reg);
202
203 /* d */
204 reg = READ4(sc, IMGCFG_CTRL_00);
205 reg &= ~S2F_CONDONE_OE;
206 reg &= ~S2F_NSTATUS_OE;
207 reg |= CTRL_00_NCONFIG;
208 reg |= CTRL_00_NENABLE_NSTATUS;
209 reg |= CTRL_00_NENABLE_CONDONE;
210 reg &= ~CTRL_00_NENABLE_NCONFIG;
211 WRITE4(sc, IMGCFG_CTRL_00, reg);
212
213 /* Step 5 */
214 reg = READ4(sc, IMGCFG_CTRL_01);
215 reg &= ~CTRL_01_S2F_NENABLE_CONFIG;
216 WRITE4(sc, IMGCFG_CTRL_01, reg);
217
218 /* Step 6 */
219 fpga_wait_dclk_pulses(sc, 0x100);
220
221 /* Step 7. a */
222 reg = READ4(sc, IMGCFG_CTRL_01);
223 reg |= CTRL_01_S2F_PR_REQUEST;
224 WRITE4(sc, IMGCFG_CTRL_01, reg);
225
226 /* b, c */
227 fpga_wait_dclk_pulses(sc, 0x7ff);
228
229 /* Step 8 */
230 tout = 10;
231 while (tout--) {
232 reg = READ4(sc, IMGCFG_STAT);
233 if (reg & F2S_PR_ERROR) {
234 device_printf(sc->dev,
235 "Error: PR failed on open.\n");
236 return (ENXIO);
237 }
238 if (reg & F2S_PR_READY) {
239 break;
240 }
241 }
242 if (tout == 0) {
243 device_printf(sc->dev,
244 "Error: Timeout waiting PR ready bit.\n");
245 return (ENXIO);
246 }
247
248 return (0);
249 }
250
251 static int
252 fpga_close(struct cdev *dev, int flags __unused,
253 int fmt __unused, struct thread *td __unused)
254 {
255 struct fpgamgr_a10_softc *sc;
256 int tout;
257 int reg;
258
259 sc = dev->si_drv1;
260
261 /* Step 10 */
262 tout = 10;
263 while (tout--) {
264 reg = READ4(sc, IMGCFG_STAT);
265 if (reg & F2S_PR_ERROR) {
266 device_printf(sc->dev,
267 "Error: PR failed.\n");
268 return (ENXIO);
269 }
270 if (reg & F2S_PR_DONE) {
271 break;
272 }
273 }
274
275 /* Step 11 */
276 reg = READ4(sc, IMGCFG_CTRL_01);
277 reg &= ~CTRL_01_S2F_PR_REQUEST;
278 WRITE4(sc, IMGCFG_CTRL_01, reg);
279
280 /* Step 12, 13 */
281 fpga_wait_dclk_pulses(sc, 0x100);
282
283 /* Step 14 */
284 reg = READ4(sc, IMGCFG_CTRL_02);
285 reg &= ~CTRL_02_EN_CFG_CTRL;
286 WRITE4(sc, IMGCFG_CTRL_02, reg);
287
288 /* Step 15 */
289 reg = READ4(sc, IMGCFG_CTRL_01);
290 reg |= CTRL_01_S2F_NCE;
291 WRITE4(sc, IMGCFG_CTRL_01, reg);
292
293 /* Step 16 */
294 reg = READ4(sc, IMGCFG_CTRL_01);
295 reg |= CTRL_01_S2F_NENABLE_CONFIG;
296 WRITE4(sc, IMGCFG_CTRL_01, reg);
297
298 /* Step 17 */
299 reg = READ4(sc, IMGCFG_STAT);
300 if ((reg & F2S_USERMODE) == 0) {
301 device_printf(sc->dev,
302 "Error: invalid mode\n");
303 return (ENXIO);
304 };
305
306 if ((reg & F2S_CONDONE_PIN) == 0) {
307 device_printf(sc->dev,
308 "Error: configuration not done\n");
309 return (ENXIO);
310 };
311
312 if ((reg & F2S_NSTATUS_PIN) == 0) {
313 device_printf(sc->dev,
314 "Error: nstatus pin\n");
315 return (ENXIO);
316 };
317
318 return (0);
319 }
320
321 static int
322 fpga_write(struct cdev *dev, struct uio *uio, int ioflag)
323 {
324 struct fpgamgr_a10_softc *sc;
325 uint32_t buffer;
326
327 sc = dev->si_drv1;
328
329 /*
330 * Step 9.
331 * Device supports 4-byte writes only.
332 */
333
334 while (uio->uio_resid >= 4) {
335 uiomove(&buffer, 4, uio);
336 bus_space_write_4(sc->bst_data, sc->bsh_data,
337 0x0, buffer);
338 }
339
340 switch (uio->uio_resid) {
341 case 3:
342 uiomove(&buffer, 3, uio);
343 buffer &= 0xffffff;
344 bus_space_write_4(sc->bst_data, sc->bsh_data,
345 0x0, buffer);
346 break;
347 case 2:
348 uiomove(&buffer, 2, uio);
349 buffer &= 0xffff;
350 bus_space_write_4(sc->bst_data, sc->bsh_data,
351 0x0, buffer);
352 break;
353 case 1:
354 uiomove(&buffer, 1, uio);
355 buffer &= 0xff;
356 bus_space_write_4(sc->bst_data, sc->bsh_data,
357 0x0, buffer);
358 break;
359 default:
360 break;
361 };
362
363 return (0);
364 }
365
366 static int
367 fpga_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
368 struct thread *td)
369 {
370
371 return (0);
372 }
373
374 static struct cdevsw fpga_cdevsw = {
375 .d_version = D_VERSION,
376 .d_open = fpga_open,
377 .d_close = fpga_close,
378 .d_write = fpga_write,
379 .d_ioctl = fpga_ioctl,
380 .d_name = "FPGA Manager",
381 };
382
383 static int
384 fpgamgr_a10_probe(device_t dev)
385 {
386
387 if (!ofw_bus_status_okay(dev))
388 return (ENXIO);
389
390 if (!ofw_bus_is_compatible(dev, "altr,socfpga-a10-fpga-mgr"))
391 return (ENXIO);
392
393 device_set_desc(dev, "Arria 10 FPGA Manager");
394
395 return (BUS_PROBE_DEFAULT);
396 }
397
398 static int
399 fpgamgr_a10_attach(device_t dev)
400 {
401 struct fpgamgr_a10_softc *sc;
402
403 sc = device_get_softc(dev);
404 sc->dev = dev;
405
406 if (bus_alloc_resources(dev, fpgamgr_a10_spec, sc->res)) {
407 device_printf(dev, "Could not allocate resources.\n");
408 return (ENXIO);
409 }
410
411 /* Memory interface */
412 sc->bst_data = rman_get_bustag(sc->res[1]);
413 sc->bsh_data = rman_get_bushandle(sc->res[1]);
414
415 sc->mgr_cdev = make_dev(&fpga_cdevsw, 0, UID_ROOT, GID_WHEEL,
416 0600, "fpga%d", device_get_unit(sc->dev));
417
418 if (sc->mgr_cdev == NULL) {
419 device_printf(dev, "Failed to create character device.\n");
420 return (ENXIO);
421 }
422
423 sc->mgr_cdev->si_drv1 = sc;
424
425 return (0);
426 }
427
428 static device_method_t fpgamgr_a10_methods[] = {
429 DEVMETHOD(device_probe, fpgamgr_a10_probe),
430 DEVMETHOD(device_attach, fpgamgr_a10_attach),
431 { 0, 0 }
432 };
433
434 static driver_t fpgamgr_a10_driver = {
435 "fpgamgr_a10",
436 fpgamgr_a10_methods,
437 sizeof(struct fpgamgr_a10_softc),
438 };
439
440 DRIVER_MODULE(fpgamgr_a10, simplebus, fpgamgr_a10_driver, 0, 0);
Cache object: fc3b4af003e11dd62a5cd44062c92fc4
|