diff options
author | Piotr Dymacz <pepe2k@gmail.com> | 2019-03-03 20:23:31 +0100 |
---|---|---|
committer | Piotr Dymacz <pepe2k@gmail.com> | 2019-03-08 19:28:31 +0100 |
commit | 24de7c29e5f70863a2962de79521b60bce4dce2f (patch) | |
tree | 8d6e84a2c7043aaa262951bf19a01ad8d71ca83c /target/linux/ipq40xx/patches-4.14/088-0005-i2c-qup-schedule-EOT-and-FLUSH-tags-at-the-end-of-tr.patch | |
parent | ff8a8074b291511d300c8dcfd2cfbe35cdb9c068 (diff) | |
download | upstream-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.patch | 126 |
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); |