These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / i2c / busses / i2c-at91.c
index 9bd10a9..10835d1 100644 (file)
 
 /* AT91 TWI register definitions */
 #define        AT91_TWI_CR             0x0000  /* Control Register */
-#define        AT91_TWI_START          0x0001  /* Send a Start Condition */
-#define        AT91_TWI_STOP           0x0002  /* Send a Stop Condition */
-#define        AT91_TWI_MSEN           0x0004  /* Master Transfer Enable */
-#define        AT91_TWI_SVDIS          0x0020  /* Slave Transfer Disable */
-#define        AT91_TWI_QUICK          0x0040  /* SMBus quick command */
-#define        AT91_TWI_SWRST          0x0080  /* Software Reset */
+#define        AT91_TWI_START          BIT(0)  /* Send a Start Condition */
+#define        AT91_TWI_STOP           BIT(1)  /* Send a Stop Condition */
+#define        AT91_TWI_MSEN           BIT(2)  /* Master Transfer Enable */
+#define        AT91_TWI_MSDIS          BIT(3)  /* Master Transfer Disable */
+#define        AT91_TWI_SVEN           BIT(4)  /* Slave Transfer Enable */
+#define        AT91_TWI_SVDIS          BIT(5)  /* Slave Transfer Disable */
+#define        AT91_TWI_QUICK          BIT(6)  /* SMBus quick command */
+#define        AT91_TWI_SWRST          BIT(7)  /* Software Reset */
+#define        AT91_TWI_ACMEN          BIT(16) /* Alternative Command Mode Enable */
+#define        AT91_TWI_ACMDIS         BIT(17) /* Alternative Command Mode Disable */
+#define        AT91_TWI_THRCLR         BIT(24) /* Transmit Holding Register Clear */
+#define        AT91_TWI_RHRCLR         BIT(25) /* Receive Holding Register Clear */
+#define        AT91_TWI_LOCKCLR        BIT(26) /* Lock Clear */
+#define        AT91_TWI_FIFOEN         BIT(28) /* FIFO Enable */
+#define        AT91_TWI_FIFODIS        BIT(29) /* FIFO Disable */
 
 #define        AT91_TWI_MMR            0x0004  /* Master Mode Register */
 #define        AT91_TWI_IADRSZ_1       0x0100  /* Internal Device Address Size */
-#define        AT91_TWI_MREAD          0x1000  /* Master Read Direction */
+#define        AT91_TWI_MREAD          BIT(12) /* Master Read Direction */
 
 #define        AT91_TWI_IADR           0x000c  /* Internal Address Register */
 
 #define        AT91_TWI_CWGR           0x0010  /* Clock Waveform Generator Reg */
 
 #define        AT91_TWI_SR             0x0020  /* Status Register */
-#define        AT91_TWI_TXCOMP         0x0001  /* Transmission Complete */
-#define        AT91_TWI_RXRDY          0x0002  /* Receive Holding Register Ready */
-#define        AT91_TWI_TXRDY          0x0004  /* Transmit Holding Register Ready */
-
-#define        AT91_TWI_OVRE           0x0040  /* Overrun Error */
-#define        AT91_TWI_UNRE           0x0080  /* Underrun Error */
-#define        AT91_TWI_NACK           0x0100  /* Not Acknowledged */
+#define        AT91_TWI_TXCOMP         BIT(0)  /* Transmission Complete */
+#define        AT91_TWI_RXRDY          BIT(1)  /* Receive Holding Register Ready */
+#define        AT91_TWI_TXRDY          BIT(2)  /* Transmit Holding Register Ready */
+#define        AT91_TWI_OVRE           BIT(6)  /* Overrun Error */
+#define        AT91_TWI_UNRE           BIT(7)  /* Underrun Error */
+#define        AT91_TWI_NACK           BIT(8)  /* Not Acknowledged */
+#define        AT91_TWI_LOCK           BIT(23) /* TWI Lock due to Frame Errors */
 
 #define        AT91_TWI_INT_MASK \
        (AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK)
 #define        AT91_TWI_RHR            0x0030  /* Receive Holding Register */
 #define        AT91_TWI_THR            0x0034  /* Transmit Holding Register */
 
