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 145 static int 146 fpga_open(struct cdev *dev, int flags __unused, 147 int fmt __unused, struct thread *td __unused) 148 { 149 struct fpgamgr_a10_softc *sc; 150 int tout; 151 int msel; 152 int reg; 153 154 sc = dev->si_drv1; 155 156 /* Step 1 */ 157 reg = READ4(sc, IMGCFG_STAT); 158 if ((reg & F2S_USERMODE) == 0) { 159 device_printf(sc->dev, "Error: invalid mode\n"); 160 return (ENXIO); 161 }; 162 163 /* Step 2 */ 164 reg = READ4(sc, IMGCFG_STAT); 165 msel = (reg & F2S_MSEL_M) >> F2S_MSEL_S; 166 if ((msel != MSEL_PASSIVE_FAST) && \ 167 (msel != MSEL_PASSIVE_SLOW)) { 168 device_printf(sc->dev, 169 "Error: invalid msel %d\n", msel); 170 return (ENXIO); 171 }; 172 173 /* 174 * Step 3. 175 * TODO: add support for compressed, encrypted images. 176 */ 177 reg = READ4(sc, IMGCFG_CTRL_02); 178 reg &= ~(CTRL_02_CDRATIO_M); 179 WRITE4(sc, IMGCFG_CTRL_02, reg); 180 181 reg = READ4(sc, IMGCFG_CTRL_02); 182 reg &= ~CTRL_02_CFGWIDTH_32; 183 WRITE4(sc, IMGCFG_CTRL_02, reg); 184 185 /* Step 4. a */ 186 reg = READ4(sc, IMGCFG_CTRL_01); 187 reg &= ~CTRL_01_S2F_PR_REQUEST; 188 WRITE4(sc, IMGCFG_CTRL_01, reg); 189 190 reg = READ4(sc, IMGCFG_CTRL_00); 191 reg |= CTRL_00_NCONFIG; 192 WRITE4(sc, IMGCFG_CTRL_00, reg); 193 194 /* b */ 195 reg = READ4(sc, IMGCFG_CTRL_01); 196 reg &= ~CTRL_01_S2F_NCE; 197 WRITE4(sc, IMGCFG_CTRL_01, reg); 198 199 /* c */ 200 reg = READ4(sc, IMGCFG_CTRL_02); 201 reg |= CTRL_02_EN_CFG_CTRL; 202 WRITE4(sc, IMGCFG_CTRL_02, reg); 203 204 /* d */ 205 reg = READ4(sc, IMGCFG_CTRL_00); 206 reg &= ~S2F_CONDONE_OE; 207 reg &= ~S2F_NSTATUS_OE; 208 reg |= CTRL_00_NCONFIG; 209 reg |= CTRL_00_NENABLE_NSTATUS; 210 reg |= CTRL_00_NENABLE_CONDONE; 211 reg &= ~CTRL_00_NENABLE_NCONFIG; 212 WRITE4(sc, IMGCFG_CTRL_00, reg); 213 214 /* Step 5 */ 215 reg = READ4(sc, IMGCFG_CTRL_01); 216 reg &= ~CTRL_01_S2F_NENABLE_CONFIG; 217 WRITE4(sc, IMGCFG_CTRL_01, reg); 218 219 /* Step 6 */ 220 fpga_wait_dclk_pulses(sc, 0x100); 221 222 /* Step 7. a */ 223 reg = READ4(sc, IMGCFG_CTRL_01); 224 reg |= CTRL_01_S2F_PR_REQUEST; 225 WRITE4(sc, IMGCFG_CTRL_01, reg); 226 227 /* b, c */ 228 fpga_wait_dclk_pulses(sc, 0x7ff); 229 230 /* Step 8 */ 231 tout = 10; 232 while (tout--) { 233 reg = READ4(sc, IMGCFG_STAT); 234 if (reg & F2S_PR_ERROR) { 235 device_printf(sc->dev, 236 "Error: PR failed on open.\n"); 237 return (ENXIO); 238 } 239 if (reg & F2S_PR_READY) { 240 break; 241 } 242 } 243 if (tout == 0) { 244 device_printf(sc->dev, 245 "Error: Timeout waiting PR ready bit.\n"); 246 return (ENXIO); 247 } 248 249 return (0); 250 } 251 252 static int 253 fpga_close(struct cdev *dev, int flags __unused, 254 int fmt __unused, struct thread *td __unused) 255 { 256 struct fpgamgr_a10_softc *sc; 257 int tout; 258 int reg; 259 260 sc = dev->si_drv1; 261 262 /* Step 10 */ 263 tout = 10; 264 while (tout--) { 265 reg = READ4(sc, IMGCFG_STAT); 266 if (reg & F2S_PR_ERROR) { 267 device_printf(sc->dev, 268 "Error: PR failed.\n"); 269 return (ENXIO); 270 } 271 if (reg & F2S_PR_DONE) { 272 break; 273 } 274 } 275 276 /* Step 11 */ 277 reg = READ4(sc, IMGCFG_CTRL_01); 278 reg &= ~CTRL_01_S2F_PR_REQUEST; 279 WRITE4(sc, IMGCFG_CTRL_01, reg); 280 281 /* Step 12, 13 */ 282 fpga_wait_dclk_pulses(sc, 0x100); 283 284 /* Step 14 */ 285 reg = READ4(sc, IMGCFG_CTRL_02); 286 reg &= ~CTRL_02_EN_CFG_CTRL; 287 WRITE4(sc, IMGCFG_CTRL_02, reg); 288 289 /* Step 15 */ 290 reg = READ4(sc, IMGCFG_CTRL_01); 291 reg |= CTRL_01_S2F_NCE; 292 WRITE4(sc, IMGCFG_CTRL_01, reg); 293 294 /* Step 16 */ 295 reg = READ4(sc, IMGCFG_CTRL_01); 296 reg |= CTRL_01_S2F_NENABLE_CONFIG; 297 WRITE4(sc, IMGCFG_CTRL_01, reg); 298 299 /* Step 17 */ 300 reg = READ4(sc, IMGCFG_STAT); 301 if ((reg & F2S_USERMODE) == 0) { 302 device_printf(sc->dev, 303 "Error: invalid mode\n"); 304 return (ENXIO); 305 }; 306 307 if ((reg & F2S_CONDONE_PIN) == 0) { 308 device_printf(sc->dev, 309 "Error: configuration not done\n"); 310 return (ENXIO); 311 }; 312 313 if ((reg & F2S_NSTATUS_PIN) == 0) { 314 device_printf(sc->dev, 315 "Error: nstatus pin\n"); 316 return (ENXIO); 317 }; 318 319 return (0); 320 } 321 322 static int 323 fpga_write(struct cdev *dev, struct uio *uio, int ioflag) 324 { 325 struct fpgamgr_a10_softc *sc; 326 uint32_t buffer; 327 328 sc = dev->si_drv1; 329 330 /* 331 * Step 9. 332 * Device supports 4-byte writes only. 333 */ 334 335 while (uio->uio_resid >= 4) { 336 uiomove(&buffer, 4, uio); 337 bus_space_write_4(sc->bst_data, sc->bsh_data, 338 0x0, buffer); 339 } 340 341 switch (uio->uio_resid) { 342 case 3: 343 uiomove(&buffer, 3, uio); 344 buffer &= 0xffffff; 345 bus_space_write_4(sc->bst_data, sc->bsh_data, 346 0x0, buffer); 347 break; 348 case 2: 349 uiomove(&buffer, 2, uio); 350 buffer &= 0xffff; 351 bus_space_write_4(sc->bst_data, sc->bsh_data, 352 0x0, buffer); 353 break; 354 case 1: 355 uiomove(&buffer, 1, uio); 356 buffer &= 0xff; 357 bus_space_write_4(sc->bst_data, sc->bsh_data, 358 0x0, buffer); 359 break; 360 default: 361 break; 362 }; 363 364 return (0); 365 } 366 367 static int 368 fpga_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, 369 struct thread *td) 370 { 371 372 return (0); 373 } 374 375 static struct cdevsw fpga_cdevsw = { 376 .d_version = D_VERSION, 377 .d_open = fpga_open, 378 .d_close = fpga_close, 379 .d_write = fpga_write, 380 .d_ioctl = fpga_ioctl, 381 .d_name = "FPGA Manager", 382 }; 383 384 static int 385 fpgamgr_a10_probe(device_t dev) 386 { 387 388 if (!ofw_bus_status_okay(dev)) 389 return (ENXIO); 390 391 if (!ofw_bus_is_compatible(dev, "altr,socfpga-a10-fpga-mgr")) 392 return (ENXIO); 393 394 device_set_desc(dev, "Arria 10 FPGA Manager"); 395 396 return (BUS_PROBE_DEFAULT); 397 } 398 399 static int 400 fpgamgr_a10_attach(device_t dev) 401 { 402 struct fpgamgr_a10_softc *sc; 403 404 sc = device_get_softc(dev); 405 sc->dev = dev; 406 407 if (bus_alloc_resources(dev, fpgamgr_a10_spec, sc->res)) { 408 device_printf(dev, "Could not allocate resources.\n"); 409 return (ENXIO); 410 } 411 412 /* Memory interface */ 413 sc->bst_data = rman_get_bustag(sc->res[1]); 414 sc->bsh_data = rman_get_bushandle(sc->res[1]); 415 416 sc->mgr_cdev = make_dev(&fpga_cdevsw, 0, UID_ROOT, GID_WHEEL, 417 0600, "fpga%d", device_get_unit(sc->dev)); 418 419 if (sc->mgr_cdev == NULL) { 420 device_printf(dev, "Failed to create character device.\n"); 421 return (ENXIO); 422 } 423 424 sc->mgr_cdev->si_drv1 = sc; 425 426 return (0); 427 } 428 429 static device_method_t fpgamgr_a10_methods[] = { 430 DEVMETHOD(device_probe, fpgamgr_a10_probe), 431 DEVMETHOD(device_attach, fpgamgr_a10_attach), 432 { 0, 0 } 433 }; 434 435 static driver_t fpgamgr_a10_driver = { 436 "fpgamgr_a10", 437 fpgamgr_a10_methods, 438 sizeof(struct fpgamgr_a10_softc), 439 }; 440 441 static devclass_t fpgamgr_a10_devclass; 442 443 DRIVER_MODULE(fpgamgr_a10, simplebus, fpgamgr_a10_driver, 444 fpgamgr_a10_devclass, 0, 0); 445