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);
441