// SPDX-License-Identifier: GPL-2.0-only /* * I2C adapter for the IMG Serial Control Bus (SCB) IP block. * * Copyright (C) 2009, 2010, 2012, 2014 Imagination Technologies Ltd. * * There are three ways that this I2C controller can be driven: * * - Raw control of the SDA and SCK signals. * * This corresponds to MODE_RAW, which takes control of the signals * directly for a certain number of clock cycles (the INT_TIMING * interrupt can be used for timing). * * - Atomic commands. A low level I2C symbol (such as generate * start/stop/ack/nack bit, generate byte, receive byte, and receive * ACK) is given to the hardware, with detection of completion by bits * in the LINESTAT register. * * This mode of operation is used by MODE_ATOMIC, which uses an I2C * state machine in the interrupt handler to compose/react to I2C * transactions using atomic mode commands, and also by MODE_SEQUENCE, * which emits a simple fixed sequence of atomic mode commands. * * Due to software control, the use of atomic commands usually results * in suboptimal use of the bus, with gaps between the I2C symbols while * the driver decides what to do next. * * - Automatic mode. A bus address, and whether to read/write is * specified, and the hardware takes care of the I2C state machine, * using a FIFO to send/receive bytes of data to an I2C slave. The * driver just has to keep the FIFO drained or filled in response to the * appropriate FIFO interrupts. * * This corresponds to MODE_AUTOMATIC, which manages the FIFOs and deals * with control of repeated start bits between I2C messages. * * Use of automatic mode and the FIFO can make much more efficient use * of the bus compared to individual atomic commands, with potentially * no wasted time between I2C symbols or I2C messages. * * In most cases MODE_AUTOMATIC is used, however if any of the messages in * a transaction are zero byte writes (e.g. used by i2cdetect for probing * the bus), MODE_ATOMIC must be used since automatic mode is normally * started by the writing of data into the FIFO. * * The other modes are used in specific circumstances where MODE_ATOMIC and * MODE_AUTOMATIC aren't appropriate. MODE_RAW is used to implement a bus * recovery routine. MODE_SEQUENCE is used to reset the bus and make sure * it is in a sane state. * * Notice that the driver implements a timer-based timeout mechanism. * The reason for this mechanism is to reduce the number of interrupts * received in automatic mode. * * The driver would get a slave event and transaction done interrupts for * each atomic mode command that gets completed. However, these events are * not needed in automatic mode, becase those atomic mode commands are * managed automatically by the hardware. * * In practice, normal I2C transactions will be complete well before you * get the timer interrupt, as the timer is re-scheduled during FIFO * maintenance and disabled after the transaction is complete. * * In this way normal automatic mode operation isn't impacted by * unnecessary interrupts, but the exceptional abort condition can still be * detected (with a slight delay).
*/
/* * Worst incs are 1 (inaccurate) and 16*256 (irregular). * So a sensible inc is the logarithmic mean: 64 (2^6), which is * in the middle of the valid range (0-127).
*/ #define SCB_OPT_INC 64
/* Setup the clock enable filtering for 25 ns */ #define SCB_FILT_GLITCH 25
/* * Bits to return from interrupt handler functions for different modes. * This delays completion until we've finished with the registers, so that the * function waiting for completion can safely disable the clock to save power.
*/ #define ISR_COMPLETE_M BIT(31) #define ISR_FATAL_M BIT(30) #define ISR_WAITSTOP BIT(29) #define ISR_STATUS_M 0x0000ffff /* contains +ve errno */ #define ISR_COMPLETE(err) (ISR_COMPLETE_M | (ISR_STATUS_M & (err))) #define ISR_FATAL(err) (ISR_COMPLETE(err) | ISR_FATAL_M)
/* * The scb core clock is used to get the input frequency, and to disable * it after every set of transactions to save some power.
*/ struct clk *scb_clk, *sys_clk; unsignedint bitrate; bool need_wr_rd_fence;
/* state */ struct completion msg_complete;
spinlock_t lock; /* lock before doing anything with the state */ struct i2c_msg msg;
/* After the last transaction, wait for a stop bit */ bool last_msg; int msg_status;
enum img_i2c_mode mode;
u32 int_enable; /* depends on mode */
u32 line_status; /* line status over command */
/* * To avoid slave event interrupts in automatic mode, use a timer to * poll the abort condition if we don't get an interrupt for too long.
*/ struct timer_list check_timer; bool t_halt;
/* atomic mode state */ bool at_t_done; bool at_slave_event; int at_cur_cmd;
u8 at_cur_data;
/* Sequence: either reset or stop. See img_i2c_sequence. */
u8 *seq;
/* * The code to read from the master read fifo, and write to the master * write fifo, checks a bit in an SCB register before every byte to * ensure that the fifo is not full (write fifo) or empty (read fifo). * Due to clock domain crossing inside the SCB block the updated value * of this bit is only visible after 2 cycles. * * The scb_wr_rd_fence() function does 2 dummy writes (to the read-only * revision register), and it's called after reading from or writing to the * fifos to ensure that subsequent reads of the fifo status bits do not read * stale values.
*/ staticvoid img_i2c_wr_rd_fence(struct img_i2c *i2c)
{ if (i2c->need_wr_rd_fence) {
img_i2c_writel(i2c, SCB_CORE_REV_REG, 0);
img_i2c_writel(i2c, SCB_CORE_REV_REG, 0);
}
}
/* Send a single atomic mode command to the hardware */ staticvoid img_i2c_atomic_op(struct img_i2c *i2c, int cmd, u8 data)
{
i2c->at_cur_cmd = cmd;
i2c->at_cur_data = data;
/* work around lack of data setup time when generating data */ if (cmd == CMD_GEN_DATA && i2c->mode == MODE_ATOMIC) {
u32 line_status = img_i2c_readl(i2c, SCB_STATUS_REG);
if (line_status & LINESTAT_SDAT_LINE_STATUS && !(data & 0x80)) { /* hold the data line down for a moment */
img_i2c_switch_mode(i2c, MODE_RAW);
img_i2c_raw_op(i2c); return;
}
}
/* * Enable or release transaction halt for control of repeated starts. * In version 3.3 of the IP when transaction halt is set, an interrupt * will be generated after each byte of a transfer instead of after * every transfer but before the stop bit. * Due to this behaviour we have to be careful that every time we * release the transaction halt we have to re-enable it straight away * so that we only process a single byte, not doing so will result in * all remaining bytes been processed and a stop bit being issued, * which will prevent us having a repeated start.
*/ staticvoid img_i2c_transaction_halt(struct img_i2c *i2c, bool t_halt)
{
u32 val;
if (i2c->t_halt == t_halt) return;
i2c->t_halt = t_halt;
val = img_i2c_readl(i2c, SCB_CONTROL_REG); if (t_halt)
val |= SCB_CONTROL_TRANSACTION_HALT; else
val &= ~SCB_CONTROL_TRANSACTION_HALT;
img_i2c_writel(i2c, SCB_CONTROL_REG, val);
}
/* Drain data from the FIFO into the buffer (automatic mode) */ staticvoid img_i2c_read_fifo(struct img_i2c *i2c)
{ while (i2c->msg.len) {
u32 fifo_status;
u8 data;
img_i2c_wr_rd_fence(i2c);
fifo_status = img_i2c_readl(i2c, SCB_FIFO_STATUS_REG); if (fifo_status & FIFO_READ_EMPTY) break;
data = img_i2c_readl(i2c, SCB_READ_DATA_REG);
*i2c->msg.buf = data;
/* Fill the FIFO with data from the buffer (automatic mode) */ staticvoid img_i2c_write_fifo(struct img_i2c *i2c)
{ while (i2c->msg.len) {
u32 fifo_status;
img_i2c_wr_rd_fence(i2c);
fifo_status = img_i2c_readl(i2c, SCB_FIFO_STATUS_REG); if (fifo_status & FIFO_WRITE_FULL) break;
/* img_i2c_write_fifo() may modify int_enable */
img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable);
}
/* * Indicate that the transaction is complete. This is called from the * ISR to wake up the waiting thread, after which the ISR must not * access any more SCB registers.
*/ staticvoid img_i2c_complete_transaction(struct img_i2c *i2c, int status)
{
img_i2c_switch_mode(i2c, MODE_INACTIVE); if (status) {
i2c->msg_status = status;
img_i2c_transaction_halt(i2c, false);
}
complete(&i2c->msg_complete);
}
staticunsignedint img_i2c_raw_atomic_delay_handler(struct img_i2c *i2c,
u32 int_status, u32 line_status)
{ /* Stay in raw mode for this, so we don't just loop infinitely */
img_i2c_atomic_op(i2c, i2c->at_cur_cmd, i2c->at_cur_data);
img_i2c_switch_mode(i2c, MODE_ATOMIC); return 0;
}
if (int_status & INT_SLAVE_EVENT)
i2c->at_slave_event = true; if (int_status & INT_TRANSACTION_DONE)
i2c->at_t_done = true;
if (!i2c->at_slave_event || !i2c->at_t_done) return 0;
/* wait if no continue bits are set */ if (i2c->at_cur_cmd >= 0 &&
i2c->at_cur_cmd < ARRAY_SIZE(continue_bits)) { unsignedint cont_bits = continue_bits[i2c->at_cur_cmd];
if (cont_bits) {
cont_bits |= LINESTAT_ABORT_DET; if (!(i2c->line_status & cont_bits)) return 0;
}
}
/* follow the sequence of commands in i2c->seq */
next_cmd = *i2c->seq; /* stop on a nil */ if (!next_cmd) {
img_i2c_writel(i2c, SCB_OVERRIDE_REG, 0); return ISR_COMPLETE(0);
} /* when generating data, the next byte is the data */ if (next_cmd == CMD_GEN_DATA) {
++i2c->seq;
next_data = *i2c->seq;
}
++i2c->seq;
img_i2c_atomic_op(i2c, next_cmd, next_data);
next_atomic_cmd: if (next_cmd != -1) { /* don't actually stop unless we're the last transaction */ if (next_cmd == CMD_GEN_STOP && !i2c->msg_status &&
!i2c->last_msg) return ISR_COMPLETE(0);
img_i2c_atomic_op(i2c, next_cmd, next_data);
} return 0;
}
/* * Timer function to check if something has gone wrong in automatic mode (so we * don't have to handle so many interrupts just to catch an exception).
*/ staticvoid img_i2c_check_timer(struct timer_list *t)
{ struct img_i2c *i2c = timer_container_of(i2c, t, check_timer); unsignedlong flags; unsignedint line_status;
if (line_status & LINESTAT_ABORT_DET) {
dev_dbg(i2c->adap.dev.parent, "abort condition detected\n"); /* empty the read fifo */ if ((i2c->msg.flags & I2C_M_RD) &&
(int_status & INT_FIFO_FULL_FILLING))
img_i2c_read_fifo(i2c); /* use atomic mode and try to force a stop bit */
i2c->msg_status = -EIO;
img_i2c_stop_start(i2c); return 0;
}
/* Enable transaction halt on start bit */ if (!i2c->last_msg && line_status & LINESTAT_START_BIT_DET) {
img_i2c_transaction_halt(i2c, !i2c->last_msg); /* we're no longer interested in the slave event */
i2c->int_enable &= ~INT_SLAVE_EVENT;
}
if (int_status & INT_STOP_DETECTED) { /* Drain remaining data in FIFO and complete transaction */ if (i2c->msg.flags & I2C_M_RD)
img_i2c_read_fifo(i2c); return ISR_COMPLETE(0);
}
if (i2c->msg.flags & I2C_M_RD) { if (int_status & (INT_FIFO_FULL_FILLING | INT_MASTER_HALTED)) {
img_i2c_read_fifo(i2c); if (i2c->msg.len == 0) return ISR_WAITSTOP;
}
} else { if (int_status & (INT_FIFO_EMPTY | INT_MASTER_HALTED)) { if ((int_status & INT_FIFO_EMPTY) &&
i2c->msg.len == 0) return ISR_WAITSTOP;
img_i2c_write_fifo(i2c);
}
} if (int_status & INT_MASTER_HALTED) { /* * Release and then enable transaction halt, to * allow only a single byte to proceed.
*/
img_i2c_transaction_halt(i2c, false);
img_i2c_transaction_halt(i2c, !i2c->last_msg);
}
/* * Read line status and clear it until it actually is clear. We have * to be careful not to lose any line status bits that get latched.
*/
line_status = img_i2c_readl(i2c, SCB_STATUS_REG); if (line_status & LINESTAT_LATCHED) {
img_i2c_writel(i2c, SCB_CLEAR_REG,
(line_status & LINESTAT_LATCHED)
>> LINESTAT_CLEAR_SHIFT);
img_i2c_wr_rd_fence(i2c);
}
spin_lock(&i2c->lock);
/* Keep track of line status bits received */
i2c->line_status &= ~LINESTAT_INPUT_DATA;
i2c->line_status |= line_status;
/* * Certain interrupts indicate that sclk low timeout is not * a problem. If any of these are set, just continue.
*/ if ((int_status & INT_SCLK_LOW_TIMEOUT) &&
!(int_status & (INT_SLAVE_EVENT |
INT_FIFO_EMPTY |
INT_FIFO_FULL))) {
dev_crit(i2c->adap.dev.parent, "fatal: clock low timeout occurred %s addr 0x%02x\n",
(i2c->msg.flags & I2C_M_RD) ? "reading" : "writing",
i2c->msg.addr);
hret = ISR_FATAL(EIO); goto out;
}
out: if (hret & ISR_WAITSTOP) { /* * Only wait for stop on last message. * Also we may already have detected the stop bit.
*/ if (!i2c->last_msg || i2c->line_status & LINESTAT_STOP_BIT_DET)
hret = ISR_COMPLETE(0); else
img_i2c_switch_mode(i2c, MODE_WAITSTOP);
}
/* now we've finished using regs, handle transaction completion */ if (hret & ISR_COMPLETE_M) { int status = -(hret & ISR_STATUS_M);
img_i2c_complete_transaction(i2c, status); if (hret & ISR_FATAL_M)
img_i2c_switch_mode(i2c, MODE_FATAL);
}
/* Enable interrupts (int_enable may be altered by changing mode) */
img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable);
spin_unlock(&i2c->lock);
return IRQ_HANDLED;
}
/* Force a bus reset sequence and wait for it to complete */ staticint img_i2c_reset_bus(struct img_i2c *i2c)
{ unsignedlong flags; unsignedlong time_left;
staticint img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{ struct img_i2c *i2c = i2c_get_adapdata(adap); bool atomic = false; int i, ret; unsignedlong time_left;
if (i2c->mode == MODE_SUSPEND) {
WARN(1, "refusing to service transaction in suspended state\n"); return -EIO;
}
if (i2c->mode == MODE_FATAL) return -EIO;
for (i = 0; i < num; i++) { /* * 0 byte reads are not possible because the slave could try * and pull the data line low, preventing a stop bit.
*/ if (!msgs[i].len && msgs[i].flags & I2C_M_RD) return -EIO; /* * 0 byte writes are possible and used for probing, but we * cannot do them in automatic mode, so use atomic mode * instead. * * Also, the I2C_M_IGNORE_NAK mode can only be implemented * in atomic mode.
*/ if (!msgs[i].len ||
(msgs[i].flags & I2C_M_IGNORE_NAK))
atomic = true;
}
ret = pm_runtime_resume_and_get(adap->dev.parent); if (ret < 0) return ret;
for (i = 0; i < num; i++) { struct i2c_msg *msg = &msgs[i]; unsignedlong flags;
spin_lock_irqsave(&i2c->lock, flags);
/* * Make a copy of the message struct. We mustn't modify the * original or we'll confuse drivers and i2c-dev.
*/
i2c->msg = *msg;
i2c->msg_status = 0;
/* * After the last message we must have waited for a stop bit. * Not waiting can cause problems when the clock is disabled * before the stop bit is sent, and the linux I2C interface * requires separate transfers not to joined with repeated * start.
*/
i2c->last_msg = (i == num - 1);
reinit_completion(&i2c->msg_complete);
/* * Clear line status and all interrupts before starting a * transfer, as we may have unserviced interrupts from * previous transfers that might be handled in the context * of the new transfer.
*/
img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0);
img_i2c_writel(i2c, SCB_CLEAR_REG, ~0);
if (atomic) {
img_i2c_atomic_start(i2c);
} else { /* * Enable transaction halt if not the last message in * the queue so that we can control repeated starts.
*/
img_i2c_transaction_halt(i2c, !i2c->last_msg);
if (msg->flags & I2C_M_RD)
img_i2c_read(i2c); else
img_i2c_write(i2c);
/* * Release and then enable transaction halt, to * allow only a single byte to proceed. * This doesn't have an effect on the initial transfer * but will allow the following transfers to start * processing if the previous transfer was marked as * complete while the i2c block was halted.
*/
img_i2c_transaction_halt(i2c, false);
img_i2c_transaction_halt(i2c, !i2c->last_msg);
}
spin_unlock_irqrestore(&i2c->lock, flags);
/* Fencing enabled by default. */
i2c->need_wr_rd_fence = true;
/* Determine what mode we're in from the bitrate */
timing = timings[0]; for (i = 0; i < ARRAY_SIZE(timings); i++) { if (i2c->bitrate <= timings[i].max_bitrate) {
timing = timings[i]; break;
}
} if (i2c->bitrate > timings[ARRAY_SIZE(timings) - 1].max_bitrate) {
dev_warn(i2c->adap.dev.parent, "requested bitrate (%u) is higher than the max bitrate supported (%u)\n",
i2c->bitrate,
timings[ARRAY_SIZE(timings) - 1].max_bitrate);
timing = timings[ARRAY_SIZE(timings) - 1];
i2c->bitrate = timing.max_bitrate;
}
/* Find the prescale that would give us that inc (approx delay = 0) */
prescale = SCB_OPT_INC * clk_khz / (256 * 16 * bitrate_khz);
prescale = clamp_t(unsignedint, prescale, 1, 8);
clk_khz /= prescale;
/* Setup the clock increment value */
inc = (256 * 16 * bitrate_khz) / clk_khz;
/* * The clock generation logic allows to filter glitches on the bus. * This filter is able to remove bus glitches shorter than 50ns. * If the clock enable rate is greater than 20 MHz, no filtering * is required, so we need to disable it. * If it's between the 20-40 MHz range, there's no need to divide * the clock to get a filter.
*/ if (clk_khz < 20000) {
filt = SCB_FILT_DISABLE;
} elseif (clk_khz < 40000) {
filt = SCB_FILT_BYPASS;
} else { /* Calculate filter clock */
filt = (64000 / ((clk_khz / 1000) * SCB_FILT_GLITCH));
/* Scale up if needed */ if (64000 % ((clk_khz / 1000) * SCB_FILT_GLITCH))
inc++;
if (filt > SCB_FILT_INC_MASK)
filt = SCB_FILT_INC_MASK;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct img_i2c), GFP_KERNEL); if (!i2c) return -ENOMEM;
i2c->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base);
irq = platform_get_irq(pdev, 0); if (irq < 0) return irq;
i2c->sys_clk = devm_clk_get(&pdev->dev, "sys"); if (IS_ERR(i2c->sys_clk)) {
dev_err(&pdev->dev, "can't get system clock\n"); return PTR_ERR(i2c->sys_clk);
}
i2c->scb_clk = devm_clk_get(&pdev->dev, "scb"); if (IS_ERR(i2c->scb_clk)) {
dev_err(&pdev->dev, "can't get core clock\n"); return PTR_ERR(i2c->scb_clk);
}
ret = devm_request_irq(&pdev->dev, irq, img_i2c_isr, 0,
pdev->name, i2c); if (ret) {
dev_err(&pdev->dev, "can't request irq %d\n", irq); return ret;
}
/* Set up the exception check timer */
timer_setup(&i2c->check_timer, img_i2c_check_timer, 0);
i2c->bitrate = timings[0].max_bitrate; if (!of_property_read_u32(node, "clock-frequency", &val))
i2c->bitrate = val;
pm_runtime_set_autosuspend_delay(&pdev->dev, IMG_I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) {
ret = img_i2c_runtime_resume(&pdev->dev); if (ret) return ret;
}
ret = img_i2c_init(i2c); if (ret) goto rpm_disable;
ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) goto rpm_disable;
return 0;
rpm_disable: if (!pm_runtime_enabled(&pdev->dev))
img_i2c_runtime_suspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.