xref: /linux/drivers/fpga/efinix-spi.c (revision d4d5ad6c6039a4921bd9f708bd0539258d60e55e)
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