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 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 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 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 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 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 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 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