1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "sedi_driver_dma.h"
8 #include "sedi_driver_pm.h"
9 #include <sedi_driver_i2c.h>
10 #include <sedi_i2c_regs.h>
11 #include "sedi_driver_core.h"
12 
13 #define I2C_MAX_BLOCK_TS (4096)
14 
15 #define I2C_SDA_HOLD_DEFAULT (133)
16 #define I2C_FIFO_DEFAULT_WATERMARK (I2C_FIFO_DEPTH / 2U)
17 
18 #define LBW_CLK_MHZ (sedi_pm_get_lbw_clock() / 1000000)
19 
20 enum { I2C_SPEED_STANDARD = 0, I2C_SPEED_FAST, I2C_SPEED_FAST_PLUS, I2C_SPEED_HIGH, I2C_SPEED_MAX };
21 
22 #define BSETS_ABORT_SOURCE_NO_ACK  \
23 	(SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_7B_ADDR_NOACK, ACTIVE) | \
24 	 SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_10ADDR1_NOACK, ACTIVE) | \
25 	 SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_10ADDR2_NOACK, ACTIVE) | \
26 	 SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_TXDATA_NOACK, ABRT_TXDATA_NOACK_GENERATED) | \
27 	 SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_GCALL_NOACK, ABRT_GCALL_NOACK_GENERATED))
28 
29 #define BSETS_DMA_ENABLE  \
30 	(SEDI_RBFVM(I2C, DMA_CR, RDMAE, ENABLED) | \
31 	 SEDI_RBFVM(I2C, DMA_CR, TDMAE, ENABLED))
32 
33 #define BSETS_INTR_ERROR  \
34 	(SEDI_RBFVM(I2C, INTR_STAT, R_RX_UNDER, ACTIVE) | \
35 	 SEDI_RBFVM(I2C, INTR_STAT, R_RX_OVER, ACTIVE)  | \
36 	 SEDI_RBFVM(I2C, INTR_STAT, R_TX_OVER, ACTIVE)  | \
37 	 SEDI_RBFVM(I2C, INTR_STAT, R_TX_ABRT, ACTIVE))
38 
39 #define BSETS_INTR_SEND  \
40 	(SEDI_RBFVM(I2C, INTR_STAT, R_TX_EMPTY, ACTIVE) | \
41 	 SEDI_RBFVM(I2C, INTR_STAT, R_STOP_DET, ACTIVE) | \
42 	 BSETS_INTR_ERROR)
43 
44 #define BSETS_INTR_RECV  \
45 	(SEDI_RBFVM(I2C, INTR_STAT, R_TX_EMPTY, ACTIVE) | \
46 	 SEDI_RBFVM(I2C, INTR_STAT, R_RX_FULL, ACTIVE)  | \
47 	 SEDI_RBFVM(I2C, INTR_STAT, R_STOP_DET, ACTIVE) | \
48 	 BSETS_INTR_ERROR)
49 
50 #define BSETS_INTR_SLAVE  \
51 	(SEDI_RBFVM(I2C, INTR_STAT, R_RD_REQ, ACTIVE) | \
52 	 SEDI_RBFVM(I2C, INTR_STAT, R_RX_FULL, ACTIVE) | \
53 	 SEDI_RBFVM(I2C, INTR_STAT, R_STOP_DET, ACTIVE) | \
54 	 BSETS_INTR_ERROR  | \
55 	 SEDI_RBFVM(I2C, INTR_STAT, R_START_DET, ACTIVE) | \
56 	 SEDI_RBFVM(I2C, INTR_STAT, R_RESTART_DET, ACTIVE))
57 
58 #define BSETS_MASTER_DEFAULT  \
59 	(SEDI_RBFVM(I2C, CON, IC_SLAVE_DISABLE, SLAVE_DISABLED) | \
60 	 SEDI_RBFVM(I2C, CON, IC_RESTART_EN, ENABLED) | \
61 	 SEDI_RBFVM(I2C, CON, MASTER_MODE, ENABLED) | \
62 	 SEDI_RBFVM(I2C, CON, TX_EMPTY_CTRL, ENABLED))
63 
64 typedef enum {
65 	I2C_DMA_DIRECTION_TX = 0,
66 	I2C_DMA_DIRECTION_RX = 1,
67 	I2C_DMA_DIRECTION_RX_CMD = 2
68 } i2c_dma_diretion_t;
69 
70 struct i2c_context {
71 	uint32_t base;
72 
73 	sedi_i2c_capabilities_t capability;
74 	sedi_i2c_status_t status;
75 	sedi_i2c_event_cb_t cb_event;
76 
77 	uint8_t *buf;
78 	uint32_t buf_size;
79 	uint32_t buf_index;
80 	uint32_t rx_cmd_index;
81 
82 	volatile uint8_t pending;
83 
84 	uint32_t isr_flag;
85 	uint32_t isr_data;
86 
87 	int tx_dma_dev;
88 	int tx_dma_chan;
89 	int tx_dma_handshake;
90 	int rx_dma_dev;
91 	int rx_dma_chan;
92 	int rx_dma_handshake;
93 
94 	dma_memory_type_t tx_memory_type;
95 	dma_memory_type_t rx_memory_type;
96 
97 	int speed;
98 	sedi_i2c_bus_clk_t *clk_info;
99 	sedi_i2c_bus_info_t bus_info;
100 };
101 
102 static uint32_t regval_speed[I2C_SPEED_MAX] = {
103 	SEDI_RBFVM(I2C, CON, SPEED, STANDARD),
104 	SEDI_RBFVM(I2C, CON, SPEED, FAST),
105 	SEDI_RBFVM(I2C, CON, SPEED, FAST),
106 	SEDI_RBFVM(I2C, CON, SPEED, HIGH)
107 };
108 
109 /*
110  * For example, standard mode is 100KHz, 10000ns per period, 5000ns for
111  * SCL low & high level.
112  */
113 #define I2C_SS_SCL_HIGH 4000
114 #define I2C_SS_SCL_LOW 4700
115 #define I2C_FS_SCL_HIGH 600
116 #define I2C_FS_SCL_LOW 1300
117 #define I2C_FSP_SCL_HIGH 300
118 #define I2C_FSP_SCL_LOW 600
119 #ifndef I2C_SCL_400PF
120 #define I2C_HS_SCL_HIGH 70
121 #define I2C_HS_SCL_LOW 590
122 #else
123 #define I2C_HS_SCL_HIGH 160
124 #define I2C_HS_SCL_LOW 320
125 #endif
126 
127 #define I2C_CONTEXT_INIT(x)                                                                        \
128 	{                                                                                          \
129 		.base = SEDI_IREG_BASE(I2C, x), .speed = I2C_SPEED_FAST,                           \
130 		.tx_dma_handshake = DMA_HWID_I2C##x##_TX, .rx_dma_handshake = DMA_HWID_I2C##x##_RX,\
131 		.tx_memory_type = DMA_SRAM_MEM, .rx_memory_type = DMA_SRAM_MEM                     \
132 	}
133 struct i2c_context contexts[SEDI_I2C_NUM] = { I2C_CONTEXT_INIT(0), I2C_CONTEXT_INIT(1),
134 					      I2C_CONTEXT_INIT(2) };
135 
136 static void i2c_isr_complete(sedi_i2c_t i2c_device, bool is_error);
init_i2c_prescale(sedi_i2c_bus_info_t * bus_info)137 static void init_i2c_prescale(sedi_i2c_bus_info_t *bus_info)
138 {
139 	if (bus_info->std_clk.hcnt == 0) {
140 
141 		bus_info->std_clk.sda_hold = LBW_CLK_MHZ * I2C_SDA_HOLD_DEFAULT / NS_PER_US;
142 		bus_info->fst_clk.sda_hold = LBW_CLK_MHZ * I2C_SDA_HOLD_DEFAULT / NS_PER_US;
143 		bus_info->fsp_clk.sda_hold = LBW_CLK_MHZ * I2C_SDA_HOLD_DEFAULT / NS_PER_US;
144 		bus_info->high_clk.sda_hold = LBW_CLK_MHZ * I2C_SDA_HOLD_DEFAULT / NS_PER_US;
145 
146 		bus_info->std_clk.hcnt = LBW_CLK_MHZ * I2C_SS_SCL_HIGH / NS_PER_US;
147 		bus_info->fst_clk.hcnt = LBW_CLK_MHZ * I2C_FS_SCL_HIGH / NS_PER_US;
148 		bus_info->fsp_clk.hcnt = LBW_CLK_MHZ * I2C_FSP_SCL_HIGH / NS_PER_US;
149 		bus_info->high_clk.hcnt = LBW_CLK_MHZ * I2C_HS_SCL_HIGH / NS_PER_US;
150 
151 		bus_info->std_clk.lcnt = LBW_CLK_MHZ * I2C_SS_SCL_LOW / NS_PER_US;
152 		bus_info->fst_clk.lcnt = LBW_CLK_MHZ * I2C_FS_SCL_LOW / NS_PER_US;
153 		bus_info->fsp_clk.lcnt = LBW_CLK_MHZ * I2C_FSP_SCL_LOW / NS_PER_US;
154 		bus_info->high_clk.lcnt = LBW_CLK_MHZ * I2C_HS_SCL_LOW / NS_PER_US;
155 	}
156 }
157 
dw_i2c_enable(uint32_t base)158 static void dw_i2c_enable(uint32_t base)
159 {
160 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
161 
162 	if (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, ENABLED, &i2c->enable_status)) {
163 		return;
164 	}
165 
166 	/* prevent tx empty interrupt after enable */
167 	i2c->intr_mask = 0;
168 
169 	i2c->enable = SEDI_RBFVM(I2C, ENABLE, ENABLE, ENABLED);
170 	while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, DISABLED, &i2c->enable_status))
171 		;
172 }
173 
dw_i2c_disable(uint32_t base)174 static int dw_i2c_disable(uint32_t base)
175 {
176 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
177 
178 	/* If already disabled, return */
179 	if (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE, ENABLE, DISABLED, &i2c->enable)) {
180 		return 0;
181 	}
182 
183 	i2c->dma_cr = 0;
184 	i2c->intr_mask = 0;
185 
186 	if (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, MST_ACTIVITY, ACTIVE, &i2c->status)) {
187 		SEDI_PREG_RBFV_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable);
188 		while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable))
189 			;
190 	}
191 
192 	while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, MST_ACTIVITY, ACTIVE, &i2c->status))
193 		;
194 
195 	i2c->enable = 0;
196 	while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, ENABLED, &i2c->enable_status))
197 		;
198 
199 	return 0;
200 }
201 
dw_i2c_config_addr(uint32_t base,uint16_t slave_addr)202 static int dw_i2c_config_addr(uint32_t base, uint16_t slave_addr)
203 {
204 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
205 
206 	i2c->tar = SEDI_RBFM_VALUE(I2C, TAR, IC_TAR, slave_addr);
207 	if (slave_addr & SEDI_I2C_ADDRESS_10BIT) {
208 		SEDI_PREG_RBFV_SET(I2C, TAR, IC_10BITADDR_MASTER, ADDR_10BITS, &i2c->tar);
209 	}
210 
211 	return 0;
212 }
213 
dw_i2c_config_speed(uint32_t base,int speed,sedi_i2c_bus_clk_t * cfg)214 static int dw_i2c_config_speed(uint32_t base, int speed,
215 		sedi_i2c_bus_clk_t *cfg)
216 {
217 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
218 
219 	if (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, ENABLED, &i2c->enable_status)) {
220 		return -1;
221 	}
222 
223 	i2c->con = BSETS_MASTER_DEFAULT | regval_speed[speed];
224 
225 	/* config sda_hold if needed */
226 	if (cfg->sda_hold) {
227 		i2c->sda_hold = cfg->sda_hold;
228 	}
229 
230 	switch (speed) {
231 	case I2C_SPEED_STANDARD:
232 		i2c->ss_scl_hcnt = cfg->hcnt;
233 		i2c->ss_scl_lcnt = cfg->lcnt;
234 		break;
235 	case I2C_SPEED_FAST:
236 	case I2C_SPEED_FAST_PLUS:
237 		i2c->fs_scl_hcnt = cfg->hcnt;
238 		i2c->fs_scl_lcnt = cfg->lcnt;
239 		break;
240 	case I2C_SPEED_HIGH:
241 		i2c->hs_scl_hcnt = cfg->hcnt;
242 		i2c->hs_scl_lcnt = cfg->lcnt;
243 		break;
244 	default:
245 		return SEDI_DRIVER_ERROR_UNSUPPORTED;
246 	}
247 
248 	return 0;
249 }
250 
dw_i2c_config_txfifo(uint32_t base,uint32_t watermark)251 static int dw_i2c_config_txfifo(uint32_t base, uint32_t watermark)
252 {
253 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
254 
255 	SEDI_PREG_RBF_SET(I2C, TX_TL, TX_TL, watermark, &i2c->tx_tl);
256 
257 	return 0;
258 }
259 
dw_i2c_config_rxfifo(uint32_t base,uint32_t watermark)260 static int dw_i2c_config_rxfifo(uint32_t base, uint32_t watermark)
261 {
262 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
263 
264 	SEDI_PREG_RBF_SET(I2C, RX_TL, RX_TL, watermark - 1, &i2c->rx_tl);
265 
266 	return 0;
267 }
268 
dw_i2c_poll_write(uint32_t base,const uint8_t * buffer,uint32_t length,bool pending)269 static int dw_i2c_poll_write(uint32_t base, const uint8_t *buffer, uint32_t length, bool pending)
270 {
271 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
272 
273 	uint32_t cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, WRITE);
274 
275 	for (uint32_t i = 0; i < length; i++) {
276 		if ((i == length - 1) && (!pending)) {
277 			cmd |= SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE);
278 		}
279 
280 		i2c->data_cmd = buffer[i] | cmd;
281 		/* Check abort and error */
282 		do {
283 			if (i2c->raw_intr_stat & BSETS_INTR_ERROR) {
284 				return -1;
285 			}
286 
287 		} while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, TFNF, FULL, &i2c->status));
288 	}
289 
290 	/* Wait for end */
291 	while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, &i2c->status)) {
292 	}
293 
294 	return 0;
295 }
296 
dw_i2c_poll_read(uint32_t base,uint8_t * buffer,uint32_t length,bool pending)297 static int dw_i2c_poll_read(uint32_t base, uint8_t *buffer, uint32_t length, bool pending)
298 {
299 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
300 	uint32_t cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ);
301 
302 	for (uint32_t i = 0; i < length; i++) {
303 		if ((i == length - 1) && (!pending)) {
304 			cmd |= SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE);
305 		}
306 
307 		i2c->data_cmd = cmd;
308 		do {
309 			/* Check abort and error*/
310 			if (i2c->raw_intr_stat & BSETS_INTR_ERROR) {
311 				return -1;
312 			}
313 
314 		} while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, RFNE, EMPTY, &i2c->status));
315 
316 		buffer[i] = (uint8_t)(i2c->data_cmd & 0xFF);
317 	}
318 
319 	/* Wait for end */
320 	while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, &i2c->status)) {
321 	}
322 
323 	return 0;
324 }
325 
dw_i2c_irq_config(uint32_t base,uint32_t config)326 static inline void dw_i2c_irq_config(uint32_t base, uint32_t config)
327 {
328 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base;
329 
330 	i2c->intr_mask = config;
331 }
332 
dw_i2c_clear_interrupt(uint32_t base)333 static uint32_t dw_i2c_clear_interrupt(uint32_t base)
334 {
335 	sedi_i2c_regs_t *i2c = (void *)base;
336 	uint32_t value;
337 	uint32_t stat;
338 
339 	stat = i2c->intr_stat;
340 
341 	value = i2c->clr_rx_under;
342 	value = i2c->clr_rx_over;
343 	value = i2c->clr_tx_over;
344 	value = i2c->clr_tx_abrt;
345 	value = i2c->clr_stop_det;
346 	value = i2c->clr_intr;
347 	PARAM_UNUSED(value);
348 
349 	return stat;
350 }
351 
dw_i2c_dma_enable(uint32_t base,int fifo_depth)352 static void dw_i2c_dma_enable(uint32_t base, int fifo_depth)
353 {
354 	sedi_i2c_regs_t *i2c = (void *)base;
355 
356 	i2c->dma_tdlr = SEDI_RBFM_VALUE(I2C, DMA_TDLR, DMATDL, fifo_depth);
357 	i2c->dma_rdlr = SEDI_RBFM_VALUE(I2C, DMA_RDLR, DMARDL, fifo_depth - 1);
358 
359 	i2c->dma_cr = BSETS_DMA_ENABLE;
360 }
361 
362 /* force enter IDLE mode */
dw_i2c_abort(struct i2c_context * context)363 static void dw_i2c_abort(struct i2c_context *context)
364 {
365 	sedi_i2c_regs_t *i2c = (void *)context->base;
366 	uint32_t value;
367 
368 	if (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE, ENABLE, DISABLED, &i2c->enable)) {
369 		return;
370 	}
371 
372 	i2c->dma_cr = 0;
373 	i2c->intr_mask = 0;
374 
375 	SEDI_PREG_RBFV_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable);
376 
377 	/* Waiting for abort operation finished, HW can clear */
378 	while (SEDI_PREG_RBFV_IS_SET(I2C, RAW_INTR_STAT, TX_ABRT, INACTIVE, &i2c->raw_intr_stat)) {
379 		;
380 	}
381 
382 	while (SEDI_PREG_RBFV_GET(I2C, RXFLR, RXFLR, &i2c->rxflr) != 0) {
383 		value = i2c->data_cmd;
384 	}
385 
386 	dw_i2c_irq_config(context->base, 0);
387 
388 	dw_i2c_config_txfifo(context->base, 0);
389 	dw_i2c_config_rxfifo(context->base, 0);
390 
391 	/* Clear the abort state */
392 	dw_i2c_clear_interrupt(context->base);
393 	PARAM_UNUSED(value);
394 }
395 
dw_i2c_dr_address(uint32_t base)396 static uint32_t dw_i2c_dr_address(uint32_t base)
397 {
398 	sedi_i2c_regs_t *i2c = (void *)base;
399 
400 	return (uint32_t)&i2c->data_cmd;
401 }
402 
dw_i2c_abort_analysis(uint32_t base)403 static uint32_t dw_i2c_abort_analysis(uint32_t base)
404 {
405 	sedi_i2c_regs_t *i2c = (void *)base;
406 	uint32_t abort_src, event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE;
407 
408 	abort_src = i2c->tx_abrt_source;
409 
410 	if (abort_src & BSETS_ABORT_SOURCE_NO_ACK) {
411 		event |= SEDI_I2C_EVENT_ADDRESS_NACK;
412 	}
413 
414 	if (SEDI_PREG_RBFV_IS_SET(I2C, TX_ABRT_SOURCE, ARB_LOST, ABRT_LOST_GENERATED, &abort_src)) {
415 		event |= SEDI_I2C_EVENT_ARBITRATION_LOST;
416 	}
417 
418 	return event;
419 }
420 
421 /* Used for sending cmd for I2C read operation */
i2c_ask_data(sedi_i2c_t i2c_device)422 static void i2c_ask_data(sedi_i2c_t i2c_device)
423 {
424 	struct i2c_context *context = &contexts[i2c_device];
425 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
426 
427 	uint32_t tx_fifo_space = 0, rx_fifo_space = 0;
428 	uint32_t rx_pending = context->rx_cmd_index - context->buf_index;
429 	uint32_t size = context->buf_size - context->rx_cmd_index;
430 	uint32_t fifo_size = 0;
431 	uint32_t data = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ);
432 	bool last_data = false;
433 
434 	/* No need to send anymore */
435 	if (context->rx_cmd_index == context->buf_size) {
436 		return;
437 	}
438 
439 	/* Decide how many space there are */
440 	if ((I2C_FIFO_DEPTH - SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr)) <= rx_pending) {
441 		return;
442 	}
443 
444 	tx_fifo_space = I2C_FIFO_DEPTH - SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) -
445 			rx_pending;
446 
447 	/* To prevent RX FIFO overflow, need to make sure command number less
448 	 * than the space in RX FIFO.
449 	 */
450 	rx_fifo_space = I2C_FIFO_DEPTH - SEDI_PREG_RBFV_GET(I2C, RXFLR, RXFLR, &i2c->rxflr);
451 
452 	if (tx_fifo_space < rx_fifo_space) {
453 		fifo_size = tx_fifo_space;
454 	} else {
455 		fifo_size = rx_fifo_space;
456 	}
457 
458 	if (size <= fifo_size) {
459 		last_data = true;
460 	} else {
461 		size = fifo_size;
462 	}
463 
464 	while (size > 0) {
465 		/* If it is first data, need RESTART */
466 		if (context->rx_cmd_index == 0) {
467 			data |= SEDI_RBFVM(I2C, DATA_CMD, RESTART, ENABLE);
468 		}
469 
470 		/* Last data need STOP flag */
471 		if ((size == 1) && last_data && (!(context->pending))) {
472 			data |= SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE);
473 			/*  Disable tx empty interrupt */
474 			i2c->intr_mask &= ~SEDI_RBFVM(I2C, INTR_MASK, M_TX_EMPTY, DISABLED);
475 		}
476 
477 		i2c->data_cmd = data;
478 		context->rx_cmd_index++;
479 		size--;
480 
481 		/* Reset data */
482 		data = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ);
483 	}
484 }
485 
i2c_send(sedi_i2c_t i2c_device)486 static void i2c_send(sedi_i2c_t i2c_device)
487 {
488 	struct i2c_context *context = &contexts[i2c_device];
489 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
490 
491 	uint32_t tx_fifo_space = 0;
492 	uint32_t size = context->buf_size - context->buf_index;
493 	uint32_t data = 0;
494 	uint8_t *buf = context->buf;
495 	bool last_data = false;
496 
497 	if (context->buf_index == context->buf_size) {
498 		return;
499 	}
500 
501 	/* Decide how many space there are */
502 	tx_fifo_space = I2C_FIFO_DEPTH - SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr);
503 
504 	if (size <= tx_fifo_space) {
505 		last_data = true;
506 	} else {
507 		size = tx_fifo_space;
508 	}
509 
510 	/* Not last data */
511 	while (size > 1) {
512 		data = buf[context->buf_index];
513 		i2c->data_cmd = data;
514 		size--;
515 		context->buf_index++;
516 	}
517 
518 	/* Last data transfer  */
519 	data = buf[context->buf_index];
520 
521 	/* If it is the last data for whole transfer */
522 	if (last_data) {
523 		/* NO need to send STOP, but need to change watermark
524 		 * to 0, this will have a interrupt while all data sent out
525 		 */
526 		if (context->pending) {
527 			SEDI_PREG_RBF_SET(I2C, TX_TL, TX_TL, 0, &i2c->tx_tl);
528 		} else {
529 			SEDI_PREG_RBFV_SET(I2C, DATA_CMD, STOP, ENABLE, &data);
530 			/* Disable tx empty interrupt */
531 			i2c->intr_mask &= ~SEDI_RBFVM(I2C, INTR_MASK, M_TX_EMPTY, DISABLED);
532 		}
533 	}
534 
535 	i2c->data_cmd = data;
536 	context->buf_index++;
537 }
538 
539 /******************************************************************************
540  * SEDI interface
541  *****************************************************************************/
542 
543 #define SEDI_I2C_DRV_VERSION SEDI_DRIVER_VERSION_MAJOR_MINOR(1, 0)
544 #define SEDI_I2C_DMA_CHANNEL_UNUSED (-1)
545 
546 static const sedi_driver_version_t driver_version = { SEDI_I2C_API_VERSION, SEDI_I2C_DRV_VERSION };
547 
548 static sedi_i2c_capabilities_t driver_capabilities[SEDI_I2C_NUM] = { 0 };
549 /* Used for I2C DMA Rx */
550 static uint8_t dma_cmd __attribute__((aligned(32))) = 1;
551 
sedi_i2c_get_version(void)552 sedi_driver_version_t sedi_i2c_get_version(void)
553 {
554 	return driver_version;
555 }
556 
sedi_i2c_get_capabilities(IN sedi_i2c_t i2c_device,sedi_i2c_capabilities_t * cap)557 int sedi_i2c_get_capabilities(IN sedi_i2c_t i2c_device, sedi_i2c_capabilities_t *cap)
558 {
559 	struct i2c_context *context = &contexts[i2c_device];
560 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
561 
562 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
563 
564 	if (sedi_dev_is_self_owned(SEDI_DEVID_I2C0 + i2c_device)) {
565 		driver_capabilities[i2c_device].is_available = 1;
566 	} else {
567 		driver_capabilities[i2c_device].is_available = 0;
568 	}
569 
570 	driver_capabilities[i2c_device].rx_buffer_depth =
571 		SEDI_PREG_RBFV_GET(I2C, COMP_PARAM_1, RX_BUFFER_DEPTH, &i2c->comp_param_1) + 1;
572 	driver_capabilities[i2c_device].tx_buffer_depth =
573 		SEDI_PREG_RBFV_GET(I2C, COMP_PARAM_1, TX_BUFFER_DEPTH, &i2c->comp_param_1) + 1;
574 	driver_capabilities[i2c_device].dma =
575 		SEDI_PREG_RBFV_GET(I2C, COMP_PARAM_1, HAS_DMA, &i2c->comp_param_1);
576 
577 	*cap = driver_capabilities[i2c_device];
578 
579 	return SEDI_DRIVER_OK;
580 }
581 
sedi_i2c_init(IN sedi_i2c_t i2c_device,IN sedi_i2c_event_cb_t cb_event,IN uint32_t base)582 int32_t sedi_i2c_init(IN sedi_i2c_t i2c_device,
583 		IN sedi_i2c_event_cb_t cb_event, IN uint32_t base)
584 {
585 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
586 
587 	struct i2c_context *context = &contexts[i2c_device];
588 
589 	if (!sedi_dev_is_self_owned(SEDI_DEVID_I2C0 + i2c_device)) {
590 		return SEDI_DRIVER_ERROR_NO_DEV;
591 	}
592 
593 	context->cb_event = cb_event;
594 	context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
595 	context->rx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
596 
597 	init_i2c_prescale(&(context->bus_info));
598 
599 	context->base = base;
600 
601 	/* i2c default configuration */
602 	context->speed = I2C_SPEED_STANDARD;
603 	context->clk_info = &(context->bus_info.std_clk);
604 	dw_i2c_config_speed(context->base, context->speed, context->clk_info);
605 
606 	return SEDI_DRIVER_OK;
607 }
608 
sedi_i2c_uninit(IN sedi_i2c_t i2c_device)609 int32_t sedi_i2c_uninit(IN sedi_i2c_t i2c_device)
610 {
611 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
612 
613 	struct i2c_context *context = &contexts[i2c_device];
614 
615 	context->cb_event = NULL;
616 
617 	return SEDI_DRIVER_OK;
618 }
619 
sedi_i2c_set_power(IN sedi_i2c_t i2c_device,IN sedi_power_state_t state)620 int32_t sedi_i2c_set_power(IN sedi_i2c_t i2c_device, IN sedi_power_state_t state)
621 {
622 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
623 
624 	struct i2c_context *context = &contexts[i2c_device];
625 	sedi_devid_t id = SEDI_DEVID_I2C0 + i2c_device;
626 	int32_t ret = SEDI_DRIVER_OK;
627 
628 	switch (state) {
629 	case SEDI_POWER_FULL:
630 		sedi_pm_set_device_power(id, state);
631 		dw_i2c_clear_interrupt(context->base);
632 		dw_i2c_irq_config(context->base, 0);
633 		dw_i2c_disable(context->base);
634 		dw_i2c_config_speed(context->base, context->speed,
635 			context->clk_info);
636 		break;
637 	case SEDI_POWER_SUSPEND:
638 	case SEDI_POWER_FORCE_SUSPEND:
639 	case SEDI_POWER_LOW:
640 		dw_i2c_irq_config(context->base, 0);
641 		sedi_pm_set_device_power(id, state);
642 		break;
643 	case SEDI_POWER_OFF:
644 	default:
645 		ret = SEDI_DRIVER_ERROR_UNSUPPORTED;
646 		break;
647 	}
648 
649 	return ret;
650 }
651 
callback_tx_dma_transfer(const sedi_dma_t dma,const int chan,const int event,void * param)652 static void callback_tx_dma_transfer(const sedi_dma_t dma, const int chan, const int event,
653 				     void *param)
654 {
655 	struct i2c_context *context = &contexts[(int)param];
656 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
657 	uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR;
658 
659 	PARAM_UNUSED(dma);
660 	PARAM_UNUSED(chan);
661 
662 	/* DMA error, go to end */
663 	if (event != SEDI_DMA_EVENT_TRANSFER_DONE) {
664 		context->status.event = i2c_event;
665 		i2c_isr_complete((sedi_i2c_t)param, true);
666 		return;
667 	}
668 
669 	SEDI_PREG_RBFV_SET(I2C, DMA_CR, TDMAE, DISABLED, &i2c->dma_cr);
670 	context->buf_index = context->buf_size;
671 	context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
672 
673 	if (context->pending) {
674 		/* If no STOP, all data sent by DMA, enable TX_EMPTY interrupt
675 		 * to get stop condition.
676 		 */
677 		SEDI_PREG_RBF_SET(I2C, TX_TL, TX_TL, 0, &i2c->tx_tl);
678 		SEDI_PREG_RBFV_SET(I2C, INTR_MASK, M_TX_EMPTY, DISABLED, &i2c->intr_mask);
679 	} else {
680 		/* WA for I2C DMA transfer, wait until FIFO not full*/
681 		/* If need STOP, last data sent by interrupt */
682 		while (SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) == I2C_FIFO_DEPTH) {
683 		}
684 		i2c->data_cmd = context->buf[context->buf_size - 1] |
685 				SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE);
686 	}
687 }
688 
callback_rx_dma_transfer(const sedi_dma_t dma,const int chan,const int event,void * param)689 static void callback_rx_dma_transfer(const sedi_dma_t dma, const int chan, const int event,
690 				     void *param)
691 {
692 	struct i2c_context *context = &contexts[(int)param];
693 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
694 	uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR;
695 
696 	PARAM_UNUSED(dma);
697 	PARAM_UNUSED(chan);
698 
699 	/* DMA error, go to end */
700 	if (event != SEDI_DMA_EVENT_TRANSFER_DONE) {
701 		context->status.event = i2c_event;
702 		i2c_isr_complete((sedi_i2c_t)param, true);
703 		return;
704 	}
705 
706 	/* Disable the Rx dma request */
707 	SEDI_PREG_RBFV_SET(I2C, DMA_CR, RDMAE, DISABLED, &i2c->dma_cr);
708 	context->buf_index = context->buf_size;
709 	context->rx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
710 }
711 
callback_rx_cmd_dma_transfer(const sedi_dma_t dma,const int chan,const int event,void * param)712 static void callback_rx_cmd_dma_transfer(const sedi_dma_t dma, const int chan, const int event,
713 					 void *param)
714 {
715 	struct i2c_context *context = &contexts[(int)param];
716 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
717 	uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR;
718 
719 	PARAM_UNUSED(dma);
720 	PARAM_UNUSED(chan);
721 
722 	/* DMA error, go to end */
723 	if (event != SEDI_DMA_EVENT_TRANSFER_DONE) {
724 		context->status.event = i2c_event;
725 		i2c_isr_complete((sedi_i2c_t)param, true);
726 		return;
727 	}
728 
729 	context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
730 
731 	/* Send the last command, which is different from previous one*/
732 	while (SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) == I2C_FIFO_DEPTH) {
733 	}
734 	if (context->pending) {
735 		i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ);
736 	} else {
737 		i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) | SEDI_RBFVM(I2C, DATA_CMD,
738 				STOP, ENABLE);
739 	}
740 }
741 
config_and_enable_dma_channel(sedi_i2c_t i2c_dev,int dma,int handshake,int chan,uint32_t src,uint32_t dst,uint32_t len,i2c_dma_diretion_t dir)742 static int config_and_enable_dma_channel(sedi_i2c_t i2c_dev, int dma, int handshake, int chan,
743 					 uint32_t src, uint32_t dst, uint32_t len,
744 					 i2c_dma_diretion_t dir)
745 {
746 	int ret;
747 	int dma_dir;
748 	int dma_per_dir;
749 
750 	if (dir == I2C_DMA_DIRECTION_TX) {
751 		dma_dir = DMA_MEMORY_TO_PERIPHERAL;
752 		dma_per_dir = DMA_HS_PER_TX;
753 		ret = sedi_dma_init(dma, chan, callback_tx_dma_transfer, (void *)i2c_dev);
754 		DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
755 	} else if (dir == I2C_DMA_DIRECTION_RX) {
756 		dma_dir = DMA_PERIPHERAL_TO_MEMORY;
757 		dma_per_dir = DMA_HS_PER_RX;
758 		ret = sedi_dma_init(dma, chan, callback_rx_dma_transfer, (void *)i2c_dev);
759 		DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
760 	} else {
761 		dma_dir = DMA_PERIPHERAL_TO_PERIPHERAL;
762 		dma_per_dir = DMA_HS_PER_TX;
763 		ret = sedi_dma_init(dma, chan, callback_rx_cmd_dma_transfer, (void *)i2c_dev);
764 		DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
765 	}
766 
767 	ret = sedi_dma_set_power(dma, chan, SEDI_POWER_FULL);
768 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
769 
770 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_BURST_LENGTH, DMA_BURST_TRANS_LENGTH_1);
771 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
772 
773 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_SR_TRANS_WIDTH, DMA_TRANS_WIDTH_8);
774 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
775 
776 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_DT_TRANS_WIDTH, DMA_TRANS_WIDTH_8);
777 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
778 
779 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_HS_DEVICE_ID, handshake);
780 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
781 
782 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_HS_POLARITY, DMA_HS_POLARITY_HIGH);
783 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
784 
785 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_DIRECTION, dma_dir);
786 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
787 
788 	ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_HS_DEVICE_ID_PER_DIR, dma_per_dir);
789 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
790 
791 	ret = sedi_dma_start_transfer(dma, chan, src, dst, len);
792 	DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR);
793 
794 	return ret;
795 }
796 
sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device,IN uint32_t addr,IN uint8_t * data,IN uint32_t num,IN bool pending,IN uint32_t dma_dev,IN uint32_t dma_chan)797 int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN uint8_t *data,
798 	IN uint32_t num, IN bool pending, IN uint32_t dma_dev, IN uint32_t dma_chan)
799 {
800 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
801 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
802 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
803 
804 	struct i2c_context *context = &contexts[i2c_device];
805 
806 	/* dma max block ts 4095, need slicing if exceed, tbd */
807 	if (num <= SEDI_I2C_DMA_LENGTH_LIMIT || num > I2C_MAX_BLOCK_TS) {
808 		return SEDI_DRIVER_ERROR_PARAMETER;
809 	}
810 
811 	if (context->status.busy) {
812 		return SEDI_DRIVER_ERROR_BUSY;
813 	}
814 
815 	dw_i2c_clear_interrupt(context->base);
816 	dw_i2c_config_addr(context->base, addr);
817 	dw_i2c_enable(context->base);
818 
819 	context->status.busy = 1U;
820 	context->status.direction = 0U;
821 	context->status.event = SEDI_I2C_EVENT_TRANSFER_NONE;
822 	context->pending = pending;
823 	context->buf = (void *)data;
824 	context->buf_size = num;
825 	context->buf_index = 0;
826 	context->tx_dma_dev = dma_dev;
827 	context->tx_dma_chan = dma_chan;
828 
829 	dw_i2c_irq_config(context->base,
830 			BSETS_INTR_ERROR | SEDI_RBFVM(I2C, INTR_MASK, M_STOP_DET, DISABLED));
831 
832 	dw_i2c_dma_enable(context->base, 1);
833 
834 	config_and_enable_dma_channel(i2c_device, context->tx_dma_dev, context->tx_dma_handshake,
835 		context->tx_dma_chan, (uint32_t)data, dw_i2c_dr_address(context->base),
836 		pending ? num : num - 1, I2C_DMA_DIRECTION_TX);
837 
838 	return SEDI_DRIVER_OK;
839 }
840 
sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device,IN uint32_t addr,OUT uint8_t * data,IN uint32_t num,IN bool pending,IN uint32_t rx_dma_dev,IN uint32_t rx_dma_chan,IN uint32_t cmd_dma_dev,IN uint32_t cmd_dma_chan)841 int32_t sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, OUT uint8_t *data,
842 	IN uint32_t num, IN bool pending, IN uint32_t rx_dma_dev, IN uint32_t rx_dma_chan,
843 	IN uint32_t cmd_dma_dev, IN uint32_t cmd_dma_chan)
844 {
845 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
846 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
847 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
848 
849 	struct i2c_context *context = &contexts[i2c_device];
850 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
851 
852 	/* dma max block ts 4095, need slicing if exceed, tbd */
853 	if (num <= SEDI_I2C_DMA_LENGTH_LIMIT || num > I2C_MAX_BLOCK_TS) {
854 		return SEDI_DRIVER_ERROR_PARAMETER;
855 	}
856 
857 	if (context->status.busy) {
858 		return SEDI_DRIVER_ERROR_BUSY;
859 	}
860 
861 	dw_i2c_clear_interrupt(context->base);
862 	dw_i2c_config_addr(context->base, addr);
863 	dw_i2c_enable(context->base);
864 
865 	context->status.busy = 1U;
866 	context->status.direction = 1U;
867 	context->status.event = SEDI_I2C_EVENT_TRANSFER_NONE;
868 	context->pending = pending;
869 	context->buf = data;
870 	context->buf_size = num;
871 	context->buf_index = 0;
872 	context->rx_dma_dev = rx_dma_dev;
873 	context->rx_dma_chan = rx_dma_chan;
874 	context->tx_dma_dev = cmd_dma_dev;
875 	context->tx_dma_chan = cmd_dma_chan;
876 
877 	dw_i2c_irq_config(context->base,
878 			BSETS_INTR_ERROR | SEDI_RBFVM(I2C, INTR_MASK, M_STOP_DET, DISABLED));
879 
880 	/* First write the command into register and clean cache */
881 	i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) |
882 			SEDI_RBFVM(I2C, DATA_CMD, RESTART, ENABLE);
883 	sedi_core_clean_dcache_by_addr((uint32_t *)(&dma_cmd), sizeof(dma_cmd));
884 
885 	dw_i2c_dma_enable(context->base, 1);
886 
887 	/* Command is written for next read per request */
888 	config_and_enable_dma_channel(i2c_device, context->tx_dma_dev, context->tx_dma_handshake,
889 		context->tx_dma_chan, (uint32_t)&dma_cmd, dw_i2c_dr_address(context->base) + 1,
890 		num - 2, I2C_DMA_DIRECTION_RX_CMD);
891 
892 	/* data transfer */
893 	config_and_enable_dma_channel(i2c_device, context->rx_dma_dev, context->rx_dma_handshake,
894 		context->rx_dma_chan, dw_i2c_dr_address(context->base), (uint32_t)data, num,
895 		I2C_DMA_DIRECTION_RX);
896 
897 	return SEDI_DRIVER_OK;
898 }
899 
sedi_i2c_master_write_async(IN sedi_i2c_t i2c_device,IN uint32_t addr,IN uint8_t * data,IN uint32_t num,IN bool pending)900 int32_t sedi_i2c_master_write_async(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN uint8_t *data,
901 				    IN uint32_t num, IN bool pending)
902 {
903 	uint32_t irq = BSETS_INTR_SEND;
904 
905 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
906 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
907 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
908 	DBG_CHECK(0 != num, SEDI_DRIVER_ERROR_PARAMETER);
909 
910 	struct i2c_context *context = &contexts[i2c_device];
911 
912 	if (context->status.busy) {
913 		return SEDI_DRIVER_ERROR_BUSY;
914 	}
915 
916 	/* Clear all status first */
917 	dw_i2c_clear_interrupt(context->base);
918 	dw_i2c_config_addr(context->base, addr);
919 
920 	/* Set watermark */
921 	if (num < I2C_FIFO_DEFAULT_WATERMARK) {
922 		/* If less than half FIFO, just set watermark to transfer size
923 		 */
924 		dw_i2c_config_txfifo(context->base, num);
925 	} else {
926 		dw_i2c_config_txfifo(context->base, I2C_FIFO_DEFAULT_WATERMARK);
927 	}
928 
929 	/* Enable I2C */
930 	dw_i2c_enable(context->base);
931 
932 	/* Set internal state */
933 	context->status.busy = 1U;
934 	context->status.direction = 0U;
935 	/* Reset event to default */
936 	context->status.event = SEDI_I2C_EVENT_TRANSFER_NONE;
937 
938 	context->buf = (uint8_t *)data;
939 	context->buf_size = num;
940 	context->rx_cmd_index = 0;
941 	context->buf_index = 0;
942 	context->pending = pending;
943 
944 	/* FIFO fill */
945 	i2c_send(i2c_device);
946 	if (context->buf_index == num && !pending)
947 		irq &= ~SEDI_RBFVM(I2C, INTR_MASK, M_TX_EMPTY, DISABLED);
948 
949 	dw_i2c_irq_config(context->base, irq);
950 
951 	return SEDI_DRIVER_OK;
952 }
953 
sedi_i2c_master_read_async(IN sedi_i2c_t i2c_device,IN uint32_t addr,OUT uint8_t * data,IN uint32_t num,IN bool pending)954 int32_t sedi_i2c_master_read_async(IN sedi_i2c_t i2c_device, IN uint32_t addr, OUT uint8_t *data,
955 				   IN uint32_t num, IN bool pending)
956 {
957 	uint32_t irq = BSETS_INTR_RECV;
958 
959 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
960 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
961 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
962 	DBG_CHECK(0 != num, SEDI_DRIVER_ERROR_PARAMETER);
963 
964 	struct i2c_context *context = &contexts[i2c_device];
965 
966 	if (context->status.busy) {
967 		return SEDI_DRIVER_ERROR_BUSY;
968 	}
969 
970 	/* Clear all status first */
971 	dw_i2c_clear_interrupt(context->base);
972 	dw_i2c_config_addr(context->base, addr);
973 
974 	/* Set watermark, receive needs both tx and rx */
975 	if (num < I2C_FIFO_DEFAULT_WATERMARK) {
976 		/* If less than half FIFO, just set watermark to transfer size
977 		 */
978 		dw_i2c_config_rxfifo(context->base, num);
979 		dw_i2c_config_txfifo(context->base, 0);
980 	} else {
981 		dw_i2c_config_rxfifo(context->base, I2C_FIFO_DEFAULT_WATERMARK);
982 		dw_i2c_config_txfifo(context->base, I2C_FIFO_DEFAULT_WATERMARK);
983 	}
984 
985 	/* Enable I2C */
986 	dw_i2c_enable(context->base);
987 
988 	context->status.busy = 1U;
989 	context->status.direction = 1U;
990 	/* Reset event to default */
991 	context->status.event = SEDI_I2C_EVENT_TRANSFER_NONE;
992 
993 	context->buf = (uint8_t *)data;
994 	context->buf_size = num;
995 	context->buf_index = 0;
996 	context->rx_cmd_index = 0;
997 	context->pending = pending;
998 
999 	/* FIFO fill */
1000 	i2c_ask_data(i2c_device);
1001 	if (context->rx_cmd_index == num && !pending)
1002 		irq &= ~SEDI_RBFVM(I2C, INTR_MASK, M_TX_EMPTY, DISABLED);
1003 
1004 	dw_i2c_irq_config(context->base, irq);
1005 
1006 	return SEDI_DRIVER_OK;
1007 }
1008 
sedi_i2c_master_poll_write(IN sedi_i2c_t i2c_device,IN uint32_t addr,IN uint8_t * data,IN uint32_t num,IN bool pending)1009 int32_t sedi_i2c_master_poll_write(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN uint8_t *data,
1010 				   IN uint32_t num, IN bool pending)
1011 {
1012 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
1013 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
1014 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
1015 	DBG_CHECK(0 != num, SEDI_DRIVER_ERROR_PARAMETER);
1016 
1017 	int ret;
1018 	struct i2c_context *context = &contexts[i2c_device];
1019 
1020 	if (context->status.busy) {
1021 		return SEDI_DRIVER_ERROR_BUSY;
1022 	}
1023 
1024 	/* Clear all status first */
1025 	dw_i2c_clear_interrupt(context->base);
1026 	dw_i2c_config_addr(context->base, addr);
1027 
1028 	context->status.busy = 1U;
1029 	context->status.direction = 0U;
1030 	/* Reset event to default */
1031 	context->status.event = SEDI_I2C_EVENT_TRANSFER_NONE;
1032 
1033 	dw_i2c_enable(context->base);
1034 
1035 	ret = dw_i2c_poll_write(context->base, data, num, pending);
1036 
1037 	if (ret != 0) {
1038 		context->status.event = dw_i2c_abort_analysis(context->base);
1039 		dw_i2c_clear_interrupt(context->base);
1040 		dw_i2c_disable(context->base);
1041 	} else {
1042 		context->status.event = SEDI_I2C_EVENT_TRANSFER_DONE;
1043 	}
1044 	context->status.busy = 0U;
1045 	context->buf_index = num;
1046 
1047 	return (ret == 0) ? SEDI_DRIVER_OK : SEDI_DRIVER_ERROR;
1048 }
1049 
sedi_i2c_master_poll_read(IN sedi_i2c_t i2c_device,IN uint32_t addr,OUT uint8_t * data,IN uint32_t num,IN bool pending)1050 int32_t sedi_i2c_master_poll_read(IN sedi_i2c_t i2c_device, IN uint32_t addr, OUT uint8_t *data,
1051 				  IN uint32_t num, IN bool pending)
1052 {
1053 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
1054 	DBG_CHECK(0 != (addr & SEDI_RBFM(I2C, TAR, IC_TAR)), SEDI_DRIVER_ERROR_PARAMETER);
1055 	DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER);
1056 	DBG_CHECK(0 != num, SEDI_DRIVER_ERROR_PARAMETER);
1057 
1058 	int ret;
1059 	struct i2c_context *context = &contexts[i2c_device];
1060 
1061 	if (context->status.busy) {
1062 		return SEDI_DRIVER_ERROR_BUSY;
1063 	}
1064 
1065 	/* Clear all status first */
1066 	dw_i2c_clear_interrupt(context->base);
1067 	dw_i2c_config_addr(context->base, addr);
1068 
1069 	/* Enable I2C */
1070 	dw_i2c_enable(context->base);
1071 
1072 	context->status.busy = 1U;
1073 	context->status.direction = 1U;
1074 	/* Reset event to default */
1075 	context->status.event = SEDI_I2C_EVENT_TRANSFER_DONE;
1076 
1077 	ret = dw_i2c_poll_read(context->base, data, num, pending);
1078 
1079 	if (ret != 0) {
1080 		context->status.event = dw_i2c_abort_analysis(context->base);
1081 		dw_i2c_clear_interrupt(context->base);
1082 		dw_i2c_disable(context->base);
1083 	}
1084 	context->status.busy = 0U;
1085 	context->buf_index = num;
1086 
1087 	return (ret == 0) ? SEDI_DRIVER_OK : SEDI_DRIVER_ERROR;
1088 }
1089 
sedi_i2c_get_data_count(IN sedi_i2c_t i2c_device)1090 int32_t sedi_i2c_get_data_count(IN sedi_i2c_t i2c_device)
1091 {
1092 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
1093 
1094 	struct i2c_context *context = &contexts[i2c_device];
1095 
1096 	return context->buf_index;
1097 }
1098 
sedi_i2c_control(IN sedi_i2c_t i2c_device,IN uint32_t control,IN uint32_t arg)1099 int32_t sedi_i2c_control(IN sedi_i2c_t i2c_device, IN uint32_t control, IN uint32_t arg)
1100 {
1101 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
1102 
1103 	int ret = 0;
1104 	struct i2c_context *context = &contexts[i2c_device];
1105 
1106 	switch (control) {
1107 	case SEDI_I2C_BUS_SPEED:
1108 		if (arg == SEDI_I2C_BUS_SPEED_STANDARD) {
1109 			context->speed = I2C_SPEED_STANDARD;
1110 			context->clk_info = &(context->bus_info.std_clk);
1111 		} else if (arg == SEDI_I2C_BUS_SPEED_FAST) {
1112 			context->speed = I2C_SPEED_FAST;
1113 			context->clk_info = &(context->bus_info.fst_clk);
1114 		} else if (arg == SEDI_I2C_BUS_SPEED_FAST_PLUS) {
1115 			context->speed = I2C_SPEED_FAST_PLUS;
1116 			context->clk_info = &(context->bus_info.fsp_clk);
1117 		} else if (arg == SEDI_I2C_BUS_SPEED_HIGH) {
1118 			context->speed = I2C_SPEED_HIGH;
1119 			context->clk_info = &(context->bus_info.high_clk);
1120 		} else {
1121 			ret = SEDI_DRIVER_ERROR;
1122 		}
1123 		dw_i2c_disable(context->base);
1124 		dw_i2c_config_speed(context->base, context->speed,
1125 		       context->clk_info);
1126 		break;
1127 
1128 	/* force i2c enter IDLE mode */
1129 	case SEDI_I2C_ABORT_TRANSFER:
1130 		if (context->tx_dma_chan > SEDI_I2C_DMA_CHANNEL_UNUSED) {
1131 			sedi_dma_abort_transfer(context->tx_dma_dev,
1132 						context->tx_dma_chan);
1133 			context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
1134 		}
1135 		if (context->rx_dma_chan > SEDI_I2C_DMA_CHANNEL_UNUSED) {
1136 			sedi_dma_abort_transfer(context->rx_dma_dev,
1137 						context->rx_dma_chan);
1138 			context->rx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED;
1139 		}
1140 		dw_i2c_abort(context);
1141 		context->pending = 0;
1142 		context->status.busy = 0;
1143 		break;
1144 	case SEDI_I2C_SET_TX_MEMORY_TYPE:
1145 		context->tx_memory_type = arg;
1146 		break;
1147 	case SEDI_I2C_SET_RX_MEMORY_TYPE:
1148 		context->rx_memory_type = arg;
1149 		break;
1150 	default:
1151 		ret = SEDI_DRIVER_ERROR;
1152 		break;
1153 	}
1154 
1155 	if (ret != 0) {
1156 		return SEDI_DRIVER_ERROR;
1157 	}
1158 
1159 	return SEDI_DRIVER_OK;
1160 }
1161 
sedi_i2c_get_status(IN sedi_i2c_t i2c_device,sedi_i2c_status_t * status)1162 int sedi_i2c_get_status(IN sedi_i2c_t i2c_device, sedi_i2c_status_t *status)
1163 {
1164 	DBG_CHECK(i2c_device < SEDI_I2C_NUM, SEDI_DRIVER_ERROR_PARAMETER);
1165 	DBG_CHECK(NULL != status, SEDI_DRIVER_ERROR_PARAMETER);
1166 
1167 	struct i2c_context *context = &contexts[i2c_device];
1168 
1169 	*status = context->status;
1170 
1171 	return SEDI_DRIVER_OK;
1172 }
1173 
i2c_isr_recv(sedi_i2c_t i2c_device)1174 static void i2c_isr_recv(sedi_i2c_t i2c_device)
1175 {
1176 	struct i2c_context *context = &contexts[i2c_device];
1177 	sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base);
1178 	uint32_t data_remain;
1179 
1180 	/* Receive all data from FIFO */
1181 	uint32_t size = SEDI_PREG_RBFV_GET(I2C, RXFLR, RXFLR, &i2c->rxflr);
1182 
1183 	if (context->rx_cmd_index < size) {
1184 		uint32_t dummy;
1185 
1186 		while (size) {
1187 			dummy = i2c->data_cmd;
1188 			size--;
1189 		}
1190 		(void)dummy;
1191 
1192 		return;
1193 	}
1194 
1195 	while (size > 0) {
1196 		context->buf[context->buf_index] = SEDI_PREG_RBFV_GET(I2C,
1197 				DATA_CMD, DAT, &i2c->data_cmd);
1198 		context->buf_index++;
1199 		size--;
1200 	}
1201 
1202 	/* If need to change watermark */
1203 	data_remain = context->buf_size - context->buf_index;
1204 	if ((data_remain <= SEDI_PREG_RBFV_GET(I2C, RX_TL, RX_TL, &i2c->rx_tl)) &&
1205 			(data_remain != 0)) {
1206 		SEDI_PREG_RBF_SET(I2C, RX_TL, RX_TL, data_remain - 1, &i2c->rx_tl);
1207 	}
1208 }
1209 
i2c_isr_complete(sedi_i2c_t i2c_device,bool is_error)1210 static void i2c_isr_complete(sedi_i2c_t i2c_device, bool is_error)
1211 {
1212 	struct i2c_context *context = &contexts[i2c_device];
1213 	sedi_i2c_regs_t *regs = (void *)context->base;
1214 	uint32_t val;
1215 
1216 	dw_i2c_irq_config(context->base, 0);
1217 
1218 	dw_i2c_config_txfifo(context->base, 0);
1219 	dw_i2c_config_rxfifo(context->base, 0);
1220 
1221 	if (context->status.event == SEDI_I2C_EVENT_TRANSFER_NONE) {
1222 		if (is_error) {
1223 			context->status.event = dw_i2c_abort_analysis(context->base);
1224 		} else {
1225 			context->status.event = SEDI_I2C_EVENT_TRANSFER_DONE;
1226 		}
1227 	}
1228 
1229 	/* Flush FIFO */
1230 	if (context->status.event != SEDI_I2C_EVENT_TRANSFER_DONE) {
1231 		dw_i2c_disable(context->base);
1232 	}
1233 
1234 	context->pending = 0;
1235 	context->status.busy = 0;
1236 
1237 	/* Clear all interrupt, this will clear abort source register*/
1238 	val = regs->clr_intr;
1239 	dw_i2c_clear_interrupt(context->base);
1240 
1241 	if (context->cb_event) {
1242 		context->cb_event(context->status.event);
1243 	}
1244 	PARAM_UNUSED(val);
1245 }
1246 
sedi_i2c_isr_handler(IN sedi_i2c_t i2c_device)1247 void sedi_i2c_isr_handler(IN sedi_i2c_t i2c_device)
1248 {
1249 	struct i2c_context *context = &contexts[i2c_device];
1250 	sedi_i2c_regs_t *regs = (void *)context->base;
1251 	uint32_t stat, val;
1252 
1253 	/* Return if enter into isr unexpectedly */
1254 	if (context->status.busy == 0) {
1255 		return;
1256 	}
1257 
1258 	/* Get interrupt status */
1259 	stat = regs->intr_stat;
1260 
1261 	/* If error happened, go to end*/
1262 	if (stat & BSETS_INTR_ERROR) {
1263 		i2c_isr_complete(i2c_device, true);
1264 		return;
1265 	}
1266 
1267 	/* check if there is a entity in rx fifo */
1268 	if (SEDI_PREG_RBFV_IS_SET(I2C, INTR_STAT, R_RX_FULL, ACTIVE, &stat)) {
1269 		i2c_isr_recv(i2c_device);
1270 		/* For receive with no STOP, while all data received, ended */
1271 		if ((context->buf_index == context->buf_size) && (context->pending)) {
1272 			i2c_isr_complete(i2c_device, false);
1273 			return;
1274 		}
1275 	}
1276 
1277 	/* For transfer need STOP flag, use STOP as transfer end condition */
1278 	if ((SEDI_PREG_RBFV_IS_SET(I2C, INTR_STAT, R_STOP_DET, ACTIVE, &stat)) &&
1279 			(context->pending == 0)) {
1280 		/* Clear stop detect interrupt */
1281 		val = regs->clr_stop_det;
1282 		i2c_isr_complete(i2c_device, false);
1283 		return;
1284 	}
1285 	/* For send with no STOP, while TX FIFO empty, ended */
1286 	if ((context->pending) && (context->buf_index == context->buf_size) &&
1287 	    (SEDI_PREG_RBFV_IS_SET(I2C, INTR_STAT, R_TX_EMPTY, ACTIVE, &stat))) {
1288 		i2c_isr_complete(i2c_device, false);
1289 		return;
1290 	}
1291 
1292 	/* TX empty condition */
1293 	if (SEDI_PREG_RBFV_IS_SET(I2C, INTR_STAT, R_TX_EMPTY, ACTIVE, &stat)) {
1294 		/*If it is read operation, need to send cmd*/
1295 		if (context->status.direction == 1) {
1296 			i2c_ask_data(i2c_device);
1297 		} else {
1298 			i2c_send(i2c_device);
1299 		}
1300 	}
1301 	PARAM_UNUSED(val);
1302 }
1303