[PATCH v2 00/10] ARM: sunxi: Introduce Allwinner H3 support

237 views
Skip to first unread message

Jens Kuske

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

This is v2 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


The first four patches are documentation updates and generic changes to the
sunxi clock and pinctrl drivers, preparing them for the H3 addition.

Patch 1 updates the sunxi README with new SoCs, including the H3

Patch 2 adds support for multiple parents to the sunxi gates clock, needed
for the new bus gates in H3

Patch 3 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 4 prepares the sunxi pinctrl driver for building the SoC specific parts
as modules. This is later used for the H3 pinctrl driver. I believe the other
sunxi SoCs could or should be changed to tristate too, but that's independend
from this series and I wouldn't be able to test them anyway.

The remaining patches add H3 support.

Patch 5 adds machine support for the H3.

Patch 6 adds support for the basic clocks.

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

Patch 8 adds a new compatible for the H3 reset controller

Patch 9 adds the DTSI for the H3.

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


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 (10):
Documentation: sunxi: Update Allwinner SoC documentation
clk: sunxi: Add support for multiple parents to gates
clk: sunxi: Let divs clocks read the base factor clock name from
devicetree
pinctrl: sunxi: Prepare for building SoC specific drivers as modules
ARM: sunxi: Introduce Allwinner H3 support
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/arm/sunxi/README | 18 +-
Documentation/devicetree/bindings/arm/sunxi.txt | 1 +
Documentation/devicetree/bindings/clock/sunxi.txt | 6 +
.../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 | 446 ++++++++++++++++++
arch/arm/mach-sunxi/Kconfig | 2 +-
arch/arm/mach-sunxi/sunxi.c | 4 +-
drivers/clk/sunxi/clk-sunxi.c | 84 +++-
drivers/pinctrl/sunxi/Kconfig | 8 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 522 +++++++++++++++++++++
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 25 +-
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 +
drivers/reset/reset-sunxi.c | 1 +
17 files changed, 1180 insertions(+), 22 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/pinctrl/sunxi/pinctrl-sun8i-h3.c

--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:11 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
There are some new Allwinner SoCs available, namely A33, A83T and H3.
Update the documentation to mention those and the related documents.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
Documentation/arm/sunxi/README | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
index 1fe2d7f..5e38e15 100644
--- a/Documentation/arm/sunxi/README
+++ b/Documentation/arm/sunxi/README
@@ -36,7 +36,7 @@ SunXi family
+ User Manual
http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf

- - Allwinner A23
+ - Allwinner A23 (sun8i)
+ Datasheet
http://dl.linux-sunxi.org/A23/A23%20Datasheet%20V1.0%2020130830.pdf
+ User Manual
@@ -55,7 +55,23 @@ SunXi family
+ User Manual
http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20User%20Manual%20%20V1.0%2020130322.pdf

+ - Allwinner A33 (sun8i)
+ + Datasheet
+ http://dl.linux-sunxi.org/A33/A33%20Datasheet%20release%201.1.pdf
+ + User Manual
+ http://dl.linux-sunxi.org/A33/A33%20user%20manual%20release%201.1.pdf
+
+ - Allwinner H3 (sun8i)
+ + Datasheet
+ http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
+
* Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs
- Allwinner A80
+ Datasheet
http://dl.linux-sunxi.org/A80/A80_Datasheet_Revision_1.0_0404.pdf
+
+ * Octa ARM Cortex-A7 based SoCs
+ - Allwinner A83T
+ + Not Supported
+ + Datasheet
+ http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf
--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:13 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Some newer sunxi SoCs (A83T, H3) don't have individual registers for
AHB1, APB1 and APB2 gates anymore, but one big bus gates area where each
gate can have a different parent.

The current clock driver sets the same parent for all gates in a group.
This commit adds a new parents field to the gates_data structure, which
allows us to specify an array of parent indices for every single gate.

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

diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 9a82f17..17cba4d 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -898,6 +898,8 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,

