Lines Matching +full:tclk +full:- +full:period
2 * (C) Copyright 2009-2010
5 * Portions Copyright (C) 2010 - 2016 Cavium, Inc.
22 #include "i2c-octeon-core.h"
33 i2c->int_disable(i2c); in octeon_i2c_isr()
34 wake_up(&i2c->queue); in octeon_i2c_isr()
45 * octeon_i2c_wait - wait for the IFLG to be set
58 if (i2c->broken_irq_mode) { in octeon_i2c_wait()
59 u64 end = get_jiffies_64() + i2c->adap.timeout; in octeon_i2c_wait()
65 return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT; in octeon_i2c_wait()
68 i2c->int_enable(i2c); in octeon_i2c_wait()
69 time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c), in octeon_i2c_wait()
70 i2c->adap.timeout); in octeon_i2c_wait()
71 i2c->int_disable(i2c); in octeon_i2c_wait()
73 if (i2c->broken_irq_check && !time_left && in octeon_i2c_wait()
75 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n"); in octeon_i2c_wait()
76 i2c->broken_irq_mode = true; in octeon_i2c_wait()
81 return -ETIMEDOUT; in octeon_i2c_wait()
88 return (__raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)) & SW_TWSI_V) == 0; in octeon_i2c_hlc_test_valid()
98 * Cleanup low-level state & enable high-level controller.
105 if (i2c->hlc_enabled) in octeon_i2c_hlc_enable()
107 i2c->hlc_enabled = true; in octeon_i2c_hlc_enable()
131 if (!i2c->hlc_enabled) in octeon_i2c_hlc_disable()
134 i2c->hlc_enabled = false; in octeon_i2c_hlc_disable()
142 if (i2c->block_enabled || !OCTEON_REG_BLOCK_CTL(i2c)) in octeon_i2c_block_enable()
145 i2c->block_enabled = true; in octeon_i2c_block_enable()
146 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_block_enable()
148 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_block_enable()
155 if (!i2c->block_enabled || !OCTEON_REG_BLOCK_CTL(i2c)) in octeon_i2c_block_disable()
158 i2c->block_enabled = false; in octeon_i2c_block_disable()
159 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_block_disable()
161 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_block_disable()
165 * octeon_i2c_hlc_wait - wait for an HLC operation to complete
168 * Returns: 0 on success, otherwise -ETIMEDOUT.
178 if (i2c->broken_irq_mode) { in octeon_i2c_hlc_wait()
179 u64 end = get_jiffies_64() + i2c->adap.timeout; in octeon_i2c_hlc_wait()
185 return octeon_i2c_hlc_test_valid(i2c) ? 0 : -ETIMEDOUT; in octeon_i2c_hlc_wait()
188 i2c->hlc_int_enable(i2c); in octeon_i2c_hlc_wait()
189 time_left = wait_event_timeout(i2c->queue, in octeon_i2c_hlc_wait()
191 i2c->adap.timeout); in octeon_i2c_hlc_wait()
192 i2c->hlc_int_disable(i2c); in octeon_i2c_hlc_wait()
196 if (i2c->broken_irq_check && !time_left && in octeon_i2c_hlc_wait()
198 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n"); in octeon_i2c_hlc_wait()
199 i2c->broken_irq_mode = true; in octeon_i2c_hlc_wait()
204 return -ETIMEDOUT; in octeon_i2c_hlc_wait()
217 if (i2c->hlc_enabled) in octeon_i2c_check_status()
218 stat = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_check_status()
231 /* ACK allowed on pre-terminal bytes only */ in octeon_i2c_check_status()
235 return -EIO; in octeon_i2c_check_status()
241 return -EIO; in octeon_i2c_check_status()
248 return -EAGAIN; in octeon_i2c_check_status()
255 return -EOPNOTSUPP; in octeon_i2c_check_status()
265 return -EOPNOTSUPP; in octeon_i2c_check_status()
269 return -EIO; in octeon_i2c_check_status()
273 return -ENXIO; in octeon_i2c_check_status()
276 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_check_status()
279 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_check_status()
280 return -EIO; in octeon_i2c_check_status()
282 dev_err(i2c->dev, "unhandled state: %d\n", stat); in octeon_i2c_check_status()
283 return -EIO; in octeon_i2c_check_status()
291 ret = i2c_recover_bus(&i2c->adap); in octeon_i2c_recovery()
293 /* recover failed, try hardware re-init */ in octeon_i2c_recovery()
299 * octeon_i2c_start - send START to the bus
325 return (ret) ? ret : -EAGAIN; in octeon_i2c_start()
335 * octeon_i2c_read - receive data from the bus via low-level controller
391 return -EPROTO; in octeon_i2c_read()
404 * octeon_i2c_write - send data to the bus via low-level controller
442 /* high-level-controller pure read of up to 8 bytes */
453 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_read()
457 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_read()
462 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_read()
466 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) in octeon_i2c_hlc_read()
470 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_read()
471 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_read()
479 /* high-level-controller pure write of up to 8 bytes */
490 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_write()
494 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) in octeon_i2c_hlc_write()
500 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_write()
502 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_write()
505 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_write()
510 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_write()
522 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_cmd_send()
552 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_read_cmd()
557 /* high-level-controller composite write+read, msg0=addr, msg1=data */
567 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_comp_read()
576 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_read()
580 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) in octeon_i2c_hlc_comp_read()
584 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_comp_read()
585 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_comp_read()
593 /* high-level-controller composite write+write, m[0]len<=2, m[1]len<=8 */
604 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_comp_write()
611 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) in octeon_i2c_hlc_comp_write()
615 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_comp_write()
620 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_comp_write()
626 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_write()
635 * octeon_i2c_hlc_block_comp_read - high-level-controller composite block read
655 /* Write (size - 1) into block control register */ in octeon_i2c_hlc_block_comp_read()
656 len = msgs[1].len - 1; in octeon_i2c_hlc_block_comp_read()
657 octeon_i2c_writeq_flush((u64)len, i2c->twsi_base + OCTEON_REG_BLOCK_CTL(i2c)); in octeon_i2c_hlc_block_comp_read()
668 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_block_comp_read()
676 i2c->twsi_base + OCTEON_REG_BLOCK_STS(i2c)); in octeon_i2c_hlc_block_comp_read()
678 /* Byte-swap FIFO data and copy into msg buffer */ in octeon_i2c_hlc_block_comp_read()
679 __be64 rd = cpu_to_be64(__raw_readq(i2c->twsi_base + OCTEON_REG_BLOCK_FIFO(i2c))); in octeon_i2c_hlc_block_comp_read()
681 memcpy(&msgs[1].buf[i], &rd, min(8, msgs[1].len - i)); in octeon_i2c_hlc_block_comp_read()
690 * octeon_i2c_hlc_block_comp_write - high-level-controller composite block write
710 /* Write (size - 1) into block control register */ in octeon_i2c_hlc_block_comp_write()
711 len = msgs[1].len - 1; in octeon_i2c_hlc_block_comp_write()
712 octeon_i2c_writeq_flush((u64)len, i2c->twsi_base + OCTEON_REG_BLOCK_CTL(i2c)); in octeon_i2c_hlc_block_comp_write()
723 i2c->twsi_base + OCTEON_REG_BLOCK_STS(i2c)); in octeon_i2c_hlc_block_comp_write()
728 memcpy(&buf, &msgs[1].buf[i], min(8, msgs[1].len - i)); in octeon_i2c_hlc_block_comp_write()
730 /* Byte-swap message data and write into FIFO */ in octeon_i2c_hlc_block_comp_write()
732 octeon_i2c_writeq_flush((u64)buf, i2c->twsi_base + OCTEON_REG_BLOCK_FIFO(i2c)); in octeon_i2c_hlc_block_comp_write()
735 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_block_comp_write()
742 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_block_comp_write()
754 * octeon_i2c_xfer - The driver's xfer function
766 if (IS_LS_FREQ(i2c->twsi_freq)) { in octeon_i2c_xfer()
801 /* zero-length messages are not supported */ in octeon_i2c_xfer()
802 if (!pmsg->len) { in octeon_i2c_xfer()
803 ret = -EOPNOTSUPP; in octeon_i2c_xfer()
811 if (pmsg->flags & I2C_M_RD) in octeon_i2c_xfer()
812 ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
813 &pmsg->len, pmsg->flags & I2C_M_RECV_LEN); in octeon_i2c_xfer()
815 ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
816 pmsg->len); in octeon_i2c_xfer()
826 int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; in octeon_i2c_set_clock() local
830 * to cover wider range of divisors, note thp = TCLK half period and in octeon_i2c_set_clock()
836 is_plat_otx2 = octeon_i2c_is_otx2(to_pci_dev(i2c->dev)); in octeon_i2c_set_clock()
841 if (!IS_LS_FREQ(i2c->twsi_freq)) in octeon_i2c_set_clock()
853 for (mdiv_idx = 15; mdiv_idx >= mdiv_min && delta_hz != 0; mdiv_idx--) { in octeon_i2c_set_clock()
858 tclk = i2c->twsi_freq * (mdiv_idx + 1) * ds; in octeon_i2c_set_clock()
859 tclk *= (1 << ndiv_idx); in octeon_i2c_set_clock()
861 thp_base = (i2c->sys_freq / tclk) - 2; in octeon_i2c_set_clock()
863 thp_base = (i2c->sys_freq / (tclk * 2)) - 1; in octeon_i2c_set_clock()
871 foscl = i2c->sys_freq / (thp_idx + 2); in octeon_i2c_set_clock()
873 foscl = i2c->sys_freq / in octeon_i2c_set_clock()
877 if (foscl > i2c->twsi_freq) in octeon_i2c_set_clock()
879 diff = abs(foscl - i2c->twsi_freq); in octeon_i2c_set_clock()
899 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_set_clock()
901 if (!IS_LS_FREQ(i2c->twsi_freq)) in octeon_i2c_set_clock()
905 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_set_clock()
917 for (tries = 10; tries && status != STAT_IDLE; tries--) { in octeon_i2c_init_lowlevel()
925 dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", in octeon_i2c_init_lowlevel()
927 return -EIO; in octeon_i2c_init_lowlevel()