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/param.h>
38 #include <sys/systm.h>
39 #include <sys/bus.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/malloc.h>
43 #include <sys/rman.h>
44 #include <sys/timeet.h>
45 #include <sys/timetc.h>
46 #include <sys/conf.h>
47 #include <sys/uio.h>
48
49 #include <dev/ofw/openfirm.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #include <machine/bus.h>
54 #include <machine/cpu.h>
55 #include <machine/intr.h>
56
57 #include <arm/altera/socfpga/socfpga_common.h>
58
59 #define FPGAMGR_DCLKCNT 0x8 /* DCLK Count Register */
60 #define FPGAMGR_DCLKSTAT 0xC /* DCLK Status Register */
61 #define FPGAMGR_GPO 0x10 /* General-Purpose Output Register */
62 #define FPGAMGR_GPI 0x14 /* General-Purpose Input Register */
63 #define FPGAMGR_MISCI 0x18 /* Miscellaneous Input Register */
64 #define IMGCFG_CTRL_00 0x70
65 #define S2F_CONDONE_OE (1 << 24)
66 #define S2F_NSTATUS_OE (1 << 16)
67 #define CTRL_00_NCONFIG (1 << 8)
68 #define CTRL_00_NENABLE_CONDONE (1 << 2)
69 #define CTRL_00_NENABLE_NSTATUS (1 << 1)
70 #define CTRL_00_NENABLE_NCONFIG (1 << 0)
71 #define IMGCFG_CTRL_01 0x74
72 #define CTRL_01_S2F_NCE (1 << 24)
73 #define CTRL_01_S2F_PR_REQUEST (1 << 16)
74 #define CTRL_01_S2F_NENABLE_CONFIG (1 << 0)
75 #define IMGCFG_CTRL_02 0x78
76 #define CTRL_02_CDRATIO_S 16
77 #define CTRL_02_CDRATIO_M (0x3 << CTRL_02_CDRATIO_S)
78 #define CTRL_02_CFGWIDTH_16 (0 << 24)
79 #define CTRL_02_CFGWIDTH_32 (1 << 24)
80 #define CTRL_02_EN_CFG_DATA (1 << 8)
81 #define CTRL_02_EN_CFG_CTRL (1 << 0)
82 #define IMGCFG_STAT 0x80
83 #define F2S_PR_ERROR (1 << 11)
84 #define F2S_PR_DONE (1 << 10)
85 #define F2S_PR_READY (1 << 9)
86 #define F2S_MSEL_S 16
87 #define F2S_MSEL_M (0x7 << F2S_MSEL_S)
88 #define MSEL_PASSIVE_FAST 0
89 #define MSEL_PASSIVE_SLOW 1
90 #define F2S_NCONFIG_PIN (1 << 12)
91 #define F2S_CONDONE_OE (1 << 7)
92 #define F2S_NSTATUS_PIN (1 << 4)
93 #define F2S_CONDONE_PIN (1 << 6)
94 #define F2S_USERMODE (1 << 2)
95
96 struct fpgamgr_a10_softc {
97 struct resource *res[2];
98 bus_space_tag_t bst_data;
99 bus_space_handle_t bsh_data;
100 struct cdev *mgr_cdev;
101 device_t dev;
102 };
103
104 static struct resource_spec fpgamgr_a10_spec[] = {
105 { SYS_RES_MEMORY, 0, RF_ACTIVE },
106 { SYS_RES_MEMORY, 1, RF_ACTIVE },
107 { -1, 0 }
108 };
109
110 static int
fpga_wait_dclk_pulses(struct fpgamgr_a10_softc * sc,int npulses)111 fpga_wait_dclk_pulses(struct fpgamgr_a10_softc *sc, int npulses)
112 {
113 int tout;
114
115 /* Clear done bit, if any */
116 if (READ4(sc, FPGAMGR_DCLKSTAT) != 0)
117 WRITE4(sc, FPGAMGR_DCLKSTAT, 0x1);
118
119 /* Request DCLK pulses */
120 WRITE4(sc, FPGAMGR_DCLKCNT, npulses);
121
122 /* Wait finish */
123 tout = 1000;
124 while (tout > 0) {
125 if (READ4(sc, FPGAMGR_DCLKSTAT) == 1) {
126 WRITE4(sc, FPGAMGR_DCLKSTAT, 0x1);
127 break;
128 }
129 tout--;
130 DELAY(10);
131 }
132 if (tout == 0) {
133 device_printf(sc->dev,
134 "Error: dclkpulses wait timeout\n");
135 return (1);
136 }
137
138 return (0);
139 }
140
141 static int
fpga_open(struct cdev * dev,int flags __unused,int fmt __unused,struct thread * td __unused)142 fpga_open(struct cdev *dev, int flags __unused,
143 int fmt __unused, struct thread *td __unused)
144 {
145 struct fpgamgr_a10_softc *sc;
146 int tout;
147 int msel;
148 int reg;
149
150 sc = dev->si_drv1;
151
152 /* Step 1 */
153 reg = READ4(sc, IMGCFG_STAT);
154 if ((reg & F2S_USERMODE) == 0) {
155 device_printf(sc->dev, "Error: invalid mode\n");
156 return (ENXIO);
157 };
158
159 /* Step 2 */
160 reg = READ4(sc, IMGCFG_STAT);
161 msel = (reg & F2S_MSEL_M) >> F2S_MSEL_S;
162 if ((msel != MSEL_PASSIVE_FAST) && \
163 (msel != MSEL_PASSIVE_SLOW)) {
164 device_printf(sc->dev,
165 "Error: invalid msel %d\n", msel);
166 return (ENXIO);
167 };
168
169 /*
170 * Step 3.
171 * TODO: add support for compressed, encrypted images.
172 */
173 reg = READ4(sc, IMGCFG_CTRL_02);
174 reg &= ~(CTRL_02_CDRATIO_M);
175 WRITE4(sc, IMGCFG_CTRL_02, reg);
176
177 reg = READ4(sc, IMGCFG_CTRL_02);
178 reg &= ~CTRL_02_CFGWIDTH_32;
179 WRITE4(sc, IMGCFG_CTRL_02, reg);
180
181 /* Step 4. a */
182 reg = READ4(sc, IMGCFG_CTRL_01);
183 reg &= ~CTRL_01_S2F_PR_REQUEST;
184 WRITE4(sc, IMGCFG_CTRL_01, reg);
185
186 reg = READ4(sc, IMGCFG_CTRL_00);
187 reg |= CTRL_00_NCONFIG;
188 WRITE4(sc, IMGCFG_CTRL_00, reg);
189
190 /* b */
191 reg = READ4(sc, IMGCFG_CTRL_01);
192 reg &= ~CTRL_01_S2F_NCE;
193 WRITE4(sc, IMGCFG_CTRL_01, reg);
194
195 /* c */
196 reg = READ4(sc, IMGCFG_CTRL_02);
197 reg |= CTRL_02_EN_CFG_CTRL;
198 WRITE4(sc, IMGCFG_CTRL_02, reg);
199
200 /* d */
201 reg = READ4(sc, IMGCFG_CTRL_00);
202 reg &= ~S2F_CONDONE_OE;
203 reg &= ~S2F_NSTATUS_OE;
204 reg |= CTRL_00_NCONFIG;
205 reg |= CTRL_00_NENABLE_NSTATUS;
206 reg |= CTRL_00_NENABLE_CONDONE;
207 reg &= ~CTRL_00_NENABLE_NCONFIG;
208 WRITE4(sc, IMGCFG_CTRL_00, reg);
209
210 /* Step 5 */
211 reg = READ4(sc, IMGCFG_CTRL_01);
212 reg &= ~CTRL_01_S2F_NENABLE_CONFIG;
213 WRITE4(sc, IMGCFG_CTRL_01, reg);
214
215 /* Step 6 */
216 fpga_wait_dclk_pulses(sc, 0x100);
217
218 /* Step 7. a */
219 reg = READ4(sc, IMGCFG_CTRL_01);
220 reg |= CTRL_01_S2F_PR_REQUEST;
221 WRITE4(sc, IMGCFG_CTRL_01, reg);
222
223 /* b, c */
224 fpga_wait_dclk_pulses(sc, 0x7ff);
225
226 /* Step 8 */
227 tout = 10;
228 while (tout--) {
229 reg = READ4(sc, IMGCFG_STAT);
230 if (reg & F2S_PR_ERROR) {
231 device_printf(sc->dev,
232 "Error: PR failed on open.\n");
233 return (ENXIO);
234 }
235 if (reg & F2S_PR_READY) {
236 break;
237 }
238 }
239 if (tout == 0) {
240 device_printf(sc->dev,
241 "Error: Timeout waiting PR ready bit.\n");
242 return (ENXIO);
243 }
244
245 return (0);
246 }
247
248 static int
fpga_close(struct cdev * dev,int flags __unused,int fmt __unused,struct thread * td __unused)249 fpga_close(struct cdev *dev, int flags __unused,
250 int fmt __unused, struct thread *td __unused)
251 {
252 struct fpgamgr_a10_softc *sc;
253 int tout;
254 int reg;
255
256 sc = dev->si_drv1;
257
258 /* Step 10 */
259 tout = 10;
260 while (tout--) {
261 reg = READ4(sc, IMGCFG_STAT);
262 if (reg & F2S_PR_ERROR) {
263 device_printf(sc->dev,
264 "Error: PR failed.\n");
265 return (ENXIO);
266 }
267 if (reg & F2S_PR_DONE) {
268 break;
269 }
270 }
271
272 /* Step 11 */
273 reg = READ4(sc, IMGCFG_CTRL_01);
274 reg &= ~CTRL_01_S2F_PR_REQUEST;
275 WRITE4(sc, IMGCFG_CTRL_01, reg);
276
277 /* Step 12, 13 */
278 fpga_wait_dclk_pulses(sc, 0x100);
279
280 /* Step 14 */
281 reg = READ4(sc, IMGCFG_CTRL_02);
282 reg &= ~CTRL_02_EN_CFG_CTRL;
283 WRITE4(sc, IMGCFG_CTRL_02, reg);
284
285 /* Step 15 */
286 reg = READ4(sc, IMGCFG_CTRL_01);
287 reg |= CTRL_01_S2F_NCE;
288 WRITE4(sc, IMGCFG_CTRL_01, reg);
289
290 /* Step 16 */
291 reg = READ4(sc, IMGCFG_CTRL_01);
292 reg |= CTRL_01_S2F_NENABLE_CONFIG;
293 WRITE4(sc, IMGCFG_CTRL_01, reg);
294
295 /* Step 17 */
296 reg = READ4(sc, IMGCFG_STAT);
297 if ((reg & F2S_USERMODE) == 0) {
298 device_printf(sc->dev,
299 "Error: invalid mode\n");
300 return (ENXIO);
301 };
302
303 if ((reg & F2S_CONDONE_PIN) == 0) {
304 device_printf(sc->dev,
305 "Error: configuration not done\n");
306 return (ENXIO);
307 };
308
309 if ((reg & F2S_NSTATUS_PIN) == 0) {
310 device_printf(sc->dev,
311 "Error: nstatus pin\n");
312 return (ENXIO);
313 };
314
315 return (0);
316 }
317
318 static int
fpga_write(struct cdev * dev,struct uio * uio,int ioflag)319 fpga_write(struct cdev *dev, struct uio *uio, int ioflag)
320 {
321 struct fpgamgr_a10_softc *sc;
322 uint32_t buffer;
323
324 sc = dev->si_drv1;
325
326 /*
327 * Step 9.
328 * Device supports 4-byte writes only.
329 */
330
331 while (uio->uio_resid >= 4) {
332 uiomove(&buffer, 4, uio);
333 bus_space_write_4(sc->bst_data, sc->bsh_data,
334 0x0, buffer);
335 }
336
337 switch (uio->uio_resid) {
338 case 3:
339 uiomove(&buffer, 3, uio);
340 buffer &= 0xffffff;
341 bus_space_write_4(sc->bst_data, sc->bsh_data,
342 0x0, buffer);
343 break;
344 case 2:
345 uiomove(&buffer, 2, uio);
346 buffer &= 0xffff;
347 bus_space_write_4(sc->bst_data, sc->bsh_data,
348 0x0, buffer);
349 break;
350 case 1:
351 uiomove(&buffer, 1, uio);
352 buffer &= 0xff;
353 bus_space_write_4(sc->bst_data, sc->bsh_data,
354 0x0, buffer);
355 break;
356 default:
357 break;
358 };
359
360 return (0);
361 }
362
363 static int
fpga_ioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flags,struct thread * td)364 fpga_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
365 struct thread *td)
366 {
367
368 return (0);
369 }
370
371 static struct cdevsw fpga_cdevsw = {
372 .d_version = D_VERSION,
373 .d_open = fpga_open,
374 .d_close = fpga_close,
375 .d_write = fpga_write,
376 .d_ioctl = fpga_ioctl,
377 .d_name = "FPGA Manager",
378 };
379
380 static int
fpgamgr_a10_probe(device_t dev)381 fpgamgr_a10_probe(device_t dev)
382 {
383
384 if (!ofw_bus_status_okay(dev))
385 return (ENXIO);
386
387 if (!ofw_bus_is_compatible(dev, "altr,socfpga-a10-fpga-mgr"))
388 return (ENXIO);
389
390 device_set_desc(dev, "Arria 10 FPGA Manager");
391
392 return (BUS_PROBE_DEFAULT);
393 }
394
395 static int
fpgamgr_a10_attach(device_t dev)396 fpgamgr_a10_attach(device_t dev)
397 {
398 struct fpgamgr_a10_softc *sc;
399
400 sc = device_get_softc(dev);
401 sc->dev = dev;
402
403 if (bus_alloc_resources(dev, fpgamgr_a10_spec, sc->res)) {
404 device_printf(dev, "Could not allocate resources.\n");
405 return (ENXIO);
406 }
407
408 /* Memory interface */
409 sc->bst_data = rman_get_bustag(sc->res[1]);
410 sc->bsh_data = rman_get_bushandle(sc->res[1]);
411
412 sc->mgr_cdev = make_dev(&fpga_cdevsw, 0, UID_ROOT, GID_WHEEL,
413 0600, "fpga%d", device_get_unit(sc->dev));
414
415 if (sc->mgr_cdev == NULL) {
416 device_printf(dev, "Failed to create character device.\n");
417 return (ENXIO);
418 }
419
420 sc->mgr_cdev->si_drv1 = sc;
421
422 return (0);
423 }
424
425 static device_method_t fpgamgr_a10_methods[] = {
426 DEVMETHOD(device_probe, fpgamgr_a10_probe),
427 DEVMETHOD(device_attach, fpgamgr_a10_attach),
428 { 0, 0 }
429 };
430
431 static driver_t fpgamgr_a10_driver = {
432 "fpgamgr_a10",
433 fpgamgr_a10_methods,
434 sizeof(struct fpgamgr_a10_softc),
435 };
436
437 DRIVER_MODULE(fpgamgr_a10, simplebus, fpgamgr_a10_driver, 0, 0);
438