diff mbox

[U-Boot,v2,1/1] ARM: kirkwood: mvebu_mmc: Speed up access time

Message ID 1417705419-15652-1-git-send-email-drEagle@doukki.net
State Superseded
Delegated to: Stefan Roese
Headers show

Commit Message

DrEagle Dec. 4, 2014, 3:03 p.m. UTC
Review delays and timeouts.
Get around 20 x faster access on Sheevaplug tests.

 Changes in v2:
 - increase number of loops
 - remove initial delay

 Changes in v1:
 - review all loops, delays and timeouts

Signed-off-by: Gérald Kerma <drEagle@doukki.net>
---
 drivers/mmc/mvebu_mmc.c | 66 +++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 27 deletions(-)

Comments

DrEagle Dec. 13, 2014, 8:35 p.m. UTC | #1
This serie of patches speed up access time of MVEBUMMC driver

This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
	 * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
	 * register is sometimes not set before a while when some
	 * "unusual" data block sizes are used (such as with the SWITCH
	 * command), even despite the fact that the XFER_DONE interrupt
	 * was raised.  And if another data transfer starts before
	 * this bit comes to good sense (which eventually happens by
	 * itself) then the new transfer simply fails with a timeout.

It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
It may also fixes some SD types incompatibilities

### before patch

Marvell>> ext2load mmc 0:1 0x800000 uImage
1613392 bytes read in 977 ms (1.6 MiB/s)

### with fix

Marvell>> ext2load mmc 0:1 0x800000 uImage
1613392 bytes read in 83 ms (18.5 MiB/s)


Gérald Kerma (6):
  MVEBUMMC : Change copyright date
  MVEBUMMC : Speed up access time
  MVEBUMMC : FIX debug strings
  MVEBUMMC : REMOVE unnecessary delays
  MVEBUMMC : CLEAN code
  MVEBUMMC : REMOVE unnecessary delay from init

 drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
 include/mvebu_mmc.h     |   1 +
 2 files changed, 61 insertions(+), 43 deletions(-)
Mario Schuknecht Dec. 15, 2014, 11:14 a.m. UTC | #2
2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net>:
>
>
> This serie of patches speed up access time of MVEBUMMC driver
>
> This is allowed by a fix in MVEBUMMC init status check inspired from linux
> MVSDIO driver.
>          * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>          * register is sometimes not set before a while when some
>          * "unusual" data block sizes are used (such as with the SWITCH
>          * command), even despite the fact that the XFER_DONE interrupt
>          * was raised.  And if another data transfer starts before
>          * this bit comes to good sense (which eventually happens by
>          * itself) then the new transfer simply fails with a timeout.
>
> It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
> It may also fixes some SD types incompatibilities
>
> ### before patch
>
> Marvell>> ext2load mmc 0:1 0x800000 uImage
> 1613392 bytes read in 977 ms (1.6 MiB/s)
>
> ### with fix
>
> Marvell>> ext2load mmc 0:1 0x800000 uImage
> 1613392 bytes read in 83 ms (18.5 MiB/s)
>
>
>
Looks good to me.
ACK to this series of patches:


> Gérald Kerma (6):
>   MVEBUMMC : Change copyright date
>   MVEBUMMC : Speed up access time
>   MVEBUMMC : FIX debug strings
>   MVEBUMMC : REMOVE unnecessary delays
>   MVEBUMMC : CLEAN code
>   MVEBUMMC : REMOVE unnecessary delay from init


>  drivers/mmc/mvebu_mmc.c | 103
> ++++++++++++++++++++++++++++--------------------
>  include/mvebu_mmc.h     |   1 +
>  2 files changed, 61 insertions(+), 43 deletions(-)
>
> --
> 2.1.3
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
DrEagle Dec. 17, 2014, 9:22 a.m. UTC | #3
Hi,

Any chance to be included in the next release of u-boot ?

Regards,
Gérald

Le 15/12/2014 12:14, Mario Schuknecht a écrit :
> 
> 2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net <mailto:drEagle@doukki.net>>:
> 
> 
>     This serie of patches speed up access time of MVEBUMMC driver
> 
>     This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
>              * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>              * register is sometimes not set before a while when some
>              * "unusual" data block sizes are used (such as with the SWITCH
>              * command), even despite the fact that the XFER_DONE interrupt
>              * was raised.  And if another data transfer starts before
>              * this bit comes to good sense (which eventually happens by
>              * itself) then the new transfer simply fails with a timeout.
> 
>     It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
>     It may also fixes some SD types incompatibilities
> 
>     ### before patch
> 
>     Marvell>> ext2load mmc 0:1 0x800000 uImage
>     1613392 bytes read in 977 ms (1.6 MiB/s)
> 
>     ### with fix
> 
>     Marvell>> ext2load mmc 0:1 0x800000 uImage
>     1613392 bytes read in 83 ms (18.5 MiB/s)
> 
> 
> 
> Looks good to me.
> ACK to this series of patches:
>  
> 
>     Gérald Kerma (6):
>       MVEBUMMC : Change copyright date
>       MVEBUMMC : Speed up access time
>       MVEBUMMC : FIX debug strings
>       MVEBUMMC : REMOVE unnecessary delays
>       MVEBUMMC : CLEAN code
>       MVEBUMMC : REMOVE unnecessary delay from init
> 
> 
>      drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
>      include/mvebu_mmc.h     |   1 +
>      2 files changed, 61 insertions(+), 43 deletions(-)
> 
>     --
>     2.1.3
>     _______________________________________________
>     U-Boot mailing list
>     U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de>
>     http://lists.denx.de/mailman/listinfo/u-boot
> 
>
Pantelis Antoniou Dec. 17, 2014, 10:18 a.m. UTC | #4
Hi Gerald,

Last pull-req for mmc was last Friday, I intend to issue another this Friday too.

Regards

— Pantelis

> On Dec 17, 2014, at 11:22 , drEagle <dreagle@doukki.net> wrote:
> 
> Hi,
> 
> Any chance to be included in the next release of u-boot ?
> 
> Regards,
> Gérald
> 
> Le 15/12/2014 12:14, Mario Schuknecht a écrit :
>> 
>> 2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net <mailto:drEagle@doukki.net>>:
>> 
>> 
>>    This serie of patches speed up access time of MVEBUMMC driver
>> 
>>    This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
>>             * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>>             * register is sometimes not set before a while when some
>>             * "unusual" data block sizes are used (such as with the SWITCH
>>             * command), even despite the fact that the XFER_DONE interrupt
>>             * was raised.  And if another data transfer starts before
>>             * this bit comes to good sense (which eventually happens by
>>             * itself) then the new transfer simply fails with a timeout.
>> 
>>    It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
>>    It may also fixes some SD types incompatibilities
>> 
>>    ### before patch
>> 
>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>    1613392 bytes read in 977 ms (1.6 MiB/s)
>> 
>>    ### with fix
>> 
>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>    1613392 bytes read in 83 ms (18.5 MiB/s)
>> 
>> 
>> 
>> Looks good to me.
>> ACK to this series of patches:
>> 
>> 
>>    Gérald Kerma (6):
>>      MVEBUMMC : Change copyright date
>>      MVEBUMMC : Speed up access time
>>      MVEBUMMC : FIX debug strings
>>      MVEBUMMC : REMOVE unnecessary delays
>>      MVEBUMMC : CLEAN code
>>      MVEBUMMC : REMOVE unnecessary delay from init
>> 
>> 
>>     drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
>>     include/mvebu_mmc.h     |   1 +
>>     2 files changed, 61 insertions(+), 43 deletions(-)
>> 
>>    --
>>    2.1.3
>>    _______________________________________________
>>    U-Boot mailing list
>>    U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de>
>>    http://lists.denx.de/mailman/listinfo/u-boot
>> 
>>
DrEagle Dec. 23, 2014, 1:01 p.m. UTC | #5
Hi Pantelis,

Is these patches reviewed and upstreamed ?

Regards,
Gérald

