All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80
@ 2014-12-03  6:35 Chen-Yu Tsai
  2014-12-03  6:35 ` [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80 Chen-Yu Tsai
                   ` (9 more replies)
  0 siblings, 10 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Maxime,

This series enables MMC support on the A80 using existing drivers
we have. The A80 has 4 MMC controllers. These controllers share
a common clock gate and reset control, which are then sub-divided
to each controller.

The phase clocks are the same as the older SoCs, so it should be
straight forward to add them with the rest of the sunxi family.
I did find that Allwinner's kernel uses different delay values
for the A80, but so far I've not run into any issues using the
mainline kernel.

Patch 1 adds module 0 type clock support for the A80. These are
essentially the same as mod0 clocks on other Allwinner SoCs, except
for the wider mux bits.

Patch 2 adds mmc mod clocks to the DTSI.

Patch 3 adds support for the mmc config (term from user manual) clocks.
This is the part that breaks out the clock gates and reset controls
for each controller. This is implemented as a platform driver, as
the shared reset control must be de-asserted for any of either this
or the mmc blocks to work.

Patch 4 adds clock-indices properties to the AHB/APB gate clocks.
This is needed for of_clk_get_parent_name to work properly, as we
use bit indices instead of counting the entries.

Patch 5 adds the mmc config clock nodes to the DTSI.

Patch 6 adds the mmc controller nodes to the DTSI.

Patch 7 and 9 add the pinmux settings for mmc0 and mmc2.

Patch 8 and 10 enable mmc0 and mmc2 on the A80 Optimus Board.

Kudos to Andreas for figuring out all the DT bits. His SoB
is on the relevant patches.


Cheers
ChenYu Tsai


Chen-Yu Tsai (10):
  clk: sunxi: Add module 0 (storage) style clock support for A80
  ARM: dts: sun9i: Add mmc module clock nodes for A80
  clk: sunxi: Add driver for A80 MMC config clocks/resets
  ARM: dts: sun9i: Add clock-indices property for bus gate clocks
  ARM: dts: sun9i: Add mmc config clock nodes
  ARM: dts: sun9i: Add mmc controller nodes to the A80 dtsi
  ARM: dts: sun9i: Add pinmux setting for mmc0
  ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board
  ARM: dts: sun9i: Add pinmux settings for mmc2
  ARM: dts: sun9i: Enable mmc2 on A80 Optimus Board

 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
 arch/arm/boot/dts/sun9i-a80-optimus.dts           |  33 ++++
 arch/arm/boot/dts/sun9i-a80.dtsi                  | 122 ++++++++++++
 drivers/clk/sunxi/Makefile                        |   1 +
 drivers/clk/sunxi/clk-mod0.c                      |  24 +++
 drivers/clk/sunxi/clk-sun9i-mmc.c                 | 228 ++++++++++++++++++++++
 6 files changed, 410 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk-sun9i-mmc.c

-- 
2.1.3

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

