Re: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400

2015-08-07 Thread Dong Aisheng
On Wed, Aug 05, 2015 at 06:38:37PM +0800, Haibo Chen wrote:
 The imx7d usdhc is derived from imx6sx, the difference is that
 imx7d support HS400.
 
 So introduce a new compatible string for imx7d and add HS400
 support for imx7d usdhc.
 
 Signed-off-by: Haibo Chen haibo.c...@freescale.com
 ---
  drivers/mmc/host/sdhci-esdhc-imx.c | 81 
 ++
  1 file changed, 81 insertions(+)
 
 diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
 b/drivers/mmc/host/sdhci-esdhc-imx.c
 index c6b9f64..48f009c 100644
 --- a/drivers/mmc/host/sdhci-esdhc-imx.c
 +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
 @@ -44,6 +44,7 @@
  #define  ESDHC_MIX_CTRL_EXE_TUNE (1  22)
  #define  ESDHC_MIX_CTRL_SMPCLK_SEL   (1  23)
  #define  ESDHC_MIX_CTRL_FBCLK_SEL(1  25)
 +#define  ESDHC_MIX_CTRL_HS400_EN (1  26)
  /* Bits 3 and 6 are not SDHCI standard definitions */
  #define  ESDHC_MIX_CTRL_SDHCI_MASK   0xb7
  /* Tuning bits */
 @@ -60,6 +61,16 @@
  #define  ESDHC_TUNE_CTRL_MIN 0
  #define  ESDHC_TUNE_CTRL_MAX ((1  7) - 1)
  
 +/* strobe dll register */
 +#define ESDHC_STROBE_DLL_CTRL0x70
 +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1  0)
 +#define ESDHC_STROBE_DLL_CTRL_RESET  (1  1)
 +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT   3
 +
 +#define ESDHC_STROBE_DLL_STATUS  0x74
 +#define ESDHC_STROBE_DLL_STS_REF_LOCK(1  1)
 +#define ESDHC_STROBE_DLL_STS_SLV_LOCK0x1
 +
  #define ESDHC_TUNING_CTRL0xcc
  #define ESDHC_STD_TUNING_EN  (1  24)
  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
 @@ -120,6 +131,11 @@
  #define ESDHC_FLAG_ERR004536 BIT(7)
  /* The IP supports HS200 mode */
  #define ESDHC_FLAG_HS200 BIT(8)
 +/* The IP supports HS400 mode */
 +#define ESDHC_FLAG_HS400 BIT(9)
 +
 +/* A higher clock ferquency than this rate requires strobell dll control */
 +#define ESDHC_STROBE_DLL_CLK_FREQ1
  
  struct esdhc_soc_data {
   u32 flags;
 @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
   | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
  };
  
 +static struct esdhc_soc_data usdhc_imx7d_data = {
 + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
 + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
 + | ESDHC_FLAG_HS400,
 +};
 +
  struct pltfm_imx_data {
   u32 scratchpad;
   struct pinctrl *pinctrl;
 @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
   { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, },
   { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, },
   { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, },
 + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, },
   { /* sentinel */ }
  };
  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
 @@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int 
 reg)
   val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
   | SDHCI_SUPPORT_SDR50
   | SDHCI_USE_SDR50_TUNING;
 +
 + if (imx_data-socdata-flags  ESDHC_FLAG_HS400)
 + val |= SDHCI_SUPPORT_HS400;
   }
   }
  
 @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
   break;
   case MMC_TIMING_UHS_SDR104:
   case MMC_TIMING_MMC_HS200:
 + case MMC_TIMING_MMC_HS400:
   pinctrl = imx_data-pins_200mhz;
   break;
   default:
 @@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
   return pinctrl_select_state(imx_data-pinctrl, pinctrl);
  }
  
 +/*
 + * For HS400 eMMC, there is a data_strobe line, this signal is generated
 + * by the device and used for data output and CRC status response output
 + * in HS400 mode. The frequency of this signal follows the frequency of
 + * CLK generated by host. Host receive the data which is aligned to the
 + * edge of data_strobe line. Due to the time delay between CLK line and
 + * data_strobe line, if the delay time is larger than one clock cycle,
 + * then CLK and data_strobe line will misaligned, read error shows up.
 + * So when the CLK is higher than 100MHz, each clock cycle is short enough,
 + * host should config the delay target.
 + */
 +static void esdhc_set_strobe_dll(struct sdhci_host *host)
 +{
 + u32 v;
 +
 + if (host-mmc-actual_clock  ESDHC_STROBE_DLL_CLK_FREQ) {
 + /* force a reset on strobe dll */
 + writel(ESDHC_STROBE_DLL_CTRL_RESET,
 + host-ioaddr + ESDHC_STROBE_DLL_CTRL);
 + /*
 +  * enable strobe dll ctrl and adjust the delay target
 +  * for the uSDHC loopback read clock
 +  */
 + v = ESDHC_STROBE_DLL_CTRL_ENABLE |
 + (7  

Re: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400

2015-08-07 Thread Dong Aisheng
On Fri, Aug 07, 2015 at 05:53:01PM +0800, Chen Haibo-B51421 wrote:
 
 
  -Original Message-
  From: Dong Aisheng [mailto:aisheng.d...@freescale.com]
  Sent: Friday, August 07, 2015 3:39 PM
  To: Chen Haibo-B51421
  Cc: robh...@kernel.org; pawel.m...@arm.com; mark.rutl...@arm.com;
  ijc+devicet...@hellion.org.uk; ga...@codeaurora.org; shawn...@kernel.org;
  ker...@pengutronix.de; li...@arm.linux.org.uk; ulf.hans...@linaro.org;
  johan.dery...@barco.com; m...@pengutronix.de; Estevam Fabio-R49496; Dong
  Aisheng-B29396; devicet...@vger.kernel.org; linux-ker...@vger.kernel.org;
  linux-arm-ker...@lists.infradead.org; linux-mmc@vger.kernel.org
  Subject: Re: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
  support HS400
  
  On Wed, Aug 05, 2015 at 06:38:37PM +0800, Haibo Chen wrote:
   The imx7d usdhc is derived from imx6sx, the difference is that imx7d
   support HS400.
  
   So introduce a new compatible string for imx7d and add HS400 support
   for imx7d usdhc.
  
   Signed-off-by: Haibo Chen haibo.c...@freescale.com
   ---
drivers/mmc/host/sdhci-esdhc-imx.c | 81
   ++
1 file changed, 81 insertions(+)
  
   diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
   b/drivers/mmc/host/sdhci-esdhc-imx.c
   index c6b9f64..48f009c 100644
   --- a/drivers/mmc/host/sdhci-esdhc-imx.c
   +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
   @@ -44,6 +44,7 @@
#define  ESDHC_MIX_CTRL_EXE_TUNE (1  22)
#define  ESDHC_MIX_CTRL_SMPCLK_SEL   (1  23)
#define  ESDHC_MIX_CTRL_FBCLK_SEL(1  25)
   +#define  ESDHC_MIX_CTRL_HS400_EN (1  26)
/* Bits 3 and 6 are not SDHCI standard definitions */
#define  ESDHC_MIX_CTRL_SDHCI_MASK   0xb7
/* Tuning bits */
   @@ -60,6 +61,16 @@
#define  ESDHC_TUNE_CTRL_MIN 0
#define  ESDHC_TUNE_CTRL_MAX ((1  7) - 1)
  
   +/* strobe dll register */
   +#define ESDHC_STROBE_DLL_CTRL0x70
   +#define ESDHC_STROBE_DLL_CTRL_ENABLE (1  0)
   +#define ESDHC_STROBE_DLL_CTRL_RESET  (1  1)
   +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT   3
   +
   +#define ESDHC_STROBE_DLL_STATUS  0x74
   +#define ESDHC_STROBE_DLL_STS_REF_LOCK(1  1)
   +#define ESDHC_STROBE_DLL_STS_SLV_LOCK0x1
   +
#define ESDHC_TUNING_CTRL0xcc
#define ESDHC_STD_TUNING_EN  (1  24)
/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
   -120,6 +131,11 @@
#define ESDHC_FLAG_ERR004536 BIT(7)
/* The IP supports HS200 mode */
#define ESDHC_FLAG_HS200 BIT(8)
   +/* The IP supports HS400 mode */
   +#define ESDHC_FLAG_HS400 BIT(9)
   +
   +/* A higher clock ferquency than this rate requires strobell dll
  control */
   +#define ESDHC_STROBE_DLL_CLK_FREQ1
  
struct esdhc_soc_data {
 u32 flags;
   @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
 | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
  
   +static struct esdhc_soc_data usdhc_imx7d_data = {
   + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
   + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
   + | ESDHC_FLAG_HS400,
   +};
   +
struct pltfm_imx_data {
 u32 scratchpad;
 struct pinctrl *pinctrl;
   @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
  = {
 { .compatible = fsl,imx6sx-usdhc, .data = usdhc_imx6sx_data, },
 { .compatible = fsl,imx6sl-usdhc, .data = usdhc_imx6sl_data, },
 { .compatible = fsl,imx6q-usdhc, .data = usdhc_imx6q_data, },
   + { .compatible = fsl,imx7d-usdhc, .data = usdhc_imx7d_data, },
 { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +297,9 @@ static
   u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 | SDHCI_SUPPORT_SDR50
 | SDHCI_USE_SDR50_TUNING;
   +
   + if (imx_data-socdata-flags  ESDHC_FLAG_HS400)
   + val |= SDHCI_SUPPORT_HS400;
 }
 }
  
   @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host
  *host,
 break;
 case MMC_TIMING_UHS_SDR104:
 case MMC_TIMING_MMC_HS200:
   + case MMC_TIMING_MMC_HS400:
 pinctrl = imx_data-pins_200mhz;
 break;
 default:
   @@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host
  *host,
 return pinctrl_select_state(imx_data-pinctrl, pinctrl);  }
  
   +/*
   + * For HS400 eMMC, there is a data_strobe line, this signal is
   +generated
   + * by the device and used for data output and CRC status response
   +output
   + * in HS400 mode. The frequency of this signal follows the frequency
   +of
   + * CLK generated by host. Host receive the data which is aligned to
   +the
   + * edge of data_strobe line. Due