Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-25 Thread Steve Sakoman
On Sat, Oct 23, 2010 at 8:14 AM, Ghorai, Sukumar s-gho...@ti.com wrote:


 -Original Message-
 From: u-boot-boun...@lists.denx.de [mailto:u-boot-boun...@lists.denx.de]
 On Behalf Of Steve Sakoman
 Sent: Friday, October 15, 2010 3:14 AM
 To: John Rigby
 Cc: u-boot@lists.denx.de; Alagu Sankar; Andy Fleming
 Subject: Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

 On Mon, Oct 4, 2010 at 1:32 PM, John Rigby jcri...@gmail.com wrote:
  Alagu,
 
  This never made it into Andy's tree nor upstream.  Could you submit a
  new patch to current upstream with the config option removed as Andy
  said he did back in May?  Maybe we can get it commited via some other
  maintainer.  Steve Sakoman seems to have done some MMC work lately.

 I've done some testing with this patch on OMAP3 and OMAP4, in the
 always enabled version.

 I compared the old legacy mmc driver vs the new generic mmc driver vs
 new generic mmc driver with multiblock read support added.

 The good news is that the generic mmc driver for OMAP is almost twice
 as fast as the old legacy driver.  These patches should be in the next
 u-boot-ti pull request and so will be in mainline shortly.

 The bad news is that multiblock reads seem to make no difference :-(

 For reading a 45MB file from an ext3 partition using ext2load I get:

 legacy:              62 seconds
 generic:             35 seconds
 generic w/ multi: 35 seconds

 I'm happy to resubmit the multi-block read patch because it does seem
 to work properly and may even yield improvements on other
 architectures.

 Would you like me to do that?

 [Ghorai]
 would you please try with additional change?

Yes! That is much better!

Now multiblock reads are faster :-)

The results (including the old legacy mmc driver for reference):

legacy:  62 seconds
generic: 35 seconds
generic w/ multi: 9 seconds

I will add my Acked-by and Tested-by and submit the final patch to
the list later today.

Steve


 $git diff drivers/mmc/omap_hsmmc.c

 diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
 index f8b9840..7f3f968 100644
 --- a/drivers/mmc/omap_hsmmc.c
 +++ b/drivers/mmc/omap_hsmmc.c
 @@ -401,6 +401,7 @@ int omap_mmc_init(int dev_index)

        mmc-f_min = 40;
        mmc-f_max = 5200;
 +       mmc-b_max = 0x;

        mmc_register(mmc);


 Steve
 ___
 U-Boot mailing list
 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


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-25 Thread Ghorai, Sukumar


 -Original Message-
 From: Steve Sakoman [mailto:sako...@gmail.com]
 Sent: Monday, October 25, 2010 11:00 PM
 To: Ghorai, Sukumar
 Cc: John Rigby; u-boot@lists.denx.de; Alagu Sankar; Andy Fleming
 Subject: Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support
 
 On Sat, Oct 23, 2010 at 8:14 AM, Ghorai, Sukumar s-gho...@ti.com wrote:
 
 
  -Original Message-
  From: u-boot-boun...@lists.denx.de [mailto:u-boot-
 boun...@lists.denx.de]
  On Behalf Of Steve Sakoman
  Sent: Friday, October 15, 2010 3:14 AM
  To: John Rigby
  Cc: u-boot@lists.denx.de; Alagu Sankar; Andy Fleming
  Subject: Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support
 
  On Mon, Oct 4, 2010 at 1:32 PM, John Rigby jcri...@gmail.com wrote:
   Alagu,
  
   This never made it into Andy's tree nor upstream.  Could you submit a
   new patch to current upstream with the config option removed as Andy
   said he did back in May?  Maybe we can get it commited via some other
   maintainer.  Steve Sakoman seems to have done some MMC work lately.
 
  I've done some testing with this patch on OMAP3 and OMAP4, in the
  always enabled version.
 
  I compared the old legacy mmc driver vs the new generic mmc driver vs
  new generic mmc driver with multiblock read support added.
 
  The good news is that the generic mmc driver for OMAP is almost twice
  as fast as the old legacy driver.  These patches should be in the next
  u-boot-ti pull request and so will be in mainline shortly.
 
  The bad news is that multiblock reads seem to make no difference :-(
 
  For reading a 45MB file from an ext3 partition using ext2load I get:
 
  legacy:              62 seconds
  generic:             35 seconds
  generic w/ multi: 35 seconds
 
  I'm happy to resubmit the multi-block read patch because it does seem
  to work properly and may even yield improvements on other
  architectures.
 
  Would you like me to do that?
 
  [Ghorai]
  would you please try with additional change?
 
 Yes! That is much better!
 
 Now multiblock reads are faster :-)
 
 The results (including the old legacy mmc driver for reference):
 
 legacy:  62 seconds
 generic: 35 seconds
 generic w/ multi: 9 seconds
 
 I will add my Acked-by and Tested-by and submit the final patch to
 the list later today.
