[PATCH V1] mmc: mediatek: correct the setting of recheck_sdio_irq

2020-11-18 Thread Yong Mao
From: yong mao 

correct the setting of recheck_sdio_irq for each mediatek SoC.

Signed-off-by: Yong Mao 
---
 drivers/mmc/host/mtk-sd.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index fc5ee5df91ad..d49e5ccfca9e 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -463,7 +463,7 @@ struct msdc_host {
 
 static const struct mtk_mmc_compatible mt8135_compat = {
.clk_div_bits = 8,
-   .recheck_sdio_irq = false,
+   .recheck_sdio_irq = true,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE,
.async_fifo = false,
@@ -502,7 +502,7 @@ static const struct mtk_mmc_compatible mt8183_compat = {
 
 static const struct mtk_mmc_compatible mt2701_compat = {
.clk_div_bits = 12,
-   .recheck_sdio_irq = false,
+   .recheck_sdio_irq = true,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE0,
.async_fifo = true,
@@ -528,7 +528,7 @@ static const struct mtk_mmc_compatible mt2712_compat = {
 
 static const struct mtk_mmc_compatible mt7622_compat = {
.clk_div_bits = 12,
-   .recheck_sdio_irq = false,
+   .recheck_sdio_irq = true,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE0,
.async_fifo = true,
@@ -541,7 +541,7 @@ static const struct mtk_mmc_compatible mt7622_compat = {
 
 static const struct mtk_mmc_compatible mt8516_compat = {
.clk_div_bits = 12,
-   .recheck_sdio_irq = false,
+   .recheck_sdio_irq = true,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE0,
.async_fifo = true,
@@ -552,7 +552,7 @@ static const struct mtk_mmc_compatible mt8516_compat = {
 
 static const struct mtk_mmc_compatible mt7620_compat = {
.clk_div_bits = 8,
-   .recheck_sdio_irq = false,
+   .recheck_sdio_irq = true,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE,
.async_fifo = false,
@@ -565,6 +565,7 @@ static const struct mtk_mmc_compatible mt7620_compat = {
 
 static const struct mtk_mmc_compatible mt6779_compat = {
.clk_div_bits = 12,
+   .recheck_sdio_irq = false,
.hs400_tune = false,
.pad_tune_reg = MSDC_PAD_TUNE0,
.async_fifo = true,
-- 
2.18.0



[PATCH v2] mmc: mediatek: enable SDIO IRQ low level trigger function

2019-08-28 Thread Yong Mao
In-Reply-To: 




[PATCH v2] mmc: mediatek: enable SDIO IRQ low level trigger function

2019-08-28 Thread Yong Mao
From: yong mao 

SDIO IRQ is not defaultly triggered by low level,
but by falling edge. It needs to set related register
to enable SDIO IRQ low level trigger function.
Otherwise the SDIO IRQ may be lost in some specail condition.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 33f4b63..585f0c7 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -192,6 +192,7 @@
 #define SDC_STS_CMDBUSY (0x1 << 1) /* RW */
 #define SDC_STS_SWR_COMPL   (0x1 << 31)/* RW */
 
+#define SDC_DAT1_IRQ_TRIGGER   (0x1 << 19) /* RW */
 /* SDC_ADV_CFG0 mask */
 #define SDC_RX_ENHANCE_EN  (0x1 << 20) /* RW */
 
@@ -1568,6 +1569,7 @@ static void msdc_init_hw(struct msdc_host *host)
 
/* Config SDIO device detect interrupt function */
sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+   sdr_set_bits(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER);
 
/* Configure to default data timeout */
sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
-- 
1.9.1



[PATCH] mmc: mediatek: enable SDIO IRQ low level trigger function

2019-08-28 Thread Yong Mao
From: yong mao 

SDIO IRQ is not defaultly triggered by low level,
but by falling edge. It needs to set related register
to enable SDIO IRQ low level trigger function.
Otherwise the SDIO IRQ may be lost in some specail condition.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 33f4b63..2444268 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -192,6 +192,7 @@
 #define SDC_STS_CMDBUSY (0x1 << 1) /* RW */
 #define SDC_STS_SWR_COMPL   (0x1 << 31)/* RW */
 
+#define SDC_DAT1_IRQ_TRIGGER   (0x1 << 20) /* RW */
 /* SDC_ADV_CFG0 mask */
 #define SDC_RX_ENHANCE_EN  (0x1 << 20) /* RW */
 
@@ -1568,6 +1569,7 @@ static void msdc_init_hw(struct msdc_host *host)
 
/* Config SDIO device detect interrupt function */
sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+   sdr_set_bits(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER);
 
/* Configure to default data timeout */
sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
-- 
1.9.1



[PATCH v2 2/3] ARM64: dts: mediatek: Enable mmc3 for supporting sdio feature

2017-04-18 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description of mmc3 for supporting sdio feature

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |   77 +++
 1 file changed, 77 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 1c3634f..fb8fa5c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -68,6 +68,14 @@
gpio = < 9 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+   sdio_fixed_3v3: regulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "3V3";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   gpio = < 85 GPIO_ACTIVE_HIGH>;
+   };
 };
 
  {
@@ -156,6 +164,25 @@
vqmmc-supply = <_vmc_reg>;
 };
 
+ {
+   status = "okay";
+   pinctrl-names = "default", "state_uhs";
+   pinctrl-0 = <_pins_default>;
+   pinctrl-1 = <_pins_uhs>;
+   bus-width = <4>;
+   max-frequency = <2>;
+   cap-sd-highspeed;
+   sd-uhs-sdr50;
+   sd-uhs-sdr104;
+   mediatek,clk-pad-delay = <5>;
+   keep-power-in-suspend;
+   enable-sdio-wakeup;
+   cap-sdio-irq;
+   vmmc-supply = <_fixed_3v3>;
+   vqmmc-supply = <_vgp3_reg>;
+   non-removable;
+};
+
  {
disp_pwm0_pins: disp_pwm0_pins {
pins1 {
@@ -261,6 +288,56 @@
};
};
 
+   mmc3_pins_default: mmc3default {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   bias-pull-down;
+   drive-strength = ;
+   };
+   };
+
+   mmc3_pins_uhs: mmc3 {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   drive-strength = ;
+   bias-pull-down = ;
+   };
+   };
+
usb_id_pins_float: usb_iddig_pull_up {
pins_iddig {
pinmux = ;
-- 
1.7.9.5



[PATCH v2 2/3] ARM64: dts: mediatek: Enable mmc3 for supporting sdio feature

2017-04-18 Thread Yong Mao
From: yong mao 

Add description of mmc3 for supporting sdio feature

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |   77 +++
 1 file changed, 77 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 1c3634f..fb8fa5c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -68,6 +68,14 @@
gpio = < 9 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+   sdio_fixed_3v3: regulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "3V3";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   gpio = < 85 GPIO_ACTIVE_HIGH>;
+   };
 };
 
  {
@@ -156,6 +164,25 @@
vqmmc-supply = <_vmc_reg>;
 };
 
+ {
+   status = "okay";
+   pinctrl-names = "default", "state_uhs";
+   pinctrl-0 = <_pins_default>;
+   pinctrl-1 = <_pins_uhs>;
+   bus-width = <4>;
+   max-frequency = <2>;
+   cap-sd-highspeed;
+   sd-uhs-sdr50;
+   sd-uhs-sdr104;
+   mediatek,clk-pad-delay = <5>;
+   keep-power-in-suspend;
+   enable-sdio-wakeup;
+   cap-sdio-irq;
+   vmmc-supply = <_fixed_3v3>;
+   vqmmc-supply = <_vgp3_reg>;
+   non-removable;
+};
+
  {
disp_pwm0_pins: disp_pwm0_pins {
pins1 {
@@ -261,6 +288,56 @@
};
};
 
+   mmc3_pins_default: mmc3default {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   bias-pull-down;
+   drive-strength = ;
+   };
+   };
+
+   mmc3_pins_uhs: mmc3 {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   drive-strength = ;
+   bias-pull-down = ;
+   };
+   };
+
usb_id_pins_float: usb_iddig_pull_up {
pins_iddig {
pinmux = ;
-- 
1.7.9.5



[PATCH v2 3/3] mmc: sdio: mediatek: Support SDIO feature

2017-04-18 Thread Yong Mao
From: yong mao <yong@mediatek.com>

1. Add irqlock to protect accessing the shared register
2. Implement enable_sdio_irq interface
3. Add msdc_recheck_sdio_irq mechanism to make sure all interrupts
   can be processed immediately

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  182 +++--
 1 file changed, 143 insertions(+), 39 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..fdae197 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -118,6 +118,7 @@
 #define MSDC_PS_CDSTS   (0x1 << 1) /* R  */
 #define MSDC_PS_CDDEBOUNCE  (0xf << 12)/* RW */
 #define MSDC_PS_DAT (0xff << 16)   /* R  */
+#define MSDC_PS_DATA1   (0x1 << 17)/* R  */
 #define MSDC_PS_CMD (0x1 << 24)/* R  */
 #define MSDC_PS_WP  (0x1 << 31)/* R  */
 
@@ -312,6 +313,7 @@ struct msdc_host {
int cmd_rsp;
 
spinlock_t lock;
+   spinlock_t irqlock;/* irq lock */
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -330,12 +332,14 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq;/* host interrupt */
+   bool irq_thread_alive;
 
struct clk *src_clk;/* msdc source clock */
struct clk *h_clk;  /* msdc h_clk */
u32 mclk;   /* mmc subsystem clock frequency */
u32 src_clk_freq;   /* source clock frequency */
u32 sclk;   /* SD/MS bus clock frequency */
+   bool clock_on;
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
@@ -343,6 +347,7 @@ struct msdc_host {
u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
bool hs400_cmd_resp_sel_rising;
 /* cmd response sample selection for HS400 */
+   u32 clk_pad_delay;
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -399,6 +404,7 @@ static void msdc_reset_hw(struct msdc_host *host)
 
 static void msdc_cmd_next(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd);
+static void msdc_recheck_sdio_irq(struct msdc_host *host);
 
 static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
@@ -525,6 +531,7 @@ static void msdc_gate_clock(struct msdc_host *host)
 {
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->h_clk);
+   host->clock_on = false;
 }
 
 static void msdc_ungate_clock(struct msdc_host *host)
@@ -533,6 +540,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
clk_prepare_enable(host->src_clk);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
+   host->clock_on = true;
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -541,6 +549,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 flags;
u32 div;
u32 sclk;
+   unsigned long irq_flags;
 
if (!hz) {
dev_dbg(host->dev, "set mclk to 0\n");
@@ -549,8 +558,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
return;
}
 
+   spin_lock_irqsave(>irqlock, irq_flags);
flags = readl(host->base + MSDC_INTEN);
sdr_clr_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
+
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
if (timing == MMC_TIMING_UHS_DDR50 ||
timing == MMC_TIMING_MMC_DDR52 ||
@@ -600,7 +612,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
host->timing = timing;
/* need because clk changed. */
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+   spin_lock_irqsave(>irqlock, irq_flags);
sdr_set_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
 
/*
 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
@@ -708,6 +723,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host 
*host,
 static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
struct mmc_command *cmd, struct mmc_data *data)
 {
+   unsigned long flags;
bool read;
 
WARN_ON(host->data);

[PATCH v2 3/3] mmc: sdio: mediatek: Support SDIO feature

2017-04-18 Thread Yong Mao
From: yong mao 

1. Add irqlock to protect accessing the shared register
2. Implement enable_sdio_irq interface
3. Add msdc_recheck_sdio_irq mechanism to make sure all interrupts
   can be processed immediately

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  182 +++--
 1 file changed, 143 insertions(+), 39 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..fdae197 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -118,6 +118,7 @@
 #define MSDC_PS_CDSTS   (0x1 << 1) /* R  */
 #define MSDC_PS_CDDEBOUNCE  (0xf << 12)/* RW */
 #define MSDC_PS_DAT (0xff << 16)   /* R  */
+#define MSDC_PS_DATA1   (0x1 << 17)/* R  */
 #define MSDC_PS_CMD (0x1 << 24)/* R  */
 #define MSDC_PS_WP  (0x1 << 31)/* R  */
 
@@ -312,6 +313,7 @@ struct msdc_host {
int cmd_rsp;
 
spinlock_t lock;
+   spinlock_t irqlock;/* irq lock */
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -330,12 +332,14 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq;/* host interrupt */
+   bool irq_thread_alive;
 
struct clk *src_clk;/* msdc source clock */
struct clk *h_clk;  /* msdc h_clk */
u32 mclk;   /* mmc subsystem clock frequency */
u32 src_clk_freq;   /* source clock frequency */
u32 sclk;   /* SD/MS bus clock frequency */
+   bool clock_on;
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
@@ -343,6 +347,7 @@ struct msdc_host {
u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
bool hs400_cmd_resp_sel_rising;
 /* cmd response sample selection for HS400 */
+   u32 clk_pad_delay;
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -399,6 +404,7 @@ static void msdc_reset_hw(struct msdc_host *host)
 
 static void msdc_cmd_next(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd);
+static void msdc_recheck_sdio_irq(struct msdc_host *host);
 
 static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
@@ -525,6 +531,7 @@ static void msdc_gate_clock(struct msdc_host *host)
 {
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->h_clk);
+   host->clock_on = false;
 }
 
 static void msdc_ungate_clock(struct msdc_host *host)
@@ -533,6 +540,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
clk_prepare_enable(host->src_clk);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
+   host->clock_on = true;
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -541,6 +549,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 flags;
u32 div;
u32 sclk;
+   unsigned long irq_flags;
 
if (!hz) {
dev_dbg(host->dev, "set mclk to 0\n");
@@ -549,8 +558,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
return;
}
 
+   spin_lock_irqsave(>irqlock, irq_flags);
flags = readl(host->base + MSDC_INTEN);
sdr_clr_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
+
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
if (timing == MMC_TIMING_UHS_DDR50 ||
timing == MMC_TIMING_MMC_DDR52 ||
@@ -600,7 +612,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
host->timing = timing;
/* need because clk changed. */
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+   spin_lock_irqsave(>irqlock, irq_flags);
sdr_set_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
 
/*
 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
@@ -708,6 +723,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host 
*host,
 static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
struct mmc_command *cmd, struct mmc_data *data)
 {
+   unsigned long flags;
bool read;
 
WARN_ON(host->data);
@@ -716,8 +732,12 @@ static void msdc_start_data(struct msdc_host *host, struct 
mmc_request *mrq

[RESEND v2] mmc: mediatek: Support SDIO feature

2017-04-18 Thread Yong Mao
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   2 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |  77 ++
 drivers/mmc/host/mtk-sd.c| 182 ++-
 3 files changed, 222 insertions(+), 39 deletions(-)

-- 
1.8.1.1.dirty



[RESEND v2] mmc: mediatek: Support SDIO feature

2017-04-18 Thread Yong Mao
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   2 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |  77 ++
 drivers/mmc/host/mtk-sd.c| 182 ++-
 3 files changed, 222 insertions(+), 39 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v2 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-04-18 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for mediatek,clk-pad-delay

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..fbb3fd6 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -30,6 +30,7 @@ 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,clk-pad-delay: clock pad delay setting
 
 Examples:
 mmc0: mmc@1123 {
@@ -50,4 +51,5 @@ mmc0: mmc@1123 {
mediatek,hs200-cmd-int-delay = <26>;
mediatek,hs400-cmd-int-delay = <14>;
mediatek,hs400-cmd-resp-sel-rising;
+   mediatek,clk-pad-delay = <5>;
 };
-- 
1.7.9.5



[PATCH v2 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-04-18 Thread Yong Mao
From: yong mao 

Add description for mediatek,clk-pad-delay

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..fbb3fd6 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -30,6 +30,7 @@ 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,clk-pad-delay: clock pad delay setting
 
 Examples:
 mmc0: mmc@1123 {
@@ -50,4 +51,5 @@ mmc0: mmc@1123 {
mediatek,hs200-cmd-int-delay = <26>;
mediatek,hs400-cmd-int-delay = <14>;
mediatek,hs400-cmd-resp-sel-rising;
+   mediatek,clk-pad-delay = <5>;
 };
-- 
1.7.9.5



[PATCH v5 2/3] ARM64: dts: mediatek: configure some fixed mmc parameters

2017-03-15 Thread Yong Mao
From: yong mao <yong@mediatek.com>

configure some fixed mmc parameters

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..1c3634f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mediatek,hs200-cmd-int-delay=<26>;
+   mediatek,hs400-cmd-int-delay=<14>;
+   mediatek,hs400-cmd-resp-sel-rising;
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v5 2/3] ARM64: dts: mediatek: configure some fixed mmc parameters

2017-03-15 Thread Yong Mao
From: yong mao 

configure some fixed mmc parameters

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..1c3634f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mediatek,hs200-cmd-int-delay=<26>;
+   mediatek,hs400-cmd-int-delay=<14>;
+   mediatek,hs400-cmd-resp-sel-rising;
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v5 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-15 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for mediatek,hs200-cmd-int-delay
Add description for mediatek,hs400-cmd-int-delay
Add description for mediatek,hs400-cmd-resp-sel-rising

Signed-off-by: Yong Mao <yong@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..4182ea3 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,15 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- 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.
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +47,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mediatek,hs200-cmd-int-delay = <26>;
+   mediatek,hs400-cmd-int-delay = <14>;
+   mediatek,hs400-cmd-resp-sel-rising;
 };
-- 
1.7.9.5



[PATCH v5 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-15 Thread Yong Mao
From: yong mao 

Add description for mediatek,hs200-cmd-int-delay
Add description for mediatek,hs400-cmd-int-delay
Add description for mediatek,hs400-cmd-resp-sel-rising

Signed-off-by: Yong Mao 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..4182ea3 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,15 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- 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.
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +47,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mediatek,hs200-cmd-int-delay = <26>;
+   mediatek,hs400-cmd-int-delay = <14>;
+   mediatek,hs400-cmd-resp-sel-rising;
 };
-- 
1.7.9.5



[PATCH v5 0/3] Use data tune for CMD line tune

2017-03-15 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  ARM64: dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  12 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 168 ---
 3 files changed, 167 insertions(+), 16 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v5 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-03-15 Thread Yong Mao
From: yong mao <yong@mediatek.com>

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  168 -
 1 file changed, 152 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..07f3236 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,10 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   bool hs400_cmd_resp_sel_rising;
+/* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +612,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1320,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1343,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
 
sdr_clr_bits(host-&g

[PATCH v5 0/3] Use data tune for CMD line tune

2017-03-15 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  ARM64: dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  12 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 168 ---
 3 files changed, 167 insertions(+), 16 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v5 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-03-15 Thread Yong Mao
From: yong mao 

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  168 -
 1 file changed, 152 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..07f3236 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,10 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   bool hs400_cmd_resp_sel_rising;
+/* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +612,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1320,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1343,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
 
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
for (i = 0 ; i < PAD_DE

Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-07 Thread Yong Mao
On Fri, 2017-03-03 at 11:49 +0800, Yong Mao wrote:
> On Fri, 2017-02-24 at 16:47 -0600, Rob Herring wrote:
> > On Fri, Feb 24, 2017 at 3:59 AM, Yong Mao <yong@mediatek.com> wrote:
> > > Dear Rob,
> > >
> > > Could you please help to make comments for this patch?
> > > Thanks.
> > 
> > I already did comment. It's still wrong as Ulf commented. So fix and
> > send a new version. It has to go to the DT list if you want to be in
> > my queue.
> > 
> > Rob
> 
> After reviewing the history, We guess your mentioned Ulf's comments is as 
> below.
>   
> "> +- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
> > + The value is an integer from 0 to 31
> 
> Please change to:
> 
> mediatek,hs200-cmd-delay
> 
> ... and if there is a unit, like ns or us, please add that a suffix.
> 
> > +- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
> > + The value is an integer from 0 to 31
> 
> mediatek,hs400-cmd-delay and add unit if applicable.
> 
> > +- mtk-hs400-cmd-resp-sel: HS400 command response sample selection
> > + The value is an integer from 0 to 1
> 
> mediatek,hs400-cmd-resp-sel
> 
> And make it a boolean value instead!"
> 
> ==> We already fix this comment in v4. 
> We use "mediatek,hs200-cmd-int-delay" to replace "mtk-hs200-cmd-int-delay", 
> but not use "mediatek,hs200-cmd-delay". This is because "-int-" here means 
> internal.
> We should not drop it.
> 
> And this field does not have unit, it only have total 32 stages.
> We also change the description in v4.
> 
> For comment about "mtk-hs400-cmd-resp-sel", we also make it a boolean value 
> in v4.
> And re-name it as "mediatek,hs400-cmd-resp-rising".
> 
> Please help to point out where we need to modify.
> Thanks.
> 
> 

Please help to point out a bright way for this patch.
We are anxiously waiting for your response.

Best Regards,
Yong Mao.




Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-07 Thread Yong Mao
On Fri, 2017-03-03 at 11:49 +0800, Yong Mao wrote:
> On Fri, 2017-02-24 at 16:47 -0600, Rob Herring wrote:
> > On Fri, Feb 24, 2017 at 3:59 AM, Yong Mao  wrote:
> > > Dear Rob,
> > >
> > > Could you please help to make comments for this patch?
> > > Thanks.
> > 
> > I already did comment. It's still wrong as Ulf commented. So fix and
> > send a new version. It has to go to the DT list if you want to be in
> > my queue.
> > 
> > Rob
> 
> After reviewing the history, We guess your mentioned Ulf's comments is as 
> below.
>   
> "> +- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
> > + The value is an integer from 0 to 31
> 
> Please change to:
> 
> mediatek,hs200-cmd-delay
> 
> ... and if there is a unit, like ns or us, please add that a suffix.
> 
> > +- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
> > + The value is an integer from 0 to 31
> 
> mediatek,hs400-cmd-delay and add unit if applicable.
> 
> > +- mtk-hs400-cmd-resp-sel: HS400 command response sample selection
> > + The value is an integer from 0 to 1
> 
> mediatek,hs400-cmd-resp-sel
> 
> And make it a boolean value instead!"
> 
> ==> We already fix this comment in v4. 
> We use "mediatek,hs200-cmd-int-delay" to replace "mtk-hs200-cmd-int-delay", 
> but not use "mediatek,hs200-cmd-delay". This is because "-int-" here means 
> internal.
> We should not drop it.
> 
> And this field does not have unit, it only have total 32 stages.
> We also change the description in v4.
> 
> For comment about "mtk-hs400-cmd-resp-sel", we also make it a boolean value 
> in v4.
> And re-name it as "mediatek,hs400-cmd-resp-rising".
> 
> Please help to point out where we need to modify.
> Thanks.
> 
> 

Please help to point out a bright way for this patch.
We are anxiously waiting for your response.

Best Regards,
Yong Mao.




[PATCH v2] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
yong mao (1):
  mmc: mediatek: Fixed bug where clock frequency could be set wrong

 drivers/mmc/host/mtk-sd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
1.8.1.1.dirty




[PATCH v2] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
yong mao (1):
  mmc: mediatek: Fixed bug where clock frequency could be set wrong

 drivers/mmc/host/mtk-sd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
1.8.1.1.dirty




[PATCH] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
From: yong mao <yong@mediatek.com>

This patch can fix two issues:

Issue 1:
In previous code, div may be overflow when setting clock frequency
as f_min. We can use DIV_ROUND_UP to fix this boundary related
issue.

Issue 2:
In previous code, we can not set the correct clock frequency when
div equals 0xff.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..3ad5228 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -591,7 +591,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
}
}
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-   (mode << 8) | (div % 0xff));
+ (mode << 8) | div);
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
@@ -1692,7 +1692,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
host->src_clk_freq = clk_get_rate(host->src_clk);
/* Set host parameters to mmc */
mmc->ops = _msdc_ops;
-   mmc->f_min = host->src_clk_freq / (4 * 255);
+   mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
 
mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
/* MMC core transfer sizes tunable parameters */
-- 
1.7.9.5



[PATCH] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
From: yong mao 

This patch can fix two issues:

Issue 1:
In previous code, div may be overflow when setting clock frequency
as f_min. We can use DIV_ROUND_UP to fix this boundary related
issue.

Issue 2:
In previous code, we can not set the correct clock frequency when
div equals 0xff.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..3ad5228 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -591,7 +591,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
}
}
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-   (mode << 8) | (div % 0xff));
+ (mode << 8) | div);
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
@@ -1692,7 +1692,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
host->src_clk_freq = clk_get_rate(host->src_clk);
/* Set host parameters to mmc */
mmc->ops = _msdc_ops;
-   mmc->f_min = host->src_clk_freq / (4 * 255);
+   mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
 
mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
/* MMC core transfer sizes tunable parameters */
-- 
1.7.9.5



Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
On Thu, 2017-03-02 at 20:20 +0800, Daniel Kurtz wrote:
> On Wed, Mar 1, 2017 at 5:56 PM, Yong Mao <yong@mediatek.com> wrote:
> > On Tue, 2017-02-28 at 14:56 +0800, Daniel Kurtz wrote:
> >> On Fri, Feb 24, 2017 at 5:38 PM, Yong Mao <yong@mediatek.com> wrote:
> >> > From:   Yong Mao <yong@mediatek.com>
> >> > To: Daniel Kurtz <djku...@chromium.org>
> >> > Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock 
> >> > frequency
> >> > could be set wrong
> >> > Date:   Fri, 24 Feb 2017 17:33:37 +0800
> >> >
> >> >
> >> > On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> >> >> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao <yong@mediatek.com>
> >> > wrote:
> >> >> >
> >> >> > From: yong mao <yong@mediatek.com>
> >> >> >
> >> >> > This patch can fix two issues:
> >> >> >
> >> >> > Issue 1:
> >> >> > The maximum value of clock divider is 0xff.
> >> >> > Because the type of div is u32, div may be larger than max_div.
> >> >> > In this case, we should use max_div to set the clock frequency.
> >> >> >
> >> >> > Issue 2:
> >> >> > In previous code, we can not set the correct clock frequency when
> >> >> > div equals 0xff.
> >> >> >
> >> >> > Signed-off-by: Yong Mao <yong@mediatek.com>
> >> >> > Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
> >> >> > ---
> >> >> >  drivers/mmc/host/mtk-sd.c |   13 -
> >> >> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >> >> >
> >> >> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> >> >> > index 07f3236..3174445 100644
> >> >> > --- a/drivers/mmc/host/mtk-sd.c
> >> >> > +++ b/drivers/mmc/host/mtk-sd.c
> >> >> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
> >> > *host, unsigned char timing, u32 hz)
> >> >> > u32 mode;
> >> >> > u32 flags;
> >> >> > u32 div;
> >> >> > +   u32 max_div;
> >> >>
> >> >> There's really no need for this variable.  Just use 0xff below.
> >> > For all of our IC, max_div is not a constant.
> >> > We will upstream another patch which max_div will get the different
> >> > value depending on the IC.
> >> > Therefore, we keep the max_div as a variable here.
> >>
> >> Please add the variable in the patch that uses it as a variable.
> >>
> >> >
> >> >>
> >> >> > u32 sclk;
> >> >> >
> >> >> > if (!hz) {
> >> >> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
> >> > *host, unsigned char timing, u32 hz)
> >> >> > sclk = (host->src_clk_freq >> 2) / div;
> >> >> > }
> >> >> > }
> >> >> > +
> >> >> > +   /**
> >> >> > +* The maximum value of div is 0xff.
> >> >> > +* Check if the div is larger than max_div.
> >> >> > +*/
> >> >> > +   max_div = 0xff;
> >> >> > +   if (div > max_div) {
> >> >> > +   div = max_div;
> >> >> > +   sclk = (host->src_clk_freq >> 2) / div;
> >> >> > +   }
> >> >> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
> >> > MSDC_CFG_CKDIV,
> >> >> > -   (mode << 8) | (div % 0xff));
> >> >> > + (mode << 8) | div);
> >> >>
> >> >> Hmm, I don't know much about this sub-system, but should we even be
> >> >> allowing requests to set a frequency that we can't actually achieve
> >> >> with the divider?
> >> >>
> >> >
> >> > No. We can not get a frequency that we can't actually achieve with the
> >> > divider. This patch is to solve this kind of issue.
> >>
> >> Sorry, I am trying to understand why we need this patch.
> >>

Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-03 Thread Yong Mao
On Thu, 2017-03-02 at 20:20 +0800, Daniel Kurtz wrote:
> On Wed, Mar 1, 2017 at 5:56 PM, Yong Mao  wrote:
> > On Tue, 2017-02-28 at 14:56 +0800, Daniel Kurtz wrote:
> >> On Fri, Feb 24, 2017 at 5:38 PM, Yong Mao  wrote:
> >> > From:   Yong Mao 
> >> > To: Daniel Kurtz 
> >> > Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock 
> >> > frequency
> >> > could be set wrong
> >> > Date:   Fri, 24 Feb 2017 17:33:37 +0800
> >> >
> >> >
> >> > On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> >> >> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao 
> >> > wrote:
> >> >> >
> >> >> > From: yong mao 
> >> >> >
> >> >> > This patch can fix two issues:
> >> >> >
> >> >> > Issue 1:
> >> >> > The maximum value of clock divider is 0xff.
> >> >> > Because the type of div is u32, div may be larger than max_div.
> >> >> > In this case, we should use max_div to set the clock frequency.
> >> >> >
> >> >> > Issue 2:
> >> >> > In previous code, we can not set the correct clock frequency when
> >> >> > div equals 0xff.
> >> >> >
> >> >> > Signed-off-by: Yong Mao 
> >> >> > Signed-off-by: Chaotian Jing 
> >> >> > ---
> >> >> >  drivers/mmc/host/mtk-sd.c |   13 -
> >> >> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >> >> >
> >> >> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> >> >> > index 07f3236..3174445 100644
> >> >> > --- a/drivers/mmc/host/mtk-sd.c
> >> >> > +++ b/drivers/mmc/host/mtk-sd.c
> >> >> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
> >> > *host, unsigned char timing, u32 hz)
> >> >> > u32 mode;
> >> >> > u32 flags;
> >> >> > u32 div;
> >> >> > +   u32 max_div;
> >> >>
> >> >> There's really no need for this variable.  Just use 0xff below.
> >> > For all of our IC, max_div is not a constant.
> >> > We will upstream another patch which max_div will get the different
> >> > value depending on the IC.
> >> > Therefore, we keep the max_div as a variable here.
> >>
> >> Please add the variable in the patch that uses it as a variable.
> >>
> >> >
> >> >>
> >> >> > u32 sclk;
> >> >> >
> >> >> > if (!hz) {
> >> >> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
> >> > *host, unsigned char timing, u32 hz)
> >> >> > sclk = (host->src_clk_freq >> 2) / div;
> >> >> > }
> >> >> > }
> >> >> > +
> >> >> > +   /**
> >> >> > +* The maximum value of div is 0xff.
> >> >> > +* Check if the div is larger than max_div.
> >> >> > +*/
> >> >> > +   max_div = 0xff;
> >> >> > +   if (div > max_div) {
> >> >> > +   div = max_div;
> >> >> > +   sclk = (host->src_clk_freq >> 2) / div;
> >> >> > +   }
> >> >> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
> >> > MSDC_CFG_CKDIV,
> >> >> > -   (mode << 8) | (div % 0xff));
> >> >> > + (mode << 8) | div);
> >> >>
> >> >> Hmm, I don't know much about this sub-system, but should we even be
> >> >> allowing requests to set a frequency that we can't actually achieve
> >> >> with the divider?
> >> >>
> >> >
> >> > No. We can not get a frequency that we can't actually achieve with the
> >> > divider. This patch is to solve this kind of issue.
> >>
> >> Sorry, I am trying to understand why we need this patch.
> >>
> >> AFAICT, it looks like sometimes msdc_set_mclk() is being called with
> >> hz that cannot be generated by your hardware.  In particular,
> >> sometimes the original code computes "div > 255&

Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-02 Thread Yong Mao
On Fri, 2017-02-24 at 16:47 -0600, Rob Herring wrote:
> On Fri, Feb 24, 2017 at 3:59 AM, Yong Mao <yong@mediatek.com> wrote:
> > Dear Rob,
> >
> > Could you please help to make comments for this patch?
> > Thanks.
> 
> I already did comment. It's still wrong as Ulf commented. So fix and
> send a new version. It has to go to the DT list if you want to be in
> my queue.
> 
> Rob

