1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3  * Copyright © 2023 Calian Ltd.  All rights reserved.
4  *
5  * Driver for the Xilinx AXI IIC Bus Interface.
6  * This is an FPGA logic core as described by Xilinx document PG090.
7  */
8 
9 #include <errno.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/irq.h>
14 
15 LOG_MODULE_REGISTER(i2c_xilinx_axi, CONFIG_I2C_LOG_LEVEL);
16 
17 #include "i2c-priv.h"
18 #include "i2c_xilinx_axi.h"
19 
20 struct i2c_xilinx_axi_config {
21 	mem_addr_t base;
22 	void (*irq_config_func)(const struct device *dev);
23 	/* Whether device has working dynamic read (broken prior to core rev. 2.1) */
24 	bool dyn_read_working;
25 };
26 
27 struct i2c_xilinx_axi_data {
28 	struct k_event irq_event;
29 	/* Serializes between ISR and other calls */
30 	struct k_spinlock lock;
31 	/* Provides exclusion against multiple concurrent requests */
32 	struct k_mutex mutex;
33 
34 #if defined(CONFIG_I2C_TARGET)
35 	struct i2c_target_config *target_cfg;
36 	bool target_reading;
37 	bool target_read_aborted;
38 	bool target_writing;
39 #endif
40 };
41 
i2c_xilinx_axi_reinit(const struct i2c_xilinx_axi_config * config)42 static void i2c_xilinx_axi_reinit(const struct i2c_xilinx_axi_config *config)
43 {
44 	LOG_DBG("Controller reinit");
45 	sys_write32(SOFTR_KEY, config->base + REG_SOFTR);
46 	sys_write32(CR_TX_FIFO_RST, config->base + REG_CR);
47 	sys_write32(CR_EN, config->base + REG_CR);
48 	sys_write32(GIE_ENABLE, config->base + REG_GIE);
49 }
50 
51 #if defined(CONFIG_I2C_TARGET)
52 
53 #define I2C_XILINX_AXI_TARGET_INTERRUPTS                                                           \
54 	(ISR_ADDR_TARGET | ISR_NOT_ADDR_TARGET | ISR_RX_FIFO_FULL | ISR_TX_FIFO_EMPTY |            \
55 	 ISR_TX_ERR_TARGET_COMP)
56 
i2c_xilinx_axi_target_setup(const struct i2c_xilinx_axi_config * config,struct i2c_target_config * cfg)57 static void i2c_xilinx_axi_target_setup(const struct i2c_xilinx_axi_config *config,
58 					struct i2c_target_config *cfg)
59 {
60 	i2c_xilinx_axi_reinit(config);
61 
62 	sys_write32(ISR_ADDR_TARGET, config->base + REG_IER);
63 	sys_write32(cfg->address << 1, config->base + REG_ADR);
64 	sys_write32(0, config->base + REG_RX_FIFO_PIRQ);
65 }
66 
i2c_xilinx_axi_target_register(const struct device * dev,struct i2c_target_config * cfg)67 static int i2c_xilinx_axi_target_register(const struct device *dev, struct i2c_target_config *cfg)
68 {
69 	const struct i2c_xilinx_axi_config *config = dev->config;
70 	struct i2c_xilinx_axi_data *data = dev->data;
71 	k_spinlock_key_t key;
72 	int ret;
73 
74 	if (cfg->flags & I2C_TARGET_FLAGS_ADDR_10_BITS) {
75 		/* Optionally supported in core, but not implemented in driver yet */
76 		return -EOPNOTSUPP;
77 	}
78 
79 	k_mutex_lock(&data->mutex, K_FOREVER);
80 	key = k_spin_lock(&data->lock);
81 
82 	if (data->target_cfg) {
83 		ret = -EBUSY;
84 		goto out_unlock;
85 	}
86 
87 	data->target_cfg = cfg;
88 	i2c_xilinx_axi_target_setup(config, cfg);
89 	ret = 0;
90 
91 out_unlock:
92 	k_spin_unlock(&data->lock, key);
93 	LOG_DBG("Target register ret=%d", ret);
94 	k_mutex_unlock(&data->mutex);
95 	return ret;
96 }
97 
i2c_xilinx_axi_target_unregister(const struct device * dev,struct i2c_target_config * cfg)98 static int i2c_xilinx_axi_target_unregister(const struct device *dev, struct i2c_target_config *cfg)
99 {
100 	const struct i2c_xilinx_axi_config *config = dev->config;
101 	struct i2c_xilinx_axi_data *data = dev->data;
102 	k_spinlock_key_t key;
103 	uint32_t int_enable;
104 	int ret;
105 
106 	k_mutex_lock(&data->mutex, K_FOREVER);
107 	key = k_spin_lock(&data->lock);
108 
109 	if (!data->target_cfg) {
110 		ret = -EINVAL;
111 		goto out_unlock;
112 	}
113 
114 	if (data->target_reading || data->target_writing) {
115 		ret = -EBUSY;
116 		goto out_unlock;
117 	}
118 
119 	data->target_cfg = NULL;
120 	sys_write32(0, config->base + REG_ADR);
121 
122 	sys_write32(CR_EN, config->base + REG_CR);
123 	int_enable = sys_read32(config->base + REG_IER);
124 	int_enable &= ~I2C_XILINX_AXI_TARGET_INTERRUPTS;
125 	sys_write32(int_enable, config->base + REG_IER);
126 	ret = 0;
127 
128 out_unlock:
129 	k_spin_unlock(&data->lock, key);
130 	LOG_DBG("Target unregister ret=%d", ret);
131 	k_mutex_unlock(&data->mutex);
132 	return ret;
133 }
134 
i2c_xilinx_axi_target_isr(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,uint32_t * int_status,uint32_t * ints_to_clear,uint32_t * int_enable)135 static void i2c_xilinx_axi_target_isr(const struct i2c_xilinx_axi_config *config,
136 				      struct i2c_xilinx_axi_data *data, uint32_t *int_status,
137 				      uint32_t *ints_to_clear, uint32_t *int_enable)
138 {
139 	if (*int_status & ISR_ADDR_TARGET) {
140 		LOG_DBG("Addressed as target");
141 		*int_status &= ~ISR_ADDR_TARGET;
142 		*int_enable &= ~ISR_ADDR_TARGET;
143 		*int_enable |= ISR_NOT_ADDR_TARGET;
144 		*ints_to_clear |= ISR_NOT_ADDR_TARGET;
145 
146 		if (sys_read32(config->base + REG_SR) & SR_SRW) {
147 			uint8_t read_byte;
148 
149 			data->target_reading = true;
150 			*ints_to_clear |= ISR_TX_FIFO_EMPTY | ISR_TX_ERR_TARGET_COMP;
151 			*int_enable |= ISR_TX_FIFO_EMPTY | ISR_TX_ERR_TARGET_COMP;
152 			if ((*data->target_cfg->callbacks->read_requested)(data->target_cfg,
153 									   &read_byte)) {
154 				LOG_DBG("target read_requested rejected");
155 				data->target_read_aborted = true;
156 				read_byte = 0xFF;
157 			}
158 			sys_write32(read_byte, config->base + REG_TX_FIFO);
159 		} else {
160 			data->target_writing = true;
161 			*int_enable |= ISR_RX_FIFO_FULL;
162 			if ((*data->target_cfg->callbacks->write_requested)(data->target_cfg)) {
163 				uint32_t cr = sys_read32(config->base + REG_CR);
164 
165 				LOG_DBG("target write_requested rejected");
166 				cr |= CR_TXAK;
167 				sys_write32(cr, config->base + REG_CR);
168 			}
169 		}
170 	} else if (*int_status & ISR_NOT_ADDR_TARGET) {
171 		LOG_DBG("Not addressed as target");
172 		(*data->target_cfg->callbacks->stop)(data->target_cfg);
173 		data->target_reading = false;
174 		data->target_read_aborted = false;
175 		data->target_writing = false;
176 
177 		sys_write32(CR_EN, config->base + REG_CR);
178 		*int_status &= ~ISR_NOT_ADDR_TARGET;
179 		*int_enable &= ~I2C_XILINX_AXI_TARGET_INTERRUPTS;
180 		*int_enable |= ISR_ADDR_TARGET;
181 		*ints_to_clear |= ISR_ADDR_TARGET;
182 	} else if (data->target_writing && (*int_status & ISR_RX_FIFO_FULL)) {
183 		*int_status &= ~ISR_RX_FIFO_FULL;
184 		const uint8_t written_byte =
185 			sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;
186 
187 		if ((*data->target_cfg->callbacks->write_received)(data->target_cfg,
188 								   written_byte)) {
189 			uint32_t cr = sys_read32(config->base + REG_CR);
190 
191 			LOG_DBG("target write_received rejected");
192 			cr |= CR_TXAK;
193 			sys_write32(cr, config->base + REG_CR);
194 		}
195 	} else if (data->target_reading && (*int_status & ISR_TX_ERR_TARGET_COMP)) {
196 		/* Controller has NAKed the last byte read, so no more to send.
197 		 * Ignore TX FIFO empty so we don't write an extra byte.
198 		 */
199 		LOG_DBG("target read completed");
200 		*int_status &= ~ISR_TX_ERR_TARGET_COMP;
201 		*int_enable &= ~ISR_TX_FIFO_EMPTY;
202 		*ints_to_clear |= ISR_TX_FIFO_EMPTY;
203 	} else if (data->target_reading && (*int_status & ISR_TX_FIFO_EMPTY)) {
204 		*int_status &= ~ISR_TX_FIFO_EMPTY;
205 		uint8_t read_byte = 0xFF;
206 
207 		if (!data->target_read_aborted &&
208 		   (*data->target_cfg->callbacks->read_processed)(data->target_cfg,
209 								  &read_byte)) {
210 			LOG_DBG("target read_processed rejected");
211 			data->target_read_aborted = true;
212 		}
213 		sys_write32(read_byte, config->base + REG_TX_FIFO);
214 	}
215 }
216 #endif
217 
i2c_xilinx_axi_isr(const struct device * dev)218 static void i2c_xilinx_axi_isr(const struct device *dev)
219 {
220 	const struct i2c_xilinx_axi_config *config = dev->config;
221 	struct i2c_xilinx_axi_data *data = dev->data;
222 	const k_spinlock_key_t key = k_spin_lock(&data->lock);
223 	uint32_t int_enable = sys_read32(config->base + REG_IER);
224 	uint32_t int_status = sys_read32(config->base + REG_ISR) & int_enable;
225 	uint32_t ints_to_clear = int_status;
226 
227 	LOG_DBG("ISR called for 0x%08" PRIxPTR ", status 0x%02x", config->base, int_status);
228 
229 	if (int_status & ISR_ARB_LOST) {
230 		/* Must clear MSMS before clearing interrupt */
231 		uint32_t cr = sys_read32(config->base + REG_CR);
232 
233 		cr &= ~CR_MSMS;
234 		sys_write32(cr, config->base + REG_CR);
235 	}
236 
237 #if defined(CONFIG_I2C_TARGET)
238 	if (data->target_cfg && (int_status & I2C_XILINX_AXI_TARGET_INTERRUPTS)) {
239 		/* This clears events from int_status which are already handled */
240 		i2c_xilinx_axi_target_isr(config, data, &int_status, &ints_to_clear, &int_enable);
241 	}
242 #endif
243 
244 	/* Mask any interrupts which have not already been handled separately */
245 	sys_write32(int_enable & ~int_status, config->base + REG_IER);
246 	/* Be careful, writing 1 to a bit that is not currently set in ISR will SET it! */
247 	sys_write32(ints_to_clear & sys_read32(config->base + REG_ISR), config->base + REG_ISR);
248 
249 	k_spin_unlock(&data->lock, key);
250 	if (int_status) {
251 		k_event_post(&data->irq_event, int_status);
252 	}
253 }
254 
i2c_xilinx_axi_configure(const struct device * dev,uint32_t dev_config)255 static int i2c_xilinx_axi_configure(const struct device *dev, uint32_t dev_config)
256 {
257 	const struct i2c_xilinx_axi_config *config = dev->config;
258 
259 	LOG_INF("Configuring %s at 0x%08" PRIxPTR, dev->name, config->base);
260 	i2c_xilinx_axi_reinit(config);
261 	return 0;
262 }
263 
i2c_xilinx_axi_wait_interrupt(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,uint32_t int_mask)264 static uint32_t i2c_xilinx_axi_wait_interrupt(const struct i2c_xilinx_axi_config *config,
265 					      struct i2c_xilinx_axi_data *data, uint32_t int_mask)
266 {
267 	const k_spinlock_key_t key = k_spin_lock(&data->lock);
268 	const uint32_t int_enable = sys_read32(config->base + REG_IER) | int_mask;
269 	uint32_t events;
270 
271 	LOG_DBG("Set IER to 0x%02x", int_enable);
272 	sys_write32(int_enable, config->base + REG_IER);
273 	k_event_clear(&data->irq_event, int_mask);
274 	k_spin_unlock(&data->lock, key);
275 
276 	events = k_event_wait(&data->irq_event, int_mask, false, K_MSEC(100));
277 
278 	LOG_DBG("Got ISR events 0x%02x", events);
279 	if (!events) {
280 		LOG_ERR("Timeout waiting for ISR events 0x%02x, SR 0x%02x, ISR 0x%02x", int_mask,
281 			sys_read32(config->base + REG_SR), sys_read32(config->base + REG_ISR));
282 	}
283 	return events;
284 }
285 
i2c_xilinx_axi_clear_interrupt_no_lock(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,uint32_t int_mask)286 static void i2c_xilinx_axi_clear_interrupt_no_lock(const struct i2c_xilinx_axi_config *config,
287 						   struct i2c_xilinx_axi_data *data,
288 						   uint32_t int_mask)
289 {
290 	const uint32_t int_status = sys_read32(config->base + REG_ISR);
291 
292 	if (int_status & int_mask) {
293 		sys_write32(int_status & int_mask, config->base + REG_ISR);
294 	}
295 }
296 
i2c_xilinx_axi_clear_interrupt(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,uint32_t int_mask)297 static void i2c_xilinx_axi_clear_interrupt(const struct i2c_xilinx_axi_config *config,
298 					   struct i2c_xilinx_axi_data *data, uint32_t int_mask)
299 {
300 	const k_spinlock_key_t key = k_spin_lock(&data->lock);
301 
302 	i2c_xilinx_axi_clear_interrupt_no_lock(config, data, int_mask);
303 
304 	k_spin_unlock(&data->lock, key);
305 }
306 
i2c_xilinx_axi_wait_rx_full(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,uint32_t read_bytes)307 static int i2c_xilinx_axi_wait_rx_full(const struct i2c_xilinx_axi_config *config,
308 				       struct i2c_xilinx_axi_data *data, uint32_t read_bytes)
309 {
310 	uint32_t events;
311 
312 	i2c_xilinx_axi_clear_interrupt(config, data, ISR_RX_FIFO_FULL);
313 	if (!(sys_read32(config->base + REG_SR) & SR_RX_FIFO_EMPTY) &&
314 	    (sys_read32(config->base + REG_RX_FIFO_OCY) & RX_FIFO_OCY_MASK) + 1 >= read_bytes) {
315 		LOG_DBG("RX already full on checking, SR 0x%02x RXOCY 0x%02x",
316 			sys_read32(config->base + REG_SR),
317 			sys_read32(config->base + REG_RX_FIFO_OCY));
318 		return 0;
319 	}
320 	events = i2c_xilinx_axi_wait_interrupt(config, data, ISR_RX_FIFO_FULL | ISR_ARB_LOST);
321 	if (!events) {
322 		return -ETIMEDOUT;
323 	}
324 	if (events & ISR_ARB_LOST) {
325 		LOG_ERR("Arbitration lost on RX");
326 		return -ENXIO;
327 	}
328 	return 0;
329 }
330 
i2c_xilinx_axi_read_nondyn(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,struct i2c_msg * msg,uint16_t addr)331 static int i2c_xilinx_axi_read_nondyn(const struct i2c_xilinx_axi_config *config,
332 				      struct i2c_xilinx_axi_data *data, struct i2c_msg *msg,
333 				      uint16_t addr)
334 {
335 	uint8_t *read_ptr = msg->buf;
336 	uint32_t bytes_left = msg->len;
337 	uint32_t cr = CR_EN | CR_MSMS;
338 
339 	if (!bytes_left) {
340 		return -EINVAL;
341 	}
342 	if (bytes_left == 1) {
343 		/* Set TXAK bit now, to NAK after the first byte is received */
344 		cr |= CR_TXAK;
345 	}
346 
347 	/**
348 	 * The Xilinx core's RX FIFO full logic seems rather broken in that the interrupt
349 	 * is triggered, and the I2C receive is throttled, only when the FIFO occupancy
350 	 * equals the PIRQ threshold, not when greater or equal. In the non-dynamic mode
351 	 * of operation, we need to stop the read prior to the last bytes being received
352 	 * from the target in order to set the TXAK bit and clear MSMS to terminate the
353 	 * receive properly.
354 	 * However, if we previously allowed multiple bytes into the RX FIFO, this requires
355 	 * reducing the PIRQ threshold to 0 (single byte) during the receive operation. This
356 	 * can cause the receive to unthrottle (since FIFO occupancy now exceeds PIRQ
357 	 * threshold) and depending on timing between the driver code and the core,
358 	 * this can cause the core to try to receive more data into the FIFO than desired
359 	 * and cause various unexpected results.
360 	 *
361 	 * To avoid this, we only receive one byte at a time in the non-dynamic mode.
362 	 * Dynamic mode doesn't have this issue as it provides the RX byte count to the
363 	 * controller specifically and the TXAK and MSMS bits are handled automatically.
364 	 */
365 	sys_write32(0, config->base + REG_RX_FIFO_PIRQ);
366 
367 	if (msg->flags & I2C_MSG_RESTART) {
368 		cr |= CR_RSTA;
369 
370 		sys_write32(cr, config->base + REG_CR);
371 		sys_write32((addr << 1) | I2C_MSG_READ, config->base + REG_TX_FIFO);
372 	} else {
373 		sys_write32((addr << 1) | I2C_MSG_READ, config->base + REG_TX_FIFO);
374 		sys_write32(cr, config->base + REG_CR);
375 	}
376 
377 	while (bytes_left) {
378 		int ret = i2c_xilinx_axi_wait_rx_full(config, data, 1);
379 
380 		if (ret) {
381 			return ret;
382 		}
383 
384 		if (bytes_left == 2) {
385 			/* Set TXAK so the last byte is NAKed */
386 			cr |= CR_TXAK;
387 		} else if (bytes_left == 1 && (msg->flags & I2C_MSG_STOP)) {
388 			/* Before reading the last byte, clear MSMS to issue a stop if required */
389 			cr &= ~CR_MSMS;
390 		}
391 		cr &= ~CR_RSTA;
392 		sys_write32(cr, config->base + REG_CR);
393 
394 		*read_ptr++ = sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;
395 		bytes_left--;
396 	}
397 	return 0;
398 }
399 
i2c_xilinx_axi_read_dyn(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,struct i2c_msg * msg,uint16_t addr)400 static int i2c_xilinx_axi_read_dyn(const struct i2c_xilinx_axi_config *config,
401 				   struct i2c_xilinx_axi_data *data, struct i2c_msg *msg,
402 				   uint16_t addr)
403 {
404 	uint8_t *read_ptr = msg->buf;
405 	uint32_t bytes_left = msg->len;
406 	uint32_t bytes_to_read = bytes_left;
407 	uint32_t cr = CR_EN;
408 	uint32_t len_word = bytes_left;
409 
410 	if (!bytes_left || bytes_left > MAX_DYNAMIC_READ_LEN) {
411 		return -EINVAL;
412 	}
413 	if (msg->flags & I2C_MSG_RESTART) {
414 		cr |= CR_MSMS | CR_RSTA;
415 	}
416 	sys_write32(cr, config->base + REG_CR);
417 
418 	if (bytes_to_read > FIFO_SIZE) {
419 		bytes_to_read = FIFO_SIZE;
420 	}
421 	sys_write32(bytes_to_read - 1, config->base + REG_RX_FIFO_PIRQ);
422 	sys_write32((addr << 1) | I2C_MSG_READ | TX_FIFO_START, config->base + REG_TX_FIFO);
423 
424 	if (msg->flags & I2C_MSG_STOP) {
425 		len_word |= TX_FIFO_STOP;
426 	}
427 	sys_write32(len_word, config->base + REG_TX_FIFO);
428 
429 	while (bytes_left) {
430 		int ret;
431 
432 		bytes_to_read = bytes_left;
433 		if (bytes_to_read > FIFO_SIZE) {
434 			bytes_to_read = FIFO_SIZE;
435 		}
436 
437 		sys_write32(bytes_to_read - 1, config->base + REG_RX_FIFO_PIRQ);
438 		ret = i2c_xilinx_axi_wait_rx_full(config, data, bytes_to_read);
439 		if (ret) {
440 			return ret;
441 		}
442 
443 		while (bytes_to_read) {
444 			*read_ptr++ = sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;
445 			bytes_to_read--;
446 			bytes_left--;
447 		}
448 	}
449 	return 0;
450 }
451 
i2c_xilinx_axi_wait_tx_done(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data)452 static int i2c_xilinx_axi_wait_tx_done(const struct i2c_xilinx_axi_config *config,
453 				       struct i2c_xilinx_axi_data *data)
454 {
455 	const uint32_t finish_bits = ISR_BUS_NOT_BUSY | ISR_TX_FIFO_EMPTY;
456 
457 	uint32_t events = i2c_xilinx_axi_wait_interrupt(
458 		config, data, finish_bits | ISR_TX_ERR_TARGET_COMP | ISR_ARB_LOST);
459 	if (!(events & finish_bits) || (events & ~finish_bits)) {
460 		if (!events) {
461 			return -ETIMEDOUT;
462 		}
463 		if (events & ISR_ARB_LOST) {
464 			LOG_ERR("Arbitration lost on TX");
465 			return -EAGAIN;
466 		}
467 		LOG_ERR("TX received NAK");
468 		return -ENXIO;
469 	}
470 	return 0;
471 }
472 
i2c_xilinx_axi_wait_not_busy(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data)473 static int i2c_xilinx_axi_wait_not_busy(const struct i2c_xilinx_axi_config *config,
474 					struct i2c_xilinx_axi_data *data)
475 {
476 	if (sys_read32(config->base + REG_SR) & SR_BB) {
477 		uint32_t events = i2c_xilinx_axi_wait_interrupt(config, data, ISR_BUS_NOT_BUSY);
478 
479 		if (events != ISR_BUS_NOT_BUSY) {
480 			LOG_ERR("Bus stuck busy");
481 			i2c_xilinx_axi_reinit(config);
482 			return -EBUSY;
483 		}
484 	}
485 	return 0;
486 }
487 
i2c_xilinx_axi_write(const struct i2c_xilinx_axi_config * config,struct i2c_xilinx_axi_data * data,const struct i2c_msg * msg,uint16_t addr)488 static int i2c_xilinx_axi_write(const struct i2c_xilinx_axi_config *config,
489 				struct i2c_xilinx_axi_data *data, const struct i2c_msg *msg,
490 				uint16_t addr)
491 {
492 	const uint8_t *write_ptr = msg->buf;
493 	uint32_t bytes_left = msg->len;
494 	uint32_t cr = CR_EN | CR_TX;
495 	uint32_t fifo_space = FIFO_SIZE - 1; /* account for address being written */
496 
497 	if (msg->flags & I2C_MSG_RESTART) {
498 		cr |= CR_MSMS | CR_RSTA;
499 	}
500 
501 	i2c_xilinx_axi_clear_interrupt(config, data, ISR_TX_ERR_TARGET_COMP | ISR_ARB_LOST);
502 
503 	sys_write32(cr, config->base + REG_CR);
504 	sys_write32((addr << 1) | TX_FIFO_START, config->base + REG_TX_FIFO);
505 
506 	/* TX FIFO empty detection is somewhat fragile because the status register
507 	 * TX_FIFO_EMPTY bit can be set prior to the transaction actually being
508 	 * complete, so we have to rely on the TX empty interrupt.
509 	 * However, delays in writing data to the TX FIFO could cause it
510 	 * to run empty in the middle of the process, causing us to get a spurious
511 	 * completion detection from the interrupt. Therefore we disable interrupts
512 	 * while the TX FIFO is being filled up to try to avoid this.
513 	 */
514 
515 	while (bytes_left) {
516 		uint32_t bytes_to_send = bytes_left;
517 		const k_spinlock_key_t key = k_spin_lock(&data->lock);
518 		int ret;
519 
520 		if (bytes_to_send > fifo_space) {
521 			bytes_to_send = fifo_space;
522 		}
523 		while (bytes_to_send) {
524 			uint32_t write_word = *write_ptr++;
525 
526 			if (bytes_left == 1 && (msg->flags & I2C_MSG_STOP)) {
527 				write_word |= TX_FIFO_STOP;
528 			}
529 			sys_write32(write_word, config->base + REG_TX_FIFO);
530 			bytes_to_send--;
531 			bytes_left--;
532 		}
533 		i2c_xilinx_axi_clear_interrupt_no_lock(config, data,
534 						       ISR_TX_FIFO_EMPTY | ISR_BUS_NOT_BUSY);
535 		k_spin_unlock(&data->lock, key);
536 
537 		ret = i2c_xilinx_axi_wait_tx_done(config, data);
538 		if (ret) {
539 			return ret;
540 		}
541 		fifo_space = FIFO_SIZE;
542 	}
543 	return 0;
544 }
545 
i2c_xilinx_axi_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)546 static int i2c_xilinx_axi_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
547 				   uint16_t addr)
548 {
549 	const struct i2c_xilinx_axi_config *config = dev->config;
550 	struct i2c_xilinx_axi_data *data = dev->data;
551 	int ret;
552 
553 	k_mutex_lock(&data->mutex, K_FOREVER);
554 
555 	ret = i2c_xilinx_axi_wait_not_busy(config, data);
556 	if (ret) {
557 		goto out_unlock;
558 	}
559 
560 	if (!num_msgs) {
561 		goto out_unlock;
562 	}
563 
564 	/**
565 	 * Reinitializing before each transfer shouldn't technically be needed, but
566 	 * seems to improve general reliability. The Linux driver also does this.
567 	 */
568 	i2c_xilinx_axi_reinit(config);
569 
570 	do {
571 		if (msgs->flags & I2C_MSG_ADDR_10_BITS) {
572 			/* Optionally supported in core, but not implemented in driver yet */
573 			ret = -EOPNOTSUPP;
574 			goto out_check_target;
575 		}
576 		if (msgs->flags & I2C_MSG_READ) {
577 			if (config->dyn_read_working && msgs->len <= MAX_DYNAMIC_READ_LEN) {
578 				ret = i2c_xilinx_axi_read_dyn(config, data, msgs, addr);
579 			} else {
580 				ret = i2c_xilinx_axi_read_nondyn(config, data, msgs, addr);
581 			}
582 		} else {
583 			ret = i2c_xilinx_axi_write(config, data, msgs, addr);
584 		}
585 		if (!ret && (msgs->flags & I2C_MSG_STOP)) {
586 			ret = i2c_xilinx_axi_wait_not_busy(config, data);
587 		}
588 		if (ret) {
589 			goto out_check_target;
590 		}
591 		msgs++;
592 		num_msgs--;
593 	} while (num_msgs);
594 
595 out_check_target:
596 #if defined(CONFIG_I2C_TARGET)
597 	/* If a target is registered, then ensure the controller gets put back
598 	 * into a suitable state to handle target transfers.
599 	 */
600 	k_spinlock_key_t key = k_spin_lock(&data->lock);
601 
602 	if (data->target_cfg) {
603 		i2c_xilinx_axi_target_setup(config, data->target_cfg);
604 	}
605 	k_spin_unlock(&data->lock, key);
606 #endif
607 
608 out_unlock:
609 	k_mutex_unlock(&data->mutex);
610 	return ret;
611 }
612 
i2c_xilinx_axi_init(const struct device * dev)613 static int i2c_xilinx_axi_init(const struct device *dev)
614 {
615 	const struct i2c_xilinx_axi_config *config = dev->config;
616 	struct i2c_xilinx_axi_data *data = dev->data;
617 	int error;
618 
619 	k_event_init(&data->irq_event);
620 	k_mutex_init(&data->mutex);
621 
622 	error = i2c_xilinx_axi_configure(dev, I2C_MODE_CONTROLLER);
623 	if (error) {
624 		return error;
625 	}
626 
627 	config->irq_config_func(dev);
628 
629 	LOG_INF("initialized");
630 	return 0;
631 }
632 
633 static DEVICE_API(i2c, i2c_xilinx_axi_driver_api) = {
634 	.configure = i2c_xilinx_axi_configure,
635 	.transfer = i2c_xilinx_axi_transfer,
636 #if defined(CONFIG_I2C_TARGET)
637 	.target_register = i2c_xilinx_axi_target_register,
638 	.target_unregister = i2c_xilinx_axi_target_unregister,
639 #endif
640 #ifdef CONFIG_I2C_RTIO
641 	.iodev_submit = i2c_iodev_submit_fallback,
642 #endif
643 };
644 
645 #define I2C_XILINX_AXI_INIT(n, compat)                                                             \
646 	static void i2c_xilinx_axi_config_func_##compat##_##n(const struct device *dev);           \
647                                                                                                    \
648 	static const struct i2c_xilinx_axi_config i2c_xilinx_axi_config_##compat##_##n = {         \
649 		.base = DT_INST_REG_ADDR(n),                                                       \
650 		.irq_config_func = i2c_xilinx_axi_config_func_##compat##_##n,                      \
651 		.dyn_read_working = DT_INST_NODE_HAS_COMPAT(n, xlnx_xps_iic_2_1)};                 \
652                                                                                                    \
653 	static struct i2c_xilinx_axi_data i2c_xilinx_axi_data_##compat##_##n;                      \
654                                                                                                    \
655 	I2C_DEVICE_DT_INST_DEFINE(n, i2c_xilinx_axi_init, NULL,                                    \
656 				  &i2c_xilinx_axi_data_##compat##_##n,                             \
657 				  &i2c_xilinx_axi_config_##compat##_##n, POST_KERNEL,              \
658 				  CONFIG_I2C_INIT_PRIORITY, &i2c_xilinx_axi_driver_api);           \
659                                                                                                    \
660 	static void i2c_xilinx_axi_config_func_##compat##_##n(const struct device *dev)            \
661 	{                                                                                          \
662 		ARG_UNUSED(dev);                                                                   \
663                                                                                                    \
664 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_xilinx_axi_isr,         \
665 			    DEVICE_DT_INST_GET(n), 0);                                             \
666                                                                                                    \
667 		irq_enable(DT_INST_IRQN(n));                                                       \
668 	}
669 
670 #define DT_DRV_COMPAT xlnx_xps_iic_2_1
671 DT_INST_FOREACH_STATUS_OKAY_VARGS(I2C_XILINX_AXI_INIT, DT_DRV_COMPAT)
672 #undef DT_DRV_COMPAT
673 #define DT_DRV_COMPAT xlnx_xps_iic_2_00_a
674 DT_INST_FOREACH_STATUS_OKAY_VARGS(I2C_XILINX_AXI_INIT, DT_DRV_COMPAT)
675