+#define        AT91_TWI_ACR            0x0040  /* Alternative Command Register */
+#define        AT91_TWI_ACR_DATAL(len) ((len) & 0xff)
+#define        AT91_TWI_ACR_DIR        BIT(8)
+
+#define        AT91_TWI_FMR            0x0050  /* FIFO Mode Register */
+#define        AT91_TWI_FMR_TXRDYM(mode)       (((mode) & 0x3) << 0)
+#define        AT91_TWI_FMR_TXRDYM_MASK        (0x3 << 0)
+#define        AT91_TWI_FMR_RXRDYM(mode)       (((mode) & 0x3) << 4)
+#define        AT91_TWI_FMR_RXRDYM_MASK        (0x3 << 4)
+#define        AT91_TWI_ONE_DATA       0x0
+#define        AT91_TWI_TWO_DATA       0x1
+#define        AT91_TWI_FOUR_DATA      0x2
+
+#define        AT91_TWI_FLR            0x0054  /* FIFO Level Register */
+
+#define        AT91_TWI_FSR            0x0060  /* FIFO Status Register */
+#define        AT91_TWI_FIER           0x0064  /* FIFO Interrupt Enable Register */
+#define        AT91_TWI_FIDR           0x0068  /* FIFO Interrupt Disable Register */
+#define        AT91_TWI_FIMR           0x006c  /* FIFO Interrupt Mask Register */
+
+#define        AT91_TWI_VER            0x00fc  /* Version Register */
+
 struct at91_twi_pdata {
        unsigned clk_max_div;
        unsigned clk_offset;
        bool has_unre_flag;
+       bool has_alt_cmd;
        struct at_dma_slave dma_slave;
 };
 
 struct at91_twi_dma {
        struct dma_chan *chan_rx;
        struct dma_chan *chan_tx;
-       struct scatterlist sg;
+       struct scatterlist sg[2];
        struct dma_async_tx_descriptor *data_desc;
        enum dma_data_direction direction;
        bool buf_mapped;
@@ -107,6 +139,7 @@ struct at91_twi_dev {
        struct at91_twi_pdata *pdata;
        bool use_dma;
        bool recv_len_abort;
+       u32 fifo_size;
        struct at91_twi_dma dma;
 };
 
@@ -140,6 +173,9 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev)
 {
        at91_disable_twi_interrupts(dev);
        at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+       /* FIFO should be enabled immediately after the software reset */
+       if (dev->fifo_size)
+               at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);
        at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
        at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
        at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
@@ -186,7 +222,7 @@ static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
                dma->xfer_in_progress = false;
        }
        if (dma->buf_mapped) {
-               dma_unmap_single(dev->dev, sg_dma_address(&dma->sg),
+               dma_unmap_single(dev->dev, sg_dma_address(&dma->sg[0]),
                                 dev->buf_len, dma->direction);
                dma->buf_mapped = false;
        }
@@ -196,14 +232,16 @@ static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
 
 static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
 {
-       if (dev->buf_len <= 0)
+       if (!dev->buf_len)
                return;
 
-       at91_twi_write(dev, AT91_TWI_THR, *dev->buf);
+       /* 8bit write works with and without FIFO */
+       writeb_relaxed(*dev->buf, dev->base + AT91_TWI_THR);
 
        /* send stop when last byte has been written */
        if (--dev->buf_len == 0)
-               at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
+               if (!dev->pdata->has_alt_cmd)
+                       at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
 
        dev_dbg(dev->dev, "wrote 0x%x, to go %d\n", *dev->buf, dev->buf_len);
 
@@ -214,7 +252,7 @@ static void at91_twi_write_data_dma_callback(void *data)
 {
        struct at91_twi_dev *dev = (struct at91_twi_dev *)data;
 
-       dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
+       dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg[0]),
                         dev->buf_len, DMA_TO_DEVICE);
 
        /*
@@ -225,7 +263,8 @@ static void at91_twi_write_data_dma_callback(void *data)
         * we just have to enable TXCOMP one.
         */
        at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
-       at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
+       if (!dev->pdata->has_alt_cmd)
+               at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
 }
 
 static void at91_twi_write_data_dma(struct at91_twi_dev *dev)
@@ -234,8 +273,9 @@ static void at91_twi_write_data_dma(struct at91_twi_dev *dev)
        struct dma_async_tx_descriptor *txdesc;
        struct at91_twi_dma *dma = &dev->dma;
        struct dma_chan *chan_tx = dma->chan_tx;
