summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@stericsson.com>2011-12-14 11:16:02 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:57 +0200
commit7acb3a6f3496c5f12197ea3272bdeedfa9133246 (patch)
treeced36eb29cb0c276a5ec746d46b1deae56251625
parent5e13c86df896b657e453626305cd04a8a6e69610 (diff)
mach-ux500: Cumulative changes into board-*-sdi.c files
Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> mach-ux500: Add SDIO WLAN support on sdi1 Fixing sdi0 access on snowball MMC_CAP_SD_HIGHSPEED is not supported on snowball resulting on initialisation errors. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> mach-ux500: sdio/wlan: Initialized SDIO after all others SDI, because it blocks SDI thread till CW1200/WLAN is up Temporary workaround, a better way in SDIO card detection must be found Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> mach-ux500: Add SDIO VDD handler for GPIO config It seems as PL18X does not drive all pins in a correct way when the block is powered but not initialized. Since CW1200 is sensitive to this (it samples the DAT2 signal level on bootup to choose between SPI and SDIO mode), it must be assured that the pins are in a correct state at all times. This is done by adding a VDD handler for SDI1 which reconfigures all the pins to GPIO pins with pullups when PL18X is not in an initialized state. ST-Ericsson ID: 327586 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com> mach-ux500: Enable DMA for sdi1 ST-Ericsson ID: 329007 Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> mach-ux500: mmc: Fix for MMC working on u5500 and DMA support. Configuring DMA support on u5500 for MMC. ST Ericsson ID:WP257117 Signed-off-by: seshagh <seshagiri.holi@stericsson.com> mach-ux500: sdi0: Enable 8 bit mode for MMC Enable 8-bit mode in platform data for EMMC driver in U4500. ST-Ericsson Id: ER 332947 Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> mach-ux500: Use pm_runtime for sdi[x] for GPIOs + board-mop500-pins.c alignment Setup GPIO pins for sdi0, sdi1, sdi2 and sdi4 to be controlled by pm_runtime. GPIO pins for card detect and levelshifter is not included. ST-Ericsson ID: ER334765 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> mach-ux500:sdi3: Added platform data for SDIO support Added platform data for SDIO support on U4500 board Needs rework for power saving part (MMC_CAP_DISABLE, wakeup_handler not present) ST-Ericsson Id: AP 337858 Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> mach-ux500:u5500: Fixup vdd_handler for sdi1 Levelshifter was not enabled at POWER_ON, this is corrected. Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> mach-ux500:u5500: set vsel of levelshifter to 2.9V configure the vsel to get 2.9V output for the levelshifter ST-Ericsson ID: ER 339616 Signed-off-by: Hanumath Prasad <hanumath.prasad@stericsson.com> mach-ux500: Fix build problems temporary Very temporary fixes to make it build until we have proper fixes for this issues. Signed-off-by: Robert Marklund <robert.marklund@stericsson.com> mach-ux500: mmc: Fix board merge & cleanup Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> mach-ux500: Suppress ../../ for external include Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> ARM: ux500: sdi: Remove u8500 v1 support ST-Ericsson Linux next: Not tested, ask SSM for ER ST-Ericsson ID: 342987 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com> mach-ux500: Solved rebase conflict for sd/mmc U8500: From commit 69a86710 by Philippe Langlais, corrections done for MCI defines. From commit 2e7233f2 by Philippe Langlais, corrections done for SDIO_CMD53 workaround. U5500: From commit be4f9997 by Philippe Langlais, corrections done for SDIO_CMD53 workaround. u5500:SD/MMC migrate to kernel3.0 SD/MMC platform data migrate to kernel3.0 ST-Ericsson ID: 352334 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> mach-ux500:u8500: Clean up sdi[n] configurations This makes an inital clean up of the mmc/sd/sdio devices for kernel 3.0. Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com> mach-ux500:u5500: Clean up sdi[n] configurations This makes an initial clean up of the mmc/sd/sdio devices for kernel 3.0. Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com> ux500: u8500: Change DMA configuration for SD-card This patch is a mixture of two earlier patches: By Sebastian Rasmussen: ux500: Use other logical DMA channel for SD-card Previously PoP eMMC SDI has been in the same event group as SD-card SDI, which means that they have been sharing the same physical DMA channels. Moreover one of those channels was reserved for other purposes, causing transfers for each interface to compete for the same physical DMA channel. In addition there appears to be a HW issue that causes data to be lost in the middle of DMA transfers, which ended up with DMAC and MMCI not agreeing on how much data was still to be transferred, thereby resulting in a hang and eventually in a crash. This patch moves SD-card DMA transfers to another event group which means that it no longer competes for the same physical DMA channel. This results in that no data is lost in the transfers and no hang is observed. By Rabin Vincent: ux500: mop500: force SD/MMC and MSP2 TX onto different channels SD/MMC with event line 1 can be in channel 0 or 1. Force both Rx and Tx onto channel 0. Both will anyway not used at the same time, and with this change channel 1 will be available for MSP2 Tx without sharing. Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> mach-ux500: Re-introduce specific mmc init for Snowball boards Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> fix board-mop500-sdi
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c32
-rw-r--r--arch/arm/mach-ux500/board-u5500-sdi.c244
2 files changed, 240 insertions, 36 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 920251cf834..14a7b6e69d0 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -11,15 +11,16 @@
#include <linux/amba/mmci.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
+#include <linux/delay.h>
#include <asm/mach-types.h>
#include <plat/ste_dma40.h>
#include <mach/devices.h>
#include <mach/hardware.h>
+#include <mach/ste-dma40-db8500.h>
#include "devices-db8500.h"
#include "board-mop500.h"
-#include "ste-dma40-db8500.h"
/*
* v2 has a new version of this block that need to be forced, the number found
@@ -50,6 +51,7 @@ static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
*/
gpio_direction_output(sdi0_vsel, 0);
gpio_direction_output(sdi0_en, 1);
+ udelay(100);
break;
case MMC_POWER_OFF:
gpio_direction_output(sdi0_vsel, 0);
@@ -64,19 +66,23 @@ static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
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,
+ .src_dev_type = DB8500_DMA_DEV1_SD_MMC0_RX,
.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
+ .use_fixed_channel = true,
+ .phy_channel = 0,
};
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,
+ .dst_dev_type = DB8500_DMA_DEV1_SD_MMC0_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
+ .use_fixed_channel = true,
+ .phy_channel = 0,
};
#endif
@@ -121,14 +127,6 @@ static void sdi0_configure(struct device *parent)
db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
}
-void mop500_sdi_tc35892_init(struct device *parent)
-{
- mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
- sdi0_en = GPIO_SDMMC_EN;
- sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
- sdi0_configure(parent);
-}
-
/*
* SDI1 (SDIO WLAN)
*/
@@ -241,6 +239,16 @@ static struct mmci_platform_data mop500_sdi4_data = {
#endif
};
+void mop500_sdi_tc35892_init(struct device *parent)
+{
+ mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
+ sdi0_en = GPIO_SDMMC_EN;
+ sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
+ sdi0_configure(parent);
+ /* WLAN SDIO channel */
+ db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
+}
+
void __init mop500_sdi_init(struct device *parent)
{
/* PoP:ed eMMC */
@@ -267,6 +275,8 @@ void __init snowball_sdi_init(struct device *parent)
sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
sdi0_configure(parent);
+ /* WLAN SDIO channel */
+ db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
}
void __init hrefv60_sdi_init(struct device *parent)
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c
index 836112eedde..de6e0e5192b 100644
--- a/arch/arm/mach-ux500/board-u5500-sdi.c
+++ b/arch/arm/mach-ux500/board-u5500-sdi.c
@@ -5,34 +5,28 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
#include <linux/amba/mmci.h>
#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
-#include <plat/pincfg.h>
-#include <plat/gpio-nomadik.h>
-#include <mach/db5500-regs.h>
+#include <asm/mach-types.h>
#include <plat/ste_dma40.h>
+#include <mach/devices.h>
+#include <mach/hardware.h>
+#include <mach/ste-dma40-db5500.h>
-#include "pins-db5500.h"
#include "devices-db5500.h"
-#include "ste-dma40-db5500.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,
-};
+#include "board-u5500.h"
+/*
+ * SDI 0 (eMMC)
+ */
#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = {
+static struct stedma40_chan_cfg sdi0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
.src_dev_type = DB5500_DMA_DEV24_SDMMC0_RX,
@@ -41,7 +35,7 @@ struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = {
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
-static struct stedma40_chan_cfg u5500_sdi0_dma_cfg_tx = {
+static struct stedma40_chan_cfg sdi0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
@@ -61,14 +55,214 @@ static struct mmci_platform_data u5500_sdi0_data = {
.gpio_wp = -1,
#ifdef CONFIG_STE_DMA40
.dma_filter = stedma40_filter,
- .dma_rx_param = &u5500_sdi0_dma_cfg_rx,
- .dma_tx_param = &u5500_sdi0_dma_cfg_tx,
+ .dma_rx_param = &sdi0_dma_cfg_rx,
+ .dma_tx_param = &sdi0_dma_cfg_tx,
+#endif
+};
+
+/*
+ * SDI 1 (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 u5500_sdi1_vdd_handler(struct device *dev, unsigned int vdd,
+ unsigned char power_mode)
+{
+ switch (power_mode) {
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ /*
+ * 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.
+ */
+ gpio_set_value_cansleep(GPIO_MMC_CARD_CTRL, 1);
+ udelay(100);
+ break;
+ case MMC_POWER_OFF:
+ gpio_set_value_cansleep(GPIO_MMC_CARD_CTRL, 0);
+ break;
+ }
+
+ return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
+ MCI_DATA2DIREN;
+}
+
+static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .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 = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .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,
+};
+
+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 |
+ MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_MMC_HIGHSPEED,
+ .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
+};
+
+/*
+ * SDI2 (EMMC2)
+ */
+
+static struct stedma40_chan_cfg sdi2_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB5500_DMA_DEV26_SDMMC2_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 sdi2_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB5500_DMA_DEV26_SDMMC2_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+
+static struct mmci_platform_data u5500_sdi2_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .f_max = 50000000,
+ .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 = &sdi2_dma_cfg_rx,
+ .dma_tx_param = &sdi2_dma_cfg_tx,
#endif
};
+/*
+ * SDI 3 (SDIO WLAN)
+ */
+#ifdef SDIO_DMA_ON
+#ifdef CONFIG_STE_DMA40
+static struct stedma40_chan_cfg sdi3_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB5500_DMA_DEV27_SDMMC3_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 sdi3_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB5500_DMA_DEV27_SDMMC3_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+#endif
+#endif
+
+static struct mmci_platform_data u5500_sdi3_data = {
+ .ocr_mask = MMC_VDD_29_30,
+ .f_max = 50000000,
+ .capabilities = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+#ifdef SDIO_DMA_ON
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &sdi3_dma_cfg_rx,
+ .dma_tx_param = &sdi3_dma_cfg_tx,
+#endif
+#endif
+};
+
+static void sdi1_configure(void)
+{
+ 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_warning("unable to config sdi0 gpios for level shifter.\n");
+ return;
+ }
+ /* Select the default 2.9V and eanble level shifter */
+ gpio_direction_output(pin[0], 1);
+ gpio_direction_output(pin[1], 0);
+}
+
+#define SDI_PID_V1 0x00480180
+#define SDI_PID_V2 0x10480180
+#define BACKUPRAM_ROM_DEBUG_ADDR 0xFFC
+#define MMC_BLOCK_ID 0x20
void __init u5500_sdi_init(struct device *parent)
{
- nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
+ u32 periphid = 0;
+ int mmc_blk = 0;
+
+ if (cpu_is_u5500v1())
+ periphid = SDI_PID_V1;
+ else
+ periphid = SDI_PID_V2;
+
+ if (cpu_is_u5500v2())
+ /*
+ * Fix me in 5500 v2.1
+ * Dynamic detection of booting device by reading
+ * ROM debug register from BACKUP RAM and register the
+ * corresponding EMMC.
+ * This is done due to wrong configuration of MMC0 clock
+ * in ROM code for u5500 v2.
+ */
+ mmc_blk = readl(__io_address(U5500_BACKUPRAM1_BASE) +
+ BACKUPRAM_ROM_DEBUG_ADDR);
+
+ if (mmc_blk & MMC_BLOCK_ID)
+ db5500_add_sdi2(parent, &u5500_sdi2_data, periphid);
+ else
+ db5500_add_sdi0(parent, &u5500_sdi0_data, periphid);
- db5500_add_sdi0(parent, &u5500_sdi0_data);
+ sdi1_configure();
+ db5500_add_sdi1(parent, &u5500_sdi1_data, periphid);
+ db5500_add_sdi3(parent, &u5500_sdi3_data, periphid);
}