diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9851065574..b82ec18445 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -538,8 +538,8 @@ config ARCH_SUNXI select OF_BOARD_SETUP select OF_CONTROL select OF_SEPARATE - select SPL_STACK_R if !MACH_SUN9I - select SPL_SYS_MALLOC_SIMPLE if !MACH_SUN9I + select SPL_STACK_R if SUPPORT_SPL + select SPL_SYS_MALLOC_SIMPLE if SUPPORT_SPL select SYS_NS16550 select USB select USB_STORAGE diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6defdfb190..ce006aed77 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -54,6 +54,7 @@ machine-$(CONFIG_ARCH_MVEBU) += mvebu # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X machine-$(CONFIG_ORION5X) += orion5x machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx +machine-$(CONFIG_ARCH_SUNXI) += sunxi machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_STM32) += stm32 diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index ce8e5717e7..4d2274a38e 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -8,38 +8,10 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-y += timer.o -obj-y += board.o -obj-y += clock.o -obj-y += cpu_info.o -obj-y += dram_helpers.o -obj-y += pinmux.o -ifndef CONFIG_MACH_SUN9I -obj-y += usb_phy.o -endif -obj-$(CONFIG_MACH_SUN6I) += prcm.o -obj-$(CONFIG_MACH_SUN8I) += prcm.o -obj-$(CONFIG_MACH_SUN9I) += prcm.o -obj-$(CONFIG_MACH_SUN6I) += p2wi.o -obj-$(CONFIG_MACH_SUN8I) += rsb.o -obj-$(CONFIG_MACH_SUN9I) += rsb.o -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 -ifdef CONFIG_MACH_SUN8I_A83T -obj-y += clock_sun8i_a83t.o -else -obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o -endif -obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o + obj-$(CONFIG_MACH_SUN6I) += tzpc.o obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o -obj-$(CONFIG_AXP152_POWER) += pmic_bus.o -obj-$(CONFIG_AXP209_POWER) += pmic_bus.o -obj-$(CONFIG_AXP221_POWER) += pmic_bus.o -obj-$(CONFIG_AXP818_POWER) += pmic_bus.o - ifndef CONFIG_SPL_BUILD ifdef CONFIG_ARMV7_PSCI obj-$(CONFIG_MACH_SUN6I) += psci_sun6i.o @@ -49,13 +21,5 @@ endif endif ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_MACH_SUN4I) += dram_sun4i.o -obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o -obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o -obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o -obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o -obj-$(CONFIG_MACH_SUN8I_A33) += dram_sun8i_a33.o -obj-$(CONFIG_MACH_SUN8I_A83T) += dram_sun8i_a83t.o -obj-$(CONFIG_MACH_SUN8I_H3) += dram_sun8i_h3.o obj-y += fel_utils.o endif diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 50bcc0b5b9..ea635e4efe 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -206,6 +206,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-2.dtb \ sun8i-h3-orangepi-pc.dtb \ sun8i-h3-orangepi-plus.dtb +dtb-$(CONFIG_MACH_SUN50I) += \ + pine64_plus.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ sun9i-a80-cubieboard4.dtb diff --git a/arch/arm/dts/a64.dtsi b/arch/arm/dts/a64.dtsi new file mode 100644 index 0000000000..f3ad00024a --- /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 + * + * 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"; + 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"; + }; + + 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,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@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 = ; + }; +}; diff --git a/arch/arm/dts/pine64.dts b/arch/arm/dts/pine64.dts new file mode 100644 index 0000000000..dcc998f24c --- /dev/null +++ b/arch/arm/dts/pine64.dts @@ -0,0 +1,62 @@ +/* + * 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/; + +/memreserve/ 0x45000000 0x00200000; +/memreserve/ 0x41010000 0x00010800; +/memreserve/ 0x40100000 0x00006000; + +#include "pine64_common.dtsi" + +/ { + model = "Pine64"; + compatible = "pine64,pine64", "allwinner,a64"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0x40000000 0x20000000>; + }; +}; diff --git a/arch/arm/dts/pine64_common.dtsi b/arch/arm/dts/pine64_common.dtsi new file mode 100644 index 0000000000..d968d764b8 --- /dev/null +++ b/arch/arm/dts/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/arm/dts/pine64_plus.dts b/arch/arm/dts/pine64_plus.dts new file mode 100644 index 0000000000..5daff514e2 --- /dev/null +++ b/arch/arm/dts/pine64_plus.dts @@ -0,0 +1,63 @@ +/* + * 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/; + +/memreserve/ 0x45000000 0x00200000; +/memreserve/ 0x41010000 0x00010800; +/memreserve/ 0x40100000 0x00006000; + +#include "pine64_common.dtsi" + +/ { + model = "Pine64+"; + compatible = "pine64,pine64_plus", "allwinner,a64"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + /* There is a model with 2GB of DRAM, but U-Boot fixes this for us. */ + memory { + reg = <0x40000000 0x40000000>; + }; +}; diff --git a/arch/arm/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/dts/sun8i-a83t-allwinner-h8homlet-v2.dts index 342e1d33fa..c8495d7624 100644 --- a/arch/arm/dts/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/arch/arm/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -57,8 +57,20 @@ }; }; +&ehci0 { + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_b>; status = "okay"; }; + +&usb_otg { + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/dts/sun8i-a83t-cubietruck-plus.dts index 88b1e0970b..8437c8f59e 100644 --- a/arch/arm/dts/sun8i-a83t-cubietruck-plus.dts +++ b/arch/arm/dts/sun8i-a83t-cubietruck-plus.dts @@ -58,8 +58,20 @@ }; }; +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_b>; status = "okay"; }; + +&usb_otg { + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-a83t.dtsi b/arch/arm/dts/sun8i-a83t.dtsi index d3473f81b1..0fe73e173f 100644 --- a/arch/arm/dts/sun8i-a83t.dtsi +++ b/arch/arm/dts/sun8i-a83t.dtsi @@ -224,5 +224,39 @@ #interrupt-cells = <3>; interrupts = ; }; + + usb_otg: usb@01c19000 { + compatible = "allwinner,sun8i-a33-musb"; + interrupts = ; + interrupt-names = "mc"; + status = "disabled"; + }; + + ehci0: usb@01c1a000 { + compatible = "allwinner,sun8i-a83t-ehci", "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = ; + status = "disabled"; + }; + + ohci0: usb@01c1a400 { + compatible = "allwinner,sun8i-a83t-ohci", "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = ; + status = "disabled"; + }; + + ehci1: usb@01c1b000 { + compatible = "allwinner,sun8i-a83t-ehci", "generic-ehci"; + reg = <0x01c1b000 0x100>; + interrupts = ; + status = "disabled"; + }; + + r_pio: pinctrl@01f02c00 { + compatible = "allwinner,sun8i-a83t-r-pinctrl"; + reg = <0x01f02c00 0x400>; + interrupts = ; + }; }; }; diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 6c0573fe58..3747f74d36 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 -#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) +#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ + defined(CONFIG_MACH_SUN50I) #include #elif defined(CONFIG_MACH_SUN9I) #include diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 9de7754bb0..f2990db928 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -350,10 +350,12 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31) -#ifndef CONFIG_MACH_SUN8I -#define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ -#else +#if defined(CONFIG_MACH_SUN50I) +#define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ +#elif defined(CONFIG_MACH_SUN8I) #define MBUS_CLK_DEFAULT 0x81000003 /* PLL6 / 4 */ +#else +#define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ #endif #define MBUS_CLK_GATE (0x1 << 31) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h b/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h index 5f93d7f39d..5e1346e524 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun8i_a83t.h @@ -224,14 +224,14 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY0_RST (0x1 << 0) #define CCM_USB_CTRL_PHY1_RST (0x1 << 1) -#define CCM_USB_CTRL_PHY2_RST (0x1 << 2) +#define CCM_USB_CTRL_HSIC_RST (0x1 << 2) /* There is no global phy clk gate on sun6i, define as 0 */ #define CCM_USB_CTRL_PHYGATE 0 #define CCM_USB_CTRL_PHY0_CLK (0x1 << 8) #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9) -#define CCM_USB_CTRL_PHY2_CLK (0x1 << 10) +#define CCM_USB_CTRL_HSIC_CLK (0x1 << 10) +#define CCM_USB_CTRL_12M_CLK (0x1 << 11) #define CCM_USB_CTRL_OHCI0_CLK (0x1 << 16) -#define CCM_USB_CTRL_OHCI1_CLK (0x1 << 17) #define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 649f6cd840..1ace548022 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 a129dd4ee0..ca9a4f99ad 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/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile new file mode 100644 index 0000000000..ad3d6c4918 --- /dev/null +++ b/arch/arm/mach-sunxi/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2012 Henrik Nordstrom +# +# Based on some other Makefile +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += board.o +obj-y += clock.o +obj-y += cpu_info.o +obj-y += dram_helpers.o +obj-y += pinmux.o +ifndef CONFIG_MACH_SUN9I +obj-y += usb_phy.o +endif +obj-$(CONFIG_MACH_SUN6I) += prcm.o +obj-$(CONFIG_MACH_SUN8I) += prcm.o +obj-$(CONFIG_MACH_SUN9I) += prcm.o +obj-$(CONFIG_MACH_SUN6I) += p2wi.o +obj-$(CONFIG_MACH_SUN8I) += rsb.o +obj-$(CONFIG_MACH_SUN9I) += rsb.o +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 +obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o +endif +obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o + +obj-$(CONFIG_AXP152_POWER) += pmic_bus.o +obj-$(CONFIG_AXP209_POWER) += pmic_bus.o +obj-$(CONFIG_AXP221_POWER) += pmic_bus.o +obj-$(CONFIG_AXP818_POWER) += pmic_bus.o + +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_MACH_SUN4I) += dram_sun4i.o +obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o +obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o +obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o +obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o +obj-$(CONFIG_MACH_SUN8I_A33) += dram_sun8i_a33.o +obj-$(CONFIG_MACH_SUN8I_A83T) += dram_sun8i_a83t.o +obj-$(CONFIG_MACH_SUN8I_H3) += dram_sun8i_h3.o +endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/mach-sunxi/board.c similarity index 85% rename from arch/arm/cpu/armv7/sunxi/board.c rename to arch/arm/mach-sunxi/board.c index 7653148c67..20149dabc8 100644 --- a/arch/arm/cpu/armv7/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 + +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); @@ -120,18 +148,30 @@ void s_init(void) */ #if defined CONFIG_MACH_SUN6I setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); -#elif defined CONFIG_MACH_SUN8I_A23 - uint version; +#elif defined CONFIG_MACH_SUN8I + __maybe_unused uint version; /* Unlock sram version info reg, read it, relock */ setbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15)); - version = readl(SUNXI_SRAMC_BASE + 0x24); + version = readl(SUNXI_SRAMC_BASE + 0x24) >> 16; clrbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15)); - if ((version & 0xffff0000) == 0x16500000) + /* + * Ideally this would be a switch case, but we do not know exactly + * which versions there are and which version needs which settings, + * so reproduce the per SoC code from the BSP. + */ +#if defined CONFIG_MACH_SUN8I_A23 + if (version == 0x1650) setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); else /* 0x1661 ? */ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0xc0); +#elif defined CONFIG_MACH_SUN8I_A33 + if (version != 0x1667) + setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0xc0); +#endif + /* A83T BSP never modifies SUNXI_SRAMC_BASE + 0x44 */ + /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif #if defined CONFIG_MACH_SUN6I || \ @@ -253,7 +293,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/cpu/armv7/sunxi/clock.c b/arch/arm/mach-sunxi/clock.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/clock.c rename to arch/arm/mach-sunxi/clock.c diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/mach-sunxi/clock_sun4i.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/clock_sun4i.c rename to arch/arm/mach-sunxi/clock_sun4i.c diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/clock_sun6i.c rename to arch/arm/mach-sunxi/clock_sun6i.c diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun8i_a83t.c b/arch/arm/mach-sunxi/clock_sun8i_a83t.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/clock_sun8i_a83t.c rename to arch/arm/mach-sunxi/clock_sun8i_a83t.c diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun9i.c b/arch/arm/mach-sunxi/clock_sun9i.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/clock_sun9i.c rename to arch/arm/mach-sunxi/clock_sun9i.c diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c similarity index 77% rename from arch/arm/cpu/armv7/sunxi/cpu_info.c rename to arch/arm/mach-sunxi/cpu_info.c index b9bc70ca86..76b6719d99 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -38,6 +38,20 @@ int sunxi_get_ss_bonding_id(void) } #endif +#ifdef CONFIG_MACH_SUN8I +uint sunxi_get_sram_id(void) +{ + uint id; + + /* Unlock sram info reg, read it, relock */ + setbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15)); + id = readl(SUNXI_SRAMC_BASE + 0x24) >> 16; + clrbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15)); + + return id; +} +#endif + #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { @@ -66,15 +80,17 @@ int print_cpuinfo(void) #elif defined CONFIG_MACH_SUN7I puts("CPU: Allwinner A20 (SUN7I)\n"); #elif defined CONFIG_MACH_SUN8I_A23 - puts("CPU: Allwinner A23 (SUN8I)\n"); + printf("CPU: Allwinner A23 (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN8I_A33 - puts("CPU: Allwinner A33 (SUN8I)\n"); + printf("CPU: Allwinner A33 (SUN8I %04x)\n", sunxi_get_sram_id()); +#elif defined CONFIG_MACH_SUN8I_A83T + printf("CPU: Allwinner A83T (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN8I_H3 - puts("CPU: Allwinner H3 (SUN8I)\n"); + printf("CPU: Allwinner H3 (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN9I 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"); @@ -91,7 +107,7 @@ int sunxi_get_sid(unsigned int *sid) int i; for (i = 0; i< 4; i++) - sid[i] = readl(SUNXI_SID_BASE + 4 * i); + sid[i] = readl((ulong)SUNXI_SID_BASE + 4 * i); return 0; #else diff --git a/arch/arm/cpu/armv7/sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c similarity index 87% rename from arch/arm/cpu/armv7/sunxi/dram_helpers.c rename to arch/arm/mach-sunxi/dram_helpers.c index 9a94e1b679..50318d2eb6 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_helpers.c +++ b/arch/arm/mach-sunxi/dram_helpers.c @@ -30,8 +30,8 @@ bool mctl_mem_matches(u32 offset) { /* Try to write different values to RAM at two addresses */ writel(0, CONFIG_SYS_SDRAM_BASE); - writel(0xaa55aa55, CONFIG_SYS_SDRAM_BASE + offset); + writel(0xaa55aa55, (ulong)CONFIG_SYS_SDRAM_BASE + offset); /* Check if the same value is actually observed when reading back */ return readl(CONFIG_SYS_SDRAM_BASE) == - readl(CONFIG_SYS_SDRAM_BASE + offset); + readl((ulong)CONFIG_SYS_SDRAM_BASE + offset); } diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun4i.c b/arch/arm/mach-sunxi/dram_sun4i.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun4i.c rename to arch/arm/mach-sunxi/dram_sun4i.c diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun6i.c b/arch/arm/mach-sunxi/dram_sun6i.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun6i.c rename to arch/arm/mach-sunxi/dram_sun6i.c diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a23.c b/arch/arm/mach-sunxi/dram_sun8i_a23.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun8i_a23.c rename to arch/arm/mach-sunxi/dram_sun8i_a23.c diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c rename to arch/arm/mach-sunxi/dram_sun8i_a33.c diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c b/arch/arm/mach-sunxi/dram_sun8i_a83t.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c rename to arch/arm/mach-sunxi/dram_sun8i_a83t.c diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c rename to arch/arm/mach-sunxi/dram_sun8i_h3.c diff --git a/arch/arm/cpu/armv7/sunxi/p2wi.c b/arch/arm/mach-sunxi/p2wi.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/p2wi.c rename to arch/arm/mach-sunxi/p2wi.c diff --git a/arch/arm/cpu/armv7/sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/pinmux.c rename to arch/arm/mach-sunxi/pinmux.c diff --git a/arch/arm/cpu/armv7/sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/pmic_bus.c rename to arch/arm/mach-sunxi/pmic_bus.c diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/mach-sunxi/prcm.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/prcm.c rename to arch/arm/mach-sunxi/prcm.c diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/mach-sunxi/rsb.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/rsb.c rename to arch/arm/mach-sunxi/rsb.c diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c similarity index 86% rename from arch/arm/cpu/armv7/sunxi/usb_phy.c rename to arch/arm/mach-sunxi/usb_phy.c index 0749fbdadc..b258ce4443 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/mach-sunxi/usb_phy.c @@ -34,6 +34,16 @@ #define REG_PHY_UNK_H3 0x420 #define REG_PMU_UNK_H3 0x810 +/* A83T specific control bits for PHY0 */ +#define SUNXI_PHY_CTL_VBUSVLDEXT BIT(5) +#define SUNXI_PHY_CTL_SIDDQ BIT(3) + +/* A83T HSIC specific bits */ +#define SUNXI_EHCI_HS_FORCE BIT(20) +#define SUNXI_EHCI_CONNECT_DET BIT(17) +#define SUNXI_EHCI_CONNECT_INT BIT(16) +#define SUNXI_EHCI_HSIC BIT(1) + static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus; @@ -42,7 +52,7 @@ static struct sunxi_usb_phy { int id; int init_count; int power_on_count; - int base; + ulong base; } sunxi_usb_phy[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, @@ -56,7 +66,12 @@ static struct sunxi_usb_phy { }, #if CONFIG_SUNXI_USB_PHYS >= 3 { +#ifdef CONFIG_MACH_SUN8I_A83T + .usb_rst_mask = CCM_USB_CTRL_HSIC_RST | CCM_USB_CTRL_HSIC_CLK | + CCM_USB_CTRL_12M_CLK, +#else .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, +#endif .id = 2, .base = SUNXI_USB2_BASE, }, @@ -97,8 +112,8 @@ static int get_id_detect_gpio(int index) return -EINVAL; } -static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, - int data, int len) +__maybe_unused static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, + int data, int len) { int j = 0, usbc_bit = 0; void *dest = (void *)SUNXI_USB0_BASE + SUNXI_USB_CSR; @@ -137,6 +152,10 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) clrbits_le32(phy->base + REG_PMU_UNK_H3, 0x02); } +#elif defined CONFIG_MACH_SUN8I_A83T +static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) +{ +} #else static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) { @@ -174,6 +193,13 @@ static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) SUNXI_EHCI_AHB_INCRX_ALIGN_EN | SUNXI_EHCI_ULPI_BYPASS_EN; +#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 2) + bits |= SUNXI_EHCI_HS_FORCE | + SUNXI_EHCI_CONNECT_INT | + SUNXI_EHCI_HSIC; +#endif + if (enable) setbits_le32(addr, bits); else @@ -184,9 +210,11 @@ static void sunxi_usb_phy_passby(struct sunxi_usb_phy *phy, int enable) void sunxi_usb_phy_enable_squelch_detect(int index, int enable) { +#ifndef CONFIG_MACH_SUN8I_A83T struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; usb_phy_write(phy, 0x3c, enable ? 0 : 2, 2); +#endif } void sunxi_usb_phy_init(int index) @@ -204,6 +232,15 @@ void sunxi_usb_phy_init(int index) if (phy->id != 0) sunxi_usb_phy_passby(phy, SUNXI_USB_PASSBY_EN); + +#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 0) { + setbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_VBUSVLDEXT); + clrbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_SIDDQ); + } +#endif } void sunxi_usb_phy_exit(int index) @@ -218,6 +255,13 @@ void sunxi_usb_phy_exit(int index) if (phy->id != 0) sunxi_usb_phy_passby(phy, !SUNXI_USB_PASSBY_EN); +#ifdef CONFIG_MACH_SUN8I_A83T + if (phy->id == 0) { + setbits_le32(SUNXI_USB0_BASE + SUNXI_USB_CSR, + SUNXI_PHY_CTL_SIDDQ); + } +#endif + clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); } diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 5e72fac7f9..464fa0fa58 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/MAINTAINERS b/board/sunxi/MAINTAINERS index 5f2f4fed8a..430d770cd2 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -63,6 +63,8 @@ F: configs/q8_a33_tablet_800x480_defconfig F: configs/q8_a33_tablet_1024x600_defconfig F: include/configs/sun9i.h F: configs/Merrii_A80_Optimus_defconfig +F: include/configs/sun50i.h +F: configs/pine64_plus_defconfig A20-OLIMEX-SOM-EVB BOARD M: Marcus Cooper diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 2d5335f953..3cf36147b2 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -21,6 +21,9 @@ #include #include #include +#ifndef CONFIG_ARM64 +#include +#endif #include #include #include @@ -73,18 +76,38 @@ DECLARE_GLOBAL_DATA_PTR; /* add board specific code here */ int board_init(void) { - int id_pfr1, ret; + __maybe_unused int id_pfr1, 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) @@ -110,6 +133,15 @@ int dram_init(void) return 0; } +#ifdef CONFIG_MACH_SUN50I +void dram_init_banksize(void) +{ + /* We need to reserve the first 16MB of RAM for ATF */ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE + (16 * 1024 * 1024); + gd->bd->bi_dram[0].size = get_effective_memsize() - (16 * 1024 * 1024); +} +#endif + #if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) static void nand_pinmux_setup(void) { @@ -264,7 +296,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); @@ -486,6 +518,12 @@ void sunxi_board_init(void) power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); #endif + +#ifdef CONFIG_AXP818_POWER + power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT); + power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT); + power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT); +#endif #endif printf("DRAM:"); ramsize = sunxi_dram_init(); @@ -541,7 +579,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/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig index af96f5bd12..25b48d9cb5 100644 --- a/configs/A10-OLinuXino-Lime_defconfig +++ b/configs/A10-OLinuXino-Lime_defconfig @@ -13,4 +13,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3)" # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_AXP_ALDO3_VOLT=2800 +CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index b5181c6880..419cdfb5ee 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -13,5 +13,8 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3)" # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_RTL8211X_PHY_FORCE_MASTER=y CONFIG_ETH_DESIGNWARE=y +CONFIG_AXP_ALDO3_VOLT=2800 +CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index e27698d0dd..151a0a3d3a 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -12,4 +12,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPC(3)" # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y CONFIG_ETH_DESIGNWARE=y +CONFIG_AXP_ALDO3_VOLT=2800 +CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig index 001d31bad5..1603b6fffe 100644 --- a/configs/A20-Olimex-SOM-EVB_defconfig +++ b/configs/A20-Olimex-SOM-EVB_defconfig @@ -16,5 +16,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3)" # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set CONFIG_CMD_GPIO=y +CONFIG_RTL8211X_PHY_FORCE_MASTER=y CONFIG_ETH_DESIGNWARE=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Cubietruck_plus_defconfig b/configs/Cubietruck_plus_defconfig index bb0b336a76..d625c21fcb 100644 --- a/configs/Cubietruck_plus_defconfig +++ b/configs/Cubietruck_plus_defconfig @@ -6,13 +6,21 @@ CONFIG_DRAM_ZQ=15355 CONFIG_DRAM_ODT_EN=y CONFIG_MMC0_CD_PIN="PF6" CONFIG_I2C0_ENABLE=y +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_USB0_ID_DET="PH11" +CONFIG_USB1_VBUS_PIN="PD29" +CONFIG_USB2_VBUS_PIN="PL6" CONFIG_AXP_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-cubietruck-plus" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPD(20)" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y CONFIG_AXP_DLDO3_VOLT=2500 CONFIG_AXP_DLDO4_VOLT=3300 +CONFIG_AXP_FLDO1_VOLT=1200 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_MUSB_HOST=y diff --git a/configs/h8_homlet_v2_defconfig b/configs/h8_homlet_v2_defconfig index 4742aaf693..e04d96bee8 100644 --- a/configs/h8_homlet_v2_defconfig +++ b/configs/h8_homlet_v2_defconfig @@ -4,6 +4,9 @@ CONFIG_MACH_SUN8I_A83T=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=15355 CONFIG_DRAM_ODT_EN=y +CONFIG_MMC0_CD_PIN="PF6" +CONFIG_USB0_VBUS_PIN="PL5" +CONFIG_USB1_VBUS_PIN="PL6" CONFIG_AXP_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-allwinner-h8homlet-v2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set @@ -11,5 +14,6 @@ CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set -CONFIG_AXP_DCDC1_VOLT=3000 -CONFIG_AXP_DCDC5_VOLT=1500 +CONFIG_AXP_DLDO4_VOLT=3300 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_MUSB_HOST=y diff --git a/configs/pine64_plus_defconfig b/configs/pine64_plus_defconfig new file mode 100644 index 0000000000..c37d378ab7 --- /dev/null +++ b/configs/pine64_plus_defconfig @@ -0,0 +1,12 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN50I=y +CONFIG_DRAM_CLK=672 +CONFIG_DRAM_ZQ=3881915 +# CONFIG_VIDEO is not set +CONFIG_DEFAULT_DEVICE_TREE="pine64_plus" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index bd2ac892d0..ec00827f8f 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -59,10 +59,11 @@ static int axp_gpio_direction_output(struct udevice *dev, unsigned pin, u8 reg; switch (pin) { -#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ +#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC + /* Only available on later PMICs */ case SUNXI_GPIO_AXP0_VBUS_ENABLE: - ret = pmic_bus_clrbits(AXP221_MISC_CTRL, - AXP221_MISC_CTRL_N_VBUSEN_FUNC); + ret = pmic_bus_clrbits(AXP_MISC_CTRL, + AXP_MISC_CTRL_N_VBUSEN_FUNC); if (ret) return ret; @@ -90,10 +91,11 @@ static int axp_gpio_get_value(struct udevice *dev, unsigned pin) mask = AXP_POWER_STATUS_VBUS_PRESENT; break; #endif -#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ +#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC + /* Only available on later PMICs */ case SUNXI_GPIO_AXP0_VBUS_ENABLE: - ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val); - mask = AXP221_VBUS_IPSOUT_DRIVEBUS; + ret = pmic_bus_read(AXP_VBUS_IPSOUT, &val); + mask = AXP_VBUS_IPSOUT_DRIVEBUS; break; #endif default: @@ -115,14 +117,15 @@ static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) u8 reg; switch (pin) { -#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */ +#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC + /* Only available on later PMICs */ case SUNXI_GPIO_AXP0_VBUS_ENABLE: if (val) - return pmic_bus_setbits(AXP221_VBUS_IPSOUT, - AXP221_VBUS_IPSOUT_DRIVEBUS); + return pmic_bus_setbits(AXP_VBUS_IPSOUT, + AXP_VBUS_IPSOUT_DRIVEBUS); else - return pmic_bus_clrbits(AXP221_VBUS_IPSOUT, - AXP221_VBUS_IPSOUT_DRIVEBUS); + return pmic_bus_clrbits(AXP_VBUS_IPSOUT, + AXP_VBUS_IPSOUT_DRIVEBUS); #endif default: reg = axp_get_gpio_ctrl_reg(pin); diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 7b33094d84..ce2dc4ae41 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -339,7 +339,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; if (data) { - if ((u32) data->dest & 0x3) { + if ((u32)(long)data->dest & 0x3) { error = -1; goto out; } @@ -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/net/Kconfig b/drivers/net/Kconfig index 2a229b8999..e0008fd1a4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -13,6 +13,27 @@ config PHYLIB help Enable Ethernet PHY (physical media interface) support. +config RTL8211X_PHY_FORCE_MASTER + bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode" + depends on PHYLIB + help + Force master mode for 1000BASE-T on RTl8211x PHYs (except for RTL8211F). + This can work around link stability and data corruption issues on gigabit + links which can occur in slave mode on certain PHYs, e.g. on the + RTL8211C(L). + + Please note that two directly connected devices (i.e. via crossover cable) + will not be able to establish a link between each other if they both force + master mode. Multiple devices forcing master mode when connected by a + network switch do not pose a problem as the switch configures its affected + ports into slave mode. + + This option only affects gigabit links. If you must establish a direct + connection between two devices which both force master mode, try forcing + the link speed to 100MBit/s. + + If unsure, say N. + menuconfig NETDEVICES bool "Network device support" depends on NET diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 259a87fcc5..359ec5048e 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -12,6 +12,10 @@ #define PHY_AUTONEGOTIATE_TIMEOUT 5000 +/* RTL8211x 1000BASE-T Control Register */ +#define MIIM_RTL8211x_CTRL1000T_MSCE (1 << 12); +#define MIIM_RTL8211X_CTRL1000T_MASTER (1 << 11); + /* RTL8211x PHY Status Register */ #define MIIM_RTL8211x_PHY_STATUS 0x11 #define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000 @@ -53,7 +57,14 @@ static int rtl8211x_config(struct phy_device *phydev) */ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, MIIM_RTL8211x_PHY_INTR_DIS); - +#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER + unsigned int reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); + /* force manual master/slave configuration */ + reg |= MIIM_RTL8211x_CTRL1000T_MSCE; + /* force master mode */ + reg |= MIIM_RTL8211X_CTRL1000T_MASTER; + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); +#endif /* read interrupt status just to clear it */ phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index adc64552e7..3c41bca32a 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" @@ -118,13 +118,12 @@ config AXP_DCDC4_VOLT config AXP_DCDC5_VOLT int "axp pmic dcdc5 voltage" depends on AXP221_POWER || AXP818_POWER - default 1800 if AXP818_POWER default 1500 if MACH_SUN6I || MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to disable dcdc5. On A23 / A31 / A33 / A83T boards dcdc5 is VCC-DRAM and should be 1.5V, - 1.8V for A83T. + 1.35V if DDR3L is used. config AXP_ALDO1_VOLT int "axp pmic (a)ldo1 voltage" @@ -239,6 +238,33 @@ config AXP_ELDO3_VOLT 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). +config AXP_FLDO1_VOLT + int "axp pmic fldo1 voltage" + depends on AXP818_POWER + default 0 if MACH_SUN8I_A83T + ---help--- + Set the voltage (mV) to program the axp pmic fldo1 at, set to 0 to + disable fldo1. + On A83T / H8 boards fldo1 is VCC-HSIC and should be 1.2V if HSIC is + used. + +config AXP_FLDO2_VOLT + int "axp pmic eldo2 voltage" + depends on AXP818_POWER + default 900 if MACH_SUN8I_A83T + ---help--- + Set the voltage (mV) to program the axp pmic fldo2 at, set to 0 to + disable fldo2. + On A83T / H8 boards fldo2 is VCC-CPUS and should be 0.9V. + +config AXP_FLDO3_VOLT + int "axp pmic fldo3 voltage" + depends on AXP818_POWER + default 0 + ---help--- + Set the voltage (mV) to program the axp pmic fldo3 at, set to 0 to + disable fldo3. + config SY8106A_VOUT1_VOLT int "SY8106A pmic VOUT1 voltage" depends on SY8106A_POWER diff --git a/drivers/power/axp818.c b/drivers/power/axp818.c index e885d02984..3ac05ffefe 100644 --- a/drivers/power/axp818.c +++ b/drivers/power/axp818.c @@ -191,6 +191,40 @@ int axp_set_eldo(int eldo_num, unsigned int mvolt) AXP818_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); } +int axp_set_fldo(int fldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg; + + if (fldo_num < 1 || fldo_num > 3) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP818_OUTPUT_CTRL3, + AXP818_OUTPUT_CTRL3_FLDO1_EN << (fldo_num - 1)); + + if (fldo_num < 3) { + cfg = axp818_mvolt_to_cfg(mvolt, 700, 1450, 50); + ret = pmic_bus_write(AXP818_FLDO1_CTRL + (fldo_num - 1), cfg); + } else { + /* + * Special case for FLDO3, which is DCDC5 / 2 or FLDOIN / 2 + * Since FLDOIN is unknown, test against DCDC5. + */ + if (mvolt * 2 == CONFIG_AXP_DCDC5_VOLT) + ret = pmic_bus_clrbits(AXP818_FLDO2_3_CTRL, + AXP818_FLDO2_3_CTRL_FLDO3_VOL); + else + ret = pmic_bus_setbits(AXP818_FLDO2_3_CTRL, + AXP818_FLDO2_3_CTRL_FLDO3_VOL); + } + if (ret) + return ret; + + return pmic_bus_setbits(AXP818_OUTPUT_CTRL3, + AXP818_OUTPUT_CTRL3_FLDO1_EN << (fldo_num - 1)); +} + int axp_init(void) { u8 axp_chip_id; diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index 677a5d3b07..d5eb492169 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -91,6 +91,7 @@ static const struct udevice_id ehci_usb_ids[] = { { .compatible = "allwinner,sun6i-a31-ehci", }, { .compatible = "allwinner,sun7i-a20-ehci", }, { .compatible = "allwinner,sun8i-a23-ehci", }, + { .compatible = "allwinner,sun8i-a83t-ehci", }, { .compatible = "allwinner,sun8i-h3-ehci", }, { .compatible = "allwinner,sun9i-a80-ehci", }, { } diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c index d4fb95abe1..6f3f4cec16 100644 --- a/drivers/usb/host/ohci-sunxi.c +++ b/drivers/usb/host/ohci-sunxi.c @@ -94,6 +94,7 @@ static const struct udevice_id ohci_usb_ids[] = { { .compatible = "allwinner,sun6i-a31-ohci", }, { .compatible = "allwinner,sun7i-a20-ohci", }, { .compatible = "allwinner,sun8i-a23-ohci", }, + { .compatible = "allwinner,sun8i-a83t-ohci", }, { .compatible = "allwinner,sun8i-h3-ohci", }, { .compatible = "allwinner,sun9i-a80-ohci", }, { } diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h index 4dc9abbe02..0f18dd7f7e 100644 --- a/drivers/usb/musb-new/musb_regs.h +++ b/drivers/usb/musb-new/musb_regs.h @@ -434,7 +434,7 @@ static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) static inline u8 musb_read_configdata(void __iomem *mbase) { -#ifdef CONFIG_MACH_SUN8I_A33 +#if defined CONFIG_MACH_SUN8I_A33 || defined CONFIG_MACH_SUN8I_A83T /* allwinner saves a reg, and we need to hardcode this */ return 0xde; #else diff --git a/include/axp221.h b/include/axp221.h index 04cd8c2be4..b4b64b0e87 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -43,12 +43,8 @@ #define AXP221_ALDO1_CTRL 0x28 #define AXP221_ALDO2_CTRL 0x29 #define AXP221_ALDO3_CTRL 0x2a -#define AXP221_VBUS_IPSOUT 0x30 -#define AXP221_VBUS_IPSOUT_DRIVEBUS (1 << 2) #define AXP221_SHUTDOWN 0x32 #define AXP221_SHUTDOWN_POWEROFF (1 << 7) -#define AXP221_MISC_CTRL 0x8f -#define AXP221_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) #define AXP221_PAGE 0xff /* Page 1 addresses */ @@ -57,6 +53,10 @@ /* For axp_gpio.c */ #define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_VBUS_IPSOUT 0x30 +#define AXP_VBUS_IPSOUT_DRIVEBUS (1 << 2) +#define AXP_MISC_CTRL 0x8f +#define AXP_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) #define AXP_GPIO0_CTRL 0x90 #define AXP_GPIO1_CTRL 0x92 #define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ diff --git a/include/axp818.h b/include/axp818.h index 46d05ad04b..5630eed04d 100644 --- a/include/axp818.h +++ b/include/axp818.h @@ -41,6 +41,7 @@ #define AXP818_ELDO3_CTRL 0x1b #define AXP818_FLDO1_CTRL 0x1c #define AXP818_FLDO2_3_CTRL 0x1d +#define AXP818_FLDO2_3_CTRL_FLDO3_VOL (1 << 4) #define AXP818_DCDC1_CTRL 0x20 #define AXP818_DCDC2_CTRL 0x21 #define AXP818_DCDC3_CTRL 0x22 @@ -53,11 +54,13 @@ #define AXP818_ALDO2_CTRL 0x29 #define AXP818_ALDO3_CTRL 0x2a -int axp818_init(void); - /* For axp_gpio.c */ #define AXP_POWER_STATUS 0x00 -#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_VBUS_IPSOUT 0x30 +#define AXP_VBUS_IPSOUT_DRIVEBUS (1 << 2) +#define AXP_MISC_CTRL 0x8f +#define AXP_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) #define AXP_GPIO0_CTRL 0x90 #define AXP_GPIO1_CTRL 0x92 #define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ diff --git a/include/axp_pmic.h b/include/axp_pmic.h index 0f14683509..b203cc88dd 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -31,6 +31,7 @@ int axp_set_aldo3(unsigned int mvolt); int axp_set_aldo4(unsigned int mvolt); int axp_set_dldo(int dldo_num, unsigned int mvolt); int axp_set_eldo(int eldo_num, unsigned int mvolt); +int axp_set_fldo(int fldo_num, unsigned int mvolt); int axp_init(void); int axp_get_sid(unsigned int *sid); diff --git a/include/configs/sun50i.h b/include/configs/sun50i.h new file mode 100644 index 0000000000..0fdb4c7b99 --- /dev/null +++ b/include/configs/sun50i.h @@ -0,0 +1,25 @@ +/* + * Configuration settings for the Allwinner A64 (sun50i) CPU + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * A64 specific configuration + */ + +#define CONFIG_SUNXI_USB_PHYS 1 + +#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 + +#endif /* __CONFIG_H */ diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h index 93863b59bc..95ccc35708 100644 --- a/include/configs/sun6i.h +++ b/include/configs/sun6i.h @@ -25,7 +25,6 @@ #define CONFIG_ARMV7_PSCI 1 #define CONFIG_ARMV7_PSCI_NR_CPUS 4 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE -#define CONFIG_TIMER_CLK_FREQ 24000000 /* * Include common sunxi configuration where most the settings are diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index 56101a9ffc..0dd29029b9 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -22,7 +22,6 @@ #define CONFIG_ARMV7_PSCI 1 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE -#define CONFIG_TIMER_CLK_FREQ 24000000 /* * Include common sunxi configuration where most the settings are diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 7c0ab1eab4..bf1b740b18 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -20,6 +20,8 @@ #ifdef CONFIG_MACH_SUN8I_H3 #define CONFIG_SUNXI_USB_PHYS 4 +#elif defined CONFIG_MACH_SUN8I_A83T + #define CONFIG_SUNXI_USB_PHYS 3 #else #define CONFIG_SUNXI_USB_PHYS 2 #endif @@ -38,8 +40,6 @@ #endif #endif -#define CONFIG_TIMER_CLK_FREQ 24000000 - /* * Include common sunxi configuration where most the settings are */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index a3994e1a6a..8f11eb90c1 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -56,6 +56,7 @@ /* CPU */ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_SYS_CACHELINE_SIZE 64 +#define CONFIG_TIMER_CLK_FREQ 24000000 /* * The DRAM Base differs between some models. We cannot use macros for the @@ -90,7 +91,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 +100,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 +189,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 +206,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 || \