1 /* 2 * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP 3 * 4 * Copyright (C) 2017 DENX Software Engineering 5 * 6 * Anatolij Gustschin <agust@denx.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * Manage Altera FPGA firmware using PCIe CvP. 18 * Firmware must be in binary "rbf" format. 19 */ 20 21 #include <linux/delay.h> 22 #include <linux/device.h> 23 #include <linux/fpga/fpga-mgr.h> 24 #include <linux/module.h> 25 #include <linux/pci.h> 26 #include <linux/sizes.h> 27 28 #define CVP_BAR 0 /* BAR used for data transfer in memory mode */ 29 #define CVP_DUMMY_WR 244 /* dummy writes to clear CvP state machine */ 30 #define TIMEOUT_US 2000 /* CVP STATUS timeout for USERMODE polling */ 31 32 /* Vendor Specific Extended Capability Registers */ 33 #define VSE_PCIE_EXT_CAP_ID 0x200 34 #define VSE_PCIE_EXT_CAP_ID_VAL 0x000b /* 16bit */ 35 36 #define VSE_CVP_STATUS 0x21c /* 32bit */ 37 #define VSE_CVP_STATUS_CFG_RDY BIT(18) /* CVP_CONFIG_READY */ 38 #define VSE_CVP_STATUS_CFG_ERR BIT(19) /* CVP_CONFIG_ERROR */ 39 #define VSE_CVP_STATUS_CVP_EN BIT(20) /* ctrl block is enabling CVP */ 40 #define VSE_CVP_STATUS_USERMODE BIT(21) /* USERMODE */ 41 #define VSE_CVP_STATUS_CFG_DONE BIT(23) /* CVP_CONFIG_DONE */ 42 #define VSE_CVP_STATUS_PLD_CLK_IN_USE BIT(24) /* PLD_CLK_IN_USE */ 43 44 #define VSE_CVP_MODE_CTRL 0x220 /* 32bit */ 45 #define VSE_CVP_MODE_CTRL_CVP_MODE BIT(0) /* CVP (1) or normal mode (0) */ 46 #define VSE_CVP_MODE_CTRL_HIP_CLK_SEL BIT(1) /* PMA (1) or fabric clock (0) */ 47 #define VSE_CVP_MODE_CTRL_NUMCLKS_OFF 8 /* NUMCLKS bits offset */ 48 #define VSE_CVP_MODE_CTRL_NUMCLKS_MASK GENMASK(15, 8) 49 50 #define VSE_CVP_DATA 0x228 /* 32bit */ 51 #define VSE_CVP_PROG_CTRL 0x22c /* 32bit */ 52 #define VSE_CVP_PROG_CTRL_CONFIG BIT(0) 53 #define VSE_CVP_PROG_CTRL_START_XFER BIT(1) 54 55 #define VSE_UNCOR_ERR_STATUS 0x234 /* 32bit */ 56 #define VSE_UNCOR_ERR_CVP_CFG_ERR BIT(5) /* CVP_CONFIG_ERROR_LATCHED */ 57 58 #define DRV_NAME "altera-cvp" 59 #define ALTERA_CVP_MGR_NAME "Altera CvP FPGA Manager" 60 61 /* Optional CvP config error status check for debugging */ 62 static bool altera_cvp_chkcfg; 63 64 struct altera_cvp_conf { 65 struct fpga_manager *mgr; 66 struct pci_dev *pci_dev; 67 void __iomem *map; 68 void (*write_data)(struct altera_cvp_conf *, u32); 69 char mgr_name[64]; 70 u8 numclks; 71 }; 72 73 static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr) 74 { 75 struct altera_cvp_conf *conf = mgr->priv; 76 u32 status; 77 78 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &status); 79 80 if (status & VSE_CVP_STATUS_CFG_DONE) 81 return FPGA_MGR_STATE_OPERATING; 82 83 if (status & VSE_CVP_STATUS_CVP_EN) 84 return FPGA_MGR_STATE_POWER_UP; 85 86 return FPGA_MGR_STATE_UNKNOWN; 87 } 88 89 static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val) 90 { 91 writel(val, conf->map); 92 } 93 94 static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val) 95 { 96 pci_write_config_dword(conf->pci_dev, VSE_CVP_DATA, val); 97 } 98 99 /* switches between CvP clock and internal clock */ 100 static void altera_cvp_dummy_write(struct altera_cvp_conf *conf) 101 { 102 unsigned int i; 103 u32 val; 104 105 /* set 1 CVP clock cycle for every CVP Data Register Write */ 106 pci_read_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, &val); 107 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 108 val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 109 pci_write_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, val); 110 111 for (i = 0; i < CVP_DUMMY_WR; i++) 112 conf->write_data(conf, 0); /* dummy data, could be any value */ 113 } 114 115 static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask, 116 u32 status_val, int timeout_us) 117 { 118 unsigned int retries; 119 u32 val; 120 121 retries = timeout_us / 10; 122 if (timeout_us % 10) 123 retries++; 124 125 do { 126 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 127 if ((val & status_mask) == status_val) 128 return 0; 129 130 /* use small usleep value to re-check and break early */ 131 usleep_range(10, 11); 132 } while (--retries); 133 134 return -ETIMEDOUT; 135 } 136 137 static int altera_cvp_teardown(struct fpga_manager *mgr, 138 struct fpga_image_info *info) 139 { 140 struct altera_cvp_conf *conf = mgr->priv; 141 struct pci_dev *pdev = conf->pci_dev; 142 int ret; 143 u32 val; 144 145 /* STEP 12 - reset START_XFER bit */ 146 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 147 val &= ~VSE_CVP_PROG_CTRL_START_XFER; 148 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 149 150 /* STEP 13 - reset CVP_CONFIG bit */ 151 val &= ~VSE_CVP_PROG_CTRL_CONFIG; 152 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 153 154 /* 155 * STEP 14 156 * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy 157 * writes to the HIP 158 */ 159 altera_cvp_dummy_write(conf); /* from CVP clock to internal clock */ 160 161 /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */ 162 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0, 10); 163 if (ret) 164 dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n"); 165 166 return ret; 167 } 168 169 static int altera_cvp_write_init(struct fpga_manager *mgr, 170 struct fpga_image_info *info, 171 const char *buf, size_t count) 172 { 173 struct altera_cvp_conf *conf = mgr->priv; 174 struct pci_dev *pdev = conf->pci_dev; 175 u32 iflags, val; 176 int ret; 177 178 iflags = info ? info->flags : 0; 179 180 if (iflags & FPGA_MGR_PARTIAL_RECONFIG) { 181 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); 182 return -EINVAL; 183 } 184 185 /* Determine allowed clock to data ratio */ 186 if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM) 187 conf->numclks = 8; /* ratio for all compressed images */ 188 else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM) 189 conf->numclks = 4; /* for uncompressed and encrypted images */ 190 else 191 conf->numclks = 1; /* for uncompressed and unencrypted images */ 192 193 /* STEP 1 - read CVP status and check CVP_EN flag */ 194 pci_read_config_dword(pdev, VSE_CVP_STATUS, &val); 195 if (!(val & VSE_CVP_STATUS_CVP_EN)) { 196 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val); 197 return -ENODEV; 198 } 199 200 if (val & VSE_CVP_STATUS_CFG_RDY) { 201 dev_warn(&mgr->dev, "CvP already started, teardown first\n"); 202 ret = altera_cvp_teardown(mgr, info); 203 if (ret) 204 return ret; 205 } 206 207 /* 208 * STEP 2 209 * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned) 210 */ 211 /* switch from fabric to PMA clock */ 212 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 213 val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 214 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 215 216 /* set CVP mode */ 217 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 218 val |= VSE_CVP_MODE_CTRL_CVP_MODE; 219 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 220 221 /* 222 * STEP 3 223 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP 224 */ 225 altera_cvp_dummy_write(conf); 226 227 /* STEP 4 - set CVP_CONFIG bit */ 228 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 229 /* request control block to begin transfer using CVP */ 230 val |= VSE_CVP_PROG_CTRL_CONFIG; 231 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 232 233 /* STEP 5 - poll CVP_CONFIG READY for 1 with 10us timeout */ 234 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 235 VSE_CVP_STATUS_CFG_RDY, 10); 236 if (ret) { 237 dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n"); 238 return ret; 239 } 240 241 /* 242 * STEP 6 243 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP 244 */ 245 altera_cvp_dummy_write(conf); 246 247 /* STEP 7 - set START_XFER */ 248 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 249 val |= VSE_CVP_PROG_CTRL_START_XFER; 250 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 251 252 /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */ 253 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 254 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 255 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 256 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 257 258 return 0; 259 } 260 261 static inline int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes) 262 { 263 struct altera_cvp_conf *conf = mgr->priv; 264 u32 val; 265 266 /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ 267 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 268 if (val & VSE_CVP_STATUS_CFG_ERR) { 269 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", 270 bytes); 271 return -EPROTO; 272 } 273 return 0; 274 } 275 276 static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, 277 size_t count) 278 { 279 struct altera_cvp_conf *conf = mgr->priv; 280 const u32 *data; 281 size_t done, remaining; 282 int status = 0; 283 u32 mask; 284 285 /* STEP 9 - write 32-bit data from RBF file to CVP data register */ 286 data = (u32 *)buf; 287 remaining = count; 288 done = 0; 289 290 while (remaining >= 4) { 291 conf->write_data(conf, *data++); 292 done += 4; 293 remaining -= 4; 294 295 /* 296 * STEP 10 (optional) and STEP 11 297 * - check error flag 298 * - loop until data transfer completed 299 * Config images can be huge (more than 40 MiB), so 300 * only check after a new 4k data block has been written. 301 * This reduces the number of checks and speeds up the 302 * configuration process. 303 */ 304 if (altera_cvp_chkcfg && !(done % SZ_4K)) { 305 status = altera_cvp_chk_error(mgr, done); 306 if (status < 0) 307 return status; 308 } 309 } 310 311 /* write up to 3 trailing bytes, if any */ 312 mask = BIT(remaining * 8) - 1; 313 if (mask) 314 conf->write_data(conf, *data & mask); 315 316 if (altera_cvp_chkcfg) 317 status = altera_cvp_chk_error(mgr, count); 318 319 return status; 320 } 321 322 static int altera_cvp_write_complete(struct fpga_manager *mgr, 323 struct fpga_image_info *info) 324 { 325 struct altera_cvp_conf *conf = mgr->priv; 326 struct pci_dev *pdev = conf->pci_dev; 327 int ret; 328 u32 mask; 329 u32 val; 330 331 ret = altera_cvp_teardown(mgr, info); 332 if (ret) 333 return ret; 334 335 /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */ 336 pci_read_config_dword(pdev, VSE_UNCOR_ERR_STATUS, &val); 337 if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) { 338 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n"); 339 return -EPROTO; 340 } 341 342 /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */ 343 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 344 val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 345 val &= ~VSE_CVP_MODE_CTRL_CVP_MODE; 346 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 347 348 /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */ 349 mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE; 350 ret = altera_cvp_wait_status(conf, mask, mask, TIMEOUT_US); 351 if (ret) 352 dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n"); 353 354 return ret; 355 } 356 357 static const struct fpga_manager_ops altera_cvp_ops = { 358 .state = altera_cvp_state, 359 .write_init = altera_cvp_write_init, 360 .write = altera_cvp_write, 361 .write_complete = altera_cvp_write_complete, 362 }; 363 364 static ssize_t chkcfg_show(struct device_driver *dev, char *buf) 365 { 366 return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg); 367 } 368 369 static ssize_t chkcfg_store(struct device_driver *drv, const char *buf, 370 size_t count) 371 { 372 int ret; 373 374 ret = kstrtobool(buf, &altera_cvp_chkcfg); 375 if (ret) 376 return ret; 377 378 return count; 379 } 380 381 static DRIVER_ATTR_RW(chkcfg); 382 383 static int altera_cvp_probe(struct pci_dev *pdev, 384 const struct pci_device_id *dev_id); 385 static void altera_cvp_remove(struct pci_dev *pdev); 386 387 static struct pci_device_id altera_cvp_id_tbl[] = { 388 { PCI_VDEVICE(ALTERA, PCI_ANY_ID) }, 389 { } 390 }; 391 MODULE_DEVICE_TABLE(pci, altera_cvp_id_tbl); 392 393 static struct pci_driver altera_cvp_driver = { 394 .name = DRV_NAME, 395 .id_table = altera_cvp_id_tbl, 396 .probe = altera_cvp_probe, 397 .remove = altera_cvp_remove, 398 }; 399 400 static int altera_cvp_probe(struct pci_dev *pdev, 401 const struct pci_device_id *dev_id) 402 { 403 struct altera_cvp_conf *conf; 404 struct fpga_manager *mgr; 405 u16 cmd, val; 406 int ret; 407 408 /* 409 * First check if this is the expected FPGA device. PCI config 410 * space access works without enabling the PCI device, memory 411 * space access is enabled further down. 412 */ 413 pci_read_config_word(pdev, VSE_PCIE_EXT_CAP_ID, &val); 414 if (val != VSE_PCIE_EXT_CAP_ID_VAL) { 415 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val); 416 return -ENODEV; 417 } 418 419 conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL); 420 if (!conf) 421 return -ENOMEM; 422 423 /* 424 * Enable memory BAR access. We cannot use pci_enable_device() here 425 * because it will make the driver unusable with FPGA devices that 426 * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit 427 * platform. Such BARs will not have an assigned address range and 428 * pci_enable_device() will fail, complaining about not claimed BAR, 429 * even if the concerned BAR is not needed for FPGA configuration 430 * at all. Thus, enable the device via PCI config space command. 431 */ 432 pci_read_config_word(pdev, PCI_COMMAND, &cmd); 433 if (!(cmd & PCI_COMMAND_MEMORY)) { 434 cmd |= PCI_COMMAND_MEMORY; 435 pci_write_config_word(pdev, PCI_COMMAND, cmd); 436 } 437 438 ret = pci_request_region(pdev, CVP_BAR, "CVP"); 439 if (ret) { 440 dev_err(&pdev->dev, "Requesting CVP BAR region failed\n"); 441 goto err_disable; 442 } 443 444 conf->pci_dev = pdev; 445 conf->write_data = altera_cvp_write_data_iomem; 446 447 conf->map = pci_iomap(pdev, CVP_BAR, 0); 448 if (!conf->map) { 449 dev_warn(&pdev->dev, "Mapping CVP BAR failed\n"); 450 conf->write_data = altera_cvp_write_data_config; 451 } 452 453 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s", 454 ALTERA_CVP_MGR_NAME, pci_name(pdev)); 455 456 mgr = devm_fpga_mgr_create(&pdev->dev, conf->mgr_name, 457 &altera_cvp_ops, conf); 458 if (!mgr) { 459 ret = -ENOMEM; 460 goto err_unmap; 461 } 462 463 pci_set_drvdata(pdev, mgr); 464 465 ret = fpga_mgr_register(mgr); 466 if (ret) 467 goto err_unmap; 468 469 ret = driver_create_file(&altera_cvp_driver.driver, 470 &driver_attr_chkcfg); 471 if (ret) { 472 dev_err(&pdev->dev, "Can't create sysfs chkcfg file\n"); 473 fpga_mgr_unregister(mgr); 474 goto err_unmap; 475 } 476 477 return 0; 478 479 err_unmap: 480 pci_iounmap(pdev, conf->map); 481 pci_release_region(pdev, CVP_BAR); 482 err_disable: 483 cmd &= ~PCI_COMMAND_MEMORY; 484 pci_write_config_word(pdev, PCI_COMMAND, cmd); 485 return ret; 486 } 487 488 static void altera_cvp_remove(struct pci_dev *pdev) 489 { 490 struct fpga_manager *mgr = pci_get_drvdata(pdev); 491 struct altera_cvp_conf *conf = mgr->priv; 492 u16 cmd; 493 494 driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg); 495 fpga_mgr_unregister(mgr); 496 pci_iounmap(pdev, conf->map); 497 pci_release_region(pdev, CVP_BAR); 498 pci_read_config_word(pdev, PCI_COMMAND, &cmd); 499 cmd &= ~PCI_COMMAND_MEMORY; 500 pci_write_config_word(pdev, PCI_COMMAND, cmd); 501 } 502 503 module_pci_driver(altera_cvp_driver); 504 505 MODULE_LICENSE("GPL v2"); 506 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); 507 MODULE_DESCRIPTION("Module to load Altera FPGA over CvP"); 508