[PATCH v3 08/20] mmc: am654_sdhci: Add support for software tuning
Jaehoon Chung
jh80.chung at samsung.com
Mon Jan 25 23:41:53 CET 2021
On 1/21/21 9:40 PM, Aswath Govindraju wrote:
> From: Faiz Abbas <faiz_abbas at ti.com>
>
> With the new SW tuning App note[1], a custom tuning algorithm is
> required for eMMC HS200, HS400 and SD card UHS modes. The algorithm
> involves running through the 32 possible input tap delay values and
> sending the appropriate tuning command (CMD19/21) for each of them
> to get a fail or pass result for each of the values. Typically, the
> range will have a small contiguous failing window. Considering the
> tuning range as a circular buffer, the algorithm then sets a final
> tuned value directly opposite to the failing window.
>
> [1] https://www.ti.com/lit/pdf/spract9
>
> Signed-off-by: Faiz Abbas <faiz_abbas at ti.com>
> Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>
Reviewed-by: Jaehoon Chung <jh80.chung at samsung.com>
Best Regards,
Jaehoon Chung
> ---
> drivers/mmc/am654_sdhci.c | 45 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
> index e86ef1a8b218..9549420c6582 100644
> --- a/drivers/mmc/am654_sdhci.c
> +++ b/drivers/mmc/am654_sdhci.c
> @@ -9,6 +9,7 @@
> #include <common.h>
> #include <dm.h>
> #include <malloc.h>
> +#include <mmc.h>
> #include <power-domain.h>
> #include <regmap.h>
> #include <sdhci.h>
> @@ -368,7 +369,48 @@ static int am654_sdhci_deferred_probe(struct sdhci_host *host)
> return sdhci_probe(dev);
> }
>
> +#ifdef MMC_SUPPORTS_TUNING
> +#define ITAP_MAX 32
> +static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
> +{
> + struct udevice *dev = mmc->dev;
> + struct am654_sdhci_plat *plat = dev_get_plat(dev);
> + int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len;
> + u32 itap;
> +
> + /* Enable ITAPDLY */
> + regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK,
> + 1 << ITAPDLYENA_SHIFT);
> +
> + for (itap = 0; itap < ITAP_MAX; itap++) {
> + am654_sdhci_write_itapdly(plat, itap);
> +
> + cur_val = !mmc_send_tuning(mmc, opcode, NULL);
> + if (cur_val && !prev_val)
> + pass_window = itap;
> +
> + if (!cur_val)
> + fail_len++;
> +
> + prev_val = cur_val;
> + }
> + /*
> + * Having determined the length of the failing window and start of
> + * the passing window calculate the length of the passing window and
> + * set the final value halfway through it considering the range as a
> + * circular buffer
> + */
> + pass_len = ITAP_MAX - fail_len;
> + itap = (pass_window + (pass_len >> 1)) % ITAP_MAX;
> + am654_sdhci_write_itapdly(plat, itap);
> +
> + return 0;
> +}
> +#endif
> const struct sdhci_ops am654_sdhci_ops = {
> +#ifdef MMC_SUPPORTS_TUNING
> + .platform_execute_tuning = am654_sdhci_execute_tuning,
> +#endif
> .deferred_probe = am654_sdhci_deferred_probe,
> .set_ios_post = &am654_sdhci_set_ios_post,
> .set_control_reg = &am654_sdhci_set_control_reg,
> @@ -408,6 +450,9 @@ static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
> }
>
> const struct sdhci_ops j721e_4bit_sdhci_ops = {
> +#ifdef MMC_SUPPORTS_TUNING
> + .platform_execute_tuning = am654_sdhci_execute_tuning,
> +#endif
> .deferred_probe = am654_sdhci_deferred_probe,
> .set_ios_post = &j721e_4bit_sdhci_set_ios_post,
> };
>
More information about the U-Boot
mailing list