After reviewing the history, We guess your mentioned Ulf's comments is as below.
  
"> +- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
> + The value is an integer from 0 to 31

Please change to:

mediatek,hs200-cmd-delay

... and if there is a unit, like ns or us, please add that a suffix.

> +- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
> + The value is an integer from 0 to 31

mediatek,hs400-cmd-delay and add unit if applicable.

> +- mtk-hs400-cmd-resp-sel: HS400 command response sample selection
> + The value is an integer from 0 to 1

mediatek,hs400-cmd-resp-sel

And make it a boolean value instead!"

==> We already fix this comment in v4. 
We use "mediatek,hs200-cmd-int-delay" to replace "mtk-hs200-cmd-int-delay", 
but not use "mediatek,hs200-cmd-delay". This is because "-int-" here means 
internal.
We should not drop it.

And this field does not have unit, it only have total 32 stages.
We also change the description in v4.

For comment about "mtk-hs400-cmd-resp-sel", we also make it a boolean value in 
v4.
And re-name it as "mediatek,hs400-cmd-resp-rising".

Please help to point out where we need to modify.
Thanks.





Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-03-02 Thread Yong Mao
On Fri, 2017-02-24 at 16:47 -0600, Rob Herring wrote:
> On Fri, Feb 24, 2017 at 3:59 AM, Yong Mao  wrote:
> > Dear Rob,
> >
> > Could you please help to make comments for this patch?
> > Thanks.
> 
> I already did comment. It's still wrong as Ulf commented. So fix and
> send a new version. It has to go to the DT list if you want to be in
> my queue.
> 
> Rob

After reviewing the history, We guess your mentioned Ulf's comments is as below.
  
"> +- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
> + The value is an integer from 0 to 31

Please change to:

mediatek,hs200-cmd-delay

... and if there is a unit, like ns or us, please add that a suffix.

> +- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
> + The value is an integer from 0 to 31

mediatek,hs400-cmd-delay and add unit if applicable.

> +- mtk-hs400-cmd-resp-sel: HS400 command response sample selection
> + The value is an integer from 0 to 1

mediatek,hs400-cmd-resp-sel

And make it a boolean value instead!"

==> We already fix this comment in v4. 
We use "mediatek,hs200-cmd-int-delay" to replace "mtk-hs200-cmd-int-delay", 
but not use "mediatek,hs200-cmd-delay". This is because "-int-" here means 
internal.
We should not drop it.

And this field does not have unit, it only have total 32 stages.
We also change the description in v4.

For comment about "mtk-hs400-cmd-resp-sel", we also make it a boolean value in 
v4.
And re-name it as "mediatek,hs400-cmd-resp-rising".

Please help to point out where we need to modify.
Thanks.





Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-01 Thread Yong Mao
On Tue, 2017-02-28 at 14:56 +0800, Daniel Kurtz wrote:
> On Fri, Feb 24, 2017 at 5:38 PM, Yong Mao <yong@mediatek.com> wrote:
> > From:   Yong Mao <yong@mediatek.com>
> > To: Daniel Kurtz <djku...@chromium.org>
> > Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock 
> > frequency
> > could be set wrong
> > Date:   Fri, 24 Feb 2017 17:33:37 +0800
> >
> >
> > On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> >> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao <yong@mediatek.com>
> > wrote:
> >> >
> >> > From: yong mao <yong@mediatek.com>
> >> >
> >> > This patch can fix two issues:
> >> >
> >> > Issue 1:
> >> > The maximum value of clock divider is 0xff.
> >> > Because the type of div is u32, div may be larger than max_div.
> >> > In this case, we should use max_div to set the clock frequency.
> >> >
> >> > Issue 2:
> >> > In previous code, we can not set the correct clock frequency when
> >> > div equals 0xff.
> >> >
> >> > Signed-off-by: Yong Mao <yong@mediatek.com>
> >> > Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
> >> > ---
> >> >  drivers/mmc/host/mtk-sd.c |   13 -
> >> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> >> > index 07f3236..3174445 100644
> >> > --- a/drivers/mmc/host/mtk-sd.c
> >> > +++ b/drivers/mmc/host/mtk-sd.c
> >> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
> > *host, unsigned char timing, u32 hz)
> >> > u32 mode;
> >> > u32 flags;
> >> > u32 div;
> >> > +   u32 max_div;
> >>
> >> There's really no need for this variable.  Just use 0xff below.
> > For all of our IC, max_div is not a constant.
> > We will upstream another patch which max_div will get the different
> > value depending on the IC.
> > Therefore, we keep the max_div as a variable here.
> 
> Please add the variable in the patch that uses it as a variable.
> 
> >
> >>
> >> > u32 sclk;
> >> >
> >> > if (!hz) {
> >> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
> > *host, unsigned char timing, u32 hz)
> >> > sclk = (host->src_clk_freq >> 2) / div;
> >> > }
> >> > }
> >> > +
> >> > +   /**
> >> > +* The maximum value of div is 0xff.
> >> > +* Check if the div is larger than max_div.
> >> > +*/
> >> > +   max_div = 0xff;
> >> > +   if (div > max_div) {
> >> > +   div = max_div;
> >> > +   sclk = (host->src_clk_freq >> 2) / div;
> >> > +   }
> >> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
> > MSDC_CFG_CKDIV,
> >> > -   (mode << 8) | (div % 0xff));
> >> > + (mode << 8) | div);
> >>
> >> Hmm, I don't know much about this sub-system, but should we even be
> >> allowing requests to set a frequency that we can't actually achieve
> >> with the divider?
> >>
> >
> > No. We can not get a frequency that we can't actually achieve with the
> > divider. This patch is to solve this kind of issue.
> 
> Sorry, I am trying to understand why we need this patch.
> 
> AFAICT, it looks like sometimes msdc_set_mclk() is being called with
> hz that cannot be generated by your hardware.  In particular,
> sometimes the original code computes "div > 255".
> To work around this problem, this patch just caps the divider value to
> 255, which is the maximum divider provided by the hardware.  However,
> presumably this means that in this case we won't actually be
> generating the requested hz value.
> 
> So, can you please explain in what exact scenario this patch is
> required, and justify why it is ok to generate a clock other than the
> requested in this case?
> 
> -Dan
> 

This issue is hidden deeply. It is a boundary related issue.
Let me take the real value to explain how this issue occurs.

1. mmc->f_min = host->src_clk_freq / (4 * 255);
   mmc->f_min = 4 / (4 * 255) = 392156;
2. mmc core 

Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-03-01 Thread Yong Mao
On Tue, 2017-02-28 at 14:56 +0800, Daniel Kurtz wrote:
> On Fri, Feb 24, 2017 at 5:38 PM, Yong Mao  wrote:
> > From:   Yong Mao 
> > To: Daniel Kurtz 
> > Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock 
> > frequency
> > could be set wrong
> > Date:   Fri, 24 Feb 2017 17:33:37 +0800
> >
> >
> > On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> >> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao 
> > wrote:
> >> >
> >> > From: yong mao 
> >> >
> >> > This patch can fix two issues:
> >> >
> >> > Issue 1:
> >> > The maximum value of clock divider is 0xff.
> >> > Because the type of div is u32, div may be larger than max_div.
> >> > In this case, we should use max_div to set the clock frequency.
> >> >
> >> > Issue 2:
> >> > In previous code, we can not set the correct clock frequency when
> >> > div equals 0xff.
> >> >
> >> > Signed-off-by: Yong Mao 
> >> > Signed-off-by: Chaotian Jing 
> >> > ---
> >> >  drivers/mmc/host/mtk-sd.c |   13 -
> >> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> >> > index 07f3236..3174445 100644
> >> > --- a/drivers/mmc/host/mtk-sd.c
> >> > +++ b/drivers/mmc/host/mtk-sd.c
> >> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
> > *host, unsigned char timing, u32 hz)
> >> > u32 mode;
> >> > u32 flags;
> >> > u32 div;
> >> > +   u32 max_div;
> >>
> >> There's really no need for this variable.  Just use 0xff below.
> > For all of our IC, max_div is not a constant.
> > We will upstream another patch which max_div will get the different
> > value depending on the IC.
> > Therefore, we keep the max_div as a variable here.
> 
> Please add the variable in the patch that uses it as a variable.
> 
> >
> >>
> >> > u32 sclk;
> >> >
> >> > if (!hz) {
> >> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
> > *host, unsigned char timing, u32 hz)
> >> > sclk = (host->src_clk_freq >> 2) / div;
> >> > }
> >> > }
> >> > +
> >> > +   /**
> >> > +* The maximum value of div is 0xff.
> >> > +* Check if the div is larger than max_div.
> >> > +*/
> >> > +   max_div = 0xff;
> >> > +   if (div > max_div) {
> >> > +   div = max_div;
> >> > +   sclk = (host->src_clk_freq >> 2) / div;
> >> > +   }
> >> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
> > MSDC_CFG_CKDIV,
> >> > -   (mode << 8) | (div % 0xff));
> >> > + (mode << 8) | div);
> >>
> >> Hmm, I don't know much about this sub-system, but should we even be
> >> allowing requests to set a frequency that we can't actually achieve
> >> with the divider?
> >>
> >
> > No. We can not get a frequency that we can't actually achieve with the
> > divider. This patch is to solve this kind of issue.
> 
> Sorry, I am trying to understand why we need this patch.
> 
> AFAICT, it looks like sometimes msdc_set_mclk() is being called with
> hz that cannot be generated by your hardware.  In particular,
> sometimes the original code computes "div > 255".
> To work around this problem, this patch just caps the divider value to
> 255, which is the maximum divider provided by the hardware.  However,
> presumably this means that in this case we won't actually be
> generating the requested hz value.
> 
> So, can you please explain in what exact scenario this patch is
> required, and justify why it is ok to generate a clock other than the
> requested in this case?
> 
> -Dan
> 

This issue is hidden deeply. It is a boundary related issue.
Let me take the real value to explain how this issue occurs.

1. mmc->f_min = host->src_clk_freq / (4 * 255);
   mmc->f_min = 4 / (4 * 255) = 392156;
2. mmc core tries to initialize emmc by using 40hz.
   If the first try failed, it will retry by using max(30hz,
mmc->f_min)= 392156hz
3. msdc_set_mclk will be invoked by mmc core to set the clock.
   and then followi

Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-02-24 Thread Yong Mao
Dear Rob,