Le 17/12/2014 11:18, Pantelis Antoniou a écrit :
> Hi Gerald,
> 
> Last pull-req for mmc was last Friday, I intend to issue another this Friday too.
> 
> Regards
> 
> — Pantelis
> 
>> On Dec 17, 2014, at 11:22 , drEagle <dreagle@doukki.net> wrote:
>>
>> Hi,
>>
>> Any chance to be included in the next release of u-boot ?
>>
>> Regards,
>> Gérald
>>
>> Le 15/12/2014 12:14, Mario Schuknecht a écrit :
>>>
>>> 2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net <mailto:drEagle@doukki.net>>:
>>>
>>>
>>>    This serie of patches speed up access time of MVEBUMMC driver
>>>
>>>    This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
>>>             * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>>>             * register is sometimes not set before a while when some
>>>             * "unusual" data block sizes are used (such as with the SWITCH
>>>             * command), even despite the fact that the XFER_DONE interrupt
>>>             * was raised.  And if another data transfer starts before
>>>             * this bit comes to good sense (which eventually happens by
>>>             * itself) then the new transfer simply fails with a timeout.
>>>
>>>    It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
>>>    It may also fixes some SD types incompatibilities
>>>
>>>    ### before patch
>>>
>>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>    1613392 bytes read in 977 ms (1.6 MiB/s)
>>>
>>>    ### with fix
>>>
>>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>    1613392 bytes read in 83 ms (18.5 MiB/s)
>>>
>>>
>>>
>>> Looks good to me.
>>> ACK to this series of patches:
>>>
>>>
>>>    Gérald Kerma (6):
>>>      MVEBUMMC : Change copyright date
>>>      MVEBUMMC : Speed up access time
>>>      MVEBUMMC : FIX debug strings
>>>      MVEBUMMC : REMOVE unnecessary delays
>>>      MVEBUMMC : CLEAN code
>>>      MVEBUMMC : REMOVE unnecessary delay from init
>>>
>>>
>>>     drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
>>>     include/mvebu_mmc.h     |   1 +
>>>     2 files changed, 61 insertions(+), 43 deletions(-)
>>>
>>>    --
>>>    2.1.3
>>>    _______________________________________________
>>>    U-Boot mailing list
>>>    U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de>
>>>    http://lists.denx.de/mailman/listinfo/u-boot
>>>
>>>
DrEagle Jan. 3, 2015, 4:06 p.m. UTC | #6
Hi,

any news for this patch ?

Regards,
Gérald,

Le 23/12/2014 14:01, drEagle a écrit :
> Hi Pantelis,
> 
> Is these patches reviewed and upstreamed ?
> 
> Regards,
> Gérald
> 
> Le 17/12/2014 11:18, Pantelis Antoniou a écrit :
>> Hi Gerald,
>>
>> Last pull-req for mmc was last Friday, I intend to issue another this Friday too.
>>
>> Regards
>>
>> — Pantelis
>>
>>> On Dec 17, 2014, at 11:22 , drEagle <dreagle@doukki.net> wrote:
>>>
>>> Hi,
>>>
>>> Any chance to be included in the next release of u-boot ?
>>>
>>> Regards,
>>> Gérald
>>>
>>> Le 15/12/2014 12:14, Mario Schuknecht a écrit :
>>>>
>>>> 2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net <mailto:drEagle@doukki.net>>:
>>>>
>>>>
>>>>    This serie of patches speed up access time of MVEBUMMC driver
>>>>
>>>>    This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
>>>>             * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>>>>             * register is sometimes not set before a while when some
>>>>             * "unusual" data block sizes are used (such as with the SWITCH
>>>>             * command), even despite the fact that the XFER_DONE interrupt
>>>>             * was raised.  And if another data transfer starts before
>>>>             * this bit comes to good sense (which eventually happens by
>>>>             * itself) then the new transfer simply fails with a timeout.
>>>>
>>>>    It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
>>>>    It may also fixes some SD types incompatibilities
>>>>
>>>>    ### before patch
>>>>
>>>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>>    1613392 bytes read in 977 ms (1.6 MiB/s)
>>>>
>>>>    ### with fix
>>>>
>>>>    Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>>    1613392 bytes read in 83 ms (18.5 MiB/s)
>>>>
>>>>
>>>>
>>>> Looks good to me.
>>>> ACK to this series of patches:
>>>>
>>>>
>>>>    Gérald Kerma (6):
>>>>      MVEBUMMC : Change copyright date
>>>>      MVEBUMMC : Speed up access time
>>>>      MVEBUMMC : FIX debug strings
>>>>      MVEBUMMC : REMOVE unnecessary delays
>>>>      MVEBUMMC : CLEAN code
>>>>      MVEBUMMC : REMOVE unnecessary delay from init
>>>>
>>>>
>>>>     drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
>>>>     include/mvebu_mmc.h     |   1 +
>>>>     2 files changed, 61 insertions(+), 43 deletions(-)
>>>>
>>>>    --
>>>>    2.1.3
>>>>    _______________________________________________
>>>>    U-Boot mailing list
>>>>    U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de>
>>>>    http://lists.denx.de/mailman/listinfo/u-boot
>>>>
>>>>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
Pantelis Antoniou Jan. 5, 2015, 6:31 p.m. UTC | #7
All applied,

There’s something called a Christmas break so no worries now :)

