/* check for arbitration lost, clear if set */ if (temp & MSR_ALF) {
writel(temp, lpi2c_imx->base + LPI2C_MSR); return -EAGAIN;
}
/* check for bus not busy */ if (err) {
dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n"); if (lpi2c_imx->adapter.bus_recovery_info)
i2c_recover_bus(&lpi2c_imx->adapter); return -ETIMEDOUT;
}
do {
data = readl(lpi2c_imx->base + LPI2C_MRDR); if (data & MRDR_RXEMPTY) break;
lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff;
} while (1);
/* * First byte is the length of remaining packet in the SMBus block * data read. Add it to msgs->len.
*/ if (lpi2c_imx->block_data) {
blocklen = lpi2c_imx->rx_buf[0];
lpi2c_imx->msglen += blocklen;
}
/* * When the length of data is less than I2C_DMA_THRESHOLD, * cpu mode is used directly to avoid low performance.
*/ return !(msg->len < I2C_DMA_THRESHOLD);
}
/* * Calculate the number of rx command words via the DMA TX channel * writing into command register based on the i2c msg len, and build * the rx command words buffer.
*/
cmd_num = DIV_ROUND_UP(rx_remain, CHUNK_DATA);
dma->rx_cmd_buf = kcalloc(cmd_num, sizeof(u16), GFP_KERNEL);
dma->rx_cmd_buf_len = cmd_num * sizeof(u16);
for (i = fifosize / 2; i > 0; i--) if (!(len % i)) break;
return i;
}
/* * For a highest DMA efficiency, tx/rx burst number should be calculated according * to the FIFO depth.
*/ staticvoid lpi2c_imx_dma_burst_num_calculate(struct lpi2c_imx_struct *lpi2c_imx)
{ struct lpi2c_imx_dma *dma = lpi2c_imx->dma; unsignedint cmd_num;
if (dma->dma_msg_flag & I2C_M_RD) { /* * One RX cmd word can trigger DMA receive no more than 256 bytes. * The number of RX cmd words should be calculated based on the data * length.
*/
cmd_num = DIV_ROUND_UP(dma->dma_len, CHUNK_DATA);
dma->tx_burst_num = lpi2c_imx_find_max_burst_num(lpi2c_imx->txfifosize,
cmd_num);
dma->rx_burst_num = lpi2c_imx_find_max_burst_num(lpi2c_imx->rxfifosize,
dma->dma_len);
} else {
dma->tx_burst_num = lpi2c_imx_find_max_burst_num(lpi2c_imx->txfifosize,
dma->dma_len);
}
}
staticvoid lpi2c_dma_enable(struct lpi2c_imx_struct *lpi2c_imx)
{ struct lpi2c_imx_dma *dma = lpi2c_imx->dma; /* * TX interrupt will be triggered when the number of words in * the transmit FIFO is equal or less than TX watermark. * RX interrupt will be triggered when the number of words in * the receive FIFO is greater than RX watermark. * In order to trigger the DMA interrupt, TX watermark should be * set equal to the DMA TX burst number but RX watermark should * be set less than the DMA RX burst number.
*/ if (dma->dma_msg_flag & I2C_M_RD) { /* Set I2C TX/RX watermark */
writel(dma->tx_burst_num | (dma->rx_burst_num - 1) << 16,
lpi2c_imx->base + LPI2C_MFCR); /* Enable I2C DMA TX/RX function */
writel(MDER_TDDE | MDER_RDDE, lpi2c_imx->base + LPI2C_MDER);
} else { /* Set I2C TX watermark */
writel(dma->tx_burst_num, lpi2c_imx->base + LPI2C_MFCR); /* Enable I2C DMA TX function */
writel(MDER_TDDE, lpi2c_imx->base + LPI2C_MDER);
}
/* * When lpi2c is in TX DMA mode we can use one DMA TX channel to write * data word into TXFIFO, but in RX DMA mode it is different. * * The LPI2C MTDR register is a command data and transmit data register. * Bits 8-10 are the command data field and Bits 0-7 are the transmit * data field. When the LPI2C master needs to read data, the number of * bytes to read should be set in the command field and RECV_DATA should * be set into the command data field to receive (DATA[7:0] + 1) bytes. * The recv data command word is made of RECV_DATA in the command data * field and the number of bytes to read in transmit data field. When the * length of data to be read exceeds 256 bytes, recv data command word * needs to be written to TXFIFO multiple times. * * So when in RX DMA mode, the TX channel also must to be configured to * send RX command words and the RX command word must be set in advance * before transmitting.
*/ staticint lpi2c_imx_dma_xfer(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg)
{ struct lpi2c_imx_dma *dma = lpi2c_imx->dma; int ret;
/* When DMA mode fails before transferring, CPU mode can be used. */
dma->using_pio_mode = true;
ret = lpi2c_dma_config(lpi2c_imx); if (ret) {
dev_err(&lpi2c_imx->adapter.dev, "Failed to configure DMA (%d)\n", ret); goto disable_dma;
}
lpi2c_dma_enable(lpi2c_imx);
ret = lpi2c_dma_submit(lpi2c_imx); if (ret) {
dev_err(&lpi2c_imx->adapter.dev, "DMA submission failed (%d)\n", ret); goto disable_dma;
}
if (dma->dma_msg_flag & I2C_M_RD) {
ret = lpi2c_imx_alloc_rx_cmd_buf(lpi2c_imx); if (ret) goto disable_cleanup_data_dma;
ret = lpi2c_dma_rx_cmd_submit(lpi2c_imx); if (ret) goto disable_cleanup_data_dma;
}
ret = lpi2c_imx_dma_msg_complete(lpi2c_imx); if (ret) goto disable_cleanup_all_dma;
/* When encountering NACK in transfer, clean up all DMA transfers */ if ((readl(lpi2c_imx->base + LPI2C_MSR) & MSR_NDF) && !ret) {
ret = -EIO; goto disable_cleanup_all_dma;
}
if (dma->dma_msg_flag & I2C_M_RD)
dma_unmap_single(dma->chan_tx->device->dev, dma->dma_tx_addr,
dma->rx_cmd_buf_len, DMA_TO_DEVICE);
lpi2c_dma_unmap(dma);
goto disable_dma;
disable_cleanup_all_dma: if (dma->dma_msg_flag & I2C_M_RD)
lpi2c_cleanup_rx_cmd_dma(dma);
disable_cleanup_data_dma:
lpi2c_cleanup_dma(dma);
disable_dma: /* Disable I2C DMA function */
writel(0, lpi2c_imx->base + LPI2C_MDER);
if (dma->dma_msg_flag & I2C_M_RD)
kfree(dma->rx_cmd_buf);
if (ret)
i2c_put_dma_safe_msg_buf(dma->dma_buf, msg, false); else
i2c_put_dma_safe_msg_buf(dma->dma_buf, msg, true);
return ret;
}
staticint lpi2c_imx_xfer_common(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num, bool atomic)
{ struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(adapter); unsignedint temp; int i, result;
result = lpi2c_imx_master_enable(lpi2c_imx); if (result) return result;
for (i = 0; i < num; i++) {
result = lpi2c_imx_start(lpi2c_imx, &msgs[i], atomic); if (result) goto disable;
if (atomic) {
result = lpi2c_imx_pio_xfer_atomic(lpi2c_imx, &msgs[i]);
} else {
init_completion(&lpi2c_imx->complete);
if (is_use_dma(lpi2c_imx, &msgs[i])) {
result = lpi2c_imx_dma_xfer(lpi2c_imx, &msgs[i]); if (result && lpi2c_imx->dma->using_pio_mode)
result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]);
} else {
result = lpi2c_imx_pio_xfer(lpi2c_imx, &msgs[i]);
}
}
if (result) goto stop;
if (!(msgs[i].flags & I2C_M_RD)) {
result = lpi2c_imx_txfifo_empty(lpi2c_imx, atomic); if (result) goto stop;
}
}
stop:
lpi2c_imx_stop(lpi2c_imx, atomic);
temp = readl(lpi2c_imx->base + LPI2C_MSR); if ((temp & MSR_NDF) && !result)
result = -EIO;
if (lpi2c_imx->target) {
u32 scr = readl(lpi2c_imx->base + LPI2C_SCR);
u32 ssr = readl(lpi2c_imx->base + LPI2C_SSR);
u32 sier_filter = ssr & readl(lpi2c_imx->base + LPI2C_SIER);
/* * The target is enabled and an interrupt has been triggered. * Enter the target's irq handler.
*/ if ((scr & SCR_SEN) && sier_filter) return lpi2c_imx_target_isr(lpi2c_imx, ssr, sier_filter);
}
/* * Otherwise the interrupt has been triggered by the master. * Enter the master's irq handler.
*/ return lpi2c_imx_master_isr(lpi2c_imx);
}
/* * set SCFGR2: FILTSDA, FILTSCL and CLKHOLD * * FILTSCL/FILTSDA can eliminate signal skew. It should generally be * set to the same value and should be set >= 50ns. * * CLKHOLD is only used when clock stretching is enabled, but it will * extend the clock stretching to ensure there is an additional delay * between the target driving SDA and the target releasing the SCL pin. * * CLKHOLD setting is crucial for lpi2c target. When master read data * from target, if there is a delay caused by cpu idle, excessive load, * or other delays between two bytes in one message transmission, it * will cause a short interval time between the driving SDA signal and * releasing SCL signal. The lpi2c master will mistakenly think it is a stop * signal resulting in an arbitration failure. This issue can be avoided * by setting CLKHOLD. * * In order to ensure lpi2c function normally when the lpi2c speed is as * low as 100kHz, CLKHOLD should be set to 3 and it is also compatible with * higher clock frequency like 400kHz and 1MHz.
*/
temp = SCFGR2_FILTSDA(2) | SCFGR2_FILTSCL(2) | SCFGR2_CLKHOLD(3);
writel(temp, lpi2c_imx->base + LPI2C_SCFGR2);
/* * Enable module: * SCR_FILTEN can enable digital filter and output delay counter for LPI2C * target mode. So SCR_FILTEN need be asserted when enable SDA/SCL FILTER * and CLKHOLD.
*/
writel(SCR_SEN | SCR_FILTEN, lpi2c_imx->base + LPI2C_SCR);
ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); if (ret) return ret;
/* * Lock the parent clock rate to avoid getting parent clock upon * each transfer
*/
ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk); if (ret) return dev_err_probe(&pdev->dev, ret, "can't lock I2C peripheral clock rate\n");
lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk); if (!lpi2c_imx->rate_per) return dev_err_probe(&pdev->dev, -EINVAL, "can't get I2C peripheral clock rate\n");
/* Init optional bus recovery function */
ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev); /* Give it another chance if pinctrl used is not ready yet */ if (ret == -EPROBE_DEFER) goto rpm_disable;
/* Init DMA */
ret = lpi2c_dma_init(&pdev->dev, phy_addr); if (ret) { if (ret == -EPROBE_DEFER) goto rpm_disable;
dev_info(&pdev->dev, "use pio mode\n");
}
ret = i2c_add_adapter(&lpi2c_imx->adapter); if (ret) goto rpm_disable;
ret = pm_runtime_force_resume(dev); if (ret) return ret;
/* * If the I2C module powers down during system suspend, * the register values will be lost. Therefore, reinitialize * the target when the system resumes.
*/ if (lpi2c_imx->target)
lpi2c_imx_target_init(lpi2c_imx);
return 0;
}
staticint lpi2c_suspend(struct device *dev)
{ /* * Some I2C devices may need the I2C controller to remain active * during resume_noirq() or suspend_noirq(). If the controller is * autosuspended, there is no way to wake it up once runtime PM is * disabled (in suspend_late()). * * During system resume, the I2C controller will be available only * after runtime PM is re-enabled (in resume_early()). However, this * may be too late for some devices. * * Wake up the controller in the suspend() callback while runtime PM * is still enabled. The I2C controller will remain available until * the suspend_noirq() callback (pm_runtime_force_suspend()) is * called. During resume, the I2C controller can be restored by the * resume_noirq() callback (pm_runtime_force_resume()). * * Finally, the resume() callback re-enables autosuspend, ensuring * the I2C controller remains available until the system enters * suspend_noirq() and from resume_noirq().
*/ return pm_runtime_resume_and_get(dev);
}
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.