Patchwork [U-Boot,3/4] Tegra114: MMC: Add SD bus power-rail init routine

login
register
mail settings
Submitter Tom Warren
Date March 12, 2013, 4:17 p.m.
Message ID <1363105031-30296-4-git-send-email-twarren@nvidia.com>
Download mbox | patch
Permalink /patch/227076/
State Superseded
Delegated to: Tom Warren
Headers show

Comments

Tom Warren - March 12, 2013, 4:17 p.m.
T114 requires SD bus power-rail bringup for the SDIO card on SDMMC3.

Signed-off-by: Tom Warren <twarren@nvidia.com>
---
 board/nvidia/dalmore/dalmore.c |   75 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
Stephen Warren - March 12, 2013, 5:54 p.m.
On 03/12/2013 10:17 AM, Tom Warren wrote:
> T114 requires SD bus power-rail bringup for the SDIO card on SDMMC3.

> diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c

> +#if defined(CONFIG_TEGRA_MMC)

It always is for Dalmore, right?

> +void board_sdmmc_voltage_init(void)

> +	/* TPS65913: LDO9_VOLTAGE = 3.3V */
> +	data_buffer[0] = 0x31;
> +	reg = 0x61;
> +
> +	for (i = 0; i < MAX_I2C_RETRY; ++i) {
> +		ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
> +		if (ret) {
> +			udelay(100);
> +			printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
> +				__func__, reg, data_buffer[0], ret);
> +		}
> +	}

Is there actually a need to retry these transactions; is there any
evidence they're expected to fail? Hopefully the HW isn't flaky like that.

AFAIK, the kernel driver for the PMIC doesn't retry these if they fail.
Hopefully it doesn't need to start doing so.
Tom Warren - March 12, 2013, 6:05 p.m.
Stephen,

On Tue, Mar 12, 2013 at 10:54 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 03/12/2013 10:17 AM, Tom Warren wrote:
>> T114 requires SD bus power-rail bringup for the SDIO card on SDMMC3.
>
>> diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c
>
>> +#if defined(CONFIG_TEGRA_MMC)
>
> It always is for Dalmore, right?
Yep, but I always like to provide the means to disable a feature
(whether it be SPI, or MMC, or USB) so you can build a stripped-down
or de-featured version for testing.
Having said that, I haven't tested lately whether T114 (or T20 or T30)
will build OK w/MMC undefined/removed.

>
>> +void board_sdmmc_voltage_init(void)
>
>> +     /* TPS65913: LDO9_VOLTAGE = 3.3V */
>> +     data_buffer[0] = 0x31;
>> +     reg = 0x61;
>> +
>> +     for (i = 0; i < MAX_I2C_RETRY; ++i) {
>> +             ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
>> +             if (ret) {
>> +                     udelay(100);
>> +                     printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
>> +                             __func__, reg, data_buffer[0], ret);
>> +             }
>> +     }
>
> Is there actually a need to retry these transactions; is there any
> evidence they're expected to fail? Hopefully the HW isn't flaky like that.
This is how it was done in the original internal U-Boot code I got the
I2C writes from (also done this way on T30). I did add the printf
error writes, though, when I was having a PWR_I2C/I2C5/dev 0 problem.
I think Whistler does something similar.

>
> AFAIK, the kernel driver for the PMIC doesn't retry these if they fail.
> Hopefully it doesn't need to start doing so.
Stephen Warren - March 12, 2013, 6:13 p.m.
On 03/12/2013 12:05 PM, Tom Warren wrote:
> Stephen,
> 
> On Tue, Mar 12, 2013 at 10:54 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 03/12/2013 10:17 AM, Tom Warren wrote:
>>> T114 requires SD bus power-rail bringup for the SDIO card on SDMMC3.
>>
>>> diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c

>>> +void board_sdmmc_voltage_init(void)
>>
>>> +     /* TPS65913: LDO9_VOLTAGE = 3.3V */
>>> +     data_buffer[0] = 0x31;
>>> +     reg = 0x61;
>>> +
>>> +     for (i = 0; i < MAX_I2C_RETRY; ++i) {
>>> +             ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
>>> +             if (ret) {
>>> +                     udelay(100);
>>> +                     printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
>>> +                             __func__, reg, data_buffer[0], ret);
>>> +             }
>>> +     }
>>
>> Is there actually a need to retry these transactions; is there any
>> evidence they're expected to fail? Hopefully the HW isn't flaky like that.
>
> This is how it was done in the original internal U-Boot code I got the
> I2C writes from (also done this way on T30). I did add the printf
> error writes, though, when I was having a PWR_I2C/I2C5/dev 0 problem.
> I think Whistler does something similar.

Whistler doesn't do any retries. That's why I was surprised by this. I
would assert we should remove the retry logic unless there's a specific
need for it, in which case we need to port it to the kernel too.

Patch

diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c
index 7449b5b..43f377b 100644
--- a/board/nvidia/dalmore/dalmore.c
+++ b/board/nvidia/dalmore/dalmore.c
@@ -18,6 +18,11 @@ 
 #include <asm/arch/pinmux.h>
 #include <asm/arch/gp_padctrl.h>
 #include "pinmux-config-dalmore.h"
+#include <i2c.h>
+
+#define BAT_I2C_ADDRESS		0x48	/* TPS65090 charger */
+#define PMU_I2C_ADDRESS		0x58	/* TPS65913 PMU */
+#define MAX_I2C_RETRY		3
 
 /*
  * Routine: pinmux_init
@@ -37,3 +42,73 @@  void pinmux_init(void)
 	/* Initialize any non-default pad configs (APB_MISC_GP regs) */
 	padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl));
 }
+
+#if defined(CONFIG_TEGRA_MMC)
+/*
+ * Do I2C/PMU writes to bring up SD card bus power
+ *
+ */
+void board_sdmmc_voltage_init(void)
+{
+	uchar reg, data_buffer[1];
+	int i, ret;
+
+	ret = i2c_set_bus_num(0);/* PMU is on bus 0 */
+	if (ret)
+		printf("%s: i2c_set_bus_num returned %d\n", __func__, ret);
+
+	/* TPS65913: LDO9_VOLTAGE = 3.3V */
+	data_buffer[0] = 0x31;
+	reg = 0x61;
+
+	for (i = 0; i < MAX_I2C_RETRY; ++i) {
+		ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+		if (ret) {
+			udelay(100);
+			printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+				__func__, reg, data_buffer[0], ret);
+		}
+	}
+
+	/* TPS65913: LDO9_CTRL = Active */
+	data_buffer[0] = 0x01;
+	reg = 0x60;
+
+	for (i = 0; i < MAX_I2C_RETRY; ++i) {
+		ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+		if (ret) {
+			udelay(100);
+			printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+			 __func__, reg, data_buffer[0], ret);
+		}
+	}
+
+	/* TPS65090: FET6_CTRL = enable output auto discharge, enable FET6 */
+	data_buffer[0] = 0x03;
+	reg = 0x14;
+
+	for (i = 0; i < MAX_I2C_RETRY; ++i) {
+		ret = i2c_write(BAT_I2C_ADDRESS, reg, 1, data_buffer, 1);
+		if (ret) {
+			udelay(100);
+			printf("%s: BAT i2c_write %02X<-%02X returned %d\n",
+				__func__, reg, data_buffer[0], ret);
+		}
+	}
+}
+
+/*
+ * Routine: pin_mux_mmc
+ * Description: setup the MMC muxes, power rails, etc.
+ */
+void pin_mux_mmc(void)
+{
+	/*
+	 * NOTE: We don't do mmc-specific pin muxes here.
+	 * They were done globally in pinmux_init().
+	 */
+
+	/* Bring up the SDIO3 power rail */
+	board_sdmmc_voltage_init();
+}
+#endif /* MMC */