RE: [PATCH] Davinci SDIO Support

2010-03-17 Thread Nori, Sekhar

Hi Alagu,

On Mon, Mar 15, 2010 at 18:12:43, alagusan...@embwise.com wrote:
 From: Alagu Sankar alagusan...@embwise.com

 Added SDIO Support for Davinci Platforms.  This is tested with DM355 and DM365
 EVM platforms using Libertas driver with SD8686 and SD8688 SDIO WiFi cards.
 There is a hack to support Libertas firmware download. This hack may not be
 required for other SDIO cards.

Can you please separate the 'hack' from the
actual patch adding the basic support.

That way folks can review them separately and
hopefully someone with a different WLAN card
can say if the 'hack' is really required for
all cards.

Thanks,
Sekhar

___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


[PATCH] Davinci SDIO Support

2010-03-16 Thread alagusankar
From: Alagu Sankar alagusan...@embwise.com

Added SDIO Support for Davinci Platforms.  This is tested with DM355 and DM365
EVM platforms using Libertas driver with SD8686 and SD8688 SDIO WiFi cards.
There is a hack to support Libertas firmware download. This hack may not be
required for other SDIO cards.

Signed-off-by: alagusan...@embwise.com
---
 drivers/mmc/host/davinci_mmc.c |  131 
 1 files changed, 120 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 933cd42..2836ad1 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -32,6 +32,7 @@
 #include linux/delay.h
 #include linux/dma-mapping.h
 #include linux/mmc/mmc.h
+#include linux/mmc/card.h
 
 #include mach/mmc.h
 #include mach/edma.h
@@ -66,8 +67,8 @@
 #define DAVINCI_MMCBLNC  0x60
 #define DAVINCI_SDIOCTL  0x64
 #define DAVINCI_SDIOST0  0x68
-#define DAVINCI_SDIOEN   0x6C
-#define DAVINCI_SDIOST   0x70
+#define DAVINCI_SDIOIEN  0x6C
+#define DAVINCI_SDIOIST  0x70
 #define DAVINCI_MMCFIFOCTL   0x74 /* FIFO Control Register */
 
 /* DAVINCI_MMCCTL definitions */
@@ -135,6 +136,23 @@
 /* MMCSD Init clock in Hz in opendrain mode */
 #define MMCSD_INIT_CLOCK   20
 
