/* * 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 "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_cd = GPIO_SDMMC_CD, .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 }; void mop500_sdi_tc35892_init(void) { int ret; ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN"); if (!ret) ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL, "GPIO_SDMMC_1V8_3V_SEL"); if (ret) return; gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 0); gpio_direction_output(GPIO_SDMMC_EN, 1); db8500_add_sdi0(&mop500_sdi0_data); } /* * 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) { /* 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); /* On-board eMMC */ db8500_add_sdi4(&mop500_sdi4_data); /* * sdi0 will finally be added when the TC35892 initializes and calls * mop500_sdi_tc35892_init() above. */ }