struct gates_data {
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
+ /* If used, ARRAY_SIZE(parents) has to be >= bitmap_weight(mask) */
+ const u8 *parents;
};

static const struct gates_data sun4i_axi_gates_data __initconst = {
@@ -1000,16 +1002,21 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
struct gates_data *data)
{
struct clk_onecell_data *clk_data;
+ const char *parents[SUNXI_MAX_PARENTS];
const char *clk_parent;
const char *clk_name;
void __iomem *reg;
+ int npar = 0;
int qty;
int i = 0;
int j = 0;

reg = of_iomap(node, 0);

- clk_parent = of_clk_get_parent_name(node, 0);
+ while (npar < SUNXI_MAX_PARENTS &&
+ (parents[npar] = of_clk_get_parent_name(node, npar)) != NULL)
+ npar++;
+ clk_parent = parents[0];

/* Worst-case size approximation and memory allocation */
qty = find_last_bit(data->mask, SUNXI_GATES_MAX_SIZE);
@@ -1026,6 +1033,9 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
of_property_read_string_index(node, "clock-output-names",
j, &clk_name);

+ if (data->parents && !WARN_ON(data->parents[j] >= npar))
+ clk_parent = parents[data->parents[j]];
+
clk_data->clks[i] = clk_register_gate(NULL, clk_name,
clk_parent, 0,
reg + 4 * (i/32), i % 32,
--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:14 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
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.

The sun4i PLL5 clock doesn't have a output for the base factor clock,
so we still have to use the name field there.

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

diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 17cba4d..afe560c 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -708,18 +708,10 @@ static const struct factors_data sun4i_pll5_data __initconst = {
.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 = {
@@ -1099,7 +1091,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 */
@@ -1141,6 +1133,7 @@ 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;
void __iomem *reg;
int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
int flags, clkflags;
@@ -1149,8 +1142,17 @@ 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;
+ }
+ }
+
/* 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.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:15 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Add a remove function and export the init and remove function
to allow us to build the SoC specific drivers as modules.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 25 +++++++++++++++++++------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 ++
2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index f8e171b..4ef6b3d 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -856,7 +856,6 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
struct sunxi_pinctrl *pctl;
struct resource *res;
int i, ret, last_pin;
- struct clk *clk;

pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
@@ -954,13 +953,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
goto gpiochip_error;
}

- clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
+ pctl->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pctl->clk)) {
+ ret = PTR_ERR(pctl->clk);
goto gpiochip_error;
}

- ret = clk_prepare_enable(clk);
+ ret = clk_prepare_enable(pctl->clk);
if (ret)
goto gpiochip_error;

@@ -1015,10 +1014,24 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
return 0;

clk_error:
- clk_disable_unprepare(clk);
+ clk_disable_unprepare(pctl->clk);
gpiochip_error:
gpiochip_remove(pctl->chip);
pinctrl_error:
pinctrl_unregister(pctl->pctl_dev);
return ret;
}
+EXPORT_SYMBOL(sunxi_pinctrl_init);
+
+int sunxi_pinctrl_remove(struct platform_device *pdev)
+{
+ struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
+
+ gpiochip_remove(pctl->chip);
+ pinctrl_unregister(pctl->pctl_dev);
+
+ clk_disable_unprepare(pctl->clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(sunxi_pinctrl_remove);
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index e248e81..4442676 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -126,6 +126,7 @@ struct sunxi_pinctrl {
unsigned *irq_array;
spinlock_t lock;
struct pinctrl_dev *pctl_dev;
+ struct clk *clk;
};

#define SUNXI_PIN(_pin, ...) \
@@ -285,5 +286,6 @@ static inline u32 sunxi_irq_status_offset(u16 irq)

int sunxi_pinctrl_init(struct platform_device *pdev,
const struct sunxi_pinctrl_desc *desc);
+int sunxi_pinctrl_remove(struct platform_device *pdev);

#endif /* __PINCTRL_SUNXI_H */
--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:17 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
The Allwinner H3 is a quad-core Cortex-A7-based SoC. It is very similar
to other sun8i family SoCs like the A23.

Signed-off-by: Jens Kuske <jens...@gmail.com>
---
Documentation/devicetree/bindings/arm/sunxi.txt | 1 +
arch/arm/mach-sunxi/Kconfig | 2 +-
arch/arm/mach-sunxi/sunxi.c | 4 +++-
3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt
index 42941fd..3cb4b94 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.txt
+++ b/Documentation/devicetree/bindings/arm/sunxi.txt
@@ -9,4 +9,5 @@ using one of the following compatible strings:
allwinner,sun6i-a31
allwinner,sun7i-a20
allwinner,sun8i-a23
+ allwinner,sun8i-h3
allwinner,sun9i-a80
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 81502b9..4efe2d4 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -35,7 +35,7 @@ config MACH_SUN7I
select SUN5I_HSTIMER

config MACH_SUN8I
- bool "Allwinner A23 (sun8i) SoCs support"
+ bool "Allwinner sun8i Family SoCs support"
default ARCH_SUNXI
select ARM_GIC
select MFD_SUN6I_PRCM
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 1bc811a..8270902 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -67,10 +67,12 @@ MACHINE_END

static const char * const sun8i_board_dt_compat[] = {
"allwinner,sun8i-a23",
+ "allwinner,sun8i-h3",
NULL,
};

-DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
+DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i Family")
+ .init_time = sun6i_timer_init,
.dt_compat = sun8i_board_dt_compat,
.init_late = sunxi_dt_cpufreq_init,
MACHINE_END
--
2.4.0

Jens Kuske

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

It makes use of the new multiple parents option for the bus gates.
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 | 6 +++
drivers/clk/sunxi/clk-sunxi.c | 50 ++++++++++++++++++++++-
2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 4fa11af..e367963 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -14,6 +14,7 @@ Required properties:
"allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock
"allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock
"allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
+ "allwinner,sun8i-h3-pll6-clk" - for the PLL6 clock on H3
"allwinner,sun9i-a80-gt-clk" - for the GT bus clock on A80
"allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock
"allwinner,sun4i-a10-axi-clk" - for the AXI clock
@@ -28,6 +29,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 +57,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
@@ -95,6 +98,9 @@ The "allwinner,sun9i-a80-mmc-config-clk" clock also requires:
For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
dummy clocks at 25 MHz and 125 MHz, respectively. See example.

+For "allwinner,sun8i-h3-bus-gates-clk", the parent clocks shall be
+AHB1, AHB2, APB1 and APB2, in that order.
+
Clock consumers should specify the desired clocks they use with a
"clocks" phandle cell. Consumers that are using a gated clock should
provide an additional ID in their clock property. This ID is the
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index afe560c..79364be 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -771,6 +771,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)
{
@@ -886,7 +890,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
* sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
*/

-#define SUNXI_GATES_MAX_SIZE 64
+#define SUNXI_GATES_MAX_SIZE 160

struct gates_data {
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
@@ -990,6 +994,36 @@ static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
.mask = {0x1F0007},
};

+#define BUS_GATE_PARENT_AHB1 0
+#define BUS_GATE_PARENT_AHB2 1
+#define BUS_GATE_PARENT_APB1 2
+#define BUS_GATE_PARENT_APB2 3
+
+static const u8 sun8i_h3_bus_gates_parents[] __initconst = {
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB2, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB2, BUS_GATE_PARENT_AHB2, BUS_GATE_PARENT_AHB2,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_AHB1, BUS_GATE_PARENT_APB1,
+ BUS_GATE_PARENT_APB1, BUS_GATE_PARENT_APB1, BUS_GATE_PARENT_APB1,
+ BUS_GATE_PARENT_APB1, BUS_GATE_PARENT_APB1, BUS_GATE_PARENT_APB1,
+ BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_APB2,
+ BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_APB2,
+ BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_APB2, BUS_GATE_PARENT_AHB1,
+ BUS_GATE_PARENT_AHB1
+};
+
+static const struct gates_data sun8i_h3_bus_gates_data __initconst = {
+ .mask = {0xffbe6760, 0x00701b39, 0x00007123, 0x001f0007, 0x00000081},
+ .parents = sun8i_h3_bus_gates_parents,
+};
+
static void __init sunxi_gates_clk_setup(struct device_node *node,
struct gates_data *data)
{
@@ -1110,6 +1144,16 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
}
};

+static const struct divs_data sun8i_h3_pll6_divs_data __initconst = {
+ .factors = &sun6i_a31_pll6_data,
+ .ndivs = 3,
+ .div = {
+ { .fixed = 2 }, /* normal output, pll6 */
+ { .self = 1 }, /* base factor clock, pll6 x2 */
+ { .fixed = 4 }, /* divided output, pll6 /2 */
+ }
+};
+
/**
* sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
*
@@ -1283,6 +1327,7 @@ static const struct of_device_id clk_divs_match[] __initconst = {
{.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,},
{.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,},
{.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,},
+ {.compatible = "allwinner,sun8i-h3-pll6-clk", .data = &sun8i_h3_pll6_divs_data,},
{}
};

@@ -1290,6 +1335,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,},
{}
};

@@ -1319,6 +1365,7 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
{.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
+ {.compatible = "allwinner,sun8i-h3-bus-gates-clk", .data = &sun8i_h3_bus_gates_data,},
{}
};

@@ -1403,6 +1450,7 @@ static void __init sun6i_init_clocks(struct device_node *node)
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_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks);

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

Jens Kuske

unread,
May 15, 2015, 12:39:20 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
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>
---
.../bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 1 +
drivers/pinctrl/sunxi/Kconfig | 8 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 522 +++++++++++++++++++++
4 files changed, 532 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 fdd8046..c46af8e 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -16,6 +16,7 @@ Required properties:
"allwinner,sun7i-a20-pinctrl"
"allwinner,sun8i-a23-pinctrl"
"allwinner,sun8i-a23-r-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 2eb893e..6c1cec5 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -43,6 +43,14 @@ config PINCTRL_SUN8I_A23_R
depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON

+config PINCTRL_SUN8I_H3
+ tristate "Allwinner H3 pinctrl driver"
+ default MACH_SUN8I
+ select PINCTRL_SUNXI_COMMON
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ main Port Controller (PIO) of the Allwinner H3 SoC.
+
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 b796d57..fd4a068 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -11,4 +11,5 @@ obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o
obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.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..d5ab91c
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
@@ -0,0 +1,522 @@
+/*
+ * 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", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_h3_pinctrl_match);
+
+static struct platform_driver sun8i_h3_pinctrl_driver = {
+ .probe = sun8i_h3_pinctrl_probe,
+ .remove = sunxi_pinctrl_remove,
+ .driver = {
+ .name = "sun8i-h3-pinctrl",
+ .of_match_table = sun8i_h3_pinctrl_match,
+ },
+};
+module_platform_driver(sun8i_h3_pinctrl_driver);
+
+MODULE_AUTHOR("Jens Kuske <jens...@gmail.com>");
+MODULE_DESCRIPTION("Allwinner H3 pinctrl driver");
+MODULE_LICENSE("GPL");
--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:21 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Adding a new compatible allows us to define SoC specific behaviour
if necessary, for example forcing a particular device out of reset
even if no driver is actually using it.

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

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..6f12b5c 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -124,6 +124,7 @@ 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", },
{ /* sentinel */ },
};

