Seaboard uses SDMMC4, SDMMC3. Harmony uses SDMMC4, SDMMC2. Move
board_init_mmc and gpio_config_mmc into board-specific files, so boards
can choose which ports to set up. Split clock_init_mmc and pin_mux_mmc
into per-port functions, and export them for use by boards.

Signed-off-by: Stephen Warren <swar...@nvidia.com>
---
 board/nvidia/common/board.c      |   77 ++++++++++++++++++++++++--------------
 board/nvidia/common/board.h      |    8 +++-
 board/nvidia/harmony/harmony.c   |   56 +++++++++++++++++++++++++--
 board/nvidia/seaboard/seaboard.c |   23 +++++++++++
 drivers/mmc/tegra2_mmc.c         |   18 +++++++++
 5 files changed, 148 insertions(+), 34 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 8033612..6c09a4c 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -102,20 +102,37 @@ static void pin_mux_uart(void)
 
 #ifdef CONFIG_TEGRA2_MMC
 /*
- * Routine: clock_init_mmc
- * Description: init the PLL and clocks for the SDMMC controllers
+ * Routine: clock_init_mmc4
+ * Description: init the PLL and clocks for SDMMC4 controller
  */
-static void clock_init_mmc(void)
+void clock_init_mmc4(void)
 {
        clock_start_periph_pll(PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH, 20000000);
+}
+
+/*
+ * Routine: clock_init_mmc3
+ * Description: init the PLL and clocks for SDMMC3 controller
+ */
+void clock_init_mmc3(void)
+{
        clock_start_periph_pll(PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH, 20000000);
 }
 
 /*
- * Routine: pin_mux_mmc
- * Description: setup the pin muxes/tristate values for the SDMMC(s)
+ * Routine: clock_init_mmc2
+ * Description: init the PLL and clocks for SDMMC2 controller
  */
-static void pin_mux_mmc(void)
+void clock_init_mmc2(void)
+{
+       clock_start_periph_pll(PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH, 20000000);
+}
+
+/*
+ * Routine: pin_mux_mmc4
+ * Description: setup the pin muxes/tristate values for SDMMC4
+ */
+void pin_mux_mmc4(void)
 {
        /* SDMMC4: config 3, x8 on 2nd set of pins */
        pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4);
@@ -125,7 +142,14 @@ static void pin_mux_mmc(void)
        pinmux_tristate_disable(PINGRP_ATB);
        pinmux_tristate_disable(PINGRP_GMA);
        pinmux_tristate_disable(PINGRP_GME);
+}
 
+/*
+ * Routine: pin_mux_mmc3
+ * Description: setup the pin muxes/tristate values for SDMMC3
+ */
+void pin_mux_mmc3(void)
+{
        /* SDMMC3: SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */
        pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3);
        pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3);
@@ -135,6 +159,25 @@ static void pin_mux_mmc(void)
        pinmux_tristate_disable(PINGRP_SDD);
        pinmux_tristate_disable(PINGRP_SDB);
 }
