Skip to content

Instantly share code, notes, and snippets.

Created October 26, 2015 02:14
Show Gist options
  • Save anonymous/893bab16081e339f37c5 to your computer and use it in GitHub Desktop.
Save anonymous/893bab16081e339f37c5 to your computer and use it in GitHub Desktop.

Revisions

  1. @invalid-email-address Anonymous created this gist Oct 26, 2015.
    1,480 changes: 1,480 additions & 0 deletions Basic_H3_support.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1480 @@
    From ef1d1a9e7f26c477951e183649fae22716760ca2 Mon Sep 17 00:00:00 2001
    From: Marco Franceschetti <[email protected]>
    Date: Sun, 25 Oct 2015 20:00:28 +0100
    Subject: [PATCH] Add basic H3 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

    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/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/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/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
    index 7d3e495..45daa66 100644
    --- a/arch/arm/boot/dts/Makefile
    +++ b/arch/arm/boot/dts/Makefile
    @@ -656,7 +656,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 @@
    +/*
    + * Copyright (C) 2015 Jens Kuske <[email protected]>
    + *
    + * 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.
    + */
    +
    +/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";
    +};
    diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
    new file mode 100644
    index 0000000..4114e17
    --- /dev/null
    +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
    @@ -0,0 +1,499 @@
    +/*
    + * Copyright (C) 2015 Jens Kuske <[email protected]>
    + *
    + * 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 = <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>;
    + 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>;
    + clocks = <&ahb1>, <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb2>, <&ahb1>,
    + <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb2>,
    + <&ahb2>, <&ahb2>, <&ahb1>,
    + <&ahb1>, <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>, <&ahb1>,
    + <&ahb1>, <&ahb1>, <&ahb1>,
    + <&ahb1>, <&apb1>,
    + <&apb1>, <&apb1>, <&apb1>,
    + <&apb1>, <&apb1>, <&apb1>,
    + <&apb2>, <&apb2>, <&apb2>,
    + <&apb2>, <&apb2>,
    + <&apb2>, <&apb2>, <&apb2>,
    + <&ahb1>, <&ahb1>;
    + 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@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";
    + #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 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>;
    + };
    + };
    +};
    diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
    index f5a35b8..ecaff7f8 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 <[email protected]>
    + *
    + * Based on clk-simple-gates.c, which is:
    + * Copyright 2015 Maxime Ripard
    + *
    + * Maxime Ripard <[email protected]>
    + *
    + * 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 9c79af0c..6293c65 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 = {
    @@ -778,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)
    {
    @@ -902,6 +897,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 +937,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 */
    @@ -953,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 */
    }
    };

    @@ -983,6 +980,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 +990,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);
    @@ -1130,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,},
    {}
    };

    @@ -1212,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)
    {
    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 <[email protected]>
    + *
    + * Based on pinctrl-sun8i-a23.c, which is:
    + * Copyright (C) 2014 Chen-Yu Tsai <[email protected]>
    + * Copyright (C) 2014 Maxime Ripard <[email protected]>
    + *
    + * 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);
    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.6.1

    66 changes: 66 additions & 0 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    #!/bin/bash
    (echo n; echo p; echo 1; echo 2048; echo +15M; echo n; echo p; echo 2; echo 32768; echo +240M; echo p; echo w) | fdisk /dev/sdb
    mkfs.vfat /dev/sdb1
    rm -rf u-boot
    git clone git://git.denx.de/u-boot.git
    cd u-boot
    git remote add jemk https://github.com/jemk/u-boot-sunxi.git
    git remote add sunxi-wip https://github.com/jwrdegoede/u-boot-sunxi
    git fetch --all --depth=1
    git branch orangepi sunxi-wip/sunxi-wip
    git checkout orangepi
    git cherry-pick jemk/sunxi/h3~4..jemk/sunxi/h3
    make ARCH=arm -j 5 CROSS_COMPILE=arm-linux-gnueabihf- xunlong_orangepi_plus_defconfig
    make ARCH=arm -j 5 CROSS_COMPILE=arm-linux-gnueabihf-
    dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8
    sync


    cd /home/faddat
    rm -rf linux
    git clone https://github.com/torvalds/linux --depth=1
    cd linux

    git remote add linux-next git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
    git fetch --all
    git branch orangepi linux-next/master
    git checkout orangepi
    git apply --check Basic_H3_support.patch
    git am --signoff Basic_H3_support.patch
    make ARCH=arm -j 5 CROSS_COMPILE=arm-linux-gnueabihf- sunxi_defconfig
    make ARCH=arm -j 5 CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x40008000 INSTALL_MOD_PATH=output uImage dtbs modules
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=output modules_install

    rm -rf /tmp/sdcard
    mkdir /tmp/sdcard
    mount -t vfat /dev/sdb1 /tmp/sdcard/
    cp /home/faddat/linux/arch/arm/boot/uimage /tmp/sdcard
    cp /home/faddat/linux/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dtb /tmp/sdcard
    cat > /tmp/boot.cmd << "EOF"
    #COMMON SETTINGS
    setenv fdt_high ffffffff
    #Settings for booting from the card.
    setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage
    setenv loaddtb fatload mmc 0 \$fdt_addr_r sun8i-h3-orangepi-plus.dtb
    setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
    setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r
    run uenvcmd
    EOF

    mkimage -C none -A arm -T script -d /tmp/boot.cmd /tmp/sdcard/boot.scr

    cat > /tmp/sdcard/uEnv.txt << EOF
    setenv fdt_high ffffffff
    setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage
    setenv loaddtb fatload mmc 0 \$fdt_addr_r sun8i-h3-orangepi-plus.dtb
    setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
    setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r
    run uenvcmd
    EOF

    cd /tmp/
    wget http://downloads.openwrt.org/snapshots/trunk/sunxi/generic/openwrt-sunxi-root.ext4
    resize2fs /tmp/openwrt-sunxi-root.ext4 240M
    dd if=/tmp/openwrt-sunxi-root.ext4 of=/dev/sdb2 bs=128k
    sync
    umount /tmp/sdcard