--
2.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:24 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
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 | 446 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 446 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..d541145
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -0,0 +1,446 @@
+/*
+ * 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";
+ };
+
+ pll6: clk@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-h3-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6", "pll6x2", "pll6d2";
+ };
+
+ pll8: clk@01c20044 {
+ #clock-cells = <0>;
+ 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-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";
+ };
+ };
+
+ soc@01c00000 {
+ 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";
+ };
+
+ 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";
+ };
+
+ 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";
+ };
+
+ 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;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ 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 208>;
+ 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 209>;
+ 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 210>;
+ 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 211>;
+ 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.4.0

Jens Kuske

unread,
May 15, 2015, 12:39:25 PM5/15/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Jens Kuske, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
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 31e1f41..c5a96a9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -571,7 +571,8 @@ dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-wexler-tab7200.dtb
dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-a23-ippo-q8h-v5.dtb \
- sun8i-a23-ippo-q8h-v1.2.dtb
+ sun8i-a23-ippo-q8h-v1.2.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.4.0

Chen-Yu Tsai

unread,
May 15, 2015, 10:10:15 PM5/15/15
to Jens Kuske, VishnuPatekar, Rob Herring, linux-...@vger.kernel.org, Mike Turquette, devic...@vger.kernel.org, Hans de Goede, Linus Walleij, Maxime Ripard, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Emilio López

Please excuse the bad formatting.
I'm at the airport without my laptop.

This will not work. All the static factors_data structs are const.
You should make a copy of it, maybe on the stack,
update the .name field, and pass that to sunxi_factors_clk_setup().

ChenYu

Paul Bolle

unread,
May 16, 2015, 11:32:32 AM5/16/15
to Jens Kuske, Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Just a nit: a license mismatch.

(I didn't bring this up in v1. Perhaps I should have.)

On Fri, 2015-05-15 at 18:38 +0200, Jens Kuske wrote:
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c

> + * 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.

This states the license is GPL v2.

> +MODULE_LICENSE("GPL");

According to include/linux/module.h this states the license is GPL v2 or
later. So I think that either the comment at the top of this file or the
ident used in the MODULE_LICENSE() macro needs to change.


Paul Bolle

Maxime Ripard

unread,
May 17, 2015, 8:55:03 AM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
On Fri, May 15, 2015 at 06:38:51PM +0200, Jens Kuske wrote:
> There are some new Allwinner SoCs available, namely A33, A83T and H3.
> Update the documentation to mention those and the related documents.
>
> Signed-off-by: Jens Kuske <jens...@gmail.com>

Applied, thanks!
Maxime

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

Maxime Ripard

unread,
May 17, 2015, 8:55:04 AM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi Jens,
I'm currently removing that code, so I was more expecting a new
standalone driver for that clock.
signature.asc

Maxime Ripard

unread,
May 17, 2015, 9:10:04 AM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
I'm not sure we should expect the factor clock to have a self factor.

what about taking the first output and taking the substring up to the
first "_" ?
signature.asc

Maxime Ripard

unread,
May 17, 2015, 3:00:07 PM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
We should also remove the domain and the interrupt mapping here.
signature.asc

Maxime Ripard

unread,
May 17, 2015, 3:00:08 PM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
On Fri, May 15, 2015 at 06:38:55PM +0200, Jens Kuske wrote:
> The Allwinner H3 is a quad-core Cortex-A7-based SoC. It is very similar
> to other sun8i family SoCs like the A23.
>
> Signed-off-by: Jens Kuske <jens...@gmail.com>

Applied, thanks!
signature.asc

Maxime Ripard

unread,
May 17, 2015, 3:00:16 PM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
PINCTRL_SUNXI_COMMON should probably be turned into a tristate as well
signature.asc

Maxime Ripard

unread,
May 17, 2015, 3:00:16 PM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
On Fri, May 15, 2015 at 06:38:58PM +0200, Jens Kuske wrote:
> Adding a new compatible allows us to define SoC specific behaviour
> if necessary, for example forcing a particular device out of reset
> even if no driver is actually using it.
>
> Signed-off-by: Jens Kuske <jens...@gmail.com>

This should have been sent to the reset framework maintainer.

Looks good otherwise.
signature.asc

Maxime Ripard

unread,
May 17, 2015, 3:00:16 PM5/17/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
I think something like this:

if (index < .. || index > ..)
clk_parent = "ahb1"
if (index == .. || index < ...)
clk_parent = "ahb2"
etc...

Would be both easier to maintain and to read.

> +
> +static const struct gates_data sun8i_h3_bus_gates_data __initconst = {
> + .mask = {0xffbe6760, 0x00701b39, 0x00007123, 0x001f0007, 0x00000081},
> + .parents = sun8i_h3_bus_gates_parents,
> +};
> +
> static void __init sunxi_gates_clk_setup(struct device_node *node,
> struct gates_data *data)
> {
> @@ -1110,6 +1144,16 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
> }
> };
>
> +static const struct divs_data sun8i_h3_pll6_divs_data __initconst = {
> + .factors = &sun6i_a31_pll6_data,
> + .ndivs = 3,
> + .div = {
> + { .fixed = 2 }, /* normal output, pll6 */
> + { .self = 1 }, /* base factor clock, pll6 x2 */
> + { .fixed = 4 }, /* divided output, pll6 /2 */
> + }
> +};

