From 0df1f2533629b743e0f5f1a35abdac8f282f13aa Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Fri, 6 May 2011 11:23:56 +0200 Subject: mach-ux500: Fix for MMC working on u5500 and DMA support. Configuring DMA support on u5500 for MMC. ST Ericsson ID:WP257117 Change-Id: I00c45e47e77a6a472e8eb8471a64e163036cd8c8 Signed-off-by: seshagh Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18722 Reviewed-by: Preetham-rao K Tested-by: Preetham-rao K Conflicts: arch/arm/mach-ux500/Makefile arch/arm/mach-ux500/board-u5500-sdi.c arch/arm/mach-ux500/board-u5500.c --- arch/arm/mach-ux500/board-u5500-sdi.c | 100 ++++++++++++++++++++++++++++------ arch/arm/mach-ux500/board-u5500.c | 18 ++++++ arch/arm/mach-ux500/board-u5500.h | 14 +++++ 3 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 arch/arm/mach-ux500/board-u5500.h (limited to 'arch/arm') diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c index d5485b68ffb..365a770c09a 100644 --- a/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/arch/arm/mach-ux500/board-u5500-sdi.c @@ -16,21 +16,11 @@ #include "pins-db5500.h" #include "devices-db5500.h" +#include "board-u5500.h" -static pin_cfg_t u5500_sdi_pins[] = { - /* SDI0 (POP eMMC) */ - GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP, - GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, -}; - +/* + * SDI0 (EMMC) + */ #ifdef CONFIG_STE_DMA40 struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, @@ -50,6 +40,26 @@ static struct stedma40_chan_cfg u5500_sdi0_dma_cfg_tx = { .dst_info.data_width = STEDMA40_WORD_WIDTH, }; #endif +/* + * SDI1 (SD/MMC) + */ +#ifdef CONFIG_STE_DMA40 +static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB5500_DMA_DEV25_SDMMC1_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; + +static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB5500_DMA_DEV25_SDMMC1_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif static struct mmci_platform_data u5500_sdi0_data = { .ocr_mask = MMC_VDD_165_195, @@ -66,9 +76,67 @@ static struct mmci_platform_data u5500_sdi0_data = { #endif }; -void __init u5500_sdi_init(void) +static u32 u5500_sdi1_vdd_handler(struct device *dev, unsigned int vdd, + unsigned char power_mode) +{ + /* + * Level shifter voltage should depend on vdd to when deciding + * on either 1.8V or 2.9V. Once the decision has been made the + * level shifter must be disabled and re-enabled with a changed + * select signal in order to switch the voltage. Since there is + * no framework support yet for indicating 1.8V in vdd, use the + * default 2.9V. + */ + if (power_mode == MMC_POWER_UP) + gpio_set_value_cansleep(GPIO_MMC_CARD_CTRL, 1); + else if (power_mode == MMC_POWER_OFF) + gpio_set_value_cansleep(GPIO_MMC_CARD_CTRL, 0); + return 0; +} + +static struct mmci_platform_data u5500_sdi1_data = { + .vdd_handler = u5500_sdi1_vdd_handler, + .ocr_mask = MMC_VDD_29_30, + .f_max = 50000000, + .capabilities = MMC_CAP_4_BIT_DATA, + .gpio_cd = GPIO_SDMMC_CD, + .gpio_wp = -1, + .cd_invert = true, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &sdi1_dma_cfg_rx, + .dma_tx_param = &sdi1_dma_cfg_tx, +#endif +}; + +static void sdi1_configure(void) { - nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); + int pin[2]; + int ret; + + /* Level-shifter GPIOs */ + pin[0] = GPIO_MMC_CARD_CTRL; + pin[1] = GPIO_MMC_CARD_VSEL; + + ret = gpio_request(pin[0], "MMC_CARD_CTRL"); + if (!ret) + ret = gpio_request(pin[1], "MMC_CARD_VSEL"); + if (ret) { + pr_err("mach-u5500: error in configuring \ + GPIO pins for MMC\n"); + return; + } + /* Select the default 2.9V and eanble level shifter */ + gpio_direction_output(pin[0], 1); + gpio_direction_output(pin[1], 1); + +} + +void __init u5500_sdi_init(void) +{ db5500_add_sdi0(&u5500_sdi0_data); + sdi1_configure(); + db5500_add_sdi1(&u5500_sdi1_data); } + diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 20ca76d6dab..41610c5002e 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -95,6 +95,24 @@ static pin_cfg_t u5500_pins[] = { /* TOUCH_IRQ */ GPIO179_GPIO | PIN_INPUT_PULLUP, + + /* SDI1 (SD-CARD) */ + GPIO191_MC1_DAT0 | PIN_INPUT_PULLUP, + GPIO192_MC1_DAT1 | PIN_INPUT_PULLUP, + GPIO193_MC1_DAT2 | PIN_INPUT_PULLUP, + GPIO194_MC1_DAT3 | PIN_INPUT_PULLUP, + GPIO195_MC1_CLK | PIN_OUTPUT_LOW, + GPIO196_MC1_CMD | PIN_INPUT_PULLUP, + GPIO197_MC1_CMDDIR | PIN_OUTPUT_HIGH, + GPIO198_MC1_FBCLK | PIN_INPUT_NOPULL, + GPIO199_MC1_DAT0DIR | PIN_OUTPUT_HIGH, + /* SD-CARD detect/levelshifter pins */ + GPIO180_GPIO | PIN_INPUT_PULLUP, + GPIO227_GPIO, + GPIO185_GPIO, + + /* Display & HDMI HW sync */ + GPIO204_LCD_VSI1 | PIN_INPUT_PULLUP, }; /* diff --git a/arch/arm/mach-ux500/board-u5500.h b/arch/arm/mach-ux500/board-u5500.h new file mode 100644 index 00000000000..7bb0ea918bc --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __BOARD_U5500_H +#define __BOARD_U5500_H + +#define GPIO_SDMMC_CD 180 +#define GPIO_MMC_CARD_CTRL 227 +#define GPIO_MMC_CARD_VSEL 185 + +#endif -- cgit v1.2.3