Hi Andrew,

Looks good. I don’t have a DDR capable board to test, but at first glance
it’s fine.

> On Dec 1, 2014, at 14:59 , Andrew Gabbasov <andrew_gabba...@mentor.com> wrote:
> 
> If the MMC_MODE_DDR_52MHz flag is set in card capabilities bitmask,
> it is never cleared, even if switching to DDR mode fails, and if
> the controller driver uses this flag to check the DDR mode, it can
> take incorrect actions.
> 
> Also, DDR related checks in mmc_startup() incorrectly handle the case
> when the host controller does not support some bus widths (e.g. can't
> support 8 bits), since the host_caps is checked for DDR bit, but not
> bus width bits.
> 
> This fix clearly separates using of card_caps bitmask, having there
> the flags for the capabilities, that the card can support, and actual
> operation mode, described outside of card_caps (i.e. bus_width and
> ddr_mode fields in mmc structure). Separate host controller drivers
> may need to be updated to use the actual flags. Respectively,
> the capabilities checks in mmc_startup are made more correct and clear.
> 
> Also, some clean up is made with errors handling and code syntax layout.
> 
> Signed-off-by: Andrew Gabbasov <andrew_gabba...@mentor.com>
> ---
> common/cmd_mmc.c  |  3 ++-
> drivers/mmc/mmc.c | 52 +++++++++++++++++++++++++++++++---------------------
> include/mmc.h     |  1 +
> 3 files changed, 34 insertions(+), 22 deletions(-)
> 
> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
> index 4286e26..96478e4 100644
> --- a/common/cmd_mmc.c
> +++ b/common/cmd_mmc.c
> @@ -90,7 +90,8 @@ static void print_mmcinfo(struct mmc *mmc)
>       puts("Capacity: ");
>       print_size(mmc->capacity, "\n");
> 
> -     printf("Bus Width: %d-bit\n", mmc->bus_width);
> +     printf("Bus Width: %d-bit%s\n", mmc->bus_width,
> +                     mmc->ddr_mode ? " DDR" : "");
> }
> static struct mmc *init_mmc_device(int dev, bool force_init)
> {
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 44a4feb..4603a81 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -159,7 +159,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
> {
>       struct mmc_cmd cmd;
> 
> -     if (mmc->card_caps & MMC_MODE_DDR_52MHz)
> +     if (mmc->ddr_mode)
>               return 0;
> 
>       cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
> @@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc)
>       char cardtype;
>       int err;
> 
> -     mmc->card_caps = 0;
> +     mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
> 
>       if (mmc_host_is_spi(mmc))
>               return 0;
> @@ -1103,8 +1103,10 @@ static int mmc_startup(struct mmc *mmc)
> 
>               /* An array to map CSD bus widths to host cap bits */
>               static unsigned ext_to_hostcaps[] = {
> -                     [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
> -                     [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
> +                     [EXT_CSD_DDR_BUS_WIDTH_4] =
> +                             MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
> +                     [EXT_CSD_DDR_BUS_WIDTH_8] =
> +                             MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
>                       [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
>                       [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
>               };
> @@ -1116,13 +1118,13 @@ static int mmc_startup(struct mmc *mmc)
> 
>               for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
>                       unsigned int extw = ext_csd_bits[idx];
> +                     unsigned int caps = ext_to_hostcaps[extw];
> 
>                       /*
> -                      * Check to make sure the controller supports
> -                      * this bus width, if it's more than 1
> +                      * Check to make sure the card and controller support
> +                      * these capabilities
>                        */
> -                     if (extw != EXT_CSD_BUS_WIDTH_1 &&
> -                                     !(mmc->cfg->host_caps & 
> ext_to_hostcaps[extw]))
> +                     if ((mmc->card_caps & caps) != caps)
>                               continue;
> 
>                       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> @@ -1131,26 +1133,33 @@ static int mmc_startup(struct mmc *mmc)
>                       if (err)
>                               continue;
> 
> +                     mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
>                       mmc_set_bus_width(mmc, widths[idx]);
> 
>                       err = mmc_send_ext_csd(mmc, test_csd);
> +
> +                     if (err)
> +                             continue;
> +
>                       /* Only compare read only fields */
> -                     if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
> -                                 == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
> -                              && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \
> -                                 == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \
> -                              && ext_csd[EXT_CSD_REV] \
> -                                 == test_csd[EXT_CSD_REV]
> -                              && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
> -                                 == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
> -                              && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
> -                                     &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
> -
> -                             mmc->card_caps |= ext_to_hostcaps[extw];
> +                     if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
> +                             == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
> +                         ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
> +                             == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
> +                         ext_csd[EXT_CSD_REV]
> +                             == test_csd[EXT_CSD_REV] &&
> +                         ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
> +                             == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
> +                         memcmp(&ext_csd[EXT_CSD_SEC_CNT],
> +                                &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
>                               break;
> -                     }
> +                     else
> +                             err = SWITCH_ERR;
>               }
> 
> +             if (err)
> +                     return err;
> +
>               if (mmc->card_caps & MMC_MODE_HS) {
>                       if (mmc->card_caps & MMC_MODE_HS_52MHz)
>                               mmc->tran_speed = 52000000;
> @@ -1299,6 +1308,7 @@ int mmc_start_init(struct mmc *mmc)
>       if (err)
>               return err;
> 
> +     mmc->ddr_mode = 0;
>       mmc_set_bus_width(mmc, 1);
>       mmc_set_clock(mmc, 1);
> 
> diff --git a/include/mmc.h b/include/mmc.h
> index d74a190..9c6d792 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -314,6 +314,7 @@ struct mmc {
>       char init_in_progress;  /* 1 if we have done mmc_start_init() */
>       char preinit;           /* start init as early as possible */
>       uint op_cond_response;  /* the response byte from the last op_cond */
> +     int ddr_mode;
> };
> 
> int mmc_register(struct mmc *mmc);
> -- 
> 2.1.0

Applied, thanks.

— Pantelis

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

Reply via email to