This is exactly the same clock as A31's PLL6, it shouldn't be declared
as a different one.
signature.asc

Jens Kuske

unread,
May 18, 2015, 6:06:59 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,
How do you want to replace that code? To me this looks like a good way
to set up all the different gates sunxi has.

Jens

Jens Kuske

unread,
May 18, 2015, 6:07:02 AM5/18/15
to Chen-Yu Tsai, VishnuPatekar, Rob Herring, linux-...@vger.kernel.org, Mike Turquette, devic...@vger.kernel.org, Hans de Goede, Linus Walleij, Maxime Ripard, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Emilio López
Hi,

On 05/16/15 04:10, Chen-Yu Tsai wrote:
> 2015年5月16日 上午12:39於 "Jens Kuske" <jens...@gmail.com>寫道:
[..]
>> @@ -1141,6 +1133,7 @@ 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;

Isn't this a copy?

>> void __iomem *reg;
>> int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
>> int flags, clkflags;
>> @@ -1149,8 +1142,17 @@ 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);
>
> Please excuse the bad formatting.
> I'm at the airport without my laptop.
>
> This will not work. All the static factors_data structs are const.
> You should make a copy of it, maybe on the stack,
> update the .name field, and pass that to sunxi_factors_clk_setup().
>

If I didn't miss anything, or misunderstood what you want to copy, this
should be working fine.

