diff mbox

[U-Boot,v4,3/4] tegra2: Modify MMC driver to handle power and cd GPIOs

Message ID 1318432727-32446-3-git-send-email-swarren@nvidia.com
State Superseded, archived
Headers show

Commit Message

Stephen Warren Oct. 12, 2011, 3:18 p.m. UTC
Pass the GPIO numbers for power and card detect to tegra2_mmc_init(), and
modify that function to perform all required GPIO initialization. This
removes the need for board files to perform these operations.

Move board_mmc_getcd() into tegra2_mmc.c now that the driver knows which
GPIOs to use.

Update affected call-sites in seaboard.c and harmony.c. Note that this
change should make all SD ports work on Harmony, since the required GPIO
setup is now being performed.

v4: Fix prototype of tegra2_mmc_init() in board.h to match driver change.
    Remove prototype of gpio_config_mmc() from board.h

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Tested-by: Simon Glass <sjg@chromium.org>
---
 board/nvidia/common/board.h      |    3 +-
 board/nvidia/harmony/harmony.c   |   27 ++---------------------
 board/nvidia/seaboard/seaboard.c |   33 +----------------------------
 drivers/mmc/tegra2_mmc.c         |   42 ++++++++++++++++++++++++++++++++-----
 drivers/mmc/tegra2_mmc.h         |    4 ++-
 5 files changed, 45 insertions(+), 64 deletions(-)

Comments

Thierry Reding Nov. 16, 2011, 8:29 p.m. UTC | #1
* Stephen Warren wrote:
> Pass the GPIO numbers for power and card detect to tegra2_mmc_init(), and
> modify that function to perform all required GPIO initialization. This
> removes the need for board files to perform these operations.
> 
> Move board_mmc_getcd() into tegra2_mmc.c now that the driver knows which
> GPIOs to use.
> 
> Update affected call-sites in seaboard.c and harmony.c. Note that this
> change should make all SD ports work on Harmony, since the required GPIO
> setup is now being performed.
> 
> v4: Fix prototype of tegra2_mmc_init() in board.h to match driver change.
>     Remove prototype of gpio_config_mmc() from board.h
> 
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> Tested-by: Simon Glass <sjg@chromium.org>
> ---
>  board/nvidia/common/board.h      |    3 +-
>  board/nvidia/harmony/harmony.c   |   27 ++---------------------
>  board/nvidia/seaboard/seaboard.c |   33 +----------------------------
>  drivers/mmc/tegra2_mmc.c         |   42 ++++++++++++++++++++++++++++++++-----
>  drivers/mmc/tegra2_mmc.h         |    4 ++-
>  5 files changed, 45 insertions(+), 64 deletions(-)
> 
> diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
> index 344e702..35acbca 100644
> --- a/board/nvidia/common/board.h
> +++ b/board/nvidia/common/board.h
> @@ -26,7 +26,6 @@
>  
>  void tegra2_start(void);
>  void gpio_config_uart(void);
> -void gpio_config_mmc(void);
> -int tegra2_mmc_init(int dev_index, int bus_width);
> +int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
[...]

Can we move tegra2_start() and tegra2_mmc_init() into a common Tegra2 header
instead of a board-specific one, please? Both functions are not implemented
below board/nvidia/common, so there is no need to make their prototype only
visible for board/nvidia. Otherwise other boards will have to duplicate this
prototype and need to keep it in sync.

tegra2_start() can probably go into arch/arm/include/asm/arch-tegra2/tegra2.h
and tegra2_mmc_init() could for example go into a new mmc.h in the same
directory.

