Skip to contentSkip to conversation

i2c: davinci: Increase module clock frequency

PATCH Superseded Alexander Sverdlin 3 participants 8 messages Nov 19, 2015 – Nov 30, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 i2c: davinci: Increase module clock frequency

I2C controller used in Keystone SoC has an undocumented peculiarity which results in SDA-SCL margins being dependent on module clock. Driving high capacity bus near its limits can result in STOP condition sometimes being understood as REPEATED-START by slaves (or NACK instead of ACK, etc...). Driving the module with higher clocks increases the margin between SDA and SCL transitions, making the operations with higher bus rates more robust. Therefore, target the module clock to 12MHz instead of 7MHz, still staying within the specification limits.

Before the change STOP timing looked like this on 400kHz:

SDA ----------+ +----

                 \        /
                  \      /
                   +----+
                       (1)
SCL   --+          +------------
         \        /
          \      /
           +----+
               (2)

While only point (1) signals STOP, point (2) could be incorrectly recognized as repeated-START (almost no margin between SDA and SCL transitions).

After the change there is at least 600ns margin measured between SCL fall and SDA fall during STOP generation:

SDA ------+ +----

             \        /
              \      /
               +----+

SCL --+ +--------

         \        /
          \      /
           +----+
           ->|    |<- 600ns
                ->|   |<- tSUSTO

So called tSUSTO (setup time for STOP condition) is still slightly higher than 600ns, so no problem here.

---
 drivers/i2c/busses/i2c-davinci.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/i2c/busses/i2c-davinci.c +1 -1
index c5628a4..87c46a4 100644
@@ -203,7 +203,7 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 	 */
 
 	/* get minimum of 7 MHz clock, but max of 12 MHz */
-	psc = (input_clock / 7000000) - 1;
+	psc = (input_clock / 12000000) - 1;
 	if ((input_clock / (psc + 1)) > 12000000)
 		psc++;	/* better to run under spec than over */
 	d = (psc >= 2) ? 5 : 7 - psc;
Acked-by on v1 1/1
#1 lore raw
Quoted 40 lines · Alexander Sverdlin

I2C controller used in Keystone SoC has an undocumented peculiarity which results in SDA-SCL margins being dependent on module clock. Driving high capacity bus near its limits can result in STOP condition sometimes being understood as REPEATED-START by slaves (or NACK instead of ACK, etc...). Driving the module with higher clocks increases the margin between SDA and SCL transitions, making the operations with higher bus rates more robust. Therefore, target the module clock to 12MHz instead of 7MHz, still staying within the specification limits.

Before the change STOP timing looked like this on 400kHz:

SDA ----------+ +----

                  \        /
                   \      /
                    +----+
                        (1)
SCL   --+          +------------
          \        /
           \      /
            +----+
                (2)

While only point (1) signals STOP, point (2) could be incorrectly recognized as repeated-START (almost no margin between SDA and SCL transitions).

After the change there is at least 600ns margin measured between SCL fall and SDA fall during STOP generation:

SDA ------+ +----

              \        /
               \      /
                +----+

SCL --+ +--------

          \        /
           \      /
            +----+
            ->|    |<- 600ns
                 ->|   |<- tSUSTO
Quoted 5 lines

So called tSUSTO (setup time for STOP condition) is still slightly higher than 600ns, so no problem here.

---

Nice text artwork.

#2 lore raw
In reply to Alexander Sverdlin

drivers/i2c/busses/i2c-davinci.c static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) · line 206

Quoted 3 lines
drivers/i2c/busses/i2c-davinci.c +1 -1
 	/* get minimum of 7 MHz clock, but max of 12 MHz */
-	psc = (input_clock / 7000000) - 1;
+	psc = (input_clock / 12000000) - 1;

Doesn't make this the above comment invalid?

#3 lore raw

Hi!

Quoted 4 lines · EXT Wolfram Sang
Quoted 3 lines

/* get minimum of 7 MHz clock, but max of 12 MHz */

drivers/i2c/busses/i2c-davinci.c static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) · line 206

Quoted 2 lines
drivers/i2c/busses/i2c-davinci.c +1 -1
-	psc = (input_clock / 7000000) - 1;
+	psc = (input_clock / 12000000) - 1;

Doesn't make this the above comment invalid?

