[U-Boot] [PATCH 0/4] Tegra114: MMC: Add MMC driver for T114/Dalmore

This patchset adds SDMMC device-tree support to the Tegra114 dts files, and enables the Tegra MMC driver on Tegra114 Dalmore.
Tested on my Dalmore E1611 board, eMMC and SD-Card work fine, can load a kernel off of a SD card OK, card detect works, and the env is now stored in eMMC (end of the 2nd 'boot' sector, same as Tegra20/30).
Tom Warren (4): Tegra114: fdt: Add SDMMC (sdhci) nodes for T114 boards (Dalmore for now) Tegra114: Dalmore: Add SDIO3 pad config to pinctrl_config table Tegra114: MMC: Add SD bus power-rail init routine Tegra114: MMC: Enable DT MMC driver support for Tegra114 Dalmore boards
arch/arm/dts/tegra114.dtsi | 32 +++++++++ arch/arm/include/asm/arch-tegra114/gp_padctrl.h | 7 ++ board/nvidia/dalmore/dalmore.c | 79 +++++++++++++++++++++++ board/nvidia/dalmore/pinmux-config-dalmore.h | 2 + board/nvidia/dts/tegra114-dalmore.dts | 13 ++++ include/configs/dalmore.h | 12 +++- 6 files changed, 144 insertions(+), 1 deletions(-)

Took these values directly from the kernel dts files.
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/dts/tegra114.dtsi | 32 ++++++++++++++++++++++++++++++++ board/nvidia/dts/tegra114-dalmore.dts | 13 +++++++++++++ 2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi index 701c0f9..5dbe3b2 100644 --- a/arch/arm/dts/tegra114.dtsi +++ b/arch/arm/dts/tegra114.dtsi @@ -75,4 +75,36 @@ clocks = <&tegra_car 47>; status = "disabled"; }; + + sdhci@78000000 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000000 0x200>; + interrupts = <0 14 0x04>; + clocks = <&tegra_car 14>; + status = "disable"; + }; + + sdhci@78000200 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000200 0x200>; + interrupts = <0 15 0x04>; + clocks = <&tegra_car 9>; + status = "disable"; + }; + + sdhci@78000400 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000400 0x200>; + interrupts = <0 19 0x04>; + clocks = <&tegra_car 69>; + status = "disable"; + }; + + sdhci@78000600 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000600 0x200>; + interrupts = <0 31 0x04>; + clocks = <&tegra_car 15>; + status = "disable"; + }; }; diff --git a/board/nvidia/dts/tegra114-dalmore.dts b/board/nvidia/dts/tegra114-dalmore.dts index 30cf1fb..7d0ce5b 100644 --- a/board/nvidia/dts/tegra114-dalmore.dts +++ b/board/nvidia/dts/tegra114-dalmore.dts @@ -12,6 +12,8 @@ i2c2 = "/i2c@7000c400"; i2c3 = "/i2c@7000c500"; i2c4 = "/i2c@7000c700"; + sdhci0 = "/sdhci@78000600"; + sdhci1 = "/sdhci@78000400"; };
memory { @@ -43,4 +45,15 @@ status = "okay"; clock-frequency = <400000>; }; + + sdhci@78000400 { + cd-gpios = <&gpio 170 1>; /* gpio PV2 */ + bus-width = <4>; + status = "okay"; + }; + + sdhci@78000600 { + bus-width = <8>; + status = "okay"; + }; };

