All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-20  9:13 ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

Change in v2:
Drop the 400mhz and use assigned-clock-parents to instead
Split the original tune patch to several independent patches
Re-write the mmc_send_tuning()
Fix GPD checksum error
Move the HS400 setting to ops->prepare_hs400_tuning()	
Modify SD driving settings

Change in v1:
Add DT bindings for eMMC hardware reset
Add pinctrl of data strobe pin for HS400 mode
Modify eMMC driving settings
Add 400mhz source clock for HS400 mode
Add eMMC HS200/HS400 mode support
Add SD SDR50/SDR104 mode support
Add implement of tune function with CMD19/CMD21

Chaotian Jing (9):
  mmc: core: Add DT bindings for eMMC hardware reset support
  mmc: dt-bindings: update Mediatek MMC bindings
  mmc: mediatek: make cmd_ints_mask to const
  mmc: mediatek: change the argument "ddr" to "timing"
  mmc: mediatek: fix got GPD checksum error interrupt when data transfer
  mmc: mediatek: add implement of ops->hw_reset()
  mmc: mmc: extend the mmc_send_tuning()
  mmc: mediatek: add HS400 support
  arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support

 Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
 drivers/mmc/core/host.c                          |   2 +
 drivers/mmc/core/mmc_ops.c                       |   8 +-
 drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
 drivers/mmc/host/dw_mmc.c                        |   2 +-
 drivers/mmc/host/dw_mmc.h                        |   2 +-
 drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
 drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
 drivers/mmc/host/sdhci-msm.c                     |   2 +-
 drivers/mmc/host/sdhci-sirf.c                    |   2 +-
 include/linux/mmc/core.h                         |   2 +-
 13 files changed, 314 insertions(+), 51 deletions(-)

-- 
1.8.1.1.dirty


^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-20  9:13 ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

Change in v2:
Drop the 400mhz and use assigned-clock-parents to instead
Split the original tune patch to several independent patches
Re-write the mmc_send_tuning()
Fix GPD checksum error
Move the HS400 setting to ops->prepare_hs400_tuning()	
Modify SD driving settings

Change in v1:
Add DT bindings for eMMC hardware reset
Add pinctrl of data strobe pin for HS400 mode
Modify eMMC driving settings
Add 400mhz source clock for HS400 mode
Add eMMC HS200/HS400 mode support
Add SD SDR50/SDR104 mode support
Add implement of tune function with CMD19/CMD21

Chaotian Jing (9):
  mmc: core: Add DT bindings for eMMC hardware reset support
  mmc: dt-bindings: update Mediatek MMC bindings
  mmc: mediatek: make cmd_ints_mask to const
  mmc: mediatek: change the argument "ddr" to "timing"
  mmc: mediatek: fix got GPD checksum error interrupt when data transfer
  mmc: mediatek: add implement of ops->hw_reset()
  mmc: mmc: extend the mmc_send_tuning()
  mmc: mediatek: add HS400 support
  arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support

 Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
 drivers/mmc/core/host.c                          |   2 +
 drivers/mmc/core/mmc_ops.c                       |   8 +-
 drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
 drivers/mmc/host/dw_mmc.c                        |   2 +-
 drivers/mmc/host/dw_mmc.h                        |   2 +-
 drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
 drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
 drivers/mmc/host/sdhci-msm.c                     |   2 +-
 drivers/mmc/host/sdhci-sirf.c                    |   2 +-
 include/linux/mmc/core.h                         |   2 +-
 13 files changed, 314 insertions(+), 51 deletions(-)

-- 
1.8.1.1.dirty

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-20  9:13 ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Change in v2:
Drop the 400mhz and use assigned-clock-parents to instead
Split the original tune patch to several independent patches
Re-write the mmc_send_tuning()
Fix GPD checksum error
Move the HS400 setting to ops->prepare_hs400_tuning()	
Modify SD driving settings

Change in v1:
Add DT bindings for eMMC hardware reset
Add pinctrl of data strobe pin for HS400 mode
Modify eMMC driving settings
Add 400mhz source clock for HS400 mode
Add eMMC HS200/HS400 mode support
Add SD SDR50/SDR104 mode support
Add implement of tune function with CMD19/CMD21

Chaotian Jing (9):
  mmc: core: Add DT bindings for eMMC hardware reset support
  mmc: dt-bindings: update Mediatek MMC bindings
  mmc: mediatek: make cmd_ints_mask to const
  mmc: mediatek: change the argument "ddr" to "timing"
  mmc: mediatek: fix got GPD checksum error interrupt when data transfer
  mmc: mediatek: add implement of ops->hw_reset()
  mmc: mmc: extend the mmc_send_tuning()
  mmc: mediatek: add HS400 support
  arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support

 Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
 drivers/mmc/core/host.c                          |   2 +
 drivers/mmc/core/mmc_ops.c                       |   8 +-
 drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
 drivers/mmc/host/dw_mmc.c                        |   2 +-
 drivers/mmc/host/dw_mmc.h                        |   2 +-
 drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
 drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
 drivers/mmc/host/sdhci-msm.c                     |   2 +-
 drivers/mmc/host/sdhci-sirf.c                    |   2 +-
 include/linux/mmc/core.h                         |   2 +-
 13 files changed, 314 insertions(+), 51 deletions(-)

-- 
1.8.1.1.dirty

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 1/9] mmc: core: Add DT bindings for eMMC hardware reset support
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

Sometime only need set MMC_CAP_HW_RESET for one of MMC hosts,
So set it in device tree is better.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 1 +
 drivers/mmc/core/host.c                       | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 0384fc3..f693baf 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -37,6 +37,7 @@ Optional properties:
 - sd-uhs-sdr104: SD UHS SDR104 speed is supported
 - sd-uhs-ddr50: SD UHS DDR50 speed is supported
 - cap-power-off-card: powering off the card is safe
+- cap-mmc-hw-reset: eMMC hardware reset is supported
 - cap-sdio-irq: enable SDIO IRQ signalling on this interface
 - full-pwr-cycle: full power cycle of the card is supported
 - mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index abd933b..04fdc2f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -507,6 +507,8 @@ int mmc_of_parse(struct mmc_host *host)
 		host->caps |= MMC_CAP_UHS_DDR50;
 	if (of_property_read_bool(np, "cap-power-off-card"))
 		host->caps |= MMC_CAP_POWER_OFF_CARD;
+	if (of_property_read_bool(np, "cap-mmc-hw-reset"))
+		host->caps |= MMC_CAP_HW_RESET;
 	if (of_property_read_bool(np, "cap-sdio-irq"))
 		host->caps |= MMC_CAP_SDIO_IRQ;
 	if (of_property_read_bool(np, "full-pwr-cycle"))
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 1/9] mmc: core: Add DT bindings for eMMC hardware reset support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

Sometime only need set MMC_CAP_HW_RESET for one of MMC hosts,
So set it in device tree is better.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 1 +
 drivers/mmc/core/host.c                       | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 0384fc3..f693baf 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -37,6 +37,7 @@ Optional properties:
 - sd-uhs-sdr104: SD UHS SDR104 speed is supported
 - sd-uhs-ddr50: SD UHS DDR50 speed is supported
 - cap-power-off-card: powering off the card is safe
+- cap-mmc-hw-reset: eMMC hardware reset is supported
 - cap-sdio-irq: enable SDIO IRQ signalling on this interface
 - full-pwr-cycle: full power cycle of the card is supported
 - mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index abd933b..04fdc2f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -507,6 +507,8 @@ int mmc_of_parse(struct mmc_host *host)
 		host->caps |= MMC_CAP_UHS_DDR50;
 	if (of_property_read_bool(np, "cap-power-off-card"))
 		host->caps |= MMC_CAP_POWER_OFF_CARD;
+	if (of_property_read_bool(np, "cap-mmc-hw-reset"))
+		host->caps |= MMC_CAP_HW_RESET;
 	if (of_property_read_bool(np, "cap-sdio-irq"))
 		host->caps |= MMC_CAP_SDIO_IRQ;
 	if (of_property_read_bool(np, "full-pwr-cycle"))
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 1/9] mmc: core: Add DT bindings for eMMC hardware reset support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Sometime only need set MMC_CAP_HW_RESET for one of MMC hosts,
So set it in device tree is better.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 1 +
 drivers/mmc/core/host.c                       | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 0384fc3..f693baf 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -37,6 +37,7 @@ Optional properties:
 - sd-uhs-sdr104: SD UHS SDR104 speed is supported
 - sd-uhs-ddr50: SD UHS DDR50 speed is supported
 - cap-power-off-card: powering off the card is safe
+- cap-mmc-hw-reset: eMMC hardware reset is supported
 - cap-sdio-irq: enable SDIO IRQ signalling on this interface
 - full-pwr-cycle: full power cycle of the card is supported
 - mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index abd933b..04fdc2f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -507,6 +507,8 @@ int mmc_of_parse(struct mmc_host *host)
 		host->caps |= MMC_CAP_UHS_DDR50;
 	if (of_property_read_bool(np, "cap-power-off-card"))
 		host->caps |= MMC_CAP_POWER_OFF_CARD;
+	if (of_property_read_bool(np, "cap-mmc-hw-reset"))
+		host->caps |= MMC_CAP_HW_RESET;
 	if (of_property_read_bool(np, "cap-sdio-irq"))
 		host->caps |= MMC_CAP_SDIO_IRQ;
 	if (of_property_read_bool(np, "full-pwr-cycle"))
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 2/9] mmc: dt-bindings: update Mediatek MMC bindings
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

Add 400Mhz clock source for HS400 mode

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index a1adfa4..0120c7f 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -17,6 +17,11 @@ Required properties:
 - vmmc-supply: power to the Core
 - vqmmc-supply: power to the IO
 
+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
+
 Examples:
 mmc0: mmc@11230000 {
 	compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc";
@@ -24,9 +29,13 @@ mmc0: mmc@11230000 {
 	interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
-	clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
+	clocks = <&pericfg CLK_PERI_MSDC30_0>,
+	         <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
 	clock-names = "source", "hclk";
 	pinctrl-names = "default", "state_uhs";
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+	hs400-ds-delay = <0x14015>;
 };
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 2/9] mmc: dt-bindings: update Mediatek MMC bindings
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

Add 400Mhz clock source for HS400 mode

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index a1adfa4..0120c7f 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -17,6 +17,11 @@ Required properties:
 - vmmc-supply: power to the Core
 - vqmmc-supply: power to the IO
 
+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
+
 Examples:
 mmc0: mmc@11230000 {
 	compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc";
@@ -24,9 +29,13 @@ mmc0: mmc@11230000 {
 	interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
-	clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
+	clocks = <&pericfg CLK_PERI_MSDC30_0>,
+	         <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
 	clock-names = "source", "hclk";
 	pinctrl-names = "default", "state_uhs";
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+	hs400-ds-delay = <0x14015>;
 };
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 2/9] mmc: dt-bindings: update Mediatek MMC bindings
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Add 400Mhz clock source for HS400 mode

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index a1adfa4..0120c7f 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -17,6 +17,11 @@ Required properties:
 - vmmc-supply: power to the Core
 - vqmmc-supply: power to the IO
 
+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
+
 Examples:
 mmc0: mmc at 11230000 {
 	compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc";
@@ -24,9 +29,13 @@ mmc0: mmc at 11230000 {
 	interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
-	clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
+	clocks = <&pericfg CLK_PERI_MSDC30_0>,
+	         <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
 	clock-names = "source", "hclk";
 	pinctrl-names = "default", "state_uhs";
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+	hs400-ds-delay = <0x14015>;
 };
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 3/9] mmc: mediatek: make cmd_ints_mask to const
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

