* [PATCH v3 0/13] arm64: allwinner: a64: Enable MMC support
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
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
* [PATCH v3 1/13] mmc: sunxi: Fix clock frequency change sequence
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 2/13] mmc: sunxi: Gate the clock when rate is 0
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH] ARM: shmobile: r8a7779: marzen: Fix sata device status
From: Geert Uytterhoeven @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
Device nodes representing I/O devices should be marked disabled in the
SoC-specific DTS, and overridden by board-specific DTSes where needed.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
arch/arm/boot/dts/r8a7779-marzen.dts | 4 ++++
arch/arm/boot/dts/r8a7779.dtsi | 1 +
2 files changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts
index 676151b70185d1a5..89c5b24a3d03f049 100644
--- a/arch/arm/boot/dts/r8a7779-marzen.dts
+++ b/arch/arm/boot/dts/r8a7779-marzen.dts
@@ -216,6 +216,10 @@
};
};
+&sata {
+ status = "okay";
+};
+
&scif2 {
pinctrl-0 = <&scif2_pins>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index f47a0edc26d4879c..ae2d9a9c65af43c0 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -347,6 +347,7 @@
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7779_CLK_SATA>;
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
+ status = "disabled";
};
sdhi0: sd at ffe4c000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v3 3/13] mmc: sunxi: Always set signal delay to 0 for A64
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 4/13] mmc: sunxi: Enable the new timings for the A64 MMC controllers
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 5/13] mmc: sunxi: Mask DATA0 when updating the clock
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 6/13] mmc: sunxi: Add EMMC (MMC2) controller compatible
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 7/13] mmc: sunxi: Add more debug messages
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 8/13] arm64: allwinner: a64: Add MMC nodes
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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 at 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 at 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 at 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 at 1c81000 {
compatible = "arm,gic-400";
reg = <0x01c81000 0x1000>,
--
git-series 0.8.11
^ permalink raw reply related
* [PATCH v3 9/13] arm64: allwinner: a64: Add MMC pinctrl nodes
From: Maxime Ripard @ 2017-01-16 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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 at 0 {
pins = "PB8", "PB9";
function = "uart0";
--
git-series 0.8.11
^ permalink raw reply related
* [PATCH v3 10/13] arm64: allwinner: a64: Increase the MMC max frequency
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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
* [PATCH v3 11/13] arm64: allwinner: pine64: add MMC support
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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 = <®_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
* [PATCH v3 12/13] arm64: allwinner: a64: add UART1 pin nodes
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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 at 1c28000 {
--
git-series 0.8.11
^ permalink raw reply related
* [PATCH v3 13/13] arm64: allwinner: add BananaPi-M64 support
From: Maxime Ripard @ 2017-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.a06ce1672d7a72ee7f9bbca46fdd223edd6b2313.1484585798.git-series.maxime.ripard@free-electrons.com>
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 = <®_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 = <®_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <®_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
* [PATCH] arm64: dts: r8a7795: Add missing power-domains property for sata
From: Geert Uytterhoeven @ 2017-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
This went unnoticed as the sata_rcar driver doesn't support Runtime PM
yet, but manages module clocks manually.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 972e379c05967c32..026a16ac41b422a1 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1148,6 +1148,7 @@
reg = <0 0xee300000 0 0x1fff>;
interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 815>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
status = "disabled";
};
--
1.9.1
^ permalink raw reply related
* [PATCH v19 00/15] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
From: Mark Rutland @ 2017-01-16 17:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161221064603.11830-1-fu.wei@linaro.org>
Hi,
On Wed, Dec 21, 2016 at 02:45:48PM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> This patchset:
> (1)Preparation for adding GTDT support in arm_arch_timer:
> 1. Move some enums and marcos to header file;
> 2. Add a new enum for spi type;
> 3. Improve printk relevant code;
> 4. Rename some enums and defines;
Can we please rework these first few patches into a series:
1. Clean up printk() usage
2. Rename the type macros
3. Rename the PPI enum & enum values
4. Move the type macro and PPI enum into a header
5. Add new enum for SPIs
Please leave CNTHCL_* as they originally were. It's not part of the
interface of the driver, and leaving them as they are will save us an
interdependency with KVM.
I'm happy to queue that immediately, as it's purely structural and
shouldn't have a functional impact anywhere. That will also shrink the
series a bit, and we can rebase the following patches atop of that.
> 5. Rework PPI determination;
> 6. Rework counter frequency detection;
> 7. Refactor arch_timer_needs_probing, move it into DT init call
> 8. Introduce some new structs and refactor the MMIO timer init code
> for reusing some common code.
I'll review these in separate replies.
Thanks,
Mark.
^ permalink raw reply
* [PATCH] ARM: dts: da850-lcdk: enable pwm nodes
From: Frode Isaksen @ 2017-01-16 17:03 UTC (permalink / raw)
To: linux-arm-kernel
Enable the ecap1 and ecap2 pwm nodes for the
lcdk board.
Note that the other pwm nodes are not enabled,
since the pins are shared with ethernet and spi.
Signed-off-by: Frode Isaksen <fisaksen@baylibre.com>
---
arch/arm/boot/dts/da850-lcdk.dts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 60e027e..6f4c367 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -322,3 +322,15 @@
};
};
};
+
+&ecap1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap1_pins>;
+ status = "okay";
+};
+
+&ecap2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap2_pins>;
+ status = "okay";
+};
--
2.7.4
^ permalink raw reply related
* [PATCH v2 net-next 0/2] mvneta xmit_more and bql support
From: Marcin Wojtas @ 2017-01-16 17:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This is a delayed v2 of short patchset, which introduces xmit_more and BQL
to mvneta driver. The only one change was added in xmit_more support -
condition check preventing excessive descriptors concatenation before
flushing in HW.
Any comments or feedback would be welcome.
Best regards,
Marcin
Changelog:
v1 -> v2:
* Add checking condition that ensures too much descriptors are not
concatenated before flushing in HW.
Marcin Wojtas (1):
net: mvneta: add BQL support
Simon Guinot (1):
net: mvneta: add xmit_more support
drivers/net/ethernet/marvell/mvneta.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH v2 net-next 1/2] net: mvneta: add xmit_more support
From: Marcin Wojtas @ 2017-01-16 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484586512-16412-1-git-send-email-mw@semihalf.com>
From: Simon Guinot <simon.guinot@sequanux.org>
Basing on xmit_more flag of the skb, TX descriptors can be concatenated
before flushing. This commit delay Tx descriptor flush if the queue is
running and if there is more skb's to send.
A maximum allowed number of descriptors for flushing at once due to
MVNETA_TXQ_UPDATE_REG(q) reqisters limitation, is 255. Because of that
a new macro was added (MVNETA_TXQ_DEC_SENT_MASK) in order to ensure that
concatenated amount of descriptor does not exceed that value.
Signed-off-by: Simon Guinot <simon.guinot@sequanux.org>
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
drivers/net/ethernet/marvell/mvneta.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 3607d8f..9624537 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -224,6 +224,7 @@
#define MVNETA_TXQ_SENT_THRESH_MASK(coal) ((coal) << 16)
#define MVNETA_TXQ_UPDATE_REG(q) (0x3c60 + ((q) << 2))
#define MVNETA_TXQ_DEC_SENT_SHIFT 16
+#define MVNETA_TXQ_DEC_SENT_MASK 0xff
#define MVNETA_TXQ_STATUS_REG(q) (0x3c40 + ((q) << 2))
#define MVNETA_TXQ_SENT_DESC_SHIFT 16
#define MVNETA_TXQ_SENT_DESC_MASK 0x3fff0000
@@ -525,6 +526,7 @@ struct mvneta_tx_queue {
* descriptor ring
*/
int count;
+ int pending;
int tx_stop_threshold;
int tx_wake_threshold;
@@ -818,8 +820,9 @@ static void mvneta_txq_pend_desc_add(struct mvneta_port *pp,
/* Only 255 descriptors can be added@once ; Assume caller
* process TX desriptors in quanta less than 256
*/
- val = pend_desc;
+ val = pend_desc + txq->pending;
mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
+ txq->pending = 0;
}
/* Get pointer to next TX descriptor to be processed (send) by HW */
@@ -2399,11 +2402,15 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id);
txq->count += frags;
- mvneta_txq_pend_desc_add(pp, txq, frags);
-
if (txq->count >= txq->tx_stop_threshold)
netif_tx_stop_queue(nq);
+ if (!skb->xmit_more || netif_xmit_stopped(nq) ||
+ txq->pending + frags > MVNETA_TXQ_DEC_SENT_MASK)
+ mvneta_txq_pend_desc_add(pp, txq, frags);
+ else
+ txq->pending += frags;
+
u64_stats_update_begin(&stats->syncp);
stats->tx_packets++;
stats->tx_bytes += len;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 net-next 2/2] net: mvneta: add BQL support
From: Marcin Wojtas @ 2017-01-16 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484586512-16412-1-git-send-email-mw@semihalf.com>
Tests showed that when whole bandwidth is consumed, the latency for
various kind of traffic can reach high values. With saturated
link (e.g. with iperf from target to host) simple ping could take
significant amount of time. BQL proved to improve this situation
when implemented in mvneta driver. Measurements of ping latency
for 3 link speeds:
Speed | Latency w/o BQL | Latency with BQL
10 | 7-14 ms | 3.5 ms
100 | 2-12 ms | 0.6 ms
1000 | often timeout | up to 2ms
Decreasing latency as above result in sligt performance cost - 4kpps
(-1.4%) when pushing 64B packets via two bridged interfaces of Armada 38x.
For 1500B packets in the same setup, the mpstat tool showed +8% of
CPU occupation (default affinity, second CPU idle). Even though this
cost seems reasonable to take, considering other improvements.
This commit adds byte queue limit mechanism for the mvneta driver.
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
drivers/net/ethernet/marvell/mvneta.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 9624537..6dcc951 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1759,8 +1759,10 @@ static struct mvneta_tx_queue *mvneta_tx_done_policy(struct mvneta_port *pp,
/* Free tx queue skbuffs */
static void mvneta_txq_bufs_free(struct mvneta_port *pp,
- struct mvneta_tx_queue *txq, int num)
+ struct mvneta_tx_queue *txq, int num,
+ struct netdev_queue *nq)
{
+ unsigned int bytes_compl = 0, pkts_compl = 0;
int i;
for (i = 0; i < num; i++) {
@@ -1768,6 +1770,11 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,
txq->txq_get_index;
struct sk_buff *skb = txq->tx_skb[txq->txq_get_index];
+ if (skb) {
+ bytes_compl += skb->len;
+ pkts_compl++;
+ }
+
mvneta_txq_inc_get(txq);
if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
@@ -1778,6 +1785,8 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,
continue;
dev_kfree_skb_any(skb);
}
+
+ netdev_tx_completed_queue(nq, pkts_compl, bytes_compl);
}
/* Handle end of transmission */
@@ -1791,7 +1800,7 @@ static void mvneta_txq_done(struct mvneta_port *pp,
if (!tx_done)
return;
- mvneta_txq_bufs_free(pp, txq, tx_done);
+ mvneta_txq_bufs_free(pp, txq, tx_done, nq);
txq->count -= tx_done;
@@ -2401,6 +2410,8 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id);
+ netdev_tx_sent_queue(nq, len);
+
txq->count += frags;
if (txq->count >= txq->tx_stop_threshold)
netif_tx_stop_queue(nq);
@@ -2429,9 +2440,10 @@ static void mvneta_txq_done_force(struct mvneta_port *pp,
struct mvneta_tx_queue *txq)
{
+ struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
int tx_done = txq->count;
- mvneta_txq_bufs_free(pp, txq, tx_done);
+ mvneta_txq_bufs_free(pp, txq, tx_done, nq);
/* reset txq */
txq->count = 0;
@@ -2957,6 +2969,8 @@ static int mvneta_txq_init(struct mvneta_port *pp,
static void mvneta_txq_deinit(struct mvneta_port *pp,
struct mvneta_tx_queue *txq)
{
+ struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
+
kfree(txq->tx_skb);
if (txq->tso_hdrs)
@@ -2968,6 +2982,8 @@ static void mvneta_txq_deinit(struct mvneta_port *pp,
txq->size * MVNETA_DESC_ALIGNED_SIZE,
txq->descs, txq->descs_phys);
+ netdev_tx_reset_queue(nq);
+
txq->descs = NULL;
txq->last_desc = 0;
txq->next_desc_to_proc = 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v3 01/24] [media] dt-bindings: Add bindings for i.MX media driver
From: Steve Longerbeam @ 2017-01-16 17:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484568579.8415.91.camel@pengutronix.de>
On 01/16/2017 04:09 AM, Philipp Zabel wrote:
> On Fri, 2017-01-13 at 11:03 -0800, Steve Longerbeam wrote:
>> On 01/13/2017 03:55 AM, Philipp Zabel wrote:
>>> Am Freitag, den 06.01.2017, 18:11 -0800 schrieb Steve Longerbeam:
>>>> Add bindings documentation for the i.MX media driver.
>>>>
>>>> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
>>>> ---
>>>> Documentation/devicetree/bindings/media/imx.txt | 57 +++++++++++++++++++++++++
>>>> 1 file changed, 57 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/media/imx.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/media/imx.txt b/Documentation/devicetree/bindings/media/imx.txt
>>>> new file mode 100644
>>>> index 0000000..254b64a
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/media/imx.txt
>>>> @@ -0,0 +1,57 @@
>>>> +Freescale i.MX Media Video Devices
>>>> +
>>>> +Video Media Controller node
>>>> +---------------------------
>>>> +
>>>> +This is the parent media controller node for video capture support.
>>>> +
>>>> +Required properties:
>>>> +- compatible : "fsl,imx-media";
>>> Would you be opposed to calling this "capture-subsystem" instead of
>>> "imx-media"? We already use "fsl,imx-display-subsystem" and
>>> "fsl,imx-gpu-subsystem" for the display and GPU compound devices.
>> sure. Some pie-in-the-sky day when DRM and media are unified,
>> there could be a single device that handles them all,
> Indeed :)
>
>> but for now
>> I'm fine with "fsl,capture-subsystem".
> Actually, I meant fsl,imx-capture-subsystem.
right, I caught my error and that is the name chosen.
> fsl,imx-media-subsystem
> would be fine, too. Either way, I'll be happy if it looks similar to the
> other two.
>
> [...]
>>> This is a clever method to get better frame timestamps. Too bad about
>>> the routing requirements. Can this be used on Nitrogen6X?
>> Absolutely, this support just needs use of the input-capture channels in the
>> imx GPT. I still need to submit the patch to the imx-gpt driver that adds an
>> input capture API, so at this point fsl,input-capture-channel has no effect,
>> but it does work (tested on SabreAuto).
> Nice.
>
> [...]
>>>> +Required properties:
>>>> +- compatible : "fsl,imx6-mipi-csi2";
>>> I think this should get an additional "snps,dw-mipi-csi2" compatible,
>>> since the only i.MX6 specific part is the bolted-on IPU2CSI gasket.
>> right, minus the gasket it's a Synopsys core. I'll add that compatible flag.
>> Or should wait until the day this subdev is exported for general use, after
>> pulling out the gasket specifics?
> It can be added right away.
ok, I will add.
Steve
>
>>>> +- reg : physical base address and length of the register set;
>>>> +- clocks : the MIPI CSI-2 receiver requires three clocks: hsi_tx
>>>> + (the DPHY clock), video_27m, and eim_sel;
>>> Note that hsi_tx is incorrectly named. CCGR3[CG8] just happens to be the
>>> shared gate bit that gates the HSI clocks as well as the MIPI
>>> "ac_clk_125m", "cfg_clk", "ips_clk", and "pll_refclk" inputs to the mipi
>>> csi-2 core, but we are missing shared gate clocks in the clock tree for
>>> these.
>> Yes, so many clocks for the MIPI core. Why so many? I would think
>> there would need to be at most three: a clock for the MIPI CSI-2 core
>> and HSI core, and a clock for the D-PHY (oh and maybe a clock for an
>> M-PHY if there is one). I have no clue what all these other clocks are.
>> But anyway, a single gating bit, CCGR3[CG8], seems to enable them all.
> I would imagine the CSI-2 core has a high-speed clock input from the
> D-PHY for serial input, an APB clock for register access (ips_clk), and
> a pixel clock input for the parallel output (pixel_clk), at least.
> The D-PHY will have a PLL reference input (pll_refclk?) and probably its
> own register clock (cfg_clk?).
>
> I've looked at the MIPI DSI chapter, and it looks like ac_clk_125m is
> used for DSI only.
>
>>> Both cfg_clk and pll_refclk are sourced from video_27m, so "cfg" ->
>>> video_27m seems fine.
>>> But I don't get "dphy".
>> I presume it's the clock for the D-PHY.
>>
>>> Which input clock would that correspond to?
>>> "pll_refclk?"
>> the mux at CDCDR says it comes from PLL3_120M, or PLL2_PFD2.
> I think that makes sense.
>
> regards
> Philipp
>
^ permalink raw reply
* [PATCH v3 06/24] ARM: dts: imx6-sabrelite: add OV5642 and OV5640 camera sensors
From: Steve Longerbeam @ 2017-01-16 17:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484571323.8415.98.camel@pengutronix.de>
On 01/16/2017 04:55 AM, Philipp Zabel wrote:
> On Fri, 2017-01-13 at 15:04 -0800, Steve Longerbeam wrote:
>
>>>> @@ -299,6 +326,52 @@
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&pinctrl_i2c2>;
>>>> status = "okay";
>>>> +
>>>> + ov5640: camera at 40 {
>>>> + compatible = "ovti,ov5640";
>>>> + pinctrl-names = "default";
>>>> + pinctrl-0 = <&pinctrl_ov5640>;
>>>> + clocks = <&mipi_xclk>;
>>>> + clock-names = "xclk";
>>>> + reg = <0x40>;
>>>> + xclk = <22000000>;
>>> This is superfluous, you can use clk_get_rate on mipi_xclk.
>> This property is actually there to tell the driver what to set the
>> rate to, with clk_set_rate(). So you are saying it would be better
>> to set the rate in the device tree and the driver should only
>> retrieve the rate?
> Yes. Given that this is a reference clock input that is constant on a
> given board and never changes during runtime, I think this is the
> correct way. The clock will be fixed rate on most boards, I assume.
Ok, that makes sense, I'll make that change.
Steve
^ permalink raw reply
* [PATCH 0/3] watchdog: imx2: handle WMCR only being available on i.MX35 and later
From: Magnus Lilja @ 2017-01-16 17:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170109095039.11979-1-u.kleine-koenig@pengutronix.de>
Hi,
On 9 January 2017 at 10:50, Uwe Kleine-K?nig
<u.kleine-koenig@pengutronix.de> wrote:
> Hello,
>
> this is my approach to fix the issue reported by Vladimir Zapolskiy.
>
...
> Best regards
> Uwe
>
> Uwe Kleine-K?nig (3):
> watchdog: imx2: Only i.MX35 and later have a WMCR register
> dts: teach newer i.MX machines to have the i.MX35 type watchdog
> watchdog: imx2: add compatibility for new i.MX35 type watchdog
>
> .../devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 +-
> arch/arm/boot/dts/imx25.dtsi | 2 +-
> arch/arm/boot/dts/imx35.dtsi | 2 +-
> arch/arm/boot/dts/imx50.dtsi | 2 +-
> arch/arm/boot/dts/imx51.dtsi | 2 +-
> arch/arm/boot/dts/imx53.dtsi | 2 +-
> arch/arm/boot/dts/imx6qdl.dtsi | 2 +-
> arch/arm/boot/dts/imx6sl.dtsi | 4 +-
> arch/arm/boot/dts/imx6sx.dtsi | 6 +-
> arch/arm/boot/dts/imx6ul.dtsi | 4 +-
> arch/arm/boot/dts/imx7s.dtsi | 8 +-
> arch/arm/boot/dts/vfxxx.dtsi | 2 +-
> arch/arm/mach-imx/devices/devices-common.h | 1 +
> arch/arm/mach-imx/devices/platform-imx2-wdt.c | 13 +--
> drivers/watchdog/imx2_wdt.c | 97 ++++++++++++++++++++--
> 15 files changed, 116 insertions(+), 33 deletions(-)
Tested on i.MX31 PDK board.
Tested-by: Magnus Lilja <lilja.magnus@gmail.com>
^ permalink raw reply
* [PATCH v19 05/15] clocksource/drivers/arm_arch_timer: rework PPI determination
From: Mark Rutland @ 2017-01-16 17:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161221064603.11830-6-fu.wei@linaro.org>
On Wed, Dec 21, 2016 at 02:45:53PM +0800, fu.wei at linaro.org wrote:
[...]
> - if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
> - bool has_ppi;
> + if (is_hyp_mode_available() && is_kernel_in_hyp_mode())
> + return ARCH_TIMER_HYP_PPI;
>
> - if (is_kernel_in_hyp_mode()) {
> - arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
> - has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI];
> - } else {
> - arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
> - has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] ||
> - !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
> - }
> + if (arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
> + return ARCH_TIMER_VIRT_PPI;
>
> - if (!has_ppi) {
> - pr_warn("No interrupt available, giving up\n");
> - return -EINVAL;
> - }
> - }
> + if (IS_ENABLED(CONFIG_ARM64))
> + return ARCH_TIMER_PHYS_NONSECURE_PPI;
> +
> + return ARCH_TIMER_PHYS_SECURE_PPI;
For a 32-bit platform booted at hyp (with a virt PPI available), the new
logic will select ARCH_TIMER_VIRT_PPI. I beleive that will break KVM.
I think the logic should be:
if (is_kernel_in_hyp_mode())
return ARCH_TIMER_HYP_PPI;
if (!is_hyp_mode_available() &&
arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
return ARCH_TIMER_VIRT_PPI;
if (IS_ENABLED(CONFIG_ARM64))
return ARCH_TIMER_PHYS_NONSECURE_PPI;
return ARCH_TIMER_PHYS_SECURE_PPI;
Please use that instead (keeping the comment you retained).
> +static int __init arch_timer_init(void)
> +{
> + int ret;
>
> ret = arch_timer_register();
> if (ret)
> @@ -904,6 +906,13 @@ static int __init arch_timer_of_init(struct device_node *np)
> if (IS_ENABLED(CONFIG_ARM) &&
> of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
> arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
> + else
> + arch_timer_uses_ppi = arch_timer_select_ppi();
> +
> + if (!arch_timer_ppi[arch_timer_uses_ppi]) {
> + pr_err("No interrupt available, giving up\n");
> + return -EINVAL;
> + }
>
> /* On some systems, the counter stops ticking when in suspend. */
> arch_counter_suspend_stop = of_property_read_bool(np,
> @@ -1049,6 +1058,12 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
> /* Get the frequency from CNTFRQ */
> arch_timer_detect_rate(NULL, NULL);
>
> + arch_timer_uses_ppi = arch_timer_select_ppi();
> + if (!arch_timer_ppi[arch_timer_uses_ppi]) {
> + pr_err("No interrupt available, giving up\n");
> + return -EINVAL;
> + }
I see that we have to duplicate this so we can special-case the
DT-specific behaviour, so that's fine by me.
If you can fix the arch_timer_select_ppi() logic as above, this should
be fine.
Thanks,
Mark.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox