Browse Source

Merge branch 'master' of http://git.denx.de/u-boot-sunxi

Tom Rini 9 years ago
parent
commit
b7e84c93c4

+ 1 - 0
arch/arm/cpu/armv7/sunxi/Makefile

@@ -28,6 +28,7 @@ obj-$(CONFIG_MACH_SUN6I)	+= clock_sun6i.o
 obj-$(CONFIG_MACH_SUN7I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN7I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN8I)	+= clock_sun6i.o
 obj-$(CONFIG_MACH_SUN8I)	+= clock_sun6i.o
 obj-$(CONFIG_MACH_SUN9I)	+= clock_sun9i.o
 obj-$(CONFIG_MACH_SUN9I)	+= clock_sun9i.o
+obj-$(CONFIG_MACH_SUN6I)	+= tzpc.o
 
 
 obj-$(CONFIG_AXP152_POWER)	+= pmic_bus.o
 obj-$(CONFIG_AXP152_POWER)	+= pmic_bus.o
 obj-$(CONFIG_AXP209_POWER)	+= pmic_bus.o
 obj-$(CONFIG_AXP209_POWER)	+= pmic_bus.o

+ 5 - 0
arch/arm/cpu/armv7/sunxi/board.c

@@ -23,6 +23,7 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/timer.h>
 #include <asm/arch/timer.h>
+#include <asm/arch/tzpc.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/mmc.h>
 
 
 #include <linux/compiler.h>
 #include <linux/compiler.h>
@@ -115,6 +116,10 @@ void s_init(void)
 		"orr r0, r0, #1 << 6\n"
 		"orr r0, r0, #1 << 6\n"
 		"mcr p15, 0, r0, c1, c0, 1\n");
 		"mcr p15, 0, r0, c1, c0, 1\n");
 #endif
 #endif
+#if defined CONFIG_MACH_SUN6I
+	/* Enable non-secure access to the RTC */
+	tzpc_init();
+#endif
 
 
 	clock_init();
 	clock_init();
 	timer_init();
 	timer_init();

+ 18 - 0
arch/arm/cpu/armv7/sunxi/tzpc.c

@@ -0,0 +1,18 @@
+/*
+ * (C) Copyright 2015 Chen-Yu Tsai <wens@csie.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/tzpc.h>
+
+/* Configure Trust Zone Protection Controller */
+void tzpc_init(void)
+{
+	struct sunxi_tzpc *tzpc = (struct sunxi_tzpc *)SUNXI_TZPC_BASE;
+
+	/* Enable non-secure access to the RTC */
+	writel(SUNXI_TZPC_DECPORT0_RTC, &tzpc->decport0_set);
+}

+ 3 - 0
arch/arm/dts/Makefile

@@ -96,6 +96,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
 	sun5i-a13-forfun-q88db.dtb \
 	sun5i-a13-forfun-q88db.dtb \
 	sun5i-a13-hsg-h702.dtb \
 	sun5i-a13-hsg-h702.dtb \
 	sun5i-a13-inet-86vs.dtb \
 	sun5i-a13-inet-86vs.dtb \
+	sun5i-a13-inet-98v-rev2.dtb \
 	sun5i-a13-olinuxino.dtb \
 	sun5i-a13-olinuxino.dtb \
 	sun5i-a13-olinuxino-micro.dtb \
 	sun5i-a13-olinuxino-micro.dtb \
 	sun5i-a13-tzx-q8-713b7.dtb \
 	sun5i-a13-tzx-q8-713b7.dtb \
@@ -121,6 +122,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-m3.dtb \
 	sun7i-a20-m3.dtb \
 	sun7i-a20-m5.dtb \
 	sun7i-a20-m5.dtb \
 	sun7i-a20-mk808c.dtb \
 	sun7i-a20-mk808c.dtb \
+	sun7i-a20-olimex-som-evb.dtb \
 	sun7i-a20-olinuxino-lime.dtb \
 	sun7i-a20-olinuxino-lime.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-micro.dtb \
 	sun7i-a20-olinuxino-micro.dtb \
@@ -134,6 +136,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-yones-toptech-bd1078.dtb
 	sun7i-a20-yones-toptech-bd1078.dtb
 dtb-$(CONFIG_MACH_SUN8I_A23) += \
 dtb-$(CONFIG_MACH_SUN8I_A23) += \
 	sun8i-a23-evb.dtb \
 	sun8i-a23-evb.dtb \
+	sun8i-a23-gt90h-v4.dtb \
 	sun8i-a23-ippo-q8h-v5.dtb \
 	sun8i-a23-ippo-q8h-v5.dtb \
 	sun8i-a23-ippo-q8h-v1.2.dtb
 	sun8i-a23-ippo-q8h-v1.2.dtb
 dtb-$(CONFIG_MACH_SUN8I_A33) += \
 dtb-$(CONFIG_MACH_SUN8I_A33) += \

+ 236 - 0
arch/arm/dts/sun5i-a13-inet-98v-rev2.dts

@@ -0,0 +1,236 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.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.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "INet-98V Rev 02";
+	compatible = "primux,inet98v-rev2", "allwinner,sun5i-a13";
+
+	aliases {
+		serial0 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic@34 {
+		reg = <0x34>;
+		interrupts = <0>;
+	};
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+
+	pcf8563: rtc@51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lradc {
+	vref-supply = <&reg_ldo2>;
+	status = "okay";
+
+	button@200 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <200000>;
+	};
+
+	button@400 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <400000>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+	cd-inverted;
+	status = "okay";
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins_a>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+
+	mmccard: mmccard@0 {
+		reg = <0>;
+		compatible = "mmc-card";
+		broken-hpi;
+	};
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_inet98fv2: mmc0_cd_pin@0 {
+		allwinner,pins = "PG0";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1250000>;
+	regulator-max-microvolt = <1250000>;
+	regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_usb0_vbus {
+	gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins_b>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb0_vbus_pin_a {
+	allwinner,pins = "PG12";
+};
+
+&usb1_vbus_pin_a {
+	allwinner,pins = "PG11";
+};
+
+&usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	status = "okay";
+};

+ 244 - 0
arch/arm/dts/sun7i-a20-olimex-som-evb.dts

@@ -0,0 +1,244 @@
+/*
+ * Copyright 2015 - Marcus Cooper <codekipper@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.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Olimex A20-Olimex-SOM-EVB";
+	compatible = "olimex,a20-olimex-som-evb", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_olimex_som_evb>;
+
+		green {
+			label = "a20-olimex-som-evb:green:usr";
+			gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	reg_axp_ipsout: axp_ipsout {
+		compatible = "regulator-fixed";
+		regulator-name = "axp-ipsout";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	phy = <&phy1>;
+	phy-mode = "rgmii";
+	status = "okay";
+
+	phy1: ethernet-phy@1 {
+		reg = <1>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic@34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	ahci_pwr_pin_olimex_som_evb: ahci_pwr_pin@1 {
+		allwinner,pins = "PC3";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	led_pins_olimex_som_evb: led_pins@0 {
+		allwinner,pins = "PH2";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PH04";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PH05";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&reg_ahci_5v {
+	pinctrl-0 = <&ahci_pwr_pin_olimex_som_evb>;
+	gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1425000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpios = <&pio 7 04 GPIO_ACTIVE_HIGH>; /* PH04 */
+	usb0_vbus_det-gpios = <&pio 7 05 GPIO_ACTIVE_HIGH>; /* PH05 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};

+ 145 - 0
arch/arm/dts/sun8i-a23-gt90h-v4.dts

@@ -0,0 +1,145 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.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.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Allwinner GT90H Quad Core Tablet (v4)";
+	compatible = "allwinner,gt90h-v4", "allwinner,sun8i-a33";
+
+	aliases {
+		serial0 = &r_uart;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&lradc {
+	vref-supply = <&reg_vcc3v0>;
+	status = "okay";
+
+	button@200 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <200000>;
+	};
+
+	button@400 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <400000>;
+	};
+
+	button@600 {
+		label = "Back";
+		linux,code = <KEY_BACK>;
+		channel = <0>;
+		voltage = <600000>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gt90h>;
+	/* FIXME this really is aldo1, correct once we've pmic support */
+	vmmc-supply = <&reg_vcc3v0>;
+	bus-width = <4>;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+	cd-inverted;
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_gt90h: mmc0_cd_pin@0 {
+		allwinner,pins = "PB4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&r_uart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&r_uart_pins_a>;
+	status = "okay";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};

+ 23 - 0
arch/arm/include/asm/arch-sunxi/tzpc.h

@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2015 Chen-Yu Tsai <wens@csie.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_TZPC_H
+#define _SUNXI_TZPC_H
+
+#ifndef __ASSEMBLY__
+struct sunxi_tzpc {
+	u32 r0size;		/* 0x00 Size of secure RAM region */
+	u32 decport0_status;	/* 0x04 Status of decode protection port 0 */
+	u32 decport0_set;	/* 0x08 Set decode protection port 0 */
+	u32 decport0_clear;	/* 0x0c Clear decode protection port 0 */
+};
+#endif
+
+#define SUNXI_TZPC_DECPORT0_RTC	(1 << 1)
+
+void tzpc_init(void);
+
+#endif /* _SUNXI_TZPC_H */

+ 1 - 0
board/sunxi/Kconfig

@@ -425,6 +425,7 @@ config VIDEO_LCD_MODE
 	LCD panel timing details string, leave empty if there is no LCD panel.
 	LCD panel timing details string, leave empty if there is no LCD panel.
 	This is in drivers/video/videomodes.c: video_get_params() format, e.g.
 	This is in drivers/video/videomodes.c: video_get_params() format, e.g.
 	x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0
 	x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0
+	Also see: http://linux-sunxi.org/LCD
 
 
 config VIDEO_LCD_DCLK_PHASE
 config VIDEO_LCD_DCLK_PHASE
 	int "LCD panel display clock phase"
 	int "LCD panel display clock phase"

+ 9 - 1
board/sunxi/MAINTAINERS

@@ -8,9 +8,9 @@ F:	configs/ba10_tv_box_defconfig
 F:	configs/Chuwi_V7_CW0825_defconfig
 F:	configs/Chuwi_V7_CW0825_defconfig
 F:	configs/Cubieboard_defconfig
 F:	configs/Cubieboard_defconfig
 F:	configs/Hyundai_A7HD_defconfig
 F:	configs/Hyundai_A7HD_defconfig
+F:	configs/inet97fv2_defconfig
 F:	configs/jesurun_q5_defconfig
 F:	configs/jesurun_q5_defconfig
 F:	configs/Mele_A1000_defconfig
 F:	configs/Mele_A1000_defconfig
-F:	configs/Mele_A1000G_quad_defconfig
 F:	configs/Mele_M3_defconfig
 F:	configs/Mele_M3_defconfig
 F:	configs/Mini-X_defconfig
 F:	configs/Mini-X_defconfig
 F:	configs/mk802_defconfig
 F:	configs/mk802_defconfig
@@ -21,11 +21,13 @@ F:	configs/A13-OLinuXino_defconfig
 F:	configs/A13-OLinuXinoM_defconfig
 F:	configs/A13-OLinuXinoM_defconfig
 F:	configs/Auxtek-T003_defconfig
 F:	configs/Auxtek-T003_defconfig
 F:	configs/Auxtek-T004_defconfig
 F:	configs/Auxtek-T004_defconfig
+F:	configs/inet98v_rev2_defconfig
 F:	configs/mk802_a10s_defconfig
 F:	configs/mk802_a10s_defconfig
 F:	configs/r7-tv-dongle_defconfig
 F:	configs/r7-tv-dongle_defconfig
 F:	configs/UTOO_P66_defconfig
 F:	configs/UTOO_P66_defconfig
 F:	include/configs/sun6i.h
 F:	include/configs/sun6i.h
 F:	configs/CSQ_CS908_defconfig
 F:	configs/CSQ_CS908_defconfig
+F:	configs/Mele_A1000G_quad_defconfig
 F:	configs/Mele_M9_defconfig
 F:	configs/Mele_M9_defconfig
 F:	include/configs/sun7i.h
 F:	include/configs/sun7i.h
 F:	configs/A20-OLinuXino_MICRO_defconfig
 F:	configs/A20-OLinuXino_MICRO_defconfig
@@ -40,11 +42,17 @@ F:	configs/qt840a_defconfig
 F:	configs/Wits_Pro_A20_DKT_defconfig
 F:	configs/Wits_Pro_A20_DKT_defconfig
 F:	include/configs/sun8i.h
 F:	include/configs/sun8i.h
 F:	configs/ga10h_v1_1_defconfig
 F:	configs/ga10h_v1_1_defconfig
+F:	configs/gt90h_v4_defconfig
 F:	configs/Ippo_q8h_v1_2_defconfig
 F:	configs/Ippo_q8h_v1_2_defconfig
 F:	configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
 F:	configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
 F:	include/configs/sun9i.h
 F:	include/configs/sun9i.h
 F:	configs/Merrii_A80_Optimus_defconfig
 F:	configs/Merrii_A80_Optimus_defconfig
 
 
+A20-OLIMEX-SOM-EVB BOARD
+M:	Marcus Cooper <codekipper@gmail.com>
+S:	Maintained
+F:	configs/A20-Olimex-SOM-EVB_defconfig
+
 A20-OLINUXINO-LIME BOARD
 A20-OLINUXINO-LIME BOARD
 M:	FUKAUMI Naoki <naobsd@gmail.com>
 M:	FUKAUMI Naoki <naobsd@gmail.com>
 S:	Maintained
 S:	Maintained

+ 24 - 10
board/sunxi/board.c

@@ -31,6 +31,7 @@
 #include <asm/arch/usb_phy.h>
 #include <asm/arch/usb_phy.h>
 #include <asm/gpio.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/io.h>
+#include <nand.h>
 #include <net.h>
 #include <net.h>
 
 
 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
@@ -107,26 +108,44 @@ int dram_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_SPL_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
 static void nand_pinmux_setup(void)
 static void nand_pinmux_setup(void)
 {
 {
 	unsigned int pin;
 	unsigned int pin;
-	for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(6); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
 
 
-	for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(22); pin++)
+	for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++)
 		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
 		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
 
 
+#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I
+	for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++)
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
+#endif
+	/* sun4i / sun7i do have a PC23, but it is not used for nand,
+	 * only sun7i has a PC24 */
+#ifdef CONFIG_MACH_SUN7I
 	sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
 	sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
+#endif
 }
 }
 
 
 static void nand_clock_setup(void)
 static void nand_clock_setup(void)
 {
 {
 	struct sunxi_ccm_reg *const ccm =
 	struct sunxi_ccm_reg *const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
 	setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
 	setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
+#ifdef CONFIG_MACH_SUN9I
+	setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
+#else
+	setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
+#endif
 	setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
 	setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
 }
 }
