text: From a10349f1710a11239c58da3a7e5b353c6b2070c2 Mon Sep 17 00:00:00 2001
  From: Chaotian Jing <chaotian.jing@mediatek.com>
  Date: Mon, 16 Oct 2017 09:46:32 +0800
  Subject: [PATCH 153/224] mmc: mediatek: add pad_tune0 support
  
  from mt2701, the register of PAD_TUNE has been phased out,
  while there is a new register of PAD_TUNE0
  
  Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
  Tested-by: Sean Wang <sean.wang@mediatek.com>
  Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  ---
   drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++-----------------
   1 file changed, 33 insertions(+), 18 deletions(-)
  
  --- a/drivers/mmc/host/mtk-sd.c
  +++ b/drivers/mmc/host/mtk-sd.c
  @@ -75,6 +75,7 @@
   #define MSDC_PATCH_BIT   0xb0
   #define MSDC_PATCH_BIT1  0xb4
   #define MSDC_PAD_TUNE    0xec
  +#define MSDC_PAD_TUNE0   0xf0
   #define PAD_DS_TUNE      0x188
   #define PAD_CMD_TUNE     0x18c
   #define EMMC50_CFG0      0x208
  @@ -303,6 +304,7 @@ struct msdc_save_para {
   struct mtk_mmc_compatible {
   	u8 clk_div_bits;
   	bool hs400_tune; /* only used for MT8173 */
  +	u32 pad_tune_reg;
   };
   
   struct msdc_tune_para {
  @@ -364,21 +366,25 @@ struct msdc_host {
   static const struct mtk_mmc_compatible mt8135_compat = {
   	.clk_div_bits = 8,
   	.hs400_tune = false,
  +	.pad_tune_reg = MSDC_PAD_TUNE,
   };
   
   static const struct mtk_mmc_compatible mt8173_compat = {
   	.clk_div_bits = 8,
   	.hs400_tune = true,
  +	.pad_tune_reg = MSDC_PAD_TUNE,
   };
   
   static const struct mtk_mmc_compatible mt2701_compat = {
   	.clk_div_bits = 12,
   	.hs400_tune = false,
  +	.pad_tune_reg = MSDC_PAD_TUNE0,
   };
   
   static const struct mtk_mmc_compatible mt2712_compat = {
   	.clk_div_bits = 12,
   	.hs400_tune = false,
  +	.pad_tune_reg = MSDC_PAD_TUNE0,
   };
   
   static const struct of_device_id msdc_of_ids[] = {
  @@ -583,6 +589,7 @@ static void msdc_set_mclk(struct msdc_ho
   	u32 flags;
   	u32 div;
   	u32 sclk;
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
   
   	if (!hz) {
   		dev_dbg(host->dev, "set mclk to 0\n");
  @@ -665,10 +672,10 @@ static void msdc_set_mclk(struct msdc_ho
   	 */
   	if (host->sclk <= 52000000) {
   		writel(host->def_tune_para.iocon, host->base + MSDC_IOCON);
  -		writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
  +		writel(host->def_tune_para.pad_tune, host->base + tune_reg);
   	} else {
   		writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON);
  -		writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
  +		writel(host->saved_tune_para.pad_tune, host->base + tune_reg);
   		writel(host->saved_tune_para.pad_cmd_tune,
   		       host->base + PAD_CMD_TUNE);
   	}
  @@ -1226,6 +1233,7 @@ static irqreturn_t msdc_irq(int irq, voi
   static void msdc_init_hw(struct msdc_host *host)
   {
   	u32 val;
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
   
   	/* Configure to MMC/SD mode, clock free running */
   	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);
  @@ -1241,7 +1249,7 @@ static void msdc_init_hw(struct msdc_hos
   	val = readl(host->base + MSDC_INT);
   	writel(val, host->base + MSDC_INT);
   
  -	writel(0, host->base + MSDC_PAD_TUNE);
  +	writel(0, host->base + tune_reg);
   	writel(0, host->base + MSDC_IOCON);
   	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
   	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
  @@ -1261,7 +1269,7 @@ static void msdc_init_hw(struct msdc_hos
   	sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
   
   	host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
  -	host->def_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
  +	host->def_tune_para.pad_tune = readl(host->base + tune_reg);
   	dev_dbg(host->dev, "init hardware done!");
   }
   
  @@ -1404,18 +1412,19 @@ static int msdc_tune_response(struct mmc
   	struct msdc_delay_phase internal_delay_phase;
   	u8 final_delay, final_maxlen;
   	u32 internal_delay = 0;
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
   	int cmd_err;
   	int i, j;
   
   	if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
   	    mmc->ios.timing == MMC_TIMING_UHS_SDR104)
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_CMDRRDLY,
   			      host->hs200_cmd_int_delay);
   
   	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
   	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_CMDRDLY, i);
   		/*
   		 * Using the same parameters, it may sometimes pass the test,
  @@ -1439,7 +1448,7 @@ static int msdc_tune_response(struct mmc
   
   	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
   	for (i = 0; i < PAD_DELAY_MAX; i++) {
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_CMDRDLY, i);
   		/*
   		 * Using the same parameters, it may sometimes pass the test,
  @@ -1464,12 +1473,12 @@ skip_fall:
   		final_maxlen = final_fall_delay.maxlen;
   	if (final_maxlen == final_rise_delay.maxlen) {
   		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
  -		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
  +		sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY,
   			      final_rise_delay.final_phase);
   		final_delay = final_rise_delay.final_phase;
   	} else {
   		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
  -		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
  +		sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY,
   			      final_fall_delay.final_phase);
   		final_delay = final_fall_delay.final_phase;
   	}
  @@ -1477,7 +1486,7 @@ skip_fall:
   		goto skip_internal;
   
   	for (i = 0; i < PAD_DELAY_MAX; i++) {
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_CMDRRDLY, i);
   		mmc_send_tuning(mmc, opcode, &cmd_err);
   		if (!cmd_err)
  @@ -1485,7 +1494,7 @@ skip_fall:
   	}
   	dev_dbg(host->dev, "Final internal delay: 0x%x\n", internal_delay);
   	internal_delay_phase = get_best_delay(host, internal_delay);
  -	sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY,
  +	sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
   		      internal_delay_phase.final_phase);
   skip_internal:
   	dev_dbg(host->dev, "Final cmd pad delay: %x\n", final_delay);
  @@ -1548,12 +1557,13 @@ static int msdc_tune_data(struct mmc_hos
   	u32 rise_delay = 0, fall_delay = 0;
   	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
   	u8 final_delay, final_maxlen;
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
   	int i, ret;
   
   	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
   	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
   	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_DATRRDLY, i);
   		ret = mmc_send_tuning(mmc, opcode, NULL);
   		if (!ret)
  @@ -1568,7 +1578,7 @@ static int msdc_tune_data(struct mmc_hos
   	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
   	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
   	for (i = 0; i < PAD_DELAY_MAX; i++) {
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_DATRRDLY, i);
   		ret = mmc_send_tuning(mmc, opcode, NULL);
   		if (!ret)
  @@ -1581,14 +1591,14 @@ skip_fall:
   	if (final_maxlen == final_rise_delay.maxlen) {
   		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
   		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_DATRRDLY,
   			      final_rise_delay.final_phase);
   		final_delay = final_rise_delay.final_phase;
   	} else {
   		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
   		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
  -		sdr_set_field(host->base + MSDC_PAD_TUNE,
  +		sdr_set_field(host->base + tune_reg,
   			      MSDC_PAD_TUNE_DATRRDLY,
   			      final_fall_delay.final_phase);
   		final_delay = final_fall_delay.final_phase;
  @@ -1602,6 +1612,7 @@ static int msdc_execute_tuning(struct mm
   {
   	struct msdc_host *host = mmc_priv(mmc);
   	int ret;
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
   
   	if (host->hs400_mode &&
   	    host->dev_comp->hs400_tune)
  @@ -1619,7 +1630,7 @@ static int msdc_execute_tuning(struct mm
   	}
   
   	host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
  -	host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
  +	host->saved_tune_para.pad_tune = readl(host->base + tune_reg);
   	host->saved_tune_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
   	return ret;
   }
  @@ -1860,10 +1871,12 @@ static int msdc_drv_remove(struct platfo
   #ifdef CONFIG_PM
   static void msdc_save_reg(struct msdc_host *host)
   {
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
  +
   	host->save_para.msdc_cfg = readl(host->base + MSDC_CFG);
   	host->save_para.iocon = readl(host->base + MSDC_IOCON);
   	host->save_para.sdc_cfg = readl(host->base + SDC_CFG);
  -	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
  +	host->save_para.pad_tune = readl(host->base + tune_reg);
   	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
   	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
   	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
  @@ -1873,10 +1886,12 @@ static void msdc_save_reg(struct msdc_ho
   
   static void msdc_restore_reg(struct msdc_host *host)
   {
  +	u32 tune_reg = host->dev_comp->pad_tune_reg;
  +
   	writel(host->save_para.msdc_cfg, host->base + MSDC_CFG);
   	writel(host->save_para.iocon, host->base + MSDC_IOCON);
   	writel(host->save_para.sdc_cfg, host->base + SDC_CFG);
  -	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
  +	writel(host->save_para.pad_tune, host->base + tune_reg);
   	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
   	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
   	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
  