Lines Matching +full:partial +full:- +full:fpga +full:- +full:config

1 // SPDX-License-Identifier: GPL-2.0-only
3 * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP
9 * Manage Altera FPGA firmware using PCIe CvP.
15 #include <linux/fpga/fpga-mgr.h>
62 #define DRV_NAME "altera-cvp"
63 #define ALTERA_CVP_MGR_NAME "Altera CvP FPGA Manager"
69 /* Optional CvP config error status check for debugging */
98 return pci_read_config_byte(conf->pci_dev, conf->vsec_offset + where, in altera_read_config_byte()
105 return pci_read_config_dword(conf->pci_dev, conf->vsec_offset + where, in altera_read_config_dword()
112 return pci_write_config_dword(conf->pci_dev, conf->vsec_offset + where, in altera_write_config_dword()
118 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_state()
134 writel(val, conf->map); in altera_cvp_write_data_iomem()
139 pci_write_config_dword(conf->pci_dev, conf->vsec_offset + VSE_CVP_DATA, in altera_cvp_write_data_config()
156 conf->write_data(conf, 0); /* dummy data, could be any value */ in altera_cvp_dummy_write()
174 /* use small usleep value to re-check and break early */ in altera_cvp_wait_status()
176 } while (--retries); in altera_cvp_wait_status()
178 return -ETIMEDOUT; in altera_cvp_wait_status()
183 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_chk_error()
187 /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ in altera_cvp_chk_error()
190 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", in altera_cvp_chk_error()
192 return -EPROTO; in altera_cvp_chk_error()
211 dev_err(&conf->pci_dev->dev, in altera_cvp_v2_clear_state()
219 dev_err(&conf->pci_dev->dev, in altera_cvp_v2_clear_state()
225 conf->priv->poll_time_us); in altera_cvp_v2_clear_state()
232 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_v2_wait_for_credit()
239 dev_err(&conf->pci_dev->dev, in altera_cvp_v2_wait_for_credit()
245 if (val - (u8)conf->sent_packets) in altera_cvp_v2_wait_for_credit()
250 dev_err(&conf->pci_dev->dev, in altera_cvp_v2_wait_for_credit()
252 val, conf->sent_packets); in altera_cvp_v2_wait_for_credit()
253 return -EAGAIN; in altera_cvp_v2_wait_for_credit()
258 } while (timeout--); in altera_cvp_v2_wait_for_credit()
260 dev_err(&conf->pci_dev->dev, "Timeout waiting for credit\n"); in altera_cvp_v2_wait_for_credit()
261 return -ETIMEDOUT; in altera_cvp_v2_wait_for_credit()
271 conf->write_data(conf, *data++); in altera_cvp_send_block()
276 mask = BIT(remainder * 8) - 1; in altera_cvp_send_block()
278 conf->write_data(conf, *data & mask); in altera_cvp_send_block()
287 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_teardown()
291 /* STEP 12 - reset START_XFER bit */ in altera_cvp_teardown()
296 /* STEP 13 - reset CVP_CONFIG bit */ in altera_cvp_teardown()
302 * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy in altera_cvp_teardown()
305 if (conf->priv->switch_clk) in altera_cvp_teardown()
306 conf->priv->switch_clk(conf); in altera_cvp_teardown()
308 /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */ in altera_cvp_teardown()
310 conf->priv->poll_time_us); in altera_cvp_teardown()
312 dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n"); in altera_cvp_teardown()
321 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_write_init()
325 iflags = info ? info->flags : 0; in altera_cvp_write_init()
328 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); in altera_cvp_write_init()
329 return -EINVAL; in altera_cvp_write_init()
334 conf->numclks = 8; /* ratio for all compressed images */ in altera_cvp_write_init()
336 conf->numclks = 4; /* for uncompressed and encrypted images */ in altera_cvp_write_init()
338 conf->numclks = 1; /* for uncompressed and unencrypted images */ in altera_cvp_write_init()
340 /* STEP 1 - read CVP status and check CVP_EN flag */ in altera_cvp_write_init()
343 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val); in altera_cvp_write_init()
344 return -ENODEV; in altera_cvp_write_init()
348 dev_warn(&mgr->dev, "CvP already started, tear down first\n"); in altera_cvp_write_init()
356 * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned) in altera_cvp_write_init()
370 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP in altera_cvp_write_init()
372 if (conf->priv->switch_clk) in altera_cvp_write_init()
373 conf->priv->switch_clk(conf); in altera_cvp_write_init()
375 if (conf->priv->clear_state) { in altera_cvp_write_init()
376 ret = conf->priv->clear_state(conf); in altera_cvp_write_init()
378 dev_err(&mgr->dev, "Problem clearing out state\n"); in altera_cvp_write_init()
383 conf->sent_packets = 0; in altera_cvp_write_init()
385 /* STEP 4 - set CVP_CONFIG bit */ in altera_cvp_write_init()
391 /* STEP 5 - poll CVP_CONFIG READY for 1 with timeout */ in altera_cvp_write_init()
394 conf->priv->poll_time_us); in altera_cvp_write_init()
396 dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n"); in altera_cvp_write_init()
402 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP in altera_cvp_write_init()
404 if (conf->priv->switch_clk) in altera_cvp_write_init()
405 conf->priv->switch_clk(conf); in altera_cvp_write_init()
410 dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n"); in altera_cvp_write_init()
415 /* STEP 7 - set START_XFER */ in altera_cvp_write_init()
420 /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */ in altera_cvp_write_init()
421 if (conf->priv->switch_clk) { in altera_cvp_write_init()
424 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; in altera_cvp_write_init()
433 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_write()
438 /* STEP 9 - write 32-bit data from RBF file to CVP data register */ in altera_cvp_write()
445 if (conf->priv->wait_credit) { in altera_cvp_write()
446 status = conf->priv->wait_credit(mgr, done); in altera_cvp_write()
448 dev_err(&conf->pci_dev->dev, in altera_cvp_write()
454 len = min(conf->priv->block_size, remaining); in altera_cvp_write()
458 remaining -= len; in altera_cvp_write()
459 conf->sent_packets++; in altera_cvp_write()
463 * - check error flag in altera_cvp_write()
464 * - loop until data transfer completed in altera_cvp_write()
465 * Config images can be huge (more than 40 MiB), so in altera_cvp_write()
486 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_write_complete()
494 /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */ in altera_cvp_write_complete()
497 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n"); in altera_cvp_write_complete()
498 return -EPROTO; in altera_cvp_write_complete()
501 /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */ in altera_cvp_write_complete()
507 /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */ in altera_cvp_write_complete()
510 conf->priv->user_time_us); in altera_cvp_write_complete()
512 dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n"); in altera_cvp_write_complete()
587 dev_err(&pdev->dev, "No Vendor Specific Offset.\n"); in altera_cvp_probe()
588 return -ENODEV; in altera_cvp_probe()
592 * First check if this is the expected FPGA device. PCI config in altera_cvp_probe()
598 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val); in altera_cvp_probe()
599 return -ENODEV; in altera_cvp_probe()
604 dev_err(&pdev->dev, in altera_cvp_probe()
607 return -ENODEV; in altera_cvp_probe()
610 conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL); in altera_cvp_probe()
612 return -ENOMEM; in altera_cvp_probe()
614 conf->vsec_offset = offset; in altera_cvp_probe()
618 * because it will make the driver unusable with FPGA devices that in altera_cvp_probe()
619 * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit in altera_cvp_probe()
622 * even if the concerned BAR is not needed for FPGA configuration in altera_cvp_probe()
623 * at all. Thus, enable the device via PCI config space command. in altera_cvp_probe()
633 dev_err(&pdev->dev, "Requesting CVP BAR region failed\n"); in altera_cvp_probe()
637 conf->pci_dev = pdev; in altera_cvp_probe()
638 conf->write_data = altera_cvp_write_data_iomem; in altera_cvp_probe()
640 if (conf->vsec_offset == V1_VSEC_OFFSET) in altera_cvp_probe()
641 conf->priv = &cvp_priv_v1; in altera_cvp_probe()
643 conf->priv = &cvp_priv_v2; in altera_cvp_probe()
645 conf->map = pci_iomap(pdev, CVP_BAR, 0); in altera_cvp_probe()
646 if (!conf->map) { in altera_cvp_probe()
647 dev_warn(&pdev->dev, "Mapping CVP BAR failed\n"); in altera_cvp_probe()
648 conf->write_data = altera_cvp_write_data_config; in altera_cvp_probe()
651 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s", in altera_cvp_probe()
654 mgr = fpga_mgr_register(&pdev->dev, conf->mgr_name, in altera_cvp_probe()
666 if (conf->map) in altera_cvp_probe()
667 pci_iounmap(pdev, conf->map); in altera_cvp_probe()
678 struct altera_cvp_conf *conf = mgr->priv; in altera_cvp_remove()
682 if (conf->map) in altera_cvp_remove()
683 pci_iounmap(pdev, conf->map); in altera_cvp_remove()
717 MODULE_DESCRIPTION("Module to load Altera FPGA over CvP");