[PATCH 1/6] clk: sunxi: Let divs clocks read the base factor clock name from devicetree

2327 views
Skip to first unread message

Jens Kuske

unread,
Oct 21, 2015, 12:13:36 PM10/21/15
to Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
Currently, the sunxi clock driver gets the name for the base factor clock
of divs clocks from the name field in factors_data. This prevents reusing
of the factor clock for clocks with same properties, but different name.

This commit makes the divs setup function try to get a name from
clock-output-names in the devicetree. It also removes the name field where
possible and merges the sun4i PLL5 and PLL6 clocks.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
drivers/clk/sunxi/clk-sunxi.c | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 9c79af0c..7c4aee0 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -704,21 +704,12 @@ static const struct factors_data sun4i_pll5_data __initconst = {
.enable = 31,
.table = &sun4i_pll5_config,
.getter = sun4i_get_pll5_factors,
- .name = "pll5",
-};
-
-static const struct factors_data sun4i_pll6_data __initconst = {
- .enable = 31,
- .table = &sun4i_pll5_config,
- .getter = sun4i_get_pll5_factors,
- .name = "pll6",
};

static const struct factors_data sun6i_a31_pll6_data __initconst = {
.enable = 31,
.table = &sun6i_a31_pll6_config,
.getter = sun6i_a31_get_pll6_factors,
- .name = "pll6x2",
};

