linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support
@ 2017-01-16 16:56 Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence Maxime Ripard
                   ` (13 more replies)
  0 siblings, 14 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

Hi,

Here is a new attempt at getting the MMC controllers running, following the
work done by Andre.

This has been tested on a board with one SDIO device (a Marvell WiFi chip)
and a Kingston eMMC with 1.8V IOs.

For SDIO, the HS DDR mode works just fine. That serie also enables the
SDR104 mode to work on the devices that are capable of this.

For the eMMC, HS200 with the voltage switch works. HS400 doesn't at the
moment, but since it's significantly more complex, and at the same time
Allwinner recommends to limit its frequency to 100MHz, this doesn't have
any benefits. If there's any at some point, this can be added later.

Let me know what you think,
Maxime

Changes from v2:
  - Enabled SDR104, limited the frequency to 150MHz. 200MHz was too high.
  - Added more fixes to the gating and frequency rate change sequence
  - Added one more patch to mask DATA0 when updating the clock that was
    needed to get SDR104 to run
  - Added the patches to enable it on a few boards done by Andre
  - Amended the comments as suggested by Andre.
  - Added some tags

Andre Przywara (4):
  arm64: allwinner: a64: Add MMC nodes
  arm64: allwinner: pine64: add MMC support
  arm64: allwinner: a64: add UART1 pin nodes
  arm64: allwinner: add BananaPi-M64 support

Maxime Ripard (9):
  mmc: sunxi: Fix clock frequency change sequence
  mmc: sunxi: Gate the clock when rate is 0
  mmc: sunxi: Always set signal delay to 0 for A64
  mmc: sunxi: Enable the new timings for the A64 MMC controllers
  mmc: sunxi: Mask DATA0 when updating the clock
  mmc: sunxi: Add EMMC (MMC2) controller compatible
  mmc: sunxi: Add more debug messages
  arm64: allwinner: a64: Add MMC pinctrl nodes
  arm64: allwinner: a64: Increase the MMC max frequency

 arch/arm64/boot/dts/allwinner/Makefile                    |   1 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 120 +++++++-
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts       |  20 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi             |  77 ++++-
 drivers/mmc/host/sunxi-mmc.c                              | 101 +++---
 5 files changed, 278 insertions(+), 41 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts

base-commit: bc34c1af0a280e27eafe3f86b9ad87fe0c9ea715
-- 
git-series 0.8.11

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

* [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-24  8:12   ` Ulf Hansson
  2017-01-16 16:56 ` [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0 Maxime Ripard
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The MMC and SD specifications documents that the clock frequency should
only be changed once gated.

The current code first modifies the parent clock, gates it and then
modifies the internal divider. This means that since the parent clock rate
might be changed, the bus clock might be changed as well before it is
gated, which breaks the specification.

Move the gating before the parent rate modification.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index b1d1303389a7..ab4324e6eb74 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -761,6 +761,10 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 	u32 rval, clock = ios->clock;
 	int ret;
 
+	ret = sunxi_mmc_oclk_onoff(host, 0);
+	if (ret)
+		return ret;
+
 	/* 8 bit DDR requires a higher module clock */
 	if (ios->timing == MMC_TIMING_MMC_DDR52 &&
 	    ios->bus_width == MMC_BUS_WIDTH_8)
@@ -783,10 +787,6 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 		return ret;
 	}
 
-	ret = sunxi_mmc_oclk_onoff(host, 0);
-	if (ret)
-		return ret;
-
 	/* clear internal divider */
 	rval = mmc_readl(host, REG_CLKCR);
 	rval &= ~0xff;
-- 
git-series 0.8.11

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

* [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-24  8:14   ` Ulf Hansson
  2017-01-16 16:56 ` [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64 Maxime Ripard
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The MMC core assumes that the code will gate the clock when the bus
frequency is set to 0, which we've been ignoring so far.

Handle that.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index ab4324e6eb74..019f95e8e7c5 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -765,6 +765,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 	if (ret)
 		return ret;
 
+	if (!ios->clock)
+		return 0;
+
 	/* 8 bit DDR requires a higher module clock */
 	if (ios->timing == MMC_TIMING_MMC_DDR52 &&
 	    ios->bus_width == MMC_BUS_WIDTH_8)
@@ -882,7 +885,7 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	mmc_writel(host, REG_GCTRL, rval);
 
 	/* set up clock */
-	if (ios->clock && ios->power_mode) {
+	if (ios->power_mode) {
 		host->ferror = sunxi_mmc_clk_set_rate(host, ios);
 		/* Android code had a usleep_range(50000, 55000); here */
 	}
-- 
git-series 0.8.11

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

* [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0 Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-24  8:16   ` Ulf Hansson
  2017-01-16 16:56 ` [PATCH v3 4/13] mmc: sunxi: Enable the new timings for the A64 MMC controllers Maxime Ripard
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

Experience have shown that the using the  autocalibration could severely
degrade the performances of the MMC bus.

Allwinner is using in its BSP a delay set to 0 for all the modes but HS400.
Remove the calibration code for now, and add comments to document our
findings.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 50 ++++++++++++-------------------------
 1 file changed, 17 insertions(+), 33 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 019f95e8e7c5..b9c8a62bc212 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -683,41 +683,19 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 
 static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off)
 {
-	u32 reg = readl(host->reg_base + reg_off);
-	u32 delay;
-	unsigned long timeout;
-
 	if (!host->cfg->can_calibrate)
 		return 0;
 
-	reg &= ~(SDXC_CAL_DL_MASK << SDXC_CAL_DL_SW_SHIFT);
-	reg &= ~SDXC_CAL_DL_SW_EN;
-
-	writel(reg | SDXC_CAL_START, host->reg_base + reg_off);
-
-	dev_dbg(mmc_dev(host->mmc), "calibration started\n");
-
-	timeout = jiffies + HZ * SDXC_CAL_TIMEOUT;
-
-	while (!((reg = readl(host->reg_base + reg_off)) & SDXC_CAL_DONE)) {
-		if (time_before(jiffies, timeout))
-			cpu_relax();
-		else {
-			reg &= ~SDXC_CAL_START;
-			writel(reg, host->reg_base + reg_off);
-
-			return -ETIMEDOUT;
-		}
-	}
-
-	delay = (reg >> SDXC_CAL_DL_SHIFT) & SDXC_CAL_DL_MASK;
-
-	reg &= ~SDXC_CAL_START;
-	reg |= (delay << SDXC_CAL_DL_SW_SHIFT) | SDXC_CAL_DL_SW_EN;
-
-	writel(reg, host->reg_base + reg_off);
-
-	dev_dbg(mmc_dev(host->mmc), "calibration ended, reg is 0x%x\n", reg);
+	/*
+	 * FIXME:
+	 * This is not clear how the calibration is supposed to work
+	 * yet. The best rate have been obtained by simply setting the
+	 * delay to 0, as Allwinner does in its BSP.
+	 *
+	 * The only mode that doesn't have such a delay is HS400, that
+	 * is in itself a TODO.
+	 */
+	writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off);
 
 	return 0;
 }
@@ -809,7 +787,13 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 	if (ret)
 		return ret;
 
-	/* TODO: enable calibrate on sdc2 SDXC_REG_DS_DL_REG of A64 */
+	/*
+	 * FIXME:
+	 *
+	 * In HS400 we'll also need to calibrate the data strobe
+	 * signal. This should only happen on the MMC2 controller (at
+	 * least on the A64).
+	 */
 
 	return sunxi_mmc_oclk_onoff(host, 1);
 }
-- 
git-series 0.8.11

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

* [PATCH v3 4/13] mmc: sunxi: Enable the new timings for the A64 MMC controllers
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (2 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64 Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock Maxime Ripard
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The A64 MMC controllers need to set a "new timings" bit when a new rate is
set.

The actual meaning of that bit is not clear yet, but not setting it leads
to some corner-case issues, like the CMD53 failing, which is used to
implement SDIO packet aggregation.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 6 ++++++
 1 file changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index b9c8a62bc212..51d6388a194e 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -253,6 +253,8 @@ struct sunxi_mmc_cfg {
 
 	/* does the IP block support autocalibration? */
 	bool can_calibrate;
+
+	bool needs_new_timings;
 };
 
 struct sunxi_mmc_host {
@@ -779,6 +781,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 	}
 	mmc_writel(host, REG_CLKCR, rval);
 
+	if (host->cfg->needs_new_timings)
+		mmc_writel(host, REG_SD_NTSR, SDXC_2X_TIMING_MODE);
+
 	ret = sunxi_mmc_clk_set_phase(host, ios, rate);
 	if (ret)
 		return ret;
@@ -1076,6 +1081,7 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
 	.idma_des_size_bits = 16,
 	.clk_delays = NULL,
 	.can_calibrate = true,
+	.needs_new_timings = true,
 };
 
 static const struct of_device_id sunxi_mmc_of_match[] = {
-- 
git-series 0.8.11

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

* [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (3 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 4/13] mmc: sunxi: Enable the new timings for the A64 MMC controllers Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-24  8:18   ` Ulf Hansson
  2017-01-16 16:56 ` [PATCH v3 6/13] mmc: sunxi: Add EMMC (MMC2) controller compatible Maxime Ripard
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The A64 MMC controllers need DATA0 to be masked while updating the clock,
otherwise any subsequent command will result in a timeout.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 51d6388a194e..6bbe61397b7c 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -101,6 +101,7 @@
 	(SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET)
 
 /* clock control bits */
+#define SDXC_MASK_DATA0			BIT(31)
 #define SDXC_CARD_CLOCK_ON		BIT(16)
 #define SDXC_LOW_POWER_ON		BIT(17)
 
@@ -254,6 +255,9 @@ struct sunxi_mmc_cfg {
 	/* does the IP block support autocalibration? */
 	bool can_calibrate;
 
+	/* Does DATA0 needs to be masked while the clock is updated */
+	bool mask_data0;
+
 	bool needs_new_timings;
 };
 
@@ -657,10 +661,12 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 	u32 rval;
 
 	rval = mmc_readl(host, REG_CLKCR);
-	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
+	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
 
 	if (oclk_en)
 		rval |= SDXC_CARD_CLOCK_ON;
+	if (host->cfg->mask_data0)
+		rval |= SDXC_MASK_DATA0;
 
 	mmc_writel(host, REG_CLKCR, rval);
 
@@ -680,6 +686,11 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 		return -EIO;
 	}
 
+	if (host->cfg->mask_data0) {
+		rval = mmc_readl(host, REG_CLKCR);
+		mmc_writel(host, REG_CLKCR, rval & ~SDXC_MASK_DATA0);
+	}
+
 	return 0;
 }
 
@@ -1081,6 +1092,7 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
 	.idma_des_size_bits = 16,
 	.clk_delays = NULL,
 	.can_calibrate = true,
+	.mask_data0 = true,
 	.needs_new_timings = true,
 };
 
-- 
git-series 0.8.11

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

* [PATCH v3 6/13] mmc: sunxi: Add EMMC (MMC2) controller compatible
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (4 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-16 16:56 ` [PATCH v3 7/13] mmc: sunxi: Add more debug messages Maxime Ripard
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The MMC2 controller on the A64 is kind of a special beast.