Could you please help to make comments for this patch?
Thanks.

On Tue, 2017-01-24 at 09:02 +0100, Ulf Hansson wrote:
> +Rob, devicetree
> 
> On 21 January 2017 at 09:55, Yong Mao <yong@mediatek.com> wrote:
> > From: yong mao <yong@mediatek.com>
> >
> > Add description for mediatek,hs200-cmd-int-delay
> > Add description for mediatek,hs400-cmd-int-delay
> > Add description for mediatek,hs400-cmd-resp-sel-rising
> >
> > Signed-off-by: Yong Mao <yong@mediatek.com>
> 
> You need an ack from a DT maintainer for this. I have added Rob and
> the devicetree list on cc.
> 
> Kind regards
> Uffe
> 
> > ---
> >  Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
> > b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > index 0120c7f..4182ea3 100644
> > --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > @@ -21,6 +21,15 @@ Optional properties:
> >  - assigned-clocks: PLL of the source clock
> >  - assigned-clock-parents: parent of source clock, used for HS400 mode to 
> > get 400Mhz source clock
> >  - hs400-ds-delay: HS400 DS delay setting
> > +- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
> > +   This field has total 32 stages.
> > +   The value is an integer from 0 to 31.
> > +- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
> > +   This field has total 32 stages.
> > +   The value is an integer from 0 to 31.
> > +- 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.
> >
> >  Examples:
> >  mmc0: mmc@1123 {
> > @@ -38,4 +47,7 @@ mmc0: mmc@1123 {
> > assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
> > assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
> > hs400-ds-delay = <0x14015>;
> > +   mediatek,hs200-cmd-int-delay = <26>;
> > +   mediatek,hs400-cmd-int-delay = <14>;
> > +   mediatek,hs400-cmd-resp-sel-rising;
> >  };
> > --
> > 1.7.9.5
> >




Re: [PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-02-24 Thread Yong Mao
Dear Rob,

Could you please help to make comments for this patch?
Thanks.

On Tue, 2017-01-24 at 09:02 +0100, Ulf Hansson wrote:
> +Rob, devicetree
> 
> On 21 January 2017 at 09:55, Yong Mao  wrote:
> > From: yong mao 
> >
> > Add description for mediatek,hs200-cmd-int-delay
> > Add description for mediatek,hs400-cmd-int-delay
> > Add description for mediatek,hs400-cmd-resp-sel-rising
> >
> > Signed-off-by: Yong Mao 
> 
> You need an ack from a DT maintainer for this. I have added Rob and
> the devicetree list on cc.
> 
> Kind regards
> Uffe
> 
> > ---
> >  Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
> > b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > index 0120c7f..4182ea3 100644
> > --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
> > @@ -21,6 +21,15 @@ Optional properties:
> >  - assigned-clocks: PLL of the source clock
> >  - assigned-clock-parents: parent of source clock, used for HS400 mode to 
> > get 400Mhz source clock
> >  - hs400-ds-delay: HS400 DS delay setting
> > +- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
> > +   This field has total 32 stages.
> > +   The value is an integer from 0 to 31.
> > +- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
> > +   This field has total 32 stages.
> > +   The value is an integer from 0 to 31.
> > +- 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.
> >
> >  Examples:
> >  mmc0: mmc@1123 {
> > @@ -38,4 +47,7 @@ mmc0: mmc@1123 {
> > assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
> > assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
> > hs400-ds-delay = <0x14015>;
> > +   mediatek,hs200-cmd-int-delay = <26>;
> > +   mediatek,hs400-cmd-int-delay = <14>;
> > +   mediatek,hs400-cmd-resp-sel-rising;
> >  };
> > --
> > 1.7.9.5
> >




Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
From:   Yong Mao <yong@mediatek.com>
To: Daniel Kurtz <djku...@chromium.org>
Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency
could be set wrong
Date:   Fri, 24 Feb 2017 17:33:37 +0800


On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao <yong@mediatek.com>
wrote:
> >
> > From: yong mao <yong@mediatek.com>
> >
> > This patch can fix two issues:
> >
> > Issue 1:
> > The maximum value of clock divider is 0xff.
> > Because the type of div is u32, div may be larger than max_div.
> > In this case, we should use max_div to set the clock frequency.
> >
> > Issue 2:
> > In previous code, we can not set the correct clock frequency when
> > div equals 0xff.
> >
> > Signed-off-by: Yong Mao <yong@mediatek.com>
> > Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
> > ---
> >  drivers/mmc/host/mtk-sd.c |   13 -
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 07f3236..3174445 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
*host, unsigned char timing, u32 hz)
> > u32 mode;
> > u32 flags;
> > u32 div;
> > +   u32 max_div;
> 
> There's really no need for this variable.  Just use 0xff below.
For all of our IC, max_div is not a constant.
We will upstream another patch which max_div will get the different
value depending on the IC.
Therefore, we keep the max_div as a variable here.

> 
> > u32 sclk;
> >
> > if (!hz) {
> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
*host, unsigned char timing, u32 hz)
> > sclk = (host->src_clk_freq >> 2) / div;
> > }
> > }
> > +
> > +   /**
> > +* The maximum value of div is 0xff.
> > +* Check if the div is larger than max_div.
> > +*/
> > +   max_div = 0xff;
> > +   if (div > max_div) {
> > +   div = max_div;
> > +   sclk = (host->src_clk_freq >> 2) / div;
> > +   }
> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
MSDC_CFG_CKDIV,
> > -   (mode << 8) | (div % 0xff));
> > + (mode << 8) | div);
> 
> Hmm, I don't know much about this sub-system, but should we even be
> allowing requests to set a frequency that we can't actually achieve
> with the divider?
> 

No. We can not get a frequency that we can't actually achieve with the
divider. This patch is to solve this kind of issue.


> > sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
> > while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
> > cpu_relax();
> > --
> > 1.7.9.5
> >
> >
> > ___
> > Linux-mediatek mailing list
> > linux-media...@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek





Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
From:   Yong Mao 
To: Daniel Kurtz 
Subject:Re: [PATCH v1] mmc: mediatek: Fixed bug where clock frequency
could be set wrong
Date:   Fri, 24 Feb 2017 17:33:37 +0800


On Fri, 2017-02-24 at 17:52 +0900, Daniel Kurtz wrote:
> On Fri, Feb 24, 2017 at 5:22 PM, Yong Mao 
wrote:
> >
> > From: yong mao 
> >
> > This patch can fix two issues:
> >
> > Issue 1:
> > The maximum value of clock divider is 0xff.
> > Because the type of div is u32, div may be larger than max_div.
> > In this case, we should use max_div to set the clock frequency.
> >
> > Issue 2:
> > In previous code, we can not set the correct clock frequency when
> > div equals 0xff.
> >
> > Signed-off-by: Yong Mao 
> > Signed-off-by: Chaotian Jing 
> > ---
> >  drivers/mmc/host/mtk-sd.c |   13 -
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 07f3236..3174445 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host
*host, unsigned char timing, u32 hz)
> > u32 mode;
> > u32 flags;
> > u32 div;
> > +   u32 max_div;
> 
> There's really no need for this variable.  Just use 0xff below.
For all of our IC, max_div is not a constant.
We will upstream another patch which max_div will get the different
value depending on the IC.
Therefore, we keep the max_div as a variable here.

> 
> > u32 sclk;
> >
> > if (!hz) {
> > @@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host
*host, unsigned char timing, u32 hz)
> > sclk = (host->src_clk_freq >> 2) / div;
> > }
> > }
> > +
> > +   /**
> > +* The maximum value of div is 0xff.
> > +* Check if the div is larger than max_div.
> > +*/
> > +   max_div = 0xff;
> > +   if (div > max_div) {
> > +   div = max_div;
> > +   sclk = (host->src_clk_freq >> 2) / div;
> > +   }
> > sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD |
MSDC_CFG_CKDIV,
> > -   (mode << 8) | (div % 0xff));
> > + (mode << 8) | div);
> 
> Hmm, I don't know much about this sub-system, but should we even be
> allowing requests to set a frequency that we can't actually achieve
> with the divider?
> 

No. We can not get a frequency that we can't actually achieve with the
divider. This patch is to solve this kind of issue.


> > sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
> > while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
> > cpu_relax();
> > --
> > 1.7.9.5
> >
> >
> > ___
> > Linux-mediatek mailing list
> > linux-media...@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek





[PATCH v1] Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
yong mao (1):
  mmc: mediatek: Fixed bug where clock frequency could be set wrong

 drivers/mmc/host/mtk-sd.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

-- 
1.8.1.1.dirty



[PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
From: yong mao <yong@mediatek.com>

This patch can fix two issues:

Issue 1:
The maximum value of clock divider is 0xff.
Because the type of div is u32, div may be larger than max_div.
In this case, we should use max_div to set the clock frequency.

Issue 2:
In previous code, we can not set the correct clock frequency when
div equals 0xff.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |   13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..3174445 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 mode;
u32 flags;
u32 div;
+   u32 max_div;
u32 sclk;
 
if (!hz) {
@@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
sclk = (host->src_clk_freq >> 2) / div;
}
}
+
+   /**
+* The maximum value of div is 0xff.
+* Check if the div is larger than max_div.
+*/
+   max_div = 0xff;
+   if (div > max_div) {
+   div = max_div;
+   sclk = (host->src_clk_freq >> 2) / div;
+   }
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-   (mode << 8) | (div % 0xff));
+ (mode << 8) | div);
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
-- 
1.7.9.5



[PATCH v1] Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
yong mao (1):
  mmc: mediatek: Fixed bug where clock frequency could be set wrong

 drivers/mmc/host/mtk-sd.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

-- 
1.8.1.1.dirty



[PATCH v1] mmc: mediatek: Fixed bug where clock frequency could be set wrong

2017-02-24 Thread Yong Mao
From: yong mao 

This patch can fix two issues:

Issue 1:
The maximum value of clock divider is 0xff.
Because the type of div is u32, div may be larger than max_div.
In this case, we should use max_div to set the clock frequency.

Issue 2:
In previous code, we can not set the correct clock frequency when
div equals 0xff.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |   13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..3174445 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -540,6 +540,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 mode;
u32 flags;
u32 div;
+   u32 max_div;
u32 sclk;
 
if (!hz) {
@@ -590,8 +591,18 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
sclk = (host->src_clk_freq >> 2) / div;
}
}
+
+   /**
+* The maximum value of div is 0xff.
+* Check if the div is larger than max_div.
+*/
+   max_div = 0xff;
+   if (div > max_div) {
+   div = max_div;
+   sclk = (host->src_clk_freq >> 2) / div;
+   }
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
-   (mode << 8) | (div % 0xff));
+ (mode << 8) | div);
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
-- 
1.7.9.5



[PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-21 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for mediatek,hs200-cmd-int-delay
Add description for mediatek,hs400-cmd-int-delay
Add description for mediatek,hs400-cmd-resp-sel-rising

Signed-off-by: Yong Mao <yong@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..4182ea3 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,15 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- 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.
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +47,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mediatek,hs200-cmd-int-delay = <26>;
+   mediatek,hs400-cmd-int-delay = <14>;
+   mediatek,hs400-cmd-resp-sel-rising;
 };
-- 
1.7.9.5