+
+void board_nand_init(void)
+{
+	nand_pinmux_setup();
+	nand_clock_setup();
+}
 #endif
 #endif
 
 
 #ifdef CONFIG_GENERIC_MMC
 #ifdef CONFIG_GENERIC_MMC
@@ -437,7 +456,7 @@ void sunxi_board_init(void)
 #ifdef CONFIG_AXP221_POWER
 #ifdef CONFIG_AXP221_POWER
 	power_failed = axp221_init();
 	power_failed = axp221_init();
 	power_failed |= axp221_set_dcdc1(CONFIG_AXP221_DCDC1_VOLT);
 	power_failed |= axp221_set_dcdc1(CONFIG_AXP221_DCDC1_VOLT);
-	power_failed |= axp221_set_dcdc2(1200); /* A31:VDD-GPU, A23:VDD-SYS */
+	power_failed |= axp221_set_dcdc2(CONFIG_AXP221_DCDC2_VOLT);
 	power_failed |= axp221_set_dcdc3(1200); /* VDD-CPU */
 	power_failed |= axp221_set_dcdc3(1200); /* VDD-CPU */
 #ifdef CONFIG_MACH_SUN6I
 #ifdef CONFIG_MACH_SUN6I
 	power_failed |= axp221_set_dcdc4(1200); /* A31:VDD-SYS */
 	power_failed |= axp221_set_dcdc4(1200); /* A31:VDD-SYS */
@@ -453,11 +472,6 @@ void sunxi_board_init(void)
 	power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
 	power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
 #endif
 #endif
 
 