Jens

Jens Kuske

unread,
May 18, 2015, 6:07:03 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Maybe not, but in that case it would fall back to the name provided in
the factors_data struct, as it is the case for sun4i pll5.

> what about taking the first output and taking the substring up to the
> first "_" ?

That only works for the sun[457]i pll5 & pll6, for sun[68]i the base
clock name would have to be "pll6x2".

Jens

Jens Kuske

unread,
May 18, 2015, 6:07:05 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,
Ouch, I missed that. Only looked at the *_error: labels.

Apart from that, currently the kernel panics some seconds after removing
the pinctrl module because mmc wants to access a gpio. Can this be
prevented somehow? I think pinctrl must not be removed once other
devices use any pin-related things.

Jens

Jens Kuske

unread,
May 18, 2015, 6:07:06 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,
At least as long as there aren't too many disjunct groups.
But it would mean duplicate setup functions for each SoC (or something
like sun8i_h3_bus_gate_get_parent(int index))

But since you want to rework the gate setup anyway I think I'll wait
until then. Currently I can't see how this should look like.

>
>> +
>> +static const struct gates_data sun8i_h3_bus_gates_data __initconst = {
>> + .mask = {0xffbe6760, 0x00701b39, 0x00007123, 0x001f0007, 0x00000081},
>> + .parents = sun8i_h3_bus_gates_parents,
>> +};
>> +
>> static void __init sunxi_gates_clk_setup(struct device_node *node,
>> struct gates_data *data)
>> {
>> @@ -1110,6 +1144,16 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
>> }
>> };
>>
>> +static const struct divs_data sun8i_h3_pll6_divs_data __initconst = {
>> + .factors = &sun6i_a31_pll6_data,
>> + .ndivs = 3,
>> + .div = {
>> + { .fixed = 2 }, /* normal output, pll6 */
>> + { .self = 1 }, /* base factor clock, pll6 x2 */
>> + { .fixed = 4 }, /* divided output, pll6 /2 */
>> + }
>> +};
>
> This is exactly the same clock as A31's PLL6, it shouldn't be declared
> as a different one.