SDIO1 (the SD-card slot on Dalmore) needs to have its pads setup before the MMC driver is added.
Signed-off-by: Tom Warren twarren@nvidia.com --- arch/arm/include/asm/arch-tegra114/gp_padctrl.h | 7 +++++++ board/nvidia/dalmore/dalmore.c | 4 ++++ board/nvidia/dalmore/pinmux-config-dalmore.h | 2 ++ 3 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/arch-tegra114/gp_padctrl.h b/arch/arm/include/asm/arch-tegra114/gp_padctrl.h index c538bdd..82c70cb 100644 --- a/arch/arm/include/asm/arch-tegra114/gp_padctrl.h +++ b/arch/arm/include/asm/arch-tegra114/gp_padctrl.h @@ -56,4 +56,11 @@ struct apb_misc_gp_ctlr { u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */ };
+/* SDMMC1/3 settings from section 27.5 of T114 TRM */ +#define SDIOCFG_DRVUP_SLWF 0 +#define SDIOCFG_DRVDN_SLWR 0 +#define SDIOCFG_DRVUP 0x24 +#define SDIOCFG_DRVDN 0x14 +#define SDIOCFG_HSM 1 + #endif /* _TEGRA114_GP_PADCTRL_H_ */ diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c index 2020a5f..7449b5b 100644 --- a/board/nvidia/dalmore/dalmore.c +++ b/board/nvidia/dalmore/dalmore.c @@ -16,6 +16,7 @@
#include <common.h> #include <asm/arch/pinmux.h> +#include <asm/arch/gp_padctrl.h> #include "pinmux-config-dalmore.h"
/* @@ -32,4 +33,7 @@ void pinmux_init(void)
pinmux_config_table(unused_pins_lowpower, ARRAY_SIZE(unused_pins_lowpower)); + + /* Initialize any non-default pad configs (APB_MISC_GP regs) */ + padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl)); } diff --git a/board/nvidia/dalmore/pinmux-config-dalmore.h b/board/nvidia/dalmore/pinmux-config-dalmore.h index e6fe842..7af3f75 100644 --- a/board/nvidia/dalmore/pinmux-config-dalmore.h +++ b/board/nvidia/dalmore/pinmux-config-dalmore.h @@ -364,5 +364,7 @@ static struct pingroup_config tegra114_pinmux_set_nontristate[] = {
static struct padctrl_config dalmore_padctrl[] = { /* (_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */ + DEFAULT_PADCFG(SDIO3, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \ + SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, ENABLE), }; #endif /* PINMUX_CONFIG_COMMON_H */

On 03/12/2013 10:17 AM, Tom Warren wrote:
SDIO1 (the SD-card slot on Dalmore) needs to have its pads setup before the MMC driver is added.
diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c
- /* Initialize any non-default pad configs (APB_MISC_GP regs) */
- padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl));
Given that you're only using this table for the very first time here ...
diff --git a/board/nvidia/dalmore/pinmux-config-dalmore.h b/board/nvidia/dalmore/pinmux-config-dalmore.h
static struct padctrl_config dalmore_padctrl[] = { /* (_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */
- DEFAULT_PADCFG(SDIO3, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \
SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, ENABLE),
};
... and it was empty before now, I'd be inclined to remove the *dalmore* files from the Tegra114 pinmux series that implemented padgrp_config_table(), and just do all the Dalmore-specific stuff in this patch.
But it's not a big deal.

Stephen,
On Tue, Mar 12, 2013 at 10:52 AM, Stephen Warren swarren@wwwdotorg.org wrote:
On 03/12/2013 10:17 AM, Tom Warren wrote:
SDIO1 (the SD-card slot on Dalmore) needs to have its pads setup before the MMC driver is added.
diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c
/* Initialize any non-default pad configs (APB_MISC_GP regs) */
padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl));
Given that you're only using this table for the very first time here ...
diff --git a/board/nvidia/dalmore/pinmux-config-dalmore.h b/board/nvidia/dalmore/pinmux-config-dalmore.h
static struct padctrl_config dalmore_padctrl[] = { /* (_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */
DEFAULT_PADCFG(SDIO3, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \
SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, ENABLE),
};
... and it was empty before now, I'd be inclined to remove the *dalmore* files from the Tegra114 pinmux series that implemented padgrp_config_table(), and just do all the Dalmore-specific stuff in this patch.
But it's not a big deal.
Yeah, I thought of doing that, but I already had this all working/tested/MAKEALL'd, and have to take off early today, so I sent the patchset as-is.
Thanks,
Tom

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

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.

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.

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.

Tested on my Dalmore E1611 board, eMMC and SD-Card work fine, can load a kernel off of an SD card OK, card detect works, and the env is now stored in eMMC (end of the 2nd 'boot' sector, same as Tegra20/30).
Signed-off-by: Tom Warren twarren@nvidia.com --- include/configs/dalmore.h | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/include/configs/dalmore.h b/include/configs/dalmore.h index b1a6e34..afce56a 100644 --- a/include/configs/dalmore.h +++ b/include/configs/dalmore.h @@ -50,7 +50,17 @@ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_CMD_I2C
-#define CONFIG_ENV_IS_NOWHERE +/* SD/MMC */ +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_TEGRA_MMC +#define CONFIG_CMD_MMC + +/* Environment in eMMC, at the end of 2nd "boot sector" */ +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2
#define MACH_TYPE_DALMORE 4304 /* not yet in mach-types.h */

On 03/12/2013 10:17 AM, Tom Warren wrote:
Tested on my Dalmore E1611 board, eMMC and SD-Card work fine, can load a kernel off of an SD card OK, card detect works, and the env is now stored in eMMC (end of the 2nd 'boot' sector, same as Tegra20/30).
diff --git a/include/configs/dalmore.h b/include/configs/dalmore.h
+/* Environment in eMMC, at the end of 2nd "boot sector" */ +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2
I believe that Dalmore's eMMC "boot" sectors are 4MiB in size, so that'd want to be (4096 - 512) * 1024) - CONFIG_ENV_SIZE. At least, that's what "mmcinfo" told me when running our downstream U-Boot on my Dalmore.
Aside from the comments I've made, the series, Reviewed-by: Stephen Warren swarren@nvidia.com
participants (2)
-
Stephen Warren
-
Tom Warren