[PATCH v4 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-21 Thread Yong Mao
From: yong mao <yong@mediatek.com>

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  168 -
 1 file changed, 152 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..07f3236 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,10 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   bool hs400_cmd_resp_sel_rising;
+/* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +612,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1320,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1343,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
 
sdr_clr_bits(host-&g

[PATCH v4 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-21 Thread Yong Mao
From: yong mao 

Add description for mediatek,hs200-cmd-int-delay
Add description for mediatek,hs400-cmd-int-delay
Add description for mediatek,hs400-cmd-resp-sel-rising

Signed-off-by: Yong Mao 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..4182ea3 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,15 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting.
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting
+   This field has total 32 stages.
+   The value is an integer from 0 to 31.
+- 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.
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +47,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mediatek,hs200-cmd-int-delay = <26>;
+   mediatek,hs400-cmd-int-delay = <14>;
+   mediatek,hs400-cmd-resp-sel-rising;
 };
-- 
1.7.9.5



[PATCH v4 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-21 Thread Yong Mao
From: yong mao 

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  168 -
 1 file changed, 152 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..07f3236 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,10 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   bool hs400_cmd_resp_sel_rising;
+/* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +612,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1320,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1343,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
 
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
for (i = 0 ; i < PAD_DE

[PATCH v4 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-21 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  ARM64: dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  12 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 168 ---
 3 files changed, 167 insertions(+), 16 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v4 2/3] ARM64: dts: mediatek: configure some fixed mmc parameters

2017-01-21 Thread Yong Mao
From: yong mao <yong@mediatek.com>

configure some fixed mmc parameters

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..1c3634f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mediatek,hs200-cmd-int-delay=<26>;
+   mediatek,hs400-cmd-int-delay=<14>;
+   mediatek,hs400-cmd-resp-sel-rising;
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v4 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-21 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  ARM64: dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  12 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 168 ---
 3 files changed, 167 insertions(+), 16 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v4 2/3] ARM64: dts: mediatek: configure some fixed mmc parameters

2017-01-21 Thread Yong Mao
From: yong mao 

configure some fixed mmc parameters

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..1c3634f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mediatek,hs200-cmd-int-delay=<26>;
+   mediatek,hs400-cmd-int-delay=<14>;
+   mediatek,hs400-cmd-resp-sel-rising;
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v3 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-19 Thread Yong Mao
From: yong mao <yong@mediatek.com>

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  170 -
 1 file changed, 153 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..b4e1c43 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs400_cmd_resp_sel;  /* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +611,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1319,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1342,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
 
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
  

[PATCH v3 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-19 Thread Yong Mao
From: yong mao 

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error. And also it may cause
cannot boot up issue.

Fot getting a set of better parameters, our emmc host supports
data tune mechanism.Therefore, our emmc driver also should change
to use data tune for CMD line.

Because our emmc host use the different clock source to sample the
CMD signal between HS200 and HS400 mode, the parameters are also
different between these two modes.
Separate cmd internal delay for HS200/HS400 mode.

This change can fix "System can not boot up" issue.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  170 -
 1 file changed, 153 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..b4e1c43 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1)  /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs400_cmd_resp_sel;  /* cmd response sample selection for HS400 */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +611,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1319,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1342,67 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
+
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ 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++) {
   

[PATCH v3 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-19 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for mtk-hs200-cmd-int-delay
Add description for mtk-hs400-cmd-int-delay
Add description for mtk-hs400-cmd-resp-sel

Signed-off-by: Yong Mao <yong@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |9 +
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..149f472 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,12 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
+  The value is an integer from 0 to 31
+- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
+  The value is an integer from 0 to 31
+- mtk-hs400-cmd-resp-sel:  HS400 command response sample selection
+  The value is an integer from 0 to 1
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +44,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mtk-hs200-cmd-int-delay = <26>;
+   mtk-hs400-cmd-int-delay = <14>;
+   mtk-hs400-cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



[PATCH v3 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-19 Thread Yong Mao
From: yong mao 

Add description for mtk-hs200-cmd-int-delay
Add description for mtk-hs400-cmd-int-delay
Add description for mtk-hs400-cmd-resp-sel

Signed-off-by: Yong Mao 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |9 +
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..149f472 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,12 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- mtk-hs200-cmd-int-delay: HS200 command internal delay setting.
+  The value is an integer from 0 to 31
+- mtk-hs400-cmd-int-delay: HS400 command internal delay setting
+  The value is an integer from 0 to 31
+- mtk-hs400-cmd-resp-sel:  HS400 command response sample selection
+  The value is an integer from 0 to 1
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +44,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   mtk-hs200-cmd-int-delay = <26>;
+   mtk-hs400-cmd-int-delay = <14>;
+   mtk-hs400-cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



[PATCH v3 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-19 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   9 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 170 ---
 3 files changed, 165 insertions(+), 17 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v3 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-19 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   9 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 170 ---
 3 files changed, 165 insertions(+), 17 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v3 2/3] dts: mediatek: configure some fixed mmc parameters

2017-01-19 Thread Yong Mao
From: yong mao <yong@mediatek.com>

configure some fixed mmc parameters

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..403705e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mtk-hs200-cmd-int-delay=<26>;
+   mtk-hs400-cmd-int-delay=<14>;
+   mtk-hs400-cmd-resp-sel=<0>; /* 0:rising, 1:falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v3 2/3] dts: mediatek: configure some fixed mmc parameters

2017-01-19 Thread Yong Mao
From: yong mao 

configure some fixed mmc parameters

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..403705e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   mtk-hs200-cmd-int-delay=<26>;
+   mtk-hs400-cmd-int-delay=<14>;
+   mtk-hs400-cmd-resp-sel=<0>; /* 0:rising, 1:falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v2 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-17 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   6 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 169 ---
 3 files changed, 161 insertions(+), 17 deletions(-)

-- 
1.8.1.1



[PATCH v2 2/3] dts: mediatek: configure some fixed mmc parameters

2017-01-17 Thread Yong Mao
From: yong mao <yong@mediatek.com>

configure some fixed mmc parameters

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..7356a32 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   hs200-cmd-int-delay=<26>;
+   hs400-cmd-int-delay=<14>;
+   cmd-resp-sel=<0>; /* 0:rising, 1:falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v2 2/3] dts: mediatek: configure some fixed mmc parameters

2017-01-17 Thread Yong Mao
From: yong mao 

configure some fixed mmc parameters

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..7356a32 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   hs200-cmd-int-delay=<26>;
+   hs400-cmd-int-delay=<14>;
+   cmd-resp-sel=<0>; /* 0:rising, 1:falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
-- 
1.7.9.5



[PATCH v2 0/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-17 Thread Yong Mao
yong mao (3):
  mmc: dt-bindings: update Mediatek MMC bindings
  dts: mediatek: configure some fixed mmc parameters
  mmc: mediatek: Use data tune for CMD line tune

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   6 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 169 ---
 3 files changed, 161 insertions(+), 17 deletions(-)

-- 
1.8.1.1



[PATCH v2 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-17 Thread Yong Mao
From: yong mao <yong@mediatek.com>

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error.
And also it may cause cannot boot up issue.

Fot getting a set of better parameters,
our emmc host supports data tune mechanism.
Therefore, our emmc driver also should change
to use data tune for CMD line

Because our emmc host use the different clock source
to sample the CMD signal between HS200 and HS400 mode,
the parameters are also different between these two modes.
Separate cmd internal delay for HS200/HS400 mode

This change can fix "System can not boot up" issue

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  169 -
 1 file changed, 152 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..26f9d3b 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs200_cmd_resp_sel; /* cmd response sample selection */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +611,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1319,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1342,66 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
 
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
fo

[PATCH v2 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-17 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for hs200-cmd-int-delay
Add description for hs400-cmd-int-delay
Add description for cmd-resp-sel

Signed-off-by: Yong Mao <yong@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..2dbb3b0 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,9 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- hs200-cmd-int-delay: HS200 command internal delay setting
+- hs400-cmd-int-delay: HS400 command internal delay setting
+- cmd-resp-sel: command response sample selection
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +41,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



[PATCH v2 3/3] mmc: mediatek: Use data tune for CMD line tune

2017-01-17 Thread Yong Mao
From: yong mao 

If we don't select a set of better parameters for our emmc host,
It may easily occur CMD response CRC error.
And also it may cause cannot boot up issue.

Fot getting a set of better parameters,
our emmc host supports data tune mechanism.
Therefore, our emmc driver also should change
to use data tune for CMD line

Because our emmc host use the different clock source
to sample the CMD signal between HS200 and HS400 mode,
the parameters are also different between these two modes.
Separate cmd internal delay for HS200/HS400 mode

This change can fix "System can not boot up" issue

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  169 -
 1 file changed, 152 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..26f9d3b 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,13 +211,18 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
 
+#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
+
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
 #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4)   /* RW */
@@ -284,12 +290,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +339,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs200_cmd_resp_sel; /* cmd response sample selection */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -600,8 +611,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
} 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_cmd_tune,
+  host->base + PAD_CMD_TUNE);
}
 
+   if (timing == MMC_TIMING_MMC_HS400)
+   sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
@@ -1302,7 +1319,7 @@ static struct msdc_delay_phase get_best_delay(struct 
msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
-   if (len >= 8 && start_final < 4)
+   if (len >= 12 && start_final < 4)
break;
}
 
@@ -1325,36 +1342,66 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 
opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+   struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+   u32 internal_delay = 0;
int cmd_err;
-   int i;
+   int i, j;
 
+   if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+   mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ 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_

[PATCH v2 1/3] mmc: dt-bindings: update Mediatek MMC bindings

2017-01-17 Thread Yong Mao
From: yong mao 

Add description for hs200-cmd-int-delay
Add description for hs400-cmd-int-delay
Add description for cmd-resp-sel

Signed-off-by: Yong Mao 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..2dbb3b0 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,9 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- hs200-cmd-int-delay: HS200 command internal delay setting
+- hs400-cmd-int-delay: HS400 command internal delay setting
+- cmd-resp-sel: command response sample selection
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +41,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



Re: [PATCH 1/2] mmc: mediatek: Use data tune for CMD line tune

2017-01-13 Thread Yong Mao
On Thu, 2017-01-12 at 11:39 +0100, Ulf Hansson wrote:
> On 12 January 2017 at 11:04, Yong Mao <yong@mediatek.com> wrote:
> > From: yong mao <yong@mediatek.com>
> >
> > CMD response CRC error may cause cannot boot up
> > Change to use data tune for CMD line
> > Separate cmd internal delay for HS200/HS400 mode
> 
> Please try to work a little bit on improving the change log. Moreover
> as this is a fix for a regression (it seems like so?), please try to
> make that clear.
This change can fix CMD respose CRC issue in our platform.
I will try to make it clear in next version.

> 
> >
> > Signed-off-by: Yong Mao <yong@mediatek.com>
> > Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +
> 
> Changes to the DTS files should be a separate change. Please split it
> into its own patch.
> 
> >  drivers/mmc/host/mtk-sd.c   |  169 
> > +++
> >  2 files changed, 149 insertions(+), 23 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
> > b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > index 0ecaad4..29c3100 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > @@ -134,6 +134,9 @@
> > bus-width = <8>;
> > max-frequency = <5000>;
> > cap-mmc-highspeed;
> > +   hs200-cmd-int-delay = <26>;
> > +   hs400-cmd-int-delay = <14>;
> > +   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
> > vmmc-supply = <_vemc_3v3_reg>;
> > vqmmc-supply = <_vio18_reg>;
> > non-removable;
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 80ba034..93eb395 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -75,6 +75,7 @@
> >  #define MSDC_PATCH_BIT1  0xb4
> >  #define MSDC_PAD_TUNE0xec
> >  #define PAD_DS_TUNE  0x188
> > +#define PAD_CMD_TUNE 0x18c
> >  #define EMMC50_CFG0  0x208
> >
> >  
> > /*--*/
> > @@ -210,12 +211,17 @@
> >  #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
> >  #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* RW */
> >
> > -#define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
> > -#define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* 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 */
> 
> Is there a white space change somewhere here? I don't see any changes
> to MSDC_PAD_TUNE_DATRRDLY and MSDC_PAD_TUNE_CMDRDLY.
> 
Sorry. I will fix in next version.

> > +#define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27)  /* RW */
> >
> > -#define PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
> > -#define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
> > -#define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
> > +#define PAD_DS_TUNE_DLY1  (0x1f << 2)   /* RW */
> > +#define PAD_DS_TUNE_DLY2  (0x1f << 7)   /* RW */
> > +#define PAD_DS_TUNE_DLY3  (0x1f << 12)  /* RW */
> > +
> 
> Ditto.
Ditto.

> 
> > +#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
> >
> >  #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
> >  #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
> > @@ -236,7 +242,9 @@
> >  #define CMD_TIMEOUT (HZ/10 * 5)/* 100ms x5 */
> >  #define DAT_TIMEOUT (HZ* 5)/* 1000ms x5 */
> >
> > -#define PAD_DELAY_MAX  32 /* PAD delay cells */
> > +#define PAD_DELAY_MAX32 /* PAD delay cells */
> 
> Ditto.
> 
Ditto.

> > +#define ENOUGH_MARGIN_MIN12 /* Enough Margin */
> > +#define PREFER_START_POS_MAX 4  /* Prefer start position */
> >  
> > /*--*/
> >  /* Descriptor Structure
> >  */
> >  
> > /*--*/
> > @@ -284,12 +292,14 @@ struct msdc_save_para {
> > u32 patch_bit0;
> > u32 patch_bit1;

Re: [PATCH 1/2] mmc: mediatek: Use data tune for CMD line tune

2017-01-13 Thread Yong Mao
On Thu, 2017-01-12 at 11:39 +0100, Ulf Hansson wrote:
> On 12 January 2017 at 11:04, Yong Mao  wrote:
> > From: yong mao 
> >
> > CMD response CRC error may cause cannot boot up
> > Change to use data tune for CMD line
> > Separate cmd internal delay for HS200/HS400 mode
> 
> Please try to work a little bit on improving the change log. Moreover
> as this is a fix for a regression (it seems like so?), please try to
> make that clear.
This change can fix CMD respose CRC issue in our platform.
I will try to make it clear in next version.

> 
> >
> > Signed-off-by: Yong Mao 
> > Signed-off-by: Chaotian Jing 
> > ---
> >  arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +
> 
> Changes to the DTS files should be a separate change. Please split it
> into its own patch.
> 
> >  drivers/mmc/host/mtk-sd.c   |  169 
> > +++
> >  2 files changed, 149 insertions(+), 23 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
> > b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > index 0ecaad4..29c3100 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> > @@ -134,6 +134,9 @@
> > bus-width = <8>;
> > max-frequency = <5000>;
> > cap-mmc-highspeed;
> > +   hs200-cmd-int-delay = <26>;
> > +   hs400-cmd-int-delay = <14>;
> > +   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
> > vmmc-supply = <_vemc_3v3_reg>;
> > vqmmc-supply = <_vio18_reg>;
> > non-removable;
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 80ba034..93eb395 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -75,6 +75,7 @@
> >  #define MSDC_PATCH_BIT1  0xb4
> >  #define MSDC_PAD_TUNE0xec
> >  #define PAD_DS_TUNE  0x188
> > +#define PAD_CMD_TUNE 0x18c
> >  #define EMMC50_CFG0  0x208
> >
> >  
> > /*--*/
> > @@ -210,12 +211,17 @@
> >  #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
> >  #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* RW */
> >
> > -#define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
> > -#define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* 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 */
> 
> Is there a white space change somewhere here? I don't see any changes
> to MSDC_PAD_TUNE_DATRRDLY and MSDC_PAD_TUNE_CMDRDLY.
> 
Sorry. I will fix in next version.

> > +#define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27)  /* RW */
> >
> > -#define PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
> > -#define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
> > -#define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
> > +#define PAD_DS_TUNE_DLY1  (0x1f << 2)   /* RW */
> > +#define PAD_DS_TUNE_DLY2  (0x1f << 7)   /* RW */
> > +#define PAD_DS_TUNE_DLY3  (0x1f << 12)  /* RW */
> > +
> 
> Ditto.
Ditto.

> 
> > +#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
> >
> >  #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
> >  #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
> > @@ -236,7 +242,9 @@
> >  #define CMD_TIMEOUT (HZ/10 * 5)/* 100ms x5 */
> >  #define DAT_TIMEOUT (HZ* 5)/* 1000ms x5 */
> >
> > -#define PAD_DELAY_MAX  32 /* PAD delay cells */
> > +#define PAD_DELAY_MAX32 /* PAD delay cells */
> 
> Ditto.
> 
Ditto.

> > +#define ENOUGH_MARGIN_MIN12 /* Enough Margin */
> > +#define PREFER_START_POS_MAX 4  /* Prefer start position */
> >  
> > /*--*/
> >  /* Descriptor Structure
> >  */
> >  
> > /*--*/
> > @@ -284,12 +292,14 @@ struct msdc_save_para {
> > u32 patch_bit0;
> > u32 patch_bit1;
> > u32 pad_ds_tune;
> > +   u32 pad_cmd_tune;
> > u32 emmc50_cfg0;
> >  };
&

[PATCH 1/2] mmc: mediatek: Use data tune for CMD line tune

2017-01-12 Thread Yong Mao
From: yong mao <yong@mediatek.com>

CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +
 drivers/mmc/host/mtk-sd.c   |  169 +++
 2 files changed, 149 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..29c3100 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..93eb395 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,12 +211,17 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* RW */
 
-#define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
-#define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
-#define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
-#define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
+#define PAD_DS_TUNE_DLY1  (0x1f << 2)   /* RW */
+#define PAD_DS_TUNE_DLY2  (0x1f << 7)   /* RW */
+#define PAD_DS_TUNE_DLY3  (0x1f << 12)  /* RW */
+
+#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
 
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
@@ -236,7 +242,9 @@
 #define CMD_TIMEOUT (HZ/10 * 5)/* 100ms x5 */
 #define DAT_TIMEOUT (HZ* 5)/* 1000ms x5 */
 
-#define PAD_DELAY_MAX  32 /* PAD delay cells */
+#define PAD_DELAY_MAX32 /* PAD delay cells */
+#define ENOUGH_MARGIN_MIN12 /* Enough Margin */
+#define PREFER_START_POS_MAX 4  /* Prefer start position */
 /*--*/
 /* Descriptor Structure */
 /*--*/
@@ -284,12 +292,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +341,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs200_cmd_resp_sel; /* cmd response sample selection */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -596,12 +609,21 @@ static void msdc_set_mclk(struct msdc_host *host, 
unsigned char timing, u32 hz)
 */
if (host->sclk <= 5200) {
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 + MSDC_PAD_TUNE);
} 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.iocon,
+  host->base + MSDC_IOCON);
+   writel(host->saved_tune_para.pad_tune,
+  host->ba

[PATCH 1/2] mmc: mediatek: Use data tune for CMD line tune

2017-01-12 Thread Yong Mao
From: yong mao 

CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |3 +
 drivers/mmc/host/mtk-sd.c   |  169 +++
 2 files changed, 149 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..29c3100 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <5000>;
cap-mmc-highspeed;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
vmmc-supply = <_vemc_3v3_reg>;
vqmmc-supply = <_vio18_reg>;
non-removable;
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..93eb395 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE0xec
 #define PAD_DS_TUNE  0x188
+#define PAD_CMD_TUNE 0x18c
 #define EMMC50_CFG0  0x208
 
 /*--*/
@@ -210,12 +211,17 @@
 #define MSDC_PATCH_BIT_SPCPUSH(0x1 << 29)  /* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)  /* RW */
 
-#define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
-#define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* 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 PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
-#define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
-#define PAD_DS_TUNE_DLY3 (0x1f << 12)  /* RW */
+#define PAD_DS_TUNE_DLY1  (0x1f << 2)   /* RW */
+#define PAD_DS_TUNE_DLY2  (0x1f << 7)   /* RW */
+#define PAD_DS_TUNE_DLY3  (0x1f << 12)  /* RW */
+
+#define PAD_CMD_TUNE_RX_DLY3  (0x1f << 1)   /* RW */
 
 #define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */
 #define EMMC50_CFG_CRCSTS_EDGE(0x1 << 3)   /* RW */
@@ -236,7 +242,9 @@
 #define CMD_TIMEOUT (HZ/10 * 5)/* 100ms x5 */
 #define DAT_TIMEOUT (HZ* 5)/* 1000ms x5 */
 
-#define PAD_DELAY_MAX  32 /* PAD delay cells */
+#define PAD_DELAY_MAX32 /* PAD delay cells */
+#define ENOUGH_MARGIN_MIN12 /* Enough Margin */
+#define PREFER_START_POS_MAX 4  /* Prefer start position */
 /*--*/
 /* Descriptor Structure */
 /*--*/
@@ -284,12 +292,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+   u32 pad_cmd_tune;
u32 emmc50_cfg0;
 };
 
 struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+   u32 pad_cmd_tune;
 };
 
 struct msdc_delay_phase {
@@ -331,6 +341,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
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 */
+   u32 hs200_cmd_resp_sel; /* cmd response sample selection */
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -596,12 +609,21 @@ static void msdc_set_mclk(struct msdc_host *host, 
unsigned char timing, u32 hz)
 */
if (host->sclk <= 5200) {
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 + MSDC_PAD_TUNE);
} 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.iocon,
+  host->base + MSDC_IOCON);
+   writel(host->saved_tune_para.pad_tune,
+  host->base + MSDC_PAD_TUNE);
+   writel(

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

2017-01-12 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description for hs200-cmd-int-delay
Add description for hs400-cmd-int-delay
Add description for cmd-resp-sel

Signed-off-by: Yong Mao <yong@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..2dbb3b0 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,9 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- hs200-cmd-int-delay: HS200 command internal delay setting
+- hs400-cmd-int-delay: HS400 command internal delay setting
+- cmd-resp-sel: command response sample selection
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +41,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



[PATCH 0/2] Use data tune for CMD line tune

2017-01-12 Thread Yong Mao
CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode

yong mao (2):
  mmc: mediatek: Use data tune for CMD line tune
  mmc: dt-bindings: update Mediatek MMC bindings

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   6 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 169 ---
 3 files changed, 155 insertions(+), 23 deletions(-)

-- 
1.8.1.1




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

2017-01-12 Thread Yong Mao
From: yong mao 

Add description for hs200-cmd-int-delay
Add description for hs400-cmd-int-delay
Add description for cmd-resp-sel

Signed-off-by: Yong Mao 
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt 
b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 0120c7f..2dbb3b0 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -21,6 +21,9 @@ Optional properties:
 - assigned-clocks: PLL of the source clock
 - assigned-clock-parents: parent of source clock, used for HS400 mode to get 
400Mhz source clock
 - hs400-ds-delay: HS400 DS delay setting
+- hs200-cmd-int-delay: HS200 command internal delay setting
+- hs400-cmd-int-delay: HS400 command internal delay setting
+- cmd-resp-sel: command response sample selection
 
 Examples:
 mmc0: mmc@1123 {
@@ -38,4 +41,7 @@ mmc0: mmc@1123 {
assigned-clocks = < CLK_TOP_MSDC50_0_SEL>;
assigned-clock-parents = < CLK_TOP_MSDCPLL_D2>;
hs400-ds-delay = <0x14015>;
+   hs200-cmd-int-delay = <26>;
+   hs400-cmd-int-delay = <14>;
+   cmd-resp-sel = <0>; /* 0: rising, 1: falling */
 };
-- 
1.7.9.5



[PATCH 0/2] Use data tune for CMD line tune

2017-01-12 Thread Yong Mao
CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode

yong mao (2):
  mmc: mediatek: Use data tune for CMD line tune
  mmc: dt-bindings: update Mediatek MMC bindings

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |   6 +
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts  |   3 +
 drivers/mmc/host/mtk-sd.c| 169 ---
 3 files changed, 155 insertions(+), 23 deletions(-)

-- 
1.8.1.1




Re: [PATCH 1/4] mmc: mediatek: Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
On Thu, 2016-12-01 at 10:51 +0100, Ulf Hansson wrote:
> On 8 November 2016 at 07:08, Yong Mao <yong@mediatek.com> wrote:
> > From: yong mao <yong@mediatek.com>
> >
> > When initializing EMMC, after switch to HS400,
> > it will issue CMD6 to change ext_csd, if first CMD6 got CRC
> > error, the repeat CMD6 may get timeout, that's
> > because SDCBSY was cleared by msdc_reset_hw()
> 
> Sorry for the delay!
> 
> We have recently been re-working the sequence for how to deal more
> properly with CMD6 in the mmc core.
> 
> The changes done so far should mostly concern switches to HS and HS
> DDR, but I think you should run a re-test to make sure you still hit
> the same problems.
> 
Happy New Year!

The issue we met is not only just for CMD6, but also for other R1B CMD.
Your new changes does not cover all of these cases.
We would like to make error handle in the core layer to deal with these
issues.

I had submitted a new path ([PATCH v2] Fix CMD6 timeout issue) to you,
please help to review it.
Thanks.


> >
> > Signed-off-by: Yong Mao <yong@mediatek.com>
> > Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
> > ---
> >  drivers/mmc/host/mtk-sd.c |   77 
> > ++---
> >  1 file changed, 51 insertions(+), 26 deletions(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 84e9afc..b29683b 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -826,6 +826,15 @@ static bool msdc_cmd_done(struct msdc_host *host, int 
> > events,
> > return true;
> >  }
> >
> > +static int msdc_card_busy(struct mmc_host *mmc)
> > +{
> > +   struct msdc_host *host = mmc_priv(mmc);
> > +   u32 status = readl(host->base + MSDC_PS);
> > +
> > +   /* check if data0 is low */
> > +   return !(status & BIT(16));
> > +}
> > +
> >  /* It is the core layer's responsibility to ensure card status
> >   * is correct before issue a request. but host design do below
> >   * checks recommended.
> 
> Hmm. Why?
> 
> I think you should rely on the mmc core to invoke the ->card_busy()
> ops instead. The core knows better when it's needed.
> 
> Perhaps that may also resolve some of these issues for you!?
In my latest patch, msdc_card_busy will not be used in mtk-sd.c
directly. It only can be invoked by ->card_busy() in the mmc core.


> 
> > @@ -835,10 +844,20 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
> > *host,
> >  {
> > /* The max busy time we can endure is 20ms */
> > unsigned long tmo = jiffies + msecs_to_jiffies(20);
> > +   u32 count = 0;
> > +
> > +   if (in_interrupt()) {
> > +   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > +  (count < 1000)) {
> > +   udelay(1);
> > +   count++;
> 
> This seems like a bad idea, "busy-wait" in irq context is never a good idea.
Thanks. The modification here is not for the current issue.
I will submit a new patch to discuss with you.


> > +   }
> > +   } else {
> > +   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > +  time_before(jiffies, tmo))
> > +   cpu_relax();
> > +   }
> >
> > -   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > -   time_before(jiffies, tmo))
> > -   cpu_relax();
> > if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
> > dev_err(host->dev, "CMD bus busy detected\n");
> > host->error |= REQ_CMD_BUSY;
> > @@ -846,17 +865,35 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
> > *host,
> > return false;
> > }
> >
> > -   if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
> > -   tmo = jiffies + msecs_to_jiffies(20);
> > -   /* R1B or with data, should check SDCBUSY */
> > -   while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
> > -   time_before(jiffies, tmo))
> > -   cpu_relax();
> > -   if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
> > -   dev_err(host->dev, "Controller busy detected\n");
> 