static const struct factors_data sun5i_a13_ahb_data __initconst = {
@@ -902,6 +893,7 @@ struct gates_data {

#define SUNXI_DIVS_MAX_QTY 4
#define SUNXI_DIVISOR_WIDTH 2
+#define SUNXI_DIVS_BASE_NAME_MAX_LEN 8

struct divs_data {
const struct factors_data *factors; /* data for the factor clock */
@@ -941,7 +933,7 @@ static const struct divs_data pll5_divs_data __initconst = {
};

static const struct divs_data pll6_divs_data __initconst = {
- .factors = &sun4i_pll6_data,
+ .factors = &sun4i_pll5_data,
.ndivs = 4,
.div = {
{ .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
@@ -983,6 +975,8 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
struct clk_gate *gate = NULL;
struct clk_fixed_factor *fix_factor;
struct clk_divider *divider;
+ struct factors_data factors = *data->factors;
+ char base_name[SUNXI_DIVS_BASE_NAME_MAX_LEN];
void __iomem *reg;
int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
int flags, clkflags;
@@ -991,8 +985,31 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
if (data->ndivs)
ndivs = data->ndivs;

+ /* Try to find a name for base factor clock */
+ for (i = 0; i < ndivs; i++) {
+ if (data->div[i].self) {
+ of_property_read_string_index(node, "clock-output-names",
+ i, &factors.name);
+ break;
+ }
+ }
+ /* If we don't have a .self clk use the first output-name up to '_' */
+ if (factors.name == NULL) {
+ of_property_read_string_index(node, "clock-output-names",
+ 0, &clk_name);
+
+ for (i = 0; i < SUNXI_DIVS_BASE_NAME_MAX_LEN - 1 &&
+ clk_name[i] != '_' &&
+ clk_name[i] != '\0'; i++) {
+ base_name[i] = clk_name[i];
+ }
+
+ base_name[i] = '\0';
+ factors.name = base_name;
+ }
+
/* Set up factor clock that we will be dividing */
- pclk = sunxi_factors_clk_setup(node, data->factors);
+ pclk = sunxi_factors_clk_setup(node, &factors);
parent = __clk_get_name(pclk);

reg = of_iomap(node, 0);
--
2.6.1

Jens Kuske

unread,
Oct 21, 2015, 12:13:36 PM10/21/15
to Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
Hi everyone,

This is v3 of my patch series introducing basic kernel support for Allwinner's
H3 SoC. It mainly adds basic clocks and pinctrl. It also adds interrupts,
timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly compatible
to those in earlier SoCs like A23 and A31, and can simply be reused.

These patches are based on Maxime's sunxi/for-next branch from
git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git


Patch 1 improves the sunxi divs clock to read the name of the base factor clock
from devicetree instead of hardcoding it, which allows us to reuse sun6i-pll6
for our pll8.

Patch 2 adds support for the basic clocks.

Patch 3 adds the pin sets for the H3 main PIO.

Patch 4 adds a new compatible for the H3 reset controller

Patch 5 adds the DTSI for the H3.

Patch 6 adds a DTS for the Orange Pi Plus SBC, which these patches
were developed and tested with.


Changes since v2:
- add mbus clock
- add Maxime's suggestion to take the substring up to the first "_" as name
for the divs base clock
- use A31 pll6 for H3 pll6
- use a clock similar to the new simple gates for H3 bus gates
- drop the pinctrl-as-module patch since pinctrl and gpio don't seem to be
ready for removable drivers
- documentation and machine support are merged already

Changes since v1:
- Update sunxi README in Documentation
- Add the multiple parents gates and use them for bus-gates instead of
ahb1, ahb2, apb1 and apb2 gates
- Merge the pll8 clock with sun6i pll6
- Merge the ahb12, apb1 and apb2 resets to bus-resets with own compatible
- Add sun6i_timer_init to sun8i machine
- Remove the single SoC names from machine definition, its sun8i family
- Make the pinctrl driver tristate and put its Kconfig entry in the right order
- Rename pinctrl "scr" to "sim" and clock "sim" to "scr" to match user manual
- Remove the address paragraph from GPL in dts and dtsi
- Some style cleanup and line wrapping in dtsi
- Add ARM architected timers
- dmaengine isn't included anymore, it is merged already

Best Regards,
Jens


Jens Kuske (6):
clk: sunxi: Let divs clocks read the base factor clock name from
devicetree
clk: sunxi: Add H3 clocks support
pinctrl: sunxi: Add H3 PIO controller support
reset: sunxi: Add compatible for Allwinner H3 bus resets
ARM: dts: sunxi: Add Allwinner H3 DTSI
ARM: dts: sun8i: Add Orange Pi Plus support

Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
.../bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 1 +
.../bindings/reset/allwinner,sunxi-clock-reset.txt | 1 +
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 77 +++
arch/arm/boot/dts/sun8i-h3.dtsi | 499 ++++++++++++++++++++
drivers/clk/sunxi/Makefile | 1 +
drivers/clk/sunxi/clk-bus-gates.c | 105 +++++
drivers/clk/sunxi/clk-sunxi.c | 47 +-
drivers/pinctrl/sunxi/Kconfig | 4 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 516 +++++++++++++++++++++
drivers/reset/reset-sunxi.c | 1 +
13 files changed, 1245 insertions(+), 13 deletions(-)
create mode 100644 arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
create mode 100644 arch/arm/boot/dts/sun8i-h3.dtsi
create mode 100644 drivers/clk/sunxi/clk-bus-gates.c
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c

--
2.6.1

Jens Kuske

unread,
Oct 21, 2015, 12:13:40 PM10/21/15
to Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The H3 clock control unit is similar to the those of other sun8i family
members like the A23.

It adds a new bus gates clock similar to the simple gates, but with a
different parent clock for each single gate.
Some of the gates use the new AHB2 clock as parent, whose clock source
is muxable between AHB1 and PLL6/2. The documentation isn't totally clear
about which devices belong to AHB2 now, especially USB EHIC/OHIC, so it
is mostly based on Allwinner kernel source code.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
drivers/clk/sunxi/Makefile | 1 +
drivers/clk/sunxi/clk-bus-gates.c | 105 ++++++++++++++++++++++
drivers/clk/sunxi/clk-sunxi.c | 12 ++-
4 files changed, 117 insertions(+), 3 deletions(-)
create mode 100644 drivers/clk/sunxi/clk-bus-gates.c

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 8a47b77..d303dec 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -28,6 +28,7 @@ Required properties:
"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
"allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
"allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
+ "allwinner,sun8i-h3-ahb2-clk" - for the AHB2 clock on H3
"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
"allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80
@@ -55,6 +56,7 @@ Required properties:
"allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
+ "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3
"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
"allwinner,sun4i-a10-mmc-clk" - for the MMC clock
"allwinner,sun9i-a80-mmc-clk" - for mmc module clocks on A80
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index f5a35b8..ecaff7f 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -5,6 +5,7 @@
obj-y += clk-sunxi.o clk-factors.o
obj-y += clk-a10-hosc.o
obj-y += clk-a20-gmac.o
+obj-y += clk-bus-gates.o
obj-y += clk-mod0.o
obj-y += clk-simple-gates.o
obj-y += clk-sun8i-mbus.o
diff --git a/drivers/clk/sunxi/clk-bus-gates.c b/drivers/clk/sunxi/clk-bus-gates.c
new file mode 100644
index 0000000..5bba0b9
--- /dev/null
+++ b/drivers/clk/sunxi/clk-bus-gates.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jens...@gmail.com>
+ *
+ * Based on clk-simple-gates.c, which is:
+ * Copyright 2015 Maxime Ripard
+ *
+ * Maxime Ripard <maxime...@free-electrons.com>
+ *
+ * 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.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+static DEFINE_SPINLOCK(gates_lock);
+
+static void __init sunxi_bus_gates_setup(struct device_node *node,
+ const int protected[],
+ int nprotected)
+{
+ struct clk_onecell_data *clk_data;
+ const char *clk_parent, *clk_name;
+ struct property *prop;
+ struct resource res;
+ void __iomem *clk_reg;
+ void __iomem *reg;
+ const __be32 *p;
+ int number, i = 0, j;
+ u8 clk_bit;
+ u32 index;
+
+ reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+ if (IS_ERR(reg))
+ return;
+
+ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_data)
+ goto err_unmap;
+
+ number = of_property_count_u32_elems(node, "clock-indices");
+ of_property_read_u32_index(node, "clock-indices", number - 1, &number);
+
+ clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL);
+ if (!clk_data->clks)
+ goto err_free_data;
+
+ of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+ of_property_read_string_index(node, "clock-output-names",
+ i, &clk_name);
+
+ clk_parent = of_clk_get_parent_name(node, i);
+
+ clk_reg = reg + 4 * (index / 32);
+ clk_bit = index % 32;
+
+ clk_data->clks[index] = clk_register_gate(NULL, clk_name,
+ clk_parent, 0,
+ clk_reg,
+ clk_bit,
+ 0, &gates_lock);
+ i++;
+
+ if (IS_ERR(clk_data->clks[index])) {
+ WARN_ON(true);
+ continue;
+ }
+
+ for (j = 0; j < nprotected; j++)
+ if (protected[j] == index)
+ clk_prepare_enable(clk_data->clks[index]);
+
+ }
+
+ clk_data->clk_num = number + 1;
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ return;
+
+err_free_data:
+ kfree(clk_data);
+err_unmap:
+ iounmap(reg);
+ of_address_to_resource(node, 0, &res);
+ release_mem_region(res.start, resource_size(&res));
+}
+
+static void __init sunxi_bus_gates_init(struct device_node *node)
+{
+ sunxi_bus_gates_setup(node, NULL, 0);
+}
+
+CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk",
+ sunxi_bus_gates_init);
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 7c4aee0..6293c65 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -769,6 +769,10 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = {
.shift = 12,
};

+static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = {
+ .shift = 0,
+};
+
static void __init sunxi_mux_clk_setup(struct device_node *node,
struct mux_data *data)
{
@@ -945,10 +949,11 @@ static const struct divs_data pll6_divs_data __initconst = {

static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
.factors = &sun6i_a31_pll6_data,
- .ndivs = 2,
+ .ndivs = 3,
.div = {
{ .fixed = 2 }, /* normal output */
{ .self = 1 }, /* base factor clock, 2x */
+ { .fixed = 4 }, /* divided output, /2 */
}
};

@@ -1000,9 +1005,8 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,

for (i = 0; i < SUNXI_DIVS_BASE_NAME_MAX_LEN - 1 &&
clk_name[i] != '_' &&
- clk_name[i] != '\0'; i++) {
+ clk_name[i] != '\0'; i++)
base_name[i] = clk_name[i];
- }

base_name[i] = '\0';
factors.name = base_name;
@@ -1147,6 +1151,7 @@ static const struct of_device_id clk_divs_match[] __initconst = {
static const struct of_device_id clk_mux_match[] __initconst = {
{.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
+ {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,},
{}
};

@@ -1229,6 +1234,7 @@ CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks);
CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks);
+CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks);

static void __init sun9i_init_clocks(struct device_node *node)
{
--
2.6.1

Code Kipper

unread,
Oct 21, 2015, 1:11:09 PM10/21/15
to jens...@gmail.com, linux-sunxi
On 21 October 2015 at 18:13, Jens Kuske <jens...@gmail.com> wrote:
> Hi everyone,
>
> This is v3 of my patch series introducing basic kernel support for Allwinner's
> H3 SoC. It mainly adds basic clocks and pinctrl. It also adds interrupts,
> timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly compatible
> to those in earlier SoCs like A23 and A31, and can simply be reused.
>
> These patches are based on Maxime's sunxi/for-next branch from
> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git

Thanks for the update...just seconds ago managed to get some chatter
after the "Starting Kernel" prompt on my Orange Pi 2 using the patch
from http://moinejf.free.fr/opi2/ but I will switch over to these new
ones to verify. I'm also using your u-boot so there has been some
progress in the Kipper household this evening.

Thanks again,
CK
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Code Kipper

unread,
Oct 21, 2015, 1:34:31 PM10/21/15
to jens...@gmail.com, linux-sunxi
On 21 October 2015 at 19:11, Code Kipper <codek...@gmail.com> wrote:
> On 21 October 2015 at 18:13, Jens Kuske <jens...@gmail.com> wrote:
>> Hi everyone,
>>
>> This is v3 of my patch series introducing basic kernel support for Allwinner's
>> H3 SoC. It mainly adds basic clocks and pinctrl. It also adds interrupts,
>> timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly compatible
>> to those in earlier SoCs like A23 and A31, and can simply be reused.
>>
>> These patches are based on Maxime's sunxi/for-next branch from
>> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git
>
> Thanks for the update...just seconds ago managed to get some chatter
> after the "Starting Kernel" prompt on my Orange Pi 2 using the patch
> from http://moinejf.free.fr/opi2/ but I will switch over to these new
> ones to verify. I'm also using your u-boot so there has been some
> progress in the Kipper household this evening.
>
> Thanks again,
> CK
Coool....it's booting...now to find me a rootfs!

Hans de Goede

unread,
Oct 21, 2015, 3:19:03 PM10/21/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net
Hi Jens,

On 21-10-15 18:13, Jens Kuske wrote:
> Hi everyone,
>
> This is v3 of my patch series introducing basic kernel support for Allwinner's
> H3 SoC. It mainly adds basic clocks and pinctrl. It also adds interrupts,
> timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly compatible
> to those in earlier SoCs like A23 and A31, and can simply be reused.
>
> These patches are based on Maxime's sunxi/for-next branch from
> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git
>
>
> Patch 1 improves the sunxi divs clock to read the name of the base factor clock
> from devicetree instead of hardcoding it, which allows us to reuse sun6i-pll6
> for our pll8.
>
> Patch 2 adds support for the basic clocks.
>
> Patch 3 adds the pin sets for the H3 main PIO.
>
> Patch 4 adds a new compatible for the H3 reset controller
>
> Patch 5 adds the DTSI for the H3.
>
> Patch 6 adds a DTS for the Orange Pi Plus SBC, which these patches
> were developed and tested with.

Great to see that you've started working on this again. Last weekend I
ended up working on this too together with Reinder E.N. de Haan <rei...@mveas.com>
(added to the Cc).

We took a slightly different approach for the gates clocks, see:

https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

And specifically:

https://github.com/jwrdegoede/linux-sunxi/commit/80a1afe319d5d1a0c426d42e75d37f0c64e8ea0b

Combined with:

https://github.com/jwrdegoede/linux-sunxi/commit/d508da5feb5048f6674d6b24b58ac9058fb9d877

This deals with the per gate parents the same way the rockchip
clock code does, and it seems to be quite a bit less code then your solution.

So now we've two solutions to chose from :) Since you seem to be back to
working on this I'll refrain from doing any further work, at least
without coordinating. Maxime, can you let us know which solution for the
gates clock parents is best, or tell us if you think both solutions are
no good :)

(I wanted to get in touch with you about the work done this weekend,
but your posting of this v3 has sorta pre-empted that).

Other then the slightly different solution for the gates, the code in my tree
is a straight forward port of your v2.

Thanks for your work on this!

Regards,

Hans


p.s.

I'm teaching a kernel driver course at my local hackerspace in the netherlands:

https://revspace.nl/KernelDriverProgrammingCourse2015

Which is where our work on this this weekend originated. The next planned
course day is November 1st and I expect Reinder to be working on the H3
again then. I think the plan was to tackle USB next. Reinder can you confirm
this ? If you (Jens) want to work on USB before then, that is fine, but please
coordinate their is plenty to do, so no need for us to be doing (more) double
work.

Hans de Goede

unread,
Oct 21, 2015, 3:24:05 PM10/21/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,

On 21-10-15 18:13, Jens Kuske wrote:
> Hi everyone,
>
> This is v3 of my patch series introducing basic kernel support for Allwinner's
> H3 SoC. It mainly adds basic clocks and pinctrl. It also adds interrupts,
> timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly compatible
> to those in earlier SoCs like A23 and A31, and can simply be reused.
>
> These patches are based on Maxime's sunxi/for-next branch from
> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git

p.s.

For the next version you will want to base these on the sunxi-next branch of:

https://github.com/linux-sunxi/linux-sunxi.git

There is at least a conflict with the pio driver due to the addition of
the a83 pio driver which mripard/linux/sunxi/for-next does not have, where
as linux-sunxi/sunxi-next does have that merged in.

Regards,

Hans

Julian Calaby

unread,
Oct 21, 2015, 8:16:02 PM10/21/15
to jens...@gmail.com, Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, Mailing List, Arm, linux-...@vger.kernel.org, linux-sunxi
Hi Jens,

On Thu, Oct 22, 2015 at 3:13 AM, Jens Kuske <jens...@gmail.com> wrote:
> The H3 clock control unit is similar to the those of other sun8i family
> members like the A23.
>
> It adds a new bus gates clock similar to the simple gates, but with a
> different parent clock for each single gate.
> Some of the gates use the new AHB2 clock as parent, whose clock source
> is muxable between AHB1 and PLL6/2. The documentation isn't totally clear
> about which devices belong to AHB2 now, especially USB EHIC/OHIC, so it
> is mostly based on Allwinner kernel source code.
>
> Signed-off-by: Jens Kuske <jens...@gmail.com>
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
> drivers/clk/sunxi/Makefile | 1 +
> drivers/clk/sunxi/clk-bus-gates.c | 105 ++++++++++++++++++++++
> drivers/clk/sunxi/clk-sunxi.c | 12 ++-
> 4 files changed, 117 insertions(+), 3 deletions(-)
> create mode 100644 drivers/clk/sunxi/clk-bus-gates.c
>
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 7c4aee0..6293c65 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c

This hunk should be in patch 1:

> @@ -1000,9 +1005,8 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
>
> for (i = 0; i < SUNXI_DIVS_BASE_NAME_MAX_LEN - 1 &&
> clk_name[i] != '_' &&
> - clk_name[i] != '\0'; i++) {
> + clk_name[i] != '\0'; i++)
> base_name[i] = clk_name[i];
> - }
>
> base_name[i] = '\0';
> factors.name = base_name;