+
+/*
+ * Routine: pin_mux_mmc2
+ * Description: setup the pin muxes/tristate values for SDMMC2
+ */
+void pin_mux_mmc2(void)
+{
+       /* SDMMC2: SDIO2_CLK, SDIO2_CMD, SDIO2_DAT[7:0] */
+       pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2);
+       pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2);
+
+       pinmux_tristate_disable(PINGRP_DTA);
+       pinmux_tristate_disable(PINGRP_DTD);
+
+       /* For power GPIO PI6 */
+       pinmux_tristate_disable(PINGRP_ATA);
+       /* For power GPIO PT3 */
+       pinmux_tristate_disable(PINGRP_DTB);
+}
 #endif
 
 /*
@@ -152,28 +195,6 @@ int board_init(void)
        return 0;
 }
 
-#ifdef CONFIG_TEGRA2_MMC
-/* this is a weak define that we are overriding */
-int board_mmc_init(bd_t *bd)
-{
-       debug("board_mmc_init called\n");
-       /* Enable clocks, muxes, etc. for SDMMC controllers */
-       clock_init_mmc();
-       pin_mux_mmc();
-       gpio_config_mmc();
-
-       debug("board_mmc_init: init eMMC\n");
-       /* init dev 0, eMMC chip, with 8-bit bus */
-       tegra2_mmc_init(0, 8);
-
-       debug("board_mmc_init: init SD slot\n");
-       /* init dev 1, SD slot, with 4-bit bus */
-       tegra2_mmc_init(1, 4);
-
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_BOARD_EARLY_INIT_F
 int board_early_init_f(void)
 {
diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
index 344e702..eee475d 100644
--- a/board/nvidia/common/board.h
+++ b/board/nvidia/common/board.h
@@ -26,7 +26,13 @@
 
 void tegra2_start(void);
 void gpio_config_uart(void);
-void gpio_config_mmc(void);
+void clock_init_mmc4(void);
+void clock_init_mmc3(void);
+void clock_init_mmc2(void);
+void pin_mux_mmc4(void);
+void pin_mux_mmc3(void);
+void pin_mux_mmc2(void);
 int tegra2_mmc_init(int dev_index, int bus_width);
+int tegra2_mmc_index(struct mmc *mmc);
 
 #endif /* BOARD_H */
diff --git a/board/nvidia/harmony/harmony.c b/board/nvidia/harmony/harmony.c
index cbb30d6..228ae2e 100644
--- a/board/nvidia/harmony/harmony.c
+++ b/board/nvidia/harmony/harmony.c
@@ -23,10 +23,13 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/clock.h>
 #include <asm/arch/tegra2.h>
+#include <asm/gpio.h>
 #ifdef CONFIG_TEGRA2_MMC
 #include <mmc.h>
 #endif
+#include "../common/board.h"
 
 /*
  * Routine: gpio_config_uart
@@ -43,18 +46,61 @@ void gpio_config_uart(void)
  */
 void gpio_config_mmc(void)
 {
-       /* Not implemented for now */
+       /* Set SDMMC4 power (GPIO I6) */
+       gpio_request(GPIO_PI6, "SDMMC4 power");
+       gpio_direction_output(GPIO_PI6, 1);
+
+       /* Config pin as GPI for SDMMC4 Card Detect (GPIO H2) */
+       gpio_request(GPIO_PH2, "SDMMC4 card detect");
+       gpio_direction_input(GPIO_PH2);
+
+       /* Set SDMMC2 power (GPIO T3) */
+       gpio_request(GPIO_PT3, "SDMMC2 power");
+       gpio_direction_output(GPIO_PT3, 1);
+
+       /* Config pin as GPI for SDMMC2 Card Detect (GPIO I5) */
+       gpio_request(GPIO_PI5, "SDMMC2 card detect");
+       gpio_direction_input(GPIO_PI5);
+}
+
+/* this is a weak define that we are overriding */
+int board_mmc_init(bd_t *bd)
+{
+       debug("board_mmc_init called\n");
+       /* Enable clocks, muxes, etc. for SDMMC controllers */
+       clock_init_mmc4();
+       clock_init_mmc2();
+       pin_mux_mmc4();
+       pin_mux_mmc2();
+       gpio_config_mmc();
+
+       debug("board_mmc_init: init SD slot J26\n");
+       /* init dev 0, SD slot J26, with 8-bit bus */
+       tegra2_mmc_init(0, 8);
+
+       debug("board_mmc_init: init SD slot J5\n");
+       /* init dev 2, SD slot J5, with 8-bit bus */
+       tegra2_mmc_init(2, 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");
-       /*
-        * Hard-code CD presence for now. Need to add GPIO inputs
-        * for Harmony
-        */
        *cd = 1;
+
+       if (tegra2_mmc_index(mmc) == 0) {
+               /* Harmony SDMMC4 = SDIO4_CD = GPIO_PH2 */
+               if (gpio_get_value(GPIO_PH2))
+                       *cd = 0;
+       } else {
+               /* Harmony SDMMC2 = SDIO2_CD = GPIO_PI5 */
+               if (gpio_get_value(GPIO_PI5))
+                       *cd = 0;
+       }
+
        return 0;
 }
 #endif
diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c
index 578d909..37edbca 100644
--- a/board/nvidia/seaboard/seaboard.c
+++ b/board/nvidia/seaboard/seaboard.c
@@ -28,6 +28,7 @@
 #ifdef CONFIG_TEGRA2_MMC
 #include <mmc.h>
 #endif
+#include "../common/board.h"
 
 /*
  * Routine: gpio_config_uart
@@ -71,6 +72,28 @@ void gpio_config_mmc(void)
 }
 
 /* this is a weak define that we are overriding */
+int board_mmc_init(bd_t *bd)
+{
+       debug("board_mmc_init called\n");
+       /* Enable clocks, muxes, etc. for SDMMC controllers */
+       clock_init_mmc4();
+       clock_init_mmc3();
+       pin_mux_mmc4();
+       pin_mux_mmc3();
+       gpio_config_mmc();
+
+       debug("board_mmc_init: init eMMC\n");
+       /* init dev 0, eMMC chip, with 8-bit bus */
+       tegra2_mmc_init(0, 8);
+
+       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");
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 9e741f2..223dbf3 100644
--- a/drivers/mmc/tegra2_mmc.c
+++ b/drivers/mmc/tegra2_mmc.c
@@ -478,3 +478,21 @@ int tegra2_mmc_init(int dev_index, int bus_width)
                dev_index, bus_width);
        return tegra2_mmc_initialize(dev_index, bus_width);
 }
+
+int tegra2_mmc_index(struct mmc *mmc)
+{
+       struct mmc_host *host = (struct mmc_host *)mmc->priv;
+
+       switch (host->base) {
+       case TEGRA2_SDMMC3_BASE:
+               return 1;
+       case TEGRA2_SDMMC2_BASE:
+               return 2;
+       case TEGRA2_SDMMC1_BASE:
+               return 3;
+       case TEGRA2_SDMMC4_BASE:
+       default:
+               return 0;
+       }
+}
+
-- 
1.7.0.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to