-#ifdef CONFIG_SPL_NAND_SUNXI
-	nand_pinmux_setup();
-	nand_clock_setup();
-#endif
-
 	printf("DRAM:");
 	printf("DRAM:");
 	ramsize = sunxi_dram_init();
 	ramsize = sunxi_dram_init();
 	printf(" %lu MiB\n", ramsize >> 20);
 	printf(" %lu MiB\n", ramsize >> 20);

+ 1 - 0
configs/A10-OLinuXino-Lime_defconfig

@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN4I=y
 CONFIG_MACH_SUN4I=y
 CONFIG_DRAM_CLK=480
 CONFIG_DRAM_CLK=480
 CONFIG_DRAM_EMR1=4
 CONFIG_DRAM_EMR1=4
+CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_SYS_CLK_FREQ=912000000
 CONFIG_SYS_CLK_FREQ=912000000
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-olinuxino-lime"
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-olinuxino-lime"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set

+ 1 - 1
configs/A13-OLinuXinoM_defconfig

@@ -3,11 +3,11 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
 CONFIG_MACH_SUN5I=y
 CONFIG_DRAM_CLK=408
 CONFIG_DRAM_CLK=408
 CONFIG_DRAM_EMR1=0
 CONFIG_DRAM_EMR1=0
+CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_USB1_VBUS_PIN="PG11"
 # CONFIG_VIDEO_HDMI is not set
 # CONFIG_VIDEO_HDMI is not set
 CONFIG_VIDEO_VGA_VIA_LCD=y
 CONFIG_VIDEO_VGA_VIA_LCD=y
 CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
-CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="PB10"
 CONFIG_VIDEO_LCD_POWER="PB10"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro"
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro"

+ 1 - 1
configs/A13-OLinuXino_defconfig

@@ -3,12 +3,12 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
 CONFIG_MACH_SUN5I=y
 CONFIG_DRAM_CLK=408
 CONFIG_DRAM_CLK=408
 CONFIG_DRAM_EMR1=0
 CONFIG_DRAM_EMR1=0
+CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_AXP_GPIO=y
 CONFIG_AXP_GPIO=y
 # CONFIG_VIDEO_HDMI is not set
 # CONFIG_VIDEO_HDMI is not set
 CONFIG_VIDEO_VGA_VIA_LCD=y
 CONFIG_VIDEO_VGA_VIA_LCD=y
 CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
-CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"

+ 1 - 0
configs/A20-OLinuXino-Lime_defconfig

@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN7I=y
 CONFIG_MACH_SUN7I=y
 CONFIG_DRAM_CLK=480
 CONFIG_DRAM_CLK=480
+CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime"
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y

+ 16 - 0
configs/A20-Olimex-SOM-EVB_defconfig

@@ -0,0 +1,16 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN7I=y
+CONFIG_DRAM_CLK=480
+CONFIG_MMC0_CD_PIN="PH1"
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="PH5"
+CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olimex-som-evb"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3)"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_USB_EHCI_HCD=y

+ 1 - 0
configs/Ampe_A76_defconfig

@@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=432
 CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_USB0_VBUS_PIN="PG12"
 CONFIG_USB0_VBUS_PIN="PG12"
 CONFIG_USB0_VBUS_DET="PG1"
 CONFIG_USB0_VBUS_DET="PG1"
+CONFIG_USB0_ID_DET="PG2"
 CONFIG_AXP_GPIO=y
 CONFIG_AXP_GPIO=y
 # CONFIG_VIDEO_HDMI is not set
 # CONFIG_VIDEO_HDMI is not set
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0"

+ 1 - 0
configs/Cubieboard_defconfig

@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN4I=y
 CONFIG_MACH_SUN4I=y
 CONFIG_DRAM_CLK=480
 CONFIG_DRAM_CLK=480
+CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard"
 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y

+ 1 - 0
configs/Cubietruck_defconfig

@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN7I=y
 CONFIG_MACH_SUN7I=y
 CONFIG_DRAM_CLK=432
 CONFIG_DRAM_CLK=432
+CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_VIDEO_VGA=y
 CONFIG_VIDEO_VGA=y
 CONFIG_GMAC_TX_DELAY=1
 CONFIG_GMAC_TX_DELAY=1
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck"
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck"

+ 26 - 0
configs/gt90h_v4_defconfig

@@ -0,0 +1,26 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_A23=y
+CONFIG_DRAM_CLK=480
+CONFIG_DRAM_ZQ=32767
+CONFIG_MMC0_CD_PIN="PB4"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
+CONFIG_AXP_GPIO=y
+CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:55000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_POWER="PH7"
+CONFIG_VIDEO_LCD_BL_EN="PH6"
+CONFIG_VIDEO_LCD_BL_PWM="PH0"
+CONFIG_USB_MUSB_HOST=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-gt90h-v4"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_AXP221_DCDC2_VOLT=1100
+CONFIG_AXP221_DLDO1_VOLT=3300
+CONFIG_AXP221_ALDO1_VOLT=3000

+ 20 - 0
configs/inet97fv2_defconfig

@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN4I=y
+CONFIG_DRAM_CLK=408
+CONFIG_DRAM_EMR1=4
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="PH5"
+CONFIG_USB0_ID_DET="PH4"
+CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:24,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_USB_MUSB_HOST=y
+CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-inet97fv2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set

+ 22 - 0
configs/inet98v_rev2_defconfig

@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN5I=y
+CONFIG_DRAM_CLK=432
+CONFIG_MMC0_CD_PIN="PG0"
+CONFIG_USB0_VBUS_PIN="PG12"
+CONFIG_USB0_VBUS_DET="PG1"
+CONFIG_USB0_ID_DET="PG2"
+CONFIG_AXP_GPIO=y
+# CONFIG_VIDEO_HDMI is not set
+CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_POWER="AXP0-0"
+CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_USB_MUSB_HOST=y
+CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-inet-98v-rev2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set

+ 4 - 2
drivers/mmc/sunxi_mmc.c

@@ -257,9 +257,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
 	const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
 	const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
 					      SUNXI_MMC_STATUS_FIFO_FULL;
 					      SUNXI_MMC_STATUS_FIFO_FULL;
 	unsigned i;
 	unsigned i;
-	unsigned byte_cnt = data->blocksize * data->blocks;
-	unsigned timeout_msecs = 2000;
 	unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
 	unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
+	unsigned byte_cnt = data->blocksize * data->blocks;
+	unsigned timeout_msecs = byte_cnt >> 8;
+	if (timeout_msecs < 2000)
+		timeout_msecs = 2000;
 
 
 	/* Always read / write data through the CPU */
 	/* Always read / write data through the CPU */
 	setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
 	setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);

+ 17 - 40
drivers/mtd/nand/Kconfig

@@ -63,6 +63,14 @@ config NAND_PXA3XX
 	  This enables the driver for the NAND flash device found on
 	  This enables the driver for the NAND flash device found on
 	  PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 	  PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 
 
+config NAND_SUNXI
+	bool "Support for NAND on Allwinner SoCs in SPL"
+	depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+	select SYS_NAND_SELF_INIT
+	---help---
+	Enable support for NAND. This option allows SPL to read from
+	sunxi NAND using DMA transfers.
+
 comment "Generic NAND options"
 comment "Generic NAND options"
 
 
 # Enhance depends when converting drivers to Kconfig which use this config
 # Enhance depends when converting drivers to Kconfig which use this config
@@ -84,6 +92,15 @@ config SYS_NAND_BUSWIDTH_16BIT
 	    not available while configuring controller. So a static CONFIG_NAND_xx
 	    not available while configuring controller. So a static CONFIG_NAND_xx
 	    is needed to know the device's bus-width in advance.
 	    is needed to know the device's bus-width in advance.
 
 
+# Enhance depends when converting drivers to Kconfig which use this config
+config SYS_NAND_U_BOOT_OFFS
+	hex "Location in NAND to read U-Boot from"
+	default 0x8000 if NAND_SUNXI
+	depends on NAND_SUNXI
+	help
+	Set the offset from the start of the nand where u-boot should be
+	loaded from.
+
 if SPL
 if SPL
 
 
 config SPL_NAND_DENALI
 config SPL_NAND_DENALI
@@ -92,46 +109,6 @@ config SPL_NAND_DENALI
 	  This is a small implementation of the Denali NAND controller
 	  This is a small implementation of the Denali NAND controller
 	  for use on SPL.
 	  for use on SPL.
 
 
-config SPL_NAND_SUNXI
-	bool "Support for NAND on Allwinner A20 in SPL"
-	depends on MACH_SUN7I
-	---help---
-	Enable support for NAND. This option allows SPL to read from
-	sunxi NAND using DMA transfers.
-	Depending on the NAND chip, values like ECC strength and page sizes
-	have to be configured.
-
-config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END
-	hex "Size of syndrome partitions in sunxi NAND"
-	default 0x400000
-	depends on SPL_NAND_SUNXI
-	---help---
-	End address for boot partitions on NAND. Those partitions have a
-	different random seed that has to match the sunxi BROM setting.
-
-config NAND_SUNXI_SPL_ECC_STRENGTH
-	int "ECC Strength for sunxi NAND"
-	default 40
-	depends on SPL_NAND_SUNXI
-	---help---
-	ECC strength used by the sunxi NAND SPL driver. This is specific to the
-	chosen NAND chip and has to match the value used by the sunxi BROM.
-
-config NAND_SUNXI_SPL_ECC_PAGE_SIZE
-	hex "ECC page size for sunxi NAND"
-	default 0x400
-	depends on SPL_NAND_SUNXI
-	---help---
-	ECC page size used by the sunxi NAND SPL driver for syndrome partitions.
-	This setting has to match the value used by the sunxi BROM.
-
-config NAND_SUNXI_SPL_PAGE_SIZE
-	hex "Page size for sunxi NAND"
-	default 0x2000
-	depends on SPL_NAND_SUNXI
-	---help---
-	Page size of the NAND flash used by the sunxi NAND SPL driver. This is
-	specific to the chosen NAND chip.
 endif
 endif
 
 
 endmenu
 endmenu

+ 1 - 1
drivers/mtd/nand/Makefile

@@ -12,7 +12,6 @@ NORMAL_DRIVERS=y
 endif
 endif
 
 
 obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
 obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
-obj-$(CONFIG_SPL_NAND_SUNXI) += sunxi_nand_spl.o
 obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
 obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
 obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
 obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
 obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
@@ -77,5 +76,6 @@ obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
 obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
 obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
+obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o
 
 
 endif # drivers
 endif # drivers

+ 155 - 113
drivers/mtd/nand/sunxi_nand_spl.c

@@ -5,9 +5,10 @@
  * SPDX-License-Identifier:     GPL-2.0+
  * SPDX-License-Identifier:     GPL-2.0+
  */
  */
 
 
+#include <asm/arch/clock.h>
+#include <asm/io.h>
 #include <common.h>
 #include <common.h>
 #include <config.h>
 #include <config.h>
-#include <asm/io.h>
 #include <nand.h>
 #include <nand.h>
 
 
 /* registers */
 /* registers */
@@ -41,6 +42,8 @@
 #define NFC_CTL_EN                 (1 << 0)
 #define NFC_CTL_EN                 (1 << 0)
 #define NFC_CTL_RESET              (1 << 1)
 #define NFC_CTL_RESET              (1 << 1)
 #define NFC_CTL_RAM_METHOD         (1 << 14)
 #define NFC_CTL_RAM_METHOD         (1 << 14)
+#define NFC_CTL_PAGE_SIZE_MASK     (0xf << 8)
+#define NFC_CTL_PAGE_SIZE(a)       ((fls(a) - 11) << 8)
 
 
 
 
 #define NFC_ECC_EN                 (1 << 0)
 #define NFC_ECC_EN                 (1 << 0)
@@ -64,7 +67,8 @@
 #define NFC_SEND_CMD3              (1 << 28)
 #define NFC_SEND_CMD3              (1 << 28)
 #define NFC_SEND_CMD4              (1 << 29)
 #define NFC_SEND_CMD4              (1 << 29)
 
 
-#define NFC_CMD_INT_FLAG           (1 << 1)
+#define NFC_ST_CMD_INT_FLAG        (1 << 1)
+#define NFC_ST_DMA_INT_FLAG        (1 << 2)
 
 
 #define NFC_READ_CMD_OFFSET         0
 #define NFC_READ_CMD_OFFSET         0
 #define NFC_RANDOM_READ_CMD0_OFFSET 8
 #define NFC_RANDOM_READ_CMD0_OFFSET 8
@@ -85,6 +89,7 @@
 
 
 #define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
 #define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
+#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
 #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
 #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
@@ -94,10 +99,6 @@
 
 
 /* minimal "boot0" style NAND support for Allwinner A20 */
 /* minimal "boot0" style NAND support for Allwinner A20 */
 
 
-/* temporary buffer in internal ram */
-unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE]
-	__aligned(0x10) __section(".text#");
-
 /* random seed used by linux */
 /* random seed used by linux */
 const uint16_t random_seed[128] = {
 const uint16_t random_seed[128] = {
 	0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
 	0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
@@ -156,6 +157,8 @@ void nand_init(void)
 {
 {
 	uint32_t val;
 	uint32_t val;
 
 
+	board_nand_init();
+
 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
 	/* enable and reset CTL */
 	/* enable and reset CTL */
 	writel(val | NFC_CTL_EN | NFC_CTL_RESET,
 	writel(val | NFC_CTL_EN | NFC_CTL_RESET,
@@ -165,86 +168,49 @@ void nand_init(void)
 				 NFC_CTL_RESET, MAX_RETRIES)) {
 				 NFC_CTL_RESET, MAX_RETRIES)) {
 		printf("Couldn't initialize nand\n");
 		printf("Couldn't initialize nand\n");
 	}
 	}
+
+	/* reset NAND */
+	writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
+	writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
+	       SUNXI_NFC_BASE + NFC_CMD);
+
+	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
+			 MAX_RETRIES)) {
+		printf("Error timeout waiting for nand reset\n");
+		return;
+	}
+	writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
 }
 }
 
 
-static void nand_read_page(unsigned int real_addr, int syndrome,
-			   uint32_t *ecc_errors)
+static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size,
+	int addr_cycles, uint32_t real_addr, dma_addr_t dst, int syndrome)
 {
 {
 	uint32_t val;
 	uint32_t val;
-	int ecc_off = 0;
+	int i, ecc_off = 0;
 	uint16_t ecc_mode = 0;
 	uint16_t ecc_mode = 0;
 	uint16_t rand_seed;
 	uint16_t rand_seed;
 	uint32_t page;
 	uint32_t page;
 	uint16_t column;
 	uint16_t column;
-	uint32_t oob_offset;
-
-	switch (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH) {
-	case 16:
-		ecc_mode = 0;
-		ecc_off = 0x20;
-		break;
-	case 24:
-		ecc_mode = 1;
-		ecc_off = 0x2e;
-		break;
-	case 28:
-		ecc_mode = 2;
-		ecc_off = 0x32;
-		break;
-	case 32:
-		ecc_mode = 3;
-		ecc_off = 0x3c;
-		break;
-	case 40:
-		ecc_mode = 4;
-		ecc_off = 0x4a;
-		break;
-	case 48:
-		ecc_mode = 4;
-		ecc_off = 0x52;
-		break;
-	case 56:
-		ecc_mode = 4;
-		ecc_off = 0x60;
-		break;
-	case 60:
-		ecc_mode = 4;
-		ecc_off = 0x0;
-		break;
-	case 64:
-		ecc_mode = 4;
-		ecc_off = 0x0;
-		break;
-	default:
-		ecc_mode = 0;
-		ecc_off = 0;
-	}
+	static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
 
 
-	if (ecc_off == 0) {
-		printf("Unsupported ECC strength (%d)!\n",
-		       CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH);
-		return;
+	for (i = 0; i < ARRAY_SIZE(strengths); i++) {
+		if (ecc_strength == strengths[i]) {
+			ecc_mode = i;
+			break;
+		}
 	}
 	}
 
 
-	/* clear temp_buf */
-	memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE);
+	/* HW ECC always request ECC bytes for 1024 bytes blocks */
+	ecc_off = DIV_ROUND_UP(ecc_strength * fls(8 * 1024), 8);
+	/* HW ECC always work with even numbers of ECC bytes */
+	ecc_off += (ecc_off & 1);
+	ecc_off += 4; /* prepad */
 
 
-	/* set CMD  */
-	writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
-	       SUNXI_NFC_BASE + NFC_CMD);
-
-	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG,
-			 MAX_RETRIES)) {
-		printf("Error while initilizing command interrupt\n");
-		return;
-	}
-
-	page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
-	column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
+	page = real_addr / page_size;
+	column = real_addr % page_size;
 
 
 	if (syndrome)
 	if (syndrome)