Um, sorry, but I can't see the /2 output at A31's pll6.

Or shall we add the /2 output to A31's PLL6 and simply ignore it on A31?
I don't think this is a good idea, what happens if we need to add an
additional output on A31 later.

Regards,
Jens

Jens Kuske

unread,
May 18, 2015, 6:07:09 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Hi,
Probably, as well as all the other SoC specific drivers. But I think
this should be a separate patch, its independent from this addition.

But given the remove-panic problems I mentioned earlier this whole
pinctrl-as-module topic needs some attention from more experienced devs
I guess, this is beyond my current kernel knowledge.

Regards,
Jens

Jens Kuske

unread,
May 18, 2015, 6:07:10 AM5/18/15
to Maxime Ripard, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
On 05/17/15 16:31, Maxime Ripard wrote:
> On Fri, May 15, 2015 at 06:38:58PM +0200, Jens Kuske wrote:
>> Adding a new compatible allows us to define SoC specific behaviour
>> if necessary, for example forcing a particular device out of reset
>> even if no driver is actually using it.
>>
>> Signed-off-by: Jens Kuske <jens...@gmail.com>
>
> This should have been sent to the reset framework maintainer.

I knew I missed something. Given all the other comments, I'll need a v3
anyway.

Jens

Chen-Yu Tsai