+       unsigned int sg_len = 1;
 
-       if (dev->buf_len <= 0)
+       if (!dev->buf_len)
                return;
 
        dma->direction = DMA_TO_DEVICE;
@@ -249,10 +289,43 @@ static void at91_twi_write_data_dma(struct at91_twi_dev *dev)
        }
        dma->buf_mapped = true;
        at91_twi_irq_restore(dev);
-       sg_dma_len(&dma->sg) = dev->buf_len;
-       sg_dma_address(&dma->sg) = dma_addr;
 
-       txdesc = dmaengine_prep_slave_sg(chan_tx, &dma->sg, 1, DMA_MEM_TO_DEV,
+       if (dev->fifo_size) {
+               size_t part1_len, part2_len;
+               struct scatterlist *sg;
+               unsigned fifo_mr;
+
+               sg_len = 0;
+
+               part1_len = dev->buf_len & ~0x3;
+               if (part1_len) {
+                       sg = &dma->sg[sg_len++];
+                       sg_dma_len(sg) = part1_len;
+                       sg_dma_address(sg) = dma_addr;
+               }
+
+               part2_len = dev->buf_len & 0x3;
+               if (part2_len) {
+                       sg = &dma->sg[sg_len++];
+                       sg_dma_len(sg) = part2_len;
+                       sg_dma_address(sg) = dma_addr + part1_len;
+               }
+
+               /*
+                * DMA controller is triggered when at least 4 data can be
+                * written into the TX FIFO
+                */
+               fifo_mr = at91_twi_read(dev, AT91_TWI_FMR);
+               fifo_mr &= ~AT91_TWI_FMR_TXRDYM_MASK;
+               fifo_mr |= AT91_TWI_FMR_TXRDYM(AT91_TWI_FOUR_DATA);
+               at91_twi_write(dev, AT91_TWI_FMR, fifo_mr);
+       } else {
+               sg_dma_len(&dma->sg[0]) = dev->buf_len;
+               sg_dma_address(&dma->sg[0]) = dma_addr;
+       }
+
+       txdesc = dmaengine_prep_slave_sg(chan_tx, dma->sg, sg_len,
+                                        DMA_MEM_TO_DEV,
                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!txdesc) {
                dev_err(dev->dev, "dma prep slave sg failed\n");
@@ -274,10 +347,17 @@ error:
 
 static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
 {
-       if (dev->buf_len <= 0)
+       /*
+        * If we are in this case, it means there is garbage data in RHR, so
+        * delete them.
+        */
+       if (!dev->buf_len) {
+               at91_twi_read(dev, AT91_TWI_RHR);
                return;
+       }
 
-       *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
+       /* 8bit read works with and without FIFO */
+       *dev->buf = readb_relaxed(dev->base + AT91_TWI_RHR);
        --dev->buf_len;
 
        /* return if aborting, we only needed to read RHR to clear RXRDY*/
@@ -301,7 +381,7 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
        }
 
        /* send stop if second but last byte has been read */
-       if (dev->buf_len == 1)
+       if (!dev->pdata->has_alt_cmd && dev->buf_len == 1)
                at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
 
        dev_dbg(dev->dev, "read 0x%x, to go %d\n", *dev->buf, dev->buf_len);
@@ -312,14 +392,18 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
 static void at91_twi_read_data_dma_callback(void *data)
 {
        struct at91_twi_dev *dev = (struct at91_twi_dev *)data;
+       unsigned ier = AT91_TWI_TXCOMP;
 
-       dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
+       dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg[0]),
                         dev->buf_len, DMA_FROM_DEVICE);
 
-       /* The last two bytes have to be read without using dma */
-       dev->buf += dev->buf_len - 2;
-       dev->buf_len = 2;
-       at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY | AT91_TWI_TXCOMP);
+       if (!dev->pdata->has_alt_cmd) {
+               /* The last two bytes have to be read without using dma */
+               dev->buf += dev->buf_len - 2;
+               dev->buf_len = 2;
+               ier |= AT91_TWI_RXRDY;
+       }
+       at91_twi_write(dev, AT91_TWI_IER, ier);
 }
 
 static void at91_twi_read_data_dma(struct at91_twi_dev *dev)
