mmc: mediatek: add support of mt2701/mt2712

25 messages, 5 authors, 2017-10-09 · open the first message on its own page

mmc: mediatek: add support of mt2701/mt2712

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:05

  This serial of patches are adding support of mt2701/mt2712.
there are many changes and HW improvement between mt8173 and
mt2701/mt2712, below is a list of these changes:
  1. enlarge CLKDIV bits from 8 to 12
  2. remove the PAD_TUNE register and add a new PAD_TUNE0 register
  3. add data sync and async fifo feature
  4. add busy_check feature
  5. add stop_clk fix
  6. add enhance_rx support
  7. add a seperate CG of source clock

mt2712 supports full of these features, mt2701 supports part of it, and
add a "mediatek,latch-ck" to work-around as it do not support stop-clk
fix.

Note: As Pinctrl/CCF are not ready now, so that current patches do not
include DTS part.


Chaotian Jing (12):
  mmc: dt-bindings: update Mediatek MMC bindings
  arm64: dts: mt8173: remove "mediatek,mt8135-mmc" from mmc nodes
  mmc: mediatek: add support of mt2701/mt2712
  mmc: mediatek: make hs400_tune_response only for mt8173
  mmc: mediatek: add pad_tune0 support
  mmc: mediatek: add async fifo and data tune support
  mmc: mediatek: add busy_check support
  mmc: mediatek: add stop_clk fix and enhance_rx support
  mmc: mediatek: add support of source_cg clock
  mmc: mediatek: add latch-ck support
  mmc: mediatek: improve eMMC hs400 mode read performance
  mmc: mediatek: perfer to use rise edge latching for cmd line

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  13 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi         |  12 +-
 drivers/mmc/host/mtk-sd.c                        | 298 ++++++++++++++++++++---
 3 files changed, 275 insertions(+), 48 deletions(-)

-- 
1.9.1

[PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:08

Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.
 
 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+	"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
 - pinctrl-names: should be "default", "state_uhs"
 - pinctrl-0: should contain default/high speed pin ctrl
 - pinctrl-1: should contain uhs mode pin ctrl
@@ -30,6 +35,8 @@ Optional properties:
 - mediatek,hs400-cmd-resp-sel-rising:  HS400 command response sample selection
 				       If present,HS400 command responses are sampled on rising edges.
 				       If not present,HS400 command responses are sampled on falling edges.
+- mediatek,latch-ck: Some projects do not support enhance_rx, need set correct latch-ck to avoid data crc
+		     error caused by stop clock(fifo full)
 
 Examples:
 mmc0: mmc at 11230000 {
-- 
1.8.1.1.dirty

[PATCH 03/12] mmc: mediatek: add support of mt2701/mt2712

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:14

mt2701/mt2712 has 12bit clock div, which is not compatible with
mt8135/mt8173. and, some additional features will be added in
mt2701/mt2712, so that need distinguish it by comatibale name.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 82 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 267f7ab..643c795 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -95,6 +95,9 @@
 #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
 #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
 #define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
+#define MSDC_CFG_HS400_CK_MODE_EXTRA  (0x1 << 22)	/* RW */
+#define MSDC_CFG_CKDIV_EXTRA    (0xfff << 8)	/* RW */
+#define MSDC_CFG_CKMOD_EXTRA    (0x3 << 20)	/* RW */
 
 /* MSDC_IOCON mask */
 #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
@@ -295,6 +298,10 @@ struct msdc_save_para {
 	u32 emmc50_cfg0;
 };
 
+struct mtk_mmc_compatible {
+	u8 clk_div_bits;
+};
+
 struct msdc_tune_para {
 	u32 iocon;
 	u32 pad_tune;
@@ -309,6 +316,7 @@ struct msdc_delay_phase {
 
 struct msdc_host {
 	struct device *dev;
+	const struct mtk_mmc_compatible *dev_comp;
 	struct mmc_host *mmc;	/* mmc structure */
 	int cmd_rsp;
 
@@ -350,6 +358,31 @@ struct msdc_host {
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
 };
 
+static const struct mtk_mmc_compatible mt8135_compat = {
+	.clk_div_bits = 8,
+};
+
+static const struct mtk_mmc_compatible mt8173_compat = {
+	.clk_div_bits = 8,
+};
+
+static const struct mtk_mmc_compatible mt2701_compat = {
+	.clk_div_bits = 12,
+};
+
+static const struct mtk_mmc_compatible mt2712_compat = {
+	.clk_div_bits = 12,
+};
+
+static const struct of_device_id msdc_of_ids[] = {
+	{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
+	{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
+	{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
+	{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
+	{}
+};
+MODULE_DEVICE_TABLE(of, msdc_of_ids);
+
 static void sdr_set_bits(void __iomem *reg, u32 bs)
 {
 	u32 val = readl(reg);
@@ -509,7 +542,12 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
 		timeout = (ns + clk_ns - 1) / clk_ns + clks;
 		/* in 1048576 sclk cycle unit */
 		timeout = (timeout + (0x1 << 20) - 1) >> 20;
-		sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &mode);
+		if (host->dev_comp->clk_div_bits == 8)
+			sdr_get_field(host->base + MSDC_CFG,
+				      MSDC_CFG_CKMOD, &mode);
+		else
+			sdr_get_field(host->base + MSDC_CFG,
+				      MSDC_CFG_CKMOD_EXTRA, &mode);
 		/*DDR mode will double the clk cycles for data timeout */
 		timeout = mode >= 2 ? timeout * 2 : timeout;
 		timeout = timeout > 1 ? timeout - 1 : 0;
@@ -548,7 +586,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+	if (host->dev_comp->clk_div_bits == 8)
+		sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+	else
+		sdr_clr_bits(host->base + MSDC_CFG,
+			     MSDC_CFG_HS400_CK_MODE_EXTRA);
 	if (timing == MMC_TIMING_UHS_DDR50 ||
 	    timing == MMC_TIMING_MMC_DDR52 ||
 	    timing == MMC_TIMING_MMC_HS400) {
@@ -568,8 +610,12 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 		if (timing == MMC_TIMING_MMC_HS400 &&
 		    hz >= (host->src_clk_freq >> 1)) {
-			sdr_set_bits(host->base + MSDC_CFG,
-				     MSDC_CFG_HS400_CK_MODE);
+			if (host->dev_comp->clk_div_bits == 8)
+				sdr_set_bits(host->base + MSDC_CFG,
+					     MSDC_CFG_HS400_CK_MODE);
+			else
+				sdr_set_bits(host->base + MSDC_CFG,
+					     MSDC_CFG_HS400_CK_MODE_EXTRA);
 			sclk = host->src_clk_freq >> 1;
 			div = 0; /* div is ignore when bit18 is set */
 		}
@@ -587,8 +633,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 		}
 	}
-	sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-		      (mode << 8) | div);
+	if (host->dev_comp->clk_div_bits == 8)
+		sdr_set_field(host->base + MSDC_CFG,
+			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
+			      (mode << 8) | div);
+	else
+		sdr_set_field(host->base + MSDC_CFG,
+			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
+			      (mode << 12) | div);
+
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
 		cpu_relax();
@@ -1617,12 +1670,17 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	struct mmc_host *mmc;
 	struct msdc_host *host;
 	struct resource *res;
+	const struct of_device_id *of_id;
 	int ret;
 
 	if (!pdev->dev.of_node) {
 		dev_err(&pdev->dev, "No DT found\n");
 		return -EINVAL;
 	}
+
+	of_id = of_match_node(msdc_of_ids, pdev->dev.of_node);
+	if (!of_id)
+		return -EINVAL;
 	/* Allocate MMC host for this device */
 	mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
 	if (!mmc)
@@ -1686,11 +1744,15 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
+	host->dev_comp = of_id->data;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
 	/* Set host parameters to mmc */
 	mmc->ops = &mt_msdc_ops;
-	mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
+	if (host->dev_comp->clk_div_bits == 8)
+		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
+	else
+		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
 
 	mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
 	/* MMC core transfer sizes tunable parameters */
@@ -1839,12 +1901,6 @@ static int msdc_runtime_resume(struct device *dev)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-static const struct of_device_id msdc_of_ids[] = {
-	{   .compatible = "mediatek,mt8135-mmc", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, msdc_of_ids);
-
 static struct platform_driver mt_msdc_driver = {
 	.probe = msdc_drv_probe,
 	.remove = msdc_drv_remove,
-- 
1.8.1.1.dirty

[PATCH 05/12] mmc: mediatek: add pad_tune0 support

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:20

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>
---
 drivers/mmc/host/mtk-sd.c | 69 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index e8f8ad9..43144e1 100644
--- 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
@@ -300,6 +301,7 @@ struct msdc_save_para {
 
 struct mtk_mmc_compatible {
 	u8 clk_div_bits;
+	bool pad_tune0;
 };
 
 struct msdc_tune_para {
@@ -361,18 +363,22 @@ struct msdc_host {
 
 static const struct mtk_mmc_compatible mt8135_compat = {
 	.clk_div_bits = 8,
+	.pad_tune0 = false,
 };
 
 static const struct mtk_mmc_compatible mt8173_compat = {
 	.clk_div_bits = 8,
+	.pad_tune0 = false,
 };
 
 static const struct mtk_mmc_compatible mt2701_compat = {
 	.clk_div_bits = 12,
+	.pad_tune0 = true,
 };
 
 static const struct mtk_mmc_compatible mt2712_compat = {
 	.clk_div_bits = 12,
+	.pad_tune0 = true,
 };
 
 static const struct of_device_id msdc_of_ids[] = {
@@ -577,6 +583,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	u32 flags;
 	u32 div;
 	u32 sclk;
+	u32 tune_reg = MSDC_PAD_TUNE;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
 
 	if (!hz) {
 		dev_dbg(host->dev, "set mclk to 0\n");
@@ -659,10 +669,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	 */
 	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);
 	}
@@ -1220,7 +1230,10 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
 static void msdc_init_hw(struct msdc_host *host)
 {
 	u32 val;
+	u32 tune_reg = MSDC_PAD_TUNE;
 
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
 	/* Configure to MMC/SD mode, clock free running */
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);
 
@@ -1235,7 +1248,7 @@ static void msdc_init_hw(struct msdc_host *host)
 	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);
@@ -1255,7 +1268,7 @@ static void msdc_init_hw(struct msdc_host *host)
 	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!");
 }
 
@@ -1398,18 +1411,22 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 	struct msdc_delay_phase internal_delay_phase;
 	u8 final_delay, final_maxlen;
 	u32 internal_delay = 0;
+	u32 tune_reg = MSDC_PAD_TUNE;
 	int cmd_err;
 	int i, j;
 
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
+
 	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,
@@ -1433,7 +1450,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 
 	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,
@@ -1458,12 +1475,12 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 		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;
 	}
@@ -1471,7 +1488,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 		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)
@@ -1479,7 +1496,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 	}
 	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);
@@ -1541,12 +1558,16 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 	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 = MSDC_PAD_TUNE;
 	int i, ret;
 
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
+
 	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)
@@ -1561,7 +1582,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 	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)
@@ -1574,14 +1595,14 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 	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;
@@ -1595,6 +1616,10 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
+	u32 tune_reg = MSDC_PAD_TUNE;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
 
 	if (host->hs400_mode &&
 	    !strcmp(host->compatible, "mediatek,mt8173-mmc"))
@@ -1612,7 +1637,7 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	}
 
 	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;
 }
@@ -1854,10 +1879,14 @@ static int msdc_drv_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static void msdc_save_reg(struct msdc_host *host)
 {
+	u32 tune_reg = MSDC_PAD_TUNE;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
 	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);
@@ -1867,10 +1896,14 @@ static void msdc_save_reg(struct msdc_host *host)
 
 static void msdc_restore_reg(struct msdc_host *host)
 {
+	u32 tune_reg = MSDC_PAD_TUNE;
+
+	if (host->dev_comp->pad_tune0)
+		tune_reg = MSDC_PAD_TUNE0;
 	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);
-- 
1.8.1.1.dirty

[PATCH 07/12] mmc: mediatek: add busy_check support

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:25

bit7 of PATCH_BIT1 has different meaning in new design, to
compatible with previous platform, clear this bit in new
platform.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index e7462fe..555824d 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -315,6 +315,7 @@ struct mtk_mmc_compatible {
 	bool pad_tune0;
 	bool async_fifo;
 	bool data_tune;
+	bool busy_check;
 };
 
 struct msdc_tune_para {
@@ -379,6 +380,7 @@ struct msdc_host {
 	.pad_tune0 = false,
 	.async_fifo = false,
 	.data_tune = false,
+	.busy_check = false,
 };
 
 static const struct mtk_mmc_compatible mt8173_compat = {
@@ -386,6 +388,7 @@ struct msdc_host {
 	.pad_tune0 = false,
 	.async_fifo = false,
 	.data_tune = false,
+	.busy_check = false,
 };
 
 static const struct mtk_mmc_compatible mt2701_compat = {
@@ -393,6 +396,7 @@ struct msdc_host {
 	.pad_tune0 = true,
 	.async_fifo = true,
 	.data_tune = true,
+	.busy_check = false,
 };
 
 static const struct mtk_mmc_compatible mt2712_compat = {
@@ -400,6 +404,7 @@ struct msdc_host {
 	.pad_tune0 = true,
 	.async_fifo = true,
 	.data_tune = true,
+	.busy_check = true,
 };
 
 static const struct of_device_id msdc_of_ids[] = {
@@ -1276,6 +1281,8 @@ static void msdc_init_hw(struct msdc_host *host)
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+	if (host->dev_comp->busy_check)
+		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7));
 	if (host->dev_comp->async_fifo) {
 		sdr_set_field(host->base + MSDC_PATCH_BIT2,
 			      MSDC_PB2_RESPWAIT, 3);
-- 
1.8.1.1.dirty

[PATCH 06/12] mmc: mediatek: add async fifo and data tune support

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:27

mt2701/mt2712 supports async fifo & data tune, which can improve
host stability.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 43144e1..e7462fe 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -74,6 +74,7 @@
 #define MSDC_DMA_CFG     0x9c
 #define MSDC_PATCH_BIT   0xb0
 #define MSDC_PATCH_BIT1  0xb4
+#define MSDC_PATCH_BIT2  0xb8
 #define MSDC_PAD_TUNE    0xec
 #define MSDC_PAD_TUNE0   0xf0
 #define PAD_DS_TUNE      0x188
@@ -216,11 +217,20 @@
 #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */
 
+#define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */
+#define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28)   /* RW */
+#define MSDC_PB2_RESPWAIT         (0x3 << 2)    /* RW */
+#define MSDC_PB2_RESPSTSENSEL     (0x7 << 16)   /* RW */
+#define MSDC_PB2_CRCSTSENSEL      (0x7 << 29)   /* RW */
+
 #define MSDC_PAD_TUNE_DATWRDLY	  (0x1f <<  0)	/* RW */
 #define MSDC_PAD_TUNE_DATRRDLY	  (0x1f <<  8)	/* RW */
 #define MSDC_PAD_TUNE_CMDRDLY	  (0x1f << 16)  /* RW */
 #define MSDC_PAD_TUNE_CMDRRDLY	  (0x1f << 22)	/* RW */
 #define MSDC_PAD_TUNE_CLKTDLY	  (0x1f << 27)  /* RW */
+#define MSDC_PAD_TUNE_RXDLYSEL	  (0x1 << 15)   /* RW */
+#define MSDC_PAD_TUNE_RD_SEL	  (0x1 << 13)   /* RW */
+#define MSDC_PAD_TUNE_CMD_SEL	  (0x1 << 21)   /* RW */
 
 #define PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
@@ -294,6 +304,7 @@ struct msdc_save_para {
 	u32 pad_tune;
 	u32 patch_bit0;
 	u32 patch_bit1;
+	u32 patch_bit2;
 	u32 pad_ds_tune;
 	u32 pad_cmd_tune;
 	u32 emmc50_cfg0;
@@ -302,6 +313,8 @@ struct msdc_save_para {
 struct mtk_mmc_compatible {
 	u8 clk_div_bits;
 	bool pad_tune0;
+	bool async_fifo;
+	bool data_tune;
 };
 
 struct msdc_tune_para {
@@ -364,21 +377,29 @@ struct msdc_host {
 static const struct mtk_mmc_compatible mt8135_compat = {
 	.clk_div_bits = 8,
 	.pad_tune0 = false,
+	.async_fifo = false,
+	.data_tune = false,
 };
 
 static const struct mtk_mmc_compatible mt8173_compat = {
 	.clk_div_bits = 8,
 	.pad_tune0 = false,
+	.async_fifo = false,
+	.data_tune = false,
 };
 
 static const struct mtk_mmc_compatible mt2701_compat = {
 	.clk_div_bits = 12,
 	.pad_tune0 = true,
+	.async_fifo = true,
+	.data_tune = true,
 };
 
 static const struct mtk_mmc_compatible mt2712_compat = {
 	.clk_div_bits = 12,
 	.pad_tune0 = true,
+	.async_fifo = true,
+	.data_tune = true,
 };
 
 static const struct of_device_id msdc_of_ids[] = {
@@ -1253,8 +1274,29 @@ static void msdc_init_hw(struct msdc_host *host)
 	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
 	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
-	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
+	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+	if (host->dev_comp->async_fifo) {
+		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+			      MSDC_PB2_RESPWAIT, 3);
+		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+			      MSDC_PB2_RESPSTSENSEL, 2);
+		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+			      MSDC_PB2_CRCSTSENSEL, 2);
+		/* use async fifo, then no need tune internal delay */
+		sdr_clr_bits(host->base + MSDC_PATCH_BIT2,
+			     MSDC_PATCH_BIT2_CFGRESP);
+		sdr_set_bits(host->base + MSDC_PATCH_BIT2,
+			     MSDC_PATCH_BIT2_CFGCRCSTS);
+	}
+
+	if (host->dev_comp->data_tune) {
+		sdr_set_bits(host->base + tune_reg,
+			     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
+	} else {
+		/* choose clock tune */
+		sdr_set_bits(host->base + tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
+	}
 
 	/* Configure to enable SDIO mode.
 	 * it's must otherwise sdio cmd5 failed
@@ -1269,6 +1311,8 @@ static void msdc_init_hw(struct msdc_host *host)
 
 	host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
 	host->def_tune_para.pad_tune = readl(host->base + tune_reg);
+	host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
+	host->saved_tune_para.pad_tune = readl(host->base + tune_reg);
 	dev_dbg(host->dev, "init hardware done!");
 }
 
@@ -1484,7 +1528,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 			      final_fall_delay.final_phase);
 		final_delay = final_fall_delay.final_phase;
 	}
-	if (host->hs200_cmd_int_delay)
+	if (host->dev_comp->async_fifo || host->hs200_cmd_int_delay)
 		goto skip_internal;
 
 	for (i = 0; i < PAD_DELAY_MAX; i++) {
@@ -1648,6 +1692,8 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 	host->hs400_mode = true;
 
 	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
+	/* hs400 mode must set it to 0 */
+	sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
 	return 0;
 }
 
@@ -1889,6 +1935,7 @@ static void msdc_save_reg(struct msdc_host *host)
 	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.patch_bit2 = readl(host->base + MSDC_PATCH_BIT2);
 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
@@ -1906,6 +1953,7 @@ static void msdc_restore_reg(struct msdc_host *host)
 	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.patch_bit2, host->base + MSDC_PATCH_BIT2);
 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
-- 
1.8.1.1.dirty

[PATCH 08/12] mmc: mediatek: add stop_clk fix and enhance_rx support

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:29

mt2712 supports stop_clk fix and enhance_rx, which can improve
host stability.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 555824d..5d99e05 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -67,6 +67,7 @@
 #define SDC_RESP2        0x48
 #define SDC_RESP3        0x4c
 #define SDC_BLK_NUM      0x50
+#define SDC_ADV_CFG0     0x64
 #define EMMC_IOCON       0x7c
 #define SDC_ACMD_RESP    0x80
 #define MSDC_DMA_SA      0x90
@@ -80,6 +81,7 @@
 #define PAD_DS_TUNE      0x188
 #define PAD_CMD_TUNE     0x18c
 #define EMMC50_CFG0      0x208
+#define SDC_FIFO_CFG     0x228
 
 /*--------------------------------------------------------------------------*/
 /* Register Mask                                                            */
@@ -188,6 +190,9 @@
 #define SDC_STS_CMDBUSY         (0x1 << 1)	/* RW */
 #define SDC_STS_SWR_COMPL       (0x1 << 31)	/* RW */
 
+/* SDC_ADV_CFG0 mask */
+#define SDC_RX_ENHANCE_EN	(0x1 << 20)	/* RW */
+
 /* MSDC_DMA_CTRL mask */
 #define MSDC_DMA_CTRL_START     (0x1 << 0)	/* W */
 #define MSDC_DMA_CTRL_STOP      (0x1 << 1)	/* W */
@@ -217,6 +222,8 @@
 #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */
 
+#define MSDC_PATCH_BIT1_STOP_DLY  (0xf << 8)    /* RW */
+
 #define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */
 #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28)   /* RW */
 #define MSDC_PB2_RESPWAIT         (0x3 << 2)    /* RW */
@@ -242,6 +249,9 @@
 #define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)   /* RW */
 
+#define SDC_FIFO_CFG_WRVALIDSEL   (0x1 << 24)  /* RW */
+#define SDC_FIFO_CFG_RDVALIDSEL   (0x1 << 25)  /* RW */
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -308,6 +318,7 @@ struct msdc_save_para {
 	u32 pad_ds_tune;
 	u32 pad_cmd_tune;
 	u32 emmc50_cfg0;
+	u32 sdc_fifo_cfg;
 };
 
 struct mtk_mmc_compatible {
@@ -316,6 +327,8 @@ struct mtk_mmc_compatible {
 	bool async_fifo;
 	bool data_tune;
 	bool busy_check;
+	bool stop_clk_fix;
+	bool enhance_rx;
 };
 
 struct msdc_tune_para {
@@ -381,6 +394,8 @@ struct msdc_host {
 	.async_fifo = false,
 	.data_tune = false,
 	.busy_check = false,
+	.stop_clk_fix = false,
+	.enhance_rx = false,
 };
 
 static const struct mtk_mmc_compatible mt8173_compat = {
@@ -389,6 +404,8 @@ struct msdc_host {
 	.async_fifo = false,
 	.data_tune = false,
 	.busy_check = false,
+	.stop_clk_fix = false,
+	.enhance_rx = false,
 };
 
 static const struct mtk_mmc_compatible mt2701_compat = {
@@ -397,6 +414,8 @@ struct msdc_host {
 	.async_fifo = true,
 	.data_tune = true,
 	.busy_check = false,
+	.stop_clk_fix = false,
+	.enhance_rx = false,
 };
 
 static const struct mtk_mmc_compatible mt2712_compat = {
@@ -405,6 +424,8 @@ struct msdc_host {
 	.async_fifo = true,
 	.data_tune = true,
 	.busy_check = true,
+	.stop_clk_fix = true,
+	.enhance_rx = true,
 };
 
 static const struct of_device_id msdc_of_ids[] = {
@@ -1281,15 +1302,31 @@ static void msdc_init_hw(struct msdc_host *host)
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+
+	if (host->dev_comp->stop_clk_fix) {
+		sdr_set_field(host->base + MSDC_PATCH_BIT1,
+			      MSDC_PATCH_BIT1_STOP_DLY, 3);
+		sdr_clr_bits(host->base + SDC_FIFO_CFG,
+			     SDC_FIFO_CFG_WRVALIDSEL);
+		sdr_clr_bits(host->base + SDC_FIFO_CFG,
+			     SDC_FIFO_CFG_RDVALIDSEL);
+	}
+
 	if (host->dev_comp->busy_check)
 		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7));
+
 	if (host->dev_comp->async_fifo) {
 		sdr_set_field(host->base + MSDC_PATCH_BIT2,
 			      MSDC_PB2_RESPWAIT, 3);
-		sdr_set_field(host->base + MSDC_PATCH_BIT2,
-			      MSDC_PB2_RESPSTSENSEL, 2);
-		sdr_set_field(host->base + MSDC_PATCH_BIT2,
-			      MSDC_PB2_CRCSTSENSEL, 2);
+		if (host->dev_comp->enhance_rx) {
+			sdr_set_bits(host->base + SDC_ADV_CFG0,
+				     SDC_RX_ENHANCE_EN);
+		} else {
+			sdr_set_field(host->base + MSDC_PATCH_BIT2,
+				      MSDC_PB2_RESPSTSENSEL, 2);
+			sdr_set_field(host->base + MSDC_PATCH_BIT2,
+				      MSDC_PB2_CRCSTSENSEL, 2);
+		}
 		/* use async fifo, then no need tune internal delay */
 		sdr_clr_bits(host->base + MSDC_PATCH_BIT2,
 			     MSDC_PATCH_BIT2_CFGRESP);
@@ -1946,6 +1983,7 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
+	host->save_para.sdc_fifo_cfg = readl(host->base + SDC_FIFO_CFG);
 }
 
 static void msdc_restore_reg(struct msdc_host *host)
@@ -1964,6 +2002,7 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
+	writel(host->save_para.sdc_fifo_cfg, host->base + SDC_FIFO_CFG);
 }
 
 static int msdc_runtime_suspend(struct device *dev)
-- 
1.8.1.1.dirty

[PATCH 09/12] mmc: mediatek: add support of source_cg clock

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:35

source clock need an independent cg to control, when doing clk mode
switch, need gate source clock to avoid hw issue(multi-bit sync hw hang)

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 5d99e05..522fd0a 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -372,6 +372,7 @@ struct msdc_host {
 
 	struct clk *src_clk;	/* msdc source clock */
 	struct clk *h_clk;      /* msdc h_clk */
+	struct clk *src_clk_cg; /* msdc source clock control gate */
 	u32 mclk;		/* mmc subsystem clock frequency */
 	u32 src_clk_freq;	/* source clock frequency */
 	u32 sclk;		/* SD/MS bus clock frequency */
@@ -612,6 +613,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
 
 static void msdc_gate_clock(struct msdc_host *host)
 {
+	clk_disable_unprepare(host->src_clk_cg);
 	clk_disable_unprepare(host->src_clk);
 	clk_disable_unprepare(host->h_clk);
 }
@@ -620,6 +622,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
 {
 	clk_prepare_enable(host->h_clk);
 	clk_prepare_enable(host->src_clk);
+	clk_prepare_enable(host->src_clk_cg);
 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
 		cpu_relax();
 }
@@ -691,6 +694,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 		}
 	}
+	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
+	/*
+	 * As src_clk/HCLK use the same bit to gate/ungate,
+	 * So if want to only gate src_clk, need gate its parent(mux).
+	 */
+	if (host->src_clk_cg)
+		clk_disable_unprepare(host->src_clk_cg);
+	else
+		clk_disable_unprepare(clk_get_parent(host->src_clk));
 	if (host->dev_comp->clk_div_bits == 8)
 		sdr_set_field(host->base + MSDC_CFG,
 			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
@@ -699,10 +711,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 		sdr_set_field(host->base + MSDC_CFG,
 			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
 			      (mode << 12) | div);
+	if (host->src_clk_cg)
+		clk_prepare_enable(host->src_clk_cg);
+	else
+		clk_prepare_enable(clk_get_parent(host->src_clk));
 
-	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
 		cpu_relax();
+	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	host->sclk = sclk;
 	host->mclk = hz;
 	host->timing = timing;
@@ -1832,6 +1848,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	/*source clock control gate is optional clock*/
+	host->src_clk_cg = devm_clk_get(&pdev->dev, "source_cg");
+	if (IS_ERR(host->src_clk_cg))
+		host->src_clk_cg = NULL;
+
 	host->irq = platform_get_irq(pdev, 0);
 	if (host->irq < 0) {
 		ret = -EINVAL;
-- 
1.8.1.1.dirty

[PATCH 11/12] mmc: mediatek: improve eMMC hs400 mode read performance

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:39

enlarge outstanding value to improve read performance

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 9 +++++++++
 1 file changed, 9 insertions(+)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 3328d59..49d4d79 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -81,6 +81,7 @@
 #define PAD_DS_TUNE      0x188
 #define PAD_CMD_TUNE     0x18c
 #define EMMC50_CFG0      0x208
+#define EMMC50_CFG3      0x220
 #define SDC_FIFO_CFG     0x228
 
 /*--------------------------------------------------------------------------*/
@@ -249,6 +250,8 @@
 #define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)   /* RW */
 
+#define EMMC50_CFG3_OUTS_WR       (0x1f << 0)  /* RW */
+
 #define SDC_FIFO_CFG_WRVALIDSEL   (0x1 << 24)  /* RW */
 #define SDC_FIFO_CFG_RDVALIDSEL   (0x1 << 25)  /* RW */
 
@@ -318,6 +321,7 @@ struct msdc_save_para {
 	u32 pad_ds_tune;
 	u32 pad_cmd_tune;
 	u32 emmc50_cfg0;
+	u32 emmc50_cfg3;
 	u32 sdc_fifo_cfg;
 };
 
@@ -1757,6 +1761,9 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
 	/* hs400 mode must set it to 0 */
 	sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
+	/* to improve read performance, set outstanding to 2 */
+	sdr_set_field(host->base + EMMC50_CFG3, EMMC50_CFG3_OUTS_WR, 2);
+
 	return 0;
 }
 
@@ -2010,6 +2017,7 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
+	host->save_para.emmc50_cfg3 = readl(host->base + EMMC50_CFG3);
 	host->save_para.sdc_fifo_cfg = readl(host->base + SDC_FIFO_CFG);
 }
 
@@ -2029,6 +2037,7 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
+	writel(host->save_para.emmc50_cfg3, host->base + EMMC50_CFG3);
 	writel(host->save_para.sdc_fifo_cfg, host->base + SDC_FIFO_CFG);
 }
 
-- 
1.8.1.1.dirty

[PATCH 12/12] mmc: mediatek: perfer to use rise edge latching for cmd line

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:08:57

data lines have applied to perfer to use rise edge, also need
apply it to cmd line.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 49d4d79..9f21cdb 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1554,7 +1554,8 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
 	}
 	final_rise_delay = get_best_delay(host, rise_delay);
 	/* if rising edge has enough margin, then do not scan falling edge */
-	if (final_rise_delay.maxlen >= 12 && final_rise_delay.start < 4)
+	if (final_rise_delay.maxlen >= 12 ||
+	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
 		goto skip_fall;
 
 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
-- 
1.8.1.1.dirty

[PATCH 10/12] mmc: mediatek: add latch-ck support

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:10:24

some platform(eg.mt2701) does not support "stop clk fix", in
this case, need set correct latch-ck to avoid crc error caused
by stop clock block-internally.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 522fd0a..3328d59 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -378,6 +378,7 @@ struct msdc_host {
 	u32 sclk;		/* SD/MS bus clock frequency */
 	unsigned char timing;
 	bool vqmmc_enabled;
+	u32 latch_ck;
 	u32 hs400_ds_delay;
 	u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */
 	u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
@@ -1668,6 +1669,8 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
 	if (host->dev_comp->pad_tune0)
 		tune_reg = MSDC_PAD_TUNE0;
 
+	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_INT_DAT_LATCH_CK_SEL,
+		      host->latch_ck);
 	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++) {
@@ -1783,6 +1786,9 @@ static void msdc_hw_reset(struct mmc_host *mmc)
 static void msdc_of_property_parse(struct platform_device *pdev,
 				   struct msdc_host *host)
 {
+	of_property_read_u32(pdev->dev.of_node, "mediatek,latch-ck",
+			     &host->latch_ck);
+
 	of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
 			     &host->hs400_ds_delay);
 
-- 
1.8.1.1.dirty

[PATCH 04/12] mmc: mediatek: make hs400_tune_response only for mt8173

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:12:08

the origin design of hs400_tune_response is for mt8173 because of
mt8173 has a special design. for doing that, we add a new member
"compatible", by now it's only for mt8173.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 643c795..e8f8ad9 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -317,6 +317,7 @@ struct msdc_delay_phase {
 struct msdc_host {
 	struct device *dev;
 	const struct mtk_mmc_compatible *dev_comp;
+	const char *compatible;
 	struct mmc_host *mmc;	/* mmc structure */
 	int cmd_rsp;
 
@@ -666,7 +667,8 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 		       host->base + PAD_CMD_TUNE);
 	}
 
-	if (timing == MMC_TIMING_MMC_HS400)
+	if (timing == MMC_TIMING_MMC_HS400 &&
+	    !strcmp(host->compatible, "mediatek,mt8173-mmc"))
 		sdr_set_field(host->base + PAD_CMD_TUNE,
 			      MSDC_PAD_TUNE_CMDRRDLY,
 			      host->hs400_cmd_int_delay);
@@ -1594,7 +1596,8 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
 
-	if (host->hs400_mode)
+	if (host->hs400_mode &&
+	    !strcmp(host->compatible, "mediatek,mt8173-mmc"))
 		ret = hs400_tune_response(mmc, opcode);
 	else
 		ret = msdc_tune_response(mmc, opcode);
@@ -1745,6 +1748,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
 
 	host->dev = &pdev->dev;
 	host->dev_comp = of_id->data;
+	host->compatible = of_id->compatible;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
 	/* Set host parameters to mmc */
-- 
1.8.1.1.dirty

[PATCH 02/12] arm64: dts: mt8173: remove "mediatek,mt8135-mmc" from mmc nodes

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-12 09:12:40

devicetree bindings has been updated to support multi-platforms,
so that each platform has its owns compatible name.
And, this compatible name may used in driver to distinguish with
other platform.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index b99a273..26396ef 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -682,8 +682,7 @@
 		};
 
 		mmc0: mmc at 11230000 {
-			compatible = "mediatek,mt8173-mmc",
-				     "mediatek,mt8135-mmc";
+			compatible = "mediatek,mt8173-mmc";
 			reg = <0 0x11230000 0 0x1000>;
 			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&pericfg CLK_PERI_MSDC30_0>,
@@ -693,8 +692,7 @@
 		};
 
 		mmc1: mmc at 11240000 {
-			compatible = "mediatek,mt8173-mmc",
-				     "mediatek,mt8135-mmc";
+			compatible = "mediatek,mt8173-mmc";
 			reg = <0 0x11240000 0 0x1000>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&pericfg CLK_PERI_MSDC30_1>,
@@ -704,8 +702,7 @@
 		};
 
 		mmc2: mmc at 11250000 {
-			compatible = "mediatek,mt8173-mmc",
-				     "mediatek,mt8135-mmc";
+			compatible = "mediatek,mt8173-mmc";
 			reg = <0 0x11250000 0 0x1000>;
 			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&pericfg CLK_PERI_MSDC30_2>,
@@ -715,8 +712,7 @@
 		};
 
 		mmc3: mmc at 11260000 {
-			compatible = "mediatek,mt8173-mmc",
-				     "mediatek,mt8135-mmc";
+			compatible = "mediatek,mt8173-mmc";
 			reg = <0 0x11260000 0 0x1000>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&pericfg CLK_PERI_MSDC30_3>,
-- 
1.8.1.1.dirty

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Rob Herring <robh@kernel.org>
Date: 2017-09-13 14:10:32

On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject. 
Please make the subject somewhat unique.
quoted hunk
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.
 
 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+	"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for 
existing compatible strings if the driver requires it.
quoted hunk
 - pinctrl-names: should be "default", "state_uhs"
 - pinctrl-0: should contain default/high speed pin ctrl
 - pinctrl-1: should contain uhs mode pin ctrl
@@ -30,6 +35,8 @@ Optional properties:
 - mediatek,hs400-cmd-resp-sel-rising:  HS400 command response sample selection
 				       If present,HS400 command responses are sampled on rising edges.
 				       If not present,HS400 command responses are sampled on falling edges.
+- mediatek,latch-ck: Some projects do not support enhance_rx, need set correct latch-ck to avoid data crc
What's a project?
+		     error caused by stop clock(fifo full)
 
 Examples:
 mmc0: mmc at 11230000 {
-- 
1.8.1.1.dirty

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-14 02:10:36

On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject. 
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.
 
 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+	"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for 
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
quoted
 - pinctrl-names: should be "default", "state_uhs"
 - pinctrl-0: should contain default/high speed pin ctrl
 - pinctrl-1: should contain uhs mode pin ctrl
@@ -30,6 +35,8 @@ Optional properties:
 - mediatek,hs400-cmd-resp-sel-rising:  HS400 command response sample selection
 				       If present,HS400 command responses are sampled on rising edges.
 				       If not present,HS400 command responses are sampled on falling edges.
+- mediatek,latch-ck: Some projects do not support enhance_rx, need set correct latch-ck to avoid data crc
What's a project?
eg, MT2701
quoted
+		     error caused by stop clock(fifo full)
 
 Examples:
 mmc0: mmc at 11230000 {
-- 
1.8.1.1.dirty

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Linus Walleij <hidden>
Date: 2017-09-21 11:38:31

On Thu, Sep 14, 2017 at 4:10 AM, Chaotian Jing
[off-list ref] wrote:
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
quoted
+- mediatek,latch-ck: Some projects do not support enhance_rx, need set correct latch-ck to avoid data crc
What's a project?
eg, MT2701
Replace the word "project" with the word "system" or "SoC" in
your patch.

Yours,
Linus Walleij

Re: [PATCH 03/12] mmc: mediatek: add support of mt2701/mt2712

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-26 01:38:45

Hi Ulf,

Sorry to disturb you, Do you have some comments of these series of
patch ?
Thx!
On Tue, 2017-09-12 at 17:07 +0800, Chaotian Jing wrote:
quoted hunk
mt2701/mt2712 has 12bit clock div, which is not compatible with
mt8135/mt8173. and, some additional features will be added in
mt2701/mt2712, so that need distinguish it by comatibale name.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 82 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 267f7ab..643c795 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -95,6 +95,9 @@
 #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
 #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
 #define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
+#define MSDC_CFG_HS400_CK_MODE_EXTRA  (0x1 << 22)	/* RW */
+#define MSDC_CFG_CKDIV_EXTRA    (0xfff << 8)	/* RW */
+#define MSDC_CFG_CKMOD_EXTRA    (0x3 << 20)	/* RW */
 
 /* MSDC_IOCON mask */
 #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
@@ -295,6 +298,10 @@ struct msdc_save_para {
 	u32 emmc50_cfg0;
 };
 
+struct mtk_mmc_compatible {
+	u8 clk_div_bits;
+};
+
 struct msdc_tune_para {
 	u32 iocon;
 	u32 pad_tune;
@@ -309,6 +316,7 @@ struct msdc_delay_phase {
 
 struct msdc_host {
 	struct device *dev;
+	const struct mtk_mmc_compatible *dev_comp;
 	struct mmc_host *mmc;	/* mmc structure */
 	int cmd_rsp;
 
@@ -350,6 +358,31 @@ struct msdc_host {
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
 };
 
+static const struct mtk_mmc_compatible mt8135_compat = {
+	.clk_div_bits = 8,
+};
+
+static const struct mtk_mmc_compatible mt8173_compat = {
+	.clk_div_bits = 8,
+};
+
+static const struct mtk_mmc_compatible mt2701_compat = {
+	.clk_div_bits = 12,
+};
+
+static const struct mtk_mmc_compatible mt2712_compat = {
+	.clk_div_bits = 12,
+};
+
+static const struct of_device_id msdc_of_ids[] = {
+	{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
+	{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
+	{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
+	{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
+	{}
+};
+MODULE_DEVICE_TABLE(of, msdc_of_ids);
+
 static void sdr_set_bits(void __iomem *reg, u32 bs)
 {
 	u32 val = readl(reg);
@@ -509,7 +542,12 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
 		timeout = (ns + clk_ns - 1) / clk_ns + clks;
 		/* in 1048576 sclk cycle unit */
 		timeout = (timeout + (0x1 << 20) - 1) >> 20;
-		sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &mode);
+		if (host->dev_comp->clk_div_bits == 8)
+			sdr_get_field(host->base + MSDC_CFG,
+				      MSDC_CFG_CKMOD, &mode);
+		else
+			sdr_get_field(host->base + MSDC_CFG,
+				      MSDC_CFG_CKMOD_EXTRA, &mode);
 		/*DDR mode will double the clk cycles for data timeout */
 		timeout = mode >= 2 ? timeout * 2 : timeout;
 		timeout = timeout > 1 ? timeout - 1 : 0;
@@ -548,7 +586,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+	if (host->dev_comp->clk_div_bits == 8)
+		sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+	else
+		sdr_clr_bits(host->base + MSDC_CFG,
+			     MSDC_CFG_HS400_CK_MODE_EXTRA);
 	if (timing == MMC_TIMING_UHS_DDR50 ||
 	    timing == MMC_TIMING_MMC_DDR52 ||
 	    timing == MMC_TIMING_MMC_HS400) {
@@ -568,8 +610,12 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 		if (timing == MMC_TIMING_MMC_HS400 &&
 		    hz >= (host->src_clk_freq >> 1)) {
-			sdr_set_bits(host->base + MSDC_CFG,
-				     MSDC_CFG_HS400_CK_MODE);
+			if (host->dev_comp->clk_div_bits == 8)
+				sdr_set_bits(host->base + MSDC_CFG,
+					     MSDC_CFG_HS400_CK_MODE);
+			else
+				sdr_set_bits(host->base + MSDC_CFG,
+					     MSDC_CFG_HS400_CK_MODE_EXTRA);
 			sclk = host->src_clk_freq >> 1;
 			div = 0; /* div is ignore when bit18 is set */
 		}
@@ -587,8 +633,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 		}
 	}
-	sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-		      (mode << 8) | div);
+	if (host->dev_comp->clk_div_bits == 8)
+		sdr_set_field(host->base + MSDC_CFG,
+			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
+			      (mode << 8) | div);
+	else
+		sdr_set_field(host->base + MSDC_CFG,
+			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
+			      (mode << 12) | div);
+
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
 		cpu_relax();
@@ -1617,12 +1670,17 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	struct mmc_host *mmc;
 	struct msdc_host *host;
 	struct resource *res;
+	const struct of_device_id *of_id;
 	int ret;
 
 	if (!pdev->dev.of_node) {
 		dev_err(&pdev->dev, "No DT found\n");
 		return -EINVAL;
 	}
+
+	of_id = of_match_node(msdc_of_ids, pdev->dev.of_node);
+	if (!of_id)
+		return -EINVAL;
 	/* Allocate MMC host for this device */
 	mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
 	if (!mmc)
@@ -1686,11 +1744,15 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
+	host->dev_comp = of_id->data;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
 	/* Set host parameters to mmc */
 	mmc->ops = &mt_msdc_ops;
-	mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
+	if (host->dev_comp->clk_div_bits == 8)
+		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
+	else
+		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
 
 	mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
 	/* MMC core transfer sizes tunable parameters */
@@ -1839,12 +1901,6 @@ static int msdc_runtime_resume(struct device *dev)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-static const struct of_device_id msdc_of_ids[] = {
-	{   .compatible = "mediatek,mt8135-mmc", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, msdc_of_ids);
-
 static struct platform_driver mt_msdc_driver = {
 	.probe = msdc_drv_probe,
 	.remove = msdc_drv_remove,

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Ulf Hansson <hidden>
Date: 2017-09-26 22:34:04

On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.

 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe

Re: [PATCH 02/12] arm64: dts: mt8173: remove "mediatek,mt8135-mmc" from mmc nodes

From: Ulf Hansson <hidden>
Date: 2017-09-26 22:37:04

On 12 September 2017 at 11:07, Chaotian Jing [off-list ref] wrote:
devicetree bindings has been updated to support multi-platforms,
so that each platform has its owns compatible name.
And, this compatible name may used in driver to distinguish with
other platform.
This does not seems to be DT backwards compatible.

If the driver starts interpreting the "mt8135-mmc" differently,
wouldn't that lead to old DTBs to become broken?

Kind regards
Uffe
quoted hunk
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index b99a273..26396ef 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -682,8 +682,7 @@
                };

                mmc0: mmc at 11230000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11230000 0 0x1000>;
                        interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_0>,
@@ -693,8 +692,7 @@
                };

                mmc1: mmc at 11240000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11240000 0 0x1000>;
                        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_1>,
@@ -704,8 +702,7 @@
                };

                mmc2: mmc at 11250000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11250000 0 0x1000>;
                        interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_2>,
@@ -715,8 +712,7 @@
                };

                mmc3: mmc at 11260000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11260000 0 0x1000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_3>,
--
1.8.1.1.dirty

Re: [PATCH 02/12] arm64: dts: mt8173: remove "mediatek,mt8135-mmc" from mmc nodes

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-27 01:14:57

On Wed, 2017-09-27 at 00:37 +0200, Ulf Hansson wrote:
On 12 September 2017 at 11:07, Chaotian Jing [off-list ref] wrote:
quoted
devicetree bindings has been updated to support multi-platforms,
so that each platform has its owns compatible name.
And, this compatible name may used in driver to distinguish with
other platform.
This does not seems to be DT backwards compatible.

If the driver starts interpreting the "mt8135-mmc" differently,
wouldn't that lead to old DTBs to become broken?

Kind regards
Uffe
At patch 03/12, it shows that no difference between "mt8135-mmc" and
"mt8173-mmc", and following changes will make difference between these
two.
but, the user should update DTS & driver together,then will do not have
compatible issue.
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index b99a273..26396ef 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -682,8 +682,7 @@
                };

                mmc0: mmc at 11230000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11230000 0 0x1000>;
                        interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_0>,
@@ -693,8 +692,7 @@
                };

                mmc1: mmc at 11240000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11240000 0 0x1000>;
                        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_1>,
@@ -704,8 +702,7 @@
                };

                mmc2: mmc at 11250000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11250000 0 0x1000>;
                        interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_2>,
@@ -715,8 +712,7 @@
                };

                mmc3: mmc at 11260000 {
-                       compatible = "mediatek,mt8173-mmc",
-                                    "mediatek,mt8135-mmc";
+                       compatible = "mediatek,mt8173-mmc";
                        reg = <0 0x11260000 0 0x1000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>;
                        clocks = <&pericfg CLK_PERI_MSDC30_3>,
--
1.8.1.1.dirty

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-27 01:18:30

On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.

 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe
The source_cg is required(MUST) at MT2712 and future SoCs, but not
required(do not have it) at previous SoCs, so that put it at required
properties, let the driver to handle it.

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-09-29 01:56:17

On Wed, 2017-09-27 at 09:18 +0800, Chaotian Jing wrote:
On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
quoted
On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.

 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe
The source_cg is required(MUST) at MT2712 and future SoCs, but not
required(do not have it) at previous SoCs, so that put it at required
properties, let the driver to handle it.
Any other comments about it ? still must not add a required binding for
it ? if add a optional binding for it, how to add it ? as cannot
duplicate "clocks" & "clock-names" in one node.

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Ulf Hansson <hidden>
Date: 2017-10-02 06:53:41

[...]
quoted
quoted
quoted
quoted
quoted
 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe
The source_cg is required(MUST) at MT2712 and future SoCs, but not
required(do not have it) at previous SoCs, so that put it at required
properties, let the driver to handle it.
Then you must explain that in the binding...

On 29 September 2017 at 03:56, Chaotian Jing [off-list ref] wrote:
On Wed, 2017-09-27 at 09:18 +0800, Chaotian Jing wrote:
quoted
On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
quoted
On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.
Any other comments about it ? still must not add a required binding for
it ? if add a optional binding for it, how to add it ? as cannot
duplicate "clocks" & "clock-names" in one node.
I suggest you keep the description of the new clock name part of the
"Required properties:" header. However, after each clock name,
explicit state when the clock is required/optional. Something along
the lines as sdhci-msm does it.
Documentation/devicetree/bindings/mmc/sdhci-msm.txt

Kind regards
Uffe

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Yingjoe Chen <hidden>
Date: 2017-10-02 10:49:24

On Fri, 2017-09-29 at 09:56 +0800, Chaotian Jing wrote:
On Wed, 2017-09-27 at 09:18 +0800, Chaotian Jing wrote:
quoted
On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
quoted
On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.

 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe
The source_cg is required(MUST) at MT2712 and future SoCs, but not
required(do not have it) at previous SoCs, so that put it at required
properties, let the driver to handle it.
Any other comments about it ? still must not add a required binding for
it ? if add a optional binding for it, how to add it ? as cannot
duplicate "clocks" & "clock-names" in one node.

Chaotian,

You can follow examples of scpsys [1]:

- clock, clock-names: clocks according to the common clock binding.
                      These are clocks which hardware needs to be
                      enabled before enabling certain power domains.
	Required clocks for MT2701: "mm", "mfg", "ethif"
	Required clocks for MT6797: "mm", "mfg", "vdec"
	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"

[1]:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt?h=v4.13.4

Joe.C

Re: [PATCH 01/12] mmc: dt-bindings: update Mediatek MMC bindings

From: Chaotian Jing <chaotian.jing@mediatek.com>
Date: 2017-10-09 02:16:40

On Mon, 2017-10-02 at 08:53 +0200, Ulf Hansson wrote:
[...]
quoted
quoted
quoted
quoted
quoted
quoted
 Required properties:
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
+- compatible: value should be either of the following.
+   "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
+   "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+   "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+   "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
+- reg: physical base address of the controller and length
 - interrupts: Should contain MSDC interrupt number
-- clocks: MSDC source clock, HCLK
-- clock-names: "source", "hclk"
+- clocks: MSDC source clock, HCLK, source_cg
+- clock-names: "source", "hclk", "source_cg"
All chips support source_cg? That's not backwards compatible for
existing compatible strings if the driver requires it.
Not all chips support source_cg, for chips which do not support
source_cg, no need source_cg here, and the driver will parse it
to know if current chip support it.
In such case you must not add add a required binding for it. I think
that is what Rob is trying to point out for you.

[...]

Kind regards
Uffe
The source_cg is required(MUST) at MT2712 and future SoCs, but not
required(do not have it) at previous SoCs, so that put it at required
properties, let the driver to handle it.
Then you must explain that in the binding...

On 29 September 2017 at 03:56, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-27 at 09:18 +0800, Chaotian Jing wrote:
quoted
On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
quoted
On 14 September 2017 at 04:10, Chaotian Jing [off-list ref] wrote:
quoted
On Wed, 2017-09-13 at 09:10 -0500, Rob Herring wrote:
quoted
On Tue, Sep 12, 2017 at 05:07:41PM +0800, Chaotian Jing wrote:
quoted
Change the comptiable for support of multi-platform
Add description for reg
Add description for source_cg
Add description for mediatek,latch-ck
This is at least the 3rd patch with exactly the same vague subject.
Please make the subject somewhat unique.
Thx, will change the subject at next version
quoted
quoted
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..405cd06 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -7,10 +7,15 @@ This file documents differences between the core properties in mmc.txt
 and the properties used by the msdc driver.
Any other comments about it ? still must not add a required binding for
it ? if add a optional binding for it, how to add it ? as cannot
duplicate "clocks" & "clock-names" in one node.
I suggest you keep the description of the new clock name part of the
"Required properties:" header. However, after each clock name,
explicit state when the clock is required/optional. Something along
the lines as sdhci-msm does it.
Documentation/devicetree/bindings/mmc/sdhci-msm.txt

Kind regards
Uffe
Thx, I will send a new series of patch v2 to review.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help