cmd_ints_mask and data_ints_mask are constant value,
so make it to const

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b2e89d3..8b3e15d 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -353,7 +353,10 @@ 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 u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
+			MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
+			MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
+static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
 			MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
 			MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
 
@@ -725,10 +728,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	if (done)
 		return true;
 
-	sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -818,10 +818,7 @@ static void msdc_start_command(struct msdc_host *host,
 	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
 	mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
 
-	sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 	writel(cmd->arg, host->base + SDC_ARG);
 	writel(rawcmd, host->base + SDC_CMD);
 }
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 3/9] mmc: mediatek: make cmd_ints_mask to const
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

cmd_ints_mask and data_ints_mask are constant value,
so make it to const

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b2e89d3..8b3e15d 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -353,7 +353,10 @@ 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 u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
+			MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
+			MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
+static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
 			MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
 			MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
 
@@ -725,10 +728,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	if (done)
 		return true;
 
-	sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -818,10 +818,7 @@ static void msdc_start_command(struct msdc_host *host,
 	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
 	mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
 
-	sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 	writel(cmd->arg, host->base + SDC_ARG);
 	writel(rawcmd, host->base + SDC_CMD);
 }
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 3/9] mmc: mediatek: make cmd_ints_mask to const
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

cmd_ints_mask and data_ints_mask are constant value,
so make it to const

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b2e89d3..8b3e15d 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -353,7 +353,10 @@ 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 u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
+			MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
+			MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
+static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
 			MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
 			MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
 
@@ -725,10 +728,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	if (done)
 		return true;
 
-	sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -818,10 +818,7 @@ static void msdc_start_command(struct msdc_host *host,
 	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
 	mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
 
-	sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 	writel(cmd->arg, host->base + SDC_ARG);
 	writel(rawcmd, host->base + SDC_CMD);
 }
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 4/9] mmc: mediatek: change the argument "ddr" to "timing"
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

use the ios->timing directly is better
It can reflect current timing and do settings by timing

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 8b3e15d..c877ded 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -297,7 +297,7 @@ struct msdc_host {
 	u32 mclk;		/* mmc subsystem clock frequency */
 	u32 src_clk_freq;	/* source clock frequency */
 	u32 sclk;		/* SD/MS bus clock frequency */
-	bool ddr;
+	unsigned char timing;
 	bool vqmmc_enabled;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
@@ -488,7 +488,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
 		cpu_relax();
 }
 
-static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
+static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 {
 	u32 mode;
 	u32 flags;
@@ -504,7 +504,8 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	if (ddr) { /* may need to modify later */
+	if (timing == MMC_TIMING_UHS_DDR50 ||
+	    timing == MMC_TIMING_MMC_DDR52) {
 		mode = 0x2; /* ddr mode and use divisor */
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
@@ -535,12 +536,12 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 		cpu_relax();
 	host->sclk = sclk;
 	host->mclk = hz;
-	host->ddr = ddr;
+	host->timing = timing;
 	/* need because clk changed. */
 	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
 	sdr_set_bits(host->base + MSDC_INTEN, flags);
 
-	dev_dbg(host->dev, "sclk: %d, ddr: %d\n", host->sclk, ddr);
+	dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
 static inline u32 msdc_cmd_find_resp(struct msdc_host *host,
@@ -1158,14 +1159,9 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
-	u32 ddr = 0;
 
 	pm_runtime_get_sync(host->dev);
 
-	if (ios->timing == MMC_TIMING_UHS_DDR50 ||
-	    ios->timing == MMC_TIMING_MMC_DDR52)
-		ddr = 1;
-
 	msdc_set_buswidth(host, ios->bus_width);
 
 	/* Suspend/Resume will do power off/on */
@@ -1202,8 +1198,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		break;
 	}
 
-	if (host->mclk != ios->clock || host->ddr != ddr)
-		msdc_set_mclk(host, ddr, ios->clock);
+	if (host->mclk != ios->clock || host->timing != ios->timing)
+		msdc_set_mclk(host, ios->timing, ios->clock);
 
 end:
 	pm_runtime_mark_last_busy(host->dev);
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 4/9] mmc: mediatek: change the argument "ddr" to "timing"
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Mark Rutland, Krzysztof Kozlowski, Seungwon Jeon,
	Catalin Marinas, Will Deacon, linux-kernel, Minda Chen,
	Dong Aisheng, Lars-Peter Clausen, Weijun Yang, Jaehoon Chung,
	linux-samsung-soc, Howard Chen, Kukjin Kim, linux-arm-kernel,
	linux-mmc, ivan.ivanov, devicetree, Pawel Moll, Ian Campbell,
	Sascha Hauer, Hans de Goede, Rob Herring, linux-mediatek,
	Matthias Brugger

use the ios->timing directly is better
It can reflect current timing and do settings by timing

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 8b3e15d..c877ded 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -297,7 +297,7 @@ struct msdc_host {
 	u32 mclk;		/* mmc subsystem clock frequency */
 	u32 src_clk_freq;	/* source clock frequency */
 	u32 sclk;		/* SD/MS bus clock frequency */
-	bool ddr;
+	unsigned char timing;
 	bool vqmmc_enabled;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
@@ -488,7 +488,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
 		cpu_relax();
 }
 
-static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
+static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 {
 	u32 mode;
 	u32 flags;
@@ -504,7 +504,8 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	if (ddr) { /* may need to modify later */
+	if (timing == MMC_TIMING_UHS_DDR50 ||
+	    timing == MMC_TIMING_MMC_DDR52) {
 		mode = 0x2; /* ddr mode and use divisor */
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
@@ -535,12 +536,12 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 		cpu_relax();
 	host->sclk = sclk;
 	host->mclk = hz;
-	host->ddr = ddr;
+	host->timing = timing;
 	/* need because clk changed. */
 	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
 	sdr_set_bits(host->base + MSDC_INTEN, flags);
 
-	dev_dbg(host->dev, "sclk: %d, ddr: %d\n", host->sclk, ddr);
+	dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
 static inline u32 msdc_cmd_find_resp(struct msdc_host *host,
@@ -1158,14 +1159,9 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
-	u32 ddr = 0;
 
 	pm_runtime_get_sync(host->dev);
 
-	if (ios->timing == MMC_TIMING_UHS_DDR50 ||
-	    ios->timing == MMC_TIMING_MMC_DDR52)
-		ddr = 1;
-
 	msdc_set_buswidth(host, ios->bus_width);
 
 	/* Suspend/Resume will do power off/on */
@@ -1202,8 +1198,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		break;
 	}
 
-	if (host->mclk != ios->clock || host->ddr != ddr)
-		msdc_set_mclk(host, ddr, ios->clock);
+	if (host->mclk != ios->clock || host->timing != ios->timing)
+		msdc_set_mclk(host, ios->timing, ios->clock);
 
 end:
 	pm_runtime_mark_last_busy(host->dev);
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 4/9] mmc: mediatek: change the argument "ddr" to "timing"
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

use the ios->timing directly is better
It can reflect current timing and do settings by timing

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 8b3e15d..c877ded 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -297,7 +297,7 @@ struct msdc_host {
 	u32 mclk;		/* mmc subsystem clock frequency */
 	u32 src_clk_freq;	/* source clock frequency */
 	u32 sclk;		/* SD/MS bus clock frequency */
-	bool ddr;
+	unsigned char timing;
 	bool vqmmc_enabled;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
@@ -488,7 +488,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
 		cpu_relax();
 }
 
-static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
+static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 {
 	u32 mode;
 	u32 flags;
@@ -504,7 +504,8 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	if (ddr) { /* may need to modify later */
+	if (timing == MMC_TIMING_UHS_DDR50 ||
+	    timing == MMC_TIMING_MMC_DDR52) {
 		mode = 0x2; /* ddr mode and use divisor */
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
@@ -535,12 +536,12 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 		cpu_relax();
 	host->sclk = sclk;
 	host->mclk = hz;
-	host->ddr = ddr;
+	host->timing = timing;
 	/* need because clk changed. */
 	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
 	sdr_set_bits(host->base + MSDC_INTEN, flags);
 
-	dev_dbg(host->dev, "sclk: %d, ddr: %d\n", host->sclk, ddr);
+	dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
 static inline u32 msdc_cmd_find_resp(struct msdc_host *host,
@@ -1158,14 +1159,9 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
-	u32 ddr = 0;
 
 	pm_runtime_get_sync(host->dev);
 
-	if (ios->timing == MMC_TIMING_UHS_DDR50 ||
-	    ios->timing == MMC_TIMING_MMC_DDR52)
-		ddr = 1;
-
 	msdc_set_buswidth(host, ios->bus_width);
 
 	/* Suspend/Resume will do power off/on */
@@ -1202,8 +1198,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		break;
 	}
 
-	if (host->mclk != ios->clock || host->ddr != ddr)
-		msdc_set_mclk(host, ddr, ios->clock);
+	if (host->mclk != ios->clock || host->timing != ios->timing)
+		msdc_set_mclk(host, ios->timing, ios->clock);
 
 end:
 	pm_runtime_mark_last_busy(host->dev);
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 5/9] mmc: mediatek: fix got GPD checksum error interrupt when data transfer
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

Even if we only use one gpd, we need alloc 2 gpd and make
the gpd->next pointer to the second gpd, or may get gpd checksum
error, this was checked by hardware

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index c877ded..3858163 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1145,11 +1145,14 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
 	struct mt_bdma_desc *bd = dma->bd;
 	int i;
 
-	memset(gpd, 0, sizeof(struct mt_gpdma_desc));
+	memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2);
 
 	gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */
 	gpd->ptr = (u32)dma->bd_addr; /* physical address */
-
+	/* gpd->next is must set for desc DMA
+	 * That's why must alloc 2 gpd structure.
+	 */
+	gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc);
 	memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM);
 	for (i = 0; i < (MAX_BD_NUM - 1); i++)
 		bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1);
@@ -1306,7 +1309,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
 
 	host->timeout_clks = 3 * 1048576;
 	host->dma.gpd = dma_alloc_coherent(&pdev->dev,
-				sizeof(struct mt_gpdma_desc),
+				2 * sizeof(struct mt_gpdma_desc),
 				&host->dma.gpd_addr, GFP_KERNEL);
 	host->dma.bd = dma_alloc_coherent(&pdev->dev,
 				MAX_BD_NUM * sizeof(struct mt_bdma_desc),
@@ -1347,7 +1350,7 @@ release:
 release_mem:
 	if (host->dma.gpd)
 		dma_free_coherent(&pdev->dev,
-			sizeof(struct mt_gpdma_desc),
+			2 * sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
 	if (host->dma.bd)
 		dma_free_coherent(&pdev->dev,
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 5/9] mmc: mediatek: fix got GPD checksum error interrupt when data transfer
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Mark Rutland, Krzysztof Kozlowski, Seungwon Jeon,
	Catalin Marinas, Will Deacon, linux-kernel, Minda Chen,
	Dong Aisheng, Lars-Peter Clausen, Weijun Yang, Jaehoon Chung,
	linux-samsung-soc, Howard Chen, Kukjin Kim, linux-arm-kernel,
	linux-mmc, ivan.ivanov, devicetree, Pawel Moll, Ian Campbell,
	Sascha Hauer, Hans de Goede, Rob Herring, linux-mediatek,
	Matthias Brugger

Even if we only use one gpd, we need alloc 2 gpd and make
the gpd->next pointer to the second gpd, or may get gpd checksum
error, this was checked by hardware

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index c877ded..3858163 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1145,11 +1145,14 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
 	struct mt_bdma_desc *bd = dma->bd;
 	int i;
 
-	memset(gpd, 0, sizeof(struct mt_gpdma_desc));
+	memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2);
 
 	gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */
 	gpd->ptr = (u32)dma->bd_addr; /* physical address */
-
+	/* gpd->next is must set for desc DMA
+	 * That's why must alloc 2 gpd structure.
+	 */
+	gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc);
 	memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM);
 	for (i = 0; i < (MAX_BD_NUM - 1); i++)
 		bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1);