+/* DAVINCI_SDIOCTL definitions */
+#define SDIOCTL_RDWTRQ_SETBIT(0)
+#define SDIOCTL_RDWTCR_SETBIT(1)
+
+/* DAVINCI_SDIOST0 definitions */
+#define SDIOST0_DAT1_HI   BIT(0)
+#define SDIOST0_INTPRDBIT(1)
+#define SDIOST0_RDWTSTBIT(2)
+
+/* DAVINCI_SDIOIEN definitions */
+#define SDIOIEN_IOINTEN   BIT(0)
+#define SDIOIEN_RWSEN BIT(1)
+
+/* DAVINCI_SDIOIST definitions */
+#define SDIOIST_IOINT BIT(0)
+#define SDIOIST_RWS   BIT(1)
+
 /*
  * One scatterlist dma segment is at most MAX_CCNT rw_threshold units,
  * and we handle up to NR_SG segments.  MMC_BLOCK_BOUNCE kicks in only
@@ -147,6 +165,8 @@
 
 #define NR_SG  16
 
+#define DAVINCI_SDIO_IRQ(dev_id)   (((dev_id) == 0) ? sdio0 : sdio1)
+
 static unsigned rw_threshold = 32;
 module_param(rw_threshold, uint, S_IRUGO);
 MODULE_PARM_DESC(rw_threshold,
@@ -164,7 +184,7 @@ struct mmc_davinci_host {
unsigned int mmc_input_clk;
void __iomem *base;
struct resource *mem_res;
-   int irq;
+   int mmc_irq, sdio_irq;
unsigned char bus_mode;
 
 #define DAVINCI_MMC_DATADIR_NONE   0
@@ -184,6 +204,7 @@ struct mmc_davinci_host {
u32 rxdma, txdma;
bool use_dma;
bool do_dma;
+   bool sdio_int;
 
/* Scatterlist DMA uses one or more parameter RAM entries:
 * the main one (associated with rxdma or txdma) plus zero or
@@ -670,6 +691,24 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, 
struct mmc_request *req)
host-buffer = NULL;
host-bytes_left = data-blocks * data-blksz;
 
+/*
+ * Hack for overcoming the 2ms delay required by Libertas helper
+ * firmware download.  Without this delay the primary firmware load fails
+ * without an error.  Not having the delay does not result in host
+ * controller error (or) helper firmware download error.  But will result
+ * in primary firmware load error.
+ *
+ * May not be required for usage with other SDIO client drivers and
+ * should be removed after identifying the root cause in consultation
+ * with the libertas developers.
+ */
+   if (host-mmc-card) {
+   if (mmc_card_sdio(host-mmc-card)) {
+   if ((data-blksz == 64))
+   mdelay(2);
+   }
+   }
+
/* For now we try to use DMA whenever we won't need partial FIFO
 * reads or writes, either for the whole transfer (as tested here)
 * or for any individual scatterlist segment (tested when we call
@@ -862,6 +901,19 @@ mmc_davinci_xfer_done(struct mmc_davinci_host *host, 
struct mmc_data *data)
 {
host-data = NULL;
 
+   if (host-mmc-caps  MMC_CAP_SDIO_IRQ) {
+   /* SDIO Interrupt Detection work-around as suggested by
+* Davinci Errata (TMS320DM355 Silicon Revision 1.1 Errata
+* 2.1.5)
+* Signal SDIO interrupt only if it is enabled by core
+*/
+   if (host-sdio_int  (!((readl(host-base + DAVINCI_SDIOST0))
+SDIOST0_DAT1_HI))) {
+   writel(SDIOIST_IOINT, host-base + DAVINCI_SDIOIST);
+   mmc_signal_sdio_irq(host-mmc);
+   }
+   }
+
if (host-do_dma) {
davinci_abort_dma(host);
 
@@ -928,6 +980,22 @@ davinci_abort_data(struct mmc_davinci_host *host, struct 
mmc_data *data)
mmc_davinci_reset_ctrl(host, 0);
 }
 