Thanks,

--
Julian Calaby

Email: julian...@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

Jens Kuske

unread,
Oct 22, 2015, 3:49:21 AM10/22/15
to Hans de Goede, Maxime Ripard, Chen-Yu Tsai, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net
Hi,

On 21/10/15 21:18, Hans de Goede wrote:
>
> Great to see that you've started working on this again. Last weekend I
> ended up working on this too together with Reinder E.N. de Haan <rei...@mveas.com>
> (added to the Cc).
>
> We took a slightly different approach for the gates clocks, see:
>
> https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip
>
> And specifically:
>
> https://github.com/jwrdegoede/linux-sunxi/commit/80a1afe319d5d1a0c426d42e75d37f0c64e8ea0b
>
> Combined with:
>
> https://github.com/jwrdegoede/linux-sunxi/commit/d508da5feb5048f6674d6b24b58ac9058fb9d877
>
> This deals with the per gate parents the same way the rockchip
> clock code does, and it seems to be quite a bit less code then your solution.
>
> So now we've two solutions to chose from :) Since you seem to be back to
> working on this I'll refrain from doing any further work, at least
> without coordinating. Maxime, can you let us know which solution for the
> gates clock parents is best, or tell us if you think both solutions are
> no good :)

I'd actually prefer your solution. I duplicated the simple-gates code
when trying a different approach and never revisited that decision.

>
> (I wanted to get in touch with you about the work done this weekend,
> but your posting of this v3 has sorta pre-empted that).
>
> Other then the slightly different solution for the gates, the code in my tree
> is a straight forward port of your v2.
>
> Thanks for your work on this!
>
> Regards,
>
> Hans
>
>
> p.s.
>
> I'm teaching a kernel driver course at my local hackerspace in the netherlands:
>
> https://revspace.nl/KernelDriverProgrammingCourse2015
>
> Which is where our work on this this weekend originated. The next planned
> course day is November 1st and I expect Reinder to be working on the H3
> again then. I think the plan was to tackle USB next. Reinder can you confirm
> this ? If you (Jens) want to work on USB before then, that is fine, but please
> coordinate their is plenty to do, so no need for us to be doing (more) double
> work.
>

I don't plan to work on USB soon, my next step would have been Ethernet
and finishing the basic u-boot support. You know my u-boot H3 wip tree I
hope? Before we duplicate our work there too...
https://github.com/jemk/u-boot-sunxi/tree/sunxi/h3

Jens

Jens Kuske

unread,
Oct 22, 2015, 3:49:43 AM10/22/15
to Julian Calaby, Maxime Ripard, Chen-Yu Tsai, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, Mailing List, Arm, linux-...@vger.kernel.org, linux-sunxi

On 22/10/15 02:15, Julian Calaby wrote:
>
> This hunk should be in patch 1:

Indeed, Thanks.

Jens

Jean-Francois Moine

unread,
Oct 22, 2015, 4:31:44 AM10/22/15
to Hans de Goede, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, Reinder E.N. de Haan, linux-...@vger.kernel.org, linux...@googlegroups.com, linux-ar...@lists.infradead.org, zhao_...@263.net
On Wed, 21 Oct 2015 21:18:45 +0200
Hans de Goede <hdeg...@redhat.com> wrote:

> Great to see that you've started working on this again. Last weekend I
> ended up working on this too together with Reinder E.N. de Haan <rei...@mveas.com>
> (added to the Cc).
>
> We took a slightly different approach for the gates clocks, see:
>
> https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip
>
> And specifically:
>
> https://github.com/jwrdegoede/linux-sunxi/commit/80a1afe319d5d1a0c426d42e75d37f0c64e8ea0b
>
> Combined with:
>
> https://github.com/jwrdegoede/linux-sunxi/commit/d508da5feb5048f6674d6b24b58ac9058fb9d877
>
> This deals with the per gate parents the same way the rockchip
> clock code does, and it seems to be quite a bit less code then your solution.

Here is a simpler patch:

diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c
index 6ce9118..8fecaeab 100644
--- a/drivers/clk/sunxi/clk-simple-gates.c
+++ b/drivers/clk/sunxi/clk-simple-gates.c
@@ -35,6 +35,7 @@ static void __init sunxi_simple_gates_setup(struct device_node *node,
void __iomem *reg;
const __be32 *p;
int number, i = 0, j;
+ bool parent_per_gate;
u8 clk_bit;
u32 index;

@@ -43,6 +44,7 @@ static void __init sunxi_simple_gates_setup(struct device_node *node,
return;

clk_parent = of_clk_get_parent_name(node, 0);
+ parent_per_gate = of_clk_get_parent_count(node) != 1;

clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
if (!clk_data)
@@ -58,6 +60,8 @@ static void __init sunxi_simple_gates_setup(struct device_node *node,
of_property_for_each_u32(node, "clock-indices", prop, p, index) {
of_property_read_string_index(node, "clock-output-names",
i, &clk_name);
+ if (parent_per_gate)
+ clk_parent = of_clk_get_parent_name(node, i);

clk_reg = reg + 4 * (index / 32);
clk_bit = index % 32;


--
Ken ar c'hentañ | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/

Hans de Goede

unread,
Oct 22, 2015, 4:49:25 AM10/22/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net
Hi,

On 22-10-15 09:49, Jens Kuske wrote:
> Hi,
>
> On 21/10/15 21:18, Hans de Goede wrote:
>>
>> Great to see that you've started working on this again. Last weekend I
>> ended up working on this too together with Reinder E.N. de Haan <rei...@mveas.com>
>> (added to the Cc).
>>
>> We took a slightly different approach for the gates clocks, see:
>>
>> https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip
>>
>> And specifically:
>>
>> https://github.com/jwrdegoede/linux-sunxi/commit/80a1afe319d5d1a0c426d42e75d37f0c64e8ea0b
>>
>> Combined with:
>>
>> https://github.com/jwrdegoede/linux-sunxi/commit/d508da5feb5048f6674d6b24b58ac9058fb9d877
>>
>> This deals with the per gate parents the same way the rockchip
>> clock code does, and it seems to be quite a bit less code then your solution.
>>
>> So now we've two solutions to chose from :) Since you seem to be back to
>> working on this I'll refrain from doing any further work, at least
>> without coordinating. Maxime, can you let us know which solution for the
>> gates clock parents is best, or tell us if you think both solutions are
>> no good :)
>
> I'd actually prefer your solution. I duplicated the simple-gates code
> when trying a different approach and never revisited that decision.

Ok, note then when you switch to my solution (or the improved version of it
or the improved version Jean-Francois Moine suggests) the dtsi now has a list
of clocks with one per gate, rather then clock indices. You can save yourself
some time by taking that list from the dtsi patch in my tree, rather then
building it yourself manually.

>> (I wanted to get in touch with you about the work done this weekend,
>> but your posting of this v3 has sorta pre-empted that).
>>
>> Other then the slightly different solution for the gates, the code in my tree
>> is a straight forward port of your v2.
>>
>> Thanks for your work on this!
>>
>> Regards,
>>
>> Hans
>>
>>
>> p.s.
>>
>> I'm teaching a kernel driver course at my local hackerspace in the netherlands:
>>
>> https://revspace.nl/KernelDriverProgrammingCourse2015
>>
>> Which is where our work on this this weekend originated. The next planned
>> course day is November 1st and I expect Reinder to be working on the H3
>> again then. I think the plan was to tackle USB next. Reinder can you confirm
>> this ? If you (Jens) want to work on USB before then, that is fine, but please
>> coordinate their is plenty to do, so no need for us to be doing (more) double
>> work.
>>
>
> I don't plan to work on USB soon, my next step would have been Ethernet
> and finishing the basic u-boot support. You know my u-boot H3 wip tree I
> hope? Before we duplicate our work there too...
> https://github.com/jemk/u-boot-sunxi/tree/sunxi/h3

I was not aware of that work, at a first glance it looks good. Can you rebase
this on top of current u-boot/master (or v2015.10) and then submit it upstream ?

2 questions which come to mind immediately:

1) Where does the dram init logic come from, AFAIK Allwinner has not provided
any H3 dram init code ?

2) I see no pmic code in there. I know these boards do not use an axp pmic,
but according to my info at least the Orange Pi 2 (which I have) uses a
sy8106a pmic, it is not entirely clear to me yet if this one needs any
init though, I've mailed the Orange Pi people about this.

Regards,

Hans



Hans de Goede

unread,
Oct 22, 2015, 5:08:50 AM10/22/15
to Jean-Francois Moine, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Mike Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, Reinder E.N. de Haan, linux-...@vger.kernel.org, linux...@googlegroups.com, linux-ar...@lists.infradead.org, zhao_...@263.net
Hi,
Yes good one, doing things that way indeed is better.

Regards,

Hans

Jens Kuske

unread,
Oct 22, 2015, 7:52:45 AM10/22/15
to Hans de Goede, Maxime Ripard, Chen-Yu Tsai, Emilio López, Vishnu Patekar, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net

On 22/10/15 10:49, Hans de Goede wrote:
> Hi,
>
> On 22-10-15 09:49, Jens Kuske wrote:
[..]
>>
>> I don't plan to work on USB soon, my next step would have been Ethernet
>> and finishing the basic u-boot support. You know my u-boot H3 wip tree I
>> hope? Before we duplicate our work there too...
>> https://github.com/jemk/u-boot-sunxi/tree/sunxi/h3
>
> I was not aware of that work, at a first glance it looks good. Can you rebase
> this on top of current u-boot/master (or v2015.10) and then submit it upstream ?

I will, after fixing some more things (like your question 2).

>
> 2 questions which come to mind immediately:
>
> 1) Where does the dram init logic come from, AFAIK Allwinner has not provided
> any H3 dram init code ?

It's from the Draco H3 TV Stick SDK:

http://www.cnx-software.com/2015/06/14/tronsmart-draco-h3-tv-stick-firmware-and-sdk-released/

>
> 2) I see no pmic code in there. I know these boards do not use an axp pmic,
> but according to my info at least the Orange Pi 2 (which I have) uses a
> sy8106a pmic, it is not entirely clear to me yet if this one needs any
> init though, I've mailed the Orange Pi people about this.

Correct, the CPU voltage is provided by a i2c controllable regulator (sy8106a)
without any datasheet. I've found how to set the voltage in above SDK, but I
first want test this carefully.

There's also the problem that we have to use the OpenRISC core for power
management (especially poweroff), since there is no external PMIC. This can
be done later of course, but we should think about how to do it.

Jens

Jens Kuske

unread,
Oct 27, 2015, 12:50:44 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
Hi everyone,

This is v4 of my patch series introducing basic kernel support for Allwinner's
H3 SoC. It mainly adds basic clocks, resets and pinctrl. It also adds
interrupts, timers, watchdog, RTC, dmaengine, MMC and UARTs, which are mostly
compatible to those in earlier SoCs like A23 and A31, and can simply be reused.

These patches are based on the sunxi-next branch from
git://github.com/linux-sunxi/linux-sunxi.git


Patch 1 improves the sunxi divs clock to read the name of the base factor clock
from devicetree instead of hardcoding it, which allows us to reuse sun6i-pll6
for our pll8.

Patch 2 adds support for the basic clocks.

Patch 3 adds the pin sets for the H3 main PIO.

Patch 4 adds the H3 reset controller

Patch 5 adds the DTSI for the H3.

Patch 6 adds a DTS for the Orange Pi Plus SBC, which these patches
were developed and tested with.


Changes since v3:
- add a clock driver specific to the bus gates instead of listing parents in
the DTSI
- skip the holes in the reset controller with of_xlate()
reset: sunxi: Add Allwinner H3 bus resets
ARM: dts: sunxi: Add Allwinner H3 DTSI
ARM: dts: sun8i: Add Orange Pi Plus support

Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
.../bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 1 +
.../bindings/reset/allwinner,sunxi-clock-reset.txt | 1 +
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 77 +++
arch/arm/boot/dts/sun8i-h3.dtsi | 482 +++++++++++++++++++
drivers/clk/sunxi/Makefile | 1 +
drivers/clk/sunxi/clk-sun8i-bus-gates.c | 111 +++++
drivers/clk/sunxi/clk-sunxi.c | 47 +-
drivers/pinctrl/sunxi/Kconfig | 4 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 516 +++++++++++++++++++++
drivers/reset/reset-sunxi.c | 30 +-
13 files changed, 1260 insertions(+), 16 deletions(-)
create mode 100644 arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
create mode 100644 arch/arm/boot/dts/sun8i-h3.dtsi
create mode 100644 drivers/clk/sunxi/clk-sun8i-bus-gates.c
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c

--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:44 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
Currently, the sunxi clock driver gets the name for the base factor clock
of divs clocks from the name field in factors_data. This prevents reusing
of the factor clock for clocks with same properties, but different name.

This commit makes the divs setup function try to get a name from
clock-output-names in the devicetree. It also removes the name field where
possible and merges the sun4i PLL5 and PLL6 clocks.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
drivers/clk/sunxi/clk-sunxi.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 9c79af0c..270de42 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -991,8 +985,30 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
if (data->ndivs)
ndivs = data->ndivs;

+ /* Try to find a name for base factor clock */
+ for (i = 0; i < ndivs; i++) {
+ if (data->div[i].self) {
+ of_property_read_string_index(node, "clock-output-names",
+ i, &factors.name);
+ break;
+ }
+ }
+ /* If we don't have a .self clk use the first output-name up to '_' */
+ if (factors.name == NULL) {
+ of_property_read_string_index(node, "clock-output-names",
+ 0, &clk_name);
+
+ for (i = 0; i < SUNXI_DIVS_BASE_NAME_MAX_LEN - 1 &&
+ clk_name[i] != '_' &&
+ clk_name[i] != '\0'; i++)
+ base_name[i] = clk_name[i];
+
+ base_name[i] = '\0';
+ factors.name = base_name;
+ }
+
/* Set up factor clock that we will be dividing */
- pclk = sunxi_factors_clk_setup(node, data->factors);
+ pclk = sunxi_factors_clk_setup(node, &factors);
parent = __clk_get_name(pclk);

reg = of_iomap(node, 0);
--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:45 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The H3 clock control unit is similar to the those of other sun8i family
members like the A23.

It adds a new bus gates clock similar to the simple gates, but with a
different parent clock for each single gate.
Some of the gates use the new AHB2 clock as parent, whose clock source
is muxable between AHB1 and PLL6/2. The documentation isn't totally clear
about which devices belong to AHB2 now, especially USB EHIC/OHIC, so it
is mostly based on Allwinner kernel source code.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
drivers/clk/sunxi/Makefile | 1 +
drivers/clk/sunxi/clk-sun8i-bus-gates.c | 111 ++++++++++++++++++++++
drivers/clk/sunxi/clk-sunxi.c | 9 +-
4 files changed, 122 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/sunxi/clk-sun8i-bus-gates.c

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 8a47b77..d303dec 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -28,6 +28,7 @@ Required properties:
"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
"allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
"allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
+ "allwinner,sun8i-h3-ahb2-clk" - for the AHB2 clock on H3
"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
"allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80
@@ -55,6 +56,7 @@ Required properties:
"allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
+ "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3
"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
"allwinner,sun4i-a10-mmc-clk" - for the MMC clock
"allwinner,sun9i-a80-mmc-clk" - for mmc module clocks on A80
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index cb4c299..f520af6 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -10,6 +10,7 @@ obj-y += clk-a10-pll2.o
obj-y += clk-a20-gmac.o
obj-y += clk-mod0.o
obj-y += clk-simple-gates.o
+obj-y += clk-sun8i-bus-gates.o
obj-y += clk-sun8i-mbus.o
obj-y += clk-sun9i-core.o
obj-y += clk-sun9i-mmc.o
diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c
new file mode 100644
index 0000000..ad605fa
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c
@@ -0,0 +1,111 @@
+static void __init sun8i_h3_bus_gates_init(struct device_node *node)
+{
+ const char *clocks[] = { "ahb1", "ahb2", "apb1", "apb2" };
+ enum { AHB1, AHB2, APB1, APB2 } clk_parent;
+ struct clk_onecell_data *clk_data;
+ const char *clk_name;
+ struct property *prop;
+ struct resource res;
+ void __iomem *clk_reg;
+ void __iomem *reg;
+ const __be32 *p;
+ int number, i;
+ u8 clk_bit;
+ u32 index;
+
+ reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+ if (IS_ERR(reg))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(clocks); i++) {
+ index = of_property_match_string(node, "clock-names", clocks[i]);
+ if (index < 0)
+ return;
+
+ clocks[i] = of_clk_get_parent_name(node, index);
+ }
+
+ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_data)
+ goto err_unmap;
+
+ number = of_property_count_u32_elems(node, "clock-indices");
+ of_property_read_u32_index(node, "clock-indices", number - 1, &number);
+
+ clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL);
+ if (!clk_data->clks)
+ goto err_free_data;
+
+ i = 0;
+ of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+ of_property_read_string_index(node, "clock-output-names",
+ i, &clk_name);
+
+ if (index == 17 || (index >= 29 && index <= 31))
+ clk_parent = AHB2;
+ else if (index <= 63 || index >= 128)
+ clk_parent = AHB1;
+ else if (index >= 64 && index <= 95)
+ clk_parent = APB1;
+ else if (index >= 96 && index <= 127)
+ clk_parent = APB2;
+
+ clk_reg = reg + 4 * (index / 32);
+ clk_bit = index % 32;
+
+ clk_data->clks[index] = clk_register_gate(NULL, clk_name,
+ clocks[clk_parent], 0,
+ clk_reg,
+ clk_bit,
+ 0, &gates_lock);
+ i++;
+
+ if (IS_ERR(clk_data->clks[index])) {
+ WARN_ON(true);
+ continue;
+ }
+ }
+
+ clk_data->clk_num = number + 1;
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ return;
+
+err_free_data:
+ kfree(clk_data);
+err_unmap:
+ iounmap(reg);
+ of_address_to_resource(node, 0, &res);
+ release_mem_region(res.start, resource_size(&res));
+}
+
+CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk",
+ sun8i_h3_bus_gates_init);
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 270de42..6293c65 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -769,6 +769,10 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = {
.shift = 12,
};

+static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = {
+ .shift = 0,
+};
+
static void __init sunxi_mux_clk_setup(struct device_node *node,
struct mux_data *data)
{
@@ -945,10 +949,11 @@ static const struct divs_data pll6_divs_data __initconst = {

static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
.factors = &sun6i_a31_pll6_data,
- .ndivs = 2,
+ .ndivs = 3,
.div = {
{ .fixed = 2 }, /* normal output */
{ .self = 1 }, /* base factor clock, 2x */
+ { .fixed = 4 }, /* divided output, /2 */
}
};

@@ -1146,6 +1151,7 @@ static const struct of_device_id clk_divs_match[] __initconst = {
static const struct of_device_id clk_mux_match[] __initconst = {
{.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
+ {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,},
{}
};

@@ -1228,6 +1234,7 @@ CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks);
CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks);
+CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks);

