Re: [PATCHv5] mmc: dw_mmc: change to use recommended reset procedure

2014-07-13 Thread Jaehoon Chung
On 07/12/2014 05:53 AM, Sonny Rao wrote:
 This patch changes the fifo reset code to follow the reset procedure
 outlined in the documentation of Synopsys Mobile storage host databook.
 
 Signed-off-by: Sonny Rao sonny...@chromium.org
 Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com
 ---
 v2: Add Generic DMA support
 per the documentation, move interrupt clear before wait
 make the test for DMA host-use_dma rather than host-using_dma
 add proper return values (although it appears no caller checks)
 v3: rename fifo reset function, and change callers
 use this combined reset function in dw_mci_resume()
 just one caller left (probe), so get rid of dw_mci_ctrl_all_reset()
 use DMA reset bit for all systems which use DMA
 remove extra IDMAC reset in dw_mci_work_routine_card()
 do CIU clock update in error path, if CIU reset cleared
 v4: remove comment about FIFO reset in dw_mci_work_routine_card()
 move down error message when control reset clears but others don't
  and clarify the error stating that we will still update clocks
 make flags for all reset bits a macro
 v5: don't use dw_mci_reset() in dw_mci_resume() and instead match what
 is done in dw_mci_probe() and don't force inline dw_mci_resume()
 ---
  drivers/mmc/host/dw_mmc.c | 86 
 ++-
  drivers/mmc/host/dw_mmc.h |  5 +++
  2 files changed, 68 insertions(+), 23 deletions(-)
 
 diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
 index 55cd110..db25494 100644
 --- a/drivers/mmc/host/dw_mmc.c
 +++ b/drivers/mmc/host/dw_mmc.c
 @@ -111,8 +111,7 @@ static const u8 tuning_blk_pattern_8bit[] = {
   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
  };
  
 -static inline bool dw_mci_fifo_reset(struct dw_mci *host);
 -static inline bool dw_mci_ctrl_all_reset(struct dw_mci *host);
 +static bool dw_mci_reset(struct dw_mci *host);
  
  #if defined(CONFIG_DEBUG_FS)
  static int dw_mci_req_show(struct seq_file *s, void *v)
 @@ -1254,7 +1253,7 @@ static int dw_mci_data_complete(struct dw_mci *host, 
 struct mmc_data *data)