unread,
May 18, 2015, 10:45:57 AM5/18/15
to Jens Kuske, Chen-Yu Tsai, VishnuPatekar, Rob Herring, linux-kernel, Mike Turquette, devicetree, Hans de Goede, Linus Walleij, Maxime Ripard, linux-arm-kernel, linux-sunxi, Emilio López
On Mon, May 18, 2015 at 5:15 PM, Jens Kuske <jens...@gmail.com> wrote:
> Hi,
>
> On 05/16/15 04:10, Chen-Yu Tsai wrote:
>> 2015年5月16日 上午12:39於 "Jens Kuske" <jens...@gmail.com>寫道:
> [..]
>>> @@ -1141,6 +1133,7 @@ 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;
>
> Isn't this a copy?

You're right. Sorry for the noise.

Maxime Ripard

unread,
May 19, 2015, 3:55:04 AM5/19/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
By using clock-indices and moving all this gate stuff out of clk-sunxi
and into a new driver.

It's done already, I just need to make sure everything works at it
used to on all the SoCs.
signature.asc

Maxime Ripard

unread,
May 19, 2015, 4:00:03 AM5/19/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
pinctrl_unregister doesn't look like it cares about whether or not
there's users left in the system.

Maybe the easiest path would be to just make this builtin like Paul
suggested then ... :/
signature.asc

Chen-Yu Tsai

unread,
May 19, 2015, 4:03:04 AM5/19/15
to Maxime Ripard, Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
Is there a way to mark modules as not removable? At least we can keep
the multi-platform kernel image small.

Maxime Ripard

unread,
May 19, 2015, 4:20:04 AM5/19/15
to Chen-Yu Tsai, Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Vishnu Patekar, Hans de Goede, devicetree, linux-arm-kernel, linux-kernel, linux-sunxi
If there's no module_exit, the module will only be removable through a
rmmod -f, which seems like an acceptable solution.
signature.asc

Maxime Ripard

unread,
May 19, 2015, 4:30:04 AM5/19/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
Which doesn't really solve the underlying issue, just make it work in
your (pll6/pll8) case.

> > what about taking the first output and taking the substring up to the
> > first "_" ?
>
> That only works for the sun[457]i pll5 & pll6, for sun[68]i the base
> clock name would have to be "pll6x2".

Why?

It's called pll6 in the datasheet, it should really be called
pll6. The fact that there is some fixed factors or dividers on some
children only impacts those children, and not the system as a whole.

