]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/base/opae_i2c.c
2 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2010-2019 Intel Corporation
6 #include "opae_osdep.h"
9 static int i2c_transfer(struct altera_i2c_dev
*dev
,
10 struct i2c_msg
*msg
, int num
)
14 for (ret
= 0, try = 0; try < I2C_XFER_RETRY
; try++) {
15 ret
= dev
->xfer(dev
, msg
, num
);
26 int i2c_read(struct altera_i2c_dev
*dev
, int flags
, unsigned int slave_addr
,
27 u32 offset
, u8
*buf
, u32 count
)
32 if (flags
& I2C_FLAG_ADDR16
)
33 msgbuf
[i
++] = offset
>> 8;
37 struct i2c_msg msg
[2] = {
55 return i2c_transfer(dev
, msg
, 2);
58 int i2c_write(struct altera_i2c_dev
*dev
, int flags
, unsigned int slave_addr
,
59 u32 offset
, u8
*buffer
, int len
)
69 buf
= opae_malloc(I2C_MAX_OFFSET_LEN
+ len
);
73 msg
.addr
= slave_addr
;
77 if (flags
& I2C_FLAG_ADDR16
)
78 msg
.buf
[i
++] = offset
>> 8;
80 msg
.buf
[i
++] = offset
;
81 opae_memcpy(&msg
.buf
[i
], buffer
, len
);
84 ret
= i2c_transfer(dev
, &msg
, 1);
90 int i2c_read8(struct altera_i2c_dev
*dev
, unsigned int slave_addr
, u32 offset
,
93 return i2c_read(dev
, 0, slave_addr
, offset
, buf
, count
);
96 int i2c_read16(struct altera_i2c_dev
*dev
, unsigned int slave_addr
, u32 offset
,
99 return i2c_read(dev
, I2C_FLAG_ADDR16
, slave_addr
, offset
,
103 int i2c_write8(struct altera_i2c_dev
*dev
, unsigned int slave_addr
, u32 offset
,
106 return i2c_write(dev
, 0, slave_addr
, offset
, buf
, count
);
109 int i2c_write16(struct altera_i2c_dev
*dev
, unsigned int slave_addr
, u32 offset
,
112 return i2c_write(dev
, I2C_FLAG_ADDR16
, slave_addr
, offset
,
116 static void i2c_indirect_write(struct altera_i2c_dev
*dev
, u32 reg
,
121 ctrl
= I2C_CTRL_W
| (reg
>> 2);
123 opae_writeq(value
& I2C_WRITE_DATA_MASK
, dev
->base
+ I2C_WRITE
);
124 opae_writeq(ctrl
, dev
->base
+ I2C_CTRL
);
127 static u32
i2c_indirect_read(struct altera_i2c_dev
*dev
, u32 reg
)
133 ctrl
= I2C_CTRL_R
| (reg
>> 2);
134 opae_writeq(ctrl
, dev
->base
+ I2C_CTRL
);
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
);
140 value
= tmp
& I2C_READ_DATA_MASK
;
145 static void altera_i2c_transfer(struct altera_i2c_dev
*dev
, u32 data
)
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
);
154 static void altera_i2c_disable(struct altera_i2c_dev
*dev
)
156 u32 val
= i2c_indirect_read(dev
, ALTERA_I2C_CTRL
);
158 i2c_indirect_write(dev
, ALTERA_I2C_CTRL
, val
&~ALTERA_I2C_CTRL_EN
);
161 static void altera_i2c_enable(struct altera_i2c_dev
*dev
)
163 u32 val
= i2c_indirect_read(dev
, ALTERA_I2C_CTRL
);
165 i2c_indirect_write(dev
, ALTERA_I2C_CTRL
, val
| ALTERA_I2C_CTRL_EN
);
168 static void altera_i2c_reset(struct altera_i2c_dev
*dev
)
170 altera_i2c_disable(dev
);
171 altera_i2c_enable(dev
);
174 static int altera_i2c_wait_core_idle(struct altera_i2c_dev
*dev
)
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");
190 static void altera_i2c_enable_interrupt(struct altera_i2c_dev
*dev
,
191 u32 mask
, bool enable
)
195 status
= i2c_indirect_read(dev
, ALTERA_I2C_ISER
);
197 dev
->isr_mask
= status
| mask
;
199 dev
->isr_mask
= status
&~mask
;
201 i2c_indirect_write(dev
, ALTERA_I2C_ISER
, dev
->isr_mask
);
204 static void altera_i2c_interrupt_clear(struct altera_i2c_dev
*dev
, u32 mask
)
208 int_en
= i2c_indirect_read(dev
, ALTERA_I2C_ISR
);
210 i2c_indirect_write(dev
, ALTERA_I2C_ISR
, int_en
| mask
);
213 static void altera_i2c_read_rx_fifo(struct altera_i2c_dev
*dev
)
218 rx_avail
= i2c_indirect_read(dev
, ALTERA_I2C_RX_FIFO_LVL
);
219 bytes
= min(rx_avail
, dev
->msg_len
);
221 while (bytes
-- > 0) {
222 *dev
->buf
++ = i2c_indirect_read(dev
, ALTERA_I2C_RX_DATA
);
224 altera_i2c_transfer(dev
, 0);
228 static void altera_i2c_stop(struct altera_i2c_dev
*dev
)
230 i2c_indirect_write(dev
, ALTERA_I2C_TFR_CMD
, ALTERA_I2C_TFR_CMD_STO
);
233 static int altera_i2c_fill_tx_fifo(struct altera_i2c_dev
*dev
)
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
;
244 while (bytes
-- > 0) {
245 altera_i2c_transfer(dev
, *dev
->buf
++);
252 static u8
i2c_8bit_addr_from_msg(const struct i2c_msg
*msg
)
254 return (msg
->addr
<< 1) | (msg
->flags
& I2C_M_RD
? 1 : 0);
257 static int altera_i2c_wait_complete(struct altera_i2c_dev
*dev
,
262 while (!((*status
= i2c_indirect_read(dev
, ALTERA_I2C_ISR
))
264 if (retry
++ > ALTERA_I2C_TIMEOUT_US
)
273 static bool altera_handle_i2c_status(struct altera_i2c_dev
*dev
, u32 status
)
275 bool read
, finish
= false;
278 read
= (dev
->msg
->flags
& I2C_M_RD
) != 0;
280 if (status
& ALTERA_I2C_ISR_ARB
) {
281 altera_i2c_interrupt_clear(dev
, ALTERA_I2C_ISR_ARB
);
282 dev
->msg_err
= -EAGAIN
;
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
);
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");
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
);
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
);
309 dev_err(dev
, "unexpected status:0x%x\n", status
);
310 altera_i2c_interrupt_clear(dev
, ALTERA_I2C_ALL_IRQ
);
314 ret
= altera_i2c_wait_core_idle(dev
);
316 dev_err(dev
, "message timeout\n");
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");
326 static bool altera_i2c_poll_status(struct altera_i2c_dev
*dev
)
333 if (altera_i2c_wait_complete(dev
, &status
)) {
334 dev_err(dev
, "altera i2c wait complete timeout, status=0x%x\n",
339 finish
= altera_handle_i2c_status(dev
, status
);
341 if (i
++ > I2C_XFER_RETRY
)
349 static int altera_i2c_xfer_msg(struct altera_i2c_dev
*dev
,
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
);
358 dev
->msg_len
= msg
->len
;
361 altera_i2c_enable(dev
);
363 /*make sure RX FIFO is emtry*/
365 i2c_indirect_read(dev
, ALTERA_I2C_RX_DATA
);
366 } while (i2c_indirect_read(dev
, ALTERA_I2C_RX_FIFO_LVL
));
368 i2c_indirect_write(dev
, ALTERA_I2C_TFR_CMD_RW_D
,
369 ALTERA_I2C_TFR_CMD_STA
| addr
);
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);
378 int_mask
|= ALTERA_I2C_ISR_TXRDY
;
379 altera_i2c_enable_interrupt(dev
, int_mask
, true);
380 altera_i2c_fill_tx_fifo(dev
);
383 finish
= altera_i2c_poll_status(dev
);
385 dev
->msg_err
= -ETIMEDOUT
;
386 dev_err(dev
, "%s: i2c transfer error\n", __func__
);
389 altera_i2c_enable_interrupt(dev
, int_mask
, false);
391 if (i2c_indirect_read(dev
, ALTERA_I2C_STATUS
) & ALTERA_I2C_STAT_CORE
)
392 dev_info(dev
, "core not idle...\n");
394 altera_i2c_disable(dev
);
399 static int altera_i2c_xfer(struct altera_i2c_dev
*dev
,
400 struct i2c_msg
*msg
, int num
)
405 for (i
= 0; i
< num
; i
++, msg
++) {
406 ret
= altera_i2c_xfer_msg(dev
, msg
);
414 static void altera_i2c_hardware_init(struct altera_i2c_dev
*dev
)
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
);
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;
428 tmp
|= ALTERA_I2C_CTRL_BSPEED
;
429 /*Fast mode SCL 33/66*/
430 t_high
= divisor
*1/3;
434 i2c_indirect_write(dev
, ALTERA_I2C_CTRL
, tmp
);
436 dev_info(dev
, "%s: rate=%uHz per_clk=%uMHz -> ratio=1:%u\n",
437 __func__
, dev
->bus_clk_rate
, clk_mhz
, divisor
);
440 altera_i2c_reset(dev
);
442 /*Set SCL high Time*/
443 i2c_indirect_write(dev
, ALTERA_I2C_SCL_HIGH
, t_high
);
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);
449 altera_i2c_enable_interrupt(dev
, ALTERA_I2C_ALL_IRQ
, false);
452 struct altera_i2c_dev
*altera_i2c_probe(void *base
)
454 struct altera_i2c_dev
*dev
;
456 dev
= opae_malloc(sizeof(*dev
));
460 dev
->base
= (u8
*)base
;
461 dev
->i2c_param
.info
= opae_readq(dev
->base
+ I2C_PARAM
);
463 if (dev
->i2c_param
.devid
!= 0xEE011) {
464 dev_err(dev
, "find a invalid i2c master\n");
468 dev
->fifo_size
= dev
->i2c_param
.fifo_depth
;
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;
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
;
480 altera_i2c_hardware_init(dev
);
485 int altera_i2c_remove(struct altera_i2c_dev
*dev
)
487 altera_i2c_disable(dev
);