* After an error, there may be data lingering
* in the FIFO
*/
 - dw_mci_fifo_reset(host);
 + dw_mci_reset(host);
   } else {
   data-bytes_xfered = data-blocks * data-blksz;
   data-error = 0;
 @@ -1371,7 +1370,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
  
   /* CMD error in data command */
   if (mrq-cmd-error  mrq-data)
 - dw_mci_fifo_reset(host);
 + dw_mci_reset(host);
  
   host-cmd = NULL;
   host-data = NULL;
 @@ -1982,14 +1981,8 @@ static void dw_mci_work_routine_card(struct 
 work_struct *work)
   }
  
   /* Power down slot */
 - if (present == 0) {
 - /* Clear down the FIFO */
 - dw_mci_fifo_reset(host);
 -#ifdef CONFIG_MMC_DW_IDMAC
 - dw_mci_idmac_reset(host);
 -#endif
 -
 - }
 + if (present == 0)
 + dw_mci_reset(host);
  
   spin_unlock_bh(host-lock);
  
 @@ -2323,8 +2316,11 @@ static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 
 reset)
   return false;
  }
  
 -static inline bool dw_mci_fifo_reset(struct dw_mci *host)
 +static bool dw_mci_reset(struct dw_mci *host)
  {
 + u32 flags = SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET;
 + bool ret = false;
 +
   /*
* Reseting generates a block interrupt, hence setting
* the scatter-gather pointer to NULL.
 @@ -2334,15 +2330,59 @@ static inline bool dw_mci_fifo_reset(struct dw_mci 
 *host)
   host-sg = NULL;
   }
  
 - return dw_mci_ctrl_reset(host, SDMMC_CTRL_FIFO_RESET);
 -}
 + if (host-use_dma)
 + flags |= SDMMC_CTRL_DMA_RESET;
  
 -static inline bool dw_mci_ctrl_all_reset(struct dw_mci *host)
 -{
 - return dw_mci_ctrl_reset(host,
 -  SDMMC_CTRL_FIFO_RESET |
 -  SDMMC_CTRL_RESET |
 -  SDMMC_CTRL_DMA_RESET);
 + if (dw_mci_ctrl_reset(host, flags)) {
 + /*
 +  * In all cases we clear the RAWINTS register to clear any
 +  * interrupts.
 +  */
 + mci_writel(host, RINTSTS, 0x);
 +
 + /* if using dma we wait for dma_req to clear */
 + if (host-use_dma) {
 + unsigned long timeout = jiffies + msecs_to_jiffies(500);
 + u32 status;
 + do {
 + status = mci_readl(host, STATUS);
 + if (!(status  SDMMC_STATUS_DMA_REQ))
 +

[PATCHv5] mmc: dw_mmc: change to use recommended reset procedure

2014-07-11 Thread Sonny Rao
This patch changes the fifo reset code to follow the reset procedure
outlined in the documentation of Synopsys Mobile storage host databook.

Signed-off-by: Sonny Rao sonny...@chromium.org
Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com
---
v2: Add Generic DMA support
per the documentation, move interrupt clear before wait
make the test for DMA host-use_dma rather than host-using_dma
add proper return values (although it appears no caller checks)
v3: rename fifo reset function, and change callers
use this combined reset function in dw_mci_resume()
just one caller left (probe), so get rid of dw_mci_ctrl_all_reset()
use DMA reset bit for all systems which use DMA
remove extra IDMAC reset in dw_mci_work_routine_card()
do CIU clock update in error path, if CIU reset cleared
v4: remove comment about FIFO reset in dw_mci_work_routine_card()
move down error message when control reset clears but others don't
 and clarify the error stating that we will still update clocks
make flags for all reset bits a macro
v5: don't use dw_mci_reset() in dw_mci_resume() and instead match what
is done in dw_mci_probe() and don't force inline dw_mci_resume()
---
 drivers/mmc/host/dw_mmc.c | 86 ++-
 drivers/mmc/host/dw_mmc.h |  5 +++
 2 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 55cd110..db25494 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -111,8 +111,7 @@ static const u8 tuning_blk_pattern_8bit[] = {
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
 };
 
-static inline bool dw_mci_fifo_reset(struct dw_mci *host);
-static inline bool dw_mci_ctrl_all_reset(struct dw_mci *host);
+static bool dw_mci_reset(struct dw_mci *host);
 
 #if defined(CONFIG_DEBUG_FS)
 static int dw_mci_req_show(struct seq_file *s, void *v)
@@ -1254,7 +1253,7 @@ static int dw_mci_data_complete(struct dw_mci *host, 
struct mmc_data *data)
 * After an error, there may be data lingering
 * in the FIFO
 */
-   dw_mci_fifo_reset(host);
+   dw_mci_reset(host);
} else {
data-bytes_xfered = data-blocks * data-blksz;
data-error = 0;
@@ -1371,7 +1370,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
 
/* CMD error in data command */
if (mrq-cmd-error  mrq-data)
-   dw_mci_fifo_reset(host);
+   dw_mci_reset(host);
 
host-cmd = NULL;
host-data = NULL;
@@ -1982,14 +1981,8 @@ static void dw_mci_work_routine_card(struct work_struct 
*work)
}
 
/* Power down slot */
-   if (present == 0) {
-   /* Clear down the FIFO */
-   dw_mci_fifo_reset(host);
-#ifdef CONFIG_MMC_DW_IDMAC
-   dw_mci_idmac_reset(host);
-#endif
-
-   }
+   if (present == 0)
+   dw_mci_reset(host);
 
spin_unlock_bh(host-lock);
 
@@ -2323,8 +2316,11 @@ static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 
reset)
return false;
 }
 
-static inline bool dw_mci_fifo_reset(struct dw_mci *host)
+static bool dw_mci_reset(struct dw_mci *host)
 {
+   u32 flags = SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET;
+   bool ret = false;
+
/*
 * Reseting generates a block interrupt, hence setting
 * the scatter-gather pointer to NULL.
@@ -2334,15 +2330,59 @@ static inline bool dw_mci_fifo_reset(struct dw_mci 
*host)
host-sg = NULL;
}
 
-   return dw_mci_ctrl_reset(host, SDMMC_CTRL_FIFO_RESET);
-}
+   if (host-use_dma)
+   flags |= SDMMC_CTRL_DMA_RESET;
 
-static inline bool dw_mci_ctrl_all_reset(struct dw_mci *host)
-{
-   return dw_mci_ctrl_reset(host,
-SDMMC_CTRL_FIFO_RESET |
-SDMMC_CTRL_RESET |
-SDMMC_CTRL_DMA_RESET);
+   if (dw_mci_ctrl_reset(host, flags)) {
+   /*
+* In all cases we clear the RAWINTS register to clear any
+* interrupts.
+*/
+   mci_writel(host, RINTSTS, 0x);
+
+   /* if using dma we wait for dma_req to clear */
+   if (host-use_dma) {
+   unsigned long timeout = jiffies + msecs_to_jiffies(500);
+   u32 status;
+   do {
+   status = mci_readl(host, STATUS);
+   if (!(status  SDMMC_STATUS_DMA_REQ))
+   break;
+   cpu_relax();
+