1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * FPGA Manager Driver for Efinix 4 * 5 * Copyright (C) 2025 iris-GmbH infrared & intelligent sensors 6 * 7 * Ian Dannapel <iansdannapel@gmail.com> 8 * 9 * Load Efinix FPGA firmware over SPI using the serial configuration interface. 10 * 11 * Note: Only passive mode (host initiates transfer) is currently supported. 12 */ 13 14 #include <linux/delay.h> 15 #include <linux/fpga/fpga-mgr.h> 16 #include <linux/gpio/consumer.h> 17 #include <linux/module.h> 18 #include <linux/of.h> 19 #include <linux/spi/spi.h> 20 21 /* 22 * 13 dummy bytes generate 104 SPI clock cycles (8 bits each). 23 * Used to meet the requirement for >100 clock cycles idle sequence. 24 */ 25 #define EFINIX_SPI_IDLE_CYCLES_BYTES 13 26 27 /* 28 * tDMIN: Minimum time between deassertion of CRESET_N to first 29 * valid configuration data. (32 µs) 30 */ 31 #define EFINIX_TDMIN_US_MIN 35 32 #define EFINIX_TDMIN_US_MAX 40 33 34 /* 35 * tCRESET_N: Minimum CRESET_N low pulse width required to 36 * trigger re-configuration. (320 ns) 37 */ 38 #define EFINIX_TCRESETN_DELAY_MIN_US 1 39 #define EFINIX_TCRESETN_DELAY_MAX_US 2 40 41 /* 42 * tUSER: Minimum configuration duration after CDONE goes high 43 * before entering user mode. (25 µs) 44 */ 45 #define EFINIX_TUSER_US_MIN 30 46 #define EFINIX_TUSER_US_MAX 35 47 48 struct efinix_spi_conf { 49 struct spi_device *spi; 50 struct gpio_desc *cdone; 51 struct gpio_desc *reset; 52 }; 53 54 static void efinix_spi_reset(struct efinix_spi_conf *conf) 55 { 56 gpiod_set_value(conf->reset, 1); 57 usleep_range(EFINIX_TCRESETN_DELAY_MIN_US, EFINIX_TCRESETN_DELAY_MAX_US); 58 gpiod_set_value(conf->reset, 0); 59 usleep_range(EFINIX_TDMIN_US_MIN, EFINIX_TDMIN_US_MAX); 60 } 61 62 static enum fpga_mgr_states efinix_spi_state(struct fpga_manager *mgr) 63 { 64 struct efinix_spi_conf *conf = mgr->priv; 65 66 if (conf->cdone && gpiod_get_value(conf->cdone) == 1) 67 return FPGA_MGR_STATE_OPERATING; 68 69 return FPGA_MGR_STATE_UNKNOWN; 70 } 71 72 static int efinix_spi_write_init(struct fpga_manager *mgr, 73 struct fpga_image_info *info, 74 const char *buf, size_t count) 75 { 76 struct efinix_spi_conf *conf = mgr->priv; 77 struct spi_transfer assert_cs = { 78 /* Keep CS asserted across configuration. */ 79 .cs_change = 1, 80 }; 81 struct spi_message message; 82 int ret; 83 84 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { 85 dev_err(&mgr->dev, "Partial reconfiguration not supported\n"); 86 return -EOPNOTSUPP; 87 } 88 89 /* 90 * Efinix passive SPI configuration requires chip select to stay 91 * asserted from reset until the bitstream is fully clocked in. 92 * Lock the SPI bus so no other device can toggle CS between the 93 * reset pulse and the write/complete transfers. 94 */ 95 spi_bus_lock(conf->spi->controller); 96 spi_message_init_with_transfers(&message, &assert_cs, 1); 97 ret = spi_sync_locked(conf->spi, &message); 98 if (ret) { 99 spi_bus_unlock(conf->spi->controller); 100 return ret; 101 } 102 103 /* Reset with CS asserted */ 104 efinix_spi_reset(conf); 105 106 return 0; 107 } 108 109 static int efinix_spi_write(struct fpga_manager *mgr, const char *buf, 110 size_t count) 111 { 112 struct spi_transfer write_xfer = { 113 .tx_buf = buf, 114 .len = count, 115 .cs_change = 1, 116 }; 117 struct efinix_spi_conf *conf = mgr->priv; 118 struct spi_message message; 119 int ret; 120 121 spi_message_init_with_transfers(&message, &write_xfer, 1); 122 ret = spi_sync_locked(conf->spi, &message); 123 if (ret) { 124 dev_err(&mgr->dev, "SPI error in firmware write: %d\n", ret); 125 spi_bus_unlock(conf->spi->controller); 126 } 127 128 return ret; 129 } 130 131 static int efinix_spi_write_complete(struct fpga_manager *mgr, 132 struct fpga_image_info *info) 133 { 134 unsigned long timeout = 135 jiffies + usecs_to_jiffies(info->config_complete_timeout_us); 136 struct spi_transfer clk_cycles = { 137 .len = EFINIX_SPI_IDLE_CYCLES_BYTES, 138 /* Release CS after the trailing idle clocks are sent. */ 139 .cs_change = 0, 140 }; 141 struct efinix_spi_conf *conf = mgr->priv; 142 struct spi_message message; 143 int done, ret; 144 bool expired = false; 145 u8 *dummy_buf; 146 147 dummy_buf = kzalloc(EFINIX_SPI_IDLE_CYCLES_BYTES, GFP_KERNEL); 148 if (!dummy_buf) { 149 ret = -ENOMEM; 150 goto unlock_spi; 151 } 152 153 /* 154 * Keep the bus locked while sending the trailing idle clocks, then 155 * let this final transfer deassert CS to terminate configuration. 156 */ 157 clk_cycles.tx_buf = dummy_buf; 158 spi_message_init_with_transfers(&message, &clk_cycles, 1); 159 ret = spi_sync_locked(conf->spi, &message); 160 if (ret) { 161 dev_err(&mgr->dev, "SPI error in write complete: %d\n", ret); 162 goto free_buf; 163 } 164 165 if (conf->cdone) { 166 while (!expired) { 167 done = gpiod_get_value(conf->cdone); 168 if (done < 0) { 169 ret = done; 170 goto free_buf; 171 } 172 if (done) 173 break; 174 175 usleep_range(10, 20); 176 expired = time_after(jiffies, timeout); 177 } 178 179 if (expired) { 180 dev_err(&mgr->dev, "Timeout waiting for CDONE\n"); 181 ret = -ETIMEDOUT; 182 goto free_buf; 183 } 184 } 185 186 usleep_range(EFINIX_TUSER_US_MIN, EFINIX_TUSER_US_MAX); 187 188 free_buf: 189 kfree(dummy_buf); 190 unlock_spi: 191 spi_bus_unlock(conf->spi->controller); 192 193 return ret; 194 } 195 196 static const struct fpga_manager_ops efinix_spi_ops = { 197 .state = efinix_spi_state, 198 .write_init = efinix_spi_write_init, 199 .write = efinix_spi_write, 200 .write_complete = efinix_spi_write_complete, 201 }; 202 203 static int efinix_spi_probe(struct spi_device *spi) 204 { 205 struct efinix_spi_conf *conf; 206 struct fpga_manager *mgr; 207 208 if (!(spi->mode & SPI_CPHA) || !(spi->mode & SPI_CPOL)) 209 return dev_err_probe(&spi->dev, -EINVAL, 210 "Unsupported SPI mode, set CPHA and CPOL\n"); 211 212 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); 213 if (!conf) 214 return -ENOMEM; 215 216 conf->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH); 217 if (IS_ERR(conf->reset)) 218 return dev_err_probe(&spi->dev, PTR_ERR(conf->reset), 219 "Failed to get RESET gpio\n"); 220 221 conf->cdone = devm_gpiod_get_optional(&spi->dev, "cdone", GPIOD_IN); 222 if (IS_ERR(conf->cdone)) 223 return dev_err_probe(&spi->dev, PTR_ERR(conf->cdone), 224 "Failed to get CDONE gpio\n"); 225 226 conf->spi = spi; 227 228 mgr = devm_fpga_mgr_register(&spi->dev, 229 "Efinix FPGA Manager", 230 &efinix_spi_ops, conf); 231 232 return PTR_ERR_OR_ZERO(mgr); 233 } 234 235 static const struct of_device_id efinix_spi_of_match[] = { 236 { .compatible = "efinix,trion-config", }, 237 {} 238 }; 239 MODULE_DEVICE_TABLE(of, efinix_spi_of_match); 240 241 static const struct spi_device_id efinix_ids[] = { 242 { "trion-config", 0 }, 243 {}, 244 }; 245 MODULE_DEVICE_TABLE(spi, efinix_ids); 246 247 static struct spi_driver efinix_spi_driver = { 248 .driver = { 249 .name = "efinix-spi", 250 .of_match_table = efinix_spi_of_match, 251 }, 252 .probe = efinix_spi_probe, 253 .id_table = efinix_ids, 254 }; 255 256 module_spi_driver(efinix_spi_driver); 257 258 MODULE_LICENSE("GPL"); 259 MODULE_AUTHOR("Ian Dannapel <iansdannapel@gmail.com>"); 260 MODULE_DESCRIPTION("Efinix FPGA SPI Programming Driver"); 261