[Ghorai] please add
Tested-by: Sukumar Ghorai s-gho...@ti.com

And will submit a separate patch as mentioned below.

 
 Steve
 
 
  $git diff drivers/mmc/omap_hsmmc.c
 
  diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
  index f8b9840..7f3f968 100644
  --- a/drivers/mmc/omap_hsmmc.c
  +++ b/drivers/mmc/omap_hsmmc.c
  @@ -401,6 +401,7 @@ int omap_mmc_init(int dev_index)
 
         mmc-f_min = 40;
         mmc-f_max = 5200;
  +       mmc-b_max = 0x;
 
         mmc_register(mmc);
 
 
  Steve
  ___
  U-Boot mailing list
  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


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-23 Thread Ghorai, Sukumar


 -Original Message-
 From: u-boot-boun...@lists.denx.de [mailto:u-boot-boun...@lists.denx.de]
 On Behalf Of Steve Sakoman
 Sent: Friday, October 15, 2010 3:14 AM
 To: John Rigby
 Cc: u-boot@lists.denx.de; Alagu Sankar; Andy Fleming
 Subject: Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support
 
 On Mon, Oct 4, 2010 at 1:32 PM, John Rigby jcri...@gmail.com wrote:
  Alagu,
 
  This never made it into Andy's tree nor upstream.  Could you submit a
  new patch to current upstream with the config option removed as Andy
  said he did back in May?  Maybe we can get it commited via some other
  maintainer.  Steve Sakoman seems to have done some MMC work lately.
 
 I've done some testing with this patch on OMAP3 and OMAP4, in the
 always enabled version.
 
 I compared the old legacy mmc driver vs the new generic mmc driver vs
 new generic mmc driver with multiblock read support added.
 
 The good news is that the generic mmc driver for OMAP is almost twice
 as fast as the old legacy driver.  These patches should be in the next
 u-boot-ti pull request and so will be in mainline shortly.
 
 The bad news is that multiblock reads seem to make no difference :-(
 
 For reading a 45MB file from an ext3 partition using ext2load I get:
 
 legacy:  62 seconds
 generic: 35 seconds
 generic w/ multi: 35 seconds
 
 I'm happy to resubmit the multi-block read patch because it does seem
 to work properly and may even yield improvements on other
 architectures.
 
 Would you like me to do that?
[Ghorai]
would you please try with additional change?
$git diff drivers/mmc/omap_hsmmc.c

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index f8b9840..7f3f968 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -401,6 +401,7 @@ int omap_mmc_init(int dev_index)

mmc-f_min = 40;
mmc-f_max = 5200;
+   mmc-b_max = 0x;

mmc_register(mmc);

 
 Steve
 ___
 U-Boot mailing list
 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


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-14 Thread Steve Sakoman
On Mon, Oct 4, 2010 at 1:32 PM, John Rigby jcri...@gmail.com wrote:
 Alagu,

 This never made it into Andy's tree nor upstream.  Could you submit a
 new patch to current upstream with the config option removed as Andy
 said he did back in May?  Maybe we can get it commited via some other
 maintainer.  Steve Sakoman seems to have done some MMC work lately.

I've done some testing with this patch on OMAP3 and OMAP4, in the
always enabled version.

I compared the old legacy mmc driver vs the new generic mmc driver vs
new generic mmc driver with multiblock read support added.

The good news is that the generic mmc driver for OMAP is almost twice
as fast as the old legacy driver.  These patches should be in the next
u-boot-ti pull request and so will be in mainline shortly.

The bad news is that multiblock reads seem to make no difference :-(

For reading a 45MB file from an ext3 partition using ext2load I get:

legacy:  62 seconds
generic: 35 seconds
generic w/ multi: 35 seconds

I'm happy to resubmit the multi-block read patch because it does seem
to work properly and may even yield improvements on other
architectures.

Would you like me to do that?

Steve
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-14 Thread Paulraj, Sandeep


 
 On Mon, Oct 4, 2010 at 1:32 PM, John Rigby jcri...@gmail.com wrote:
  Alagu,
 
  This never made it into Andy's tree nor upstream.  Could you submit a
  new patch to current upstream with the config option removed as Andy
  said he did back in May?  Maybe we can get it commited via some other
  maintainer.  Steve Sakoman seems to have done some MMC work lately.
 
 I've done some testing with this patch on OMAP3 and OMAP4, in the
 always enabled version.
 
 I compared the old legacy mmc driver vs the new generic mmc driver vs
 new generic mmc driver with multiblock read support added.
 
 The good news is that the generic mmc driver for OMAP is almost twice
 as fast as the old legacy driver.  These patches should be in the next
 u-boot-ti pull request and so will be in mainline shortly.
 
 The bad news is that multiblock reads seem to make no difference :-(
 
 For reading a 45MB file from an ext3 partition using ext2load I get:
 
 legacy:  62 seconds
 generic: 35 seconds
 generic w/ multi: 35 seconds
 
 I'm happy to resubmit the multi-block read patch because it does seem
 to work properly and may even yield improvements on other
 architectures.
 
 Would you like me to do that?
 
 Steve

Yes please submit updated patches if you have them in your tree. Others might 
want to participate in a new round of review.

Sandeep

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-10-04 Thread John Rigby
Alagu,

This never made it into Andy's tree nor upstream.  Could you submit a
new patch to current upstream with the config option removed as Andy
said he did back in May?  Maybe we can get it commited via some other
maintainer.  Steve Sakoman seems to have done some MMC work lately.

Thanks,
John

On Fri, May 14, 2010 at 11:37 AM, Andy Fleming aflem...@gmail.com wrote:
 On Wed, May 12, 2010 at 4:38 AM, Alagu Sankar alagusan...@embwise.com wrote:
 Added Multi-Block Read support for Generic MMC. Modified existing multi-block
 write to limit the maximum number of blocks per transfer.  This feature is
 enabled with CONFIG_MMC_MBLOCK option.  A new member is added in the mmc
 structure for the host controller to specify the maximum number of blocks it
 supports.

 Signed-off-by: Alagu Sankar alagusan...@embwise.com


 I removed the config option, and just made this always how it works.  Applied.

 Thanks!
 ___
 U-Boot mailing list
 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


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-09-13 Thread Lei Wen
Hi,

Has this changed been merged into uboot mainline?
Current mmc framework read is rather slow comparing with the write...

If we could get the multiply-read behavior, that would be nice. :-)

Thanks,
Lei

On Sat, May 15, 2010 at 1:37 AM, Andy Fleming aflem...@gmail.com wrote:
 On Wed, May 12, 2010 at 4:38 AM, Alagu Sankar alagusan...@embwise.com wrote:
 Added Multi-Block Read support for Generic MMC. Modified existing multi-block
 write to limit the maximum number of blocks per transfer.  This feature is
 enabled with CONFIG_MMC_MBLOCK option.  A new member is added in the mmc
 structure for the host controller to specify the maximum number of blocks it
 supports.

 Signed-off-by: Alagu Sankar alagusan...@embwise.com


 I removed the config option, and just made this always how it works.  Applied.

 Thanks!
 ___
 U-Boot mailing list
 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


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-05-14 Thread Andy Fleming
On Wed, May 12, 2010 at 4:38 AM, Alagu Sankar alagusan...@embwise.com wrote:
 Added Multi-Block Read support for Generic MMC. Modified existing multi-block
 write to limit the maximum number of blocks per transfer.  This feature is
 enabled with CONFIG_MMC_MBLOCK option.  A new member is added in the mmc
 structure for the host controller to specify the maximum number of blocks it
 supports.

 Signed-off-by: Alagu Sankar alagusan...@embwise.com


I removed the config option, and just made this always how it works.  Applied.

Thanks!
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-05-13 Thread Lv Terry-R65388
Hi,

Personally I think this patch can be used as common. CONFIG_MMC_MBLOCK 
is not needed.
It can improve performance a lot for generic mmc.

Thanks~~

Yours
Terry 

 -Original Message-
 From: u-boot-boun...@lists.denx.de 
 [mailto:u-boot-boun...@lists.denx.de] On Behalf Of Alagu Sankar
 Sent: 2010年5月12日 17:43
 To: u-boot@lists.denx.de
 Subject: [U-Boot] [PATCH 3/4] MMC Multi-block Support
 
 Added Multi-Block Read support for Generic MMC. Modified 
 existing multi-block write to limit the maximum number of 
 blocks per transfer.  This feature is enabled with 
 CONFIG_MMC_MBLOCK option.  A new member is added in the mmc 
 structure for the host controller to specify the maximum 
 number of blocks it supports.
 
 Signed-off-by: Alagu Sankar alagusan...@embwise.com
 ---
  drivers/mmc/mmc.c |  156 
 +
  include/mmc.h |3 +
  2 files changed, 159 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 
 e7abf94..3f5a200 100644
 --- a/drivers/mmc/mmc.c
 +++ b/drivers/mmc/mmc.c
 @@ -77,6 +77,7 @@ struct mmc *find_mmc_device(int dev_num)
   return NULL;
  }
  
 +#ifndef CONFIG_MMC_MBLOCK
  static ulong
  mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const 
 void*src)  { @@ -238,6 +239,156 @@ static ulong mmc_bread(int 
 dev_num, ulong start, lbaint_t blkcnt, void *dst)
   return blkcnt;
  }
  
 +#else
 +
 +static int mmc_write_blocks(struct mmc *mmc, const char 
 *src, uint start,
 + uint blkcnt)
 +{
 + struct mmc_cmd cmd;
 + struct mmc_data data;
 + int err;
 + int blklen;
 +
 + blklen = mmc-write_bl_len;
 +
 + err = mmc_set_blocklen(mmc, mmc-write_bl_len);
 +
 + if (err) {
 + printf(set write bl len failed\n\r);
 + return err;
 + }
 +
 + if (blkcnt  1)
 + cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
 + else
 + cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
 +
 + if (mmc-high_capacity)
 + cmd.cmdarg = start;
 + else
 + cmd.cmdarg = start * blklen;
 +
 + cmd.resp_type = MMC_RSP_R1;
 + cmd.flags = 0;
 +
 + data.src = src;
 + data.blocks = blkcnt;
 + data.blocksize = blklen;
 + data.flags = MMC_DATA_WRITE;
 +
 + err = mmc_send_cmd(mmc, cmd, data);
 +
 + if (err) {
 + printf(mmc write failed\n\r);
 + return err;
 + }
 +
 + if (blkcnt  1) {
 + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 + cmd.cmdarg = 0;
 + cmd.resp_type = MMC_RSP_R1b;
 + cmd.flags = 0;
 + err = mmc_send_cmd(mmc, cmd, NULL);
 + }
 +
 + return err;
 +}
 +
 +static ulong
 +mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const 
 void *src) 
 +{
 + int err;
 + int i;
 + struct mmc *mmc = find_mmc_device(dev_num);
 + uint b_max = mmc-b_max;
 +
 + if (!mmc)
 + return 0;
 +
 + for (i = blkcnt; i  0; i -= b_max) {
 + uint blocks = (i  b_max) ? b_max : i;
 +
 + err = mmc_write_blocks(mmc, src, start, blocks);
 + if (err)
 + return blkcnt - i;
 + start += blocks;
 + src += (mmc-write_bl_len * blocks);
 + }
 +
 + return blkcnt;
 +}
 +
 +int mmc_read_blocks(struct mmc *mmc, void *dst, uint blocknum, uint 
 +blkcnt) {
 + int err;
 + struct mmc_cmd cmd;
 + struct mmc_data data;
 +
 + if (blkcnt  1)
 + cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
 + else
 + cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
 +
 + if (mmc-high_capacity)
 + cmd.cmdarg = blocknum;
 + else
 + cmd.cmdarg = blocknum * mmc-read_bl_len;
 +
 + cmd.resp_type = MMC_RSP_R1;
 + cmd.flags = 0;
 +
 + data.dest = dst;
 + data.blocks = blkcnt;
 + data.blocksize = mmc-read_bl_len;
 + data.flags = MMC_DATA_READ;
 +
 + err = mmc_send_cmd(mmc, cmd, data);
 + if (err)
 + return err;
 +
 + if (blkcnt  1) {
 + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 + cmd.cmdarg = 0;
 + cmd.resp_type = MMC_RSP_R1b;
 + cmd.flags = 0;
 + err = mmc_send_cmd(mmc, cmd, NULL);
 + }
 +
 + return err;
 +}
 +
 +static ulong mmc_bread(int dev_num, ulong start, lbaint_t 
 blkcnt, void 
 +*dst) {
 + int err;
 + int i;
 + struct mmc *mmc = find_mmc_device(dev_num);
 + uint b_max = mmc-b_max;
 +
 + if (!mmc)
 + return 0;
 +
 + /* We always do full block reads from the card */
 + err = mmc_set_blocklen(mmc, mmc-read_bl_len);
 + if (err)
 + return 0;
 +
 + for (i = blkcnt; i  0; i -= b_max) {
 + uint blocks = (i  b_max) ? b_max : i;
 +
 + err = mmc_read_blocks(mmc, dst, start, blocks);
 + if (err) {
 + printf(block read failed: %d\n

[U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-05-12 Thread Alagu Sankar
Added Multi-Block Read support for Generic MMC. Modified existing multi-block
write to limit the maximum number of blocks per transfer.  This feature is
enabled with CONFIG_MMC_MBLOCK option.  A new member is added in the mmc
structure for the host controller to specify the maximum number of blocks it
supports.

Signed-off-by: Alagu Sankar alagusan...@embwise.com
---
 drivers/mmc/mmc.c |  156 +
 include/mmc.h |3 +
 2 files changed, 159 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e7abf94..3f5a200 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -77,6 +77,7 @@ struct mmc *find_mmc_device(int dev_num)
return NULL;
 }
 
+#ifndef CONFIG_MMC_MBLOCK
 static ulong
 mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
 {
@@ -238,6 +239,156 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t 
blkcnt, void *dst)
return blkcnt;
 }
 
+#else
+
+static int mmc_write_blocks(struct mmc *mmc, const char *src, uint start,
+   uint blkcnt)
+{
+   struct mmc_cmd cmd;
+   struct mmc_data data;
+   int err;
+   int blklen;
+
+   blklen = mmc-write_bl_len;
+
+   err = mmc_set_blocklen(mmc, mmc-write_bl_len);
+
+   if (err) {
+   printf(set write bl len failed\n\r);
+   return err;
+   }
+
+   if (blkcnt  1)
+   cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+   else
+   cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+
+   if (mmc-high_capacity)
+   cmd.cmdarg = start;
+   else
+   cmd.cmdarg = start * blklen;
+
+   cmd.resp_type = MMC_RSP_R1;
+   cmd.flags = 0;
+
+   data.src = src;
+   data.blocks = blkcnt;
+   data.blocksize = blklen;
+   data.flags = MMC_DATA_WRITE;
+
+   err = mmc_send_cmd(mmc, cmd, data);
+
+   if (err) {
+   printf(mmc write failed\n\r);
+   return err;
+   }
+
+   if (blkcnt  1) {
+   cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+   cmd.cmdarg = 0;
+   cmd.resp_type = MMC_RSP_R1b;
+   cmd.flags = 0;
+   err = mmc_send_cmd(mmc, cmd, NULL);
+   }
+
+   return err;
+}
+
+static ulong
+mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void *src)
+{
+   int err;
+   int i;
+   struct mmc *mmc = find_mmc_device(dev_num);
+   uint b_max = mmc-b_max;
+
+   if (!mmc)
+   return 0;
+
+   for (i = blkcnt; i  0; i -= b_max) {
+   uint blocks = (i  b_max) ? b_max : i;
+
+   err = mmc_write_blocks(mmc, src, start, blocks);
+   if (err)
+   return blkcnt - i;
+   start += blocks;
+   src += (mmc-write_bl_len * blocks);
+   }
+
+   return blkcnt;
+}
+
+int mmc_read_blocks(struct mmc *mmc, void *dst, uint blocknum, uint blkcnt)
+{
+   int err;
+   struct mmc_cmd cmd;
+   struct mmc_data data;
+
+   if (blkcnt  1)
+   cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
+   else
+   cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
+
+   if (mmc-high_capacity)
+   cmd.cmdarg = blocknum;
+   else
+   cmd.cmdarg = blocknum * mmc-read_bl_len;
+
+   cmd.resp_type = MMC_RSP_R1;
+   cmd.flags = 0;
+
+   data.dest = dst;
+   data.blocks = blkcnt;
+   data.blocksize = mmc-read_bl_len;
+   data.flags = MMC_DATA_READ;
+
+   err = mmc_send_cmd(mmc, cmd, data);
+   if (err)
+   return err;
+
+   if (blkcnt  1) {
+   cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+   cmd.cmdarg = 0;
+   cmd.resp_type = MMC_RSP_R1b;
+   cmd.flags = 0;
+   err = mmc_send_cmd(mmc, cmd, NULL);
+   }
+
+   return err;
+}
+
+static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
+{
+   int err;
+   int i;
+   struct mmc *mmc = find_mmc_device(dev_num);
+   uint b_max = mmc-b_max;
+
+   if (!mmc)
+   return 0;
+
+   /* We always do full block reads from the card */
+   err = mmc_set_blocklen(mmc, mmc-read_bl_len);
+   if (err)
+   return 0;
+
+   for (i = blkcnt; i  0; i -= b_max) {
+   uint blocks = (i  b_max) ? b_max : i;
+
+   err = mmc_read_blocks(mmc, dst, start, blocks);
+   if (err) {
+   printf(block read failed: %d\n, err);
+   return blkcnt - i;
+   }
+   start += blocks;
+   dst += (mmc-read_bl_len * blocks);
+   }
+
+   return blkcnt;
+}
+
+#endif
+
 int mmc_go_idle(struct mmc* mmc)
 {
struct mmc_cmd cmd;
@@ -858,6 +1009,11 @@ int mmc_register(struct mmc *mmc)
mmc-block_dev.block_read = mmc_bread;
mmc-block_dev.block_write = mmc_bwrite;
 

[U-Boot] [PATCH 3/4] MMC Multi-block Support

2010-05-12 Thread Alagu Sankar
Added Multi-Block Read support for Generic MMC. Modified existing multi-block
write to limit the maximum number of blocks per transfer.  This feature is
enabled with CONFIG_MMC_MBLOCK option.  A new member is added in the mmc
structure for the host controller to specify the maximum number of blocks it
supports.

Signed-off-by: Alagu Sankar alagusan...@embwise.com
---
 drivers/mmc/mmc.c |  156 +
 include/mmc.h |3 +
 2 files changed, 159 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e7abf94..3f5a200 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -77,6 +77,7 @@ struct mmc *find_mmc_device(int dev_num)
return NULL;
 }
 
+#ifndef CONFIG_MMC_MBLOCK
 static ulong
 mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
 {
@@ -238,6 +239,156 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t 
blkcnt, void *dst)
return blkcnt;
 }
 
+#else
+
+static int mmc_write_blocks(struct mmc *mmc, const char *src, uint start,
+   uint blkcnt)
+{
+   struct mmc_cmd cmd;
+   struct mmc_data data;
+   int err;
+   int blklen;
+
+   blklen = mmc-write_bl_len;
+
+   err = mmc_set_blocklen(mmc, mmc-write_bl_len);
+
+   if (err) {
+   printf(set write bl len failed\n\r);
+   return err;
+   }
+
+   if (blkcnt  1)
+   cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+   else
+   cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+
+   if (mmc-high_capacity)
+   cmd.cmdarg = start;
+   else
+   cmd.cmdarg = start * blklen;
+
+   cmd.resp_type = MMC_RSP_R1;
+   cmd.flags = 0;
+
+   data.src = src;
+   data.blocks = blkcnt;
+   data.blocksize = blklen;
+   data.flags = MMC_DATA_WRITE;
+
+   err = mmc_send_cmd(mmc, cmd, data);
+
+   if (err) {
+   printf(mmc write failed\n\r);
+   return err;
+   }
+
+   if (blkcnt  1) {
+   cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+   cmd.cmdarg = 0;
+   cmd.resp_type = MMC_RSP_R1b;
+   cmd.flags = 0;
+   err = mmc_send_cmd(mmc, cmd, NULL);
+   }
+
+   return err;
+}
+
+static ulong
+mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void *src)
+{
+   int err;
+   int i;
+   struct mmc *mmc = find_mmc_device(dev_num);
+   uint b_max = mmc-b_max;
+
+   if (!mmc)
+   return 0;
+
+   for (i = blkcnt; i  0; i -= b_max) {
+   uint blocks = (i  b_max) ? b_max : i;
+
+   err = mmc_write_blocks(mmc, src, start, blocks);
+   if (err)
+   return blkcnt - i;
+   start += blocks;
+   src += (mmc-write_bl_len * blocks);
+   }
+
+   return blkcnt;
+}
+
+int mmc_read_blocks(struct mmc *mmc, void *dst, uint blocknum, uint blkcnt)
+{
+   int err;
+   struct mmc_cmd cmd;
+   struct mmc_data data;
+
+   if (blkcnt  1)
+   cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
+   else
+   cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
+
+   if (mmc-high_capacity)
+   cmd.cmdarg = blocknum;
+   else
+   cmd.cmdarg = blocknum * mmc-read_bl_len;
+
+   cmd.resp_type = MMC_RSP_R1;
+   cmd.flags = 0;
+
+   data.dest = dst;
+   data.blocks = blkcnt;
+   data.blocksize = mmc-read_bl_len;
+   data.flags = MMC_DATA_READ;
+
+   err = mmc_send_cmd(mmc, cmd, data);
+   if (err)
+   return err;
+
+   if (blkcnt  1) {
+   cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+   cmd.cmdarg = 0;
+   cmd.resp_type = MMC_RSP_R1b;
+   cmd.flags = 0;
+   err = mmc_send_cmd(mmc, cmd, NULL);
+   }
+
+   return err;
+}
+
+static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
+{
+   int err;
+   int i;
+   struct mmc *mmc = find_mmc_device(dev_num);
+   uint b_max = mmc-b_max;
+
+   if (!mmc)
+   return 0;
+
+   /* We always do full block reads from the card */
+   err = mmc_set_blocklen(mmc, mmc-read_bl_len);
+   if (err)
+   return 0;
+
+   for (i = blkcnt; i  0; i -= b_max) {
+   uint blocks = (i  b_max) ? b_max : i;
+
+   err = mmc_read_blocks(mmc, dst, start, blocks);
+   if (err) {
+   printf(block read failed: %d\n, err);
+   return blkcnt - i;
+   }
+   start += blocks;
+   dst += (mmc-read_bl_len * blocks);
+   }
+
+   return blkcnt;
+}
+
+#endif
+
 int mmc_go_idle(struct mmc* mmc)
 {
struct mmc_cmd cmd;
@@ -858,6 +1009,11 @@ int mmc_register(struct mmc *mmc)
mmc-block_dev.block_read = mmc_bread;
mmc-block_dev.block_write = mmc_bwrite;