Re: [PATCH v1] mmc: mmc: add hs400 mode support for lx2160a

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 15, 2018 at 6:05 AM Yinbo Zhu <yinbo.zhu@xxxxxxx> wrote:
>
> From: Yangbo Lu <yangbo.lu@xxxxxxx>
>

The prefix to the title probably should just be "mmc:". The changes
below seems to be generic, but the title mentioned specifically
LX2160a.  Is this change breaking anything for other modes or devices?
 You probably should explain it more in the commit message.

> 1. Set SDTIMNGCTL[FLW_CTL_BG] just after HS400 tuning.
> 2. Clear TBCTL[TB_EN] before switching from DDR to HS400.
> 3. Re-set TBCTL[TB_EN] when switching to HS400.
> 4. Remove useless controller DDR timing setting for HS400.
> 5. add prepare_ddr_to_hs400 callback.
> 6. improve tuning block enabling/disabling.
>
> Signed-off-by: Yangbo Lu <yangbo.lu@xxxxxxx>
> Signed-off-by: Yinbo Zhu <yinbo.zhu@xxxxxxx>
> ---
>  drivers/mmc/core/mmc.c            |    3 +++
>  drivers/mmc/host/sdhci-of-esdhc.c |   32 +++++++++++++++++++++++---------
>  include/linux/mmc/host.h          |    1 +
>  3 files changed, 27 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 4f4a627..a5a3b3b 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1148,6 +1148,9 @@ static int mmc_select_hs400(struct mmc_card *card)
>                 goto out_err;
>
>         /* Switch card to DDR */
> +       if (host->ops->prepare_ddr_to_hs400)
> +               host->ops->prepare_ddr_to_hs400(host);
> +
>         err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>                          EXT_CSD_BUS_WIDTH,
>                          EXT_CSD_DDR_BUS_WIDTH_8,
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index efae07c..dea6611 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -738,6 +738,7 @@ static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable)
>         u32 val;
>
>         esdhc_clock_enable(host, false);
> +

No need to add new line.

>         val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
>         val |= ESDHC_FLUSH_ASYNC_FIFO;
>         sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> @@ -748,6 +749,7 @@ static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable)
>         else
>                 val &= ~ESDHC_TB_EN;
>         sdhci_writel(host, val, ESDHC_TBCTL);
> +

No need to add new line.

>         esdhc_clock_enable(host, true);
>  }
>
> @@ -756,13 +758,26 @@ static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
>         struct sdhci_host *host = mmc_priv(mmc);
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>         struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> +       bool hs400_tuning;
> +       u32 val;
> +       int ret;
>
>         if (esdhc->quirk_limited_clk_division &&
>             host->flags & SDHCI_HS400_TUNING)
>                 esdhc_of_set_clock(host, host->clock);
>
>         esdhc_tuning_block_enable(host, true);
> -       return sdhci_execute_tuning(mmc, opcode);
> +
> +       hs400_tuning = host->flags & SDHCI_HS400_TUNING;
> +       ret = sdhci_execute_tuning(mmc, opcode);
> +
> +       if (hs400_tuning) {
> +               val = sdhci_readl(host, ESDHC_SDTIMNGCTL);
> +               val |= ESDHC_FLW_CTL_BG;
> +               sdhci_writel(host, val, ESDHC_SDTIMNGCTL);
> +       }
> +
> +       return ret;
>  }
>
>  static void esdhc_set_ddr_signaling(struct sdhci_host *host)
> @@ -791,18 +806,10 @@ static void esdhc_set_ddr_signaling(struct sdhci_host *host)
>  static void esdhc_set_uhs_signaling(struct sdhci_host *host,
>                                     unsigned int timing)
>  {
> -       u32 val;
> -
>         if (timing == MMC_TIMING_MMC_DDR52 ||
>             timing == MMC_TIMING_UHS_DDR50) {
>                 esdhc_set_ddr_signaling(host);
>         } else if (timing == MMC_TIMING_MMC_HS400) {
> -               val = sdhci_readl(host, ESDHC_SDTIMNGCTL);
> -               val |= ESDHC_FLW_CTL_BG;
> -               sdhci_writel(host, val, ESDHC_SDTIMNGCTL);
> -
> -               esdhc_tuning_block_enable(host, false);
> -               esdhc_set_ddr_signaling(host);
>                 esdhc_tuning_block_enable(host, true);
>         } else {
>                 sdhci_set_uhs_signaling(host, timing);
> @@ -963,6 +970,12 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>         }
>  }
>
> +static int esdhc_prepare_ddr_to_hs400(struct mmc_host *mmc)
> +{
> +       esdhc_tuning_block_enable(mmc_priv(mmc), false);
> +       return 0;
> +}
> +
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
>  {
>         struct sdhci_host *host;
> @@ -986,6 +999,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>         host->mmc_host_ops.start_signal_voltage_switch =
>                 esdhc_signal_voltage_switch;
>         host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
> +       host->mmc_host_ops.prepare_ddr_to_hs400 = esdhc_prepare_ddr_to_hs400;
>         host->tuning_delay = 1;
>
>         esdhc_init(pdev, host);
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 0b24394..c97ffd6 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -146,6 +146,7 @@ struct mmc_host_ops {
>
>         /* Prepare HS400 target operating frequency depending host driver */
>         int     (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
> +       int     (*prepare_ddr_to_hs400)(struct mmc_host *host);
>         /* Prepare enhanced strobe depending host driver */
>         void    (*hs400_enhanced_strobe)(struct mmc_host *host,
>                                          struct mmc_ios *ios);
> --
> 1.7.1
>



[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux