LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
@ 2016-01-19 10:02 Sricharan R
  2016-01-19 10:02 ` [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts Sricharan R
                   ` (6 more replies)
  0 siblings, 7 replies; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

i2c: qup: Add support for v2 tags and bam dma

QUP from version 2.1.1 onwards, supports a new format of i2c command tags.
Tag codes instructs the controller to perform a operation like read/write.
This new tagging version is required for adding bam dma capabilities.
V2 tags supports transfer of more than 256 bytes in a single i2c transaction.
Also adding bam dma support facilitates transferring each i2c_msg in i2c_msgs
without a 'stop' bit in between which is required for some of the clients.

Tested this series on apq8074 dragon board eeprom client on i2c bus1

[V7] Added tested-by tags and fixed a small comment

[V6] Added review tags and fixed a checkpatch warning in patch 4/6.

[V5] Addressed few more comments from Ivan T. Ivanov.
     Squashed patch 2 and 3 as no point in having only few lines of
     common code between v1 and v2 tags for increased complexity.
     Couple of non functional review comments fixes in patch 3, 4.
     Added a change in patch 4 to have proper transfer completion in
     a corner case. patch 5, 6 unchanged.

[V4] Added a patch to factor out some common code.
     Removed support for freq > 400KHZ as per comments.
     Addressed comments from Ivan T. Ivanov to keep the code for
     V2 support in a separate path.
     Changed the authorship of V2 tags support patch.

[V3] Added support to coalesce each i2c_msg in i2c_msgs for fifo and
     block mode in Patch 2. Also addressed further code comments.

     http://comments.gmane.org/gmane.linux.drivers.i2c/22497

[V2] Addressed comments from Ivan T. Ivanov, Andy Gross [v1] Initial Version

Sricharan R (6):
  i2c: qup: Change qup_wait_writeready function to use for all timeouts
  i2c: qup: Add V2 tags support
  i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  i2c: qup: Add bam dma capabilities
  dts: msm8974: Add blsp2_bam dma node
  dts: msm8974: Add dma channels for blsp2_i2c1 node

 arch/arm/boot/dts/qcom-msm8974.dtsi |  14 +-
 drivers/i2c/busses/i2c-qup.c        | 922 ++++++++++++++++++++++++++++++++++--
 2 files changed, 887 insertions(+), 49 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-02-12 18:37   ` Wolfram Sang
  2016-01-19 10:02 ` [PATCH V7 2/6] i2c: qup: Add V2 tags support Sricharan R
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

qup_wait_writeready waits only on a output fifo empty event.
Change the same function to accept the event and data length
to wait as parameters. This way the same function can be used for
timeouts in other places as well.

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
Tested-by: Archit Taneja <architt@codeaurora.org>
Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
---
 drivers/i2c/busses/i2c-qup.c | 67 +++++++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index fdcbdab..81ed120 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -98,6 +98,9 @@
 #define QUP_STATUS_ERROR_FLAGS		0x7c
 
 #define QUP_READ_LIMIT			256
+#define SET_BIT				0x1
+#define RESET_BIT			0x0
+#define ONE_BYTE			0x1
 
 struct qup_i2c_dev {
 	struct device		*dev;
@@ -221,26 +224,42 @@ static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state)
 	return 0;
 }
 
-static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup)
+/**
+ * qup_i2c_wait_ready - wait for a give number of bytes in tx/rx path
+ * @qup: The qup_i2c_dev device
+ * @op: The bit/event to wait on
+ * @val: value of the bit to wait on, 0 or 1
+ * @len: The length the bytes to be transferred
+ */
+static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val,
+			      int len)
 {
 	unsigned long timeout;
 	u32 opflags;
 	u32 status;
+	u32 shift = __ffs(op);
 
-	timeout = jiffies + HZ;
+	len *= qup->one_byte_t;
+	/* timeout after a wait of twice the max time */
+	timeout = jiffies + len * 4;
 
 	for (;;) {
 		opflags = readl(qup->base + QUP_OPERATIONAL);
 		status = readl(qup->base + QUP_I2C_STATUS);
 
-		if (!(opflags & QUP_OUT_NOT_EMPTY) &&
-		    !(status & I2C_STATUS_BUS_ACTIVE))
-			return 0;
+		if (((opflags & op) >> shift) == val) {
+			if (op == QUP_OUT_NOT_EMPTY) {
+				if (!(status & I2C_STATUS_BUS_ACTIVE))
+					return 0;
+			} else {
+				return 0;
+			}
+		}
 
 		if (time_after(jiffies, timeout))
 			return -ETIMEDOUT;
 
-		usleep_range(qup->one_byte_t, qup->one_byte_t * 2);
+		usleep_range(len, len * 2);
 	}
 }
 
@@ -261,13 +280,13 @@ static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	}
 }
 
-static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
 	u32 addr = msg->addr << 1;
 	u32 qup_tag;
-	u32 opflags;
 	int idx;
 	u32 val;
+	int ret = 0;
 
 	if (qup->pos == 0) {
 		val = QUP_TAG_START | addr;
@@ -279,9 +298,10 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 
 	while (qup->pos < msg->len) {
 		/* Check that there's space in the FIFO for our pair */
-		opflags = readl(qup->base + QUP_OPERATIONAL);
-		if (opflags & QUP_OUT_FULL)
-			break;
+		ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL, RESET_BIT,
+					 4 * ONE_BYTE);
+		if (ret)
+			return ret;
 
 		if (qup->pos == msg->len - 1)
 			qup_tag = QUP_TAG_STOP;
@@ -300,6 +320,8 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 		qup->pos++;
 		idx++;
 	}
+
+	return ret;
 }
 
 static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
@@ -325,7 +347,9 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 		if (ret)
 			goto err;
 
-		qup_i2c_issue_write(qup, msg);
+		ret = qup_i2c_issue_write(qup, msg);
+		if (ret)
+			goto err;
 
 		ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
 		if (ret)
@@ -347,7 +371,7 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	} while (qup->pos < msg->len);
 
 	/* Wait for the outstanding data in the fifo to drain */
-	ret = qup_i2c_wait_writeready(qup);
+	ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE);
 
 err:
 	disable_irq(qup->irq);
@@ -384,18 +408,19 @@ static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 }
 
 
-static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static int qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
-	u32 opflags;
 	u32 val = 0;
 	int idx;
+	int ret = 0;
 
 	for (idx = 0; qup->pos < msg->len; idx++) {
 		if ((idx & 1) == 0) {
 			/* Check that FIFO have data */
-			opflags = readl(qup->base + QUP_OPERATIONAL);
-			if (!(opflags & QUP_IN_NOT_EMPTY))
-				break;
+			ret = qup_i2c_wait_ready(qup, QUP_IN_NOT_EMPTY,
+						 SET_BIT, 4 * ONE_BYTE);
+			if (ret)
+				return ret;
 
 			/* Reading 2 words at time */
 			val = readl(qup->base + QUP_IN_FIFO_BASE);
@@ -405,6 +430,8 @@ static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 			msg->buf[qup->pos++] = val >> QUP_MSW_SHIFT;
 		}
 	}
+
+	return ret;
 }
 
 static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
@@ -450,7 +477,9 @@ static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 			goto err;
 		}
 