-		column += (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
-			* ecc_off;
+		column += (column / ecc_page_size) * ecc_off;
 
 
 	/* clear ecc status */
 	/* clear ecc status */
 	writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
 	writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
@@ -262,15 +228,11 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
 	writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL);
 	writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL);
 
 
-	if (syndrome) {
-		writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+	if (!syndrome)
+		writel(page_size + (column / ecc_page_size) * ecc_off,
 		       SUNXI_NFC_BASE + NFC_SPARE_AREA);
 		       SUNXI_NFC_BASE + NFC_SPARE_AREA);
-	} else {
-		oob_offset = CONFIG_NAND_SUNXI_SPL_PAGE_SIZE
-			+ (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
-			* ecc_off;
-		writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA);
-	}
+
+	flush_dcache_range(dst, ALIGN(dst + ecc_page_size, ARCH_DMA_MINALIGN));
 
 
 	/* SUNXI_DMA */
 	/* SUNXI_DMA */
 	writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
 	writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
@@ -278,15 +240,15 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
 	writel(SUNXI_NFC_BASE + NFC_IO_DATA,
 	writel(SUNXI_NFC_BASE + NFC_IO_DATA,
 	       SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
 	       SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
 	/* read to RAM */
 	/* read to RAM */
-	writel((uint32_t)temp_buf,
-	       SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
+	writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
 	writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC
 	writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC
 			| SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
 			| SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
 			SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
 			SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
-	writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+	writel(ecc_page_size,
 	       SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */
 	       SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */
 	writel(SUNXI_DMA_DDMA_CFG_REG_LOADING
 	writel(SUNXI_DMA_DDMA_CFG_REG_LOADING
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32
+		| SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO
 		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO
 		| SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
 		| SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
@@ -300,54 +262,134 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
 	writel(((page & 0xFFFF) << 16) | column,
 	writel(((page & 0xFFFF) << 16) | column,
 	       SUNXI_NFC_BASE + NFC_ADDR_LOW);
 	       SUNXI_NFC_BASE + NFC_ADDR_LOW);
 	writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
 	writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
+	writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
 	writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS |
 	writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS |
-		NFC_PAGE_CMD | NFC_WAIT_FLAG | (4 << NFC_ADDR_NUM_OFFSET) |
+		NFC_PAGE_CMD | NFC_WAIT_FLAG |
+		((addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) |
 		NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0),
 		NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0),
 		SUNXI_NFC_BASE + NFC_CMD);
 		SUNXI_NFC_BASE + NFC_CMD);
 
 
-	if (!check_value(SUNXI_NFC_BASE + NFC_ST, (1 << 2),
+	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG,
 			 MAX_RETRIES)) {
 			 MAX_RETRIES)) {
 		printf("Error while initializing dma interrupt\n");
 		printf("Error while initializing dma interrupt\n");
-		return;
+		return -1;
 	}
 	}
+	writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
 
 
 	if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
 	if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
 				 SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) {
 				 SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) {
 		printf("Error while waiting for dma transfer to finish\n");
 		printf("Error while waiting for dma transfer to finish\n");
-		return;
+		return -1;
 	}
 	}
 
 
+	invalidate_dcache_range(dst,
+			        ALIGN(dst + ecc_page_size, ARCH_DMA_MINALIGN));
+
 	if (readl(SUNXI_NFC_BASE + NFC_ECC_ST))
 	if (readl(SUNXI_NFC_BASE + NFC_ECC_ST))
-		(*ecc_errors)++;
+		return -1;
+
+	return 0;
+}
+
+static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size,
+	int addr_cycles, uint32_t offs, uint32_t size, void *dest, int syndrome)
+{
+	void *end = dest + size;
+
+	clrsetbits_le32(SUNXI_NFC_BASE + NFC_CTL, NFC_CTL_PAGE_SIZE_MASK,
+			NFC_CTL_PAGE_SIZE(page_size));
+
+	for ( ;dest < end; dest += ecc_page_size, offs += ecc_page_size) {
+		if (nand_read_page(page_size, ecc_strength, ecc_page_size,
+				   addr_cycles, offs, (dma_addr_t)dest,
+				   syndrome))
+			return -1;
+	}
+
+	return 0;
+}
+
+static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest,
+			    int syndrome)
+{
+	const struct {
+		int page_size;
+		int ecc_strength;
+		int ecc_page_size;
+		int addr_cycles;
+	} nand_configs[] = {
+		{  8192, 40, 1024, 5 },
+		{ 16384, 56, 1024, 5 },
+		{  8192, 24, 1024, 5 },
+	};
+	static int nand_config = -1;
+	int i;
+
+	if (nand_config == -1) {
+		for (i = 0; i < ARRAY_SIZE(nand_configs); i++) {
+			debug("nand: trying page %d ecc %d / %d addr %d: ",
+			      nand_configs[i].page_size,
+			      nand_configs[i].ecc_strength,
+			      nand_configs[i].ecc_page_size,
+			      nand_configs[i].addr_cycles);
+			if (nand_read_ecc(nand_configs[i].page_size,
+					  nand_configs[i].ecc_strength,
+					  nand_configs[i].ecc_page_size,
+					  nand_configs[i].addr_cycles,
+					  offs, size, dest, syndrome) == 0) {
+				debug("success\n");
+				nand_config = i;
+				return 0;
+			}
+			debug("failed\n");
+		}
+		return -1;
+	}
+
+	return nand_read_ecc(nand_configs[nand_config].page_size,
+			     nand_configs[nand_config].ecc_strength,
+			     nand_configs[nand_config].ecc_page_size,
+			     nand_configs[nand_config].addr_cycles,
+			     offs, size, dest, syndrome);
 }
 }
 
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
 {
 {
-	void *current_dest;
-	uint32_t count;
-	uint32_t current_count;
-	uint32_t ecc_errors = 0;
-
-	memset(dest, 0x0, size); /* clean destination memory */
-	for (current_dest = dest;
-			current_dest < (dest + size);
-			current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) {
-		nand_read_page(offs, offs
-				< CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END,
-			       &ecc_errors);
-		count = current_dest - dest;
-
-		if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
-			current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
-		else
-			current_count = size - count;
-
-		memcpy(current_dest,
-		       temp_buf,
-		       current_count);
-		offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
+	const uint32_t boot_offsets[] = {
+		0 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
+		1 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
+		2 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
+		4 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS,
+	};
+	int i, syndrome;
+
+	if (CONFIG_SYS_NAND_U_BOOT_OFFS == CONFIG_SPL_PAD_TO)
+		syndrome = 1; /* u-boot-dtb.bin appended to SPL */
+	else
+		syndrome = 0; /* u-boot-dtb.bin on its own partition */
+
+	if (offs == CONFIG_SYS_NAND_U_BOOT_OFFS) {
+		for (i = 0; i < ARRAY_SIZE(boot_offsets); i++) {
+			if (nand_read_buffer(boot_offsets[i], size,
+					     dest, syndrome) == 0)
+				return 0;
+		}
+		return -1;
 	}
 	}
-	return ecc_errors ? -1 : 0;
+
+	return nand_read_buffer(offs, size, dest, syndrome);
 }
 }
 
 
-void nand_deselect(void) {}
+void nand_deselect(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
+#ifdef CONFIG_MACH_SUN9I
+	clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
+#else
+	clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
+#endif
+	clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
+}

+ 9 - 0
drivers/power/Kconfig

@@ -22,6 +22,15 @@ config AXP221_DCDC1_VOLT
 	things like GPIO-s, sdcard interfaces, etc. On most boards this is
 	things like GPIO-s, sdcard interfaces, etc. On most boards this is
 	undervolted to 3.0V to safe battery.
 	undervolted to 3.0V to safe battery.
 
 
+config AXP221_DCDC2_VOLT
+	int "axp221 dcdc2 voltage"
+	depends on AXP221_POWER
+	default 1200
+	---help---
+	Set the voltage (mV) to program the axp221 dcdc2 at, set to 0 to
+	disable dcdc2. On A31 boards this is typically used for VDD-GPU,
+	on A23/A33 for VDD-SYS, this should normally be set to 1.2V.
+
 config AXP221_DLDO1_VOLT
 config AXP221_DLDO1_VOLT
 	int "axp221 dldo1 voltage"
 	int "axp221 dldo1 voltage"
 	depends on AXP221_POWER
 	depends on AXP221_POWER

+ 1 - 3
drivers/usb/musb-new/Kconfig

@@ -21,8 +21,6 @@ config USB_MUSB_SUNXI
 	default y
 	default y
 	---help---
 	---help---
 	Say y here to enable support for the sunxi OTG / DRC USB controller
 	Say y here to enable support for the sunxi OTG / DRC USB controller
-	used on almost all sunxi boards. Note currently u-boot can only have
-	one usb host controller enabled at a time, so enabling this on boards
-	which also use the ehci host controller will result in build errors.
+	used on almost all sunxi boards.
 
 
 endif
 endif

+ 3 - 9
include/configs/sunxi-common.h

@@ -137,16 +137,10 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_INITRD_TAG
 #define CONFIG_SERIAL_TAG
 #define CONFIG_SERIAL_TAG
 
 
-#if defined(CONFIG_SPL_NAND_SUNXI)
-#define CONFIG_SPL_NAND_DRIVERS
-#define CONFIG_SPL_NAND_SUPPORT
-
-#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000
-#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000
-
+#ifdef CONFIG_NAND_SUNXI
+#define CONFIG_SPL_NAND_SUPPORT 1
 #endif
 #endif
 
 
-
 /* mmc config */
 /* mmc config */
 #if !defined(CONFIG_UART0_PORT_F)
 #if !defined(CONFIG_UART0_PORT_F)
 #define CONFIG_MMC
 #define CONFIG_MMC
@@ -185,7 +179,7 @@
 
 
 #define CONFIG_SYS_NO_FLASH
 #define CONFIG_SYS_NO_FLASH
 
 
-#define CONFIG_SYS_MONITOR_LEN		(512 << 10)	/* 512 KiB */
+#define CONFIG_SYS_MONITOR_LEN		(768 << 10)	/* 768 KiB */
 #define CONFIG_IDENT_STRING		" Allwinner Technology"
 #define CONFIG_IDENT_STRING		" Allwinner Technology"
 
 
 #define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512) KiB */
 #define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512) KiB */