]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/base/opae_i2c.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / raw / ifpga_rawdev / base / opae_i2c.c
1
2 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2010-2019 Intel Corporation
4 */
5
6 #include "opae_osdep.h"
7 #include "opae_i2c.h"
8
9 static int i2c_transfer(struct altera_i2c_dev *dev,
10 struct i2c_msg *msg, int num)
11 {
12 int ret, try;
13
14 for (ret = 0, try = 0; try < I2C_XFER_RETRY; try++) {
15 ret = dev->xfer(dev, msg, num);
16 if (ret != -EAGAIN)
17 break;
18 }
19
20 return ret;
21 }
22
23 /**
24 * i2c read function
25 */
26 int i2c_read(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
27 u32 offset, u8 *buf, u32 count)
28 {
29 u8 msgbuf[2];
30 int i = 0;
31
32 if (flags & I2C_FLAG_ADDR16)
33 msgbuf[i++] = offset >> 8;
34
35 msgbuf[i++] = offset;
36
37 struct i2c_msg msg[2] = {
38 {
39 .addr = slave_addr,
40 .flags = 0,
41 .len = i,
42 .buf = msgbuf,
43 },
44 {
45 .addr = slave_addr,
46 .flags = I2C_M_RD,
47 .len = count,
48 .buf = buf,
49 },
50 };
51
52 if (!dev->xfer)
53 return -ENODEV;
54
55 return i2c_transfer(dev, msg, 2);
56 }
57
58 int i2c_write(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
59 u32 offset, u8 *buffer, int len)
60 {
61 struct i2c_msg msg;
62 u8 *buf;
63 int ret;
64 int i = 0;
65
66 if (!dev->xfer)
67 return -ENODEV;
68
69 buf = opae_malloc(I2C_MAX_OFFSET_LEN + len);
70 if (!buf)
71 return -ENOMEM;
72
73 msg.addr = slave_addr;
74 msg.flags = 0;
75 msg.buf = buf;
76
77 if (flags & I2C_FLAG_ADDR16)
78 msg.buf[i++] = offset >> 8;
79
80 msg.buf[i++] = offset;
81 opae_memcpy(&msg.buf[i], buffer, len);
82 msg.len = i + len;
83
84 ret = i2c_transfer(dev, &msg, 1);
85
86 opae_free(buf);
87 return ret;
88 }
89
90 int i2c_read8(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
91 u8 *buf, u32 count)
92 {
93 return i2c_read(dev, 0, slave_addr, offset, buf, count);
94 }
95
96 int i2c_read16(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
97 u8 *buf, u32 count)
98 {
99 return i2c_read(dev, I2C_FLAG_ADDR16, slave_addr, offset,
100 buf, count);
101 }
102
103 int i2c_write8(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
104 u8 *buf, u32 count)
105 {
106 return i2c_write(dev, 0, slave_addr, offset, buf, count);
107 }
108
109 int i2c_write16(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
110 u8 *buf, u32 count)
111 {
112 return i2c_write(dev, I2C_FLAG_ADDR16, slave_addr, offset,
113 buf, count);
114 }
115
116 static void i2c_indirect_write(struct altera_i2c_dev *dev, u32 reg,
117 u32 value)
118 {
119 u64 ctrl;
120
121 ctrl = I2C_CTRL_W | (reg >> 2);
122
123 opae_writeq(value & I2C_WRITE_DATA_MASK, dev->base + I2C_WRITE);
124 opae_writeq(ctrl, dev->base + I2C_CTRL);
125 }
126
127 static u32 i2c_indirect_read(struct altera_i2c_dev *dev, u32 reg)
128 {
129 u64 tmp;
130 u64 ctrl;
131 u32 value;
132
133 ctrl = I2C_CTRL_R | (reg >> 2);
134 opae_writeq(ctrl, dev->base + I2C_CTRL);
135
136 /* FIXME: Read one more time to avoid HW timing issue. */
137 tmp = opae_readq(dev->base + I2C_READ);
138 tmp = opae_readq(dev->base + I2C_READ);
139
140 value = tmp & I2C_READ_DATA_MASK;
141
142 return value;
143 }
144
145 static void altera_i2c_transfer(struct altera_i2c_dev *dev, u32 data)
146 {
147 /*send STOP on last byte*/
148 if (dev->msg_len == 1)
149 data |= ALTERA_I2C_TFR_CMD_STO;
150 if (dev->msg_len > 0)
151 i2c_indirect_write(dev, ALTERA_I2C_TFR_CMD, data);
152 }
153
154 static void altera_i2c_disable(struct altera_i2c_dev *dev)
155 {
156 u32 val = i2c_indirect_read(dev, ALTERA_I2C_CTRL);
157
158 i2c_indirect_write(dev, ALTERA_I2C_CTRL, val&~ALTERA_I2C_CTRL_EN);
159 }
160
161 static void altera_i2c_enable(struct altera_i2c_dev *dev)
162 {
163 u32 val = i2c_indirect_read(dev, ALTERA_I2C_CTRL);
164
165 i2c_indirect_write(dev, ALTERA_I2C_CTRL, val | ALTERA_I2C_CTRL_EN);
166 }
167
168 static void altera_i2c_reset(struct altera_i2c_dev *dev)
169 {
170 altera_i2c_disable(dev);
171 altera_i2c_enable(dev);
172 }
173
174 static int altera_i2c_wait_core_idle(struct altera_i2c_dev *dev)
175 {
176 int retry = 0;
177
178 while (i2c_indirect_read(dev, ALTERA_I2C_STATUS)
179 & ALTERA_I2C_STAT_CORE) {
180 if (retry++ > ALTERA_I2C_TIMEOUT_US) {
181 dev_err(dev, "timeout: Core Status not IDLE...\n");
182 return -EBUSY;
183 }
184 udelay(1);
185 }
186
187 return 0;
188 }
189
190 static void altera_i2c_enable_interrupt(struct altera_i2c_dev *dev,
191 u32 mask, bool enable)
192 {
193 u32 status;
194
195 status = i2c_indirect_read(dev, ALTERA_I2C_ISER);
196 if (enable)
197 dev->isr_mask = status | mask;
198 else
199 dev->isr_mask = status&~mask;
200
201 i2c_indirect_write(dev, ALTERA_I2C_ISER, dev->isr_mask);
202 }
203
204 static void altera_i2c_interrupt_clear(struct altera_i2c_dev *dev, u32 mask)
205 {
206 u32 int_en;
207
208 int_en = i2c_indirect_read(dev, ALTERA_I2C_ISR);
209
210 i2c_indirect_write(dev, ALTERA_I2C_ISR, int_en | mask);
211 }
212
213 static void altera_i2c_read_rx_fifo(struct altera_i2c_dev *dev)
214 {
215 size_t rx_avail;
216 size_t bytes;
217
218 rx_avail = i2c_indirect_read(dev, ALTERA_I2C_RX_FIFO_LVL);
219 bytes = min(rx_avail, dev->msg_len);
220
221 while (bytes-- > 0) {
222 *dev->buf++ = i2c_indirect_read(dev, ALTERA_I2C_RX_DATA);
223 dev->msg_len--;
224 altera_i2c_transfer(dev, 0);
225 }
226 }
227
228 static void altera_i2c_stop(struct altera_i2c_dev *dev)
229 {
230 i2c_indirect_write(dev, ALTERA_I2C_TFR_CMD, ALTERA_I2C_TFR_CMD_STO);
231 }
232
233 static int altera_i2c_fill_tx_fifo(struct altera_i2c_dev *dev)
234 {
235 size_t tx_avail;
236 int bytes;
237 int ret;
238
239 tx_avail = dev->fifo_size -
240 i2c_indirect_read(dev, ALTERA_I2C_TC_FIFO_LVL);
241 bytes = min(tx_avail, dev->msg_len);
242 ret = dev->msg_len - bytes;
243
244 while (bytes-- > 0) {
245 altera_i2c_transfer(dev, *dev->buf++);
246 dev->msg_len--;
247 }
248
249 return ret;
250 }
251
252 static u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
253 {
254 return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
255 }
256
257 static int altera_i2c_wait_complete(struct altera_i2c_dev *dev,
258 u32 *status)
259 {
260 int retry = 0;
261
262 while (!((*status = i2c_indirect_read(dev, ALTERA_I2C_ISR))
263 & dev->isr_mask)) {
264 if (retry++ > ALTERA_I2C_TIMEOUT_US)
265 return -EBUSY;
266
267 udelay(1000);
268 }
269
270 return 0;
271 }
272
273 static bool altera_handle_i2c_status(struct altera_i2c_dev *dev, u32 status)
274 {
275 bool read, finish = false;
276 int ret;
277
278 read = (dev->msg->flags & I2C_M_RD) != 0;
279
280 if (status & ALTERA_I2C_ISR_ARB) {
281 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ISR_ARB);
282 dev->msg_err = -EAGAIN;
283 finish = true;
284 } else if (status & ALTERA_I2C_ISR_NACK) {
285 dev_debug(dev, "could not get ACK\n");
286 dev->msg_err = -ENXIO;
287 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ISR_NACK);
288 altera_i2c_stop(dev);
289 finish = true;
290 } else if (read && (status & ALTERA_I2C_ISR_RXOF)) {
291 /* RX FIFO Overflow */
292 altera_i2c_read_rx_fifo(dev);
293 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ISER_RXOF_EN);
294 altera_i2c_stop(dev);
295 dev_err(dev, "error: RX FIFO overflow\n");
296 finish = true;
297 } else if (read && (status & ALTERA_I2C_ISR_RXRDY)) {
298 altera_i2c_read_rx_fifo(dev);
299 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ISR_RXRDY);
300 if (!dev->msg_len)
301 finish = true;
302 } else if (!read && (status & ALTERA_I2C_ISR_TXRDY)) {
303 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ISR_TXRDY);
304 if (dev->msg_len > 0)
305 altera_i2c_fill_tx_fifo(dev);
306 else
307 finish = true;
308 } else {
309 dev_err(dev, "unexpected status:0x%x\n", status);
310 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ALL_IRQ);
311 }
312
313 if (finish) {
314 ret = altera_i2c_wait_core_idle(dev);
315 if (ret)
316 dev_err(dev, "message timeout\n");
317
318 altera_i2c_enable_interrupt(dev, ALTERA_I2C_ALL_IRQ, false);
319 altera_i2c_interrupt_clear(dev, ALTERA_I2C_ALL_IRQ);
320 dev_debug(dev, "message done\n");
321 }
322
323 return finish;
324 }
325
326 static bool altera_i2c_poll_status(struct altera_i2c_dev *dev)
327 {
328 u32 status;
329 bool finish = false;
330 int i = 0;
331
332 do {
333 if (altera_i2c_wait_complete(dev, &status)) {
334 dev_err(dev, "altera i2c wait complete timeout, status=0x%x\n",
335 status);
336 return -EBUSY;
337 }
338
339 finish = altera_handle_i2c_status(dev, status);
340
341 if (i++ > I2C_XFER_RETRY)
342 break;
343
344 } while (!finish);
345
346 return finish;
347 }
348
349 static int altera_i2c_xfer_msg(struct altera_i2c_dev *dev,
350 struct i2c_msg *msg)
351 {
352 u32 int_mask = ALTERA_I2C_ISR_RXOF |
353 ALTERA_I2C_ISR_ARB | ALTERA_I2C_ISR_NACK;
354 u8 addr = i2c_8bit_addr_from_msg(msg);
355 bool finish;
356
357 dev->msg = msg;
358 dev->msg_len = msg->len;
359 dev->buf = msg->buf;
360 dev->msg_err = 0;
361 altera_i2c_enable(dev);
362
363 /*make sure RX FIFO is emtry*/
364 do {
365 i2c_indirect_read(dev, ALTERA_I2C_RX_DATA);
366 } while (i2c_indirect_read(dev, ALTERA_I2C_RX_FIFO_LVL));
367
368 i2c_indirect_write(dev, ALTERA_I2C_TFR_CMD_RW_D,
369 ALTERA_I2C_TFR_CMD_STA | addr);
370
371 /*enable irq*/
372 if (msg->flags & I2C_M_RD) {
373 int_mask |= ALTERA_I2C_ISR_RXOF | ALTERA_I2C_ISR_RXRDY;
374 /* in polling mode, we should set this ISR register? */
375 altera_i2c_enable_interrupt(dev, int_mask, true);
376 altera_i2c_transfer(dev, 0);
377 } else {
378 int_mask |= ALTERA_I2C_ISR_TXRDY;
379 altera_i2c_enable_interrupt(dev, int_mask, true);
380 altera_i2c_fill_tx_fifo(dev);
381 }
382
383 finish = altera_i2c_poll_status(dev);
384 if (!finish) {
385 dev->msg_err = -ETIMEDOUT;
386 dev_err(dev, "%s: i2c transfer error\n", __func__);
387 }
388
389 altera_i2c_enable_interrupt(dev, int_mask, false);
390
391 if (i2c_indirect_read(dev, ALTERA_I2C_STATUS) & ALTERA_I2C_STAT_CORE)
392 dev_info(dev, "core not idle...\n");
393
394 altera_i2c_disable(dev);
395
396 return dev->msg_err;
397 }
398
399 static int altera_i2c_xfer(struct altera_i2c_dev *dev,
400 struct i2c_msg *msg, int num)
401 {
402 int ret = 0;
403 int i;
404
405 for (i = 0; i < num; i++, msg++) {
406 ret = altera_i2c_xfer_msg(dev, msg);
407 if (ret)
408 break;
409 }
410
411 return ret;
412 }
413
414 static void altera_i2c_hardware_init(struct altera_i2c_dev *dev)
415 {
416 u32 divisor = dev->i2c_clk / dev->bus_clk_rate;
417 u32 clk_mhz = dev->i2c_clk / 1000000;
418 u32 tmp = (ALTERA_I2C_THRESHOLD << ALTERA_I2C_CTRL_RXT_SHFT) |
419 (ALTERA_I2C_THRESHOLD << ALTERA_I2C_CTRL_TCT_SHFT);
420 u32 t_high, t_low;
421
422 if (dev->bus_clk_rate <= 100000) {
423 tmp &= ~ALTERA_I2C_CTRL_BSPEED;
424 /*standard mode SCL 50/50*/
425 t_high = divisor*1/2;
426 t_low = divisor*1/2;
427 } else {
428 tmp |= ALTERA_I2C_CTRL_BSPEED;
429 /*Fast mode SCL 33/66*/
430 t_high = divisor*1/3;
431 t_low = divisor*2/3;
432 }
433
434 i2c_indirect_write(dev, ALTERA_I2C_CTRL, tmp);
435
436 dev_info(dev, "%s: rate=%uHz per_clk=%uMHz -> ratio=1:%u\n",
437 __func__, dev->bus_clk_rate, clk_mhz, divisor);
438
439 /*reset the i2c*/
440 altera_i2c_reset(dev);
441
442 /*Set SCL high Time*/
443 i2c_indirect_write(dev, ALTERA_I2C_SCL_HIGH, t_high);
444 /*Set SCL low time*/
445 i2c_indirect_write(dev, ALTERA_I2C_SCL_LOW, t_low);
446 /*Set SDA Hold time, 300ms*/
447 i2c_indirect_write(dev, ALTERA_I2C_SDA_HOLD, (300*clk_mhz)/1000);
448
449 altera_i2c_enable_interrupt(dev, ALTERA_I2C_ALL_IRQ, false);
450 }
451
452 struct altera_i2c_dev *altera_i2c_probe(void *base)
453 {
454 struct altera_i2c_dev *dev;
455
456 dev = opae_malloc(sizeof(*dev));
457 if (!dev)
458 return NULL;
459
460 dev->base = (u8 *)base;
461 dev->i2c_param.info = opae_readq(dev->base + I2C_PARAM);
462
463 if (dev->i2c_param.devid != 0xEE011) {
464 dev_err(dev, "find a invalid i2c master\n");
465 return NULL;
466 }
467
468 dev->fifo_size = dev->i2c_param.fifo_depth;
469
470 if (dev->i2c_param.max_req == ALTERA_I2C_100KHZ)
471 dev->bus_clk_rate = 100000;
472 else if (dev->i2c_param.max_req == ALTERA_I2C_400KHZ)
473 /* i2c bus clk 400KHz*/
474 dev->bus_clk_rate = 400000;
475
476 /* i2c input clock for vista creek is 100MHz */
477 dev->i2c_clk = dev->i2c_param.ref_clk * 1000000;
478 dev->xfer = altera_i2c_xfer;
479
480 altera_i2c_hardware_init(dev);
481
482 return dev;
483 }
484
485 int altera_i2c_remove(struct altera_i2c_dev *dev)
486 {
487 altera_i2c_disable(dev);
488
489 return 0;
490 }