+static irqreturn_t mmc_davinci_sdio_irq(int irq, void *dev_id)
+{
+   struct mmc_davinci_host *host = (struct mmc_davinci_host 

[PATCH] Davinci SDIO Support

2010-03-15 Thread alagusankar
From: Alagu Sankar alagusan...@embwise.com

Added SDIO Support for Davinci Platforms.  This is tested with DM355 and DM365
EVM platforms using Libertas driver with SD8686 and SD8688 SDIO WiFi cards.
There is a hack to support Libertas firmware download. This hack may not be
required for other SDIO cards.

Signed-off-by: alagusan...@embwise.com
---
 drivers/mmc/host/davinci_mmc.c |  131 
 1 files changed, 120 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 933cd42..2836ad1 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -32,6 +32,7 @@
 #include linux/delay.h
 #include linux/dma-mapping.h
 #include linux/mmc/mmc.h
+#include linux/mmc/card.h
 
 #include mach/mmc.h
 #include mach/edma.h
@@ -66,8 +67,8 @@
 #define DAVINCI_MMCBLNC  0x60
 #define DAVINCI_SDIOCTL  0x64
 #define DAVINCI_SDIOST0  0x68
-#define DAVINCI_SDIOEN   0x6C
-#define DAVINCI_SDIOST   0x70
+#define DAVINCI_SDIOIEN  0x6C
+#define DAVINCI_SDIOIST  0x70
 #define DAVINCI_MMCFIFOCTL   0x74 /* FIFO Control Register */
 
 /* DAVINCI_MMCCTL definitions */
@@ -135,6 +136,23 @@
 /* MMCSD Init clock in Hz in opendrain mode */
 #define MMCSD_INIT_CLOCK   20
 
+/* DAVINCI_SDIOCTL definitions */
+#define SDIOCTL_RDWTRQ_SETBIT(0)
+#define SDIOCTL_RDWTCR_SETBIT(1)
+
+/* DAVINCI_SDIOST0 definitions */
+#define SDIOST0_DAT1_HI   BIT(0)
+#define SDIOST0_INTPRDBIT(1)
+#define SDIOST0_RDWTSTBIT(2)
+
+/* DAVINCI_SDIOIEN definitions */
+#define SDIOIEN_IOINTEN   BIT(0)
+#define SDIOIEN_RWSEN BIT(1)
+
+/* DAVINCI_SDIOIST definitions */
+#define SDIOIST_IOINT BIT(0)
+#define SDIOIST_RWS   BIT(1)
+
 /*
  * One scatterlist dma segment is at most MAX_CCNT rw_threshold units,
  * and we handle up to NR_SG segments.  MMC_BLOCK_BOUNCE kicks in only
@@ -147,6 +165,8 @@
 
 #define NR_SG  16
 
+#define DAVINCI_SDIO_IRQ(dev_id)   (((dev_id) == 0) ? sdio0 : sdio1)
+
 static unsigned rw_threshold = 32;
 module_param(rw_threshold, uint, S_IRUGO);
 MODULE_PARM_DESC(rw_threshold,
@@ -164,7 +184,7 @@ struct mmc_davinci_host {
unsigned int mmc_input_clk;
void __iomem *base;
struct resource *mem_res;
-   int irq;
+   int mmc_irq, sdio_irq;
unsigned char bus_mode;
 
 #define DAVINCI_MMC_DATADIR_NONE   0
@@ -184,6 +204,7 @@ struct mmc_davinci_host {
u32 rxdma, txdma;
bool use_dma;
bool do_dma;
+   bool sdio_int;
 
/* Scatterlist DMA uses one or more parameter RAM entries:
 * the main one (associated with rxdma or txdma) plus zero or
@@ -670,6 +691,24 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, 
struct mmc_request *req)
host-buffer = NULL;
host-bytes_left = data-blocks * data-blksz;
 
+/*
+ * Hack for overcoming the 2ms delay required by Libertas helper
+ * firmware download.  Without this delay the primary firmware load fails
+ * without an error.  Not having the delay does not result in host
+ * controller error (or) helper firmware download error.  But will result
+ * in primary firmware load error.
+ *
+ * May not be required for usage with other SDIO client drivers and
+ * should be removed after identifying the root cause in consultation
+ * with the libertas developers.
+ */
+   if (host-mmc-card) {
+   if (mmc_card_sdio(host-mmc-card)) {
+   if ((data-blksz == 64))
+   mdelay(2);
+   }
+   }
+
/* For now we try to use DMA whenever we won't need partial FIFO
 * reads or writes, either for the whole transfer (as tested here)
 * or for any individual scatterlist segment (tested when we call
@@ -862,6 +901,19 @@ mmc_davinci_xfer_done(struct mmc_davinci_host *host, 
struct mmc_data *data)
 {
host-data = NULL;
 
+   if (host-mmc-caps  MMC_CAP_SDIO_IRQ) {
+   /* SDIO Interrupt Detection work-around as suggested by
+* Davinci Errata (TMS320DM355 Silicon Revision 1.1 Errata
+* 2.1.5)
+* Signal SDIO interrupt only if it is enabled by core
+*/
+   if (host-sdio_int  (!((readl(host-base + DAVINCI_SDIOST0))
+SDIOST0_DAT1_HI))) {
+   writel(SDIOIST_IOINT, host-base + DAVINCI_SDIOIST);
+   mmc_signal_sdio_irq(host-mmc);
+   }
+   }
+
if (host-do_dma) {
davinci_abort_dma(host);
 
@@ -928,6 +980,22 @@ davinci_abort_data(struct mmc_davinci_host *host, struct 
mmc_data *data)
mmc_davinci_reset_ctrl(host, 0);
 }
 
+static irqreturn_t mmc_davinci_sdio_irq(int irq, void *dev_id)
+{
+   struct mmc_davinci_host *host = (struct mmc_davinci_host