Re: [PATCH 1/4] mmc: mediatek: Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
On Thu, 2016-12-01 at 10:51 +0100, Ulf Hansson wrote:
> On 8 November 2016 at 07:08, Yong Mao  wrote:
> > From: yong mao 
> >
> > When initializing EMMC, after switch to HS400,
> > it will issue CMD6 to change ext_csd, if first CMD6 got CRC
> > error, the repeat CMD6 may get timeout, that's
> > because SDCBSY was cleared by msdc_reset_hw()
> 
> Sorry for the delay!
> 
> We have recently been re-working the sequence for how to deal more
> properly with CMD6 in the mmc core.
> 
> The changes done so far should mostly concern switches to HS and HS
> DDR, but I think you should run a re-test to make sure you still hit
> the same problems.
> 
Happy New Year!

The issue we met is not only just for CMD6, but also for other R1B CMD.
Your new changes does not cover all of these cases.
We would like to make error handle in the core layer to deal with these
issues.

I had submitted a new path ([PATCH v2] Fix CMD6 timeout issue) to you,
please help to review it.
Thanks.


> >
> > Signed-off-by: Yong Mao 
> > Signed-off-by: Chaotian Jing 
> > ---
> >  drivers/mmc/host/mtk-sd.c |   77 
> > ++---
> >  1 file changed, 51 insertions(+), 26 deletions(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 84e9afc..b29683b 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -826,6 +826,15 @@ static bool msdc_cmd_done(struct msdc_host *host, int 
> > events,
> > return true;
> >  }
> >
> > +static int msdc_card_busy(struct mmc_host *mmc)
> > +{
> > +   struct msdc_host *host = mmc_priv(mmc);
> > +   u32 status = readl(host->base + MSDC_PS);
> > +
> > +   /* check if data0 is low */
> > +   return !(status & BIT(16));
> > +}
> > +
> >  /* It is the core layer's responsibility to ensure card status
> >   * is correct before issue a request. but host design do below
> >   * checks recommended.
> 
> Hmm. Why?
> 
> I think you should rely on the mmc core to invoke the ->card_busy()
> ops instead. The core knows better when it's needed.
> 
> Perhaps that may also resolve some of these issues for you!?
In my latest patch, msdc_card_busy will not be used in mtk-sd.c
directly. It only can be invoked by ->card_busy() in the mmc core.


> 
> > @@ -835,10 +844,20 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
> > *host,
> >  {
> > /* The max busy time we can endure is 20ms */
> > unsigned long tmo = jiffies + msecs_to_jiffies(20);
> > +   u32 count = 0;
> > +
> > +   if (in_interrupt()) {
> > +   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > +  (count < 1000)) {
> > +   udelay(1);
> > +   count++;
> 
> This seems like a bad idea, "busy-wait" in irq context is never a good idea.
Thanks. The modification here is not for the current issue.
I will submit a new patch to discuss with you.


> > +   }
> > +   } else {
> > +   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > +  time_before(jiffies, tmo))
> > +   cpu_relax();
> > +   }
> >
> > -   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
> > -   time_before(jiffies, tmo))
> > -   cpu_relax();
> > if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
> > dev_err(host->dev, "CMD bus busy detected\n");
> > host->error |= REQ_CMD_BUSY;
> > @@ -846,17 +865,35 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
> > *host,
> > return false;
> > }
> >
> > -   if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
> > -   tmo = jiffies + msecs_to_jiffies(20);
> > -   /* R1B or with data, should check SDCBUSY */
> > -   while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
> > -   time_before(jiffies, tmo))
> > -   cpu_relax();
> > -   if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
> > -   dev_err(host->dev, "Controller busy detected\n");
> > -   host->error |= REQ_CMD_BUSY;
> > -   msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd)

[PATCH v2 2/2] mmc: mediatek: correct the implementation of msdc_card_busy

2017-01-03 Thread Yong Mao
From: yong mao <yong@mediatek.com>

