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