[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