While the general controller design is the same than the other MMC
controllers in the SoC, it also has a bunch of features and changes that
prevent it to be driven in the same way.

It has for example a different bus width limit, a different maximum
frequency, and, for some reason, the maximum buffer size of a DMA
descriptor.

Add a new compatible specifically for this controller.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 8 ++++++++
 1 file changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 6bbe61397b7c..f0f6922bca8a 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -5,6 +5,7 @@
  * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch>
  * (C) Copyright 2013-2014 David Lanzend�rfer <david.lanzendoerfer@o2s.ch>
  * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2017 Sootech SA
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -1096,12 +1097,19 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
 	.needs_new_timings = true,
 };
 
+static const struct sunxi_mmc_cfg sun50i_a64_emmc_cfg = {
+	.idma_des_size_bits = 13,
+	.clk_delays = NULL,
+	.can_calibrate = true,
+};
+
 static const struct of_device_id sunxi_mmc_of_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
 	{ .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
 	{ .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg },
 	{ .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg },
 	{ .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
+	{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
-- 
git-series 0.8.11

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

* [PATCH v3 7/13] mmc: sunxi: Add more debug messages
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (5 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 6/13] mmc: sunxi: Add EMMC (MMC2) controller compatible Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-24  8:22   ` Ulf Hansson
  2017-01-16 16:56 ` [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes Maxime Ripard
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

Add a bit more debug messages that can be helpful when debugging the clock
setup.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/mmc/host/sunxi-mmc.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index f0f6922bca8a..40ed287ceb1c 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -661,6 +661,9 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 	unsigned long expire = jiffies + msecs_to_jiffies(750);
 	u32 rval;
 
+	dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n",
+		oclk_en ? "en" : "dis");
+
 	rval = mmc_readl(host, REG_CLKCR);
 	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
 
@@ -737,6 +740,7 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host,
 			index = SDXC_CLK_50M_DDR;
 		}
 	} else {
+		dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n");
 		return -EINVAL;
 	}
 
@@ -753,6 +757,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 	u32 rval, clock = ios->clock;
 	int ret;
 
+	dev_dbg(mmc_dev(host->mmc), "setting clk to %u (requested %u)\n",
+		clock, ios->clock);
+
 	ret = sunxi_mmc_oclk_onoff(host, 0);
 	if (ret)
 		return ret;
@@ -771,8 +778,7 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
 			clock, rate);
 		return rate;
 	}