And the fact that the "base" clock is pll6x2 and not pll6 itself is
very debatable. How do you know which clock is the base one? Most
clocks are actually using pll6 as a reference.
signature.asc

Maxime Ripard

unread,
May 19, 2015, 4:55:04 AM5/19/15
to Jens Kuske, Emilio López, Mike Turquette, Linus Walleij, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux...@googlegroups.com
We shouldn't care too much about how we can factorise things that
don't need to be factorised.

We have a single user for a clock like this one. Don't try to be smart
by covering all possible cases that might or might not happen in the
future, just make it work for your single user, hardcoding everything
is a good option here.

> >> +static const struct gates_data sun8i_h3_bus_gates_data __initconst = {
> >> + .mask = {0xffbe6760, 0x00701b39, 0x00007123, 0x001f0007, 0x00000081},
> >> + .parents = sun8i_h3_bus_gates_parents,
> >> +};
> >> +
> >> static void __init sunxi_gates_clk_setup(struct device_node *node,
> >> struct gates_data *data)
> >> {
> >> @@ -1110,6 +1144,16 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
> >> }
> >> };
> >>
> >> +static const struct divs_data sun8i_h3_pll6_divs_data __initconst = {
> >> + .factors = &sun6i_a31_pll6_data,
> >> + .ndivs = 3,
> >> + .div = {
> >> + { .fixed = 2 }, /* normal output, pll6 */
> >> + { .self = 1 }, /* base factor clock, pll6 x2 */
> >> + { .fixed = 4 }, /* divided output, pll6 /2 */
> >> + }
> >> +};
> >
> > This is exactly the same clock as A31's PLL6, it shouldn't be declared
> > as a different one.
>
> Um, sorry, but I can't see the /2 output at A31's pll6.
>
> Or shall we add the /2 output to A31's PLL6 and simply ignore it on A31?
> I don't think this is a good idea, what happens if we need to add an
> additional output on A31 later.

This /2 output is not an output, it really is an input of some other
clocks.

This whole thing is currently a mess, I agree, but still, it's the
exact same clock from a register point of view. How it's used by other
components in the system shouldn't matter at all.
signature.asc

Linus Walleij

unread,
May 19, 2015, 10:04:59 AM5/19/15
to Jens Kuske, Maxime Ripard, Emilio López, Mike Turquette, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux-sunxi
On Fri, May 15, 2015 at 6:38 PM, Jens Kuske <jens...@gmail.com> wrote:

> 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>

Waiting for Maxime's ACKs on these patches before merging.

Yours,
Linus Walleij

Linus Walleij

unread,
May 19, 2015, 10:58:20 AM5/19/15
to Maxime Ripard, Johan Hovold, Jens Kuske, Emilio López, Mike Turquette, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux-sunxi
On Tue, May 19, 2015 at 9:55 AM, Maxime Ripard
<maxime...@free-electrons.com> wrote:

>> Apart from that, currently the kernel panics some seconds after removing
>> the pinctrl module because mmc wants to access a gpio. Can this be
>> prevented somehow? I think pinctrl must not be removed once other
>> devices use any pin-related things.
>
> pinctrl_unregister doesn't look like it cares about whether or not
> there's users left in the system.

Both GPIO and pinctrl has this problem, Johan Hovold has been
looking at fixing the GPIO side of things.

Patches welcome.

Yours,
Linus Walleij

Maxime Ripard

unread,
May 19, 2015, 11:05:05 AM5/19/15
to Linus Walleij, Jens Kuske, Emilio López, Mike Turquette, Rob Herring, Chen-Yu Tsai, Vishnu Patekar, Hans de Goede, devic...@vger.kernel.org, linux-ar...@lists.infradead.org, linux-...@vger.kernel.org, linux-sunxi
There's still the modules issue being debated on another patch of this
serie, so there will probably be a v3 of these patches.
signature.asc
Reply all
Reply to author
Forward
0 new messages