[U-Boot] [PATCH v2 3/4] tegra2: Enable second SD port (J5) on Harmony
Stephen Warren
swarren at nvidia.com
Tue Oct 4 19:32:47 CEST 2011
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 <swarren at 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 1310e3d..0667eaa 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
More information about the U-Boot
mailing list