@@ -328,23 +412,38 @@ static void at91_twi_read_data_dma(struct at91_twi_dev *dev)
        struct dma_async_tx_descriptor *rxdesc;
        struct at91_twi_dma *dma = &dev->dma;
        struct dma_chan *chan_rx = dma->chan_rx;
+       size_t buf_len;
 
+       buf_len = (dev->pdata->has_alt_cmd) ? dev->buf_len : dev->buf_len - 2;
        dma->direction = DMA_FROM_DEVICE;
 
        /* Keep in mind that we won't use dma to read the last two bytes */
        at91_twi_irq_save(dev);
-       dma_addr = dma_map_single(dev->dev, dev->buf, dev->buf_len - 2,
-                                 DMA_FROM_DEVICE);
+       dma_addr = dma_map_single(dev->dev, dev->buf, buf_len, DMA_FROM_DEVICE);
        if (dma_mapping_error(dev->dev, dma_addr)) {
                dev_err(dev->dev, "dma map failed\n");
                return;
        }
        dma->buf_mapped = true;
        at91_twi_irq_restore(dev);
-       dma->sg.dma_address = dma_addr;
-       sg_dma_len(&dma->sg) = dev->buf_len - 2;
 
-       rxdesc = dmaengine_prep_slave_sg(chan_rx, &dma->sg, 1, DMA_DEV_TO_MEM,
+       if (dev->fifo_size && IS_ALIGNED(buf_len, 4)) {
+               unsigned fifo_mr;
+
+               /*
+                * DMA controller is triggered when at least 4 data can be
+                * read from the RX FIFO
+                */
+               fifo_mr = at91_twi_read(dev, AT91_TWI_FMR);
+               fifo_mr &= ~AT91_TWI_FMR_RXRDYM_MASK;
+               fifo_mr |= AT91_TWI_FMR_RXRDYM(AT91_TWI_FOUR_DATA);
+               at91_twi_write(dev, AT91_TWI_FMR, fifo_mr);
+       }
+
+       sg_dma_len(&dma->sg[0]) = buf_len;
+       sg_dma_address(&dma->sg[0]) = dma_addr;
+
+       rxdesc = dmaengine_prep_slave_sg(chan_rx, dma->sg, 1, DMA_DEV_TO_MEM,
                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!rxdesc) {
                dev_err(dev->dev, "dma prep slave sg failed\n");
@@ -372,19 +471,73 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
 
        if (!irqstatus)
                return IRQ_NONE;
-       else if (irqstatus & AT91_TWI_RXRDY)
+       /*
+        * In reception, the behavior of the twi device (before sama5d2) is
+        * weird. There is some magic about RXRDY flag! When a data has been
+        * almost received, the reception of a new one is anticipated if there
+        * is no stop command to send. That is the reason why ask for sending
+        * the stop command not on the last data but on the second last one.
+        *
+        * Unfortunately, we could still have the RXRDY flag set even if the
+        * transfer is done and we have read the last data. It might happen
+        * when the i2c slave device sends too quickly data after receiving the
+        * ack from the master. The data has been almost received before having
+        * the order to send stop. In this case, sending the stop command could
+        * cause a RXRDY interrupt with a TXCOMP one. It is better to manage
+        * the RXRDY interrupt first in order to not keep garbage data in the
+        * Receive Holding Register for the next transfer.
+        */
+       if (irqstatus & AT91_TWI_RXRDY)
                at91_twi_read_next_byte(dev);
-       else if (irqstatus & AT91_TWI_TXRDY)
-               at91_twi_write_next_byte(dev);
-
-       /* catch error flags */
-       dev->transfer_status |= status;
 
+       /*
+        * When a NACK condition is detected, the I2C controller sets the NACK,
+        * TXCOMP and TXRDY bits all together in the Status Register (SR).
+        *
+        * 1 - Handling NACK errors with CPU write transfer.
+        *
+        * In such case, we should not write the next byte into the Transmit
+        * Holding Register (THR) otherwise the I2C controller would start a new
+        * transfer and the I2C slave is likely to reply by another NACK.
+        *
+        * 2 - Handling NACK errors with DMA write transfer.
+        *
+        * By setting the TXRDY bit in the SR, the I2C controller also triggers
+        * the DMA controller to write the next data into the THR. Then the
+        * result depends on the hardware version of the I2C controller.
+        *
+        * 2a - Without support of the Alternative Command mode.
+        *
+        * This is the worst case: the DMA controller is triggered to write the
+        * next data into the THR, hence starting a new transfer: the I2C slave
+        * is likely to reply by another NACK.
+        * Concurrently, this interrupt handler is likely to be called to manage
+        * the first NACK before the I2C controller detects the second NACK and
+        * sets once again the NACK bit into the SR.
+        * When handling the first NACK, this interrupt handler disables the I2C
+        * controller interruptions, especially the NACK interrupt.
+        * Hence, the NACK bit is pending into the SR. This is why we should
+        * read the SR to clear all pending interrupts at the beginning of
+        * at91_do_twi_transfer() before actually starting a new transfer.
+        *
+        * 2b - With support of the Alternative Command mode.
+        *
+        * When a NACK condition is detected, the I2C controller also locks the
+        * THR (and sets the LOCK bit in the SR): even though the DMA controller
+        * is triggered by the TXRDY bit to write the next data into the THR,
+        * this data actually won't go on the I2C bus hence a second NACK is not
+        * generated.
+        */
        if (irqstatus & (AT91_TWI_TXCOMP | AT91_TWI_NACK)) {
                at91_disable_twi_interrupts(dev);
                complete(&dev->cmd_complete);
+       } else if (irqstatus & AT91_TWI_TXRDY) {
+               at91_twi_write_next_byte(dev);
        }
 
+       /* catch error flags */
+       dev->transfer_status |= status;
+
        return IRQ_HANDLED;
 }
 
@@ -393,6 +546,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
        int ret;
        unsigned long time_left;
        bool has_unre_flag = dev->pdata->has_unre_flag;
+       bool has_alt_cmd = dev->pdata->has_alt_cmd;
 
        /*
         * WARNING: the TXCOMP bit in the Status Register is NOT a clear on
@@ -402,6 +556,21 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
         * empty and STOP condition has been sent.
         * Consequently, we should enable NACK interrupt rather than TXCOMP to
         * detect transmission failure.
+        * Indeed let's take the case of an i2c write command using DMA.
+        * Whenever the slave doesn't acknowledge a byte, the LOCK, NACK and
+        * TXCOMP bits are set together into the Status Register.
+        * LOCK is a clear on write bit, which is set to prevent the DMA
+        * controller from sending new data on the i2c bus after a NACK
+        * condition has happened. Once locked, this i2c peripheral stops
+        * triggering the DMA controller for new data but it is more than
+        * likely that a new DMA transaction is already in progress, writing
+        * into the Transmit Holding Register. Since the peripheral is locked,
+        * these new data won't be sent to the i2c bus but they will remain
+        * into the Transmit Holding Register, so TXCOMP bit is cleared.
+        * Then when the interrupt handler is called, the Status Register is
+        * read: the TXCOMP bit is clear but NACK bit is still set. The driver
+        * manage the error properly, without waiting for timeout.
+        * This case can be reproduced easyly when writing into an at24 eeprom.
         *
         * Besides, the TXCOMP bit is already set before the i2c transaction
         * has been started. For read transactions, this bit is cleared when
@@ -417,9 +586,9 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
         * condition since we don't know whether the TXCOMP interrupt is enabled
         * before or after the DMA has started to write into THR. So the TXCOMP
         * interrupt is enabled later by at91_twi_write_data_dma_callback().
-        * Immediately after in that DMA callback, we still need to send the
-        * STOP condition manually writing the corresponding bit into the
-        * Control Register.
+        * Immediately after in that DMA callback, if the alternative command
+        * mode is not used, we still need to send the STOP condition manually
+        * writing the corresponding bit into the Control Register.
         */
 
        dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
@@ -428,26 +597,41 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
        reinit_completion(&dev->cmd_complete);
        dev->transfer_status = 0;
 
+       /* Clear pending interrupts, such as NACK. */
+       at91_twi_read(dev, AT91_TWI_SR);
+
+       if (dev->fifo_size) {
+               unsigned fifo_mr = at91_twi_read(dev, AT91_TWI_FMR);
+
+               /* Reset FIFO mode register */
+               fifo_mr &= ~(AT91_TWI_FMR_TXRDYM_MASK |
+                            AT91_TWI_FMR_RXRDYM_MASK);
+               fifo_mr |= AT91_TWI_FMR_TXRDYM(AT91_TWI_ONE_DATA);
+               fifo_mr |= AT91_TWI_FMR_RXRDYM(AT91_TWI_ONE_DATA);
+               at91_twi_write(dev, AT91_TWI_FMR, fifo_mr);
+
+               /* Flush FIFOs */
+               at91_twi_write(dev, AT91_TWI_CR,
+                              AT91_TWI_THRCLR | AT91_TWI_RHRCLR);
+       }
+
        if (!dev->buf_len) {
                at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
                at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
        } else if (dev->msg->flags & I2C_M_RD) {
                unsigned start_flags = AT91_TWI_START;
 
-               if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
-                       dev_err(dev->dev, "RXRDY still set!");
-                       at91_twi_read(dev, AT91_TWI_RHR);
-               }
-
                /* if only one byte is to be read, immediately stop transfer */
-               if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN))
+               if (!has_alt_cmd && dev->buf_len <= 1 &&
+                   !(dev->msg->flags & I2C_M_RECV_LEN))
                        start_flags |= AT91_TWI_STOP;
                at91_twi_write(dev, AT91_TWI_CR, start_flags);
                /*
-                * When using dma, the last byte has to be read manually in
-                * order to not send the stop command too late and then
-                * to receive extra data. In practice, there are some issues
-                * if you use the dma to read n-1 bytes because of latency.
+                * When using dma without alternative command mode, the last
+                * byte has to be read manually in order to not send the stop
+                * command too late and then to receive extra data.
+                * In practice, there are some issues if you use the dma to
+                * read n-1 bytes because of latency.
                 * Reading n-2 bytes with dma and the two last ones manually
                 * seems to be the best solution.
                 */
