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