@@ -1306,7 +1309,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
 
 	host->timeout_clks = 3 * 1048576;
 	host->dma.gpd = dma_alloc_coherent(&pdev->dev,
-				sizeof(struct mt_gpdma_desc),
+				2 * sizeof(struct mt_gpdma_desc),
 				&host->dma.gpd_addr, GFP_KERNEL);
 	host->dma.bd = dma_alloc_coherent(&pdev->dev,
 				MAX_BD_NUM * sizeof(struct mt_bdma_desc),
@@ -1347,7 +1350,7 @@ release:
 release_mem:
 	if (host->dma.gpd)
 		dma_free_coherent(&pdev->dev,
-			sizeof(struct mt_gpdma_desc),
+			2 * sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
 	if (host->dma.bd)
 		dma_free_coherent(&pdev->dev,
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 5/9] mmc: mediatek: fix got GPD checksum error interrupt when data transfer
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Even if we only use one gpd, we need alloc 2 gpd and make
the gpd->next pointer to the second gpd, or may get gpd checksum
error, this was checked by hardware

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index c877ded..3858163 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1145,11 +1145,14 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
 	struct mt_bdma_desc *bd = dma->bd;
 	int i;
 
-	memset(gpd, 0, sizeof(struct mt_gpdma_desc));
+	memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2);
 
 	gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */
 	gpd->ptr = (u32)dma->bd_addr; /* physical address */
-
+	/* gpd->next is must set for desc DMA
+	 * That's why must alloc 2 gpd structure.
+	 */
+	gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc);
 	memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM);
 	for (i = 0; i < (MAX_BD_NUM - 1); i++)
 		bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1);
@@ -1306,7 +1309,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
 
 	host->timeout_clks = 3 * 1048576;
 	host->dma.gpd = dma_alloc_coherent(&pdev->dev,
-				sizeof(struct mt_gpdma_desc),
+				2 * sizeof(struct mt_gpdma_desc),
 				&host->dma.gpd_addr, GFP_KERNEL);
 	host->dma.bd = dma_alloc_coherent(&pdev->dev,
 				MAX_BD_NUM * sizeof(struct mt_bdma_desc),
@@ -1347,7 +1350,7 @@ release:
 release_mem:
 	if (host->dma.gpd)
 		dma_free_coherent(&pdev->dev,
-			sizeof(struct mt_gpdma_desc),
+			2 * sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
 	if (host->dma.bd)
 		dma_free_coherent(&pdev->dev,
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 6/9] mmc: mediatek: add implement of ops->hw_reset()
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

add implement of ops->hw_reset() for eMMC

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 3858163..5627644 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -64,6 +64,7 @@
 #define SDC_RESP2        0x48
 #define SDC_RESP3        0x4c
 #define SDC_BLK_NUM      0x50
+#define EMMC_IOCON       0x7c
 #define SDC_ACMD_RESP    0x80
 #define MSDC_DMA_SA      0x90
 #define MSDC_DMA_CTRL    0x98
@@ -1209,6 +1210,15 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static void msdc_hw_reset(struct mmc_host *mmc)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	sdr_set_bits(host->base + EMMC_IOCON, 1);
+	udelay(10); /* 10us is enough */
+	sdr_clr_bits(host->base + EMMC_IOCON, 1);
+}
+
 static struct mmc_host_ops mt_msdc_ops = {
 	.post_req = msdc_post_req,
 	.pre_req = msdc_pre_req,
@@ -1216,6 +1226,7 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.hw_reset = msdc_hw_reset,
 };
 
 static int msdc_drv_probe(struct platform_device *pdev)
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 6/9] mmc: mediatek: add implement of ops->hw_reset()
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Mark Rutland, Krzysztof Kozlowski, Seungwon Jeon,
	Catalin Marinas, Will Deacon, linux-kernel, Minda Chen,
	Dong Aisheng, Lars-Peter Clausen, Weijun Yang, Jaehoon Chung,
	linux-samsung-soc, Howard Chen, Kukjin Kim, linux-arm-kernel,
	linux-mmc, ivan.ivanov, devicetree, Pawel Moll, Ian Campbell,
	Sascha Hauer, Hans de Goede, Rob Herring, linux-mediatek,
	Matthias Brugger

add implement of ops->hw_reset() for eMMC

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 3858163..5627644 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -64,6 +64,7 @@
 #define SDC_RESP2        0x48
 #define SDC_RESP3        0x4c
 #define SDC_BLK_NUM      0x50
+#define EMMC_IOCON       0x7c
 #define SDC_ACMD_RESP    0x80
 #define MSDC_DMA_SA      0x90
 #define MSDC_DMA_CTRL    0x98
@@ -1209,6 +1210,15 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static void msdc_hw_reset(struct mmc_host *mmc)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	sdr_set_bits(host->base + EMMC_IOCON, 1);
+	udelay(10); /* 10us is enough */
+	sdr_clr_bits(host->base + EMMC_IOCON, 1);
+}
+
 static struct mmc_host_ops mt_msdc_ops = {
 	.post_req = msdc_post_req,
 	.pre_req = msdc_pre_req,
@@ -1216,6 +1226,7 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.hw_reset = msdc_hw_reset,
 };
 
 static int msdc_drv_probe(struct platform_device *pdev)
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 6/9] mmc: mediatek: add implement of ops->hw_reset()
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

add implement of ops->hw_reset() for eMMC

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>

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

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 3858163..5627644 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -64,6 +64,7 @@
 #define SDC_RESP2        0x48
 #define SDC_RESP3        0x4c
 #define SDC_BLK_NUM      0x50
+#define EMMC_IOCON       0x7c
 #define SDC_ACMD_RESP    0x80
 #define MSDC_DMA_SA      0x90
 #define MSDC_DMA_CTRL    0x98
@@ -1209,6 +1210,15 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static void msdc_hw_reset(struct mmc_host *mmc)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	sdr_set_bits(host->base + EMMC_IOCON, 1);
+	udelay(10); /* 10us is enough */
+	sdr_clr_bits(host->base + EMMC_IOCON, 1);
+}
+
 static struct mmc_host_ops mt_msdc_ops = {
 	.post_req = msdc_post_req,
 	.pre_req = msdc_pre_req,
@@ -1216,6 +1226,7 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.hw_reset = msdc_hw_reset,
 };
 
 static int msdc_drv_probe(struct platform_device *pdev)
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 7/9] mmc: mmc: extend the mmc_send_tuning()
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

The mmc_execute_tuning() has already prepared the opcode,
there is no need to prepare it again at mmc_send_tuning(),
and, there is a BUG of mmc_send_tuning() to determine the opcode
by bus width, assume eMMC was running at HS200, 4bit mode,
then the mmc_send_tuning() will overwrite the opcode from CMD21
to CMD19, then got error.

in addition, extend an argument of "cmd_error" to allow getting
if there was cmd error when tune response.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/core/mmc_ops.c         | 8 ++++----
 drivers/mmc/host/dw_mmc-exynos.c   | 4 ++--
 drivers/mmc/host/dw_mmc.c          | 2 +-
 drivers/mmc/host/dw_mmc.h          | 2 +-
 drivers/mmc/host/sdhci-esdhc-imx.c | 6 +++---
 drivers/mmc/host/sdhci-msm.c       | 2 +-
 drivers/mmc/host/sdhci-sirf.c      | 2 +-
 include/linux/mmc/core.h           | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0e9ae1c..4305f75 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -589,7 +589,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 }
 EXPORT_SYMBOL_GPL(mmc_switch);
 