@@ -476,6 +660,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
        time_left = wait_for_completion_timeout(&dev->cmd_complete,
                                              dev->adapter.timeout);
        if (time_left == 0) {
+               dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
                dev_err(dev->dev, "controller timed out\n");
                at91_init_twi_bus(dev);
                ret = -ETIMEDOUT;
@@ -496,6 +681,12 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
                ret = -EIO;
                goto error;
        }
+       if ((has_alt_cmd || dev->fifo_size) &&
+           (dev->transfer_status & AT91_TWI_LOCK)) {
+               dev_err(dev->dev, "tx locked\n");
+               ret = -EIO;
+               goto error;
+       }
        if (dev->recv_len_abort) {
                dev_err(dev->dev, "invalid smbus block length recvd\n");
                ret = -EPROTO;
@@ -507,7 +698,15 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
        return 0;
 
 error:
+       /* first stop DMA transfer if still in progress */
        at91_twi_dma_cleanup(dev);
+       /* then flush THR/FIFO and unlock TX if locked */
+       if ((has_alt_cmd || dev->fifo_size) &&
+           (dev->transfer_status & AT91_TWI_LOCK)) {
+               dev_dbg(dev->dev, "unlock tx\n");
+               at91_twi_write(dev, AT91_TWI_CR,
+                              AT91_TWI_THRCLR | AT91_TWI_LOCKCLR);
+       }
        return ret;
 }
 
