// SPDX-License-Identifier: GPL-2.0-only /* * FPGA Manager Driver for Lattice iCE40. * * Copyright (c) 2016 Joel Holdsworth * * This driver adds support to the FPGA manager for configuring the SRAM of * Lattice iCE40 FPGAs through slave SPI.
*/
if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
dev_err(&dev->dev, "Partial reconfiguration is not supported\n"); return -ENOTSUPP;
}
/* Lock the bus, assert CRESET_B and SS_B and delay >200ns */
spi_bus_lock(dev->controller);
gpiod_set_value(priv->reset, 1);
spi_message_init(&message);
spi_message_add_tail(&assert_cs_then_reset_delay, &message);
ret = spi_sync_locked(dev, &message);
/* Come out of reset */
gpiod_set_value(priv->reset, 0);
/* Abort if the chip-select failed */ if (ret) goto fail;
/* Check CDONE is de-asserted i.e. the FPGA is reset */ if (gpiod_get_value(priv->cdone)) {
dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
ret = -EIO; goto fail;
}
/* Wait for the housekeeping to complete, and release SS_B */
spi_message_init(&message);
spi_message_add_tail(&housekeeping_delay_then_release_cs, &message);
ret = spi_sync_locked(dev, &message);
/* Check CDONE is asserted */ if (!gpiod_get_value(priv->cdone)) {
dev_err(&dev->dev, "CDONE was not asserted after firmware transfer\n"); return -EIO;
}
/* Send of zero-padding to activate the firmware */ return spi_write(dev, padding, sizeof(padding));
}
priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->dev = spi;
/* Check board setup data. */ if (spi->max_speed_hz > ICE40_SPI_MAX_SPEED) {
dev_err(dev, "SPI speed is too high, maximum speed is "
__stringify(ICE40_SPI_MAX_SPEED) "\n"); return -EINVAL;
}
if (spi->max_speed_hz < ICE40_SPI_MIN_SPEED) {
dev_err(dev, "SPI speed is too low, minimum speed is "
__stringify(ICE40_SPI_MIN_SPEED) "\n"); return -EINVAL;
}
if (spi->mode & SPI_CPHA) {
dev_err(dev, "Bad SPI mode, CPHA not supported\n"); return -EINVAL;
}
/* Set up the GPIOs */
priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN); if (IS_ERR(priv->cdone)) {
ret = PTR_ERR(priv->cdone);
dev_err(dev, "Failed to get CDONE GPIO: %d\n", ret); return ret;
}
priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(priv->reset)) {
ret = PTR_ERR(priv->reset);
dev_err(dev, "Failed to get CRESET_B GPIO: %d\n", ret); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.