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
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 <[email protected]>
---
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@11230000 {
--
1.8.1.1.dirty
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 <[email protected]>
---
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
mt2712 supports stop_clk fix and enhance_rx, which can improve
host stability.
Signed-off-by: Chaotian Jing <[email protected]>
---
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
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 <[email protected]>
---
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
enlarge outstanding value to improve read performance
Signed-off-by: Chaotian Jing <[email protected]>
---
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
data lines have applied to perfer to use rise edge, also need
apply it to cmd line.
Signed-off-by: Chaotian Jing <[email protected]>
---
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
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 <[email protected]>
---
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
mt2701/mt2712 supports async fifo & data tune, which can improve
host stability.
Signed-off-by: Chaotian Jing <[email protected]>
---
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
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 <[email protected]>
---
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
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 <[email protected]>
---
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
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 <[email protected]>
---
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
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 <[email protected]>
---
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@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@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@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@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
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.
>
> Signed-off-by: Chaotian Jing <[email protected]>
> ---
> 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.
> - 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@11230000 {
> --
> 1.8.1.1.dirty
>
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:
> > 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
> >
> > Signed-off-by: Chaotian Jing <[email protected]>
> > ---
> > 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.
>
> > - 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
>
> > + error caused by stop clock(fifo full)
> >
> > Examples:
> > mmc0: mmc@11230000 {
> > --
> > 1.8.1.1.dirty
> >
On Thu, Sep 14, 2017 at 4:10 AM, Chaotian Jing
<[email protected]> wrote:
> 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:
>> > +- 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
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:
> 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 <[email protected]>
> ---
> 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,
On 14 September 2017 at 04:10, Chaotian Jing <[email protected]> wrote:
> 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:
>> > 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
>> >
>> > Signed-off-by: Chaotian Jing <[email protected]>
>> > ---
>> > 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
On 12 September 2017 at 11:07, Chaotian Jing <[email protected]> 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
>
> Signed-off-by: Chaotian Jing <[email protected]>
> ---
> 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@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@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@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@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
>
On Wed, 2017-09-27 at 00:37 +0200, Ulf Hansson wrote:
> On 12 September 2017 at 11:07, Chaotian Jing <[email protected]> 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
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.
>
> >
> > Signed-off-by: Chaotian Jing <[email protected]>
> > ---
> > 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@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@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@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@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
> >
On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
> On 14 September 2017 at 04:10, Chaotian Jing <[email protected]> wrote:
> > 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:
> >> > 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
> >> >
> >> > Signed-off-by: Chaotian Jing <[email protected]>
> >> > ---
> >> > 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.
On Wed, 2017-09-27 at 09:18 +0800, Chaotian Jing wrote:
> On Wed, 2017-09-27 at 00:33 +0200, Ulf Hansson wrote:
> > On 14 September 2017 at 04:10, Chaotian Jing <[email protected]> wrote:
> > > 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:
> > >> > 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
> > >> >
> > >> > Signed-off-by: Chaotian Jing <[email protected]>
> > >> > ---
> > >> > 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.