The comment refers to datasheet, not really to the code. And eventual changes to the datasheet that's what can make it invalid (though I don't know TI's plans on it). Nevertheless, yes, I think, it's better to drop the comment. Should I re-spin the patch with comment removal in it?

Signature · 3 lines
Best regards,
Alexander Sverdlin.
Sent from my pdp-11
#4 lore raw
Quoted 3 lines

The comment refers to datasheet, not really to the code. And eventual changes to the datasheet that's what can make it invalid (though I don't know TI's plans on it). Nevertheless, yes, I think, it's better to drop the comment. Should I re-spin the patch with comment removal in it?

Thanks. Even better would be replacing the comment: can you give a short explanation why there is now 12MHz and what needs to be considered if the value is to be changed again?

#5 lore raw

PATCH v2 1/1 i2c: davinci: Increase module clock frequency

I2C controller used in Keystone SoC has an undocumented peculiarity which results in SDA-SCL margins being dependent on module clock. Driving high capacity bus near its limits can result in STOP condition sometimes being understood as REPEATED-START by slaves (or NACK instead of ACK, etc...). Driving the module with higher clocks increases the margin between SDA and SCL transitions, making the operations with higher bus rates more robust. Therefore, target the module clock to 12MHz instead of 7MHz, still staying within the specification limits.

Before the change STOP timing looked like this on 400kHz:

SDA ----------+ +----

                 \        /
                  \      /
                   +----+
                       (1)
SCL   --+          +------------
         \        /
          \      /
           +----+
               (2)

While only point (1) signals STOP, point (2) could be incorrectly recognized as repeated-START (almost no margin between SDA and SCL transitions).

After the change there is at least 600ns margin measured between SCL fall and SDA fall during STOP generation:

SDA ------+ +----

             \        /
              \      /
               +----+

SCL --+ +--------

         \        /
          \      /
           +----+
           ->|    |<- 600ns
                ->|   |<- tSUSTO

So called tSUSTO (setup time for STOP condition) is still slightly higher than 600ns, so no problem here.

---

Changes in v2:
- Replaced old comment referencing to datasheet.

 drivers/i2c/busses/i2c-davinci.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-davinci.c +9 -2
index c5628a4..a8bdcb5 100644
@@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 	 * d is always 6 on Keystone I2C controller
 	 */
 
-	/* get minimum of 7 MHz clock, but max of 12 MHz */
-	psc = (input_clock / 7000000) - 1;
+	/*
+	 * Both Davinci and current Keystone User Guides recommend a value
+	 * between 7MHz and 12MHz. In reality 7MHz module clock doesn't
+	 * always produce enough margin between SDA and SCL transitions.
+	 * Measurements show that the higher the module clock is, the
+	 * bigger is the margin, providing more reliable communication.
+	 * So we better target for 12MHz.
+	 */
+	psc = (input_clock / 12000000) - 1;
 	if ((input_clock / (psc + 1)) > 12000000)
 		psc++;	/* better to run under spec than over */
 	d = (psc >= 2) ? 5 : 7 - psc;
Applied
#6 lore raw
Quoted 11 lines · Alexander Sverdlin

I2C controller used in Keystone SoC has an undocumented peculiarity which results in SDA-SCL margins being dependent on module clock. Driving high capacity bus near its limits can result in STOP condition sometimes being understood as REPEATED-START by slaves (or NACK instead of ACK, etc...). Driving the module with higher clocks increases the margin between SDA and SCL transitions, making the operations with higher bus rates more robust. Therefore, target the module clock to 12MHz instead of 7MHz, still staying within the specification limits.

Before the change STOP timing looked like this on 400kHz:

Applied to for-current, thanks!

Applied
#7 lore raw
In reply to Alexander Sverdlin
Quoted 11 lines · Alexander Sverdlin

I2C controller used in Keystone SoC has an undocumented peculiarity which results in SDA-SCL margins being dependent on module clock. Driving high capacity bus near its limits can result in STOP condition sometimes being understood as REPEATED-START by slaves (or NACK instead of ACK, etc...). Driving the module with higher clocks increases the margin between SDA and SCL transitions, making the operations with higher bus rates more robust. Therefore, target the module clock to 12MHz instead of 7MHz, still staying within the specification limits.

Before the change STOP timing looked like this on 400kHz:

Applied to for-current and added stable, thanks!