-		qup_i2c_read_fifo(qup, msg);
+		ret = qup_i2c_read_fifo(qup, msg);
+		if (ret)
+			goto err;
 	} while (qup->pos < msg->len);
 
 err:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH V7 2/6] i2c: qup: Add V2 tags support
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
  2016-01-19 10:02 ` [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-02-12 18:37   ` Wolfram Sang
  2016-01-19 10:02 ` [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit Sricharan R
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

QUP from version 2.1.1 onwards, supports a new format of
i2c command tags. Tag codes instructs the controller to
perform a operation like read/write. This new tagging version
supports bam dma and transfers of more than 256 bytes without 'stop'
in between. Adding the support for the same.

For each block a data_write/read tag and data_len tag is added to
the output fifo. For the final block of data write_stop/read_stop
tag is used.

Signed-off-by: Andy Gross <andy.gross@linaro.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Tested-by: Archit Taneja <architt@codeaurora.org>
Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
---
 drivers/i2c/busses/i2c-qup.c | 415 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 386 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 81ed120..715d4d7 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -42,6 +42,7 @@
 #define QUP_IN_FIFO_BASE	0x218
 #define QUP_I2C_CLK_CTL		0x400
 #define QUP_I2C_STATUS		0x404
+#define QUP_I2C_MASTER_GEN	0x408
 
 /* QUP States and reset values */
 #define QUP_RESET_STATE		0
@@ -69,6 +70,8 @@
 #define QUP_CLOCK_AUTO_GATE	BIT(13)
 #define I2C_MINI_CORE		(2 << 8)
 #define I2C_N_VAL		15
+#define I2C_N_VAL_V2		7
+
 /* Most significant word offset in FIFO port */
 #define QUP_MSW_SHIFT		(I2C_N_VAL + 1)
 
@@ -79,6 +82,7 @@
 #define QUP_PACK_EN		BIT(15)
 
 #define QUP_REPACK_EN		(QUP_UNPACK_EN | QUP_PACK_EN)
+#define QUP_V2_TAGS_EN		1
 
 #define QUP_OUTPUT_BLOCK_SIZE(x)(((x) >> 0) & 0x03)
 #define QUP_OUTPUT_FIFO_SIZE(x)	(((x) >> 2) & 0x07)
@@ -91,6 +95,13 @@
 #define QUP_TAG_STOP		(3 << 8)
 #define QUP_TAG_REC		(4 << 8)
 
+/* QUP v2 tags */
+#define QUP_TAG_V2_START               0x81
+#define QUP_TAG_V2_DATAWR              0x82
+#define QUP_TAG_V2_DATAWR_STOP         0x83
+#define QUP_TAG_V2_DATARD              0x85
+#define QUP_TAG_V2_DATARD_STOP         0x87
+
 /* Status, Error flags */
 #define I2C_STATUS_WR_BUFFER_FULL	BIT(0)
 #define I2C_STATUS_BUS_ACTIVE		BIT(8)
@@ -102,6 +113,15 @@
 #define RESET_BIT			0x0
 #define ONE_BYTE			0x1
 
+struct qup_i2c_block {
+	int	count;
+	int	pos;
+	int	tx_tag_len;
+	int	rx_tag_len;
+	int	data_len;
+	u8	tags[6];
+};
+
 struct qup_i2c_dev {
 	struct device		*dev;
 	void __iomem		*base;
@@ -117,6 +137,7 @@ struct qup_i2c_dev {
 	int			in_blk_sz;
 
 	unsigned long		one_byte_t;
+	struct qup_i2c_block	blk;
 
 	struct i2c_msg		*msg;
 	/* Current posion in user message buffer */
@@ -263,6 +284,24 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val,
 	}
 }
 
+static void qup_i2c_set_write_mode_v2(struct qup_i2c_dev *qup,
+				      struct i2c_msg *msg)
+{
+	/* Number of entries to shift out, including the tags */
+	int total = msg->len + qup->blk.tx_tag_len;
+
+	if (total < qup->out_fifo_sz) {
+		/* FIFO mode */
+		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
+		writel(total, qup->base + QUP_MX_WRITE_CNT);
+	} else {
+		/* BLOCK mode (transfer data on chunks) */
+		writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN,
+		       qup->base + QUP_IO_MODE);
+		writel(total, qup->base + QUP_MX_OUTPUT_CNT);
+	}
+}
+
 static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
 	/* Number of entries to shift out, including the start */
@@ -324,9 +363,189 @@ static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	return ret;
 }
 
-static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static void qup_i2c_set_blk_data(struct qup_i2c_dev *qup,
+				 struct i2c_msg *msg)
+{
+	memset(&qup->blk, 0, sizeof(qup->blk));
+
+	qup->blk.data_len = msg->len;
+	qup->blk.count = (msg->len + QUP_READ_LIMIT - 1) / QUP_READ_LIMIT;
+
+	/* 4 bytes for first block and 2 writes for rest */
+	qup->blk.tx_tag_len = 4 + (qup->blk.count - 1) * 2;
+
+	/* There are 2 tag bytes that are read in to fifo for every block */
+	if (msg->flags & I2C_M_RD)
+		qup->blk.rx_tag_len = qup->blk.count * 2;
+}
+
+static int qup_i2c_send_data(struct qup_i2c_dev *qup, int tlen, u8 *tbuf,
+			     int dlen, u8 *dbuf)
+{
+	u32 val = 0, idx = 0, pos = 0, i = 0, t;
+	int  len = tlen + dlen;
+	u8 *buf = tbuf;
+	int ret = 0;
+
+	while (len > 0) {
+		ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL,
+					 RESET_BIT, 4 * ONE_BYTE);
+		if (ret) {
+			dev_err(qup->dev, "timeout for fifo out full");
+			return ret;
+		}
+
+		t = (len >= 4) ? 4 : len;
+
+		while (idx < t) {
+			if (!i && (pos >= tlen)) {
+				buf = dbuf;
+				pos = 0;
+				i = 1;
+			}
+			val |= buf[pos++] << (idx++ * 8);
+		}
+
+		writel(val, qup->base + QUP_OUT_FIFO_BASE);
+		idx  = 0;
+		val = 0;
+		len -= 4;
+	}
+
+	return ret;
+}
+
+static int qup_i2c_get_data_len(struct qup_i2c_dev *qup)
+{
+	int data_len;
+
+	if (qup->blk.data_len > QUP_READ_LIMIT)
+		data_len = QUP_READ_LIMIT;
+	else
+		data_len = qup->blk.data_len;
+
+	return data_len;
+}
+
+static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
+			    struct i2c_msg *msg)
+{
+	u16 addr = (msg->addr << 1) | ((msg->flags & I2C_M_RD) == I2C_M_RD);
+	int len = 0;
+	int data_len;
+
+	if (qup->blk.pos == 0) {
+		tags[len++] = QUP_TAG_V2_START;
+		tags[len++] = addr & 0xff;
+
+		if (msg->flags & I2C_M_TEN)
+			tags[len++] = addr >> 8;
+	}
+
+	/* Send _STOP commands for the last block */
+	if (qup->blk.pos == (qup->blk.count - 1)) {
+		if (msg->flags & I2C_M_RD)
+			tags[len++] = QUP_TAG_V2_DATARD_STOP;
+		else
+			tags[len++] = QUP_TAG_V2_DATAWR_STOP;
+	} else {
+		if (msg->flags & I2C_M_RD)
+			tags[len++] = QUP_TAG_V2_DATARD;
+		else
+			tags[len++] = QUP_TAG_V2_DATAWR;
+	}
+
+	data_len = qup_i2c_get_data_len(qup);
+
+	/* 0 implies 256 bytes */
+	if (data_len == QUP_READ_LIMIT)
+		tags[len++] = 0;
+	else
+		tags[len++] = data_len;
+
+	return len;
+}
+
+static int qup_i2c_issue_xfer_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+{
+	int data_len = 0, tag_len, index;
+	int ret;
+
+	tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg);
+	index = msg->len - qup->blk.data_len;
+
+	/* only tags are written for read */
+	if (!(msg->flags & I2C_M_RD))
+		data_len = qup_i2c_get_data_len(qup);
+
+	ret = qup_i2c_send_data(qup, tag_len, qup->blk.tags,
+				data_len, &msg->buf[index]);
+	qup->blk.data_len -= data_len;
+
+	return ret;
+}
+
+static int qup_i2c_wait_for_complete(struct qup_i2c_dev *qup,
+				     struct i2c_msg *msg)
 {
 	unsigned long left;
+	int ret = 0;
+
+	left = wait_for_completion_timeout(&qup->xfer, HZ);
+	if (!left) {
+		writel(1, qup->base + QUP_SW_RESET);
+		ret = -ETIMEDOUT;
+	}
+
+	if (qup->bus_err || qup->qup_err) {
+		if (qup->bus_err & QUP_I2C_NACK_FLAG) {
+			dev_err(qup->dev, "NACK from %x\n", msg->addr);
+			ret = -EIO;
+		}
+	}
+
+	return ret;
+}
+
+static int qup_i2c_write_one_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+{
+	int ret = 0;
+
+	qup->msg = msg;
+	qup->pos = 0;
+	enable_irq(qup->irq);
+	qup_i2c_set_blk_data(qup, msg);
+	qup_i2c_set_write_mode_v2(qup, msg);
+
+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
+	if (ret)
+		goto err;
+
+	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
+
+	do {
+		ret = qup_i2c_issue_xfer_v2(qup, msg);
+		if (ret)
+			goto err;
+
+		ret = qup_i2c_wait_for_complete(qup, msg);
+		if (ret)
+			goto err;
+
+		qup->blk.pos++;
+	} while (qup->blk.pos < qup->blk.count);
+
+	ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE);
+
+err:
+	disable_irq(qup->irq);
+	qup->msg = NULL;
+
+	return ret;
+}
+
+static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+{
 	int ret;
 
 	qup->msg = msg;
@@ -355,19 +574,9 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 		if (ret)
 			goto err;
 
-		left = wait_for_completion_timeout(&qup->xfer, HZ);
-		if (!left) {
-			writel(1, qup->base + QUP_SW_RESET);
-			ret = -ETIMEDOUT;
-			goto err;
-		}
-
-		if (qup->bus_err || qup->qup_err) {
-			if (qup->bus_err & QUP_I2C_NACK_FLAG)
-				dev_err(qup->dev, "NACK from %x\n", msg->addr);
-			ret = -EIO;
+		ret = qup_i2c_wait_for_complete(qup, msg);
+		if (ret)
 			goto err;
-		}
 	} while (qup->pos < msg->len);
 
 	/* Wait for the outstanding data in the fifo to drain */
@@ -394,6 +603,26 @@ static void qup_i2c_set_read_mode(struct qup_i2c_dev *qup, int len)
 	}
 }
 
+static void qup_i2c_set_read_mode_v2(struct qup_i2c_dev *qup, int len)
+{
+	int tx_len = qup->blk.tx_tag_len;
+
+	len += qup->blk.rx_tag_len;
+
+	if (len < qup->in_fifo_sz) {
+		/* FIFO mode */
+		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
+		writel(len, qup->base + QUP_MX_READ_CNT);
+		writel(tx_len, qup->base + QUP_MX_WRITE_CNT);
+	} else {
+		/* BLOCK mode (transfer data on chunks) */
+		writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN,
+		       qup->base + QUP_IO_MODE);
+		writel(len, qup->base + QUP_MX_INPUT_CNT);
+		writel(tx_len, qup->base + QUP_MX_OUTPUT_CNT);
+	}
+}
+
 static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
 	u32 addr, len, val;
@@ -434,16 +663,90 @@ static int qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	return ret;
 }
 
+static int qup_i2c_read_fifo_v2(struct qup_i2c_dev *qup,
+				struct i2c_msg *msg)
+{
+	u32 val;
+	int idx, pos = 0, ret = 0, total;
+
+	total = qup_i2c_get_data_len(qup);
+
+	/* 2 extra bytes for read tags */
+	while (pos < (total + 2)) {
+		/* Check that FIFO have data */
+		ret = qup_i2c_wait_ready(qup, QUP_IN_NOT_EMPTY,
+					 SET_BIT, 4 * ONE_BYTE);
+		if (ret) {
+			dev_err(qup->dev, "timeout for fifo not empty");
+			return ret;
+		}
+		val = readl(qup->base + QUP_IN_FIFO_BASE);
+
+		for (idx = 0; idx < 4; idx++, val >>= 8, pos++) {
+			/* first 2 bytes are tag bytes */
+			if (pos < 2)
+				continue;
+
+			if (pos >= (total + 2))
+				goto out;
+
+			msg->buf[qup->pos++] = val & 0xff;
+		}
+	}
+
+out:
+	qup->blk.data_len -= total;
+
+	return ret;
+}
+
+static int qup_i2c_read_one_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+{
+	int ret = 0;
+
+	qup->msg = msg;
+	qup->pos  = 0;
+	enable_irq(qup->irq);
+	qup_i2c_set_blk_data(qup, msg);
+	qup_i2c_set_read_mode_v2(qup, msg->len);
+
+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
+	if (ret)
+		goto err;
+
+	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
+
+	do {
+		ret = qup_i2c_issue_xfer_v2(qup, msg);
+		if (ret)
+			goto err;
+
+		ret = qup_i2c_wait_for_complete(qup, msg);
+		if (ret)
+			goto err;
+
+		ret = qup_i2c_read_fifo_v2(qup, msg);
+		if (ret)
+			goto err;
+
+		qup->blk.pos++;
+	} while (qup->blk.pos < qup->blk.count);
+
+err:
+	disable_irq(qup->irq);
+	qup->msg = NULL;
+
+	return ret;
+}
+
 static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
-	unsigned long left;
 	int ret;
 
 	qup->msg = msg;
 	qup->pos  = 0;
 
 	enable_irq(qup->irq);
-
 	qup_i2c_set_read_mode(qup, msg->len);
 
 	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
@@ -463,19 +766,9 @@ static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 		goto err;
 
 	do {
-		left = wait_for_completion_timeout(&qup->xfer, HZ);
-		if (!left) {
-			writel(1, qup->base + QUP_SW_RESET);
-			ret = -ETIMEDOUT;
+		ret = qup_i2c_wait_for_complete(qup, msg);
+		if (ret)
 			goto err;
-		}
-
-		if (qup->bus_err || qup->qup_err) {
-			if (qup->bus_err & QUP_I2C_NACK_FLAG)
-				dev_err(qup->dev, "NACK from %x\n", msg->addr);
-			ret = -EIO;
-			goto err;
-		}
 
 		ret = qup_i2c_read_fifo(qup, msg);
 		if (ret)
@@ -542,6 +835,60 @@ out:
 	return ret;
 }
 
+static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
+			   struct i2c_msg msgs[],
+			   int num)
+{
+	struct qup_i2c_dev *qup = i2c_get_adapdata(adap);
+	int ret, idx;
+
+	ret = pm_runtime_get_sync(qup->dev);
+	if (ret < 0)
+		goto out;
+
+	writel(1, qup->base + QUP_SW_RESET);
+	ret = qup_i2c_poll_state(qup, QUP_RESET_STATE);
+	if (ret)
+		goto out;
+
+	/* Configure QUP as I2C mini core */
+	writel(I2C_MINI_CORE | I2C_N_VAL_V2, qup->base + QUP_CONFIG);
+	writel(QUP_V2_TAGS_EN, qup->base + QUP_I2C_MASTER_GEN);
+
+	for (idx = 0; idx < num; idx++) {
+		if (msgs[idx].len == 0) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (qup_i2c_poll_state_i2c_master(qup)) {
+			ret = -EIO;
+			goto out;
+		}
+
+		reinit_completion(&qup->xfer);
+
+		if (msgs[idx].flags & I2C_M_RD)
+			ret = qup_i2c_read_one_v2(qup, &msgs[idx]);
+		else
+			ret = qup_i2c_write_one_v2(qup, &msgs[idx]);
+
+		if (!ret)
+			ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
+
+		if (ret)
+			break;
+	}
+
+	if (ret == 0)
+		ret = num;
+out:
+	pm_runtime_mark_last_busy(qup->dev);
+	pm_runtime_put_autosuspend(qup->dev);
+
+	return ret;
+}
+
 static u32 qup_i2c_func(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
@@ -552,6 +899,11 @@ static const struct i2c_algorithm qup_i2c_algo = {
 	.functionality	= qup_i2c_func,
 };
 
+static const struct i2c_algorithm qup_i2c_algo_v2 = {
+	.master_xfer	= qup_i2c_xfer_v2,
+	.functionality	= qup_i2c_func,
+};
+
 /*
  * The QUP block will issue a NACK and STOP on the bus when reaching
  * the end of the read, the length of the read is specified as one byte
@@ -601,6 +953,13 @@ static int qup_i2c_probe(struct platform_device *pdev)
 
 	of_property_read_u32(node, "clock-frequency", &clk_freq);
 
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
+		qup->adap.algo = &qup_i2c_algo;
+		qup->adap.quirks = &qup_i2c_quirks;
+	} else {
+		qup->adap.algo = &qup_i2c_algo_v2;
+	}
+
 	/* We support frequencies up to FAST Mode (400KHz) */
 	if (!clk_freq || clk_freq > 400000) {
 		dev_err(qup->dev, "clock frequency not supported %d\n",
@@ -696,8 +1055,6 @@ static int qup_i2c_probe(struct platform_device *pdev)
 		qup->out_blk_sz, qup->out_fifo_sz);
 
 	i2c_set_adapdata(&qup->adap, qup);
-	qup->adap.algo = &qup_i2c_algo;
-	qup->adap.quirks = &qup_i2c_quirks;
 	qup->adap.dev.parent = qup->dev;
 	qup->adap.dev.of_node = pdev->dev.of_node;
 	strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
  2016-01-19 10:02 ` [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts Sricharan R
  2016-01-19 10:02 ` [PATCH V7 2/6] i2c: qup: Add V2 tags support Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-01-24 11:29   ` Wolfram Sang
  2016-02-12 18:38   ` Wolfram Sang
  2016-01-19 10:02 ` [PATCH V7 4/6] i2c: qup: Add bam dma capabilities Sricharan R
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

The definition of i2c_msg says that

"If this is the last message in a group, it is followed by a STOP.
Otherwise it is followed by the next @i2c_msg transaction segment,
beginning with a (repeated) START"

So the expectation is that there is no 'STOP' bit inbetween individual
i2c_msg segments with repeated 'START'. The QUP i2c hardware has no way
to inform that there should not be a 'STOP' at the end of transaction.
The only way to implement this is to coalesce all the i2c_msg in i2c_msgs
in to one transaction and transfer them. Adding the support for the same.

This is required for some clients like touchscreen which keeps
incrementing counts across individual transfers and 'STOP' bit inbetween
resets the counter, which is not required.

This patch adds the support in non-dma mode.

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
Tested-by: Archit Taneja <architt@codeaurora.org>
Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
---
 drivers/i2c/busses/i2c-qup.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 715d4d7..f9009d6 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -112,6 +112,7 @@
 #define SET_BIT				0x1
 #define RESET_BIT			0x0
 #define ONE_BYTE			0x1
+#define QUP_I2C_MX_CONFIG_DURING_RUN   BIT(31)
 
 struct qup_i2c_block {
 	int	count;
@@ -147,6 +148,12 @@ struct qup_i2c_dev {
 	/* QUP core errors */
 	u32			qup_err;
 
+	/* To check if this is the last msg */
+	bool			is_last;
+
+	/* To configure when bus is in run state */
+	int			config_run;
+
 	struct completion	xfer;
 };
 
@@ -269,7 +276,7 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val,
 		status = readl(qup->base + QUP_I2C_STATUS);
 
 		if (((opflags & op) >> shift) == val) {
-			if (op == QUP_OUT_NOT_EMPTY) {
+			if ((op == QUP_OUT_NOT_EMPTY) && qup->is_last) {
 				if (!(status & I2C_STATUS_BUS_ACTIVE))
 					return 0;
 			} else {
@@ -290,6 +297,8 @@ static void qup_i2c_set_write_mode_v2(struct qup_i2c_dev *qup,
 	/* Number of entries to shift out, including the tags */
 	int total = msg->len + qup->blk.tx_tag_len;
 
+	total |= qup->config_run;
+
 	if (total < qup->out_fifo_sz) {
 		/* FIFO mode */
 		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
@@ -443,7 +452,7 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
 	}
 
 	/* Send _STOP commands for the last block */
-	if (qup->blk.pos == (qup->blk.count - 1)) {
+	if ((qup->blk.pos == (qup->blk.count - 1)) && qup->is_last) {
 		if (msg->flags & I2C_M_RD)
 			tags[len++] = QUP_TAG_V2_DATARD_STOP;
 		else
@@ -581,7 +590,6 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 
 	/* Wait for the outstanding data in the fifo to drain */
 	ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE);
-
 err:
 	disable_irq(qup->irq);
 	qup->msg = NULL;
@@ -608,18 +616,20 @@ static void qup_i2c_set_read_mode_v2(struct qup_i2c_dev *qup, int len)
 	int tx_len = qup->blk.tx_tag_len;
 
 	len += qup->blk.rx_tag_len;
+	len |= qup->config_run;
+	tx_len |= qup->config_run;
 
 	if (len < qup->in_fifo_sz) {
 		/* FIFO mode */
 		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-		writel(len, qup->base + QUP_MX_READ_CNT);
 		writel(tx_len, qup->base + QUP_MX_WRITE_CNT);
+		writel(len, qup->base + QUP_MX_READ_CNT);
 	} else {
 		/* BLOCK mode (transfer data on chunks) */
 		writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN,
 		       qup->base + QUP_IO_MODE);
-		writel(len, qup->base + QUP_MX_INPUT_CNT);
 		writel(tx_len, qup->base + QUP_MX_OUTPUT_CNT);
+		writel(len, qup->base + QUP_MX_INPUT_CNT);
 	}
 }
 
@@ -866,6 +876,12 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
 			goto out;
 		}
 
+		qup->is_last = (idx == (num - 1));
+		if (idx)
+			qup->config_run = QUP_I2C_MX_CONFIG_DURING_RUN;
+		else
+			qup->config_run = 0;
+
 		reinit_completion(&qup->xfer);
 
 		if (msgs[idx].flags & I2C_M_RD)
@@ -873,13 +889,13 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
 		else
 			ret = qup_i2c_write_one_v2(qup, &msgs[idx]);
 
-		if (!ret)
-			ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
-
 		if (ret)
 			break;
 	}
 
+	if (!ret)
+		ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
+
 	if (ret == 0)
 		ret = num;
 out:
@@ -1057,6 +1073,8 @@ static int qup_i2c_probe(struct platform_device *pdev)
 	i2c_set_adapdata(&qup->adap, qup);
 	qup->adap.dev.parent = qup->dev;
 	qup->adap.dev.of_node = pdev->dev.of_node;
+	qup->is_last = 1;
+
 	strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
 
 	pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
                   ` (2 preceding siblings ...)
  2016-01-19 10:02 ` [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-02-12 18:37   ` Wolfram Sang
  2016-01-19 10:02 ` [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node Sricharan R
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

QUP cores can be attached to a BAM module, which acts as
a dma engine for the QUP core. When DMA with BAM is enabled,
the BAM consumer pipe transmitted data is written to the
output FIFO and the BAM producer pipe received data is read
from the input FIFO.

With BAM capabilities, qup-i2c core can transfer more than
256 bytes, without a 'stop' which is not possible otherwise.

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
Tested-by: Archit Taneja <architt@codeaurora.org>
Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
---
 drivers/i2c/busses/i2c-qup.c | 448 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 435 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index f9009d6..7220e3a 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -14,8 +14,12 @@
  *
  */
 
+#include <linux/atomic.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
@@ -24,6 +28,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/scatterlist.h>
 
 /* QUP Registers */
 #define QUP_CONFIG		0x000
@@ -33,6 +38,7 @@
 #define QUP_OPERATIONAL		0x018
 #define QUP_ERROR_FLAGS		0x01c
 #define QUP_ERROR_FLAGS_EN	0x020
+#define QUP_OPERATIONAL_MASK	0x028
 #define QUP_HW_VERSION		0x030
 #define QUP_MX_OUTPUT_CNT	0x100
 #define QUP_OUT_FIFO_BASE	0x110
@@ -52,6 +58,7 @@
 
 #define QUP_STATE_VALID		BIT(2)
 #define QUP_I2C_MAST_GEN	BIT(4)
+#define QUP_I2C_FLUSH		BIT(6)
 
 #define QUP_OPERATIONAL_RESET	0x000ff0
 #define QUP_I2C_STATUS_RESET	0xfffffc
@@ -77,7 +84,10 @@
 
 /* Packing/Unpacking words in FIFOs, and IO modes */
 #define QUP_OUTPUT_BLK_MODE	(1 << 10)
+#define QUP_OUTPUT_BAM_MODE	(3 << 10)
 #define QUP_INPUT_BLK_MODE	(1 << 12)
+#define QUP_INPUT_BAM_MODE	(3 << 12)
+#define QUP_BAM_MODE		(QUP_OUTPUT_BAM_MODE | QUP_INPUT_BAM_MODE)
 #define QUP_UNPACK_EN		BIT(14)
 #define QUP_PACK_EN		BIT(15)
 
@@ -94,6 +104,8 @@
 #define QUP_TAG_DATA		(2 << 8)
 #define QUP_TAG_STOP		(3 << 8)
 #define QUP_TAG_REC		(4 << 8)
+#define QUP_BAM_INPUT_EOT		0x93
+#define QUP_BAM_FLUSH_STOP		0x96
 
 /* QUP v2 tags */
 #define QUP_TAG_V2_START               0x81
@@ -114,6 +126,12 @@
 #define ONE_BYTE			0x1
 #define QUP_I2C_MX_CONFIG_DURING_RUN   BIT(31)
 
+#define MX_TX_RX_LEN			SZ_64K
+#define MX_BLOCKS			(MX_TX_RX_LEN / QUP_READ_LIMIT)
+
+/* Max timeout in ms for 32k bytes */
+#define TOUT_MAX			300
+
 struct qup_i2c_block {
 	int	count;
 	int	pos;
@@ -123,6 +141,17 @@ struct qup_i2c_block {
 	u8	tags[6];
 };
 
+struct qup_i2c_tag {
+	u8 *start;
+	dma_addr_t addr;
+};
+
+struct qup_i2c_bam {
+	struct	qup_i2c_tag tag;
+	struct	dma_chan *dma;
+	struct	scatterlist *sg;
+};
+
 struct qup_i2c_dev {
 	struct device		*dev;
 	void __iomem		*base;
@@ -154,6 +183,13 @@ struct qup_i2c_dev {
 	/* To configure when bus is in run state */
 	int			config_run;
 
+	/* dma parameters */
+	bool			is_dma;
+	struct			dma_pool *dpool;
+	struct			qup_i2c_tag start_tag;
+	struct			qup_i2c_bam brx;
+	struct			qup_i2c_bam btx;
+
 	struct completion	xfer;
 };
 
@@ -230,6 +266,14 @@ static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 req_state)
 	return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK);
 }
 
+static void qup_i2c_flush(struct qup_i2c_dev *qup)
+{
+	u32 val = readl(qup->base + QUP_STATE);
+
+	val |= QUP_I2C_FLUSH;
+	writel(val, qup->base + QUP_STATE);
+}
+
 static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup)
 {
 	return qup_i2c_poll_state_mask(qup, 0, 0);
@@ -437,12 +481,14 @@ static int qup_i2c_get_data_len(struct qup_i2c_dev *qup)
 }
 
 static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
-			    struct i2c_msg *msg)
+			    struct i2c_msg *msg,  int is_dma)
 {
 	u16 addr = (msg->addr << 1) | ((msg->flags & I2C_M_RD) == I2C_M_RD);
 	int len = 0;
 	int data_len;
 
+	int last = (qup->blk.pos == (qup->blk.count - 1)) && (qup->is_last);
+
 	if (qup->blk.pos == 0) {
 		tags[len++] = QUP_TAG_V2_START;
 		tags[len++] = addr & 0xff;
@@ -452,7 +498,7 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
 	}
 
 	/* Send _STOP commands for the last block */
-	if ((qup->blk.pos == (qup->blk.count - 1)) && qup->is_last) {
+	if (last) {
 		if (msg->flags & I2C_M_RD)
 			tags[len++] = QUP_TAG_V2_DATARD_STOP;
 		else
@@ -472,6 +518,11 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
 	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;
 }
 
@@ -480,7 +531,7 @@ static int qup_i2c_issue_xfer_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	int data_len = 0, tag_len, index;
 	int ret;
 
-	tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg);
+	tag_len = qup_i2c_set_tags(qup->blk.tags, qup, msg, 0);
 	index = msg->len - qup->blk.data_len;
 
 	/* only tags are written for read */
@@ -494,6 +545,283 @@ static int qup_i2c_issue_xfer_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 	return ret;
 }
 
+static void qup_i2c_bam_cb(void *data)
+{
+	struct qup_i2c_dev *qup = data;
+
+	complete(&qup->xfer);
+}
+
+void qup_sg_set_buf(struct scatterlist *sg, void *buf, struct qup_i2c_tag *tg,
+		    unsigned int buflen, struct qup_i2c_dev *qup,
+		    int map, int dir)
+{
+	sg_set_buf(sg, buf, buflen);
+	dma_map_sg(qup->dev, sg, 1, dir);
+
+	if (!map)
+		sg_dma_address(sg) = tg->addr + ((u8 *)buf - tg->start);
+}
+
+static void qup_i2c_rel_dma(struct qup_i2c_dev *qup)
+{
+	if (qup->btx.dma)
+		dma_release_channel(qup->btx.dma);
+	if (qup->brx.dma)
+		dma_release_channel(qup->brx.dma);
+	qup->btx.dma = NULL;
+	qup->brx.dma = NULL;
+}
+
+static int qup_i2c_req_dma(struct qup_i2c_dev *qup)
+{
+	int err;
+
+	if (!qup->btx.dma) {
+		qup->btx.dma = dma_request_slave_channel_reason(qup->dev, "tx");
+		if (IS_ERR(qup->btx.dma)) {
+			err = PTR_ERR(qup->btx.dma);
+			qup->btx.dma = NULL;
+			dev_err(qup->dev, "\n tx channel not available");
+			return err;
+		}
+	}
+
+	if (!qup->brx.dma) {
+		qup->brx.dma = dma_request_slave_channel_reason(qup->dev, "rx");
+		if (IS_ERR(qup->brx.dma)) {
+			dev_err(qup->dev, "\n rx channel not available");
+			err = PTR_ERR(qup->brx.dma);
+			qup->brx.dma = NULL;
+			qup_i2c_rel_dma(qup);
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg,
+			       int num)
+{
+	struct dma_async_tx_descriptor *txd, *rxd = NULL;
+	int ret = 0, idx = 0;
+	dma_cookie_t cookie_rx, cookie_tx;
+	u32 rx_nents = 0, tx_nents = 0, len, blocks, rem;
+	u32 i, tlen, tx_len, tx_buf = 0, rx_buf = 0, off = 0;
+	u8 *tags;
+
+	while (idx < num) {
+		blocks = (msg->len + QUP_READ_LIMIT) / QUP_READ_LIMIT;
+		rem = msg->len % QUP_READ_LIMIT;
+		tx_len = 0, len = 0, i = 0;
+
+		qup->is_last = (idx == (num - 1));
+
+		qup_i2c_set_blk_data(qup, msg);
+
+		if (msg->flags & I2C_M_RD) {
+			rx_nents += (blocks * 2) + 1;
+			tx_nents += 1;
+
+			while (qup->blk.pos < blocks) {
+				/* length set to '0' implies 256 bytes */
+				tlen = (i == (blocks - 1)) ? rem : 0;
+				tags = &qup->start_tag.start[off + len];
+				len += qup_i2c_set_tags(tags, qup, msg, 1);
+
+				/* scratch buf to read the start and len tags */
+				qup_sg_set_buf(&qup->brx.sg[rx_buf++],
+					       &qup->brx.tag.start[0],
+					       &qup->brx.tag,
+					       2, qup, 0, 0);
+
+				qup_sg_set_buf(&qup->brx.sg[rx_buf++],
+					       &msg->buf[QUP_READ_LIMIT * i],
+					       NULL, tlen, qup,
+					       1, DMA_FROM_DEVICE);
+				i++;
+				qup->blk.pos = i;
+			}
+			qup_sg_set_buf(&qup->btx.sg[tx_buf++],
+				       &qup->start_tag.start[off],
+				       &qup->start_tag, len, qup, 0, 0);
+			off += len;
+			/* scratch buf to read the BAM EOT and FLUSH tags */
+			qup_sg_set_buf(&qup->brx.sg[rx_buf++],
+				       &qup->brx.tag.start[0],
+				       &qup->brx.tag, 2,
+				       qup, 0, 0);
+		} else {
+			tx_nents += (blocks * 2);
+
+			while (qup->blk.pos < blocks) {
+				tlen = (i == (blocks - 1)) ? rem : 0;
+				tags = &qup->start_tag.start[off + tx_len];
+				len = qup_i2c_set_tags(tags, qup, msg, 1);
+
+				qup_sg_set_buf(&qup->btx.sg[tx_buf++],
+					       tags,
+					       &qup->start_tag, len,
+					       qup, 0, 0);
+
+				tx_len += len;
+				qup_sg_set_buf(&qup->btx.sg[tx_buf++],
+					       &msg->buf[QUP_READ_LIMIT * i],
+					       NULL, tlen, qup, 1,
+					       DMA_TO_DEVICE);
+				i++;
+				qup->blk.pos = i;
+			}
+			off += tx_len;
+
+			if (idx == (num - 1)) {
+				len = 1;
+				if (rx_nents) {
+					qup->btx.tag.start[0] =
+							QUP_BAM_INPUT_EOT;
+					len++;
+				}
+				qup->btx.tag.start[len - 1] =
+							QUP_BAM_FLUSH_STOP;
+				qup_sg_set_buf(&qup->btx.sg[tx_buf++],
+					       &qup->btx.tag.start[0],
+					       &qup->btx.tag, len,
+					       qup, 0, 0);
+				tx_nents += 1;
+			}
+		}
+		idx++;
+		msg++;
+	}
+
+	txd = dmaengine_prep_slave_sg(qup->btx.dma, qup->btx.sg, tx_nents,
+				      DMA_MEM_TO_DEV,
+				      DMA_PREP_INTERRUPT | DMA_PREP_FENCE);
+	if (!txd) {
+		dev_err(qup->dev, "failed to get tx desc\n");
+		ret = -EINVAL;
+		goto desc_err;
+	}
+
+	if (!rx_nents) {
+		txd->callback = qup_i2c_bam_cb;
+		txd->callback_param = qup;
+	}
+
+	cookie_tx = dmaengine_submit(txd);
+	if (dma_submit_error(cookie_tx)) {
+		ret = -EINVAL;
+		goto desc_err;
+	}
+
+	dma_async_issue_pending(qup->btx.dma);
+
+	if (rx_nents) {
+		rxd = dmaengine_prep_slave_sg(qup->brx.dma, qup->brx.sg,
+					      rx_nents, DMA_DEV_TO_MEM,
+					      DMA_PREP_INTERRUPT);
+		if (!rxd) {
+			dev_err(qup->dev, "failed to get rx desc\n");
+			ret = -EINVAL;
+
+			/* abort TX descriptors */
+			dmaengine_terminate_all(qup->btx.dma);
+			goto desc_err;
+		}
+
+		rxd->callback = qup_i2c_bam_cb;
+		rxd->callback_param = qup;
+		cookie_rx = dmaengine_submit(rxd);
+		if (dma_submit_error(cookie_rx)) {
+			ret = -EINVAL;
+			goto desc_err;
+		}
+
+		dma_async_issue_pending(qup->brx.dma);
+	}
+
+	if (!wait_for_completion_timeout(&qup->xfer, TOUT_MAX * HZ)) {
+		dev_err(qup->dev, "normal trans timed out\n");
+		ret = -ETIMEDOUT;
+	}
+
+	if (ret || qup->bus_err || qup->qup_err) {
+		if (qup->bus_err & QUP_I2C_NACK_FLAG) {
+			msg--;
+			dev_err(qup->dev, "NACK from %x\n", msg->addr);
+			ret = -EIO;
+
+			if (qup_i2c_change_state(qup, QUP_RUN_STATE)) {
+				dev_err(qup->dev, "change to run state timed out");
+				return ret;
+			}
+
+			if (rx_nents)
+				writel(QUP_BAM_INPUT_EOT,
+				       qup->base + QUP_OUT_FIFO_BASE);
+
+			writel(QUP_BAM_FLUSH_STOP,
+			       qup->base + QUP_OUT_FIFO_BASE);
+
+			qup_i2c_flush(qup);
+
+			/* wait for remaining interrupts to occur */
+			if (!wait_for_completion_timeout(&qup->xfer, HZ))
+				dev_err(qup->dev, "flush timed out\n");
+
+			qup_i2c_rel_dma(qup);
+		}
+	}
+
+	dma_unmap_sg(qup->dev, qup->btx.sg, tx_nents, DMA_TO_DEVICE);
+
+	if (rx_nents)
+		dma_unmap_sg(qup->dev, qup->brx.sg, rx_nents,
+			     DMA_FROM_DEVICE);
+desc_err:
+	return ret;
+}
+
+static int qup_i2c_bam_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+			    int num)
+{
+	struct qup_i2c_dev *qup = i2c_get_adapdata(adap);
+	int ret = 0;
+
+	enable_irq(qup->irq);
+	ret = qup_i2c_req_dma(qup);
+
+	if (ret)
+		goto out;
+
+	qup->bus_err = 0;
+	qup->qup_err = 0;
+
+	writel(0, qup->base + QUP_MX_INPUT_CNT);
+	writel(0, qup->base + QUP_MX_OUTPUT_CNT);
+
+	/* set BAM mode */
+	writel(QUP_REPACK_EN | QUP_BAM_MODE, qup->base + QUP_IO_MODE);
+
+	/* mask fifo irqs */
+	writel((0x3 << 8), qup->base + QUP_OPERATIONAL_MASK);
+
+	/* set RUN STATE */
+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
+	if (ret)
+		goto out;
+
+	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
+
+	qup->msg = msg;
+	ret = qup_i2c_bam_do_xfer(qup, qup->msg, num);
+out:
+	disable_irq(qup->irq);
+
+	qup->msg = NULL;
+	return ret;
+}
+
 static int qup_i2c_wait_for_complete(struct qup_i2c_dev *qup,
 				     struct i2c_msg *msg)
 {
@@ -850,7 +1178,7 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
 			   int num)
 {
 	struct qup_i2c_dev *qup = i2c_get_adapdata(adap);
-	int ret, idx;
+	int ret, len, idx = 0, use_dma = 0;
 
 	ret = pm_runtime_get_sync(qup->dev);
 	if (ret < 0)
@@ -865,7 +1193,27 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
 	writel(I2C_MINI_CORE | I2C_N_VAL_V2, qup->base + QUP_CONFIG);
 	writel(QUP_V2_TAGS_EN, qup->base + QUP_I2C_MASTER_GEN);
 
-	for (idx = 0; idx < num; idx++) {
+	if ((qup->is_dma)) {
+		/* All i2c_msgs should be transferred using either dma or cpu */
+		for (idx = 0; idx < num; idx++) {
+			if (msgs[idx].len == 0) {
+				ret = -EINVAL;
+				goto out;
+			}
+
+			len = (msgs[idx].len > qup->out_fifo_sz) ||
+			      (msgs[idx].len > qup->in_fifo_sz);
+
+			if ((!is_vmalloc_addr(msgs[idx].buf)) && len) {
+				use_dma = 1;
+			 } else {
+				use_dma = 0;
+				break;
+			}
+		}
+	}
+
+	do {
 		if (msgs[idx].len == 0) {
 			ret = -EINVAL;
 			goto out;
@@ -884,14 +1232,15 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
 
 		reinit_completion(&qup->xfer);
 
-		if (msgs[idx].flags & I2C_M_RD)
-			ret = qup_i2c_read_one_v2(qup, &msgs[idx]);
-		else
-			ret = qup_i2c_write_one_v2(qup, &msgs[idx]);
-
-		if (ret)
-			break;
-	}
+		if (use_dma) {
+			ret = qup_i2c_bam_xfer(adap, &msgs[idx], num);
+		} else {
+			if (msgs[idx].flags & I2C_M_RD)
+				ret = qup_i2c_read_one_v2(qup, &msgs[idx]);
+			else
+				ret = qup_i2c_write_one_v2(qup, &msgs[idx]);
+		}
+	} while ((idx++ < (num - 1)) && !use_dma & !ret);
 
 	if (!ret)
 		ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
@@ -958,6 +1307,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
 	int ret, fs_div, hs_div;
 	int src_clk_freq;
 	u32 clk_freq = 100000;
+	int blocks;
 
 	qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
 	if (!qup)
@@ -974,8 +1324,63 @@ static int qup_i2c_probe(struct platform_device *pdev)
 		qup->adap.quirks = &qup_i2c_quirks;
 	} else {
 		qup->adap.algo = &qup_i2c_algo_v2;
+		ret = qup_i2c_req_dma(qup);
+
+		if (ret == -EPROBE_DEFER)
+			goto fail_dma;
+		else if (ret != 0)
+			goto nodma;
+
+		blocks = (MX_BLOCKS << 1) + 1;
+		qup->btx.sg = devm_kzalloc(&pdev->dev,
+					   sizeof(*qup->btx.sg) * blocks,
+					   GFP_KERNEL);
+		if (!qup->btx.sg) {
+			ret = -ENOMEM;
+			goto fail_dma;
+		}
+		sg_init_table(qup->btx.sg, blocks);
+
+		qup->brx.sg = devm_kzalloc(&pdev->dev,
+					   sizeof(*qup->brx.sg) * blocks,
+					   GFP_KERNEL);
+		if (!qup->brx.sg) {
+			ret = -ENOMEM;
+			goto fail_dma;
+		}
+		sg_init_table(qup->brx.sg, blocks);
+
+		/* 2 tag bytes for each block + 5 for start, stop tags */
+		size = blocks * 2 + 5;
+		qup->dpool = dma_pool_create("qup_i2c-dma-pool", &pdev->dev,
+					     size, 4, 0);
+
+		qup->start_tag.start = dma_pool_alloc(qup->dpool, GFP_KERNEL,
+						      &qup->start_tag.addr);
+		if (!qup->start_tag.start) {
+			ret = -ENOMEM;
+			goto fail_dma;
+		}
+
+		qup->brx.tag.start = dma_pool_alloc(qup->dpool,
+						    GFP_KERNEL,
+						    &qup->brx.tag.addr);
+		if (!qup->brx.tag.start) {
+			ret = -ENOMEM;
+			goto fail_dma;
+		}
+
+		qup->btx.tag.start = dma_pool_alloc(qup->dpool,
+						    GFP_KERNEL,
+						    &qup->btx.tag.addr);
+		if (!qup->btx.tag.start) {
+			ret = -ENOMEM;
+			goto fail_dma;
+		}
+		qup->is_dma = 1;
 	}
 
+nodma:
 	/* We support frequencies up to FAST Mode (400KHz) */
 	if (!clk_freq || clk_freq > 400000) {
 		dev_err(qup->dev, "clock frequency not supported %d\n",
@@ -1093,6 +1498,11 @@ fail_runtime:
 	pm_runtime_set_suspended(qup->dev);
 fail:
 	qup_i2c_disable_clocks(qup);
+fail_dma:
+	if (qup->btx.dma)
+		dma_release_channel(qup->btx.dma);
+	if (qup->brx.dma)
+		dma_release_channel(qup->brx.dma);
 	return ret;
 }
 
@@ -1100,6 +1510,18 @@ static int qup_i2c_remove(struct platform_device *pdev)
 {
 	struct qup_i2c_dev *qup = platform_get_drvdata(pdev);
 
+	if (qup->is_dma) {
+		dma_pool_free(qup->dpool, qup->start_tag.start,
+			      qup->start_tag.addr);
+		dma_pool_free(qup->dpool, qup->brx.tag.start,
+			      qup->brx.tag.addr);
+		dma_pool_free(qup->dpool, qup->btx.tag.start,
+			      qup->btx.tag.addr);
+		dma_pool_destroy(qup->dpool);
+		dma_release_channel(qup->btx.dma);
+		dma_release_channel(qup->brx.dma);
+	}
+
 	disable_irq(qup->irq);
 	qup_i2c_disable_clocks(qup);
 	i2c_del_adapter(&qup->adap);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
                   ` (3 preceding siblings ...)
  2016-01-19 10:02 ` [PATCH V7 4/6] i2c: qup: Add bam dma capabilities Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-03-25 23:17   ` Bjorn Andersson
  2016-01-19 10:02 ` [PATCH V7 6/6] dts: msm8974: Add dma channels for blsp2_i2c1 node Sricharan R
  2016-01-19 10:14 ` [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan
  6 siblings, 1 reply; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 753bdfd..7786408 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-msm8974.h>
 #include "skeleton.dtsi"
 
@@ -345,6 +345,16 @@
 			interrupt-controller;
 			#interrupt-cells = <4>;
 		};
+
+		blsp2_dma: dma-controller@f9944000 {
+			compatible = "qcom,bam-v1.4.0";
+			reg = <0xf9944000 0x19000>;
+			interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP2_AHB_CLK>;
+			clock-names = "bam_clk";
+			#dma-cells = <1>;
+			qcom,ee = <0>;
+		};
 	};
 
 	smd {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH V7 6/6] dts: msm8974: Add dma channels for blsp2_i2c1 node
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
                   ` (4 preceding siblings ...)
  2016-01-19 10:02 ` [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node Sricharan R
@ 2016-01-19 10:02 ` Sricharan R
  2016-01-19 10:14 ` [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan
  6 siblings, 0 replies; 26+ messages in thread
From: Sricharan R @ 2016-01-19 10:02 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	sricharan, architt

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 7786408..bd1be53 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -328,6 +328,8 @@
 			clock-names = "core", "iface";
 			#address-cells = <1>;
 			#size-cells = <0>;
+			dmas = <&blsp2_dma 20>, <&blsp2_dma 21>;
+			dma-names = "tx", "rx";
 		};
 
 		spmi_bus: spmi@fc4cf000 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
  2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
                   ` (5 preceding siblings ...)
  2016-01-19 10:02 ` [PATCH V7 6/6] dts: msm8974: Add dma channels for blsp2_i2c1 node Sricharan R
@ 2016-01-19 10:14 ` Sricharan
  2016-01-24 11:33   ` Wolfram Sang
  6 siblings, 1 reply; 26+ messages in thread
From: Sricharan @ 2016-01-19 10:14 UTC (permalink / raw)
  To: wsa
  Cc: devicetree, architt, linux-arm-msm, ntelkar, galak, linux-kernel,
	andy.gross, linux-i2c, iivanov, agross, dmaengine,
	linux-arm-kernel

Hi wolfram,

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces@lists.infradead.org] On Behalf Of Sricharan R
> Sent: Tuesday, January 19, 2016 3:33 PM
> To: wsa@the-dreams.de
> Cc: devicetree@vger.kernel.org; architt@codeaurora.org; linux-arm-
> msm@vger.kernel.org; ntelkar@codeaurora.org; galak@codeaurora.org;
> linux-kernel@vger.kernel.org; andy.gross@linaro.org; linux-
> i2c@vger.kernel.org; iivanov@mm-sol.com; agross@codeaurora.org;
> dmaengine@vger.kernel.org; sricharan@codeaurora.org; linux-arm-
> kernel@lists.infradead.org
> Subject: [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
> 
> i2c: qup: Add support for v2 tags and bam dma
> 
> QUP from version 2.1.1 onwards, supports a new format of i2c command
> tags.
> Tag codes instructs the controller to perform a operation like read/write.
> This new tagging version is required for adding bam dma capabilities.
> V2 tags supports transfer of more than 256 bytes in a single i2c
transaction.
> Also adding bam dma support facilitates transferring each i2c_msg in
> i2c_msgs without a 'stop' bit in between which is required for some of the
> clients.
> 
> Tested this series on apq8074 dragon board eeprom client on i2c bus1
> 
> [V7] Added tested-by tags and fixed a small comment
> 
> [V6] Added review tags and fixed a checkpatch warning in patch 4/6.
> 
> [V5] Addressed few more comments from Ivan T. Ivanov.
>      Squashed patch 2 and 3 as no point in having only few lines of
>      common code between v1 and v2 tags for increased complexity.
>      Couple of non functional review comments fixes in patch 3, 4.
>      Added a change in patch 4 to have proper transfer completion in
>      a corner case. patch 5, 6 unchanged.
> 
> [V4] Added a patch to factor out some common code.
>      Removed support for freq > 400KHZ as per comments.
>      Addressed comments from Ivan T. Ivanov to keep the code for
>      V2 support in a separate path.
>      Changed the authorship of V2 tags support patch.
> 
> [V3] Added support to coalesce each i2c_msg in i2c_msgs for fifo and
>      block mode in Patch 2. Also addressed further code comments.
> 
>      http://comments.gmane.org/gmane.linux.drivers.i2c/22497
> 
> [V2] Addressed comments from Ivan T. Ivanov, Andy Gross [v1] Initial
> Version
> 
> Sricharan R (6):
>   i2c: qup: Change qup_wait_writeready function to use for all timeouts
>   i2c: qup: Add V2 tags support
>   i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
>   i2c: qup: Add bam dma capabilities
>   dts: msm8974: Add blsp2_bam dma node
>   dts: msm8974: Add dma channels for blsp2_i2c1 node
> 
 Wolfram,  Does the first 4 patches looks good to be picked up  ?

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-01-19 10:02 ` [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit Sricharan R
@ 2016-01-24 11:29   ` Wolfram Sang
  2016-01-28  4:57     ` Sricharan
  2016-02-12 18:38   ` Wolfram Sang
  1 sibling, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2016-01-24 11:29 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 997 bytes --]

Hi,

> "If this is the last message in a group, it is followed by a STOP.
> Otherwise it is followed by the next @i2c_msg transaction segment,
> beginning with a (repeated) START"

This is correct.

> So the expectation is that there is no 'STOP' bit inbetween individual
> i2c_msg segments with repeated 'START'. The QUP i2c hardware has no way
> to inform that there should not be a 'STOP' at the end of transaction.
> The only way to implement this is to coalesce all the i2c_msg in i2c_msgs
> in to one transaction and transfer them. Adding the support for the same.

So, there will not be a REP_START condition on the bus? I am sorry to
say that I can't accept this. A REP_START is a REP_START and nothing
else. There are devices which will get confused if there is no real
REP_START condition.

Without knowing the HW in detail, can't you implement I2C_M_NOSTART and
let the touchscreen driver use it via regmap? That would be the proper
way (from what I understand).

Regards,

   Wolfram


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
  2016-01-19 10:14 ` [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan
@ 2016-01-24 11:33   ` Wolfram Sang
  2016-01-28  5:27     ` Sricharan
  0 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2016-01-24 11:33 UTC (permalink / raw)
  To: Sricharan
  Cc: devicetree, architt, linux-arm-msm, ntelkar, galak, linux-kernel,
	andy.gross, linux-i2c, iivanov, agross, dmaengine,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 749 bytes --]

> > Sricharan R (6):
> >   i2c: qup: Change qup_wait_writeready function to use for all timeouts
> >   i2c: qup: Add V2 tags support
> >   i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
> >   i2c: qup: Add bam dma capabilities
> >   dts: msm8974: Add blsp2_bam dma node
> >   dts: msm8974: Add dma channels for blsp2_i2c1 node
> > 
>  Wolfram,  Does the first 4 patches looks good to be picked up  ?

Except for patch 3 (I replied seperately), the rest looks okay to me. I
wondered a little if it would make sense to make a new driver for v2 +
DMA, because the additions were quite massive. But I'll leave it up to
you if there is enough shared code between the two versions, so that a
single driver will be better.


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-01-24 11:29   ` Wolfram Sang
@ 2016-01-28  4:57     ` Sricharan
  2016-02-04 20:09       ` Wolfram Sang
  0 siblings, 1 reply; 26+ messages in thread
From: Sricharan @ 2016-01-28  4:57 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

Hi Wolfram,

> -----Original Message-----
> From: Wolfram Sang [mailto:wsa@the-dreams.de]
> Sent: Sunday, January 24, 2016 4:59 PM
> To: Sricharan R
> Cc: devicetree@vger.kernel.org; linux-arm-msm@vger.kernel.org;
> agross@codeaurora.org; linux-kernel@vger.kernel.org; linux-
> i2c@vger.kernel.org; iivanov@mm-sol.com; galak@codeaurora.org;
> dmaengine@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> andy.gross@linaro.org; ntelkar@codeaurora.org; architt@codeaurora.org
> Subject: Re: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs
> without a stop bit
> 
> Hi,
> 
> > "If this is the last message in a group, it is followed by a STOP.
> > Otherwise it is followed by the next @i2c_msg transaction segment,
> > beginning with a (repeated) START"
> 
> This is correct.
> 
> > So the expectation is that there is no 'STOP' bit inbetween individual
> > i2c_msg segments with repeated 'START'. The QUP i2c hardware has no
> > way to inform that there should not be a 'STOP' at the end of
transaction.
> > The only way to implement this is to coalesce all the i2c_msg in
> > i2c_msgs in to one transaction and transfer them. Adding the support for
> the same.
> 
> So, there will not be a REP_START condition on the bus? I am sorry to say
that
> I can't accept this. A REP_START is a REP_START and nothing else. There
are
> devices which will get confused if there is no real REP_START condition.
> 
> Without knowing the HW in detail, can't you implement I2C_M_NOSTART
> and let the touchscreen driver use it via regmap? That would be the proper
> way (from what I understand).


Ah, so what I meant above is there is no 'STOP' bit between each msg in
i2c_msgs, 
but 'REAPEATED_START' still holds true.  We are sending 'START' bit for each
msg.
So these is how each msg in i2c_msg is sent,

|------MSG1--------|-----MSG2---------|------MSG3------------|

  |START|DATA|------|START|DATA|---|START|DATA|STOP|      

If my commit text does not make this clear, I  can reword that ?

Regards,
  Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
  2016-01-24 11:33   ` Wolfram Sang
@ 2016-01-28  5:27     ` Sricharan
  0 siblings, 0 replies; 26+ messages in thread
From: Sricharan @ 2016-01-28  5:27 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, architt, linux-arm-msm, ntelkar, agross, linux-kernel,
	dmaengine, linux-i2c, iivanov, galak, andy.gross,
	linux-arm-kernel

Hi Wolfram,

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces@lists.infradead.org] On Behalf Of Wolfram Sang
> Sent: Sunday, January 24, 2016 5:03 PM
> To: Sricharan
> Cc: devicetree@vger.kernel.org; architt@codeaurora.org; linux-arm-
> msm@vger.kernel.org; ntelkar@codeaurora.org; agross@codeaurora.org;
> linux-kernel@vger.kernel.org; dmaengine@vger.kernel.org; linux-
> i2c@vger.kernel.org; iivanov@mm-sol.com; galak@codeaurora.org;
> andy.gross@linaro.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma
> 
> > > Sricharan R (6):
> > >   i2c: qup: Change qup_wait_writeready function to use for all
timeouts
> > >   i2c: qup: Add V2 tags support
> > >   i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
> > >   i2c: qup: Add bam dma capabilities
> > >   dts: msm8974: Add blsp2_bam dma node
> > >   dts: msm8974: Add dma channels for blsp2_i2c1 node
> > >
> >  Wolfram,  Does the first 4 patches looks good to be picked up  ?
> 
> Except for patch 3 (I replied seperately), the rest looks okay to me. I
> wondered a little if it would make sense to make a new driver for v2 +
DMA,
> because the additions were quite massive. But I'll leave it up to you if
there is
> enough shared code between the two versions, so that a single driver will
be
> better.
     Hmm,  addition of V2 reused code, more than 50% addition of new loc in
this series, lot of it from DMA,
     but at this point it feels ok to have it in a single driver. 

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-01-28  4:57     ` Sricharan
@ 2016-02-04 20:09       ` Wolfram Sang
  2016-02-05  8:00         ` Sricharan
  0 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2016-02-04 20:09 UTC (permalink / raw)
  To: Sricharan
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]

Hi,

> Ah, so what I meant above is there is no 'STOP' bit between each msg in
> i2c_msgs,
> but 'REAPEATED_START' still holds true.  We are sending 'START' bit for each
> msg.
> So these is how each msg in i2c_msg is sent,
>
> |------MSG1--------|-----MSG2---------|------MSG3------------|
>
>   |START|DATA|------|START|DATA|---|START|DATA|STOP|
>
> If my commit text does not make this clear, I  can reword that ?

OK, now this looks to me perfectly fine: A number of *messages*
concatenated into one *transfer* by repeated start. That's the way it
should be.

So, I'd simply remove these words:

"The QUP i2c hardware has no way to inform that there should not be a
'STOP' at the end of transaction. The only way to implement this is to
coalesce all the i2c_msg in i2c_msgs in to one transaction and transfer
them."

This sounded like the HW needed a special handling, so I was under the
impression REP_START was broken. However, unless I misunderstood
something again, this now sounds like the standard case and we can keep
the commit message simple. If you are okay with that, I can update it
here, no need to resend.

Thanks,

   Wolfram

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-02-04 20:09       ` Wolfram Sang
@ 2016-02-05  8:00         ` Sricharan
  0 siblings, 0 replies; 26+ messages in thread
From: Sricharan @ 2016-02-05  8:00 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, architt, linux-arm-msm, ntelkar, galak, linux-kernel,
	andy.gross, linux-i2c, iivanov, agross, dmaengine,
	linux-arm-kernel

Hi Wolfram,

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces@lists.infradead.org] On Behalf Of Wolfram Sang
> Sent: Friday, February 05, 2016 1:39 AM
> To: Sricharan
> Cc: devicetree@vger.kernel.org; architt@codeaurora.org; linux-arm-
> msm@vger.kernel.org; ntelkar@codeaurora.org; galak@codeaurora.org;
> linux-kernel@vger.kernel.org; andy.gross@linaro.org; linux-
> i2c@vger.kernel.org; iivanov@mm-sol.com; agross@codeaurora.org;
> dmaengine@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs
> without a stop bit
> 
> Hi,
> 
> > Ah, so what I meant above is there is no 'STOP' bit between each msg
> > in i2c_msgs, but 'REAPEATED_START' still holds true.  We are sending
> > 'START' bit for each msg.
> > So these is how each msg in i2c_msg is sent,
> >
> > |------MSG1--------|-----MSG2---------|------MSG3------------|
> >
> >   |START|DATA|------|START|DATA|---|START|DATA|STOP|
> >
> > If my commit text does not make this clear, I  can reword that ?
> 
> OK, now this looks to me perfectly fine: A number of *messages*
> concatenated into one *transfer* by repeated start. That's the way it
should
> be.
> 
> So, I'd simply remove these words:
> 
> "The QUP i2c hardware has no way to inform that there should not be a
> 'STOP' at the end of transaction. The only way to implement this is to
> coalesce all the i2c_msg in i2c_msgs in to one transaction and transfer
them."
> 
> This sounded like the HW needed a special handling, so I was under the
> impression REP_START was broken. However, unless I misunderstood
> something again, this now sounds like the standard case and we can keep
> the commit message simple. If you are okay with that, I can update it
here,
> no need to resend.
> 
      Yes the above modified commit text looks perfect to be updated and
thanks
      for the update as well.

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-01-19 10:02 ` [PATCH V7 4/6] i2c: qup: Add bam dma capabilities Sricharan R
@ 2016-02-12 18:37   ` Wolfram Sang
  2016-02-12 18:42     ` Wolfram Sang
                       ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Wolfram Sang @ 2016-02-12 18:37 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 1770 bytes --]

On Tue, Jan 19, 2016 at 03:32:44PM +0530, Sricharan R wrote:
> QUP cores can be attached to a BAM module, which acts as
> a dma engine for the QUP core. When DMA with BAM is enabled,
> the BAM consumer pipe transmitted data is written to the
> output FIFO and the BAM producer pipe received data is read
> from the input FIFO.
> 
> With BAM capabilities, qup-i2c core can transfer more than
> 256 bytes, without a 'stop' which is not possible otherwise.
> 
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Reviewed-by: Andy Gross <andy.gross@linaro.org>
> Tested-by: Archit Taneja <architt@codeaurora.org>
> Tested-by: Telkar Nagender <ntelkar@codeaurora.org>

My code checkers found some issues:

    SPARSE
drivers/i2c/busses/i2c-qup.c:555:6: warning: symbol 'qup_sg_set_buf' was not declared. Should it be static?
drivers/i2c/busses/i2c-qup.c:1243:50: warning: dubious: !x & !y
    SMATCH
drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s = sg_next()
drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s = sg_next()
drivers/i2c/busses/i2c-qup.c:1243 qup_i2c_xfer_v2() warn: add some parenthesis here?
    CPPCHECK
drivers/i2c/busses/i2c-qup.c:1243: style: Boolean result is used in bitwise operation. Clarify expression with parentheses.
    SPATCH
drivers/i2c/busses/i2c-qup.c:1380:2-13: WARNING: Assignment of bool to 0/1
drivers/i2c/busses/i2c-qup.c:1481:1-13: WARNING: Assignment of bool to 0/1
  CC      drivers/i2c/busses/i2c-qup.o
drivers/i2c/busses/i2c-qup.c:555:6: warning: no previous prototype for 'qup_sg_set_buf' [-Wmissing-prototypes]
 void qup_sg_set_buf(struct scatterlist *sg, void *buf, struct qup_i2c_tag *tg,

Can you fix them and resend??

Thanks,

   Wolfram

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts
  2016-01-19 10:02 ` [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts Sricharan R
@ 2016-02-12 18:37   ` Wolfram Sang
  0 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2016-02-12 18:37 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 550 bytes --]

On Tue, Jan 19, 2016 at 03:32:41PM +0530, Sricharan R wrote:
> qup_wait_writeready waits only on a output fifo empty event.
> Change the same function to accept the event and data length
> to wait as parameters. This way the same function can be used for
> timeouts in other places as well.
> 
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Reviewed-by: Andy Gross <andy.gross@linaro.org>
> Tested-by: Archit Taneja <architt@codeaurora.org>
> Tested-by: Telkar Nagender <ntelkar@codeaurora.org>

Applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 2/6] i2c: qup: Add V2 tags support
  2016-01-19 10:02 ` [PATCH V7 2/6] i2c: qup: Add V2 tags support Sricharan R
@ 2016-02-12 18:37   ` Wolfram Sang
  0 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2016-02-12 18:37 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

On Tue, Jan 19, 2016 at 03:32:42PM +0530, Sricharan R wrote:
> QUP from version 2.1.1 onwards, supports a new format of
> i2c command tags. Tag codes instructs the controller to
> perform a operation like read/write. This new tagging version
> supports bam dma and transfers of more than 256 bytes without 'stop'
> in between. Adding the support for the same.
> 
> For each block a data_write/read tag and data_len tag is added to
> the output fifo. For the final block of data write_stop/read_stop
> tag is used.
> 
> Signed-off-by: Andy Gross <andy.gross@linaro.org>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Tested-by: Archit Taneja <architt@codeaurora.org>
> Tested-by: Telkar Nagender <ntelkar@codeaurora.org>

Applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  2016-01-19 10:02 ` [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit Sricharan R
  2016-01-24 11:29   ` Wolfram Sang
@ 2016-02-12 18:38   ` Wolfram Sang
  1 sibling, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2016-02-12 18:38 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 1195 bytes --]

On Tue, Jan 19, 2016 at 03:32:43PM +0530, Sricharan R wrote:
> The definition of i2c_msg says that
> 
> "If this is the last message in a group, it is followed by a STOP.
> Otherwise it is followed by the next @i2c_msg transaction segment,
> beginning with a (repeated) START"
> 
> So the expectation is that there is no 'STOP' bit inbetween individual
> i2c_msg segments with repeated 'START'. The QUP i2c hardware has no way
> to inform that there should not be a 'STOP' at the end of transaction.
> The only way to implement this is to coalesce all the i2c_msg in i2c_msgs
> in to one transaction and transfer them. Adding the support for the same.
> 
> This is required for some clients like touchscreen which keeps
> incrementing counts across individual transfers and 'STOP' bit inbetween
> resets the counter, which is not required.
> 
> This patch adds the support in non-dma mode.
> 
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Reviewed-by: Andy Gross <andy.gross@linaro.org>
> Tested-by: Archit Taneja <architt@codeaurora.org>
> Tested-by: Telkar Nagender <ntelkar@codeaurora.org>

Shortened the commit message and applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-02-12 18:37   ` Wolfram Sang
@ 2016-02-12 18:42     ` Wolfram Sang
  2016-02-13  6:58     ` Sricharan
  2016-02-22 12:24     ` Sricharan
  2 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2016-02-12 18:42 UTC (permalink / raw)
  To: Sricharan R
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 78 bytes --]

> Can you fix them and resend??

That should have been only one '?', sorry.



[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-02-12 18:37   ` Wolfram Sang
  2016-02-12 18:42     ` Wolfram Sang
@ 2016-02-13  6:58     ` Sricharan
  2016-02-22 12:24     ` Sricharan
  2 siblings, 0 replies; 26+ messages in thread
From: Sricharan @ 2016-02-13  6:58 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

Hi Wolfram,

> -----Original Message-----
> From: Wolfram Sang [mailto:wsa@the-dreams.de]
> Sent: Saturday, February 13, 2016 12:08 AM
> To: Sricharan R
> Cc: devicetree@vger.kernel.org; linux-arm-msm@vger.kernel.org;
> agross@codeaurora.org; linux-kernel@vger.kernel.org; linux-
> i2c@vger.kernel.org; iivanov@mm-sol.com; galak@codeaurora.org;
> dmaengine@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> andy.gross@linaro.org; ntelkar@codeaurora.org; architt@codeaurora.org
> Subject: Re: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
> 
> On Tue, Jan 19, 2016 at 03:32:44PM +0530, Sricharan R wrote:
> > QUP cores can be attached to a BAM module, which acts as a dma engine
> > for the QUP core. When DMA with BAM is enabled, the BAM consumer
> pipe
> > transmitted data is written to the output FIFO and the BAM producer
> > pipe received data is read from the input FIFO.
> >
> > With BAM capabilities, qup-i2c core can transfer more than
> > 256 bytes, without a 'stop' which is not possible otherwise.
> >
> > Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> > Reviewed-by: Andy Gross <andy.gross@linaro.org>
> > Tested-by: Archit Taneja <architt@codeaurora.org>
> > Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
> 
> My code checkers found some issues:
> 
>     SPARSE
> drivers/i2c/busses/i2c-qup.c:555:6: warning: symbol 'qup_sg_set_buf' was
> not declared. Should it be static?
> drivers/i2c/busses/i2c-qup.c:1243:50: warning: dubious: !x & !y
>     SMATCH
> drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s =
> sg_next()
> drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s =
> sg_next()
> drivers/i2c/busses/i2c-qup.c:1243 qup_i2c_xfer_v2() warn: add some
> parenthesis here?
>     CPPCHECK
> drivers/i2c/busses/i2c-qup.c:1243: style: Boolean result is used in
bitwise
> operation. Clarify expression with parentheses.
>     SPATCH
> drivers/i2c/busses/i2c-qup.c:1380:2-13: WARNING: Assignment of bool to 0/1
> drivers/i2c/busses/i2c-qup.c:1481:1-13: WARNING: Assignment of bool to 0/1
>   CC      drivers/i2c/busses/i2c-qup.o
> drivers/i2c/busses/i2c-qup.c:555:6: warning: no previous prototype for
> 'qup_sg_set_buf' [-Wmissing-prototypes]  void qup_sg_set_buf(struct
> scatterlist *sg, void *buf, struct qup_i2c_tag *tg,
> 
> Can you fix them and resend??

    Sorry on this , will resend this patch.

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-02-12 18:37   ` Wolfram Sang
  2016-02-12 18:42     ` Wolfram Sang
  2016-02-13  6:58     ` Sricharan
@ 2016-02-22 12:24     ` Sricharan
  2016-02-22 12:32       ` Wolfram Sang
  2 siblings, 1 reply; 26+ messages in thread
From: Sricharan @ 2016-02-22 12:24 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

Hi Wolfram,

> -----Original Message-----
> From: Sricharan [mailto:sricharan@codeaurora.org]
> Sent: Saturday, February 13, 2016 12:29 PM
> To: 'Wolfram Sang'
> Cc: 'devicetree@vger.kernel.org'; 'linux-arm-msm@vger.kernel.org';
> 'agross@codeaurora.org'; 'linux-kernel@vger.kernel.org'; 'linux-
> i2c@vger.kernel.org'; 'iivanov@mm-sol.com'; 'galak@codeaurora.org';
> 'dmaengine@vger.kernel.org'; 'linux-arm-kernel@lists.infradead.org';
> 'andy.gross@linaro.org'; 'ntelkar@codeaurora.org';
'architt@codeaurora.org'
> Subject: RE: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
> 
> Hi Wolfram,
> 
> > -----Original Message-----
> > From: Wolfram Sang [mailto:wsa@the-dreams.de]
> > Sent: Saturday, February 13, 2016 12:08 AM
> > To: Sricharan R
> > Cc: devicetree@vger.kernel.org; linux-arm-msm@vger.kernel.org;
> > agross@codeaurora.org; linux-kernel@vger.kernel.org; linux-
> > i2c@vger.kernel.org; iivanov@mm-sol.com; galak@codeaurora.org;
> > dmaengine@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > andy.gross@linaro.org; ntelkar@codeaurora.org; architt@codeaurora.org
> > Subject: Re: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
> >
> > On Tue, Jan 19, 2016 at 03:32:44PM +0530, Sricharan R wrote:
> > > QUP cores can be attached to a BAM module, which acts as a dma
> > > engine for the QUP core. When DMA with BAM is enabled, the BAM
> > > consumer
> > pipe
> > > transmitted data is written to the output FIFO and the BAM producer
> > > pipe received data is read from the input FIFO.
> > >
> > > With BAM capabilities, qup-i2c core can transfer more than
> > > 256 bytes, without a 'stop' which is not possible otherwise.
> > >
> > > Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> > > Reviewed-by: Andy Gross <andy.gross@linaro.org>
> > > Tested-by: Archit Taneja <architt@codeaurora.org>
> > > Tested-by: Telkar Nagender <ntelkar@codeaurora.org>
> >
> > My code checkers found some issues:
> >
> >     SPARSE
> > drivers/i2c/busses/i2c-qup.c:555:6: warning: symbol 'qup_sg_set_buf'
> > was not declared. Should it be static?
> > drivers/i2c/busses/i2c-qup.c:1243:50: warning: dubious: !x & !y
> >     SMATCH
> > drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s
> > =
> > sg_next()
> > drivers/i2c/busses/i2c-qup.c:165 qup_sg_set_buf warn: unused return: s
> > =
> > sg_next()
> > drivers/i2c/busses/i2c-qup.c:1243 qup_i2c_xfer_v2() warn: add some
> > parenthesis here?
> >     CPPCHECK
> > drivers/i2c/busses/i2c-qup.c:1243: style: Boolean result is used in
> > bitwise operation. Clarify expression with parentheses.
> >     SPATCH
> > drivers/i2c/busses/i2c-qup.c:1380:2-13: WARNING: Assignment of bool to
> > 0/1
> > drivers/i2c/busses/i2c-qup.c:1481:1-13: WARNING: Assignment of bool to
> 0/1
> >   CC      drivers/i2c/busses/i2c-qup.o
> > drivers/i2c/busses/i2c-qup.c:555:6: warning: no previous prototype for
> > 'qup_sg_set_buf' [-Wmissing-prototypes]  void qup_sg_set_buf(struct
> > scatterlist *sg, void *buf, struct qup_i2c_tag *tg,
> >
> > Can you fix them and resend??
> 
  Really sorry for the delay ,  sent it here [1]

  Also, while testing this series in one of a new platform, found that an
additional 
  Regression and a fix is required on top of this series. So can I send a
separate fix on top of this series ?


[1]   https://patchwork.ozlabs.org/patch/586125/

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-02-22 12:24     ` Sricharan
@ 2016-02-22 12:32       ` Wolfram Sang
  2016-02-22 13:41         ` Sricharan
  0 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2016-02-22 12:32 UTC (permalink / raw)
  To: Sricharan
  Cc: devicetree, linux-arm-msm, agross, linux-kernel, linux-i2c,
	iivanov, galak, dmaengine, linux-arm-kernel, andy.gross, ntelkar,
	architt

[-- Attachment #1: Type: text/plain, Size: 188 bytes --]


>   Regression and a fix is required on top of this series. So can I send a
> separate fix on top of this series ?

Yes, do it like this. And please quote only relevant parts of a mail.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 4/6] i2c: qup: Add bam dma capabilities
  2016-02-22 12:32       ` Wolfram Sang
@ 2016-02-22 13:41         ` Sricharan
  0 siblings, 0 replies; 26+ messages in thread
From: Sricharan @ 2016-02-22 13:41 UTC (permalink / raw)
  To: 'Wolfram Sang'
  Cc: devicetree, architt, linux-arm-msm, ntelkar, galak, linux-kernel,
	andy.gross, linux-i2c, iivanov, agross, dmaengine,
	linux-arm-kernel

Hi Wolfram,

> >   Regression and a fix is required on top of this series. So can I
> > send a separate fix on top of this series ?
> 
> Yes, do it like this. And please quote only relevant parts of a mail.
   Ok, will send a fix separately.   Sorry for the noisy reply previously ..


Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node
  2016-01-19 10:02 ` [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node Sricharan R
@ 2016-03-25 23:17   ` Bjorn Andersson
  2016-03-26  2:26     ` Andy Gross
  0 siblings, 1 reply; 26+ messages in thread
From: Bjorn Andersson @ 2016-03-25 23:17 UTC (permalink / raw)
  To: Sricharan R
  Cc: Wolfram Sang, devicetree@vger.kernel.org, linux-arm-msm,
	Andy Gross, linux-kernel@vger.kernel.org,
	linux-i2c@vger.kernel.org, Ivan T. Ivanov, Kumar Gala, dmaengine,
	linux-arm-kernel@lists.infradead.org, Andy Gross, ntelkar,
	Archit Taneja

On Tue, Jan 19, 2016 at 2:02 AM, Sricharan R <sricharan@codeaurora.org> wrote:
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Reviewed-by: Andy Gross <andy.gross@linaro.org>
> ---
>  arch/arm/boot/dts/qcom-msm8974.dtsi | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
> index 753bdfd..7786408 100644
> --- a/arch/arm/boot/dts/qcom-msm8974.dtsi
> +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
> @@ -1,6 +1,6 @@
>  /dts-v1/;
>
> -#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/clock/qcom,gcc-msm8974.h>
>  #include "skeleton.dtsi"
>
> @@ -345,6 +345,16 @@
>                         interrupt-controller;
>                         #interrupt-cells = <4>;
>                 };
> +
> +               blsp2_dma: dma-controller@f9944000 {
> +                       compatible = "qcom,bam-v1.4.0";
> +                       reg = <0xf9944000 0x19000>;
> +                       interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&gcc GCC_BLSP2_AHB_CLK>;
> +                       clock-names = "bam_clk";
> +                       #dma-cells = <1>;
> +                       qcom,ee = <0>;

Without "qcom,bam_ctrl_remote;" and
https://patchwork.kernel.org/patch/8639181/ the Xperia Honami board
fails to boot with this patch included.

> +               };
>         };
>

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node
  2016-03-25 23:17   ` Bjorn Andersson
@ 2016-03-26  2:26     ` Andy Gross
  2016-03-28 12:59       ` Sricharan
  0 siblings, 1 reply; 26+ messages in thread
From: Andy Gross @ 2016-03-26  2:26 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Sricharan R, Wolfram Sang, devicetree@vger.kernel.org,
	linux-arm-msm, Andy Gross, linux-kernel@vger.kernel.org,
	linux-i2c@vger.kernel.org, Ivan T. Ivanov, Kumar Gala, dmaengine,
	linux-arm-kernel@lists.infradead.org, ntelkar, Archit Taneja

On Fri, Mar 25, 2016 at 04:17:30PM -0700, Bjorn Andersson wrote:
> On Tue, Jan 19, 2016 at 2:02 AM, Sricharan R <sricharan@codeaurora.org> wrote:
> > Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> > Reviewed-by: Andy Gross <andy.gross@linaro.org>

<snip>

> > +               blsp2_dma: dma-controller@f9944000 {
> > +                       compatible = "qcom,bam-v1.4.0";
> > +                       reg = <0xf9944000 0x19000>;
> > +                       interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
> > +                       clocks = <&gcc GCC_BLSP2_AHB_CLK>;
> > +                       clock-names = "bam_clk";
> > +                       #dma-cells = <1>;
> > +                       qcom,ee = <0>;
> 
> Without "qcom,bam_ctrl_remote;" and
> https://patchwork.kernel.org/patch/8639181/ the Xperia Honami board
> fails to boot with this patch included.

Ouch.  At least one set of pipes must be used by some other processor and TZ has
locked down that BLSP.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node
  2016-03-26  2:26     ` Andy Gross
@ 2016-03-28 12:59       ` Sricharan
  0 siblings, 0 replies; 26+ messages in thread
From: Sricharan @ 2016-03-28 12:59 UTC (permalink / raw)
  To: 'Andy Gross', 'Bjorn Andersson'
  Cc: devicetree, 'Archit Taneja', 'Wolfram Sang',
	'linux-arm-msm', ntelkar, 'Kumar Gala',
	linux-kernel, linux-i2c, 'Ivan T. Ivanov',
	'Andy Gross', dmaengine, linux-arm-kernel

> On Fri, Mar 25, 2016 at 04:17:30PM -0700, Bjorn Andersson wrote:
> > On Tue, Jan 19, 2016 at 2:02 AM, Sricharan R <sricharan@codeaurora.org>
> wrote:
> > > Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> > > Reviewed-by: Andy Gross <andy.gross@linaro.org>
> 
> <snip>
> 
> > > +               blsp2_dma: dma-controller@f9944000 {
> > > +                       compatible = "qcom,bam-v1.4.0";
> > > +                       reg = <0xf9944000 0x19000>;
> > > +                       interrupts = <GIC_SPI 239
IRQ_TYPE_LEVEL_HIGH>;
> > > +                       clocks = <&gcc GCC_BLSP2_AHB_CLK>;
> > > +                       clock-names = "bam_clk";
> > > +                       #dma-cells = <1>;
> > > +                       qcom,ee = <0>;
> >
> > Without "qcom,bam_ctrl_remote;" and
> > https://patchwork.kernel.org/patch/8639181/ the Xperia Honami board
> > fails to boot with this patch included.
> 
> Ouch.  At least one set of pipes must be used by some other processor and
> TZ has locked down that BLSP.

 Hmm, this was not the case atleast on the apq8074DB board that I tested
this on.

Regards,
 Sricharan

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2016-03-28 12:59 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-19 10:02 [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan R
2016-01-19 10:02 ` [PATCH V7 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts Sricharan R
2016-02-12 18:37   ` Wolfram Sang
2016-01-19 10:02 ` [PATCH V7 2/6] i2c: qup: Add V2 tags support Sricharan R
2016-02-12 18:37   ` Wolfram Sang
2016-01-19 10:02 ` [PATCH V7 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit Sricharan R
2016-01-24 11:29   ` Wolfram Sang
2016-01-28  4:57     ` Sricharan
2016-02-04 20:09       ` Wolfram Sang
2016-02-05  8:00         ` Sricharan
2016-02-12 18:38   ` Wolfram Sang
2016-01-19 10:02 ` [PATCH V7 4/6] i2c: qup: Add bam dma capabilities Sricharan R
2016-02-12 18:37   ` Wolfram Sang
2016-02-12 18:42     ` Wolfram Sang
2016-02-13  6:58     ` Sricharan
2016-02-22 12:24     ` Sricharan
2016-02-22 12:32       ` Wolfram Sang
2016-02-22 13:41         ` Sricharan
2016-01-19 10:02 ` [PATCH V7 5/6] dts: msm8974: Add blsp2_bam dma node Sricharan R
2016-03-25 23:17   ` Bjorn Andersson
2016-03-26  2:26     ` Andy Gross
2016-03-28 12:59       ` Sricharan
2016-01-19 10:02 ` [PATCH V7 6/6] dts: msm8974: Add dma channels for blsp2_i2c1 node Sricharan R
2016-01-19 10:14 ` [PATCH V7 0/6] i2c: qup: Add support for v2 tags and bam dma Sricharan
2016-01-24 11:33   ` Wolfram Sang
2016-01-28  5:27     ` Sricharan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).