aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch
diff options
context:
space:
mode:
authorPiotr Dymacz <pepe2k@gmail.com>2019-03-03 20:23:31 +0100
committerPiotr Dymacz <pepe2k@gmail.com>2019-03-08 19:28:31 +0100
commit24de7c29e5f70863a2962de79521b60bce4dce2f (patch)
tree8d6e84a2c7043aaa262951bf19a01ad8d71ca83c /target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch
parentff8a8074b291511d300c8dcfd2cfbe35cdb9c068 (diff)
downloadupstream-24de7c29e5f70863a2962de79521b60bce4dce2f.tar.gz
upstream-24de7c29e5f70863a2962de79521b60bce4dce2f.tar.bz2
upstream-24de7c29e5f70863a2962de79521b60bce4dce2f.zip
ipq40xx: backport I2C QUP driver changes from 4.17
Backport below changes for I2C QUP driver from v4.17: 0668bc44a426 i2c: qup: fix copyrights and update to SPDX identifier 7239872fb340 i2c: qup: fixed releasing dma without flush operation completion eb422b539c1f i2c: qup: minor code reorganization for use_dma 6d5f37f166bb i2c: qup: remove redundant variables for BAM SG count c5adc0fa63a9 i2c: qup: schedule EOT and FLUSH tags at the end of transfer 7e6c35fe602d i2c: qup: fix the transfer length for BAM RX EOT FLUSH tags 3f450d3eea14 i2c: qup: proper error handling for i2c error in BAM mode 08f15963bc75 i2c: qup: use the complete transfer length to choose DMA mode ecb6e1e5f435 i2c: qup: change completion timeout according to transfer length 6f2f0f6465ac i2c: qup: fix buffer overflow for multiple msg of maximum xfer len f7714b4e451b i2c: qup: send NACK for last read sub transfers fbfab1ab0658 i2c: qup: reorganization of driver code to remove polling for qup v1 7545c7dba169 i2c: qup: reorganization of driver code to remove polling for qup v2 This fixes various I2C issues observed on AP120C-AC board equipped with Atmel/Microchip AT97SC3205T TPM module. Tested-by: Christian Lamparter <chunkeey@gmail.com> Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
Diffstat (limited to 'target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch')
-rw-r--r--target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch126
1 files changed, 126 insertions, 0 deletions
diff --git a/target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch b/target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch
new file mode 100644
index 0000000000..cbede84cfe
--- /dev/null
+++ b/target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch
@@ -0,0 +1,126 @@
+From c5adc0fa63a930e3313c74bb7c1d4d158130eb41 Mon Sep 17 00:00:00 2001
+From: Abhishek Sahu <absahu@codeaurora.org>
+Date: Mon, 12 Mar 2018 18:44:54 +0530
+Subject: [PATCH 05/13] i2c: qup: schedule EOT and FLUSH tags at the end of
+ transfer
+
+The role of FLUSH and EOT tag is to flush already scheduled
+descriptors in BAM HW in case of error. EOT is required only
+when descriptors are scheduled in RX FIFO. If all the messages
+are WRITE, then only FLUSH tag will be used.
+
+A single BAM transfer can have multiple read and write messages.
+The EOT and FLUSH tags should be scheduled at the end of BAM HW
+descriptors. Since the READ and WRITE can be present in any order
+so for some of the cases, these tags are not being written
+correctly.
+
+Following is one of the example
+
+ READ, READ, READ, READ
+
+Currently EOT and FLUSH tags are being written after each READ.
+If QUP gets NACK for first READ itself, then flush will be
+triggered. It will look for first FLUSH tag in TX FIFO and will
+stop there so only descriptors for first READ descriptors be
+flushed. All the scheduled descriptors should be cleared to
+generate BAM DMA completion.
+
+Now this patch is scheduling FLUSH and EOT only once after all the
+descriptors. So, flush will clear all the scheduled descriptors and
+BAM will generate the completion interrupt.
+
+Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
+Reviewed-by: Sricharan R <sricharan@codeaurora.org>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+---
+ drivers/i2c/busses/i2c-qup.c | 39 ++++++++++++++++++++++--------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-qup.c
++++ b/drivers/i2c/busses/i2c-qup.c
+@@ -551,7 +551,7 @@ static int qup_i2c_set_tags_smb(u16 addr
+ }
+
+ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
+- struct i2c_msg *msg, int is_dma)
++ struct i2c_msg *msg)
+ {
+ u16 addr = i2c_8bit_addr_from_msg(msg);
+ int len = 0;
+@@ -592,11 +592,6 @@ static int qup_i2c_set_tags(u8 *tags, st
+ else
+ tags[len++] = data_len;
+
+- if ((msg->flags & I2C_M_RD) && last && is_dma) {
+- tags[len++] = QUP_BAM_INPUT_EOT;
+- tags[len++] = QUP_BAM_FLUSH_STOP;
+- }
+-
+ return len;
+ }
+
+@@ -605,7 +600,7 @@ static int qup_i2c_issue_xfer_v2(struct
+ int data_len = 0, tag_len, index;
+ int ret;
+
+- tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg, 0);
++ tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg);
+ index = msg->len - qup->blk.data_len;
+
+ /* only tags are written for read */
+@@ -701,7 +696,7 @@ static int qup_i2c_bam_do_xfer(struct qu
+ while (qup->blk.pos < blocks) {
+ tlen = (i == (blocks - 1)) ? rem : limit;
+ tags = &qup->start_tag.start[off + len];
+- len += qup_i2c_set_tags(tags, qup, msg, 1);
++ len += qup_i2c_set_tags(tags, qup, msg);
+ qup->blk.data_len -= tlen;
+
+ /* scratch buf to read the start and len tags */
+@@ -729,17 +724,11 @@ static int qup_i2c_bam_do_xfer(struct qu
+ return ret;
+
+ off += len;
+- /* scratch buf to read the BAM EOT and FLUSH tags */
+- ret = qup_sg_set_buf(&qup->brx.sg[rx_cnt++],
+- &qup->brx.tag.start[0],
+- 2, qup, DMA_FROM_DEVICE);
+- if (ret)
+- return ret;
+ } else {
+ while (qup->blk.pos < blocks) {
+ tlen = (i == (blocks - 1)) ? rem : limit;
+ tags = &qup->start_tag.start[off + tx_len];
+- len = qup_i2c_set_tags(tags, qup, msg, 1);
++ len = qup_i2c_set_tags(tags, qup, msg);
+ qup->blk.data_len -= tlen;
+
+ ret = qup_sg_set_buf(&qup->btx.sg[tx_cnt++],
+@@ -779,6 +768,26 @@ static int qup_i2c_bam_do_xfer(struct qu
+ msg++;
+ }
+
++ /* schedule the EOT and FLUSH I2C tags */
++ len = 1;
++ if (rx_cnt) {
++ qup->btx.tag.start[0] = QUP_BAM_INPUT_EOT;
++ len++;
++
++ /* scratch buf to read the BAM EOT and FLUSH tags */
++ ret = qup_sg_set_buf(&qup->brx.sg[rx_cnt++],
++ &qup->brx.tag.start[0],
++ 2, qup, DMA_FROM_DEVICE);
++ if (ret)
++ return ret;
++ }
++
++ qup->btx.tag.start[len - 1] = QUP_BAM_FLUSH_STOP;
++ ret = qup_sg_set_buf(&qup->btx.sg[tx_cnt++], &qup->btx.tag.start[0],
++ len, qup, DMA_TO_DEVICE);
++ if (ret)
++ return ret;
++
+ txd = dmaengine_prep_slave_sg(qup->btx.dma, qup->btx.sg, tx_cnt,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_PREP_FENCE);