> On Jan 3, 2015, at 18:06 , drEagle <drEagle@DOUKKI.NET> wrote:
> 
> Hi,
> 
> any news for this patch ?
> 
> Regards,
> Gérald,
> 
> Le 23/12/2014 14:01, drEagle a écrit :
>> Hi Pantelis,
>> 
>> Is these patches reviewed and upstreamed ?
>> 
>> Regards,
>> Gérald
>> 
>> Le 17/12/2014 11:18, Pantelis Antoniou a écrit :
>>> Hi Gerald,
>>> 
>>> Last pull-req for mmc was last Friday, I intend to issue another this Friday too.
>>> 
>>> Regards
>>> 
>>> — Pantelis
>>> 
>>>> On Dec 17, 2014, at 11:22 , drEagle <dreagle@doukki.net> wrote:
>>>> 
>>>> Hi,
>>>> 
>>>> Any chance to be included in the next release of u-boot ?
>>>> 
>>>> Regards,
>>>> Gérald
>>>> 
>>>> Le 15/12/2014 12:14, Mario Schuknecht a écrit :
>>>>> 
>>>>> 2014-12-13 21:35 GMT+01:00 Gérald Kerma <drEagle@doukki.net <mailto:drEagle@doukki.net>>:
>>>>> 
>>>>> 
>>>>>   This serie of patches speed up access time of MVEBUMMC driver
>>>>> 
>>>>>   This is allowed by a fix in MVEBUMMC init status check inspired from linux MVSDIO driver.
>>>>>            * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
>>>>>            * register is sometimes not set before a while when some
>>>>>            * "unusual" data block sizes are used (such as with the SWITCH
>>>>>            * command), even despite the fact that the XFER_DONE interrupt
>>>>>            * was raised.  And if another data transfer starts before
>>>>>            * this bit comes to good sense (which eventually happens by
>>>>>            * itself) then the new transfer simply fails with a timeout.
>>>>> 
>>>>>   It allows about 10x to 40x faster access time transfer on SHEEVAPLUG MMC
>>>>>   It may also fixes some SD types incompatibilities
>>>>> 
>>>>>   ### before patch
>>>>> 
>>>>>   Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>>>   1613392 bytes read in 977 ms (1.6 MiB/s)
>>>>> 
>>>>>   ### with fix
>>>>> 
>>>>>   Marvell>> ext2load mmc 0:1 0x800000 uImage
>>>>>   1613392 bytes read in 83 ms (18.5 MiB/s)
>>>>> 
>>>>> 
>>>>> 
>>>>> Looks good to me.
>>>>> ACK to this series of patches:
>>>>> 
>>>>> 
>>>>>   Gérald Kerma (6):
>>>>>     MVEBUMMC : Change copyright date
>>>>>     MVEBUMMC : Speed up access time
>>>>>     MVEBUMMC : FIX debug strings
>>>>>     MVEBUMMC : REMOVE unnecessary delays
>>>>>     MVEBUMMC : CLEAN code
>>>>>     MVEBUMMC : REMOVE unnecessary delay from init
>>>>> 
>>>>> 
>>>>>    drivers/mmc/mvebu_mmc.c | 103 ++++++++++++++++++++++++++++--------------------
>>>>>    include/mvebu_mmc.h     |   1 +
>>>>>    2 files changed, 61 insertions(+), 43 deletions(-)
>>>>> 
>>>>>   --
>>>>>   2.1.3
>>>>>   _______________________________________________
>>>>>   U-Boot mailing list
>>>>>   U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de>
>>>>>   http://lists.denx.de/mailman/listinfo/u-boot
>>>>> 
>>>>> 
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot@lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>>
diff mbox

Patch

diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 9f98c3f..b636be6 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -23,6 +23,10 @@  DECLARE_GLOBAL_DATA_PTR;
 
 #define MVEBU_TARGET_DRAM 0
 
