[U-Boot] [PATCH 5/6] sunxi: Add support for Allwinner A64 SoCs
Alexander Graf
agraf at suse.de
Tue Mar 29 17:29:10 CEST 2016
From: Siarhei Siamashka <siarhei.siamashka at gmail.com>
The Allwinner A64 SoC is used in the Pine64. This patch adds
all bits necessary to compile U-Boot for it running in AArch64
mode.
Unfortunately SPL is not ready yet due to legal problems, so
we need to boot using the binary boot0 for now.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
[agraf: remove SPL code, move to AArch64]
Signed-off-by: Alexander Graf <agraf at suse.de>
---
arch/arm/dts/a64.dtsi | 564 ++++++++++++++++++++++++++
arch/arm/include/asm/arch-sunxi/clock.h | 3 +-
arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 +-
arch/arm/include/asm/arch-sunxi/gpio.h | 1 +
arch/arm/include/asm/arch-sunxi/spl.h | 5 +-
arch/arm/include/asm/system.h | 6 +
arch/arm/mach-sunxi/Makefile | 1 +
arch/arm/mach-sunxi/board.c | 30 +-
arch/arm/mach-sunxi/cpu_info.c | 2 +
board/sunxi/Kconfig | 9 +-
board/sunxi/board.c | 38 +-
drivers/mmc/sunxi_mmc.c | 4 +
drivers/power/Kconfig | 2 +-
include/configs/sun50i.h | 22 +
include/configs/sunxi-common.h | 20 +-
15 files changed, 697 insertions(+), 14 deletions(-)
create mode 100644 arch/arm/dts/a64.dtsi
create mode 100644 include/configs/sun50i.h
diff --git a/arch/arm/dts/a64.dtsi b/arch/arm/dts/a64.dtsi
new file mode 100644
index 0000000..f3ad000
--- /dev/null
+++ b/arch/arm/dts/a64.dtsi
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2016 ARM Ltd.
+ * based on the Allwinner H3 dtsi:
+ * Copyright (C) 2015 Jens Kuske <jenskuske at gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ compatible = "allwinner,a64";
+ 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 at 0 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <0>;
+ enable-method = "psci";
+ };
+
+ cpu at 1 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <1>;
+ enable-method = "psci";
+ };
+
+ cpu at 2 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <2>;
+ enable-method = "psci";
+ };
+
+ cpu at 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 = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ 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 at 01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ pll6: clk at 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 at 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 at 01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-axi-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb1: ahb1_clk at 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 at 01c2005c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-h3-ahb2-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&ahb1>, <&pll6d2>;
+ clock-output-names = "ahb2";
+ };
+
+ apb1: apb1_clk at 01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ apb2: apb2_clk at 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 at 01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,a64-bus-gates-clk",
+ "allwinner,sun8i-h3-bus-gates-clk";
+ reg = <0x01c20060 0x14>;
+ clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>;
+ clock-names = "ahb1", "ahb2", "apb1", "apb2";
+ clock-indices = <1>,
+ <5>, <6>, <8>,
+ <9>, <10>, <13>,
+ <14>, <17>, <18>,
+ <19>, <20>,
+ <21>, <23>,
+ <24>, <25>,
+ <28>, <29>,
+ <32>, <35>,
+ <36>, <37>,
+ <40>, <43>,
+ <44>, <52>, <53>,
+ <54>, <64>,
+ <65>, <69>, <72>,
+ <76>, <77>, <78>,
+ <96>, <97>, <98>,
+ <101>,
+ <112>, <113>,
+ <114>, <115>,
+ <116>, <135>;
+ clock-output-names = "bus_mipidsi",
+ "bus_ce", "bus_dma", "bus_mmc0",
+ "bus_mmc1", "bus_mmc2", "bus_nand",
+ "bus_sdram", "bus_gmac", "bus_ts",
+ "bus_hstimer", "bus_spi0",
+ "bus_spi1", "bus_otg",
+ "bus_otg_ehci0", "bus_ehci0",
+ "bus_otg_ohci0", "bus_ohci0",
+ "bus_ve", "bus_lcd0",
+ "bus_lcd1", "bus_deint",
+ "bus_csi", "bus_hdmi",
+ "bus_de", "bus_gpu", "bus_msgbox",
+ "bus_spinlock", "bus_codec",
+ "bus_spdif", "bus_pio", "bus_ths",
+ "bus_i2s0", "bus_i2s1", "bus_i2s2",
+ "bus_i2c0", "bus_i2c1", "bus_i2c2",
+ "bus_scr",
+ "bus_uart0", "bus_uart1",
+ "bus_uart2", "bus_uart3",
+ "bus_uart4", "bus_dbg";
+ };
+
+ mmc0_clk: clk at 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 at 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 at 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 at 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 = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc1: mmc at 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 = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc2: mmc at 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 = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ pio: pinctrl at 01c20800 {
+ compatible = "allwinner,a64-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bus_gates 69>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart0_pins_a: uart0 at 0 {
+ allwinner,pins = "PB8", "PB9";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart0_pins_b: uart0 at 1 {
+ allwinner,pins = "PF2", "PF3";
+ allwinner,function = "uart0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart1_pins: uart1 at 0 {
+ allwinner,pins = "PG6", "PG7", "PG8", "PG9";
+ allwinner,function = "uart1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart2_pins: uart2 at 0 {
+ allwinner,pins = "PB0", "PB1", "PB2", "PB3";
+ allwinner,function = "uart2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_a: uart3 at 0 {
+ allwinner,pins = "PD0", "PD1";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_b: uart3 at 1 {
+ allwinner,pins = "PH4", "PH5", "PH6", "PH7";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart4_pins: uart4 at 0 {
+ allwinner,pins = "PD2", "PD3", "PD4", "PD5";
+ allwinner,function = "uart4";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins: mmc0 at 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_default_cd_pin: mmc0_cd_pin at 0 {
+ allwinner,pins = "PF6";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc1_pins: mmc1 at 0 {
+ allwinner,pins = "PG0", "PG1", "PG2", "PG3",
+ "PG4", "PG5";
+ allwinner,function = "mmc1";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc2_pins: mmc2 at 0 {
+ allwinner,pins = "PC1", "PC5", "PC6", "PC8",
+ "PC9", "PC10";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ ahb_rst: reset at 01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-ahb1-reset";
+ reg = <0x01c202c0 0xc>;
+ };
+
+ apb1_rst: reset at 01c202d0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d0 0x4>;
+ };
+
+ apb2_rst: reset at 01c202d8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ reg = <0x01c202d8 0x4>;
+ };
+
+ uart0: serial at 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 = <&apb2_rst 16>;
+ reset-names = "apb2";
+ status = "disabled";
+ };
+
+ uart1: serial at 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 = <&apb2_rst 17>;
+ reset-names = "apb2";
+ status = "disabled";
+ };
+
+ uart2: serial at 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 = <&apb2_rst 18>;
+ reset-names = "apb2";
+ status = "disabled";
+ };
+
+ uart3: serial at 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 = <&apb2_rst 19>;
+ reset-names = "apb2";
+ status = "disabled";
+ };
+
+ uart4: serial at 01c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&bus_gates 116>;
+ resets = <&apb2_rst 20>;
+ reset-names = "apb2";
+ status = "disabled";
+ };
+
+ rtc: rtc at 01f00000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x01f00000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ 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 = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+};
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index 6c0573f..3747f74 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -17,7 +17,8 @@
/* clock control module regs definition */
#if defined(CONFIG_MACH_SUN8I_A83T)
#include <asm/arch/clock_sun8i_a83t.h>
-#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
+#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
+ defined(CONFIG_MACH_SUN50I)
#include <asm/arch/clock_sun6i.h>
#elif defined(CONFIG_MACH_SUN9I)
#include <asm/arch/clock_sun9i.h>
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 9de7754..816cf37 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -350,7 +350,9 @@ struct sunxi_ccm_reg {
#define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30)
#define CCM_HDMI_CTRL_GATE (0x1 << 31)
-#ifndef CONFIG_MACH_SUN8I
+#if defined(CONFIG_MACH_SUN50I)
+#define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */
+#elif !defined(CONFIG_MACH_SUN8I)
#define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */
#else
#define MBUS_CLK_DEFAULT 0x81000003 /* PLL6 / 4 */
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 649f6cd..1ace548 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -159,6 +159,7 @@ enum sunxi_gpio_number {
#define SUN8I_GPB_UART2 2
#define SUN8I_A33_GPB_UART0 3
#define SUN8I_A83T_GPB_UART0 2
+#define SUN50I_GPB_UART0 4
#define SUNXI_GPC_NAND 2
#define SUNXI_GPC_SDC2 3
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index a129dd4..ca9a4f9 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -12,8 +12,11 @@
#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */
#define SPL_HEADER_VERSION 1
-/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */
+#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
+#define SPL_ADDR 0x10000
+#else
#define SPL_ADDR 0x0
+#endif
/* boot head definition from sun4i boot code */
struct boot_file_head {
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 9ae890a..a165fcd 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -92,6 +92,12 @@ static inline unsigned long read_mpidr(void)
#define BSP_COREID 0
+static inline void sdelay(unsigned long n)
+{
+ int i;
+ for (i = 0; i < n; i++) asm volatile("");
+}
+
void __asm_flush_dcache_all(void);
void __asm_invalidate_dcache_all(void);
void __asm_flush_dcache_range(u64 start, u64 end);
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 114cc03..ad3d6c4 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o
obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o
obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o
obj-$(CONFIG_MACH_SUN7I) += clock_sun4i.o
+obj-$(CONFIG_MACH_SUN50I) += clock_sun6i.o
ifdef CONFIG_MACH_SUN8I_A83T
obj-y += clock_sun8i_a83t.o
else
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 7653148..ae48ead 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -40,6 +40,30 @@ struct fel_stash {
struct fel_stash fel_stash __attribute__((section(".data")));
+#ifdef CONFIG_MACH_SUN50I
+#include <asm/armv8/mmu.h>
+
+static struct mm_region sunxi_mem_map[] = {
+ {
+ /* SRAM, MMIO regions */
+ .base = 0x0UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE
+ }, {
+ /* RAM */
+ .base = 0x40000000UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+struct mm_region *mem_map = sunxi_mem_map;
+#endif
+
static int gpio_init(void)
{
#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
@@ -76,6 +100,10 @@ static int gpio_init(void)
sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I)
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN50I_GPB_UART0);
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_GPB_UART0);
+ sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);
@@ -253,7 +281,7 @@ void reset_cpu(ulong addr)
#endif
}
-#ifndef CONFIG_SYS_DCACHE_OFF
+#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index b9bc70c..36c503a 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -75,6 +75,8 @@ int print_cpuinfo(void)
puts("CPU: Allwinner A80 (SUN9I)\n");
#elif defined CONFIG_MACH_SUN8I_A83T
puts("CPU: Allwinner A83T (SUN8I)\n");
+#elif defined CONFIG_MACH_SUN50I
+ puts("CPU: Allwinner A64 (SUN50I)\n");
#else
#warning Please update cpu_info.c with correct CPU information
puts("CPU: SUNXI Family\n");
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 5e72fac..464fa0f 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -77,6 +77,11 @@ config MACH_SUN8I_H3
select SUPPORT_SPL
select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
+config MACH_SUN50I
+ bool "sun50i (Allwinner A64)"
+ select ARM64
+ select SUNXI_GEN_SUN6I
+
config MACH_SUN8I_A83T
bool "sun8i (Allwinner A83T)"
select CPU_V7
@@ -213,6 +218,7 @@ config DRAM_ODT_CORRECTION
endif
config SYS_CLK_FREQ
+ default 816000000 if MACH_SUN50I
default 912000000 if MACH_SUN7I
default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I
@@ -223,6 +229,7 @@ config SYS_CONFIG_NAME
default "sun7i" if MACH_SUN7I
default "sun8i" if MACH_SUN8I
default "sun9i" if MACH_SUN9I
+ default "sun50i" if MACH_SUN50I
config SYS_BOARD
default "sunxi"
@@ -604,7 +611,7 @@ config GMAC_TX_DELAY
Set the GMAC Transmit Clock Delay Chain value.
config SPL_STACK_R_ADDR
- default 0x4fe00000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I
+ default 0x4fe00000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I || MACH_SUN50I
default 0x2fe00000 if MACH_SUN9I
endif
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 2d5335f..74510c5 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -21,6 +21,9 @@
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/usb_phy.h>
+#ifndef CONFIG_ARM64
+#include <asm/armv7.h>
+#endif
#include <asm/gpio.h>
#include <asm/io.h>
#include <nand.h>
@@ -73,18 +76,41 @@ DECLARE_GLOBAL_DATA_PTR;
/* add board specific code here */
int board_init(void)
{
- int id_pfr1, ret;
+#ifndef CONFIG_ARM64
+ int id_pfr1;
+#endif
+ int ret;
gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
+#ifndef CONFIG_ARM64
asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
debug("id_pfr1: 0x%08x\n", id_pfr1);
/* Generic Timer Extension available? */
- if ((id_pfr1 >> 16) & 0xf) {
+ if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
+ uint32_t freq;
+
debug("Setting CNTFRQ\n");
- /* CNTFRQ == 24 MHz */
- asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000));
+
+ /*
+ * CNTFRQ is a secure register, so we will crash if we try to
+ * write this from the non-secure world (read is OK, though).
+ * In case some bootcode has already set the correct value,
+ * we avoid the risk of writing to it.
+ */
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
+ if (freq != CONFIG_TIMER_CLK_FREQ) {
+ debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
+ freq, CONFIG_TIMER_CLK_FREQ);
+#ifdef CONFIG_NON_SECURE
+ printf("arch timer frequency is wrong, but cannot adjust it\n");
+#else
+ asm volatile("mcr p15, 0, %0, c14, c0, 0"
+ : : "r"(CONFIG_TIMER_CLK_FREQ));
+#endif
+ }
}
+#endif /* !CONFIG_ARM64 */
ret = axp_gpio_init();
if (ret)
@@ -264,7 +290,7 @@ static void mmc_pinmux_setup(int sdc)
sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
}
-#elif defined(CONFIG_MACH_SUN8I)
+#elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
/* SDC2: PC5-PC6, PC8-PC16 */
for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
@@ -541,7 +567,7 @@ void get_board_serial(struct tag_serialnr *serialnr)
*/
static void parse_spl_header(const uint32_t spl_addr)
{
- struct boot_file_head *spl = (void *)spl_addr;
+ struct boot_file_head *spl = (void *)(ulong)spl_addr;
if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) {
uint8_t spl_header_version = spl->spl_signature[3];
if (spl_header_version == SPL_HEADER_VERSION) {
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 44d1a76..ce2dc4a 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -480,6 +480,10 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = MMC_MODE_4BIT;
+#ifdef CONFIG_MACH_SUN50I
+ if (sdc_no == 2)
+ cfg->host_caps = MMC_MODE_8BIT;
+#endif
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index adc6455..bdb2ff4 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -10,7 +10,7 @@ choice
default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
default AXP818_POWER if MACH_SUN8I_A83T
- default SUNXI_NO_PMIC if MACH_SUN8I_H3
+ default SUNXI_NO_PMIC if MACH_SUN8I_H3 || MACH_SUN50I
config SUNXI_NO_PMIC
boolean "board without a pmic"
diff --git a/include/configs/sun50i.h b/include/configs/sun50i.h
new file mode 100644
index 0000000..614c15e
--- /dev/null
+++ b/include/configs/sun50i.h
@@ -0,0 +1,22 @@
+/*
+ * Configuration settings for the Allwinner A64 (sun50i) CPU
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SUNXI_USB_PHYS 1
+
+#define CONFIG_TIMER_CLK_FREQ 24000000
+#define COUNTER_FREQUENCY CONFIG_TIMER_CLK_FREQ
+#define GICD_BASE 0x1c81000
+#define GICC_BASE 0x1c82000
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index a3994e1..7bea473 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -90,7 +90,7 @@
#define CONFIG_SPL_BSS_MAX_SIZE 0x00080000 /* 512 KiB */
-#ifdef CONFIG_MACH_SUN9I
+#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
/*
* The A80's A1 sram starts at 0x00010000 rather then at 0x00000000 and is
* slightly bigger. Note that it is possible to map the first 32 KiB of the
@@ -99,7 +99,7 @@
* the 1 actually activates the mapping of the first 32 KiB to 0x00000000.
*/
#define CONFIG_SYS_INIT_RAM_ADDR 0x10000
-#define CONFIG_SYS_INIT_RAM_SIZE 0x0a000 /* 40 KiB */
+#define CONFIG_SYS_INIT_RAM_SIZE 0x08000 /* FIXME: 40 KiB ? */
#else
#define CONFIG_SYS_INIT_RAM_ADDR 0x0
#define CONFIG_SYS_INIT_RAM_SIZE 0x8000 /* 32 KiB */
@@ -188,8 +188,16 @@
#define CONFIG_SPL_BOARD_LOAD_IMAGE
+#if defined(CONFIG_MACH_SUN9I)
+#define CONFIG_SPL_TEXT_BASE 0x10020 /* sram start+header */
+#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* ? KiB on sun9i */
+#elif defined(CONFIG_MACH_SUN50I)
+#define CONFIG_SPL_TEXT_BASE 0x10020 /* sram start+header */
+#define CONFIG_SPL_MAX_SIZE 0x7fe0 /* 32 KiB on sun50i */
+#else
#define CONFIG_SPL_TEXT_BASE 0x20 /* sram start+header */
#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* 24KB on sun4i/sun7i */
+#endif
#define CONFIG_SPL_LIBDISK_SUPPORT
@@ -197,14 +205,22 @@
#define CONFIG_SPL_MMC_SUPPORT
#endif
+#ifndef CONFIG_ARM64
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds"
+#endif
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 80 /* 40KiB */
#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */
+#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
+/* FIXME: 40 KiB instead of 32 KiB ? */
+#define LOW_LEVEL_SRAM_STACK 0x00018000
+#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
+#else
/* end of 32 KiB in sram */
#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */
#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
+#endif
/* I2C */
#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
--
1.8.5.6
More information about the U-Boot
mailing list