msdc_card_busy only need check if the data0 is low.
In sdio data1 irq mode, data1 may be low because of interruption.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 10ef2ae..80ba034 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1074,11 +1074,8 @@ static int msdc_card_busy(struct mmc_host *mmc)
struct msdc_host *host = mmc_priv(mmc);
u32 status = readl(host->base + MSDC_PS);
 
-   /* check if any pin between dat[0:3] is low */
-   if (((status >> 16) & 0xf) != 0xf)
-   return 1;
-
-   return 0;
+   /* only check if data0 is low */
+   return !(status & BIT(16));
 }
 
 static void msdc_request_timeout(struct work_struct *work)
-- 
1.7.9.5



[PATCH v2 2/2] mmc: mediatek: correct the implementation of msdc_card_busy

2017-01-03 Thread Yong Mao
From: yong mao 

msdc_card_busy only need check if the data0 is low.
In sdio data1 irq mode, data1 may be low because of interruption.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 10ef2ae..80ba034 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1074,11 +1074,8 @@ static int msdc_card_busy(struct mmc_host *mmc)
struct msdc_host *host = mmc_priv(mmc);
u32 status = readl(host->base + MSDC_PS);
 
-   /* check if any pin between dat[0:3] is low */
-   if (((status >> 16) & 0xf) != 0xf)
-   return 1;
-
-   return 0;
+   /* only check if data0 is low */
+   return !(status & BIT(16));
 }
 
 static void msdc_request_timeout(struct work_struct *work)
-- 
1.7.9.5



[PATCH v2 1/2] mmc: core: Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
From: yong mao <yong@mediatek.com>

When initializing EMMC, after switch to HS400,
it will issue CMD6 to change ext_csd,
if first CMD6 got CRC error,
the repeat CMD6 may get timeout,
that's because card is not back to transfer state immediately.

For resolving this issue, it need check if card is busy
before sending repeat CMD6.

Not only CMD6 here has this issue, but also other R1B CMD has
the same issue.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/core/core.c |   19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 1076b9d..8674dbb 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -566,6 +566,25 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct 
mmc_request *mrq)
 
mmc_retune_recheck(host);
 
+   /*
+* If a R1B CMD such as CMD6 occur CRC error,
+* it will retry 3 times here.
+* But before retrying, it must ensure card is in
+* transfer state.
+* Otherwise, the next retried CMD will got TMO error.
+*/
+   if (mmc_resp_type(cmd) == MMC_RSP_R1B && host->ops->card_busy) {
+   int tries = 500; /* Wait aprox 500ms at maximum */
+
+   while (host->ops->card_busy(host) && --tries)
+   mmc_delay(1);
+
+   if (tries == 0) {
+   cmd->error = -EBUSY;
+   break;
+   }
+   }
+
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
 mmc_hostname(host), cmd->opcode, cmd->error);
cmd->retries--;
-- 
1.7.9.5



[PATCH v2 1/2] mmc: core: Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
From: yong mao 

When initializing EMMC, after switch to HS400,
it will issue CMD6 to change ext_csd,
if first CMD6 got CRC error,
the repeat CMD6 may get timeout,
that's because card is not back to transfer state immediately.

For resolving this issue, it need check if card is busy
before sending repeat CMD6.

Not only CMD6 here has this issue, but also other R1B CMD has
the same issue.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/core/core.c |   19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 1076b9d..8674dbb 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -566,6 +566,25 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct 
mmc_request *mrq)
 
mmc_retune_recheck(host);
 
+   /*
+* If a R1B CMD such as CMD6 occur CRC error,
+* it will retry 3 times here.
+* But before retrying, it must ensure card is in
+* transfer state.
+* Otherwise, the next retried CMD will got TMO error.
+*/
+   if (mmc_resp_type(cmd) == MMC_RSP_R1B && host->ops->card_busy) {
+   int tries = 500; /* Wait aprox 500ms at maximum */
+
+   while (host->ops->card_busy(host) && --tries)
+   mmc_delay(1);
+
+   if (tries == 0) {
+   cmd->error = -EBUSY;
+   break;
+   }
+   }
+
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
 mmc_hostname(host), cmd->opcode, cmd->error);
cmd->retries--;
-- 
1.7.9.5



[PATCH v2] Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
yong mao (2):
  mmc: core: Fix CMD6 timeout issue
  mmc: mediatek: correct the implementation of msdc_card_busy

 drivers/mmc/core/core.c   | 19 +++
 drivers/mmc/host/mtk-sd.c |  7 ++-
 2 files changed, 21 insertions(+), 5 deletions(-)

-- 
1.8.1.1.dirty



[PATCH v2] Fix CMD6 timeout issue

2017-01-03 Thread Yong Mao
yong mao (2):
  mmc: core: Fix CMD6 timeout issue
  mmc: mediatek: correct the implementation of msdc_card_busy

 drivers/mmc/core/core.c   | 19 +++
 drivers/mmc/host/mtk-sd.c |  7 ++-
 2 files changed, 21 insertions(+), 5 deletions(-)

-- 
1.8.1.1.dirty



[PATCH 3/4] sdio: mediatek: support sdr104_clk_delay in sdio

2016-11-07 Thread Yong Mao
From: yong mao <yong@mediatek.com>

In order to let sdio run stable with 200M clock,
we should setup the value of clock delay.

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 37edf30..fba28f2 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -213,6 +213,7 @@
 
 #define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
 #define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* RW */
+#define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27)  /* RW */
 
 #define PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
@@ -335,6 +336,7 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
+   u32 sdr104_clk_delay;
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -1230,7 +1232,8 @@ static void msdc_init_hw(struct msdc_host *host)
writel(val, host->base + MSDC_INT);
spin_unlock_irqrestore(>irqlock, flags);
 
-   writel(0, host->base + MSDC_PAD_TUNE);
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CLKTDLY, host->sdr104_clk_delay);
writel(0, host->base + MSDC_IOCON);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
writel(0x403c0046, host->base + MSDC_PATCH_BIT);
@@ -1671,6 +1674,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
dev_dbg(>dev, "hs400-ds-delay: %x\n",
host->hs400_ds_delay);
 
+   if (!of_property_read_u32(pdev->dev.of_node, "sdr104-clk-delay",
+ >sdr104_clk_delay))
+   dev_dbg(>dev, "sdr104-clk-delay: %x\n",
+   host->sdr104_clk_delay);
+
host->dev = >dev;
host->mmc = mmc;
host->src_clk_freq = clk_get_rate(host->src_clk);
-- 
1.7.9.5



[PATCH 2/4] sdio: mediatek: Support sdio feature

2016-11-07 Thread Yong Mao
From: yong mao <yong@mediatek.com>

1. Add irqlock to protect accessing the shared register
2. Modify the implementation of msdc_card_busy due to SDIO
3. Implement enable_sdio_irq
4. Add msdc_recheck_sdio_irq mechanism to make sure all
   interrupts can be processed immediately

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |  167 ++---
 1 file changed, 129 insertions(+), 38 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b29683b..37edf30 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -117,6 +117,7 @@
 #define MSDC_PS_CDSTS   (0x1 << 1) /* R  */
 #define MSDC_PS_CDDEBOUNCE  (0xf << 12)/* RW */
 #define MSDC_PS_DAT (0xff << 16)   /* R  */
+#define MSDC_PS_DATA1   (0x1 << 17)/* R  */
 #define MSDC_PS_CMD (0x1 << 24)/* R  */
 #define MSDC_PS_WP  (0x1 << 31)/* R  */
 
@@ -304,6 +305,7 @@ struct msdc_host {
int cmd_rsp;
 
spinlock_t lock;
+   spinlock_t irqlock; /* sdio irq lock */
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -322,12 +324,14 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq;/* host interrupt */
+   bool irq_thread_alive;
 
struct clk *src_clk;/* msdc source clock */
struct clk *h_clk;  /* msdc h_clk */
u32 mclk;   /* mmc subsystem clock frequency */
u32 src_clk_freq;   /* source clock frequency */
u32 sclk;   /* SD/MS bus clock frequency */
+   bool clock_on;
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
@@ -387,6 +391,7 @@ static void msdc_reset_hw(struct msdc_host *host)
 
 static void msdc_cmd_next(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd);
+static void msdc_recheck_sdio_irq(struct msdc_host *host);
 
 static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
@@ -513,6 +518,7 @@ static void msdc_gate_clock(struct msdc_host *host)
 {
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->h_clk);
+   host->clock_on = false;
 }
 
 static void msdc_ungate_clock(struct msdc_host *host)
@@ -521,6 +527,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
clk_prepare_enable(host->src_clk);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
+   host->clock_on = true;
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -529,6 +536,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 flags;
u32 div;
u32 sclk;
+   unsigned long irq_flags;
 
if (!hz) {
dev_dbg(host->dev, "set mclk to 0\n");
@@ -537,8 +545,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
return;
}
 