Thierry
Stephen Warren Nov. 16, 2011, 9:05 p.m. UTC | #2
Thierry Reding wrote at Wednesday, November 16, 2011 1:29 PM:
> * Stephen Warren wrote:
> > Pass the GPIO numbers for power and card detect to tegra2_mmc_init(), and
> > modify that function to perform all required GPIO initialization. This
> > removes the need for board files to perform these operations.
> >
> > Move board_mmc_getcd() into tegra2_mmc.c now that the driver knows which
> > GPIOs to use.
> >
> > Update affected call-sites in seaboard.c and harmony.c. Note that this
> > change should make all SD ports work on Harmony, since the required GPIO
> > setup is now being performed.
...
> > diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
...
> >  void tegra2_start(void);
> >  void gpio_config_uart(void);
> > -void gpio_config_mmc(void);
> > -int tegra2_mmc_init(int dev_index, int bus_width);
> > +int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
> [...]
> 
> Can we move tegra2_start() and tegra2_mmc_init() into a common Tegra2 header
> instead of a board-specific one, please? Both functions are not implemented
> below board/nvidia/common, so there is no need to make their prototype only
> visible for board/nvidia. Otherwise other boards will have to duplicate this
> prototype and need to keep it in sync.
> 
> tegra2_start() can probably go into arch/arm/include/asm/arch-tegra2/tegra2.h
> and tegra2_mmc_init() could for example go into a new mmc.h in the same
> directory.

I'd certainly be fine with that.

It's probably simplest if you include that change in your patchset though;
my patchset doesn't change the location of these functions, so I'd have to
introduce another patch for that.
Simon Glass Nov. 17, 2011, 4:38 a.m. UTC | #3
Hi Thierry,

On Wed, Nov 16, 2011 at 1:05 PM, Stephen Warren <swarren@nvidia.com> wrote:
> Thierry Reding wrote at Wednesday, November 16, 2011 1:29 PM:
>> * Stephen Warren wrote:
>> > Pass the GPIO numbers for power and card detect to tegra2_mmc_init(), and
>> > modify that function to perform all required GPIO initialization. This
>> > removes the need for board files to perform these operations.
>> >
>> > Move board_mmc_getcd() into tegra2_mmc.c now that the driver knows which
>> > GPIOs to use.
>> >
>> > Update affected call-sites in seaboard.c and harmony.c. Note that this
>> > change should make all SD ports work on Harmony, since the required GPIO
>> > setup is now being performed.
> ...
>> > diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
> ...
>> >  void tegra2_start(void);
>> >  void gpio_config_uart(void);
>> > -void gpio_config_mmc(void);
>> > -int tegra2_mmc_init(int dev_index, int bus_width);
>> > +int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
>> [...]
>>
>> Can we move tegra2_start() and tegra2_mmc_init() into a common Tegra2 header
>> instead of a board-specific one, please? Both functions are not implemented
>> below board/nvidia/common, so there is no need to make their prototype only
>> visible for board/nvidia. Otherwise other boards will have to duplicate this
>> prototype and need to keep it in sync.
>>
>> tegra2_start() can probably go into arch/arm/include/asm/arch-tegra2/tegra2.h

That header file is supported to just be for #defines. How about
ap20.h? Anyway, sorry to say that this has been refactored and
simplified already. Patches are upstream - it's just that they are not
yet applied. Please see my patchwork if you want to base on top of
those as well (yes I know this is a pain, sorry).

Regards,
Simon

>> and tegra2_mmc_init() could for example go into a new mmc.h in the same
>> directory.
>
> I'd certainly be fine with that.
>
> It's probably simplest if you include that change in your patchset though;
> my patchset doesn't change the location of these functions, so I'd have to
> introduce another patch for that.
>
> --
> nvpublic
>
>
diff mbox

Patch

diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
index 344e702..35acbca 100644
--- a/board/nvidia/common/board.h
+++ b/board/nvidia/common/board.h
@@ -26,7 +26,6 @@ 
 
 void tegra2_start(void);
 void gpio_config_uart(void);
-void gpio_config_mmc(void);
-int tegra2_mmc_init(int dev_index, int bus_width);
+int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
 
 #endif	/* BOARD_H */
