linux-i3c.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode
@ 2019-06-19 18:36 Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 1/3] i3c: fix i2c and i3c scl rate by " Vitor Soares
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Vitor Soares @ 2019-06-19 18:36 UTC (permalink / raw)
  To: linux-i3c, Joao.Pinto; +Cc: Vitor Soares

This patch series fix the i2c and i3c scl rate according the bus mode
and LVR register. It also introduce the mixed limited bus for the
cases where i2c devices doesn't have 50 ns filter but allow higher
clock rate for i3c transfers.
Please refer table 5 and 10 of i3c bus spec v1.0 for more detail.

Please follow each patch commit message for more details and changes
made in this version.

Vitor Soares (3):
  i3c: fix i2c and i3c scl rate by bus mode
  i3c: add mixed limited bus mode
  i3c: dw: add limited bus mode support

 drivers/i3c/master.c               | 57 +++++++++++++++++++++++++++++---------
 drivers/i3c/master/dw-i3c-master.c |  1 +
 include/linux/i3c/master.h         |  5 ++++
 3 files changed, 50 insertions(+), 13 deletions(-)

-- 
2.7.4


_______________________________________________
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

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

* [PATCH v4 1/3] i3c: fix i2c and i3c scl rate by bus mode
  2019-06-19 18:36 [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Vitor Soares
@ 2019-06-19 18:36 ` Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 2/3] i3c: add mixed limited " Vitor Soares
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Vitor Soares @ 2019-06-19 18:36 UTC (permalink / raw)
  To: linux-i3c, Joao.Pinto; +Cc: Boris Brezillon, linux-kernel, stable, Vitor Soares

Currently the I3C framework limits SCL frequency to FM speed when
dealing with a mixed slow bus, even if all I2C devices are FM+ capable.

The core was also not accounting for I3C speed limitations when
operating in mixed slow mode and was erroneously using FM+ speed as the
max I2C speed when operating in mixed fast mode.

Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Signed-off-by: Vitor Soares <vitor.soares@synopsys.com>
Cc: Boris Brezillon <bbrezillon@kernel.org>
Cc: <stable@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>
---
Changes in v4:
  Print i2c-scl and i3c-scl unconditionally when in debug mode

Changes in v3:
  Change dev_warn() to dev_dbg()

Changes in v2:
  Enhance commit message
  Add dev_warn() in case user-defined i2c rate doesn't match LVR constraint
  Add dev_warn() in case user-defined i3c rate lower than i2c rate

 drivers/i3c/master.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 5f4bd52..14980db 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -91,6 +91,12 @@ void i3c_bus_normaluse_unlock(struct i3c_bus *bus)
 	up_read(&bus->lock);
 }
 
+static struct i3c_master_controller *
+i3c_bus_to_i3c_master(struct i3c_bus *i3cbus)
+{
+	return container_of(i3cbus, struct i3c_master_controller, bus);
+}
+
 static struct i3c_master_controller *dev_to_i3cmaster(struct device *dev)
 {
 	return container_of(dev, struct i3c_master_controller, dev);
@@ -565,20 +571,39 @@ static const struct device_type i3c_masterdev_type = {
 	.groups	= i3c_masterdev_groups,
 };
 
-int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode)
+int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
+		     unsigned long max_i2c_scl_rate)
 {
-	i3cbus->mode = mode;
 
-	if (!i3cbus->scl_rate.i3c)
-		i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+	struct i3c_master_controller *master = i3c_bus_to_i3c_master(i3cbus);
 
-	if (!i3cbus->scl_rate.i2c) {
-		if (i3cbus->mode == I3C_BUS_MODE_MIXED_SLOW)
-			i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE;
-		else
-			i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_PLUS_SCL_RATE;
+	i3cbus->mode = mode;
+
+	switch (i3cbus->mode) {
+	case I3C_BUS_MODE_PURE:
+		if (!i3cbus->scl_rate.i3c)
+			i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+		break;
+	case I3C_BUS_MODE_MIXED_FAST:
+		if (!i3cbus->scl_rate.i3c)
+			i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
+		if (!i3cbus->scl_rate.i2c)
+			i3cbus->scl_rate.i2c = max_i2c_scl_rate;
+		break;
+	case I3C_BUS_MODE_MIXED_SLOW:
+		if (!i3cbus->scl_rate.i2c)
+			i3cbus->scl_rate.i2c = max_i2c_scl_rate;
+		if (!i3cbus->scl_rate.i3c ||
+		    i3cbus->scl_rate.i3c > i3cbus->scl_rate.i2c)
+			i3cbus->scl_rate.i3c = i3cbus->scl_rate.i2c;
+		break;
+	default:
+		return -EINVAL;
 	}
 
+	dev_dbg(&master->dev, "i2c-scl = %ld Hz i3c-scl = %ld Hz\n",
+		i3cbus->scl_rate.i2c, i3cbus->scl_rate.i3c);
+
 	/*
 	 * I3C/I2C frequency may have been overridden, check that user-provided
 	 * values are not exceeding max possible frequency.
@@ -1966,9 +1991,6 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
 	/* LVR is encoded in reg[2]. */
 	boardinfo->lvr = reg[2];
 
-	if (boardinfo->lvr & I3C_LVR_I2C_FM_MODE)
-		master->bus.scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE;
-
 	list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
 	of_node_get(node);
 
@@ -2417,6 +2439,7 @@ int i3c_master_register(struct i3c_master_controller *master,
 			const struct i3c_master_controller_ops *ops,
 			bool secondary)
 {
+	unsigned long i2c_scl_rate = I3C_BUS_I2C_FM_PLUS_SCL_RATE;
 	struct i3c_bus *i3cbus = i3c_master_get_bus(master);
 	enum i3c_bus_mode mode = I3C_BUS_MODE_PURE;
 	struct i2c_dev_boardinfo *i2cbi;
@@ -2466,9 +2489,12 @@ int i3c_master_register(struct i3c_master_controller *master,
 			ret = -EINVAL;
 			goto err_put_dev;
 		}
+
+		if (i2cbi->lvr & I3C_LVR_I2C_FM_MODE)
+			i2c_scl_rate = I3C_BUS_I2C_FM_SCL_RATE;
 	}
 
-	ret = i3c_bus_set_mode(i3cbus, mode);
+	ret = i3c_bus_set_mode(i3cbus, mode, i2c_scl_rate);
 	if (ret)
 		goto err_put_dev;
 
-- 
2.7.4


_______________________________________________
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

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

* [PATCH v4 2/3] i3c: add mixed limited bus mode
  2019-06-19 18:36 [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 1/3] i3c: fix i2c and i3c scl rate by " Vitor Soares
@ 2019-06-19 18:36 ` Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 3/3] i3c: dw: add limited bus mode support Vitor Soares
  2019-06-20  8:56 ` [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Boris Brezillon
  3 siblings, 0 replies; 5+ messages in thread
From: Vitor Soares @ 2019-06-19 18:36 UTC (permalink / raw)
  To: linux-i3c, Joao.Pinto; +Cc: Boris Brezillon, linux-kernel, Vitor Soares

The i3c bus spec defines a bus configuration where i2c devices don't
have a 50ns filter but support SCL running at SDR max rate (12.5MHz).

This patch introduces the limited bus mode so that users can use
a higher speed in presence of i2c devices index 1.

Signed-off-by: Vitor Soares <vitor.soares@synopsys.com>
Cc: Boris Brezillon <bbrezillon@kernel.org>
Cc: <linux-kernel@vger.kernel.org>
---
Changes in v4:
  None

Changes in v3:
  None

Changes in v2:
  Enhance commit message

 drivers/i3c/master.c       | 5 +++++
 include/linux/i3c/master.h | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 14980db..76549f1 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -470,6 +470,7 @@ static int i3c_bus_init(struct i3c_bus *i3cbus)
 static const char * const i3c_bus_mode_strings[] = {
 	[I3C_BUS_MODE_PURE] = "pure",
 	[I3C_BUS_MODE_MIXED_FAST] = "mixed-fast",
+	[I3C_BUS_MODE_MIXED_LIMITED] = "mixed-limited",
 	[I3C_BUS_MODE_MIXED_SLOW] = "mixed-slow",
 };
 
@@ -585,6 +586,7 @@ int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
 			i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
 		break;
 	case I3C_BUS_MODE_MIXED_FAST:
+	case I3C_BUS_MODE_MIXED_LIMITED:
 		if (!i3cbus->scl_rate.i3c)
 			i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
 		if (!i3cbus->scl_rate.i2c)
@@ -2481,6 +2483,9 @@ int i3c_master_register(struct i3c_master_controller *master,
 				mode = I3C_BUS_MODE_MIXED_FAST;
 			break;
 		case I3C_LVR_I2C_INDEX(1):
+			if (mode < I3C_BUS_MODE_MIXED_LIMITED)
+				mode = I3C_BUS_MODE_MIXED_LIMITED;
+			break;
 		case I3C_LVR_I2C_INDEX(2):
 			if (mode < I3C_BUS_MODE_MIXED_SLOW)
 				mode = I3C_BUS_MODE_MIXED_SLOW;
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index f13fd8b..89ea461 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -250,12 +250,17 @@ struct i3c_device {
  *			     the bus. The only impact in this mode is that the
  *			     high SCL pulse has to stay below 50ns to trick I2C
  *			     devices when transmitting I3C frames
+ * @I3C_BUS_MODE_MIXED_LIMITED: I2C devices without 50ns spike filter are
+ *				present on the bus. However they allows
+ *				compliance up to the maximum SDR SCL clock
+ *				frequency.
  * @I3C_BUS_MODE_MIXED_SLOW: I2C devices without 50ns spike filter are present
  *			     on the bus
  */
 enum i3c_bus_mode {
 	I3C_BUS_MODE_PURE,
 	I3C_BUS_MODE_MIXED_FAST,
+	I3C_BUS_MODE_MIXED_LIMITED,
 	I3C_BUS_MODE_MIXED_SLOW,
 };
 
-- 
2.7.4


_______________________________________________
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

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

* [PATCH v4 3/3] i3c: dw: add limited bus mode support
  2019-06-19 18:36 [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 1/3] i3c: fix i2c and i3c scl rate by " Vitor Soares
  2019-06-19 18:36 ` [PATCH v4 2/3] i3c: add mixed limited " Vitor Soares