+   spin_lock_irqsave(>irqlock, irq_flags);
flags = readl(host->base + MSDC_INTEN);
sdr_clr_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
+
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
if (timing == MMC_TIMING_UHS_DDR50 ||
timing == MMC_TIMING_MMC_DDR52 ||
@@ -588,7 +599,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
host->timing = timing;
/* need because clk changed. */
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+   spin_lock_irqsave(>irqlock, irq_flags);
sdr_set_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
 
/*
 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
@@ -690,6 +704,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host 
*host,
 static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
struct mmc_command *cmd, struct mmc_data *data)
 {
+   unsigned long flags;
bool read;
 
WARN_ON(host->data);
@@ -698,8 +713,12 @@ static void msdc_start_data(struct msdc_host *host, struct 
mmc_request *mrq,
 
mod_delayed_work(system_wq, >req_timeout, DAT_TIMEOUT);
msdc_dma_setup(host, >dma, data);
+
+   spin_lock_irqsave(>irqlock, flags);
sdr_set_bits(host->base + MSDC_INTEN, data_ints_mask);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
+

[PATCH 2/4] sdio: mediatek: Support sdio feature

2016-11-07 Thread Yong Mao
From: yong mao 

1. Add irqlock to protect accessing the shared register
2. Modify the implementation of msdc_card_busy due to SDIO
3. Implement enable_sdio_irq
4. Add msdc_recheck_sdio_irq mechanism to make sure all
   interrupts can be processed immediately

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |  167 ++---
 1 file changed, 129 insertions(+), 38 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b29683b..37edf30 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -117,6 +117,7 @@
 #define MSDC_PS_CDSTS   (0x1 << 1) /* R  */
 #define MSDC_PS_CDDEBOUNCE  (0xf << 12)/* RW */
 #define MSDC_PS_DAT (0xff << 16)   /* R  */
+#define MSDC_PS_DATA1   (0x1 << 17)/* R  */
 #define MSDC_PS_CMD (0x1 << 24)/* R  */
 #define MSDC_PS_WP  (0x1 << 31)/* R  */
 
@@ -304,6 +305,7 @@ struct msdc_host {
int cmd_rsp;
 
spinlock_t lock;
+   spinlock_t irqlock; /* sdio irq lock */
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -322,12 +324,14 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq;/* host interrupt */
+   bool irq_thread_alive;
 
struct clk *src_clk;/* msdc source clock */
struct clk *h_clk;  /* msdc h_clk */
u32 mclk;   /* mmc subsystem clock frequency */
u32 src_clk_freq;   /* source clock frequency */
u32 sclk;   /* SD/MS bus clock frequency */
+   bool clock_on;
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
@@ -387,6 +391,7 @@ static void msdc_reset_hw(struct msdc_host *host)
 
 static void msdc_cmd_next(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd);
+static void msdc_recheck_sdio_irq(struct msdc_host *host);
 
 static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
@@ -513,6 +518,7 @@ static void msdc_gate_clock(struct msdc_host *host)
 {
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->h_clk);
+   host->clock_on = false;
 }
 
 static void msdc_ungate_clock(struct msdc_host *host)
@@ -521,6 +527,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
clk_prepare_enable(host->src_clk);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
+   host->clock_on = true;
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -529,6 +536,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
u32 flags;
u32 div;
u32 sclk;
+   unsigned long irq_flags;
 
if (!hz) {
dev_dbg(host->dev, "set mclk to 0\n");
@@ -537,8 +545,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
return;
}
 
+   spin_lock_irqsave(>irqlock, irq_flags);
flags = readl(host->base + MSDC_INTEN);
sdr_clr_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
+
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
if (timing == MMC_TIMING_UHS_DDR50 ||
timing == MMC_TIMING_MMC_DDR52 ||
@@ -588,7 +599,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned 
char timing, u32 hz)
host->timing = timing;
/* need because clk changed. */
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+   spin_lock_irqsave(>irqlock, irq_flags);
sdr_set_bits(host->base + MSDC_INTEN, flags);
+   spin_unlock_irqrestore(>irqlock, irq_flags);
 
/*
 * mmc_select_hs400() will drop to 50Mhz and High speed mode,
@@ -690,6 +704,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host 
*host,
 static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
struct mmc_command *cmd, struct mmc_data *data)
 {
+   unsigned long flags;
bool read;
 
WARN_ON(host->data);
@@ -698,8 +713,12 @@ static void msdc_start_data(struct msdc_host *host, struct 
mmc_request *mrq,
 
mod_delayed_work(system_wq, >req_timeout, DAT_TIMEOUT);
msdc_dma_setup(host, >dma, data);
+
+   spin_lock_irqsave(>irqlock, flags);
sdr_set_bits(host->base + MSDC_INTEN, data_ints_mask);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
+   spin_unlock_irqrestore(>irqlock, flags);
+
dev_dbg(host->dev, "DMA s

[PATCH 3/4] sdio: mediatek: support sdr104_clk_delay in sdio

2016-11-07 Thread Yong Mao
From: yong mao 

In order to let sdio run stable with 200M clock,
we should setup the value of clock delay.

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 37edf30..fba28f2 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -213,6 +213,7 @@
 
 #define MSDC_PAD_TUNE_DATRRDLY   (0x1f <<  8)  /* RW */
 #define MSDC_PAD_TUNE_CMDRDLY(0x1f << 16)  /* RW */
+#define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27)  /* RW */
 
 #define PAD_DS_TUNE_DLY1 (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2 (0x1f << 7)   /* RW */
@@ -335,6 +336,7 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
+   u32 sdr104_clk_delay;
bool hs400_mode;/* current eMMC will run at hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -1230,7 +1232,8 @@ static void msdc_init_hw(struct msdc_host *host)
writel(val, host->base + MSDC_INT);
spin_unlock_irqrestore(>irqlock, flags);
 
-   writel(0, host->base + MSDC_PAD_TUNE);
+   sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CLKTDLY, host->sdr104_clk_delay);
writel(0, host->base + MSDC_IOCON);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
writel(0x403c0046, host->base + MSDC_PATCH_BIT);
@@ -1671,6 +1674,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
dev_dbg(>dev, "hs400-ds-delay: %x\n",
host->hs400_ds_delay);
 
+   if (!of_property_read_u32(pdev->dev.of_node, "sdr104-clk-delay",
+ >sdr104_clk_delay))
+   dev_dbg(>dev, "sdr104-clk-delay: %x\n",
+   host->sdr104_clk_delay);
+
host->dev = >dev;
host->mmc = mmc;
host->src_clk_freq = clk_get_rate(host->src_clk);
-- 
1.7.9.5



[PATCH 4/4] dts: arm64: enable mmc3 for supporting sdio feature

2016-11-07 Thread Yong Mao
From: yong mao <yong@mediatek.com>

Add description of mmc3 for supporting sdio feature

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |   82 +++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 2a7f731..4dbd299 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -43,6 +43,14 @@
enable-active-high;
};
 
+   sdio_fixed_3v3: fixedregulator@0 {
+   compatible = "regulator-fixed";
+   regulator-name = "3V3";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   gpio = < 85 GPIO_ACTIVE_HIGH>;
+   };
+
connector {
compatible = "hdmi-connector";
label = "hdmi";
@@ -139,6 +147,25 @@
vqmmc-supply = <_vmc_reg>;
 };
 
+ {
+   status = "okay";
+   pinctrl-names = "default", "state_uhs";
+   pinctrl-0 = <_pins_default>;
+   pinctrl-1 = <_pins_uhs>;
+   bus-width = <4>;
+   max-frequency = <2>;
+   cap-sd-highspeed;
+   sd-uhs-sdr50;
+   sd-uhs-sdr104;
+   sdr104-clk-delay = <5>;
+   keep-power-in-suspend;
+   enable-sdio-wakeup;
+   cap-sdio-irq;
+   vmmc-supply = <_fixed_3v3>;
+   vqmmc-supply = <_vgp3_reg>;
+   non-removable;
+};
+
  {
disp_pwm0_pins: disp_pwm0_pins {
pins1 {
@@ -197,6 +224,36 @@
};
};
 
+   mmc3_pins_default: mmc3default {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   bias-pull-down;
+   drive-strength = ;
+   };
+
+   pins_pdn {
+   pinmux = ;
+   output-low;
+   };
+   };
+
mmc0_pins_uhs: mmc0 {
pins_cmd_dat {
pinmux = ,
@@ -243,6 +300,31 @@
bias-pull-down = ;
};
};
+
+   mmc3_pins_uhs: mmc3 {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   drive-strength = ;
+   bias-pull-down = ;
+   };
+   };
 };
 
  {
-- 
1.7.9.5



[PATCH 4/4] dts: arm64: enable mmc3 for supporting sdio feature

2016-11-07 Thread Yong Mao
From: yong mao 

Add description of mmc3 for supporting sdio feature

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |   82 +++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 2a7f731..4dbd299 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -43,6 +43,14 @@
enable-active-high;
};
 
+   sdio_fixed_3v3: fixedregulator@0 {
+   compatible = "regulator-fixed";
+   regulator-name = "3V3";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   gpio = < 85 GPIO_ACTIVE_HIGH>;
+   };
+
connector {
compatible = "hdmi-connector";
label = "hdmi";
@@ -139,6 +147,25 @@
vqmmc-supply = <_vmc_reg>;
 };
 
+ {
+   status = "okay";
+   pinctrl-names = "default", "state_uhs";
+   pinctrl-0 = <_pins_default>;
+   pinctrl-1 = <_pins_uhs>;
+   bus-width = <4>;
+   max-frequency = <2>;
+   cap-sd-highspeed;
+   sd-uhs-sdr50;
+   sd-uhs-sdr104;
+   sdr104-clk-delay = <5>;
+   keep-power-in-suspend;
+   enable-sdio-wakeup;
+   cap-sdio-irq;
+   vmmc-supply = <_fixed_3v3>;
+   vqmmc-supply = <_vgp3_reg>;
+   non-removable;
+};
+
  {
disp_pwm0_pins: disp_pwm0_pins {
pins1 {
@@ -197,6 +224,36 @@
};
};
 
+   mmc3_pins_default: mmc3default {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   bias-pull-down;
+   drive-strength = ;
+   };
+
+   pins_pdn {
+   pinmux = ;
+   output-low;
+   };
+   };
+
mmc0_pins_uhs: mmc0 {
pins_cmd_dat {
pinmux = ,
@@ -243,6 +300,31 @@
bias-pull-down = ;
};
};
+
+   mmc3_pins_uhs: mmc3 {
+   pins_dat {
+   pinmux = ,
+,
+,
+;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_cmd {
+   pinmux = ;
+   input-enable;
+   drive-strength = ;
+   bias-pull-up = ;
+   };
+
+   pins_clk {
+   pinmux = ;
+   drive-strength = ;
+   bias-pull-down = ;
+   };
+   };
 };
 
  {
-- 
1.7.9.5



[PATCH 0/4] Support sdio feature

2016-11-07 Thread Yong Mao
Fix CMD6 timeout issue
Add irqlock to protect accessing the shared register
Modify the implementation of msdc_card_busy
Add msdc_recheck_sdio_irq mechanism
Support sdr104_clk_delay in sdio
Add description of mmc3 for supporting sdio feature

yong mao (4):
  mmc: mediatek: Fix CMD6 timeout issue
  sdio: mediatek: Support sdio feature
  sdio: mediatek: support sdr104_clk_delay in sdio
  dts: arm64: enable mmc3 for supporting sdio feature

 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |  82 +
 drivers/mmc/host/mtk-sd.c   | 254 +---
 2 files changed, 271 insertions(+), 65 deletions(-)

-- 
1.8.1.1.dirty



[PATCH 1/4] mmc: mediatek: Fix CMD6 timeout issue

2016-11-07 Thread Yong Mao
From: yong mao <yong@mediatek.com>

When initializing EMMC, after switch to HS400,
it will issue CMD6 to change ext_csd, if first CMD6 got CRC
error, the repeat CMD6 may get timeout, that's
because SDCBSY was cleared by msdc_reset_hw()

Signed-off-by: Yong Mao <yong@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.j...@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c |   77 ++---
 1 file changed, 51 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 84e9afc..b29683b 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -826,6 +826,15 @@ static bool msdc_cmd_done(struct msdc_host *host, int 
events,
return true;
 }
 
+static int msdc_card_busy(struct mmc_host *mmc)
+{
+   struct msdc_host *host = mmc_priv(mmc);
+   u32 status = readl(host->base + MSDC_PS);
+
+   /* check if data0 is low */
+   return !(status & BIT(16));
+}
+
 /* It is the core layer's responsibility to ensure card status
  * is correct before issue a request. but host design do below
  * checks recommended.
@@ -835,10 +844,20 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
*host,
 {
/* The max busy time we can endure is 20ms */
unsigned long tmo = jiffies + msecs_to_jiffies(20);
+   u32 count = 0;
+
+   if (in_interrupt()) {
+   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
+  (count < 1000)) {
+   udelay(1);
+   count++;
+   }
+   } else {
+   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
+  time_before(jiffies, tmo))
+   cpu_relax();
+   }
 
-   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
-   time_before(jiffies, tmo))
-   cpu_relax();
if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
dev_err(host->dev, "CMD bus busy detected\n");
host->error |= REQ_CMD_BUSY;
@@ -846,17 +865,35 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
*host,
return false;
}
 
-   if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
-   tmo = jiffies + msecs_to_jiffies(20);
-   /* R1B or with data, should check SDCBUSY */
-   while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
-   time_before(jiffies, tmo))
-   cpu_relax();
-   if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
-   dev_err(host->dev, "Controller busy detected\n");
-   host->error |= REQ_CMD_BUSY;
-   msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
-   return false;
+   if (cmd->opcode != MMC_SEND_STATUS) {
+   count = 0;
+   /* Consider that CMD6 crc error before card was init done,
+* mmc_retune() will return directly as host->card is null.
+* and CMD6 will retry 3 times, must ensure card is in transfer
+* state when retry.
+*/
+   tmo = jiffies + msecs_to_jiffies(60 * 1000);
+   while (1) {
+   if (msdc_card_busy(host->mmc)) {
+   if (in_interrupt()) {
+   udelay(1);
+   count++;
+   } else {
+   msleep_interruptible(10);
+   }
+   } else {
+   break;
+   }
+   /* Timeout if the device never
+* leaves the program state.
+*/
+   if (count > 1000 || time_after(jiffies, tmo)) {
+   pr_err("%s: Card stuck in programming state! 
%s\n",
+  mmc_hostname(host->mmc), __func__);
+   host->error |= REQ_CMD_BUSY;
+   msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
+   return false;
+   }
}
}
return true;
@@ -1070,18 +1107,6 @@ static int msdc_ops_switch_volt(struct mmc_host *mmc, 
struct mmc_ios *ios)
return ret;
 }
 
-static int msdc_card_busy(struct mmc_host *mmc)
-{
-   struct msdc_host *host = mmc_priv(mmc);
-   u32 status = readl(host->base + MSDC_PS);
-
-   /* check if any pin between dat[0:3] is low */
-   if (((status >> 16) & 0xf) != 0xf)
-   return 1;
-
-   return 0;
-}
-
 static void msdc_request_timeout(struct work_struct *work)
 {
struct msdc_host *host = container_of(work, struct msdc_host,
-- 
1.7.9.5



[PATCH 0/4] Support sdio feature

2016-11-07 Thread Yong Mao
Fix CMD6 timeout issue
Add irqlock to protect accessing the shared register
Modify the implementation of msdc_card_busy
Add msdc_recheck_sdio_irq mechanism
Support sdr104_clk_delay in sdio
Add description of mmc3 for supporting sdio feature

yong mao (4):
  mmc: mediatek: Fix CMD6 timeout issue
  sdio: mediatek: Support sdio feature
  sdio: mediatek: support sdr104_clk_delay in sdio
  dts: arm64: enable mmc3 for supporting sdio feature

 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |  82 +
 drivers/mmc/host/mtk-sd.c   | 254 +---
 2 files changed, 271 insertions(+), 65 deletions(-)

-- 
1.8.1.1.dirty



[PATCH 1/4] mmc: mediatek: Fix CMD6 timeout issue

2016-11-07 Thread Yong Mao
From: yong mao 

When initializing EMMC, after switch to HS400,
it will issue CMD6 to change ext_csd, if first CMD6 got CRC
error, the repeat CMD6 may get timeout, that's
because SDCBSY was cleared by msdc_reset_hw()

Signed-off-by: Yong Mao 
Signed-off-by: Chaotian Jing 
---
 drivers/mmc/host/mtk-sd.c |   77 ++---
 1 file changed, 51 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 84e9afc..b29683b 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -826,6 +826,15 @@ static bool msdc_cmd_done(struct msdc_host *host, int 
events,
return true;
 }
 
+static int msdc_card_busy(struct mmc_host *mmc)
+{
+   struct msdc_host *host = mmc_priv(mmc);
+   u32 status = readl(host->base + MSDC_PS);
+
+   /* check if data0 is low */
+   return !(status & BIT(16));
+}
+
 /* It is the core layer's responsibility to ensure card status
  * is correct before issue a request. but host design do below
  * checks recommended.
@@ -835,10 +844,20 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
*host,
 {
/* The max busy time we can endure is 20ms */
unsigned long tmo = jiffies + msecs_to_jiffies(20);
+   u32 count = 0;
+
+   if (in_interrupt()) {
+   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
+  (count < 1000)) {
+   udelay(1);
+   count++;
+   }
+   } else {
+   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
+  time_before(jiffies, tmo))
+   cpu_relax();
+   }
 
-   while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
-   time_before(jiffies, tmo))
-   cpu_relax();
if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
dev_err(host->dev, "CMD bus busy detected\n");
host->error |= REQ_CMD_BUSY;
@@ -846,17 +865,35 @@ static inline bool msdc_cmd_is_ready(struct msdc_host 
*host,
return false;
}
 
-   if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
-   tmo = jiffies + msecs_to_jiffies(20);
-   /* R1B or with data, should check SDCBUSY */
-   while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
-   time_before(jiffies, tmo))
-   cpu_relax();
-   if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
-   dev_err(host->dev, "Controller busy detected\n");
-   host->error |= REQ_CMD_BUSY;
-   msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
-   return false;
+   if (cmd->opcode != MMC_SEND_STATUS) {
+   count = 0;
+   /* Consider that CMD6 crc error before card was init done,
+* mmc_retune() will return directly as host->card is null.
+* and CMD6 will retry 3 times, must ensure card is in transfer
+* state when retry.
+*/
+   tmo = jiffies + msecs_to_jiffies(60 * 1000);
+   while (1) {
+   if (msdc_card_busy(host->mmc)) {
+   if (in_interrupt()) {
+   udelay(1);
+   count++;
+   } else {
+   msleep_interruptible(10);
+   }
+   } else {
+   break;
+   }
+   /* Timeout if the device never
+* leaves the program state.
+*/
+   if (count > 1000 || time_after(jiffies, tmo)) {
+   pr_err("%s: Card stuck in programming state! 
%s\n",
+  mmc_hostname(host->mmc), __func__);
+   host->error |= REQ_CMD_BUSY;
+   msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
+   return false;
+   }
}
}
return true;
@@ -1070,18 +1107,6 @@ static int msdc_ops_switch_volt(struct mmc_host *mmc, 
struct mmc_ios *ios)
return ret;
 }
 
-static int msdc_card_busy(struct mmc_host *mmc)
-{
-   struct msdc_host *host = mmc_priv(mmc);
-   u32 status = readl(host->base + MSDC_PS);
-
-   /* check if any pin between dat[0:3] is low */
-   if (((status >> 16) & 0xf) != 0xf)
-   return 1;
-
-   return 0;
-}
-
 static void msdc_request_timeout(struct work_struct *work)
 {
struct msdc_host *host = container_of(work, struct msdc_host,
-- 
1.7.9.5