Hi friends,
I've been using Devkit 2.2 on my DM3730 development board. It works pretty well. I'm now trying to bringup wifi. This board uses an LS240 module that it is connected to the DM3730 using MMC3. I saw that Devkit 2.2 uses MS_TI_OMAP35x_WL1271_6.1.0.0.144 for the wifi drivers. By default, this code appears to be very hardcoded to use the MMC2 interface. I decided to try a quick patch to get it working using MMC3 attached here.
diff --git a/SdioDrv.c b/SdioDrv.c index 01309ab..10e4686 100644 --- a/SdioDrv.c +++ b/SdioDrv.c @@ -48,6 +48,7 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/delay.h> +#include <mach/hardware.h> #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) #include <linux/i2c/twl.h> @@ -86,9 +87,10 @@ /************************************************************************ * Defines ************************************************************************/ +int remapped_base; -#define TIWLAN_MMC_CONTROLLER 2 -#define TIWLAN_MMC_CONTROLLER_BASE_ADDR OMAP_HSMMC2_BASE +#define TIWLAN_MMC_CONTROLLER 3 +#define TIWLAN_MMC_CONTROLLER_BASE_ADDR OMAP_HSMMC3_BASE #define TIWLAN_MMC_CONTROLLER_BASE_SIZE 512 #define OMAP_MMC_MASTER_CLOCK 96000000 @@ -191,15 +193,17 @@ #define PBIAS_LITE 0x04A0 #define PBIAS_CLR 0x00 +#if 0 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) #define OMAP_MMC_REGS_BASE OMAP2_L4_IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR) #else #define OMAP_MMC_REGS_BASE IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR) #endif +#endif +#define OMAP_MMC_REGS_BASE remapped_base //TIWLAN_MMC_CONTROLLER_BASE_ADDR) -#define INT_MMC2_IRQ 86 -#define OMAP_MMC_IRQ INT_MMC2_IRQ +#define OMAP_MMC_IRQ 15 /* * MMC Host controller read/write API's. */ @@ -281,7 +285,7 @@ int g_sdio_debug_level = SDIO_DEBUGLEVEL_INFO; EXPORT_SYMBOL( g_sdio_debug_level); OMAP3530_sdiodrv_t g_drv; -struct platform_device adhoc_mmc2; +struct platform_device adhoc_mmc3; static int sdiodrv_irq_requested = 0; static int sdiodrv_mmc_power_ena = 0; static int sdiodrv_dma_on = 0; @@ -309,7 +313,7 @@ static int enable_mmc_power(int slot) PDEBUG("Enable_mmc_power() %d\n", slot); - if (slot == 2) + if (slot == 3) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, @@ -358,7 +362,7 @@ static int disable_mmc_power(int slot) PDEBUG("Disable_mmc_power() %d\n", slot); - if (slot == 2) + if (slot == 3) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, @@ -494,7 +498,7 @@ static int sdiodrv_dma_init(void) { int rc; - rc = omap_request_dma(OMAP24XX_DMA_MMC2_TX, + rc = omap_request_dma(OMAP34XX_DMA_MMC3_TX, "SDIO WRITE", NULL, &g_drv, @@ -502,11 +506,11 @@ static int sdiodrv_dma_init(void) if (rc != 0) { PERR("sdiodrv_dma_init() omap_request_dma" \ - "(OMAP24XX_DMA_MMC2_TX) FAILED\n"); + "(OMAP34XX_DMA_MMC3_TX) FAILED\n"); return rc; } - rc = omap_request_dma(OMAP24XX_DMA_MMC2_RX, + rc = omap_request_dma(OMAP34XX_DMA_MMC3_RX, "SDIO READ", sdiodrv_dma_cb, &g_drv, @@ -514,7 +518,7 @@ static int sdiodrv_dma_init(void) if (rc != 0) { PERR("sdiodrv_dma_init() omap_request_dma" - "(OMAP24XX_DMA_MMC2_RX) FAILED\n"); + "(OMAP34XX_DMA_MMC3_RX) FAILED\n"); omap_free_dma(g_drv.dma_tx_channel); return rc; } @@ -522,14 +526,14 @@ static int sdiodrv_dma_init(void) omap_set_dma_src_params(g_drv.dma_rx_channel, 0, // src_port is only for OMAP1 OMAP_DMA_AMODE_CONSTANT, - (OMAP_HSMMC2_BASE) + OMAP_HSMMC_DATA, + (OMAP_HSMMC3_BASE) + OMAP_HSMMC_DATA, 0, 0); omap_set_dma_dest_params(g_drv.dma_tx_channel, 0, // dest_port is only for OMAP1 OMAP_DMA_AMODE_CONSTANT, - (OMAP_HSMMC2_BASE) + OMAP_HSMMC_DATA, + (OMAP_HSMMC3_BASE) + OMAP_HSMMC_DATA, 0, 0); @@ -604,17 +608,21 @@ static int OMAP3530_mmc_reset(void) { int status, loops=0; + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); //p. 3598 - need to set SOFTRESET to 0x1 0bc OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | SRA); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); while ((status = OMAP_HSMMC_READ(SYSCTL) & SRA) && loops++ < SDIODRV_MAX_LOOPS); if (status & SRA) { + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PERR("OMAP3530_mmc_reset() MMC reset FAILED!! " "status=0x%x\n",status); } + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); return status; } /* end of OMAP3530_mmc_reset */ @@ -716,72 +724,97 @@ static int sdioDrv_InitHw(void) unsigned long clock_rate = 24000000; /* SDIO-CLK = 24MHz*/ - adhoc_mmc2.name = "adhoc_mmc2"; - adhoc_mmc2.id = 2; - adhoc_mmc2.dev.bus = &platform_bus_type; - adhoc_mmc2.num_resources = 0; - adhoc_mmc2.resource = NULL; + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); + adhoc_mmc3.name = "adhoc_mmc3"; + adhoc_mmc3.id = 2; + adhoc_mmc3.dev.bus = &platform_bus_type; + adhoc_mmc3.num_resources = 0; + adhoc_mmc3.resource = NULL; - pdev = (struct platform_device*)(&adhoc_mmc2); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); + pdev = (struct platform_device*)(&adhoc_mmc3); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* remember device struct for future DMA operations */ g_drv.dev = &pdev->dev; + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); rc = enable_mmc_power(TIWLAN_MMC_CONTROLLER); if (rc != 0) { + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PERR("enable_mmc_power() returned %d !!!\n", rc); goto err; } + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); sdiodrv_mmc_power_ena = 1; + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PDEBUG("Setting SDIO F&I clock Configuration\n"); - +#if 0 + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); omap_writel(omap_readl(CM_ICLKEN1_CORE) | (1<<25), CM_ICLKEN1_CORE); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); omap_writel(omap_readl(CM_FCLKEN1_CORE) | (1<<25), CM_FCLKEN1_CORE); +#endif + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); sdiodrv_iclk_enable = 1; sdiodrv_fclk_enable = 1; + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* Wait */ udelay(400); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); omap_writel(omap_readl(OMAP2_CONTROL_DEVCONF1) | (1<<6), OMAP2_CONTROL_DEVCONF1); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PDEBUG("Done setting SDIO F&I clock Configuration\n"); OMAP3530_mmc_reset(); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); //obc - init sequence p. 3600,3617 /* 1.8V */ OMAP_HSMMC_WRITE(CAPA, OMAP_HSMMC_READ(CAPA) | VS18); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); //SDVS fits p. 3650 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDVS18); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* clock gating */ OMAP_HSMMC_WRITE(SYSCONFIG, OMAP_HSMMC_READ(SYSCONFIG) | AUTOIDLE); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* bus power */ //SDBP fits p. 3650 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDBP); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* interrupts */ OMAP_HSMMC_WRITE(ISE, 0); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); OMAP_HSMMC_WRITE(IE, IE_EN_MASK); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); //p. 3601 suggests moving to the end OMAP3530_mmc_set_clock(clock_rate, &g_drv); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PINFO("SDIO clock Configuration is now set to %dMhz\n", \ (int)clock_rate/1000000); /* Bus width */ + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 4); //DTW 4 bits - p. 3650 + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | (1 << 1)); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); rc = request_irq(OMAP_MMC_IRQ, sdiodrv_irq, 0, @@ -789,12 +822,14 @@ static int sdioDrv_InitHw(void) &g_drv); if (rc != 0) { + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PERR ("sdioDrv_InitHw() - request_irq FAILED!!\n"); goto err; } sdiodrv_irq_requested = 1; if(sdiodrv_dma_on == 0){ + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); rc = sdiodrv_dma_init(); if (rc != 0) { @@ -804,25 +839,32 @@ static int sdioDrv_InitHw(void) sdiodrv_dma_on = 1; } + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); /* * send the init sequence. 80 clocks of synchronization * in the SDIO */ //doesn't match p. 3601,3617 - obc + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); OMAP_HSMMC_WRITE( CON, OMAP_HSMMC_READ(CON) | INIT_STREAM); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); OMAP_HSMMC_SEND_COMMAND( 0, 0); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); status = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS); if (!(status & CC)) { + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); PERR("sdioDrv_InitHw() SDIO Command error status = 0x%x\n", status); rc = -1; goto err; } + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); OMAP_HSMMC_WRITE( CON, OMAP_HSMMC_READ(CON) & ~INIT_STREAM); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); return 0; @@ -1193,7 +1235,7 @@ int sdioDrv_ReadAsync (unsigned int uFunc, uNumOfElem, uDmaBlockCount, OMAP_DMA_SYNC_FRAME, - OMAP24XX_DMA_MMC2_RX, + OMAP34XX_DMA_MMC3_RX, OMAP_DMA_SRC_SYNC); iStatus = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS); @@ -1338,7 +1380,7 @@ int sdioDrv_WriteAsync (unsigned int uFunc, uNumOfElem, uDmaBlockCount, OMAP_DMA_SYNC_FRAME, - OMAP24XX_DMA_MMC2_TX, + OMAP34XX_DMA_MMC3_TX, OMAP_DMA_DST_SYNC); iStatus = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS); @@ -1459,12 +1501,12 @@ void sdioDrv_PrintRegisters(void) printk( "\n SDIO control, muxing registers:"); - printk( "\n CONTROL_PADCONF_MMC2_CLK = "); - printk( " 0x%08x", CONTROL_PADCONF_MMC2_CLK); - printk( "\n CONTROL_PADCONF_MMC2_CMD = "); - printk( " 0x%08x", CONTROL_PADCONF_MMC2_DAT0); - printk( "\n CONTROL_PADCONF_MMC2_DAT2 = "); - printk( " 0x%08x", CONTROL_PADCONF_MMC2_DAT2); + printk( "\n CONTROL_PADCONF_MMC3_CLK = "); + printk( " 0x%08x", CONTROL_PADCONF_MMC3_CLK); + printk( "\n CONTROL_PADCONF_MMC3_CMD = "); + printk( " 0x%08x", CONTROL_PADCONF_MMC3_DAT0); + printk( "\n CONTROL_PADCONF_MMC3_DAT2 = "); + printk( " 0x%08x", CONTROL_PADCONF_MMC3_DAT2); printk( "\n CONTROL_DEVCONF1 = "); printk( " 0x%08x", OMAP2_CONTROL_DEVCONF1); @@ -1591,6 +1633,9 @@ int sdioDrv_init(void) PDEBUG("entering %s()\n" , __FUNCTION__ ); memset(&g_drv, 0, sizeof(g_drv)); + printk(KERN_INFO "%s:%d\n", __func__, __LINE__); + remapped_base = ioremap(0x480AD000, SZ_4K); + printk(KERN_INFO "%s:%d remapped_base=0x%x\n", __func__, __LINE__, remapped_base); #ifdef CONFIG_PM /* * Register the platform device diff --git a/omap34xx_defs.h b/omap34xx_defs.h index 403ab64..6397f25 100644 --- a/omap34xx_defs.h +++ b/omap34xx_defs.h @@ -39,6 +39,7 @@ #include <mach/hardware.h> +#define OMAP_HSMMC3_BASE 0x480AD000 //0x480b4000 #define OMAP_HSMMC2_BASE 0x480b4000 #define OMAP2_CONTROL_DEVCONF1 0x480022D8 #define CONTROL_PADCONF_MMC2_CLK 0x48002158 /* mmc2_cmd */ @@ -50,5 +51,15 @@ #define CM_FCLKEN1_CORE 0x48004A00 #define CM_ICLKEN1_CORE 0x48004A10 +#define CONTROL_PADCONF_MMC3_CLK 0x480025D8 /* mmc3_cmd */ +#define CONTROL_PADCONF_MMC3_CMD 0x480021D0 /* mmc3_cmd */ + + +#define CONTROL_PADCONF_MMC3_DAT0 0x480025E4 /* mmc3_dat0, mmc3_dat1 */ +#define CONTROL_PADCONF_MMC3_DAT2 0x480025E8 /* mmc3_dat2 */ +#define CONTROL_PADCONF_MMC3_DAT3 0x480025E0 /* mmc3_dat3 */ + + + #endif /* __OMAP34XX_DEFS__H__ */ diff --git a/sdio.mod.c b/sdio.mod.c index 784c881..4ee9137 100644 --- a/sdio.mod.c +++ b/sdio.mod.c @@ -35,6 +35,7 @@ __attribute__((section("__versions"))) = { { 0xf895fe2d, "platform_driver_register" }, { 0xa86eead4, "__create_workqueue_key" }, { 0xa61e4362, "omap_request_dma" }, + { 0xe9ce8b95, "omap_ioremap" }, { 0x506d97f5, "omap_readl" }, { 0xe6744a89, "omap_clear_dma" }, { 0x9d669763, "memcpy" }, @@ -52,4 +53,4 @@ __attribute__((section(".modinfo"))) = "depends="; -MODULE_INFO(srcversion, "1B1FF678E43775093E312F7"); +MODULE_INFO(srcversion, "E930E6E443028CFD8E54E28"); diff --git a/testsdio.mod.c b/testsdio.mod.c index 1b8f96f..16291d4 100644 --- a/testsdio.mod.c +++ b/testsdio.mod.c @@ -70,4 +70,4 @@ __attribute__((section(".modinfo"))) = "depends=sdio"; -MODULE_INFO(srcversion, "38C7E3D13CB6F6B4A78F53A"); +MODULE_INFO(srcversion, "3D5A17C6EB3C25EC78458B7");
But the initial result is just a panic due to linefetch abort. I'm not sure exactly why, I probably need to look deeper and understand this ICLKEN1/FLCKEN1 code. I was curious if anyone else has gone through this and what advice they may have for me.
Thanks,
jaya