+#define TIMEOUT_LOOP	1000000000000000000	/* maximum loops */
+#define TIMEOUT_WAIT	100			/* wait 100 us */
+#define TIMEOUT_START	100			/* wait 100 us */
+
 static void mvebu_mmc_write(u32 offs, u32 val)
 {
 	writel(val, CONFIG_SYS_MMC_BASE + (offs));
@@ -63,7 +67,7 @@  static int mvebu_mmc_setup_data(struct mmc_data *data)
 static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			      struct mmc_data *data)
 {
-	int timeout = 10;
+	u64 timeout = TIMEOUT_LOOP;
 	ushort waittype = 0;
 	ushort resptype = 0;
 	ushort xfertype = 0;
@@ -72,27 +76,32 @@  static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	debug("cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
 	      cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
 
-	udelay(10*1000);
-
 	debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
 	      cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
 
+	/* Clear status */
+	mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
+	mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+
 	/* Checking if card is busy */
 	while ((mvebu_mmc_read(SDIO_HW_STATE) & CARD_BUSY)) {
+		timeout--;
+		udelay(TIMEOUT_START);
 		if (timeout == 0) {
 			printf("%s: card busy!\n", DRIVER_NAME);
 			return -1;
 		}
-		timeout--;
-		udelay(1000);
 	}
 
 	/* Set up for a data transfer if we have one */
 	if (data) {
 		int err = mvebu_mmc_setup_data(data);
 
-		if (err)
+		if (err){
+			debug("%s: command DATA error :%x\n",
+			       DRIVER_NAME, err);
 			return err;
+		}
 	}
 
 	resptype = SDIO_CMD_INDEX(cmd->cmdidx);
@@ -148,7 +157,7 @@  static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	mvebu_mmc_write(SDIO_ERR_INTR_EN, SDIO_POLL_MASK);
 
 	/* Waiting for completion */
-	timeout = 1000000;
+	timeout = TIMEOUT_LOOP;
 
 	while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
 		if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
@@ -156,21 +165,22 @@  static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			      DRIVER_NAME, cmd->cmdidx,
 			      mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
 			if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
-				(SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+			    (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)){
+				debug("%s: command READ timed out\n",
+				       DRIVER_NAME);
 				return TIMEOUT;
+			}
+			debug("%s: command READ error\n", DRIVER_NAME);
 			return COMM_ERR;
 		}
 
 		timeout--;
-		udelay(1);
-		if (timeout <= 0) {
-			printf("%s: command timed out\n", DRIVER_NAME);
+		udelay(TIMEOUT_WAIT);
+		if (timeout == 0) {
+			debug("%s: command timed out\n", DRIVER_NAME);
 			return TIMEOUT;
 		}
 	}
-	if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
-		(SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
-		return TIMEOUT;
 
 	/* Handling response */
 	if (cmd->resp_type & MMC_RSP_136) {
@@ -213,6 +223,11 @@  static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	debug("[0x%x] ", cmd->response[3]);
 	debug("\n");
 
+	if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & SDIO_ERR_CMD_TIMEOUT){
+		debug("%s: command STATUS timed out\n", DRIVER_NAME);
+		return TIMEOUT;
+	}
+
 	return 0;
 }
 
@@ -236,33 +251,30 @@  static void mvebu_mmc_power_up(void)
 	/* enable interrupts status */
 	mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
 	mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+
+	udelay(10*1000);
 }
 
 static void mvebu_mmc_set_clk(unsigned int clock)
 {
-	unsigned int m;
-
 	if (clock == 0) {
 		debug("%s: clock off\n", DRIVER_NAME);
 		mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
 		mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
 	} else {
-		m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1;
+		u32 m = DIV_ROUND_UP(MVEBU_MMC_BASE_FAST_CLOCK,
+				     (2 * clock)) - 1;
 		if (m > MVEBU_MMC_BASE_DIV_MAX)
 			m = MVEBU_MMC_BASE_DIV_MAX;
-		mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
+		mvebu_mmc_write(SDIO_CLK_DIV, m);
+		debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
 	}
-
-	udelay(10*1000);
 }
 
 static void mvebu_mmc_set_bus(unsigned int bus)
 {
 	u32 ctrl_reg = 0;
 
-	ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
-	ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
-
 	switch (bus) {
 	case 4:
 		ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
@@ -277,7 +289,7 @@  static void mvebu_mmc_set_bus(unsigned int bus)
 	ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST;
 
 	/* default to maximum timeout */
-	ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+	ctrl_reg |= SDIO_HOST_CTRL_TMOUT_MAX;
 	ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
 
 	ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
@@ -293,7 +305,6 @@  static void mvebu_mmc_set_bus(unsigned int bus)
 	      "high-speed" : "");
 
 	mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
-	udelay(10*1000);
 }
 
 static void mvebu_mmc_set_ios(struct mmc *mmc)
@@ -355,7 +366,7 @@  static void mvebu_window_setup(void)
 
 static int mvebu_mmc_initialize(struct mmc *mmc)
 {
-	debug("%s: mvebu_mmc_initialize", DRIVER_NAME);
+	debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
 
 	/*
 	 * Setting host parameters
@@ -398,7 +409,8 @@  static const struct mmc_ops mvebu_mmc_ops = {
 static struct mmc_config mvebu_mmc_cfg = {
 	.name		= DRIVER_NAME,
 	.ops		= &mvebu_mmc_ops,
-	.f_min		= MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
+	.f_min		= DIV_ROUND_UP(MVEBU_MMC_BASE_FAST_CLOCK,
+				       MVEBU_MMC_BASE_DIV_MAX),
 	.f_max		= MVEBU_MMC_CLOCKRATE_MAX,
 	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.host_caps	= MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |