Patchwork [U-Boot,v2,1/3] Tegra: I2C: Add T114 clock support to tegra_i2c driver

login
register
mail settings
Submitter Tom Warren
Date Feb. 6, 2013, 11:26 p.m.
Message ID <1360193208-16055-2-git-send-email-twarren@nvidia.com>
Download mbox | patch
Permalink /patch/218800/
State Superseded
Delegated to: Tom Warren
Headers show

Comments

Tom Warren - Feb. 6, 2013, 11:26 p.m.
T114 has a slightly different I2C clock, with a new divisor for
standard/fast mode and HS mode. Tested on my Dalmore, and the I2C
clock is 100KHz +/- 3% on my Saleae Logic analyzer.

Signed-off-by: Tom Warren <twarren@nvidia.com>
---
v2: new

 arch/arm/include/asm/arch-tegra/tegra_i2c.h |    6 ++++++
 drivers/i2c/tegra_i2c.c                     |   22 +++++++++++++++++++++-
 2 files changed, 27 insertions(+), 1 deletions(-)
Stephen Warren - Feb. 6, 2013, 11:50 p.m.
On 02/06/2013 04:26 PM, Tom Warren wrote:
> T114 has a slightly different I2C clock, with a new divisor for
> standard/fast mode and HS mode. Tested on my Dalmore, and the I2C
> clock is 100KHz +/- 3% on my Saleae Logic analyzer.

This looks plausible to me, but best to have Laxman review it since he's
the I2C expert. I'll forward the whole original message to him for this
purpose.

At least for me though,
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Laxman Dewangan - Feb. 7, 2013, 2:52 p.m.
On Thursday 07 February 2013 04:56 AM, Tom Warren wrote:
> T114 has a slightly different I2C clock, with a new divisor for
> standard/fast mode and HS mode. Tested on my Dalmore, and the I2C
> clock is 100KHz +/- 3% on my Saleae Logic analyzer.
>
> Signed-off-by: Tom Warren <twarren@nvidia.com>
> ---
>

Changes looks good.
Acked-by: Laxman Dewangan<ldewangan@nvidia.com>

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
Laxman Dewangan - Feb. 8, 2013, 9:15 a.m.
On Thursday 07 February 2013 04:56 AM, Tom Warren wrote:
> T114 has a slightly different I2C clock, with a new divisor for
> standard/fast mode and HS mode. Tested on my Dalmore, and the I2C
> clock is 100KHz +/- 3% on my Saleae Logic analyzer.
>
> Signed-off-by: Tom Warren <twarren@nvidia.com>
> ---
> v2: new

>   	 */
>   	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
> -			       i2c_bus->speed * 2 * 8);
> +		i2c_bus->speed * 2 * 8);

I think you do not need to multipled by 2 again here. *2 can be remove.
I2C clock divder is U16 type.


>

> +
> +	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
> +		CLK_MULT_STD_FAST_MODE * (clk_div_std_fast_mode+1) *
> +		i2c_bus->speed * 2);

Same as above, *2 is not required.


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
Tom Warren - Feb. 8, 2013, 4:39 p.m.
Laxman,

On Fri, Feb 8, 2013 at 2:15 AM, Laxman Dewangan <ldewangan@nvidia.com> wrote:
> On Thursday 07 February 2013 04:56 AM, Tom Warren wrote:
>>
>> T114 has a slightly different I2C clock, with a new divisor for
>> standard/fast mode and HS mode. Tested on my Dalmore, and the I2C
>> clock is 100KHz +/- 3% on my Saleae Logic analyzer.
>>
>> Signed-off-by: Tom Warren <twarren@nvidia.com>
>> ---
>> v2: new
>
>
>>          */
>>         clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
>> -                              i2c_bus->speed * 2 * 8);
>> +               i2c_bus->speed * 2 * 8);
>
>
> I think you do not need to multipled by 2 again here. *2 can be remove.
> I2C clock divder is U16 type.
>
>
>
>>
>
>> +
>> +       clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
>> +               CLK_MULT_STD_FAST_MODE * (clk_div_std_fast_mode+1) *
>> +               i2c_bus->speed * 2);
>
>
> Same as above, *2 is not required.
I measured the I2C clock on J51 (GEN1_I2C) on my Dalmore, and the
clock is indeed 100KHz (+/- 3 Hz).

Tom
>
>
>
> -----------------------------------------------------------------------------------
> This email message is for the sole use of the intended recipient(s) and may
> contain
> confidential information.  Any unauthorized review, use, disclosure or
> distribution
> is prohibited.  If you are not the intended recipient, please contact the
> sender by
> reply email and destroy all copies of the original message.
> -----------------------------------------------------------------------------------

Patch

diff --git a/arch/arm/include/asm/arch-tegra/tegra_i2c.h b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
index 2650744..853e59b 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_i2c.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
@@ -105,6 +105,7 @@  struct i2c_ctlr {
 	u32 sl_delay_count;		/* 3C: I2C_I2C_SL_DELAY_COUNT */
 	u32 reserved_2[4];		/* 40: */
 	struct i2c_control control;	/* 50 ~ 68 */
+	u32 clk_div;			/* 6C: I2C_I2C_CLOCK_DIVISOR */
 };
 
 /* bit fields definitions for IO Packet Header 1 format */
@@ -154,6 +155,11 @@  struct i2c_ctlr {
 #define I2C_INT_ARBITRATION_LOST_SHIFT	2
 #define I2C_INT_ARBITRATION_LOST_MASK	(1 << I2C_INT_ARBITRATION_LOST_SHIFT)
 
+/* I2C_CLK_DIVISOR_REGISTER */
+#define CLK_DIV_STD_FAST_MODE		0x19
+#define CLK_DIV_HS_MODE			1
+#define CLK_MULT_STD_FAST_MODE		8
+
 /**
  * Returns the bus number of the DVC controller
  *
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index efc77fa..0558648 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -88,7 +88,27 @@  static void i2c_init_controller(struct i2c_bus *i2c_bus)
 	 * 16 to get the right frequency.
 	 */
 	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
-			       i2c_bus->speed * 2 * 8);
+		i2c_bus->speed * 2 * 8);
+#if defined(CONFIG_TEGRA114)
+	/*
+	 * T114 I2C went to a single clock source for standard/fast and
+	 * HS clock speeds. The new clock rate setting calculation is:
+	 *  SCL = CLK_SOURCE.I2C /
+	 *   (CLK_MULT_STD_FAST_MODE * (I2C_CLK_DIV_STD_FAST_MODE+1) *
+	 *   I2C FREQUENCY DIVISOR) as per the T114 TRM (sec 30.3.1).
+	 *
+	 * NOTE: We do this here, after the initial clock/pll start,
+	 * because if we read the clk_div reg before the controller
+	 * is running, we hang, and we need it for the new calc.
+	 */
+	int clk_div_std_fast_mode = readl(&i2c_bus->regs->clk_div) >> 16;
+	debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__,
+		clk_div_std_fast_mode);
+
+	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
+		CLK_MULT_STD_FAST_MODE * (clk_div_std_fast_mode+1) *
+		i2c_bus->speed * 2);
+#endif	/* T114 */
 
 	/* Reset I2C controller. */
 	i2c_reset_controller(i2c_bus);