static void __init sun9i_init_clocks(struct device_node *node)
{
--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:47 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The H3 uses the same pin controller as previous SoC's from Allwinner.
Add support for the pins controlled by the main PIO controller.

Signed-off-by: Jens Kuske <jens...@gmail.com>
Acked-by: Maxime Ripard <maxime...@free-electrons.com>
---
.../bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 1 +
drivers/pinctrl/sunxi/Kconfig | 4 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 516 +++++++++++++++++++++
4 files changed, 522 insertions(+)
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
index b321b26..e6ba602 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -18,6 +18,7 @@ Required properties:
"allwinner,sun8i-a23-r-pinctrl"
"allwinner,sun8i-a33-pinctrl"
"allwinner,sun8i-a83t-pinctrl"
+ "allwinner,sun8i-h3-pinctrl"

- reg: Should contain the register physical address and length for the
pin controller.
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index e68fd95..89ab7f5 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -51,6 +51,10 @@ config PINCTRL_SUN8I_A23_R
depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON

+config PINCTRL_SUN8I_H3
+ def_bool MACH_SUN8I
+ select PINCTRL_SUNXI_COMMON
+
config PINCTRL_SUN9I_A80
def_bool MACH_SUN9I
select PINCTRL_SUNXI_COMMON
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index e080290..6bd818e 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o
obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o
+obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o
obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
new file mode 100644
index 0000000..98d465d
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
@@ -0,0 +1,516 @@
+/*
+ * Allwinner H3 SoCs pinctrl driver.
+ *
+ * Copyright (C) 2015 Jens Kuske <jens...@gmail.com>
+ *
+ * Based on pinctrl-sun8i-a23.c, which is:
+ * Copyright (C) 2014 Chen-Yu Tsai <we...@csie.org>
+ * Copyright (C) 2014 Maxime Ripard <maxime...@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_h3_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION(0x3, "jtag"), /* MS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION(0x3, "jtag"), /* CK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart0"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart0"), /* RX */
+ SUNXI_FUNCTION(0x3, "pwm0"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "sim"), /* PWREN */
+ SUNXI_FUNCTION(0x3, "pwm1"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "sim"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "sim"), /* DATA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "sim"), /* RST */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "sim"), /* DET */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0"), /* SCK */
+ SUNXI_FUNCTION(0x3, "di"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0"), /* SDA */
+ SUNXI_FUNCTION(0x3, "di"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CS */
+ SUNXI_FUNCTION(0x3, "uart3"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart3"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
+ SUNXI_FUNCTION(0x3, "uart3"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
+ SUNXI_FUNCTION(0x3, "uart3"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spdif"), /* OUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */
+ SUNXI_FUNCTION(0x3, "i2c1"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "i2c1"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */
+ SUNXI_FUNCTION(0x3, "sim"), /* VPPEN */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */
+ SUNXI_FUNCTION(0x3, "sim"), /* VPPPP */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* WE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RE */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQS */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXD3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXD2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXD1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXD0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXCTL/RCDV */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* RXERR */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXD3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXD2L */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXD1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXD0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* CRS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXCTL/TXEN */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* TXERR */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* CLKIN/COL */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* MDC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "emac")), /* MDIO */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* PCLK */
+ SUNXI_FUNCTION(0x3, "ts")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* MCLK */
+ SUNXI_FUNCTION(0x3, "ts")), /* ERR */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */
+ SUNXI_FUNCTION(0x3, "ts")), /* SYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */
+ SUNXI_FUNCTION(0x3, "ts")), /* DVLD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D0 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D1 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D2 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D3 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D4 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D5 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D6 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* D7 */
+ SUNXI_FUNCTION(0x3, "ts")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SCK */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SDA */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* MS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DI */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart0")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DO */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
+ SUNXI_FUNCTION(0x3, "uart0")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* CK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0")), /* DET */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PG_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PG_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PG_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PG_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PG_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PG_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PG_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PG_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 8)), /* PG_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 9)), /* PG_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 10)), /* PG_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 11)), /* PG_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 12)), /* PG_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 13)), /* PG_EINT13 */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_h3_pinctrl_data = {
+ .pins = sun8i_h3_pins,
+ .npins = ARRAY_SIZE(sun8i_h3_pins),
+ .irq_banks = 2,
+};
+
+static int sun8i_h3_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_init(pdev,
+ &sun8i_h3_pinctrl_data);
+}
+
+static const struct of_device_id sun8i_h3_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-h3-pinctrl", },
+ {}
+};
+
+static struct platform_driver sun8i_h3_pinctrl_driver = {
+ .probe = sun8i_h3_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-h3-pinctrl",
+ .of_match_table = sun8i_h3_pinctrl_match,
+ },
+};
+builtin_platform_driver(sun8i_h3_pinctrl_driver);
--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:48 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The H3 bus resets have some holes between the registers, so we add
an of_xlate() function to skip them according to the datasheet.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
.../bindings/reset/allwinner,sunxi-clock-reset.txt | 1 +
drivers/reset/reset-sunxi.c | 30 +++++++++++++++++++---
2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
index c8f7757..e11f023 100644
--- a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
+++ b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
@@ -8,6 +8,7 @@ Required properties:
- compatible: Should be one of the following:
"allwinner,sun6i-a31-ahb1-reset"
"allwinner,sun6i-a31-clock-reset"
+ "allwinner,sun8i-h3-bus-reset"
- reg: should be register base and length as documented in the
datasheet
- #reset-cells: 1, see below
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
index 3d95c87..c91e146 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -75,7 +75,9 @@ static struct reset_control_ops sunxi_reset_ops = {
.deassert = sunxi_reset_deassert,
};

-static int sunxi_reset_init(struct device_node *np)
+static int sunxi_reset_init(struct device_node *np,
+ int (*of_xlate)(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec))
{
struct sunxi_reset_data *data;
struct resource res;
@@ -108,6 +110,7 @@ static int sunxi_reset_init(struct device_node *np)
data->rcdev.nr_resets = size * 32;
data->rcdev.ops = &sunxi_reset_ops;
data->rcdev.of_node = np;
+ data->rcdev.of_xlate = of_xlate;
reset_controller_register(&data->rcdev);

return 0;
@@ -117,6 +120,21 @@ err_alloc:
return ret;
};

+static int sun8i_h3_bus_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ unsigned int index = reset_spec->args[0];
+
+ if (index < 96)
+ return index;
+ else if (index < 128)
+ return index + 32;
+ else if (index < 160)
+ return index + 64;
+ else
+ return -EINVAL;
+}
+
/*
* These are the reset controller we need to initialize early on in
* our system, before we can even think of using a regular device
@@ -124,15 +142,21 @@ err_alloc:
*/
static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = {
{ .compatible = "allwinner,sun6i-a31-ahb1-reset", },
+ { .compatible = "allwinner,sun8i-h3-bus-reset", .data = sun8i_h3_bus_reset_xlate, },
{ /* sentinel */ },
};

void __init sun6i_reset_init(void)
{
struct device_node *np;
+ const struct of_device_id *match;
+ int (*of_xlate)(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec);

- for_each_matching_node(np, sunxi_early_reset_dt_ids)
- sunxi_reset_init(np);
+ for_each_matching_node_and_match(np, sunxi_early_reset_dt_ids, &match) {
+ of_xlate = match->data;
+ sunxi_reset_init(np, of_xlate);
+ }
}

