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

Submitted by Tom Warren on Feb. 6, 2013, 11:26 p.m.

Details

Message ID 1360193208-16055-2-git-send-email-twarren@nvidia.com
State Superseded
Delegated to: Tom Warren
Headers show

Commit Message

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(-)

Comments

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 hide | download patch | download mbox

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);