Patchwork [U-Boot,v6,4/5] tegra2: Modify MMC driver to handle power and cd GPIOs

login
register
mail settings
Submitter Stephen Warren
Date Oct. 12, 2011, 10:53 p.m.
Message ID <1318459989-24191-4-git-send-email-swarren@nvidia.com>
Download mbox | patch
Permalink /patch/119324/
State Superseded
Delegated to: Andy Fleming
Headers show

Comments

Stephen Warren - Oct. 12, 2011, 10:53 p.m.
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>
Acked-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(-)
Stephen Warren - Oct. 28, 2011, 5:26 p.m.
Stephen Warren wrote at Wednesday, October 12, 2011 4:53 PM:
> 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.

Andy,

This patch touches an MMC driver. If you consider it OK, could you please
Ack it so that Albert can apply the series to the ARM branch.

Thanks very much.

> 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>
> Acked-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);
> 
>  #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_ */
> --
> 1.7.0.4

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_ */