-int mmc_send_tuning(struct mmc_host *host)
+int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
 {
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
@@ -599,16 +599,13 @@ int mmc_send_tuning(struct mmc_host *host)
 	const u8 *tuning_block_pattern;
 	int size, err = 0;
 	u8 *data_buf;
-	u32 opcode;
 
 	if (ios->bus_width == MMC_BUS_WIDTH_8) {
 		tuning_block_pattern = tuning_blk_pattern_8bit;
 		size = sizeof(tuning_blk_pattern_8bit);
-		opcode = MMC_SEND_TUNING_BLOCK_HS200;
 	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
 		tuning_block_pattern = tuning_blk_pattern_4bit;
 		size = sizeof(tuning_blk_pattern_4bit);
-		opcode = MMC_SEND_TUNING_BLOCK;
 	} else
 		return -EINVAL;
 
@@ -639,6 +636,9 @@ int mmc_send_tuning(struct mmc_host *host)
 
 	mmc_wait_for_req(host, &mrq);
 
+	if (cmd_error)
+		*cmd_error = cmd.error;
+
 	if (cmd.error) {
 		err = cmd.error;
 		goto out;
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 1e75309..3a7e835 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -446,7 +446,7 @@ out:
 	return loc;
 }
 
-static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
+static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
 {
 	struct dw_mci *host = slot->host;
 	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -461,7 +461,7 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 		mci_writel(host, TMOUT, ~0);
 		smpl = dw_mci_exynos_move_next_clksmpl(host);
 
-		if (!mmc_send_tuning(mmc))
+		if (!mmc_send_tuning(mmc, opcode, NULL))
 			candiates |= (1 << smpl);
 
 	} while (start_smpl != smpl);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..be8441d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1427,7 +1427,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	int err = -EINVAL;
 
 	if (drv_data && drv_data->execute_tuning)
-		err = drv_data->execute_tuning(slot);
+		err = drv_data->execute_tuning(slot, opcode);
 	return err;
 }
 
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 8ce4674..394340f 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -281,7 +281,7 @@ struct dw_mci_drv_data {
 	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
 	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
 	int		(*parse_dt)(struct dw_mci *host);
-	int		(*execute_tuning)(struct dw_mci_slot *slot);
+	int		(*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
 	int		(*prepare_hs400_tuning)(struct dw_mci *host,
 						struct mmc_ios *ios);
 	int		(*switch_voltage)(struct mmc_host *mmc,
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 886d230..1f1582f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -759,7 +759,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	min = ESDHC_TUNE_CTRL_MIN;
 	while (min < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, min);
-		if (!mmc_send_tuning(host->mmc))
+		if (!mmc_send_tuning(host->mmc, opcode, NULL))
 			break;
 		min += ESDHC_TUNE_CTRL_STEP;
 	}
@@ -768,7 +768,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	max = min + ESDHC_TUNE_CTRL_STEP;
 	while (max < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, max);
-		if (mmc_send_tuning(host->mmc)) {
+		if (mmc_send_tuning(host->mmc, opcode, NULL)) {
 			max -= ESDHC_TUNE_CTRL_STEP;
 			break;
 		}
@@ -778,7 +778,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	/* use average delay to get the best timing */
 	avg = (min + max) / 2;
 	esdhc_prepare_tuning(host, avg);
-	ret = mmc_send_tuning(host->mmc);
+	ret = mmc_send_tuning(host->mmc, opcode, NULL);
 	esdhc_post_tuning(host);
 
 	dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 4bcee03..4695bee 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -373,7 +373,7 @@ retry:
 		if (rc)
 			return rc;
 
-		rc = mmc_send_tuning(mmc);
+		rc = mmc_send_tuning(mmc, opcode, NULL);
 		if (!rc) {
 			/* Tuning is successful at this tuning point */
 			tuned_phases[tuned_phase_cnt++] = phase;
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 8842945..d0c7ffe 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -97,7 +97,7 @@ retry:
 			clock_setting | phase,
 			SDHCI_CLK_DELAY_SETTING);
 
-		if (!mmc_send_tuning(mmc)) {
+		if (!mmc_send_tuning(mmc, opcode, NULL)) {
 			/* Tuning is successful at this tuning point */
 			tuned_phase_cnt++;
 			dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 258daf9..43a283a 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -155,7 +155,7 @@ extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
 extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
 			bool, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
-extern int mmc_send_tuning(struct mmc_host *host);
+extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
 extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
 
 #define MMC_ERASE_ARG		0x00000000
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 7/9] mmc: mmc: extend the mmc_send_tuning()
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

The mmc_execute_tuning() has already prepared the opcode,
there is no need to prepare it again at mmc_send_tuning(),
and, there is a BUG of mmc_send_tuning() to determine the opcode
by bus width, assume eMMC was running at HS200, 4bit mode,
then the mmc_send_tuning() will overwrite the opcode from CMD21
to CMD19, then got error.

in addition, extend an argument of "cmd_error" to allow getting
if there was cmd error when tune response.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/core/mmc_ops.c         | 8 ++++----
 drivers/mmc/host/dw_mmc-exynos.c   | 4 ++--
 drivers/mmc/host/dw_mmc.c          | 2 +-
 drivers/mmc/host/dw_mmc.h          | 2 +-
 drivers/mmc/host/sdhci-esdhc-imx.c | 6 +++---
 drivers/mmc/host/sdhci-msm.c       | 2 +-
 drivers/mmc/host/sdhci-sirf.c      | 2 +-
 include/linux/mmc/core.h           | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0e9ae1c..4305f75 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -589,7 +589,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 }
 EXPORT_SYMBOL_GPL(mmc_switch);
 
-int mmc_send_tuning(struct mmc_host *host)
+int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
 {
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
@@ -599,16 +599,13 @@ int mmc_send_tuning(struct mmc_host *host)
 	const u8 *tuning_block_pattern;
 	int size, err = 0;
 	u8 *data_buf;
-	u32 opcode;
 
 	if (ios->bus_width == MMC_BUS_WIDTH_8) {
 		tuning_block_pattern = tuning_blk_pattern_8bit;
 		size = sizeof(tuning_blk_pattern_8bit);
-		opcode = MMC_SEND_TUNING_BLOCK_HS200;
 	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
 		tuning_block_pattern = tuning_blk_pattern_4bit;
 		size = sizeof(tuning_blk_pattern_4bit);
-		opcode = MMC_SEND_TUNING_BLOCK;
 	} else
 		return -EINVAL;
 
@@ -639,6 +636,9 @@ int mmc_send_tuning(struct mmc_host *host)
 
 	mmc_wait_for_req(host, &mrq);
 
+	if (cmd_error)
+		*cmd_error = cmd.error;
+
 	if (cmd.error) {
 		err = cmd.error;
 		goto out;
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 1e75309..3a7e835 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -446,7 +446,7 @@ out:
 	return loc;
 }
 
-static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
+static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
 {
 	struct dw_mci *host = slot->host;
 	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -461,7 +461,7 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 		mci_writel(host, TMOUT, ~0);
 		smpl = dw_mci_exynos_move_next_clksmpl(host);
 
-		if (!mmc_send_tuning(mmc))
+		if (!mmc_send_tuning(mmc, opcode, NULL))
 			candiates |= (1 << smpl);
 
 	} while (start_smpl != smpl);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..be8441d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1427,7 +1427,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	int err = -EINVAL;
 
 	if (drv_data && drv_data->execute_tuning)
-		err = drv_data->execute_tuning(slot);
+		err = drv_data->execute_tuning(slot, opcode);
 	return err;
 }
 
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 8ce4674..394340f 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -281,7 +281,7 @@ struct dw_mci_drv_data {
 	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
 	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
 	int		(*parse_dt)(struct dw_mci *host);
-	int		(*execute_tuning)(struct dw_mci_slot *slot);
+	int		(*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
 	int		(*prepare_hs400_tuning)(struct dw_mci *host,
 						struct mmc_ios *ios);
 	int		(*switch_voltage)(struct mmc_host *mmc,
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 886d230..1f1582f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -759,7 +759,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	min = ESDHC_TUNE_CTRL_MIN;
 	while (min < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, min);
-		if (!mmc_send_tuning(host->mmc))
+		if (!mmc_send_tuning(host->mmc, opcode, NULL))
 			break;
 		min += ESDHC_TUNE_CTRL_STEP;
 	}
@@ -768,7 +768,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	max = min + ESDHC_TUNE_CTRL_STEP;
 	while (max < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, max);
-		if (mmc_send_tuning(host->mmc)) {
+		if (mmc_send_tuning(host->mmc, opcode, NULL)) {
 			max -= ESDHC_TUNE_CTRL_STEP;
 			break;
 		}
@@ -778,7 +778,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	/* use average delay to get the best timing */
 	avg = (min + max) / 2;
 	esdhc_prepare_tuning(host, avg);
-	ret = mmc_send_tuning(host->mmc);
+	ret = mmc_send_tuning(host->mmc, opcode, NULL);
 	esdhc_post_tuning(host);
 
 	dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 4bcee03..4695bee 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -373,7 +373,7 @@ retry:
 		if (rc)
 			return rc;
 
-		rc = mmc_send_tuning(mmc);
+		rc = mmc_send_tuning(mmc, opcode, NULL);
 		if (!rc) {
 			/* Tuning is successful at this tuning point */
 			tuned_phases[tuned_phase_cnt++] = phase;
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 8842945..d0c7ffe 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -97,7 +97,7 @@ retry:
 			clock_setting | phase,
 			SDHCI_CLK_DELAY_SETTING);
 
-		if (!mmc_send_tuning(mmc)) {
+		if (!mmc_send_tuning(mmc, opcode, NULL)) {
 			/* Tuning is successful at this tuning point */
 			tuned_phase_cnt++;
 			dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 258daf9..43a283a 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -155,7 +155,7 @@ extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
 extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
 			bool, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
-extern int mmc_send_tuning(struct mmc_host *host);
+extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
 extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
 
 #define MMC_ERASE_ARG		0x00000000
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 7/9] mmc: mmc: extend the mmc_send_tuning()
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

The mmc_execute_tuning() has already prepared the opcode,
there is no need to prepare it again at mmc_send_tuning(),
and, there is a BUG of mmc_send_tuning() to determine the opcode
by bus width, assume eMMC was running at HS200, 4bit mode,
then the mmc_send_tuning() will overwrite the opcode from CMD21
to CMD19, then got error.

in addition, extend an argument of "cmd_error" to allow getting
if there was cmd error when tune response.

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/core/mmc_ops.c         | 8 ++++----
 drivers/mmc/host/dw_mmc-exynos.c   | 4 ++--
 drivers/mmc/host/dw_mmc.c          | 2 +-
 drivers/mmc/host/dw_mmc.h          | 2 +-
 drivers/mmc/host/sdhci-esdhc-imx.c | 6 +++---
 drivers/mmc/host/sdhci-msm.c       | 2 +-
 drivers/mmc/host/sdhci-sirf.c      | 2 +-
 include/linux/mmc/core.h           | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0e9ae1c..4305f75 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -589,7 +589,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 }
 EXPORT_SYMBOL_GPL(mmc_switch);
 
-int mmc_send_tuning(struct mmc_host *host)
+int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
 {
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
@@ -599,16 +599,13 @@ int mmc_send_tuning(struct mmc_host *host)
 	const u8 *tuning_block_pattern;
 	int size, err = 0;
 	u8 *data_buf;
-	u32 opcode;
 
 	if (ios->bus_width == MMC_BUS_WIDTH_8) {
 		tuning_block_pattern = tuning_blk_pattern_8bit;
 		size = sizeof(tuning_blk_pattern_8bit);
-		opcode = MMC_SEND_TUNING_BLOCK_HS200;
 	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
 		tuning_block_pattern = tuning_blk_pattern_4bit;
 		size = sizeof(tuning_blk_pattern_4bit);
-		opcode = MMC_SEND_TUNING_BLOCK;
 	} else
 		return -EINVAL;
 
@@ -639,6 +636,9 @@ int mmc_send_tuning(struct mmc_host *host)
 
 	mmc_wait_for_req(host, &mrq);
 
+	if (cmd_error)
+		*cmd_error = cmd.error;
+
 	if (cmd.error) {
 		err = cmd.error;
 		goto out;
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 1e75309..3a7e835 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -446,7 +446,7 @@ out:
 	return loc;
 }
 
-static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
+static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
 {
 	struct dw_mci *host = slot->host;
 	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -461,7 +461,7 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 		mci_writel(host, TMOUT, ~0);
 		smpl = dw_mci_exynos_move_next_clksmpl(host);
 
-		if (!mmc_send_tuning(mmc))
+		if (!mmc_send_tuning(mmc, opcode, NULL))
 			candiates |= (1 << smpl);
 
 	} while (start_smpl != smpl);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..be8441d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1427,7 +1427,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	int err = -EINVAL;
 
 	if (drv_data && drv_data->execute_tuning)
-		err = drv_data->execute_tuning(slot);
+		err = drv_data->execute_tuning(slot, opcode);
 	return err;
 }
 
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 8ce4674..394340f 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -281,7 +281,7 @@ struct dw_mci_drv_data {
 	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
 	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
 	int		(*parse_dt)(struct dw_mci *host);
-	int		(*execute_tuning)(struct dw_mci_slot *slot);
+	int		(*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
 	int		(*prepare_hs400_tuning)(struct dw_mci *host,
 						struct mmc_ios *ios);
 	int		(*switch_voltage)(struct mmc_host *mmc,
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 886d230..1f1582f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -759,7 +759,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	min = ESDHC_TUNE_CTRL_MIN;
 	while (min < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, min);
-		if (!mmc_send_tuning(host->mmc))
+		if (!mmc_send_tuning(host->mmc, opcode, NULL))
 			break;
 		min += ESDHC_TUNE_CTRL_STEP;
 	}
@@ -768,7 +768,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	max = min + ESDHC_TUNE_CTRL_STEP;
 	while (max < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, max);
-		if (mmc_send_tuning(host->mmc)) {
+		if (mmc_send_tuning(host->mmc, opcode, NULL)) {
 			max -= ESDHC_TUNE_CTRL_STEP;
 			break;
 		}
@@ -778,7 +778,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	/* use average delay to get the best timing */
 	avg = (min + max) / 2;
 	esdhc_prepare_tuning(host, avg);
-	ret = mmc_send_tuning(host->mmc);
+	ret = mmc_send_tuning(host->mmc, opcode, NULL);
 	esdhc_post_tuning(host);
 
 	dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 4bcee03..4695bee 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -373,7 +373,7 @@ retry:
 		if (rc)
 			return rc;
 
-		rc = mmc_send_tuning(mmc);
+		rc = mmc_send_tuning(mmc, opcode, NULL);
 		if (!rc) {
 			/* Tuning is successful at this tuning point */
 			tuned_phases[tuned_phase_cnt++] = phase;
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 8842945..d0c7ffe 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -97,7 +97,7 @@ retry:
 			clock_setting | phase,
 			SDHCI_CLK_DELAY_SETTING);
 
-		if (!mmc_send_tuning(mmc)) {
+		if (!mmc_send_tuning(mmc, opcode, NULL)) {
 			/* Tuning is successful at this tuning point */
 			tuned_phase_cnt++;
 			dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 258daf9..43a283a 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -155,7 +155,7 @@ extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
 extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
 			bool, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
-extern int mmc_send_tuning(struct mmc_host *host);
+extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
 extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
 
 #define MMC_ERASE_ARG		0x00000000
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 8/9] mmc: mediatek: add HS400 support
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

add HS400 mode and tune support

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 241 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 236 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 5627644..528646c 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -26,6 +26,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <linux/mmc/card.h>
@@ -72,6 +73,8 @@
 #define MSDC_PATCH_BIT   0xb0
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE    0xec
+#define PAD_DS_TUNE      0x188
+#define EMMC50_CFG0      0x208
 
 /*--------------------------------------------------------------------------*/
 /* Register Mask                                                            */
@@ -88,6 +91,7 @@
 #define MSDC_CFG_CKSTB          (0x1 << 7)	/* R  */
 #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
 #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
+#define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
 
 /* MSDC_IOCON mask */
 #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
@@ -205,6 +209,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 PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
+#define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
+#define PAD_DS_TUNE_DLY3	  (0x1f << 12)  /* 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 */
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -220,6 +235,7 @@
 #define CMD_TIMEOUT         (HZ/10 * 5)	/* 100ms x5 */
 #define DAT_TIMEOUT         (HZ    * 5)	/* 1000ms x5 */
 
+#define PAD_DELAY_MAX	32 /* PAD delay cells */
 /*--------------------------------------------------------------------------*/
 /* Descriptor Structure                                                     */
 /*--------------------------------------------------------------------------*/
@@ -266,6 +282,14 @@ struct msdc_save_para {
 	u32 pad_tune;
 	u32 patch_bit0;
 	u32 patch_bit1;
+	u32 pad_ds_tune;
+	u32 emmc50_cfg0;
+};
+
+struct msdc_delay_phase {
+	u8 maxlen;
+	u8 start;
+	u8 final_phase;
 };
 
 struct msdc_host {
@@ -300,6 +324,7 @@ struct msdc_host {
 	u32 sclk;		/* SD/MS bus clock frequency */
 	unsigned char timing;
 	bool vqmmc_enabled;
+	u32 hs400_ds_delay;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
 
@@ -505,9 +530,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
+	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
 	if (timing == MMC_TIMING_UHS_DDR50 ||
-	    timing == MMC_TIMING_MMC_DDR52) {
-		mode = 0x2; /* ddr mode and use divisor */
+	    timing == MMC_TIMING_MMC_DDR52 ||
+	    timing == MMC_TIMING_MMC_HS400) {
+		if (timing == MMC_TIMING_MMC_HS400)
+			mode = 0x3;
+		else
+			mode = 0x2; /* ddr mode and use divisor */
+
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
 			sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
@@ -516,6 +547,13 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 			div = (div >> 1);
 		}
+
+		if (timing == MMC_TIMING_MMC_HS400 &&
+		    hz >= (host->src_clk_freq >> 1)) {
+			sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+			sclk = host->src_clk_freq >> 1;
+			div = 0; /* div is ignore when bit18 is set */
+		}
 	} else if (hz >= host->src_clk_freq) {
 		mode = 0x1; /* no divisor */
 		div = 0;
@@ -894,7 +932,7 @@ static void msdc_data_xfer_next(struct msdc_host *host,
 				struct mmc_request *mrq, struct mmc_data *data)
 {
 	if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error &&
-	    (!data->bytes_xfered || !mrq->sbc))
+	    !mrq->sbc)
 		msdc_start_command(host, mrq, mrq->stop);
 	else
 		msdc_request_done(host, mrq);
@@ -940,6 +978,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 
 			if (events & MSDC_INT_DATTMO)
 				data->error = -ETIMEDOUT;
+			else if (events & MSDC_INT_DATCRCERR)
+				data->error = -EILSEQ;
 
 			dev_err(host->dev, "%s: cmd=%d; blocks=%d",
 				__func__, mrq->cmd->opcode, data->blocks);
@@ -1111,10 +1151,12 @@ static void msdc_init_hw(struct msdc_host *host)
 
 	writel(0, host->base + MSDC_PAD_TUNE);
 	writel(0, host->base + MSDC_IOCON);
-	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
-	writel(0x403c004f, host->base + MSDC_PATCH_BIT);
+	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
+	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+
 	/* Configure to enable SDIO mode.
 	 * it's must otherwise sdio cmd5 failed
 	 */
@@ -1172,6 +1214,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc)) {
+			msdc_init_hw(host);
 			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
 					ios->vdd);
 			if (ret) {
@@ -1210,6 +1253,184 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static u32 test_delay_bit(u32 delay, u32 bit)
+{
+	bit %= PAD_DELAY_MAX;
+	return delay & (1 << bit);
+}
+
+static int get_delay_len(u32 delay, u32 start_bit)
+{
+	int i;
+
+	for (i = 0; i < (PAD_DELAY_MAX - start_bit); i++) {
+		if (test_delay_bit(delay, start_bit + i) == 0)
+			return i;
+	}
+	return PAD_DELAY_MAX - start_bit;
+}
+
+static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
+{
+	int start = 0, len = 0;
+	int start_final = 0, len_final = 0;
+	u8 final_phase = 0xff;
+	struct msdc_delay_phase delay_phase;
+
+	if (delay == 0) {
+		dev_err(host->dev, "phase error: [map:%x]\n", delay);
+		delay_phase.final_phase = final_phase;
+		return delay_phase;
+	}
+
+	while (start < PAD_DELAY_MAX) {
+		len = get_delay_len(delay, start);
+		if (len_final < len) {
+			start_final = start;
+			len_final = len;
+		}
+		start += len ? len : 1;
+		if (len >= 8 && start_final < 4)
+			break;
+	}
+
+	/* The rule is that to find the smallest delay cell */
+	if (start_final == 0)
+		final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
+	else
+		final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
+	dev_info(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
+		delay, len_final, final_phase);
+
+	delay_phase.maxlen = len_final;
+	delay_phase.start = start_final;
+	delay_phase.final_phase = final_phase;
+	return delay_phase;
+}
+
+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;
+	u8 final_delay, final_maxlen;
+	int cmd_err;
+	int i;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_tune_data(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;
+	u8 final_delay, final_maxlen;
+	int i, ret;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	/* Rising edge is more stable, prefer to use it */
+	if (final_rise_delay.maxlen >= 10)
+		final_maxlen = final_rise_delay.maxlen;
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	int ret;
+
+	pm_runtime_get_sync(host->dev);
+	ret = msdc_tune_response(mmc, opcode);
+	if (ret == -EIO) {
+		dev_err(host->dev, "Tune response fail!\n");
+		goto out;
+	}
+	ret = msdc_tune_data(mmc, opcode);
+	if (ret == -EIO)
+		dev_err(host->dev, "Tune data fail!\n");
+
+out:
+	pm_runtime_mark_last_busy(host->dev);
+	pm_runtime_put_autosuspend(host->dev);
+	return ret;
+}
+
+static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
+	return 0;
+}
+
 static void msdc_hw_reset(struct mmc_host *mmc)
 {
 	struct msdc_host *host = mmc_priv(mmc);
@@ -1226,6 +1447,8 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.execute_tuning = msdc_execute_tuning,
+	.prepare_hs400_tuning = msdc_prepare_hs400_tuning,
 	.hw_reset = msdc_hw_reset,
 };
 
@@ -1300,6 +1523,10 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
+				&host->hs400_ds_delay))
+		dev_dbg(&pdev->dev, "hs400-ds-delay: %x\n", host->hs400_ds_delay);
+
 	host->dev = &pdev->dev;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
@@ -1410,6 +1637,8 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
+	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
 }
 
 static void msdc_restore_reg(struct msdc_host *host)
@@ -1420,6 +1649,8 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
+	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
 }
 
 static int msdc_runtime_suspend(struct device *dev)
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 8/9] mmc: mediatek: add HS400 support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

add HS400 mode and tune support

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 241 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 236 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 5627644..528646c 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -26,6 +26,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <linux/mmc/card.h>
@@ -72,6 +73,8 @@
 #define MSDC_PATCH_BIT   0xb0
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE    0xec
+#define PAD_DS_TUNE      0x188
+#define EMMC50_CFG0      0x208
 
 /*--------------------------------------------------------------------------*/
 /* Register Mask                                                            */
@@ -88,6 +91,7 @@
 #define MSDC_CFG_CKSTB          (0x1 << 7)	/* R  */
 #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
 #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
+#define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
 
 /* MSDC_IOCON mask */
 #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
@@ -205,6 +209,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 PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
+#define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
+#define PAD_DS_TUNE_DLY3	  (0x1f << 12)  /* 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 */
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -220,6 +235,7 @@
 #define CMD_TIMEOUT         (HZ/10 * 5)	/* 100ms x5 */
 #define DAT_TIMEOUT         (HZ    * 5)	/* 1000ms x5 */
 
+#define PAD_DELAY_MAX	32 /* PAD delay cells */
 /*--------------------------------------------------------------------------*/
 /* Descriptor Structure                                                     */
 /*--------------------------------------------------------------------------*/
@@ -266,6 +282,14 @@ struct msdc_save_para {
 	u32 pad_tune;
 	u32 patch_bit0;
 	u32 patch_bit1;
+	u32 pad_ds_tune;
+	u32 emmc50_cfg0;
+};
+
+struct msdc_delay_phase {
+	u8 maxlen;
+	u8 start;
+	u8 final_phase;
 };
 
 struct msdc_host {
@@ -300,6 +324,7 @@ struct msdc_host {
 	u32 sclk;		/* SD/MS bus clock frequency */
 	unsigned char timing;
 	bool vqmmc_enabled;
+	u32 hs400_ds_delay;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
 
@@ -505,9 +530,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
+	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
 	if (timing == MMC_TIMING_UHS_DDR50 ||
-	    timing == MMC_TIMING_MMC_DDR52) {
-		mode = 0x2; /* ddr mode and use divisor */
+	    timing == MMC_TIMING_MMC_DDR52 ||
+	    timing == MMC_TIMING_MMC_HS400) {
+		if (timing == MMC_TIMING_MMC_HS400)
+			mode = 0x3;
+		else
+			mode = 0x2; /* ddr mode and use divisor */
+
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
 			sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
@@ -516,6 +547,13 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 			div = (div >> 1);
 		}
+
+		if (timing == MMC_TIMING_MMC_HS400 &&
+		    hz >= (host->src_clk_freq >> 1)) {
+			sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+			sclk = host->src_clk_freq >> 1;
+			div = 0; /* div is ignore when bit18 is set */
+		}
 	} else if (hz >= host->src_clk_freq) {
 		mode = 0x1; /* no divisor */
 		div = 0;
@@ -894,7 +932,7 @@ static void msdc_data_xfer_next(struct msdc_host *host,
 				struct mmc_request *mrq, struct mmc_data *data)
 {
 	if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error &&
-	    (!data->bytes_xfered || !mrq->sbc))
+	    !mrq->sbc)
 		msdc_start_command(host, mrq, mrq->stop);
 	else
 		msdc_request_done(host, mrq);
@@ -940,6 +978,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 
 			if (events & MSDC_INT_DATTMO)
 				data->error = -ETIMEDOUT;
+			else if (events & MSDC_INT_DATCRCERR)
+				data->error = -EILSEQ;
 
 			dev_err(host->dev, "%s: cmd=%d; blocks=%d",
 				__func__, mrq->cmd->opcode, data->blocks);
@@ -1111,10 +1151,12 @@ static void msdc_init_hw(struct msdc_host *host)
 
 	writel(0, host->base + MSDC_PAD_TUNE);
 	writel(0, host->base + MSDC_IOCON);
-	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
-	writel(0x403c004f, host->base + MSDC_PATCH_BIT);
+	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
+	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+
 	/* Configure to enable SDIO mode.
 	 * it's must otherwise sdio cmd5 failed
 	 */
@@ -1172,6 +1214,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc)) {
+			msdc_init_hw(host);
 			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
 					ios->vdd);
 			if (ret) {
@@ -1210,6 +1253,184 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static u32 test_delay_bit(u32 delay, u32 bit)
+{
+	bit %= PAD_DELAY_MAX;
+	return delay & (1 << bit);
+}
+
+static int get_delay_len(u32 delay, u32 start_bit)
+{
+	int i;
+
+	for (i = 0; i < (PAD_DELAY_MAX - start_bit); i++) {
+		if (test_delay_bit(delay, start_bit + i) == 0)
+			return i;
+	}
+	return PAD_DELAY_MAX - start_bit;
+}
+
+static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
+{
+	int start = 0, len = 0;
+	int start_final = 0, len_final = 0;
+	u8 final_phase = 0xff;
+	struct msdc_delay_phase delay_phase;
+
+	if (delay == 0) {
+		dev_err(host->dev, "phase error: [map:%x]\n", delay);
+		delay_phase.final_phase = final_phase;
+		return delay_phase;
+	}
+
+	while (start < PAD_DELAY_MAX) {
+		len = get_delay_len(delay, start);
+		if (len_final < len) {
+			start_final = start;
+			len_final = len;
+		}
+		start += len ? len : 1;
+		if (len >= 8 && start_final < 4)
+			break;
+	}
+
+	/* The rule is that to find the smallest delay cell */
+	if (start_final == 0)
+		final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
+	else
+		final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
+	dev_info(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
+		delay, len_final, final_phase);
+
+	delay_phase.maxlen = len_final;
+	delay_phase.start = start_final;
+	delay_phase.final_phase = final_phase;
+	return delay_phase;
+}
+
+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;
+	u8 final_delay, final_maxlen;
+	int cmd_err;
+	int i;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_tune_data(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;
+	u8 final_delay, final_maxlen;
+	int i, ret;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	/* Rising edge is more stable, prefer to use it */
+	if (final_rise_delay.maxlen >= 10)
+		final_maxlen = final_rise_delay.maxlen;
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	int ret;
+
+	pm_runtime_get_sync(host->dev);
+	ret = msdc_tune_response(mmc, opcode);
+	if (ret == -EIO) {
+		dev_err(host->dev, "Tune response fail!\n");
+		goto out;
+	}
+	ret = msdc_tune_data(mmc, opcode);
+	if (ret == -EIO)
+		dev_err(host->dev, "Tune data fail!\n");
+
+out:
+	pm_runtime_mark_last_busy(host->dev);
+	pm_runtime_put_autosuspend(host->dev);
+	return ret;
+}
+
+static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
+	return 0;
+}
+
 static void msdc_hw_reset(struct mmc_host *mmc)
 {
 	struct msdc_host *host = mmc_priv(mmc);
@@ -1226,6 +1447,8 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.execute_tuning = msdc_execute_tuning,
+	.prepare_hs400_tuning = msdc_prepare_hs400_tuning,
 	.hw_reset = msdc_hw_reset,
 };
 
@@ -1300,6 +1523,10 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
+				&host->hs400_ds_delay))
+		dev_dbg(&pdev->dev, "hs400-ds-delay: %x\n", host->hs400_ds_delay);
+
 	host->dev = &pdev->dev;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
@@ -1410,6 +1637,8 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
+	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
 }
 
 static void msdc_restore_reg(struct msdc_host *host)
