From 149851b015e14af11f554be955ba3944bb30ed94 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Wed, 6 Jan 2016 21:11:52 +0800 Subject: [PATCH 01/12] ARM: sunxi: Introduce Allwinner for A83T support Allwinner A83T is octa-core cortex-a7 based SoC. It's clock control unit and prcm, pinmux are different from previous sun8i series. Its processor cores are arragned in two clusters 4 cores each, similar to A80. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Documentation/arm/sunxi/README | 1 - Documentation/devicetree/bindings/arm/sunxi.txt | 1 + arch/arm/mach-sunxi/sunxi.c | 1 + drivers/clk/sunxi/clk-sunxi.c | 6 ++++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README index 430d279a8df374..e5a115f244717a 100644 --- a/Documentation/arm/sunxi/README +++ b/Documentation/arm/sunxi/README @@ -72,6 +72,5 @@ SunXi family * Octa ARM Cortex-A7 based SoCs - Allwinner A83T - + Not Supported + Datasheet http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index bb9b0faa919d09..7e79fcc36b0db6 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -11,5 +11,6 @@ using one of the following compatible strings: allwinner,sun7i-a20 allwinner,sun8i-a23 allwinner,sun8i-a33 + allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index c2be98f38e73b2..3c156190a1d442 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -69,6 +69,7 @@ MACHINE_END static const char * const sun8i_board_dt_compat[] = { "allwinner,sun8i-a23", "allwinner,sun8i-a33", + "allwinner,sun8i-a83t", "allwinner,sun8i-h3", NULL, }; diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5ba2188ee99cca..0d452536555258 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -1219,6 +1219,12 @@ 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 sun8i_a83t_init_clocks(struct device_node *node) +{ + sunxi_init_clocks(NULL, 0); +} +CLK_OF_DECLARE(sun8i_a83t_clk_init, "allwinner,sun8i-a83t", sun8i_a83t_init_clocks); + static void __init sun9i_init_clocks(struct device_node *node) { sunxi_init_clocks(NULL, 0); From b5af0c00dd7a133c53a83e4a0c5da18519ae8253 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 14 Dec 2015 01:13:40 +0000 Subject: [PATCH 02/12] irqchip: sun4i: fix compilation outside of arch/arm The Allwinner sunxi specific interrupt controller cannot be compiled for any architecture except arm: drivers/irqchip/irq-sun4i.c:25:26: fatal error: asm/mach/irq.h: No such file or directory compilation terminated. It turns out that this header is actually not needed for the driver, so remove it and allow compilation for other architectures like arm64. Signed-off-by: Andre Przywara Acked-by: Arnd Bergmann --- drivers/irqchip/irq-sun4i.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 0704362f4c824c..376b28074e0d89 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -22,7 +22,6 @@ #include #include -#include #define SUN4I_IRQ_VECTOR_REG 0x00 #define SUN4I_IRQ_PROTECTION_REG 0x08 From e379a6eeccfb75c52f96c62fab83f9d24e7ad44b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 18 Jan 2016 10:25:27 +0000 Subject: [PATCH 03/12] crypto: sunxi-ss: prevent compilation on 64-bit The driver for the sunxi-ss crypto engine is not entirely 64-bit safe, compilation on arm64 spits some warnings. The proper fix was deemed to involved [1], so since 64-bit SoCs won't have this IP block we just disable this driver for 64-bit. [1]: http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/399988.html (and the reply) Signed-off-by: Andre Przywara --- drivers/crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 07d494276aad04..737200f845ee04 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -487,7 +487,7 @@ config CRYPTO_DEV_IMGTEC_HASH config CRYPTO_DEV_SUN4I_SS tristate "Support for Allwinner Security System cryptographic accelerator" - depends on ARCH_SUNXI + depends on ARCH_SUNXI && !64BIT select CRYPTO_MD5 select CRYPTO_SHA1 select CRYPTO_AES From a2a43d39cd74951da25d12c54adfe3bebcdd3ad3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sun, 17 Jan 2016 01:36:32 +0000 Subject: [PATCH 04/12] drivers: rtc: allow compilation of sun6i RTC for all sunxi SoCs At the moment the "sun6i" RTC drivers depends on having two specific SoC families selected. The Allwinner A64 SoC has the same RTC, so extend the Kconfig option to allow inclusion of the driver for all Allwinner SoCs. Signed-off-by: Andre Przywara --- drivers/rtc/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 376322f71fd572..526eaf445fbcf2 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1360,10 +1360,11 @@ config RTC_DRV_SUN4V config RTC_DRV_SUN6I tristate "Allwinner A31 RTC" - depends on MACH_SUN6I || MACH_SUN8I + default MACH_SUN6I || MACH_SUN8I + depends on ARCH_SUNXI help - If you say Y here you will get support for the RTC found on - Allwinner A31. + If you say Y here you will get support for the RTC found in + some Allwinner SoCs like the A31 or the A64. config RTC_DRV_SUNXI tristate "Allwinner sun4i/sun7i RTC" From b7c595e8f0c144fd59c0cd3d71970d2588d1f9e9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 25 Jan 2016 00:41:04 +0000 Subject: [PATCH 05/12] arm64: Introduce Allwinner SoC config option To prepare for the Allwinner A64 SoC support, introduce a config option to allow compiling Allwinner (aka. sunxi) specific drivers for the arm64 architecture as well. This patch just defines the ARCH_SUNXI symbol to allow Allwinner specific drivers to be selected during kernel configuration. Since the MMC driver is quite essential for Linux to be useful, select it by default. Signed-off-by: Andre Przywara --- arch/arm64/Kconfig.platforms | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bdeb7..fc7cf4bd782507 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -1,5 +1,11 @@ menu "Platform selection" +config ARCH_SUNXI + bool "Allwinner sunxi 64-bit SoC Family" + select SUNXI_MMC + help + This enables support for Allwinner sunxi based SoCs like the A64. + config ARCH_BCM_IPROC bool "Broadcom iProc SoC Family" help From 7fe0a2c2524a4a0b28ee6b9b1d13c571650bd19c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 14 Dec 2015 01:15:08 +0000 Subject: [PATCH 06/12] drivers: pinctrl: add driver for Allwinner A64 SoC Based on the Allwinner A64 user manual and on the previous sunxi pinctrl drivers this introduces the pin multiplex assignments for the ARMv8 Allwinner A64 SoC. Port A is apparently used for the fixed function DRAM controller, so the ports start at B here (the manual mentions "n from 1 to 7", so not starting at 0). Signed-off-by: Andre Przywara --- .../pinctrl/allwinner,sunxi-pinctrl.txt | 1 + arch/arm64/Kconfig.platforms | 1 + drivers/pinctrl/sunxi/Kconfig | 4 + drivers/pinctrl/sunxi/Makefile | 1 + drivers/pinctrl/sunxi/pinctrl-a64.c | 606 ++++++++++++++++++ 5 files changed, 613 insertions(+) create mode 100644 drivers/pinctrl/sunxi/pinctrl-a64.c diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt index 9213b27e103666..905000247c0fdc 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt @@ -21,6 +21,7 @@ Required properties: "allwinner,sun9i-a80-r-pinctrl" "allwinner,sun8i-a83t-pinctrl" "allwinner,sun8i-h3-pinctrl" + "allwinner,a64-pinctrl" - reg: Should contain the register physical address and length for the pin controller. diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index fc7cf4bd782507..03f0f9d77cb07e 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -2,6 +2,7 @@ menu "Platform selection" config ARCH_SUNXI bool "Allwinner sunxi 64-bit SoC Family" + select PINCTRL_A64 select SUNXI_MMC help This enables support for Allwinner sunxi based SoCs like the A64. diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index f8dbc8bec0e1e5..68873f28c8cec2 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -64,4 +64,8 @@ config PINCTRL_SUN9I_A80_R depends on RESET_CONTROLLER select PINCTRL_SUNXI_COMMON +config PINCTRL_A64 + bool + select PINCTRL_SUNXI_COMMON + endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index ef82f22bb9ef59..e00ccdeb416bdf 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile @@ -12,6 +12,7 @@ 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_A33) += pinctrl-sun8i-a33.o +obj-$(CONFIG_PINCTRL_A64) += pinctrl-a64.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-a64.c b/drivers/pinctrl/sunxi/pinctrl-a64.c new file mode 100644 index 00000000000000..e72b0797f06b92 --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-a64.c @@ -0,0 +1,606 @@ +/* + * Allwinner A64 SoCs pinctrl driver. + * + * Copyright (C) 2016 - ARM Ltd. + * Author: Andre Przywara + * + * Based on pinctrl-sun7i-a20.c, which is: + * Copyright (C) 2014 Maxime Ripard + * + * 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 +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin a64_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION(0x4, "jtag"), /* MS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION(0x4, "jtag"), /* CK0 */ + SUNXI_FUNCTION(0x5, "sim"), /* VCCEN */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION(0x4, "jtag"), /* DO0 */ + SUNXI_FUNCTION(0x5, "sim"), /* VPPEN */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION(0x3, "i2s0"), /* MCLK */ + SUNXI_FUNCTION(0x4, "jtag"), /* DI0 */ + SUNXI_FUNCTION(0x5, "sim"), /* VPPPP */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif2"), /* SYNC */ + SUNXI_FUNCTION(0x3, "i2s0"), /* SYNC */ + SUNXI_FUNCTION(0x5, "sim"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif2"), /* BCLK */ + SUNXI_FUNCTION(0x3, "i2s0"), /* BCLK */ + SUNXI_FUNCTION(0x5, "sim"), /* DATA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif2"), /* DOUT */ + SUNXI_FUNCTION(0x3, "i2s0"), /* DOUT */ + SUNXI_FUNCTION(0x5, "sim"), /* RST */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif2"), /* DIN */ + SUNXI_FUNCTION(0x3, "i2s0"), /* DIN */ + SUNXI_FUNCTION(0x5, "sim"), /* DET */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "uart0"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "uart0"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* EINT9 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NWE */ + SUNXI_FUNCTION(0x4, "spi0")), /* MOSI */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NALE */ + SUNXI_FUNCTION(0x3, "mmc2"), /* DS */ + SUNXI_FUNCTION(0x4, "spi0")), /* MISO */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */ + SUNXI_FUNCTION(0x4, "spi0")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE1 */ + SUNXI_FUNCTION(0x4, "spi0")), /* CS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NRE# */ + 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"), /* NRB0 */ + 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")), /* NRB1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */ + 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"), /* NDQ1 */ + 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"), /* NDQ2 */ + 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"), /* NDQ3 */ + 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"), /* NDQ4 */ + 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"), /* NDQ5 */ + 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, "nand0"), /* NDQ6 */ + 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, "nand0"), /* NDQ7 */ + 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, "nand0"), /* NDQS */ + 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, "lcd0"), /* D2 */ + SUNXI_FUNCTION(0x3, "uart3"), /* TX */ + SUNXI_FUNCTION(0x4, "spi1"), /* CS */ + SUNXI_FUNCTION(0x5, "ccir")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ + SUNXI_FUNCTION(0x3, "uart3"), /* RX */ + SUNXI_FUNCTION(0x4, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x5, "ccir")), /* DE */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ + SUNXI_FUNCTION(0x3, "uart4"), /* TX */ + SUNXI_FUNCTION(0x4, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x5, "ccir")), /* HSYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ + SUNXI_FUNCTION(0x3, "uart4"), /* RX */ + SUNXI_FUNCTION(0x4, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x5, "ccir")), /* VSYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ + SUNXI_FUNCTION(0x3, "uart4"), /* RTS */ + SUNXI_FUNCTION(0x5, "ccir")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ + SUNXI_FUNCTION(0x3, "uart4"), /* CTS */ + SUNXI_FUNCTION(0x5, "ccir")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ + SUNXI_FUNCTION(0x4, "emac"), /* ERXD3 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ + SUNXI_FUNCTION(0x4, "emac"), /* ERXD2 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ + SUNXI_FUNCTION(0x4, "emac")), /* ERXD1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ + SUNXI_FUNCTION(0x4, "emac")), /* ERXD0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VP0 */ + SUNXI_FUNCTION(0x4, "emac")), /* ERXCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VN0 */ + SUNXI_FUNCTION(0x4, "emac")), /* ERXCTL */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VP1 */ + SUNXI_FUNCTION(0x4, "emac")), /* ENULL */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VN1 */ + SUNXI_FUNCTION(0x4, "emac"), /* ETXD3 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VP2 */ + SUNXI_FUNCTION(0x4, "emac"), /* ETXD2 */ + SUNXI_FUNCTION(0x5, "ccir")), /* D7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VN2 */ + SUNXI_FUNCTION(0x4, "emac")), /* ETXD1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VPC */ + SUNXI_FUNCTION(0x4, "emac")), /* ETXD0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* DE */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VNC */ + SUNXI_FUNCTION(0x4, "emac")), /* ETXCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VP3 */ + SUNXI_FUNCTION(0x4, "emac")), /* ETXCTL */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */ + SUNXI_FUNCTION(0x3, "lvds0"), /* VN3 */ + SUNXI_FUNCTION(0x4, "emac")), /* ECLKIN */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm"), /* PWM0 */ + SUNXI_FUNCTION(0x4, "emac")), /* EMDC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "emac")), /* EMDIO */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* PCK */ + SUNXI_FUNCTION(0x4, "ts0")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* CK */ + SUNXI_FUNCTION(0x4, "ts0")), /* ERR */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* HSYNC */ + SUNXI_FUNCTION(0x4, "ts0")), /* SYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* VSYNC */ + SUNXI_FUNCTION(0x4, "ts0")), /* DVLD */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D0 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D1 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D2 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D3 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D4 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D5 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D6 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0"), /* D7 */ + SUNXI_FUNCTION(0x4, "ts0")), /* D7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi0")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pll"), /* LOCK_DBG */ + SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17), + 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")), /* MSI */ + 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")), /* DI1 */ + 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")), /* DO1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ + SUNXI_FUNCTION(0x4, "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")), /* CK1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + /* 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(0x6, 1, 0)), /* 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(0x6, 1, 1)), /* 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(0x6, 1, 2)), /* 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(0x6, 1, 3)), /* 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(0x6, 1, 4)), /* 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(0x6, 1, 5)), /* 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(0x6, 1, 6)), /* 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(0x6, 1, 7)), /* 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(0x6, 1, 8)), /* 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(0x6, 1, 9)), /* EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif3"), /* SYNC */ + SUNXI_FUNCTION(0x3, "i2s1"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 10)), /* EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif3"), /* BCLK */ + SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 11)), /* EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif3"), /* DOUT */ + SUNXI_FUNCTION(0x3, "i2s1"), /* DOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 12)), /* EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "aif3"), /* DIN */ + SUNXI_FUNCTION(0x3, "i2s1"), /* DIN */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 13)), /* EINT13 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart3"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart3"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart3"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart3"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "owa"), /* OUT */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mic"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mic"), /* DATA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* EINT11 */ +}; + +static const struct sunxi_pinctrl_desc a64_pinctrl_data = { + .pins = a64_pins, + .npins = ARRAY_SIZE(a64_pins), + .irq_banks = 3, +}; + +static int a64_pinctrl_probe(struct platform_device *pdev) +{ + return sunxi_pinctrl_init(pdev, + &a64_pinctrl_data); +} + +static const struct of_device_id a64_pinctrl_match[] = { + { .compatible = "allwinner,a64-pinctrl", }, + {} +}; +MODULE_DEVICE_TABLE(of, a64_pinctrl_match); + +static struct platform_driver a64_pinctrl_driver = { + .probe = a64_pinctrl_probe, + .driver = { + .name = "a64-pinctrl", + .of_match_table = a64_pinctrl_match, + }, +}; +module_platform_driver(a64_pinctrl_driver); + +MODULE_AUTHOR("Andre Przywara "); +MODULE_DESCRIPTION("Allwinner A64 pinctrl driver"); +MODULE_LICENSE("GPL"); From fbfc4acb342da4ee4b3bef8df07819afd4505d38 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 29 Jan 2016 11:52:23 +0000 Subject: [PATCH 07/12] clk: sunxi: add generic multi-parent bus clock gates driver The Allwinner H3 SoC introduced bus clock gates with potentially different parents per clock gate. The H3 driver chose to hardcode the actual parent clock relation in the code. Add a new driver (which has the potential to drive the H3 and also the simple clock gates as well) which uses the power of DT to describe this relationship in an elegant and flexible way. Using one subnode for every parent clock we get away with a single DT compatible match, which can be used as a fallback value in the actual DTs without the need to add specific compatible strings to the code. This avoids adding a new driver or function for every new SoC. Signed-off-by: Andre Przywara --- drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk-multi-gates.c | 105 ++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 drivers/clk/sunxi/clk-multi-gates.c diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 3fd7901d48e494..3a9dc31e36e917 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -11,6 +11,7 @@ obj-y += clk-a10-ve.o obj-y += clk-a20-gmac.o obj-y += clk-mod0.o obj-y += clk-simple-gates.o +obj-y += clk-multi-gates.o obj-y += clk-sun8i-bus-gates.o obj-y += clk-sun8i-mbus.o obj-y += clk-sun9i-core.o diff --git a/drivers/clk/sunxi/clk-multi-gates.c b/drivers/clk/sunxi/clk-multi-gates.c new file mode 100644 index 00000000000000..76e715a19f0d41 --- /dev/null +++ b/drivers/clk/sunxi/clk-multi-gates.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 ARM Ltd. + * + * Based on clk-sun8i-bus-gates.c, which is: + * Copyright (C) 2015 Jens Kuske + * Based on clk-simple-gates.c, which is: + * Copyright 2015 Maxime Ripard + * + * 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 +#include +#include +#include +#include + +static DEFINE_SPINLOCK(gates_lock); + +static void __init sunxi_parse_parent(struct device_node *node, + struct clk_onecell_data *clk_data, + void __iomem *reg) +{ + const char *parent = of_clk_get_parent_name(node, 0); + const char *clk_name; + struct property *prop; + struct clk *clk; + const __be32 *p; + int index, i = 0; + + of_property_for_each_u32(node, "clock-indices", prop, p, index) { + of_property_read_string_index(node, "clock-output-names", + i, &clk_name); + + clk = clk_register_gate(NULL, clk_name, parent, 0, + reg + 4 * (index / 32), index % 32, + 0, &gates_lock); + i++; + if (IS_ERR(clk)) { + pr_warn("could not register gate clock \"%s\"\n", + clk_name); + continue; + } + if (clk_data->clks[index]) + pr_warn("bus-gate clock %s: index #%d already registered as %s\n", + clk_name, index, "?"); + else + clk_data->clks[index] = clk; + } +} + +static void __init sunxi_multi_bus_gates_init(struct device_node *node) +{ + struct clk_onecell_data *clk_data; + struct device_node *child; + struct property *prop; + struct resource res; + void __iomem *reg; + const __be32 *p; + int number = 0; + int 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; + + for_each_child_of_node(node, child) + of_property_for_each_u32(child, "clock-indices", prop, p, index) + number = max(number, index); + + clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL); + if (!clk_data->clks) + goto err_free_data; + + for_each_child_of_node(node, child) + sunxi_parse_parent(child, clk_data, reg); + + clk_data->clk_num = number + 1; + if (of_clk_add_provider(node, of_clk_src_onecell_get, clk_data)) + pr_err("registering bus-gate clock %s failed\n", node->name); + + return; + +err_free_data: + kfree(clk_data); +err_unmap: + iounmap(reg); + of_address_to_resource(node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +} + +CLK_OF_DECLARE(sunxi_multi_bus_gates, "allwinner,sunxi-multi-bus-gates-clk", + sunxi_multi_bus_gates_init); From 4cff1c1b7d43686a66dc9a739aa3b25800df41dd Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2016 21:40:59 +0000 Subject: [PATCH 08/12] clk: sunxi: add generic allwinner,sunxi name The only difference between the different compatible matches at the end of clk-sunxi.c are the critical clocks. Two SoCs get away so far without any, so there is no reason to enumerate those SoCs in here explicitly, though we have to keep them in for compatibility reasons. Rename the init function to highlight this generic feature and add a new, generic DT compatible string which can be used as a fallback value in the future should a particular SoC don't need any special treatment. Signed-off-by: Andre Przywara --- Documentation/devicetree/bindings/arm/sunxi.txt | 4 ++++ drivers/clk/sunxi/clk-sunxi.c | 14 ++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index 7e79fcc36b0db6..980e0651cfc573 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -14,3 +14,7 @@ using one of the following compatible strings: allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 + +For Allwinner SoCs without any specific needs the generic fallback value of: + allwinner,sunxi +can be used. diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index e460a6b0068c9a..efcce857e5d372 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -1052,14 +1052,12 @@ 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 sun8i_a83t_init_clocks(struct device_node *node) +static void __init sunxi_generic_init_clocks(struct device_node *node) { sunxi_init_clocks(NULL, 0); } -CLK_OF_DECLARE(sun8i_a83t_clk_init, "allwinner,sun8i-a83t", sun8i_a83t_init_clocks); - -static void __init sun9i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(NULL, 0); -} -CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); +CLK_OF_DECLARE(sun8i_a83t_clk_init, "allwinner,sun8i-a83t", + sunxi_generic_init_clocks); +CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", + sunxi_generic_init_clocks); +CLK_OF_DECLARE(sunxi_clk_init, "allwinner,sunxi", sunxi_generic_init_clocks); From 39535cb724e00e200f1fcf23db04b09f5043d161 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 1 Feb 2016 00:22:06 +0000 Subject: [PATCH 09/12] clk: sunxi: improve error reporting for the mux clock clk_register_mux returns a pointer wrapped error value in case of failure, so a simple NULL check is not sufficient to catch errors. Fix that and elaborate on the failure reason on the way. The whole function does not return any error value, so silently failing may leave users scratching their heads because the kernel does not provide any clues on what's wrong. Signed-off-by: Andre Przywara --- drivers/clk/sunxi/clk-sunxi.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index efcce857e5d372..9416e0f3fe201e 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -627,17 +627,29 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, reg = of_iomap(node, 0); i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_warn("%s: could not read clock-output-names for \"%s\"\n", + __func__, clk_name); + goto out_unmap; + } clk = clk_register_mux(NULL, clk_name, parents, i, CLK_SET_RATE_PARENT, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_warn("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); + goto out_unmap; } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + return; + +out_unmap: + iounmap(reg); } From b6793602cba70cb0461b115dff29d1ff2a53d64d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 1 Feb 2016 00:26:01 +0000 Subject: [PATCH 10/12] clk: sunxi: add critical-clocks property to mux clocks The only reason we match the different root compatible strings when registering the different sunxi clock types is to provide a list of critical clocks. Tell the mux clock (for a start) to get this property from the device tree, allowing new SoCs to refer to the generic fallback compatible string when the DT provides the critical clock information. Signed-off-by: Andre Przywara --- drivers/clk/sunxi/clk-sunxi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 9416e0f3fe201e..e1e5a8f9e3b777 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -644,6 +644,11 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, goto out_unmap; } + if (of_property_read_bool(node, "critical-clocks")) { + pr_debug("marked clock %s as critical\n", clk_name); + clk_prepare_enable(clk); + } + of_clk_add_provider(node, of_clk_src_simple_get, clk); clk_register_clkdev(clk, clk_name, NULL); return; @@ -1064,6 +1069,10 @@ 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); +/* + * Those SoCs here either don't have a specific critical clock to + * protect or they mark the critical clocks as such in their DT. + */ static void __init sunxi_generic_init_clocks(struct device_node *node) { sunxi_init_clocks(NULL, 0); From 555bb2cbb36b086545a490f1db116d8d928b7916 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 18 Jan 2016 10:24:31 +0000 Subject: [PATCH 11/12] arm64: dts: add Allwinner A64 SoC .dtsi The Allwinner A64 SoC is low-cost SoC with 4 ARM Cortex-A53 cores and the typical tablet / TV box peripherals. The Soc is based on the (32-bit) Allwinner H3 chip, sharing most of the peripherals and the memory map. Although the cores are proper 64-bit ones, the whole SoC is actually limited to 4GB (including all the supported DRAM), so we use 32-bit address and size cells. This has the nice feature of us being able to reuse the DT for 32-bit kernels as well. This .dtsi lists the hardware that we support so far. Signed-off-by: Andre Przywara --- .../devicetree/bindings/arm/sunxi.txt | 1 + .../devicetree/bindings/clock/sunxi.txt | 1 + arch/arm64/boot/dts/allwinner/a64.dtsi | 583 ++++++++++++++++++ 3 files changed, 585 insertions(+) create mode 100644 arch/arm64/boot/dts/allwinner/a64.dtsi diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index 980e0651cfc573..4a8385393a463d 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -14,6 +14,7 @@ using one of the following compatible strings: allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 + allwinner,a64 For Allwinner SoCs without any specific needs the generic fallback value of: allwinner,sunxi diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index e59f57b24777c4..44b0c6cfcba678 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -77,6 +77,7 @@ Required properties: "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80 "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80 "allwinner,sun4i-a10-ve-clk" - for the Video Engine clock + "allwinner,a64-bus-gates-clk" - for the A64 multi-parent bus gates clock Required properties for all clocks: - reg : shall be the control register address for the clock. diff --git a/arch/arm64/boot/dts/allwinner/a64.dtsi b/arch/arm64/boot/dts/allwinner/a64.dtsi new file mode 100644 index 00000000000000..8dce10ff8d85d4 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/a64.dtsi @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2016 ARM Ltd. + * based on the Allwinner H3 dtsi: + * Copyright (C) 2015 Jens Kuske + * + * 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 +#include + +/ { + compatible = "allwinner,a64", "allwinner,sunxi"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <0>; + enable-method = "psci"; + }; + + cpu@1 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <1>; + enable-method = "psci"; + }; + + cpu@2 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <2>; + enable-method = "psci"; + }; + + cpu@3 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2", "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + memory { + device_type = "memory"; + reg = <0x40000000 0>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + 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,sun6i-a31-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6", "pll6x2"; + }; + + pll6d2: pll6d2_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <2>; + clock-mult = <1>; + clocks = <&pll6 0>; + clock-output-names = "pll6d2"; + }; + + /* dummy clock until pll6 can be reused */ + pll8: pll8_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <1>; + clock-output-names = "pll8"; + }; + + 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"; + critical-clocks = <0>; + }; + + 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>, <&pll6d2>; + 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 1>, <&pll6 1>; + clock-output-names = "apb2"; + }; + + bus_gates: clk@01c20060 { + #clock-cells = <1>; + compatible = "allwinner,a64-bus-gates-clk", + "allwinner,sunxi-multi-bus-gates-clk"; + reg = <0x01c20060 0x14>; + ahb1_parent { + clocks = <&ahb1>; + clock-indices = <1>, <5>, + <6>, <8>, + <9>, <10>, + <13>, <14>, + <18>, <19>, + <20>, <21>, + <23>, <24>, + <25>, <28>, + <32>, <35>, + <36>, <37>, + <40>, <43>, + <44>, <52>, + <53>, <54>, + <135>; + clock-output-names = "bus_mipidsi", "bus_ce", + "bus_dma", "bus_mmc0", + "bus_mmc1", "bus_mmc2", + "bus_nand", "bus_sdram", + "bus_ts", "bus_hstimer", + "bus_spi0", "bus_spi1", + "bus_otg", "bus_otg_ehci0", + "bus_ehci0", "bus_otg_ohci0", + "bus_ve", "bus_lcd0", + "bus_lcd1", "bus_deint", + "bus_csi", "bus_hdmi", + "bus_de", "bus_gpu", + "bus_msgbox", "bus_spinlock", + "bus_dbg"; + }; + ahb2_parent { + clocks = <&ahb2>; + clock-indices = <17>, <29>; + clock-output-names = "bus_gmac", "bus_ohci0"; + }; + apb1_parent { + clocks = <&apb1>; + clock-indices = <64>, <65>, + <69>, <72>, + <76>, <77>, + <78>; + clock-output-names = "bus_codec", "bus_spdif", + "bus_pio", "bus_ths", + "bus_i2s0", "bus_i2s1", + "bus_i2s2"; + }; + abp2_parent { + clocks = <&apb2>; + clock-indices = <96>, <97>, + <98>, <101>, + <112>, <113>, + <114>, <115>, + <116>; + clock-output-names = "bus_i2c0", "bus_i2c1", + "bus_i2c2", "bus_scr", + "bus_uart0", "bus_uart1", + "bus_uart2", "bus_uart3", + "bus_uart4"; + }; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-mmc-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 0>, <&pll8>; + 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>; + 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>; + clock-output-names = "mmc2", + "mmc2_output", + "mmc2_sample"; + }; + }; + + regulators { + reg_vcc3v3: vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + 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 = <&ahb_rst 8>; + reset-names = "ahb"; + interrupts = ; + 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 = <&ahb_rst 9>; + reset-names = "ahb"; + interrupts = ; + 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 = <&ahb_rst 10>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + pio: pinctrl@01c20800 { + compatible = "allwinner,a64-pinctrl"; + reg = <0x01c20800 0x400>; + interrupts = , + , + ; + clocks = <&bus_gates 69>; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <2>; + + uart0_pins_a: uart0@0 { + allwinner,pins = "PB8", "PB9"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_b: uart0@1 { + allwinner,pins = "PF2", "PF3"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart1_pins: uart1@0 { + allwinner,pins = "PG6", "PG7", "PG8", "PG9"; + allwinner,function = "uart1"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart2_pins: uart2@0 { + allwinner,pins = "PB0", "PB1", "PB2", "PB3"; + allwinner,function = "uart2"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart3_pins_a: uart3@0 { + allwinner,pins = "PD0", "PD1"; + allwinner,function = "uart3"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart3_pins_b: uart3@1 { + allwinner,pins = "PH4", "PH5", "PH6", "PH7"; + allwinner,function = "uart3"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart4_pins: uart4@0 { + allwinner,pins = "PD2", "PD3", "PD4", "PD5"; + allwinner,function = "uart4"; + allwinner,drive = ; + allwinner,pull = ; + }; + + mmc0_pins: mmc0@0 { + allwinner,pins = "PF0", "PF1", "PF2", "PF3", + "PF4", "PF5"; + allwinner,function = "mmc0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + mmc0_default_cd_pin: mmc0_cd_pin@0 { + allwinner,pins = "PF6"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + mmc1_pins: mmc1@0 { + allwinner,pins = "PG0", "PG1", "PG2", "PG3", + "PG4", "PG5"; + allwinner,function = "mmc1"; + allwinner,drive = ; + allwinner,pull = ; + }; + + mmc2_pins: mmc2@0 { + allwinner,pins = "PC1", "PC5", "PC6", "PC8", + "PC9", "PC10"; + allwinner,function = "mmc2"; + allwinner,drive = ; + allwinner,pull = ; + }; + }; + + ahb_rst: reset@01c202c0 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-ahb1-reset"; + reg = <0x01c202c0 0xc>; + }; + + apb1_rst: reset@01c202d0 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-clock-reset"; + reg = <0x01c202d0 0x4>; + }; + + apb2_rst: reset@01c202d8 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-clock-reset"; + reg = <0x01c202d8 0x4>; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&bus_gates 112>; + resets = <&apb2_rst 16>; + reset-names = "apb2"; + status = "disabled"; + }; + + uart1: serial@01c28400 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28400 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&bus_gates 113>; + resets = <&apb2_rst 17>; + reset-names = "apb2"; + status = "disabled"; + }; + + uart2: serial@01c28800 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28800 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&bus_gates 114>; + resets = <&apb2_rst 18>; + reset-names = "apb2"; + status = "disabled"; + }; + + uart3: serial@01c28c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28c00 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&bus_gates 115>; + resets = <&apb2_rst 19>; + reset-names = "apb2"; + status = "disabled"; + }; + + uart4: serial@01c29000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c29000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&bus_gates 116>; + resets = <&apb2_rst 20>; + reset-names = "apb2"; + status = "disabled"; + }; + + rtc: rtc@01f00000 { + compatible = "allwinner,sun6i-a31-rtc"; + reg = <0x01f00000 0x54>; + interrupts = , + ; + }; + }; + + gic: interrupt-controller@{ + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + #address-cells = <0>; + + reg = <0x01C81000 0x1000>, + <0x01C82000 0x2000>, + <0x01C84000 0x2000>, + <0x01C86000 0x2000>; + interrupts = ; + }; +}; From 0fa75782806ae9d938dda083aa60932b7796f652 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 19 Jan 2016 10:36:39 +0000 Subject: [PATCH 12/12] arm64: dts: add Pine64 support The Pine64 is a cost-efficient development board based on the Allwinner A64 SoC. There are three models: the basic version with Fast Ethernet and 512 MB of DRAM (Pine64) and two Pine64+ versions, which both feature Gigabit Ethernet and additional connectors for touchscreens and a camera. Or as my son put it: "Those are smaller and these are missing." ;-) The two Pine64+ models just differ in the amount of DRAM (1GB vs. 2GB). Since U-Boot will figure out the right size for us and patches the DT accordingly we just need to provide one DT for the Pine64+. Signed-off-by: Andre Przywara --- .../devicetree/bindings/vendor-prefixes.txt | 1 + arch/arm64/boot/dts/Makefile | 1 + arch/arm64/boot/dts/allwinner/Makefile | 5 ++ arch/arm64/boot/dts/allwinner/pine64.dts | 58 ++++++++++++++ .../boot/dts/allwinner/pine64_common.dtsi | 76 +++++++++++++++++++ arch/arm64/boot/dts/allwinner/pine64_plus.dts | 59 ++++++++++++++ 6 files changed, 200 insertions(+) create mode 100644 arch/arm64/boot/dts/allwinner/Makefile create mode 100644 arch/arm64/boot/dts/allwinner/pine64.dts create mode 100644 arch/arm64/boot/dts/allwinner/pine64_common.dtsi create mode 100644 arch/arm64/boot/dts/allwinner/pine64_plus.dts diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 72e2c5a2b3278f..0c22fa95efe318 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -175,6 +175,7 @@ parade Parade Technologies Inc. pericom Pericom Technology Inc. phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd +pine64 Pine64 plathome Plat'Home Co., Ltd. plda PLDA pixcir PIXCIR MICROELECTRONICS Co., Ltd diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index f832b8a7453a30..3b7428a2a10e98 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -1,3 +1,4 @@ +dts-dirs += allwinner dts-dirs += altera dts-dirs += amd dts-dirs += apm diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile new file mode 100644 index 00000000000000..65f4e24a2c0334 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -0,0 +1,5 @@ +dtb-$(CONFIG_ARCH_SUNXI) += pine64_plus.dtb pine64.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/allwinner/pine64.dts b/arch/arm64/boot/dts/allwinner/pine64.dts new file mode 100644 index 00000000000000..ebea5dde6b096e --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/pine64.dts @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 ARM Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "pine64_common.dtsi" + +/ { + model = "Pine64"; + compatible = "pine64,pine64", "allwinner,a64", "allwinner,sunxi"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0x40000000 0x20000000>; + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/pine64_common.dtsi b/arch/arm64/boot/dts/allwinner/pine64_common.dtsi new file mode 100644 index 00000000000000..d968d764b8b0c7 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/pine64_common.dtsi @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 ARM Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "a64.dtsi" + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>, <&mmc0_default_cd_pin>; + vmmc-supply = <®_vcc3v3>; + cd-gpios = <&pio 5 6 0>; + cd-inverted; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins_a>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/pine64_plus.dts b/arch/arm64/boot/dts/allwinner/pine64_plus.dts new file mode 100644 index 00000000000000..344752e53bacec --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/pine64_plus.dts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 ARM Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "pine64_common.dtsi" + +/ { + model = "Pine64+"; + compatible = "pine64,pine64_plus", "allwinner,a64", "allwinner,sunxi"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + /* There is a model with 2GB of DRAM, but U-Boot fixes this for us. */ + memory { + reg = <0x40000000 0x40000000>; + }; +};