diff --git a/board/nvidia/harmony/harmony.c b/board/nvidia/harmony/harmony.c
index f2c3867..3cbe820 100644
--- a/board/nvidia/harmony/harmony.c
+++ b/board/nvidia/harmony/harmony.c
@@ -25,6 +25,7 @@ 
 #include <asm/io.h>
 #include <asm/arch/tegra2.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 #ifdef CONFIG_TEGRA2_MMC
 #include <mmc.h>
 #endif
@@ -72,15 +73,6 @@  static void pin_mux_mmc(void)
 	pinmux_tristate_disable(PINGRP_ATC);
 }
 
-/*
- * Routine: gpio_config_mmc
- * Description: Set GPIOs for SD card
- */
-void gpio_config_mmc(void)
-{
-	/* Not implemented for now */
-}
-
 /* this is a weak define that we are overriding */
 int board_mmc_init(bd_t *bd)
 {
@@ -88,29 +80,16 @@  int board_mmc_init(bd_t *bd)
 
 	/* Enable muxes, etc. for SDMMC controllers */
 	pin_mux_mmc();
-	gpio_config_mmc();
 
 	debug("board_mmc_init: init SD slot J26\n");
 	/* init dev 0, SD slot J26, with 4-bit bus */
 	/* The board has an 8-bit bus, but 8-bit doesn't work yet */
-	tegra2_mmc_init(0, 4);
+	tegra2_mmc_init(0, 4, GPIO_PI6, GPIO_PH2);
 
 	debug("board_mmc_init: init SD slot J5\n");
 	/* init dev 2, SD slot J5, with 4-bit bus */
-	tegra2_mmc_init(2, 4);
+	tegra2_mmc_init(2, 4, GPIO_PT3, GPIO_PI5);
 
 	return 0;
 }
-
-/* this is a weak define that we are overriding */
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
-{
-	debug("board_mmc_getcd called\n");
-	/*
-	 * Hard-code CD presence for now. Need to add GPIO inputs
-	 * for Harmony
-	 */
-	*cd = 1;
-	return 0;
-}
 #endif
diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c
index 22a0e69..356d616 100644
--- a/board/nvidia/seaboard/seaboard.c
+++ b/board/nvidia/seaboard/seaboard.c
@@ -87,19 +87,6 @@  static void pin_mux_mmc(void)
 	pinmux_tristate_disable(PINGRP_ATC);
 }
 
-/*
- * Routine: gpio_config_mmc
- * Description: Set GPIOs for SDMMC3 SDIO slot.
- */
-void gpio_config_mmc(void)
-{
-	/* Set EN_VDDIO_SD (GPIO I6) */
-	gpio_direction_output(GPIO_PI6, 1);
-
-	/* Config pin as GPI for Card Detect (GPIO I5) */
-	gpio_direction_input(GPIO_PI5);
-}
-
 /* this is a weak define that we are overriding */
 int board_mmc_init(bd_t *bd)
 {
@@ -107,31 +94,15 @@  int board_mmc_init(bd_t *bd)
 
 	/* Enable muxes, etc. for SDMMC controllers */
 	pin_mux_mmc();
-	gpio_config_mmc();
 
 	debug("board_mmc_init: init eMMC\n");
 	/* init dev 0, eMMC chip, with 4-bit bus */
 	/* The board has an 8-bit bus, but 8-bit doesn't work yet */
-	tegra2_mmc_init(0, 4);
+	tegra2_mmc_init(0, 4, -1, -1);
 
 	debug("board_mmc_init: init SD slot\n");
 	/* init dev 1, SD slot, with 4-bit bus */
-	tegra2_mmc_init(1, 4);
-
-	return 0;
-}
-
-/* this is a weak define that we are overriding */
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
-{
-	debug("board_mmc_getcd called\n");
-	*cd = 1;			/* Assume card is inserted, or eMMC */
-
-	if (IS_SD(mmc)) {
-		/* Seaboard SDMMC3 = SDIO3_CD = GPIO_PI5 */
-		if (gpio_get_value(GPIO_PI5))
-			*cd = 0;
-	}
+	tegra2_mmc_init(1, 4, GPIO_PI6, GPIO_PI5);
 
 	return 0;
 }
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 78b1190..3de9c5d 100644
--- a/drivers/mmc/tegra2_mmc.c
+++ b/drivers/mmc/tegra2_mmc.c
@@ -21,6 +21,7 @@ 
 
 #include <common.h>
 #include <mmc.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/clock.h>
