aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbhishek Sahu <absahu@codeaurora.org>2018-03-12 09:14:54 -0400
committerWolfram Sang <wsa@the-dreams.de>2018-03-24 08:19:38 -0400
commitc5adc0fa63a930e3313c74bb7c1d4d158130eb41 (patch)
tree2a10dda89d6e7688e1387dd6d2ad70e2ce968525
parent6d5f37f166bb07b04b4d42e9d1f5427b7931cd3c (diff)
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>
-rw-r--r--drivers/i2c/busses/i2c-qup.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index d97045898447..b2e8f574cd15 100644
--- 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, u8 *tags, struct qup_i2c_dev *qup,
551} 551}
552 552
553static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup, 553static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
554 struct i2c_msg *msg, int is_dma) 554 struct i2c_msg *msg)
555{ 555{
556 u16 addr = i2c_8bit_addr_from_msg(msg); 556 u16 addr = i2c_8bit_addr_from_msg(msg);
557 int len = 0; 557 int len = 0;
@@ -592,11 +592,6 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
592 else 592 else
593 tags[len++] = data_len; 593 tags[len++] = data_len;
594 594
595 if ((msg->flags & I2C_M_RD) && last && is_dma) {
596 tags[len++] = QUP_BAM_INPUT_EOT;
597 tags[len++] = QUP_BAM_FLUSH_STOP;
598 }
599
600 return len; 595 return len;
601} 596}
602 597
@@ -605,7 +600,7 @@ static int qup_i2c_issue_xfer_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
605 int data_len = 0, tag_len, index; 600 int data_len = 0, tag_len, index;
606 int ret; 601 int ret;
607 602
608 tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg, 0); 603 tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg);
609 index = msg->len - qup->blk.data_len; 604 index = msg->len - qup->blk.data_len;
610 605
611 /* only tags are written for read */ 606 /* only tags are written for read */
@@ -701,7 +696,7 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg,
701 while (qup->blk.pos < blocks) { 696 while (qup->blk.pos < blocks) {
702 tlen = (i == (blocks - 1)) ? rem : limit; 697 tlen = (i == (blocks - 1)) ? rem : limit;
703 tags = &qup->start_tag.start[off + len]; 698 tags = &qup->start_tag.start[off + len];
704 len += qup_i2c_set_tags(tags, qup, msg, 1); 699 len += qup_i2c_set_tags(tags, qup, msg);
705 qup->blk.data_len -= tlen; 700 qup->blk.data_len -= tlen;
706 701
707 /* scratch buf to read the start and len tags */ 702 /* scratch buf to read the start and len tags */
@@ -729,17 +724,11 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg,
729 return ret; 724 return ret;
730 725
731 off += len; 726 off += len;
732 /* scratch buf to read the BAM EOT and FLUSH tags */
733 ret = qup_sg_set_buf(&qup->brx.sg[rx_cnt++],
734 &qup->brx.tag.start[0],
735 2, qup, DMA_FROM_DEVICE);
736 if (ret)
737 return ret;
738 } else { 727 } else {
739 while (qup->blk.pos < blocks) { 728 while (qup->blk.pos < blocks) {
740 tlen = (i == (blocks - 1)) ? rem : limit; 729 tlen = (i == (blocks - 1)) ? rem : limit;
741 tags = &qup->start_tag.start[off + tx_len]; 730 tags = &qup->start_tag.start[off + tx_len];
742 len = qup_i2c_set_tags(tags, qup, msg, 1); 731 len = qup_i2c_set_tags(tags, qup, msg);
743 qup->blk.data_len -= tlen; 732 qup->blk.data_len -= tlen;
744 733
745 ret = qup_sg_set_buf(&qup->btx.sg[tx_cnt++], 734 ret = qup_sg_set_buf(&qup->btx.sg[tx_cnt++],
@@ -779,6 +768,26 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg,
779 msg++; 768 msg++;
780 } 769 }
781 770
771 /* schedule the EOT and FLUSH I2C tags */
772 len = 1;
773 if (rx_cnt) {
774 qup->btx.tag.start[0] = QUP_BAM_INPUT_EOT;
775 len++;
776
777 /* scratch buf to read the BAM EOT and FLUSH tags */
778 ret = qup_sg_set_buf(&qup->brx.sg[rx_cnt++],
779 &qup->brx.tag.start[0],
780 2, qup, DMA_FROM_DEVICE);
781 if (ret)
782 return ret;
783 }
784
785 qup->btx.tag.start[len - 1] = QUP_BAM_FLUSH_STOP;
786 ret = qup_sg_set_buf(&qup->btx.sg[tx_cnt++], &qup->btx.tag.start[0],
787 len, qup, DMA_TO_DEVICE);
788 if (ret)
789 return ret;
790
782 txd = dmaengine_prep_slave_sg(qup->btx.dma, qup->btx.sg, tx_cnt, 791 txd = dmaengine_prep_slave_sg(qup->btx.dma, qup->btx.sg, tx_cnt,
783 DMA_MEM_TO_DEV, 792 DMA_MEM_TO_DEV,
784 DMA_PREP_INTERRUPT | DMA_PREP_FENCE); 793 DMA_PREP_INTERRUPT | DMA_PREP_FENCE);