* [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
@ 2014-12-03  6:35 ` Chen-Yu Tsai
  2014-12-06 17:13   ` Maxime Ripard
  2014-12-03  6:35 ` [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes " Chen-Yu Tsai
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

The module 0 style clocks, or storage module clocks as named in the
official SDK, are almost the same as the module 0 clocks on earlier
Allwinner SoCs. The only difference is wider mux register bits.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
 drivers/clk/sunxi/clk-mod0.c                      | 24 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 9dc4f55..d0fb9c5 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -58,6 +58,7 @@ Required properties:
 	"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
 	"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
 	"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
+	"allwinner,sun9i-a80-mod0-clk" - for module 0 (storage) clocks on A80
 	"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
 	"allwinner,sun7i-a20-out-clk" - for the external output clocks
 	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
index 658d74f..d72063f 100644
--- a/drivers/clk/sunxi/clk-mod0.c
+++ b/drivers/clk/sunxi/clk-mod0.c
@@ -93,6 +93,30 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node)
 }
 CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);
 
+static const struct factors_data sun9i_a80_mod0_data __initconst = {
+	.enable = 31,
+	.mux = 24,
+	.muxmask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
+	.table = &sun4i_a10_mod0_config,
+	.getter = sun4i_a10_get_mod0_factors,
+};
+
+static void __init sun9i_a80_mod0_setup(struct device_node *node)
+{
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for mod0-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_mod0_data,
+			       &sun4i_a10_mod0_lock, reg);
+}
+CLK_OF_DECLARE(sun9i_a80_mod0, "allwinner,sun9i-a80-mod0-clk", sun9i_a80_mod0_setup);
+
 static DEFINE_SPINLOCK(sun5i_a13_mbus_lock);
 
 static void __init sun5i_a13_mbus_setup(struct device_node *node)
-- 
2.1.3

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

* [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes for A80
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
  2014-12-03  6:35 ` [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80 Chen-Yu Tsai
@ 2014-12-03  6:35 ` Chen-Yu Tsai
  2014-12-06 17:24   ` Maxime Ripard
  2014-12-03  6:35 ` [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets Chen-Yu Tsai
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

The mmc module clocks are A80 specific module 0 (storage) type clocks.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 494714f..33d18dc 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -215,6 +215,38 @@
 			clock-output-names = "cci400";
 		};
 
+		mmc0_clk: clk at 06000410 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun9i-a80-mod0-clk";
+			reg = <0x06000410 0x4>;
+			clocks = <&osc24M>, <&pll4>;
+			clock-output-names = "mmc0";
+		};
+
+		mmc1_clk: clk at 06000414 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun9i-a80-mod0-clk";
+			reg = <0x06000414 0x4>;
+			clocks = <&osc24M>, <&pll4>;
+			clock-output-names = "mmc1";
+		};
+
+		mmc2_clk: clk at 06000418 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun9i-a80-mod0-clk";
+			reg = <0x06000418 0x4>;
+			clocks = <&osc24M>, <&pll4>;
+			clock-output-names = "mmc2";
+		};
+
+		mmc3_clk: clk at 0600041c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun9i-a80-mod0-clk";
+			reg = <0x0600041c 0x4>;
+			clocks = <&osc24M>, <&pll4>;
+			clock-output-names = "mmc3";
+		};
+
 		ahb0_gates: clk at 06000580 {
 			#clock-cells = <1>;
 			compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
-- 
2.1.3

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

* [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
  2014-12-03  6:35 ` [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80 Chen-Yu Tsai
  2014-12-03  6:35 ` [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes " Chen-Yu Tsai
@ 2014-12-03  6:35 ` Chen-Yu Tsai
  2014-12-06 18:01   ` Maxime Ripard
  2014-12-03  6:35 ` [PATCH 04/10] ARM: dts: sun9i: Add clock-indices property for bus gate clocks Chen-Yu Tsai
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

On the A80 SoC, the 4 mmc controllers each have a separate register
controlling their register access clocks and reset controls. These
registers in turn share a ahb clock gate and reset control.

This patch adds a platform device driver for these controls. It
requires both clocks and reset controls to be available, so using
CLK_OF_DECLARE might not be the best way.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 Documentation/devicetree/bindings/clock/sunxi.txt |   1 +
 drivers/clk/sunxi/Makefile                        |   1 +
 drivers/clk/sunxi/clk-sun9i-mmc.c                 | 228 ++++++++++++++++++++++
 3 files changed, 230 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk-sun9i-mmc.c

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index d0fb9c5..2de90ea 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -65,6 +65,7 @@ Required properties:
 	"allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
 	"allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
 	"allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
+	"allwinner,sun9i-a80-mmc-clk" - for mmc gates + resets on A80
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index a66953c..3a5292e 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun9i-core.o
+obj-y += clk-sun9i-mmc.o
 
 obj-$(CONFIG_MFD_SUN6I_PRCM) += \
 	clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
new file mode 100644
index 0000000..7569625
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2013 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai	<wens@csie.org>
+ *
+ * This program 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 program 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+#define SUN9I_MMC_WIDTH		4
+
+#define SUN9I_MMC_GATE_BIT	16
+#define SUN9I_MMC_RESET_BIT	18
+
+struct sun9i_mmc_clk_data {
+	spinlock_t			lock;
+	void __iomem			*membase;
+	struct clk			*clk;
+	struct reset_control		*reset;
+	struct clk_onecell_data		clk_data;
+	struct reset_controller_dev	rcdev;
+};
+
+static int sun9i_mmc_reset_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct sun9i_mmc_clk_data *data = container_of(rcdev,
+						       struct sun9i_mmc_clk_data,
+						       rcdev);
+	unsigned long flags;
+	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
+	u32 val;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	val = readl(reg);
+	writel(val & ~BIT(SUN9I_MMC_RESET_BIT), reg);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct sun9i_mmc_clk_data *data = container_of(rcdev,
+						       struct sun9i_mmc_clk_data,
+						       rcdev);
+	unsigned long flags;
+	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
+	u32 val;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	val = readl(reg);
+	writel(val | BIT(SUN9I_MMC_RESET_BIT), reg);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static struct reset_control_ops sun9i_mmc_reset_ops = {
+	.assert		= sun9i_mmc_reset_assert,
+	.deassert	= sun9i_mmc_reset_deassert,
+};
+
+static int sun9i_a80_mmc_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sun9i_mmc_clk_data *data;
+	struct clk_onecell_data *clk_data;
+	const char *clk_name = np->name;
+	const char *clk_parent;
+	struct resource *r;
+	int count, i, ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&data->lock);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* one clock/reset pair per word */
+	count = (r->end - r->start + 1) / SUN9I_MMC_WIDTH;
+	data->membase = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(data->membase))
+		return PTR_ERR(data->membase);
+
+	clk_data = &data->clk_data;
+	clk_data->clk_num = count;
+	clk_data->clks = devm_kcalloc(&pdev->dev, count, sizeof(struct clk *),
+				      GFP_KERNEL);
+	if (!clk_data->clks)
+		return -ENOMEM;
+
+	clk_parent = of_clk_get_parent_name(np, 0);
+	if (!clk_parent)
+		return -EINVAL;
+
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		dev_err(&pdev->dev, "Could not get clock\n");
+		return PTR_ERR(data->clk);
+	}
+
+	data->reset = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(data->reset)) {
+		dev_err(&pdev->dev, "Could not get reset control\n");
+		return PTR_ERR(data->reset);
+	}
+
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Clock enable err %d\n", ret);
+		return ret;
+	}
+
+	ret = reset_control_deassert(data->reset);
+	if (ret) {
+		dev_err(&pdev->dev, "Reset deassert err %d\n", ret);
+		goto err_reset;
+	}
+
+	for (i = 0; i < count; i++) {
+		of_property_read_string_index(np, "clock-output-names",
+					      i, &clk_name);
+
+		clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
+						      clk_parent, 0,
+						      data->membase + SUN9I_MMC_WIDTH * i,
+						      SUN9I_MMC_GATE_BIT, 0,
+						      &data->lock);
+
+		if (IS_ERR(clk_data->clks[i])) {
+			ret = PTR_ERR(clk_data->clks[i]);
+			goto err_clk_register;
+		}
+	}
+
+	ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+	if (ret)
+		goto err_clk_provider;
+
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = count;
+	data->rcdev.ops = &sun9i_mmc_reset_ops;
+	data->rcdev.of_node = pdev->dev.of_node;
+
+	ret = reset_controller_register(&data->rcdev);
+	if (ret)
+		goto err_rc_reg;
+
+	platform_set_drvdata(pdev, data);
+
+	return 0;
+
+err_rc_reg:
+	of_clk_del_provider(np);
+
+err_clk_provider:
+	for (i = 0; i < count; i++)
+		clk_unregister(clk_data->clks[i]);
+
+err_clk_register:
+	reset_control_assert(data->reset);
+
+err_reset:
+	clk_disable_unprepare(data->clk);
+
+	return ret;
+}
+
+static int sun9i_a80_mmc_clk_remove(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sun9i_mmc_clk_data *data = platform_get_drvdata(pdev);
+	struct clk_onecell_data *clk_data = &data->clk_data;
+	int i;
+
+	reset_controller_unregister(&data->rcdev);
+	of_clk_del_provider(np);
+	for (i = 0; i < clk_data->clk_num; i++)
+		clk_unregister(clk_data->clks[i]);
+
+	reset_control_assert(data->reset);
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+static const struct of_device_id sun9i_a80_mmc_clk_dt_ids[] = {
+	{ .compatible = "allwinner,sun9i-a80-mmc-clk" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver sun9i_a80_mmc_clk_driver = {
+	.driver = {
+		.name = "sun9i-a80-mmc-clk",
+		.of_match_table = sun9i_a80_mmc_clk_dt_ids,
+	},
+	.probe = sun9i_a80_mmc_clk_probe,
+	.remove = sun9i_a80_mmc_clk_remove,
+};
+module_platform_driver(sun9i_a80_mmc_clk_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_DESCRIPTION("Allwinner A80 MMC clock/reset Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.3

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

* [PATCH 04/10] ARM: dts: sun9i: Add clock-indices property for bus gate clocks
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (2 preceding siblings ...)
  2014-12-03  6:35 ` [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets Chen-Yu Tsai
@ 2014-12-03  6:35 ` Chen-Yu Tsai
  2014-12-03  6:36 ` [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes Chen-Yu Tsai
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

of_clk_get_parent_name() uses the clock-indices property to resolve
clock phandle arguments in case that the argument index does not
match the clock-output-names sequence.

This is the case on sunxi, where we use the actual bit index as the
argument to the phandle. Add the clock-indices property so that
of_clk_get_parent_name() resolves the names correctly.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 33d18dc..f3cac3a 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -252,6 +252,9 @@
 			compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
 			reg = <0x06000580 0x4>;
 			clocks = <&ahb0>;
+			clock-indices = <0>, <1>, <3>, <5>, <8>, <12>, <13>,
+					<14>, <15>, <16>, <18>, <20>, <21>,
+					<22>, <23>;
 			clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
 					"ahb0_ss", "ahb0_sd", "ahb0_nand1",
 					"ahb0_nand0", "ahb0_sdram",
@@ -265,6 +268,7 @@
 			compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
 			reg = <0x06000584 0x4>;
 			clocks = <&ahb1>;
+			clock-indices = <0>, <1>, <17>, <21>, <22>, <23>, <24>;
 			clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
 					"ahb1_gmac", "ahb1_msgbox",
 					"ahb1_spinlock", "ahb1_hstimer",
@@ -276,6 +280,8 @@
 			compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
 			reg = <0x06000588 0x4>;
 			clocks = <&ahb2>;
+			clock-indices = <0>, <1>, <2>, <4>, <5>, <7>, <8>,
+					<11>;
 			clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
 					"ahb2_edp", "ahb2_csi", "ahb2_hdmi",
 					"ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
@@ -286,6 +292,8 @@
 			compatible = "allwinner,sun9i-a80-apb0-gates-clk";
 			reg = <0x06000590 0x4>;
 			clocks = <&apb0>;
+			clock-indices = <1>, <5>, <11>, <12>, <13>, <15>,
+					<17>, <18>, <19>;
 			clock-output-names = "apb0_spdif", "apb0_pio",
 					"apb0_ac97", "apb0_i2s0", "apb0_i2s1",
 					"apb0_lradc", "apb0_gpadc", "apb0_twd",
@@ -297,6 +305,8 @@
 			compatible = "allwinner,sun9i-a80-apb1-gates-clk";
 			reg = <0x06000594 0x4>;
 			clocks = <&apb1>;
+			clock-indices = <0>, <1>, <2>, <3>, <4>,
+					<16>, <17>, <18>, <19>, <20>, <21>;
 			clock-output-names = "apb1_i2c0", "apb1_i2c1",
 					"apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
 					"apb1_uart0", "apb1_uart1",
-- 
2.1.3

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

* [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (3 preceding siblings ...)
  2014-12-03  6:35 ` [PATCH 04/10] ARM: dts: sun9i: Add clock-indices property for bus gate clocks Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  2014-12-07 15:00   ` Maxime Ripard
  2014-12-03  6:36 ` [PATCH 06/10] ARM: dts: sun9i: Add mmc controller nodes to the A80 dtsi Chen-Yu Tsai
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

Add the device tree nodes for the mmc config clock nodes.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index f3cac3a..f425d9d 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -325,6 +325,19 @@
 		 */
 		ranges = <0 0 0 0x20000000>;
 
+		mmc_config_clk: clk at 01c23000 {
+			compatible = "allwinner,sun9i-a80-mmc-clk";
+			reg = <0x01c13000 0x10>;
+			clocks = <&ahb0_gates 8>;
+			clock-names = "ahb";
+			resets = <&ahb0_resets 8>;
+			reset-names = "ahb";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			clock-output-names = "mmc0_config", "mmc1_config",
+					     "mmc2_config", "mmc3_config";
+		};
+
 		gic: interrupt-controller at 01c41000 {
 			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
 			reg = <0x01c41000 0x1000>,
-- 
2.1.3

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

* [PATCH 06/10] ARM: dts: sun9i: Add mmc controller nodes to the A80 dtsi
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (4 preceding siblings ...)
  2014-12-03  6:36 ` [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  2014-12-03  6:36 ` [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0 Chen-Yu Tsai
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

The A80 has 4 mmc controllers.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index f425d9d..c766698 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -325,6 +325,50 @@
 		 */
 		ranges = <0 0 0 0x20000000>;
 
+		mmc0: mmc at 01c0f000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&mmc_config_clk 0>, <&mmc0_clk>;
+			clock-names = "ahb", "mmc";
+			resets = <&mmc_config_clk 0>;
+			reset-names = "ahb";
+			interrupts = <0 60 4>;
+			status = "disabled";
+		};
+
+		mmc1: mmc at 01c10000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&mmc_config_clk 1>, <&mmc1_clk>;
+			clock-names = "ahb", "mmc";
+			resets = <&mmc_config_clk 1>;
+			reset-names = "ahb";
+			interrupts = <0 61 4>;
+			status = "disabled";
+		};
+
+		mmc2: mmc at 01c11000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c11000 0x1000>;
+			clocks = <&mmc_config_clk 2>, <&mmc2_clk>;
+			clock-names = "ahb", "mmc";
+			resets = <&mmc_config_clk 2>;
+			reset-names = "ahb";
+			interrupts = <0 62 4>;
+			status = "disabled";
+		};
+
+		mmc3: mmc at 01c12000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c12000 0x1000>;
+			clocks = <&mmc_config_clk 3>, <&mmc3_clk>;
+			clock-names = "ahb", "mmc";
+			resets = <&mmc_config_clk 3>;
+			reset-names = "ahb";
+			interrupts = <0 63 4>;
+			status = "disabled";
+		};
+
 		mmc_config_clk: clk at 01c23000 {
 			compatible = "allwinner,sun9i-a80-mmc-clk";
 			reg = <0x01c13000 0x10>;
-- 
2.1.3

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

* [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (5 preceding siblings ...)
  2014-12-03  6:36 ` [PATCH 06/10] ARM: dts: sun9i: Add mmc controller nodes to the A80 dtsi Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  2014-12-07 15:01   ` Maxime Ripard
  2014-12-03  6:36 ` [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board Chen-Yu Tsai
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

mmc0 is only available on port F, and is always used with a 4 bit wide
bus for the onboard micro-sd slot.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index c766698..f5b5645 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -458,6 +458,14 @@
 				allwinner,pull = <0>;
 			};
 
+			mmc0_pins: mmc0 {
+				allwinner,pins = "PF0","PF1","PF2","PF3",
+						 "PF4","PF5";
+				allwinner,function = "mmc0";
+				allwinner,drive = <2>;
+				allwinner,pull = <0>;
+			};
+
 			uart0_pins_a: uart0 at 0 {
 				allwinner,pins = "PH12", "PH13";
 				allwinner,function = "uart0";
-- 
2.1.3

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

* [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (6 preceding siblings ...)
  2014-12-03  6:36 ` [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0 Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  2014-12-07 15:02   ` Maxime Ripard
  2014-12-03  6:36 ` [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2 Chen-Yu Tsai
  2014-12-03  6:36 ` [PATCH 10/10] ARM: dts: sun9i: Enable mmc2 on A80 Optimus Board Chen-Yu Tsai
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the micro-sd slot on the A80 Optimus Board, which is connected to
mmc0. This adds the card-detect gpio and enables mmc0.

This patch also adds a 3V fixed regulator, which is the default I/O
voltage level.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80-optimus.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index 506948f..02a4aa7 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -59,6 +59,16 @@
 	};
 
 	soc {
+		mmc0: mmc at 01c0f000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
+			vmmc-supply = <&reg_vcc3v0>;
+			bus-width = <4>;
+			cd-gpios = <&pio 7 18 0>; /* PH8 */
+			cd-inverted;
+			status = "okay";
+		};
+
 		pio: pinctrl at 06000800 {
 			i2c3_pins_a: i2c3 at 0 {
 				/* Enable internal pull-up */
@@ -72,6 +82,13 @@
 				allwinner,pull = <0>;
 			};
 
+			mmc0_cd_pin_optimus: mmc0_cd_pin at 0 {
+				allwinner,pins = "PH18";
+				allwinner,function = "gpio_in";
+				allwinner,drive = <0>;
+				allwinner,pull = <1>;
+			};
+
 			uart4_pins_a: uart4 at 0 {
 				/* Enable internal pull-up */
 				allwinner,pull = <1>;
@@ -116,4 +133,11 @@
 			gpios = <&pio 7 0 0>;
 		};
 	};
+
+	reg_vcc3v0: vcc3v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v0";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+	};
 };
-- 
2.1.3

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

* [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (7 preceding siblings ...)
  2014-12-03  6:36 ` [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  2014-12-07 15:03   ` Maxime Ripard
  2014-12-03  6:36 ` [PATCH 10/10] ARM: dts: sun9i: Enable mmc2 on A80 Optimus Board Chen-Yu Tsai
  9 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

mmc2 is available on port C. Add a pinmux setting for usual 4 bit
wide bus, as well as one with the 4 extra pins for 8 bit wide bus.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index f5b5645..fc866d8 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -466,6 +466,21 @@
 				allwinner,pull = <0>;
 			};
 
+			mmc2_pins: mmc2 {
+				allwinner,pins = "PC6","PC7","PC8","PC9",
+						 "PC10","PC11";
+				allwinner,function = "mmc2";
+				allwinner,drive = <2>;
+				allwinner,pull = <1>;
+			};
+
+			mmc2_8bit_pins: mmc2_8bit {
+				allwinner,pins = "PC12","PC13","PC14","PC15";
+				allwinner,function = "mmc2";
+				allwinner,drive = <2>;
+				allwinner,pull = <1>;
+			};
+
 			uart0_pins_a: uart0 at 0 {
 				allwinner,pins = "PH12", "PH13";
 				allwinner,function = "uart0";
-- 
2.1.3

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

* [PATCH 10/10] ARM: dts: sun9i: Enable mmc2 on A80 Optimus Board
  2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
                   ` (8 preceding siblings ...)
  2014-12-03  6:36 ` [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2 Chen-Yu Tsai
@ 2014-12-03  6:36 ` Chen-Yu Tsai
  9 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-03  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

The A80 Optimus Board has a 16GB eMMC connected to mmc2, with 8 bit
wide data bus.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 arch/arm/boot/dts/sun9i-a80-optimus.dts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index 02a4aa7..69b30dd 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -69,6 +69,15 @@
 			status = "okay";
 		};
 
+		mmc2: mmc at 01c11000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc2_pins>, <&mmc2_8bit_pins>;
+			vmmc-supply = <&reg_vcc3v0>;
+			bus-width = <8>;
+			non-removable;
+			status = "okay";
+		};
+
 		pio: pinctrl at 06000800 {
 			i2c3_pins_a: i2c3 at 0 {
 				/* Enable internal pull-up */
-- 
2.1.3

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

* [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80
  2014-12-03  6:35 ` [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80 Chen-Yu Tsai
@ 2014-12-06 17:13   ` Maxime Ripard
  2014-12-07  1:13     ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-06 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Chen-Yu,

Thanks for working on this

On Wed, Dec 03, 2014 at 02:35:56PM +0800, Chen-Yu Tsai wrote:
> The module 0 style clocks, or storage module clocks as named in the
> official SDK, are almost the same as the module 0 clocks on earlier
> Allwinner SoCs. The only difference is wider mux register bits.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
>  drivers/clk/sunxi/clk-mod0.c                      | 24 +++++++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 9dc4f55..d0fb9c5 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -58,6 +58,7 @@ Required properties:
>  	"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
>  	"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
>  	"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
> +	"allwinner,sun9i-a80-mod0-clk" - for module 0 (storage) clocks on A80
>  	"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
>  	"allwinner,sun7i-a20-out-clk" - for the external output clocks
>  	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
> diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
> index 658d74f..d72063f 100644
> --- a/drivers/clk/sunxi/clk-mod0.c
> +++ b/drivers/clk/sunxi/clk-mod0.c
> @@ -93,6 +93,30 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node)
>  }
>  CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);
>  
> +static const struct factors_data sun9i_a80_mod0_data __initconst = {
> +	.enable = 31,
> +	.mux = 24,
> +	.muxmask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
> +	.table = &sun4i_a10_mod0_config,
> +	.getter = sun4i_a10_get_mod0_factors,
> +};
> +
> +static void __init sun9i_a80_mod0_setup(struct device_node *node)
> +{
> +	void __iomem *reg;
> +
> +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +	if (!reg) {
> +		pr_err("Could not get registers for mod0-clk: %s\n",
> +		       node->name);
> +		return;
> +	}
> +
> +	sunxi_factors_register(node, &sun9i_a80_mod0_data,
> +			       &sun4i_a10_mod0_lock, reg);

Is there any particular reason to use the mod0 lock there? Or since
only the A80 mod0 clocks are going to be used, it doesn't make any
difference?

(Which makes me wonder why do we the same spinlock for all the
instances of the mod0 clocks, but that's another story)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141206/e45bd20a/attachment-0001.sig>

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

* [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes for A80
  2014-12-03  6:35 ` [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes " Chen-Yu Tsai
@ 2014-12-06 17:24   ` Maxime Ripard
  2014-12-07  1:11     ` Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-06 17:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Dec 03, 2014 at 02:35:57PM +0800, Chen-Yu Tsai wrote:
> The mmc module clocks are A80 specific module 0 (storage) type clocks.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> ---
>  arch/arm/boot/dts/sun9i-a80.dtsi | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> index 494714f..33d18dc 100644
> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> @@ -215,6 +215,38 @@
>  			clock-output-names = "cci400";
>  		};
>  
> +		mmc0_clk: clk at 06000410 {
> +			#clock-cells = <0>;
> +			compatible = "allwinner,sun9i-a80-mod0-clk";
> +			reg = <0x06000410 0x4>;
> +			clocks = <&osc24M>, <&pll4>;
> +			clock-output-names = "mmc0";
> +		};
> +
> +		mmc1_clk: clk at 06000414 {
> +			#clock-cells = <0>;
> +			compatible = "allwinner,sun9i-a80-mod0-clk";
> +			reg = <0x06000414 0x4>;
> +			clocks = <&osc24M>, <&pll4>;
> +			clock-output-names = "mmc1";
> +		};
> +
> +		mmc2_clk: clk at 06000418 {
> +			#clock-cells = <0>;
> +			compatible = "allwinner,sun9i-a80-mod0-clk";
> +			reg = <0x06000418 0x4>;
> +			clocks = <&osc24M>, <&pll4>;
> +			clock-output-names = "mmc2";
> +		};
> +
> +		mmc3_clk: clk at 0600041c {
> +			#clock-cells = <0>;
> +			compatible = "allwinner,sun9i-a80-mod0-clk";
> +			reg = <0x0600041c 0x4>;
> +			clocks = <&osc24M>, <&pll4>;
> +			clock-output-names = "mmc3";
> +		};
> +

How is the phase stuff supposed to work? Is this still used on the A80?

Also, wasn't the mux supposed to have 4 bits (so something like at
least 9 parent clocks?) given your previous patch?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141206/65168323/attachment.sig>

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

* [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets
  2014-12-03  6:35 ` [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets Chen-Yu Tsai
@ 2014-12-06 18:01   ` Maxime Ripard
  2014-12-07  1:30     ` Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-06 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Dec 03, 2014 at 02:35:58PM +0800, Chen-Yu Tsai wrote:
> On the A80 SoC, the 4 mmc controllers each have a separate register
> controlling their register access clocks and reset controls. These
> registers in turn share a ahb clock gate and reset control.
> 
> This patch adds a platform device driver for these controls. It
> requires both clocks and reset controls to be available, so using
> CLK_OF_DECLARE might not be the best way.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  Documentation/devicetree/bindings/clock/sunxi.txt |   1 +
>  drivers/clk/sunxi/Makefile                        |   1 +
>  drivers/clk/sunxi/clk-sun9i-mmc.c                 | 228 ++++++++++++++++++++++
>  3 files changed, 230 insertions(+)
>  create mode 100644 drivers/clk/sunxi/clk-sun9i-mmc.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index d0fb9c5..2de90ea 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -65,6 +65,7 @@ Required properties:
>  	"allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
>  	"allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
>  	"allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
> +	"allwinner,sun9i-a80-mmc-clk" - for mmc gates + resets on A80

Please document the arguments required for this clock as well.

>  
>  Required properties for all clocks:
>  - reg : shall be the control register address for the clock.
> diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
> index a66953c..3a5292e 100644
> --- a/drivers/clk/sunxi/Makefile
> +++ b/drivers/clk/sunxi/Makefile
> @@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
>  obj-y += clk-mod0.o
>  obj-y += clk-sun8i-mbus.o
>  obj-y += clk-sun9i-core.o
> +obj-y += clk-sun9i-mmc.o
>  
>  obj-$(CONFIG_MFD_SUN6I_PRCM) += \
>  	clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
> diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
> new file mode 100644
> index 0000000..7569625
> --- /dev/null
> +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
> @@ -0,0 +1,228 @@
> +/*
> + * Copyright 2013 Chen-Yu Tsai
> + *
> + * Chen-Yu Tsai	<wens@csie.org>
> + *
> + * This program 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 program 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.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/reset.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/spinlock.h>
> +
> +#define SUN9I_MMC_WIDTH		4
> +
> +#define SUN9I_MMC_GATE_BIT	16
> +#define SUN9I_MMC_RESET_BIT	18
> +
> +struct sun9i_mmc_clk_data {
> +	spinlock_t			lock;
> +	void __iomem			*membase;
> +	struct clk			*clk;
> +	struct reset_control		*reset;
> +	struct clk_onecell_data		clk_data;
> +	struct reset_controller_dev	rcdev;
> +};
> +
> +static int sun9i_mmc_reset_assert(struct reset_controller_dev *rcdev,
> +			      unsigned long id)
> +{
> +	struct sun9i_mmc_clk_data *data = container_of(rcdev,
> +						       struct sun9i_mmc_clk_data,
> +						       rcdev);
> +	unsigned long flags;
> +	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
> +	u32 val;
> +
> +	spin_lock_irqsave(&data->lock, flags);
> +
> +	val = readl(reg);
> +	writel(val & ~BIT(SUN9I_MMC_RESET_BIT), reg);
> +
> +	spin_unlock_irqrestore(&data->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev,
> +				unsigned long id)
> +{
> +	struct sun9i_mmc_clk_data *data = container_of(rcdev,
> +						       struct sun9i_mmc_clk_data,
> +						       rcdev);
> +	unsigned long flags;
> +	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
> +	u32 val;
> +
> +	spin_lock_irqsave(&data->lock, flags);
> +
> +	val = readl(reg);
> +	writel(val | BIT(SUN9I_MMC_RESET_BIT), reg);
> +
> +	spin_unlock_irqrestore(&data->lock, flags);
> +
> +	return 0;
> +}
> +
> +static struct reset_control_ops sun9i_mmc_reset_ops = {
> +	.assert		= sun9i_mmc_reset_assert,
> +	.deassert	= sun9i_mmc_reset_deassert,
> +};
> +
> +static int sun9i_a80_mmc_clk_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct sun9i_mmc_clk_data *data;
> +	struct clk_onecell_data *clk_data;
> +	const char *clk_name = np->name;
> +	const char *clk_parent;
> +	struct resource *r;
> +	int count, i, ret;
> +
> +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&data->lock);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	/* one clock/reset pair per word */
> +	count = (r->end - r->start + 1) / SUN9I_MMC_WIDTH;

div_round_up(resource_size(r), sizeof(u32)) ?

> +	data->membase = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(data->membase))
> +		return PTR_ERR(data->membase);
> +
> +	clk_data = &data->clk_data;
> +	clk_data->clk_num = count;
> +	clk_data->clks = devm_kcalloc(&pdev->dev, count, sizeof(struct clk *),
> +				      GFP_KERNEL);
> +	if (!clk_data->clks)
> +		return -ENOMEM;
> +
> +	clk_parent = of_clk_get_parent_name(np, 0);
> +	if (!clk_parent)
> +		return -EINVAL;
> +
> +	data->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(data->clk)) {
> +		dev_err(&pdev->dev, "Could not get clock\n");
> +		return PTR_ERR(data->clk);
> +	}
> +
> +	data->reset = devm_reset_control_get(&pdev->dev, NULL);
> +	if (IS_ERR(data->reset)) {
> +		dev_err(&pdev->dev, "Could not get reset control\n");
> +		return PTR_ERR(data->reset);
> +	}
> +
> +	ret = clk_prepare_enable(data->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Clock enable err %d\n", ret);
> +		return ret;
> +	}

So that means that the clock will always be enabled, even if there's
no downstream users?

Having the either clk_prepare_enable (or clk_enable if you're in
atomic context) in the assert/deassert seems more logical.

> +	ret = reset_control_deassert(data->reset);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Reset deassert err %d\n", ret);
> +		goto err_reset;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		of_property_read_string_index(np, "clock-output-names",
> +					      i, &clk_name);
> +
> +		clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
> +						      clk_parent, 0,
> +						      data->membase + SUN9I_MMC_WIDTH * i,
> +						      SUN9I_MMC_GATE_BIT, 0,
> +						      &data->lock);
> +
> +		if (IS_ERR(clk_data->clks[i])) {
> +			ret = PTR_ERR(clk_data->clks[i]);
> +			goto err_clk_register;
> +		}
> +	}
> +
> +	ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
> +	if (ret)
> +		goto err_clk_provider;
> +
> +	data->rcdev.owner = THIS_MODULE;
> +	data->rcdev.nr_resets = count;
> +	data->rcdev.ops = &sun9i_mmc_reset_ops;
> +	data->rcdev.of_node = pdev->dev.of_node;
> +
> +	ret = reset_controller_register(&data->rcdev);
> +	if (ret)
> +		goto err_rc_reg;
> +
> +	platform_set_drvdata(pdev, data);
> +
> +	return 0;
> +
> +err_rc_reg:
> +	of_clk_del_provider(np);
> +
> +err_clk_provider:
> +	for (i = 0; i < count; i++)
> +		clk_unregister(clk_data->clks[i]);
> +
> +err_clk_register:
> +	reset_control_assert(data->reset);
> +
> +err_reset:
> +	clk_disable_unprepare(data->clk);
> +
> +	return ret;
> +}
> +
> +static int sun9i_a80_mmc_clk_remove(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct sun9i_mmc_clk_data *data = platform_get_drvdata(pdev);
> +	struct clk_onecell_data *clk_data = &data->clk_data;
> +	int i;
> +
> +	reset_controller_unregister(&data->rcdev);
> +	of_clk_del_provider(np);
> +	for (i = 0; i < clk_data->clk_num; i++)
> +		clk_unregister(clk_data->clks[i]);
> +
> +	reset_control_assert(data->reset);
> +	clk_disable_unprepare(data->clk);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id sun9i_a80_mmc_clk_dt_ids[] = {
> +	{ .compatible = "allwinner,sun9i-a80-mmc-clk" },
> +	{ /* sentinel */ }
> +};
> +
> +static struct platform_driver sun9i_a80_mmc_clk_driver = {
> +	.driver = {
> +		.name = "sun9i-a80-mmc-clk",
> +		.of_match_table = sun9i_a80_mmc_clk_dt_ids,
> +	},
> +	.probe = sun9i_a80_mmc_clk_probe,
> +	.remove = sun9i_a80_mmc_clk_remove,
> +};
> +module_platform_driver(sun9i_a80_mmc_clk_driver);
> +
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_DESCRIPTION("Allwinner A80 MMC clock/reset Driver");
> +MODULE_LICENSE("GPL v2");

What's the real benefit of enabling it as a platform driver? the reset
framework is set up early enough that you can use OF_CLK_DECLARE.

Maxime


-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141206/6d4f4d6b/attachment-0001.sig>

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

* [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes for A80
  2014-12-06 17:24   ` Maxime Ripard
@ 2014-12-07  1:11     ` Chen-Yu Tsai
  2014-12-07 15:14       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07  1:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Sun, Dec 7, 2014 at 1:24 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Wed, Dec 03, 2014 at 02:35:57PM +0800, Chen-Yu Tsai wrote:
>> The mmc module clocks are A80 specific module 0 (storage) type clocks.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> Signed-off-by: Andreas F?rber <afaerber@suse.de>
>> ---
>>  arch/arm/boot/dts/sun9i-a80.dtsi | 32 ++++++++++++++++++++++++++++++++
>>  1 file changed, 32 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
>> index 494714f..33d18dc 100644
>> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
>> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
>> @@ -215,6 +215,38 @@
>>                       clock-output-names = "cci400";
>>               };
>>
>> +             mmc0_clk: clk at 06000410 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
>> +                     reg = <0x06000410 0x4>;
>> +                     clocks = <&osc24M>, <&pll4>;
>> +                     clock-output-names = "mmc0";
>> +             };
>> +
>> +             mmc1_clk: clk at 06000414 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
>> +                     reg = <0x06000414 0x4>;
>> +                     clocks = <&osc24M>, <&pll4>;
>> +                     clock-output-names = "mmc1";
>> +             };
>> +
>> +             mmc2_clk: clk at 06000418 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
>> +                     reg = <0x06000418 0x4>;
>> +                     clocks = <&osc24M>, <&pll4>;
>> +                     clock-output-names = "mmc2";
>> +             };
>> +
>> +             mmc3_clk: clk at 0600041c {
>> +                     #clock-cells = <0>;
>> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
>> +                     reg = <0x0600041c 0x4>;
>> +                     clocks = <&osc24M>, <&pll4>;
>> +                     clock-output-names = "mmc3";
>> +             };
>> +
>
> How is the phase stuff supposed to work? Is this still used on the A80?

It is. This time, the register bits are actually documented.

> Also, wasn't the mux supposed to have 4 bits (so something like at
> least 9 parent clocks?) given your previous patch?

The mux has 4 bits of valid settings. But only the first 2 have
valid parent clocks. I suppose I should make it clear in the bindings?

Some of the other module clocks have parents on the first 2 and last
2 valid settings, so we'll need to use a mux table for them.


ChenYu

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

* [linux-sunxi] Re: [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80
  2014-12-06 17:13   ` Maxime Ripard
@ 2014-12-07  1:13     ` Chen-Yu Tsai
  2014-12-07 15:16       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07  1:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Sun, Dec 7, 2014 at 1:13 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi Chen-Yu,
>
> Thanks for working on this
>
> On Wed, Dec 03, 2014 at 02:35:56PM +0800, Chen-Yu Tsai wrote:
>> The module 0 style clocks, or storage module clocks as named in the
>> official SDK, are almost the same as the module 0 clocks on earlier
>> Allwinner SoCs. The only difference is wider mux register bits.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
>>  drivers/clk/sunxi/clk-mod0.c                      | 24 +++++++++++++++++++++++
>>  2 files changed, 25 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
>> index 9dc4f55..d0fb9c5 100644
>> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
>> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
>> @@ -58,6 +58,7 @@ Required properties:
>>       "allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
>>       "allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
>>       "allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
>> +     "allwinner,sun9i-a80-mod0-clk" - for module 0 (storage) clocks on A80
>>       "allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
>>       "allwinner,sun7i-a20-out-clk" - for the external output clocks
>>       "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
>> diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
>> index 658d74f..d72063f 100644
>> --- a/drivers/clk/sunxi/clk-mod0.c
>> +++ b/drivers/clk/sunxi/clk-mod0.c
>> @@ -93,6 +93,30 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node)
>>  }
>>  CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);
>>
>> +static const struct factors_data sun9i_a80_mod0_data __initconst = {
>> +     .enable = 31,
>> +     .mux = 24,
>> +     .muxmask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
>> +     .table = &sun4i_a10_mod0_config,
>> +     .getter = sun4i_a10_get_mod0_factors,
>> +};
>> +
>> +static void __init sun9i_a80_mod0_setup(struct device_node *node)
>> +{
>> +     void __iomem *reg;
>> +
>> +     reg = of_io_request_and_map(node, 0, of_node_full_name(node));
>> +     if (!reg) {
>> +             pr_err("Could not get registers for mod0-clk: %s\n",
>> +                    node->name);
>> +             return;
>> +     }
>> +
>> +     sunxi_factors_register(node, &sun9i_a80_mod0_data,
>> +                            &sun4i_a10_mod0_lock, reg);
>
> Is there any particular reason to use the mod0 lock there? Or since
> only the A80 mod0 clocks are going to be used, it doesn't make any
> difference?

It doesn't make any difference for now.

> (Which makes me wonder why do we the same spinlock for all the
> instances of the mod0 clocks, but that's another story)

Are you worried about contention? AFAIK we don't do anything
fancy in our code that would result in a major problem.
I was wondering the same thing a while ago.

ChenYu

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

* [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets
  2014-12-06 18:01   ` Maxime Ripard
@ 2014-12-07  1:30     ` Chen-Yu Tsai
  2014-12-07 15:20       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07  1:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Sun, Dec 7, 2014 at 2:01 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Wed, Dec 03, 2014 at 02:35:58PM +0800, Chen-Yu Tsai wrote:
>> On the A80 SoC, the 4 mmc controllers each have a separate register
>> controlling their register access clocks and reset controls. These
>> registers in turn share a ahb clock gate and reset control.
>>
>> This patch adds a platform device driver for these controls. It
>> requires both clocks and reset controls to be available, so using
>> CLK_OF_DECLARE might not be the best way.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  Documentation/devicetree/bindings/clock/sunxi.txt |   1 +
>>  drivers/clk/sunxi/Makefile                        |   1 +
>>  drivers/clk/sunxi/clk-sun9i-mmc.c                 | 228 ++++++++++++++++++++++
>>  3 files changed, 230 insertions(+)
>>  create mode 100644 drivers/clk/sunxi/clk-sun9i-mmc.c
>>
>> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
>> index d0fb9c5..2de90ea 100644
>> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
>> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
>> @@ -65,6 +65,7 @@ Required properties:
>>       "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
>>       "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
>>       "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
>> +     "allwinner,sun9i-a80-mmc-clk" - for mmc gates + resets on A80
>
> Please document the arguments required for this clock as well.

Ok.

>>
>>  Required properties for all clocks:
>>  - reg : shall be the control register address for the clock.
>> diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
>> index a66953c..3a5292e 100644
>> --- a/drivers/clk/sunxi/Makefile
>> +++ b/drivers/clk/sunxi/Makefile
>> @@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
>>  obj-y += clk-mod0.o
>>  obj-y += clk-sun8i-mbus.o
>>  obj-y += clk-sun9i-core.o
>> +obj-y += clk-sun9i-mmc.o
>>
>>  obj-$(CONFIG_MFD_SUN6I_PRCM) += \
>>       clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
>> diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
>> new file mode 100644
>> index 0000000..7569625
>> --- /dev/null
>> +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
>> @@ -0,0 +1,228 @@
>> +/*
>> + * Copyright 2013 Chen-Yu Tsai
>> + *
>> + * Chen-Yu Tsai      <wens@csie.org>
>> + *
>> + * This program 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 program 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.
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/reset.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/reset-controller.h>
>> +#include <linux/spinlock.h>
>> +
>> +#define SUN9I_MMC_WIDTH              4
>> +
>> +#define SUN9I_MMC_GATE_BIT   16
>> +#define SUN9I_MMC_RESET_BIT  18
>> +
>> +struct sun9i_mmc_clk_data {
>> +     spinlock_t                      lock;
>> +     void __iomem                    *membase;
>> +     struct clk                      *clk;
>> +     struct reset_control            *reset;
>> +     struct clk_onecell_data         clk_data;
>> +     struct reset_controller_dev     rcdev;
>> +};
>> +
>> +static int sun9i_mmc_reset_assert(struct reset_controller_dev *rcdev,
>> +                           unsigned long id)
>> +{
>> +     struct sun9i_mmc_clk_data *data = container_of(rcdev,
>> +                                                    struct sun9i_mmc_clk_data,
>> +                                                    rcdev);
>> +     unsigned long flags;
>> +     void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
>> +     u32 val;
>> +
>> +     spin_lock_irqsave(&data->lock, flags);
>> +
>> +     val = readl(reg);
>> +     writel(val & ~BIT(SUN9I_MMC_RESET_BIT), reg);
>> +
>> +     spin_unlock_irqrestore(&data->lock, flags);
>> +
>> +     return 0;
>> +}
>> +
>> +static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev,
>> +                             unsigned long id)
>> +{
>> +     struct sun9i_mmc_clk_data *data = container_of(rcdev,
>> +                                                    struct sun9i_mmc_clk_data,
>> +                                                    rcdev);
>> +     unsigned long flags;
>> +     void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
>> +     u32 val;
>> +
>> +     spin_lock_irqsave(&data->lock, flags);
>> +
>> +     val = readl(reg);
>> +     writel(val | BIT(SUN9I_MMC_RESET_BIT), reg);
>> +
>> +     spin_unlock_irqrestore(&data->lock, flags);
>> +
>> +     return 0;
>> +}
>> +
>> +static struct reset_control_ops sun9i_mmc_reset_ops = {
>> +     .assert         = sun9i_mmc_reset_assert,
>> +     .deassert       = sun9i_mmc_reset_deassert,
>> +};
>> +
>> +static int sun9i_a80_mmc_clk_probe(struct platform_device *pdev)
>> +{
>> +     struct device_node *np = pdev->dev.of_node;
>> +     struct sun9i_mmc_clk_data *data;
>> +     struct clk_onecell_data *clk_data;
>> +     const char *clk_name = np->name;
>> +     const char *clk_parent;
>> +     struct resource *r;
>> +     int count, i, ret;
>> +
>> +     data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
>> +     if (!data)
>> +             return -ENOMEM;
>> +
>> +     spin_lock_init(&data->lock);
>> +
>> +     r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +     /* one clock/reset pair per word */
>> +     count = (r->end - r->start + 1) / SUN9I_MMC_WIDTH;
>
> div_round_up(resource_size(r), sizeof(u32)) ?

Will fix.

>> +     data->membase = devm_ioremap_resource(&pdev->dev, r);
>> +     if (IS_ERR(data->membase))
>> +             return PTR_ERR(data->membase);
>> +
>> +     clk_data = &data->clk_data;
>> +     clk_data->clk_num = count;
>> +     clk_data->clks = devm_kcalloc(&pdev->dev, count, sizeof(struct clk *),
>> +                                   GFP_KERNEL);
>> +     if (!clk_data->clks)
>> +             return -ENOMEM;
>> +
>> +     clk_parent = of_clk_get_parent_name(np, 0);
>> +     if (!clk_parent)
>> +             return -EINVAL;
>> +
>> +     data->clk = devm_clk_get(&pdev->dev, NULL);
>> +     if (IS_ERR(data->clk)) {
>> +             dev_err(&pdev->dev, "Could not get clock\n");
>> +             return PTR_ERR(data->clk);
>> +     }
>> +
>> +     data->reset = devm_reset_control_get(&pdev->dev, NULL);
>> +     if (IS_ERR(data->reset)) {
>> +             dev_err(&pdev->dev, "Could not get reset control\n");
>> +             return PTR_ERR(data->reset);
>> +     }
>> +
>> +     ret = clk_prepare_enable(data->clk);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "Clock enable err %d\n", ret);
>> +             return ret;
>> +     }
>
> So that means that the clock will always be enabled, even if there's
> no downstream users?

Yes.

> Having the either clk_prepare_enable (or clk_enable if you're in
> atomic context) in the assert/deassert seems more logical.

I'll try it out and see if it works. Didn't work so well with the
USB clocks...

>> +     ret = reset_control_deassert(data->reset);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "Reset deassert err %d\n", ret);
>> +             goto err_reset;
>> +     }
>> +
>> +     for (i = 0; i < count; i++) {
>> +             of_property_read_string_index(np, "clock-output-names",
>> +                                           i, &clk_name);
>> +
>> +             clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
>> +                                                   clk_parent, 0,
>> +                                                   data->membase + SUN9I_MMC_WIDTH * i,
>> +                                                   SUN9I_MMC_GATE_BIT, 0,
>> +                                                   &data->lock);
>> +
>> +             if (IS_ERR(clk_data->clks[i])) {
>> +                     ret = PTR_ERR(clk_data->clks[i]);
>> +                     goto err_clk_register;
>> +             }
>> +     }
>> +
>> +     ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
>> +     if (ret)
>> +             goto err_clk_provider;
>> +
>> +     data->rcdev.owner = THIS_MODULE;
>> +     data->rcdev.nr_resets = count;
>> +     data->rcdev.ops = &sun9i_mmc_reset_ops;
>> +     data->rcdev.of_node = pdev->dev.of_node;
>> +
>> +     ret = reset_controller_register(&data->rcdev);
>> +     if (ret)
>> +             goto err_rc_reg;
>> +
>> +     platform_set_drvdata(pdev, data);
>> +
>> +     return 0;
>> +
>> +err_rc_reg:
>> +     of_clk_del_provider(np);
>> +
>> +err_clk_provider:
>> +     for (i = 0; i < count; i++)
>> +             clk_unregister(clk_data->clks[i]);
>> +
>> +err_clk_register:
>> +     reset_control_assert(data->reset);
>> +
>> +err_reset:
>> +     clk_disable_unprepare(data->clk);
>> +
>> +     return ret;
>> +}
>> +
>> +static int sun9i_a80_mmc_clk_remove(struct platform_device *pdev)
>> +{
>> +     struct device_node *np = pdev->dev.of_node;
>> +     struct sun9i_mmc_clk_data *data = platform_get_drvdata(pdev);
>> +     struct clk_onecell_data *clk_data = &data->clk_data;
>> +     int i;
>> +
>> +     reset_controller_unregister(&data->rcdev);
>> +     of_clk_del_provider(np);
>> +     for (i = 0; i < clk_data->clk_num; i++)
>> +             clk_unregister(clk_data->clks[i]);
>> +
>> +     reset_control_assert(data->reset);
>> +     clk_disable_unprepare(data->clk);
>> +
>> +     return 0;
>> +}
>> +
>> +static const struct of_device_id sun9i_a80_mmc_clk_dt_ids[] = {
>> +     { .compatible = "allwinner,sun9i-a80-mmc-clk" },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver sun9i_a80_mmc_clk_driver = {
>> +     .driver = {
>> +             .name = "sun9i-a80-mmc-clk",
>> +             .of_match_table = sun9i_a80_mmc_clk_dt_ids,
>> +     },
>> +     .probe = sun9i_a80_mmc_clk_probe,
>> +     .remove = sun9i_a80_mmc_clk_remove,
>> +};
>> +module_platform_driver(sun9i_a80_mmc_clk_driver);
>> +
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_DESCRIPTION("Allwinner A80 MMC clock/reset Driver");
>> +MODULE_LICENSE("GPL v2");
>
> What's the real benefit of enabling it as a platform driver? the reset
> framework is set up early enough that you can use OF_CLK_DECLARE.

This clock/reset block also requires a reset control de-asserted. The
reset controllers are currently setup using platform devices. Are you
suggesting I use "allwinner,sun6i-a31-ahb1-reset" instead? That would
also imply having a .init_time callback for sun9i, and having
sun6i_reset_init() before of_clk_init(). Kind of confusing (not sure
this is the right word) for something not so critical.

Also we get to use devres, but that's just a bonus.

Thanks
ChenYu

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

* [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes
  2014-12-03  6:36 ` [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes Chen-Yu Tsai
@ 2014-12-07 15:00   ` Maxime Ripard
  2014-12-07 16:00     ` Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Dec 03, 2014 at 02:36:00PM +0800, Chen-Yu Tsai wrote:
> Add the device tree nodes for the mmc config clock nodes.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  arch/arm/boot/dts/sun9i-a80.dtsi | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> index f3cac3a..f425d9d 100644
> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> @@ -325,6 +325,19 @@
>  		 */
>  		ranges = <0 0 0 0x20000000>;
>  
> +		mmc_config_clk: clk at 01c23000 {
> +			compatible = "allwinner,sun9i-a80-mmc-clk";
> +			reg = <0x01c13000 0x10>;

The reg and the unit-address don't match.

Also, this used to be defined in the clocks node for the USB case, it
would be good to do the same here.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/c349f392/attachment.sig>

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

* [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0
  2014-12-03  6:36 ` [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0 Chen-Yu Tsai
@ 2014-12-07 15:01   ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Dec 03, 2014 at 02:36:02PM +0800, Chen-Yu Tsai wrote:
> mmc0 is only available on port F, and is always used with a 4 bit wide
> bus for the onboard micro-sd slot.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> ---
>  arch/arm/boot/dts/sun9i-a80.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> index c766698..f5b5645 100644
> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> @@ -458,6 +458,14 @@
>  				allwinner,pull = <0>;
>  			};
>  
> +			mmc0_pins: mmc0 {
> +				allwinner,pins = "PF0","PF1","PF2","PF3",
> +						 "PF4","PF5";

A space after each comma please.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/c5769288/attachment.sig>

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

* [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board
  2014-12-03  6:36 ` [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board Chen-Yu Tsai
@ 2014-12-07 15:02   ` Maxime Ripard
  2014-12-07 15:18     ` Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Dec 03, 2014 at 02:36:03PM +0800, Chen-Yu Tsai wrote:
> Enable the micro-sd slot on the A80 Optimus Board, which is connected to
> mmc0. This adds the card-detect gpio and enables mmc0.
> 
> This patch also adds a 3V fixed regulator, which is the default I/O
> voltage level.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> ---
>  arch/arm/boot/dts/sun9i-a80-optimus.dts | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
> index 506948f..02a4aa7 100644
> --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
> +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
> @@ -59,6 +59,16 @@
>  	};
>  
>  	soc {
> +		mmc0: mmc at 01c0f000 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
> +			vmmc-supply = <&reg_vcc3v0>;
> +			bus-width = <4>;
> +			cd-gpios = <&pio 7 18 0>; /* PH8 */
> +			cd-inverted;
> +			status = "okay";
> +		};
> +
>  		pio: pinctrl at 06000800 {
>  			i2c3_pins_a: i2c3 at 0 {
>  				/* Enable internal pull-up */
> @@ -72,6 +82,13 @@
>  				allwinner,pull = <0>;
>  			};
>  
> +			mmc0_cd_pin_optimus: mmc0_cd_pin at 0 {
> +				allwinner,pins = "PH18";
> +				allwinner,function = "gpio_in";
> +				allwinner,drive = <0>;
> +				allwinner,pull = <1>;
> +			};
> +
>  			uart4_pins_a: uart4 at 0 {
>  				/* Enable internal pull-up */
>  				allwinner,pull = <1>;
> @@ -116,4 +133,11 @@
>  			gpios = <&pio 7 0 0>;
>  		};
>  	};
> +
> +	reg_vcc3v0: vcc3v0 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v0";
> +		regulator-min-microvolt = <3000000>;
> +		regulator-max-microvolt = <3000000>;
> +	};

There's already such a regulator in sunxi-common-regulators.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/9d729f61/attachment.sig>

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

* [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2
  2014-12-03  6:36 ` [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2 Chen-Yu Tsai
@ 2014-12-07 15:03   ` Maxime Ripard
  2014-12-07 15:11     ` Chen-Yu Tsai
  0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 03, 2014 at 02:36:04PM +0800, Chen-Yu Tsai wrote:
> mmc2 is available on port C. Add a pinmux setting for usual 4 bit
> wide bus, as well as one with the 4 extra pins for 8 bit wide bus.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> ---
>  arch/arm/boot/dts/sun9i-a80.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> index f5b5645..fc866d8 100644
> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> @@ -466,6 +466,21 @@
>  				allwinner,pull = <0>;
>  			};
>  
> +			mmc2_pins: mmc2 {
> +				allwinner,pins = "PC6","PC7","PC8","PC9",
> +						 "PC10","PC11";
> +				allwinner,function = "mmc2";
> +				allwinner,drive = <2>;
> +				allwinner,pull = <1>;
> +			};
> +
> +			mmc2_8bit_pins: mmc2_8bit {
> +				allwinner,pins = "PC12","PC13","PC14","PC15";
> +				allwinner,function = "mmc2";
> +				allwinner,drive = <2>;
> +				allwinner,pull = <1>;
> +			};
> +

Hmmm, how is that 8 bits? There's only 4 pins here.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/50e5d716/attachment.sig>

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

* [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2
  2014-12-07 15:03   ` Maxime Ripard
@ 2014-12-07 15:11     ` Chen-Yu Tsai
  2014-12-07 17:46       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 7, 2014 at 11:03 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Wed, Dec 03, 2014 at 02:36:04PM +0800, Chen-Yu Tsai wrote:
>> mmc2 is available on port C. Add a pinmux setting for usual 4 bit
>> wide bus, as well as one with the 4 extra pins for 8 bit wide bus.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> Signed-off-by: Andreas F?rber <afaerber@suse.de>
>> ---
>>  arch/arm/boot/dts/sun9i-a80.dtsi | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
>> index f5b5645..fc866d8 100644
>> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
>> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
>> @@ -466,6 +466,21 @@
>>                               allwinner,pull = <0>;
>>                       };
>>
>> +                     mmc2_pins: mmc2 {
>> +                             allwinner,pins = "PC6","PC7","PC8","PC9",
>> +                                              "PC10","PC11";
>> +                             allwinner,function = "mmc2";
>> +                             allwinner,drive = <2>;
>> +                             allwinner,pull = <1>;
>> +                     };
>> +
>> +                     mmc2_8bit_pins: mmc2_8bit {
>> +                             allwinner,pins = "PC12","PC13","PC14","PC15";
>> +                             allwinner,function = "mmc2";
>> +                             allwinner,drive = <2>;
>> +                             allwinner,pull = <1>;
>> +                     };
>> +
>
> Hmmm, how is that 8 bits? There's only 4 pins here.

The 8bit setting only includes the upper 4 bits.
Using both settings together you get an 8 bit bus,
along with CMD and CLK pins, for a total of 10 pins.

Or is this the wrong way?

ChenYu

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

* [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes for A80
  2014-12-07  1:11     ` Chen-Yu Tsai
@ 2014-12-07 15:14       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 07, 2014 at 09:11:17AM +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Sun, Dec 7, 2014 at 1:24 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > Hi,
> >
> > On Wed, Dec 03, 2014 at 02:35:57PM +0800, Chen-Yu Tsai wrote:
> >> The mmc module clocks are A80 specific module 0 (storage) type clocks.
> >>
> >> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> >> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> >> ---
> >>  arch/arm/boot/dts/sun9i-a80.dtsi | 32 ++++++++++++++++++++++++++++++++
> >>  1 file changed, 32 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> >> index 494714f..33d18dc 100644
> >> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> >> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> >> @@ -215,6 +215,38 @@
> >>                       clock-output-names = "cci400";
> >>               };
> >>
> >> +             mmc0_clk: clk at 06000410 {
> >> +                     #clock-cells = <0>;
> >> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
> >> +                     reg = <0x06000410 0x4>;
> >> +                     clocks = <&osc24M>, <&pll4>;
> >> +                     clock-output-names = "mmc0";
> >> +             };
> >> +
> >> +             mmc1_clk: clk at 06000414 {
> >> +                     #clock-cells = <0>;
> >> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
> >> +                     reg = <0x06000414 0x4>;
> >> +                     clocks = <&osc24M>, <&pll4>;
> >> +                     clock-output-names = "mmc1";
> >> +             };
> >> +
> >> +             mmc2_clk: clk at 06000418 {
> >> +                     #clock-cells = <0>;
> >> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
> >> +                     reg = <0x06000418 0x4>;
> >> +                     clocks = <&osc24M>, <&pll4>;
> >> +                     clock-output-names = "mmc2";
> >> +             };
> >> +
> >> +             mmc3_clk: clk at 0600041c {
> >> +                     #clock-cells = <0>;
> >> +                     compatible = "allwinner,sun9i-a80-mod0-clk";
> >> +                     reg = <0x0600041c 0x4>;
> >> +                     clocks = <&osc24M>, <&pll4>;
> >> +                     clock-output-names = "mmc3";
> >> +             };
> >> +
> >
> > How is the phase stuff supposed to work? Is this still used on the A80?
> 
> It is. This time, the register bits are actually documented.

Ok, cool.

Depending on when the patches are coming in, that might conflict with
the last bits of the MMC clocks rework I'm about to send.

> > Also, wasn't the mux supposed to have 4 bits (so something like at
> > least 9 parent clocks?) given your previous patch?
> 
> The mux has 4 bits of valid settings. But only the first 2 have
> valid parent clocks. I suppose I should make it clear in the bindings?

Not really, this is an implementation detail, it shouldn't leak in the
DT. What you have is fine.

> Some of the other module clocks have parents on the first 2 and last
> 2 valid settings, so we'll need to use a mux table for them.

Ok.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/c4f67af3/attachment-0001.sig>

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

* [linux-sunxi] Re: [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80
  2014-12-07  1:13     ` [linux-sunxi] " Chen-Yu Tsai
@ 2014-12-07 15:16       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 07, 2014 at 09:13:46AM +0800, Chen-Yu Tsai wrote:
> > (Which makes me wonder why do we the same spinlock for all the
> > instances of the mod0 clocks, but that's another story)
> 
> Are you worried about contention? AFAIK we don't do anything
> fancy in our code that would result in a major problem.
> I was wondering the same thing a while ago.

Yes. While I'm not overly concerned about a performance bottleneck, it
does seems a bit odd to have a shared lock when there's no shared
resources.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/a2295bc8/attachment.sig>

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

* [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board
  2014-12-07 15:02   ` Maxime Ripard
@ 2014-12-07 15:18     ` Chen-Yu Tsai
  2014-12-07 15:35       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07 15:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 7, 2014 at 11:02 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Wed, Dec 03, 2014 at 02:36:03PM +0800, Chen-Yu Tsai wrote:
>> Enable the micro-sd slot on the A80 Optimus Board, which is connected to
>> mmc0. This adds the card-detect gpio and enables mmc0.
>>
>> This patch also adds a 3V fixed regulator, which is the default I/O
>> voltage level.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> Signed-off-by: Andreas F?rber <afaerber@suse.de>
>> ---
>>  arch/arm/boot/dts/sun9i-a80-optimus.dts | 24 ++++++++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
>> index 506948f..02a4aa7 100644
>> --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
>> +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
>> @@ -59,6 +59,16 @@
>>       };
>>
>>       soc {
>> +             mmc0: mmc at 01c0f000 {
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
>> +                     vmmc-supply = <&reg_vcc3v0>;
>> +                     bus-width = <4>;
>> +                     cd-gpios = <&pio 7 18 0>; /* PH8 */
>> +                     cd-inverted;
>> +                     status = "okay";
>> +             };
>> +
>>               pio: pinctrl at 06000800 {
>>                       i2c3_pins_a: i2c3 at 0 {
>>                               /* Enable internal pull-up */
>> @@ -72,6 +82,13 @@
>>                               allwinner,pull = <0>;
>>                       };
>>
>> +                     mmc0_cd_pin_optimus: mmc0_cd_pin at 0 {
>> +                             allwinner,pins = "PH18";
>> +                             allwinner,function = "gpio_in";
>> +                             allwinner,drive = <0>;
>> +                             allwinner,pull = <1>;
>> +                     };
>> +
>>                       uart4_pins_a: uart4 at 0 {
>>                               /* Enable internal pull-up */
>>                               allwinner,pull = <1>;
>> @@ -116,4 +133,11 @@
>>                       gpios = <&pio 7 0 0>;
>>               };
>>       };
>> +
>> +     reg_vcc3v0: vcc3v0 {
>> +             compatible = "regulator-fixed";
>> +             regulator-name = "vcc3v0";
>> +             regulator-min-microvolt = <3000000>;
>> +             regulator-max-microvolt = <3000000>;
>> +     };
>
> There's already such a regulator in sunxi-common-regulators.

I cannot include sunxi-common-regulators, not without a lot of work.
sunxi-common-regulators includes a soc/pio node, but the addresses,
and thus the node names are different. This results in:

ERROR (duplicate_label): Duplicate label 'pio' on
/soc at 01c00000/pinctrl at 01c20800 and /soc/pinctrl at 06000800

If we move to preprocessor-based includes and phandle referencing
(&pio { .... })
to override/add nodes and properties, then it would work. But that is
a lot of work
going through all of our DTs.

I'd prefer getting things working first, and do the rework later. As far as DT
compatibility goes, there shouldn't be any difference in the DTB.

ChenYu

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

* [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets
  2014-12-07  1:30     ` Chen-Yu Tsai
@ 2014-12-07 15:20       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 07, 2014 at 09:30:34AM +0800, Chen-Yu Tsai wrote:
> > Having the either clk_prepare_enable (or clk_enable if you're in
> > atomic context) in the assert/deassert seems more logical.
> 
> I'll try it out and see if it works. Didn't work so well with the
> USB clocks...

If it doesn't, it would be good to know why, it really should work.

> >> +     ret = reset_control_deassert(data->reset);
> >> +     if (ret) {
> >> +             dev_err(&pdev->dev, "Reset deassert err %d\n", ret);
> >> +             goto err_reset;
> >> +     }
> >> +
> >> +     for (i = 0; i < count; i++) {
> >> +             of_property_read_string_index(np, "clock-output-names",
> >> +                                           i, &clk_name);
> >> +
> >> +             clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
> >> +                                                   clk_parent, 0,
> >> +                                                   data->membase + SUN9I_MMC_WIDTH * i,
> >> +                                                   SUN9I_MMC_GATE_BIT, 0,
> >> +                                                   &data->lock);
> >> +
> >> +             if (IS_ERR(clk_data->clks[i])) {
> >> +                     ret = PTR_ERR(clk_data->clks[i]);
> >> +                     goto err_clk_register;
> >> +             }
> >> +     }
> >> +
> >> +     ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
> >> +     if (ret)
> >> +             goto err_clk_provider;
> >> +
> >> +     data->rcdev.owner = THIS_MODULE;
> >> +     data->rcdev.nr_resets = count;
> >> +     data->rcdev.ops = &sun9i_mmc_reset_ops;
> >> +     data->rcdev.of_node = pdev->dev.of_node;
> >> +
> >> +     ret = reset_controller_register(&data->rcdev);
> >> +     if (ret)
> >> +             goto err_rc_reg;
> >> +
> >> +     platform_set_drvdata(pdev, data);
> >> +
> >> +     return 0;
> >> +
> >> +err_rc_reg:
> >> +     of_clk_del_provider(np);
> >> +
> >> +err_clk_provider:
> >> +     for (i = 0; i < count; i++)
> >> +             clk_unregister(clk_data->clks[i]);
> >> +
> >> +err_clk_register:
> >> +     reset_control_assert(data->reset);
> >> +
> >> +err_reset:
> >> +     clk_disable_unprepare(data->clk);
> >> +
> >> +     return ret;
> >> +}
> >> +
> >> +static int sun9i_a80_mmc_clk_remove(struct platform_device *pdev)
> >> +{
> >> +     struct device_node *np = pdev->dev.of_node;
> >> +     struct sun9i_mmc_clk_data *data = platform_get_drvdata(pdev);
> >> +     struct clk_onecell_data *clk_data = &data->clk_data;
> >> +     int i;
> >> +
> >> +     reset_controller_unregister(&data->rcdev);
> >> +     of_clk_del_provider(np);
> >> +     for (i = 0; i < clk_data->clk_num; i++)
> >> +             clk_unregister(clk_data->clks[i]);
> >> +
> >> +     reset_control_assert(data->reset);
> >> +     clk_disable_unprepare(data->clk);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static const struct of_device_id sun9i_a80_mmc_clk_dt_ids[] = {
> >> +     { .compatible = "allwinner,sun9i-a80-mmc-clk" },
> >> +     { /* sentinel */ }
> >> +};
> >> +
> >> +static struct platform_driver sun9i_a80_mmc_clk_driver = {
> >> +     .driver = {
> >> +             .name = "sun9i-a80-mmc-clk",
> >> +             .of_match_table = sun9i_a80_mmc_clk_dt_ids,
> >> +     },
> >> +     .probe = sun9i_a80_mmc_clk_probe,
> >> +     .remove = sun9i_a80_mmc_clk_remove,
> >> +};
> >> +module_platform_driver(sun9i_a80_mmc_clk_driver);
> >> +
> >> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> >> +MODULE_DESCRIPTION("Allwinner A80 MMC clock/reset Driver");
> >> +MODULE_LICENSE("GPL v2");
> >
> > What's the real benefit of enabling it as a platform driver? the reset
> > framework is set up early enough that you can use OF_CLK_DECLARE.
> 
> This clock/reset block also requires a reset control de-asserted. The
> reset controllers are currently setup using platform devices. Are you
> suggesting I use "allwinner,sun6i-a31-ahb1-reset" instead? That would
> also imply having a .init_time callback for sun9i, and having
> sun6i_reset_init() before of_clk_init(). Kind of confusing (not sure
> this is the right word) for something not so critical.
> 
> Also we get to use devres, but that's just a bonus.

Ok, it makes sense then.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/5602c9fc/attachment.sig>

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

* [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board
  2014-12-07 15:18     ` Chen-Yu Tsai
@ 2014-12-07 15:35       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 07, 2014 at 11:18:28PM +0800, Chen-Yu Tsai wrote:
> >> +     reg_vcc3v0: vcc3v0 {
> >> +             compatible = "regulator-fixed";
> >> +             regulator-name = "vcc3v0";
> >> +             regulator-min-microvolt = <3000000>;
> >> +             regulator-max-microvolt = <3000000>;
> >> +     };
> >
> > There's already such a regulator in sunxi-common-regulators.
> 
> I cannot include sunxi-common-regulators, not without a lot of work.
> sunxi-common-regulators includes a soc/pio node, but the addresses,
> and thus the node names are different. This results in:
> 
> ERROR (duplicate_label): Duplicate label 'pio' on
> /soc at 01c00000/pinctrl at 01c20800 and /soc/pinctrl at 06000800
> 
> If we move to preprocessor-based includes and phandle referencing
> (&pio { .... })
> to override/add nodes and properties, then it would work. But that is
> a lot of work
> going through all of our DTs.

Not really, you can just do so in sunxi-common-regulator. There's no
need to do it everywhere else.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/de956048/attachment.sig>

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

* [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes
  2014-12-07 15:00   ` Maxime Ripard
@ 2014-12-07 16:00     ` Chen-Yu Tsai
  2014-12-07 17:45       ` Maxime Ripard
  0 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2014-12-07 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 7, 2014 at 11:00 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Wed, Dec 03, 2014 at 02:36:00PM +0800, Chen-Yu Tsai wrote:
>> Add the device tree nodes for the mmc config clock nodes.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  arch/arm/boot/dts/sun9i-a80.dtsi | 13 +++++++++++++
>>  1 file changed, 13 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
>> index f3cac3a..f425d9d 100644
>> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
>> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
>> @@ -325,6 +325,19 @@
>>                */
>>               ranges = <0 0 0 0x20000000>;
>>
>> +             mmc_config_clk: clk at 01c23000 {
>> +                     compatible = "allwinner,sun9i-a80-mmc-clk";
>> +                     reg = <0x01c13000 0x10>;
>
> The reg and the unit-address don't match.

Will fix.

> Also, this used to be defined in the clocks node for the USB case, it
> would be good to do the same here.

As it is a platform driver, it can't be under the clocks node, which
doesn't instantiate platform devices. (That is, assuming you're ok
with it being a platform driver.)

ChenYu

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

* [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes
  2014-12-07 16:00     ` Chen-Yu Tsai
@ 2014-12-07 17:45       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 17:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 08, 2014 at 12:00:21AM +0800, Chen-Yu Tsai wrote:
> As it is a platform driver, it can't be under the clocks node, which
> doesn't instantiate platform devices. (That is, assuming you're ok
> with it being a platform driver.)

That shouldn't have any impact on the DT itself, but yeah, you're
right.

I guess we should just kill that clocks node for memory mapped clocks
one day.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/386251cd/attachment.sig>

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

* [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2
  2014-12-07 15:11     ` Chen-Yu Tsai
@ 2014-12-07 17:46       ` Maxime Ripard
  0 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2014-12-07 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 07, 2014 at 11:11:06PM +0800, Chen-Yu Tsai wrote:
> On Sun, Dec 7, 2014 at 11:03 PM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > On Wed, Dec 03, 2014 at 02:36:04PM +0800, Chen-Yu Tsai wrote:
> >> mmc2 is available on port C. Add a pinmux setting for usual 4 bit
> >> wide bus, as well as one with the 4 extra pins for 8 bit wide bus.
> >>
> >> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> >> Signed-off-by: Andreas F?rber <afaerber@suse.de>
> >> ---
> >>  arch/arm/boot/dts/sun9i-a80.dtsi | 15 +++++++++++++++
> >>  1 file changed, 15 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
> >> index f5b5645..fc866d8 100644
> >> --- a/arch/arm/boot/dts/sun9i-a80.dtsi
> >> +++ b/arch/arm/boot/dts/sun9i-a80.dtsi
> >> @@ -466,6 +466,21 @@
> >>                               allwinner,pull = <0>;
> >>                       };
> >>
> >> +                     mmc2_pins: mmc2 {
> >> +                             allwinner,pins = "PC6","PC7","PC8","PC9",
> >> +                                              "PC10","PC11";
> >> +                             allwinner,function = "mmc2";
> >> +                             allwinner,drive = <2>;
> >> +                             allwinner,pull = <1>;
> >> +                     };
> >> +
> >> +                     mmc2_8bit_pins: mmc2_8bit {
> >> +                             allwinner,pins = "PC12","PC13","PC14","PC15";
> >> +                             allwinner,function = "mmc2";
> >> +                             allwinner,drive = <2>;
> >> +                             allwinner,pull = <1>;
> >> +                     };
> >> +
> >
> > Hmmm, how is that 8 bits? There's only 4 pins here.
> 
> The 8bit setting only includes the upper 4 bits.
> Using both settings together you get an 8 bit bus,
> along with CMD and CLK pins, for a total of 10 pins.
> 
> Or is this the wrong way?

The way it's usually done is that you have two standalone nodes. Just
like what's done for the UARTs for example.

Maxime


-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141207/f30b618c/attachment-0001.sig>

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

end of thread, other threads:[~2014-12-07 17:46 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-03  6:35 [PATCH 00/10] ARM: sun9i: Enable MMC support on Allwinner A80 Chen-Yu Tsai
2014-12-03  6:35 ` [PATCH 01/10] clk: sunxi: Add module 0 (storage) style clock support for A80 Chen-Yu Tsai
2014-12-06 17:13   ` Maxime Ripard
2014-12-07  1:13     ` [linux-sunxi] " Chen-Yu Tsai
2014-12-07 15:16       ` Maxime Ripard
2014-12-03  6:35 ` [PATCH 02/10] ARM: dts: sun9i: Add mmc module clock nodes " Chen-Yu Tsai
2014-12-06 17:24   ` Maxime Ripard
2014-12-07  1:11     ` Chen-Yu Tsai
2014-12-07 15:14       ` Maxime Ripard
2014-12-03  6:35 ` [PATCH 03/10] clk: sunxi: Add driver for A80 MMC config clocks/resets Chen-Yu Tsai
2014-12-06 18:01   ` Maxime Ripard
2014-12-07  1:30     ` Chen-Yu Tsai
2014-12-07 15:20       ` Maxime Ripard
2014-12-03  6:35 ` [PATCH 04/10] ARM: dts: sun9i: Add clock-indices property for bus gate clocks Chen-Yu Tsai
2014-12-03  6:36 ` [PATCH 05/10] ARM: dts: sun9i: Add mmc config clock nodes Chen-Yu Tsai
2014-12-07 15:00   ` Maxime Ripard
2014-12-07 16:00     ` Chen-Yu Tsai
2014-12-07 17:45       ` Maxime Ripard
2014-12-03  6:36 ` [PATCH 06/10] ARM: dts: sun9i: Add mmc controller nodes to the A80 dtsi Chen-Yu Tsai
2014-12-03  6:36 ` [PATCH 07/10] ARM: dts: sun9i: Add pinmux setting for mmc0 Chen-Yu Tsai
2014-12-07 15:01   ` Maxime Ripard
2014-12-03  6:36 ` [PATCH 08/10] ARM: dts: sun9i: Enable mmc0 on A80 Optimus Board Chen-Yu Tsai
2014-12-07 15:02   ` Maxime Ripard
2014-12-07 15:18     ` Chen-Yu Tsai
2014-12-07 15:35       ` Maxime Ripard
2014-12-03  6:36 ` [PATCH 09/10] ARM: dts: sun9i: Add pinmux settings for mmc2 Chen-Yu Tsai
2014-12-07 15:03   ` Maxime Ripard
2014-12-07 15:11     ` Chen-Yu Tsai
2014-12-07 17:46       ` Maxime Ripard
2014-12-03  6:36 ` [PATCH 10/10] ARM: dts: sun9i: Enable mmc2 on A80 Optimus Board Chen-Yu Tsai

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