/* * The JTAG ID's of the supported FPGA's. The ID is 32bit wide * reversed as noted in the manual.
*/ #define ID_ECP3_17 0xc2088080 #define ID_ECP3_35 0xc2048080
/* FPGA commands */ #define FPGA_CMD_READ_ID 0x07 /* plus 24 bits */ #define FPGA_CMD_READ_STATUS 0x09 /* plus 24 bits */ #define FPGA_CMD_CLEAR 0x70 #define FPGA_CMD_REFRESH 0x71 #define FPGA_CMD_WRITE_EN 0x4a /* plus 2 bits */ #define FPGA_CMD_WRITE_DIS 0x4f /* plus 8 bits */ #define FPGA_CMD_WRITE_INC 0x41 /* plus 0 bits */
/* * The status register is 32bit revered, DONE is bit 17 from the TN1222.pdf * (LatticeECP3 Slave SPI Port User's Guide)
*/ #define FPGA_STATUS_DONE 0x00004000 #define FPGA_STATUS_CLEARED 0x00010000
if (fw->size == 0) {
dev_err(&spi->dev, "Error: Firmware size is 0!\n"); goto out;
}
/* Fill dummy data (24 stuffing bits for commands) */
txbuf[1] = 0x00;
txbuf[2] = 0x00;
txbuf[3] = 0x00;
/* Trying to speak with the FPGA via SPI... */
txbuf[0] = FPGA_CMD_READ_ID;
spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
jedec_id = get_unaligned_be32(&rxbuf[4]);
dev_dbg(&spi->dev, "FPGA JTAG ID=%08x\n", jedec_id);
for (i = 0; i < ARRAY_SIZE(ecp3_dev); i++) { if (jedec_id == ecp3_dev[i].jedec_id) break;
} if (i == ARRAY_SIZE(ecp3_dev)) {
dev_err(&spi->dev, "Error: No supported FPGA detected (JEDEC_ID=%08x)!\n",
jedec_id); goto out;
}
/* * Wait for FPGA memory to become cleared
*/ for (i = 0; i < FPGA_CLEAR_LOOP_COUNT; i++) {
txbuf[0] = FPGA_CMD_READ_STATUS;
spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
status = get_unaligned_be32(&rxbuf[4]); if (status == FPGA_STATUS_CLEARED) break;
msleep(FPGA_CLEAR_MSLEEP);
}
if (i == FPGA_CLEAR_LOOP_COUNT) {
dev_err(&spi->dev, "Error: Timeout waiting for FPGA to clear (status=%08x)!\n",
status);
kfree(buffer); goto out;
}
dev_info(&spi->dev, "Configuring the FPGA...\n");
spi_write(spi, buffer, fw->size + 8);
/* Check result */ if (status & FPGA_STATUS_DONE)
dev_info(&spi->dev, "FPGA successfully configured!\n"); else
dev_info(&spi->dev, "FPGA not configured (DONE not set)\n");
/* * Don't forget to release the firmware again
*/
release_firmware(fw);
kfree(buffer);
out:
complete(&data->fw_loaded);
}
staticint lattice_ecp3_probe(struct spi_device *spi)
{ struct fpga_data *data; int err;
data = devm_kzalloc(&spi->dev, sizeof(*data), GFP_KERNEL); if (!data) {
dev_err(&spi->dev, "Memory allocation for fpga_data failed\n"); return -ENOMEM;
}
spi_set_drvdata(spi, data);
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.