/*
--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:50 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The Allwinner H3 is a home entertainment system oriented SoC with
four Cortex-A7 cores and a Mali-400MP2 GPU.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
arch/arm/boot/dts/sun8i-h3.dtsi | 482 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 482 insertions(+)
create mode 100644 arch/arm/boot/dts/sun8i-h3.dtsi

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
new file mode 100644
index 0000000..c18b5f7
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jens...@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file 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 file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <24000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc24M: osc24M_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24M";
+ };
+
+ osc32k: osc32k_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "osc32k";
+ };
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ /* dummy clock until actually implemented */
+ pll5: pll5_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ clock-output-names = "pll5";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6", "pll6x2", "pll6d2";
+ };
+
+ pll8: clk@01c20044 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun6i-a31-pll6-clk";
+ reg = <0x01c20044 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll8", "pll8x2";
+ };
+
+ cpu: cpu_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb1: ahb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-ahb1-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
+ clock-output-names = "ahb1";
+ };
+
+ ahb2: ahb2_clk@01c2005c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-h3-ahb2-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&ahb1>, <&pll6 2>;
+ clock-output-names = "ahb2";
+ };
+
+ apb1: apb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ apb2: apb2_clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
+ clock-output-names = "apb2";
+ };
+
+ bus_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-h3-bus-gates-clk";
+ reg = <0x01c20060 0x14>;
+ clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>;
+ clock-names = "ahb1", "ahb2", "apb1", "apb2";
+ clock-indices = <5>, <6>, <8>,
+ <9>, <10>, <13>,
+ <14>, <17>, <18>,
+ <19>, <20>,
+ <21>, <23>,
+ <24>, <25>,
+ <26>, <27>,
+ <28>, <29>,
+ <30>, <31>, <32>,
+ <35>, <36>, <37>,
+ <40>, <41>, <43>,
+ <44>, <52>, <53>,
+ <54>, <64>,
+ <65>, <69>, <72>,
+ <76>, <77>, <78>,
+ <96>, <97>, <98>,
+ <112>, <113>,
+ <114>, <115>, <116>,
+ <128>, <135>;
+ clock-output-names = "ahb1_ce", "ahb1_dma", "ahb1_mmc0",
+ "ahb1_mmc1", "ahb1_mmc2", "ahb1_nand",
+ "ahb1_sdram", "ahb2_gmac", "ahb1_ts",
+ "ahb1_hstimer", "ahb1_spi0",
+ "ahb1_spi1", "ahb1_otg",
+ "ahb1_otg_ehci0", "ahb1_ehic1",
+ "ahb1_ehic2", "ahb1_ehic3",
+ "ahb1_otg_ohci0", "ahb2_ohic1",
+ "ahb2_ohic2", "ahb2_ohic3", "ahb1_ve",
+ "ahb1_lcd0", "ahb1_lcd1", "ahb1_deint",
+ "ahb1_csi", "ahb1_tve", "ahb1_hdmi",
+ "ahb1_de", "ahb1_gpu", "ahb1_msgbox",
+ "ahb1_spinlock", "apb1_codec",
+ "apb1_spdif", "apb1_pio", "apb1_ths",
+ "apb1_i2s0", "apb1_i2s1", "apb1_i2s2",
+ "apb2_i2c0", "apb2_i2c1", "apb2_i2c2",
+ "apb2_uart0", "apb2_uart1",
+ "apb2_uart2", "apb2_uart3", "apb2_scr",
+ "ahb1_ephy", "ahb1_dbg";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 0>, <&pll8 0>;
+ clock-output-names = "mmc0",
+ "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@01c2008c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 0>, <&pll8 0>;
+ clock-output-names = "mmc1",
+ "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@01c20090 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 0>, <&pll8 0>;
+ clock-output-names = "mmc2",
+ "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mbus_clk: clk@01c2015c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-mbus-clk";
+ reg = <0x01c2015c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5>;
+ clock-output-names = "mbus";
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun8i-h3-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bus_gates 6>;
+ resets = <&bus_rst 6>;
+ #dma-cells = <1>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&bus_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&bus_rst 8>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&bus_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&bus_rst 9>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&bus_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&bus_rst 10>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun8i-h3-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bus_gates 69>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PA4", "PA5";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0", "PF1", "PF2", "PF3",
+ "PF4", "PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin: mmc0_cd_pin@0 {
+ allwinner,pins = "PF6";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc1_pins_a: mmc1@0 {
+ allwinner,pins = "PG0", "PG1", "PG2", "PG3",
+ "PG4", "PG5";
+ allwinner,function = "mmc1";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ bus_rst: reset@01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun8i-h3-bus-reset";
+ reg = <0x01c202c0 0x1c>;
+ };
+
+ timer@01c20c00 {
+ compatible = "allwinner,sun4i-a10-timer";
+ reg = <0x01c20c00 0xa0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
+ wdt0: watchdog@01c20ca0 {
+ compatible = "allwinner,sun6i-a31-wdt";
+ reg = <0x01c20ca0 0x20>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ uart0: serial@01c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&bus_gates 112>;
+ resets = <&bus_rst 144>;
+ dmas = <&dma 6>, <&dma 6>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart1: serial@01c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&bus_gates 113>;
+ resets = <&bus_rst 145>;
+ dmas = <&dma 7>, <&dma 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart2: serial@01c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&bus_gates 114>;
+ resets = <&bus_rst 146>;
+ dmas = <&dma 8>, <&dma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&bus_gates 115>;
+ resets = <&bus_rst 147>;
+ dmas = <&dma 9>, <&dma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@01c81000 {
+ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x1000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ rtc: rtc@01f00000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x01f00000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+};
--
2.6.2

Jens Kuske

unread,
Oct 27, 2015, 12:50:51 PM10/27/15
to Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Jens Kuske
The Orange Pi Plus is a SBC based on the Allwinner H3 SoC
with 8GB eMMC, multiple USB ports through a USB hub chip, SATA through
a USB-SATA bridge, one uSD slot, a 10/100/1000M ethernet port,
WiFi, HDMI, headphone jack, IR receiver, a microphone, a CSI connector
and a 40-pin GPIO header.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 77 ++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 78ade1a..476658d 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -645,7 +645,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-a33-ga10h-v1.1.dtb \
sun8i-a33-ippo-q8h-v1.2.dtb \
sun8i-a33-q8-tablet.dtb \
- sun8i-a33-sinlinx-sina33.dtb
+ sun8i-a33-sinlinx-sina33.dtb \
+ sun8i-h3-orangepi-plus.dtb
dtb-$(CONFIG_MACH_SUN9I) += \
sun9i-a80-optimus.dtb \
sun9i-a80-cubieboard4.dtb
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
new file mode 100644
index 0000000..e67df59
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
@@ -0,0 +1,77 @@
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Xunlong Orange Pi Plus";
+ compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ cd-inverted;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
--
2.6.2

Jean-Francois Moine

unread,
Oct 27, 2015, 2:04:10 PM10/27/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com, linux-ar...@lists.infradead.org
On Tue, 27 Oct 2015 17:50:20 +0100
Jens Kuske <jens...@gmail.com> wrote:

> Changes since v3:
> - add a clock driver specific to the bus gates instead of listing parents in
> the DTSI
> - skip the holes in the reset controller with of_xlate()

Hi, Maxime, there we are :(. The H3 description is hardcoded and the
next SoCs will ask for more and more code. I wonder what is the use of
a DT...

Peter Korsgaard

unread,
Oct 27, 2015, 3:24:26 PM10/27/15
to Hans de Goede, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net
>>>>> "Hans" == Hans de Goede <hdeg...@redhat.com> writes:

Hi,

> 2) I see no pmic code in there. I know these boards do not use an axp pmic,
> but according to my info at least the Orange Pi 2 (which I have) uses a
> sy8106a pmic, it is not entirely clear to me yet if this one needs any
> init though, I've mailed the Orange Pi people about this.

Did you hear back from them? I haven't been able to find any datasheet
describing the i2c interface, but the orange pi pc schematics has a note
that Vout is defined by the Ru1 / Ru2 resistors, so it sounds like i2c
configuration isn't critical to get something running.

--
Bye, Peter Korsgaard

Mihail Tommonen

unread,
Oct 27, 2015, 5:34:06 PM10/27/15
to linux-sunxi, hdeg...@redhat.com, jens...@gmail.com, maxime...@free-electrons.com, we...@csie.org, linus....@linaro.org, rob...@kernel.org, p.z...@pengutronix.de, emi...@elopez.com.ar, vishnupa...@gmail.com, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, rei...@mveas.com, zhao_...@263.net, pe...@korsgaard.com
I have a feeling that sy8106a could be related to Silergy other pmics. Maybe something custom made, with special voltage, i2c address etc.


-Miskab

Julian Calaby

unread,
Oct 27, 2015, 7:12:34 PM10/27/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, Mailing List, Arm, linux-...@vger.kernel.org, linux-sunxi
Hi Jens,
A way to make this reusable in the future might be to encode it in a
structure like:

static const struct bus_clock_paths sun8i_h3_bus_clock_paths __initdata = {
{.parent = 2, .min = 17, .max = 17}, /* index 17 is from AHB2 */
{.parent = 2, .min = 29, .max = 31}, /* AHB2 bank */
{.parent = 1, .min = 63, .max = 128}, /* AHB1 bank */
...
{}
};

Then the code here can be reused for other clocks like this in the
future without too much bloat. (And this would potentially could be
generic enough for other platforms.)

zhao_steven

unread,
Oct 28, 2015, 5:51:43 AM10/28/15
to Peter Korsgaard, Hans de Goede, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Linus Walleij, Rob Herring, Philipp Zabel, EmilioLópez, Vishnu Patekar, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi, Reinder E.N. de Haan
Dear all,
     SY8106 datasheet. 

steven
SY8106A_datasheet.pdf

Philipp Zabel

unread,
Oct 28, 2015, 7:42:52 AM10/28/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi Jens,

Am Dienstag, den 27.10.2015, 17:50 +0100 schrieb Jens Kuske:
[...]
> --- a/drivers/reset/reset-sunxi.c
> +++ b/drivers/reset/reset-sunxi.c
> @@ -75,7 +75,9 @@ static struct reset_control_ops sunxi_reset_ops = {
> .deassert = sunxi_reset_deassert,
> };
>
> -static int sunxi_reset_init(struct device_node *np)
> +static int sunxi_reset_init(struct device_node *np,
> + int (*of_xlate)(struct reset_controller_dev *rcdev,
> + const struct of_phandle_args *reset_spec))

I'd add a tab to the indentation and drop the of_xlate parameter names.
If you agree to this change, I'll fix it up when I apply it.

best regards
Philipp

Chen-Yu Tsai

unread,
Oct 30, 2015, 3:33:30 AM10/30/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Hi,
What's the extra "pll6d2"? If you have an extra output, it's not compatible with
"allwinner,sun6i-a31-pll6-clk".
And this would be wrong if you don't update the pll6 compatible or driver.
There's no output on n = 2.

You could also chain a fixed divider directly in the driver.
ahb1_ehci1? Same for the following 3 lines.

> + "ahb1_ehic2", "ahb1_ehic3",
> + "ahb1_otg_ohci0", "ahb2_ohic1",
> + "ahb2_ohic2", "ahb2_ohic3", "ahb1_ve",
> + "ahb1_lcd0", "ahb1_lcd1", "ahb1_deint",
> + "ahb1_csi", "ahb1_tve", "ahb1_hdmi",
> + "ahb1_de", "ahb1_gpu", "ahb1_msgbox",
> + "ahb1_spinlock", "apb1_codec",
> + "apb1_spdif", "apb1_pio", "apb1_ths",
> + "apb1_i2s0", "apb1_i2s1", "apb1_i2s2",
> + "apb2_i2c0", "apb2_i2c1", "apb2_i2c2",
> + "apb2_uart0", "apb2_uart1",
> + "apb2_uart2", "apb2_uart3", "apb2_scr",
> + "ahb1_ephy", "ahb1_dbg";

If it weren't for the last 2 clocks, we could cleanly split out apb1 and apb2
gates. Having a separate AHB clock gate taking 2 addresses seems messy
as well. :(
This should be in the board DTS, unless this is the reference design,
in which case you should name the label like "mmc0_cd_pin_reference_design".
Aren't you handling the holes in the bus_rst driver? If so,
isn't it supposed to align both bus_gates and bus_rst indexes?

Same for the other UARTs.

Thanks

Regards
ChenYu

Chen-Yu Tsai

unread,
Oct 30, 2015, 3:46:53 AM10/30/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
On Wed, Oct 28, 2015 at 12:50 AM, Jens Kuske <jens...@gmail.com> wrote:
> Currently, the sunxi clock driver gets the name for the base factor clock
> of divs clocks from the name field in factors_data. This prevents reusing
> of the factor clock for clocks with same properties, but different name.
>
> This commit makes the divs setup function try to get a name from
> clock-output-names in the devicetree. It also removes the name field where
> possible and merges the sun4i PLL5 and PLL6 clocks.

This patch actually removes all static declarations of the name field,
which is a good thing!
This actually only works for the sun4i divs clocks. sun6i-a31-pll6 uses a
different naming convention. sun4i-a10-pll2 uses yet another, though that's
not a divs clock. Maybe we should work on unifying them. Maxime?

Other than these 2 bits of information, this patch looks good.


Regards
ChenYu

Chen-Yu Tsai

unread,
Oct 30, 2015, 4:08:51 AM10/30/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Hi,

On Wed, Oct 28, 2015 at 12:50 AM, Jens Kuske <jens...@gmail.com> wrote:
<snip>

> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXD3 */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXD2 */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXD1 */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXD0 */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXCK */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXCTL/RCDV */

RXDV?

> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* RXERR */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* TXD3 */
> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* TXD2L */

Trailing "L" there.

> + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "emac")), /* TXD1 */

<snip>

> + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
> + SUNXI_FUNCTION(0x0, "gpio_in"),
> + SUNXI_FUNCTION(0x1, "gpio_out"),
> + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
> + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PG_EINT0 */

Datasheet say EINT is function 0x6. Same for all the other pins in group G.
The rest looks good. Thanks!


Regards
ChenYu

Arnd Bergmann

unread,
Oct 30, 2015, 4:27:19 AM10/30/15
to linux-ar...@lists.infradead.org, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
On Tuesday 27 October 2015 17:50:24 Jens Kuske wrote:
>
> +static int sun8i_h3_bus_reset_xlate(struct reset_controller_dev *rcdev,
> + const struct of_phandle_args *reset_spec)
> +{
> + unsigned int index = reset_spec->args[0];
> +
> + if (index < 96)
> + return index;
> + else if (index < 128)
> + return index + 32;
> + else if (index < 160)
> + return index + 64;
> + else
> + return -EINVAL;
> +}
> +
>

This looks like you are doing something wrong and should either
put the actual number into DT, or use a two-cell representation,
with the first cell indicating the block (0, 1 or 2), and the
second cell the index.

Arnd

Arnd Bergmann

unread,
Oct 30, 2015, 4:29:06 AM10/30/15
to linux-ar...@lists.infradead.org, Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
On Tuesday 27 October 2015 17:50:22 Jens Kuske wrote:
> + of_property_read_string_index(node, "clock-output-names",
> + i, &clk_name);
> +
> + if (index == 17 || (index >= 29 && index <= 31))
> + clk_parent = AHB2;
> + else if (index <= 63 || index >= 128)
> + clk_parent = AHB1;
> + else if (index >= 64 && index <= 95)
> + clk_parent = APB1;
> + else if (index >= 96 && index <= 127)
> + clk_parent = APB2;
> +
> + clk_reg = reg + 4 * (index / 32);
>

Same as for the reset driver, this probably means you should have one
cell to indicate which bus it is for, and another cell for the
index.

Arnd

Jean-Francois Moine

unread,
Oct 30, 2015, 6:34:48 AM10/30/15
to Jens Kuske, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com, linux-ar...@lists.infradead.org
On Tue, 27 Oct 2015 17:50:25 +0100
Jens Kuske <jens...@gmail.com> wrote:

> The Allwinner H3 is a home entertainment system oriented SoC with
> four Cortex-A7 cores and a Mali-400MP2 GPU.
>
> Signed-off-by: Jens Kuske <jens...@gmail.com>
> ---
> arch/arm/boot/dts/sun8i-h3.dtsi | 482 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 482 insertions(+)
> create mode 100644 arch/arm/boot/dts/sun8i-h3.dtsi
>
> diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> new file mode 100644
> index 0000000..c18b5f7
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
[snip]
> + soc {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + dma: dma-controller@01c02000 {
> + compatible = "allwinner,sun8i-h3-dma";
> + reg = <0x01c02000 0x1000>;
> + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&bus_gates 6>;
> + resets = <&bus_rst 6>;
> + #dma-cells = <1>;
> + };
[snip]
> +
> + bus_rst: reset@01c202c0 {
> + #reset-cells = <1>;
> + compatible = "allwinner,sun8i-h3-bus-reset";
> + reg = <0x01c202c0 0x1c>;
> + };
> +
[snip]
> + uart0: serial@01c28000 {
> + compatible = "snps,dw-apb-uart";
> + reg = <0x01c28000 0x400>;
> + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> + reg-shift = <2>;
> + reg-io-width = <4>;
> + clocks = <&bus_gates 112>;
> + resets = <&bus_rst 144>;
> + dmas = <&dma 6>, <&dma 6>;
> + dma-names = "rx", "tx";
> + status = "disabled";
> + };

The reset definitions would be clearer with declarations as the other
Allwinner SoCs and without driver hack:

soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;

dma: dma-controller@01c02000 {
compatible = "allwinner,sun8i-h3-dma";
reg = <0x01c02000 0x1000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bus_gates 6>;
resets = <&rst_reg0 6>;
#dma-cells = <1>;
};
...
rst_reg0: reset@01c202c0 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x01c202c0 0x04>;
};
...
rst_reg4: reset@01c202d8 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x01c202d8 0x04>;
};
...
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&bus_gates 112>;
resets = <&rst_reg4 16>;
dmas = <&dma 6>, <&dma 6>;
dma-names = "rx", "tx";
status = "disabled";
};

