On Wed, Mar 19, 2008 at 08:53:48PM +0200, Keppler Alecrim wrote: > What about DMA channel? Isn't it necessary? > > diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c > index 3d4a7d1..262d846 100644 > --- a/drivers/mmc/host/omap_hsmmc.c > +++ b/drivers/mmc/host/omap_hsmmc.c > @@ -514,10 +514,18 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host > *host, struct mmc_request *req) > > if (!(data->flags & MMC_DATA_WRITE)) { > host->dma_dir = DMA_FROM_DEVICE; > - sync_dev = OMAP24XX_DMA_MMC1_RX; > + if (host->id == OMAP_MMC1_DEVID) > + sync_dev = OMAP24XX_DMA_MMC1_RX; > + else > + sync_dev = OMAP24XX_DMA_MMC2_RX; > + > } else { > host->dma_dir = DMA_TO_DEVICE; > - sync_dev = OMAP24XX_DMA_MMC1_TX; > + if (host->id == OMAP_MMC1_DEVID) > + sync_dev = OMAP24XX_DMA_MMC1_TX; > + else > + sync_dev = OMAP24XX_DMA_MMC2_TX; > + > } Indeed. The kernel I'm working with already had this though. Okay, I checked other differences between in the omap_hsmmc.c that I'm working with and didn't find anything necessary for MMC2. I've incorporated this into the patch below, which I think is everything needed to get MMC2 working. This should emphasize the point that someone needs to test with this patch, as I am unable to test it myself. I would also like someone familiar with both OMAP 2430 and 2420 to look at the pin-muxing changes in the patch. I found that some pins were being set up in the MMC1 configuration with the same configuration register offsets as those for MMC2. I assumed that those were for the 2420 and modified the MMC1 initialization accordingly. If these changes are correct I will break them out into a separate patch before I submit. Cheers, Seth diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index fb639f5..48704b2 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -210,6 +210,14 @@ MUX_CFG_24XX("AC10_2430_MCBSP2_FSX_OFF",0x012E, 0, 0, 0, 1) MUX_CFG_24XX("AD16_2430_MCBSP2_CLX_OFF",0x012F, 0, 0, 0, 1) MUX_CFG_24XX("AE13_2430_MCBSP2_DX_OFF", 0x0130, 0, 0, 0, 1) MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF", 0x0131, 0, 0, 0, 1) + +/* MMC2 */ +MUX_CFG_24XX("V26_2430_MMC2_CLKO", 0x0f9, 0, 0, 0, 1) +MUX_CFG_24XX("V24_2430_MMC2_DAT3", 0x0fa, 0, 0, 0, 1) +MUX_CFG_24XX("W20_2430_MMC2_CMD", 0x0fb, 0, 0, 0, 1) +MUX_CFG_24XX("V23_2430_MMC2_DAT0", 0x0fc, 0, 0, 0, 1) +MUX_CFG_24XX("V25_2430_MMC2_DAT2", 0x0fd, 0, 0, 0, 1) +MUX_CFG_24XX("Y24_2430_MMC2_DAT1", 0x0fe, 0, 0, 0, 1) }; #define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index ec9a999..1859ed4 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -161,7 +161,17 @@ static inline void omap_init_kp(void) {} #define OMAP_MMC1_BASE 0xfffb7800 #define OMAP_MMC1_INT INT_MMC #endif -#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ + +#if defined(CONFIG_ARCH_OMAP16XX) +#define OMAP_MMC2_BASE 0xfffb7c00 +#define OMAP_MMC2_INT INT_1610_MMC2 +#elif defined(CONFIG_ARCH_OMAP2430) +#define OMAP_MMC2_BASE 0x480b4000 +#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ +#endif + +#define OMAP_MMC2_SUPPORT \ + (defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430)) static struct omap_mmc_platform_data mmc1_data; @@ -190,7 +200,7 @@ static struct platform_device mmc_omap_device1 = { .resource = mmc1_resources, }; -#ifdef CONFIG_ARCH_OMAP16XX +#if OMAP_MMC2_SUPPORT static struct omap_mmc_platform_data mmc2_data; @@ -204,7 +214,7 @@ static struct resource mmc2_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = INT_1610_MMC2, + .start = OMAP_MMC2_INT, .flags = IORESOURCE_IRQ, }, }; @@ -243,11 +253,13 @@ static void __init omap_init_mmc(void) if (mmc->enabled) { if (cpu_is_omap24xx()) { omap_cfg_reg(H18_24XX_MMC_CMD); - omap_cfg_reg(H15_24XX_MMC_CLKI); omap_cfg_reg(G19_24XX_MMC_CLKO); omap_cfg_reg(F20_24XX_MMC_DAT0); - omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); - omap_cfg_reg(G18_24XX_MMC_CMD_DIR); + if (cpu_is_omap242x()) { + omap_cfg_reg(H15_24XX_MMC_CLKI); + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); + omap_cfg_reg(G18_24XX_MMC_CMD_DIR); + } } else { omap_cfg_reg(MMC_CMD); omap_cfg_reg(MMC_CLK); @@ -263,9 +275,11 @@ static void __init omap_init_mmc(void) omap_cfg_reg(H14_24XX_MMC_DAT1); omap_cfg_reg(E19_24XX_MMC_DAT2); omap_cfg_reg(D19_24XX_MMC_DAT3); - omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); - omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); - omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); + if (cpu_is_omap242x()) { + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); + } } else { omap_cfg_reg(MMC_DAT1); /* NOTE: DAT2 can be on W10 (here) or M15 */ @@ -291,25 +305,39 @@ static void __init omap_init_mmc(void) (void) platform_device_register(&mmc_omap_device1); } -#ifdef CONFIG_ARCH_OMAP16XX +#if OMAP_MMC2_SUPPORT /* block 2 is on newer chips, and has many pinout options */ mmc = &mmc_conf->mmc[1]; if (mmc->enabled) { if (!mmc->nomux) { - omap_cfg_reg(Y8_1610_MMC2_CMD); - omap_cfg_reg(Y10_1610_MMC2_CLK); - omap_cfg_reg(R18_1610_MMC2_CLKIN); - omap_cfg_reg(W8_1610_MMC2_DAT0); + if (cpu_is_omap243x()) { + omap_cfg_reg(V26_2430_MMC2_CLKO); + omap_cfg_reg(W20_2430_MMC2_CMD); + omap_cfg_reg(V23_2430_MMC2_DAT0); + } else { + omap_cfg_reg(Y8_1610_MMC2_CMD); + omap_cfg_reg(Y10_1610_MMC2_CLK); + omap_cfg_reg(R18_1610_MMC2_CLKIN); + omap_cfg_reg(W8_1610_MMC2_DAT0); + } if (mmc->wire4) { - omap_cfg_reg(V8_1610_MMC2_DAT1); - omap_cfg_reg(W15_1610_MMC2_DAT2); - omap_cfg_reg(R10_1610_MMC2_DAT3); + if (cpu_is_omap243x()) { + omap_cfg_reg(Y24_2430_MMC2_DAT1); + omap_cfg_reg(V25_2430_MMC2_DAT2); + omap_cfg_reg(V24_2430_MMC2_DAT3); + } else { + omap_cfg_reg(V8_1610_MMC2_DAT1); + omap_cfg_reg(W15_1610_MMC2_DAT2); + omap_cfg_reg(R10_1610_MMC2_DAT3); + } } /* These are needed for the level shifter */ - omap_cfg_reg(V9_1610_MMC2_CMDDIR); - omap_cfg_reg(V5_1610_MMC2_DATDIR0); - omap_cfg_reg(W19_1610_MMC2_DATDIR1); + if (cpu_is_omap16xx()) { + omap_cfg_reg(V9_1610_MMC2_CMDDIR); + omap_cfg_reg(V5_1610_MMC2_DATDIR0); + omap_cfg_reg(W19_1610_MMC2_DATDIR1); + } } /* Feedback clock must be set on OMAP-1710 MMC2 */ diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 3d4a7d1..0f1bb9c 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -388,8 +388,12 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) * If a MMC dual voltage card is detected, the set_ios fn calls * this fn with VDD bit set for 1.8V. Upon card removal from the * slot, mmc_omap_detect fn sets the VDD back to 3V. + * + * Only MMC1 supports 3.0V. MMC2 will not function if SDVS30 is + * set in HCTL. */ - if (((1 << vdd) == MMC_VDD_32_33) || ((1 << vdd) == MMC_VDD_33_34)) + if (host->id == OMAP_MMC1_DEVID && (((1 << vdd) == MMC_VDD_32_33) || + ((1 << vdd) == MMC_VDD_33_34))) reg_val |= SDVS30; if ((1 << vdd) == MMC_VDD_165_195) reg_val |= SDVS18; @@ -514,10 +518,16 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req) if (!(data->flags & MMC_DATA_WRITE)) { host->dma_dir = DMA_FROM_DEVICE; - sync_dev = OMAP24XX_DMA_MMC1_RX; + if (host->id == OMAP_MMC1_DEVID) + sync_dev = OMAP24XX_DMA_MMC1_RX; + else + sync_dev = OMAP24XX_DMA_MMC2_RX; } else { host->dma_dir = DMA_TO_DEVICE; - sync_dev = OMAP24XX_DMA_MMC1_TX; + if (host->id == OMAP_MMC1_DEVID) + sync_dev = OMAP24XX_DMA_MMC1_TX; + else + sync_dev = OMAP24XX_DMA_MMC2_TX; } ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb, @@ -689,6 +699,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev) struct mmc_omap_host *host = NULL; struct resource *res; int ret = 0, irq; + u32 hctl, capa; if (pdata == NULL) { dev_err(&pdev->dev, "Platform Data is missing\n"); @@ -775,11 +786,20 @@ static int __init omap_mmc_probe(struct platform_device *pdev) if (pdata->conf.wire4) mmc->caps |= MMC_CAP_4_BIT_DATA; + /* Only MMC1 supports 3.0V */ + if (host->id == OMAP_MMC1_DEVID) { + hctl = SDVS30; + capa = VS30 | VS18; + } else { + hctl = SDVS18; + capa = VS18; + } + OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) | SDVS30); + OMAP_HSMMC_READ(host->base, HCTL) | hctl); - OMAP_HSMMC_WRITE(host->base, CAPA, OMAP_HSMMC_READ(host->base, - CAPA) | VS30 | VS18); + OMAP_HSMMC_WRITE(host->base, CAPA, + OMAP_HSMMC_READ(host->base, CAPA) | capa); /* Set the controller to AUTO IDLE mode */ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h index f216b4d..c58db03 100644 --- a/include/asm-arm/arch-omap/mux.h +++ b/include/asm-arm/arch-omap/mux.h @@ -641,6 +641,14 @@ enum omap24xx_index { AE13_2430_MCBSP2_DX_OFF, AD13_2430_MCBSP2_DR_OFF, + /* 2430 MMC2 */ + V26_2430_MMC2_CLKO, + V24_2430_MMC2_DAT3, + W20_2430_MMC2_CMD, + V23_2430_MMC2_DAT0, + V25_2430_MMC2_DAT2, + Y24_2430_MMC2_DAT1, + }; enum omap34xx_index { -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html