From 849369d6c66d3054688672f97d31fceb8e8230fb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Dec 2015 04:40:36 +0000 Subject: initial_commit --- arch/arm/mach-ux500/board-mop500-sdi.c | 218 +++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 arch/arm/mach-ux500/board-mop500-sdi.c (limited to 'arch/arm/mach-ux500/board-mop500-sdi.c') diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c new file mode 100644 index 00000000..7c6cb4fa --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Hanumath Prasad + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "devices-db8500.h" +#include "board-mop500.h" +#include "ste-dma40-db8500.h" + +/* + * SDI 0 (MicroSD slot) + */ + +/* MMCIPOWER bits */ +#define MCI_DATA2DIREN (1 << 2) +#define MCI_CMDDIREN (1 << 3) +#define MCI_DATA0DIREN (1 << 4) +#define MCI_DATA31DIREN (1 << 5) +#define MCI_FBCLKEN (1 << 7) + +static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, + unsigned char power_mode) +{ + if (power_mode == MMC_POWER_UP) + gpio_set_value_cansleep(GPIO_SDMMC_EN, 1); + else if (power_mode == MMC_POWER_OFF) + gpio_set_value_cansleep(GPIO_SDMMC_EN, 0); + + return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | + MCI_DATA2DIREN | MCI_DATA31DIREN; +} + +#ifdef CONFIG_STE_DMA40 +struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV29_SD_MM0_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 mop500_sdi0_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif + +static struct mmci_platform_data mop500_sdi0_data = { + .vdd_handler = mop500_sdi0_vdd_handler, + .ocr_mask = MMC_VDD_29_30, + .f_max = 100000000, + .capabilities = MMC_CAP_4_BIT_DATA, + .gpio_wp = -1, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &mop500_sdi0_dma_cfg_rx, + .dma_tx_param = &mop500_sdi0_dma_cfg_tx, +#endif +}; + +/* GPIO pins used by the sdi0 level shifter */ +static int sdi0_en = -1; +static int sdi0_vsel = -1; + +static void sdi0_configure(void) +{ + int ret; + + ret = gpio_request(sdi0_en, "level shifter enable"); + if (!ret) + ret = gpio_request(sdi0_vsel, + "level shifter 1v8-3v select"); + + if (ret) { + pr_warning("unable to config sdi0 gpios for level shifter.\n"); + return; + } + + /* Select the default 2.9V and enable level shifter */ + gpio_direction_output(sdi0_vsel, 0); + gpio_direction_output(sdi0_en, 1); + + /* Add the device, force v2 to subrevision 1 */ + if (cpu_is_u8500v2()) + db8500_add_sdi0(&mop500_sdi0_data, 0x10480180); + else + db8500_add_sdi0(&mop500_sdi0_data, 0); +} + +void mop500_sdi_tc35892_init(void) +{ + mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; + sdi0_en = GPIO_SDMMC_EN; + sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL; + sdi0_configure(); +} + +/* + * SDI 2 (POP eMMC, not on DB8500ed) + */ + +#ifdef CONFIG_STE_DMA40 +struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV28_SD_MM2_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 mop500_sdi2_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif + +static struct mmci_platform_data mop500_sdi2_data = { + .ocr_mask = MMC_VDD_165_195, + .f_max = 100000000, + .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_cd = -1, + .gpio_wp = -1, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &mop500_sdi2_dma_cfg_rx, + .dma_tx_param = &mop500_sdi2_dma_cfg_tx, +#endif +}; + +/* + * SDI 4 (on-board eMMC) + */ + +#ifdef CONFIG_STE_DMA40 +struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV42_SD_MM4_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 mop500_sdi4_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX, + .src_info.data_width = STEDMA40_WORD_WIDTH, + .dst_info.data_width = STEDMA40_WORD_WIDTH, +}; +#endif + +static struct mmci_platform_data mop500_sdi4_data = { + .ocr_mask = MMC_VDD_29_30, + .f_max = 100000000, + .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED, + .gpio_cd = -1, + .gpio_wp = -1, +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &mop500_sdi4_dma_cfg_rx, + .dma_tx_param = &mop500_sdi4_dma_cfg_tx, +#endif +}; + +void __init mop500_sdi_init(void) +{ + u32 periphid = 0; + + /* v2 has a new version of this block that need to be forced */ + if (cpu_is_u8500v2()) + periphid = 0x10480180; + /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ + if (!cpu_is_u8500v10()) + mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; + db8500_add_sdi2(&mop500_sdi2_data, periphid); + + /* On-board eMMC */ + db8500_add_sdi4(&mop500_sdi4_data, periphid); + + if (machine_is_hrefv60()) { + mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; + sdi0_en = HREFV60_SDMMC_EN_GPIO; + sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; + sdi0_configure(); + } + /* + * On boards with the TC35892 GPIO expander, sdi0 will finally + * be added when the TC35892 initializes and calls + * mop500_sdi_tc35892_init() above. + */ +} -- cgit v1.2.3