This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, master has been updated via 56e211f66eda13d263a9aa4e2aa81c2cfd1bb50f (commit) via 9894fb91f18a11fc7ef6c7032cff7dc897189a92 (commit) from ff3bae7b8974808300078a7be3b46852860e4d9b (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 56e211f66eda13d263a9aa4e2aa81c2cfd1bb50f Author: Arne Fitzenreiter arne_f@ipfire.org Date: Fri Dec 19 07:12:40 2014 +0100
u-boot: update to 2014.4. and add BPi support.
commit 9894fb91f18a11fc7ef6c7032cff7dc897189a92 Author: Arne Fitzenreiter arne_f@ipfire.org Date: Fri Dec 19 07:10:50 2014 +0100
kernel: update to 3.14.27.
-----------------------------------------------------------------------
Summary of changes: config/rootfiles/common/armv5tel/u-boot | 16 +- .../77 => core/86}/filelists/armv5tel/u-boot | 0 config/u-boot/boot.scr | Bin 419 -> 0 bytes config/u-boot/boot.script | 7 - config/u-boot/convert_bootscript | 1 - config/u-boot/uEnv.txt | 3 + lfs/flash-images | 10 +- lfs/linux | 19 +- lfs/u-boot | 18 +- ...-509d96d4f1f602d62d36db660973249e16f9d088.patch | 10002 +++++++++++++++++++ .../sunxi/002-uboot-jwrdegoede-psci-support.patch | 1495 +++ ...fix-gmac-not-working-reliable-on-bananapi.patch | 20 + 12 files changed, 11558 insertions(+), 33 deletions(-) copy config/rootfiles/{oldcore/77 => core/86}/filelists/armv5tel/u-boot (100%) delete mode 100755 config/u-boot/boot.scr delete mode 100755 config/u-boot/boot.script delete mode 100755 config/u-boot/convert_bootscript create mode 100644 config/u-boot/uEnv.txt create mode 100644 src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch create mode 100644 src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch create mode 100644 src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch
Difference in files: diff --git a/config/rootfiles/common/armv5tel/u-boot b/config/rootfiles/common/armv5tel/u-boot index b139d7e..a31e3cf 100644 --- a/config/rootfiles/common/armv5tel/u-boot +++ b/config/rootfiles/common/armv5tel/u-boot @@ -1,16 +1,16 @@ #boot/MLO -boot/boot.scr -boot/boot.script -boot/convert_bootscript #boot/u-boot.img +boot/uEnv.txt usr/bin/mkimage #usr/share/u-boot +#usr/share/u-boot/banana_pi +usr/share/u-boot/banana_pi/u-boot-sunxi-with-spl.bin #usr/share/u-boot/pandaboard -#usr/share/u-boot/pandaboard/MLO -#usr/share/u-boot/pandaboard/u-boot.img +usr/share/u-boot/pandaboard/MLO +usr/share/u-boot/pandaboard/u-boot.img #usr/share/u-boot/wandboard_dl -#usr/share/u-boot/wandboard_dl/u-boot.imx +usr/share/u-boot/wandboard_dl/u-boot.imx #usr/share/u-boot/wandboard_quad -#usr/share/u-boot/wandboard_quad/u-boot.imx +usr/share/u-boot/wandboard_quad/u-boot.imx #usr/share/u-boot/wandboard_solo -#usr/share/u-boot/wandboard_solo/u-boot.imx +usr/share/u-boot/wandboard_solo/u-boot.imx diff --git a/config/rootfiles/core/86/filelists/armv5tel/u-boot b/config/rootfiles/core/86/filelists/armv5tel/u-boot new file mode 120000 index 0000000..3df31a8 --- /dev/null +++ b/config/rootfiles/core/86/filelists/armv5tel/u-boot @@ -0,0 +1 @@ +../../../../common/armv5tel/u-boot \ No newline at end of file diff --git a/config/u-boot/boot.scr b/config/u-boot/boot.scr deleted file mode 100755 index 0fb1193..0000000 Binary files a/config/u-boot/boot.scr and /dev/null differ diff --git a/config/u-boot/boot.script b/config/u-boot/boot.script deleted file mode 100755 index 2017e71..0000000 --- a/config/u-boot/boot.script +++ /dev/null @@ -1,7 +0,0 @@ -setenv initrd_high 90000000 -fatload mmc 0:1 0x82000000 zImage-ipfire-multi -#fatload mmc 0:1 0x85000000 uInit-ipfire-multi -fatload mmc 0:1 ${fdtaddr} omap4-${board_name}.dtb -setenv bootargs video=800x600 console=tty1 rootwait smsc95xx.macaddr=$usbethaddr root=/dev/mmcblk0p3 ro -#bootz 0x82000000 0x85000000 ${fdtaddr} -bootz 0x82000000 - ${fdtaddr} diff --git a/config/u-boot/convert_bootscript b/config/u-boot/convert_bootscript deleted file mode 100755 index 962191f..0000000 --- a/config/u-boot/convert_bootscript +++ /dev/null @@ -1 +0,0 @@ -mkimage -A arm -T script -C none -d boot.script boot.scr diff --git a/config/u-boot/uEnv.txt b/config/u-boot/uEnv.txt new file mode 100644 index 0000000..b3bfb47 --- /dev/null +++ b/config/u-boot/uEnv.txt @@ -0,0 +1,3 @@ +uenvcmd=if test "$board" = "panda" ;then run bootpanda; else run bootbananapi; fi; +bootpanda=setenv initrd_high 90000000; fatload mmc 0:1 0x82000000 zImage-ipfire-multi; fatload mmc 0:1 ${fdtaddr} omap4-${board_name}.dtb; setenv bootargs video=800x600 console=tty1 rootwait smsc95xx.macaddr=$usbethaddr root=/dev/mmcblk0p3 ro; bootz 0x82000000 - ${fdtaddr}; +bootbananapi=setenv fdt_high ffffffff; fatload mmc 0:1 0x46000000 zImage-ipfire-multi; fatload mmc 0:1 0x49000000 sun7i-a20-bananapi.dtb; setenv bootargs console=ttyS0,115200n8 rootwait root=/dev/mmcblk0p3 rootwait; bootz 0x46000000 - 0x49000000; diff --git a/lfs/flash-images b/lfs/flash-images index d2050b4..e92a506 100644 --- a/lfs/flash-images +++ b/lfs/flash-images @@ -116,7 +116,7 @@ endif mkdir -pv $(MNThdd)/boot mount $(PART_BOOT) $(MNThdd)/boot
- # Install MLO and uboot first + # Install Pandaboard MLO and uboot first ifeq "$(MACHINE_TYPE)" "arm" cp -v /boot/MLO $(MNThdd)/boot/ cp -v /boot/u-boot.img $(MNThdd)/boot/ @@ -148,8 +148,7 @@ ifeq "$(SCON)" "1"
ifeq "$(MACHINE_TYPE)" "arm" sed -i -e "s| console=tty1 | console=ttyAMA0,115200n8 |g" $(MNThdd)/boot/cmdline.txt - sed -i -e "s| console=tty1 | console=ttyO2,115200n8 |g" $(MNThdd)/boot/boot.script - cd $(MNThdd)/boot && ./convert_bootscript + sed -i -e "s| console=tty1 | console=ttyO2,115200n8 |g" $(MNThdd)/boot/uEnv.txt endif endif
@@ -216,6 +215,11 @@ endif # not copied to a block device) dd if=/dev/zero bs=1M count=$(PADDING) >> $(IMG)
+ifeq "$(MACHINE_TYPE)" "arm" + # Install u-boot for LeMaker Banana Pi into image 8KB + dd if=/usr/share/u-boot/banana_pi/u-boot-sunxi-with-spl.bin of=$(IMG) bs=1K seek=8 conv=notrunc +endif + # Compress Image pigz -f9 < $(IMG) > $(IMAGE_FILE) rm -rf $(IMG) $(MNThdd) diff --git a/lfs/linux b/lfs/linux index 25206ba..5b0de46 100644 --- a/lfs/linux +++ b/lfs/linux @@ -24,11 +24,11 @@
include Config
-VER = 3.14.26 +VER = 3.14.27
-RPI_PATCHES = 3.14.26-grsec-ipfire1 -A7M_PATCHES = 3.14.26-grsec-ipfire1 -GRS_PATCHES = grsecurity-3.0-3.14.26-201412071005.patch.xz +RPI_PATCHES = 3.14.27-grsec-ipfire1 +A7M_PATCHES = 3.14.27-grsec-ipfire1 +GRS_PATCHES = grsecurity-3.0-3.14.27-201412170659.patch.xz
THISAPP = linux-$(VER) DL_FILE = linux-$(VER).tar.xz @@ -37,7 +37,7 @@ DIR_APP = $(DIR_SRC)/$(THISAPP) CFLAGS = CXXFLAGS =
-PAK_VER = 54 +PAK_VER = 55 DEPS = ""
VERSUFIX=ipfire$(KCFG) @@ -77,13 +77,10 @@ rpi-patches-$(RPI_PATCHES).patch.xz = $(URL_IPFIRE)/rpi-patches-$(RPI_PATCHES). arm7-multi-patches-$(A7M_PATCHES).patch.xz = $(URL_IPFIRE)/arm7-multi-patches-$(A7M_PATCHES).patch.xz $(GRS_PATCHES) = $(URL_IPFIRE)/$(GRS_PATCHES)
-$(DL_FILE)_MD5 = 9a91a9c507c9efb68c7075e151c30fa7 - +$(DL_FILE)_MD5 = 0af2d0702df6ee6d7181e697e0af3481 rpi-patches-$(RPI_PATCHES).patch.xz_MD5 = 543a77d5602829f78b18788e5cb82188 - -arm7-multi-patches-$(A7M_PATCHES).patch.xz_MD5 = c395cb6c1946d1c0fb7edc66ea912e86 - -$(GRS_PATCHES)_MD5 = d98e1c65baab50e6669616785dbc34e1 +arm7-multi-patches-$(A7M_PATCHES).patch.xz_MD5 = 7014ce20d9ede588ea2c244d901cbeeb +$(GRS_PATCHES)_MD5 = 66af1d48af9dce2d0eb363bbc6bfb668
install : $(TARGET)
diff --git a/lfs/u-boot b/lfs/u-boot index eafb592..1552566 100644 --- a/lfs/u-boot +++ b/lfs/u-boot @@ -24,7 +24,7 @@
include Config
-VER = 2013.10 +VER = 2014.04
THISAPP = u-boot-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -41,7 +41,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = a076a044b64371edc52f7e562b13f6b2 +$(DL_FILE)_MD5 = 6d2116d1385a66e9a59742caa9d62a54
install : $(TARGET)
@@ -84,7 +84,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) # Install pandaboard uboot as default cd $(DIR_APP) && install MLO /boot/ cd $(DIR_APP) && install u-boot.img /boot/ - cp -vf $(DIR_SRC)/config/u-boot/* /boot/ cd $(DIR_APP) && make distclean
# Wandboard Quad @@ -111,9 +110,22 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) /usr/share/u-boot/wandboard_solo cd $(DIR_APP) && make distclean
+ # LeMaker Banana Pi + -mkdir -pv /usr/share/u-boot/banana_pi + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch + cd $(DIR_APP) && make CROSS_COMPILE="" Bananapi_config + cd $(DIR_APP) && make CROSS_COMPILE="" HOSTCC="gcc $(CFLAGS)" + cd $(DIR_APP) && install -v -m 644 u-boot-sunxi-with-spl.bin \ + /usr/share/u-boot/banana_pi + # mkimage cd $(DIR_APP) && make CROSS_COMPILE="" HOSTCC="gcc $(CFLAGS)" tools cd $(DIR_APP) && install -v -m 755 tools/mkimage /usr/bin
+ # config (uEnv.txt) + cp -vf $(DIR_SRC)/config/u-boot/* /boot/ + @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch b/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch new file mode 100644 index 0000000..15aac6b --- /dev/null +++ b/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch @@ -0,0 +1,10002 @@ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/cmd_boot.c u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c +--- u-boot-2014.04/arch/arm/cpu/armv7/cmd_boot.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c 2014-09-06 16:58:35.193953144 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++/* ++ * Misc boot support ++ */ ++#include <common.h> ++#include <command.h> ++ ++#ifdef CONFIG_CMD_GO ++unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, ++ char * const argv[]) ++{ ++ invalidate_icache_all(); ++ return entry(argc, argv); ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/Makefile u-boot-sunxi/arch/arm/cpu/armv7/Makefile +--- u-boot-2014.04/arch/arm/cpu/armv7/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/arch/arm/cpu/armv7/Makefile 2014-09-06 16:58:35.185953145 +0200 +@@ -11,8 +11,9 @@ + + obj-y += cpu.o + obj-y += syslib.o ++obj-y += cmd_boot.o + +-ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY),) ++ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),) + ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) + obj-y += lowlevel_init.o + endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/board.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,166 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Some init for sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <i2c.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <serial.h> ++#ifdef CONFIG_SPL_BUILD ++#include <spl.h> ++#endif ++#include <asm/gpio.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/watchdog.h> ++ ++#ifdef CONFIG_SPL_BUILD ++/* Pointer to the global data structure for SPL */ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* The sunxi internal brom will try to loader external bootloader ++ * from mmc0, nand flash, mmc2. ++ * Unfortunately we can't check how SPL was loaded so assume ++ * it's always the first SD/MMC controller ++ */ ++u32 spl_boot_device(void) ++{ ++ return BOOT_DEVICE_MMC1; ++} ++ ++/* No confirmation data available in SPL yet. Hardcode bootmode */ ++u32 spl_boot_mode(void) ++{ ++ return MMCSD_MODE_RAW; ++} ++#endif ++ ++int gpio_init(void) ++{ ++#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F) ++#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I) ++ /* disable GPB22,23 as uart0 tx,rx to avoid conflict */ ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); ++#endif ++ sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPF(4), 1); ++#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)) ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPB(23), 1); ++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN6I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPH(20), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPH(21), 2); ++ sunxi_gpio_set_pull(SUNXI_GPH(21), 1); ++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPB(20), 1); ++#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX); ++ sunxi_gpio_set_pull(SUNXI_GPG(4), 1); ++#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_SUN8I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX); ++ sunxi_gpio_set_pull(SUNXI_GPL(3), 1); ++#else ++#error Unsupported console port number. Please fix pin mux settings in board.c ++#endif ++ ++ return 0; ++} ++ ++void reset_cpu(ulong addr) ++{ ++ watchdog_set(0); ++ while (1); ++} ++ ++/* do some early init */ ++void s_init(void) ++{ ++#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || defined CONFIG_SUN6I) ++ /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ ++ asm volatile( ++ "mrc p15, 0, r0, c1, c0, 1\n" ++ "orr r0, r0, #1 << 6\n" ++ "mcr p15, 0, r0, c1, c0, 1\n"); ++#endif ++ ++ watchdog_init(); ++ clock_init(); ++ timer_init(); ++ gpio_init(); ++ i2c_init_board(); ++ ++#ifdef CONFIG_SPL_BUILD ++ gd = &gdata; ++ preloader_console_init(); ++ ++#ifdef CONFIG_SPL_I2C_SUPPORT ++ /* Needed early by sunxi_board_init if PMU is enabled */ ++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ++#endif ++#endif ++/* No SPL on sun6i, so we do sunxi_board_init() from non spl there */ ++#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++ sunxi_board_init(); ++#endif ++} ++ ++#ifndef CONFIG_SYS_DCACHE_OFF ++void enable_caches(void) ++{ ++ /* Enable D-cache. I-cache is already enabled in start.S */ ++ dcache_enable(); ++} ++#endif ++ ++#ifdef CONFIG_CMD_NET ++/* ++ * Initializes on-chip ethernet controllers. ++ * to override, implement board_eth_init() ++ */ ++int cpu_eth_init(bd_t *bis) ++{ ++ __maybe_unused int rc; ++ ++#ifdef CONFIG_MACPWR ++ gpio_direction_output(CONFIG_MACPWR, 1); ++ mdelay(200); ++#endif ++ ++#ifdef CONFIG_SUNXI_EMAC ++ rc = sunxi_emac_initialize(bis); ++ if (rc < 0) { ++ printf("sunxi: failed to initialize emac\n"); ++ return rc; ++ } ++#endif ++ ++#ifdef CONFIG_SUNXI_GMAC ++ rc = sunxi_gmac_initialize(bis); ++ if (rc < 0) { ++ printf("sunxi: failed to initialize gmac\n"); ++ return rc; ++ } ++#endif ++ ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++int clock_init(void) ++{ ++#ifdef CONFIG_SPL_BUILD ++ clock_init_safe(); ++#endif ++ clock_init_uart(); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun4i.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun4i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun4i.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,188 @@ ++/* ++ * sun4i, sun5i and sun7i specific clock code ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++#ifdef CONFIG_SPL_BUILD ++void clock_init_safe(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Set safe defaults until PMU is configured */ ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); ++ sdelay(200); ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++#ifdef CONFIG_SUN7I ++ writel(0x1 << AHB_GATE_OFFSET_DMA | readl(&ccm->ahb_gate0), ++ &ccm->ahb_gate0); ++#endif ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++#endif ++ ++void clock_init_uart(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* uart clock source is apb1 */ ++ writel(APB1_CLK_SRC_OSC24M| ++ APB1_CLK_RATE_N_1| ++ APB1_CLK_RATE_M(1), ++ &ccm->apb1_clk_div_cfg); ++ ++ /* open the clock for uart */ ++ setbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++} ++ ++int clock_twi_onoff(int port, int state) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ if (port > 2) ++ return -1; ++ ++ /* set the apb clock gate for twi */ ++ if (state) ++ setbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT+port)); ++ else ++ clrbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT+port)); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SPL_BUILD ++#define PLL1_CFG(N, K, M, P) ( 1 << CCM_PLL1_CFG_ENABLE_SHIFT | \ ++ 0 << CCM_PLL1_CFG_VCO_RST_SHIFT | \ ++ 8 << CCM_PLL1_CFG_VCO_BIAS_SHIFT | \ ++ 0 << CCM_PLL1_CFG_PLL4_EXCH_SHIFT | \ ++ 16 << CCM_PLL1_CFG_BIAS_CUR_SHIFT | \ ++ (P)<< CCM_PLL1_CFG_DIVP_SHIFT | \ ++ 2 << CCM_PLL1_CFG_LCK_TMR_SHIFT | \ ++ (N)<< CCM_PLL1_CFG_FACTOR_N_SHIFT | \ ++ (K)<< CCM_PLL1_CFG_FACTOR_K_SHIFT | \ ++ 0 << CCM_PLL1_CFG_SIG_DELT_PAT_IN_SHIFT | \ ++ 0 << CCM_PLL1_CFG_SIG_DELT_PAT_EN_SHIFT | \ ++ (M)<< CCM_PLL1_CFG_FACTOR_M_SHIFT) ++ ++static struct { ++ u32 pll1_cfg; ++ unsigned int freq; ++} pll1_para[] = { ++ /* This array must be ordered by frequency. */ ++ { PLL1_CFG(16, 0, 0, 0), 384000000 }, ++ { PLL1_CFG(16, 1, 0, 0), 768000000 }, ++ { PLL1_CFG(20, 1, 0, 0), 960000000 }, ++ { PLL1_CFG(21, 1, 0, 0), 1008000000}, ++ { PLL1_CFG(22, 1, 0, 0), 1056000000}, ++ { PLL1_CFG(23, 1, 0, 0), 1104000000}, ++ { PLL1_CFG(24, 1, 0, 0), 1152000000}, ++ { PLL1_CFG(25, 1, 0, 0), 1200000000}, ++ { PLL1_CFG(26, 1, 0, 0), 1248000000}, ++ { PLL1_CFG(27, 1, 0, 0), 1296000000}, ++ { PLL1_CFG(28, 1, 0, 0), 1344000000}, ++ { PLL1_CFG(29, 1, 0, 0), 1392000000}, ++ { PLL1_CFG(30, 1, 0, 0), 1440000000}, ++ { PLL1_CFG(31, 1, 0, 0), 1488000000}, ++ /* Final catchall entry */ ++ { PLL1_CFG(31, 1, 0, 0), ~0}, ++}; ++ ++void clock_set_pll1(unsigned int hz) ++{ ++ int i = 0; ++ int axi, ahb, apb0; ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Find target frequency */ ++ while (pll1_para[i].freq < hz) ++ i++; ++ ++ hz = pll1_para[i].freq; ++ ++ /* Calculate system clock divisors */ ++ axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */ ++ ahb = DIV_ROUND_UP(hz/axi, 204000000); /* Max 250MHz */ ++ apb0 = 2; /* Max 150MHz */ ++ ++ printf("CPU: %uHz, AXI/AHB/APB: %d/%d/%d\n", hz, axi, ahb, apb0); ++ ++ /* Map divisors to register values */ ++ axi = axi - 1; ++ if (ahb > 4) ++ ahb = 3; ++ else if (ahb > 2) ++ ahb = 2; ++ else if (ahb > 1) ++ ahb = 1; ++ else ++ ahb = 0; ++ ++ apb0 = apb0 - 1; ++ ++ /* Switch to 24MHz clock while changing PLL1 */ ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++ ++ /* Configure sys clock divisors */ ++ writel(axi << AXI_DIV_SHIFT | ++ ahb << AHB_DIV_SHIFT | ++ apb0 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ ++ /* Configure PLL1 at the desired frequency */ ++ writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg); ++ sdelay(200); ++ ++ /* Switch CPU to PLL1 */ ++ writel(axi << AXI_DIV_SHIFT | ++ ahb << AHB_DIV_SHIFT | ++ apb0 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++} ++#endif ++ ++unsigned int clock_get_pll6(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ uint32_t rval = readl(&ccm->pll6_cfg); ++ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT); ++ int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; ++ return 24000000 * n * k / 2; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun6i.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun6i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun6i.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,110 @@ ++/* ++ * sun6i specific clock code ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/sys_proto.h> ++ ++#ifdef CONFIG_SPL_BUILD ++void clock_init_safe(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sunxi_prcm_reg * const prcm = ++ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; ++ ++ /* Set PLL ldo voltage without this PLL6 does not work properly */ ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140) | ++ PRCM_PLL_CTRL_LDO_KEY, &prcm->pll_ctrl1); ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140) | ++ PRCM_PLL_CTRL_LDO_KEY, &prcm->pll_ctrl1); ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140), ++ &prcm->pll_ctrl1); ++ ++ /* AXI and PLL1 settings from boot0 / boot1, PLL1 set to 486 Mhz */ ++ writel(AXI_DIV_3 << AXI_DIV_SHIFT | ++ ATB_DIV_2 << ATB_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_axi_cfg); ++ writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); ++ sdelay(200); ++ writel(AXI_DIV_3 << AXI_DIV_SHIFT | ++ ATB_DIV_2 << ATB_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_axi_cfg); ++ ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++#endif ++ ++void clock_init_uart(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++#if CONFIG_CONS_INDEX < 5 ++ /* uart clock source is apb2 */ ++ writel(APB2_CLK_SRC_OSC24M| ++ APB2_CLK_RATE_N_1| ++ APB2_CLK_RATE_M(1), ++ &ccm->apb2_div); ++ ++ /* open the clock for uart */ ++ setbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++ ++ /* deassert uart reset */ ++ setbits_le32(&ccm->apb2_reset_cfg, ++ 1 << (APB2_RESET_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++#else ++ /* enable R_PIO and R_UART clocks, and de-assert resets */ ++ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART); ++#endif ++ ++ /* Dup with clock_init_safe(), drop once sun6i SPL support lands */ ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++ ++int clock_twi_onoff(int port, int state) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ if (port > 3) ++ return -1; ++ ++ /* set the apb clock gate for twi */ ++ if (state) ++ setbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port)); ++ else ++ clrbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port)); ++ ++ return 0; ++} ++ ++unsigned int clock_get_pll6(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ uint32_t rval = readl(&ccm->pll6_cfg); ++ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1; ++ int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; ++ return 24000000 * n * k / 2; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,29 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/watchdog.h> ++ ++int do_sunxi_watchdog(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[]) ++{ ++ unsigned long interval; ++ ++ if (argc < 2) { ++ printf("usage: watchdog seconds\n"); ++ printf("over %d to disable watchdog\n", WDT_MAX_TIMEOUT); ++ } ++ interval = simple_strtoul(argv[1], NULL, 10); ++ watchdog_set((unsigned int)interval); ++ ++ return 0; ++} ++ ++U_BOOT_CMD( ++ watchdog, 2, 1, do_sunxi_watchdog, ++ "Set watchdog [0 - 16]. [17+} disables", ++ "" ++); +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/config.mk u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/config.mk 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,8 @@ ++# Build a combined spl + u-boot image ++ifdef CONFIG_SPL ++ifndef CONFIG_SPL_BUILD ++ifndef CONFIG_SPL_FEL ++ALL-y += u-boot-sunxi-with-spl.bin ++endif ++endif ++endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cpu_info.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cpu_info.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,38 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++ ++#ifdef CONFIG_DISPLAY_CPUINFO ++int print_cpuinfo(void) ++{ ++#ifdef CONFIG_SUN4I ++ puts("CPU: Allwinner A10 (SUN4I)\n"); ++#elif defined CONFIG_SUN5I ++ u32 val = readl(SUNXI_SID_BASE + 0x08); ++ switch ((val >> 12) & 0xf) { ++ case 0: puts("CPU: Allwinner A12 (SUN5I)\n"); break; ++ case 3: puts("CPU: Allwinner A13 (SUN5I)\n"); break; ++ case 7: puts("CPU: Allwinner A10s (SUN5I)\n"); break; ++ default: puts("CPU: Allwinner A1X (SUN5I)\n"); ++ } ++#elif defined CONFIG_SUN6I ++ puts("CPU: Allwinner A31 (SUN6I)\n"); ++#elif defined CONFIG_SUN7I ++ puts("CPU: Allwinner A20 (SUN7I)\n"); ++#elif defined CONFIG_SUN8I ++ puts("CPU: Allwinner A23 (SUN8I)\n"); ++#else ++#warning Please update cpu_info.c with correct CPU information ++ puts("CPU: SUNXI Family\n"); ++#endif ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/dram.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/dram.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,693 @@ ++/* ++ * sunxi DRAM controller initialization ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * Based on sun4i Linux kernel sources mach-sunxi/pm/standby/dram*.c ++ * and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++/* ++ * Unfortunately the only documentation we have on the sun7i DRAM ++ * controller is Allwinner boot0 + boot1 code, and that code uses ++ * magic numbers & shifts with no explanations. Hence this code is ++ * rather undocumented and full of magic. ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/dram.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/sys_proto.h> ++ ++#define CPU_CFG_CHIP_VER(n) ((n) << 6) ++#define CPU_CFG_CHIP_VER_MASK CPU_CFG_CHIP_VER(0x3) ++#define CPU_CFG_CHIP_REV_A 0x0 ++#define CPU_CFG_CHIP_REV_C1 0x1 ++#define CPU_CFG_CHIP_REV_C2 0x2 ++#define CPU_CFG_CHIP_REV_B 0x3 ++ ++/* ++ * Wait up to 1s for mask to be clear in given reg. ++ */ ++static void await_completion(u32 *reg, u32 mask) ++{ ++ unsigned long tmo = timer_get_us() + 1000000; ++ ++ while (readl(reg) & mask) { ++ if (timer_get_us() > tmo) ++ panic("Timeout initialising DRAM\n"); ++ } ++} ++ ++static void mctl_ddr3_reset(void) ++{ ++ struct sunxi_dram_reg *dram = ++ (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++#ifdef CONFIG_SUN4I ++ struct sunxi_timer_reg *timer = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ u32 reg_val; ++ ++ writel(0, &timer->cpu_cfg); ++ reg_val = readl(&timer->cpu_cfg); ++ ++ if ((reg_val & CPU_CFG_CHIP_VER_MASK) != ++ CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) { ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ udelay(2); ++ clrbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ } else ++#endif ++ { ++ clrbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ udelay(2); ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ } ++} ++ ++static void mctl_set_drive(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++#ifdef CONFIG_SUN7I ++ clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28), ++#else ++ clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3), ++#endif ++ DRAM_MCR_MODE_EN(0x3) | ++ 0xffc); ++} ++ ++static void mctl_itm_disable(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrsetbits_le32(&dram->ccr, DRAM_CCR_INIT, DRAM_CCR_ITM_OFF); ++} ++ ++static void mctl_itm_enable(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF); ++} ++ ++static void mctl_enable_dll0(u32 phase) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ ((phase >> 16) & 0x3f) << 6); ++ clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET, DRAM_DLLCR_DISABLE); ++ udelay(2); ++ ++ clrbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE); ++ udelay(22); ++ ++ clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET); ++ udelay(22); ++} ++ ++/* ++ * Note: This differs from pm/standby in that it checks the bus width ++ */ ++static void mctl_enable_dllx(u32 phase) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 i, n, bus_width; ++ ++ bus_width = readl(&dram->dcr); ++ ++ if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) == ++ DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT)) ++ n = DRAM_DCR_NR_DLLCR_32BIT; ++ else ++ n = DRAM_DCR_NR_DLLCR_16BIT; ++ ++ for (i = 1; i < n; i++) { ++ clrsetbits_le32(&dram->dllcr[i], 0xf << 14, ++ (phase & 0xf) << 14); ++ clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET, ++ DRAM_DLLCR_DISABLE); ++ phase >>= 4; ++ } ++ udelay(2); ++ ++ for (i = 1; i < n; i++) ++ clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET | ++ DRAM_DLLCR_DISABLE); ++ udelay(22); ++ ++ for (i = 1; i < n; i++) ++ clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE, ++ DRAM_DLLCR_NRESET); ++ udelay(22); ++} ++ ++static u32 hpcr_value[32] = { ++#ifdef CONFIG_SUN5I ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x1035, ++ 0x1035, 0x0731, 0x1031, 0, ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0x0301, 0 ++#endif ++#ifdef CONFIG_SUN4I ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x5031, ++ 0x1035, 0x0731, 0x1031, 0x0735, ++ 0x1035, 0x1031, 0x0731, 0x1035, ++ 0x1031, 0x0301, 0x0301, 0x0731 ++#endif ++#ifdef CONFIG_SUN7I ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x1035, ++ 0x1035, 0x0731, 0x1031, 0x0735, ++ 0x1035, 0x1031, 0x0731, 0x1035, ++ 0x0001, 0x1031, 0, 0x1031 ++ /* last row differs from boot0 source table ++ * 0x1031, 0x0301, 0x0301, 0x0731 ++ * but boot0 code skips #28 and #30, and sets #29 and #31 to the ++ * value from #28 entry (0x1031) ++ */ ++#endif ++}; ++ ++static void mctl_configure_hostport(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 i; ++ ++ for (i = 0; i < 32; i++) ++ writel(hpcr_value[i], &dram->hpcr[i]); ++} ++ ++static void mctl_setup_dram_clock(u32 clk) ++{ ++ u32 reg_val; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* setup DRAM PLL */ ++ reg_val = readl(&ccm->pll5_cfg); ++ reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */ ++ reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */ ++ reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ ++ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ ++ if (clk >= 540 && clk < 552) { ++ /* dram = 540MHz, pll5p = 540MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else if (clk >= 512 && clk < 528) { ++ /* dram = 512MHz, pll5p = 384MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16)); ++ reg_val |= CCM_PLL5_CTRL_P(2); ++ } else if (clk >= 496 && clk < 504) { ++ /* dram = 496MHz, pll5p = 372MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31)); ++ reg_val |= CCM_PLL5_CTRL_P(2); ++ } else if (clk >= 468 && clk < 480) { ++ /* dram = 468MHz, pll5p = 468MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else if (clk >= 396 && clk < 408) { ++ /* dram = 396MHz, pll5p = 396MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else { ++ /* any other frequency that is a multiple of 24 */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); ++ reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2)); ++ } ++ reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */ ++ reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */ ++ writel(reg_val, &ccm->pll5_cfg); ++ udelay(5500); ++ ++ setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK); ++ ++#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I) ++ /* reset GPS */ ++ clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE); ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS); ++ udelay(1); ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS); ++#endif ++ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ /* setup MBUS clock */ ++ reg_val = CCM_MBUS_CTRL_GATE | ++#if defined(CONFIG_SUN7I) && defined(CONFIG_FAST_MBUS) ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(3)); ++#elif defined(CONFIG_SUN7I) && !defined(CONFIG_FAST_MBUS) ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); ++#else /* defined(CONFIG_SUN5I) */ ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); ++#endif ++ writel(reg_val, &ccm->mbus_clk_cfg); ++#endif ++ ++ /* ++ * open DRAMC AHB & DLL register clock ++ * close it first ++ */ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); ++#else ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); ++#endif ++ udelay(22); ++ ++ /* then open it */ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); ++#else ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); ++#endif ++ udelay(22); ++} ++ ++static int dramc_scan_readpipe(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ ++ /* data training trigger */ ++#ifdef CONFIG_SUN7I ++ clrbits_le32(&dram->csr, DRAM_CSR_FAILED); ++#endif ++ setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING); ++ ++ /* check whether data training process has completed */ ++ await_completion(&dram->ccr, DRAM_CCR_DATA_TRAINING); ++ ++ /* check data training result */ ++ reg_val = readl(&dram->csr); ++ if (reg_val & DRAM_CSR_FAILED) ++ return -1; ++ ++ return 0; ++} ++ ++static int dramc_scan_dll_para(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ const u32 dqs_dly[7] = {0x3, 0x2, 0x1, 0x0, 0xe, 0xd, 0xc}; ++ const u32 clk_dly[15] = {0x07, 0x06, 0x05, 0x04, 0x03, ++ 0x02, 0x01, 0x00, 0x08, 0x10, ++ 0x18, 0x20, 0x28, 0x30, 0x38}; ++ u32 clk_dqs_count[15]; ++ u32 dqs_i, clk_i, cr_i; ++ u32 max_val, min_val; ++ u32 dqs_index, clk_index; ++ ++ /* Find DQS_DLY Pass Count for every CLK_DLY */ ++ for (clk_i = 0; clk_i < 15; clk_i++) { ++ clk_dqs_count[clk_i] = 0; ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ (clk_dly[clk_i] & 0x3f) << 6); ++ for (dqs_i = 0; dqs_i < 7; dqs_i++) { ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_i] & 0x4f) << 14); ++ } ++ udelay(2); ++ if (dramc_scan_readpipe() == 0) ++ clk_dqs_count[clk_i]++; ++ } ++ } ++ /* Test DQS_DLY Pass Count for every CLK_DLY from up to down */ ++ for (dqs_i = 15; dqs_i > 0; dqs_i--) { ++ max_val = 15; ++ min_val = 15; ++ for (clk_i = 0; clk_i < 15; clk_i++) { ++ if (clk_dqs_count[clk_i] == dqs_i) { ++ max_val = clk_i; ++ if (min_val == 15) ++ min_val = clk_i; ++ } ++ } ++ if (max_val < 15) ++ break; ++ } ++ ++ /* Check if Find a CLK_DLY failed */ ++ if (!dqs_i) ++ goto fail; ++ ++ /* Find the middle index of CLK_DLY */ ++ clk_index = (max_val + min_val) >> 1; ++ if ((max_val == (15 - 1)) && (min_val > 0)) ++ /* if CLK_DLY[MCTL_CLK_DLY_COUNT] is very good, then the middle ++ * value can be more close to the max_val ++ */ ++ clk_index = (15 + clk_index) >> 1; ++ else if ((max_val < (15 - 1)) && (min_val == 0)) ++ /* if CLK_DLY[0] is very good, then the middle value can be more ++ * close to the min_val ++ */ ++ clk_index >>= 1; ++ if (clk_dqs_count[clk_index] < dqs_i) ++ clk_index = min_val; ++ ++ /* Find the middle index of DQS_DLY for the CLK_DLY got above, and Scan ++ * read pipe again ++ */ ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ (clk_dly[clk_index] & 0x3f) << 6); ++ max_val = 7; ++ min_val = 7; ++ for (dqs_i = 0; dqs_i < 7; dqs_i++) { ++ clk_dqs_count[dqs_i] = 0; ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_i] & 0x4f) << 14); ++ } ++ udelay(2); ++ if (dramc_scan_readpipe() == 0) { ++ clk_dqs_count[dqs_i] = 1; ++ max_val = dqs_i; ++ if (min_val == 7) ++ min_val = dqs_i; ++ } ++ } ++ ++ if (max_val < 7) { ++ dqs_index = (max_val + min_val) >> 1; ++ if ((max_val == (7-1)) && (min_val > 0)) ++ dqs_index = (7 + dqs_index) >> 1; ++ else if ((max_val < (7-1)) && (min_val == 0)) ++ dqs_index >>= 1; ++ if (!clk_dqs_count[dqs_index]) ++ dqs_index = min_val; ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_index] & 0x4f) << 14); ++ } ++ udelay(2); ++ return dramc_scan_readpipe(); ++ } ++ ++fail: ++ clrbits_le32(&dram->dllcr[0], 0x3f << 6); ++ for (cr_i = 1; cr_i < 5; cr_i++) ++ clrbits_le32(&dram->dllcr[cr_i], 0x4f << 14); ++ udelay(2); ++ ++ return dramc_scan_readpipe(); ++} ++ ++static void dramc_clock_output_en(u32 on) ++{ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ if (on) ++ setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); ++ else ++ clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); ++#endif ++#ifdef CONFIG_SUN4I ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ if (on) ++ setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); ++ else ++ clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); ++#endif ++} ++ ++static const u16 tRFC_table[2][6] = { ++ /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */ ++ /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */ ++ { 77, 108, 131, 200, 336, 336 }, ++ /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */ ++ { 93, 93, 113, 164, 308, 359 } ++}; ++ ++static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 tRFC, tREFI; ++ ++ tRFC = (tRFC_table[type][density] * clk + 1023) >> 10; ++ tREFI = (7987 * clk) >> 10; /* <= 7.8us */ ++ ++ writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr); ++} ++ ++unsigned long dramc_init(struct dram_para *para) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ u32 density; ++ int ret_val; ++ ++ /* check input dram parameter structure */ ++ if (!para) ++ return 0; ++ ++ /* setup DRAM relative clock */ ++ mctl_setup_dram_clock(para->clock); ++ ++#ifdef CONFIG_SUN5I ++ /* Disable any pad power save control */ ++ writel(0, &dram->ppwrsctl); ++#endif ++ ++ /* reset external DRAM */ ++#ifndef CONFIG_SUN7I ++ mctl_ddr3_reset(); ++#endif ++ mctl_set_drive(); ++ ++ /* dram clock off */ ++ dramc_clock_output_en(0); ++ ++#ifdef CONFIG_SUN4I ++ /* select dram controller 1 */ ++ writel(DRAM_CSEL_MAGIC, &dram->csel); ++#endif ++ ++ mctl_itm_disable(); ++ mctl_enable_dll0(para->tpr3); ++ ++ /* configure external DRAM */ ++ reg_val = 0x0; ++ if (para->type == DRAM_MEMORY_TYPE_DDR3) ++ reg_val |= DRAM_DCR_TYPE_DDR3; ++ reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3); ++ ++ if (para->density == 256) ++ density = DRAM_DCR_CHIP_DENSITY_256M; ++ else if (para->density == 512) ++ density = DRAM_DCR_CHIP_DENSITY_512M; ++ else if (para->density == 1024) ++ density = DRAM_DCR_CHIP_DENSITY_1024M; ++ else if (para->density == 2048) ++ density = DRAM_DCR_CHIP_DENSITY_2048M; ++ else if (para->density == 4096) ++ density = DRAM_DCR_CHIP_DENSITY_4096M; ++ else if (para->density == 8192) ++ density = DRAM_DCR_CHIP_DENSITY_8192M; ++ else ++ density = DRAM_DCR_CHIP_DENSITY_256M; ++ ++ reg_val |= DRAM_DCR_CHIP_DENSITY(density); ++ reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1); ++ reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1); ++ reg_val |= DRAM_DCR_CMD_RANK_ALL; ++ reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE); ++ writel(reg_val, &dram->dcr); ++ ++#ifdef CONFIG_SUN7I ++ setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1)); ++ if (para->tpr4 & 0x2) ++ clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1)); ++ dramc_clock_output_en(1); ++#endif ++ ++#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)) ++ /* set odt impendance divide ratio */ ++ reg_val = ((para->zq) >> 8) & 0xfffff; ++ reg_val |= ((para->zq) & 0xff) << 20; ++ reg_val |= (para->zq) & 0xf0000000; ++ writel(reg_val, &dram->zqcr0); ++#endif ++ ++#ifdef CONFIG_SUN7I ++ /* Set CKE Delay to about 1ms */ ++ setbits_le32(&dram->idcr, 0x1ffff); ++#endif ++ ++#ifdef CONFIG_SUN7I ++ if ((readl(&dram->ppwrsctl) & 0x1) != 0x1) ++ mctl_ddr3_reset(); ++ else ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++#else ++ /* dram clock on */ ++ dramc_clock_output_en(1); ++#endif ++ ++ udelay(1); ++ ++ await_completion(&dram->ccr, DRAM_CCR_INIT); ++ ++ mctl_enable_dllx(para->tpr3); ++ ++#ifdef CONFIG_SUN4I ++ /* set odt impedance divide ratio */ ++ reg_val = ((para->zq) >> 8) & 0xfffff; ++ reg_val |= ((para->zq) & 0xff) << 20; ++ reg_val |= (para->zq) & 0xf0000000; ++ writel(reg_val, &dram->zqcr0); ++#endif ++ ++#ifdef CONFIG_SUN4I ++ /* set I/O configure register */ ++ reg_val = 0x00cc0000; ++ reg_val |= (para->odt_en) & 0x3; ++ reg_val |= ((para->odt_en) & 0x3) << 30; ++ writel(reg_val, &dram->iocr); ++#endif ++ ++ /* set refresh period */ ++ dramc_set_autorefresh_cycle(para->clock, para->type - 2, density); ++ ++ /* set timing parameters */ ++ writel(para->tpr0, &dram->tpr0); ++ writel(para->tpr1, &dram->tpr1); ++ writel(para->tpr2, &dram->tpr2); ++ ++ if (para->type == DRAM_MEMORY_TYPE_DDR3) { ++ reg_val = DRAM_MR_BURST_LENGTH(0x0); ++#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)) ++ reg_val |= DRAM_MR_POWER_DOWN; ++#endif ++ reg_val |= DRAM_MR_CAS_LAT(para->cas - 4); ++ reg_val |= DRAM_MR_WRITE_RECOVERY(0x5); ++ } else if (para->type == DRAM_MEMORY_TYPE_DDR2) { ++ reg_val = DRAM_MR_BURST_LENGTH(0x2); ++ reg_val |= DRAM_MR_CAS_LAT(para->cas); ++ reg_val |= DRAM_MR_WRITE_RECOVERY(0x5); ++ } ++ writel(reg_val, &dram->mr); ++ ++ writel(para->emr1, &dram->emr); ++ writel(para->emr2, &dram->emr2); ++ writel(para->emr3, &dram->emr3); ++ ++ /* set DQS window mode */ ++ clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE); ++ ++#ifdef CONFIG_SUN7I ++ /* Command rate timing mode 2T & 1T */ ++ if (para->tpr4 & 0x1) ++ setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T); ++#endif ++ /* reset external DRAM */ ++ setbits_le32(&dram->ccr, DRAM_CCR_INIT); ++ await_completion(&dram->ccr, DRAM_CCR_INIT); ++ ++#ifdef CONFIG_SUN7I ++ /* setup zq calibration manual */ ++ reg_val = readl(&dram->ppwrsctl); ++ if ((reg_val & 0x1) == 1) { ++ /* super_standby_flag = 1 */ ++ ++ reg_val = readl(0x01c20c00 + 0x120); /* rtc */ ++ reg_val &= 0x000fffff; ++ reg_val |= 0x17b00000; ++ writel(reg_val, &dram->zqcr0); ++ ++ /* exit self-refresh state */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); ++ /* check whether command has been executed */ ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ ++ /* dram pad hold off */ ++ setbits_le32(&dram->ppwrsctl, 0x16510000); ++ ++ await_completion(&dram->ppwrsctl, 0x1); ++ ++ /* exit self-refresh state */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); ++ ++ /* check whether command has been executed */ ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ ++ /* issue a refresh command */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27); ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ } ++#endif ++ ++ /* scan read pipe value */ ++ mctl_itm_enable(); ++ if (para->tpr3 & (0x1 << 31)) { ++ ret_val = dramc_scan_dll_para(); ++ if (ret_val == 0) ++ para->tpr3 = ++ (((readl(&dram->dllcr[0]) >> 6) & 0x3f) << 16) | ++ (((readl(&dram->dllcr[1]) >> 14) & 0xf) << 0) | ++ (((readl(&dram->dllcr[2]) >> 14) & 0xf) << 4) | ++ (((readl(&dram->dllcr[3]) >> 14) & 0xf) << 8) | ++ (((readl(&dram->dllcr[4]) >> 14) & 0xf) << 12 ++ ); ++ } else { ++ ret_val = dramc_scan_readpipe(); ++ } ++ ++ if (ret_val < 0) ++ return 0; ++ ++ /* configure all host port */ ++ mctl_configure_hostport(); ++ ++ return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/early_print.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/early_print.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Early uart print for debugging. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/early_print.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++static int uart_initialized = 0; ++ ++#if CONFIG_CONS_INDEX < 5 ++#define UART CONFIG_CONS_INDEX-1 ++#else ++/* SUNXI_R_UART_BASE */ ++#define UART 2922 ++#endif ++ ++void uart_init(void) { ++ ++ /* select dll dlh */ ++ writel(UART_LCR_DLAB, UART_LCR(UART)); ++ /* set baudrate */ ++ writel(0, UART_DLH(UART)); ++ writel(BAUD_115200, UART_DLL(UART)); ++ /* set line control */ ++ writel(LC_8_N_1, UART_LCR(UART)); ++ ++ uart_initialized = 1; ++} ++ ++#define TX_READY (readl(UART_LSR(UART)) & UART_LSR_TEMT) ++ ++void uart_putc(char c) { ++ ++ while (!TX_READY) ++ ; ++ writel(c, UART_THR(UART)); ++} ++ ++void uart_puts(const char *s) { ++ ++ while (*s) ++ uart_putc(*s++); ++} ++ ++ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/Makefile u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,44 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++# ++# 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 += timer.o ++obj-y += board.o ++obj-y += clock.o ++obj-y += pinmux.o ++obj-y += watchdog.o ++obj-$(CONFIG_SUN6I) += prcm.o ++obj-$(CONFIG_SUN8I) += prcm.o ++obj-$(CONFIG_SUN6I) += p2wi.o ++obj-$(CONFIG_SUN4I) += clock_sun4i.o ++obj-$(CONFIG_SUN5I) += clock_sun4i.o ++obj-$(CONFIG_SUN6I) += clock_sun6i.o ++obj-$(CONFIG_SUN7I) += clock_sun4i.o ++obj-$(CONFIG_SUN8I) += clock_sun6i.o ++ifdef DEBUG ++obj-y += early_print.o ++endif ++obj-$(CONFIG_BOARD_POSTCLK_INIT) += postclk_init.o ++obj-$(CONFIG_SYS_SECONDARY_ON) += secondary_init.o ++obj-$(CONFIG_SYS_SECONDARY_ON) += smp.o ++ ++ifndef CONFIG_SPL_BUILD ++obj-y += cpu_info.o ++ifdef CONFIG_CMD_WATCHDOG ++obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o ++endif ++endif ++ ++ifdef CONFIG_SPL_BUILD ++obj-$(CONFIG_SUN4I) += dram.o ++obj-$(CONFIG_SUN5I) += dram.o ++obj-$(CONFIG_SUN7I) += dram.o ++ifdef CONFIG_SPL_FEL ++obj-y += start.o ++endif ++endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/p2wi.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/p2wi.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/p2wi.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/p2wi.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,120 @@ ++/* ++ * Sunxi A31 Power Management Unit ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * Based on sun6i sources and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/p2wi.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/sys_proto.h> ++ ++void p2wi_init(void) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ ++ /* Enable p2wi and PIO clk, and de-assert their resets */ ++ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI); ++ ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUNXI_GPL0_R_P2WI_SCK); ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUNXI_GPL1_R_P2WI_SDA); ++ ++ /* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */ ++ writel(P2WI_CTRL_RESET, &p2wi->ctrl); ++ sdelay(0x100); ++ writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8), ++ &p2wi->cc); ++} ++ ++int p2wi_set_pmu_address(u8 slave_addr, u8 ctrl_reg, u8 init_data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i; ++ ++ writel(P2WI_PM_DEV_ADDR(slave_addr) | ++ P2WI_PM_CTRL_ADDR(ctrl_reg) | ++ P2WI_PM_INIT_DATA(init_data) | ++ P2WI_PM_INIT_SEND, ++ &p2wi->pm); ++ for (i = 0xffffff; i != 0; i--) ++ if (!(readl(&p2wi->pm) & P2WI_PM_INIT_SEND)) ++ break; ++ if (readl(&p2wi->pm) & P2WI_PM_INIT_SEND) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++int p2wi_read(const u8 addr, u8 *data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i, ret = 0; ++ u8 reg; ++ ++ writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0); ++ writel(P2WI_DATA_NUM_BYTES(1) | ++ P2WI_DATA_NUM_BYTES_READ, &p2wi->numbytes); ++ writel(P2WI_STAT_TRANS_DONE, &p2wi->status); ++ writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl); ++ ++ for (i = 0xffffff; i != 0; i--) { ++ reg = readl(&p2wi->status); ++ if (reg & P2WI_STAT_TRANS_ERR) { ++ ret = -EIO; ++ break; ++ } ++ if (reg & P2WI_STAT_TRANS_DONE) ++ break; ++ } ++ ++ if (i == 0) ++ ret = -ETIME; ++ ++ *data = readl(&p2wi->data0) & P2WI_DATA_BYTE_1_MASK; ++ writel(reg, &p2wi->status); /* Clear status bits */ ++ return ret; ++} ++ ++int p2wi_write(const u8 addr, u8 data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i, ret = 0; ++ u8 reg; ++ ++ writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0); ++ writel(P2WI_DATA_BYTE_1(data), &p2wi->data0); ++ writel(P2WI_DATA_NUM_BYTES(1), &p2wi->numbytes); ++ writel(P2WI_STAT_TRANS_DONE, &p2wi->status); ++ writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl); ++ ++ for (i = 0xffffff; i != 0; i--) { ++ reg = readl(&p2wi->status); ++ if (reg & P2WI_STAT_TRANS_ERR) { ++ ret = -EIO; ++ break; ++ } ++ if (reg & P2WI_STAT_TRANS_DONE) ++ break; ++ } ++ ++ if (i == 0) ++ ret = -ETIME; ++ ++ writel(reg, &p2wi->status); /* Clear status bits */ ++ return ret; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/pinmux.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/pinmux.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/gpio.h> ++ ++int sunxi_gpio_set_cfgpin(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_CFG_INDEX(pin); ++ u32 offset = GPIO_CFG_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->cfg[0] + index, 0xf << offset, val << offset); ++ ++ return 0; ++} ++ ++int sunxi_gpio_get_cfgpin(u32 pin) ++{ ++ u32 cfg; ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_CFG_INDEX(pin); ++ u32 offset = GPIO_CFG_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ cfg = readl(&pio->cfg[0] + index); ++ cfg >>= offset; ++ ++ return cfg & 0xf; ++} ++ ++int sunxi_gpio_set_drv(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_DRV_INDEX(pin); ++ u32 offset = GPIO_DRV_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->drv[0] + index, 0x3 << offset, val << offset); ++ ++ return 0; ++} ++ ++int sunxi_gpio_set_pull(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_PULL_INDEX(pin); ++ u32 offset = GPIO_PULL_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->pull[0] + index, 0x3 << offset, val << offset); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/postclk_init.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/postclk_init.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#include <asm/arch/smp.h> ++#endif ++ ++ ++int board_postclk_init(void) ++{ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++ startup_secondaries(); ++#endif ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/prcm.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/prcm.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/prcm.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/prcm.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,35 @@ ++/* ++ * Sunxi A31 Power Management Unit ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * Based on sun6i sources and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/sys_proto.h> ++ ++/* APB0 clock gate and reset bit offsets are the same. */ ++void prcm_apb0_enable(u32 flags) ++{ ++ struct sunxi_prcm_reg *prcm = ++ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; ++ ++ /* open the clock for module */ ++ setbits_le32(&prcm->apb0_gate, flags); ++ ++ /* deassert reset for module */ ++ setbits_le32(&prcm->apb0_reset, flags); ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/secondary_init.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/secondary_init.S 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * A lowlevel_init function that sets up the stack to call a C function to ++ * perform further init. ++ * ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <asm-offsets.h> ++#include <config.h> ++#include <linux/linkage.h> ++ ++ENTRY(secondary_init) ++ /* Get cpu number : r5 */ ++ mrc p15, 0, r5, c0, c0, 5 ++ and r5, r5, #0xff ++ ++ /* ++ * Setup a secondary stack, each core gets 128 bytes. ++ */ ++ ldr sp, =secondary_stack ++ mov r0, #0x80 ++ add sp, sp, r0, lsl r5 ++ ++ /* ++ * Jump to C ++ */ ++ bl secondary_start ++ENDPROC(secondary_init) ++ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/smp.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/smp.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,80 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/smp.h> ++#include <asm/arch/cpucfg.h> ++ ++/* Right now we assume only a single secondary as in sun7i */ ++#if defined(CONFIG_SUN7I) ++#define NUM_CORES 2 ++#else ++#error unsupported SoC ++#endif ++ ++static void secondary_pen(void) ++{ ++ struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE; ++ ++ while (1) { ++ __asm__ __volatile__("wfe" ::: "memory"); ++ ++ unsigned long boot_addr = readl(&cpucfg->boot_addr); ++ ++ __asm__ __volatile__( ++ "mov r14, %0 \n" ++ "bx r14 \n" ++ : : "r" (boot_addr) ++ ); ++ }; ++} ++ ++u32 secondary_stack[32*(NUM_CORES-1)]; ++ ++void secondary_start(void) ++{ ++ secondary_pen(); ++} ++ ++/* Power on secondaries */ ++void startup_secondaries(void) ++{ ++ int i; ++ struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE; ++ ++ writel((u32)secondary_init, &cpucfg->boot_addr); ++ ++ for (i = 1; i < NUM_CORES; i++) { ++ /* Assert CPU reset just in case */ ++ writel(CPU_RESET_SET, &cpucfg->cpu[i].reset_ctrl); ++ /* Ensure CPU reset also invalidates L1 caches */ ++ clrbits_le32(&cpucfg->general_ctrl, ++ GENERAL_CTRL_NO_L1_RESET_CPU(i)); ++ /* Lock CPU */ ++ clrbits_le32(&cpucfg->debug1_ctrl, 1 << i); ++ ++ /* Ramp up power to CPU1 */ ++ assert(i == 1); ++ u32 j = 0xff << 1; ++ do { ++ j = j >> 1; ++ writel(j, &cpucfg->cpu1_power_clamp); ++ } while (j != 0); ++ ++ udelay(10*1000); /* 10ms */ ++ ++ clrbits_le32(&cpucfg->cpu1_power_off, 1); ++ /* Release CPU reset */ ++ writel(CPU_RESET_CLEAR, &cpucfg->cpu[i].reset_ctrl); ++ ++ /* Unlock CPU */ ++ setbits_le32(&cpucfg->debug1_ctrl, 1 << i); ++ ++ printf("Secondary CPU%d power-on\n", i); ++ } ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/start.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/start.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1 @@ ++/* Intentionally empty. Only needed to get FEL SPL link line right */ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/timer.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/timer.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,113 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/timer.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define TIMER_MODE (0x0 << 7) /* continuous mode */ ++#define TIMER_DIV (0x0 << 4) /* pre scale 1 */ ++#define TIMER_SRC (0x1 << 2) /* osc24m */ ++#define TIMER_RELOAD (0x1 << 1) /* reload internal value */ ++#define TIMER_EN (0x1 << 0) /* enable timer */ ++ ++#define TIMER_CLOCK (24 * 1000 * 1000) ++#define COUNT_TO_USEC(x) ((x) / 24) ++#define USEC_TO_COUNT(x) ((x) * 24) ++#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) ++#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) ++ ++#define TIMER_LOAD_VAL 0xffffffff ++ ++#define TIMER_NUM 0 /* we use timer 0 */ ++ ++/* read the 32-bit timer */ ++static ulong read_timer(void) ++{ ++ struct sunxi_timer_reg *timers = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ struct sunxi_timer *timer = &timers->timer[TIMER_NUM]; ++ ++ /* ++ * The hardware timer counts down, therefore we invert to ++ * produce an incrementing timer. ++ */ ++ return ~readl(&timer->val); ++} ++ ++/* init timer register */ ++int timer_init(void) ++{ ++ struct sunxi_timer_reg *timers = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ struct sunxi_timer *timer = &timers->timer[TIMER_NUM]; ++ writel(TIMER_LOAD_VAL, &timer->inter); ++ writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN, ++ &timer->ctl); ++ ++ return 0; ++} ++ ++/* timer without interrupts */ ++ulong get_timer(ulong base) ++{ ++ return get_timer_masked() - base; ++} ++ ++ulong get_timer_masked(void) ++{ ++ /* current tick value */ ++ ulong now = TICKS_TO_HZ(read_timer()); ++ ++ if (now >= gd->arch.lastinc) /* normal (non rollover) */ ++ gd->arch.tbl += (now - gd->arch.lastinc); ++ else { ++ /* rollover */ ++ gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) ++ - gd->arch.lastinc) + now; ++ } ++ gd->arch.lastinc = now; ++ ++ return gd->arch.tbl; ++} ++ ++/* delay x useconds */ ++void __udelay(unsigned long usec) ++{ ++ long tmo = USEC_TO_COUNT(usec); ++ ulong now, last = read_timer(); ++ ++ while (tmo > 0) { ++ now = read_timer(); ++ if (now > last) /* normal (non rollover) */ ++ tmo -= now - last; ++ else /* rollover */ ++ tmo -= TIMER_LOAD_VAL - last + now; ++ last = now; ++ } ++} ++ ++/* ++ * This function is derived from PowerPC code (read timebase as long long). ++ * On ARM it just returns the timer value. ++ */ ++unsigned long long get_ticks(void) ++{ ++ return get_timer(0); ++} ++ ++/* ++ * This function is derived from PowerPC code (timebase clock frequency). ++ * On ARM it returns the number of timer ticks per second. ++ */ ++ulong get_tbclk(void) ++{ ++ return CONFIG_SYS_HZ; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,77 @@ ++/* ++ * (C) Copyright 2013 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(s_init) ++SECTIONS ++{ ++ . = 0x00002000; ++ ++ . = ALIGN(4); ++ .text : ++ { ++ *(.text.s_init) ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ . = .; ++ ++ . = ALIGN(4); ++ .rel.dyn : { ++ __rel_dyn_start = .; ++ *(.rel*) ++ __rel_dyn_end = .; ++ } ++ ++ .dynsym : { ++ __dynsym_start = .; ++ *(.dynsym) ++ } ++ ++ . = ALIGN(4); ++ .note.gnu.build-id : ++ { ++ *(.note.gnu.build-id) ++ } ++ _end = .; ++ ++ . = ALIGN(4096); ++ .mmutable : { ++ *(.mmutable) ++ } ++ ++ .bss_start __rel_dyn_start (OVERLAY) : { ++ KEEP(*(.__bss_start)); ++ __bss_base = .; ++ } ++ ++ .bss __bss_base (OVERLAY) : { ++ *(.bss*) ++ . = ALIGN(4); ++ __bss_limit = .; ++ } ++ ++ .bss_end __bss_limit (OVERLAY) : { ++ KEEP(*(.__bss_end)); ++ } ++ ++ /DISCARD/ : { *(.dynstr*) } ++ /DISCARD/ : { *(.dynamic*) } ++ /DISCARD/ : { *(.plt*) } ++ /DISCARD/ : { *(.interp*) } ++ /DISCARD/ : { *(.gnu*) } ++ /DISCARD/ : { *(.note*) } ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,52 @@ ++/* ++ * (C) Copyright 2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Based on omap-common/u-boot-spl.lds: ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, garyj@denx.de ++ * ++ * (C) Copyright 2010 ++ * Texas Instruments, <www.ti.com> ++ * Aneesh V aneesh@ti.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ ++ LENGTH = CONFIG_SPL_MAX_SIZE } ++MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ ++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE } ++ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(_start) ++SECTIONS ++{ ++ .text : ++ { ++ __start = .; ++ arch/arm/cpu/armv7/start.o (.text) ++ *(.text*) ++ } > .sram ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram ++ ++ . = ALIGN(4); ++ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ _end = .; ++ ++ .bss : ++ { ++ . = ALIGN(4); ++ __bss_start = .; ++ *(.bss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } > .sdram ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,83 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://www.linux-sunxi.org/ ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <asm/io.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/watchdog.h> ++#include <common.h> ++#include <watchdog.h> ++ ++ ++#define WDT_CTRL_RESTART (0x1 << 0) ++#define WDT_CTRL_KEY (0x0a57 << 1) ++ ++#define WDT_MODE_EN (0x1 << 0) ++#define WDT_MODE_RESET_EN (0x1 << 1) ++#define WDT_MAX_TIMEOUT 16 ++#define WDT_MODE_TIMEOUT(n) \ ++ (wdt_timeout_map[(n) < WDT_MAX_TIMEOUT ? (n) : WDT_MAX_TIMEOUT] << 3) ++ ++ ++/* ++ * Watchdog timeout table. The sunxi cores only use 4 bits for the watchdog as ++ * set by the table below. The gaps are filled by rounding up to the next ++ * second up. ++ */ ++const unsigned int wdt_timeout_map[] = { ++ [0] = 0b0000, /* 0.5s*/ ++ [1] = 0b0001, /* 1s */ ++ [2] = 0b0010, /* 2s */ ++ [3] = 0b0011, /* 3s */ ++ [4] = 0b0100, /* 4s */ ++ [5] = 0b0101, /* 5s */ ++ [6] = 0b0110, /* 6s */ ++ [7] = 0b0111, /* 8s */ ++ [8] = 0b0111, /* 8s */ ++ [9] = 0b1000, /* 10s */ ++ [10] = 0b1000, /* 10s */ ++ [11] = 0b1001, /* 12s */ ++ [12] = 0b1001, /* 12s */ ++ [13] = 0b1010, /* 14s */ ++ [14] = 0b1010, /* 14s */ ++ [15] = 0b1011, /* 16s */ ++ [16] = 0b1011, /* 16s */ ++}; ++ ++ ++void watchdog_reset(void) ++{ ++ static const struct sunxi_wdog *wdog = ++ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; ++ ++ writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); ++} ++ ++void watchdog_set(int timeout) ++{ ++ static struct sunxi_wdog *const wdog = ++ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; ++ ++ /* Set timeout, reset & enable */ ++ if (timeout >= 0) { ++ writel(WDT_MODE_TIMEOUT(timeout) | ++ WDT_MODE_RESET_EN | WDT_MODE_EN, ++ &wdog->mode); ++ } else { ++ writel(0, &wdog->mode); ++ } ++ watchdog_reset(); ++} ++ ++void watchdog_init(void) ++{ ++#ifdef CONFIG_WATCHDOG ++ watchdog_set(WDT_MAX_TIMEOUT); ++#else ++ watchdog_set(WDT_OFF); /* no timeout */ ++#endif ++} +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,33 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_H ++#define _SUNXI_CLOCK_H ++ ++#include <linux/types.h> ++ ++#define CLK_GATE_OPEN 0x1 ++#define CLK_GATE_CLOSE 0x0 ++ ++/* clock control module regs definition */ ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++#include <asm/arch/clock_sun6i.h> ++#else ++#include <asm/arch/clock_sun4i.h> ++#endif ++ ++#ifndef __ASSEMBLY__ ++int clock_init(void); ++int clock_twi_onoff(int port, int state); ++void clock_set_pll1(unsigned int hz); ++unsigned int clock_get_pll6(void); ++void clock_init_safe(void); ++void clock_init_uart(void); ++#endif ++ ++#endif /* _SUNXI_CLOCK_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun4i.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,256 @@ ++/* ++ * sun4i, sun5i and sun7i clock register definitions ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_SUN4I_H ++#define _SUNXI_CLOCK_SUN4I_H ++ ++struct sunxi_ccm_reg { ++ u32 pll1_cfg; /* 0x00 pll1 control */ ++ u32 pll1_tun; /* 0x04 pll1 tuning */ ++ u32 pll2_cfg; /* 0x08 pll2 control */ ++ u32 pll2_tun; /* 0x0c pll2 tuning */ ++ u32 pll3_cfg; /* 0x10 pll3 control */ ++ u8 res0[0x4]; ++ u32 pll4_cfg; /* 0x18 pll4 control */ ++ u8 res1[0x4]; ++ u32 pll5_cfg; /* 0x20 pll5 control */ ++ u32 pll5_tun; /* 0x24 pll5 tuning */ ++ u32 pll6_cfg; /* 0x28 pll6 control */ ++ u32 pll6_tun; /* 0x2c pll6 tuning */ ++ u32 pll7_cfg; /* 0x30 pll7 control */ ++ u32 pll1_tun2; /* 0x34 pll5 tuning2 */ ++ u8 res2[0x4]; ++ u32 pll5_tun2; /* 0x3c pll5 tuning2 */ ++ u8 res3[0xc]; ++ u32 pll_lock_dbg; /* 0x4c pll lock time debug */ ++ u32 osc24m_cfg; /* 0x50 osc24m control */ ++ u32 cpu_ahb_apb0_cfg; /* 0x54 cpu,ahb and apb0 divide ratio */ ++ u32 apb1_clk_div_cfg; /* 0x58 apb1 clock dividor */ ++ u32 axi_gate; /* 0x5c axi module clock gating */ ++ u32 ahb_gate0; /* 0x60 ahb module clock gating 0 */ ++ u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ ++ u32 apb0_gate; /* 0x68 apb0 module clock gating */ ++ u32 apb1_gate; /* 0x6c apb1 module clock gating */ ++ u8 res4[0x10]; ++ u32 nand_sclk_cfg; /* 0x80 nand sub clock control */ ++ u32 ms_sclk_cfg; /* 0x84 memory stick sub clock control */ ++ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ ++ u32 sd1_clk_cfg; /* 0x8c sd1 clock control */ ++ u32 sd2_clk_cfg; /* 0x90 sd2 clock control */ ++ u32 sd3_clk_cfg; /* 0x94 sd3 clock control */ ++ u32 ts_clk_cfg; /* 0x98 transport stream clock control */ ++ u32 ss_clk_cfg; /* 0x9c */ ++ u32 spi0_clk_cfg; /* 0xa0 */ ++ u32 spi1_clk_cfg; /* 0xa4 */ ++ u32 spi2_clk_cfg; /* 0xa8 */ ++ u32 pata_clk_cfg; /* 0xac */ ++ u32 ir0_clk_cfg; /* 0xb0 */ ++ u32 ir1_clk_cfg; /* 0xb4 */ ++ u32 iis_clk_cfg; /* 0xb8 */ ++ u32 ac97_clk_cfg; /* 0xbc */ ++ u32 spdif_clk_cfg; /* 0xc0 */ ++ u32 keypad_clk_cfg; /* 0xc4 */ ++ u32 sata_clk_cfg; /* 0xc8 */ ++ u32 usb_clk_cfg; /* 0xcc */ ++ u32 gps_clk_cfg; /* 0xd0 */ ++ u32 spi3_clk_cfg; /* 0xd4 */ ++ u8 res5[0x28]; ++ u32 dram_clk_cfg; /* 0x100 */ ++ u32 be0_clk_cfg; /* 0x104 */ ++ u32 be1_clk_cfg; /* 0x108 */ ++ u32 fe0_clk_cfg; /* 0x10c */ ++ u32 fe1_clk_cfg; /* 0x110 */ ++ u32 mp_clk_cfg; /* 0x114 */ ++ u32 lcd0_ch0_clk_cfg; /* 0x118 */ ++ u32 lcd1_ch0_clk_cfg; /* 0x11c */ ++ u32 csi_isp_clk_cfg; /* 0x120 */ ++ u8 res6[0x4]; ++ u32 tvd_clk_reg; /* 0x128 */ ++ u32 lcd0_ch1_clk_cfg; /* 0x12c */ ++ u32 lcd1_ch1_clk_cfg; /* 0x130 */ ++ u32 csi0_clk_cfg; /* 0x134 */ ++ u32 csi1_clk_cfg; /* 0x138 */ ++ u32 ve_clk_cfg; /* 0x13c */ ++ u32 audio_codec_clk_cfg; /* 0x140 */ ++ u32 avs_clk_cfg; /* 0x144 */ ++ u32 ace_clk_cfg; /* 0x148 */ ++ u32 lvds_clk_cfg; /* 0x14c */ ++ u32 hdmi_clk_cfg; /* 0x150 */ ++ u32 mali_clk_cfg; /* 0x154 */ ++ u8 res7[0x4]; ++ u32 mbus_clk_cfg; /* 0x15c */ ++ u8 res8[0x4]; ++ u32 gmac_clk_cfg; /* 0x164 */ ++}; ++ ++/* apb1 bit field */ ++#define APB1_CLK_SRC_OSC24M (0x0 << 24) ++#define APB1_CLK_SRC_PLL6 (0x1 << 24) ++#define APB1_CLK_SRC_LOSC (0x2 << 24) ++#define APB1_CLK_SRC_MASK (0x3 << 24) ++#define APB1_CLK_RATE_N_1 (0x0 << 16) ++#define APB1_CLK_RATE_N_2 (0x1 << 16) ++#define APB1_CLK_RATE_N_4 (0x2 << 16) ++#define APB1_CLK_RATE_N_8 (0x3 << 16) ++#define APB1_CLK_RATE_N_MASK (3 << 16) ++#define APB1_CLK_RATE_M(m) (((m)-1) << 0) ++#define APB1_CLK_RATE_M_MASK (0x1f << 0) ++ ++/* apb1 gate field */ ++#define APB1_GATE_UART_SHIFT (16) ++#define APB1_GATE_UART_MASK (0xff << APB1_GATE_UART_SHIFT) ++#define APB1_GATE_TWI_SHIFT (0) ++#define APB1_GATE_TWI_MASK (0xf << APB1_GATE_TWI_SHIFT) ++ ++/* clock divide */ ++#define AXI_DIV_SHIFT (0) ++#define AXI_DIV_1 0 ++#define AXI_DIV_2 1 ++#define AXI_DIV_3 2 ++#define AXI_DIV_4 3 ++#define AHB_DIV_SHIFT (4) ++#define AHB_DIV_1 0 ++#define AHB_DIV_2 1 ++#define AHB_DIV_4 2 ++#define AHB_DIV_8 3 ++#define APB0_DIV_SHIFT (8) ++#define APB0_DIV_1 0 ++#define APB0_DIV_2 1 ++#define APB0_DIV_4 2 ++#define APB0_DIV_8 3 ++#define CPU_CLK_SRC_SHIFT (16) ++#define CPU_CLK_SRC_OSC24M 1 ++#define CPU_CLK_SRC_PLL1 2 ++ ++#define CCM_PLL1_CFG_ENABLE_SHIFT 31 ++#define CCM_PLL1_CFG_VCO_RST_SHIFT 30 ++#define CCM_PLL1_CFG_VCO_BIAS_SHIFT 26 ++#define CCM_PLL1_CFG_PLL4_EXCH_SHIFT 25 ++#define CCM_PLL1_CFG_BIAS_CUR_SHIFT 20 ++#define CCM_PLL1_CFG_DIVP_SHIFT 16 ++#define CCM_PLL1_CFG_LCK_TMR_SHIFT 13 ++#define CCM_PLL1_CFG_FACTOR_N_SHIFT 8 ++#define CCM_PLL1_CFG_FACTOR_K_SHIFT 4 ++#define CCM_PLL1_CFG_SIG_DELT_PAT_IN_SHIFT 3 ++#define CCM_PLL1_CFG_SIG_DELT_PAT_EN_SHIFT 2 ++#define CCM_PLL1_CFG_FACTOR_M_SHIFT 0 ++ ++#define PLL1_CFG_DEFAULT 0xa1005000 ++ ++#define PLL6_CFG_DEFAULT 0xa1009911 ++ ++/* nand clock */ ++#define NAND_CLK_SRC_OSC24 0 ++#define NAND_CLK_DIV_N 0 ++#define NAND_CLK_DIV_M 0 ++ ++/* gps clock */ ++#define GPS_SCLK_GATING_OFF 0 ++#define GPS_RESET 0 ++ ++/* ahb clock gate bit offset */ ++#define AHB_GATE_OFFSET_GPS 26 ++#define AHB_GATE_OFFSET_SATA 25 ++#define AHB_GATE_OFFSET_PATA 24 ++#define AHB_GATE_OFFSET_SPI3 23 ++#define AHB_GATE_OFFSET_SPI2 22 ++#define AHB_GATE_OFFSET_SPI1 21 ++#define AHB_GATE_OFFSET_SPI0 20 ++#define AHB_GATE_OFFSET_TS0 18 ++#define AHB_GATE_OFFSET_EMAC 17 ++#define AHB_GATE_OFFSET_ACE 16 ++#define AHB_GATE_OFFSET_DLL 15 ++#define AHB_GATE_OFFSET_SDRAM 14 ++#define AHB_GATE_OFFSET_NAND 13 ++#define AHB_GATE_OFFSET_MS 12 ++#define AHB_GATE_OFFSET_MMC3 11 ++#define AHB_GATE_OFFSET_MMC2 10 ++#define AHB_GATE_OFFSET_MMC1 9 ++#define AHB_GATE_OFFSET_MMC0 8 ++#define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) ++#define AHB_GATE_OFFSET_BIST 7 ++#define AHB_GATE_OFFSET_DMA 6 ++#define AHB_GATE_OFFSET_SS 5 ++#define AHB_GATE_OFFSET_USB_OHCI1 4 ++#define AHB_GATE_OFFSET_USB_EHCI1 3 ++#define AHB_GATE_OFFSET_USB_OHCI0 2 ++#define AHB_GATE_OFFSET_USB_EHCI0 1 ++#define AHB_GATE_OFFSET_USB 0 ++ ++/* ahb clock gate bit offset (second register) */ ++#define AHB_GATE_OFFSET_GMAC 17 ++ ++#define CCM_AHB_GATE_GPS (0x1 << 26) ++#define CCM_AHB_GATE_SDRAM (0x1 << 14) ++#define CCM_AHB_GATE_DLL (0x1 << 15) ++#define CCM_AHB_GATE_ACE (0x1 << 16) ++ ++#define CCM_PLL5_CTRL_M(n) (((n) & 0x3) << 0) ++#define CCM_PLL5_CTRL_M_MASK CCM_PLL5_CTRL_M(0x3) ++#define CCM_PLL5_CTRL_M_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_M1(n) (((n) & 0x3) << 2) ++#define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3) ++#define CCM_PLL5_CTRL_M1_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4) ++#define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3) ++#define CCM_PLL5_CTRL_K_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_LDO (0x1 << 7) ++#define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8) ++#define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f) ++#define CCM_PLL5_CTRL_N_X(n) (n) ++#define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16) ++#define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3) ++#define CCM_PLL5_CTRL_P_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_BW (0x1 << 18) ++#define CCM_PLL5_CTRL_VCO_GAIN (0x1 << 19) ++#define CCM_PLL5_CTRL_BIAS(n) (((n) & 0x1f) << 20) ++#define CCM_PLL5_CTRL_BIAS_MASK CCM_PLL5_CTRL_BIAS(0x1f) ++#define CCM_PLL5_CTRL_BIAS_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_VCO_BIAS (0x1 << 25) ++#define CCM_PLL5_CTRL_DDR_CLK (0x1 << 29) ++#define CCM_PLL5_CTRL_BYPASS (0x1 << 30) ++#define CCM_PLL5_CTRL_EN (0x1 << 31) ++ ++#define CCM_PLL6_CTRL_N_SHIFT 8 ++#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) ++#define CCM_PLL6_CTRL_K_SHIFT 4 ++#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) ++ ++#define CCM_GPS_CTRL_RESET (0x1 << 0) ++#define CCM_GPS_CTRL_GATE (0x1 << 1) ++ ++#define CCM_DRAM_CTRL_DCLK_OUT (0x1 << 15) ++ ++#define CCM_MBUS_CTRL_M(n) (((n) & 0xf) << 0) ++#define CCM_MBUS_CTRL_M_MASK CCM_MBUS_CTRL_M(0xf) ++#define CCM_MBUS_CTRL_M_X(n) ((n) - 1) ++#define CCM_MBUS_CTRL_N(n) (((n) & 0xf) << 16) ++#define CCM_MBUS_CTRL_N_MASK CCM_MBUS_CTRL_N(0xf) ++#define CCM_MBUS_CTRL_N_X(n) (((n) >> 3) ? 3 : (((n) >> 2) ? 2 : (((n) >> 1) ? 1 : 0))) ++#define CCM_MBUS_CTRL_CLK_SRC(n) (((n) & 0x3) << 24) ++#define CCM_MBUS_CTRL_CLK_SRC_MASK CCM_MBUS_CTRL_CLK_SRC(0x3) ++#define CCM_MBUS_CTRL_CLK_SRC_HOSC 0x0 ++#define CCM_MBUS_CTRL_CLK_SRC_PLL6 0x1 ++#define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2 ++#define CCM_MBUS_CTRL_GATE (0x1 << 31) ++ ++#define CCM_MMC_CTRL_OSCM24 (0x0 << 24) ++#define CCM_MMC_CTRL_PLL6 (0x1 << 24) ++#define CCM_MMC_CTRL_PLL5 (0x2 << 24) ++ ++#define CCM_MMC_CTRL_ENABLE (0x1 << 31) ++ ++#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 ++#define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 ++#define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 ++#define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2) ++#define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2) ++ ++#endif /* _SUNXI_CLOCK_SUN4I_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun6i.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,205 @@ ++/* ++ * sun6i clock register definitions ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_SUN6I_H ++#define _SUNXI_CLOCK_SUN6I_H ++ ++struct sunxi_ccm_reg { ++ u32 pll1_cfg; /* 0x00 pll1 control */ ++ u32 reserved0; ++ u32 pll2_cfg; /* 0x08 pll2 control */ ++ u32 reserved1; ++ u32 pll3_cfg; /* 0x10 pll3 control */ ++ u32 reserved2; ++ u32 pll4_cfg; /* 0x18 pll4 control */ ++ u32 reserved3; ++ u32 pll5_cfg; /* 0x20 pll5 control */ ++ u32 reserved4; ++ u32 pll6_cfg; /* 0x28 pll6 control */ ++ u32 reserved5; ++ u32 pll7_cfg; /* 0x30 pll7 control */ ++ u32 reserved6; ++ u32 pll8_cfg; /* 0x38 pll8 control */ ++ u32 reserved7; ++ u32 mipi_pll_cfg; /* 0x40 MIPI pll control */ ++ u32 pll9_cfg; /* 0x44 pll9 control */ ++ u32 pll10_cfg; /* 0x48 pll10 control */ ++ u32 reserved8; ++ u32 cpu_axi_cfg; /* 0x50 CPU/AXI divide ratio */ ++ u32 ahb1_apb1_div; /* 0x54 AHB1/APB1 divide ratio */ ++ u32 apb2_div; /* 0x58 APB2 divide ratio */ ++ u32 axi_gate; /* 0x5c axi module clock gating */ ++ u32 ahb_gate0; /* 0x60 ahb module clock gating 0 */ ++ u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ ++ u32 apb1_gate; /* 0x68 apb1 module clock gating */ ++ u32 apb2_gate; /* 0x6c apb2 module clock gating */ ++ u32 reserved9[4]; ++ u32 nand0_clk_cfg; /* 0x80 nand0 clock control */ ++ u32 nand1_clk_cfg; /* 0x84 nand1 clock control */ ++ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ ++ u32 sd1_clk_cfg; /* 0x8c sd1 clock control */ ++ u32 sd2_clk_cfg; /* 0x90 sd2 clock control */ ++ u32 sd3_clk_cfg; /* 0x94 sd3 clock control */ ++ u32 ts_clk_cfg; /* 0x98 transport stream clock control */ ++ u32 ss_clk_cfg; /* 0x9c security system clock control */ ++ u32 spi0_clk_cfg; /* 0xa0 spi0 clock control */ ++ u32 spi1_clk_cfg; /* 0xa4 spi1 clock control */ ++ u32 spi2_clk_cfg; /* 0xa8 spi2 clock control */ ++ u32 spi3_clk_cfg; /* 0xac spi3 clock control */ ++ u32 i2s0_clk_cfg; /* 0xb0 I2S0 clock control*/ ++ u32 i2s1_clk_cfg; /* 0xb4 I2S1 clock control */ ++ u32 reserved10[2]; ++ u32 spdif_clk_cfg; /* 0xc0 SPDIF clock control */ ++ u32 reserved11[2]; ++ u32 usb_clk_cfg; /* 0xcc USB clock control */ ++ u32 gmac_clk_cfg; /* 0xd0 GMAC clock control */ ++ u32 reserved12[7]; ++ u32 mdfs_clk_cfg; /* 0xf0 MDFS clock control */ ++ u32 dram_clk_cfg; /* 0xf4 DRAM configuration clock control */ ++ u32 reserved13[2]; ++ u32 dram_clk_gate; /* 0x100 DRAM module gating */ ++ u32 be0_clk_cfg; /* 0x104 BE0 module clock */ ++ u32 be1_clk_cfg; /* 0x108 BE1 module clock */ ++ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ ++ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ ++ u32 mp_clk_cfg; /* 0x114 MP module clock */ ++ u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ ++ u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */ ++ u32 reserved14[3]; ++ u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */ ++ u32 lcd1_ch1_clk_cfg; /* 0x130 LCD1 CH1 module clock */ ++ u32 csi0_clk_cfg; /* 0x134 CSI0 module clock */ ++ u32 csi1_clk_cfg; /* 0x138 CSI1 module clock */ ++ u32 ve_clk_cfg; /* 0x13c VE module clock */ ++ u32 adda_clk_cfg; /* 0x140 ADDA module clock */ ++ u32 avs_clk_cfg; /* 0x144 AVS module clock */ ++ u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ ++ u32 reserved15; ++ u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ ++ u32 ps_clk_cfg; /* 0x154 PS module clock */ ++ u32 mtc_clk_cfg; /* 0x158 MTC module clock */ ++ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ ++ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ ++ u32 reserved16; ++ u32 mipi_dsi_clk_cfg; /* 0x168 MIPI DSI clock control */ ++ u32 mipi_csi_clk_cfg; /* 0x16c MIPI CSI clock control */ ++ u32 reserved17[4]; ++ u32 iep_drc0_clk_cfg; /* 0x180 IEP DRC0 module clock */ ++ u32 iep_drc1_clk_cfg; /* 0x184 IEP DRC1 module clock */ ++ u32 iep_deu0_clk_cfg; /* 0x188 IEP DEU0 module clock */ ++ u32 iep_deu1_clk_cfg; /* 0x18c IEP DEU1 module clock */ ++ u32 reserved18[4]; ++ u32 gpu_core_clk_cfg; /* 0x1a0 GPU core clock config */ ++ u32 gpu_mem_clk_cfg; /* 0x1a4 GPU memory clock config */ ++ u32 gpu_hyd_clk_cfg; /* 0x1a0 GPU HYD clock config */ ++ u32 reserved19[21]; ++ u32 pll_lock; /* 0x200 PLL Lock Time */ ++ u32 pll1_lock; /* 0x204 PLL1 Lock Time */ ++ u32 reserved20[6]; ++ u32 pll1_bias_cfg; /* 0x220 PLL1 Bias config */ ++ u32 pll2_bias_cfg; /* 0x224 PLL2 Bias config */ ++ u32 pll3_bias_cfg; /* 0x228 PLL3 Bias config */ ++ u32 pll4_bias_cfg; /* 0x22c PLL4 Bias config */ ++ u32 pll5_bias_cfg; /* 0x230 PLL5 Bias config */ ++ u32 pll6_bias_cfg; /* 0x234 PLL6 Bias config */ ++ u32 pll7_bias_cfg; /* 0x238 PLL7 Bias config */ ++ u32 pll8_bias_cfg; /* 0x23c PLL8 Bias config */ ++ u32 mipi_bias_cfg; /* 0x240 MIPI Bias config */ ++ u32 pll9_bias_cfg; /* 0x244 PLL9 Bias config */ ++ u32 pll10_bias_cfg; /* 0x248 PLL10 Bias config */ ++ u32 reserved21[13]; ++ u32 pll1_pattern_cfg; /* 0x280 PLL1 Pattern config */ ++ u32 pll2_pattern_cfg; /* 0x284 PLL2 Pattern config */ ++ u32 pll3_pattern_cfg; /* 0x288 PLL3 Pattern config */ ++ u32 pll4_pattern_cfg; /* 0x28c PLL4 Pattern config */ ++ u32 pll5_pattern_cfg; /* 0x290 PLL5 Pattern config */ ++ u32 pll6_pattern_cfg; /* 0x294 PLL6 Pattern config */ ++ u32 pll7_pattern_cfg; /* 0x298 PLL7 Pattern config */ ++ u32 pll8_pattern_cfg; /* 0x29c PLL8 Pattern config */ ++ u32 mipi_pattern_cfg; /* 0x2a0 MIPI Pattern config */ ++ u32 pll9_pattern_cfg; /* 0x2a4 PLL9 Pattern config */ ++ u32 pll10_pattern_cfg; /* 0x2a8 PLL10 Pattern config */ ++ u32 reserved22[5]; ++ u32 ahb_reset0_cfg; /* 0x2c0 AHB1 Reset 0 config */ ++ u32 ahb_reset1_cfg; /* 0x2c4 AHB1 Reset 1 config */ ++ u32 ahb_reset2_cfg; /* 0x2c8 AHB1 Reset 2 config */ ++ u32 reserved23; ++ u32 apb1_reset_cfg; /* 0x2d0 APB1 Reset config */ ++ u32 reserved24; ++ u32 apb2_reset_cfg; /* 0x2d8 APB2 Reset config */ ++}; ++ ++/* apb2 bit field */ ++#define APB2_CLK_SRC_LOSC (0x0 << 24) ++#define APB2_CLK_SRC_OSC24M (0x1 << 24) ++#define APB2_CLK_SRC_PLL6 (0x2 << 24) ++#define APB2_CLK_SRC_MASK (0x3 << 24) ++#define APB2_CLK_RATE_N_1 (0x0 << 16) ++#define APB2_CLK_RATE_N_2 (0x1 << 16) ++#define APB2_CLK_RATE_N_4 (0x2 << 16) ++#define APB2_CLK_RATE_N_8 (0x3 << 16) ++#define APB2_CLK_RATE_N_MASK (3 << 16) ++#define APB2_CLK_RATE_M(m) (((m)-1) << 0) ++#define APB2_CLK_RATE_M_MASK (0x1f << 0) ++ ++/* apb2 gate field */ ++#define APB2_GATE_UART_SHIFT (16) ++#define APB2_GATE_UART_MASK (0xff << APB2_GATE_UART_SHIFT) ++#define APB2_GATE_TWI_SHIFT (0) ++#define APB2_GATE_TWI_MASK (0xf << APB2_GATE_TWI_SHIFT) ++ ++/* cpu_axi_cfg bits */ ++#define AXI_DIV_SHIFT 0 ++#define ATB_DIV_SHIFT 8 ++#define CPU_CLK_SRC_SHIFT 16 ++ ++#define AXI_DIV_1 0 ++#define AXI_DIV_2 1 ++#define AXI_DIV_3 2 ++#define AXI_DIV_4 3 ++#define ATB_DIV_1 0 ++#define ATB_DIV_2 1 ++#define ATB_DIV_4 2 ++#define CPU_CLK_SRC_OSC24M 1 ++#define CPU_CLK_SRC_PLL1 2 ++ ++#define PLL1_CFG_DEFAULT 0x90011b21 ++ ++#define PLL6_CFG_DEFAULT 0x90041811 ++ ++#define CCM_PLL6_CTRL_N_SHIFT 8 ++#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) ++#define CCM_PLL6_CTRL_K_SHIFT 4 ++#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) ++ ++#define AHB_GATE_OFFSET_MMC3 11 ++#define AHB_GATE_OFFSET_MMC2 10 ++#define AHB_GATE_OFFSET_MMC1 9 ++#define AHB_GATE_OFFSET_MMC0 8 ++#define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) ++ ++#define CCM_MMC_CTRL_OSCM24 (0x0 << 24) ++#define CCM_MMC_CTRL_PLL6 (0x1 << 24) ++ ++#define CCM_MMC_CTRL_ENABLE (0x1 << 31) ++ ++#define AHB_RESET_OFFSET_MMC3 11 ++#define AHB_RESET_OFFSET_MMC2 10 ++#define AHB_RESET_OFFSET_MMC1 9 ++#define AHB_RESET_OFFSET_MMC0 8 ++#define AHB_RESET_OFFSET_MMC(n) (AHB_RESET_OFFSET_MMC0 + (n)) ++ ++/* apb2 reset */ ++#define APB2_RESET_UART_SHIFT (16) ++#define APB2_RESET_UART_MASK (0xff << APB2_RESET_UART_SHIFT) ++#define APB2_RESET_TWI_SHIFT (0) ++#define APB2_RESET_TWI_MASK (0xf << APB2_RESET_TWI_SHIFT) ++ ++#endif /* _SUNXI_CLOCK_SUN6I_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpucfg.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpucfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CPUCFG_H_ ++#define _SUNXI_CPUCFG_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++struct sunxi_cpu_ctrl { ++ u32 reset_ctrl; ++ u32 cpu_ctrl; ++ u32 status; ++ u32 _res[13]; ++}; ++ ++#define CPU_RESET_SET 0 ++#define CPU_RESET_CLEAR 3 ++ ++#define CPU_STATUS_SMP (1 << 0) ++#define CPU_STATUS_WFE (1 << 1) ++#define CPU_STATUS_WFI (1 << 2) ++ ++struct sunxi_cpucfg { ++ u32 _res1[16]; /* 0x000 */ ++ struct sunxi_cpu_ctrl cpu[2]; /* 0x040 */ ++ u32 _res2[48]; /* 0x0c0 */ ++ u32 _res3; /* 0x180 */ ++ u32 general_ctrl; /* 0x184 */ ++ u32 _res4[2]; /* 0x188 */ ++ u32 event_input; /* 0x190 */ ++ u32 _res5[4]; /* 0x194 */ ++ u32 boot_addr; /* 0x1a4 - also known as PRIVATE_REG */ ++ u32 _res6[2]; /* 0x1a8 */ ++ u32 cpu1_power_clamp; /* 0x1b0 */ ++ u32 cpu1_power_off; /* 0x1b4 */ ++ u32 _res7[10]; /* 0x1b8 */ ++ u32 debug0_ctrl; /* 0x1e0 */ ++ u32 debug1_ctrl; /* 0x1e4 */ ++}; ++ ++#define GENERAL_CTRL_NO_L1_RESET_CPU(x) (1UL << (x)) ++#define GENERAL_CTRL_NO_L2_AUTO_RESET (1UL << 4) ++#define GENERAL_CTRL_L2_RESET_SET (0UL << 5) ++#define GENERAL_CTRL_L2_RESET_CLEAR (1UL << 5) ++#define GENERAL_CTRL_CFGSDISABLE (1UL << 8) ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_CPUCFG_H_ */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpu.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,141 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CPU_H ++#define _SUNXI_CPU_H ++ ++#define SUNXI_SRAM_A1_BASE 0x00000000 ++#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */ ++ ++#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */ ++#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */ ++#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */ ++#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ ++#define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ ++ ++#define SUNXI_SRAMC_BASE 0x01c00000 ++#define SUNXI_DRAMC_BASE 0x01c01000 ++#define SUNXI_DMA_BASE 0x01c02000 ++#define SUNXI_NFC_BASE 0x01c03000 ++#define SUNXI_TS_BASE 0x01c04000 ++#define SUNXI_SPI0_BASE 0x01c05000 ++#define SUNXI_SPI1_BASE 0x01c06000 ++#define SUNXI_MS_BASE 0x01c07000 ++#define SUNXI_TVD_BASE 0x01c08000 ++#define SUNXI_CSI0_BASE 0x01c09000 ++#define SUNXI_TVE0_BASE 0x01c0a000 ++#define SUNXI_EMAC_BASE 0x01c0b000 ++#define SUNXI_LCD0_BASE 0x01c0C000 ++#define SUNXI_LCD1_BASE 0x01c0d000 ++#define SUNXI_VE_BASE 0x01c0e000 ++#define SUNXI_MMC0_BASE 0x01c0f000 ++#define SUNXI_MMC1_BASE 0x01c10000 ++#define SUNXI_MMC2_BASE 0x01c11000 ++#define SUNXI_MMC3_BASE 0x01c12000 ++#define SUNXI_USB0_BASE 0x01c13000 ++#define SUNXI_USB1_BASE 0x01c14000 ++#define SUNXI_SS_BASE 0x01c15000 ++#define SUNXI_HDMI_BASE 0x01c16000 ++#define SUNXI_SPI2_BASE 0x01c17000 ++#define SUNXI_SATA_BASE 0x01c18000 ++#define SUNXI_PATA_BASE 0x01c19000 ++#define SUNXI_ACE_BASE 0x01c1a000 ++#define SUNXI_TVE1_BASE 0x01c1b000 ++#define SUNXI_USB2_BASE 0x01c1c000 ++#define SUNXI_CSI1_BASE 0x01c1d000 ++#define SUNXI_TZASC_BASE 0x01c1e000 ++#define SUNXI_SPI3_BASE 0x01c1f000 ++ ++#define SUNXI_CCM_BASE 0x01c20000 ++#define SUNXI_INTC_BASE 0x01c20400 ++#define SUNXI_PIO_BASE 0x01c20800 ++#define SUNXI_TIMER_BASE 0x01c20c00 ++#define SUNXI_SPDIF_BASE 0x01c21000 ++#define SUNXI_AC97_BASE 0x01c21400 ++#define SUNXI_IR0_BASE 0x01c21800 ++#define SUNXI_IR1_BASE 0x01c21c00 ++ ++#define SUNXI_IIS_BASE 0x01c22400 ++#define SUNXI_LRADC_BASE 0x01c22800 ++#define SUNXI_AD_DA_BASE 0x01c22c00 ++#define SUNXI_KEYPAD_BASE 0x01c23000 ++#define SUNXI_TZPC_BASE 0x01c23400 ++#define SUNXI_SID_BASE 0x01c23800 ++#define SUNXI_SJTAG_BASE 0x01c23c00 ++ ++#define SUNXI_TP_BASE 0x01c25000 ++#define SUNXI_PMU_BASE 0x01c25400 ++#define SUNXI_CPUCFG_BASE 0x01c25c00 /* sun7i only ? */ ++ ++#define SUNXI_UART0_BASE 0x01c28000 ++#define SUNXI_UART1_BASE 0x01c28400 ++#define SUNXI_UART2_BASE 0x01c28800 ++#define SUNXI_UART3_BASE 0x01c28c00 ++#define SUNXI_UART4_BASE 0x01c29000 ++#define SUNXI_UART5_BASE 0x01c29400 ++#define SUNXI_UART6_BASE 0x01c29800 ++#define SUNXI_UART7_BASE 0x01c29c00 ++#define SUNXI_PS2_0_BASE 0x01c2a000 ++#define SUNXI_PS2_1_BASE 0x01c2a400 ++ ++#define SUNXI_TWI0_BASE 0x01c2ac00 ++#define SUNXI_TWI1_BASE 0x01c2b000 ++#define SUNXI_TWI2_BASE 0x01c2b400 ++ ++#define SUNXI_CAN_BASE 0x01c2bc00 ++ ++#define SUNXI_SCR_BASE 0x01c2c400 ++ ++#define SUNXI_GPS_BASE 0x01c30000 ++#define SUNXI_MALI400_BASE 0x01c40000 ++#define SUNXI_GMAC_BASE 0x01c50000 ++ ++#define SUNXI_DRAM_COM_BASE 0x01c62000 ++#define SUNXI_DRAM_CTL_BASE 0x01c63000 ++#define SUNXI_DRAM_PHY_CH1_BASE 0x01c65000 ++#define SUNXI_DRAM_PHY_CH2_BASE 0x01c66000 ++ ++/* module sram */ ++#define SUNXI_SRAM_C_BASE 0x01d00000 ++ ++#define SUNXI_DE_FE0_BASE 0x01e00000 ++#define SUNXI_DE_FE1_BASE 0x01e20000 ++#define SUNXI_DE_BE0_BASE 0x01e60000 ++#define SUNXI_DE_BE1_BASE 0x01e40000 ++#define SUNXI_MP_BASE 0x01e80000 ++#define SUNXI_AVG_BASE 0x01ea0000 ++ ++#define SUNXI_PRCM_BASE 0x01f01400 ++#define SUNXI_R_UART_BASE 0x01f02800 ++#define SUNXI_R_PIO_BASE 0x01f02c00 ++#define SUNXI_P2WI_BASE 0x01f03400 ++ ++/* CoreSight Debug Module */ ++#define SUNXI_CSDM_BASE 0x3f500000 ++ ++#define SUNXI_DDRII_DDRIII_BASE 0x40000000 /* 2 GiB */ ++ ++#define SUNXI_BROM_BASE 0xffff0000 /* 32 kiB */ ++ ++#define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) ++ ++#ifndef __ASSEMBLY__ ++/* boot type */ ++enum sunxi_boot_type_t { ++ SUNXI_BOOT_TYPE_NULL, ++ SUNXI_BOOT_TYPE_MMC0, ++ SUNXI_BOOT_TYPE_NAND, ++ SUNXI_BOOT_TYPE_MMC2, ++ SUNXI_BOOT_TYPE_SPI ++}; ++ ++void sunxi_board_init(void); ++void sunxi_reset(void); ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _CPU_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/dram.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/dram.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,179 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Sunxi platform dram register definition. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_DRAM_H ++#define _SUNXI_DRAM_H ++ ++#include <linux/types.h> ++ ++struct sunxi_dram_reg { ++ u32 ccr; /* 0x00 controller configuration register */ ++ u32 dcr; /* 0x04 dram configuration register */ ++ u32 iocr; /* 0x08 i/o configuration register */ ++ u32 csr; /* 0x0c controller status register */ ++ u32 drr; /* 0x10 dram refresh register */ ++ u32 tpr0; /* 0x14 dram timing parameters register 0 */ ++ u32 tpr1; /* 0x18 dram timing parameters register 1 */ ++ u32 tpr2; /* 0x1c dram timing parameters register 2 */ ++ u32 gdllcr; /* 0x20 global dll control register */ ++ u8 res0[0x28]; ++ u32 rslr0; /* 0x4c rank system latency register */ ++ u32 rslr1; /* 0x50 rank system latency register */ ++ u8 res1[0x8]; ++ u32 rdgr0; /* 0x5c rank dqs gating register */ ++ u32 rdgr1; /* 0x60 rank dqs gating register */ ++ u8 res2[0x34]; ++ u32 odtcr; /* 0x98 odt configuration register */ ++ u32 dtr0; /* 0x9c data training register 0 */ ++ u32 dtr1; /* 0xa0 data training register 1 */ ++ u32 dtar; /* 0xa4 data training address register */ ++ u32 zqcr0; /* 0xa8 zq control register 0 */ ++ u32 zqcr1; /* 0xac zq control register 1 */ ++ u32 zqsr; /* 0xb0 zq status register */ ++ u32 idcr; /* 0xb4 initializaton delay configure reg */ ++ u8 res3[0x138]; ++ u32 mr; /* 0x1f0 mode register */ ++ u32 emr; /* 0x1f4 extended mode register */ ++ u32 emr2; /* 0x1f8 extended mode register */ ++ u32 emr3; /* 0x1fc extended mode register */ ++ u32 dllctr; /* 0x200 dll control register */ ++ u32 dllcr[5]; /* 0x204 dll control register 0(byte 0) */ ++ /* 0x208 dll control register 1(byte 1) */ ++ /* 0x20c dll control register 2(byte 2) */ ++ /* 0x210 dll control register 3(byte 3) */ ++ /* 0x214 dll control register 4(byte 4) */ ++ u32 dqtr0; /* 0x218 dq timing register */ ++ u32 dqtr1; /* 0x21c dq timing register */ ++ u32 dqtr2; /* 0x220 dq timing register */ ++ u32 dqtr3; /* 0x224 dq timing register */ ++ u32 dqstr; /* 0x228 dqs timing register */ ++ u32 dqsbtr; /* 0x22c dqsb timing register */ ++ u32 mcr; /* 0x230 mode configure register */ ++ u8 res[0x8]; ++ u32 ppwrsctl; /* 0x23c pad power save control */ ++ u32 apr; /* 0x240 arbiter period register */ ++ u32 pldtr; /* 0x244 priority level data threshold reg */ ++ u8 res5[0x8]; ++ u32 hpcr[32]; /* 0x250 host port configure register */ ++ u8 res6[0x10]; ++ u32 csel; /* 0x2e0 controller select register */ ++}; ++ ++struct dram_para { ++ u32 clock; ++ u32 type; ++ u32 rank_num; ++ u32 density; ++ u32 io_width; ++ u32 bus_width; ++ u32 cas; ++ u32 zq; ++ u32 odt_en; ++ u32 size; ++ u32 tpr0; ++ u32 tpr1; ++ u32 tpr2; ++ u32 tpr3; ++ u32 tpr4; ++ u32 tpr5; ++ u32 emr1; ++ u32 emr2; ++ u32 emr3; ++}; ++ ++#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5) ++#define DRAM_CCR_DQS_GATE (0x1 << 14) ++#define DRAM_CCR_DQS_DRIFT_COMP (0x1 << 17) ++#define DRAM_CCR_ITM_OFF (0x1 << 28) ++#define DRAM_CCR_DATA_TRAINING (0x1 << 30) ++#define DRAM_CCR_INIT (0x1 << 31) ++ ++#define DRAM_MEMORY_TYPE_DDR1 1 ++#define DRAM_MEMORY_TYPE_DDR2 2 ++#define DRAM_MEMORY_TYPE_DDR3 3 ++#define DRAM_MEMORY_TYPE_LPDDR2 4 ++#define DRAM_MEMORY_TYPE_LPDDR 5 ++#define DRAM_DCR_TYPE (0x1 << 0) ++#define DRAM_DCR_TYPE_DDR2 0x0 ++#define DRAM_DCR_TYPE_DDR3 0x1 ++#define DRAM_DCR_IO_WIDTH(n) (((n) & 0x3) << 1) ++#define DRAM_DCR_IO_WIDTH_MASK DRAM_DCR_IO_WIDTH(0x3) ++#define DRAM_DCR_IO_WIDTH_8BIT 0x0 ++#define DRAM_DCR_IO_WIDTH_16BIT 0x1 ++#define DRAM_DCR_CHIP_DENSITY(n) (((n) & 0x7) << 3) ++#define DRAM_DCR_CHIP_DENSITY_MASK DRAM_DCR_CHIP_DENSITY(0x7) ++#define DRAM_DCR_CHIP_DENSITY_256M 0x0 ++#define DRAM_DCR_CHIP_DENSITY_512M 0x1 ++#define DRAM_DCR_CHIP_DENSITY_1024M 0x2 ++#define DRAM_DCR_CHIP_DENSITY_2048M 0x3 ++#define DRAM_DCR_CHIP_DENSITY_4096M 0x4 ++#define DRAM_DCR_CHIP_DENSITY_8192M 0x5 ++#define DRAM_DCR_BUS_WIDTH(n) (((n) & 0x7) << 6) ++#define DRAM_DCR_BUS_WIDTH_MASK DRAM_DCR_BUS_WIDTH(0x7) ++#define DRAM_DCR_BUS_WIDTH_32BIT 0x3 ++#define DRAM_DCR_BUS_WIDTH_16BIT 0x1 ++#define DRAM_DCR_BUS_WIDTH_8BIT 0x0 ++#define DRAM_DCR_NR_DLLCR_32BIT 5 ++#define DRAM_DCR_NR_DLLCR_16BIT 3 ++#define DRAM_DCR_NR_DLLCR_8BIT 2 ++#define DRAM_DCR_RANK_SEL(n) (((n) & 0x3) << 10) ++#define DRAM_DCR_RANK_SEL_MASK DRAM_DCR_CMD_RANK(0x3) ++#define DRAM_DCR_CMD_RANK_ALL (0x1 << 12) ++#define DRAM_DCR_MODE(n) (((n) & 0x3) << 13) ++#define DRAM_DCR_MODE_MASK DRAM_DCR_MODE(0x3) ++#define DRAM_DCR_MODE_SEQ 0x0 ++#define DRAM_DCR_MODE_INTERLEAVE 0x1 ++ ++#define DRAM_CSR_FAILED (0x1 << 20) ++ ++#define DRAM_DRR_TRFC(n) ((n) & 0xff) ++#define DRAM_DRR_TREFI(n) (((n) & 0xffff) << 8) ++#define DRAM_DRR_BURST(n) ((((n) - 1) & 0xf) << 24) ++ ++#define DRAM_MCR_MODE_NORM(n) (((n) & 0x3) << 0) ++#define DRAM_MCR_MODE_NORM_MASK DRAM_MCR_MOD_NORM(0x3) ++#define DRAM_MCR_MODE_DQ_OUT(n) (((n) & 0x3) << 2) ++#define DRAM_MCR_MODE_DQ_OUT_MASK DRAM_MCR_MODE_DQ_OUT(0x3) ++#define DRAM_MCR_MODE_ADDR_OUT(n) (((n) & 0x3) << 4) ++#define DRAM_MCR_MODE_ADDR_OUT_MASK DRAM_MCR_MODE_ADDR_OUT(0x3) ++#define DRAM_MCR_MODE_DQ_IN_OUT(n) (((n) & 0x3) << 6) ++#define DRAM_MCR_MODE_DQ_IN_OUT_MASK DRAM_MCR_MODE_DQ_IN_OUT(0x3) ++#define DRAM_MCR_MODE_DQ_TURNON_DELAY(n) (((n) & 0x7) << 8) ++#define DRAM_MCR_MODE_DQ_TURNON_DELAY_MASK DRAM_MCR_MODE_DQ_TURNON_DELAY(0x7) ++#define DRAM_MCR_MODE_ADDR_IN (0x1 << 11) ++#define DRAM_MCR_RESET (0x1 << 12) ++#define DRAM_MCR_MODE_EN(n) (((n) & 0x3) << 13) ++#define DRAM_MCR_MODE_EN_MASK DRAM_MCR_MOD_EN(0x3) ++#define DRAM_MCR_DCLK_OUT (0x1 << 16) ++ ++#define DRAM_DLLCR_NRESET (0x1 << 30) ++#define DRAM_DLLCR_DISABLE (0x1 << 31) ++ ++#define DRAM_ZQCR0_IMP_DIV(n) (((n) & 0xff) << 20) ++#define DRAM_ZQCR0_IMP_DIV_MASK DRAM_ZQCR0_IMP_DIV(0xff) ++ ++#define DRAM_IOCR_ODT_EN(n) ((((n) & 0x3) << 30) | ((n) & 0x3) << 0) ++#define DRAM_IOCR_ODT_EN_MASK DRAM_IOCR_ODT_EN(0x3) ++ ++#define DRAM_MR_BURST_LENGTH(n) (((n) & 0x7) << 0) ++#define DRAM_MR_BURST_LENGTH_MASK DRAM_MR_BURST_LENGTH(0x7) ++#define DRAM_MR_CAS_LAT(n) (((n) & 0x7) << 4) ++#define DRAM_MR_CAS_LAT_MASK DRAM_MR_CAS_LAT(0x7) ++#define DRAM_MR_WRITE_RECOVERY(n) (((n) & 0x7) << 9) ++#define DRAM_MR_WRITE_RECOVERY_MASK DRAM_MR_WRITE_RECOVERY(0x7) ++#define DRAM_MR_POWER_DOWN (0x1 << 12) ++ ++#define DRAM_CSEL_MAGIC 0x16237495 ++ ++unsigned long sunxi_dram_init(void); ++unsigned long dramc_init(struct dram_para *para); ++ ++#endif /* _SUNXI_DRAM_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/early_print.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/early_print.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,58 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Early uart print for debugging. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_EARLY_PRINT_H ++#define _SUNXI_EARLY_PRINT_H ++ ++#include <asm/arch/cpu.h> ++ ++#define SUNXI_UART_BASE SUNXI_UART0_BASE ++ ++#define UART_OFFSET 0x400 ++ ++/* receive buffer register */ ++#define UART_RBR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++/* transmit holding register */ ++#define UART_THR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++/* divisor latch low register */ ++#define UART_DLL(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++ ++/* divisor latch high register */ ++#define UART_DLH(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x4) ++/* interrupt enable reigster */ ++#define UART_IER(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x4) ++ ++/* interrupt identity register */ ++#define UART_IIR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x8) ++/* fifo control register */ ++#define UART_FCR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x8) ++ ++/* line control register */ ++#define UART_LCR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0xc) ++#define UART_LCR_DLAB (0x1 << 7) ++ ++/* line status register */ ++#define UART_LSR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x14) ++#define UART_LSR_TEMT (0x1 << 6) ++ ++ ++#define BAUD_115200 (0xd) /* 24 * 1000 * 1000 / 16 / 115200 = 13 */ ++#define NO_PARITY (0) ++#define ONE_STOP_BIT (0) ++#define DAT_LEN_8_BITS (3) ++#define LC_8_N_1 (NO_PARITY << 3 | ONE_STOP_BIT << 2 | DAT_LEN_8_BITS) ++ ++#ifndef __ASSEMBLY__ ++void uart_init(void); ++void uart_putc(char c); ++void uart_puts(const char *s); ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_EARLY_PRINT_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/gpio.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,174 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_GPIO_H ++#define _SUNXI_GPIO_H ++ ++#include <linux/types.h> ++#include <asm/arch/cpu.h> ++ ++/* ++ * sunxi has 9 banks of gpio, they are: ++ * PA0 - PA17 | PB0 - PB23 | PC0 - PC24 ++ * PD0 - PD27 | PE0 - PE31 | PF0 - PF5 ++ * PG0 - PG9 | PH0 - PH27 | PI0 - PI12 ++ */ ++ ++#define SUNXI_GPIO_A 0 ++#define SUNXI_GPIO_B 1 ++#define SUNXI_GPIO_C 2 ++#define SUNXI_GPIO_D 3 ++#define SUNXI_GPIO_E 4 ++#define SUNXI_GPIO_F 5 ++#define SUNXI_GPIO_G 6 ++#define SUNXI_GPIO_H 7 ++#define SUNXI_GPIO_I 8 ++#define SUNXI_GPIO_BANKS 9 ++ ++/* ++ * sun6i has atleast 1 additional bank, note banks J K don't exist! ++ * PL0 - PL1 at the very least is known. ++ * ++ * Note this bank is at a different register offset! ++ */ ++#define SUNXI_GPIO_L 9 ++ ++struct sunxi_gpio { ++ u32 cfg[4]; ++ u32 dat; ++ u32 drv[2]; ++ u32 pull[2]; ++}; ++ ++/* gpio interrupt control */ ++struct sunxi_gpio_int { ++ u32 cfg[3]; ++ u32 ctl; ++ u32 sta; ++ u32 deb; /* interrupt debounce */ ++}; ++ ++struct sunxi_gpio_reg { ++ struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS]; ++ u8 res[0xbc]; ++ struct sunxi_gpio_int gpio_int; ++}; ++ ++#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_BANKS) ? \ ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \ ++ (struct sunxi_gpio *)SUNXI_R_PIO_BASE) ++ ++#define GPIO_BANK(pin) ((pin) >> 5) ++#define GPIO_NUM(pin) ((pin) & 0x1f) ++ ++#define GPIO_CFG_INDEX(pin) (((pin) & 0x1f) >> 3) ++#define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1f) & 0x7) << 2) ++ ++#define GPIO_DRV_INDEX(pin) (((pin) & 0x1f) >> 4) ++#define GPIO_DRV_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) ++ ++#define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4) ++#define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) ++ ++/* GPIO bank sizes */ ++#define SUNXI_GPIO_A_NR 32 ++#define SUNXI_GPIO_B_NR 32 ++#define SUNXI_GPIO_C_NR 32 ++#define SUNXI_GPIO_D_NR 32 ++#define SUNXI_GPIO_E_NR 32 ++#define SUNXI_GPIO_F_NR 32 ++#define SUNXI_GPIO_G_NR 32 ++#define SUNXI_GPIO_H_NR 32 ++#define SUNXI_GPIO_I_NR 32 ++#define SUNXI_GPIO_L_NR 32 ++ ++#define SUNXI_GPIO_NEXT(__gpio) \ ++ ((__gpio##_START) + (__gpio##_NR) + 0) ++ ++enum sunxi_gpio_number { ++ SUNXI_GPIO_A_START = 0, ++ SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A), ++ SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B), ++ SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C), ++ SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D), ++ SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E), ++ SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F), ++ SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G), ++ SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H), ++ SUNXI_GPIO_L_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_I), ++}; ++ ++/* SUNXI GPIO number definitions */ ++#define SUNXI_GPA(_nr) (SUNXI_GPIO_A_START + (_nr)) ++#define SUNXI_GPB(_nr) (SUNXI_GPIO_B_START + (_nr)) ++#define SUNXI_GPC(_nr) (SUNXI_GPIO_C_START + (_nr)) ++#define SUNXI_GPD(_nr) (SUNXI_GPIO_D_START + (_nr)) ++#define SUNXI_GPE(_nr) (SUNXI_GPIO_E_START + (_nr)) ++#define SUNXI_GPF(_nr) (SUNXI_GPIO_F_START + (_nr)) ++#define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr)) ++#define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr)) ++#define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr)) ++#define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr)) ++ ++/* GPIO pin function config */ ++#define SUNXI_GPIO_INPUT 0 ++#define SUNXI_GPIO_OUTPUT 1 ++ ++#define SUNXI_GPA0_EMAC 2 ++#define SUN7I_GPA0_GMAC 5 ++ ++#define SUNXI_GPB0_TWI0 2 ++ ++#define SUN4I_GPB22_UART0_TX 2 ++#define SUN4I_GPB23_UART0_RX 2 ++ ++#define SUN5I_GPB19_UART0_TX 2 ++#define SUN5I_GPB20_UART0_RX 2 ++ ++#define SUN5I_GPG3_UART1_TX 4 ++#define SUN5I_GPG4_UART1_RX 4 ++ ++#define SUNXI_GPC6_SDC2 3 ++ ++#define SUNXI_GPF0_SDC0 2 ++ ++#define SUNXI_GPF2_SDC0 2 ++ ++#ifdef CONFIG_SUN8I ++#define SUNXI_GPF2_UART0_TX 3 ++#define SUNXI_GPF4_UART0_RX 3 ++#else ++#define SUNXI_GPF2_UART0_TX 4 ++#define SUNXI_GPF4_UART0_RX 4 ++#endif ++ ++#define SUN4I_GPG0_SDC1 4 ++ ++#define SUN4I_GPH22_SDC1 5 ++ ++#define SUN4I_GPI4_SDC3 2 ++ ++/* GPIO pin pull-up/down config */ ++#define SUNXI_GPIO_PULL_DISABLE 0 ++#define SUNXI_GPIO_PULL_UP 1 ++#define SUNXI_GPIO_PULL_DOWN 2 ++ ++#define SUNXI_GPL0_R_P2WI_SCK 3 ++#define SUNXI_GPL1_R_P2WI_SDA 3 ++ ++#define SUN8I_GPL2_R_UART_TX 2 ++#define SUN8I_GPL3_R_UART_RX 2 ++ ++int sunxi_gpio_set_cfgpin(u32 pin, u32 val); ++int sunxi_gpio_get_cfgpin(u32 pin); ++int sunxi_gpio_set_drv(u32 pin, u32 val); ++int sunxi_gpio_set_pull(u32 pin, u32 val); ++int sunxi_name_to_gpio(const char *name); ++#define name_to_gpio(name) sunxi_name_to_gpio(name) ++ ++#endif /* _SUNXI_GPIO_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/i2c.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/i2c.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * Copyright 2014 - Hans de Goede hdegoede@redhat.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef _SUNXI_I2C_H_ ++#define _SUNXI_I2C_H_ ++ ++#include <asm/arch/cpu.h> ++ ++#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE ++/* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ ++#define CONFIG_SYS_TCLK 24000000 ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/mmc.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/mmc.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,122 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Aaron leafy.myeh@allwinnertech.com ++ * ++ * MMC register definition for allwinner sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_MMC_H ++#define _SUNXI_MMC_H ++ ++#include <linux/types.h> ++ ++struct sunxi_mmc { ++ u32 gctrl; /* 0x00 global control */ ++ u32 clkcr; /* 0x04 clock control */ ++ u32 timeout; /* 0x08 time out */ ++ u32 width; /* 0x0c bus width */ ++ u32 blksz; /* 0x10 block size */ ++ u32 bytecnt; /* 0x14 byte count */ ++ u32 cmd; /* 0x18 command */ ++ u32 arg; /* 0x1c argument */ ++ u32 resp0; /* 0x20 response 0 */ ++ u32 resp1; /* 0x24 response 1 */ ++ u32 resp2; /* 0x28 response 2 */ ++ u32 resp3; /* 0x2c response 3 */ ++ u32 imask; /* 0x30 interrupt mask */ ++ u32 mint; /* 0x34 masked interrupt status */ ++ u32 rint; /* 0x38 raw interrupt status */ ++ u32 status; /* 0x3c status */ ++ u32 ftrglevel; /* 0x40 FIFO threshold watermark*/ ++ u32 funcsel; /* 0x44 function select */ ++ u32 cbcr; /* 0x48 CIU byte count */ ++ u32 bbcr; /* 0x4c BIU byte count */ ++ u32 dbgc; /* 0x50 debug enable */ ++ u32 res0[11]; ++ u32 dmac; /* 0x80 internal DMA control */ ++ u32 dlba; /* 0x84 internal DMA descr list base address */ ++ u32 idst; /* 0x88 internal DMA status */ ++ u32 idie; /* 0x8c internal DMA interrupt enable */ ++ u32 chda; /* 0x90 */ ++ u32 cbda; /* 0x94 */ ++}; ++ ++#define SUNXI_MMC_CLK_POWERSAVE (0x1 << 17) ++#define SUNXI_MMC_CLK_ENABLE (0x1 << 16) ++#define SUNXI_MMC_CLK_DIVIDER_MASK (0xff) ++ ++#define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0) ++#define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1) ++#define SUNXI_MMC_GCTRL_DMA_RESET (0x1 << 2) ++#define SUNXI_MMC_GCTRL_RESET (SUNXI_MMC_GCTRL_SOFT_RESET|\ ++ SUNXI_MMC_GCTRL_FIFO_RESET|\ ++ SUNXI_MMC_GCTRL_DMA_RESET) ++#define SUNXI_MMC_GCTRL_DMA_ENABLE (0x1 << 5) ++#define SUNXI_MMC_GCTRL_ACCESS_BY_AHB (0x1 << 31) ++ ++#define SUNXI_MMC_CMD_RESP_EXPIRE (0x1 << 6) ++#define SUNXI_MMC_CMD_LONG_RESPONSE (0x1 << 7) ++#define SUNXI_MMC_CMD_CHK_RESPONSE_CRC (0x1 << 8) ++#define SUNXI_MMC_CMD_DATA_EXPIRE (0x1 << 9) ++#define SUNXI_MMC_CMD_WRITE (0x1 << 10) ++#define SUNXI_MMC_CMD_AUTO_STOP (0x1 << 12) ++#define SUNXI_MMC_CMD_WAIT_PRE_OVER (0x1 << 13) ++#define SUNXI_MMC_CMD_SEND_INIT_SEQ (0x1 << 15) ++#define SUNXI_MMC_CMD_UPCLK_ONLY (0x1 << 21) ++#define SUNXI_MMC_CMD_START (0x1 << 31) ++ ++#define SUNXI_MMC_RINT_RESP_ERROR (0x1 << 1) ++#define SUNXI_MMC_RINT_COMMAND_DONE (0x1 << 2) ++#define SUNXI_MMC_RINT_DATA_OVER (0x1 << 3) ++#define SUNXI_MMC_RINT_TX_DATA_REQUEST (0x1 << 4) ++#define SUNXI_MMC_RINT_RX_DATA_REQUEST (0x1 << 5) ++#define SUNXI_MMC_RINT_RESP_CRC_ERROR (0x1 << 6) ++#define SUNXI_MMC_RINT_DATA_CRC_ERROR (0x1 << 7) ++#define SUNXI_MMC_RINT_RESP_TIMEOUT (0x1 << 8) ++#define SUNXI_MMC_RINT_DATA_TIMEOUT (0x1 << 9) ++#define SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE (0x1 << 10) ++#define SUNXI_MMC_RINT_FIFO_RUN_ERROR (0x1 << 11) ++#define SUNXI_MMC_RINT_HARD_WARE_LOCKED (0x1 << 12) ++#define SUNXI_MMC_RINT_START_BIT_ERROR (0x1 << 13) ++#define SUNXI_MMC_RINT_AUTO_COMMAND_DONE (0x1 << 14) ++#define SUNXI_MMC_RINT_END_BIT_ERROR (0x1 << 15) ++#define SUNXI_MMC_RINT_SDIO_INTERRUPT (0x1 << 16) ++#define SUNXI_MMC_RINT_CARD_INSERT (0x1 << 30) ++#define SUNXI_MMC_RINT_CARD_REMOVE (0x1 << 31) ++#define SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT \ ++ (SUNXI_MMC_RINT_RESP_ERROR | \ ++ SUNXI_MMC_RINT_RESP_CRC_ERROR | \ ++ SUNXI_MMC_RINT_DATA_CRC_ERROR | \ ++ SUNXI_MMC_RINT_RESP_TIMEOUT | \ ++ SUNXI_MMC_RINT_DATA_TIMEOUT | \ ++ SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE | \ ++ SUNXI_MMC_RINT_FIFO_RUN_ERROR | \ ++ SUNXI_MMC_RINT_HARD_WARE_LOCKED | \ ++ SUNXI_MMC_RINT_START_BIT_ERROR | \ ++ SUNXI_MMC_RINT_END_BIT_ERROR) /* 0xbfc2 */ ++#define SUNXI_MMC_RINT_INTERRUPT_DONE_BIT \ ++ (SUNXI_MMC_RINT_AUTO_COMMAND_DONE | \ ++ SUNXI_MMC_RINT_DATA_OVER | \ ++ SUNXI_MMC_RINT_COMMAND_DONE | \ ++ SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE) ++ ++#define SUNXI_MMC_STATUS_RXWL_FLAG (0x1 << 0) ++#define SUNXI_MMC_STATUS_TXWL_FLAG (0x1 << 1) ++#define SUNXI_MMC_STATUS_FIFO_EMPTY (0x1 << 2) ++#define SUNXI_MMC_STATUS_FIFO_FULL (0x1 << 3) ++#define SUNXI_MMC_STATUS_CARD_PRESENT (0x1 << 8) ++#define SUNXI_MMC_STATUS_CARD_DATA_BUSY (0x1 << 9) ++#define SUNXI_MMC_STATUS_DATA_FSM_BUSY (0x1 << 10) ++ ++#define SUNXI_MMC_IDMAC_RESET (0x1 << 0) ++#define SUNXI_MMC_IDMAC_FIXBURST (0x1 << 1) ++#define SUNXI_MMC_IDMAC_ENABLE (0x1 << 7) ++ ++#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0) ++#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1) ++ ++int sunxi_mmc_init(int sdc_no); ++#endif /* _SUNXI_MMC_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/p2wi.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/p2wi.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/p2wi.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/p2wi.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,142 @@ ++/* ++ * Sunxi platform Push-Push i2c register definition. ++ * ++ * (c) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * (c)Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_P2WI_H ++#define _SUNXI_P2WI_H ++ ++#include <linux/types.h> ++ ++#define P2WI_CTRL_RESET (0x1 << 0) ++#define P2WI_CTRL_IRQ_EN (0x1 << 1) ++#define P2WI_CTRL_TRANS_ABORT (0x1 << 6) ++#define P2WI_CTRL_TRANS_START (0x1 << 7) ++ ++#define __P2WI_CC_CLK(n) (((n) & 0xff) << 0) ++#define P2WI_CC_CLK_MASK __P2WI_CC_CLK_DIV(0xff) ++#define __P2WI_CC_CLK_DIV(n) (((n) >> 1) - 1) ++#define P2WI_CC_CLK_DIV(n) \ ++ __P2WI_CC_CLK(__P2WI_CC_CLK_DIV(n)) ++#define P2WI_CC_SDA_OUT_DELAY(n) (((n) & 0x7) << 8) ++#define P2WI_CC_SDA_OUT_DELAY_MASK P2WI_CC_SDA_OUT_DELAY(0x7) ++ ++#define P2WI_IRQ_TRANS_DONE (0x1 << 0) ++#define P2WI_IRQ_TRANS_ERR (0x1 << 1) ++#define P2WI_IRQ_LOAD_BUSY (0x1 << 2) ++ ++#define P2WI_STAT_TRANS_DONE (0x1 << 0) ++#define P2WI_STAT_TRANS_ERR (0x1 << 1) ++#define P2WI_STAT_LOAD_BUSY (0x1 << 2) ++#define __P2WI_STAT_TRANS_ERR(n) (((n) & 0xff) << 8) ++#define P2WI_STAT_TRANS_ERR_MASK __P2WI_STAT_TRANS_ERR_ID(0xff) ++#define __P2WI_STAT_TRANS_ERR_BYTE_1 0x01 ++#define __P2WI_STAT_TRANS_ERR_BYTE_2 0x02 ++#define __P2WI_STAT_TRANS_ERR_BYTE_3 0x04 ++#define __P2WI_STAT_TRANS_ERR_BYTE_4 0x08 ++#define __P2WI_STAT_TRANS_ERR_BYTE_5 0x10 ++#define __P2WI_STAT_TRANS_ERR_BYTE_6 0x20 ++#define __P2WI_STAT_TRANS_ERR_BYTE_7 0x40 ++#define __P2WI_STAT_TRANS_ERR_BYTE_8 0x80 ++#define P2WI_STAT_TRANS_ERR_BYTE_1 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_1) ++#define P2WI_STAT_TRANS_ERR_BYTE_2 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_2) ++#define P2WI_STAT_TRANS_ERR_BYTE_3 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_3) ++#define P2WI_STAT_TRANS_ERR_BYTE_4 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_4) ++#define P2WI_STAT_TRANS_ERR_BYTE_5 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_5) ++#define P2WI_STAT_TRANS_ERR_BYTE_6 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_6) ++#define P2WI_STAT_TRANS_ERR_BYTE_7 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_7) ++#define P2WI_STAT_TRANS_ERR_BYTE_8 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_8) ++ ++#define P2WI_DATADDR_BYTE_1(n) (((n) & 0xff) << 0) ++#define P2WI_DATADDR_BYTE_1_MASK P2WI_DATADDR_BYTE_1(0xff) ++#define P2WI_DATADDR_BYTE_2(n) (((n) & 0xff) << 8) ++#define P2WI_DATADDR_BYTE_2_MASK P2WI_DATADDR_BYTE_2(0xff) ++#define P2WI_DATADDR_BYTE_3(n) (((n) & 0xff) << 16) ++#define P2WI_DATADDR_BYTE_3_MASK P2WI_DATADDR_BYTE_3(0xff) ++#define P2WI_DATADDR_BYTE_4(n) (((n) & 0xff) << 24) ++#define P2WI_DATADDR_BYTE_4_MASK P2WI_DATADDR_BYTE_4(0xff) ++#define P2WI_DATADDR_BYTE_5(n) (((n) & 0xff) << 0) ++#define P2WI_DATADDR_BYTE_5_MASK P2WI_DATADDR_BYTE_5(0xff) ++#define P2WI_DATADDR_BYTE_6(n) (((n) & 0xff) << 8) ++#define P2WI_DATADDR_BYTE_6_MASK P2WI_DATADDR_BYTE_6(0xff) ++#define P2WI_DATADDR_BYTE_7(n) (((n) & 0xff) << 16) ++#define P2WI_DATADDR_BYTE_7_MASK P2WI_DATADDR_BYTE_7(0xff) ++#define P2WI_DATADDR_BYTE_8(n) (((n) & 0xff) << 24) ++#define P2WI_DATADDR_BYTE_8_MASK P2WI_DATADDR_BYTE_8(0xff) ++ ++#define __P2WI_DATA_NUM_BYTES(n) (((n) & 0x7) << 0) ++#define P2WI_DATA_NUM_BYTES_MASK __P2WI_DATA_NUM_BYTES(0x7) ++#define P2WI_DATA_NUM_BYTES(n) __P2WI_DATA_NUM_BYTES((n) - 1) ++#define P2WI_DATA_NUM_BYTES_READ (0x1 << 4) ++ ++#define P2WI_DATA_BYTE_1(n) (((n) & 0xff) << 0) ++#define P2WI_DATA_BYTE_1_MASK P2WI_DATA_BYTE_1(0xff) ++#define P2WI_DATA_BYTE_2(n) (((n) & 0xff) << 8) ++#define P2WI_DATA_BYTE_2_MASK P2WI_DATA_BYTE_2(0xff) ++#define P2WI_DATA_BYTE_3(n) (((n) & 0xff) << 16) ++#define P2WI_DATA_BYTE_3_MASK P2WI_DATA_BYTE_3(0xff) ++#define P2WI_DATA_BYTE_4(n) (((n) & 0xff) << 24) ++#define P2WI_DATA_BYTE_4_MASK P2WI_DATA_BYTE_4(0xff) ++#define P2WI_DATA_BYTE_5(n) (((n) & 0xff) << 0) ++#define P2WI_DATA_BYTE_5_MASK P2WI_DATA_BYTE_5(0xff) ++#define P2WI_DATA_BYTE_6(n) (((n) & 0xff) << 8) ++#define P2WI_DATA_BYTE_6_MASK P2WI_DATA_BYTE_6(0xff) ++#define P2WI_DATA_BYTE_7(n) (((n) & 0xff) << 16) ++#define P2WI_DATA_BYTE_7_MASK P2WI_DATA_BYTE_7(0xff) ++#define P2WI_DATA_BYTE_8(n) (((n) & 0xff) << 24) ++#define P2WI_DATA_BYTE_8_MASK P2WI_DATA_BYTE_8(0xff) ++ ++#define P2WI_LINECTRL_SDA_CTRL_EN (0x1 << 0) ++#define P2WI_LINECTRL_SDA_OUT_HIGH (0x1 << 1) ++#define P2WI_LINECTRL_SCL_CTRL_EN (0x1 << 2) ++#define P2WI_LINECTRL_SCL_OUT_HIGH (0x1 << 3) ++#define P2WI_LINECTRL_SDA_STATE_HIGH (0x1 << 4) ++#define P2WI_LINECTRL_SCL_STATE_HIGH (0x1 << 5) ++ ++#define P2WI_PM_DEV_ADDR(n) (((n) & 0xff) << 0) ++#define P2WI_PM_DEV_ADDR_MASK P2WI_PM_DEV_ADDR(0xff) ++#define P2WI_PM_CTRL_ADDR(n) (((n) & 0xff) << 8) ++#define P2WI_PM_CTRL_ADDR_MASK P2WI_PM_CTRL_ADDR(0xff) ++#define P2WI_PM_INIT_DATA(n) (((n) & 0xff) << 16) ++#define P2WI_PM_INIT_DATA_MASK P2WI_PM_INIT_DATA(0xff) ++#define P2WI_PM_INIT_SEND (0x1 << 31) ++ ++#ifndef __ASSEMBLY__ ++struct sunxi_p2wi_reg { ++ u32 ctrl; /* 0x00 control */ ++ u32 cc; /* 0x04 clock control */ ++ u32 irq; /* 0x08 interrupt */ ++ u32 status; /* 0x0c status */ ++ u32 dataddr0; /* 0x10 data address 0 */ ++ u32 dataddr1; /* 0x14 data address 1 */ ++ u32 numbytes; /* 0x18 num bytes */ ++ u32 data0; /* 0x1c data buffer 0 */ ++ u32 data1; /* 0x20 data buffer 1 */ ++ u32 linectrl; /* 0x24 line control */ ++ u32 pm; /* 0x28 power management */ ++}; ++ ++void p2wi_init(void); ++int p2wi_set_pmu_address(u8 slave_addr, u8 ctrl_reg, u8 init_data); ++int p2wi_read(const u8 addr, u8 *data); ++int p2wi_write(const u8 addr, u8 data); ++ ++#endif /* __ASSEMBLY__ */ ++#endif /* _SUNXI_P2WI_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/prcm.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/prcm.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/prcm.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/prcm.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,238 @@ ++/* ++ * Sunxi A31 Power Management Unit register definition. ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_PRCM_H ++#define _SUNXI_PRCM_H ++ ++#define __PRCM_CPUS_CFG_PRE(n) (((n) & 0x3) << 4) ++#define PRCM_CPUS_CFG_PRE_MASK __PRCM_CPUS_CFG_PRE(0x3) ++#define __PRCM_CPUS_CFG_PRE_DIV(n) (((n) >> 1) - 1) ++#define PRCM_CPUS_CFG_PRE_DIV(n) \ ++ __PRCM_CPUS_CFG_PRE(__PRCM_CPUS_CFG_CLK_PRE(n)) ++#define __PRCM_CPUS_CFG_POST(n) (((n) & 0x1f) << 8) ++#define PRCM_CPUS_CFG_POST_MASK __PRCM_CPUS_CFG_POST(0x1f) ++#define __PRCM_CPUS_CFG_POST_DIV(n) ((n) - 1) ++#define PRCM_CPUS_CFG_POST_DIV(n) \ ++ __PRCM_CPUS_CFG_POST_DIV(__PRCM_CPUS_CFG_POST_DIV(n)) ++#define __PRCM_CPUS_CFG_CLK_SRC(n) (((n) & 0x3) << 16) ++#define PRCM_CPUS_CFG_CLK_SRC_MASK __PRCM_CPUS_CFG_CLK_SRC(0x3) ++#define __PRCM_CPUS_CFG_CLK_SRC_LOSC 0x0 ++#define __PRCM_CPUS_CFG_CLK_SRC_HOSC 0x1 ++#define __PRCM_CPUS_CFG_CLK_SRC_PLL6 0x2 ++#define __PRCM_CPUS_CFG_CLK_SRC_PDIV 0x3 ++#define PRCM_CPUS_CFG_CLK_SRC_LOSC \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_LOSC) ++#define PRCM_CPUS_CFG_CLK_SRC_HOSC \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_HOSC) ++#define PRCM_CPUS_CFG_CLK_SRC_PLL6 \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PLL6) ++#define PRCM_CPUS_CFG_CLK_SRC_PDIV \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PDIV) ++ ++#define __PRCM_APB0_RATIO(n) (((n) & 0x3) <<0) ++#define PRCM_APB0_RATIO_DIV_MASK __PRCM_APB0_RATIO_DIV(0x3) ++#define __PRCM_APB0_RATIO_DIV(n) (((n) >> 1) - 1) ++#define PRCM_APB0_RATIO_DIV(n) \ ++ __PRCM_APB0_RATIO(__PRCM_APB0_RATIO_DIV(n)) ++ ++#define PRCM_CPU_CFG_NEON_CLK_EN (0x1 << 0) ++#define PRCM_CPU_CFG_CPU_CLK_EN (0x1 << 1) ++ ++#define PRCM_APB0_GATE_PIO (0x1 << 0) ++#define PRCM_APB0_GATE_IR (0x1 << 1) ++#define PRCM_APB0_GATE_TIMER01 (0x1 << 2) ++#define PRCM_APB0_GATE_P2WI (0x1 << 3) ++#define PRCM_APB0_GATE_UART (0x1 << 4) ++#define PRCM_APB0_GATE_1WIRE (0x1 << 5) ++#define PRCM_APB0_GATE_I2C (0x1 << 6) ++ ++#define PRCM_APB0_RESET_PIO (0x1 << 0) ++#define PRCM_APB0_RESET_IR (0x1 << 1) ++#define PRCM_APB0_RESET_TIMER01 (0x1 << 2) ++#define PRCM_APB0_RESET_P2WI (0x1 << 3) ++#define PRCM_APB0_RESET_UART (0x1 << 4) ++#define PRCM_APB0_RESET_1WIRE (0x1 << 5) ++#define PRCM_APB0_RESET_I2C (0x1 << 6) ++ ++#define PRCM_PLL_CTRL_PLL_BIAS (0x1 << 0) ++#define PRCM_PLL_CTRL_HOSC_GAIN_ENH (0x1 << 1) ++#define __PRCM_PLL_CTRL_USB_CLK_SRC(n) (((n) & 0x3) << 4) ++#define PRCM_PLL_CTRL_USB_CLK_SRC_MASK \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(0x3) ++#define __PRCM_PLL_CTRL_USB_CLK_0 0x0 ++#define __PRCM_PLL_CTRL_USB_CLK_1 0x1 ++#define __PRCM_PLL_CTRL_USB_CLK_2 0x2 ++#define __PRCM_PLL_CTRL_USB_CLK_3 0x3 ++#define PRCM_PLL_CTRL_USB_CLK_0 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_0) ++#define PRCM_PLL_CTRL_USB_CLK_1 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_1) ++#define PRCM_PLL_CTRL_USB_CLK_2 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_2) ++#define PRCM_PLL_CTRL_USB_CLK_3 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_3) ++#define __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) (((n) & 0x3) << 12) ++#define PRCM_PLL_CTRL_INT_PLL_IN_SEL_MASK \ ++ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(0x3) ++#define PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) \ ++ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) ++#define __PRCM_PLL_CTRL_HOSC_CLK_SEL(n) (((n) & 0x3) << 20) ++#define PRCM_PLL_CTRL_HOSC_CLK_SEL_MASK \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(0x3) ++#define __PRCM_PLL_CTRL_HOSC_CLK_0 0x0 ++#define __PRCM_PLL_CTRL_HOSC_CLK_1 0x1 ++#define __PRCM_PLL_CTRL_HOSC_CLK_2 0x2 ++#define __PRCM_PLL_CTRL_HOSC_CLK_3 0x3 ++#define PRCM_PLL_CTRL_HOSC_CLK_0 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_0) ++#define PRCM_PLL_CTRL_HOSC_CLK_1 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_1) ++#define PRCM_PLL_CTRL_HOSC_CLK_2 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_2) ++#define PRCM_PLL_CTRL_HOSC_CLK_3 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_3) ++#define PRCM_PLL_CTRL_PLL_TST_SRC_EXT (0x1 << 24) ++#define PRCM_PLL_CTRL_LDO_DIGITAL_EN (0x1 << 0) ++#define PRCM_PLL_CTRL_LDO_ANALOG_EN (0x1 << 1) ++#define PRCM_PLL_CTRL_EXT_OSC_EN (0x1 << 2) ++#define PRCM_PLL_CTRL_CLK_TST_EN (0x1 << 3) ++#define PRCM_PLL_CTRL_IN_PWR_HIGH (0x1 << 15) /* 3.3 for hi 2.5 for lo */ ++#define __PRCM_PLL_CTRL_VDD_LDO_OUT(n) (((n) & 0x7) << 16) ++#define PRCM_PLL_CTRL_LDO_OUT_MASK \ ++ __PRCM_PLL_CTRL_LDO_OUT(0x7) ++/* When using the low voltage 20 mV steps, and high voltage 30 mV steps */ ++#define PRCM_PLL_CTRL_LDO_OUT_L(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7) ++#define PRCM_PLL_CTRL_LDO_OUT_H(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1160) / 30) & 0x7) ++#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000) ++#define PRCM_PLL_CTRL_LDO_OUT_HV(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 30) + 1160) ++#define PRCM_PLL_CTRL_LDO_KEY (0xa7 << 24) ++ ++#define PRCM_CLK_1WIRE_GATE (0x1 << 31) ++ ++#define __PRCM_CLK_MOD0_M(n) (((n) & 0xf) << 0) ++#define PRCM_CLK_MOD0_M_MASK __PRCM_CLK_MOD0_M(0xf) ++#define __PRCM_CLK_MOD0_M_X(n) (n - 1) ++#define PRCM_CLK_MOD0_M(n) __PRCM_CLK_MOD0_M(__PRCM_CLK_MOD0_M_X(n)) ++#define PRCM_CLK_MOD0_OUT_PHASE(n) (((n) & 0x7) << 8) ++#define PRCM_CLK_MOD0_OUT_PHASE_MASK(n) PRCM_CLK_MOD0_OUT_PHASE(0x7) ++#define _PRCM_CLK_MOD0_N(n) (((n) & 0x3) << 16) ++#define PRCM_CLK_MOD0_N_MASK __PRCM_CLK_MOD_N(0x3) ++#define __PRCM_CLK_MOD0_N_X(n) (((n) >> 1) -1) ++#define PRCM_CLK_MOD0_N(n) __PRCM_CLK_MOD0_N(__PRCM_CLK_MOD0_N_X(n)) ++#define PRCM_CLK_MOD0_SMPL_PHASE(n) (((n) & 0x7) << 20) ++#define PRCM_CLK_MOD0_SMPL_PHASE_MASK PRCM_CLK_MOD0_SMPL_PHASE(0x7) ++#define PRCM_CLK_MOD0_SRC_SEL(n) (((n) & 0x7) << 24) ++#define PRCM_CLK_MOD0_SRC_SEL_MASK PRCM_CLK_MOD0_SRC_SEL(0x7) ++#define PRCM_CLK_MOD0_GATE_EN (0x1 << 31) ++ ++#define PRCM_APB0_RESET_PIO (0x1 << 0) ++#define PRCM_APB0_RESET_IR (0x1 << 1) ++#define PRCM_APB0_RESET_TIMER01 (0x1 << 2) ++#define PRCM_APB0_RESET_P2WI (0x1 << 3) ++#define PRCM_APB0_RESET_UART (0x1 << 4) ++#define PRCM_APB0_RESET_1WIRE (0x1 << 5) ++#define PRCM_APB0_RESET_I2C (0x1 << 6) ++ ++#define __PRCM_CLK_OUTD_M(n) (((n) & 0x7) << 8) ++#define PRCM_CLK_OUTD_M_MASK __PRCM_CLK_OUTD_M(0x7) ++#define __PRCM_CLK_OUTD_M_X() ((n) - 1) ++#define PRCM_CLK_OUTD_M(n) __PRCM_CLK_OUTD_M(__PRCM_CLK_OUTD_M_X(n)) ++#define __PRCM_CLK_OUTD_N(n) (((n) & 0x7) << 20) ++#define PRCM_CLK_OUTD_N_MASK __PRCM_CLK_OUTD_N(0x7) ++#define __PRCM_CLK_OUTD_N_X(n) (((n) >> 1) - 1) ++#define PRCM_CLK_OUTD_N(n) __PRCM_CLK_OUTD_N(__PRCM_CLK_OUTD_N_X(n) ++#define __PRCM_CLK_OUTD_SRC_SEL(n) (((n) & 0x3) << 24) ++#define PRCM_CLK_OUTD_SRC_SEL_MASK __PRCM_CLK_OUTD_SRC_SEL(0x3) ++#define __PRCM_CLK_OUTD_SRC_LOSC2 0x0 ++#define __PRCM_CLK_OUTD_SRC_LOSC 0x1 ++#define __PRCM_CLK_OUTD_SRC_HOSC 0x2 ++#define __PRCM_CLK_OUTD_SRC_ERR 0x3 ++#define PRCM_CLK_OUTD_SRC_LOSC2 \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC2) ++#define PRCM_CLK_OUTD_SRC_LOSC \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC) ++#define PRCM_CLK_OUTD_SRC_HOSC \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_HOSC) ++#define PRCM_CLK_OUTD_SRC_ERR \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_ERR) ++#define PRCM_CLK_OUTD_EN (0x1 << 31) ++ ++#define PRCM_CPU0_PWROFF (0x1 << 0) ++#define PRCM_CPU1_PWROFF (0x1 << 1) ++#define PRCM_CPU2_PWROFF (0x1 << 2) ++#define PRCM_CPU3_PWROFF (0x1 << 3) ++#define PRCM_CPU_ALL_PWROFF (0xf << 0) ++ ++#define PRCM_VDD_SYS_DRAM_CH0_PAD_HOLD_PWROFF (0x1 << 0) ++#define PRCM_VDD_SYS_DRAM_CH1_PAD_HOLD_PWROFF (0x1 << 1) ++#define PRCM_VDD_SYS_AVCC_A_PWROFF (0x1 << 2) ++#define PRCM_VDD_SYS_CPU0_VDD_PWROFF (0x1 << 3) ++ ++#define PRCM_VDD_GPU_PWROFF (0x1 << 0) ++ ++#define PRCM_VDD_SYS_RESET (0x1 << 0) ++ ++#define PRCM_CPU1_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU1_PWR_CLAMP_MASK PRCM_CPU1_PWR_CLAMP(0xff) ++ ++#define PRCM_CPU2_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU2_PWR_CLAMP_MASK PRCM_CPU2_PWR_CLAMP(0xff) ++ ++#define PRCM_CPU3_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU3_PWR_CLAMP_MASK PRCM_CPU3_PWR_CLAMP(0xff) ++ ++#ifndef __ASSEMBLY__ ++struct sunxi_prcm_reg { ++ u32 cpus_cfg; /* 0x000 */ ++ u8 res0[0x8]; /* 0x004 */ ++ u32 apb0_ratio; /* 0x00c */ ++ u32 cpu0_cfg; /* 0x010 */ ++ u32 cpu1_cfg; /* 0x014 */ ++ u32 cpu2_cfg; /* 0x018 */ ++ u32 cpu3_cfg; /* 0x01c */ ++ u8 res1[0x8]; /* 0x020 */ ++ u32 apb0_gate; /* 0x028 */ ++ u8 res2[0x14]; /* 0x02c */ ++ u32 pll_ctrl0; /* 0x040 */ ++ u32 pll_ctrl1; /* 0x044 */ ++ u8 res3[0x8]; /* 0x048 */ ++ u32 clk_1wire; /* 0x050 */ ++ u32 clk_ir; /* 0x054 */ ++ u8 res4[0x58]; /* 0x058 */ ++ u32 apb0_reset; /* 0x0b0 */ ++ u8 res5[0x3c]; /* 0x0b4 */ ++ u32 clk_outd; /* 0x0f0 */ ++ u8 res6[0xc]; /* 0x0f4 */ ++ u32 cpu_pwroff; /* 0x100 */ ++ u8 res7[0xc]; /* 0x104 */ ++ u32 vdd_sys_pwroff; /* 0x110 */ ++ u8 res8[0x4]; /* 0x114 */ ++ u32 gpu_pwroff; /* 0x118 */ ++ u8 res9[0x4]; /* 0x11c */ ++ u32 vdd_pwr_reset; /* 0x120 */ ++ u8 res10[0x20]; /* 0x124 */ ++ u32 cpu1_pwr_clamp; /* 0x144 */ ++ u32 cpu2_pwr_clamp; /* 0x148 */ ++ u32 cpu3_pwr_clamp; /* 0x14c */ ++ u8 res11[0x30]; /* 0x150 */ ++ u32 dram_pwr; /* 0x180 */ ++ u8 res12[0xc]; /* 0x184 */ ++ u32 dram_tst; /* 0x190 */ ++}; ++ ++void prcm_apb0_enable(u32 flags); ++#endif /* __ASSEMBLY__ */ ++#endif /* _PRCM_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/smp.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/smp.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_SMP_H_ ++#define _SUNXI_SMP_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++void startup_secondaries(void); ++ ++/* Assembly entry point */ ++extern void secondary_init(void); ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_SMP_H_ */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/spl.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/spl.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * This is a copy of omap3/spl.h: ++ * ++ * (C) Copyright 2012 ++ * Texas Instruments, <www.ti.com> ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef _ASM_ARCH_SPL_H_ ++#define _ASM_SPL_H_ ++ ++#define BOOT_DEVICE_NONE 0 ++#define BOOT_DEVICE_XIP 1 ++#define BOOT_DEVICE_NAND 2 ++#define BOOT_DEVICE_ONE_NAND 3 ++#define BOOT_DEVICE_MMC2 5 /*emmc*/ ++#define BOOT_DEVICE_MMC1 6 ++#define BOOT_DEVICE_XIPWAIT 7 ++#define BOOT_DEVICE_MMC2_2 0xff ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/sys_proto.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/sys_proto.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SYS_PROTO_H_ ++#define _SYS_PROTO_H_ ++ ++#include <linux/types.h> ++ ++void sdelay(unsigned long); ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/timer.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/timer.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,88 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Configuration settings for the Allwinner A10-evb board. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_TIMER_H_ ++#define _SUNXI_TIMER_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/types.h> ++ ++/* General purpose timer */ ++struct sunxi_timer { ++ u32 ctl; ++ u32 inter; ++ u32 val; ++ u8 res[4]; ++}; ++ ++/* Audio video sync*/ ++struct sunxi_avs { ++ u32 ctl; /* 0x80 */ ++ u32 cnt0; /* 0x84 */ ++ u32 cnt1; /* 0x88 */ ++ u32 div; /* 0x8c */ ++}; ++ ++/* 64 bit counter */ ++struct sunxi_64cnt { ++ u32 ctl; /* 0xa0 */ ++ u32 lo; /* 0xa4 */ ++ u32 hi; /* 0xa8 */ ++}; ++ ++/* Watchdog */ ++struct sunxi_wdog { ++ u32 ctl; /* 0x90 */ ++ u32 mode; /* 0x94 */ ++}; ++ ++/* Rtc */ ++struct sunxi_rtc { ++ u32 ctl; /* 0x100 */ ++ u32 yymmdd; /* 0x104 */ ++ u32 hhmmss; /* 0x108 */ ++}; ++ ++/* Alarm */ ++struct sunxi_alarm { ++ u32 ddhhmmss; /* 0x10c */ ++ u32 hhmmss; /* 0x110 */ ++ u32 en; /* 0x114 */ ++ u32 irqen; /* 0x118 */ ++ u32 irqsta; /* 0x11c */ ++}; ++ ++/* Timer general purpose register */ ++struct sunxi_tgp { ++ u32 tgpd; ++}; ++ ++struct sunxi_timer_reg { ++ u32 tirqen; /* 0x00 */ ++ u32 tirqsta; /* 0x04 */ ++ u8 res1[8]; ++ struct sunxi_timer timer[6]; /* We have 6 timers */ ++ u8 res2[16]; ++ struct sunxi_avs avs; ++ struct sunxi_wdog wdog; ++ u8 res3[8]; ++ struct sunxi_64cnt cnt64; ++ u8 res4[0x58]; ++ struct sunxi_rtc rtc; ++ struct sunxi_alarm alarm; ++ struct sunxi_tgp tgp[4]; ++ u8 res5[8]; ++ u32 cpu_cfg; ++}; ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/watchdog.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/watchdog.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://www.linux-sunxi.org/ ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_WATCHDOG_H_ ++#define _SUNXI_WATCHDOG_H_ ++ ++/* Timeout limits */ ++#define WDT_MAX_TIMEOUT 16 ++#define WDT_OFF -1 ++ ++#ifndef __ASSEMBLY__ ++void watchdog_reset(void); ++void watchdog_set(int timeout); ++void watchdog_init(void); ++#endif /* __ASSEMBLY__ */ ++ ++#endif +diff -ruN u-boot-2014.04/board/sunxi/board.c u-boot-sunxi/board/sunxi/board.c +--- u-boot-2014.04/board/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/board.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,239 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Some board init for the Allwinner A10-evb board. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#ifdef CONFIG_AXP152_POWER ++#include <axp152.h> ++#endif ++#ifdef CONFIG_AXP209_POWER ++#include <axp209.h> ++#endif ++#ifdef CONFIG_AXP221_POWER ++#include <axp221.h> ++#endif ++#include <asm/arch/clock.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/dram.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/mmc.h> ++#include <asm/io.h> ++#include <net.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* add board specific code here */ ++int board_init(void) ++{ ++ int id_pfr1; ++ ++ gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); ++ ++ 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) { ++ debug("Setting CNTFRQ\n"); ++ /* CNTFRQ == 24 MHz */ ++ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000)); ++ } ++ ++#ifdef CONFIG_STATUS_LED ++ status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); ++#endif ++ return 0; ++} ++ ++#ifdef CONFIG_DISPLAY_BOARDINFO ++int checkboard(void) ++{ ++ printf("Board: %s\n", CONFIG_SYS_BOARD_NAME); ++ ++ return 0; ++} ++#endif ++ ++int dram_init(void) ++{ ++ gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_GENERIC_MMC ++static void mmc_pinmux_setup(int sdc) ++{ ++ unsigned int pin; ++ ++ switch (sdc) { ++ case 0: ++ /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ ++ for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 1: ++ /* CMD-PH22, CLK-PH23, D0~D3-PH24~27 : 5 */ ++ for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUN4I_GPH22_SDC1); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 2: ++ /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ ++ for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 3: ++ /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ ++ for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ default: ++ printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); ++ break; ++ } ++} ++ ++int board_mmc_init(bd_t *bis) ++{ ++ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); ++#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA) ++ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); ++#endif ++ ++ return 0; ++} ++#endif ++ ++void i2c_init_board(void) ++{ ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0); ++ clock_twi_onoff(0, 1); ++} ++ ++#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++void sunxi_board_init(void) ++{ ++ int power_failed = 0; ++#if !defined(CONFIG_SUN6I) && !defined(CONFIG_SUN8I) ++ unsigned long ramsize; ++#endif ++ ++#ifdef CONFIG_AXP152_POWER ++ power_failed = axp152_init(); ++ power_failed |= axp152_set_dcdc2(1400); ++ power_failed |= axp152_set_dcdc3(1500); ++ power_failed |= axp152_set_dcdc4(1250); ++ power_failed |= axp152_set_ldo2(3000); ++#endif ++#ifdef CONFIG_AXP209_POWER ++ power_failed |= axp209_init(); ++ power_failed |= axp209_set_dcdc2(1400); ++#ifdef CONFIG_FAST_MBUS ++ power_failed |= axp209_set_dcdc3(1300); ++#else ++ power_failed |= axp209_set_dcdc3(1250); ++#endif ++ power_failed |= axp209_set_ldo2(3000); ++ power_failed |= axp209_set_ldo3(2800); ++ power_failed |= axp209_set_ldo4(2800); ++#endif ++#ifdef CONFIG_AXP221_POWER ++ power_failed = axp221_init(); ++ power_failed |= axp221_set_dcdc1(3300); ++ power_failed |= axp221_set_dcdc2(1200); ++ power_failed |= axp221_set_dcdc3(1260); ++ power_failed |= axp221_set_dcdc4(1200); ++ power_failed |= axp221_set_dcdc5(1500); ++#ifdef CONFIG_ENABLE_DLDO1_POWER ++ power_failed |= axp221_set_dldo1(3300); ++#endif ++#endif ++ ++#if !defined(CONFIG_SUN6I) && !defined(CONFIG_SUN8I) ++ printf("DRAM:"); ++ ramsize = sunxi_dram_init(); ++ printf(" %lu MiB\n", ramsize >> 20); ++ if (!ramsize) ++ hang(); ++ ++ /* ++ * Only clock up the CPU to full speed if we are reasonably ++ * assured it's being powered with suitable core voltage ++ */ ++ if (!power_failed) ++ clock_set_pll1(CONFIG_CLK_FULL_SPEED); ++ else ++ printf("Failed to set core voltage! Can't set CPU frequency\n"); ++#endif ++} ++#endif ++ ++#if defined(CONFIG_SPL_OS_BOOT) && defined(CONFIG_AXP209_POWER) ++int spl_start_uboot(void) ++{ ++ if (axp209_poweron_by_dc()) ++ return 0; ++ axp209_power_button(); /* Clear any pending button event */ ++ mdelay(100); ++ return axp209_power_button(); ++} ++#endif ++ ++#ifdef CONFIG_SPL_DISPLAY_PRINT ++void spl_display_print(void) ++{ ++ printf("Board: %s\n", CONFIG_SYS_BOARD_NAME); ++} ++#endif ++ ++#ifdef CONFIG_MISC_INIT_R ++int misc_init_r(void) ++{ ++ if (!getenv("ethaddr")) { ++ uint32_t reg_val = readl(SUNXI_SID_BASE); ++ ++ if (reg_val) { ++ uint8_t mac_addr[6]; ++ ++ mac_addr[0] = 0x02; /* Non OUI / registered MAC address */ ++ mac_addr[1] = (reg_val >> 0) & 0xff; ++ reg_val = readl(SUNXI_SID_BASE + 0x0c); ++ mac_addr[2] = (reg_val >> 24) & 0xff; ++ mac_addr[3] = (reg_val >> 16) & 0xff; ++ mac_addr[4] = (reg_val >> 8) & 0xff; ++ mac_addr[5] = (reg_val >> 0) & 0xff; ++ ++ eth_setenv_enetaddr("ethaddr", mac_addr); ++ } ++ } ++ ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/board/sunxi/dram_a10_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c +--- u-boot-2014.04/board/sunxi/dram_a10_olinuxino_l.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a13_oli_micro.c u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c +--- u-boot-2014.04/board/sunxi/dram_a13_oli_micro.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,32 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 256, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++ ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a13_olinuxino.c u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c +--- u-boot-2014.04/board/sunxi/dram_a13_olinuxino.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l2.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l2.c +--- u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l.c +--- u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_ainol_aw1.c u-boot-sunxi/board/sunxi/dram_ainol_aw1.c +--- u-boot-2014.04/board/sunxi/dram_ainol_aw1.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_ainol_aw1.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_auxtek_t003.c u-boot-sunxi/board/sunxi/dram_auxtek_t003.c +--- u-boot-2014.04/board/sunxi/dram_auxtek_t003.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_auxtek_t003.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_cubieboard.c u-boot-sunxi/board/sunxi/dram_cubieboard.c +--- u-boot-2014.04/board/sunxi/dram_cubieboard.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubieboard.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_cubietruck.c u-boot-sunxi/board/sunxi/dram_cubietruck.c +--- u-boot-2014.04/board/sunxi/dram_cubietruck.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubietruck.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 2048, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x1, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_eu3000.c u-boot-sunxi/board/sunxi/dram_eu3000.c +--- u-boot-2014.04/board/sunxi/dram_eu3000.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_eu3000.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_forfun_q88db.c u-boot-sunxi/board/sunxi/dram_forfun_q88db.c +--- u-boot-2014.04/board/sunxi/dram_forfun_q88db.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_forfun_q88db.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_gooseberry_a721.c u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c +--- u-boot-2014.04/board/sunxi/dram_gooseberry_a721.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 1024, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_h6.c u-boot-sunxi/board/sunxi/dram_h6.c +--- u-boot-2014.04/board/sunxi/dram_h6.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_h6.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_hackberry.c u-boot-sunxi/board/sunxi/dram_hackberry.c +--- u-boot-2014.04/board/sunxi/dram_hackberry.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_hackberry.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_icou_fatty_i.c u-boot-sunxi/board/sunxi/dram_icou_fatty_i.c +--- u-boot-2014.04/board/sunxi/dram_icou_fatty_i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_icou_fatty_i.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_inet_k70hc.c u-boot-sunxi/board/sunxi/dram_inet_k70hc.c +--- u-boot-2014.04/board/sunxi/dram_inet_k70hc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_inet_k70hc.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x12331a7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_linksprite_pcduino3.c u-boot-sunxi/board/sunxi/dram_linksprite_pcduino3.c +--- u-boot-2014.04/board/sunxi/dram_linksprite_pcduino3.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_linksprite_pcduino3.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7a, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_megafeis_a08.c u-boot-sunxi/board/sunxi/dram_megafeis_a08.c +--- u-boot-2014.04/board/sunxi/dram_megafeis_a08.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_megafeis_a08.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_merrii_m2.c u-boot-sunxi/board/sunxi/dram_merrii_m2.c +--- u-boot-2014.04/board/sunxi/dram_merrii_m2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_merrii_m2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 127, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x0, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mini_x_a10s.c u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c +--- u-boot-2014.04/board/sunxi/dram_mini_x_a10s.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mk802_a10s.c u-boot-sunxi/board/sunxi/dram_mk802_a10s.c +--- u-boot-2014.04/board/sunxi/dram_mk802_a10s.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802_a10s.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mk802ii_a20.c u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c +--- u-boot-2014.04/board/sunxi/dram_mk802ii_a20.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_olimex_a13_som.c u-boot-sunxi/board/sunxi/dram_olimex_a13_som.c +--- u-boot-2014.04/board/sunxi/dram_olimex_a13_som.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_olimex_a13_som.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,32 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++ ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_protab2.c u-boot-sunxi/board/sunxi/dram_pov_protab2.c +--- u-boot-2014.04/board/sunxi/dram_pov_protab2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_protab2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_protab2_xxl.c u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c +--- u-boot-2014.04/board/sunxi/dram_pov_protab2_xxl.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_tab_p703.c u-boot-sunxi/board/sunxi/dram_pov_tab_p703.c +--- u-boot-2014.04/board/sunxi/dram_pov_tab_p703.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_tab_p703.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x56b9697b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_r7dongle.c u-boot-sunxi/board/sunxi/dram_r7dongle.c +--- u-boot-2014.04/board/sunxi/dram_r7dongle.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_r7dongle.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x04, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sanei_n90.c u-boot-sunxi/board/sunxi/dram_sanei_n90.c +--- u-boot-2014.04/board/sunxi/dram_sanei_n90.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sanei_n90.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,30 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 456, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_semitime_g2.c u-boot-sunxi/board/sunxi/dram_semitime_g2.c +--- u-boot-2014.04/board/sunxi/dram_semitime_g2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_semitime_g2.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, /* in MiB */ ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x00, ++ .tpr4 = 0x00, ++ .tpr5 = 0x00, ++ .emr1 = 0x00, ++ .emr2 = 0x10, ++ .emr3 = 0x00, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_312_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_312_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 312, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_512.c u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_512.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_512.c u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_512.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun5i_408_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_408_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_408_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_408_512_busw16_iow8.c u-boot-sunxi/board/sunxi/dram_sun5i_408_512_busw16_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_408_512_busw16_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_408_512_busw16_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_432_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun5i_432_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_432_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_432_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_360_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_360_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_360_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_360_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_384_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_384_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_384_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_384_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_384_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_384_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_384_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_384_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_432_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_432_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_432_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_432_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_460_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_460_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_460_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_460_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x1, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_wexler_tab_7200.c u-boot-sunxi/board/sunxi/dram_wexler_tab_7200.c +--- u-boot-2014.04/board/sunxi/dram_wexler_tab_7200.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_wexler_tab_7200.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_wobo_i5.c u-boot-sunxi/board/sunxi/dram_wobo_i5.c +--- u-boot-2014.04/board/sunxi/dram_wobo_i5.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_wobo_i5.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x04, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_xzpad700.c u-boot-sunxi/board/sunxi/dram_xzpad700.c +--- u-boot-2014.04/board/sunxi/dram_xzpad700.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_xzpad700.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x56b9487b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_zatab.c u-boot-sunxi/board/sunxi/dram_zatab.c +--- u-boot-2014.04/board/sunxi/dram_zatab.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_zatab.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/gmac.c u-boot-sunxi/board/sunxi/gmac.c +--- u-boot-2014.04/board/sunxi/gmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/gmac.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,43 @@ ++#include <common.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <asm/gpio.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++ ++int sunxi_gmac_initialize(bd_t *bis) ++{ ++ int pin; ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Set up clock gating */ ++ setbits_le32(&ccm->ahb_gate1, 0x1 << AHB_GATE_OFFSET_GMAC); ++ ++ /* Set MII clock */ ++#ifdef CONFIG_RGMII ++ setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | ++ CCM_GMAC_CTRL_GPIT_RGMII); ++#else ++ setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII | ++ CCM_GMAC_CTRL_GPIT_MII); ++#endif ++ ++ /* Configure pin mux settings for GMAC */ ++ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { ++#ifdef CONFIG_RGMII ++ /* skip unused pins in RGMII mode */ ++ if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14)) ++ continue; ++#endif ++ sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC); ++ sunxi_gpio_set_drv(pin, 3); ++ } ++ ++#ifdef CONFIG_RGMII ++ return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII); ++#else ++ return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_MII); ++#endif ++} +diff -ruN u-boot-2014.04/board/sunxi/Makefile u-boot-sunxi/board/sunxi/Makefile +--- u-boot-2014.04/board/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/Makefile 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,95 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++# ++# Based on some other board Makefile ++# ++# (C) Copyright 2000-2003 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++obj-y += board.o ++obj-$(CONFIG_SUNXI_GMAC) += gmac.o ++obj-$(CONFIG_A10_MID_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_A10_OLINUXINO_L) += dram_a10_olinuxino_l.o ++obj-$(CONFIG_A10S_OLINUXINO_M) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o ++obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o ++obj-$(CONFIG_A13_MID) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_A20_OLINUXINO_L) += dram_a20_olinuxino_l.o ++obj-$(CONFIG_A20_OLINUXINO_L2) += dram_a20_olinuxino_l2.o ++obj-$(CONFIG_A20_OLINUXINO_M) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_A20_SOM) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_AINOL_AW1) += dram_ainol_aw1.o ++obj-$(CONFIG_AMPE_A76) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_AUXTEK_T003) += dram_auxtek_t003.o ++obj-$(CONFIG_AUXTEK_T004) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_BA10_TV_BOX) += dram_sun4i_384_1024_iow8.o ++obj-$(CONFIG_COBY_MID7042) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_COBY_MID8042) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_COBY_MID9742) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_MARSBOARD_A10) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MARSBOARD_A20) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o ++obj-$(CONFIG_CUBIEBOARD2) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_BANANAPI) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o ++obj-$(CONFIG_DNS_M82) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_EOMA68_A10) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_EOMA68_A20) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_EU3000) += dram_eu3000.o ++obj-$(CONFIG_FORFUN_Q88DB) += dram_forfun_q88db.o ++obj-$(CONFIG_GOOSEBERRY_A721) += dram_gooseberry_a721.o ++obj-$(CONFIG_H6) += dram_h6.o ++obj-$(CONFIG_HACKBERRY) += dram_hackberry.o ++obj-$(CONFIG_HBD_MID_S906) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_HCORE_HC860) += dram_sun4i_384_1024_iow16.o ++obj-$(CONFIG_HYUNDAI_A7) += dram_sun4i_360_512.o ++obj-$(CONFIG_A7HD) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_I12_TVBOX) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_ICOU_FATTY_I) += dram_icou_fatty_i.o ++obj-$(CONFIG_INTERRA3) += dram_mk802ii_a20.o ++obj-$(CONFIG_INET_86VZ) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_INET97F_II) += dram_sun4i_408_512.o ++obj-$(CONFIG_INET_K70HC) += dram_inet_k70hc.o ++obj-$(CONFIG_ITEADA10) += dram_cubieboard.o ++obj-$(CONFIG_ITEADA20) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_JESURUN_Q5) += dram_sun4i_312_1024_iow8.o ++obj-$(CONFIG_K1001L1C) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_KURIO_7S) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_LANGCENT_H6S) += dram_sun7i_360_512_busw16_iow16.o ++obj-$(CONFIG_LINKSPRITE_PCDUINO3) += dram_linksprite_pcduino3.o ++obj-$(CONFIG_MEFAFEIS_A08) += dram_megafeis_a08.o ++obj-$(CONFIG_MELE_A1000) += dram_sun4i_360_512.o ++obj-$(CONFIG_MELE_A1000G) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_MELE_A3700) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_MERRII_HUMMINGBIRD_A20) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_MINI_X) += dram_sun4i_360_512.o ++obj-$(CONFIG_MINI_X_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MINI_X_A10S) += dram_mini_x_a10s.o ++obj-$(CONFIG_MK802) += dram_sun4i_360_512.o ++obj-$(CONFIG_MK802_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MK802_A10S) += dram_mk802_a10s.o ++obj-$(CONFIG_MK802II) += dram_sun4i_408_1024_iow8.o ++obj-$(CONFIG_MK802II_A20) += dram_mk802ii_a20.o ++obj-$(CONFIG_MK808C_A20) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_OLIMEX_A13_SOM) += dram_olimex_a13_som.o ++obj-$(CONFIG_PCDUINO) += dram_sun4i_408_1024_iow8.o ++obj-$(CONFIG_PENGPOD700) += dram_sun4i_384_1024_iow8.o ++obj-$(CONFIG_PENGPOD1000) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_PINERIVER-H25) += dram_sun5i_408_1024_iow16.o ++obj-$(CONFIG_POV_TAB_P703) += dram_pov_tab_p703.o ++obj-$(CONFIG_POV_PROTAB2) += dram_pov_protab2.o ++obj-$(CONFIG_POV_PROTAB2_XXL) += dram_pov_protab2_xxl.o ++obj-$(CONFIG_QT840A) += dram_sun7i_384_512_busw16_iow16.o ++obj-$(CONFIG_R7DONGLE) += dram_r7dongle.o ++obj-$(CONFIG_SANEI_N90) += dram_sanei_n90.o ++obj-$(CONFIG_SEMITIME_G2) += dram_semitime_g2.o ++obj-$(CONFIG_TZX_Q8_713B6) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_TZX_Q8_713B7) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_UHOST_U1A) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_WEXLER_TAB_7200) += dram_wexler_tab_7200.o ++obj-$(CONFIG_WOBO_I5) += dram_wobo_i5.o ++obj-$(CONFIG_XZPAD700) += dram_xzpad700.o ++obj-$(CONFIG_ZATAB) += dram_zatab.o ++obj-$(CONFIG_MERRII_M2) += dram_merrii_m2.o +diff -ruN u-boot-2014.04/boards.cfg u-boot-sunxi/boards.cfg +--- u-boot-2014.04/boards.cfg 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/boards.cfg 2014-09-06 16:58:36.185953115 +0200 +@@ -371,6 +371,111 @@ + Active arm armv7 s5pc1xx samsung goni s5p_goni - Mateusz Zalega m.zalega@samsung.com + Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang mk7.kang@samsung.com + Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - ++Active arm armv7 sunxi - sunxi A10_MID_1GB sun4i:A10_MID_1GB,SPL - ++Active arm armv7 sunxi - sunxi A10-OLinuXino-Lime sun4i:A10_OLINUXINO_L,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A10s-OLinuXino-M sun5i:A10S_OLINUXINO_M,STATUSLED=131,AXP152_POWER,CONS_INDEX=1,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A10s-OLinuXino-M_FEL sun5i:A10S_OLINUXINO_M,STATUSLED=131,AXP152_POWER,CONS_INDEX=1,SPL_FEL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A13-OLinuXino sun5i:A13_OLINUXINO,SPL,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXino_FEL sun5i:A13_OLINUXINO,SPL_FEL,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXino_FEL_sdcon sun5i:A13_OLINUXINO,SPL_FEL,STATUSLED=201,UART0_PORT_F - ++Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXinoM_FEL sun5i:A13_OLINUXINOM,SPL_FEL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13_MID sun5i:A13_MID,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_Lime sun7i:A20_OLINUXINO_L,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_Lime2 sun7i:A20_OLINUXINO_L2,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_GMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO_FEL sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-SOM sun7i:A20_SOM,SPL,SUNXI_GMAC,RGMII,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Ainol_AW1 sun7i:AINOL_AW1,SPL - ++Active arm armv7 sunxi - sunxi Ampe_A76 sun5i:AMPE_A76,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi Auxtek-T003 sun5i:AUXTEK_T003,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Auxtek-T004 sun5i:AUXTEK_T004,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi ba10_tv_box sun4i:BA10_TV_BOX,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi Bananapi sun7i:BANANAPI,SPL,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Bananapi_FEL sun7i:BANANAPI,SPL_FEL,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Coby_MID7042 sun4i:COBY_MID7042,SPL - ++Active arm armv7 sunxi - sunxi Coby_MID8042 sun4i:COBY_MID8042,SPL - ++Active arm armv7 sunxi - sunxi Coby_MID9742 sun4i:COBY_MID9742,SPL - ++Active arm armv7 sunxi - sunxi Iteaduino_Plus_A10 sun4i:ITEADA10,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Iteaduino_Plus_A20 sun7i:ITEADA20,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Colombus sun6i:COLOMBUS,AXP221_POWER,ENABLE_DLDO1_POWER - ++Active arm armv7 sunxi - sunxi Ippo_q8h sun8i:IPPO_Q8H,NO_AXP,CONS_INDEX=5 - ++Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Cubieboard2 sun7i:CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubieboard2_FEL sun7i:CUBIEBOARD2,SPL_FEL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubieboard_FEL sun4i:CUBIEBOARD,SPL_FEL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi DNS_M82 sun4i:DNS_M82,SPL - ++Active arm armv7 sunxi - sunxi EOMA68_A10 sun4i:EOMA68_A10,SPL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A10_FEL sun4i:EOMA68_A10,SPL_FEL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A20 sun7i:EOMA68_A20,SPL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A20_FEL sun7i:EOMA68_A20,SPL_FEL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EU3000 sun7i:EU3000,SPL - ++Active arm armv7 sunxi - sunxi Forfun_Q88DB sun7i:FORFUN_Q88DB,SPL - ++Active arm armv7 sunxi - sunxi Gooseberry_A721 sun4i:GOOSEBERRY_A721,SPL - ++Active arm armv7 sunxi - sunxi H6 sun4i:H6,SPL - ++Active arm armv7 sunxi - sunxi Hackberry sun4i:HACKBERRY,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(19) - ++Active arm armv7 sunxi - sunxi HBD_MID_S906 sun7i:HBD_MID_S906,SPL - ++Active arm armv7 sunxi - sunxi HCore_HC860 sun4i:HCORE_HC860,SPL - ++Active arm armv7 sunxi - sunxi Hyundai_A7 sun4i:HYUNDAI_A7,SPL - ++Active arm armv7 sunxi - sunxi Hyundai_A7HD sun4i:A7HD,SPL - ++Active arm armv7 sunxi - sunxi i12-tvbox sun7i:I12_TVBOX,SPL,FAST_MBUS,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi ICOU_Fatty_I sun7i:ICOU_FATTY_I,SPL - ++Active arm armv7 sunxi - sunxi Interra-3 sun7i:INTERRA3,SPL,SUNXI_GMAC,FAST_MBUS,MMC_SUNXI_SLOT=2 - ++Active arm armv7 sunxi - sunxi INet_86VZ sun5i:INET_86VZ,SPL - ++Active arm armv7 sunxi - sunxi INet_86VZ_FEL sun5i:INET_86VZ,SPL_FEL,UART0_PORT_F - ++Active arm armv7 sunxi - sunxi INet97F-II sun4i:INET97F_II,SPL - ++Active arm armv7 sunxi - sunxi INet_K70HC sun7i:INET_K70HC,SPL - ++Active arm armv7 sunxi - sunxi Jesurun-Q5 sun4i:JESURUN_Q5,SPL,SUNXI_EMAC,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi K1001L1C sun7i:K1001L1C,SPL - ++Active arm armv7 sunxi - sunxi Kurio_7S sun7i:KURIO_7S,SPL - ++Active arm armv7 sunxi - sunxi Langcent_H6S sun7i:LANGCENT_H6S,SPL - ++Active arm armv7 sunxi - sunxi Linksprite_pcDuino3 sun7i:LINKSPRITE_PCDUINO3,SPL,SUNXI_GMAC,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Marsboard_A10 sun4i:MARSBOARD_A10,SPL,SUNXI_EMAC,NO_AXP - ++Active arm armv7 sunxi - sunxi Marsboard_A20 sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP - ++Active arm armv7 sunxi - sunxi Marsboard_A20_debug sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP,SYS_SECONDARY_ON - ++Active arm armv7 sunxi - sunxi Megafeis_A08 sun5i:MEFAFEIS_A08,SPL - ++Active arm armv7 sunxi - sunxi Mele_A1000 sun4i:MELE_A1000,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000_FEL sun4i:MELE_A1000,SPL_FEL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000G sun4i:MELE_A1000G,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A3700 sun4i:MELE_A3700,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Merrii_Hummingbird_A20 sun7i:MERRII_HUMMINGBIRD_A20,SPL - ++Active arm armv7 sunxi - sunxi merrii_m2 sun7i:MERRII_M2,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi Mini-X sun4i:MINI_X,SPL - ++Active arm armv7 sunxi - sunxi Mini-X-1Gb sun4i:MINI_X_1GB,SPL - ++Active arm armv7 sunxi - sunxi Mini-X_A10s sun5i:MINI_X_A10S,SPL - ++Active arm armv7 sunxi - sunxi mk802 sun4i:MK802,SPL,NO_AXP - ++Active arm armv7 sunxi - sunxi mk802-1gb sun4i:MK802_1GB,SPL,NO_AXP - ++Active arm armv7 sunxi - sunxi mk802_a10s sun5i:MK802_A10S,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi mk802ii_A20 sun7i:MK802II_A20,SPL - ++Active arm armv7 sunxi - sunxi mk802ii sun4i:MK802II,SPL - ++Active arm armv7 sunxi - sunxi mk808c_A20 sun7i:MK808C_A20,SPL - ++Active arm armv7 sunxi - sunxi OLIMEX-A13-SOM sun5i:OLIMEX_A13_SOM,SPL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi pcDuino sun4i:PCDUINO,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi pengpod1000 sun4i:PENGPOD1000,SPL - ++Active arm armv7 sunxi - sunxi pengpod700 sun4i:PENGPOD700,SPL - ++Active arm armv7 suxni - sunxi pineriver-h25 sun5i:PINERIVER-H25,SPL ++Active arm armv7 sunxi - sunxi POV_TAB_P703 sun5i:POV_TAB_P703,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_IPS9 sun4i:POV_PROTAB2,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_IPS_3g sun4i:POV_PROTAB2,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_XXL sun4i:POV_PROTAB2_XXL,SPL - ++Active arm armv7 sunxi - sunxi qt840a sun7i:QT840A,SPL,FAST_MBUS,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Sanei_N90 sun4i:SANEI_N90,SPL - ++Active arm armv7 sunxi - sunxi Semitime_G2 sun5i:SEMITIME_G2,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi sun4i sun4i:SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun4i_sdcon sun4i:UART0_PORT_F,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i sun5i:SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i_sdcon sun5i:UART0_PORT_F,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i_uart1 sun5i:CONS_INDEX=2,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi TZX-Q8-713B6 sun5i:TZX_Q8_713B6,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi TZX-Q8-713B7 sun5i:TZX_Q8_713B7,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi uhost_u1a sun4i:UHOST_U1A,SPL,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Wexler_TAB_7200 sun7i:WEXLER_TAB_7200,SPL - ++Active arm armv7 sunxi - sunxi wobo-i5 sun5i:WOBO_I5,SPL,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi xzpad700 sun5i:XZPAD700,SPL - ++Active arm armv7 sunxi - sunxi zatab sun4i:ZATAB,SPL - + Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier mathieu.poirier@linaro.org + Active arm armv7 u8500 st-ericsson u8500 u8500_href - - + Active arm armv7 vf610 freescale vf610twr vf610twr vf610twr:IMX_CONFIG=board/freescale/vf610twr/imximage.cfg Alison Wang b18965@freescale.com +diff -ruN u-boot-2014.04/common/spl/spl_mmc.c u-boot-sunxi/common/spl/spl_mmc.c +--- u-boot-2014.04/common/spl/spl_mmc.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/common/spl/spl_mmc.c 2014-09-06 16:58:36.205953114 +0200 +@@ -29,8 +29,10 @@ + if (err == 0) + goto end; + +- if (image_get_magic(header) != IH_MAGIC) ++ if (image_get_magic(header) != IH_MAGIC) { ++ printf("spl: not an uImage at %lu\n", sector); + return -1; ++ } + + spl_parse_image_header(header); + +diff -ruN u-boot-2014.04/drivers/gpio/Makefile u-boot-sunxi/drivers/gpio/Makefile +--- u-boot-2014.04/drivers/gpio/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/gpio/Makefile 2014-09-06 16:58:36.253953113 +0200 +@@ -34,3 +34,4 @@ + obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o + obj-$(CONFIG_TCA642X) += tca642x.o + oby-$(CONFIG_SX151X) += sx151x.o ++obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o +diff -ruN u-boot-2014.04/drivers/gpio/sunxi_gpio.c u-boot-sunxi/drivers/gpio/sunxi_gpio.c +--- u-boot-2014.04/drivers/gpio/sunxi_gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/gpio/sunxi_gpio.c 2014-09-06 16:58:36.253953113 +0200 +@@ -0,0 +1,102 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/gpio.h> ++ ++static int sunxi_gpio_output(u32 pin, u32 val) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ if (val) ++ dat |= 0x1 << num; ++ else ++ dat &= ~(0x1 << num); ++ ++ writel(dat, &pio->dat); ++ ++ return 0; ++} ++ ++static int sunxi_gpio_input(u32 pin) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ dat >>= num; ++ ++ return dat & 0x1; ++} ++ ++int gpio_request(unsigned gpio, const char *label) ++{ ++ return 0; ++} ++ ++int gpio_free(unsigned gpio) ++{ ++ return 0; ++} ++ ++int gpio_direction_input(unsigned gpio) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT); ++ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_direction_output(unsigned gpio, int value) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT); ++ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int gpio_get_value(unsigned gpio) ++{ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_set_value(unsigned gpio, int value) ++{ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int sunxi_name_to_gpio(const char *name) ++{ ++ int group = 0; ++ int groupsize = 9 * 32; ++ long pin; ++ char *eptr; ++ if (*name == 'P' || *name == 'p') ++ name++; ++ if (*name >= 'A') { ++ group = *name - (*name > 'a' ? 'a' : 'A'); ++ groupsize = 32; ++ name++; ++ } ++ ++ pin = simple_strtol(name, &eptr, 10); ++ if (!*name || *eptr) ++ return -1; ++ if (pin < 0 || pin > groupsize || group >= 9) ++ return -1; ++ return group * 32 + pin; ++} +diff -ruN u-boot-2014.04/drivers/i2c/Makefile u-boot-sunxi/drivers/i2c/Makefile +--- u-boot-2014.04/drivers/i2c/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/i2c/Makefile 2014-09-06 16:58:36.265953112 +0200 +@@ -27,5 +27,6 @@ + obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o + obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o + obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o ++obj-$(CONFIG_SYS_I2C_SUNXI) += mvtwsi.o + obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o + obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o +diff -ruN u-boot-2014.04/drivers/i2c/mvtwsi.c u-boot-sunxi/drivers/i2c/mvtwsi.c +--- u-boot-2014.04/drivers/i2c/mvtwsi.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/i2c/mvtwsi.c 2014-09-06 16:58:36.265953112 +0200 +@@ -22,6 +22,8 @@ + #include <asm/arch/orion5x.h> + #elif defined(CONFIG_KIRKWOOD) + #include <asm/arch/kirkwood.h> ++#elif defined(CONFIG_SUNXI) ++#include <asm/arch/i2c.h> + #else + #error Driver mvtwsi not supported by SoC or board + #endif +@@ -30,6 +32,20 @@ + * TWSI register structure + */ + ++#ifdef CONFIG_SUNXI ++ ++struct mvtwsi_registers { ++ u32 slave_address; ++ u32 xtnd_slave_addr; ++ u32 data; ++ u32 control; ++ u32 status; ++ u32 baudrate; ++ u32 soft_reset; ++}; ++ ++#else ++ + struct mvtwsi_registers { + u32 slave_address; + u32 data; +@@ -43,6 +59,8 @@ + u32 soft_reset; + }; + ++#endif ++ + /* + * Control register fields + */ +@@ -216,21 +234,7 @@ + */ + + #define TWSI_FREQUENCY(m, n) \ +- ((u8) (CONFIG_SYS_TCLK / (10 * (m + 1) * 2 * (1 << n)))) +- +-/* +- * These are required to be reprogrammed before enabling the controller +- * because a reset loses them. +- * Default values come from the spec, but a twsi_reset will change them. +- * twsi_slave_address left uninitialized lest checkpatch.pl complains. +- */ +- +-/* Baudrate generator: m (bits 7..4) =4, n (bits 3..0) =4 */ +-static u8 twsi_baud_rate = 0x44; /* baudrate at controller reset */ +-/* Default frequency corresponding to default m=4, n=4 */ +-static u8 twsi_actual_speed = TWSI_FREQUENCY(4, 4); +-/* Default slave address is 0 (so is an uninitialized static) */ +-static u8 twsi_slave_address; ++ (CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n))) + + /* + * Reset controller. +@@ -238,7 +242,7 @@ + * Controller reset also resets the baud rate and slave address, so + * re-establish them. + */ +-static void twsi_reset(void) ++static void twsi_reset(u8 baud_rate, u8 slave_address) + { + /* ensure controller will be enabled by any twsi*() function */ + twsi_control_flags = MVTWSI_CONTROL_TWSIEN; +@@ -247,9 +251,9 @@ + /* wait 2 ms -- this is what the Marvell LSP does */ + udelay(20000); + /* set baud rate */ +- writel(twsi_baud_rate, &twsi->baudrate); ++ writel(baud_rate, &twsi->baudrate); + /* set slave address even though we don't use it */ +- writel(twsi_slave_address, &twsi->slave_address); ++ writel(slave_address, &twsi->slave_address); + writel(0, &twsi->xtnd_slave_addr); + /* assert STOP but don't care for the result */ + (void) twsi_stop(0); +@@ -277,12 +281,8 @@ + } + } + } +- /* save baud rate and slave for later calls to twsi_reset */ +- twsi_baud_rate = baud; +- twsi_actual_speed = highest_speed; +- twsi_slave_address = slaveadd; + /* reset controller */ +- twsi_reset(); ++ twsi_reset(baud, slaveadd); + } + + /* +diff -ruN u-boot-2014.04/drivers/mmc/Makefile u-boot-sunxi/drivers/mmc/Makefile +--- u-boot-2014.04/drivers/mmc/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/mmc/Makefile 2014-09-06 16:58:36.281953112 +0200 +@@ -28,6 +28,7 @@ + obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o + obj-$(CONFIG_DWMMC) += dw_mmc.o + obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o ++obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o + obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o + obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o + ifdef CONFIG_SPL_BUILD +diff -ruN u-boot-2014.04/drivers/mmc/sunxi_mmc.c u-boot-sunxi/drivers/mmc/sunxi_mmc.c +--- u-boot-2014.04/drivers/mmc/sunxi_mmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/mmc/sunxi_mmc.c 2014-09-06 16:58:36.281953112 +0200 +@@ -0,0 +1,385 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Aaron leafy.myeh@allwinnertech.com ++ * ++ * MMC driver for allwinner sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <mmc.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/mmc.h> ++ ++struct sunxi_mmc_host { ++ unsigned mmc_no; ++ uint32_t *mclkreg; ++ unsigned database; ++ unsigned fatal_err; ++ unsigned mod_clk; ++ struct sunxi_mmc *reg; ++ struct mmc_config cfg; ++}; ++ ++/* support 4 mmc hosts */ ++struct sunxi_mmc_host mmc_host[4]; ++ ++static int mmc_resource_init(int sdc_no) ++{ ++ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ debug("init mmc %d resource\n", sdc_no); ++ ++ switch (sdc_no) { ++ case 0: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; ++ mmchost->mclkreg = &ccm->sd0_clk_cfg; ++ break; ++ case 1: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; ++ mmchost->mclkreg = &ccm->sd1_clk_cfg; ++ break; ++ case 2: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; ++ mmchost->mclkreg = &ccm->sd2_clk_cfg; ++ break; ++ case 3: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; ++ mmchost->mclkreg = &ccm->sd3_clk_cfg; ++ break; ++ default: ++ printf("Wrong mmc number %d\n", sdc_no); ++ return -1; ++ } ++#ifdef CONFIG_SUN6I ++ mmchost->database = (unsigned int)mmchost->reg + 0x200; ++#else ++ mmchost->database = (unsigned int)mmchost->reg + 0x100; ++#endif ++ mmchost->mmc_no = sdc_no; ++ ++ return 0; ++} ++ ++static int mmc_clk_io_on(int sdc_no) ++{ ++ unsigned int pll_clk; ++ unsigned int divider; ++ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ debug("init mmc %d clock and io\n", sdc_no); ++ ++ /* config ahb clock */ ++ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); ++ ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++ /* unassert reset */ ++ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); ++#endif ++ ++ /* config mod clock */ ++ pll_clk = clock_get_pll6(); ++ /* should be close to 100 MHz but no more, so round up */ ++ divider = ((pll_clk + 99999999) / 100000000) - 1; ++ writel(CCM_MMC_CTRL_ENABLE | CCM_MMC_CTRL_PLL6 | divider, ++ mmchost->mclkreg); ++ mmchost->mod_clk = pll_clk / (divider + 1); ++ ++ return 0; ++} ++ ++static int mmc_update_clk(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int cmd; ++ unsigned timeout_msecs = 2000; ++ ++ cmd = SUNXI_MMC_CMD_START | ++ SUNXI_MMC_CMD_UPCLK_ONLY | ++ SUNXI_MMC_CMD_WAIT_PRE_OVER; ++ writel(cmd, &mmchost->reg->cmd); ++ while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) { ++ if (!timeout_msecs--) ++ return -1; ++ udelay(1000); ++ } ++ ++ /* clock update sets various irq status bits, clear these */ ++ writel(readl(&mmchost->reg->rint), &mmchost->reg->rint); ++ ++ return 0; ++} ++ ++static int mmc_config_clock(struct mmc *mmc, unsigned div) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned rval = readl(&mmchost->reg->clkcr); ++ ++ /* Disable Clock */ ++ rval &= ~SUNXI_MMC_CLK_ENABLE; ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ ++ /* Change Divider Factor */ ++ rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; ++ rval |= div; ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ /* Re-enable Clock */ ++ rval |= SUNXI_MMC_CLK_ENABLE; ++ writel(rval, &mmchost->reg->clkcr); ++ ++ if (mmc_update_clk(mmc)) ++ return -1; ++ ++ return 0; ++} ++ ++static void mmc_set_ios(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int clkdiv = 0; ++ ++ debug("set ios: bus_width: %x, clock: %d, mod_clk: %d\n", ++ mmc->bus_width, mmc->clock, mmchost->mod_clk); ++ ++ /* Change clock first */ ++ clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2; ++ if (mmc->clock) { ++ if (mmc_config_clock(mmc, clkdiv)) { ++ mmchost->fatal_err = 1; ++ return; ++ } ++ } ++ ++ /* Change bus width */ ++ if (mmc->bus_width == 8) ++ writel(0x2, &mmchost->reg->width); ++ else if (mmc->bus_width == 4) ++ writel(0x1, &mmchost->reg->width); ++ else ++ writel(0x0, &mmchost->reg->width); ++} ++ ++static int mmc_core_init(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ ++ /* Reset controller */ ++ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); ++ udelay(1000); ++ ++ return 0; ++} ++ ++static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ const int reading = !!(data->flags & MMC_DATA_READ); ++ const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : ++ SUNXI_MMC_STATUS_FIFO_FULL; ++ unsigned i; ++ unsigned byte_cnt = data->blocksize * data->blocks; ++ unsigned timeout_msecs = 2000; ++ unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); ++ ++ /* Always read / write data through the CPU */ ++ setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); ++ ++ for (i = 0; i < (byte_cnt >> 2); i++) { ++ while (readl(&mmchost->reg->status) & status_bit) { ++ if (!timeout_msecs--) ++ return -1; ++ udelay(1000); ++ } ++ ++ if (reading) ++ buff[i] = readl(mmchost->database); ++ else ++ writel(buff[i], mmchost->database); ++ } ++ ++ return 0; ++} ++ ++static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, ++ unsigned int done_bit, const char *what) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int status; ++ ++ do { ++ status = readl(&mmchost->reg->rint); ++ if (!timeout_msecs-- || ++ (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { ++ debug("%s timeout %x\n", what, ++ status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); ++ return TIMEOUT; ++ } ++ udelay(1000); ++ } while (!(status & done_bit)); ++ ++ return 0; ++} ++ ++static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ++ struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int cmdval = SUNXI_MMC_CMD_START; ++ unsigned int timeout_msecs; ++ int error = 0; ++ unsigned int status = 0; ++ unsigned int bytecnt = 0; ++ ++ if (mmchost->fatal_err) ++ return -1; ++ if (cmd->resp_type & MMC_RSP_BUSY) ++ debug("mmc cmd %d check rsp busy\n", cmd->cmdidx); ++ if (cmd->cmdidx == 12) ++ return 0; ++ ++ if (!cmd->cmdidx) ++ cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; ++ if (cmd->resp_type & MMC_RSP_PRESENT) ++ cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE; ++ if (cmd->resp_type & MMC_RSP_136) ++ cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE; ++ if (cmd->resp_type & MMC_RSP_CRC) ++ cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; ++ ++ if (data) { ++ if ((u32) data->dest & 0x3) { ++ error = -1; ++ goto out; ++ } ++ ++ cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER; ++ if (data->flags & MMC_DATA_WRITE) ++ cmdval |= SUNXI_MMC_CMD_WRITE; ++ if (data->blocks > 1) ++ cmdval |= SUNXI_MMC_CMD_AUTO_STOP; ++ writel(data->blocksize, &mmchost->reg->blksz); ++ writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt); ++ } ++ ++ debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no, ++ cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); ++ writel(cmd->cmdarg, &mmchost->reg->arg); ++ ++ if (!data) ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ++ /* ++ * transfer data and check status ++ * STATREG[2] : FIFO empty ++ * STATREG[3] : FIFO full ++ */ ++ if (data) { ++ int ret = 0; ++ ++ bytecnt = data->blocksize * data->blocks; ++ debug("trans data %d bytes\n", bytecnt); ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ret = mmc_trans_data_by_cpu(mmc, data); ++ if (ret) { ++ error = readl(&mmchost->reg->rint) & \ ++ SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; ++ error = TIMEOUT; ++ goto out; ++ } ++ } ++ ++ error = mmc_rint_wait(mmc, 0xfffff, SUNXI_MMC_RINT_COMMAND_DONE, "cmd"); ++ if (error) ++ goto out; ++ ++ if (data) { ++ timeout_msecs = 120; ++ debug("cacl timeout %x msec\n", timeout_msecs); ++ error = mmc_rint_wait(mmc, timeout_msecs, ++ data->blocks > 1 ? ++ SUNXI_MMC_RINT_AUTO_COMMAND_DONE : ++ SUNXI_MMC_RINT_DATA_OVER, ++ "data"); ++ if (error) ++ goto out; ++ } ++ ++ if (cmd->resp_type & MMC_RSP_BUSY) { ++ timeout_msecs = 2000; ++ do { ++ status = readl(&mmchost->reg->status); ++ if (!timeout_msecs--) { ++ debug("busy timeout\n"); ++ error = TIMEOUT; ++ goto out; ++ } ++ udelay(1000); ++ } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY); ++ } ++ ++ if (cmd->resp_type & MMC_RSP_136) { ++ cmd->response[0] = readl(&mmchost->reg->resp3); ++ cmd->response[1] = readl(&mmchost->reg->resp2); ++ cmd->response[2] = readl(&mmchost->reg->resp1); ++ cmd->response[3] = readl(&mmchost->reg->resp0); ++ debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ cmd->response[3], cmd->response[2], ++ cmd->response[1], cmd->response[0]); ++ } else { ++ cmd->response[0] = readl(&mmchost->reg->resp0); ++ debug("mmc resp 0x%08x\n", cmd->response[0]); ++ } ++out: ++ if (error < 0) { ++ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); ++ mmc_update_clk(mmc); ++ } ++ writel(0xffffffff, &mmchost->reg->rint); ++ writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, ++ &mmchost->reg->gctrl); ++ ++ return error; ++} ++ ++static const struct mmc_ops sunxi_mmc_ops = { ++ .send_cmd = mmc_send_cmd, ++ .set_ios = mmc_set_ios, ++ .init = mmc_core_init, ++}; ++ ++int sunxi_mmc_init(int sdc_no) ++{ ++ struct mmc_config *cfg = &mmc_host[sdc_no].cfg; ++ ++ memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); ++ ++ cfg->name = "SUNXI SD/MMC"; ++ cfg->ops = &sunxi_mmc_ops; ++ ++ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; ++ cfg->host_caps = MMC_MODE_4BIT; ++ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; ++ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; ++ ++ cfg->f_min = 400000; ++ cfg->f_max = 52000000; ++ ++ mmc_resource_init(sdc_no); ++ mmc_clk_io_on(sdc_no); ++ ++ if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) ++ return -1; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/net/designware.c u-boot-sunxi/drivers/net/designware.c +--- u-boot-2014.04/drivers/net/designware.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/designware.c 2014-09-06 16:58:36.301953111 +0200 +@@ -249,7 +249,7 @@ + rx_descs_init(dev); + tx_descs_init(dev); + +- writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); ++ writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); + + writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, + &dma_p->opmode); +@@ -280,10 +280,18 @@ + u32 desc_num = priv->tx_currdescnum; + struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; + +- /* Invalidate only "status" field for the following check */ +- invalidate_dcache_range((unsigned long)&desc_p->txrx_status, +- (unsigned long)&desc_p->txrx_status + +- sizeof(desc_p->txrx_status)); ++ /* ++ * Strictly we only need to invalidate the "txrx_status" field ++ * for the following check, but on some platforms we cannot ++ * invalidate only 4 bytes, so roundup to ++ * ARCH_DMA_MINALIGN. This is safe because the individual ++ * descriptors in the array are each aligned to ++ * ARCH_DMA_MINALIGN. ++ */ ++ invalidate_dcache_range( ++ (unsigned long)desc_p, ++ (unsigned long)desc_p + ++ roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); + + /* Check if the descriptor is owned by CPU */ + if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { +@@ -351,7 +359,7 @@ + /* Invalidate received data */ + invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, + (unsigned long)desc_p->dmamac_addr + +- length); ++ roundup(length, ARCH_DMA_MINALIGN)); + + NetReceive(desc_p->dmamac_addr, length); + +@@ -390,6 +398,8 @@ + if (!phydev) + return -1; + ++ phy_connect_dev(phydev, dev); ++ + phydev->supported &= PHY_GBIT_FEATURES; + phydev->advertising = phydev->supported; + +@@ -412,7 +422,8 @@ + * Since the priv structure contains the descriptors which need a strict + * buswidth alignment, memalign is used to allocate memory + */ +- priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev)); ++ priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN, ++ sizeof(struct dw_eth_dev)); + if (!priv) { + free(dev); + return -ENOMEM; +diff -ruN u-boot-2014.04/drivers/net/designware.h u-boot-sunxi/drivers/net/designware.h +--- u-boot-2014.04/drivers/net/designware.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/designware.h 2014-09-06 16:58:36.301953111 +0200 +@@ -77,18 +77,18 @@ + + #define DW_DMA_BASE_OFFSET (0x1000) + ++/* Default DMA Burst length */ ++#ifndef CONFIG_DW_GMAC_DEFAULT_DMA_PBL ++#define CONFIG_DW_GMAC_DEFAULT_DMA_PBL 8 ++#endif ++ + /* Bus mode register definitions */ + #define FIXEDBURST (1 << 16) + #define PRIORXTX_41 (3 << 14) + #define PRIORXTX_31 (2 << 14) + #define PRIORXTX_21 (1 << 14) + #define PRIORXTX_11 (0 << 14) +-#define BURST_1 (1 << 8) +-#define BURST_2 (2 << 8) +-#define BURST_4 (4 << 8) +-#define BURST_8 (8 << 8) +-#define BURST_16 (16 << 8) +-#define BURST_32 (32 << 8) ++#define DMA_PBL (CONFIG_DW_GMAC_DEFAULT_DMA_PBL<<8) + #define RXHIGHPRIO (1 << 1) + #define DMAMAC_SRST (1 << 0) + +@@ -215,15 +215,14 @@ + #endif + + struct dw_eth_dev { +- u32 interface; +- u32 tx_currdescnum; +- u32 rx_currdescnum; +- + struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; + struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; ++ char txbuffs[TX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); ++ char rxbuffs[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); + +- char txbuffs[TX_TOTAL_BUFSIZE]; +- char rxbuffs[RX_TOTAL_BUFSIZE]; ++ u32 interface; ++ u32 tx_currdescnum; ++ u32 rx_currdescnum; + + struct eth_mac_regs *mac_regs_p; + struct eth_dma_regs *dma_regs_p; +diff -ruN u-boot-2014.04/drivers/net/Makefile u-boot-sunxi/drivers/net/Makefile +--- u-boot-2014.04/drivers/net/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/Makefile 2014-09-06 16:58:36.297953112 +0200 +@@ -50,7 +50,7 @@ + obj-$(CONFIG_SH_ETHER) += sh_eth.o + obj-$(CONFIG_SMC91111) += smc91111.o + obj-$(CONFIG_SMC911X) += smc911x.o +-obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o ++obj-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o + obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o + obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o + obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o +diff -ruN u-boot-2014.04/drivers/net/sunxi_emac.c u-boot-sunxi/drivers/net/sunxi_emac.c +--- u-boot-2014.04/drivers/net/sunxi_emac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/net/sunxi_emac.c 2014-09-06 16:58:36.317953111 +0200 +@@ -0,0 +1,521 @@ ++/* ++ * sunxi_emac.c -- Allwinner A10 ethernet driver ++ * ++ * (C) Copyright 2012, Stefan Roese sr@denx.de ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <linux/err.h> ++#include <malloc.h> ++#include <miiphy.h> ++#include <net.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++ ++/* EMAC register */ ++struct emac_regs { ++ u32 ctl; /* 0x00 */ ++ u32 tx_mode; /* 0x04 */ ++ u32 tx_flow; /* 0x08 */ ++ u32 tx_ctl0; /* 0x0c */ ++ u32 tx_ctl1; /* 0x10 */ ++ u32 tx_ins; /* 0x14 */ ++ u32 tx_pl0; /* 0x18 */ ++ u32 tx_pl1; /* 0x1c */ ++ u32 tx_sta; /* 0x20 */ ++ u32 tx_io_data; /* 0x24 */ ++ u32 tx_io_data1;/* 0x28 */ ++ u32 tx_tsvl0; /* 0x2c */ ++ u32 tx_tsvh0; /* 0x30 */ ++ u32 tx_tsvl1; /* 0x34 */ ++ u32 tx_tsvh1; /* 0x38 */ ++ u32 rx_ctl; /* 0x3c */ ++ u32 rx_hash0; /* 0x40 */ ++ u32 rx_hash1; /* 0x44 */ ++ u32 rx_sta; /* 0x48 */ ++ u32 rx_io_data; /* 0x4c */ ++ u32 rx_fbc; /* 0x50 */ ++ u32 int_ctl; /* 0x54 */ ++ u32 int_sta; /* 0x58 */ ++ u32 mac_ctl0; /* 0x5c */ ++ u32 mac_ctl1; /* 0x60 */ ++ u32 mac_ipgt; /* 0x64 */ ++ u32 mac_ipgr; /* 0x68 */ ++ u32 mac_clrt; /* 0x6c */ ++ u32 mac_maxf; /* 0x70 */ ++ u32 mac_supp; /* 0x74 */ ++ u32 mac_test; /* 0x78 */ ++ u32 mac_mcfg; /* 0x7c */ ++ u32 mac_mcmd; /* 0x80 */ ++ u32 mac_madr; /* 0x84 */ ++ u32 mac_mwtd; /* 0x88 */ ++ u32 mac_mrdd; /* 0x8c */ ++ u32 mac_mind; /* 0x90 */ ++ u32 mac_ssrr; /* 0x94 */ ++ u32 mac_a0; /* 0x98 */ ++ u32 mac_a1; /* 0x9c */ ++}; ++ ++/* SRAMC register */ ++struct sunxi_sramc_regs { ++ u32 ctrl0; ++ u32 ctrl1; ++}; ++ ++/* 0: Disable 1: Aborted frame enable(default) */ ++#define EMAC_TX_AB_M (0x1 << 0) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_TX_TM (0x1 << 1) ++ ++#define EMAC_TX_SETUP (0) ++ ++/* 0: DRQ asserted 1: DRQ automatically(default) */ ++#define EMAC_RX_DRQ_MODE (0x1 << 1) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_RX_TM (0x1 << 2) ++/* 0: Normal(default) 1: Pass all Frames */ ++#define EMAC_RX_PA (0x1 << 4) ++/* 0: Normal(default) 1: Pass Control Frames */ ++#define EMAC_RX_PCF (0x1 << 5) ++/* 0: Normal(default) 1: Pass Frames with CRC Error */ ++#define EMAC_RX_PCRCE (0x1 << 6) ++/* 0: Normal(default) 1: Pass Frames with Length Error */ ++#define EMAC_RX_PLE (0x1 << 7) ++/* 0: Normal 1: Pass Frames length out of range(default) */ ++#define EMAC_RX_POR (0x1 << 8) ++/* 0: Not accept 1: Accept unicast Packets(default) */ ++#define EMAC_RX_UCAD (0x1 << 16) ++/* 0: Normal(default) 1: DA Filtering */ ++#define EMAC_RX_DAF (0x1 << 17) ++/* 0: Not accept 1: Accept multicast Packets(default) */ ++#define EMAC_RX_MCO (0x1 << 20) ++/* 0: Disable(default) 1: Enable Hash filter */ ++#define EMAC_RX_MHF (0x1 << 21) ++/* 0: Not accept 1: Accept Broadcast Packets(default) */ ++#define EMAC_RX_BCO (0x1 << 22) ++/* 0: Disable(default) 1: Enable SA Filtering */ ++#define EMAC_RX_SAF (0x1 << 24) ++/* 0: Normal(default) 1: Inverse Filtering */ ++#define EMAC_RX_SAIF (0x1 << 25) ++ ++#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ ++ EMAC_RX_MCO | EMAC_RX_BCO) ++ ++/* 0: Disable 1: Enable Receive Flow Control(default) */ ++#define EMAC_MAC_CTL0_RFC (0x1 << 2) ++/* 0: Disable 1: Enable Transmit Flow Control(default) */ ++#define EMAC_MAC_CTL0_TFC (0x1 << 3) ++ ++#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) ++ ++/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ ++#define EMAC_MAC_CTL1_FLC (0x1 << 1) ++/* 0: Disable(default) 1: Enable Huge Frame */ ++#define EMAC_MAC_CTL1_HF (0x1 << 2) ++/* 0: Disable(default) 1: Enable MAC Delayed CRC */ ++#define EMAC_MAC_CTL1_DCRC (0x1 << 3) ++/* 0: Disable 1: Enable MAC CRC(default) */ ++#define EMAC_MAC_CTL1_CRC (0x1 << 4) ++/* 0: Disable 1: Enable MAC PAD Short frames(default) */ ++#define EMAC_MAC_CTL1_PC (0x1 << 5) ++/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ ++#define EMAC_MAC_CTL1_VC (0x1 << 6) ++/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ ++#define EMAC_MAC_CTL1_ADP (0x1 << 7) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_PRE (0x1 << 8) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_LPE (0x1 << 9) ++/* 0: Disable(default) 1: Enable no back off */ ++#define EMAC_MAC_CTL1_NB (0x1 << 12) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_BNB (0x1 << 13) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_ED (0x1 << 14) ++ ++#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ ++ EMAC_MAC_CTL1_PC) ++ ++#define EMAC_MAC_IPGT 0x15 ++ ++#define EMAC_MAC_NBTB_IPG1 0xc ++#define EMAC_MAC_NBTB_IPG2 0x12 ++ ++#define EMAC_MAC_CW 0x37 ++#define EMAC_MAC_RM 0xf ++ ++#define EMAC_MAC_MFL 0x0600 ++ ++/* Receive status */ ++#define EMAC_CRCERR (0x1 << 4) ++#define EMAC_LENERR (0x3 << 5) ++ ++#define DMA_CPU_TRRESHOLD 2000 ++ ++struct emac_eth_dev { ++ u32 speed; ++ u32 duplex; ++ u32 phy_configured; ++ int link_printed; ++}; ++ ++struct emac_rxhdr { ++ s16 rx_len; ++ u16 rx_status; ++}; ++ ++static void emac_inblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ u32 *buf = data; ++ ++ do { ++ u32 x = readl(reg); ++ *buf++ = x; ++ } while (--cnt); ++ } ++} ++ ++static void emac_outblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ const u32 *buf = data; ++ ++ do { ++ writel(*buf++, reg); ++ } while (--cnt); ++ } ++} ++ ++/* Read a word from phyxcer */ ++static int emac_phy_read(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short *value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait read complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ *value = readl(®s->mac_mrdd); ++ ++ return 0; ++} ++ ++/* Write a word to phyxcer */ ++static int emac_phy_write(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait write complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ writel(value, ®s->mac_mwtd); ++ ++ return 0; ++} ++ ++static void emac_setup(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ u32 reg_val; ++ u16 phy_val; ++ u32 duplex_flag; ++ ++ /* Set up TX */ ++ writel(EMAC_TX_SETUP, ®s->tx_mode); ++ ++ /* Set up RX */ ++ writel(EMAC_RX_SETUP, ®s->rx_ctl); ++ ++ /* Set MAC */ ++ /* Set MAC CTL0 */ ++ writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); ++ ++ /* Set MAC CTL1 */ ++ emac_phy_read(dev->name, 1, 0, &phy_val); ++ debug("PHY SETUP, reg 0 value: %x\n", phy_val); ++ duplex_flag = !!(phy_val & (1 << 8)); ++ ++ reg_val = 0; ++ if (duplex_flag) ++ reg_val = (0x1 << 0); ++ writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); ++ ++ /* Set up IPGT */ ++ writel(EMAC_MAC_IPGT, ®s->mac_ipgt); ++ ++ /* Set up IPGR */ ++ writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); ++ ++ /* Set up Collison window */ ++ writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); ++ ++ /* Set up Max Frame Length */ ++ writel(EMAC_MAC_MFL, ®s->mac_maxf); ++} ++ ++static void emac_reset(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ debug("resetting device\n"); ++ ++ /* RESET device */ ++ writel(0, ®s->ctl); ++ udelay(200); ++ ++ writel(1, ®s->ctl); ++ udelay(200); ++} ++ ++static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_eth_dev *priv = dev->priv; ++ u16 phy_reg; ++ ++ /* Init EMAC */ ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x8); ++ udelay(1); ++ ++ /* Init MAC */ ++ ++ /* Soft reset MAC */ ++ clrbits_le32(®s->mac_ctl0, 0x1 << 15); ++ ++ /* Clear RX counter */ ++ writel(0x0, ®s->rx_fbc); ++ udelay(1); ++ ++ /* Set up EMAC */ ++ emac_setup(dev); ++ ++ writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | ++ dev->enetaddr[2], ®s->mac_a1); ++ writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | ++ dev->enetaddr[5], ®s->mac_a0); ++ ++ mdelay(1); ++ ++ emac_reset(dev); ++ ++ /* PHY POWER UP */ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); ++ mdelay(1); ++ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ ++ priv->speed = miiphy_speed(dev->name, 0); ++ priv->duplex = miiphy_duplex(dev->name, 0); ++ ++ /* Print link status only once */ ++ if (!priv->link_printed) { ++ printf("ENET Speed is %d Mbps - %s duplex connection\n", ++ priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); ++ priv->link_printed = 1; ++ } ++ ++ /* Set EMAC SPEED depend on PHY */ ++ clrsetbits_le32(®s->mac_supp, 1 << 8, ++ ((phy_reg & (0x1 << 13)) >> 13) << 8); ++ ++ /* Set duplex depend on phy */ ++ clrsetbits_le32(®s->mac_ctl1, 1 << 0, ++ ((phy_reg & (0x1 << 8)) >> 8) << 0); ++ ++ /* Enable RX/TX */ ++ setbits_le32(®s->ctl, 0x7); ++ ++ return 0; ++} ++ ++static void sunxi_emac_eth_halt(struct eth_device *dev) ++{ ++ /* Nothing to do here */ ++} ++ ++static int sunxi_emac_eth_recv(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_rxhdr rxhdr; ++ u32 rxcount; ++ u32 reg_val; ++ int rx_len; ++ int rx_status; ++ int good_packet; ++ ++ /* Check packet ready or not */ ++ ++ /* Race warning: The first packet might arrive with ++ * the interrupts disabled, but the second will fix ++ */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) { ++ /* Had one stuck? */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) ++ return 0; ++ } ++ ++ reg_val = readl(®s->rx_io_data); ++ if (reg_val != 0x0143414d) { ++ /* Disable RX */ ++ clrbits_le32(®s->ctl, 0x1 << 2); ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x1 << 3); ++ while (readl(®s->rx_ctl) & (0x1 << 3)) ++ ; ++ ++ /* Enable RX */ ++ setbits_le32(®s->ctl, 0x1 << 2); ++ ++ return 0; ++ } ++ ++ /* A packet ready now ++ * Get status/length ++ */ ++ good_packet = 1; ++ ++ emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); ++ ++ rx_len = rxhdr.rx_len; ++ rx_status = rxhdr.rx_status; ++ ++ /* Packet Status check */ ++ if (rx_len < 0x40) { ++ good_packet = 0; ++ debug("RX: Bad Packet (runt)\n"); ++ } ++ ++ /* rx_status is identical to RSR register. */ ++ if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { ++ good_packet = 0; ++ if (rx_status & EMAC_CRCERR) ++ printf("crc error\n"); ++ if (rx_status & EMAC_LENERR) ++ printf("length error\n"); ++ } ++ ++ /* Move data from EMAC */ ++ if (good_packet) { ++ if (rx_len > DMA_CPU_TRRESHOLD) { ++ printf("Received packet is too big (len=%d)\n", rx_len); ++ } else { ++ emac_inblk_32bit((void *)®s->rx_io_data, ++ NetRxPackets[0], rx_len); ++ ++ /* Pass to upper layer */ ++ NetReceive(NetRxPackets[0], rx_len); ++ return rx_len; ++ } ++ } ++ ++ return 0; ++} ++ ++static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* Select channel 0 */ ++ writel(0, ®s->tx_ins); ++ ++ /* Write packet */ ++ emac_outblk_32bit((void *)®s->tx_io_data, packet, len); ++ ++ /* Set TX len */ ++ writel(len, ®s->tx_pl0); ++ ++ /* Start translate from fifo to phy */ ++ setbits_le32(®s->tx_ctl0, 1); ++ ++ return 0; ++} ++ ++int sunxi_emac_initialize(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sunxi_sramc_regs *sram = ++ (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; ++ struct emac_regs *regs = ++ (struct emac_regs *)SUNXI_EMAC_BASE; ++ struct eth_device *dev; ++ struct emac_eth_dev *priv; ++ int pin; ++ ++ dev = malloc(sizeof(*dev)); ++ if (dev == NULL) ++ return -ENOMEM; ++ ++ priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); ++ if (!priv) { ++ free(dev); ++ return -ENOMEM; ++ } ++ ++ memset(dev, 0, sizeof(*dev)); ++ memset(priv, 0, sizeof(struct emac_eth_dev)); ++ ++ /* Map SRAM to EMAC */ ++ setbits_le32(&sram->ctrl1, 0x5 << 2); ++ ++ /* Configure pin mux settings for MII Ethernet */ ++ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPA0_EMAC); ++ ++ /* Set up clock gating */ ++ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); ++ ++ /* Set MII clock */ ++ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); ++ ++ dev->iobase = (int)regs; ++ dev->priv = priv; ++ dev->init = sunxi_emac_eth_init; ++ dev->halt = sunxi_emac_eth_halt; ++ dev->send = sunxi_emac_eth_send; ++ dev->recv = sunxi_emac_eth_recv; ++ strcpy(dev->name, "emac"); ++ ++ eth_register(dev); ++ ++ miiphy_register(dev->name, emac_phy_read, emac_phy_write); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/net/sunxi_wemac.c u-boot-sunxi/drivers/net/sunxi_wemac.c +--- u-boot-2014.04/drivers/net/sunxi_wemac.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/sunxi_wemac.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,525 +0,0 @@ +-/* +- * sunxi_wemac.c -- Allwinner A10 ethernet driver +- * +- * (C) Copyright 2012, Stefan Roese sr@denx.de +- * +- * SPDX-License-Identifier: GPL-2.0+ +- */ +- +-#include <common.h> +-#include <malloc.h> +-#include <net.h> +-#include <miiphy.h> +-#include <linux/err.h> +-#include <asm/io.h> +-#include <asm/arch/clock.h> +-#include <asm/arch/gpio.h> +- +-/* EMAC register */ +-struct wemac_regs { +- u32 ctl; /* 0x00 */ +- u32 tx_mode; /* 0x04 */ +- u32 tx_flow; /* 0x08 */ +- u32 tx_ctl0; /* 0x0c */ +- u32 tx_ctl1; /* 0x10 */ +- u32 tx_ins; /* 0x14 */ +- u32 tx_pl0; /* 0x18 */ +- u32 tx_pl1; /* 0x1c */ +- u32 tx_sta; /* 0x20 */ +- u32 tx_io_data; /* 0x24 */ +- u32 tx_io_data1; /* 0x28 */ +- u32 tx_tsvl0; /* 0x2c */ +- u32 tx_tsvh0; /* 0x30 */ +- u32 tx_tsvl1; /* 0x34 */ +- u32 tx_tsvh1; /* 0x38 */ +- u32 rx_ctl; /* 0x3c */ +- u32 rx_hash0; /* 0x40 */ +- u32 rx_hash1; /* 0x44 */ +- u32 rx_sta; /* 0x48 */ +- u32 rx_io_data; /* 0x4c */ +- u32 rx_fbc; /* 0x50 */ +- u32 int_ctl; /* 0x54 */ +- u32 int_sta; /* 0x58 */ +- u32 mac_ctl0; /* 0x5c */ +- u32 mac_ctl1; /* 0x60 */ +- u32 mac_ipgt; /* 0x64 */ +- u32 mac_ipgr; /* 0x68 */ +- u32 mac_clrt; /* 0x6c */ +- u32 mac_maxf; /* 0x70 */ +- u32 mac_supp; /* 0x74 */ +- u32 mac_test; /* 0x78 */ +- u32 mac_mcfg; /* 0x7c */ +- u32 mac_mcmd; /* 0x80 */ +- u32 mac_madr; /* 0x84 */ +- u32 mac_mwtd; /* 0x88 */ +- u32 mac_mrdd; /* 0x8c */ +- u32 mac_mind; /* 0x90 */ +- u32 mac_ssrr; /* 0x94 */ +- u32 mac_a0; /* 0x98 */ +- u32 mac_a1; /* 0x9c */ +-}; +- +-/* SRAMC register */ +-struct sunxi_sramc_regs { +- u32 ctrl0; +- u32 ctrl1; +-}; +- +-/* 0: Disable 1: Aborted frame enable(default) */ +-#define EMAC_TX_AB_M (0x1 << 0) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_TX_TM (0x1 << 1) +- +-#define EMAC_TX_SETUP (0) +- +-/* 0: DRQ asserted 1: DRQ automatically(default) */ +-#define EMAC_RX_DRQ_MODE (0x1 << 1) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_RX_TM (0x1 << 2) +-/* 0: Normal(default) 1: Pass all Frames */ +-#define EMAC_RX_PA (0x1 << 4) +-/* 0: Normal(default) 1: Pass Control Frames */ +-#define EMAC_RX_PCF (0x1 << 5) +-/* 0: Normal(default) 1: Pass Frames with CRC Error */ +-#define EMAC_RX_PCRCE (0x1 << 6) +-/* 0: Normal(default) 1: Pass Frames with Length Error */ +-#define EMAC_RX_PLE (0x1 << 7) +-/* 0: Normal 1: Pass Frames length out of range(default) */ +-#define EMAC_RX_POR (0x1 << 8) +-/* 0: Not accept 1: Accept unicast Packets(default) */ +-#define EMAC_RX_UCAD (0x1 << 16) +-/* 0: Normal(default) 1: DA Filtering */ +-#define EMAC_RX_DAF (0x1 << 17) +-/* 0: Not accept 1: Accept multicast Packets(default) */ +-#define EMAC_RX_MCO (0x1 << 20) +-/* 0: Disable(default) 1: Enable Hash filter */ +-#define EMAC_RX_MHF (0x1 << 21) +-/* 0: Not accept 1: Accept Broadcast Packets(default) */ +-#define EMAC_RX_BCO (0x1 << 22) +-/* 0: Disable(default) 1: Enable SA Filtering */ +-#define EMAC_RX_SAF (0x1 << 24) +-/* 0: Normal(default) 1: Inverse Filtering */ +-#define EMAC_RX_SAIF (0x1 << 25) +- +-#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ +- EMAC_RX_MCO | EMAC_RX_BCO) +- +-/* 0: Disable 1: Enable Receive Flow Control(default) */ +-#define EMAC_MAC_CTL0_RFC (0x1 << 2) +-/* 0: Disable 1: Enable Transmit Flow Control(default) */ +-#define EMAC_MAC_CTL0_TFC (0x1 << 3) +- +-#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) +- +-/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ +-#define EMAC_MAC_CTL1_FLC (0x1 << 1) +-/* 0: Disable(default) 1: Enable Huge Frame */ +-#define EMAC_MAC_CTL1_HF (0x1 << 2) +-/* 0: Disable(default) 1: Enable MAC Delayed CRC */ +-#define EMAC_MAC_CTL1_DCRC (0x1 << 3) +-/* 0: Disable 1: Enable MAC CRC(default) */ +-#define EMAC_MAC_CTL1_CRC (0x1 << 4) +-/* 0: Disable 1: Enable MAC PAD Short frames(default) */ +-#define EMAC_MAC_CTL1_PC (0x1 << 5) +-/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ +-#define EMAC_MAC_CTL1_VC (0x1 << 6) +-/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ +-#define EMAC_MAC_CTL1_ADP (0x1 << 7) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_PRE (0x1 << 8) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_LPE (0x1 << 9) +-/* 0: Disable(default) 1: Enable no back off */ +-#define EMAC_MAC_CTL1_NB (0x1 << 12) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_BNB (0x1 << 13) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_ED (0x1 << 14) +- +-#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ +- EMAC_MAC_CTL1_PC) +- +-#define EMAC_MAC_IPGT 0x15 +- +-#define EMAC_MAC_NBTB_IPG1 0xC +-#define EMAC_MAC_NBTB_IPG2 0x12 +- +-#define EMAC_MAC_CW 0x37 +-#define EMAC_MAC_RM 0xF +- +-#define EMAC_MAC_MFL 0x0600 +- +-/* Receive status */ +-#define EMAC_CRCERR (1 << 4) +-#define EMAC_LENERR (3 << 5) +- +-#define DMA_CPU_TRRESHOLD 2000 +- +-struct wemac_eth_dev { +- u32 speed; +- u32 duplex; +- u32 phy_configured; +- int link_printed; +-}; +- +-struct wemac_rxhdr { +- s16 rx_len; +- u16 rx_status; +-}; +- +-static void wemac_inblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- u32 *buf = data; +- +- do { +- u32 x = readl(reg); +- *buf++ = x; +- } while (--cnt); +- } +-} +- +-static void wemac_outblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- const u32 *buf = data; +- +- do { +- writel(*buf++, reg); +- } while (--cnt); +- } +-} +- +-/* +- * Read a word from phyxcer +- */ +-static int wemac_phy_read(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short *value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait read complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- *value = readl(®s->mac_mrdd); +- +- return 0; +-} +- +-/* +- * Write a word to phyxcer +- */ +-static int wemac_phy_write(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait write complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- writel(value, ®s->mac_mwtd); +- +- return 0; +-} +- +-static void emac_setup(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- u32 reg_val; +- u16 phy_val; +- u32 duplex_flag; +- +- /* Set up TX */ +- writel(EMAC_TX_SETUP, ®s->tx_mode); +- +- /* Set up RX */ +- writel(EMAC_RX_SETUP, ®s->rx_ctl); +- +- /* Set MAC */ +- /* Set MAC CTL0 */ +- writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); +- +- /* Set MAC CTL1 */ +- wemac_phy_read(dev->name, 1, 0, &phy_val); +- debug("PHY SETUP, reg 0 value: %x\n", phy_val); +- duplex_flag = !!(phy_val & (1 << 8)); +- +- reg_val = 0; +- if (duplex_flag) +- reg_val = (0x1 << 0); +- writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); +- +- /* Set up IPGT */ +- writel(EMAC_MAC_IPGT, ®s->mac_ipgt); +- +- /* Set up IPGR */ +- writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); +- +- /* Set up Collison window */ +- writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); +- +- /* Set up Max Frame Length */ +- writel(EMAC_MAC_MFL, ®s->mac_maxf); +-} +- +-static void wemac_reset(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- debug("resetting device\n"); +- +- /* RESET device */ +- writel(0, ®s->ctl); +- udelay(200); +- +- writel(1, ®s->ctl); +- udelay(200); +-} +- +-static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_eth_dev *priv = dev->priv; +- u16 phy_reg; +- +- /* Init EMAC */ +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 0x8); +- udelay(1); +- +- /* Init MAC */ +- +- /* Soft reset MAC */ +- clrbits_le32(®s->mac_ctl0, 1 << 15); +- +- /* Set MII clock */ +- clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); +- +- /* Clear RX counter */ +- writel(0x0, ®s->rx_fbc); +- udelay(1); +- +- /* Set up EMAC */ +- emac_setup(dev); +- +- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | +- dev->enetaddr[2], ®s->mac_a1); +- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | +- dev->enetaddr[5], ®s->mac_a0); +- +- mdelay(1); +- +- wemac_reset(dev); +- +- /* PHY POWER UP */ +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); +- mdelay(1); +- +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- +- priv->speed = miiphy_speed(dev->name, 0); +- priv->duplex = miiphy_duplex(dev->name, 0); +- +- /* Print link status only once */ +- if (!priv->link_printed) { +- printf("ENET Speed is %d Mbps - %s duplex connection\n", +- priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); +- priv->link_printed = 1; +- } +- +- /* Set EMAC SPEED depend on PHY */ +- clrsetbits_le32(®s->mac_supp, 1 << 8, +- ((phy_reg & (1 << 13)) >> 13) << 8); +- +- /* Set duplex depend on phy */ +- clrsetbits_le32(®s->mac_ctl1, 1 << 0, +- ((phy_reg & (1 << 8)) >> 8) << 0); +- +- /* Enable RX/TX */ +- setbits_le32(®s->ctl, 0x7); +- +- return 0; +-} +- +-static void sunxi_wemac_eth_halt(struct eth_device *dev) +-{ +- /* Nothing to do here */ +-} +- +-static int sunxi_wemac_eth_recv(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_rxhdr rxhdr; +- u32 rxcount; +- u32 reg_val; +- int rx_len; +- int rx_status; +- int good_packet; +- +- /* Check packet ready or not */ +- +- /* +- * Race warning: The first packet might arrive with +- * the interrupts disabled, but the second will fix +- */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) { +- /* Had one stuck? */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) +- return 0; +- } +- +- reg_val = readl(®s->rx_io_data); +- if (reg_val != 0x0143414d) { +- /* Disable RX */ +- clrbits_le32(®s->ctl, 1 << 2); +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 1 << 3); +- while (readl(®s->rx_ctl) & (1 << 3)) +- ; +- +- /* Enable RX */ +- setbits_le32(®s->ctl, 1 << 2); +- +- return 0; +- } +- +- /* +- * A packet ready now +- * Get status/length +- */ +- good_packet = 1; +- +- wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); +- +- rx_len = rxhdr.rx_len; +- rx_status = rxhdr.rx_status; +- +- /* Packet Status check */ +- if (rx_len < 0x40) { +- good_packet = 0; +- debug("RX: Bad Packet (runt)\n"); +- } +- +- /* rx_status is identical to RSR register. */ +- if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { +- good_packet = 0; +- if (rx_status & EMAC_CRCERR) +- printf("crc error\n"); +- if (rx_status & EMAC_LENERR) +- printf("length error\n"); +- } +- +- /* Move data from WEMAC */ +- if (good_packet) { +- if (rx_len > DMA_CPU_TRRESHOLD) { +- printf("Received packet is too big (len=%d)\n", rx_len); +- } else { +- wemac_inblk_32bit((void *)®s->rx_io_data, +- NetRxPackets[0], rx_len); +- +- /* Pass to upper layer */ +- NetReceive(NetRxPackets[0], rx_len); +- return rx_len; +- } +- } +- +- return 0; +-} +- +-static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* Select channel 0 */ +- writel(0, ®s->tx_ins); +- +- /* Write packet */ +- wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); +- +- /* Set TX len */ +- writel(len, ®s->tx_pl0); +- +- /* Start translate from fifo to phy */ +- setbits_le32(®s->tx_ctl0, 1); +- +- return 0; +-} +- +-int sunxi_wemac_initialize(void) +-{ +- struct sunxi_ccm_reg *const ccm = +- (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; +- struct sunxi_sramc_regs *sram = +- (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; +- struct eth_device *dev; +- struct wemac_eth_dev *priv; +- int pin; +- +- dev = malloc(sizeof(*dev)); +- if (dev == NULL) +- return -ENOMEM; +- +- priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); +- if (!priv) { +- free(dev); +- return -ENOMEM; +- } +- +- memset(dev, 0, sizeof(*dev)); +- memset(priv, 0, sizeof(struct wemac_eth_dev)); +- +- /* Map SRAM to EMAC */ +- setbits_le32(&sram->ctrl1, 0x5 << 2); +- +- /* Configure pin mux settings for MII Ethernet */ +- for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) +- sunxi_gpio_set_cfgpin(pin, 2); +- +- /* Set up clock gating */ +- setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); +- +- dev->iobase = SUNXI_EMAC_BASE; +- dev->priv = priv; +- dev->init = sunxi_wemac_eth_init; +- dev->halt = sunxi_wemac_eth_halt; +- dev->send = sunxi_wemac_eth_send; +- dev->recv = sunxi_wemac_eth_recv; +- strcpy(dev->name, "wemac"); +- +- eth_register(dev); +- +- miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); +- +- return 0; +-} +diff -ruN u-boot-2014.04/drivers/power/axp152.c u-boot-sunxi/drivers/power/axp152.c +--- u-boot-2014.04/drivers/power/axp152.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp152.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,112 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <common.h> ++#include <i2c.h> ++#include <axp152.h> ++ ++enum axp152_reg { ++ AXP152_CHIP_VERSION = 0x3, ++ AXP152_DCDC2_VOLTAGE = 0x23, ++ AXP152_DCDC3_VOLTAGE = 0x27, ++ AXP152_DCDC4_VOLTAGE = 0x2B, ++ AXP152_LDO2_VOLTAGE = 0x2A, ++ AXP152_SHUTDOWN = 0x32, ++}; ++ ++#define AXP152_POWEROFF (1 << 7) ++ ++static int axp152_write(enum axp152_reg reg, u8 val) ++{ ++ return i2c_write(0x30, reg, 1, &val, 1); ++} ++ ++static int axp152_read(enum axp152_reg reg, u8 *val) ++{ ++ return i2c_read(0x30, reg, 1, val, 1); ++} ++ ++static int axp152_mvolt_to_target(int mvolt, int min, int max, int div) ++{ ++ if (mvolt < min) ++ mvolt = min; ++ else if (mvolt > max) ++ mvolt = max; ++ ++ return (mvolt - min) / div; ++} ++ ++int axp152_set_dcdc2(int mvolt) ++{ ++ int rc, target; ++ u8 current; ++ ++ target = axp152_mvolt_to_target(mvolt, 700, 2275, 25); ++ ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != target) { ++ if (current < target) ++ current++; ++ else ++ current--; ++ rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ return rc; ++} ++ ++int axp152_set_dcdc3(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); ++ ++ return axp152_write(AXP152_DCDC3_VOLTAGE, target); ++} ++ ++int axp152_set_dcdc4(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); ++ ++ return axp152_write(AXP152_DCDC4_VOLTAGE, target); ++} ++ ++int axp152_set_ldo2(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 100); ++ ++ return axp152_write(AXP152_LDO2_VOLTAGE, target); ++} ++ ++void axp152_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp152_read(AXP152_SHUTDOWN, &val) != 0) ++ return; ++ ++ val |= AXP152_POWEROFF; ++ ++ if (axp152_write(AXP152_SHUTDOWN, val) != 0) ++ return; ++ ++ udelay(10000); /* wait for power to drain */ ++} ++ ++int axp152_init(void) ++{ ++ u8 ver; ++ int rc; ++ ++ rc = axp152_read(AXP152_CHIP_VERSION, &ver); ++ if (rc) ++ return rc; ++ ++ if (ver != 0x05) ++ return -1; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/power/axp209.c u-boot-sunxi/drivers/power/axp209.c +--- u-boot-2014.04/drivers/power/axp209.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp209.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,180 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <i2c.h> ++#include <axp209.h> ++ ++enum axp209_reg { ++ AXP209_POWER_STATUS = 0x00, ++ AXP209_CHIP_VERSION = 0x03, ++ AXP209_DCDC2_VOLTAGE = 0x23, ++ AXP209_DCDC3_VOLTAGE = 0x27, ++ AXP209_LDO24_VOLTAGE = 0x28, ++ AXP209_LDO3_VOLTAGE = 0x29, ++ AXP209_IRQ_STATUS5 = 0x4c, ++ AXP209_SHUTDOWN = 0x32, ++}; ++ ++#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) ++ ++#define AXP209_IRQ5_PEK_UP (1 << 6) ++#define AXP209_IRQ5_PEK_DOWN (1 << 5) ++ ++#define AXP209_POWEROFF (1 << 7) ++ ++static int axp209_write(enum axp209_reg reg, u8 val) ++{ ++ return i2c_write(0x34, reg, 1, &val, 1); ++} ++ ++static int axp209_read(enum axp209_reg reg, u8 *val) ++{ ++ return i2c_read(0x34, reg, 1, val, 1); ++} ++ ++static int axp209_mvolt_to_cfg(int mvolt, int min, int max, int div) ++{ ++ if (mvolt < min) ++ mvolt = min; ++ else if (mvolt > max) ++ mvolt = max; ++ ++ return (mvolt - min) / div; ++} ++ ++int axp209_set_dcdc2(int mvolt) ++{ ++ int cfg, rc; ++ u8 current; ++ ++ cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); ++ ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != cfg) { ++ if (current < cfg) ++ current++; ++ else ++ current--; ++ ++ rc = axp209_write(AXP209_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ ++ return rc; ++} ++ ++int axp209_set_dcdc3(int mvolt) ++{ ++ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25); ++ ++ return axp209_write(AXP209_DCDC3_VOLTAGE, cfg); ++} ++ ++int axp209_set_ldo2(int mvolt) ++{ ++ int rc, cfg; ++ u8 reg; ++ ++ cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100); ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ /* LDO2 configuration is in upper 4 bits */ ++ reg = (reg & 0x0f) | (cfg << 4); ++ return axp209_write(AXP209_LDO24_VOLTAGE, reg); ++} ++ ++int axp209_set_ldo3(int mvolt) ++{ ++ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); ++ ++ if (mvolt == -1) ++ cfg = 0x80; /* determined by LDO3IN pin */ ++ ++ return axp209_write(AXP209_LDO3_VOLTAGE, cfg); ++} ++ ++int axp209_set_ldo4(int mvolt) ++{ ++ int cfg, rc; ++ static const int vindex[] = { ++ 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500, ++ 2700, 2800, 3000, 3100, 3200, 3300 ++ }; ++ u8 reg; ++ ++ /* Translate mvolt to register cfg value, requested <= selected */ ++ for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--); ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ /* LDO4 configuration is in lower 4 bits */ ++ reg = (reg & 0xf0) | (cfg << 0); ++ return axp209_write(AXP209_LDO24_VOLTAGE, reg); ++} ++ ++void axp209_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp209_read(AXP209_SHUTDOWN, &val) != 0) ++ return; ++ ++ val |= AXP209_POWEROFF; ++ ++ if (axp209_write(AXP209_SHUTDOWN, val) != 0) ++ return; ++ ++ udelay(10000); /* wait for power to drain */ ++} ++ ++int axp209_init(void) ++{ ++ u8 ver; ++ int rc; ++ ++ rc = axp209_read(AXP209_CHIP_VERSION, &ver); ++ if (rc) ++ return rc; ++ ++ /* Low 4 bits is chip version */ ++ ver &= 0x0f; ++ ++ if (ver != 0x1) ++ return -1; ++ ++ return 0; ++} ++ ++int axp209_poweron_by_dc(void) ++{ ++ u8 v; ++ ++ if (axp209_read(AXP209_POWER_STATUS, &v)) ++ return 0; ++ ++ return (v & AXP209_POWER_STATUS_ON_BY_DC); ++} ++ ++int axp209_power_button(void) ++{ ++ u8 v; ++ ++ if (axp209_read(AXP209_IRQ_STATUS5, &v)) ++ return 0; ++ ++ axp209_write(AXP209_IRQ_STATUS5, AXP209_IRQ5_PEK_DOWN); ++ ++ return v & AXP209_IRQ5_PEK_DOWN; ++} +diff -ruN u-boot-2014.04/drivers/power/axp221.c u-boot-sunxi/drivers/power/axp221.c +--- u-boot-2014.04/drivers/power/axp221.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp221.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,73 @@ ++/* ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/arch/p2wi.h> ++#include <axp221.h> ++ ++int axp221_set_dcdc1(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC1_CTRL, (mvolt - 1600) / 100); ++} ++ ++int axp221_set_dcdc2(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC2_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc3(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC3_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc4(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC4_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc5(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC5_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dldo1(unsigned int mvolt) ++{ ++ int ret; ++ u8 val; ++ ++ ret = p2wi_write(AXP221_DLDO1_CTRL, (mvolt - 700) / 100); ++ if (ret) ++ return ret; ++ ++ ret = p2wi_read(AXP221_OUTPUT_CTRL2, &val); ++ if (ret) ++ return ret; ++ ++ val |= 1 << 3; ++ return p2wi_write(AXP221_OUTPUT_CTRL2, val); ++} ++ ++int axp221_init(void) ++{ ++ u8 axp_chip_id; ++ int ret; ++ ++ p2wi_init(); ++ ret = p2wi_set_pmu_address(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, ++ AXP221_INIT_DATA); ++ if (ret) ++ return ret; ++ ++ ret = p2wi_read(AXP221_CHIP_ID, &axp_chip_id); ++ if (ret) ++ return ret; ++ ++ if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17)) ++ return -ENODEV; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/power/Makefile u-boot-sunxi/drivers/power/Makefile +--- u-boot-2014.04/drivers/power/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/power/Makefile 2014-09-06 16:58:36.321953111 +0200 +@@ -5,6 +5,9 @@ + # SPDX-License-Identifier: GPL-2.0+ + # + ++obj-$(CONFIG_AXP152_POWER) += axp152.o ++obj-$(CONFIG_AXP209_POWER) += axp209.o ++obj-$(CONFIG_AXP221_POWER) += axp221.o + obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o + obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o + obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o +diff -ruN u-boot-2014.04/drivers/serial/arm_dcc.c u-boot-sunxi/drivers/serial/arm_dcc.c +--- u-boot-2014.04/drivers/serial/arm_dcc.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/serial/arm_dcc.c 2014-09-06 16:58:36.329953111 +0200 +@@ -29,7 +29,7 @@ + #include <common.h> + #include <serial.h> + +-#if defined(CONFIG_CPU_V6) ++#if defined(CONFIG_CPU_V6) || 1 + /* + * ARMV6 + */ +diff -ruN u-boot-2014.04/.git/config u-boot-sunxi/.git/config +--- u-boot-2014.04/.git/config 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/config 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1,11 @@ ++[core] ++ repositoryformatversion = 0 ++ filemode = true ++ bare = false ++ logallrefupdates = true ++[remote "origin"] ++ fetch = +refs/heads/*:refs/remotes/origin/* ++ url = https://github.com/linux-sunxi/u-boot-sunxi ++[branch "sunxi"] ++ remote = origin ++ merge = refs/heads/sunxi +diff -ruN u-boot-2014.04/.git/description u-boot-sunxi/.git/description +--- u-boot-2014.04/.git/description 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/description 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1 @@ ++Unnamed repository; edit this file 'description' to name the repository. +diff -ruN u-boot-2014.04/.git/HEAD u-boot-sunxi/.git/HEAD +--- u-boot-2014.04/.git/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++ref: refs/heads/sunxi +diff -ruN u-boot-2014.04/.git/hooks/applypatch-msg.sample u-boot-sunxi/.git/hooks/applypatch-msg.sample +--- u-boot-2014.04/.git/hooks/applypatch-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/applypatch-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,15 @@ ++#!/bin/sh ++# ++# An example hook script to check the commit log message taken by ++# applypatch from an e-mail message. ++# ++# The hook should exit with non-zero status after issuing an ++# appropriate message if it wants to stop the commit. The hook is ++# allowed to edit the commit message file. ++# ++# To enable this hook, rename this file to "applypatch-msg". ++ ++. git-sh-setup ++test -x "$GIT_DIR/hooks/commit-msg" && ++ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} ++: +diff -ruN u-boot-2014.04/.git/hooks/commit-msg.sample u-boot-sunxi/.git/hooks/commit-msg.sample +--- u-boot-2014.04/.git/hooks/commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/commit-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,24 @@ ++#!/bin/sh ++# ++# An example hook script to check the commit log message. ++# Called by "git commit" with one argument, the name of the file ++# that has the commit message. The hook should exit with non-zero ++# status after issuing an appropriate message if it wants to stop the ++# commit. The hook is allowed to edit the commit message file. ++# ++# To enable this hook, rename this file to "commit-msg". ++ ++# Uncomment the below to add a Signed-off-by line to the message. ++# Doing this in a hook is a bad idea in general, but the prepare-commit-msg ++# hook is more suited to it. ++# ++# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^(.*>).*$/Signed-off-by: \1/p') ++# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" ++ ++# This example catches duplicate Signed-off-by lines. ++ ++test "" = "$(grep '^Signed-off-by: ' "$1" | ++ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { ++ echo >&2 Duplicate Signed-off-by lines. ++ exit 1 ++} +diff -ruN u-boot-2014.04/.git/hooks/post-update.sample u-boot-sunxi/.git/hooks/post-update.sample +--- u-boot-2014.04/.git/hooks/post-update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/post-update.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,8 @@ ++#!/bin/sh ++# ++# An example hook script to prepare a packed repository for use over ++# dumb transports. ++# ++# To enable this hook, rename this file to "post-update". ++ ++exec git update-server-info +diff -ruN u-boot-2014.04/.git/hooks/pre-applypatch.sample u-boot-sunxi/.git/hooks/pre-applypatch.sample +--- u-boot-2014.04/.git/hooks/pre-applypatch.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-applypatch.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,14 @@ ++#!/bin/sh ++# ++# An example hook script to verify what is about to be committed ++# by applypatch from an e-mail message. ++# ++# The hook should exit with non-zero status after issuing an ++# appropriate message if it wants to stop the commit. ++# ++# To enable this hook, rename this file to "pre-applypatch". ++ ++. git-sh-setup ++test -x "$GIT_DIR/hooks/pre-commit" && ++ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} ++: +diff -ruN u-boot-2014.04/.git/hooks/pre-commit.sample u-boot-sunxi/.git/hooks/pre-commit.sample +--- u-boot-2014.04/.git/hooks/pre-commit.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-commit.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,50 @@ ++#!/bin/sh ++# ++# An example hook script to verify what is about to be committed. ++# Called by "git commit" with no arguments. The hook should ++# exit with non-zero status after issuing an appropriate message if ++# it wants to stop the commit. ++# ++# To enable this hook, rename this file to "pre-commit". ++ ++if git rev-parse --verify HEAD >/dev/null 2>&1 ++then ++ against=HEAD ++else ++ # Initial commit: diff against an empty tree object ++ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 ++fi ++ ++# If you want to allow non-ascii filenames set this variable to true. ++allownonascii=$(git config hooks.allownonascii) ++ ++# Redirect output to stderr. ++exec 1>&2 ++ ++# Cross platform projects tend to avoid non-ascii filenames; prevent ++# them from being added to the repository. We exploit the fact that the ++# printable range starts at the space character and ends with tilde. ++if [ "$allownonascii" != "true" ] && ++ # Note that the use of brackets around a tr range is ok here, (it's ++ # even required, for portability to Solaris 10's /usr/bin/tr), since ++ # the square bracket bytes happen to fall in the designated range. ++ test $(git diff --cached --name-only --diff-filter=A -z $against | ++ LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 ++then ++ echo "Error: Attempt to add a non-ascii file name." ++ echo ++ echo "This can cause problems if you want to work" ++ echo "with people on other platforms." ++ echo ++ echo "To be portable it is advisable to rename the file ..." ++ echo ++ echo "If you know what you are doing you can disable this" ++ echo "check using:" ++ echo ++ echo " git config hooks.allownonascii true" ++ echo ++ exit 1 ++fi ++ ++# If there are whitespace errors, print the offending file names and fail. ++exec git diff-index --check --cached $against -- +diff -ruN u-boot-2014.04/.git/hooks/prepare-commit-msg.sample u-boot-sunxi/.git/hooks/prepare-commit-msg.sample +--- u-boot-2014.04/.git/hooks/prepare-commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/prepare-commit-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,36 @@ ++#!/bin/sh ++# ++# An example hook script to prepare the commit log message. ++# Called by "git commit" with the name of the file that has the ++# commit message, followed by the description of the commit ++# message's source. The hook's purpose is to edit the commit ++# message file. If the hook fails with a non-zero status, ++# the commit is aborted. ++# ++# To enable this hook, rename this file to "prepare-commit-msg". ++ ++# This hook includes three examples. The first comments out the ++# "Conflicts:" part of a merge commit. ++# ++# The second includes the output of "git diff --name-status -r" ++# into the message, just before the "git status" output. It is ++# commented because it doesn't cope with --amend or with squashed ++# commits. ++# ++# The third example adds a Signed-off-by line to the message, that can ++# still be edited. This is rarely a good idea. ++ ++case "$2,$3" in ++ merge,) ++ /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; ++ ++# ,|template,) ++# /usr/bin/perl -i.bak -pe ' ++# print "\n" . `git diff --cached --name-status -r` ++# if /^#/ && $first++ == 0' "$1" ;; ++ ++ *) ;; ++esac ++ ++# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^(.*>).*$/Signed-off-by: \1/p') ++# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" +diff -ruN u-boot-2014.04/.git/hooks/pre-rebase.sample u-boot-sunxi/.git/hooks/pre-rebase.sample +--- u-boot-2014.04/.git/hooks/pre-rebase.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-rebase.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,169 @@ ++#!/bin/sh ++# ++# Copyright (c) 2006, 2008 Junio C Hamano ++# ++# The "pre-rebase" hook is run just before "git rebase" starts doing ++# its job, and can prevent the command from running by exiting with ++# non-zero status. ++# ++# The hook is called with the following parameters: ++# ++# $1 -- the upstream the series was forked from. ++# $2 -- the branch being rebased (or empty when rebasing the current branch). ++# ++# This sample shows how to prevent topic branches that are already ++# merged to 'next' branch from getting rebased, because allowing it ++# would result in rebasing already published history. ++ ++publish=next ++basebranch="$1" ++if test "$#" = 2 ++then ++ topic="refs/heads/$2" ++else ++ topic=`git symbolic-ref HEAD` || ++ exit 0 ;# we do not interrupt rebasing detached HEAD ++fi ++ ++case "$topic" in ++refs/heads/??/*) ++ ;; ++*) ++ exit 0 ;# we do not interrupt others. ++ ;; ++esac ++ ++# Now we are dealing with a topic branch being rebased ++# on top of master. Is it OK to rebase it? ++ ++# Does the topic really exist? ++git show-ref -q "$topic" || { ++ echo >&2 "No such branch $topic" ++ exit 1 ++} ++ ++# Is topic fully merged to master? ++not_in_master=`git rev-list --pretty=oneline ^master "$topic"` ++if test -z "$not_in_master" ++then ++ echo >&2 "$topic is fully merged to master; better remove it." ++ exit 1 ;# we could allow it, but there is no point. ++fi ++ ++# Is topic ever merged to next? If so you should not be rebasing it. ++only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` ++only_next_2=`git rev-list ^master ${publish} | sort` ++if test "$only_next_1" = "$only_next_2" ++then ++ not_in_topic=`git rev-list "^$topic" master` ++ if test -z "$not_in_topic" ++ then ++ echo >&2 "$topic is already up-to-date with master" ++ exit 1 ;# we could allow it, but there is no point. ++ else ++ exit 0 ++ fi ++else ++ not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` ++ /usr/bin/perl -e ' ++ my $topic = $ARGV[0]; ++ my $msg = "* $topic has commits already merged to public branch:\n"; ++ my (%not_in_next) = map { ++ /^([0-9a-f]+) /; ++ ($1 => 1); ++ } split(/\n/, $ARGV[1]); ++ for my $elem (map { ++ /^([0-9a-f]+) (.*)$/; ++ [$1 => $2]; ++ } split(/\n/, $ARGV[2])) { ++ if (!exists $not_in_next{$elem->[0]}) { ++ if ($msg) { ++ print STDERR $msg; ++ undef $msg; ++ } ++ print STDERR " $elem->[1]\n"; ++ } ++ } ++ ' "$topic" "$not_in_next" "$not_in_master" ++ exit 1 ++fi ++ ++<<\DOC_END ++ ++This sample hook safeguards topic branches that have been ++published from being rewound. ++ ++The workflow assumed here is: ++ ++ * Once a topic branch forks from "master", "master" is never ++ merged into it again (either directly or indirectly). ++ ++ * Once a topic branch is fully cooked and merged into "master", ++ it is deleted. If you need to build on top of it to correct ++ earlier mistakes, a new topic branch is created by forking at ++ the tip of the "master". This is not strictly necessary, but ++ it makes it easier to keep your history simple. ++ ++ * Whenever you need to test or publish your changes to topic ++ branches, merge them into "next" branch. ++ ++The script, being an example, hardcodes the publish branch name ++to be "next", but it is trivial to make it configurable via ++$GIT_DIR/config mechanism. ++ ++With this workflow, you would want to know: ++ ++(1) ... if a topic branch has ever been merged to "next". Young ++ topic branches can have stupid mistakes you would rather ++ clean up before publishing, and things that have not been ++ merged into other branches can be easily rebased without ++ affecting other people. But once it is published, you would ++ not want to rewind it. ++ ++(2) ... if a topic branch has been fully merged to "master". ++ Then you can delete it. More importantly, you should not ++ build on top of it -- other people may already want to ++ change things related to the topic as patches against your ++ "master", so if you need further changes, it is better to ++ fork the topic (perhaps with the same name) afresh from the ++ tip of "master". ++ ++Let's look at this example: ++ ++ o---o---o---o---o---o---o---o---o---o "next" ++ / / / / ++ / a---a---b A / / ++ / / / / ++ / / c---c---c---c B / ++ / / / \ / ++ / / / b---b C \ / ++ / / / / \ / ++ ---o---o---o---o---o---o---o---o---o---o---o "master" ++ ++ ++A, B and C are topic branches. ++ ++ * A has one fix since it was merged up to "next". ++ ++ * B has finished. It has been fully merged up to "master" and "next", ++ and is ready to be deleted. ++ ++ * C has not merged to "next" at all. ++ ++We would want to allow C to be rebased, refuse A, and encourage ++B to be deleted. ++ ++To compute (1): ++ ++ git rev-list ^master ^topic next ++ git rev-list ^master next ++ ++ if these match, topic has not merged in next at all. ++ ++To compute (2): ++ ++ git rev-list master..topic ++ ++ if this is empty, it is fully merged to "master". ++ ++DOC_END +diff -ruN u-boot-2014.04/.git/hooks/update.sample u-boot-sunxi/.git/hooks/update.sample +--- u-boot-2014.04/.git/hooks/update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/update.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,128 @@ ++#!/bin/sh ++# ++# An example hook script to blocks unannotated tags from entering. ++# Called by "git receive-pack" with arguments: refname sha1-old sha1-new ++# ++# To enable this hook, rename this file to "update". ++# ++# Config ++# ------ ++# hooks.allowunannotated ++# This boolean sets whether unannotated tags will be allowed into the ++# repository. By default they won't be. ++# hooks.allowdeletetag ++# This boolean sets whether deleting tags will be allowed in the ++# repository. By default they won't be. ++# hooks.allowmodifytag ++# This boolean sets whether a tag may be modified after creation. By default ++# it won't be. ++# hooks.allowdeletebranch ++# This boolean sets whether deleting branches will be allowed in the ++# repository. By default they won't be. ++# hooks.denycreatebranch ++# This boolean sets whether remotely creating branches will be denied ++# in the repository. By default this is allowed. ++# ++ ++# --- Command line ++refname="$1" ++oldrev="$2" ++newrev="$3" ++ ++# --- Safety check ++if [ -z "$GIT_DIR" ]; then ++ echo "Don't run this script from the command line." >&2 ++ echo " (if you want, you could supply GIT_DIR then run" >&2 ++ echo " $0 <ref> <oldrev> <newrev>)" >&2 ++ exit 1 ++fi ++ ++if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then ++ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2 ++ exit 1 ++fi ++ ++# --- Config ++allowunannotated=$(git config --bool hooks.allowunannotated) ++allowdeletebranch=$(git config --bool hooks.allowdeletebranch) ++denycreatebranch=$(git config --bool hooks.denycreatebranch) ++allowdeletetag=$(git config --bool hooks.allowdeletetag) ++allowmodifytag=$(git config --bool hooks.allowmodifytag) ++ ++# check for no description ++projectdesc=$(sed -e '1q' "$GIT_DIR/description") ++case "$projectdesc" in ++"Unnamed repository"* | "") ++ echo "*** Project description file hasn't been set" >&2 ++ exit 1 ++ ;; ++esac ++ ++# --- Check types ++# if $newrev is 0000...0000, it's a commit to delete a ref. ++zero="0000000000000000000000000000000000000000" ++if [ "$newrev" = "$zero" ]; then ++ newrev_type=delete ++else ++ newrev_type=$(git cat-file -t $newrev) ++fi ++ ++case "$refname","$newrev_type" in ++ refs/tags/*,commit) ++ # un-annotated tag ++ short_refname=${refname##refs/tags/} ++ if [ "$allowunannotated" != "true" ]; then ++ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 ++ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 ++ exit 1 ++ fi ++ ;; ++ refs/tags/*,delete) ++ # delete tag ++ if [ "$allowdeletetag" != "true" ]; then ++ echo "*** Deleting a tag is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/tags/*,tag) ++ # annotated tag ++ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 ++ then ++ echo "*** Tag '$refname' already exists." >&2 ++ echo "*** Modifying a tag is not allowed in this repository." >&2 ++ exit 1 ++ fi ++ ;; ++ refs/heads/*,commit) ++ # branch ++ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then ++ echo "*** Creating a branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/heads/*,delete) ++ # delete branch ++ if [ "$allowdeletebranch" != "true" ]; then ++ echo "*** Deleting a branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/remotes/*,commit) ++ # tracking branch ++ ;; ++ refs/remotes/*,delete) ++ # delete tracking branch ++ if [ "$allowdeletebranch" != "true" ]; then ++ echo "*** Deleting a tracking branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ *) ++ # Anything else (is there anything else?) ++ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 ++ exit 1 ++ ;; ++esac ++ ++# --- Finished ++exit 0 +Binary files u-boot-2014.04/.git/index and u-boot-sunxi/.git/index differ +diff -ruN u-boot-2014.04/.git/info/exclude u-boot-sunxi/.git/info/exclude +--- u-boot-2014.04/.git/info/exclude 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/info/exclude 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,6 @@ ++# git ls-files --others --exclude-from=.git/info/exclude ++# Lines that start with '#' are comments. ++# For a project mostly in C, the following would be a good set of ++# exclude patterns (uncomment them if you want to use them): ++# *.[oa] ++# *~ +diff -ruN u-boot-2014.04/.git/logs/HEAD u-boot-sunxi/.git/logs/HEAD +--- u-boot-2014.04/.git/logs/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +diff -ruN u-boot-2014.04/.git/logs/refs/heads/sunxi u-boot-sunxi/.git/logs/refs/heads/sunxi +--- u-boot-2014.04/.git/logs/refs/heads/sunxi 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/heads/sunxi 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +diff -ruN u-boot-2014.04/.git/logs/refs/remotes/origin/HEAD u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD +--- u-boot-2014.04/.git/logs/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +Binary files u-boot-2014.04/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.idx and u-boot-sunxi/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.idx differ +Binary files u-boot-2014.04/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.pack and u-boot-sunxi/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.pack differ +diff -ruN u-boot-2014.04/.git/packed-refs u-boot-sunxi/.git/packed-refs +--- u-boot-2014.04/.git/packed-refs 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/packed-refs 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1,25 @@ ++# pack-refs with: peeled ++3212c6fd4beaa14a21a57e5241022702c986f82e refs/remotes/origin/lichee-dev ++c0860ba179bc0cf016831ceeeacd0dd4e287a860 refs/remotes/origin/lichee-dev-a20 ++1076d3bdd67db39f34bc91857c636525874441ae refs/remotes/origin/lichee/lichee-dev ++40b4fba701c1824cc60c7ab966f4a5dd674e947d refs/remotes/origin/lichee/lichee-dev-ICS ++cf54463fd782c690cf790ca35b5a15504b57c287 refs/remotes/origin/lichee/lichee-dev-mmc ++218f643881c0dabd7e40cdb21a757416fa80afb2 refs/remotes/origin/old/sunxi-current ++509d96d4f1f602d62d36db660973249e16f9d088 refs/remotes/origin/sunxi ++43fb1236c3330676f49220cc1dfc235eb0558e4c refs/remotes/origin/sunxi-patchqueue ++80fd9a5c5b87ba2f48f4a71b666839870e780be6 refs/remotes/origin/wip/a20 ++27113637710a574d1fb6325817ffa9ced7afe019 refs/tags/v2011.09-sun4i ++^22b38fa5c0348ac4f285f038999f9a617f98e73a ++9ba56441491542cd06b30c514e544d96b29ef801 refs/tags/v2011.09-sun4i-20120808 ++88eacf3372855579760ba6bc8fa3e0d4e53fdef8 refs/tags/v2012.10-sunxi ++1ae18d97d24c5d6dd4cb7949d8e5fb602728601c refs/tags/v2013.01-sunxi ++fc40799c144d035c595c4abe3032a03be8f0e2c4 refs/tags/v2013.01.01-sunxi ++90c8c0c88362d1e39bb1433f04b9a21bb1c74e45 refs/tags/v2013.04-sunxi ++57ff4519ba0f47f1647f7def5864ae4c9ef3e6a0 refs/tags/v2013.07-rc1-sunxi ++c416374795b584f025a80b1f81db215456567155 refs/tags/v2013.07-sunxi ++8969c6f654248ececdfcf05eb51de9a8bc0a8703 refs/tags/v2013.07-sunxi.2 ++88b1df7ee9c15c821a2209791f513b21596f21b4 refs/tags/v2013.07-sunxi.3 ++569c37da7dfd4ed93b6e8b5993df760b9ed18c8d refs/tags/v2013.07-sunxi.4 ++7a63a6882876b76e47746c1254e8cd1120a52b0d refs/tags/v2013.10-rc1-sunxi ++951e509384822e39149c22f44cde6a01f5105c40 refs/tags/v2013.10-rc2-sunxi ++09ef3a640a3eb58e66eedcf239193e2ab548e730 refs/tags/v2013.10-sunxi +diff -ruN u-boot-2014.04/.git/refs/heads/sunxi u-boot-sunxi/.git/refs/heads/sunxi +--- u-boot-2014.04/.git/refs/heads/sunxi 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/heads/sunxi 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++509d96d4f1f602d62d36db660973249e16f9d088 +diff -ruN u-boot-2014.04/.git/refs/remotes/origin/HEAD u-boot-sunxi/.git/refs/remotes/origin/HEAD +--- u-boot-2014.04/.git/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/remotes/origin/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++ref: refs/remotes/origin/sunxi +diff -ruN u-boot-2014.04/include/axp152.h u-boot-sunxi/include/axp152.h +--- u-boot-2014.04/include/axp152.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp152.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++int axp152_set_dcdc2(int mvolt); ++int axp152_set_dcdc3(int mvolt); ++int axp152_set_dcdc4(int mvolt); ++int axp152_set_ldo2(int mvolt); ++void axp152_poweroff(void); ++int axp152_init(void); +diff -ruN u-boot-2014.04/include/axp209.h u-boot-sunxi/include/axp209.h +--- u-boot-2014.04/include/axp209.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp209.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++extern int axp209_set_dcdc2(int mvolt); ++extern int axp209_set_dcdc3(int mvolt); ++extern int axp209_set_ldo2(int mvolt); ++extern int axp209_set_ldo3(int mvolt); ++extern int axp209_set_ldo4(int mvolt); ++extern void axp209_poweroff(void); ++extern int axp209_init(void); ++extern int axp209_poweron_by_dc(void); ++extern int axp209_power_button(void); +diff -ruN u-boot-2014.04/include/axp221.h u-boot-sunxi/include/axp221.h +--- u-boot-2014.04/include/axp221.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp221.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * ++ * X-Powers AXP221 Power Management IC driver ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define AXP221_CHIP_ADDR 0x68 ++#define AXP221_CTRL_ADDR 0x3e ++#define AXP221_INIT_DATA 0x3e ++ ++#define AXP221_CHIP_ID 0x03 ++#define AXP221_OUTPUT_CTRL1 0x10 ++#define AXP221_OUTPUT_CTRL2 0x12 ++#define AXP221_OUTPUT_CTRL3 0x13 ++#define AXP221_DLDO1_CTRL 0x15 ++#define AXP221_DCDC1_CTRL 0x21 ++#define AXP221_DCDC2_CTRL 0x22 ++#define AXP221_DCDC3_CTRL 0x23 ++#define AXP221_DCDC4_CTRL 0x24 ++#define AXP221_DCDC5_CTRL 0x25 ++ ++int axp221_set_dcdc1(unsigned int mvolt); ++int axp221_set_dcdc2(unsigned int mvolt); ++int axp221_set_dcdc3(unsigned int mvolt); ++int axp221_set_dcdc4(unsigned int mvolt); ++int axp221_set_dcdc5(unsigned int mvolt); ++int axp221_set_dldo1(unsigned int mvolt); ++int axp221_init(void); +diff -ruN u-boot-2014.04/include/config_fallbacks.h u-boot-sunxi/include/config_fallbacks.h +--- u-boot-2014.04/include/config_fallbacks.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/include/config_fallbacks.h 2014-09-06 16:58:36.401953108 +0200 +@@ -55,6 +55,10 @@ + #define HAVE_BLOCK_DEVICE + #endif + ++#ifndef CONFIG_SYS_BOARD_NAME ++#define CONFIG_SYS_BOARD_NAME CONFIG_SYS_TARGET ++#endif ++ + #if (defined(CONFIG_PARTITION_UUIDS) || \ + defined(CONFIG_EFI_PARTITION) || \ + defined(CONFIG_RANDOM_UUID) || \ +diff -ruN u-boot-2014.04/include/configs/sun4i.h u-boot-sunxi/include/configs/sun4i.h +--- u-boot-2014.04/include/configs/sun4i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun4i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Configuration settings for the Allwinner A10 (sun4i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A10 specific configuration ++ */ ++#define CONFIG_SUN4I /* sun4i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 1008000000 ++ ++#define CONFIG_SYS_PROMPT "sun4i# " ++#define CONFIG_MACH_TYPE 4104 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun5i.h u-boot-sunxi/include/configs/sun5i.h +--- u-boot-2014.04/include/configs/sun5i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun5i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Configuration settings for the Allwinner A13 (sun5i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_SUN5I /* sun5i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 1008000000 ++ ++#define CONFIG_SYS_PROMPT "sun5i# " ++#define CONFIG_MACH_TYPE 4138 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun6i.h u-boot-sunxi/include/configs/sun6i.h +--- u-boot-2014.04/include/configs/sun6i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun6i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,43 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * (C) Copyright 2013 Maxime Ripard maxime.ripard@free-electrons.com ++ * ++ * Configuration settings for the Allwinner A31 (sun6i) CPU ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A31 specific configuration ++ */ ++#define CONFIG_SUN6I /* sun6i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun6i# " ++#define CONFIG_MACH_TYPE 3892 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun7i.h u-boot-sunxi/include/configs/sun7i.h +--- u-boot-2014.04/include/configs/sun7i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun7i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * Configuration settings for the Allwinner A20 (sun7i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A20 specific configuration ++ */ ++#define CONFIG_SUN7I /* sun7i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 912000000 ++ ++#define CONFIG_SYS_PROMPT "sun7i# " ++#define CONFIG_MACH_TYPE 4283 ++ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#define CONFIG_BOARD_POSTCLK_INIT 1 ++#endif ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun8i.h u-boot-sunxi/include/configs/sun8i.h +--- u-boot-2014.04/include/configs/sun8i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun8i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,28 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * (C) Copyright 2013 Maxime Ripard maxime.ripard@free-electrons.com ++ * (C) Copyright 2014 Chen-Yu Tsai wens@csie.org ++ * ++ * Configuration settings for the Allwinner A23 (sun8i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A23 specific configuration ++ */ ++#define CONFIG_SUN8I /* sun8i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun8i# " ++#define CONFIG_MACH_TYPE 4137 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sunxi-common.h u-boot-sunxi/include/configs/sunxi-common.h +--- u-boot-2014.04/include/configs/sunxi-common.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sunxi-common.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,427 @@ ++/* ++ * (C) Copyright 2012-2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Configuration settings for the Allwinner sunxi series of boards. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_COMMON_CONFIG_H ++#define _SUNXI_COMMON_CONFIG_H ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_SUNXI /* sunxi family */ ++#ifdef CONFIG_SPL_BUILD ++#ifndef CONFIG_SPL_FEL ++#define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */ ++#endif ++#endif ++ ++#include <asm/arch/cpu.h> /* get chip and board defs */ ++ ++#define CONFIG_SYS_TEXT_BASE 0x4a000000 ++ ++/* ++ * Display CPU and Board information ++ */ ++#define CONFIG_DISPLAY_CPUINFO ++#define CONFIG_DISPLAY_BOARDINFO ++ ++/* Serial & console */ ++#define CONFIG_SYS_NS16550 ++#define CONFIG_SYS_NS16550_SERIAL ++/* ns16550 reg in the low bits of cpu reg */ ++#define CONFIG_SYS_NS16550_REG_SIZE -4 ++#define CONFIG_SYS_NS16550_CLK 24000000 ++#define CONFIG_SYS_NS16550_COM1 SUNXI_UART0_BASE ++#define CONFIG_SYS_NS16550_COM2 SUNXI_UART1_BASE ++#define CONFIG_SYS_NS16550_COM3 SUNXI_UART2_BASE ++#define CONFIG_SYS_NS16550_COM4 SUNXI_UART3_BASE ++#define CONFIG_SYS_NS16550_COM5 SUNXI_R_UART_BASE ++ ++/* DRAM Base */ ++#define CONFIG_SYS_SDRAM_BASE 0x40000000 ++#define CONFIG_SYS_INIT_RAM_ADDR 0x0 ++#define CONFIG_SYS_INIT_RAM_SIZE 0x8000 /* 32 KiB */ ++ ++#define CONFIG_SYS_INIT_SP_OFFSET \ ++ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) ++#define CONFIG_SYS_INIT_SP_ADDR \ ++ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) ++ ++/* A10 has 1 banks of DRAM, we use only bank 1 in U-Boot */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN7I) ++#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ ++#else ++#define PHYS_SDRAM_0_SIZE 0x40000000 /* 1 GiB */ ++#endif ++#if 0 ++/* Nand config */ ++#define CONFIG_NAND ++#define CONFIG_NAND_SUNXI ++#define CONFIG_CMD_NAND /* NAND support */ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++#define CONFIG_SYS_NAND_BASE 0x00 ++#endif ++ ++#define CONFIG_CMD_MEMORY ++#define CONFIG_CMD_SETEXPR ++ ++#define CONFIG_SETUP_MEMORY_TAGS ++#define CONFIG_CMDLINE_TAG ++#define CONFIG_INITRD_TAG ++ ++/* mmc config */ ++/* Can't use MMC slot 0 if the UART is directed there */ ++#if !defined CONFIG_UART0_PORT_F || CONFIG_MMC_SUNXI_SLOT != 0 ++#define CONFIG_MMC ++#define CONFIG_GENERIC_MMC ++#define CONFIG_CMD_MMC ++#define CONFIG_MMC_SUNXI ++#ifndef CONFIG_MMC_SUNXI_SLOT ++#define CONFIG_MMC_SUNXI_SLOT 0 ++#endif ++#define CONFIG_ENV_IS_IN_MMC ++#define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ ++#endif ++ ++/* 4MB of malloc() pool */ ++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (4 << 20)) ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CONFIG_CMD_ECHO ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ ++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ ++#define CONFIG_SYS_GENERIC_BOARD ++ ++/* Boot Argument Buffer Size */ ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ ++#define CONFIG_SYS_LOAD_ADDR 0x48000000 /* default load address */ ++ ++/* standalone support */ ++#define CONFIG_STANDALONE_LOAD_ADDR 0x48000000 ++ ++#define CONFIG_SYS_HZ 1000 ++ ++/* baudrate */ ++#define CONFIG_BAUDRATE 115200 ++ ++/* The stack sizes are set up in start.S using the settings below */ ++#define CONFIG_STACKSIZE (256 << 10) /* 256 KiB */ ++ ++/* FLASH and environment organization */ ++ ++#define CONFIG_SYS_NO_FLASH ++ ++#define CONFIG_SYS_MONITOR_LEN (512 << 10) /* 512 KiB */ ++#define CONFIG_IDENT_STRING " Allwinner Technology" ++ ++#define CONFIG_ENV_OFFSET (544 << 10) /* (8 + 24 + 512) KiB */ ++#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ ++ ++#ifdef CONFIG_SPL_FEL ++#define RUN_BOOT_RAM "run boot_ram;" ++#else ++#define RUN_BOOT_RAM "" ++#endif ++ ++#define CONFIG_BOOTCOMMAND \ ++ RUN_BOOT_RAM \ ++ "if run loadbootenv; then " \ ++ "echo Loaded environment from ${bootenv};" \ ++ "env import -t ${scriptaddr} ${filesize};" \ ++ "fi;" \ ++ "if test -n \"${uenvcmd}\"; then " \ ++ "echo Running uenvcmd ...;" \ ++ "run uenvcmd;" \ ++ "fi;" \ ++ "if run loadbootscr; then "\ ++ "echo Jumping to ${bootscr};" \ ++ "source ${scriptaddr};" \ ++ "fi;" \ ++ "run autoboot;" \ ++ "" ++ ++#ifdef CONFIG_CMD_WATCHDOG ++#define RESET_WATCHDOG "watchdog 0" ++#else ++#define RESET_WATCHDOG "true" ++#endif ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "bootm_size=0x10000000\0" \ ++ "console=ttyS0,115200\0" \ ++ "panicarg=panic=10\0" \ ++ "extraargs=\0" \ ++ "loglevel=8\0" \ ++ "scriptaddr=0x44000000\0" \ ++ "device=mmc\0" \ ++ "partition=0:1\0" \ ++ "setargs=" \ ++ "if test -z \\"$root\\"; then"\ ++ " if test \\"$bootpath\\" = "/boot/"; then"\ ++ " root="/dev/mmcblk0p1 rootwait";"\ ++ " else" \ ++ " root="/dev/mmcblk0p2 rootwait";"\ ++ " fi;"\ ++ " fi;"\ ++ " setenv bootargs console=${console} root=${root}" \ ++ " loglevel=${loglevel} ${panicarg} ${extraargs}" \ ++ "\0" \ ++ "kernel=uImage\0" \ ++ "bootenv=uEnv.txt\0" \ ++ "bootscr=boot.scr\0" \ ++ "script=script.bin\0" \ ++ "loadbootscr=" \ ++ "fatload $device $partition $scriptaddr ${bootscr}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr boot/${bootscr}" \ ++ " ||" \ ++ "ext2load $device $partition $scriptaddr ${bootscr}" \ ++ "\0" \ ++ "loadbootenv=" \ ++ "fatload $device $partition $scriptaddr ${bootenv}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr boot/${bootenv}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr ${bootenv}" \ ++ "\0" \ ++ "loadkernel=" \ ++ "if "\ ++ "bootpath=/boot/" \ ++ " && " \ ++ "ext2load $device $partition 0x43000000 ${bootpath}${script}" \ ++ " && " \ ++ "ext2load $device $partition 0x48000000 ${bootpath}${kernel}" \ ++ ";then true; elif " \ ++ "bootpath=/" \ ++ " && " \ ++ "fatload $device $partition 0x43000000 ${script}" \ ++ " && " \ ++ "fatload $device $partition 0x48000000 ${kernel}" \ ++ ";then true; elif " \ ++ "bootpath=/" \ ++ " && " \ ++ "ext2load $device $partition 0x43000000 ${bootpath}${script}" \ ++ " && " \ ++ "ext2load $device $partition 0x48000000 ${bootpath}${kernel}" \ ++ ";then true; else "\ ++ "false" \ ++ ";fi" \ ++ "\0" \ ++ "autoboot=" \ ++ "run loadkernel" \ ++ " && " \ ++ "run setargs" \ ++ " && " \ ++ RESET_WATCHDOG \ ++ " && " \ ++ "bootm 0x48000000" \ ++ "\0" \ ++ "boot_ram=" \ ++ "saved_stdout=$stdout;setenv stdout nc;"\ ++ "if iminfo 0x41000000; then" \ ++ " " RESET_WATCHDOG ";"\ ++ " setenv stdout $saved_stdout;" \ ++ " source 0x41000000;" \ ++ "else" \ ++ " setenv stdout $saved_stdout;" \ ++ "fi" \ ++ "\0" \ ++ "" ++ ++#define CONFIG_SYS_BOOT_GET_CMDLINE ++ ++#include <config_cmd_default.h> ++ ++#define CONFIG_FAT_WRITE /* enable write access */ ++ ++#define CONFIG_SPL_FRAMEWORK ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#define CONFIG_SPL_SERIAL_SUPPORT ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_DISPLAY_PRINT ++ ++/* Falcon boot mode support */ ++/* Disabled by default on sun4i/sun7i. Many GCC versions produces a too ++ * large SPL for A10/A20 with this on. sun5i however accepts a much larger ++ * SPL ++ */ ++#if defined( CONFIG_SUN5I ) || defined ( CONFIG_SYS_THUMB_BUILD ) ++#define CONFIG_SPL_OS_BOOT ++#endif ++ ++#ifdef CONFIG_SPL_FEL ++ ++#define CONFIG_SPL ++#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds" ++#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi" ++#define CONFIG_SPL_TEXT_BASE 0x2000 ++#define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */ ++ ++#else /* CONFIG_SPL */ ++ ++#define CONFIG_SPL_BSS_START_ADDR 0x4ff80000 ++#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KiB */ ++ ++#define CONFIG_SPL_TEXT_BASE 0x20 /* sram start+header */ ++#ifdef CONFIG_SUN5I ++#define CONFIG_SPL_MAX_SIZE 0x75e0 /* 7748+ is used */ ++#else ++#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* 24KB on sun4i/sun7i */ ++#endif ++ ++#define CONFIG_SPL_LIBDISK_SUPPORT ++#define CONFIG_SPL_MMC_SUPPORT ++ ++#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" ++ ++#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 80 /* 40KiB */ ++#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */ ++ ++#endif /* CONFIG_SPL */ ++/* end of 32 KiB in sram */ ++#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ ++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK ++#define CONFIG_SYS_SPL_MALLOC_START 0x4ff00000 ++#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00080000 /* 512 KiB */ ++ ++#ifdef CONFIG_SPL_OS_BOOT ++#define CONFIG_CMD_SPL ++#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_0 + 0x100) ++#ifdef CONFIG_SPL_MMC_SUPPORT ++#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 1344 ++#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 256 ++#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 1600 ++#endif ++#endif ++ ++#undef CONFIG_CMD_FPGA ++#undef CONFIG_CMD_NET ++#undef CONFIG_CMD_NFS ++ ++/* I2C */ ++#if !defined CONFIG_SUN6I && !defined CONFIG_SUN8I ++#define CONFIG_SPL_I2C_SUPPORT ++#endif ++/* No CONFIG_SYS_I2C as we use the non converted mvtwsi driver */ ++#define CONFIG_HARD_I2C ++#define CONFIG_SYS_I2C_SUNXI ++#define CONFIG_SYS_I2C_SPEED 400000 ++#define CONFIG_SYS_I2C_SLAVE 0x7f ++#define CONFIG_CMD_I2C ++ ++/* Watchdog */ ++#if 0 ++#define CONFIG_WATCHDOG /* automatic watchdog support */ ++#define CONFIG_CMD_WATCHDOG /* watchdog command setting the watchdog timeout */ ++#endif ++ ++/* GPIO */ ++#define CONFIG_SUNXI_GPIO ++#define CONFIG_CMD_GPIO ++ ++/* PMU */ ++#if !defined CONFIG_AXP152_POWER && !defined CONFIG_AXP221_POWER && !defined CONFIG_NO_AXP ++#define CONFIG_AXP209_POWER ++#endif ++#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || defined CONFIG_AXP221_POWER ++#define CONFIG_SPL_POWER_SUPPORT ++#endif ++ ++#ifdef CONFIG_STATUSLED ++#define STATUS_LED_BIT CONFIG_STATUSLED ++#endif ++#ifdef CONFIG_STATUSLED1 ++#define STATUS_LED_BIT1 CONFIG_STATUSLED1 ++#endif ++#ifdef CONFIG_STATUSLED2 ++#define STATUS_LED_BIT2 CONFIG_STATUSLED2 ++#endif ++#ifdef CONFIG_STATUSLED3 ++#define STATUS_LED_BIT3 CONFIG_STATUSLED3 ++#endif ++ ++#ifndef CONFIG_SPL_BUILD ++#ifdef STATUS_LED_BIT ++#define CONFIG_GPIO_LED ++#define CONFIG_STATUS_LED ++#ifndef STATUS_LED_BOOT ++#define STATUS_LED_BOOT 0 ++#endif ++#ifndef STATUS_LED_STATE ++#define STATUS_LED_STATE STATUS_LED_ON ++#define STATUS_LED_PERIOD 1 ++#endif ++#ifndef STATUS_LED_STATE1 ++#define STATUS_LED_STATE1 STATUS_LED_OFF ++#define STATUS_LED_PERIOD1 1 ++#endif ++#ifndef STATUS_LED_STATE2 ++#define STATUS_LED_STATE2 STATUS_LED_OFF ++#define STATUS_LED_PERIOD2 1 ++#endif ++#ifndef STATUS_LED_STATE3 ++#define STATUS_LED_STATE3 STATUS_LED_OFF ++#define STATUS_LED_PERIOD3 1 ++#endif ++#define CONFIG_BOARD_SPECIFIC_LED ++#define CONFIG_CMD_LED ++#endif ++#endif ++ ++/* Define this to have serial channel 1 (UART0) redirected to SD port */ ++/* #define CONFIG_UART0_PORT_F */ ++ ++#ifndef CONFIG_CONS_INDEX ++#define CONFIG_CONS_INDEX 1 /* UART0 */ ++#endif ++ ++/* Ethernet support */ ++#ifdef CONFIG_SUNXI_EMAC ++#define CONFIG_MII /* MII PHY management */ ++#endif ++ ++#ifdef CONFIG_SUNXI_GMAC ++#define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ ++#define CONFIG_DW_AUTONEG ++#define CONFIG_PHY_GIGE /* GMAC can use gigabit PHY */ ++#define CONFIG_PHY_ADDR 1 ++#define CONFIG_MII /* MII PHY management */ ++#define CONFIG_PHYLIB ++#endif ++ ++#ifdef CONFIG_CMD_NET ++#define CONFIG_CMD_NFS ++#define CONFIG_CMD_DNS ++#define CONFIG_NETCONSOLE ++#define CONFIG_BOOTP_DNS2 ++#define CONFIG_BOOTP_SEND_HOSTNAME ++#endif ++ ++#if !defined CONFIG_ENV_IS_IN_MMC && \ ++ !defined CONFIG_ENV_IS_IN_NAND && \ ++ !defined CONFIG_ENV_IS_IN_FAT && \ ++ !defined CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_MISC_INIT_R ++ ++#ifndef CONFIG_SPL_BUILD ++#include <config_distro_defaults.h> ++#endif ++ ++#endif /* _SUNXI_COMMON_CONFIG_H */ +diff -ruN u-boot-2014.04/include/netdev.h u-boot-sunxi/include/netdev.h +--- u-boot-2014.04/include/netdev.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/include/netdev.h 2014-09-06 16:58:36.485953106 +0200 +@@ -79,7 +79,8 @@ + int skge_initialize(bd_t *bis); + int smc91111_initialize(u8 dev_num, int base_addr); + int smc911x_initialize(u8 dev_num, int base_addr); +-int sunxi_wemac_initialize(bd_t *bis); ++int sunxi_emac_initialize(bd_t *bis); ++int sunxi_gmac_initialize(bd_t *bis); + int tsi108_eth_initialize(bd_t *bis); + int uec_standard_init(bd_t *bis); + int uli526x_initialize(bd_t *bis); +diff -ruN u-boot-2014.04/Makefile u-boot-sunxi/Makefile +--- u-boot-2014.04/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/Makefile 2014-09-06 16:58:35.065953148 +0200 +@@ -870,6 +870,13 @@ + u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE + $(call if_changed,pad_cat) + ++ifneq ($(CONFIG_SUNXI),) ++OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \ ++ --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff ++u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE ++ $(call if_changed,pad_cat) ++endif ++ + ifneq ($(CONFIG_TEGRA),) + OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE) + u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE +@@ -1081,6 +1088,9 @@ + spl/u-boot-spl: tools prepare + $(Q)$(MAKE) obj=spl -f $(srctree)/spl/Makefile all + ++spl/sunxi-spl.bin: spl/u-boot-spl ++ @: ++ + tpl/u-boot-tpl.bin: tools prepare + $(Q)$(MAKE) obj=tpl -f $(srctree)/spl/Makefile all CONFIG_TPL_BUILD=y + +diff -ruN u-boot-2014.04/mkconfig u-boot-sunxi/mkconfig +--- u-boot-2014.04/mkconfig 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/mkconfig 2014-09-06 16:58:36.509953105 +0200 +@@ -174,6 +174,7 @@ + echo "#define CONFIG_SYS_ARCH "${arch}"" >> config.h + echo "#define CONFIG_SYS_CPU "${cpu}"" >> config.h + echo "#define CONFIG_SYS_BOARD "${board}"" >> config.h ++echo "#define CONFIG_SYS_TARGET "${BOARD_NAME}"" >> config.h + + [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR "${vendor}"" >> config.h + +diff -ruN u-boot-2014.04/snapshot.commit u-boot-sunxi/snapshot.commit +--- u-boot-2014.04/snapshot.commit 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/snapshot.commit 2014-09-06 16:58:36.521953105 +0200 +@@ -1 +1 @@ +-dda0dbfc69f3d560c87f5be85f127ed862ea6721 Mon, 14 Apr 2014 15:19:24 -0400 ++$Format:%H %cD$ +diff -ruN u-boot-2014.04/spl/Makefile u-boot-sunxi/spl/Makefile +--- u-boot-2014.04/spl/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/spl/Makefile 2014-09-06 16:58:36.521953105 +0200 +@@ -188,6 +188,12 @@ + ALL-y += $(obj)/$(BOARD)-spl.bin + endif + ++ifdef CONFIG_SUNXI ++ifndef CONFIG_SPL_FEL ++ALL-y += $(obj)/sunxi-spl.bin ++endif ++endif ++ + all: $(ALL-y) + + ifdef CONFIG_SAMSUNG +@@ -215,6 +221,13 @@ + LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE) + endif + ++ifdef CONFIG_SUNXI ++quiet_cmd_mksunxiboot = MKSUNXI $@ ++cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ ++$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin ++ $(call if_changed,mksunxiboot) ++endif ++ + quiet_cmd_u-boot-spl = LD $@ + cmd_u-boot-spl = cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \ +diff -ruN u-boot-2014.04/tools/.gitignore u-boot-sunxi/tools/.gitignore +--- u-boot-2014.04/tools/.gitignore 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/tools/.gitignore 2014-09-06 16:58:36.521953105 +0200 +@@ -9,6 +9,7 @@ + /mkexynosspl + /mpc86x_clk + /mxsboot ++/mksunxiboot + /ncb + /proftool + /relocate-rela +diff -ruN u-boot-2014.04/tools/Makefile u-boot-sunxi/tools/Makefile +--- u-boot-2014.04/tools/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/tools/Makefile 2014-09-06 16:58:36.521953105 +0200 +@@ -120,6 +120,8 @@ + hostprogs-$(CONFIG_MX28) += mxsboot$(SFX) + HOSTCFLAGS_mxsboot$(SFX).o := -pedantic + ++hostprogs-$(CONFIG_SUNXI) += mksunxiboot$(SFX) ++ + hostprogs-$(CONFIG_NETCONSOLE) += ncb$(SFX) + hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) + +diff -ruN u-boot-2014.04/tools/mksunxiboot.c u-boot-sunxi/tools/mksunxiboot.c +--- u-boot-2014.04/tools/mksunxiboot.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.c 2014-09-06 16:58:36.529953105 +0200 +@@ -0,0 +1,140 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * a simple tool to generate bootable image for sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <fcntl.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <string.h> ++#include <errno.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++ ++/* boot head definition from sun4i boot code */ ++struct boot_file_head { ++ uint32_t b_instruction; /* one intruction jumping to real code */ ++ uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ ++ uint32_t check_sum; /* generated by PC */ ++ uint32_t length; /* generated by PC */ ++ /* ++ * We use a simplified header, only filling in what is needed ++ * by the boot ROM. To be compatible with Allwinner tools we ++ * would need to implement the proper fields here instead of ++ * padding. ++ */ ++ uint8_t pad[12]; /* align to 32 bytes */ ++}; ++ ++#define BOOT0_MAGIC "eGON.BT0" ++#define STAMP_VALUE 0x5F0A6C39 ++ ++/* check sum functon from sun4i boot code */ ++int gen_check_sum(struct boot_file_head *head_p) ++{ ++ uint32_t length; ++ uint32_t *buf; ++ uint32_t loop; ++ uint32_t i; ++ uint32_t sum; ++ ++ length = head_p->length; ++ if ((length & 0x3) != 0) /* must 4-byte-aligned */ ++ return -1; ++ buf = (uint32_t *)head_p; ++ head_p->check_sum = STAMP_VALUE; /* fill stamp */ ++ loop = length >> 2; ++ ++ /* calculate the sum */ ++ for (i = 0, sum = 0; i < loop; i++) ++ sum += buf[i]; ++ ++ /* write back check sum */ ++ head_p->check_sum = sum; ++ ++ return 0; ++} ++ ++#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1) ++#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) ++ ++#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */ ++#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head)) ++#define BLOCK_SIZE 512 ++ ++struct boot_img { ++ struct boot_file_head header; ++ char code[SRAM_LOAD_MAX_SIZE]; ++ char pad[BLOCK_SIZE]; ++}; ++ ++int main(int argc, char *argv[]) ++{ ++ int fd_in, fd_out; ++ struct boot_img img; ++ unsigned file_size; ++ int count; ++ ++ if (argc < 2) { ++ printf("\tThis program makes an input bin file to sun4i " \ ++ "bootable image.\n" \ ++ "\tUsage: %s input_file out_putfile\n", argv[0]); ++ return EXIT_FAILURE; ++ } ++ ++ fd_in = open(argv[1], O_RDONLY); ++ if (fd_in < 0) { ++ perror("Open input file"); ++ return EXIT_FAILURE; ++ } ++ ++ memset(img.pad, 0, BLOCK_SIZE); ++ ++ /* get input file size */ ++ file_size = lseek(fd_in, 0, SEEK_END); ++ ++ if (file_size > SRAM_LOAD_MAX_SIZE) { ++ fprintf(stderr, "ERROR: File too large!\n"); ++ return EXIT_FAILURE; ++ } ++ ++ fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666); ++ if (fd_out < 0) { ++ perror("Open output file"); ++ return EXIT_FAILURE; ++ } ++ ++ /* read file to buffer to calculate checksum */ ++ lseek(fd_in, 0, SEEK_SET); ++ count = read(fd_in, img.code, file_size); ++ if (count != file_size) { ++ perror("Reading input image"); ++ return EXIT_FAILURE; ++ } ++ ++ /* fill the header */ ++ img.header.b_instruction = /* b instruction */ ++ 0xEA000000 | /* jump to the first instr after the header */ ++ ((sizeof(struct boot_file_head) / sizeof(int) - 2) ++ & 0x00FFFFFF); ++ memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */ ++ img.header.length = ++ ALIGN(file_size + sizeof(struct boot_file_head), BLOCK_SIZE); ++ gen_check_sum(&img.header); ++ ++ count = write(fd_out, &img, img.header.length); ++ if (count != img.header.length) { ++ perror("Writing output"); ++ return EXIT_FAILURE; ++ } ++ ++ close(fd_in); ++ close(fd_out); ++ ++ return EXIT_SUCCESS; ++} +diff -ruN u-boot-2014.04/tools/mksunxiboot.README u-boot-sunxi/tools/mksunxiboot.README +--- u-boot-2014.04/tools/mksunxiboot.README 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.README 2014-09-06 16:58:36.529953105 +0200 +@@ -0,0 +1,13 @@ ++This program make a arm binary file can be loaded by Allwinner A10 and related ++chips from storage media such as nand and mmc. ++ ++More information about A10 boot, please refer to ++http://rhombus-tech.net/allwinner_a10/a10_boot_process/ ++ ++To compile this program, just type make, you will get 'mksunxiboot'. ++ ++To use it, ++$./mksunxiboot u-boot.bin u-boot-mmc.bin ++then you can write it to a mmc card with dd. ++$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8 ++then insert your mmc card to your A10 tablet, you can boot from mmc card. diff --git a/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch b/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch new file mode 100644 index 0000000..65407aa --- /dev/null +++ b/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch @@ -0,0 +1,1495 @@ +From 86f31982ac62e80fe586cad2e0a49a7b22e3d4ee Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:07 +0000 +Subject: [PATCH] ARM: HYP/non-sec: move switch to non-sec to the last boot + phase + +Having the switch to non-secure in the "prep" phase is causing +all kind of troubles, as that stage can be called multiple times. + +Instead, move the switch to non-secure to the last possible phase, +when there is no turning back anymore. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/lib/bootm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 47ee070..10634a4 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -242,7 +242,6 @@ static void boot_prep_linux(bootm_headers_t *images) + printf("FDT and ATAGS support not compiled in - hanging\n"); + hang(); + } +- do_nonsec_virt_switch(); + } + + /* Subcommand: GO */ +@@ -287,8 +286,10 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) + else + r2 = gd->bd->bi_boot_params; + +- if (!fake) ++ if (!fake) { ++ do_nonsec_virt_switch(); + kernel_entry(0, machid, r2); ++ } + #endif + } + +From c26d288f6cbc6d53219001d42476f314c403257b Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:08 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add a barrier after setting SCR.NS==1 + +A CP15 instruction execution can be reordered, requiring an +isb to be sure it is executed in program order. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 6367e09..12de5c2 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -46,6 +46,7 @@ _secure_monitor: + #endif + + mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) ++ isb + + #ifdef CONFIG_ARMV7_VIRT + mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value +From 06feeea3c84cc58ff3d5c19f6a430886495f86ce Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:09 +0000 +Subject: [PATCH] ARM: non-sec: reset CNTVOFF to zero + +Before switching to non-secure, make sure that CNTVOFF is set +to zero on all CPUs. Otherwise, kernel running in non-secure +without HYP enabled (hence using virtual timers) may observe +timers that are not synchronized, effectively seeing time +going backward... + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 12de5c2..b5c946f 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -38,10 +38,10 @@ _secure_monitor: + bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits + orr r1, r1, #0x31 @ enable NS, AW, FW bits + +-#ifdef CONFIG_ARMV7_VIRT + mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 + and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits + cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) ++#ifdef CONFIG_ARMV7_VIRT + orreq r1, r1, #0x100 @ allow HVC instruction + #endif + +@@ -52,7 +52,14 @@ _secure_monitor: + mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value + mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR + #endif ++ bne 1f + ++ @ Reset CNTVOFF to 0 before leaving monitor mode ++ mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 ++ ands r0, r0, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits ++ movne r0, #0 ++ mcrrne p15, 4, r0, r0, c14 @ Reset CNTVOFF to zero ++1: + movs pc, lr @ return to non-secure SVC + + _hyp_trap: +From 054bcf5147ff5a20298bce5b3bdfbf3e1c797594 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:10 +0000 +Subject: [PATCH] ARM: add missing HYP mode constant + +In order to be able to use the various mode constants (far more +readable than random hex values), add the missing HYP and A +values. + +Also update arm/lib/interrupts.c to display HYP instead of an +unknown value. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/include/asm/proc-armv/ptrace.h | 2 ++ + arch/arm/lib/interrupts.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h +index 21aef58..71df5a9 100644 +--- a/arch/arm/include/asm/proc-armv/ptrace.h ++++ b/arch/arm/include/asm/proc-armv/ptrace.h +@@ -38,12 +38,14 @@ struct pt_regs { + #define IRQ_MODE 0x12 + #define SVC_MODE 0x13 + #define ABT_MODE 0x17 ++#define HYP_MODE 0x1a + #define UND_MODE 0x1b + #define SYSTEM_MODE 0x1f + #define MODE_MASK 0x1f + #define T_BIT 0x20 + #define F_BIT 0x40 + #define I_BIT 0x80 ++#define A_BIT 0x100 + #define CC_V_BIT (1 << 28) + #define CC_C_BIT (1 << 29) + #define CC_Z_BIT (1 << 30) +diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c +index 758b013..f6b7c03 100644 +--- a/arch/arm/lib/interrupts.c ++++ b/arch/arm/lib/interrupts.c +@@ -103,7 +103,7 @@ void show_regs (struct pt_regs *regs) + "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", + "UK4_32", "UK5_32", "UK6_32", "ABT_32", +- "UK8_32", "UK9_32", "UK10_32", "UND_32", ++ "UK8_32", "UK9_32", "HYP_32", "UND_32", + "UK12_32", "UK13_32", "UK14_32", "SYS_32", + }; + +From 213a8d9b7e613210d3c7d8b99c95b454ad0527d8 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:11 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add separate section for secure code + +In anticipation of refactoring the HYP/non-secure code to run +from secure RAM, add a new linker section that will contain that +code. + +Nothing is using it just yet. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/config.mk | 2 +- + arch/arm/cpu/u-boot.lds | 30 ++++++++++++++++++++++++++++++ + arch/arm/lib/sections.c | 2 ++ + 3 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/config.mk b/arch/arm/config.mk +index 66ecc2e..2bdfca5 100644 +--- a/arch/arm/config.mk ++++ b/arch/arm/config.mk +@@ -113,7 +113,7 @@ endif + ifdef CONFIG_ARM64 + OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn + else +-OBJCOPYFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn ++OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn + endif + + ifneq ($(CONFIG_IMX_CONFIG),) +diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds +index 33c1f99..f45885d 100644 +--- a/arch/arm/cpu/u-boot.lds ++++ b/arch/arm/cpu/u-boot.lds +@@ -7,6 +7,8 @@ + * SPDX-License-Identifier: GPL-2.0+ + */ + ++#include <config.h> ++ + OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") + OUTPUT_ARCH(arm) + ENTRY(_start) +@@ -22,6 +24,34 @@ SECTIONS + *(.text*) + } + ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI) ++ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++#define CONFIG_ARMV7_SECURE_BASE ++#endif ++ ++ .__secure_start : { ++ . = ALIGN(0x1000); ++ *(.__secure_start) ++ } ++ ++ .secure_text CONFIG_ARMV7_SECURE_BASE : ++ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) ++ { ++ *(._secure.text) ++ } ++ ++ . = LOADADDR(.__secure_start) + ++ SIZEOF(.__secure_start) + ++ SIZEOF(.secure_text); ++ ++ __secure_end_lma = .; ++ .__secure_end : AT(__secure_end_lma) { ++ *(.__secure_end) ++ LONG(0x1d1071c); /* Must output something to reset LMA */ ++ } ++#endif ++ + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + +diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c +index 5b30bcb..a1205c3 100644 +--- a/arch/arm/lib/sections.c ++++ b/arch/arm/lib/sections.c +@@ -25,4 +25,6 @@ char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); + char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); + char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); + char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); ++char __secure_start[0] __attribute__((section(".__secure_start"))); ++char __secure_end[0] __attribute__((section(".__secure_end"))); + char _end[0] __attribute__((section(".__end"))); +From d7ebd8f57e84ea92ef0cf55080f0acec9c6d1ace Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:12 +0000 +Subject: [PATCH] ARM: HYP/non-sec: allow relocation to secure RAM + +The current non-sec switching code suffers from one major issue: +it cannot run in secure RAM, as a large part of u-boot still needs +to be run while we're switched to non-secure. + +This patch reworks the whole HYP/non-secure strategy by: +- making sure the secure code is the *last* thing u-boot executes + before entering the payload +- performing an exception return from secure mode directly into + the payload +- allowing the code to be dynamically relocated to secure RAM + before switching to non-secure. + +This involves quite a bit of horrible code, specially as u-boot +relocation is quite primitive. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 161 +++++++++++++++++++-------------------- + arch/arm/cpu/armv7/virt-v7.c | 59 +++++--------- + arch/arm/include/asm/armv7.h | 10 ++- + arch/arm/include/asm/secure.h | 26 +++++++ + arch/arm/lib/bootm.c | 22 +++--- + 5 files changed, 138 insertions(+), 140 deletions(-) + create mode 100644 arch/arm/include/asm/secure.h + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index b5c946f..2a43e3c 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -10,10 +10,13 @@ + #include <linux/linkage.h> + #include <asm/gic.h> + #include <asm/armv7.h> ++#include <asm/proc-armv/ptrace.h> + + .arch_extension sec + .arch_extension virt + ++ .pushsection ._secure.text, "ax" ++ + .align 5 + /* the vector table for secure state and HYP mode */ + _monitor_vectors: +@@ -22,51 +25,86 @@ _monitor_vectors: + adr pc, _secure_monitor + .word 0 + .word 0 +- adr pc, _hyp_trap ++ .word 0 + .word 0 + .word 0 + ++.macro is_cpu_virt_capable tmp ++ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1 ++ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits ++ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT) ++.endm ++ + /* + * secure monitor handler + * U-boot calls this "software interrupt" in start.S + * This is executed on a "smc" instruction, we use a "smc #0" to switch + * to non-secure state. +- * We use only r0 and r1 here, due to constraints in the caller. ++ * r0, r1, r2: passed to the callee ++ * ip: target PC + */ + _secure_monitor: +- mrc p15, 0, r1, c1, c1, 0 @ read SCR +- bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits +- orr r1, r1, #0x31 @ enable NS, AW, FW bits ++ mrc p15, 0, r5, c1, c1, 0 @ read SCR ++ bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits ++ orr r5, r5, #0x31 @ enable NS, AW, FW bits + +- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 +- and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits +- cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) ++ mov r6, #SVC_MODE @ default mode is SVC ++ is_cpu_virt_capable r4 + #ifdef CONFIG_ARMV7_VIRT +- orreq r1, r1, #0x100 @ allow HVC instruction ++ orreq r5, r5, #0x100 @ allow HVC instruction ++ moveq r6, #HYP_MODE @ Enter the kernel as HYP + #endif + +- mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) ++ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set) + isb + +-#ifdef CONFIG_ARMV7_VIRT +- mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value +- mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR +-#endif + bne 1f + + @ Reset CNTVOFF to 0 before leaving monitor mode +- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 +- ands r0, r0, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits +- movne r0, #0 +- mcrrne p15, 4, r0, r0, c14 @ Reset CNTVOFF to zero ++ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1 ++ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits ++ movne r4, #0 ++ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero + 1: +- movs pc, lr @ return to non-secure SVC +- +-_hyp_trap: +- mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1 +- mov pc, lr @ do no switch modes, but +- @ return to caller +- ++ mov lr, ip ++ mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F ++ tst lr, #1 @ Check for Thumb PC ++ orrne ip, ip, #T_BIT @ Set T if Thumb ++ orr ip, ip, r6 @ Slot target mode in ++ msr spsr_cxfs, ip @ Set full SPSR ++ movs pc, lr @ ERET to non-secure ++ ++ENTRY(_do_nonsec_entry) ++ mov ip, r0 ++ mov r0, r1 ++ mov r1, r2 ++ mov r2, r3 ++ smc #0 ++ENDPROC(_do_nonsec_entry) ++ ++.macro get_cbar_addr addr ++#ifdef CONFIG_ARM_GIC_BASE_ADDRESS ++ ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS ++#else ++ mrc p15, 4, \addr, c15, c0, 0 @ read CBAR ++ bfc \addr, #0, #15 @ clear reserved bits ++#endif ++.endm ++ ++.macro get_gicd_addr addr ++ get_cbar_addr \addr ++ add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset ++.endm ++ ++.macro get_gicc_addr addr, tmp ++ get_cbar_addr \addr ++ is_cpu_virt_capable \tmp ++ movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 ++ moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 ++ add \addr, \addr, \tmp ++.endm ++ ++#ifndef CONFIG_ARMV7_PSCI + /* + * Secondary CPUs start here and call the code for the core specific parts + * of the non-secure and HYP mode transition. The GIC distributor specific +@@ -74,31 +112,21 @@ _hyp_trap: + * Then they go back to wfi and wait to be woken up by the kernel again. + */ + ENTRY(_smp_pen) +- mrs r0, cpsr +- orr r0, r0, #0xc0 +- msr cpsr, r0 @ disable interrupts +- ldr r1, =_start +- mcr p15, 0, r1, c12, c0, 0 @ set VBAR ++ cpsid i ++ cpsid f + + bl _nonsec_init +- mov r12, r0 @ save GICC address +-#ifdef CONFIG_ARMV7_VIRT +- bl _switch_to_hyp +-#endif +- +- ldr r1, [r12, #GICC_IAR] @ acknowledge IPI +- str r1, [r12, #GICC_EOIR] @ signal end of interrupt + + adr r0, _smp_pen @ do not use this address again + b smp_waitloop @ wait for IPIs, board specific + ENDPROC(_smp_pen) ++#endif + + /* + * Switch a core to non-secure state. + * + * 1. initialize the GIC per-core interface + * 2. allow coprocessor access in non-secure modes +- * 3. switch the cpu mode (by calling "smc #0") + * + * Called from smp_pen by secondary cores and directly by the BSP. + * Do not assume that the stack is available and only use registers +@@ -108,38 +136,23 @@ ENDPROC(_smp_pen) + * though, but we check this in C before calling this function. + */ + ENTRY(_nonsec_init) +-#ifdef CONFIG_ARM_GIC_BASE_ADDRESS +- ldr r2, =CONFIG_ARM_GIC_BASE_ADDRESS +-#else +- mrc p15, 4, r2, c15, c0, 0 @ read CBAR +- bfc r2, #0, #15 @ clear reserved bits +-#endif +- add r3, r2, #GIC_DIST_OFFSET @ GIC dist i/f offset ++ get_gicd_addr r3 ++ + mvn r1, #0 @ all bits to 1 + str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts + +- mrc p15, 0, r0, c0, c0, 0 @ read MIDR +- ldr r1, =MIDR_PRIMARY_PART_MASK +- and r0, r0, r1 @ mask out variant and revision ++ get_gicc_addr r3, r1 + +- ldr r1, =MIDR_CORTEX_A7_R0P0 & MIDR_PRIMARY_PART_MASK +- cmp r0, r1 @ check for Cortex-A7 +- +- ldr r1, =MIDR_CORTEX_A15_R0P0 & MIDR_PRIMARY_PART_MASK +- cmpne r0, r1 @ check for Cortex-A15 +- +- movne r1, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 +- moveq r1, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 +- add r3, r2, r1 @ r3 = GIC CPU i/f addr +- +- mov r1, #1 @ set GICC_CTLR[enable] ++ mov r1, #3 @ Enable both groups + str r1, [r3, #GICC_CTLR] @ and clear all other bits + mov r1, #0xff + str r1, [r3, #GICC_PMR] @ set priority mask register + ++ mrc p15, 0, r0, c1, c1, 2 + movw r1, #0x3fff +- movt r1, #0x0006 +- mcr p15, 0, r1, c1, c1, 2 @ NSACR = all copros to non-sec ++ movt r1, #0x0004 ++ orr r0, r0, r1 ++ mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec + + /* The CNTFRQ register of the generic timer needs to be + * programmed in secure state. Some primary bootloaders / firmware +@@ -157,21 +170,9 @@ ENTRY(_nonsec_init) + + adr r1, _monitor_vectors + mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors +- +- mrc p15, 0, ip, c12, c0, 0 @ save secure copy of VBAR +- + isb +- smc #0 @ call into MONITOR mode +- +- mcr p15, 0, ip, c12, c0, 0 @ write non-secure copy of VBAR +- +- mov r1, #1 +- str r1, [r3, #GICC_CTLR] @ enable non-secure CPU i/f +- add r2, r2, #GIC_DIST_OFFSET +- str r1, [r2, #GICD_CTLR] @ allow private interrupts + + mov r0, r3 @ return GICC address +- + bx lr + ENDPROC(_nonsec_init) + +@@ -183,18 +184,10 @@ ENTRY(smp_waitloop) + ldr r1, [r1] + cmp r0, r1 @ make sure we dont execute this code + beq smp_waitloop @ again (due to a spurious wakeup) +- mov pc, r1 ++ mov r0, r1 ++ b _do_nonsec_entry + ENDPROC(smp_waitloop) + .weak smp_waitloop + #endif + +-ENTRY(_switch_to_hyp) +- mov r0, lr +- mov r1, sp @ save SVC copy of LR and SP +- isb +- hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 +- mov sp, r1 +- mov lr, r0 @ restore SVC copy of LR and SP +- +- bx lr +-ENDPROC(_switch_to_hyp) ++ .popsection +diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c +index 2cd604f..6500030 100644 +--- a/arch/arm/cpu/armv7/virt-v7.c ++++ b/arch/arm/cpu/armv7/virt-v7.c +@@ -13,17 +13,10 @@ + #include <asm/armv7.h> + #include <asm/gic.h> + #include <asm/io.h> ++#include <asm/secure.h> + + unsigned long gic_dist_addr; + +-static unsigned int read_cpsr(void) +-{ +- unsigned int reg; +- +- asm volatile ("mrs %0, cpsr\n" : "=r" (reg)); +- return reg; +-} +- + static unsigned int read_id_pfr1(void) + { + unsigned int reg; +@@ -72,6 +65,18 @@ static unsigned long get_gicd_base_address(void) + #endif + } + ++static void relocate_secure_section(void) ++{ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++ size_t sz = __secure_end - __secure_start; ++ ++ memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz); ++ flush_dcache_range(CONFIG_ARMV7_SECURE_BASE, ++ CONFIG_ARMV7_SECURE_BASE + sz + 1); ++ invalidate_icache_all(); ++#endif ++} ++ + static void kick_secondary_cpus_gic(unsigned long gicdaddr) + { + /* kick all CPUs (except this one) by writing to GICD_SGIR */ +@@ -83,35 +88,7 @@ void __weak smp_kick_all_cpus(void) + kick_secondary_cpus_gic(gic_dist_addr); + } + +-int armv7_switch_hyp(void) +-{ +- unsigned int reg; +- +- /* check whether we are in HYP mode already */ +- if ((read_cpsr() & 0x1f) == 0x1a) { +- debug("CPU already in HYP mode\n"); +- return 0; +- } +- +- /* check whether the CPU supports the virtualization extensions */ +- reg = read_id_pfr1(); +- if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) { +- printf("HYP mode: Virtualization extensions not implemented.\n"); +- return -1; +- } +- +- /* call the HYP switching code on this CPU also */ +- _switch_to_hyp(); +- +- if ((read_cpsr() & 0x1F) != 0x1a) { +- printf("HYP mode: switch not successful.\n"); +- return -1; +- } +- +- return 0; +-} +- +-int armv7_switch_nonsec(void) ++int armv7_init_nonsec(void) + { + unsigned int reg; + unsigned itlinesnr, i; +@@ -147,11 +124,13 @@ int armv7_switch_nonsec(void) + for (i = 1; i <= itlinesnr; i++) + writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); + +- smp_set_core_boot_addr((unsigned long)_smp_pen, -1); ++#ifndef CONFIG_ARMV7_PSCI ++ smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1); + smp_kick_all_cpus(); ++#endif + + /* call the non-sec switching code on this CPU also */ +- _nonsec_init(); +- ++ relocate_secure_section(); ++ secure_ram_addr(_nonsec_init)(); + return 0; + } +diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h +index 395444e..11476dd 100644 +--- a/arch/arm/include/asm/armv7.h ++++ b/arch/arm/include/asm/armv7.h +@@ -78,13 +78,17 @@ void v7_outer_cache_inval_range(u32 start, u32 end); + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + +-int armv7_switch_nonsec(void); +-int armv7_switch_hyp(void); ++int armv7_init_nonsec(void); + + /* defined in assembly file */ + unsigned int _nonsec_init(void); ++void _do_nonsec_entry(void *target_pc, unsigned long r0, ++ unsigned long r1, unsigned long r2); + void _smp_pen(void); +-void _switch_to_hyp(void); ++ ++extern char __secure_start[]; ++extern char __secure_end[]; ++ + #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */ + + #endif /* ! __ASSEMBLY__ */ +diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h +new file mode 100644 +index 0000000..effdb18 +--- /dev/null ++++ b/arch/arm/include/asm/secure.h +@@ -0,0 +1,26 @@ ++#ifndef __ASM_SECURE_H ++#define __ASM_SECURE_H ++ ++#include <config.h> ++ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++/* ++ * Warning, horror ahead. ++ * ++ * The target code lives in our "secure ram", but u-boot doesn't know ++ * that, and has blindly added reloc_off to every relocation ++ * entry. Gahh. Do the opposite conversion. This hack also prevents ++ * GCC from generating code veeners, which u-boot doesn't relocate at ++ * all... ++ */ ++#define secure_ram_addr(_fn) ({ \ ++ DECLARE_GLOBAL_DATA_PTR; \ ++ void *__fn = _fn; \ ++ typeof(_fn) *__tmp = (__fn - gd->reloc_off); \ ++ __tmp; \ ++ }) ++#else ++#define secure_ram_addr(_fn) (_fn) ++#endif ++ ++#endif +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 10634a4..61aa14e 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -20,6 +20,7 @@ + #include <libfdt.h> + #include <fdt_support.h> + #include <asm/bootm.h> ++#include <asm/secure.h> + #include <linux/compiler.h> + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +@@ -184,27 +185,17 @@ static void setup_end_tag(bd_t *bd) + + __weak void setup_board_tags(struct tag **in_params) {} + ++#ifdef CONFIG_ARM64 + static void do_nonsec_virt_switch(void) + { +-#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +- if (armv7_switch_nonsec() == 0) +-#ifdef CONFIG_ARMV7_VIRT +- if (armv7_switch_hyp() == 0) +- debug("entered HYP mode\n"); +-#else +- debug("entered non-secure state\n"); +-#endif +-#endif +- +-#ifdef CONFIG_ARM64 + smp_kick_all_cpus(); + flush_dcache_all(); /* flush cache before swtiching to EL2 */ + armv8_switch_to_el2(); + #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + armv8_switch_to_el1(); + #endif +-#endif + } ++#endif + + /* Subcommand: PREP */ + static void boot_prep_linux(bootm_headers_t *images) +@@ -287,8 +278,13 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) + r2 = gd->bd->bi_boot_params; + + if (!fake) { +- do_nonsec_virt_switch(); ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ armv7_init_nonsec(); ++ secure_ram_addr(_do_nonsec_entry)(kernel_entry, ++ 0, machid, r2); ++#else + kernel_entry(0, machid, r2); ++#endif + } + #endif + } +From 8ea1554da4a6e556d3213a77cf59daa1c154bdb5 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:13 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add generic ARMv7 PSCI code + +Implement core support for PSCI. As this is generic code, it doesn't +implement anything really useful (all the functions are returning +Not Implemented). + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/Makefile | 4 ++ + arch/arm/cpu/armv7/psci.S | 105 ++++++++++++++++++++++++++++++++++++++++++++ + arch/arm/include/asm/psci.h | 35 +++++++++++++++ + 3 files changed, 144 insertions(+) + create mode 100644 arch/arm/cpu/armv7/psci.S + create mode 100644 arch/arm/include/asm/psci.h + +diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile +index 6f17771..0cf5c45 100644 +--- a/arch/arm/cpu/armv7/Makefile ++++ b/arch/arm/cpu/armv7/Makefile +@@ -24,6 +24,10 @@ obj-y += nonsec_virt.o + obj-y += virt-v7.o + endif + ++ifneq ($(CONFIG_ARMV7_PSCI),) ++obj-y += psci.o ++endif ++ + obj-$(CONFIG_KONA) += kona-common/ + obj-$(CONFIG_OMAP_COMMON) += omap-common/ + obj-$(CONFIG_TEGRA) += tegra-common/ +diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S +new file mode 100644 +index 0000000..a9341e0 +--- /dev/null ++++ b/arch/arm/cpu/armv7/psci.S +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/. ++ */ ++ ++#include <config.h> ++#include <linux/linkage.h> ++#include <asm/psci.h> ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++ .align 5 ++ .globl _psci_vectors ++_psci_vectors: ++ b default_psci_vector @ reset ++ b default_psci_vector @ undef ++ b _smc_psci @ smc ++ b default_psci_vector @ pabort ++ b default_psci_vector @ dabort ++ b default_psci_vector @ hyp ++ b default_psci_vector @ irq ++ b psci_fiq_enter @ fiq ++ ++ENTRY(psci_fiq_enter) ++ movs pc, lr ++ENDPROC(psci_fiq_enter) ++.weak psci_fiq_enter ++ ++ENTRY(default_psci_vector) ++ movs pc, lr ++ENDPROC(default_psci_vector) ++.weak default_psci_vector ++ ++ENTRY(psci_cpu_suspend) ++ENTRY(psci_cpu_off) ++ENTRY(psci_cpu_on) ++ENTRY(psci_migrate) ++ mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) ++ mov pc, lr ++ENDPROC(psci_migrate) ++ENDPROC(psci_cpu_on) ++ENDPROC(psci_cpu_off) ++ENDPROC(psci_cpu_suspend) ++.weak psci_cpu_suspend ++.weak psci_cpu_off ++.weak psci_cpu_on ++.weak psci_migrate ++ ++_psci_table: ++ .word ARM_PSCI_FN_CPU_SUSPEND ++ .word psci_cpu_suspend ++ .word ARM_PSCI_FN_CPU_OFF ++ .word psci_cpu_off ++ .word ARM_PSCI_FN_CPU_ON ++ .word psci_cpu_on ++ .word ARM_PSCI_FN_MIGRATE ++ .word psci_migrate ++ .word 0 ++ .word 0 ++ ++_smc_psci: ++ push {r3-r7,lr} ++ ++ @ Switch to secure ++ mrc p15, 0, r7, c1, c1, 0 ++ bic r4, r7, #1 ++ mcr p15, 0, r4, c1, c1, 0 ++ isb ++ ++ adr r4, _psci_table ++1: ldr r5, [r4] @ Load PSCI function ID ++ ldr r6, [r4, #4] @ Load target PC ++ cmp r5, #0 @ If reach the end, bail out ++ mvneq r0, #0 @ Return -1 (Not Implemented) ++ beq 2f ++ cmp r0, r5 @ If not matching, try next entry ++ addne r4, r4, #8 ++ bne 1b ++ cmp r6, #0 @ Not implemented ++ moveq r0, #ARM_PSCI_RET_NI ++ beq 2f ++ ++ blx r6 @ Execute PSCI function ++ ++ @ Switch back to non-secure ++ mcr p15, 0, r7, c1, c1, 0 ++ ++2: pop {r3-r7, lr} ++ movs pc, lr @ Return to the kernel ++ ++ .popsection +diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h +new file mode 100644 +index 0000000..704b4b0 +--- /dev/null ++++ b/arch/arm/include/asm/psci.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/. ++ */ ++ ++#ifndef __ARM_PSCI_H__ ++#define __ARM_PSCI_H__ ++ ++/* PSCI interface */ ++#define ARM_PSCI_FN_BASE 0x95c1ba5e ++#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n)) ++ ++#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0) ++#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1) ++#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2) ++#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3) ++ ++#define ARM_PSCI_RET_SUCCESS 0 ++#define ARM_PSCI_RET_NI (-1) ++#define ARM_PSCI_RET_INVAL (-2) ++#define ARM_PSCI_RET_DENIED (-3) ++ ++#endif /* __ARM_PSCI_H__ */ +From 0ca6171c385fed00125b320592ee94922f44f13a Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:14 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add the option for a second-stage monitor + +Allow the switch to a second stage secure monitor just before +switching to non-secure. + +This allows a resident piece of firmware to be active once the +kernel has been entered (the u-boot monitor is dead anyway, +its pages being reused). + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 2a43e3c..745670e 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -44,10 +44,19 @@ _monitor_vectors: + * ip: target PC + */ + _secure_monitor: ++#ifdef CONFIG_ARMV7_PSCI ++ ldr r5, =_psci_vectors @ Switch to the next monitor ++ mcr p15, 0, r5, c12, c0, 1 ++ isb ++ ++ @ Obtain a secure stack, and configure the PSCI backend ++ bl psci_arch_init ++#endif ++ + mrc p15, 0, r5, c1, c1, 0 @ read SCR +- bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits ++ bic r5, r5, #0x4a @ clear IRQ, EA, nET bits + orr r5, r5, #0x31 @ enable NS, AW, FW bits +- ++ @ FIQ preserved for secure mode + mov r6, #SVC_MODE @ default mode is SVC + is_cpu_virt_capable r4 + #ifdef CONFIG_ARMV7_VIRT +From 9aa373162eb2cc0055a6e4ecd46977c911de1124 Mon Sep 17 00:00:00 2001 +From: Ma Haijun mahaijuns@gmail.com +Date: Sat, 15 Feb 2014 12:51:10 +0000 +Subject: [PATCH] ARM: convert arch_fixup_memory_node to a generic FDT fixup + function + +Some architecture needs extra device tree setup. Instead of adding +yet another hook, convert arch_fixup_memory_node to be a generic +FDT fixup function. + +[maz: collapsed 3 patches into one, rewrote commit message] + +Signed-off-by: Ma Haijun mahaijuns@gmail.com +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/lib/bootm-fdt.c | 2 +- + arch/arm/lib/bootm.c | 2 +- + common/image-fdt.c | 7 +++++-- + include/common.h | 6 +++--- + 4 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c +index e40691d..8394e15 100644 +--- a/arch/arm/lib/bootm-fdt.c ++++ b/arch/arm/lib/bootm-fdt.c +@@ -20,7 +20,7 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-int arch_fixup_memory_node(void *blob) ++int arch_fixup_fdt(void *blob) + { + bd_t *bd = gd->bd; + int bank; +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 61aa14e..4cff6b0 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -357,7 +357,7 @@ void boot_prep_vxworks(bootm_headers_t *images) + if (images->ft_addr) { + off = fdt_path_offset(images->ft_addr, "/memory"); + if (off < 0) { +- if (arch_fixup_memory_node(images->ft_addr)) ++ if (arch_fixup_fdt(images->ft_addr)) + puts("## WARNING: fixup memory failed!\n"); + } + } +diff --git a/common/image-fdt.c b/common/image-fdt.c +index a54a919..6f074de 100644 +--- a/common/image-fdt.c ++++ b/common/image-fdt.c +@@ -445,7 +445,7 @@ __weak int ft_verify_fdt(void *fdt) + return 1; + } + +-__weak int arch_fixup_memory_node(void *blob) ++__weak int arch_fixup_fdt(void *blob) + { + return 0; + } +@@ -462,7 +462,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, + puts(" - must RESET the board to recover.\n"); + return -1; + } +- arch_fixup_memory_node(blob); ++ if (arch_fixup_fdt(blob) < 0) { ++ puts("ERROR: arch specific fdt fixup failed"); ++ return -1; ++ } + if (IMAGE_OF_BOARD_SETUP) + ft_board_setup(blob, gd->bd); + fdt_fixup_ethernet(blob); +diff --git a/include/common.h b/include/common.h +index cbd3c9e..700b015 100644 +--- a/include/common.h ++++ b/include/common.h +@@ -326,14 +326,14 @@ int arch_early_init_r(void); + void board_show_dram(ulong size); + + /** +- * arch_fixup_memory_node() - Write arch-specific memory information to fdt ++ * arch_fixup_fdt() - Write arch-specific information to fdt + * +- * Defined in arch/$(ARCH)/lib/bootm.c ++ * Defined in arch/$(ARCH)/lib/bootm-fdt.c + * + * @blob: FDT blob to write to + * @return 0 if ok, or -ve FDT_ERR_... on failure + */ +-int arch_fixup_memory_node(void *blob); ++int arch_fixup_fdt(void *blob); + + /* common/flash.c */ + void flash_perror (int); +From ccdf689da800c9f1c5226146e936b071c7ec8800 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:15 +0000 +Subject: [PATCH] ARM: HYP/non-sec/PSCI: emit DT nodes + +Generate the PSCI node in the device tree. + +Also add a reserve section for the "secure" code that lives in +in normal RAM, so that the kernel knows it'd better not trip on +it. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/Makefile | 1 + + arch/arm/cpu/armv7/virt-dt.c | 100 +++++++++++++++++++++++++++++++++++++++++++ + arch/arm/include/asm/armv7.h | 1 + + arch/arm/lib/bootm-fdt.c | 11 ++++- + 4 files changed, 111 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/cpu/armv7/virt-dt.c + +diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile +index 0cf5c45..93a5a69 100644 +--- a/arch/arm/cpu/armv7/Makefile ++++ b/arch/arm/cpu/armv7/Makefile +@@ -22,6 +22,7 @@ endif + ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),) + obj-y += nonsec_virt.o + obj-y += virt-v7.o ++obj-y += virt-dt.o + endif + + ifneq ($(CONFIG_ARMV7_PSCI),) +diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c +new file mode 100644 +index 0000000..0b0d6a7 +--- /dev/null ++++ b/arch/arm/cpu/armv7/virt-dt.c +@@ -0,0 +1,100 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/. ++ */ ++ ++#include <common.h> ++#include <stdio_dev.h> ++#include <linux/ctype.h> ++#include <linux/types.h> ++#include <asm/global_data.h> ++#include <libfdt.h> ++#include <fdt_support.h> ++#include <asm/armv7.h> ++#include <asm/psci.h> ++ ++static int fdt_psci(void *fdt) ++{ ++#ifdef CONFIG_ARMV7_PSCI ++ int nodeoff; ++ int tmp; ++ ++ nodeoff = fdt_path_offset(fdt, "/cpus"); ++ if (nodeoff < 0) { ++ printf("couldn't find /cpus\n"); ++ return nodeoff; ++ } ++ ++ /* add 'enable-method = "psci"' to each cpu node */ ++ for (tmp = fdt_first_subnode(fdt, nodeoff); ++ tmp >= 0; ++ tmp = fdt_next_subnode(fdt, tmp)) { ++ const struct fdt_property *prop; ++ int len; ++ ++ prop = fdt_get_property(fdt, tmp, "device_type", &len); ++ if (!prop) ++ continue; ++ if (len < 4) ++ continue; ++ if (strcmp(prop->data, "cpu")) ++ continue; ++ ++ fdt_setprop_string(fdt, tmp, "enable-method", "psci"); ++ } ++ ++ nodeoff = fdt_path_offset(fdt, "/psci"); ++ if (nodeoff < 0) { ++ nodeoff = fdt_path_offset(fdt, "/"); ++ if (nodeoff < 0) ++ return nodeoff; ++ ++ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); ++ if (nodeoff < 0) ++ return nodeoff; ++ } ++ ++ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); ++ if (tmp) ++ return tmp; ++#endif ++ return 0; ++} ++ ++int armv7_update_dt(void *fdt) ++{ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++ /* secure code lives in RAM, keep it alive */ ++ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, ++ __secure_end - __secure_start); ++#endif ++ ++ return fdt_psci(fdt); ++} +diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h +index 11476dd..323f282 100644 +--- a/arch/arm/include/asm/armv7.h ++++ b/arch/arm/include/asm/armv7.h +@@ -79,6 +79,7 @@ void v7_outer_cache_inval_range(u32 start, u32 end); + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + + int armv7_init_nonsec(void); ++int armv7_update_dt(void *fdt); + + /* defined in assembly file */ + unsigned int _nonsec_init(void); +diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c +index 8394e15..ccb76c7 100644 +--- a/arch/arm/lib/bootm-fdt.c ++++ b/arch/arm/lib/bootm-fdt.c +@@ -17,13 +17,14 @@ + + #include <common.h> + #include <fdt_support.h> ++#include <asm/armv7.h> + + DECLARE_GLOBAL_DATA_PTR; + + int arch_fixup_fdt(void *blob) + { + bd_t *bd = gd->bd; +- int bank; ++ int bank, ret; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + +@@ -32,5 +33,11 @@ int arch_fixup_fdt(void *blob) + size[bank] = bd->bi_dram[bank].size; + } + +- return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); ++ ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); ++ if (ret) ++ return ret; ++ ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ return armv7_update_dt(blob); ++#endif + } +From d5ee64675e6481e4f29e48e494ea132cd74786c8 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:17 +0000 +Subject: [PATCH] sunxi: HYP/non-sec: add sun7i PSCI backend + +So far, only supporting the CPU_ON method. +Other functions can be added later. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/sunxi/Makefile | 3 + + arch/arm/cpu/armv7/sunxi/psci.S | 162 ++++++++++++++++++++++++++++++++++++++ + include/configs/sun7i.h | 6 ++ + 3 files changed, 171 insertions(+) + create mode 100644 arch/arm/cpu/armv7/sunxi/psci.S + +diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile +index 19e4b17..0df6772 100644 +--- a/arch/arm/cpu/armv7/sunxi/Makefile ++++ b/arch/arm/cpu/armv7/sunxi/Makefile +@@ -32,6 +32,9 @@ obj-y += cpu_info.o + ifdef CONFIG_CMD_WATCHDOG + obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o + endif ++ifdef CONFIG_ARMV7_PSCI ++obj-y += psci.o ++endif + endif + + ifdef CONFIG_SPL_BUILD +diff --git a/arch/arm/cpu/armv7/sunxi/psci.S b/arch/arm/cpu/armv7/sunxi/psci.S +new file mode 100644 +index 0000000..0084c81 +--- /dev/null ++++ b/arch/arm/cpu/armv7/sunxi/psci.S +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * Based on code by Carl van Schaik carl@ok-labs.com. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/. ++ */ ++ ++#include <config.h> ++#include <asm/psci.h> ++#include <asm/arch/cpu.h> ++ ++/* ++ * Memory layout: ++ * ++ * SECURE_RAM to text_end : ++ * ._secure_text section ++ * text_end to ALIGN_PAGE(text_end): ++ * nothing ++ * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000) ++ * 1kB of stack per CPU (4 CPUs max). ++ */ ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++#define ONE_MS (CONFIG_SYS_CLK_FREQ / 1000) ++#define TEN_MS (10 * ONE_MS) ++ ++.macro timer_wait reg, ticks ++ @ Program CNTP_TVAL ++ movw \reg, #(\ticks & 0xffff) ++ movt \reg, #(\ticks >> 16) ++ mcr p15, 0, \reg, c14, c2, 0 ++ isb ++ @ Enable physical timer, mask interrupt ++ mov \reg, #3 ++ mcr p15, 0, \reg, c14, c2, 1 ++ @ Poll physical timer until ISTATUS is on ++1: isb ++ mrc p15, 0, \reg, c14, c2, 1 ++ ands \reg, \reg, #4 ++ bne 1b ++ @ Disable timer ++ mov \reg, #0 ++ mcr p15, 0, \reg, c14, c2, 1 ++ isb ++.endm ++ ++.globl psci_arch_init ++psci_arch_init: ++ mrc p15, 0, r5, c1, c1, 0 @ Read SCR ++ bic r5, r5, #1 @ Secure mode ++ mcr p15, 0, r5, c1, c1, 0 @ Write SCR ++ isb ++ ++ mrc p15, 0, r4, c0, c0, 5 @ MPIDR ++ and r4, r4, #3 @ cpu number in cluster ++ mov r5, #400 @ 1kB of stack per CPU ++ mul r4, r4, r5 ++ ++ adr r5, text_end @ end of text ++ add r5, r5, #0x2000 @ Skip two pages ++ lsr r5, r5, #12 @ Align to start of page ++ lsl r5, r5, #12 ++ sub sp, r5, r4 @ here's our stack! ++ ++ bx lr ++ ++ @ r1 = target CPU ++ @ r2 = target PC ++.globl psci_cpu_on ++psci_cpu_on: ++ adr r0, _target_pc ++ str r2, [r0] ++ dsb ++ ++ movw r0, #(SUNXI_CPUCFG_BASE & 0xffff) ++ movt r0, #(SUNXI_CPUCFG_BASE >> 16) ++ ++ @ CPU mask ++ and r1, r1, #3 @ only care about first cluster ++ mov r4, #1 ++ lsl r4, r4, r1 ++ ++ adr r6, _sunxi_cpu_entry ++ str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) ++ ++ @ Assert reset on target CPU ++ mov r6, #0 ++ lsl r5, r1, #6 @ 64 bytes per CPU ++ add r5, r5, #0x40 @ Offset from base ++ add r5, r5, r0 @ CPU control block ++ str r6, [r5] @ Reset CPU ++ ++ @ l1 invalidate ++ ldr r6, [r0, #0x184] ++ bic r6, r6, r4 ++ str r6, [r0, #0x184] ++ ++ @ Lock CPU ++ ldr r6, [r0, #0x1e4] ++ bic r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ @ Release power clamp ++ movw r6, #0x1ff ++ movt r6, #0 ++1: lsrs r6, r6, #1 ++ str r6, [r0, #0x1b0] ++ bne 1b ++ ++ timer_wait r1, TEN_MS ++ ++ @ Clear power gating ++ ldr r6, [r0, #0x1b4] ++ bic r6, r6, #1 ++ str r6, [r0, #0x1b4] ++ ++ @ Deassert reset on target CPU ++ mov r6, #3 ++ str r6, [r5] ++ ++ @ Unlock CPU ++ ldr r6, [r0, #0x1e4] ++ orr r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS ++ mov pc, lr ++ ++_target_pc: ++ .word 0 ++ ++_sunxi_cpu_entry: ++ @ Set SMP bit ++ mrc p15, 0, r0, c1, c0, 1 ++ orr r0, r0, #0x40 ++ mcr p15, 0, r0, c1, c0, 1 ++ isb ++ ++ bl _nonsec_init ++ bl psci_arch_init ++ ++ adr r0, _target_pc ++ ldr r0, [r0] ++ b _do_nonsec_entry ++ ++text_end: ++ .popsection +diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h +index 11cc9ea..bae7b37 100644 +--- a/include/configs/sun7i.h ++++ b/include/configs/sun7i.h +@@ -22,6 +22,12 @@ + #define CONFIG_BOARD_POSTCLK_INIT 1 + #endif + ++#define CONFIG_ARMV7_VIRT 1 ++#define CONFIG_ARMV7_NONSEC 1 ++#define CONFIG_ARMV7_PSCI 1 ++#define CONFIG_ARMV7_PSCI_NR_CPUS 2 ++#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE ++ + /* + * Include common sunxi configuration where most the settings are + */ +From a74a847c3727209a45c30a80c01b930938941dd4 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:18 +0000 +Subject: [PATCH] sunxi: HYP/non-sec: configure CNTFRQ on all CPUs + +CNTFRQ needs to be properly configured on all CPUs. Otherwise, +virtual machines hoping to find valuable information on secondary +CPUs will be disapointed... + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + include/configs/sun7i.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h +index bae7b37..58a254b 100644 +--- a/include/configs/sun7i.h ++++ b/include/configs/sun7i.h +@@ -27,6 +27,7 @@ + #define CONFIG_ARMV7_PSCI 1 + #define CONFIG_ARMV7_PSCI_NR_CPUS 2 + #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE ++#define CONFIG_SYS_CLK_FREQ 24000000 + + /* + * Include common sunxi configuration where most the settings are diff --git a/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch b/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch new file mode 100644 index 0000000..6bc8c93 --- /dev/null +++ b/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch @@ -0,0 +1,20 @@ +diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c +index e7ff952..f58c963 100644 +--- a/board/sunxi/gmac.c ++++ b/board/sunxi/gmac.c +@@ -24,6 +24,15 @@ int sunxi_gmac_initialize(bd_t *bis) + CCM_GMAC_CTRL_GPIT_MII); + #endif + ++ /* ++ * HdG: this is necessary to get GMAC to work reliable on the ++ * Bananapi. We don't know what these undocumented bits do, so this ++ * is a Bananapi specific hack for now. ++ */ ++#ifdef CONFIG_BANANAPI ++ setbits_le32(&ccm->gmac_clk_cfg, 0x3 << 10); ++#endif ++ + /* Configure pin mux settings for GMAC */ + for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { + #ifdef CONFIG_RGMII
hooks/post-receive -- IPFire 2.x development tree