Commit 011fde48 authored by Yangbo Lu's avatar Yangbo Lu Committed by Ulf Hansson

mmc: sdhci-of-esdhc: make sure delay chain locked for HS400

For eMMC HS400 mode initialization, the DLL reset is a required step
if DLL is enabled to use previously, like in bootloader.
This step has not been documented in reference manual, but the RM will
be fixed sooner or later.

This patch is to add the step of DLL reset, and make sure delay chain
locked for HS400.
Signed-off-by: default avatarYangbo Lu <yangbo.lu@nxp.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20201020081116.20918-1-yangbo.lu@nxp.com
Fixes: 54e08d9a ("mmc: sdhci-of-esdhc: add hs400 mode support")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 0add6e9b
......@@ -5,6 +5,7 @@
* Copyright (c) 2007 Freescale Semiconductor, Inc.
* Copyright (c) 2009 MontaVista Software, Inc.
* Copyright (c) 2010 Pengutronix e.K.
* Copyright 2020 NXP
* Author: Wolfram Sang <kernel@pengutronix.de>
*/
......@@ -88,6 +89,7 @@
/* DLL Config 0 Register */
#define ESDHC_DLLCFG0 0x160
#define ESDHC_DLL_ENABLE 0x80000000
#define ESDHC_DLL_RESET 0x40000000
#define ESDHC_DLL_FREQ_SEL 0x08000000
/* DLL Config 1 Register */
......
......@@ -4,6 +4,7 @@
*
* Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
* Copyright (c) 2009 MontaVista Software, Inc.
* Copyright 2020 NXP
*
* Authors: Xiaobo Xie <X.Xie@freescale.com>
* Anton Vorontsov <avorontsov@ru.mvista.com>
......@@ -19,6 +20,7 @@
#include <linux/clk.h>
#include <linux/ktime.h>
#include <linux/dma-mapping.h>
#include <linux/iopoll.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include "sdhci-pltfm.h"
......@@ -743,6 +745,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
if (host->mmc->actual_clock == MMC_HS200_MAX_DTR)
temp |= ESDHC_DLL_FREQ_SEL;
sdhci_writel(host, temp, ESDHC_DLLCFG0);
temp |= ESDHC_DLL_RESET;
sdhci_writel(host, temp, ESDHC_DLLCFG0);
udelay(1);
temp &= ~ESDHC_DLL_RESET;
sdhci_writel(host, temp, ESDHC_DLLCFG0);
/* Wait max 20 ms */
if (read_poll_timeout(sdhci_readl, temp,
temp & ESDHC_DLL_STS_SLV_LOCK,
10, 20000, false,
host, ESDHC_DLLSTAT0))
pr_err("%s: timeout for delay chain lock.\n",
mmc_hostname(host->mmc));
temp = sdhci_readl(host, ESDHC_TBCTL);
sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment