On 05/13/2017 03:16 AM, Jean-Jacques Hiblot wrote:
> Boot partitions do not support HS200. Changing to a lower performance mode
> is required to access them.
> mmc_select_mode_and_width() and sd_select_mode_and_width() are modified to
> make it easier to call them outside of the initialization context.

This patch should be important to support the HS200 mode on u-boot..
So i need to test this..more detail..

> 
> Signed-off-by: Jean-Jacques Hiblot <jjhib...@ti.com>
> ---
>  drivers/mmc/mmc.c | 66 
> +++++++++++++++++++++++++++++++++++++++++--------------
>  include/mmc.h     |  1 +
>  2 files changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 074d286..c7dda64 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -32,6 +32,7 @@ static const unsigned int sd_au_size[] = {
>  static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
>  static void mmc_power_cycle(struct mmc *mmc);
>  static int mmc_card_busy(struct mmc *mmc);
> +static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
>  
>  #if CONFIG_IS_ENABLED(MMC_TINY)
>  static struct mmc mmc_static;
> @@ -788,10 +789,38 @@ static int mmc_set_capacity(struct mmc *mmc, int 
> part_num)
>       return 0;
>  }
>  
> +static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
> +{
> +     int forbiden = 0;

forbiden? typo?

> +     bool change = false;
> +
> +     if (part_num & PART_ACCESS_MASK)
> +             forbiden = MMC_CAP(MMC_HS_200);
> +
> +     if (MMC_CAP(mmc->selected_mode) & forbiden) {
> +             debug("selected mode (%s) is forbiden for part %d\n",
> +                   mmc_mode_name(mmc->selected_mode), part_num);
> +             change = true;
> +     } else if (mmc->selected_mode != mmc->best_mode) {
> +             debug("selected mode is not optimal\n");
> +             change = true;
> +     }
> +
> +     if (change)
> +             return mmc_select_mode_and_width(mmc,
> +                                              mmc->card_caps & ~forbiden);
> +
> +     return 0;
> +}
> +
>  int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
>  {
>       int ret;
>  
> +     ret = mmc_boot_part_access_chk(mmc, part_num);
> +     if (ret)
> +             return ret;
> +
>       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
>                        (mmc->part_config & ~PART_ACCESS_MASK)
>                        | (part_num & PART_ACCESS_MASK));
> @@ -1438,7 +1467,7 @@ static const struct mode_width_tuning 
> sd_modes_by_pref[] = {
>            mwt++) \
>               if (caps & MMC_CAP(mwt->mode))
>  
> -static int sd_select_mode_and_width(struct mmc *mmc)
> +static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
>  {
>       int err;
>       uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
> @@ -1447,11 +1476,8 @@ static int sd_select_mode_and_width(struct mmc *mmc)
>       uint caps;
>  
>  
> -     err = sd_get_capabilities(mmc);
> -     if (err)
> -             return err;
>       /* Restrict card's capabilities by what the host can do */
> -     caps = mmc->card_caps & (mmc->cfg->host_caps | MMC_MODE_1BIT);
> +     caps = card_caps & (mmc->cfg->host_caps | MMC_MODE_1BIT);
>  
>       if (!uhs_en)
>               caps &= ~UHS_CAPS;
> @@ -1582,18 +1608,14 @@ static const struct ext_csd_bus_width {
>           ecbv++) \
>               if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
>  
> -static int mmc_select_mode_and_width(struct mmc *mmc)
> +static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
>  {
>       int err;
>       const struct mode_width_tuning *mwt;
>       const struct ext_csd_bus_width *ecbw;
>  
> -     err = mmc_get_capabilities(mmc);
> -     if (err)
> -             return err;
> -
>       /* Restrict card's capabilities by what the host can do */
> -     mmc->card_caps &= (mmc->cfg->host_caps | MMC_MODE_1BIT);
> +     card_caps &= (mmc->cfg->host_caps | MMC_MODE_1BIT);
>  
>       /* Only version 4 of MMC supports wider bus widths */
>       if (mmc->version < MMC_VERSION_4)
> @@ -1605,8 +1627,10 @@ static int mmc_select_mode_and_width(struct mmc *mmc)
>               return -ENOTSUPP;
>       }
>  
> -     for_each_mmc_mode_by_pref(mmc->card_caps, mwt) {
> -             for_each_supported_width(mmc->card_caps & mwt->widths,
> +     mmc_set_clock(mmc, mmc->legacy_speed, false);
> +
> +     for_each_mmc_mode_by_pref(card_caps, mwt) {
> +             for_each_supported_width(card_caps & mwt->widths,
>                                        mmc_is_mode_ddr(mwt->mode), ecbw) {
>                       debug("trying mode %s width %d (at %d MHz)\n",
>                             mmc_mode_name(mwt->mode),
> @@ -1999,14 +2023,22 @@ static int mmc_startup(struct mmc *mmc)
>       if (err)
>               return err;
>  
> -     if (IS_SD(mmc))
> -             err = sd_select_mode_and_width(mmc);
> -     else
> -             err = mmc_select_mode_and_width(mmc);
> +     if (IS_SD(mmc)) {
> +             err = sd_get_capabilities(mmc);
> +             if (err)
> +                     return err;
> +             err = sd_select_mode_and_width(mmc, mmc->card_caps);
> +     } else {
> +             err = mmc_get_capabilities(mmc);
> +             if (err)
> +                     return err;
> +             mmc_select_mode_and_width(mmc, mmc->card_caps);
> +     }
>  
>       if (err)
>               return err;
>  
> +     mmc->best_mode = mmc->selected_mode;
>  
>       /* Fix the block length for DDR mode */
>       if (mmc->ddr_mode) {
> diff --git a/include/mmc.h b/include/mmc.h
> index 775c47e..921a7ff 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -573,6 +573,7 @@ struct mmc {
>  #endif
>       u8 *ext_csd;
>       enum bus_mode selected_mode;
> +     enum bus_mode best_mode;
>  };
>  
>  struct mmc_hwpart_conf {
> 

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

Reply via email to