@@ -1420,6 +1649,8 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
+	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
 }
 
 static int msdc_runtime_suspend(struct device *dev)
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 8/9] mmc: mediatek: add HS400 support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

add HS400 mode and tune support

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 241 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 236 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 5627644..528646c 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -26,6 +26,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <linux/mmc/card.h>
@@ -72,6 +73,8 @@
 #define MSDC_PATCH_BIT   0xb0
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE    0xec
+#define PAD_DS_TUNE      0x188
+#define EMMC50_CFG0      0x208
 
 /*--------------------------------------------------------------------------*/
 /* Register Mask                                                            */
@@ -88,6 +91,7 @@
 #define MSDC_CFG_CKSTB          (0x1 << 7)	/* R  */
 #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
 #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
+#define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
 
 /* MSDC_IOCON mask */
 #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
@@ -205,6 +209,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 PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
+#define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
+#define PAD_DS_TUNE_DLY3	  (0x1f << 12)  /* 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 */
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -220,6 +235,7 @@
 #define CMD_TIMEOUT         (HZ/10 * 5)	/* 100ms x5 */
 #define DAT_TIMEOUT         (HZ    * 5)	/* 1000ms x5 */
 
+#define PAD_DELAY_MAX	32 /* PAD delay cells */
 /*--------------------------------------------------------------------------*/
 /* Descriptor Structure                                                     */
 /*--------------------------------------------------------------------------*/
