summaryrefslogtreecommitdiff
path: root/package/boot/uboot-sunxi/patches/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/boot/uboot-sunxi/patches/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch')
-rw-r--r--package/boot/uboot-sunxi/patches/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch10002
1 files changed, 10002 insertions, 0 deletions
diff --git a/package/boot/uboot-sunxi/patches/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch b/package/boot/uboot-sunxi/patches/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch
new file mode 100644
index 0000000..15aac6b
--- /dev/null
+++ b/package/boot/uboot-sunxi/patches/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, &regs->mac_madr);
++
++ /* pull up the phy io line */
++ writel(0x1, &regs->mac_mcmd);
++
++ /* Wait read complete */
++ mdelay(1);
++
++ /* push down the phy io line */
++ writel(0x0, &regs->mac_mcmd);
++
++ /* and write data */
++ *value = readl(&regs->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, &regs->mac_madr);
++
++ /* pull up the phy io line */
++ writel(0x1, &regs->mac_mcmd);
++
++ /* Wait write complete */
++ mdelay(1);
++
++ /* push down the phy io line */
++ writel(0x0, &regs->mac_mcmd);
++
++ /* and write data */
++ writel(value, &regs->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, &regs->tx_mode);
++
++ /* Set up RX */
++ writel(EMAC_RX_SETUP, &regs->rx_ctl);
++
++ /* Set MAC */
++ /* Set MAC CTL0 */
++ writel(EMAC_MAC_CTL0_SETUP, &regs->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, &regs->mac_ctl1);
++
++ /* Set up IPGT */
++ writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
++
++ /* Set up IPGR */
++ writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
++
++ /* Set up Collison window */
++ writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
++
++ /* Set up Max Frame Length */
++ writel(EMAC_MAC_MFL, &regs->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, &regs->ctl);
++ udelay(200);
++
++ writel(1, &regs->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(&regs->rx_ctl, 0x8);
++ udelay(1);
++
++ /* Init MAC */
++
++ /* Soft reset MAC */
++ clrbits_le32(&regs->mac_ctl0, 0x1 << 15);
++
++ /* Clear RX counter */
++ writel(0x0, &regs->rx_fbc);
++ udelay(1);
++
++ /* Set up EMAC */
++ emac_setup(dev);
++
++ writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
++ dev->enetaddr[2], &regs->mac_a1);
++ writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
++ dev->enetaddr[5], &regs->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(&regs->mac_supp, 1 << 8,
++ ((phy_reg & (0x1 << 13)) >> 13) << 8);
++
++ /* Set duplex depend on phy */
++ clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
++ ((phy_reg & (0x1 << 8)) >> 8) << 0);
++
++ /* Enable RX/TX */
++ setbits_le32(&regs->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(&regs->rx_fbc);
++ if (!rxcount) {
++ /* Had one stuck? */
++ rxcount = readl(&regs->rx_fbc);
++ if (!rxcount)
++ return 0;
++ }
++
++ reg_val = readl(&regs->rx_io_data);
++ if (reg_val != 0x0143414d) {
++ /* Disable RX */
++ clrbits_le32(&regs->ctl, 0x1 << 2);
++
++ /* Flush RX FIFO */
++ setbits_le32(&regs->rx_ctl, 0x1 << 3);
++ while (readl(&regs->rx_ctl) & (0x1 << 3))
++ ;
++
++ /* Enable RX */
++ setbits_le32(&regs->ctl, 0x1 << 2);
++
++ return 0;
++ }
++
++ /* A packet ready now
++ * Get status/length
++ */
++ good_packet = 1;
++
++ emac_inblk_32bit(&regs->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 *)&regs->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, &regs->tx_ins);
++
++ /* Write packet */
++ emac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
++
++ /* Set TX len */
++ writel(len, &regs->tx_pl0);
++
++ /* Start translate from fifo to phy */
++ setbits_le32(&regs->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(&regs->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, &regs->mac_madr);
+-
+- /* pull up the phy io line */
+- writel(0x1, &regs->mac_mcmd);
+-
+- /* Wait read complete */
+- mdelay(1);
+-
+- /* push down the phy io line */
+- writel(0x0, &regs->mac_mcmd);
+-
+- /* and write data */
+- *value = readl(&regs->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, &regs->mac_madr);
+-
+- /* pull up the phy io line */
+- writel(0x1, &regs->mac_mcmd);
+-
+- /* Wait write complete */
+- mdelay(1);
+-
+- /* push down the phy io line */
+- writel(0x0, &regs->mac_mcmd);
+-
+- /* and write data */
+- writel(value, &regs->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, &regs->tx_mode);
+-
+- /* Set up RX */
+- writel(EMAC_RX_SETUP, &regs->rx_ctl);
+-
+- /* Set MAC */
+- /* Set MAC CTL0 */
+- writel(EMAC_MAC_CTL0_SETUP, &regs->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, &regs->mac_ctl1);
+-
+- /* Set up IPGT */
+- writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
+-
+- /* Set up IPGR */
+- writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
+-
+- /* Set up Collison window */
+- writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
+-
+- /* Set up Max Frame Length */
+- writel(EMAC_MAC_MFL, &regs->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, &regs->ctl);
+- udelay(200);
+-
+- writel(1, &regs->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(&regs->rx_ctl, 0x8);
+- udelay(1);
+-
+- /* Init MAC */
+-
+- /* Soft reset MAC */
+- clrbits_le32(&regs->mac_ctl0, 1 << 15);
+-
+- /* Set MII clock */
+- clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
+-
+- /* Clear RX counter */
+- writel(0x0, &regs->rx_fbc);
+- udelay(1);
+-
+- /* Set up EMAC */
+- emac_setup(dev);
+-
+- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
+- dev->enetaddr[2], &regs->mac_a1);
+- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
+- dev->enetaddr[5], &regs->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(&regs->mac_supp, 1 << 8,
+- ((phy_reg & (1 << 13)) >> 13) << 8);
+-
+- /* Set duplex depend on phy */
+- clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
+- ((phy_reg & (1 << 8)) >> 8) << 0);
+-
+- /* Enable RX/TX */
+- setbits_le32(&regs->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(&regs->rx_fbc);
+- if (!rxcount) {
+- /* Had one stuck? */
+- rxcount = readl(&regs->rx_fbc);
+- if (!rxcount)
+- return 0;
+- }
+-
+- reg_val = readl(&regs->rx_io_data);
+- if (reg_val != 0x0143414d) {
+- /* Disable RX */
+- clrbits_le32(&regs->ctl, 1 << 2);
+-
+- /* Flush RX FIFO */
+- setbits_le32(&regs->rx_ctl, 1 << 3);
+- while (readl(&regs->rx_ctl) & (1 << 3))
+- ;
+-
+- /* Enable RX */
+- setbits_le32(&regs->ctl, 1 << 2);
+-
+- return 0;
+- }
+-
+- /*
+- * A packet ready now
+- * Get status/length
+- */
+- good_packet = 1;
+-
+- wemac_inblk_32bit(&regs->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 *)&regs->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, &regs->tx_ins);
+-
+- /* Write packet */
+- wemac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
+-
+- /* Set TX len */
+- writel(len, &regs->tx_pl0);
+-
+- /* Start translate from fifo to phy */
+- setbits_le32(&regs->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, &current)) == 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, &current)) == 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, &reg);
++ 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, &reg);
++ 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.