@@ -433,20 +434,37 @@  static int mmc_core_init(struct mmc *mmc)
 	return 0;
 }
 
-static int tegra2_mmc_initialize(int dev_index, int bus_width)
+int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
 {
 	struct mmc_host *host;
+	char gpusage[12]; /* "SD/MMCn PWR" or "SD/MMCn CD" */
 	struct mmc *mmc;
 
-	debug(" mmc_initialize called\n");
+	debug(" tegra2_mmc_init: index %d, bus width %d "
+		"pwr_gpio %d cd_gpio %d\n",
+		dev_index, bus_width, pwr_gpio, cd_gpio);
 
 	host = &mmc_host[dev_index];
 
 	host->clock = 0;
+	host->pwr_gpio = pwr_gpio;
+	host->cd_gpio = cd_gpio;
 	tegra2_get_setup(host, dev_index);
 
 	clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);
 
+	if (host->pwr_gpio >= 0) {
+		sprintf(gpusage, "SD/MMC%d PWR", dev_index);
+		gpio_request(host->pwr_gpio, gpusage);
+		gpio_direction_output(host->pwr_gpio, 1);
+	}
+
+	if (host->cd_gpio >= 0) {
+		sprintf(gpusage, "SD/MMC%d CD", dev_index);
+		gpio_request(host->cd_gpio, gpusage);
+		gpio_direction_input(host->cd_gpio);
+	}
+
 	mmc = &mmc_dev[dev_index];
 
 	sprintf(mmc->name, "Tegra2 SD/MMC");
@@ -478,9 +496,21 @@  static int tegra2_mmc_initialize(int dev_index, int bus_width)
 	return 0;
 }
 
-int tegra2_mmc_init(int dev_index, int bus_width)
+/* this is a weak define that we are overriding */
+int board_mmc_getcd(u8 *cd, struct mmc *mmc)
 {
-	debug(" tegra2_mmc_init: index %d, bus width %d\n",
-		dev_index, bus_width);
-	return tegra2_mmc_initialize(dev_index, bus_width);
+	struct mmc_host *host = (struct mmc_host *)mmc->priv;
+
+	debug("board_mmc_getcd called\n");
+
+	*cd = 1; /* Assume card is inserted, or eMMC */
+
+	if (IS_SD(mmc)) {
+		if (host->cd_gpio >= 0) {
+			if (gpio_get_value(host->cd_gpio))
+				*cd = 0;
+		}
+	}
+
+	return 0;
 }
diff --git a/drivers/mmc/tegra2_mmc.h b/drivers/mmc/tegra2_mmc.h
index 28698e0..72f587b 100644
--- a/drivers/mmc/tegra2_mmc.h
+++ b/drivers/mmc/tegra2_mmc.h
@@ -74,9 +74,11 @@  struct mmc_host {
 	unsigned int clock;	/* Current clock (MHz) */
 	unsigned int base;	/* Base address, SDMMC1/2/3/4 */
 	enum periph_id mmc_id;	/* Peripheral ID: PERIPH_ID_... */
+	int pwr_gpio;		/* Power GPIO */
+	int cd_gpio;		/* Change Detect GPIO */
 };
 
-int tegra2_mmc_init(int dev_index, int bus_width);
+int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio);
 
 #endif	/* __ASSEMBLY__ */
 #endif	/* __TEGRA2_MMC_H_ */