@ 2019-06-19 18:36 ` Vitor Soares
  2019-06-20  8:56 ` [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Boris Brezillon
  3 siblings, 0 replies; 5+ messages in thread
From: Vitor Soares @ 2019-06-19 18:36 UTC (permalink / raw)
  To: linux-i3c, Joao.Pinto; +Cc: Boris Brezillon, linux-kernel, Vitor Soares

This patch add limited bus mode support for DesignWare i3c master

Signed-off-by: Vitor Soares <vitor.soares@synopsys.com>
Cc: Boris Brezillon <bbrezillon@kernel.org>
Cc: <linux-kernel@vger.kernel.org>
---
Changes in v4:
  None

Changes in v3:
  None

Changes in v2:
  None

 drivers/i3c/master/dw-i3c-master.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 1d83c97..9612d93 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -599,6 +599,7 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
 
 	switch (bus->mode) {
 	case I3C_BUS_MODE_MIXED_FAST:
+	case I3C_BUS_MODE_MIXED_LIMITED:
 		ret = dw_i2c_clk_cfg(master);
 		if (ret)
 			return ret;
-- 
2.7.4


_______________________________________________
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

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

* Re: [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode
  2019-06-19 18:36 [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Vitor Soares
                   ` (2 preceding siblings ...)
  2019-06-19 18:36 ` [PATCH v4 3/3] i3c: dw: add limited bus mode support Vitor Soares
@ 2019-06-20  8:56 ` Boris Brezillon
  3 siblings, 0 replies; 5+ messages in thread
From: Boris Brezillon @ 2019-06-20  8:56 UTC (permalink / raw)
  To: Vitor Soares; +Cc: linux-i3c, Joao.Pinto

On Wed, 19 Jun 2019 20:36:30 +0200
Vitor Soares <Vitor.Soares@synopsys.com> wrote:

> This patch series fix the i2c and i3c scl rate according the bus mode
> and LVR register. It also introduce the mixed limited bus for the
> cases where i2c devices doesn't have 50 ns filter but allow higher
> clock rate for i3c transfers.
> Please refer table 5 and 10 of i3c bus spec v1.0 for more detail.
> 
> Please follow each patch commit message for more details and changes
> made in this version.
> 
> Vitor Soares (3):
>   i3c: fix i2c and i3c scl rate by bus mode
>   i3c: add mixed limited bus mode
>   i3c: dw: add limited bus mode support

Queued to i3c/next.

Thanks,

Boris

> 
>  drivers/i3c/master.c               | 57 +++++++++++++++++++++++++++++---------
>  drivers/i3c/master/dw-i3c-master.c |  1 +
>  include/linux/i3c/master.h         |  5 ++++
>  3 files changed, 50 insertions(+), 13 deletions(-)
> 


_______________________________________________
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

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

end of thread, other threads:[~2019-06-20  8:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-19 18:36 [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Vitor Soares
2019-06-19 18:36 ` [PATCH v4 1/3] i3c: fix i2c and i3c scl rate by " Vitor Soares
2019-06-19 18:36 ` [PATCH v4 2/3] i3c: add mixed limited " Vitor Soares
2019-06-19 18:36 ` [PATCH v4 3/3] i3c: dw: add limited bus mode support Vitor Soares
2019-06-20  8:56 ` [PATCH v4 0/3] Fix i2c and i3c scl rate according bus mode Boris Brezillon

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 NNTP newsgroup(s).