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", 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;
>  
> +#ifdef CONFIG_MMC_MBLOCK
> +     if (mmc->b_max == 0)
> +             mmc->b_max = 1;
> +#endif
> +
>       INIT_LIST_HEAD (&mmc->link);
>  
>       list_add_tail (&mmc->link, &mmc_devices); diff --git 
> a/include/mmc.h b/include/mmc.h index 8973bc7..04c7eaf 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -264,6 +264,9 @@ struct mmc {
>                       struct mmc_cmd *cmd, struct mmc_data *data);
>       void (*set_ios)(struct mmc *mmc);
>       int (*init)(struct mmc *mmc);
> +#ifdef CONFIG_MMC_MBLOCK
> +     uint b_max;
> +#endif
>  };
>  
>  int mmc_register(struct mmc *mmc);
> --
> 1.6.0.6
> 
> _______________________________________________
> 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

Reply via email to