-	dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %ld\n",
-		clock, rate);
+	dev_dbg(mmc_dev(host->mmc), "Rounded clk to %ld\n", rate);
 
 	/* setting clock rate */
 	ret = clk_set_rate(host->clk_mmc, rate);
-- 
git-series 0.8.11

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

* [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (6 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 7/13] mmc: sunxi: Add more debug messages Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-16 19:16   ` Corentin Labbe
  2017-01-16 16:56 ` [PATCH v3 9/13] arm64: allwinner: a64: Add MMC pinctrl nodes Maxime Ripard
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

From: Andre Przywara <andre.przywara@arm.com>

The A64 has 3 MMC controllers, one of them being especially targeted to
eMMC. Among other things, it has a data strobe signal and a 8 bits data
width.

The two other are more usual controllers that will have a 4 bits width at
most and no data strobe signal, which limits it to more usual SD or MMC
peripherals.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 39 ++++++++++++++++++++-
 1 file changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 99b6bb1e141c..143e9706438f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -299,6 +299,45 @@
 			#size-cells = <0>;
 		};
 
+		mmc0: mmc@1c0f000 {
+			compatible = "allwinner,sun50i-a64-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc@1c10000 {
+			compatible = "allwinner,sun50i-a64-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc2: mmc@1c11000 {
+			compatible = "allwinner,sun50i-a64-emmc";
+			reg = <0x01c11000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC2>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		gic: interrupt-controller@1c81000 {
 			compatible = "arm,gic-400";
 			reg = <0x01c81000 0x1000>,
-- 
git-series 0.8.11

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

* [PATCH v3 9/13] arm64: allwinner: a64: Add MMC pinctrl nodes
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (7 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes Maxime Ripard
@ 2017-01-16 16:56 ` Maxime Ripard
  2017-01-16 16:57 ` [PATCH v3 10/13] arm64: allwinner: a64: Increase the MMC max frequency Maxime Ripard
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The A64 only has a single set of pins for each MMC controller. Since we
already have boards that require all of them, let's add them to the DTSI.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 25 ++++++++++++++++++++-
 1 file changed, 25 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 143e9706438f..8e149498e096 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -205,6 +205,31 @@
 				function = "i2c1";
 			};
 
+			mmc0_pins: mmc0-pins {
+				pins = "PF0", "PF1", "PF2", "PF3",
+				       "PF4", "PF5";
+				function = "mmc0";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			mmc1_pins: mmc1-pins {
+				pins = "PG0", "PG1", "PG2", "PG3",
+				       "PG4", "PG5";
+				function = "mmc1";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			mmc2_pins: mmc2-pins {
+				pins = "PC1", "PC5", "PC6", "PC8", "PC9",
+				       "PC10","PC11", "PC12", "PC13",
+				       "PC14", "PC15", "PC16";
+				function = "mmc2";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
 			uart0_pins_a: uart0@0 {
 				pins = "PB8", "PB9";
 				function = "uart0";
-- 
git-series 0.8.11

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

* [PATCH v3 10/13] arm64: allwinner: a64: Increase the MMC max frequency
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (8 preceding siblings ...)
  2017-01-16 16:56 ` [PATCH v3 9/13] arm64: allwinner: a64: Add MMC pinctrl nodes Maxime Ripard
@ 2017-01-16 16:57 ` Maxime Ripard
  2017-01-16 16:57 ` [PATCH v3 11/13] arm64: allwinner: pine64: add MMC support Maxime Ripard
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

The eMMC controller seem to have a maximum frequency of 200MHz, while the
regular MMC controllers are capped at 150MHz.

Since older SoCs cannot go that high, we cannot change the default maximum
frequency, but fortunately for us we have a property for that in the DT.

This also has the side effect of allowing to use the MMC HS200 and SD
SDR104 modes for the boards that support it (with either 1.2v or 1.8v IOs).

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

arm64: allwinner: a64: Limit MMC0 and MMC1 rates to 150MHz

Trying to set the bus to 200MHz on MMC1 when doing SDIO is failing.
Allwinner sets the maximum for this bus to 150MHz, so enforce that limit.

This hasn't been tested with MMC0, but the documented limit is the same,
and I expect the behaviour to be the same.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 3 +++
 1 file changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 8e149498e096..b371fccc234b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -332,6 +332,7 @@
 			resets = <&ccu RST_BUS_MMC0>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -345,6 +346,7 @@
 			resets = <&ccu RST_BUS_MMC1>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -358,6 +360,7 @@
 			resets = <&ccu RST_BUS_MMC2>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <200000000>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
git-series 0.8.11

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

* [PATCH v3 11/13] arm64: allwinner: pine64: add MMC support
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (9 preceding siblings ...)
  2017-01-16 16:57 ` [PATCH v3 10/13] arm64: allwinner: a64: Increase the MMC max frequency Maxime Ripard
@ 2017-01-16 16:57 ` Maxime Ripard
  2017-01-16 16:57 ` [PATCH v3 12/13] arm64: allwinner: a64: add UART1 pin nodes Maxime Ripard
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

From: Andre Przywara <andre.przywara@arm.com>

All Pine64 boards connect an micro-SD card slot to the first MMC
controller.
Enable the respective DT node and specify the (always-on) regulator
and card-detect pin.
As a micro-SD slot does not feature a write-protect switch, we disable
this feature.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 20 ++++++++++++++-
 1 file changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index cf9105179bcb..c680ed385da3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -44,6 +44,8 @@
 
 #include "sun50i-a64.dtsi"
 
+#include <dt-bindings/gpio/gpio.h>
+
 / {
 	model = "Pine64";
 	compatible = "pine64,pine64", "allwinner,sun50i-a64";
@@ -55,6 +57,13 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &ehci1 {
@@ -71,6 +80,17 @@
 	bias-pull-up;
 };
 
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	disable-wp;
+	bus-width = <4>;
+	status = "okay";
+};
+
 &ohci1 {
 	status = "okay";
 };
-- 
git-series 0.8.11

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

* [PATCH v3 12/13] arm64: allwinner: a64: add UART1 pin nodes
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (10 preceding siblings ...)
  2017-01-16 16:57 ` [PATCH v3 11/13] arm64: allwinner: pine64: add MMC support Maxime Ripard
@ 2017-01-16 16:57 ` Maxime Ripard
  2017-01-16 16:57 ` [PATCH v3 13/13] arm64: allwinner: add BananaPi-M64 support Maxime Ripard
  2017-01-23 10:58 ` [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

From: Andre Przywara <andre.przywara@arm.com>

On many boards UART1 connects to a Bluetooth chip, so add the pinctrl
nodes for the only pins providing access to that UART. That includes
those pins for hardware flow control (RTS/CTS).

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index b371fccc234b..8ffdc24f92ca 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -234,6 +234,16 @@
 				pins = "PB8", "PB9";
 				function = "uart0";
 			};
+
+			uart1_pins: uart1_pins {
+				pins = "PG6", "PG7";
+				function = "uart1";
+			};
+
+			uart1_rts_cts_pins: uart1_rts_cts_pins {
+				pins = "PG8", "PG9";
+				function = "uart1";
+			};
 		};
 
 		uart0: serial@1c28000 {
-- 
git-series 0.8.11

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

* [PATCH v3 13/13] arm64: allwinner: add BananaPi-M64 support
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (11 preceding siblings ...)
  2017-01-16 16:57 ` [PATCH v3 12/13] arm64: allwinner: a64: add UART1 pin nodes Maxime Ripard
@ 2017-01-16 16:57 ` Maxime Ripard
  2017-01-23 10:58 ` [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard, Ulf Hansson
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-mmc, Andre Przywara

From: Andre Przywara <andre.przywara@arm.com>

The Banana Pi M64 board is a typical single board computer based on the
Allwinner A64 SoC. Aside from the usual peripherals it features eMMC
storage, which is connected to the 8-bit capable SDHC2 controller.
Also it has a soldered WiFi/Bluetooth chip, so we enable UART1 and SDHC1
as those two interfaces are connected to it.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm64/boot/dts/allwinner/Makefile                    |   1 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 120 +++++++-
 2 files changed, 121 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 1e29a5ae8282..bc6f342be59f 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
 
 always		:= $(dtb-y)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
new file mode 100644
index 000000000000..6872135d7f84
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016 ARM Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "BananaPi-M64";
+	compatible = "sinovoip,bananapi-m64", "allwinner,sun50i-a64";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&i2c1_pins {
+	bias-pull-up;
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	disable-wp;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	status = "okay";
+};
-- 
git-series 0.8.11

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

* Re: [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes
  2017-01-16 16:56 ` [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes Maxime Ripard
@ 2017-01-16 19:16   ` Corentin Labbe
  2017-01-25  9:17     ` Maxime Ripard
  0 siblings, 1 reply; 27+ messages in thread
From: Corentin Labbe @ 2017-01-16 19:16 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Ulf Hansson, devicetree, Andre Przywara, linux-mmc,
	linux-kernel, Rob Herring, linux-arm-kernel

On Mon, Jan 16, 2017 at 05:56:58PM +0100, Maxime Ripard wrote:
> From: Andre Przywara <andre.przywara@arm.com>
> 
> The A64 has 3 MMC controllers, one of them being especially targeted to
> eMMC. Among other things, it has a data strobe signal and a 8 bits data
> width.
> 
> The two other are more usual controllers that will have a 4 bits width at
> most and no data strobe signal, which limits it to more usual SD or MMC
> peripherals.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 39 ++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 99b6bb1e141c..143e9706438f 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -299,6 +299,45 @@
>  			#size-cells = <0>;
>  		};
>  
> +		mmc0: mmc@1c0f000 {
> +			compatible = "allwinner,sun50i-a64-mmc";
> +			reg = <0x01c0f000 0x1000>;
> +			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
> +			clock-names = "ahb", "mmc";
> +			resets = <&ccu RST_BUS_MMC0>;
> +			reset-names = "ahb";
> +			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> +			status = "disabled";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		mmc1: mmc@1c10000 {
> +			compatible = "allwinner,sun50i-a64-mmc";
> +			reg = <0x01c10000 0x1000>;
> +			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
> +			clock-names = "ahb", "mmc";
> +			resets = <&ccu RST_BUS_MMC1>;
> +			reset-names = "ahb";
> +			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> +			status = "disabled";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		mmc2: mmc@1c11000 {
> +			compatible = "allwinner,sun50i-a64-emmc";
> +			reg = <0x01c11000 0x1000>;
> +			clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
> +			clock-names = "ahb", "mmc";
> +			resets = <&ccu RST_BUS_MMC2>;
> +			reset-names = "ahb";
> +			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> +			status = "disabled";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
>  		gic: interrupt-controller@1c81000 {
>  			compatible = "arm,gic-400";
>  			reg = <0x01c81000 0x1000>,

Hello

It seems that mmc node is after i2c@1c2b400 so not in address order.

Regards
Corentin Labbe

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

* Re: [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support
  2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
                   ` (12 preceding siblings ...)
  2017-01-16 16:57 ` [PATCH v3 13/13] arm64: allwinner: add BananaPi-M64 support Maxime Ripard
@ 2017-01-23 10:58 ` Maxime Ripard
  13 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:58 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

[-- Attachment #1: Type: text/plain, Size: 1079 bytes --]

Hi Ulf,

On Mon, Jan 16, 2017 at 05:56:50PM +0100, Maxime Ripard wrote:
> Hi,
> 
> Here is a new attempt at getting the MMC controllers running, following the
> work done by Andre.
> 
> This has been tested on a board with one SDIO device (a Marvell WiFi chip)
> and a Kingston eMMC with 1.8V IOs.
> 
> For SDIO, the HS DDR mode works just fine. That serie also enables the
> SDR104 mode to work on the devices that are capable of this.
> 
> For the eMMC, HS200 with the voltage switch works. HS400 doesn't at the
> moment, but since it's significantly more complex, and at the same time
> Allwinner recommends to limit its frequency to 100MHz, this doesn't have
> any benefits. If there's any at some point, this can be added later.

Unless you have objections, I'd really like this to be in
4.11. There's a bunch of things where I'm not entirely sure
(especially the clock gating part), it would be great if you could
have a look.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence
  2017-01-16 16:56 ` [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence Maxime Ripard
@ 2017-01-24  8:12   ` Ulf Hansson
  2017-01-25  8:26     ` Maxime Ripard
  0 siblings, 1 reply; 27+ messages in thread
From: Ulf Hansson @ 2017-01-24  8:12 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

On 16 January 2017 at 17:56, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The MMC and SD specifications documents that the clock frequency should
> only be changed once gated.

Where?

>
> The current code first modifies the parent clock, gates it and then
> modifies the internal divider. This means that since the parent clock rate
> might be changed, the bus clock might be changed as well before it is
> gated, which breaks the specification.
>
> Move the gating before the parent rate modification.

This all makes perfect sense to me, however I am not sure you need to
refer to the spec to justify these changes.

Kind regards
Uffe

>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index b1d1303389a7..ab4324e6eb74 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -761,6 +761,10 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>         u32 rval, clock = ios->clock;
>         int ret;
>
> +       ret = sunxi_mmc_oclk_onoff(host, 0);
> +       if (ret)
> +               return ret;
> +
>         /* 8 bit DDR requires a higher module clock */
>         if (ios->timing == MMC_TIMING_MMC_DDR52 &&
>             ios->bus_width == MMC_BUS_WIDTH_8)
> @@ -783,10 +787,6 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>                 return ret;
>         }
>
> -       ret = sunxi_mmc_oclk_onoff(host, 0);
> -       if (ret)
> -               return ret;
> -
>         /* clear internal divider */
>         rval = mmc_readl(host, REG_CLKCR);
>         rval &= ~0xff;
> --
> git-series 0.8.11

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

* Re: [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0
  2017-01-16 16:56 ` [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0 Maxime Ripard
@ 2017-01-24  8:14   ` Ulf Hansson
  0 siblings, 0 replies; 27+ messages in thread
From: Ulf Hansson @ 2017-01-24  8:14 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

On 16 January 2017 at 17:56, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The MMC core assumes that the code will gate the clock when the bus
> frequency is set to 0, which we've been ignoring so far.
>
> Handle that.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Looks good!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sunxi-mmc.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index ab4324e6eb74..019f95e8e7c5 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -765,6 +765,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>         if (ret)
>                 return ret;
>
> +       if (!ios->clock)
> +               return 0;
> +
>         /* 8 bit DDR requires a higher module clock */
>         if (ios->timing == MMC_TIMING_MMC_DDR52 &&
>             ios->bus_width == MMC_BUS_WIDTH_8)
> @@ -882,7 +885,7 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>         mmc_writel(host, REG_GCTRL, rval);
>
>         /* set up clock */
> -       if (ios->clock && ios->power_mode) {
> +       if (ios->power_mode) {
>                 host->ferror = sunxi_mmc_clk_set_rate(host, ios);
>                 /* Android code had a usleep_range(50000, 55000); here */
>         }
> --
> git-series 0.8.11

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

* Re: [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64
  2017-01-16 16:56 ` [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64 Maxime Ripard
@ 2017-01-24  8:16   ` Ulf Hansson
  2017-01-24  9:15     ` Andre Przywara
  2017-01-25  9:10     ` Maxime Ripard
  0 siblings, 2 replies; 27+ messages in thread
From: Ulf Hansson @ 2017-01-24  8:16 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

On 16 January 2017 at 17:56, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Experience have shown that the using the  autocalibration could severely
> degrade the performances of the MMC bus.
>
> Allwinner is using in its BSP a delay set to 0 for all the modes but HS400.
> Remove the calibration code for now, and add comments to document our
> findings.

So doesn't this break some platforms using HS400? Or are you saying
those are already broken?

Kind regards
Uffe

>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 50 ++++++++++++-------------------------
>  1 file changed, 17 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 019f95e8e7c5..b9c8a62bc212 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -683,41 +683,19 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>
>  static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off)
>  {
> -       u32 reg = readl(host->reg_base + reg_off);
> -       u32 delay;
> -       unsigned long timeout;
> -
>         if (!host->cfg->can_calibrate)
>                 return 0;
>
> -       reg &= ~(SDXC_CAL_DL_MASK << SDXC_CAL_DL_SW_SHIFT);
> -       reg &= ~SDXC_CAL_DL_SW_EN;
> -
> -       writel(reg | SDXC_CAL_START, host->reg_base + reg_off);
> -
> -       dev_dbg(mmc_dev(host->mmc), "calibration started\n");
> -
> -       timeout = jiffies + HZ * SDXC_CAL_TIMEOUT;
> -
> -       while (!((reg = readl(host->reg_base + reg_off)) & SDXC_CAL_DONE)) {
> -               if (time_before(jiffies, timeout))
> -                       cpu_relax();
> -               else {
> -                       reg &= ~SDXC_CAL_START;
> -                       writel(reg, host->reg_base + reg_off);
> -
> -                       return -ETIMEDOUT;
> -               }
> -       }
> -
> -       delay = (reg >> SDXC_CAL_DL_SHIFT) & SDXC_CAL_DL_MASK;
> -
> -       reg &= ~SDXC_CAL_START;
> -       reg |= (delay << SDXC_CAL_DL_SW_SHIFT) | SDXC_CAL_DL_SW_EN;
> -
> -       writel(reg, host->reg_base + reg_off);
> -
> -       dev_dbg(mmc_dev(host->mmc), "calibration ended, reg is 0x%x\n", reg);
> +       /*
> +        * FIXME:
> +        * This is not clear how the calibration is supposed to work
> +        * yet. The best rate have been obtained by simply setting the
> +        * delay to 0, as Allwinner does in its BSP.
> +        *
> +        * The only mode that doesn't have such a delay is HS400, that
> +        * is in itself a TODO.
> +        */
> +       writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off);
>
>         return 0;
>  }
> @@ -809,7 +787,13 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>         if (ret)
>                 return ret;
>
> -       /* TODO: enable calibrate on sdc2 SDXC_REG_DS_DL_REG of A64 */
> +       /*
> +        * FIXME:
> +        *
> +        * In HS400 we'll also need to calibrate the data strobe
> +        * signal. This should only happen on the MMC2 controller (at
> +        * least on the A64).
> +        */
>
>         return sunxi_mmc_oclk_onoff(host, 1);
>  }
> --
> git-series 0.8.11

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

* Re: [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock
  2017-01-16 16:56 ` [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock Maxime Ripard
@ 2017-01-24  8:18   ` Ulf Hansson
  2017-01-25  9:16     ` Maxime Ripard
  0 siblings, 1 reply; 27+ messages in thread
From: Ulf Hansson @ 2017-01-24  8:18 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

On 16 January 2017 at 17:56, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The A64 MMC controllers need DATA0 to be masked while updating the clock,
> otherwise any subsequent command will result in a timeout.

Could you elaborate on what mask DATA0 really means? I don't follow.

Kind regards
Uffe

>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 51d6388a194e..6bbe61397b7c 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -101,6 +101,7 @@
>         (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET)
>
>  /* clock control bits */
> +#define SDXC_MASK_DATA0                        BIT(31)
>  #define SDXC_CARD_CLOCK_ON             BIT(16)
>  #define SDXC_LOW_POWER_ON              BIT(17)
>
> @@ -254,6 +255,9 @@ struct sunxi_mmc_cfg {
>         /* does the IP block support autocalibration? */
>         bool can_calibrate;
>
> +       /* Does DATA0 needs to be masked while the clock is updated */
> +       bool mask_data0;
> +
>         bool needs_new_timings;
>  };
>
> @@ -657,10 +661,12 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>         u32 rval;
>
>         rval = mmc_readl(host, REG_CLKCR);
> -       rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
> +       rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
>
>         if (oclk_en)
>                 rval |= SDXC_CARD_CLOCK_ON;
> +       if (host->cfg->mask_data0)
> +               rval |= SDXC_MASK_DATA0;
>
>         mmc_writel(host, REG_CLKCR, rval);
>
> @@ -680,6 +686,11 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>                 return -EIO;
>         }
>
> +       if (host->cfg->mask_data0) {
> +               rval = mmc_readl(host, REG_CLKCR);
> +               mmc_writel(host, REG_CLKCR, rval & ~SDXC_MASK_DATA0);
> +       }
> +
>         return 0;
>  }
>
> @@ -1081,6 +1092,7 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
>         .idma_des_size_bits = 16,
>         .clk_delays = NULL,
>         .can_calibrate = true,
> +       .mask_data0 = true,
>         .needs_new_timings = true,
>  };
>
> --
> git-series 0.8.11

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

* Re: [PATCH v3 7/13] mmc: sunxi: Add more debug messages
  2017-01-16 16:56 ` [PATCH v3 7/13] mmc: sunxi: Add more debug messages Maxime Ripard
@ 2017-01-24  8:22   ` Ulf Hansson
  2017-01-25  9:16     ` Maxime Ripard
  0 siblings, 1 reply; 27+ messages in thread
From: Ulf Hansson @ 2017-01-24  8:22 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

On 16 January 2017 at 17:56, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Add a bit more debug messages that can be helpful when debugging the clock
> setup.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index f0f6922bca8a..40ed287ceb1c 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -661,6 +661,9 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>         unsigned long expire = jiffies + msecs_to_jiffies(750);
>         u32 rval;
>
> +       dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n",
> +               oclk_en ? "en" : "dis");
> +
>         rval = mmc_readl(host, REG_CLKCR);
>         rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
>
> @@ -737,6 +740,7 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host,
>                         index = SDXC_CLK_50M_DDR;
>                 }
>         } else {
> +               dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n");
>                 return -EINVAL;
>         }
>
> @@ -753,6 +757,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>         u32 rval, clock = ios->clock;
>         int ret;
>
> +       dev_dbg(mmc_dev(host->mmc), "setting clk to %u (requested %u)\n",
> +               clock, ios->clock);
> +
>

A better option is to update mmc->actual_clock. That value is
available (and the requested value) though the debugFS nodes.

>         ret = sunxi_mmc_oclk_onoff(host, 0);
>         if (ret)
>                 return ret;
> @@ -771,8 +778,7 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>                         clock, rate);
>                 return rate;
>         }
> -       dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %ld\n",
> -               clock, rate);
> +       dev_dbg(mmc_dev(host->mmc), "Rounded clk to %ld\n", rate);
>

Ditto.

>         /* setting clock rate */
>         ret = clk_set_rate(host->clk_mmc, rate);
> --
> git-series 0.8.11

Kind regards
Uffe

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

* Re: [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64
  2017-01-24  8:16   ` Ulf Hansson
@ 2017-01-24  9:15     ` Andre Przywara
  2017-01-25  9:10     ` Maxime Ripard
  1 sibling, 0 replies; 27+ messages in thread
From: Andre Przywara @ 2017-01-24  9:15 UTC (permalink / raw)
  To: Ulf Hansson, Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc

Hi Ulf,

On 24/01/17 08:16, Ulf Hansson wrote:
> On 16 January 2017 at 17:56, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>> Experience have shown that the using the  autocalibration could severely
>> degrade the performances of the MMC bus.
>>
>> Allwinner is using in its BSP a delay set to 0 for all the modes but HS400.
>> Remove the calibration code for now, and add comments to document our
>> findings.
> 
> So doesn't this break some platforms using HS400? Or are you saying
> those are already broken?

This is a sunxi specific calibration routine, which was introduced
lately (e1b8dfd1b1c6) to be used by the Allwinner's enhanced MMC
controller. This is only used by devices using the sun50i-a64-mmc
compatible, of which this series introduces the first user.

So there is no way this can regress in any way, since the code wasn't
actually used before.

Cheers,
Andre.

> 
>>
>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> ---
>>  drivers/mmc/host/sunxi-mmc.c | 50 ++++++++++++-------------------------
>>  1 file changed, 17 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index 019f95e8e7c5..b9c8a62bc212 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -683,41 +683,19 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>>
>>  static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off)
>>  {
>> -       u32 reg = readl(host->reg_base + reg_off);
>> -       u32 delay;
>> -       unsigned long timeout;
>> -
>>         if (!host->cfg->can_calibrate)
>>                 return 0;
>>
>> -       reg &= ~(SDXC_CAL_DL_MASK << SDXC_CAL_DL_SW_SHIFT);
>> -       reg &= ~SDXC_CAL_DL_SW_EN;
>> -
>> -       writel(reg | SDXC_CAL_START, host->reg_base + reg_off);
>> -
>> -       dev_dbg(mmc_dev(host->mmc), "calibration started\n");
>> -
>> -       timeout = jiffies + HZ * SDXC_CAL_TIMEOUT;
>> -
>> -       while (!((reg = readl(host->reg_base + reg_off)) & SDXC_CAL_DONE)) {
>> -               if (time_before(jiffies, timeout))
>> -                       cpu_relax();
>> -               else {
>> -                       reg &= ~SDXC_CAL_START;
>> -                       writel(reg, host->reg_base + reg_off);
>> -
>> -                       return -ETIMEDOUT;
>> -               }
>> -       }
>> -
>> -       delay = (reg >> SDXC_CAL_DL_SHIFT) & SDXC_CAL_DL_MASK;
>> -
>> -       reg &= ~SDXC_CAL_START;
>> -       reg |= (delay << SDXC_CAL_DL_SW_SHIFT) | SDXC_CAL_DL_SW_EN;
>> -
>> -       writel(reg, host->reg_base + reg_off);
>> -
>> -       dev_dbg(mmc_dev(host->mmc), "calibration ended, reg is 0x%x\n", reg);
>> +       /*
>> +        * FIXME:
>> +        * This is not clear how the calibration is supposed to work
>> +        * yet. The best rate have been obtained by simply setting the
>> +        * delay to 0, as Allwinner does in its BSP.
>> +        *
>> +        * The only mode that doesn't have such a delay is HS400, that
>> +        * is in itself a TODO.
>> +        */
>> +       writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off);
>>
>>         return 0;
>>  }
>> @@ -809,7 +787,13 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>>         if (ret)
>>                 return ret;
>>
>> -       /* TODO: enable calibrate on sdc2 SDXC_REG_DS_DL_REG of A64 */
>> +       /*
>> +        * FIXME:
>> +        *
>> +        * In HS400 we'll also need to calibrate the data strobe
>> +        * signal. This should only happen on the MMC2 controller (at
>> +        * least on the A64).
>> +        */
>>
>>         return sunxi_mmc_oclk_onoff(host, 1);
>>  }
>> --
>> git-series 0.8.11

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

* Re: [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence
  2017-01-24  8:12   ` Ulf Hansson
@ 2017-01-25  8:26     ` Maxime Ripard
  0 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-25  8:26 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

[-- Attachment #1: Type: text/plain, Size: 961 bytes --]

Hi Ulf,

On Tue, Jan 24, 2017 at 09:12:07AM +0100, Ulf Hansson wrote:
> On 16 January 2017 at 17:56, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > The MMC and SD specifications documents that the clock frequency should
> > only be changed once gated.
> 
> Where?
> 
> >
> > The current code first modifies the parent clock, gates it and then
> > modifies the internal divider. This means that since the parent clock rate
> > might be changed, the bus clock might be changed as well before it is
> > gated, which breaks the specification.
> >
> > Move the gating before the parent rate modification.
> 
> This all makes perfect sense to me, however I am not sure you need to
> refer to the spec to justify these changes.

I can't find it anymore :/

I'll resend that patch reworking the commit log.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64
  2017-01-24  8:16   ` Ulf Hansson
  2017-01-24  9:15     ` Andre Przywara
@ 2017-01-25  9:10     ` Maxime Ripard
  1 sibling, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-25  9:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

Hi Ulf,

On Tue, Jan 24, 2017 at 09:16:12AM +0100, Ulf Hansson wrote:
> On 16 January 2017 at 17:56, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > Experience have shown that the using the  autocalibration could severely
> > degrade the performances of the MMC bus.
> >
> > Allwinner is using in its BSP a delay set to 0 for all the modes but HS400.
> > Remove the calibration code for now, and add comments to document our
> > findings.
> 
> So doesn't this break some platforms using HS400? Or are you saying
> those are already broken?

Like Andre said, HS400 isn't supported at all, so there's no
regression or brokenness involved :)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock
  2017-01-24  8:18   ` Ulf Hansson
@ 2017-01-25  9:16     ` Maxime Ripard
  0 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-25  9:16 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

[-- Attachment #1: Type: text/plain, Size: 733 bytes --]

On Tue, Jan 24, 2017 at 09:18:46AM +0100, Ulf Hansson wrote:
> On 16 January 2017 at 17:56, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > The A64 MMC controllers need DATA0 to be masked while updating the clock,
> > otherwise any subsequent command will result in a timeout.
> 
> Could you elaborate on what mask DATA0 really means? I don't follow.

To be honest, I don't really know :)

This is how it's called both in the vendor tree and the datasheet. I
*think* it might be the first data line on the bus, but I'm not sure
exactly why that would cause any issue when updating the clock.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v3 7/13] mmc: sunxi: Add more debug messages
  2017-01-24  8:22   ` Ulf Hansson
@ 2017-01-25  9:16     ` Maxime Ripard
  0 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-25  9:16 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chen-Yu Tsai, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-mmc, Andre Przywara

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

On Tue, Jan 24, 2017 at 09:22:24AM +0100, Ulf Hansson wrote:
> On 16 January 2017 at 17:56, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > Add a bit more debug messages that can be helpful when debugging the clock
> > setup.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> >  drivers/mmc/host/sunxi-mmc.c | 10 ++++++++--
> >  1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> > index f0f6922bca8a..40ed287ceb1c 100644
> > --- a/drivers/mmc/host/sunxi-mmc.c
> > +++ b/drivers/mmc/host/sunxi-mmc.c
> > @@ -661,6 +661,9 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
> >         unsigned long expire = jiffies + msecs_to_jiffies(750);
> >         u32 rval;
> >
> > +       dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n",
> > +               oclk_en ? "en" : "dis");
> > +
> >         rval = mmc_readl(host, REG_CLKCR);
> >         rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
> >
> > @@ -737,6 +740,7 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host,
> >                         index = SDXC_CLK_50M_DDR;
> >                 }
> >         } else {
> > +               dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n");
> >                 return -EINVAL;
> >         }
> >
> > @@ -753,6 +757,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
> >         u32 rval, clock = ios->clock;
> >         int ret;
> >
> > +       dev_dbg(mmc_dev(host->mmc), "setting clk to %u (requested %u)\n",
> > +               clock, ios->clock);
> > +
> >
> 
> A better option is to update mmc->actual_clock. That value is
> available (and the requested value) though the debugFS nodes.

Ok, I will change that.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes
  2017-01-16 19:16   ` Corentin Labbe
@ 2017-01-25  9:17     ` Maxime Ripard
  0 siblings, 0 replies; 27+ messages in thread
From: Maxime Ripard @ 2017-01-25  9:17 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: Chen-Yu Tsai, Ulf Hansson, devicetree, Andre Przywara, linux-mmc,
	linux-kernel, Rob Herring, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2866 bytes --]

Hi Corentin,

On Mon, Jan 16, 2017 at 08:16:41PM +0100, Corentin Labbe wrote:
> On Mon, Jan 16, 2017 at 05:56:58PM +0100, Maxime Ripard wrote:
> > From: Andre Przywara <andre.przywara@arm.com>
> > 
> > The A64 has 3 MMC controllers, one of them being especially targeted to
> > eMMC. Among other things, it has a data strobe signal and a 8 bits data
> > width.
> > 
> > The two other are more usual controllers that will have a 4 bits width at
> > most and no data strobe signal, which limits it to more usual SD or MMC
> > peripherals.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 39 ++++++++++++++++++++-
> >  1 file changed, 39 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > index 99b6bb1e141c..143e9706438f 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > @@ -299,6 +299,45 @@
> >  			#size-cells = <0>;
> >  		};
> >  
> > +		mmc0: mmc@1c0f000 {
> > +			compatible = "allwinner,sun50i-a64-mmc";
> > +			reg = <0x01c0f000 0x1000>;
> > +			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
> > +			clock-names = "ahb", "mmc";
> > +			resets = <&ccu RST_BUS_MMC0>;
> > +			reset-names = "ahb";
> > +			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> > +			status = "disabled";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +		};
> > +
> > +		mmc1: mmc@1c10000 {
> > +			compatible = "allwinner,sun50i-a64-mmc";
> > +			reg = <0x01c10000 0x1000>;
> > +			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
> > +			clock-names = "ahb", "mmc";
> > +			resets = <&ccu RST_BUS_MMC1>;
> > +			reset-names = "ahb";
> > +			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> > +			status = "disabled";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +		};
> > +
> > +		mmc2: mmc@1c11000 {
> > +			compatible = "allwinner,sun50i-a64-emmc";
> > +			reg = <0x01c11000 0x1000>;
> > +			clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
> > +			clock-names = "ahb", "mmc";
> > +			resets = <&ccu RST_BUS_MMC2>;
> > +			reset-names = "ahb";
> > +			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> > +			status = "disabled";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +		};
> > +
> >  		gic: interrupt-controller@1c81000 {
> >  			compatible = "arm,gic-400";
> >  			reg = <0x01c81000 0x1000>,
> 
> Hello
> 
> It seems that mmc node is after i2c@1c2b400 so not in address order.

You're right, I'll fix this in the v3.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

end of thread, other threads:[~2017-01-25  9:18 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-16 16:56 [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence Maxime Ripard
2017-01-24  8:12   ` Ulf Hansson
2017-01-25  8:26     ` Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0 Maxime Ripard
2017-01-24  8:14   ` Ulf Hansson
2017-01-16 16:56 ` [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64 Maxime Ripard
2017-01-24  8:16   ` Ulf Hansson
2017-01-24  9:15     ` Andre Przywara
2017-01-25  9:10     ` Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 4/13] mmc: sunxi: Enable the new timings for the A64 MMC controllers Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock Maxime Ripard
2017-01-24  8:18   ` Ulf Hansson
2017-01-25  9:16     ` Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 6/13] mmc: sunxi: Add EMMC (MMC2) controller compatible Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 7/13] mmc: sunxi: Add more debug messages Maxime Ripard
2017-01-24  8:22   ` Ulf Hansson
2017-01-25  9:16     ` Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes Maxime Ripard
2017-01-16 19:16   ` Corentin Labbe
2017-01-25  9:17     ` Maxime Ripard
2017-01-16 16:56 ` [PATCH v3 9/13] arm64: allwinner: a64: Add MMC pinctrl nodes Maxime Ripard
2017-01-16 16:57 ` [PATCH v3 10/13] arm64: allwinner: a64: Increase the MMC max frequency Maxime Ripard
2017-01-16 16:57 ` [PATCH v3 11/13] arm64: allwinner: pine64: add MMC support Maxime Ripard
2017-01-16 16:57 ` [PATCH v3 12/13] arm64: allwinner: a64: add UART1 pin nodes Maxime Ripard
2017-01-16 16:57 ` [PATCH v3 13/13] arm64: allwinner: add BananaPi-M64 support Maxime Ripard
2017-01-23 10:58 ` [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).