@@ -266,6 +282,14 @@ struct msdc_save_para {
 	u32 pad_tune;
 	u32 patch_bit0;
 	u32 patch_bit1;
+	u32 pad_ds_tune;
+	u32 emmc50_cfg0;
+};
+
+struct msdc_delay_phase {
+	u8 maxlen;
+	u8 start;
+	u8 final_phase;
 };
 
 struct msdc_host {
@@ -300,6 +324,7 @@ struct msdc_host {
 	u32 sclk;		/* SD/MS bus clock frequency */
 	unsigned char timing;
 	bool vqmmc_enabled;
+	u32 hs400_ds_delay;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
 
@@ -505,9 +530,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
+	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
 	if (timing == MMC_TIMING_UHS_DDR50 ||
-	    timing == MMC_TIMING_MMC_DDR52) {
-		mode = 0x2; /* ddr mode and use divisor */
+	    timing == MMC_TIMING_MMC_DDR52 ||
+	    timing == MMC_TIMING_MMC_HS400) {
+		if (timing == MMC_TIMING_MMC_HS400)
+			mode = 0x3;
+		else
+			mode = 0x2; /* ddr mode and use divisor */
+
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
 			sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
@@ -516,6 +547,13 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			sclk = (host->src_clk_freq >> 2) / div;
 			div = (div >> 1);
 		}
+
+		if (timing == MMC_TIMING_MMC_HS400 &&
+		    hz >= (host->src_clk_freq >> 1)) {
+			sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
+			sclk = host->src_clk_freq >> 1;
+			div = 0; /* div is ignore when bit18 is set */
+		}
 	} else if (hz >= host->src_clk_freq) {
 		mode = 0x1; /* no divisor */
 		div = 0;
@@ -894,7 +932,7 @@ static void msdc_data_xfer_next(struct msdc_host *host,
 				struct mmc_request *mrq, struct mmc_data *data)
 {
 	if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error &&
-	    (!data->bytes_xfered || !mrq->sbc))
+	    !mrq->sbc)
 		msdc_start_command(host, mrq, mrq->stop);
 	else
 		msdc_request_done(host, mrq);
@@ -940,6 +978,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 
 			if (events & MSDC_INT_DATTMO)
 				data->error = -ETIMEDOUT;
+			else if (events & MSDC_INT_DATCRCERR)
+				data->error = -EILSEQ;
 
 			dev_err(host->dev, "%s: cmd=%d; blocks=%d",
 				__func__, mrq->cmd->opcode, data->blocks);
@@ -1111,10 +1151,12 @@ static void msdc_init_hw(struct msdc_host *host)
 
 	writel(0, host->base + MSDC_PAD_TUNE);
 	writel(0, host->base + MSDC_IOCON);
-	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
-	writel(0x403c004f, host->base + MSDC_PATCH_BIT);
+	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
+	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
+
 	/* Configure to enable SDIO mode.
 	 * it's must otherwise sdio cmd5 failed
 	 */
@@ -1172,6 +1214,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc)) {
+			msdc_init_hw(host);
 			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
 					ios->vdd);
 			if (ret) {
@@ -1210,6 +1253,184 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static u32 test_delay_bit(u32 delay, u32 bit)
+{
+	bit %= PAD_DELAY_MAX;
+	return delay & (1 << bit);
+}
+
+static int get_delay_len(u32 delay, u32 start_bit)
+{
+	int i;
+
+	for (i = 0; i < (PAD_DELAY_MAX - start_bit); i++) {
+		if (test_delay_bit(delay, start_bit + i) == 0)
+			return i;
+	}
+	return PAD_DELAY_MAX - start_bit;
+}
+
+static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
+{
+	int start = 0, len = 0;
+	int start_final = 0, len_final = 0;
+	u8 final_phase = 0xff;
+	struct msdc_delay_phase delay_phase;
+
+	if (delay == 0) {
+		dev_err(host->dev, "phase error: [map:%x]\n", delay);
+		delay_phase.final_phase = final_phase;
+		return delay_phase;
+	}
+
+	while (start < PAD_DELAY_MAX) {
+		len = get_delay_len(delay, start);
+		if (len_final < len) {
+			start_final = start;
+			len_final = len;
+		}
+		start += len ? len : 1;
+		if (len >= 8 && start_final < 4)
+			break;
+	}
+
+	/* The rule is that to find the smallest delay cell */
+	if (start_final == 0)
+		final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
+	else
+		final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
+	dev_info(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
+		delay, len_final, final_phase);
+
+	delay_phase.maxlen = len_final;
+	delay_phase.start = start_final;
+	delay_phase.final_phase = final_phase;
+	return delay_phase;
+}
+
+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;
+	u8 final_delay, final_maxlen;
+	int cmd_err;
+	int i;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, i);
+		mmc_send_tuning(mmc, opcode, &cmd_err);
+		if (!cmd_err)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_tune_data(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;
+	u8 final_delay, final_maxlen;
+	int i, ret;
+
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			rise_delay |= (1 << i);
+	}
+
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY, i);
+		ret = mmc_send_tuning(mmc, opcode, NULL);
+		if (!ret)
+			fall_delay |= (1 << i);
+	}
+
+	final_rise_delay = get_best_delay(host, rise_delay);
+	final_fall_delay = get_best_delay(host, fall_delay);
+
+	final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+	/* Rising edge is more stable, prefer to use it */
+	if (final_rise_delay.maxlen >= 10)
+		final_maxlen = final_rise_delay.maxlen;
+	if (final_maxlen == final_rise_delay.maxlen) {
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_rise_delay.final_phase);
+		final_delay = final_rise_delay.final_phase;
+	} else {
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATRRDLY,
+			      final_fall_delay.final_phase);
+		final_delay = final_fall_delay.final_phase;
+	}
+
+	return final_delay == 0xff? -EIO: 0;
+}
+
+static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	int ret;
+
+	pm_runtime_get_sync(host->dev);
+	ret = msdc_tune_response(mmc, opcode);
+	if (ret == -EIO) {
+		dev_err(host->dev, "Tune response fail!\n");
+		goto out;
+	}
+	ret = msdc_tune_data(mmc, opcode);
+	if (ret == -EIO)
+		dev_err(host->dev, "Tune data fail!\n");
+
+out:
+	pm_runtime_mark_last_busy(host->dev);
+	pm_runtime_put_autosuspend(host->dev);
+	return ret;
+}
+
+static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
+	return 0;
+}
+
 static void msdc_hw_reset(struct mmc_host *mmc)
 {
 	struct msdc_host *host = mmc_priv(mmc);
@@ -1226,6 +1447,8 @@ static struct mmc_host_ops mt_msdc_ops = {
 	.set_ios = msdc_ops_set_ios,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
+	.execute_tuning = msdc_execute_tuning,
+	.prepare_hs400_tuning = msdc_prepare_hs400_tuning,
 	.hw_reset = msdc_hw_reset,
 };
 
@@ -1300,6 +1523,10 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
+				&host->hs400_ds_delay))
+		dev_dbg(&pdev->dev, "hs400-ds-delay: %x\n", host->hs400_ds_delay);
+
 	host->dev = &pdev->dev;
 	host->mmc = mmc;
 	host->src_clk_freq = clk_get_rate(host->src_clk);
@@ -1410,6 +1637,8 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
+	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
 }
 
 static void msdc_restore_reg(struct msdc_host *host)
@@ -1420,6 +1649,8 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
+	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
 }
 
 static int msdc_runtime_suspend(struct device *dev)
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 9/9] arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20  9:13   ` Chaotian Jing
  -1 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov, Stephen Boyd,
	Minda Chen, Dong Aisheng, Johan Derycke, Haibo Chen,
	Fabio Estevam, Georgi Djakov, ivan.ivanov, Weijun Yang,
	Kevin Hao, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-mmc, linux-samsung-soc, srv_heupstream

add HS200/HS400 support for eMMC
add SDR50/SDR104 support for SD

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..a061221 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -70,10 +70,16 @@
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
 	bus-width = <8>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	hs400-ds-delay = <0x14015>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
 	non-removable;
 };
 
@@ -83,9 +89,10 @@
 	pinctrl-0 = <&mmc1_pins_default>;
 	pinctrl-1 = <&mmc1_pins_uhs>;
 	bus-width = <4>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-sd-highspeed;
-	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	cd-gpios = <&pio 132 0>;
 	vmmc-supply = <&mt6397_vmch_reg>;
 	vqmmc-supply = <&mt6397_vmc_reg>;
@@ -154,13 +161,19 @@
 				 <MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
 				 <MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_ds {
+			pinmux = <MT8173_PIN_67_MSDC0_DSL__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
 		};
 
@@ -178,13 +191,13 @@
 				 <MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
 				 <MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_8mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
 		};
 	};
-- 
1.8.1.1.dirty


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 9/9] arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Chaotian Jing, Lars-Peter Clausen,
	Javier Martinez Canillas, Sascha Hauer, Howard Chen,
	Adrian Hunter, Kristina Martsenko, Sergei Shtylyov

add HS200/HS400 support for eMMC
add SDR50/SDR104 support for SD

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..a061221 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -70,10 +70,16 @@
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
 	bus-width = <8>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	hs400-ds-delay = <0x14015>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
 	non-removable;
 };
 
@@ -83,9 +89,10 @@
 	pinctrl-0 = <&mmc1_pins_default>;
 	pinctrl-1 = <&mmc1_pins_uhs>;
 	bus-width = <4>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-sd-highspeed;
-	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	cd-gpios = <&pio 132 0>;
 	vmmc-supply = <&mt6397_vmch_reg>;
 	vqmmc-supply = <&mt6397_vmc_reg>;
@@ -154,13 +161,19 @@
 				 <MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
 				 <MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_ds {
+			pinmux = <MT8173_PIN_67_MSDC0_DSL__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
 		};
 
@@ -178,13 +191,13 @@
 				 <MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
 				 <MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_8mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
 		};
 	};
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 9/9] arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
@ 2015-10-20  9:13   ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-20  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

add HS200/HS400 support for eMMC
add SDR50/SDR104 support for SD

Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..a061221 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -70,10 +70,16 @@
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
 	bus-width = <8>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	hs400-ds-delay = <0x14015>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
 	non-removable;
 };
 
@@ -83,9 +89,10 @@
 	pinctrl-0 = <&mmc1_pins_default>;
 	pinctrl-1 = <&mmc1_pins_uhs>;
 	bus-width = <4>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-sd-highspeed;
-	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	cd-gpios = <&pio 132 0>;
 	vmmc-supply = <&mt6397_vmch_reg>;
 	vqmmc-supply = <&mt6397_vmc_reg>;
@@ -154,13 +161,19 @@
 				 <MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
 				 <MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
-			drive-strength = <MTK_DRIVE_2mA>;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_ds {
+			pinmux = <MT8173_PIN_67_MSDC0_DSL__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
 		};
 
@@ -178,13 +191,13 @@
 				 <MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
 				 <MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
 			input-enable;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_6mA>;
 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
 		};
 
 		pins_clk {
 			pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
-			drive-strength = <MTK_DRIVE_4mA>;
+			drive-strength = <MTK_DRIVE_8mA>;
 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
 		};
 	};
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 0/9] Add tune support of Mediatek MMC driver
  2015-10-20  9:13 ` Chaotian Jing
  (?)
@ 2015-10-20 16:41   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2015-10-20 16:41 UTC (permalink / raw)
  To: Chaotian Jing
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Lars-Peter Clausen, Javier Martinez Canillas,
	Sascha Hauer, Howard Chen, Adrian Hunter, Kristina Martsenko,
	Sergei Shtylyov, Stephen Boyd, Minda Chen, Dong Aisheng,
	Johan Derycke, Haibo Chen, Fabio Estevam, Georgi Djakov,
	Ivan Ivanov, Weijun Yang, Kevin Hao, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-mmc, linux-samsung-soc,
	srv_heupstream

On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
> Change in v2:
> Drop the 400mhz and use assigned-clock-parents to instead
> Split the original tune patch to several independent patches
> Re-write the mmc_send_tuning()
> Fix GPD checksum error
> Move the HS400 setting to ops->prepare_hs400_tuning()
> Modify SD driving settings
>
> Change in v1:
> Add DT bindings for eMMC hardware reset
> Add pinctrl of data strobe pin for HS400 mode
> Modify eMMC driving settings
> Add 400mhz source clock for HS400 mode
> Add eMMC HS200/HS400 mode support
> Add SD SDR50/SDR104 mode support
> Add implement of tune function with CMD19/CMD21
>
> Chaotian Jing (9):
>   mmc: core: Add DT bindings for eMMC hardware reset support
>   mmc: dt-bindings: update Mediatek MMC bindings
>   mmc: mediatek: make cmd_ints_mask to const
>   mmc: mediatek: change the argument "ddr" to "timing"
>   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
>   mmc: mediatek: add implement of ops->hw_reset()
>   mmc: mmc: extend the mmc_send_tuning()
>   mmc: mediatek: add HS400 support
>   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
>
>  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
>  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
>  drivers/mmc/core/host.c                          |   2 +
>  drivers/mmc/core/mmc_ops.c                       |   8 +-
>  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
>  drivers/mmc/host/dw_mmc.c                        |   2 +-
>  drivers/mmc/host/dw_mmc.h                        |   2 +-
>  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
>  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
>  drivers/mmc/host/sdhci-msm.c                     |   2 +-
>  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
>  include/linux/mmc/core.h                         |   2 +-
>  13 files changed, 314 insertions(+), 51 deletions(-)
>
> --
> 1.8.1.1.dirty

I have reviewed the patches, I think they overall looks good! Some
comments though.

You need to split patch 9, the DT parts enabling hw reset shall go in
separately.

Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
I requested you to separate the HW reset changes from $subject
patchset as they are unrelated, please do this.

Running checkpatch, it gave me warnings and errors for patch 8.
Patch7 didn't apply to my next branch.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-20 16:41   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2015-10-20 16:41 UTC (permalink / raw)
  To: Chaotian Jing
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Lars-Peter Clausen, Javier Martinez Canillas,
	Sascha Hauer, Howard Chen, Adrian Hunter, Kristina Martsenko,
	Sergei Shtylyov, Stephen Boyd

On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
> Change in v2:
> Drop the 400mhz and use assigned-clock-parents to instead
> Split the original tune patch to several independent patches
> Re-write the mmc_send_tuning()
> Fix GPD checksum error
> Move the HS400 setting to ops->prepare_hs400_tuning()
> Modify SD driving settings
>
> Change in v1:
> Add DT bindings for eMMC hardware reset
> Add pinctrl of data strobe pin for HS400 mode
> Modify eMMC driving settings
> Add 400mhz source clock for HS400 mode
> Add eMMC HS200/HS400 mode support
> Add SD SDR50/SDR104 mode support
> Add implement of tune function with CMD19/CMD21
>
> Chaotian Jing (9):
>   mmc: core: Add DT bindings for eMMC hardware reset support
>   mmc: dt-bindings: update Mediatek MMC bindings
>   mmc: mediatek: make cmd_ints_mask to const
>   mmc: mediatek: change the argument "ddr" to "timing"
>   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
>   mmc: mediatek: add implement of ops->hw_reset()
>   mmc: mmc: extend the mmc_send_tuning()
>   mmc: mediatek: add HS400 support
>   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
>
>  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
>  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
>  drivers/mmc/core/host.c                          |   2 +
>  drivers/mmc/core/mmc_ops.c                       |   8 +-
>  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
>  drivers/mmc/host/dw_mmc.c                        |   2 +-
>  drivers/mmc/host/dw_mmc.h                        |   2 +-
>  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
>  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
>  drivers/mmc/host/sdhci-msm.c                     |   2 +-
>  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
>  include/linux/mmc/core.h                         |   2 +-
>  13 files changed, 314 insertions(+), 51 deletions(-)
>
> --
> 1.8.1.1.dirty

I have reviewed the patches, I think they overall looks good! Some
comments though.

You need to split patch 9, the DT parts enabling hw reset shall go in
separately.

Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
I requested you to separate the HW reset changes from $subject
patchset as they are unrelated, please do this.

Running checkpatch, it gave me warnings and errors for patch 8.
Patch7 didn't apply to my next branch.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-20 16:41   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2015-10-20 16:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
> Change in v2:
> Drop the 400mhz and use assigned-clock-parents to instead
> Split the original tune patch to several independent patches
> Re-write the mmc_send_tuning()
> Fix GPD checksum error
> Move the HS400 setting to ops->prepare_hs400_tuning()
> Modify SD driving settings
>
> Change in v1:
> Add DT bindings for eMMC hardware reset
> Add pinctrl of data strobe pin for HS400 mode
> Modify eMMC driving settings
> Add 400mhz source clock for HS400 mode
> Add eMMC HS200/HS400 mode support
> Add SD SDR50/SDR104 mode support
> Add implement of tune function with CMD19/CMD21
>
> Chaotian Jing (9):
>   mmc: core: Add DT bindings for eMMC hardware reset support
>   mmc: dt-bindings: update Mediatek MMC bindings
>   mmc: mediatek: make cmd_ints_mask to const
>   mmc: mediatek: change the argument "ddr" to "timing"
>   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
>   mmc: mediatek: add implement of ops->hw_reset()
>   mmc: mmc: extend the mmc_send_tuning()
>   mmc: mediatek: add HS400 support
>   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
>
>  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
>  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
>  drivers/mmc/core/host.c                          |   2 +
>  drivers/mmc/core/mmc_ops.c                       |   8 +-
>  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
>  drivers/mmc/host/dw_mmc.c                        |   2 +-
>  drivers/mmc/host/dw_mmc.h                        |   2 +-
>  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
>  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
>  drivers/mmc/host/sdhci-msm.c                     |   2 +-
>  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
>  include/linux/mmc/core.h                         |   2 +-
>  13 files changed, 314 insertions(+), 51 deletions(-)
>
> --
> 1.8.1.1.dirty

I have reviewed the patches, I think they overall looks good! Some
comments though.

You need to split patch 9, the DT parts enabling hw reset shall go in
separately.

Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
I requested you to separate the HW reset changes from $subject
patchset as they are unrelated, please do this.

Running checkpatch, it gave me warnings and errors for patch 8.
Patch7 didn't apply to my next branch.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-22  2:18     ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-22  2:18 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Lars-Peter Clausen, Javier Martinez Canillas,
	Sascha Hauer, Howard Chen, Adrian Hunter, Kristina Martsenko,
	Sergei Shtylyov, Stephen Boyd, Minda Chen, Dong Aisheng,
	Johan Derycke, Haibo Chen, Fabio Estevam, Georgi Djakov,
	Ivan Ivanov, Weijun Yang, Kevin Hao, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-mmc, linux-samsung-soc,
	srv_heupstream

On Tue, 2015-10-20 at 18:41 +0200, Ulf Hansson wrote:
> On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
> > Change in v2:
> > Drop the 400mhz and use assigned-clock-parents to instead
> > Split the original tune patch to several independent patches
> > Re-write the mmc_send_tuning()
> > Fix GPD checksum error
> > Move the HS400 setting to ops->prepare_hs400_tuning()
> > Modify SD driving settings
> >
> > Change in v1:
> > Add DT bindings for eMMC hardware reset
> > Add pinctrl of data strobe pin for HS400 mode
> > Modify eMMC driving settings
> > Add 400mhz source clock for HS400 mode
> > Add eMMC HS200/HS400 mode support
> > Add SD SDR50/SDR104 mode support
> > Add implement of tune function with CMD19/CMD21
> >
> > Chaotian Jing (9):
> >   mmc: core: Add DT bindings for eMMC hardware reset support
> >   mmc: dt-bindings: update Mediatek MMC bindings
> >   mmc: mediatek: make cmd_ints_mask to const
> >   mmc: mediatek: change the argument "ddr" to "timing"
> >   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
> >   mmc: mediatek: add implement of ops->hw_reset()
> >   mmc: mmc: extend the mmc_send_tuning()
> >   mmc: mediatek: add HS400 support
> >   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
> >
> >  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
> >  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
> >  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
> >  drivers/mmc/core/host.c                          |   2 +
> >  drivers/mmc/core/mmc_ops.c                       |   8 +-
> >  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
> >  drivers/mmc/host/dw_mmc.c                        |   2 +-
> >  drivers/mmc/host/dw_mmc.h                        |   2 +-
> >  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
> >  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
> >  drivers/mmc/host/sdhci-msm.c                     |   2 +-
> >  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
> >  include/linux/mmc/core.h                         |   2 +-
> >  13 files changed, 314 insertions(+), 51 deletions(-)
> >
> > --
> > 1.8.1.1.dirty
> 
> I have reviewed the patches, I think they overall looks good! Some
> comments though.
> 
> You need to split patch 9, the DT parts enabling hw reset shall go in
> separately.
> 
Ok, will separate it at next revision.

> Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
> I requested you to separate the HW reset changes from $subject
> patchset as they are unrelated, please do this.
> 
As you know, the hw-reset is a part of mmc retune.
so that I add it to this series.

> Running checkpatch, it gave me warnings and errors for patch 8.
> Patch7 didn't apply to my next branch.
> 

I will fix the checkpatch warnings and errors at next revision.
by the way, I tried to use "git am
0007-mmc-mmc-extend-the-mmc_send_tuning.patch" in your branch,
there was no conflict, so why couldn't apply it ?
Thx!

> Kind regards
> Uffe



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-22  2:18     ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-22  2:18 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Matthias Brugger, Catalin Marinas, Will Deacon, Seungwon Jeon,
	Jaehoon Chung, Kukjin Kim, Krzysztof Kozlowski, Barry Song,
	Hans de Goede, Lars-Peter Clausen, Javier Martinez Canillas,
	Sascha Hauer, Howard Chen, Adrian Hunter, Kristina Martsenko,
	Sergei Shtylyov, Stephen Boyd

On Tue, 2015-10-20 at 18:41 +0200, Ulf Hansson wrote:
> On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
> > Change in v2:
> > Drop the 400mhz and use assigned-clock-parents to instead
> > Split the original tune patch to several independent patches
> > Re-write the mmc_send_tuning()
> > Fix GPD checksum error
> > Move the HS400 setting to ops->prepare_hs400_tuning()
> > Modify SD driving settings
> >
> > Change in v1:
> > Add DT bindings for eMMC hardware reset
> > Add pinctrl of data strobe pin for HS400 mode
> > Modify eMMC driving settings
> > Add 400mhz source clock for HS400 mode
> > Add eMMC HS200/HS400 mode support
> > Add SD SDR50/SDR104 mode support
> > Add implement of tune function with CMD19/CMD21
> >
> > Chaotian Jing (9):
> >   mmc: core: Add DT bindings for eMMC hardware reset support
> >   mmc: dt-bindings: update Mediatek MMC bindings
> >   mmc: mediatek: make cmd_ints_mask to const
> >   mmc: mediatek: change the argument "ddr" to "timing"
> >   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
> >   mmc: mediatek: add implement of ops->hw_reset()
> >   mmc: mmc: extend the mmc_send_tuning()
> >   mmc: mediatek: add HS400 support
> >   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
> >
> >  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
> >  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
> >  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
> >  drivers/mmc/core/host.c                          |   2 +
> >  drivers/mmc/core/mmc_ops.c                       |   8 +-
> >  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
> >  drivers/mmc/host/dw_mmc.c                        |   2 +-
> >  drivers/mmc/host/dw_mmc.h                        |   2 +-
> >  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
> >  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
> >  drivers/mmc/host/sdhci-msm.c                     |   2 +-
> >  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
> >  include/linux/mmc/core.h                         |   2 +-
> >  13 files changed, 314 insertions(+), 51 deletions(-)
> >
> > --
> > 1.8.1.1.dirty
> 
> I have reviewed the patches, I think they overall looks good! Some
> comments though.
> 
> You need to split patch 9, the DT parts enabling hw reset shall go in
> separately.
> 
Ok, will separate it at next revision.

> Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
> I requested you to separate the HW reset changes from $subject
> patchset as they are unrelated, please do this.
> 
As you know, the hw-reset is a part of mmc retune.
so that I add it to this series.

> Running checkpatch, it gave me warnings and errors for patch 8.
> Patch7 didn't apply to my next branch.
> 

I will fix the checkpatch warnings and errors at next revision.
by the way, I tried to use "git am
0007-mmc-mmc-extend-the-mmc_send_tuning.patch" in your branch,
there was no conflict, so why couldn't apply it ?
Thx!

> Kind regards
> Uffe


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 0/9] Add tune support of Mediatek MMC driver
@ 2015-10-22  2:18     ` Chaotian Jing
  0 siblings, 0 replies; 36+ messages in thread
From: Chaotian Jing @ 2015-10-22  2:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2015-10-20 at 18:41 +0200, Ulf Hansson wrote:
> On 20 October 2015 at 11:13, Chaotian Jing <chaotian.jing@mediatek.com> wrote:
> > Change in v2:
> > Drop the 400mhz and use assigned-clock-parents to instead
> > Split the original tune patch to several independent patches
> > Re-write the mmc_send_tuning()
> > Fix GPD checksum error
> > Move the HS400 setting to ops->prepare_hs400_tuning()
> > Modify SD driving settings
> >
> > Change in v1:
> > Add DT bindings for eMMC hardware reset
> > Add pinctrl of data strobe pin for HS400 mode
> > Modify eMMC driving settings
> > Add 400mhz source clock for HS400 mode
> > Add eMMC HS200/HS400 mode support
> > Add SD SDR50/SDR104 mode support
> > Add implement of tune function with CMD19/CMD21
> >
> > Chaotian Jing (9):
> >   mmc: core: Add DT bindings for eMMC hardware reset support
> >   mmc: dt-bindings: update Mediatek MMC bindings
> >   mmc: mediatek: make cmd_ints_mask to const
> >   mmc: mediatek: change the argument "ddr" to "timing"
> >   mmc: mediatek: fix got GPD checksum error interrupt when data transfer
> >   mmc: mediatek: add implement of ops->hw_reset()
> >   mmc: mmc: extend the mmc_send_tuning()
> >   mmc: mediatek: add HS400 support
> >   arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support
> >
> >  Documentation/devicetree/bindings/mmc/mmc.txt    |   1 +
> >  Documentation/devicetree/bindings/mmc/mtk-sd.txt |  11 +-
> >  arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  27 ++-
> >  drivers/mmc/core/host.c                          |   2 +
> >  drivers/mmc/core/mmc_ops.c                       |   8 +-
> >  drivers/mmc/host/dw_mmc-exynos.c                 |   4 +-
> >  drivers/mmc/host/dw_mmc.c                        |   2 +-
> >  drivers/mmc/host/dw_mmc.h                        |   2 +-
> >  drivers/mmc/host/mtk-sd.c                        | 296 ++++++++++++++++++++---
> >  drivers/mmc/host/sdhci-esdhc-imx.c               |   6 +-
> >  drivers/mmc/host/sdhci-msm.c                     |   2 +-
> >  drivers/mmc/host/sdhci-sirf.c                    |   2 +-
> >  include/linux/mmc/core.h                         |   2 +-
> >  13 files changed, 314 insertions(+), 51 deletions(-)
> >
> > --
> > 1.8.1.1.dirty
> 
> I have reviewed the patches, I think they overall looks good! Some
> comments though.
> 
> You need to split patch 9, the DT parts enabling hw reset shall go in
> separately.
> 
Ok, will separate it at next revision.

> Regarding the hw-reset changes in patch1, patch6 and patch9, I believe
> I requested you to separate the HW reset changes from $subject
> patchset as they are unrelated, please do this.
> 
As you know, the hw-reset is a part of mmc retune.
so that I add it to this series.

> Running checkpatch, it gave me warnings and errors for patch 8.
> Patch7 didn't apply to my next branch.
> 

I will fix the checkpatch warnings and errors at next revision.
by the way, I tried to use "git am
0007-mmc-mmc-extend-the-mmc_send_tuning.patch" in your branch,
there was no conflict, so why couldn't apply it ?
Thx!

> Kind regards
> Uffe

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2015-10-22  2:19 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-20  9:13 [PATCH v2 0/9] Add tune support of Mediatek MMC driver Chaotian Jing
2015-10-20  9:13 ` Chaotian Jing
2015-10-20  9:13 ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 1/9] mmc: core: Add DT bindings for eMMC hardware reset support Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 2/9] mmc: dt-bindings: update Mediatek MMC bindings Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 3/9] mmc: mediatek: make cmd_ints_mask to const Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 4/9] mmc: mediatek: change the argument "ddr" to "timing" Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 5/9] mmc: mediatek: fix got GPD checksum error interrupt when data transfer Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 6/9] mmc: mediatek: add implement of ops->hw_reset() Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 7/9] mmc: mmc: extend the mmc_send_tuning() Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 8/9] mmc: mediatek: add HS400 support Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13 ` [PATCH v2 9/9] arm64: dts: mediatek: add HS200/HS400/SDR50/SDR104 support Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20  9:13   ` Chaotian Jing
2015-10-20 16:41 ` [PATCH v2 0/9] Add tune support of Mediatek MMC driver Ulf Hansson
2015-10-20 16:41   ` Ulf Hansson
2015-10-20 16:41   ` Ulf Hansson
2015-10-22  2:18   ` Chaotian Jing
2015-10-22  2:18     ` Chaotian Jing
2015-10-22  2:18     ` Chaotian Jing

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.