Maxime Ripard

unread,
Nov 1, 2015, 4:46:14 AM11/1/15
to Chen-Yu Tsai, Jens Kuske, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Hi,

On Fri, Oct 30, 2015 at 03:33:05PM +0800, Chen-Yu Tsai wrote:
> > + pll6: clk@01c20028 {
> > + #clock-cells = <1>;
> > + compatible = "allwinner,sun6i-a31-pll6-clk";
> > + reg = <0x01c20028 0x4>;
> > + clocks = <&osc24M>;
> > + clock-output-names = "pll6", "pll6x2", "pll6d2";
>
> What's the extra "pll6d2"? If you have an extra output, it's not compatible with
> "allwinner,sun6i-a31-pll6-clk".

[...]

> > +
> > + ahb2: ahb2_clk@01c2005c {
> > + #clock-cells = <0>;
> > + compatible = "allwinner,sun8i-h3-ahb2-clk";
> > + reg = <0x01c2005c 0x4>;
> > + clocks = <&ahb1>, <&pll6 2>;
>
> And this would be wrong if you don't update the pll6 compatible or driver.
> There's no output on n = 2.
>
> You could also chain a fixed divider directly in the driver.

Or in the DT directly.

I'd really like to move away from the various fixed dividers output
that prevents to reuse the clock drivers when it's the only
difference, like what's done here.
Not really, the last reset registers don't have the same organization
than the bus clocks :/

Maxime

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

Maxime Ripard

unread,
Nov 1, 2015, 4:49:07 AM11/1/15
to Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,
Having the bus clocks called bus_* would make more sense I guess, or
at least it would match the datasheet names (as obscure as they are).

Thanks!
signature.asc

Jens Kuske

unread,
Nov 1, 2015, 8:40:43 AM11/1/15
to Arnd Bergmann, linux-ar...@lists.infradead.org, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
Hi,
This is what Maxime suggested in an earlier version:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/344213.html

In between I had another version with the parents in DT, but he
didn't like that too.

Jens

Jens Kuske

unread,
Nov 1, 2015, 8:40:49 AM11/1/15
to Chen-Yu Tsai, Maxime Ripard, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
On 30/10/15 08:46, Chen-Yu Tsai wrote:
> On Wed, Oct 28, 2015 at 12:50 AM, Jens Kuske <jens...@gmail.com> wrote:
[..]
>> @@ -991,8 +985,30 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
>> if (data->ndivs)
>> ndivs = data->ndivs;
>>
>> + /* Try to find a name for base factor clock */
>> + for (i = 0; i < ndivs; i++) {
>> + if (data->div[i].self) {
>> + of_property_read_string_index(node, "clock-output-names",
>> + i, &factors.name);
>> + break;
>> + }
>> + }
>> + /* If we don't have a .self clk use the first output-name up to '_' */
>
> This actually only works for the sun4i divs clocks. sun6i-a31-pll6 uses a
> different naming convention. sun4i-a10-pll2 uses yet another, though that's
> not a divs clock. Maybe we should work on unifying them. Maxime?

All the divs clocks I could find either have a .self (handled by the
first case above) or follow this naming convention, so it should work.
But if we find a better way to clean up the divs without breaking
devicetree bindings (as far as I understood we must not break them, am I
right there?) I'd be happy with that too.

Jens

Jens Kuske

unread,
Nov 1, 2015, 8:40:53 AM11/1/15
to Arnd Bergmann, linux-ar...@lists.infradead.org, Maxime Ripard, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
Hi,
I tried to fix up the somewhat strange register layout here.

>From the datasheet:
BUS_SOFT_RST_REG0 0x02C0 Bus Software Reset Register 0
BUS_SOFT_RST_REG1 0x02C4 Bus Software Reset Register 1
BUS_SOFT_RST_REG2 0x02C8 Bus Software Reset Register 2
BUS_SOFT_RST_REG3 0x02D0 Bus Software Reset Register 3
BUS_SOFT_RST_REG4 0x02D8 Bus Software Reset Register 4

0x2cc and 0x2d4 are unused for some reason, but the regs are named 0-4,
so it lead to some confusion with the actual numbers in DT.
If we shouldn't do this I would be ok with putting the actual number
into DT too.

Jens

Jens Kuske

unread,
Nov 1, 2015, 8:40:53 AM11/1/15
to Chen-Yu Tsai, Maxime Ripard, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Thanks. I had checked the whole list at least three times, but one
always overlooks something it seems.

Jens Kuske

unread,
Nov 1, 2015, 8:40:56 AM11/1/15
to Chen-Yu Tsai, Maxime Ripard, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Hi,
I'll fix them...
>
>> + "ahb1_ehic2", "ahb1_ehic3",
>> + "ahb1_otg_ohci0", "ahb2_ohic1",
>> + "ahb2_ohic2", "ahb2_ohic3", "ahb1_ve",
>> + "ahb1_lcd0", "ahb1_lcd1", "ahb1_deint",
>> + "ahb1_csi", "ahb1_tve", "ahb1_hdmi",
>> + "ahb1_de", "ahb1_gpu", "ahb1_msgbox",
>> + "ahb1_spinlock", "apb1_codec",
>> + "apb1_spdif", "apb1_pio", "apb1_ths",
>> + "apb1_i2s0", "apb1_i2s1", "apb1_i2s2",
>> + "apb2_i2c0", "apb2_i2c1", "apb2_i2c2",
>> + "apb2_uart0", "apb2_uart1",
>> + "apb2_uart2", "apb2_uart3", "apb2_scr",
>> + "ahb1_ephy", "ahb1_dbg";
>
> If it weren't for the last 2 clocks, we could cleanly split out apb1 and apb2
> gates. Having a separate AHB clock gate taking 2 addresses seems messy
> as well. :(

Well, maybe we still should do that, if we split the resets too at least
apb[12] would line up again.

I don't know what to do with these bus things any more, all variants I
sent had issues somewhere...
The datasheet mentions SDC0_DET function on PF6, so I thought this is
sort of fixed to this pin now. All designs I've seen use this pin.

Jens

Chen-Yu Tsai

unread,
Nov 1, 2015, 10:26:11 AM11/1/15
to Jens Kuske, Chen-Yu Tsai, Maxime Ripard, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
As someone who's done this a few times, I can say that it all starts
to look the same after a few rounds. :)

ChenYu

Maxime Ripard

unread,
Nov 1, 2015, 1:36:11 PM11/1/15
to Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
On Tue, Oct 27, 2015 at 05:50:25PM +0100, Jens Kuske wrote:
> + timer {
> + compatible = "arm,armv7-timer";
> + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> + clock-frequency = <24000000>;
> + arm,cpu-registers-not-fw-configured;
> + };
> +
> + memory {
> + reg = <0x40000000 0x80000000>;
> + };

What's the u-boot support like these days?

If it's ready, or at least some patches have been sent, you shouldn't
set both the memory node (that will be overriden anyway) and the
clock-frequency and arm,cpu-registers-not-fw-configured properties in
the timer node, that will prevent the kernel from booting there.
signature.asc

Maxime Ripard

unread,
Nov 4, 2015, 11:24:03 AM11/4/15
to Julian Calaby, Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, Mailing List, Arm, linux-...@vger.kernel.org, linux-sunxi
Hi Julian,

On Wed, Oct 28, 2015 at 10:12:09AM +1100, Julian Calaby wrote:
> > + of_property_for_each_u32(node, "clock-indices", prop, p, index) {
> > + of_property_read_string_index(node, "clock-output-names",
> > + i, &clk_name);
> > +
> > + if (index == 17 || (index >= 29 && index <= 31))
> > + clk_parent = AHB2;
> > + else if (index <= 63 || index >= 128)
> > + clk_parent = AHB1;
> > + else if (index >= 64 && index <= 95)
> > + clk_parent = APB1;
> > + else if (index >= 96 && index <= 127)
> > + clk_parent = APB2;
>
> A way to make this reusable in the future might be to encode it in a
> structure like:
>
> static const struct bus_clock_paths sun8i_h3_bus_clock_paths __initdata = {
> {.parent = 2, .min = 17, .max = 17}, /* index 17 is from AHB2 */
> {.parent = 2, .min = 29, .max = 31}, /* AHB2 bank */
> {.parent = 1, .min = 63, .max = 128}, /* AHB1 bank */
> ...
> {}
> };
>
> Then the code here can be reused for other clocks like this in the
> future without too much bloat. (And this would potentially could be
> generic enough for other platforms.)

We don't really need that at the moment. There's not point in writing
more complicated code to support a use case we don't have yet.

(However, something along these lines will definitely be needed if we
ever have another SoC having the same bus gates madness)
signature.asc

Maxime Ripard

unread,
Nov 4, 2015, 11:25:29 AM11/4/15
to Arnd Bergmann, linux-ar...@lists.infradead.org, Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
Hi Arnd,
It's not really comparable to the reset driver.

What's happening here is that we have a single set of (contiguous)
registers, controlling gates from different parents.
signature.asc

Maxime Ripard

unread,
Nov 4, 2015, 12:19:43 PM11/4/15
to Arnd Bergmann, linux-ar...@lists.infradead.org, Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, devic...@vger.kernel.org, Vishnu Patekar, linux-...@vger.kernel.org, Hans de Goede, linux...@googlegroups.com
Hi Arnd,

On Fri, Oct 30, 2015 at 09:27:03AM +0100, Arnd Bergmann wrote:
> On Tuesday 27 October 2015 17:50:24 Jens Kuske wrote:
> >
> > +static int sun8i_h3_bus_reset_xlate(struct reset_controller_dev *rcdev,
> > + const struct of_phandle_args *reset_spec)
> > +{
> > + unsigned int index = reset_spec->args[0];
> > +
> > + if (index < 96)
> > + return index;
> > + else if (index < 128)
> > + return index + 32;
> > + else if (index < 160)
> > + return index + 64;
> > + else
> > + return -EINVAL;
> > +}
> > +
> >
>
> This looks like you are doing something wrong and should either
> put the actual number into DT,

This is the actual number, except that there's some useless registers
in between. Allwinner documents it like that:

0x0 Reset 0
0x4 Reset 1
0xc Reset 2

So we have to adjust the offset to account with the blank register in
between (0x8).

> or use a two-cell representation, with the first cell indicating the
> block (0, 1 or 2), and the second cell the index.

And the missing register is not a block either.

That would also imply either changing the bindings of that driver (and
all the current DTS that are using it), or introducing a whole new
driver just to deal with some extraordinary offset calculation.
signature.asc

Julian Calaby

unread,
Nov 4, 2015, 5:18:09 PM11/4/15
to Maxime Ripard, Jens Kuske, Chen-Yu Tsai, Michael Turquette, Linus Walleij, Rob Herring, Philipp Zabel, Emilio López, Vishnu Patekar, Hans de Goede, devicetree, Mailing List, Arm, linux-...@vger.kernel.org, linux-sunxi
Hi Maxime,
This was a suggestion for the future to address Jens' comment about
having a bus clock driver instead of encoding it in devicetree.

Jean-Francois Moine

unread,
Nov 5, 2015, 1:47:37 AM11/5/15
to Maxime Ripard, Arnd Bergmann, devic...@vger.kernel.org, Vishnu Patekar, Emilio López, Michael Turquette, linux...@googlegroups.com, linux-...@vger.kernel.org, Hans de Goede, Chen-Yu Tsai, Rob Herring, Jens Kuske, Philipp Zabel, Linus Walleij, linux-ar...@lists.infradead.org
In the H3, the holes are not used, but what would occur if these holes
would be used for some other purpose in future SoCs? Double mapping?

Siarhei Siamashka

unread,
Nov 10, 2015, 10:40:30 PM11/10/15
to jens...@gmail.com, Hans de Goede, Maxime Ripard, Chen-Yu Tsai, Emilio López, Vishnu Patekar, linux...@googlegroups.com, Reinder E.N. de Haan, zhao_...@263.net
On Thu, 22 Oct 2015 13:52:38 +0200
Jens Kuske <jens...@gmail.com> wrote:

>
> On 22/10/15 10:49, Hans de Goede wrote:
> > Hi,
> >
> > On 22-10-15 09:49, Jens Kuske wrote:
> [..]
> >>
> >> I don't plan to work on USB soon, my next step would have been Ethernet
> >> and finishing the basic u-boot support. You know my u-boot H3 wip tree I
> >> hope? Before we duplicate our work there too...
> >> https://github.com/jemk/u-boot-sunxi/tree/sunxi/h3
> >
> > I was not aware of that work, at a first glance it looks good. Can you rebase
> > this on top of current u-boot/master (or v2015.10) and then submit it upstream ?
>
> I will, after fixing some more things (like your question 2).

FYI, this branch works mostly OK on my freshly bought Orange Pi PC
board. I only had to reduce the DRAM clock speed from 672MHz to 480MHz
to prevent the kernel from oopsing.

But when the DRAM is initialized by boot0, 672MHz seems to work without
obviously visible problems.

I will try to debug this problem and compare the configuration in the
DRAM controller hardware registers. The FEX files seem to imply that
the DRAM settings should be the same on all H3 based Orange boards,
but there might be still some deliberate difference in the configuration
or a subtle bug in your code.

> > 2 questions which come to mind immediately:
> >
> > 1) Where does the dram init logic come from, AFAIK Allwinner has not provided
> > any H3 dram init code ?
>
> It's from the Draco H3 TV Stick SDK:
>
> http://www.cnx-software.com/2015/06/14/tronsmart-draco-h3-tv-stick-firmware-and-sdk-released/

Could you please provide a bit more details about the location of this
code? I tried to downl