@@ -517,6 +716,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
        int ret;
        unsigned int_addr_flag = 0;
        struct i2c_msg *m_start = msg;
+       bool is_read, use_alt_cmd = false;
 
        dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
 
@@ -539,8 +739,23 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
                at91_twi_write(dev, AT91_TWI_IADR, internal_address);
        }
 
-       at91_twi_write(dev, AT91_TWI_MMR, (m_start->addr << 16) | int_addr_flag
-                      | ((m_start->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
+       is_read = (m_start->flags & I2C_M_RD);
+       if (dev->pdata->has_alt_cmd) {
+               if (m_start->len > 0) {
+                       at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_ACMEN);
+                       at91_twi_write(dev, AT91_TWI_ACR,
+                                      AT91_TWI_ACR_DATAL(m_start->len) |
+                                      ((is_read) ? AT91_TWI_ACR_DIR : 0));
+                       use_alt_cmd = true;
+               } else {
+                       at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_ACMDIS);
+               }
+       }
+
+       at91_twi_write(dev, AT91_TWI_MMR,
+                      (m_start->addr << 16) |
+                      int_addr_flag |
+                      ((!use_alt_cmd && is_read) ? AT91_TWI_MREAD : 0));
 
        dev->buf_len = m_start->len;
        dev->buf = m_start->buf;
@@ -581,30 +796,35 @@ static struct at91_twi_pdata at91rm9200_config = {
        .clk_max_div = 5,
        .clk_offset = 3,
        .has_unre_flag = true,
+       .has_alt_cmd = false,
 };
 
 static struct at91_twi_pdata at91sam9261_config = {
        .clk_max_div = 5,
        .clk_offset = 4,
        .has_unre_flag = false,
+       .has_alt_cmd = false,
 };
 
 static struct at91_twi_pdata at91sam9260_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
        .has_unre_flag = false,
+       .has_alt_cmd = false,
 };
 
 static struct at91_twi_pdata at91sam9g20_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
        .has_unre_flag = false,
+       .has_alt_cmd = false,
 };
 
 static struct at91_twi_pdata at91sam9g10_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
        .has_unre_flag = false,
+       .has_alt_cmd = false,
 };
 
 static const struct platform_device_id at91_twi_devtypes[] = {
@@ -633,6 +853,14 @@ static struct at91_twi_pdata at91sam9x5_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
        .has_unre_flag = false,
+       .has_alt_cmd = false,
+};
+
+static struct at91_twi_pdata sama5d2_config = {
+       .clk_max_div = 7,
+       .clk_offset = 4,
+       .has_unre_flag = true,
+       .has_alt_cmd = true,
 };
 
 static const struct of_device_id atmel_twi_dt_ids[] = {
@@ -654,6 +882,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
        }, {
                .compatible = "atmel,at91sam9x5-i2c",
                .data = &at91sam9x5_config,
+       }, {
+               .compatible = "atmel,sama5d2-i2c",
+               .data = &sama5d2_config,
        }, {
                /* sentinel */
        }
@@ -666,13 +897,32 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
        int ret = 0;
        struct dma_slave_config slave_config;
        struct at91_twi_dma *dma = &dev->dma;
+       enum dma_slave_buswidth addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+       /*
+        * The actual width of the access will be chosen in
+        * dmaengine_prep_slave_sg():
+        * for each buffer in the scatter-gather list, if its size is aligned
+        * to addr_width then addr_width accesses will be performed to transfer
+        * the buffer. On the other hand, if the buffer size is not aligned to
+        * addr_width then the buffer is transferred using single byte accesses.
+        * Please refer to the Atmel eXtended DMA controller driver.
+        * When FIFOs are used, the TXRDYM threshold can always be set to
+        * trigger the XDMAC when at least 4 data can be written into the TX
+        * FIFO, even if single byte accesses are performed.
+        * However the RXRDYM threshold must be set to fit the access width,
+        * deduced from buffer length, so the XDMAC is triggered properly to
+        * read data from the RX FIFO.
+        */
+       if (dev->fifo_size)
+               addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 
        memset(&slave_config, 0, sizeof(slave_config));
        slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR;
-       slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       slave_config.src_addr_width = addr_width;
        slave_config.src_maxburst = 1;
        slave_config.dst_addr = (dma_addr_t)phy_addr + AT91_TWI_THR;
-       slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       slave_config.dst_addr_width = addr_width;
        slave_config.dst_maxburst = 1;
        slave_config.device_fc = false;
 
@@ -704,7 +954,7 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
                goto error;
        }
 
-       sg_init_table(&dma->sg, 1);
+       sg_init_table(dma->sg, 2);
        dma->buf_mapped = false;
        dma->xfer_in_progress = false;
        dev->use_dma = true;
@@ -790,6 +1040,11 @@ static int at91_twi_probe(struct platform_device *pdev)
                        return rc;
        }
 
+       if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size",
+                                 &dev->fifo_size)) {
+               dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);
+       }
+
        rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
                        &bus_clk_rate);
        if (rc)
@@ -826,7 +1081,8 @@ static int at91_twi_probe(struct platform_device *pdev)
                return rc;
        }
 
-       dev_info(dev->dev, "AT91 i2c bus driver.\n");
+       dev_info(dev->dev, "AT91 i2c bus driver (hw version: %#x).\n",
+                at91_twi_read(dev, AT91_TWI_VER));
        return 0;
 }