Merge git://git.kernel.org/pub/scm/linux/kernel/git/nico/orion into fixes
[pandora-kernel.git] / arch / arm / mach-ux500 / board-mop500-sdi.c
index 4b99667..bf0b024 100644 (file)
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 
-#include <plat/pincfg.h>
+#include <asm/mach-types.h>
+#include <plat/ste_dma40.h>
 #include <mach/devices.h>
 #include <mach/hardware.h>
 
 #include "devices-db8500.h"
-#include "pins-db8500.h"
 #include "board-mop500.h"
-
-static pin_cfg_t mop500_sdi_pins[] = {
-       /* SDI0 (MicroSD slot) */
-       GPIO18_MC0_CMDDIR,
-       GPIO19_MC0_DAT0DIR,
-       GPIO20_MC0_DAT2DIR,
-       GPIO21_MC0_DAT31DIR,
-       GPIO22_MC0_FBCLK,
-       GPIO23_MC0_CLK,
-       GPIO24_MC0_CMD,
-       GPIO25_MC0_DAT0,
-       GPIO26_MC0_DAT1,
-       GPIO27_MC0_DAT2,
-       GPIO28_MC0_DAT3,
-
-       /* SDI4 (on-board eMMC) */
-       GPIO197_MC4_DAT3,
-       GPIO198_MC4_DAT2,
-       GPIO199_MC4_DAT1,
-       GPIO200_MC4_DAT0,
-       GPIO201_MC4_CMD,
-       GPIO202_MC4_FBCLK,
-       GPIO203_MC4_CLK,
-       GPIO204_MC4_DAT7,
-       GPIO205_MC4_DAT6,
-       GPIO206_MC4_DAT5,
-       GPIO207_MC4_DAT4,
-};
-
-static pin_cfg_t mop500_sdi2_pins[] = {
-       /* SDI2 (POP eMMC) */
-       GPIO128_MC2_CLK,
-       GPIO129_MC2_CMD,
-       GPIO130_MC2_FBCLK,
-       GPIO131_MC2_DAT0,
-       GPIO132_MC2_DAT1,
-       GPIO133_MC2_DAT2,
-       GPIO134_MC2_DAT3,
-       GPIO135_MC2_DAT4,
-       GPIO136_MC2_DAT5,
-       GPIO137_MC2_DAT6,
-       GPIO138_MC2_DAT7,
-};
+#include "ste-dma40-db8500.h"
 
 /*
  * SDI 0 (MicroSD slot)
@@ -86,48 +44,134 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
               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)
+/* 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(GPIO_SDMMC_EN, "SDMMC_EN");
+       ret = gpio_request(sdi0_en, "level shifter enable");
        if (!ret)
-               ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL,
-                                  "GPIO_SDMMC_1V8_3V_SEL");
-       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;
+       }
 
-       gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1);
-       gpio_direction_output(GPIO_SDMMC_EN, 0);
+       /* Select the default 2.9V and enable level shifter */
+       gpio_direction_output(sdi0_vsel, 0);
+       gpio_direction_output(sdi0_en, 1);
 
+       /* Add the device */
        db8500_add_sdi0(&mop500_sdi0_data);
 }
 
+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,
@@ -135,26 +179,32 @@ static struct mmci_platform_data mop500_sdi4_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)
 {
-       nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins));
+       /* 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);
 
+       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();
+       }
        /*
-        * sdi0 will finally be added when the TC35892 initializes and calls
+        * On boards with the TC35892 GPIO expander, sdi0 will finally
+        * be added when the TC35892 initializes and calls
         * mop500_sdi_tc35892_init() above.
         */
-
-       /* PoP:ed eMMC */
-       if (!cpu_is_u8500ed()) {
-               nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins));
-               /* POP eMMC on 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);
 }