From: Zoltan Herpai Date: Wed, 30 Apr 2014 19:37:56 +0000 (+0000) Subject: uboot-sunxi: add support for LinkSprite pcDuino v3 (a20) X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=9ee3edb4ca61b55af3bf730d1109aaa82c329732;p=openwrt%2Fstaging%2Frmilecki.git uboot-sunxi: add support for LinkSprite pcDuino v3 (a20) Signed-off-by: Zoltan HERPAI SVN-Revision: 40605 --- diff --git a/package/boot/uboot-sunxi/Makefile b/package/boot/uboot-sunxi/Makefile index e6ed23bd6d8..35b647e0d44 100644 --- a/package/boot/uboot-sunxi/Makefile +++ b/package/boot/uboot-sunxi/Makefile @@ -56,7 +56,11 @@ define uboot/pcDuino TITLE:=U-Boot 2014.01-rc1 for pcDuino endef -UBOOTS:=A10-OLinuXino-Lime A13-OLinuXino A20-OLinuXino_MICRO Cubieboard Cubieboard2 Cubietruck Hackberry pcDuino +define uboot/pcDuino3 + TITLE:=U-Boot 2014.01-rc1 for pcDuino3 +endef + +UBOOTS:=A10-OLinuXino-Lime A13-OLinuXino A20-OLinuXino_MICRO Cubieboard Cubieboard2 Cubietruck Hackberry pcDuino pcDuino3 define Package/uboot/template define Package/uboot-sunxi-$(1) diff --git a/package/boot/uboot-sunxi/patches/001-zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch b/package/boot/uboot-sunxi/patches/001-zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch new file mode 100644 index 00000000000..c3aed2163f2 --- /dev/null +++ b/package/boot/uboot-sunxi/patches/001-zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch @@ -0,0 +1,10772 @@ +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/cmd_boot.c u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.108100778 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * 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 ++ */ ++ ++/* ++ * Misc boot support ++ */ ++#include ++#include ++ ++#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.01-rc1/arch/arm/cpu/armv7/Makefile u-boot-sunxi/arch/arm/cpu/armv7/Makefile +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/Makefile 2014-03-05 23:14:47.108100778 +0100 +@@ -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),) ++ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_SUNXI),) + ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) + obj-y += lowlevel_init.o + endif +@@ -21,6 +22,11 @@ + ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),) + obj-y += nonsec_virt.o + obj-y += virt-v7.o ++obj-y += virt-dt.o ++endif ++ ++ifneq ($(CONFIG_ARMV7_PSCI),) ++obj-y += psci.o + endif + + obj-$(CONFIG_OMAP_COMMON) += omap-common/ +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/nonsec_virt.S u-boot-sunxi/arch/arm/cpu/armv7/nonsec_virt.S +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/nonsec_virt.S 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/nonsec_virt.S 2014-03-05 23:14:47.116100672 +0100 +@@ -10,10 +10,15 @@ + #include + #include + #include ++#include + + .arch_extension sec + .arch_extension virt + ++ .pushsection ._secure.text, "ax" ++ ++ .align 5 @ Minimal alignment for vectors ++ + /* the vector table for secure state and HYP mode */ + _monitor_vectors: + .word 0 /* reset */ +@@ -21,44 +26,92 @@ + adr pc, _secure_monitor + .word 0 + .word 0 +- adr pc, _hyp_trap + .word 0 + .word 0 ++ .word 0 ++ ++.macro is_cpu_virt_capable tmp ++ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1 ++ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits ++ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT) ++.endm + + /* + * secure monitor handler + * U-boot calls this "software interrupt" in start.S + * This is executed on a "smc" instruction, we use a "smc #0" to switch + * to non-secure state. +- * We use only r0 and r1 here, due to constraints in the caller. ++ * r0, r1, r2: passed to the callee ++ * ip: target PC + */ +- .align 5 + _secure_monitor: +- mrc p15, 0, r1, c1, c1, 0 @ read SCR +- bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits +- orr r1, r1, #0x31 @ enable NS, AW, FW bits +- +-#ifdef CONFIG_ARMV7_VIRT +- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 +- and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits +- cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) +- orreq r1, r1, #0x100 @ allow HVC instruction ++#ifdef CONFIG_ARMV7_PSCI ++ ldr r5, =_psci_vectors @ Switch to the next monitor ++ mcr p15, 0, r5, c12, c0, 1 ++ isb + #endif + +- mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) ++ mrc p15, 0, r5, c1, c1, 0 @ read SCR ++ bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits ++ orr r5, r5, #0x31 @ enable NS, AW, FW bits + ++ mov r6, #SVC_MODE @ default mode is SVC ++ is_cpu_virt_capable r4 + #ifdef CONFIG_ARMV7_VIRT +- mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value +- mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR ++ orreq r5, r5, #0x100 @ allow HVC instruction ++ moveq r6, #HYP_MODE @ Enter the kernel as HYP + #endif + +- movs pc, lr @ return to non-secure SVC ++ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set) ++ isb ++ ++ bne 1f ++ ++ @ Reset CNTVOFF to 0 before leaving monitor mode ++ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1 ++ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits ++ movne r4, #0 ++ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero ++1: ++ mov lr, ip ++ mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F ++ tst lr, #1 @ Check for Thumb PC ++ orrne ip, ip, #T_BIT @ Set T if Thumb ++ orr ip, ip, r6 @ Slot target mode in ++ msr spsr_cxfs, ip @ Set full SPSR ++ movs pc, lr @ ERET to non-secure ++ ++ENTRY(_do_nonsec_entry) ++ mov ip, r0 ++ mov r0, r1 ++ mov r1, r2 ++ mov r2, r3 ++ smc #0 ++ENDPROC(_do_nonsec_entry) ++ ++.macro get_cbar_addr addr ++#ifdef CONFIG_ARM_GIC_BASE_ADDRESS ++ ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS ++#else ++ mrc p15, 4, \addr, c15, c0, 0 @ read CBAR ++ bfc \addr, #0, #15 @ clear reserved bits ++#endif ++.endm + +-_hyp_trap: +- mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1 +- mov pc, lr @ do no switch modes, but +- @ return to caller ++.macro get_gicd_addr addr ++ get_cbar_addr \addr ++ add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset ++.endm ++ ++.macro get_gicc_addr addr, tmp ++ get_cbar_addr \addr ++ is_cpu_virt_capable \tmp ++ movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 ++ moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 ++ add \addr, \addr, \tmp ++.endm + ++#ifndef CONFIG_ARMV7_PSCI + /* + * Secondary CPUs start here and call the code for the core specific parts + * of the non-secure and HYP mode transition. The GIC distributor specific +@@ -66,31 +119,21 @@ + * Then they go back to wfi and wait to be woken up by the kernel again. + */ + ENTRY(_smp_pen) +- mrs r0, cpsr +- orr r0, r0, #0xc0 +- msr cpsr, r0 @ disable interrupts +- ldr r1, =_start +- mcr p15, 0, r1, c12, c0, 0 @ set VBAR ++ cpsid i ++ cpsid f + + bl _nonsec_init +- mov r12, r0 @ save GICC address +-#ifdef CONFIG_ARMV7_VIRT +- bl _switch_to_hyp +-#endif +- +- ldr r1, [r12, #GICC_IAR] @ acknowledge IPI +- str r1, [r12, #GICC_EOIR] @ signal end of interrupt + + adr r0, _smp_pen @ do not use this address again + b smp_waitloop @ wait for IPIs, board specific + ENDPROC(_smp_pen) ++#endif + + /* + * Switch a core to non-secure state. + * + * 1. initialize the GIC per-core interface + * 2. allow coprocessor access in non-secure modes +- * 3. switch the cpu mode (by calling "smc #0") + * + * Called from smp_pen by secondary cores and directly by the BSP. + * Do not assume that the stack is available and only use registers +@@ -100,38 +143,23 @@ + * though, but we check this in C before calling this function. + */ + ENTRY(_nonsec_init) +-#ifdef CONFIG_ARM_GIC_BASE_ADDRESS +- ldr r2, =CONFIG_ARM_GIC_BASE_ADDRESS +-#else +- mrc p15, 4, r2, c15, c0, 0 @ read CBAR +- bfc r2, #0, #15 @ clear reserved bits +-#endif +- add r3, r2, #GIC_DIST_OFFSET @ GIC dist i/f offset ++ get_gicd_addr r3 ++ + mvn r1, #0 @ all bits to 1 + str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts + +- mrc p15, 0, r0, c0, c0, 0 @ read MIDR +- ldr r1, =MIDR_PRIMARY_PART_MASK +- and r0, r0, r1 @ mask out variant and revision +- +- ldr r1, =MIDR_CORTEX_A7_R0P0 & MIDR_PRIMARY_PART_MASK +- cmp r0, r1 @ check for Cortex-A7 +- +- ldr r1, =MIDR_CORTEX_A15_R0P0 & MIDR_PRIMARY_PART_MASK +- cmpne r0, r1 @ check for Cortex-A15 +- +- movne r1, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 +- moveq r1, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 +- add r3, r2, r1 @ r3 = GIC CPU i/f addr ++ get_gicc_addr r3, r1 + + mov r1, #1 @ set GICC_CTLR[enable] + str r1, [r3, #GICC_CTLR] @ and clear all other bits + mov r1, #0xff + str r1, [r3, #GICC_PMR] @ set priority mask register + ++ mrc p15, 0, r0, c1, c1, 2 + movw r1, #0x3fff +- movt r1, #0x0006 +- mcr p15, 0, r1, c1, c1, 2 @ NSACR = all copros to non-sec ++ movt r1, #0x0004 ++ orr r0, r0, r1 ++ mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec + + /* The CNTFRQ register of the generic timer needs to be + * programmed in secure state. Some primary bootloaders / firmware +@@ -149,44 +177,24 @@ + + adr r1, _monitor_vectors + mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors +- +- mrc p15, 0, ip, c12, c0, 0 @ save secure copy of VBAR +- + isb +- smc #0 @ call into MONITOR mode +- +- mcr p15, 0, ip, c12, c0, 0 @ write non-secure copy of VBAR +- +- mov r1, #1 +- str r1, [r3, #GICC_CTLR] @ enable non-secure CPU i/f +- add r2, r2, #GIC_DIST_OFFSET +- str r1, [r2, #GICD_CTLR] @ allow private interrupts + + mov r0, r3 @ return GICC address +- + bx lr + ENDPROC(_nonsec_init) + + #ifdef CONFIG_SMP_PEN_ADDR + /* void __weak smp_waitloop(unsigned previous_address); */ + ENTRY(smp_waitloop) +- wfi ++ wfe + ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address + ldr r1, [r1] + cmp r0, r1 @ make sure we dont execute this code + beq smp_waitloop @ again (due to a spurious wakeup) +- mov pc, r1 ++ mov r0, r1 ++ b _do_nonsec_entry + ENDPROC(smp_waitloop) + .weak smp_waitloop + #endif + +-ENTRY(_switch_to_hyp) +- mov r0, lr +- mov r1, sp @ save SVC copy of LR and SP +- isb +- hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 +- mov sp, r1 +- mov lr, r0 @ restore SVC copy of LR and SP +- +- bx lr +-ENDPROC(_switch_to_hyp) ++ .popsection +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/psci.S u-boot-sunxi/arch/arm/cpu/armv7/psci.S +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/psci.S 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/psci.S 2014-03-05 23:14:47.124100564 +0100 +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++ .align 5 ++ .globl _psci_vectors ++_psci_vectors: ++ adr pc, . @ reset ++ adr pc, . @ undef ++ adr pc, _smc_psci @ smc ++ adr pc, . @ pabort ++ adr pc, . @ dabort ++ adr pc, . @ hyp ++ adr pc, . @ irq ++ adr pc, . @ fiq ++ ++ENTRY(psci_cpu_suspend) ++ENTRY(psci_cpu_off) ++ENTRY(psci_cpu_on) ++ENTRY(psci_migrate) ++ mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) ++ mov pc, lr ++ENDPROC(psci_migrate) ++ENDPROC(psci_cpu_on) ++ENDPROC(psci_cpu_off) ++ENDPROC(psci_cpu_suspend) ++.weak psci_cpu_suspend ++.weak psci_cpu_off ++.weak psci_cpu_on ++.weak psci_migrate ++ ++_psci_table: ++ .word ARM_PSCI_FN_CPU_SUSPEND ++ .word psci_cpu_suspend ++ .word ARM_PSCI_FN_CPU_OFF ++ .word psci_cpu_off ++ .word ARM_PSCI_FN_CPU_ON ++ .word psci_cpu_on ++ .word ARM_PSCI_FN_MIGRATE ++ .word psci_migrate ++ .word 0 ++ .word 0 ++ ++_secure_stacks: @ Enough to save 16 registers per CPU ++ .skip 16*4*CONFIG_ARMV7_PSCI_NR_CPUS ++_secure_stack_base: ++ ++_smc_psci: ++ @ Switch to secure mode ++ mrc p15, 0, sp, c1, c1, 0 ++ bic sp, sp, #1 ++ mcr p15, 0, sp, c1, c1, 0 ++ ++ adr sp, _secure_stack_base ++ mcr p15, 0, r0, c13, c0, 4 @ use TPIDRPRW as a tmp reg ++ mcr p15, 0, r1, c13, c0, 3 @ use TPIDRURO as a tmp reg ++ mrc p15, 0, r0, c0, c0, 5 @ MPIDR ++ and r1, r0, #3 @ cpu number in cluster ++ lsr r0, r0, #8 ++ and r0, r0, #3 @ cluster number ++ mul r1, r1, r0 @ absolute cpu nr ++ sbc sp, sp, r1, lsl #6 @ sp = sp_base - 64*cpunr ++ ++ mrc p15, 0, r0, c13, c0, 4 @ restore r0 ++ mrc p15, 0, r1, c13, c0, 3 @ restore r1 ++ ++ push {r4-r12,lr} ++ ++ adr r4, _psci_table ++1: ldr r5, [r4] @ Load PSCI function ID ++ ldr r6, [r4, #4] @ Load target PC ++ cmp r5, #0 @ If reach the end, bail out ++ mvneq r0, #0 @ Return -1 (Not Implemented) ++ beq 2f ++ cmp r0, r5 @ If not matching, try next entry ++ addne r4, r4, #8 ++ bne 1b ++ cmp r6, #0 @ Not implemented ++ moveq r0, #ARM_PSCI_RET_NI ++ beq 2f ++ ++ blx r6 @ Execute PSCI function ++ ++2: pop {r4-r12, lr} ++ ++ @ Back to non-secure ++ mrc p15, 0, sp, c1, c1, 0 ++ orr sp, sp, #1 ++ mcr p15, 0, sp, c1, c1, 0 ++ movs pc, lr @ Return to the kernel ++ ++ .popsection +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/board.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,158 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Some init for sunxi platform. ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_SPL_BUILD ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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, nannd 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_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPG(4), 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, #0x40\n" ++ "mcr p15, 0, r0, c1, c0, 1\n"); ++#endif ++ ++ watchdog_init(); ++ clock_init(); ++ timer_init(); ++ gpio_init(); ++ ++#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 ++ ++ 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 ++ ++#if defined(CONFIG_SUNXI_EMAC) || defined(CONFIG_SUNXI_GMAC) ++/* ++ * Initializes on-chip ethernet controllers. ++ * to override, implement board_eth_init() ++ */ ++int cpu_eth_init(bd_t *bis) ++{ ++#ifdef CONFIG_SUNXI_EMAC ++ sunxi_emac_initialize(bis); ++#else ++ sunxi_gmac_initialize(bis); ++#endif ++ ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/clock.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,204 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_SPL_BUILD ++static 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 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | ++ CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg); ++ writel(0xa1005000, &ccm->pll1_cfg); ++ sdelay(200); ++ writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | ++ CPU_CLK_SRC_PLL1 << 16, &ccm->cpu_ahb_apb0_cfg); ++#ifdef CONFIG_SUN5I ++ /* Power on reset default for PLL6 is 2400 MHz, which is faster then ++ * it can reliable do :| Set it to a 600 MHz instead. */ ++ writel(0x21009911, &ccm->pll6_cfg); ++#endif ++#ifdef CONFIG_SUN7I ++ writel(0x1 << 6 | readl(&ccm->ahb_gate0), &ccm->ahb_gate0); ++ writel(0x1 << 31 | readl(&ccm->pll6_cfg), &ccm->pll6_cfg); ++#endif ++} ++#endif ++ ++int clock_init(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++#ifdef CONFIG_SPL_BUILD ++ clock_init_safe(); ++#endif ++ ++#if defined(CONFIG_SUN6I) ++ /* uart clock source is apb2 */ ++ sr32(&ccm->apb2_div, 24, 2, APB2_CLK_SRC_OSC24M); ++ sr32(&ccm->apb2_div, 16, 2, APB2_FACTOR_N); ++ sr32(&ccm->apb2_div, 0, 5, APB2_FACTOR_M); ++ ++ /* open the clock for uart */ ++ sr32(&ccm->apb2_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); ++#else ++ /* uart clock source is apb1 */ ++ sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M); ++ sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N); ++ sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M); ++ ++ /* open the clock for uart */ ++ sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); ++#endif ++ ++#ifdef CONFIG_NAND_SUNXI ++ /* nand clock source is osc24m */ ++ sr32(&ccm->nand_sclk_cfg, 24, 2, NAND_CLK_SRC_OSC24); ++ sr32(&ccm->nand_sclk_cfg, 16, 2, NAND_CLK_DIV_N); ++ sr32(&ccm->nand_sclk_cfg, 0, 4, NAND_CLK_DIV_M); ++ sr32(&ccm->nand_sclk_cfg, 31, 1, CLK_GATE_OPEN); ++ /* open clock for nand */ ++ sr32(&ccm->ahb_gate0, AHB_GATE_OFFSET_NAND, 1, CLK_GATE_OPEN); ++#endif ++ ++ return 0; ++} ++ ++/* Return PLL5 frequency in Hz ++ * Note: Assumes PLL5 reference is 24MHz clock ++ */ ++unsigned int clock_get_pll5(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ uint32_t rval = readl(&ccm->pll5_cfg); ++ int n = (rval >> 8) & 0x1f; ++ int k = ((rval >> 4) & 3) + 1; ++ int p = 1 << ((rval >> 16) & 3); ++ return 24000000 * n * k / p; ++} ++ ++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 apb1 clock gate for twi */ ++ sr32(&ccm->apb1_gate, 0 + port, 1, state); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SPL_BUILD ++#define PLL1_CFG(N, K, M, P) (1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \ ++ 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \ ++ (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0) ++#define RDIV(a, b) ((a + (b) - 1) / (b)) ++ ++struct { ++ u32 pll1_cfg; ++ unsigned int freq; ++} pll1_para[] = { ++ { 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}, ++ { PLL1_CFG(31, 1, 0, 0), ~0}, ++}; ++ ++void clock_set_pll1(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 = RDIV(hz, 432000000); /* Max 450MHz */ ++ ahb = RDIV(hz/axi, 204000000); /* Max 250MHz */ ++ apb0 = 2; /* Max 150MHz */ ++ ++ printf("CPU: %dHz, 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 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | ++ CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++ ++ /* Configure sys clock divisors */ ++ writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_OSC24M << 16, ++ &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 << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_PLL1 << 16, ++ &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++} ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++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.01-rc1/arch/arm/cpu/armv7/sunxi/config.mk u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,8 @@ ++# Build a combined spl + u-boot image ++ifdef CONFIG_SPL ++ifndef CONFIG_SPL_BUILD ++ifndef CONFIG_SPL_FEL ++ALL-y = $(obj)u-boot-sunxi-with-spl.bin ++endif ++endif ++endif +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/cpu_info.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,47 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++#ifdef CONFIG_DISPLAY_CPUINFO ++int print_cpuinfo(void) ++{ ++#ifdef CONFIG_SUN4I ++ puts("CPU: Allwinner A10 (SUN4I)\n"); ++#elif defined CONFIG_SUN5I ++ /* TODO: Distinguish A13/A10s */ ++ puts("CPU: Allwinner A13/A10s (SUN5I)\n"); ++#elif defined CONFIG_SUN6I ++ puts("CPU: Allwinner A31 (SUN6I)\n"); ++#elif defined CONFIG_SUN7I ++ puts("CPU: Allwinner A20 (SUN7I)\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.01-rc1/arch/arm/cpu/armv7/sunxi/dram.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,679 @@ ++/* ++ * sunxi DRAM controller initialization ++ * (C) Copyright 2012 Henrik Nordstrom ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton ++ * ++ * 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. ++ * Berg Xing ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++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++) { ++#ifdef CONFIG_SUN7I ++ clrsetbits_le32(&dram->dllcr[i], 0xf << 14, ++#else ++ clrsetbits_le32(&dram->dllcr[i], 0x4 << 14, ++#endif ++ (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, 0x1035, ++ 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_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */ ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); ++ reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); ++ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ ++ 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 ++ ++ /* 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); ++ ++ /* ++ * 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 */ ++ while (readl(&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 ++} ++ ++#ifdef CONFIG_SUN4I ++static void dramc_set_autorefresh_cycle(u32 clk) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ u32 tmp_val; ++ u32 reg_dcr; ++ ++ if (clk < 600) { ++ reg_dcr = readl(&dram->dcr); ++ if ((reg_dcr & DRAM_DCR_CHIP_DENSITY_MASK) <= ++ DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_1024M)) ++ reg_val = (131 * clk) >> 10; ++ else ++ reg_val = (336 * clk) >> 10; ++ ++ tmp_val = (7987 * clk) >> 10; ++ tmp_val = tmp_val * 9 - 200; ++ reg_val |= tmp_val << 8; ++ reg_val |= 0x8 << 24; ++ writel(reg_val, &dram->drr); ++ } else { ++ writel(0x0, &dram->drr); ++ } ++} ++#endif /* SUN4I */ ++ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++static void dramc_set_autorefresh_cycle(u32 clk) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ u32 tmp_val; ++ reg_val = 0x83; ++ ++ tmp_val = (7987 * clk) >> 10; ++ tmp_val = tmp_val * 9 - 200; ++ reg_val |= tmp_val << 8; ++ reg_val |= 0x8 << 24; ++ writel(reg_val, &dram->drr); ++} ++#endif /* SUN5I */ ++ ++unsigned long dramc_init(struct dram_para *para) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ 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) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_256M); ++ else if (para->density == 512) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_512M); ++ else if (para->density == 1024) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_1024M); ++ else if (para->density == 2048) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_2048M); ++ else if (para->density == 4096) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_4096M); ++ else if (para->density == 8192) ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_8192M); ++ else ++ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_256M); ++ ++ 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); ++ ++ while (readl(&dram->ccr) & DRAM_CCR_INIT); ++ ++ mctl_enable_dllx(para->tpr3); ++ ++#ifdef CONFIG_SUN4I ++ /* 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_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); ++ ++ /* 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); ++ while (readl(&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 */ ++ while (readl(&dram->dcr) & (0x1 << 31)); ++ ++ udelay(2); ++ ++ /* dram pad hold off */ ++ setbits_le32(&dram->ppwrsctl, 0x16510000); ++ ++ while (readl(&dram->ppwrsctl) & 0x1); ++ ++ /* exit self-refresh state */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); ++ ++ /* check whether command has been executed */ ++ while (readl(&dram->dcr) & (0x1 << 31)); ++ udelay(2);; ++ ++ /* issue a refresh command */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27); ++ while (readl(&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((unsigned long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/early_print.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,65 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Early uart print for debugging. ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int uart_initialized = 0; ++ ++#define UART CONFIG_CONS_INDEX-1 ++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.01-rc1/arch/arm/cpu/armv7/sunxi/key.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/key.c +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/key.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/key.c 2014-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,70 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int sunxi_key_init(void) ++{ ++ struct sunxi_lradc *sunxi_key_base = ++ (struct sunxi_lradc *)SUNXI_LRADC_BASE; ++ ++ sr32(&sunxi_key_base->ctrl, 0, 1, LRADC_EN); ++ sr32(&sunxi_key_base->ctrl, 2, 2, LRADC_SAMPLE_RATE); ++ sr32(&sunxi_key_base->ctrl, 4, 2, LEVELB_VOL); ++ sr32(&sunxi_key_base->ctrl, 6, 1, LRADC_HOLD_EN); ++ sr32(&sunxi_key_base->ctrl, 12, 2, KEY_MODE_SELECT); ++ ++ /* disable all key irq */ ++ writel(0x0, &sunxi_key_base->intc); ++ /* clear all key pending */ ++ writel(0xffffffff, &sunxi_key_base->ints); ++ ++ return 0; ++} ++ ++u32 sunxi_read_key(void) ++{ ++ u32 ints; ++ u32 key = 0; ++ struct sunxi_lradc *sunxi_key_base = ++ (struct sunxi_lradc *)SUNXI_LRADC_BASE; ++ ++ ints = readl(&sunxi_key_base->ints); ++ ++ /* if there is already data pending, ++ read it */ ++ if (ints & ADC0_DATA_PENDING) { ++ key = readl(&sunxi_key_base->data0); ++#ifdef DEBUG ++ printf("key pressed, value=0x%x\n", key); ++#endif ++ } ++ /* clear the pending data */ ++ writel(ints, &sunxi_key_base->ints); ++ return key; ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/Makefile u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile 2014-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,56 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom ++# ++# Based on some other Makefile ++# (C) Copyright 2000-2003 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# 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 ++# ++ ++obj-y += timer.o ++obj-y += board.o ++obj-y += clock.o ++obj-y += pinmux.o ++obj-y += watchdog.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 += key.o ++obj-y += cpu_info.o ++ifdef CONFIG_CMD_WATCHDOG ++obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o ++endif ++ifdef CONFIG_ARMV7_PSCI ++obj-y += psci.o ++endif ++endif ++ ++ifdef CONFIG_SPL_BUILD ++obj-y += dram.o ++ifdef CONFIG_SPL_FEL ++obj-y += start.o ++endif ++endif ++ +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/pinmux.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,96 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++int sunxi_gpio_set_cfgpin(u32 pin, u32 val) ++{ ++ u32 cfg; ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_CFG_INDEX(pin); ++ u32 offset = GPIO_CFG_OFFSET(pin); ++ struct sunxi_gpio *pio = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; ++ ++ cfg = readl(&pio->cfg[0] + index); ++ cfg &= ~(0xf << offset); ++ cfg |= val << offset; ++ ++ writel(cfg, &pio->cfg[0] + index); ++ ++ 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 = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; ++ ++ cfg = readl(&pio->cfg[0] + index); ++ cfg >>= offset; ++ ++ return cfg & 0xf; ++} ++ ++int sunxi_gpio_set_drv(u32 pin, u32 val) ++{ ++ u32 drv; ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_DRV_INDEX(pin); ++ u32 offset = GPIO_DRV_OFFSET(pin); ++ struct sunxi_gpio *pio = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; ++ ++ drv = readl(&pio->drv[0] + index); ++ drv &= ~(0x3 << offset); ++ drv |= val << offset; ++ ++ writel(drv, &pio->drv[0] + index); ++ ++ return 0; ++} ++ ++int sunxi_gpio_set_pull(u32 pin, u32 val) ++{ ++ u32 pull; ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_PULL_INDEX(pin); ++ u32 offset = GPIO_PULL_OFFSET(pin); ++ struct sunxi_gpio *pio = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; ++ ++ pull = readl(&pio->pull[0] + index); ++ pull &= ~(0x3 << offset); ++ pull |= val << offset; ++ ++ writel(pull, &pio->pull[0] + index); ++ ++ return 0; ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/postclk_init.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik ++ * ++ * 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 ++ */ ++ ++#include ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#include ++#endif ++ ++ ++int board_postclk_init(void) ++{ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++ startup_secondaries(); ++#endif ++ return 0; ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/psci.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/psci.S +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/psci.S 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/psci.S 2014-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,124 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier ++ * ++ * Based on code by Carl van Schaik . ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++#define TEN_MS (10 * CONFIG_SYS_CLK_FREQ / 1000) ++ ++ @ r1 = target CPU ++ @ r2 = target PC ++.globl psci_cpu_on ++psci_cpu_on: ++ adr r0, _target_pc ++ str r2, [r0] ++ dsb ++ ++ movw r0, #(SUNXI_CPUCFG_BASE & 0xffff) ++ movt r0, #(SUNXI_CPUCFG_BASE >> 16) ++ ++ @ CPU mask ++ and r1, r1, #3 @ only care about first cluster ++ mov r4, #1 ++ lsl r4, r4, r1 ++ ++ adr r6, _sunxi_cpu_entry ++ str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) ++ ++ @ Assert reset on target CPU ++ mov r6, #0 ++ lsl r5, r1, #6 @ 64 bytes per CPU ++ add r5, r5, #0x40 @ Offset from base ++ add r5, r5, r0 @ CPU control block ++ str r6, [r5] @ Reset CPU ++ ++ @ l1 invalidate ++ ldr r6, [r0, #0x184] ++ bic r6, r6, r4 ++ str r6, [r0, #0x184] ++ ++ @ Lock CPU ++ ldr r6, [r0, #0x1e4] ++ bic r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ @ Release power clamp ++ movw r6, #0x1ff ++ movt r6, #0 ++1: lsrs r6, r6, #1 ++ str r6, [r0, #0x1b0] ++ bne 1b ++ ++ @ Write CNTP_TVAL : 10ms @ 24MHz (240000 cycles) ++ movw r1, #(TEN_MS & 0xffff) ++ movt r1, #(TEN_MS >> 16) ++ mcr p15, 0, r1, c14, c2, 0 ++ isb ++ @ Enable physical timer, mask interrupt ++ mov r1, #3 ++ mcr p15, 0, r1, c14, c2, 1 ++ @ Poll physical timer until ISTATUS is on ++1: isb ++ mrc p15, 0, r1, c14, c2, 1 ++ ands r1, r1, #4 ++ bne 1b ++ @ Disable timer ++ mov r1, #0 ++ mcr p15, 0, r1, c14, c2, 1 ++ isb ++ ++ @ Clear power gating ++ ldr r6, [r0, #0x1b4] ++ bic r6, r6, #1 ++ str r6, [r0, #0x1b4] ++ ++ @ Deassert reset on target CPU ++ mov r6, #3 ++ str r6, [r5] ++ ++ @ Unlock CPU ++ ldr r6, [r0, #0x1e4] ++ orr r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS ++ mov pc, lr ++ ++_target_pc: ++ .word 0 ++ ++_sunxi_cpu_entry: ++ @ Set SMP bit ++ mrc p15, 0, r0, c1, c0, 1 ++ orr r0, r0, #0x40 ++ mcr p15, 0, r0, c1, c0, 1 ++ isb ++ ++ bl _nonsec_init ++ ++ adr r0, _target_pc ++ ldr r0, [r0] ++ b _do_nonsec_entry ++ ++ .popsection +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/secondary_init.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,48 @@ ++/* ++ * A lowlevel_init function that sets up the stack to call a C function to ++ * perform further init. ++ * ++ * (C) Copyright 2013 ++ * Carl van Schaik ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++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.01-rc1/arch/arm/cpu/armv7/sunxi/smp.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1,96 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* 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.01-rc1/arch/arm/cpu/armv7/sunxi/start.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 +@@ -0,0 +1 @@ ++/* Intentionally empty. Only needed to get FEL SPL link line right */ +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/timer.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,120 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++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 */ ++ ++static struct sunxi_timer *timer_base = ++ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->timer[TIMER_NUM]; ++ ++/* macro to read the 32 bit timer: since it decrements, we invert read value */ ++#define READ_TIMER() (~readl(&timer_base->val)) ++ ++/* init timer register */ ++int timer_init(void) ++{ ++ writel(TIMER_LOAD_VAL, &timer_base->inter); ++ writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN, ++ &timer_base->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) ++{ ++ ulong tbclk; ++ tbclk = CONFIG_SYS_HZ; ++ return tbclk; ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds 2014-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,63 @@ ++/* ++ * (C) Copyright 2013 ARM Ltd ++ * Marc Zyngier ++ * ++ * Based on sunxi/u-boot-spl.lds: ++ * ++ * (C) Copyright 2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Based on omap-common/u-boot-spl.lds: ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, ++ * ++ * (C) Copyright 2010 ++ * Texas Instruments, ++ * Aneesh V ++ * ++ * 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 ++ */ ++ ++MEMORY { sram : ORIGIN = CONFIG_ARMV7_PSCI_BASE, LENGTH = 0x1000 } ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(_start) ++SECTIONS ++{ ++ .text : ++ { ++ _start = .; ++ *(.text*) ++ } > sram ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > sram ++ ++ . = ALIGN(4); ++ .data : { *(SORT_BY_ALIGNMENT(.data*)) } > sram ++ ++ . = ALIGN(4); ++ _end = .; ++ ++ /DISCARD/ : { ++ *(.bss*) ++ } ++} +diff -ruN u-boot-2014.01-rc1/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.01-rc1/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-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,59 @@ ++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.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds +--- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,69 @@ ++/* ++ * (C) Copyright 2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Based on omap-common/u-boot-spl.lds: ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, ++ * ++ * (C) Copyright 2010 ++ * Texas Instruments, ++ * Aneesh V ++ * ++ * 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 ++ */ ++ ++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.01-rc1/arch/arm/cpu/armv7/sunxi/watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,96 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl ++ * http://www.linux-sunxi.org/ ++ * ++ * 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., 51 Franklin Street, Fifth Floor, Boston, ++ * MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++#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.01-rc1/arch/arm/cpu/armv7/virt-dt.c u-boot-sunxi/arch/arm/cpu/armv7/virt-dt.c +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-dt.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/virt-dt.c 2014-03-05 23:14:47.132100458 +0100 +@@ -0,0 +1,100 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int fdt_psci(void *fdt) ++{ ++#ifdef CONFIG_ARMV7_PSCI ++ int nodeoff; ++ int tmp; ++ ++ nodeoff = fdt_path_offset(fdt, "/cpus"); ++ if (nodeoff < 0) { ++ printf("couldn't find /cpus\n"); ++ return nodeoff; ++ } ++ ++ /* add 'enable-method = "psci"' to each cpu node */ ++ for (tmp = fdt_first_subnode(fdt, nodeoff); ++ tmp >= 0; ++ tmp = fdt_next_subnode(fdt, tmp)) { ++ const struct fdt_property *prop; ++ int len; ++ ++ prop = fdt_get_property(fdt, tmp, "device_type", &len); ++ if (!prop) ++ continue; ++ if (len < 4) ++ continue; ++ if (strcmp(prop->data, "cpu")) ++ continue; ++ ++ fdt_setprop_string(fdt, tmp, "enable-method", "psci"); ++ } ++ ++ nodeoff = fdt_path_offset(fdt, "/psci"); ++ if (nodeoff < 0) { ++ nodeoff = fdt_path_offset(fdt, "/"); ++ if (nodeoff < 0) ++ return nodeoff; ++ ++ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); ++ if (nodeoff < 0) ++ return nodeoff; ++ } ++ ++ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); ++ if (tmp) ++ return tmp; ++#endif ++ return 0; ++} ++ ++int armv7_update_dt(void *fdt) ++{ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++ /* secure code lives in RAM, keep it alive */ ++ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, ++ __secure_end - __secure_start); ++#endif ++ ++ return fdt_psci(fdt); ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-v7.c u-boot-sunxi/arch/arm/cpu/armv7/virt-v7.c +--- u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-v7.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/virt-v7.c 2014-03-05 23:14:47.132100458 +0100 +@@ -13,17 +13,10 @@ + #include + #include + #include ++#include + + unsigned long gic_dist_addr; + +-static unsigned int read_cpsr(void) +-{ +- unsigned int reg; +- +- asm volatile ("mrs %0, cpsr\n" : "=r" (reg)); +- return reg; +-} +- + static unsigned int read_id_pfr1(void) + { + unsigned int reg; +@@ -72,6 +65,18 @@ + #endif + } + ++static void relocate_secure_section(void) ++{ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++ size_t sz = __secure_end - __secure_start; ++ ++ memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz); ++ flush_dcache_range(CONFIG_ARMV7_SECURE_BASE, ++ CONFIG_ARMV7_SECURE_BASE + sz + 1); ++ invalidate_icache_all(); ++#endif ++} ++ + static void kick_secondary_cpus_gic(unsigned long gicdaddr) + { + /* kick all CPUs (except this one) by writing to GICD_SGIR */ +@@ -83,35 +88,7 @@ + kick_secondary_cpus_gic(gic_dist_addr); + } + +-int armv7_switch_hyp(void) +-{ +- unsigned int reg; +- +- /* check whether we are in HYP mode already */ +- if ((read_cpsr() & 0x1f) == 0x1a) { +- debug("CPU already in HYP mode\n"); +- return 0; +- } +- +- /* check whether the CPU supports the virtualization extensions */ +- reg = read_id_pfr1(); +- if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) { +- printf("HYP mode: Virtualization extensions not implemented.\n"); +- return -1; +- } +- +- /* call the HYP switching code on this CPU also */ +- _switch_to_hyp(); +- +- if ((read_cpsr() & 0x1F) != 0x1a) { +- printf("HYP mode: switch not successful.\n"); +- return -1; +- } +- +- return 0; +-} +- +-int armv7_switch_nonsec(void) ++int armv7_init_nonsec(void) + { + unsigned int reg; + unsigned itlinesnr, i; +@@ -147,11 +124,13 @@ + for (i = 1; i <= itlinesnr; i++) + writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); + +- smp_set_core_boot_addr((unsigned long)_smp_pen, -1); ++#ifndef CONFIG_ARMV7_PSCI ++ smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1); + smp_kick_all_cpus(); ++#endif + + /* call the non-sec switching code on this CPU also */ +- _nonsec_init(); +- ++ relocate_secure_section(); ++ secure_ram_addr(_nonsec_init)(); + return 0; + } +diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/u-boot.lds u-boot-sunxi/arch/arm/cpu/u-boot.lds +--- u-boot-2014.01-rc1/arch/arm/cpu/u-boot.lds 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/u-boot.lds 2014-03-05 23:14:47.136100405 +0100 +@@ -7,6 +7,8 @@ + * SPDX-License-Identifier: GPL-2.0+ + */ + ++#include ++ + OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") + OUTPUT_ARCH(arm) + ENTRY(_start) +@@ -22,6 +24,34 @@ + *(.text*) + } + ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI) ++ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++#define CONFIG_ARMV7_SECURE_BASE ++#endif ++ ++ .__secure_start : { ++ . = ALIGN(0x1000); ++ *(.__secure_start) ++ } ++ ++ .secure_text CONFIG_ARMV7_SECURE_BASE : ++ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) ++ { ++ *(._secure.text) ++ } ++ ++ . = LOADADDR(.__secure_start) + ++ SIZEOF(.__secure_start) + ++ SIZEOF(.secure_text); ++ ++ __secure_end_lma = .; ++ .__secure_end : AT(__secure_end_lma) { ++ *(.__secure_end) ++ LONG(0x1d1071c); /* Must output something to reset LMA */ ++ } ++#endif ++ + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/clock.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,375 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 _SUNXI_CLOCK_H ++#define _SUNXI_CLOCK_H ++ ++#include ++ ++#define CLK_GATE_OPEN 0x1 ++#define CLK_GATE_CLOSE 0x0 ++ ++/* clock control module regs definition */ ++#if defined(CONFIG_SUN6I) ++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 MBUS0 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_OSC24M 1 ++#define APB2_FACTOR_M 0 ++#define APB2_FACTOR_N 0 ++ ++#else ++ ++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 0 ++#define APB1_FACTOR_M 0 ++#define APB1_FACTOR_N 0 ++ ++/* clock divide */ ++#define CPU_CLK_SRC_OSC24M 1 ++#define CPU_CLK_SRC_PLL1 2 ++#define AXI_DIV_1 0 ++#define AXI_DIV_2 1 ++#define AXI_DIV_3 2 ++#define AXI_DIV_4 3 ++#define AHB_DIV_1 0 ++#define AHB_DIV_2 1 ++#define AHB_DIV_4 2 ++#define AHB_DIV_8 3 ++#define APB0_DIV_1 0 ++#define APB0_DIV_2 1 ++#define APB0_DIV_4 2 ++#define APB0_DIV_8 3 ++ ++#ifdef CONFIG_SUN5I ++#define AHB_CLK_SRC_AXI 0 ++#endif ++ ++/* 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_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_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_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 /* CONFIG_SUN6I */ ++ ++#ifndef __ASSEMBLY__ ++int clock_init(void); ++int clock_twi_onoff(int port, int state); ++void clock_set_pll1(int mhz); ++unsigned int clock_get_pll5(void); ++#endif ++ ++#endif /* _SUNXI_CLOCK_H */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/cpucfg.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,71 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/cpu.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,147 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 _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 ++ ++/* 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 ++ ++/* 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); ++extern void sunxi_reset(void); ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _CPU_H */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/dram.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,191 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Berg Xing ++ * Tom Cubie ++ * ++ * Sunxi platform dram register definition. ++ * ++ * 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 _SUNXI_DRAM_H ++#define _SUNXI_DRAM_H ++ ++#include ++ ++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_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.01-rc1/arch/arm/include/asm/arch-sunxi/early_print.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,74 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Early uart print for debugging. ++ * ++ * 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 _SUNXI_EARLY_PRINT_H ++#define _SUNXI_EARLY_PRINT_H ++ ++#include ++ ++#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.01-rc1/arch/arm/include/asm/arch-sunxi/gpio.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,179 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 _SUNXI_GPIO_H ++#define _SUNXI_GPIO_H ++ ++#include ++ ++/* ++ * 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 ++ ++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[9]; ++ u8 res[0xbc]; ++ struct sunxi_gpio_int gpio_int; ++}; ++ ++#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_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 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)) ++ ++/* GPIO pin function config */ ++#define SUNXI_GPIO_INPUT 0 ++#define SUNXI_GPIO_OUTPUT 1 ++ ++#define SUNXI_GPA0_ERXD3 2 ++#define SUNXI_GPA0_SPI1_CS0 3 ++#define SUNXI_GPA0_UART2_RTS 4 ++ ++#define SUNXI_GPA1_ERXD2 2 ++#define SUNXI_GPA1_SPI1_CLK 3 ++#define SUNXI_GPA1_UART2_CTS 4 ++ ++#define SUNXI_GPA2_ERXD1 2 ++#define SUNXI_GPA2_SPI1_MOSI 3 ++#define SUNXI_GPA2_UART2_TX 4 ++ ++#define SUNXI_GPA10_UART1_TX 4 ++#define SUNXI_GPA11_UART1_RX 4 ++ ++#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_UART0_TX 4 ++#define SUN5I_GPG4_UART0_RX 4 ++ ++#define SUNXI_GPC2_NCLE 2 ++#define SUNXI_GPC2_SPI0_CLK 3 ++ ++#define SUNXI_GPC6_NRB0 2 ++#define SUNXI_GPC6_SDC2_CMD 3 ++ ++#define SUNXI_GPC7_NRB1 2 ++#define SUNXI_GPC7_SDC2_CLK 3 ++ ++#define SUNXI_GPC8_NDQ0 2 ++#define SUNXI_GPC8_SDC2_D0 3 ++ ++#define SUNXI_GPC9_NDQ1 2 ++#define SUNXI_GPC9_SDC2_D1 3 ++ ++#define SUNXI_GPC10_NDQ2 2 ++#define SUNXI_GPC10_SDC2_D2 3 ++ ++#define SUNXI_GPC11_NDQ3 2 ++#define SUNXI_GPC11_SDC2_D3 3 ++ ++#define SUNXI_GPF2_SDC0_CLK 2 ++#define SUNXI_GPF2_UART0_TX 4 ++ ++#define SUNXI_GPF4_SDC0_D3 2 ++#define SUNXI_GPF4_UART0_RX 4 ++ ++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 name_to_gpio(const char *name); ++#define name_to_gpio name_to_gpio ++ ++#endif /* _SUNXI_GPIO_H */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/i2c.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,185 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * Based on sun4i linux kernle i2c.h ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * Victor Wei ++ * ++ * 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 _SUNXI_I2C_H_ ++#define _SUNXI_I2C_H_ ++ ++struct i2c { ++ u32 saddr; /* 31:8bit res,7-1bit for slave addr,0 bit for GCE */ ++ u32 xsaddr; /* 31:8bit res,7-0bit for second addr in 10bit addr */ ++ u32 data; /* 31:8bit res, 7-0bit send or receive data byte */ ++ u32 ctl; /* INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */ ++ u32 status; /* 28 interrupt types + 0xf8 normal type = 29 */ ++ u32 clkr; /* 31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */ ++ u32 reset; /* 31:1bit res;0bit,write 1 to clear 0. */ ++ u32 efr; /* 31:2bit res,1:0 bit data byte follow read comand */ ++ u32 lctl; /* 31:6bits res 5:0bit for sda&scl control */ ++}; ++ ++/* TWI address register */ ++#define TWI_GCE_EN (0x1 << 0) /* gen call addr enable slave mode */ ++#define TWI_ADDR_MASK (0x7f << 1) /* 7:1bits */ ++#define TWI_XADDR_MASK 0xff /* 7:0bits for extend slave address */ ++ ++#define TWI_DATA_MASK 0xff /* 7:0bits for send or received */ ++ ++/* TWI Control Register Bit Fields */ ++/* 1:0 bits reserved */ ++/* set 1 to send A_ACK,then low level on SDA */ ++#define TWI_CTL_ACK (0x1 << 2) ++/* INT_FLAG,interrupt status flag: set '1' when interrupt coming */ ++#define TWI_CTL_INTFLG (0x1 << 3) ++#define TWI_CTL_STP (0x1 << 4) /* M_STP,Automatic clear 0 */ ++#define TWI_CTL_STA (0x1 << 5) /* M_STA,atutomatic clear 0 */ ++#define TWI_CTL_BUSEN (0x1 << 6) /* BUS_EN, mastr mode should be set 1 */ ++#define TWI_CTL_INTEN (0x1 << 7) /* INT_EN */ ++/* 31:8 bit reserved */ ++ ++/* ++ * TWI Clock Register Bit Fields & Masks,default value:0x0000_0000 ++ * Fin is APB CLOCK INPUT; ++ * Fsample = F0 = Fin/2^CLK_N; ++ * F1 = F0/(CLK_M+1); ++ * ++ * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10); ++ * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz ++ */ ++ ++#define TWI_CLK_DIV_M (0xf << 3) /* 6:3bit */ ++#define TWI_CLK_DIV_N (0x7 << 0) /* 2:0bit */ ++#define TWI_CLK_DIV(N, M) ((((N) & 0xf) << 3) | (((M) & 0x7) << 0)) ++ ++/* TWI Soft Reset Register Bit Fields & Masks */ ++/* write 1 to clear 0, when complete soft reset clear 0 */ ++#define TWI_SRST_SRST (0x1 << 0) ++ ++/* TWI Enhance Feature Register Bit Fields & Masks */ ++/* default -- 0x0 */ ++/* 00:no,01: 1byte, 10:2 bytes, 11: 3bytes */ ++#define TWI_EFR_MASK (0x3 << 0) ++#define TWI_EFR_WARC_0 (0x0 << 0) ++#define TWI_EFR_WARC_1 (0x1 << 0) ++#define TWI_EFR_WARC_2 (0x2 << 0) ++#define TWI_EFR_WARC_3 (0x3 << 0) ++ ++/* twi line control register -default value: 0x0000_003a */ ++/* SDA line state control enable ,1:enable;0:disable */ ++#define TWI_LCR_SDA_EN (0x01 << 0) ++/* SDA line state control bit, 1:high level;0:low level */ ++#define TWI_LCR_SDA_CTL (0x01 << 1) ++/* SCL line state control enable ,1:enable;0:disable */ ++#define TWI_LCR_SCL_EN (0x01 << 2) ++/* SCL line state control bit, 1:high level;0:low level */ ++#define TWI_LCR_SCL_CTL (0x01 << 3) ++/* current state of SDA,readonly bit */ ++#define TWI_LCR_SDA_STATE_MASK (0x01 << 4) ++/* current state of SCL,readonly bit */ ++#define TWI_LCR_SCL_STATE_MASK (0x01 << 5) ++/* 31:6bits reserved */ ++#define TWI_LCR_IDLE_STATUS 0x3a ++ ++/* TWI Status Register Bit Fields & Masks */ ++#define TWI_STAT_MASK 0xff ++/* 7:0 bits use only,default is 0xf8 */ ++#define TWI_STAT_BUS_ERR 0x00 /* BUS ERROR */ ++ ++/* Master mode use only */ ++#define TWI_STAT_TX_STA 0x08 /* START condition transmitted */ ++/* Repeated START condition transmitted */ ++#define TWI_STAT_TX_RESTA 0x10 ++/* Address+Write bit transmitted, ACK received */ ++#define TWI_STAT_TX_AW_ACK 0x18 ++/* Address+Write bit transmitted, ACK not received */ ++#define TWI_STAT_TX_AW_NAK 0x20 ++/* data byte transmitted in master mode,ack received */ ++#define TWI_STAT_TXD_ACK 0x28 ++/* data byte transmitted in master mode ,ack not received */ ++#define TWI_STAT_TXD_NAK 0x30 ++/* arbitration lost in address or data byte */ ++#define TWI_STAT_ARBLOST 0x38 ++/* Address+Read bit transmitted, ACK received */ ++#define TWI_STAT_TX_AR_ACK 0x40 ++/* Address+Read bit transmitted, ACK not received */ ++#define TWI_STAT_TX_AR_NAK 0x48 ++/* Second Address byte + Write bit transmitted, ACK received */ ++#define TWI_STAT_TX_2AW_ACK 0xd0 ++/* Second Address byte + Write bit transmitted, ACK received */ ++#define TWI_STAT_TX_2AW_NAK 0xd8 ++/* data byte received in master mode ,ack transmitted */ ++#define TWI_STAT_RXD_ACK 0x50 ++/* date byte received in master mode,not ack transmitted */ ++#define TWI_STAT_RXD_NAK 0x58 ++ ++/* Slave mode use only */ ++/* Slave address+Write bit received, ACK transmitted */ ++#define TWI_STAT_RXWS_ACK 0x60 ++/* ++ * Arbitration lost in address as master, slave address + Write bit received, ++ * ACK transmitted ++ */ ++#define TWI_STAT_ARBLOST_RXWS_ACK 0x68 ++/* General Call address received, ACK transmitted */ ++#define TWI_STAT_RXGCAS_ACK 0x70 ++/* ++ * Arbitration lost in address as master, General Call address received, ++ * ACK transmitted ++ */ ++#define TWI_STAT_ARBLOST_RXGCAS_ACK 0x78 ++/* Data byte received after slave address received, ACK transmitted */ ++#define TWI_STAT_RXDS_ACK 0x80 ++/* Data byte received after slave address received, not ACK transmitted */ ++#define TWI_STAT_RXDS_NAK 0x88 ++/* Data byte received after General Call received, ACK transmitted */ ++#define TWI_STAT_RXDGCAS_ACK 0x90 ++/* Data byte received after General Call received, not ACK transmitted */ ++#define TWI_STAT_RXDGCAS_NAK 0x98 ++/* STOP or repeated START condition received in slave */ ++#define TWI_STAT_RXSTPS_RXRESTAS 0xa0 ++/* Slave address + Read bit received, ACK transmitted */ ++#define TWI_STAT_RXRS_ACK 0xa8 ++/* ++ * Arbitration lost in address as master, slave address + Read bit received, ++ * ACK transmitted ++ */ ++#define TWI_STAT_ARBLOST_SLAR_ACK 0xb0 ++/* Data byte transmitted in slave mode, ACK received */ ++#define TWI_STAT_TXDS_ACK 0xb8 ++/* Data byte transmitted in slave mode, ACK not received */ ++#define TWI_STAT_TXDS_NAK 0xc0 ++/* Last byte transmitted in slave mode, ACK received */ ++#define TWI_STAT_TXDSL_ACK 0xc8 ++ ++/* 10bit Address, second part of address */ ++/* Second Address byte+Write bit transmitted,ACK received */ ++#define TWI_STAT_TX_SAW_ACK 0xd0 ++/* Second Address byte+Write bit transmitted,ACK not received */ ++#define TWI_STAT_TX_SAW_NAK 0xd8 ++ ++/* No relevant status infomation,INT_FLAG = 0 */ ++#define TWI_STAT_IDLE 0xf8 ++ ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/key.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/key.h +--- u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/key.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/key.h 2014-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,53 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 _SUNXI_KEY_H ++#define _SUNXI_KEY_H ++ ++#include ++ ++struct sunxi_lradc { ++ u32 ctrl; /* lradc control */ ++ u32 intc; /* interrupt control */ ++ u32 ints; /* interrupt status */ ++ u32 data0; /* lradc 0 data */ ++ u32 data1; /* lradc 1 data */ ++}; ++ ++#define LRADC_EN 0x1 /* LRADC enable */ ++#define LRADC_SAMPLE_RATE 0x2 /* 32.25 Hz */ ++#define LEVELB_VOL 0x2 /* 0x33(~1.6v) */ ++#define LRADC_HOLD_EN 0x1 /* sample hold enable */ ++#define KEY_MODE_SELECT 0x0 /* normal mode */ ++ ++#define ADC0_DATA_PENDING (0x1 << 0) /* adc0 has data */ ++#define ADC0_KEYDOWN_PENDING (0x1 << 1) /* key down */ ++#define ADC0_HOLDKEY_PENDING (0x1 << 2) /* key hold */ ++#define ADC0_ALRDY_HOLD_PENDING (0x1 << 3) /* key already hold */ ++#define ADC0_KEYUP_PENDING (0x1 << 4) /* key up */ ++ ++int sunxi_key_init(void); ++u32 sunxi_read_key(void); ++ ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/mmc.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,66 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Aaron ++ * ++ * MMC register definition for allwinner sunxi platform. ++ * ++ * 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 _SUNXI_MMC_H ++#define _SUNXI_MMC_H ++ ++#include ++ ++struct sunxi_mmc { ++ u32 gctrl; /* (0x00) SMC Global Control Register */ ++ u32 clkcr; /* (0x04) SMC Clock Control Register */ ++ u32 timeout; /* (0x08) SMC Time Out Register */ ++ u32 width; /* (0x0c) SMC Bus Width Register */ ++ u32 blksz; /* (0x10) SMC Block Size Register */ ++ u32 bytecnt; /* (0x14) SMC Byte Count Register */ ++ u32 cmd; /* (0x18) SMC Command Register */ ++ u32 arg; /* (0x1c) SMC Argument Register */ ++ u32 resp0; /* (0x20) SMC Response Register 0 */ ++ u32 resp1; /* (0x24) SMC Response Register 1 */ ++ u32 resp2; /* (0x28) SMC Response Register 2 */ ++ u32 resp3; /* (0x2c) SMC Response Register 3 */ ++ u32 imask; /* (0x30) SMC Interrupt Mask Register */ ++ u32 mint; /* (0x34) SMC Masked Interrupt Status Reg */ ++ u32 rint; /* (0x38) SMC Raw Interrupt Status Register */ ++ u32 status; /* (0x3c) SMC Status Register */ ++ u32 ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Reg */ ++ u32 funcsel; /* (0x44) SMC Function Select Register */ ++ u32 cbcr; /* (0x48) SMC CIU Byte Count Register */ ++ u32 bbcr; /* (0x4c) SMC BIU Byte Count Register */ ++ u32 dbgc; /* (0x50) SMC Debug Enable Register */ ++ u32 res0[11]; /* (0x54~0x7c) */ ++ u32 dmac; /* (0x80) SMC IDMAC Control Register */ ++ u32 dlba; /* (0x84) SMC IDMAC Descr List Base Addr Reg */ ++ u32 idst; /* (0x88) SMC IDMAC Status Register */ ++ u32 idie; /* (0x8c) SMC IDMAC Interrupt Enable Register */ ++ u32 chda; /* (0x90) */ ++ u32 cbda; /* (0x94) */ ++ u32 res1[26]; /* (0x98~0xff) */ ++ u32 fifo; /* (0x100) SMC FIFO Access Address */ ++}; ++ ++int sunxi_mmc_init(int sdc_no); ++#endif /* _SUNXI_MMC_H */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/smp.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,38 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/spl.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * This is a copy of omap3/spl.h: ++ * ++ * (C) Copyright 2012 ++ * Texas Instruments, ++ * ++ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/sys_proto.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 _SYS_PROTO_H_ ++#define _SYS_PROTO_H_ ++ ++#include ++ ++void sr32(u32 *, u32, u32, u32); ++void sdelay(unsigned long); ++ ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/timer.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,104 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Configuration settings for the Allwinner A10-evb board. ++ * ++ * 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 _SUNXI_TIMER_H_ ++#define _SUNXI_TIMER_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++#include ++ ++/* 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.01-rc1/arch/arm/include/asm/arch-sunxi/watchdog.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h +--- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 +@@ -0,0 +1,35 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl ++ * http://www.linux-sunxi.org/ ++ * ++ * 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., 51 Franklin Street, Fifth Floor, Boston, ++ * MA 02110-1301, USA. ++ */ ++ ++#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.01-rc1/arch/arm/include/asm/armv7.h u-boot-sunxi/arch/arm/include/asm/armv7.h +--- u-boot-2014.01-rc1/arch/arm/include/asm/armv7.h 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/armv7.h 2014-03-05 23:14:47.184099763 +0100 +@@ -78,13 +78,18 @@ + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + +-int armv7_switch_nonsec(void); +-int armv7_switch_hyp(void); ++int armv7_init_nonsec(void); ++int armv7_update_dt(void *fdt); + + /* defined in assembly file */ + unsigned int _nonsec_init(void); ++void _do_nonsec_entry(void *target_pc, unsigned long r0, ++ unsigned long r1, unsigned long r2); + void _smp_pen(void); +-void _switch_to_hyp(void); ++ ++extern char __secure_start[]; ++extern char __secure_end[]; ++ + #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */ + + #endif /* ! __ASSEMBLY__ */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/proc-armv/ptrace.h u-boot-sunxi/arch/arm/include/asm/proc-armv/ptrace.h +--- u-boot-2014.01-rc1/arch/arm/include/asm/proc-armv/ptrace.h 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/proc-armv/ptrace.h 2014-03-05 23:14:47.196099604 +0100 +@@ -19,12 +19,14 @@ + #define IRQ_MODE 0x12 + #define SVC_MODE 0x13 + #define ABT_MODE 0x17 ++#define HYP_MODE 0x1a + #define UND_MODE 0x1b + #define SYSTEM_MODE 0x1f + #define MODE_MASK 0x1f + #define T_BIT 0x20 + #define F_BIT 0x40 + #define I_BIT 0x80 ++#define A_BIT 0x100 + #define CC_V_BIT (1 << 28) + #define CC_C_BIT (1 << 29) + #define CC_Z_BIT (1 << 30) +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/psci.h u-boot-sunxi/arch/arm/include/asm/psci.h +--- u-boot-2014.01-rc1/arch/arm/include/asm/psci.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/psci.h 2014-03-05 23:14:47.196099604 +0100 +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef __ARM_PSCI_H__ ++#define __ARM_PSCI_H__ ++ ++/* PSCI interface */ ++#define ARM_PSCI_FN_BASE 0x95c1ba5e ++#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n)) ++ ++#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0) ++#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1) ++#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2) ++#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3) ++ ++#define ARM_PSCI_RET_SUCCESS 0 ++#define ARM_PSCI_RET_NI (-1) ++#define ARM_PSCI_RET_INVAL (-2) ++#define ARM_PSCI_RET_DENIED (-3) ++ ++#endif /* __ARM_PSCI_H__ */ +diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/secure.h u-boot-sunxi/arch/arm/include/asm/secure.h +--- u-boot-2014.01-rc1/arch/arm/include/asm/secure.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/secure.h 2014-03-05 23:14:47.196099604 +0100 +@@ -0,0 +1,26 @@ ++#ifndef __ASM_SECURE_H ++#define __ASM_SECURE_H ++ ++#include ++ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++/* ++ * Warning, horror ahead. ++ * ++ * The target code lives in our "secure ram", but u-boot doesn't know ++ * that, and has blindly added reloc_off to every relocation ++ * entry. Gahh. Do the opposite conversion. This hack also prevents ++ * GCC from generating code veeners, which u-boot doesn't relocate at ++ * all... ++ */ ++#define secure_ram_addr(_fn) ({ \ ++ DECLARE_GLOBAL_DATA_PTR; \ ++ void *__fn = _fn; \ ++ typeof(_fn) *__tmp = (__fn - gd->reloc_off); \ ++ __tmp; \ ++ }) ++#else ++#define secure_ram_addr(_fn) (_fn) ++#endif ++ ++#endif +diff -ruN u-boot-2014.01-rc1/arch/arm/lib/bootm.c u-boot-sunxi/arch/arm/lib/bootm.c +--- u-boot-2014.01-rc1/arch/arm/lib/bootm.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/lib/bootm.c 2014-03-05 23:14:47.196099604 +0100 +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +@@ -185,19 +186,6 @@ + + __weak void setup_board_tags(struct tag **in_params) {} + +-static void do_nonsec_virt_switch(void) +-{ +-#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +- if (armv7_switch_nonsec() == 0) +-#ifdef CONFIG_ARMV7_VIRT +- if (armv7_switch_hyp() == 0) +- debug("entered HYP mode\n"); +-#else +- debug("entered non-secure state\n"); +-#endif +-#endif +-} +- + /* Subcommand: PREP */ + static void boot_prep_linux(bootm_headers_t *images) + { +@@ -234,7 +222,6 @@ + printf("FDT and ATAGS support not compiled in - hanging\n"); + hang(); + } +- do_nonsec_virt_switch(); + } + + /* Subcommand: GO */ +@@ -264,8 +251,15 @@ + else + r2 = gd->bd->bi_boot_params; + +- if (!fake) ++ if (!fake) { ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ armv7_init_nonsec(); ++ secure_ram_addr(_do_nonsec_entry)(kernel_entry, ++ 0, machid, r2); ++#else + kernel_entry(0, machid, r2); ++#endif ++ } + } + + /* Main Entry point for arm bootm implementation +diff -ruN u-boot-2014.01-rc1/arch/arm/lib/bootm-fdt.c u-boot-sunxi/arch/arm/lib/bootm-fdt.c +--- u-boot-2014.01-rc1/arch/arm/lib/bootm-fdt.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/lib/bootm-fdt.c 2014-03-05 23:14:47.196099604 +0100 +@@ -17,6 +17,9 @@ + + #include + #include ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++#include ++#endif + + DECLARE_GLOBAL_DATA_PTR; + +@@ -34,3 +37,18 @@ + + return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); + } ++ ++int arch_fixup_fdt(void *blob) ++{ ++ int ret; ++ ++ ret = arch_fixup_memory_node(blob); ++ if (ret) ++ return ret; ++ ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ ret = armv7_update_dt(blob); ++#endif ++ ++ return ret; ++} +diff -ruN u-boot-2014.01-rc1/arch/arm/lib/interrupts.c u-boot-sunxi/arch/arm/lib/interrupts.c +--- u-boot-2014.01-rc1/arch/arm/lib/interrupts.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/lib/interrupts.c 2014-03-05 23:14:47.196099604 +0100 +@@ -103,7 +103,7 @@ + "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", + "UK4_32", "UK5_32", "UK6_32", "ABT_32", +- "UK8_32", "UK9_32", "UK10_32", "UND_32", ++ "UK8_32", "UK9_32", "HYP_32", "UND_32", + "UK12_32", "UK13_32", "UK14_32", "SYS_32", + }; + +diff -ruN u-boot-2014.01-rc1/arch/arm/lib/sections.c u-boot-sunxi/arch/arm/lib/sections.c +--- u-boot-2014.01-rc1/arch/arm/lib/sections.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/arch/arm/lib/sections.c 2014-03-05 23:14:47.196099604 +0100 +@@ -25,3 +25,5 @@ + char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); + char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); + char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); ++char __secure_start[0] __attribute__((section(".__secure_start"))); ++char __secure_end[0] __attribute__((section(".__secure_end"))); +diff -ruN u-boot-2014.01-rc1/board/sunxi/board.c u-boot-sunxi/board/sunxi/board.c +--- u-boot-2014.01-rc1/board/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/board.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,165 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Some board init for the Allwinner A10-evb board. ++ * ++ * 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 ++ */ ++ ++#include ++#ifdef CONFIG_AXP152_POWER ++#include ++#endif ++#ifdef CONFIG_AXP209_POWER ++#include ++#endif ++#include ++#include ++#include ++ ++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((unsigned long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_GENERIC_MMC ++int board_mmc_init(bd_t *bis) ++{ ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); ++#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA) ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); ++#endif ++ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SPL_BUILD ++void sunxi_board_init(void) ++{ ++ int power_failed = 0; ++ unsigned long ramsize; ++ ++ printf("DRAM:"); ++ ramsize = sunxi_dram_init(); ++ if (!ramsize) { ++ printf(" ?"); ++ ramsize = sunxi_dram_init(); ++ } ++ if (!ramsize) { ++ printf(" ?"); ++ ramsize = sunxi_dram_init(); ++ } ++ printf(" %lu MiB\n", ramsize >> 20); ++ if (!ramsize) ++ hang(); ++ ++#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 ++ ++ /* ++ * Only clock up the CPU to full speed if we are reasonably ++ * assured it's being powered with suitable core voltage ++ */ ++ if (!power_failed) ++#ifdef CONFIG_SUN7I ++ clock_set_pll1(912000000); ++#else ++ clock_set_pll1(1008000000); ++#endif ++ else ++ printf("Failed to set core voltage! Can't set CPU frequency\n"); ++} ++ ++#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 ++ ++#endif +diff -ruN u-boot-2014.01-rc1/board/sunxi/dram_a10_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_a10s_olinuxino_m.c u-boot-sunxi/board/sunxi/dram_a10s_olinuxino_m.c +--- u-boot-2014.01-rc1/board/sunxi/dram_a10s_olinuxino_m.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a10s_olinuxino_m.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_a13_mid.c u-boot-sunxi/board/sunxi/dram_a13_mid.c +--- u-boot-2014.01-rc1/board/sunxi/dram_a13_mid.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_mid.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_a13_oli_micro.c u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,32 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_a13_olinuxino.c u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c +--- u-boot-2014.01-rc1/board/sunxi/dram_a13_olinuxino.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_a20_olinuxino_m.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_m.c +--- u-boot-2014.01-rc1/board/sunxi/dram_a20_olinuxino_m.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_m.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include ++ ++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.01-rc1/board/sunxi/dram_auxtek_t003.c u-boot-sunxi/board/sunxi/dram_auxtek_t003.c +--- u-boot-2014.01-rc1/board/sunxi/dram_auxtek_t003.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_auxtek_t003.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_cubieboard2.c u-boot-sunxi/board/sunxi/dram_cubieboard2.c +--- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubieboard2.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_cubieboard_512.c u-boot-sunxi/board/sunxi/dram_cubieboard_512.c +--- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard_512.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubieboard_512.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .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.01-rc1/board/sunxi/dram_cubieboard.c u-boot-sunxi/board/sunxi/dram_cubieboard.c +--- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubieboard.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_cubietruck.c u-boot-sunxi/board/sunxi/dram_cubietruck.c +--- u-boot-2014.01-rc1/board/sunxi/dram_cubietruck.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubietruck.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 8192, ++ .io_width = 16, ++ .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.01-rc1/board/sunxi/dram_eoma68_a20.c u-boot-sunxi/board/sunxi/dram_eoma68_a20.c +--- u-boot-2014.01-rc1/board/sunxi/dram_eoma68_a20.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_eoma68_a20.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include ++ ++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.01-rc1/board/sunxi/dram_eu3000.c u-boot-sunxi/board/sunxi/dram_eu3000.c +--- u-boot-2014.01-rc1/board/sunxi/dram_eu3000.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_eu3000.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include ++ ++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.01-rc1/board/sunxi/dram_gooseberry_a721.c u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c +--- u-boot-2014.01-rc1/board/sunxi/dram_gooseberry_a721.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_h6.c u-boot-sunxi/board/sunxi/dram_h6.c +--- u-boot-2014.01-rc1/board/sunxi/dram_h6.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_h6.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_hackberry.c u-boot-sunxi/board/sunxi/dram_hackberry.c +--- u-boot-2014.01-rc1/board/sunxi/dram_hackberry.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_hackberry.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_inet_k70hc.c u-boot-sunxi/board/sunxi/dram_inet_k70hc.c +--- u-boot-2014.01-rc1/board/sunxi/dram_inet_k70hc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_inet_k70hc.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_megafeis_a08.c u-boot-sunxi/board/sunxi/dram_megafeis_a08.c +--- u-boot-2014.01-rc1/board/sunxi/dram_megafeis_a08.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_megafeis_a08.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_mini_x_a10s.c u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_mk802_a10s.c u-boot-sunxi/board/sunxi/dram_mk802_a10s.c +--- u-boot-2014.01-rc1/board/sunxi/dram_mk802_a10s.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802_a10s.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_mk802ii_a20.c u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c +--- u-boot-2014.01-rc1/board/sunxi/dram_mk802ii_a20.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include ++ ++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.01-rc1/board/sunxi/dram_pov_protab2.c u-boot-sunxi/board/sunxi/dram_pov_protab2.c +--- u-boot-2014.01-rc1/board/sunxi/dram_pov_protab2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_protab2.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_pov_protab2_xxl.c u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_r7dongle.c u-boot-sunxi/board/sunxi/dram_r7dongle.c +--- u-boot-2014.01-rc1/board/sunxi/dram_r7dongle.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_r7dongle.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sanei_n90.c u-boot-sunxi/board/sunxi/dram_sanei_n90.c +--- u-boot-2014.01-rc1/board/sunxi/dram_sanei_n90.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sanei_n90.c 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,30 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_312_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_360_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_360_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_360_512.c u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_384_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_408_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_sun4i_408_512.c u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c +--- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_wobo_i5.c u-boot-sunxi/board/sunxi/dram_wobo_i5.c +--- u-boot-2014.01-rc1/board/sunxi/dram_wobo_i5.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_wobo_i5.c 2014-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_xzpad700.c u-boot-sunxi/board/sunxi/dram_xzpad700.c +--- u-boot-2014.01-rc1/board/sunxi/dram_xzpad700.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_xzpad700.c 2014-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/dram_zatab.c u-boot-sunxi/board/sunxi/dram_zatab.c +--- u-boot-2014.01-rc1/board/sunxi/dram_zatab.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_zatab.c 2014-03-05 23:14:47.912090042 +0100 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++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.01-rc1/board/sunxi/Makefile u-boot-sunxi/board/sunxi/Makefile +--- u-boot-2014.01-rc1/board/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/Makefile 2014-03-05 23:14:47.908090095 +0100 +@@ -0,0 +1,85 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom ++# ++# Based on some other board Makefile ++# ++# (C) Copyright 2000-2003 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# 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 ++# ++ ++obj-y += board.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_a10s_olinuxino_m.o ++obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o ++obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o ++obj-$(CONFIG_A13_MID) += dram_a13_mid.o ++obj-$(CONFIG_A20_OLINUXINO_M) += dram_a20_olinuxino_m.o ++obj-$(CONFIG_AUXTEK_T003) += dram_auxtek_t003.o ++# This is not a typo, uses the same mem settings as the a10s-olinuxino-m ++obj-$(CONFIG_AUXTEK_T004) += dram_a10s_olinuxino_m.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_CUBIEBOARD_512) += dram_cubieboard_512.o ++obj-$(CONFIG_CUBIEBOARD2) += dram_cubieboard2.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_eoma68_a20.o ++obj-$(CONFIG_EU3000) += dram_eu3000.o ++obj-$(CONFIG_GOOSEBERRY_A721) += dram_gooseberry_a721.o ++obj-$(CONFIG_H6) += dram_h6.o ++obj-$(CONFIG_HACKBERRY) += dram_hackberry.o ++obj-$(CONFIG_A7HD) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_INTERRA3) += dram_mk802ii_a20.o ++obj-$(CONFIG_INET_86VZ) += dram_a10s_olinuxino_m.o ++obj-$(CONFIG_INET97F_II) += dram_sun4i_408_512.o ++obj-$(CONFIG_INET_K70HC) += dram_inet_k70hc.o ++obj-$(CONFIG_JESURUN_Q5) += dram_sun4i_312_1024_iow8.o ++obj-$(CONFIG_K1001L1C) += dram_a20_olinuxino_m.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_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_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_POV_PROTAB2) += dram_pov_protab2.o ++obj-$(CONFIG_POV_PROTAB2_XXL) += dram_pov_protab2_xxl.o ++obj-$(CONFIG_R7DONGLE) += dram_r7dongle.o ++obj-$(CONFIG_SANEI_N90) += dram_sanei_n90.o ++obj-$(CONFIG_UHOST_U1A) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_WOBO_I5) += dram_wobo_i5.o ++obj-$(CONFIG_XZPAD700) += dram_xzpad700.o ++obj-$(CONFIG_ZATAB) += dram_zatab.o +diff -ruN u-boot-2014.01-rc1/boards.cfg u-boot-sunxi/boards.cfg +--- u-boot-2014.01-rc1/boards.cfg 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/boards.cfg 2014-03-05 23:14:47.948089561 +0100 +@@ -344,6 +344,82 @@ + Active arm armv7 s5pc1xx samsung goni s5p_goni - Minkyu Kang + Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang + 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_MICRO sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_GMAC,FAST_MBUS - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO_FEL sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_GMAC,FAST_MBUS - ++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 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 Colombus sun6i:COLOMBUS - ++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_512 sun4i:CUBIEBOARD_512,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++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 Gooseberry_A721 sun4i:GOOSEBERRY_A721,SPL - ++Active arm armv7 sunxi - sunxi H6 sun4i:H6,SPL - ++Active arm armv7 sunxi - sunxi Hackberry sun4i:HACKBERRY,SPL - ++Active arm armv7 sunxi - sunxi Hyundai_A7HD sun4i:A7HD,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 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,STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000_FEL sun4i:MELE_A1000,SPL_FEL,SUNXI_EMAC,STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000G sun4i:MELE_A1000G,SPL,SUNXI_EMAC,STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A3700 sun4i:MELE_A3700,SPL,SUNXI_EMAC,STATUSLED=234 - ++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 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 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 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 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 uhost_u1a sun4i:UHOST_U1A,SPL,STATUSLED=34 - ++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 + 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 +diff -ruN u-boot-2014.01-rc1/common/cmd_gpio.c u-boot-sunxi/common/cmd_gpio.c +--- u-boot-2014.01-rc1/common/cmd_gpio.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/common/cmd_gpio.c 2014-03-05 23:14:47.952089507 +0100 +@@ -20,6 +20,7 @@ + GPIO_SET, + GPIO_CLEAR, + GPIO_TOGGLE, ++ GPIO_OSCILLATE, + }; + + static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +@@ -48,6 +49,7 @@ + case 's': sub_cmd = GPIO_SET; break; + case 'c': sub_cmd = GPIO_CLEAR; break; + case 't': sub_cmd = GPIO_TOGGLE; break; ++ case 'o': sub_cmd = GPIO_OSCILLATE; break; + default: goto show_usage; + } + +@@ -66,6 +68,14 @@ + if (sub_cmd == GPIO_INPUT) { + gpio_direction_input(gpio); + value = gpio_get_value(gpio); ++ } else if (sub_cmd == GPIO_OSCILLATE) { ++ int i; ++ gpio_direction_output(gpio, 0); ++ for (i = 0; i < 100000000; i++) { ++ gpio_set_value(gpio, i&1); ++ } ++ gpio_direction_input(gpio); ++ value = 0; + } else { + switch (sub_cmd) { + case GPIO_SET: value = 1; break; +diff -ruN u-boot-2014.01-rc1/common/image-fdt.c u-boot-sunxi/common/image-fdt.c +--- u-boot-2014.01-rc1/common/image-fdt.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/common/image-fdt.c 2014-03-05 23:14:47.968089294 +0100 +@@ -445,7 +445,7 @@ + return 1; + } + +-__weak int arch_fixup_memory_node(void *blob) ++__weak int arch_fixup_fdt(void *blob) + { + return 0; + } +@@ -462,7 +462,10 @@ + puts(" - must RESET the board to recover.\n"); + return -1; + } +- arch_fixup_memory_node(blob); ++ if (arch_fixup_fdt(blob) < 0) { ++ puts("ERROR: arch specific fdt fixup failed"); ++ return -1; ++ } + if (IMAAGE_OF_BOARD_SETUP) + ft_board_setup(blob, gd->bd); + fdt_fixup_ethernet(blob); +diff -ruN u-boot-2014.01-rc1/common/memsize.c u-boot-sunxi/common/memsize.c +--- u-boot-2014.01-rc1/common/memsize.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/common/memsize.c 2014-03-05 23:14:47.968089294 +0100 +@@ -21,16 +21,16 @@ + * the actually available RAM size between addresses `base' and + * `base + maxsize'. + */ +-long get_ram_size(long *base, long maxsize) ++unsigned long get_ram_size(unsigned long *base, unsigned long maxsize) + { +- volatile long *addr; +- long save[32]; +- long cnt; +- long val; +- long size; +- int i = 0; ++ volatile unsigned long *addr; ++ unsigned long save[32]; ++ unsigned long cnt; ++ unsigned long val; ++ unsigned long size; ++ int i = 0; + +- for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { ++ for (cnt = (maxsize / sizeof (unsigned long)) >> 1; cnt > 0; cnt >>= 1) { + addr = base + cnt; /* pointer arith! */ + sync (); + save[i++] = *addr; +@@ -50,7 +50,7 @@ + */ + sync (); + *addr = save[i]; +- for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { ++ for (cnt = 1; cnt < maxsize / sizeof(unsigned long); cnt <<= 1) { + addr = base + cnt; + sync (); + *addr = save[--i]; +@@ -58,15 +58,15 @@ + return (0); + } + +- for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { ++ for (cnt = 1; cnt < maxsize / sizeof (unsigned long); cnt <<= 1) { + addr = base + cnt; /* pointer arith! */ + val = *addr; + *addr = save[--i]; + if (val != ~cnt) { +- size = cnt * sizeof (long); ++ size = cnt * sizeof (unsigned long); + /* Restore the original data before leaving the function. + */ +- for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) { ++ for (cnt <<= 1; cnt < maxsize / sizeof (unsigned long); cnt <<= 1) { + addr = base + cnt; + *addr = save[--i]; + } +diff -ruN u-boot-2014.01-rc1/common/spl/spl_mmc.c u-boot-sunxi/common/spl/spl_mmc.c +--- u-boot-2014.01-rc1/common/spl/spl_mmc.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/common/spl/spl_mmc.c 2014-03-05 23:14:47.968089294 +0100 +@@ -30,8 +30,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.01-rc1/drivers/gpio/Makefile u-boot-sunxi/drivers/gpio/Makefile +--- u-boot-2014.01-rc1/drivers/gpio/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/gpio/Makefile 2014-03-05 23:14:47.996088920 +0100 +@@ -31,3 +31,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.01-rc1/drivers/gpio/sunxi_gpio.c u-boot-sunxi/drivers/gpio/sunxi_gpio.c +--- u-boot-2014.01-rc1/drivers/gpio/sunxi_gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/gpio/sunxi_gpio.c 2014-03-05 23:14:47.996088920 +0100 +@@ -0,0 +1,120 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++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 = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[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 = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[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 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.01-rc1/drivers/i2c/Makefile u-boot-sunxi/drivers/i2c/Makefile +--- u-boot-2014.01-rc1/drivers/i2c/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/i2c/Makefile 2014-03-05 23:14:48.000088867 +0100 +@@ -16,6 +16,7 @@ + obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o + obj-$(CONFIG_U8500_I2C) += u8500_i2c.o + obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o ++obj-$(CONFIG_SUNXI_I2C) += sunxi_i2c.o + obj-$(CONFIG_SYS_I2C) += i2c_core.o + obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o + obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o +diff -ruN u-boot-2014.01-rc1/drivers/i2c/sunxi_i2c.c u-boot-sunxi/drivers/i2c/sunxi_i2c.c +--- u-boot-2014.01-rc1/drivers/i2c/sunxi_i2c.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/i2c/sunxi_i2c.c 2014-03-05 23:14:48.000088867 +0100 +@@ -0,0 +1,276 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct i2c __attribute__ ((section(".data"))) *i2c_base = ++ (struct i2c *)0x1c2ac00; ++ ++void i2c_init(int speed, int slaveaddr) ++{ ++ int timeout = 0x2ff; ++ ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2); ++ clock_twi_onoff(0, 1); ++ ++ /* Enable the i2c bus */ ++ writel(TWI_CTL_BUSEN, &i2c_base->ctl); ++ ++ /* 400KHz operation M=2, N=1, 24MHz APB clock */ ++ writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr); ++ writel(TWI_SRST_SRST, &i2c_base->reset); ++ ++ while ((readl(&i2c_base->reset) & TWI_SRST_SRST) && timeout--); ++} ++ ++int i2c_probe(uchar chip) ++{ ++ return -1; ++} ++ ++static int i2c_wait_ctl(int mask, int state) ++{ ++ int timeout = 0x2ff; ++ int value = state ? mask : 0; ++ ++ debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value, ++ i2c_base->ctl, i2c_base->status); ++ ++ while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0); ++ ++ debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout, ++ i2c_base->ctl, i2c_base->status); ++ ++ if (timeout != 0) ++ return 0; ++ else ++ return -1; ++} ++ ++static void i2c_clear_irq(void) ++{ ++ writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl); ++} ++ ++static int i2c_wait_irq(void) ++{ ++ return i2c_wait_ctl(TWI_CTL_INTFLG, 1); ++} ++ ++static int i2c_wait_status(int status) ++{ ++ int timeout = 0x2ff; ++ ++ while (readl(&i2c_base->status) != status && timeout-- > 0); ++ ++ if (timeout != 0) ++ return 0; ++ else ++ return -1; ++} ++ ++static int i2c_wait_irq_status(int status) ++{ ++ if (i2c_wait_irq() != 0) ++ return -1; ++ ++ if (readl(&i2c_base->status) != status) ++ return -1; ++ ++ return 0; ++} ++ ++static int i2c_wait_bus_idle(void) ++{ ++ int timeout = 0x2ff; ++ ++ while (readl(&i2c_base->lctl) != 0x3a && timeout-- > 0); ++ ++ if (timeout != 0) ++ return 0; ++ else ++ return -1; ++} ++ ++static int i2c_stop(void) ++{ ++ u32 ctl; ++ ++ ctl = readl(&i2c_base->ctl) & 0xc0; ++ ctl |= TWI_CTL_STP; ++ ++ writel(ctl, &i2c_base->ctl); ++ ++ /* dummy to delay one I/O operation to make sure it's started */ ++ (void)readl(&i2c_base->ctl); ++ ++ if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0) ++ return -1; ++ if (i2c_wait_status(TWI_STAT_IDLE)) ++ return -1; ++ if (i2c_wait_bus_idle() != 0) ++ return -1; ++ ++ return 0; ++} ++ ++static int i2c_send_data(u8 data, u8 status) ++{ ++ debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status, ++ i2c_base->ctl, i2c_base->status); ++ ++ writel(data, &i2c_base->data); ++ i2c_clear_irq(); ++ ++ if (i2c_wait_irq_status(status) != 0) ++ return -1; ++ ++ return 0; ++} ++ ++static int i2c_start(int status) ++{ ++ u32 ctl; ++ ++ debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl, ++ i2c_base->status); ++ /* Check that the controller is idle */ ++ if (status == TWI_STAT_TX_STA && ++ readl(&i2c_base->status) != TWI_STAT_IDLE) { ++ return -1; ++ } ++ ++ writel(0, &i2c_base->efr); ++ ++ /* Send start */ ++ ctl = readl(&i2c_base->ctl); ++ ctl |= TWI_CTL_STA; /* Set start bit */ ++ ctl &= ~TWI_CTL_INTFLG; /* Clear int flag */ ++ writel(ctl, &i2c_base->ctl); ++ ++ if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0) ++ return -1; ++ if (i2c_wait_irq_status(status) != 0) ++ return -1; ++ ++ return 0; ++} ++ ++int i2c_do_read(uchar chip, uint addr, int alen, uchar *buffer, int len) ++{ ++ u32 status; ++ u32 ctl; ++ ++ if (i2c_start(TWI_STAT_TX_STA) != 0) ++ return -1; ++ ++ /* Send chip address */ ++ if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0) ++ return -1; ++ ++ /* Send data address */ ++ if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0) ++ return -1; ++ ++ /* Send restart for read */ ++ if (i2c_start(TWI_STAT_TX_RESTA) != 0) ++ return -1; ++ ++ /* Send chip address */ ++ if (i2c_send_data(chip << 1 | 1, TWI_STAT_TX_AR_ACK) != 0) ++ return -1; ++ ++ /* Set ACK mode */ ++ ctl = readl(&i2c_base->ctl); ++ ctl |= TWI_CTL_ACK; ++ writel(ctl, &i2c_base->ctl); ++ status = TWI_STAT_RXD_ACK; ++ ++ /* Read data */ ++ while (len > 0) { ++ if (len == 1) { ++ /* Set NACK mode (last byte) */ ++ ctl = readl(&i2c_base->ctl); ++ ctl &= ~TWI_CTL_ACK; ++ writel(ctl, &i2c_base->ctl); ++ status = TWI_STAT_RXD_NAK; ++ } ++ ++ i2c_clear_irq(); ++ if (i2c_wait_irq_status(status) != 0) ++ return -1; ++ ++ *buffer++ = readl(&i2c_base->data); ++ len--; ++ } ++ ++ return 0; ++} ++ ++int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) ++{ ++ int rc = i2c_do_read(chip, addr, alen, buffer, len); ++ ++ i2c_stop(); ++ ++ return rc; ++} ++ ++static int i2c_do_write(uchar chip, uint addr, int alen, uchar *buffer, ++ int len) ++{ ++ if (i2c_start(TWI_STAT_TX_STA) != 0) ++ return -1; ++ ++ /* Send chip address */ ++ if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0) ++ return -1; ++ ++ /* Send data address */ ++ if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0) ++ return -1; ++ ++ /* Send data */ ++ while (len > 0) { ++ if (i2c_send_data(*buffer++, TWI_STAT_TXD_ACK) != 0) ++ return -1; ++ len--; ++ } ++ ++ return 0; ++} ++ ++int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) ++{ ++ int rc = i2c_do_write(chip, addr, alen, buffer, len); ++ ++ i2c_stop(); ++ ++ return rc; ++} +diff -ruN u-boot-2014.01-rc1/drivers/mmc/Makefile u-boot-sunxi/drivers/mmc/Makefile +--- u-boot-2014.01-rc1/drivers/mmc/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/mmc/Makefile 2014-03-05 23:14:48.004088813 +0100 +@@ -26,6 +26,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 + ifdef CONFIG_SPL_BUILD + obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o +diff -ruN u-boot-2014.01-rc1/drivers/mmc/sunxi_mmc.c u-boot-sunxi/drivers/mmc/sunxi_mmc.c +--- u-boot-2014.01-rc1/drivers/mmc/sunxi_mmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/mmc/sunxi_mmc.c 2014-03-05 23:14:48.008088759 +0100 +@@ -0,0 +1,660 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Aaron ++ * ++ * MMC driver for allwinner sunxi platform. ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void dumphex32(char *name, char *base, int len) ++{ ++ __u32 i; ++ ++ debug("dump %s registers:", name); ++ for (i = 0; i < len; i += 4) { ++ if (!(i & 0xf)) ++ debug("\n0x%p : ", base + i); ++ debug("0x%08x ", readl(base + i)); ++ } ++ debug("\n"); ++} ++ ++static void dumpmmcreg(struct sunxi_mmc *reg) ++{ ++ debug("dump mmc registers:\n"); ++ debug("gctrl 0x%08x\n", reg->gctrl); ++ debug("clkcr 0x%08x\n", reg->clkcr); ++ debug("timeout 0x%08x\n", reg->timeout); ++ debug("width 0x%08x\n", reg->width); ++ debug("blksz 0x%08x\n", reg->blksz); ++ debug("bytecnt 0x%08x\n", reg->bytecnt); ++ debug("cmd 0x%08x\n", reg->cmd); ++ debug("arg 0x%08x\n", reg->arg); ++ debug("resp0 0x%08x\n", reg->resp0); ++ debug("resp1 0x%08x\n", reg->resp1); ++ debug("resp2 0x%08x\n", reg->resp2); ++ debug("resp3 0x%08x\n", reg->resp3); ++ debug("imask 0x%08x\n", reg->imask); ++ debug("mint 0x%08x\n", reg->mint); ++ debug("rint 0x%08x\n", reg->rint); ++ debug("status 0x%08x\n", reg->status); ++ debug("ftrglevel 0x%08x\n", reg->ftrglevel); ++ debug("funcsel 0x%08x\n", reg->funcsel); ++ debug("dmac 0x%08x\n", reg->dmac); ++ debug("dlba 0x%08x\n", reg->dlba); ++ debug("idst 0x%08x\n", reg->idst); ++ debug("idie 0x%08x\n", reg->idie); ++} ++ ++struct sunxi_mmc_des { ++ u32 reserved1_1:1; ++ u32 dic:1; /* disable interrupt on completion */ ++ u32 last_des:1; /* 1-this data buffer is the last buffer */ ++ u32 first_des:1; /* 1-data buffer is the first buffer, ++ 0-data buffer contained in the next ++ descriptor is 1st buffer */ ++ u32 des_chain:1; /* 1-the 2nd address in the descriptor is the ++ next descriptor address */ ++ u32 end_of_ring:1; /* 1-last descriptor flag when using dual ++ data buffer in descriptor */ ++ u32 reserved1_2:24; ++ u32 card_err_sum:1; /* transfer error flag */ ++ u32 own:1; /* des owner:1-idma owns it, 0-host owns it */ ++#ifdef CONFIG_SUN4I ++#define SDXC_DES_NUM_SHIFT 13 ++#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) ++ u32 data_buf1_sz:13; ++ u32 data_buf2_sz:13; ++ u32 reserverd2_1:6; ++#elif defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++#define SDXC_DES_NUM_SHIFT 16 ++#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) ++ u32 data_buf1_sz:16; ++ u32 data_buf2_sz:16; ++#else ++#error ">>>> Wrong Platform for MMC <<<<" ++#endif ++ u32 buf_addr_ptr1; ++ u32 buf_addr_ptr2; ++}; ++ ++struct sunxi_mmc_host { ++ unsigned mmc_no; ++ uint32_t *mclkreg; ++ unsigned database; ++ unsigned fatal_err; ++ unsigned mod_clk; ++ struct sunxi_mmc *reg; ++}; ++ ++/* support 4 mmc hosts */ ++struct mmc mmc_dev[4]; ++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; ++ } ++ mmchost->database = (unsigned int)mmchost->reg + 0x100; ++ mmchost->mmc_no = sdc_no; ++ ++ return 0; ++} ++ ++static int mmc_clk_io_on(int sdc_no) ++{ ++ unsigned int rval; ++ unsigned int pll5_clk; ++ unsigned int divider; ++ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; ++ static struct sunxi_gpio *gpio_c = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_C]; ++ static struct sunxi_gpio *gpio_f = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_F]; ++#if CONFIG_MMC1_PG ++ static struct sunxi_gpio *gpio_g = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_G]; ++#endif ++ static struct sunxi_gpio *gpio_h = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_H]; ++ static struct sunxi_gpio *gpio_i = ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_I]; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ debug("init mmc %d clock and io\n", sdc_no); ++ ++ /* config gpio */ ++ switch (sdc_no) { ++ case 0: ++ /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ ++ writel(0x222222, &gpio_f->cfg[0]); ++ writel(0x555, &gpio_f->pull[0]); ++ writel(0xaaa, &gpio_f->drv[0]); ++ break; ++ ++ case 1: ++#if CONFIG_MMC1_PG ++ /* PG0-CMD, PG1-CLK, PG2~5-D0~3 : 4 */ ++ writel(0x444444, &gpio_g->cfg[0]); ++ writel(0x555, &gpio_g->pull[0]); ++ writel(0xaaa, &gpio_g->drv[0]); ++#else ++ /* PH22-CMD, PH23-CLK, PH24~27-D0~D3 : 5 */ ++ writel(0x55 << 24, &gpio_h->cfg[2]); ++ writel(0x5555, &gpio_h->cfg[3]); ++ writel(0x555 << 12, &gpio_h->pull[1]); ++ writel(0xaaa << 12, &gpio_h->drv[1]); ++#endif ++ break; ++ ++ case 2: ++ /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ ++ writel(0x33 << 24, &gpio_c->cfg[0]); ++ writel(0x3333, &gpio_c->cfg[1]); ++ writel(0x555 << 12, &gpio_c->pull[0]); ++ writel(0xaaa << 12, &gpio_c->drv[0]); ++ break; ++ ++ case 3: ++ /* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */ ++ writel(0x2222 << 16, &gpio_i->cfg[0]); ++ writel(0x22, &gpio_i->cfg[1]); ++ writel(0x555 << 8, &gpio_i->pull[0]); ++ writel(0x555 << 8, &gpio_i->drv[0]); ++ break; ++ ++ default: ++ return -1; ++ } ++ ++ /* config ahb clock */ ++ rval = readl(&ccm->ahb_gate0); ++ rval |= (1 << (8 + sdc_no)); ++ writel(rval, &ccm->ahb_gate0); ++ ++ /* config mod clock */ ++ pll5_clk = clock_get_pll5(); ++ if (pll5_clk > 400000000) ++ divider = 4; ++ else ++ divider = 3; ++ writel((0x1 << 31) | (0x2 << 24) | divider, mmchost->mclkreg); ++ mmchost->mod_clk = pll5_clk / (divider + 1); ++ ++ dumphex32("ccmu", (char *)SUNXI_CCM_BASE, 0x100); ++ dumphex32("gpio", (char *)SUNXI_PIO_BASE, 0x100); ++ dumphex32("mmc", (char *)mmchost->reg, 0x100); ++ dumpmmcreg(mmchost->reg); ++ ++ return 0; ++} ++ ++static int mmc_update_clk(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; ++ unsigned int cmd; ++ unsigned timeout = 0xfffff; ++ ++ cmd = (0x1 << 31) | (0x1 << 21) | (0x1 << 13); ++ writel(cmd, &mmchost->reg->cmd); ++ while ((readl(&mmchost->reg->cmd) & (0x1 << 31)) && timeout--); ++ if (!timeout) ++ return -1; ++ ++ 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 = (struct sunxi_mmc_host *)mmc->priv; ++ unsigned rval = readl(&mmchost->reg->clkcr); ++ ++ /* ++ * CLKCREG[7:0]: divider ++ * CLKCREG[16]: on/off ++ * CLKCREG[17]: power save ++ */ ++ /* Disable Clock */ ++ rval &= ~(0x1 << 16); ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ ++ /* Change Divider Factor */ ++ rval &= ~(0xff); ++ rval |= div; ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ /* Re-enable Clock */ ++ rval |= (0x1 << 16); ++ 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 = (struct sunxi_mmc_host *)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 = (struct sunxi_mmc_host *)mmc->priv; ++ ++ /* Reset controller */ ++ writel(0x7, &mmchost->reg->gctrl); ++ ++ return 0; ++} ++ ++static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; ++ unsigned i; ++ unsigned byte_cnt = data->blocksize * data->blocks; ++ unsigned *buff; ++ unsigned timeout = 0xfffff; ++ ++ if (data->flags & MMC_DATA_READ) { ++ buff = (unsigned int *)data->dest; ++ for (i = 0; i < (byte_cnt >> 2); i++) { ++ while (--timeout && ++ (readl(&mmchost->reg->status) & (0x1 << 2))); ++ if (timeout <= 0) ++ goto out; ++ buff[i] = readl(mmchost->database); ++ timeout = 0xfffff; ++ } ++ } else { ++ buff = (unsigned int *)data->src; ++ for (i = 0; i < (byte_cnt >> 2); i++) { ++ while (--timeout && ++ (readl(&mmchost->reg->status) & (0x1 << 3))); ++ if (timeout <= 0) ++ goto out; ++ writel(buff[i], mmchost->database); ++ timeout = 0xfffff; ++ } ++ } ++ ++out: ++ if (timeout <= 0) ++ return -1; ++ ++ return 0; ++} ++ ++static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; ++ unsigned byte_cnt = data->blocksize * data->blocks; ++ unsigned char *buff; ++ unsigned des_idx = 0; ++ unsigned buff_frag_num = ++ (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT; ++ unsigned remain; ++ unsigned i, rval; ++ ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num); ++ ++ buff = data->flags & MMC_DATA_READ ? ++ (unsigned char *)data->dest : (unsigned char *)data->src; ++ remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1); ++ if (!remain) ++ remain = SDXC_DES_BUFFER_MAX_LEN; ++ ++ flush_cache((unsigned long)buff, (unsigned long)byte_cnt); ++ for (i = 0; i < buff_frag_num; i++, des_idx++) { ++ memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des)); ++ pdes[des_idx].des_chain = 1; ++ pdes[des_idx].own = 1; ++ pdes[des_idx].dic = 1; ++ if (buff_frag_num > 1 && i != buff_frag_num - 1) ++ pdes[des_idx].data_buf1_sz = ++ (SDXC_DES_BUFFER_MAX_LEN - ++ 1) & SDXC_DES_BUFFER_MAX_LEN; ++ else ++ pdes[des_idx].data_buf1_sz = remain; ++ ++ pdes[des_idx].buf_addr_ptr1 = ++ (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN; ++ if (i == 0) ++ pdes[des_idx].first_des = 1; ++ ++ if (i == buff_frag_num - 1) { ++ pdes[des_idx].dic = 0; ++ pdes[des_idx].last_des = 1; ++ pdes[des_idx].end_of_ring = 1; ++ pdes[des_idx].buf_addr_ptr2 = 0; ++ } else { ++ pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1]; ++ } ++ debug("frag %d, remain %d, des[%d](%08x): ", ++ i, remain, des_idx, (u32)&pdes[des_idx]); ++ debug("[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x\n", ++ (u32)((u32 *)&pdes[des_idx])[0], ++ (u32)((u32 *)&pdes[des_idx])[1], ++ (u32)((u32 *)&pdes[des_idx])[2], ++ (u32)((u32 *)&pdes[des_idx])[3]); ++ } ++ flush_cache((unsigned long)pdes, ++ sizeof(struct sunxi_mmc_des) * (des_idx + 1)); ++ ++ /* ++ * GCTRLREG ++ * GCTRL[2] : DMA reset ++ * GCTRL[5] : DMA enable ++ * ++ * IDMACREG ++ * IDMAC[0] : IDMA soft reset ++ * IDMAC[1] : IDMA fix burst flag ++ * IDMAC[7] : IDMA on ++ * ++ * IDIECREG ++ * IDIE[0] : IDMA transmit interrupt flag ++ * IDIE[1] : IDMA receive interrupt flag ++ */ ++ rval = readl(&mmchost->reg->gctrl); ++ /* Enable DMA */ ++ writel(rval | (0x1 << 5) | (0x1 << 2), &mmchost->reg->gctrl); ++ /* Reset iDMA */ ++ writel((0x1 << 0), &mmchost->reg->dmac); ++ /* Enable iDMA */ ++ writel((0x1 << 1) | (1 << 7), &mmchost->reg->dmac); ++ rval = readl(&mmchost->reg->idie) & (~3); ++ if (data->flags & MMC_DATA_WRITE) ++ rval |= (0x1 << 0); ++ else ++ rval |= (0x1 << 1); ++ writel(rval, &mmchost->reg->idie); ++ writel((u32) pdes, &mmchost->reg->dlba); ++ writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), ++ &mmchost->reg->ftrglevel); ++ ++ return 0; ++} ++ ++static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ++ struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; ++ unsigned int cmdval = 0x80000000; ++ signed int timeout = 0; ++ int error = 0; ++ unsigned int status = 0; ++ unsigned int usedma = 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; ++ ++ /* ++ * CMDREG ++ * CMD[5:0] : Command index ++ * CMD[6] : Has response ++ * CMD[7] : Long response ++ * CMD[8] : Check response CRC ++ * CMD[9] : Has data ++ * CMD[10] : Write ++ * CMD[11] : Steam mode ++ * CMD[12] : Auto stop ++ * CMD[13] : Wait previous over ++ * CMD[14] : About cmd ++ * CMD[15] : Send initialization ++ * CMD[21] : Update clock ++ * CMD[31] : Load cmd ++ */ ++ if (!cmd->cmdidx) ++ cmdval |= (0x1 << 15); ++ if (cmd->resp_type & MMC_RSP_PRESENT) ++ cmdval |= (0x1 << 6); ++ if (cmd->resp_type & MMC_RSP_136) ++ cmdval |= (0x1 << 7); ++ if (cmd->resp_type & MMC_RSP_CRC) ++ cmdval |= (0x1 << 8); ++ ++ if (data) { ++ if ((u32) data->dest & 0x3) { ++ error = -1; ++ goto out; ++ } ++ ++ cmdval |= (0x1 << 9) | (0x1 << 13); ++ if (data->flags & MMC_DATA_WRITE) ++ cmdval |= (0x1 << 10); ++ if (data->blocks > 1) ++ cmdval |= (0x1 << 12); ++ 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); ++#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD) ++ if (bytecnt > 64) { ++#else ++ if (0) { ++#endif ++ usedma = 1; ++ writel(readl(&mmchost->reg->gctrl) & ~(0x1 << 31), ++ &mmchost->reg->gctrl); ++ ret = mmc_trans_data_by_dma(mmc, data); ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ } else { ++ writel(readl(&mmchost->reg->gctrl) | 0x1 << 31, ++ &mmchost->reg->gctrl); ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ret = mmc_trans_data_by_cpu(mmc, data); ++ } ++ if (ret) { ++ error = readl(&mmchost->reg->rint) & 0xbfc2; ++ error = TIMEOUT; ++ goto out; ++ } ++ } ++ ++ timeout = 0xfffff; ++ do { ++ status = readl(&mmchost->reg->rint); ++ if (!timeout-- || (status & 0xbfc2)) { ++ error = status & 0xbfc2; ++ debug("cmd timeout %x\n", error); ++ error = TIMEOUT; ++ goto out; ++ } ++ } while (!(status & 0x4)); ++ ++ if (data) { ++ unsigned done = 0; ++ timeout = usedma ? 0xffff * bytecnt : 0xffff; ++ debug("cacl timeout %x\n", timeout); ++ do { ++ status = readl(&mmchost->reg->rint); ++ if (!timeout-- || (status & 0xbfc2)) { ++ error = status & 0xbfc2; ++ debug("data timeout %x\n", error); ++ error = TIMEOUT; ++ goto out; ++ } ++ if (data->blocks > 1) ++ done = status & (0x1 << 14); ++ else ++ done = status & (0x1 << 3); ++ } while (!done); ++ } ++ ++ if (cmd->resp_type & MMC_RSP_BUSY) { ++ timeout = 0xfffff; ++ do { ++ status = readl(&mmchost->reg->status); ++ if (!timeout--) { ++ debug("busy timeout\n"); ++ error = TIMEOUT; ++ goto out; ++ } ++ } while (status & (1 << 9)); ++ } ++ ++ 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 (data && usedma) { ++ /* IDMASTAREG ++ * IDST[0] : idma tx int ++ * IDST[1] : idma rx int ++ * IDST[2] : idma fatal bus error ++ * IDST[4] : idma descriptor invalid ++ * IDST[5] : idma error summary ++ * IDST[8] : idma normal interrupt sumary ++ * IDST[9] : idma abnormal interrupt sumary ++ */ ++ status = readl(&mmchost->reg->idst); ++ writel(status, &mmchost->reg->idst); ++ writel(0, &mmchost->reg->idie); ++ writel(0, &mmchost->reg->dmac); ++ writel(readl(&mmchost->reg->gctrl) & ~(0x1 << 5), ++ &mmchost->reg->gctrl); ++ } ++ if (error < 0) { ++ writel(0x7, &mmchost->reg->gctrl); ++ mmc_update_clk(mmc); ++ } ++ writel(0xffffffff, &mmchost->reg->rint); ++ writel(readl(&mmchost->reg->gctrl) | (1 << 1), &mmchost->reg->gctrl); ++ ++ return error; ++} ++ ++int sunxi_mmc_init(int sdc_no) ++{ ++ struct mmc *mmc; ++ ++ memset(&mmc_dev[sdc_no], 0, sizeof(struct mmc)); ++ memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); ++ mmc = &mmc_dev[sdc_no]; ++ ++ sprintf(mmc->name, "SUNXI SD/MMC"); ++ mmc->priv = &mmc_host[sdc_no]; ++ mmc->send_cmd = mmc_send_cmd; ++ mmc->set_ios = mmc_set_ios; ++ mmc->init = mmc_core_init; ++ ++ mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; ++ mmc->host_caps = MMC_MODE_4BIT; ++ mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; ++ ++ mmc->f_min = 400000; ++ mmc->f_max = 52000000; ++ ++ mmc_resource_init(sdc_no); ++ mmc_clk_io_on(sdc_no); ++ ++ mmc_register(mmc); ++ ++ return 0; ++} +diff -ruN u-boot-2014.01-rc1/drivers/net/designware.c u-boot-sunxi/drivers/net/designware.c +--- u-boot-2014.01-rc1/drivers/net/designware.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/net/designware.c 2014-03-05 23:14:48.024088546 +0100 +@@ -154,7 +154,7 @@ + /* Resore the HW MAC address as it has been lost during MAC reset */ + dw_write_hwaddr(dev); + +- writel(FIXEDBURST | PRIORXTX_41 | BURST_16, ++ writel(FIXEDBURST | PRIORXTX_41 | BURST_8, + &dma_p->busmode); + + writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD | +diff -ruN u-boot-2014.01-rc1/drivers/net/Makefile u-boot-sunxi/drivers/net/Makefile +--- u-boot-2014.01-rc1/drivers/net/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/net/Makefile 2014-03-05 23:14:48.020088600 +0100 +@@ -50,7 +50,8 @@ + 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_SUNXI_GMAC) += sunxi_gmac.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.01-rc1/drivers/net/sunxi_emac.c u-boot-sunxi/drivers/net/sunxi_emac.c +--- u-boot-2014.01-rc1/drivers/net/sunxi_emac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/net/sunxi_emac.c 2014-03-05 23:14:48.056088119 +0100 +@@ -0,0 +1,521 @@ ++/* ++ * sunxi_emac.c -- Allwinner A10 ethernet driver ++ * ++ * (C) Copyright 2012, Stefan Roese ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* EMAC register */ ++struct emac_regs { ++ u32 ctl; /* 0x00 */ ++ u32 tx_mode; /* 0x04 */ ++ u32 tx_flow; /* 0x08 */ ++ u32 tx_ctl0; /* 0x0c */ ++ u32 tx_ctl1; /* 0x10 */ ++ u32 tx_ins; /* 0x14 */ ++ u32 tx_pl0; /* 0x18 */ ++ u32 tx_pl1; /* 0x1c */ ++ u32 tx_sta; /* 0x20 */ ++ u32 tx_io_data; /* 0x24 */ ++ u32 tx_io_data1;/* 0x28 */ ++ u32 tx_tsvl0; /* 0x2c */ ++ u32 tx_tsvh0; /* 0x30 */ ++ u32 tx_tsvl1; /* 0x34 */ ++ u32 tx_tsvh1; /* 0x38 */ ++ u32 rx_ctl; /* 0x3c */ ++ u32 rx_hash0; /* 0x40 */ ++ u32 rx_hash1; /* 0x44 */ ++ u32 rx_sta; /* 0x48 */ ++ u32 rx_io_data; /* 0x4c */ ++ u32 rx_fbc; /* 0x50 */ ++ u32 int_ctl; /* 0x54 */ ++ u32 int_sta; /* 0x58 */ ++ u32 mac_ctl0; /* 0x5c */ ++ u32 mac_ctl1; /* 0x60 */ ++ u32 mac_ipgt; /* 0x64 */ ++ u32 mac_ipgr; /* 0x68 */ ++ u32 mac_clrt; /* 0x6c */ ++ u32 mac_maxf; /* 0x70 */ ++ u32 mac_supp; /* 0x74 */ ++ u32 mac_test; /* 0x78 */ ++ u32 mac_mcfg; /* 0x7c */ ++ u32 mac_mcmd; /* 0x80 */ ++ u32 mac_madr; /* 0x84 */ ++ u32 mac_mwtd; /* 0x88 */ ++ u32 mac_mrdd; /* 0x8c */ ++ u32 mac_mind; /* 0x90 */ ++ u32 mac_ssrr; /* 0x94 */ ++ u32 mac_a0; /* 0x98 */ ++ u32 mac_a1; /* 0x9c */ ++}; ++ ++/* SRAMC register */ ++struct sunxi_sramc_regs { ++ u32 ctrl0; ++ u32 ctrl1; ++}; ++ ++/* 0: Disable 1: Aborted frame enable(default) */ ++#define EMAC_TX_AB_M (0x1 << 0) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_TX_TM (0x1 << 1) ++ ++#define EMAC_TX_SETUP (0) ++ ++/* 0: DRQ asserted 1: DRQ automatically(default) */ ++#define EMAC_RX_DRQ_MODE (0x1 << 1) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_RX_TM (0x1 << 2) ++/* 0: Normal(default) 1: Pass all Frames */ ++#define EMAC_RX_PA (0x1 << 4) ++/* 0: Normal(default) 1: Pass Control Frames */ ++#define EMAC_RX_PCF (0x1 << 5) ++/* 0: Normal(default) 1: Pass Frames with CRC Error */ ++#define EMAC_RX_PCRCE (0x1 << 6) ++/* 0: Normal(default) 1: Pass Frames with Length Error */ ++#define EMAC_RX_PLE (0x1 << 7) ++/* 0: Normal 1: Pass Frames length out of range(default) */ ++#define EMAC_RX_POR (0x1 << 8) ++/* 0: Not accept 1: Accept unicast Packets(default) */ ++#define EMAC_RX_UCAD (0x1 << 16) ++/* 0: Normal(default) 1: DA Filtering */ ++#define EMAC_RX_DAF (0x1 << 17) ++/* 0: Not accept 1: Accept multicast Packets(default) */ ++#define EMAC_RX_MCO (0x1 << 20) ++/* 0: Disable(default) 1: Enable Hash filter */ ++#define EMAC_RX_MHF (0x1 << 21) ++/* 0: Not accept 1: Accept Broadcast Packets(default) */ ++#define EMAC_RX_BCO (0x1 << 22) ++/* 0: Disable(default) 1: Enable SA Filtering */ ++#define EMAC_RX_SAF (0x1 << 24) ++/* 0: Normal(default) 1: Inverse Filtering */ ++#define EMAC_RX_SAIF (0x1 << 25) ++ ++#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ ++ EMAC_RX_MCO | EMAC_RX_BCO) ++ ++/* 0: Disable 1: Enable Receive Flow Control(default) */ ++#define EMAC_MAC_CTL0_RFC (0x1 << 2) ++/* 0: Disable 1: Enable Transmit Flow Control(default) */ ++#define EMAC_MAC_CTL0_TFC (0x1 << 3) ++ ++#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) ++ ++/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ ++#define EMAC_MAC_CTL1_FLC (0x1 << 1) ++/* 0: Disable(default) 1: Enable Huge Frame */ ++#define EMAC_MAC_CTL1_HF (0x1 << 2) ++/* 0: Disable(default) 1: Enable MAC Delayed CRC */ ++#define EMAC_MAC_CTL1_DCRC (0x1 << 3) ++/* 0: Disable 1: Enable MAC CRC(default) */ ++#define EMAC_MAC_CTL1_CRC (0x1 << 4) ++/* 0: Disable 1: Enable MAC PAD Short frames(default) */ ++#define EMAC_MAC_CTL1_PC (0x1 << 5) ++/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ ++#define EMAC_MAC_CTL1_VC (0x1 << 6) ++/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ ++#define EMAC_MAC_CTL1_ADP (0x1 << 7) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_PRE (0x1 << 8) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_LPE (0x1 << 9) ++/* 0: Disable(default) 1: Enable no back off */ ++#define EMAC_MAC_CTL1_NB (0x1 << 12) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_BNB (0x1 << 13) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_ED (0x1 << 14) ++ ++#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ ++ EMAC_MAC_CTL1_PC) ++ ++#define EMAC_MAC_IPGT 0x15 ++ ++#define EMAC_MAC_NBTB_IPG1 0xc ++#define EMAC_MAC_NBTB_IPG2 0x12 ++ ++#define EMAC_MAC_CW 0x37 ++#define EMAC_MAC_RM 0xf ++ ++#define EMAC_MAC_MFL 0x0600 ++ ++/* Receive status */ ++#define EMAC_CRCERR (0x1 << 4) ++#define EMAC_LENERR (0x3 << 5) ++ ++#define DMA_CPU_TRRESHOLD 2000 ++ ++struct emac_eth_dev { ++ u32 speed; ++ u32 duplex; ++ u32 phy_configured; ++ int link_printed; ++}; ++ ++struct emac_rxhdr { ++ s16 rx_len; ++ u16 rx_status; ++}; ++ ++static void emac_inblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ u32 *buf = data; ++ ++ do { ++ u32 x = readl(reg); ++ *buf++ = x; ++ } while (--cnt); ++ } ++} ++ ++static void emac_outblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ const u32 *buf = data; ++ ++ do { ++ writel(*buf++, reg); ++ } while (--cnt); ++ } ++} ++ ++/* Read a word from phyxcer */ ++static int emac_phy_read(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short *value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait read complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ *value = readl(®s->mac_mrdd); ++ ++ return 0; ++} ++ ++/* Write a word to phyxcer */ ++static int emac_phy_write(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait write complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ writel(value, ®s->mac_mwtd); ++ ++ return 0; ++} ++ ++static void emac_setup(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ u32 reg_val; ++ u16 phy_val; ++ u32 duplex_flag; ++ ++ /* Set up TX */ ++ writel(EMAC_TX_SETUP, ®s->tx_mode); ++ ++ /* Set up RX */ ++ writel(EMAC_RX_SETUP, ®s->rx_ctl); ++ ++ /* Set MAC */ ++ /* Set MAC CTL0 */ ++ writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); ++ ++ /* Set MAC CTL1 */ ++ emac_phy_read(dev->name, 1, 0, &phy_val); ++ debug("PHY SETUP, reg 0 value: %x\n", phy_val); ++ duplex_flag = !!(phy_val & (1 << 8)); ++ ++ reg_val = 0; ++ if (duplex_flag) ++ reg_val = (0x1 << 0); ++ writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); ++ ++ /* Set up IPGT */ ++ writel(EMAC_MAC_IPGT, ®s->mac_ipgt); ++ ++ /* Set up IPGR */ ++ writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); ++ ++ /* Set up Collison window */ ++ writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); ++ ++ /* Set up Max Frame Length */ ++ writel(EMAC_MAC_MFL, ®s->mac_maxf); ++} ++ ++static void emac_reset(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ debug("resetting device\n"); ++ ++ /* RESET device */ ++ writel(0, ®s->ctl); ++ udelay(200); ++ ++ writel(1, ®s->ctl); ++ udelay(200); ++} ++ ++static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_eth_dev *priv = dev->priv; ++ u16 phy_reg; ++ ++ /* Init EMAC */ ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x8); ++ udelay(1); ++ ++ /* Init MAC */ ++ ++ /* Soft reset MAC */ ++ clrbits_le32(®s->mac_ctl0, 0x1 << 15); ++ ++ /* Clear RX counter */ ++ writel(0x0, ®s->rx_fbc); ++ udelay(1); ++ ++ /* Set up EMAC */ ++ emac_setup(dev); ++ ++ writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | ++ dev->enetaddr[2], ®s->mac_a1); ++ writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | ++ dev->enetaddr[5], ®s->mac_a0); ++ ++ mdelay(1); ++ ++ emac_reset(dev); ++ ++ /* PHY POWER UP */ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); ++ mdelay(1); ++ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ ++ priv->speed = miiphy_speed(dev->name, 0); ++ priv->duplex = miiphy_duplex(dev->name, 0); ++ ++ /* Print link status only once */ ++ if (!priv->link_printed) { ++ printf("ENET Speed is %d Mbps - %s duplex connection\n", ++ priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); ++ priv->link_printed = 1; ++ } ++ ++ /* Set EMAC SPEED depend on PHY */ ++ clrsetbits_le32(®s->mac_supp, 1 << 8, ++ ((phy_reg & (0x1 << 13)) >> 13) << 8); ++ ++ /* Set duplex depend on phy */ ++ clrsetbits_le32(®s->mac_ctl1, 1 << 0, ++ ((phy_reg & (0x1 << 8)) >> 8) << 0); ++ ++ /* Enable RX/TX */ ++ setbits_le32(®s->ctl, 0x7); ++ ++ return 0; ++} ++ ++static void sunxi_emac_eth_halt(struct eth_device *dev) ++{ ++ /* Nothing to do here */ ++} ++ ++static int sunxi_emac_eth_recv(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_rxhdr rxhdr; ++ u32 rxcount; ++ u32 reg_val; ++ int rx_len; ++ int rx_status; ++ int good_packet; ++ ++ /* Check packet ready or not */ ++ ++ /* Race warning: The first packet might arrive with ++ * the interrupts disabled, but the second will fix ++ */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) { ++ /* Had one stuck? */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) ++ return 0; ++ } ++ ++ reg_val = readl(®s->rx_io_data); ++ if (reg_val != 0x0143414d) { ++ /* Disable RX */ ++ clrbits_le32(®s->ctl, 0x1 << 2); ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x1 << 3); ++ while (readl(®s->rx_ctl) & (0x1 << 3)) ++ ; ++ ++ /* Enable RX */ ++ setbits_le32(®s->ctl, 0x1 << 2); ++ ++ return 0; ++ } ++ ++ /* A packet ready now ++ * Get status/length ++ */ ++ good_packet = 1; ++ ++ emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); ++ ++ rx_len = rxhdr.rx_len; ++ rx_status = rxhdr.rx_status; ++ ++ /* Packet Status check */ ++ if (rx_len < 0x40) { ++ good_packet = 0; ++ debug("RX: Bad Packet (runt)\n"); ++ } ++ ++ /* rx_status is identical to RSR register. */ ++ if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { ++ good_packet = 0; ++ if (rx_status & EMAC_CRCERR) ++ printf("crc error\n"); ++ if (rx_status & EMAC_LENERR) ++ printf("length error\n"); ++ } ++ ++ /* Move data from EMAC */ ++ if (good_packet) { ++ if (rx_len > DMA_CPU_TRRESHOLD) { ++ printf("Received packet is too big (len=%d)\n", rx_len); ++ } else { ++ emac_inblk_32bit((void *)®s->rx_io_data, ++ NetRxPackets[0], rx_len); ++ ++ /* Pass to upper layer */ ++ NetReceive(NetRxPackets[0], rx_len); ++ return rx_len; ++ } ++ } ++ ++ return 0; ++} ++ ++static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* Select channel 0 */ ++ writel(0, ®s->tx_ins); ++ ++ /* Write packet */ ++ emac_outblk_32bit((void *)®s->tx_io_data, packet, len); ++ ++ /* Set TX len */ ++ writel(len, ®s->tx_pl0); ++ ++ /* Start translate from fifo to phy */ ++ setbits_le32(®s->tx_ctl0, 1); ++ ++ return 0; ++} ++ ++int sunxi_emac_initialize(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sunxi_sramc_regs *sram = ++ (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; ++ struct emac_regs *regs = ++ (struct emac_regs *)SUNXI_EMAC_BASE; ++ struct eth_device *dev; ++ struct emac_eth_dev *priv; ++ int pin; ++ ++ dev = malloc(sizeof(*dev)); ++ if (dev == NULL) ++ return -ENOMEM; ++ ++ priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); ++ if (!priv) { ++ free(dev); ++ return -ENOMEM; ++ } ++ ++ memset(dev, 0, sizeof(*dev)); ++ memset(priv, 0, sizeof(struct emac_eth_dev)); ++ ++ /* Map SRAM to EMAC */ ++ setbits_le32(&sram->ctrl1, 0x5 << 2); ++ ++ /* Configure pin mux settings for MII Ethernet */ ++ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) ++ sunxi_gpio_set_cfgpin(pin, 2); ++ ++ /* Set up clock gating */ ++ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); ++ ++ /* Set MII clock */ ++ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); ++ ++ dev->iobase = (int)regs; ++ dev->priv = priv; ++ dev->init = sunxi_emac_eth_init; ++ dev->halt = sunxi_emac_eth_halt; ++ dev->send = sunxi_emac_eth_send; ++ dev->recv = sunxi_emac_eth_recv; ++ strcpy(dev->name, "emac"); ++ ++ eth_register(dev); ++ ++ miiphy_register(dev->name, emac_phy_read, emac_phy_write); ++ ++ return 0; ++} +diff -ruN u-boot-2014.01-rc1/drivers/net/sunxi_gmac.c u-boot-sunxi/drivers/net/sunxi_gmac.c +--- u-boot-2014.01-rc1/drivers/net/sunxi_gmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/net/sunxi_gmac.c 2014-03-05 23:14:48.056088119 +0100 +@@ -0,0 +1,45 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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, 5); ++ sunxi_gpio_set_drv(pin, 3); ++ } ++ ++#ifdef CONFIG_RGMII ++ designware_initialize(0, SUNXI_GMAC_BASE, 0x1, PHY_INTERFACE_MODE_RGMII); ++#else ++ designware_initialize(0, SUNXI_GMAC_BASE, 0x1, PHY_INTERFACE_MODE_MII); ++#endif ++ ++ return 0; ++} +diff -ruN u-boot-2014.01-rc1/drivers/net/sunxi_wemac.c u-boot-sunxi/drivers/net/sunxi_wemac.c +--- u-boot-2014.01-rc1/drivers/net/sunxi_wemac.c 2013-11-25 22:49:32.000000000 +0100 ++++ 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 +- * +- * SPDX-License-Identifier: GPL-2.0+ +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* EMAC register */ +-struct wemac_regs { +- u32 ctl; /* 0x00 */ +- u32 tx_mode; /* 0x04 */ +- u32 tx_flow; /* 0x08 */ +- u32 tx_ctl0; /* 0x0c */ +- u32 tx_ctl1; /* 0x10 */ +- u32 tx_ins; /* 0x14 */ +- u32 tx_pl0; /* 0x18 */ +- u32 tx_pl1; /* 0x1c */ +- u32 tx_sta; /* 0x20 */ +- u32 tx_io_data; /* 0x24 */ +- u32 tx_io_data1; /* 0x28 */ +- u32 tx_tsvl0; /* 0x2c */ +- u32 tx_tsvh0; /* 0x30 */ +- u32 tx_tsvl1; /* 0x34 */ +- u32 tx_tsvh1; /* 0x38 */ +- u32 rx_ctl; /* 0x3c */ +- u32 rx_hash0; /* 0x40 */ +- u32 rx_hash1; /* 0x44 */ +- u32 rx_sta; /* 0x48 */ +- u32 rx_io_data; /* 0x4c */ +- u32 rx_fbc; /* 0x50 */ +- u32 int_ctl; /* 0x54 */ +- u32 int_sta; /* 0x58 */ +- u32 mac_ctl0; /* 0x5c */ +- u32 mac_ctl1; /* 0x60 */ +- u32 mac_ipgt; /* 0x64 */ +- u32 mac_ipgr; /* 0x68 */ +- u32 mac_clrt; /* 0x6c */ +- u32 mac_maxf; /* 0x70 */ +- u32 mac_supp; /* 0x74 */ +- u32 mac_test; /* 0x78 */ +- u32 mac_mcfg; /* 0x7c */ +- u32 mac_mcmd; /* 0x80 */ +- u32 mac_madr; /* 0x84 */ +- u32 mac_mwtd; /* 0x88 */ +- u32 mac_mrdd; /* 0x8c */ +- u32 mac_mind; /* 0x90 */ +- u32 mac_ssrr; /* 0x94 */ +- u32 mac_a0; /* 0x98 */ +- u32 mac_a1; /* 0x9c */ +-}; +- +-/* SRAMC register */ +-struct sunxi_sramc_regs { +- u32 ctrl0; +- u32 ctrl1; +-}; +- +-/* 0: Disable 1: Aborted frame enable(default) */ +-#define EMAC_TX_AB_M (0x1 << 0) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_TX_TM (0x1 << 1) +- +-#define EMAC_TX_SETUP (0) +- +-/* 0: DRQ asserted 1: DRQ automatically(default) */ +-#define EMAC_RX_DRQ_MODE (0x1 << 1) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_RX_TM (0x1 << 2) +-/* 0: Normal(default) 1: Pass all Frames */ +-#define EMAC_RX_PA (0x1 << 4) +-/* 0: Normal(default) 1: Pass Control Frames */ +-#define EMAC_RX_PCF (0x1 << 5) +-/* 0: Normal(default) 1: Pass Frames with CRC Error */ +-#define EMAC_RX_PCRCE (0x1 << 6) +-/* 0: Normal(default) 1: Pass Frames with Length Error */ +-#define EMAC_RX_PLE (0x1 << 7) +-/* 0: Normal 1: Pass Frames length out of range(default) */ +-#define EMAC_RX_POR (0x1 << 8) +-/* 0: Not accept 1: Accept unicast Packets(default) */ +-#define EMAC_RX_UCAD (0x1 << 16) +-/* 0: Normal(default) 1: DA Filtering */ +-#define EMAC_RX_DAF (0x1 << 17) +-/* 0: Not accept 1: Accept multicast Packets(default) */ +-#define EMAC_RX_MCO (0x1 << 20) +-/* 0: Disable(default) 1: Enable Hash filter */ +-#define EMAC_RX_MHF (0x1 << 21) +-/* 0: Not accept 1: Accept Broadcast Packets(default) */ +-#define EMAC_RX_BCO (0x1 << 22) +-/* 0: Disable(default) 1: Enable SA Filtering */ +-#define EMAC_RX_SAF (0x1 << 24) +-/* 0: Normal(default) 1: Inverse Filtering */ +-#define EMAC_RX_SAIF (0x1 << 25) +- +-#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ +- EMAC_RX_MCO | EMAC_RX_BCO) +- +-/* 0: Disable 1: Enable Receive Flow Control(default) */ +-#define EMAC_MAC_CTL0_RFC (0x1 << 2) +-/* 0: Disable 1: Enable Transmit Flow Control(default) */ +-#define EMAC_MAC_CTL0_TFC (0x1 << 3) +- +-#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) +- +-/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ +-#define EMAC_MAC_CTL1_FLC (0x1 << 1) +-/* 0: Disable(default) 1: Enable Huge Frame */ +-#define EMAC_MAC_CTL1_HF (0x1 << 2) +-/* 0: Disable(default) 1: Enable MAC Delayed CRC */ +-#define EMAC_MAC_CTL1_DCRC (0x1 << 3) +-/* 0: Disable 1: Enable MAC CRC(default) */ +-#define EMAC_MAC_CTL1_CRC (0x1 << 4) +-/* 0: Disable 1: Enable MAC PAD Short frames(default) */ +-#define EMAC_MAC_CTL1_PC (0x1 << 5) +-/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ +-#define EMAC_MAC_CTL1_VC (0x1 << 6) +-/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ +-#define EMAC_MAC_CTL1_ADP (0x1 << 7) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_PRE (0x1 << 8) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_LPE (0x1 << 9) +-/* 0: Disable(default) 1: Enable no back off */ +-#define EMAC_MAC_CTL1_NB (0x1 << 12) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_BNB (0x1 << 13) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_ED (0x1 << 14) +- +-#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ +- EMAC_MAC_CTL1_PC) +- +-#define EMAC_MAC_IPGT 0x15 +- +-#define EMAC_MAC_NBTB_IPG1 0xC +-#define EMAC_MAC_NBTB_IPG2 0x12 +- +-#define EMAC_MAC_CW 0x37 +-#define EMAC_MAC_RM 0xF +- +-#define EMAC_MAC_MFL 0x0600 +- +-/* Receive status */ +-#define EMAC_CRCERR (1 << 4) +-#define EMAC_LENERR (3 << 5) +- +-#define DMA_CPU_TRRESHOLD 2000 +- +-struct wemac_eth_dev { +- u32 speed; +- u32 duplex; +- u32 phy_configured; +- int link_printed; +-}; +- +-struct wemac_rxhdr { +- s16 rx_len; +- u16 rx_status; +-}; +- +-static void wemac_inblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- u32 *buf = data; +- +- do { +- u32 x = readl(reg); +- *buf++ = x; +- } while (--cnt); +- } +-} +- +-static void wemac_outblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- const u32 *buf = data; +- +- do { +- writel(*buf++, reg); +- } while (--cnt); +- } +-} +- +-/* +- * Read a word from phyxcer +- */ +-static int wemac_phy_read(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short *value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait read complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- *value = readl(®s->mac_mrdd); +- +- return 0; +-} +- +-/* +- * Write a word to phyxcer +- */ +-static int wemac_phy_write(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait write complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- writel(value, ®s->mac_mwtd); +- +- return 0; +-} +- +-static void emac_setup(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- u32 reg_val; +- u16 phy_val; +- u32 duplex_flag; +- +- /* Set up TX */ +- writel(EMAC_TX_SETUP, ®s->tx_mode); +- +- /* Set up RX */ +- writel(EMAC_RX_SETUP, ®s->rx_ctl); +- +- /* Set MAC */ +- /* Set MAC CTL0 */ +- writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); +- +- /* Set MAC CTL1 */ +- wemac_phy_read(dev->name, 1, 0, &phy_val); +- debug("PHY SETUP, reg 0 value: %x\n", phy_val); +- duplex_flag = !!(phy_val & (1 << 8)); +- +- reg_val = 0; +- if (duplex_flag) +- reg_val = (0x1 << 0); +- writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); +- +- /* Set up IPGT */ +- writel(EMAC_MAC_IPGT, ®s->mac_ipgt); +- +- /* Set up IPGR */ +- writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); +- +- /* Set up Collison window */ +- writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); +- +- /* Set up Max Frame Length */ +- writel(EMAC_MAC_MFL, ®s->mac_maxf); +-} +- +-static void wemac_reset(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- debug("resetting device\n"); +- +- /* RESET device */ +- writel(0, ®s->ctl); +- udelay(200); +- +- writel(1, ®s->ctl); +- udelay(200); +-} +- +-static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_eth_dev *priv = dev->priv; +- u16 phy_reg; +- +- /* Init EMAC */ +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 0x8); +- udelay(1); +- +- /* Init MAC */ +- +- /* Soft reset MAC */ +- clrbits_le32(®s->mac_ctl0, 1 << 15); +- +- /* Set MII clock */ +- clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); +- +- /* Clear RX counter */ +- writel(0x0, ®s->rx_fbc); +- udelay(1); +- +- /* Set up EMAC */ +- emac_setup(dev); +- +- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | +- dev->enetaddr[2], ®s->mac_a1); +- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | +- dev->enetaddr[5], ®s->mac_a0); +- +- mdelay(1); +- +- wemac_reset(dev); +- +- /* PHY POWER UP */ +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); +- mdelay(1); +- +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- +- priv->speed = miiphy_speed(dev->name, 0); +- priv->duplex = miiphy_duplex(dev->name, 0); +- +- /* Print link status only once */ +- if (!priv->link_printed) { +- printf("ENET Speed is %d Mbps - %s duplex connection\n", +- priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); +- priv->link_printed = 1; +- } +- +- /* Set EMAC SPEED depend on PHY */ +- clrsetbits_le32(®s->mac_supp, 1 << 8, +- ((phy_reg & (1 << 13)) >> 13) << 8); +- +- /* Set duplex depend on phy */ +- clrsetbits_le32(®s->mac_ctl1, 1 << 0, +- ((phy_reg & (1 << 8)) >> 8) << 0); +- +- /* Enable RX/TX */ +- setbits_le32(®s->ctl, 0x7); +- +- return 0; +-} +- +-static void sunxi_wemac_eth_halt(struct eth_device *dev) +-{ +- /* Nothing to do here */ +-} +- +-static int sunxi_wemac_eth_recv(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_rxhdr rxhdr; +- u32 rxcount; +- u32 reg_val; +- int rx_len; +- int rx_status; +- int good_packet; +- +- /* Check packet ready or not */ +- +- /* +- * Race warning: The first packet might arrive with +- * the interrupts disabled, but the second will fix +- */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) { +- /* Had one stuck? */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) +- return 0; +- } +- +- reg_val = readl(®s->rx_io_data); +- if (reg_val != 0x0143414d) { +- /* Disable RX */ +- clrbits_le32(®s->ctl, 1 << 2); +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 1 << 3); +- while (readl(®s->rx_ctl) & (1 << 3)) +- ; +- +- /* Enable RX */ +- setbits_le32(®s->ctl, 1 << 2); +- +- return 0; +- } +- +- /* +- * A packet ready now +- * Get status/length +- */ +- good_packet = 1; +- +- wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); +- +- rx_len = rxhdr.rx_len; +- rx_status = rxhdr.rx_status; +- +- /* Packet Status check */ +- if (rx_len < 0x40) { +- good_packet = 0; +- debug("RX: Bad Packet (runt)\n"); +- } +- +- /* rx_status is identical to RSR register. */ +- if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { +- good_packet = 0; +- if (rx_status & EMAC_CRCERR) +- printf("crc error\n"); +- if (rx_status & EMAC_LENERR) +- printf("length error\n"); +- } +- +- /* Move data from WEMAC */ +- if (good_packet) { +- if (rx_len > DMA_CPU_TRRESHOLD) { +- printf("Received packet is too big (len=%d)\n", rx_len); +- } else { +- wemac_inblk_32bit((void *)®s->rx_io_data, +- NetRxPackets[0], rx_len); +- +- /* Pass to upper layer */ +- NetReceive(NetRxPackets[0], rx_len); +- return rx_len; +- } +- } +- +- return 0; +-} +- +-static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* Select channel 0 */ +- writel(0, ®s->tx_ins); +- +- /* Write packet */ +- wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); +- +- /* Set TX len */ +- writel(len, ®s->tx_pl0); +- +- /* Start translate from fifo to phy */ +- setbits_le32(®s->tx_ctl0, 1); +- +- return 0; +-} +- +-int sunxi_wemac_initialize(void) +-{ +- struct sunxi_ccm_reg *const ccm = +- (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; +- struct sunxi_sramc_regs *sram = +- (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; +- struct eth_device *dev; +- struct wemac_eth_dev *priv; +- int pin; +- +- dev = malloc(sizeof(*dev)); +- if (dev == NULL) +- return -ENOMEM; +- +- priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); +- if (!priv) { +- free(dev); +- return -ENOMEM; +- } +- +- memset(dev, 0, sizeof(*dev)); +- memset(priv, 0, sizeof(struct wemac_eth_dev)); +- +- /* Map SRAM to EMAC */ +- setbits_le32(&sram->ctrl1, 0x5 << 2); +- +- /* Configure pin mux settings for MII Ethernet */ +- for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) +- sunxi_gpio_set_cfgpin(pin, 2); +- +- /* Set up clock gating */ +- setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); +- +- dev->iobase = SUNXI_EMAC_BASE; +- dev->priv = priv; +- dev->init = sunxi_wemac_eth_init; +- dev->halt = sunxi_wemac_eth_halt; +- dev->send = sunxi_wemac_eth_send; +- dev->recv = sunxi_wemac_eth_recv; +- strcpy(dev->name, "wemac"); +- +- eth_register(dev); +- +- miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); +- +- return 0; +-} +diff -ruN u-boot-2014.01-rc1/drivers/power/axp152.c u-boot-sunxi/drivers/power/axp152.c +--- u-boot-2014.01-rc1/drivers/power/axp152.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp152.c 2014-03-05 23:14:48.060088066 +0100 +@@ -0,0 +1,138 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom ++ * ++ * 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 ++ */ ++#include ++#include ++#include ++ ++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, ++}; ++ ++int axp152_write(enum axp152_reg reg, u8 val) ++{ ++ return i2c_write(0x30, reg, 1, &val, 1); ++} ++ ++int axp152_read(enum axp152_reg reg, u8 *val) ++{ ++ return i2c_read(0x30, reg, 1, val, 1); ++} ++ ++int axp152_set_dcdc2(int mvolt) ++{ ++ int target = (mvolt - 700) / 25; ++ int rc; ++ u8 current; ++ ++ if (target < 0) ++ target = 0; ++ if (target > (1<<6)-1) ++ target = (1<<6)-1; ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != target) { ++ if (current < target) ++ current++; ++ else ++ current--; ++ rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ return rc; ++} ++ ++int axp152_set_dcdc3(int mvolt) ++{ ++ int target = (mvolt - 700) / 50; ++ u8 reg; ++ int rc; ++ ++ if (target < 0) ++ target = 0; ++ if (target > (1<<6)-1) ++ target = (1<<6)-1; ++ rc = axp152_write(AXP152_DCDC3_VOLTAGE, target); ++ rc |= axp152_read(AXP152_DCDC3_VOLTAGE, ®); ++ return rc; ++} ++ ++int axp152_set_dcdc4(int mvolt) ++{ ++ int target = (mvolt - 700) / 25; ++ u8 reg; ++ int rc; ++ ++ if (target < 0) ++ target = 0; ++ if (target > (1<<7)-1) ++ target = (1<<7)-1; ++ rc = axp152_write(AXP152_DCDC4_VOLTAGE, target); ++ rc |= axp152_read(AXP152_DCDC4_VOLTAGE, ®); ++ return rc; ++} ++ ++int axp152_set_ldo2(int mvolt) ++{ ++ int target = (mvolt - 700) / 100; ++ int rc; ++ u8 reg; ++ ++ if (target < 0) ++ target = 0; ++ if (target > 31) ++ target = 31; ++ rc = axp152_write(AXP152_LDO2_VOLTAGE, target); ++ rc |= axp152_read(AXP152_LDO2_VOLTAGE, ®); ++ return rc; ++} ++ ++void axp152_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp152_read(AXP152_SHUTDOWN, &val) != 0) ++ return; ++ val |= 1 << 7; ++ 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.01-rc1/drivers/power/axp209.c u-boot-sunxi/drivers/power/axp209.c +--- u-boot-2014.01-rc1/drivers/power/axp209.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp209.c 2014-03-05 23:14:48.060088066 +0100 +@@ -0,0 +1,215 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++ ++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_STATUS3 = 0x4a, ++ AXP209_IRQ_STATUS5 = 0x4c, ++ AXP209_SHUTDOWN = 0x32, ++}; ++ ++#define AXP209_POWER_STATUS_ON_BY_DC (1<<0) ++ ++#define AXP209_IRQ3_PEK_SHORT (1<<1) ++#define AXP209_IRQ3_PEK_LONG (1<<0) ++ ++#define AXP209_IRQ5_PEK_UP (1<<6) ++#define AXP209_IRQ5_PEK_DOWN (1<<5) ++ ++int axp209_write(enum axp209_reg reg, u8 val) ++{ ++ return i2c_write(0x34, reg, 1, &val, 1); ++} ++ ++int axp209_read(enum axp209_reg reg, u8 *val) ++{ ++ return i2c_read(0x34, reg, 1, val, 1); ++} ++ ++int axp209_set_dcdc2(int mvolt) ++{ ++ int cfg = (mvolt - 700) / 25; ++ int rc; ++ u8 current; ++ ++ if (cfg < 0) ++ cfg = 0; ++ if (cfg > (1 << 6) - 1) ++ cfg = (1 << 6) - 1; ++ ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != cfg) { ++ if (current < cfg) ++ current++; ++ else ++ current--; ++ ++ rc = axp209_write(AXP209_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ ++ return rc; ++} ++ ++int axp209_set_dcdc3(int mvolt) ++{ ++ int cfg = (mvolt - 700) / 25; ++ u8 reg; ++ int rc; ++ ++ if (cfg < 0) ++ cfg = 0; ++ if (cfg > (1 << 7) - 1) ++ cfg = (1 << 7) - 1; ++ ++ rc = axp209_write(AXP209_DCDC3_VOLTAGE, cfg); ++ rc |= axp209_read(AXP209_DCDC3_VOLTAGE, ®); ++ ++ return rc; ++} ++ ++int axp209_set_ldo2(int mvolt) ++{ ++ int cfg = (mvolt - 1800) / 100; ++ int rc; ++ u8 reg; ++ ++ if (cfg < 0) ++ cfg = 0; ++ if (cfg > 15) ++ cfg = 15; ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ reg = (reg & 0x0f) | (cfg << 4); ++ rc = axp209_write(AXP209_LDO24_VOLTAGE, reg); ++ if (rc) ++ return rc; ++ ++ return 0; ++} ++ ++int axp209_set_ldo3(int mvolt) ++{ ++ int cfg = (mvolt - 700) / 25; ++ ++ if (cfg < 0) ++ cfg = 0; ++ if (cfg > 127) ++ cfg = 127; ++ if (mvolt == -1) ++ cfg = 0x80; /* detemined by LDO3IN pin */ ++ ++ return axp209_write(AXP209_LDO3_VOLTAGE, cfg); ++} ++ ++int axp209_set_ldo4(int mvolt) ++{ ++ int cfg = (mvolt - 1800) / 100; ++ int 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 = 0; mvolt < vindex[cfg] && cfg < 15; cfg++); ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ /* LDO4 configuration is in lower 4 bits */ ++ reg = (reg & 0xf0) | (cfg << 0); ++ rc = axp209_write(AXP209_LDO24_VOLTAGE, reg); ++ if (rc) ++ return rc; ++ ++ return 0; ++} ++ ++void axp209_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp209_read(AXP209_SHUTDOWN, &val) != 0) ++ return; ++ ++ val |= 1 << 7; ++ ++ 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.01-rc1/drivers/power/Makefile u-boot-sunxi/drivers/power/Makefile +--- u-boot-2014.01-rc1/drivers/power/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/power/Makefile 2014-03-05 23:14:48.060088066 +0100 +@@ -5,6 +5,8 @@ + # SPDX-License-Identifier: GPL-2.0+ + # + ++obj-$(CONFIG_AXP152_POWER) += axp152.o ++obj-$(CONFIG_AXP209_POWER) += axp209.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.01-rc1/drivers/serial/arm_dcc.c u-boot-sunxi/drivers/serial/arm_dcc.c +--- u-boot-2014.01-rc1/drivers/serial/arm_dcc.c 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/drivers/serial/arm_dcc.c 2014-03-05 23:14:48.068087958 +0100 +@@ -29,7 +29,7 @@ + #include + #include + +-#if defined(CONFIG_CPU_V6) ++#if defined(CONFIG_CPU_V6) || 1 + /* + * ARMV6 + */ +diff -ruN u-boot-2014.01-rc1/.git/config u-boot-sunxi/.git/config +--- u-boot-2014.01-rc1/.git/config 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/config 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1,11 @@ ++[core] ++ repositoryformatversion = 0 ++ filemode = true ++ bare = false ++ logallrefupdates = true ++[remote "origin"] ++ fetch = +refs/heads/*:refs/remotes/origin/* ++ url = https://bitbucket.org/zuperman/u-boot-sunxi.git ++[branch "sunxi-openwrt"] ++ remote = origin ++ merge = refs/heads/sunxi-openwrt +diff -ruN u-boot-2014.01-rc1/.git/description u-boot-sunxi/.git/description +--- u-boot-2014.01-rc1/.git/description 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/description 2014-03-05 23:14:20.056462031 +0100 +@@ -0,0 +1 @@ ++Unnamed repository; edit this file 'description' to name the repository. +diff -ruN u-boot-2014.01-rc1/.git/HEAD u-boot-sunxi/.git/HEAD +--- u-boot-2014.01-rc1/.git/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/HEAD 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1 @@ ++ref: refs/heads/sunxi-openwrt +diff -ruN u-boot-2014.01-rc1/.git/hooks/applypatch-msg.sample u-boot-sunxi/.git/hooks/applypatch-msg.sample +--- u-boot-2014.01-rc1/.git/hooks/applypatch-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/applypatch-msg.sample 2014-03-05 23:14:20.072461819 +0100 +@@ -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.01-rc1/.git/hooks/commit-msg.sample u-boot-sunxi/.git/hooks/commit-msg.sample +--- u-boot-2014.01-rc1/.git/hooks/commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/commit-msg.sample 2014-03-05 23:14:20.064461925 +0100 +@@ -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.01-rc1/.git/hooks/post-update.sample u-boot-sunxi/.git/hooks/post-update.sample +--- u-boot-2014.01-rc1/.git/hooks/post-update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/post-update.sample 2014-03-05 23:14:20.076461764 +0100 +@@ -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.01-rc1/.git/hooks/pre-applypatch.sample u-boot-sunxi/.git/hooks/pre-applypatch.sample +--- u-boot-2014.01-rc1/.git/hooks/pre-applypatch.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-applypatch.sample 2014-03-05 23:14:20.072461819 +0100 +@@ -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.01-rc1/.git/hooks/pre-commit.sample u-boot-sunxi/.git/hooks/pre-commit.sample +--- u-boot-2014.01-rc1/.git/hooks/pre-commit.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-commit.sample 2014-03-05 23:14:20.076461764 +0100 +@@ -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.01-rc1/.git/hooks/prepare-commit-msg.sample u-boot-sunxi/.git/hooks/prepare-commit-msg.sample +--- u-boot-2014.01-rc1/.git/hooks/prepare-commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/prepare-commit-msg.sample 2014-03-05 23:14:20.076461764 +0100 +@@ -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.01-rc1/.git/hooks/pre-rebase.sample u-boot-sunxi/.git/hooks/pre-rebase.sample +--- u-boot-2014.01-rc1/.git/hooks/pre-rebase.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-rebase.sample 2014-03-05 23:14:20.076461764 +0100 +@@ -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.01-rc1/.git/hooks/update.sample u-boot-sunxi/.git/hooks/update.sample +--- u-boot-2014.01-rc1/.git/hooks/update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/update.sample 2014-03-05 23:14:20.068461872 +0100 +@@ -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 )" >&2 ++ exit 1 ++fi ++ ++if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then ++ echo "Usage: $0 " >&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.01-rc1/.git/index and u-boot-sunxi/.git/index differ +diff -ruN u-boot-2014.01-rc1/.git/info/exclude u-boot-sunxi/.git/info/exclude +--- u-boot-2014.01-rc1/.git/info/exclude 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/info/exclude 2014-03-05 23:14:20.064461925 +0100 +@@ -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.01-rc1/.git/logs/HEAD u-boot-sunxi/.git/logs/HEAD +--- u-boot-2014.01-rc1/.git/logs/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/HEAD 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 d57e8f49a52e59486f49346975c826cf4c298d7e root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git +diff -ruN u-boot-2014.01-rc1/.git/logs/refs/heads/sunxi-openwrt u-boot-sunxi/.git/logs/refs/heads/sunxi-openwrt +--- u-boot-2014.01-rc1/.git/logs/refs/heads/sunxi-openwrt 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/heads/sunxi-openwrt 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 d57e8f49a52e59486f49346975c826cf4c298d7e root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git +diff -ruN u-boot-2014.01-rc1/.git/logs/refs/remotes/origin/HEAD u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD +--- u-boot-2014.01-rc1/.git/logs/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 a13f6664d65ce9bc68f05f8ecd10333ea9bcb012 root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git +Binary files u-boot-2014.01-rc1/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.idx and u-boot-sunxi/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.idx differ +Binary files u-boot-2014.01-rc1/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.pack and u-boot-sunxi/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.pack differ +diff -ruN u-boot-2014.01-rc1/.git/packed-refs u-boot-sunxi/.git/packed-refs +--- u-boot-2014.01-rc1/.git/packed-refs 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/packed-refs 2014-03-05 23:14:46.760105425 +0100 +@@ -0,0 +1,6 @@ ++# pack-refs with: peeled ++b83a10f893c1b36b878a4dc992a68879f2d98153 refs/remotes/origin/sunxi-3.12 ++d57e8f49a52e59486f49346975c826cf4c298d7e refs/remotes/origin/sunxi-openwrt ++a13f6664d65ce9bc68f05f8ecd10333ea9bcb012 refs/remotes/origin/sunxi-test ++adc9e13225d092362dea4e83c03ee161859f3a94 refs/tags/sunxi-openwrt-1 ++^d57e8f49a52e59486f49346975c826cf4c298d7e +diff -ruN u-boot-2014.01-rc1/.git/refs/heads/sunxi-openwrt u-boot-sunxi/.git/refs/heads/sunxi-openwrt +--- u-boot-2014.01-rc1/.git/refs/heads/sunxi-openwrt 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/heads/sunxi-openwrt 2014-03-05 23:14:46.924103235 +0100 +@@ -0,0 +1 @@ ++d57e8f49a52e59486f49346975c826cf4c298d7e +diff -ruN u-boot-2014.01-rc1/.git/refs/remotes/origin/HEAD u-boot-sunxi/.git/refs/remotes/origin/HEAD +--- u-boot-2014.01-rc1/.git/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/remotes/origin/HEAD 2014-03-05 23:14:46.852104197 +0100 +@@ -0,0 +1 @@ ++ref: refs/remotes/origin/sunxi-test +diff -ruN u-boot-2014.01-rc1/include/axp152.h u-boot-sunxi/include/axp152.h +--- u-boot-2014.01-rc1/include/axp152.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp152.h 2014-03-05 23:14:48.156086783 +0100 +@@ -0,0 +1,27 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * 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 ++ */ ++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.01-rc1/include/axp209.h u-boot-sunxi/include/axp209.h +--- u-boot-2014.01-rc1/include/axp209.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp209.h 2014-03-05 23:14:48.156086783 +0100 +@@ -0,0 +1,31 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom ++ * ++ * 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 ++ */ ++ ++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.01-rc1/include/common.h u-boot-sunxi/include/common.h +--- u-boot-2014.01-rc1/include/common.h 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/include/common.h 2014-03-05 23:14:48.160086731 +0100 +@@ -453,7 +453,7 @@ + void api_init (void); + + /* common/memsize.c */ +-long get_ram_size (long *, long); ++unsigned long get_ram_size (unsigned long *, unsigned long); + + /* $(BOARD)/$(BOARD).c */ + void reset_phy (void); +diff -ruN u-boot-2014.01-rc1/include/config_fallbacks.h u-boot-sunxi/include/config_fallbacks.h +--- u-boot-2014.01-rc1/include/config_fallbacks.h 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/include/config_fallbacks.h 2014-03-05 23:14:48.160086731 +0100 +@@ -54,6 +54,10 @@ + #define HAVE_BLOCK_DEVICE + #endif + ++#ifndef CONFIG_SYS_BOARD_NAME ++#define CONFIG_SYS_BOARD_NAME CONFIG_SYS_TARGET ++#endif ++ + #ifndef CONFIG_SYS_PROMPT + #define CONFIG_SYS_PROMPT "=> " + #endif +diff -ruN u-boot-2014.01-rc1/include/configs/sun4i.h u-boot-sunxi/include/configs/sun4i.h +--- u-boot-2014.01-rc1/include/configs/sun4i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun4i.h 2014-03-05 23:14:48.236085715 +0100 +@@ -0,0 +1,41 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom ++ * ++ * Configuration settings for the Allwinner A10 (sun4i) 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 ++ ++/* ++ * A10 specific configuration ++ */ ++#define CONFIG_SUN4I /* sun4i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun4i# " ++#define CONFIG_MACH_TYPE 4104 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.01-rc1/include/configs/sun5i.h u-boot-sunxi/include/configs/sun5i.h +--- u-boot-2014.01-rc1/include/configs/sun5i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun5i.h 2014-03-05 23:14:48.236085715 +0100 +@@ -0,0 +1,41 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom ++ * ++ * Configuration settings for the Allwinner A13 (sun5i) 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 ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_SUN5I /* sun5i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun5i# " ++#define CONFIG_MACH_TYPE 4138 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.01-rc1/include/configs/sun6i.h u-boot-sunxi/include/configs/sun6i.h +--- u-boot-2014.01-rc1/include/configs/sun6i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun6i.h 2014-03-05 23:14:48.236085715 +0100 +@@ -0,0 +1,43 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton ++ * (C) Copyright 2013 Maxime Ripard ++ * ++ * 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 ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.01-rc1/include/configs/sun7i.h u-boot-sunxi/include/configs/sun7i.h +--- u-boot-2014.01-rc1/include/configs/sun7i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun7i.h 2014-03-05 23:14:48.236085715 +0100 +@@ -0,0 +1,53 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton ++ * ++ * Configuration settings for the Allwinner A20 (sun7i) 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 ++ ++/* ++ * A20 specific configuration ++ */ ++#define CONFIG_SUN7I /* sun7i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun7i# " ++#define CONFIG_MACH_TYPE 4283 ++ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#define CONFIG_BOARD_POSTCLK_INIT 1 ++#endif ++ ++#define CONFIG_ARMV7_VIRT 1 ++#define CONFIG_ARMV7_NONSEC 1 ++#define CONFIG_ARMV7_PSCI 1 ++#define CONFIG_ARMV7_PSCI_NR_CPUS 2 ++#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE ++#define CONFIG_SYS_CLK_FREQ 24000000 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.01-rc1/include/configs/sunxi-common.h u-boot-sunxi/include/configs/sunxi-common.h +--- u-boot-2014.01-rc1/include/configs/sunxi-common.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sunxi-common.h 2014-03-05 23:14:48.236085715 +0100 +@@ -0,0 +1,478 @@ ++/* ++ * (C) Copyright 2012-2012 Henrik Nordstrom ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Configuration settings for the Allwinner sunxi series of boards. ++ * ++ * 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 _SUNXI_COMMON_CONFIG_H ++#define _SUNXI_COMMON_CONFIG_H ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_ALLWINNER /* It's a Allwinner chip */ ++#define CONFIG_SUNXI /* which is 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 /* 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 ++ ++/* 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 ++#ifdef 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 ++#define CONFIG_CMDLINE_EDITING ++ ++/* mmc config */ ++/* Can't use MMC slot 0 if the UART is directed there */ ++#ifndef CONFIG_SUN6I ++#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_MMC_SUNXI_USE_DMA ++#define CONFIG_ENV_IS_IN_MMC ++#define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ ++#endif ++#endif ++ ++/* ++ * Size of malloc() pool ++ * 1MB = 0x100000, 0x100000 = 1024 * 1024 ++ */ ++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) ++ ++/* Flat Device Tree (FDT/DT) support */ ++#define CONFIG_OF_LIBFDT ++#define CONFIG_SYS_BOOTMAPSZ (16 << 20) ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CONFIG_SYS_LONGHELP /* undef to save memory */ ++#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ ++#define CONFIG_CMD_ECHO ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++#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 */ ++ ++/* Boot Argument Buffer Size */ ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ ++/* memtest works on */ ++#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE ++#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + (256 << 20)) ++#define CONFIG_SYS_LOAD_ADDR 0x50000000 /* default load address */ ++ ++/* standalone support */ ++#define CONFIG_STANDALONE_LOAD_ADDR 0x50000000 ++ ++#define CONFIG_SYS_HZ 1000 ++ ++/* valid baudrates */ ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 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 \ ++ "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_BOOTDELAY 3 ++#define CONFIG_SYS_BOOT_GET_CMDLINE ++#define CONFIG_AUTO_COMPLETE ++ ++#include ++ ++/* Accept zimage + raw ramdisk without mkimage headers */ ++#define CONFIG_CMD_BOOTZ ++#define CONFIG_SUPPORT_RAW_INITRD ++ ++#define CONFIG_DOS_PARTITION ++#define CONFIG_CMD_FAT /* with this we can access fat bootfs */ ++#define CONFIG_FAT_WRITE /* enable write access */ ++#define CONFIG_CMD_EXT2 /* with this we can access ext2 bootfs */ ++#define CONFIG_CMD_EXT4 /* with this we can access ext4 bootfs */ ++ ++#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 0x50000000 ++#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 ++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK ++ ++#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 */ ++#define CONFIG_SPL_I2C_SUPPORT ++#define CONFIG_SYS_I2C_SPEED 400000 ++#define CONFIG_HARD_I2C ++#define CONFIG_SUNXI_I2C ++#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_NO_AXP ++#define CONFIG_AXP209_POWER ++#endif ++#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_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 */ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#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_SYS_DCACHE_OFF /* dw driver doesn't support dcache */ ++#define CONFIG_MII /* MII PHY management */ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#endif ++ ++#ifdef CONFIG_CMD_NET ++#define CONFIG_CMD_PING ++#define CONFIG_CMD_DHCP ++#define CONFIG_CMD_NFS ++#define CONFIG_CMD_SNTP ++#define CONFIG_TIMESTAMP /* Needed by SNTP */ ++#define CONFIG_CMD_DNS ++#define CONFIG_NETCONSOLE ++#define CONFIG_BOOTP_SUBNETMASK ++#define CONFIG_BOOTP_GATEWAY ++#define CONFIG_BOOTP_HOSTNAME ++#define CONFIG_BOOTP_NISDOMAIN ++#define CONFIG_BOOTP_BOOTPATH ++#define CONFIG_BOOTP_BOOTFILESIZE ++#define CONFIG_BOOTP_DNS ++#define CONFIG_BOOTP_DNS2 ++#define CONFIG_BOOTP_SEND_HOSTNAME ++#define CONFIG_BOOTP_NTPSERVER ++#define CONFIG_BOOTP_TIMEOFFSET ++#define CONFIG_BOOTP_MAY_FAIL ++#define CONFIG_BOOTP_SERVERIP ++#define CONFIG_BOOTP_DHCP_REQUEST_DELAY 50000 ++#define CONFIG_CMD_ELF ++#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 ++ ++#endif /* _SUNXI_COMMON_CONFIG_H */ +diff -ruN u-boot-2014.01-rc1/include/netdev.h u-boot-sunxi/include/netdev.h +--- u-boot-2014.01-rc1/include/netdev.h 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/include/netdev.h 2014-03-05 23:14:48.264085341 +0100 +@@ -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.01-rc1/Makefile u-boot-sunxi/Makefile +--- u-boot-2014.01-rc1/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/Makefile 2014-03-05 23:14:46.988102381 +0100 +@@ -486,6 +486,16 @@ + conv=notrunc 2>/dev/null + cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@ + ++# sunxi: Combined object with SPL U-Boot with sunxi header (sunxi-spl.bin) ++# and the full-blown U-Boot attached to it ++$(obj)u-boot-sunxi-with-spl.bin: $(obj)spl/sunxi-spl.bin $(obj)u-boot.img ++ tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \ ++ of=$(obj)spl/sunxi-spl-pad.bin 2>/dev/null ++ dd if=$(obj)spl/sunxi-spl.bin of=$(obj)spl/sunxi-spl-pad.bin \ ++ conv=notrunc 2>/dev/null ++ cat $(obj)spl/sunxi-spl-pad.bin $(obj)u-boot.img > $@ ++ rm $(obj)spl/sunxi-spl-pad.bin ++ + ifneq ($(CONFIG_TEGRA),) + $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin +@@ -566,6 +576,9 @@ + $(obj)tpl/u-boot-tpl.bin: $(SUBDIR_TOOLS) depend + $(MAKE) -C spl all CONFIG_TPL_BUILD=y + ++$(obj)spl/sunxi-spl.bin: $(SUBDIR_TOOLS) depend ++ $(MAKE) -C spl all ++ + # Explicitly make _depend in subdirs containing multiple targets to prevent + # parallel sub-makes creating .depend files simultaneously. + depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) \ +@@ -775,6 +788,8 @@ + sinclude $(obj).boards.depend + $(obj).boards.depend: boards.cfg + @awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE)" }' $< > $@ ++ @awk '(NF && $$1 !~ /^#/ && tolower($$7) != $$7) { print tolower($$7) ": " $$7 "_config; $$(MAKE)" }' $< >> $@ ++ @awk '(NF && $$1 !~ /^#/ && tolower($$7) != $$7) { print ".PHONY: " tolower($$7) "_config"; print tolower($$7)"_config: " $$7 "_config" }' $< >> $@ + + ######################################################################### + ######################################################################### +@@ -798,6 +813,7 @@ + $(obj)tools/gen_eth_addr $(obj)tools/img2srec \ + $(obj)tools/mk{env,}image $(obj)tools/mpc86x_clk \ + $(obj)tools/mk{$(BOARD),}spl \ ++ $(obj)tools/mksunxiboot \ + $(obj)tools/mxsboot \ + $(obj)tools/ncb $(obj)tools/ubsha1 \ + $(obj)tools/kernel-doc/docproc \ +@@ -857,6 +873,7 @@ + @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f + @rm -f $(obj)dts/*.tmp + @rm -f $(obj)spl/u-boot-spl{,-pad}.ais ++ @rm -f $(obj)spl/sun?i-spl.bin + + mrproper \ + distclean: clobber unconfig +diff -ruN u-boot-2014.01-rc1/mkconfig u-boot-sunxi/mkconfig +--- u-boot-2014.01-rc1/mkconfig 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/mkconfig 2014-03-05 23:14:48.292084967 +0100 +@@ -165,6 +165,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.01-rc1/snapshot.commit u-boot-sunxi/snapshot.commit +--- u-boot-2014.01-rc1/snapshot.commit 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/snapshot.commit 2014-03-05 23:14:48.300084861 +0100 +@@ -1 +1 @@ +-d19ad726bcd5d9106f7ba9c750462fcc369f1020 Mon, 25 Nov 2013 16:49:32 -0500 ++$Format:%H %cD$ +diff -ruN u-boot-2014.01-rc1/spl/Makefile u-boot-sunxi/spl/Makefile +--- u-boot-2014.01-rc1/spl/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/spl/Makefile 2014-03-05 23:14:48.300084861 +0100 +@@ -162,6 +162,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 +@@ -169,6 +175,12 @@ + $(OBJTREE)/tools/mk$(BOARD)spl $< $@ + endif + ++ifdef CONFIG_SUNXI ++$(obj)sunxi-spl.bin: $(obj)u-boot-spl.bin ++ $(OBJTREE)/tools/mksunxiboot \ ++ $(obj)u-boot-spl.bin $(obj)sunxi-spl.bin ++endif ++ + $(obj)$(SPL_BIN).bin: $(obj)$(SPL_BIN) + $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ + +diff -ruN u-boot-2014.01-rc1/tools/.gitignore u-boot-sunxi/tools/.gitignore +--- u-boot-2014.01-rc1/tools/.gitignore 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/tools/.gitignore 2014-03-05 23:14:48.300084861 +0100 +@@ -7,6 +7,7 @@ + /mkimage + /mpc86x_clk + /mxsboot ++/mksunxiboot + /ncb + /ncp + /proftool +diff -ruN u-boot-2014.01-rc1/tools/Makefile u-boot-sunxi/tools/Makefile +--- u-boot-2014.01-rc1/tools/Makefile 2013-11-25 22:49:32.000000000 +0100 ++++ u-boot-sunxi/tools/Makefile 2014-03-05 23:14:48.300084861 +0100 +@@ -54,6 +54,7 @@ + BIN_FILES-y += mkimage$(SFX) + BIN_FILES-$(CONFIG_EXYNOS5250) += mk$(BOARD)spl$(SFX) + BIN_FILES-$(CONFIG_MX23) += mxsboot$(SFX) ++BIN_FILES-$(CONFIG_SUNXI) += mksunxiboot$(SFX) + BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX) + BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX) + BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) +@@ -91,6 +92,7 @@ + OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o + OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o + OBJ_FILES-$(CONFIG_MX23) += mxsboot.o ++OBJ_FILES-$(CONFIG_SUNXI) += mksunxiboot.o + OBJ_FILES-$(CONFIG_MX28) += mxsboot.o + OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o + OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o +@@ -235,6 +237,10 @@ + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ + ++$(obj)mksunxiboot$(SFX): $(obj)mksunxiboot.o ++ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ ++ $(HOSTSTRIP) $@ ++ + $(obj)mxsboot$(SFX): $(obj)mxsboot.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ +diff -ruN u-boot-2014.01-rc1/tools/mksunxiboot.c u-boot-sunxi/tools/mksunxiboot.c +--- u-boot-2014.01-rc1/tools/mksunxiboot.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.c 2014-03-05 23:14:48.312084700 +0100 +@@ -0,0 +1,163 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * a simple tool to generate bootable image for sunxi platform. ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef unsigned char u8; ++typedef unsigned int u32; ++ ++/* boot head definition from sun4i boot code */ ++struct boot_file_head { ++ u32 jump_instruction; /* one intruction jumping to real code */ ++ u8 magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ ++ u32 check_sum; /* generated by PC */ ++ u32 length; /* generated by PC */ ++#if 1 ++ /* We use a simplified header, only filling in what is needed by the ++ * boot ROM. To be compatible with Allwinner tools the larger header ++ * below should be used, followed by a custom header if desired. */ ++ u8 pad[12]; /* align to 32 bytes */ ++#else ++ u32 pub_head_size; /* the size of boot_file_head */ ++ u8 pub_head_vsn[4]; /* the version of boot_file_head */ ++ u8 file_head_vsn[4]; /* the version of boot0_file_head or ++ boot1_file_head */ ++ u8 Boot_vsn[4]; /* Boot version */ ++ u8 eGON_vsn[4]; /* eGON version */ ++ u8 platform[8]; /* platform information */ ++#endif ++}; ++ ++#define BOOT0_MAGIC "eGON.BT0" ++#define STAMP_VALUE 0x5F0A6C39 ++ ++/* check sum functon from sun4i boot code */ ++int gen_check_sum(void *boot_buf) ++{ ++ struct boot_file_head *head_p; ++ u32 length; ++ u32 *buf; ++ u32 loop; ++ u32 i; ++ u32 sum; ++ ++ head_p = (struct boot_file_head *)boot_buf; ++ length = head_p->length; ++ if ((length & 0x3) != 0) /* must 4-byte-aligned */ ++ return -1; ++ buf = (u32 *)boot_buf; ++ 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, load_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((void *)img.pad, 0, BLOCK_SIZE); ++ ++ /* get input file size */ ++ file_size = lseek(fd_in, 0, SEEK_END); ++ printf("File size: 0x%x\n", file_size); ++ ++ if (file_size > SRAM_LOAD_MAX_SIZE) { ++ fprintf(stderr, "ERROR: File too large!\n"); ++ return EXIT_FAILURE; ++ } else ++ load_size = ALIGN(file_size, sizeof(int)); ++ printf("Load size: 0x%x\n", load_size); ++ ++ 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, load_size); ++ printf("Read 0x%x bytes\n", count); ++ ++ /* fill the header */ ++ img.header.jump_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(load_size + sizeof(struct boot_file_head), BLOCK_SIZE); ++ gen_check_sum((void *)&img); ++ ++ count = write(fd_out, (void *)&img, img.header.length); ++ printf("Write 0x%x bytes\n", count); ++ ++ close(fd_in); ++ close(fd_out); ++ ++ return EXIT_SUCCESS; ++} +diff -ruN u-boot-2014.01-rc1/tools/mksunxiboot.README u-boot-sunxi/tools/mksunxiboot.README +--- u-boot-2014.01-rc1/tools/mksunxiboot.README 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.README 2014-03-05 23:14:48.312084700 +0100 +@@ -0,0 +1,13 @@ ++This program make a arm binary file can be loaded by Allwinner A10 and related ++chips from storage media such as nand and mmc. ++ ++More information about A10 boot, please refer to ++http://rhombus-tech.net/allwinner_a10/a10_boot_process/ ++ ++To compile this program, just type make, you will get 'mksunxiboot'. ++ ++To use it, ++$./mksunxiboot u-boot.bin u-boot-mmc.bin ++then you can write it to a mmc card with dd. ++$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8 ++then insert your mmc card to your A10 tablet, you can boot from mmc card. diff --git a/package/boot/uboot-sunxi/patches/002-pcduino3.patch b/package/boot/uboot-sunxi/patches/002-pcduino3.patch new file mode 100644 index 00000000000..1653e1b61c3 --- /dev/null +++ b/package/boot/uboot-sunxi/patches/002-pcduino3.patch @@ -0,0 +1,57 @@ +diff -ruN u-boot-2014.01-rc1.old/board/sunxi/dram_pcduino3.c u-boot-2014.01-rc1/board/sunxi/dram_pcduino3.c +--- u-boot-2014.01-rc1.old/board/sunxi/dram_pcduino3.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-2014.01-rc1/board/sunxi/dram_pcduino3.c 2014-04-23 20:04:00.919994615 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include ++#include ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .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 = 0x1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.01-rc1.old/board/sunxi/Makefile u-boot-2014.01-rc1/board/sunxi/Makefile +--- u-boot-2014.01-rc1.old/board/sunxi/Makefile 2014-04-12 18:51:34.000000000 +0200 ++++ u-boot-2014.01-rc1/board/sunxi/Makefile 2014-04-23 20:02:51.828839920 +0200 +@@ -73,6 +73,7 @@ + obj-$(CONFIG_MK802II) += dram_sun4i_408_1024_iow8.o + obj-$(CONFIG_MK802II_A20) += dram_mk802ii_a20.o + obj-$(CONFIG_PCDUINO) += dram_sun4i_408_1024_iow8.o ++obj-$(CONFIG_PCDUINO3) += dram_pcduino3.o + obj-$(CONFIG_PENGPOD700) += dram_sun4i_384_1024_iow8.o + obj-$(CONFIG_PENGPOD1000) += dram_sun4i_408_1024_iow16.o + obj-$(CONFIG_POV_PROTAB2) += dram_pov_protab2.o +diff -ruN u-boot-2014.01-rc1.old/boards.cfg u-boot-2014.01-rc1/boards.cfg +--- u-boot-2014.01-rc1.old/boards.cfg 2014-04-12 18:51:34.000000000 +0200 ++++ u-boot-2014.01-rc1/boards.cfg 2014-04-23 20:02:27.897132713 +0200 +@@ -404,6 +404,7 @@ + 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 pcDuino sun4i:PCDUINO,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi pcDuino3 sun7i:PCDUINO3,SPL,SUNXI_GMAC,FAST_MBUS - + Active arm armv7 sunxi - sunxi pengpod1000 sun4i:PENGPOD1000,SPL - + Active arm armv7 sunxi - sunxi pengpod700 sun4i:PENGPOD700,SPL - + Active arm armv7 sunxi - sunxi PoV_ProTab2_IPS9 sun4i:POV_PROTAB2,SPL - diff --git a/package/boot/uboot-sunxi/patches/zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch b/package/boot/uboot-sunxi/patches/zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch deleted file mode 100644 index c3aed2163f2..00000000000 --- a/package/boot/uboot-sunxi/patches/zuperman-d57e8f49a52e59486f49346975c826cf4c298d7e.patch +++ /dev/null @@ -1,10772 +0,0 @@ -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/cmd_boot.c u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.108100778 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * 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 -+ */ -+ -+/* -+ * Misc boot support -+ */ -+#include -+#include -+ -+#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.01-rc1/arch/arm/cpu/armv7/Makefile u-boot-sunxi/arch/arm/cpu/armv7/Makefile ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/Makefile 2014-03-05 23:14:47.108100778 +0100 -@@ -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),) -+ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_SUNXI),) - ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) - obj-y += lowlevel_init.o - endif -@@ -21,6 +22,11 @@ - ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),) - obj-y += nonsec_virt.o - obj-y += virt-v7.o -+obj-y += virt-dt.o -+endif -+ -+ifneq ($(CONFIG_ARMV7_PSCI),) -+obj-y += psci.o - endif - - obj-$(CONFIG_OMAP_COMMON) += omap-common/ -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/nonsec_virt.S u-boot-sunxi/arch/arm/cpu/armv7/nonsec_virt.S ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/nonsec_virt.S 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/nonsec_virt.S 2014-03-05 23:14:47.116100672 +0100 -@@ -10,10 +10,15 @@ - #include - #include - #include -+#include - - .arch_extension sec - .arch_extension virt - -+ .pushsection ._secure.text, "ax" -+ -+ .align 5 @ Minimal alignment for vectors -+ - /* the vector table for secure state and HYP mode */ - _monitor_vectors: - .word 0 /* reset */ -@@ -21,44 +26,92 @@ - adr pc, _secure_monitor - .word 0 - .word 0 -- adr pc, _hyp_trap - .word 0 - .word 0 -+ .word 0 -+ -+.macro is_cpu_virt_capable tmp -+ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1 -+ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits -+ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT) -+.endm - - /* - * secure monitor handler - * U-boot calls this "software interrupt" in start.S - * This is executed on a "smc" instruction, we use a "smc #0" to switch - * to non-secure state. -- * We use only r0 and r1 here, due to constraints in the caller. -+ * r0, r1, r2: passed to the callee -+ * ip: target PC - */ -- .align 5 - _secure_monitor: -- mrc p15, 0, r1, c1, c1, 0 @ read SCR -- bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits -- orr r1, r1, #0x31 @ enable NS, AW, FW bits -- --#ifdef CONFIG_ARMV7_VIRT -- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 -- and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits -- cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) -- orreq r1, r1, #0x100 @ allow HVC instruction -+#ifdef CONFIG_ARMV7_PSCI -+ ldr r5, =_psci_vectors @ Switch to the next monitor -+ mcr p15, 0, r5, c12, c0, 1 -+ isb - #endif - -- mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) -+ mrc p15, 0, r5, c1, c1, 0 @ read SCR -+ bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits -+ orr r5, r5, #0x31 @ enable NS, AW, FW bits - -+ mov r6, #SVC_MODE @ default mode is SVC -+ is_cpu_virt_capable r4 - #ifdef CONFIG_ARMV7_VIRT -- mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value -- mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR -+ orreq r5, r5, #0x100 @ allow HVC instruction -+ moveq r6, #HYP_MODE @ Enter the kernel as HYP - #endif - -- movs pc, lr @ return to non-secure SVC -+ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set) -+ isb -+ -+ bne 1f -+ -+ @ Reset CNTVOFF to 0 before leaving monitor mode -+ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1 -+ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits -+ movne r4, #0 -+ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero -+1: -+ mov lr, ip -+ mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F -+ tst lr, #1 @ Check for Thumb PC -+ orrne ip, ip, #T_BIT @ Set T if Thumb -+ orr ip, ip, r6 @ Slot target mode in -+ msr spsr_cxfs, ip @ Set full SPSR -+ movs pc, lr @ ERET to non-secure -+ -+ENTRY(_do_nonsec_entry) -+ mov ip, r0 -+ mov r0, r1 -+ mov r1, r2 -+ mov r2, r3 -+ smc #0 -+ENDPROC(_do_nonsec_entry) -+ -+.macro get_cbar_addr addr -+#ifdef CONFIG_ARM_GIC_BASE_ADDRESS -+ ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS -+#else -+ mrc p15, 4, \addr, c15, c0, 0 @ read CBAR -+ bfc \addr, #0, #15 @ clear reserved bits -+#endif -+.endm - --_hyp_trap: -- mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1 -- mov pc, lr @ do no switch modes, but -- @ return to caller -+.macro get_gicd_addr addr -+ get_cbar_addr \addr -+ add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset -+.endm -+ -+.macro get_gicc_addr addr, tmp -+ get_cbar_addr \addr -+ is_cpu_virt_capable \tmp -+ movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 -+ moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 -+ add \addr, \addr, \tmp -+.endm - -+#ifndef CONFIG_ARMV7_PSCI - /* - * Secondary CPUs start here and call the code for the core specific parts - * of the non-secure and HYP mode transition. The GIC distributor specific -@@ -66,31 +119,21 @@ - * Then they go back to wfi and wait to be woken up by the kernel again. - */ - ENTRY(_smp_pen) -- mrs r0, cpsr -- orr r0, r0, #0xc0 -- msr cpsr, r0 @ disable interrupts -- ldr r1, =_start -- mcr p15, 0, r1, c12, c0, 0 @ set VBAR -+ cpsid i -+ cpsid f - - bl _nonsec_init -- mov r12, r0 @ save GICC address --#ifdef CONFIG_ARMV7_VIRT -- bl _switch_to_hyp --#endif -- -- ldr r1, [r12, #GICC_IAR] @ acknowledge IPI -- str r1, [r12, #GICC_EOIR] @ signal end of interrupt - - adr r0, _smp_pen @ do not use this address again - b smp_waitloop @ wait for IPIs, board specific - ENDPROC(_smp_pen) -+#endif - - /* - * Switch a core to non-secure state. - * - * 1. initialize the GIC per-core interface - * 2. allow coprocessor access in non-secure modes -- * 3. switch the cpu mode (by calling "smc #0") - * - * Called from smp_pen by secondary cores and directly by the BSP. - * Do not assume that the stack is available and only use registers -@@ -100,38 +143,23 @@ - * though, but we check this in C before calling this function. - */ - ENTRY(_nonsec_init) --#ifdef CONFIG_ARM_GIC_BASE_ADDRESS -- ldr r2, =CONFIG_ARM_GIC_BASE_ADDRESS --#else -- mrc p15, 4, r2, c15, c0, 0 @ read CBAR -- bfc r2, #0, #15 @ clear reserved bits --#endif -- add r3, r2, #GIC_DIST_OFFSET @ GIC dist i/f offset -+ get_gicd_addr r3 -+ - mvn r1, #0 @ all bits to 1 - str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts - -- mrc p15, 0, r0, c0, c0, 0 @ read MIDR -- ldr r1, =MIDR_PRIMARY_PART_MASK -- and r0, r0, r1 @ mask out variant and revision -- -- ldr r1, =MIDR_CORTEX_A7_R0P0 & MIDR_PRIMARY_PART_MASK -- cmp r0, r1 @ check for Cortex-A7 -- -- ldr r1, =MIDR_CORTEX_A15_R0P0 & MIDR_PRIMARY_PART_MASK -- cmpne r0, r1 @ check for Cortex-A15 -- -- movne r1, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 -- moveq r1, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 -- add r3, r2, r1 @ r3 = GIC CPU i/f addr -+ get_gicc_addr r3, r1 - - mov r1, #1 @ set GICC_CTLR[enable] - str r1, [r3, #GICC_CTLR] @ and clear all other bits - mov r1, #0xff - str r1, [r3, #GICC_PMR] @ set priority mask register - -+ mrc p15, 0, r0, c1, c1, 2 - movw r1, #0x3fff -- movt r1, #0x0006 -- mcr p15, 0, r1, c1, c1, 2 @ NSACR = all copros to non-sec -+ movt r1, #0x0004 -+ orr r0, r0, r1 -+ mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec - - /* The CNTFRQ register of the generic timer needs to be - * programmed in secure state. Some primary bootloaders / firmware -@@ -149,44 +177,24 @@ - - adr r1, _monitor_vectors - mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors -- -- mrc p15, 0, ip, c12, c0, 0 @ save secure copy of VBAR -- - isb -- smc #0 @ call into MONITOR mode -- -- mcr p15, 0, ip, c12, c0, 0 @ write non-secure copy of VBAR -- -- mov r1, #1 -- str r1, [r3, #GICC_CTLR] @ enable non-secure CPU i/f -- add r2, r2, #GIC_DIST_OFFSET -- str r1, [r2, #GICD_CTLR] @ allow private interrupts - - mov r0, r3 @ return GICC address -- - bx lr - ENDPROC(_nonsec_init) - - #ifdef CONFIG_SMP_PEN_ADDR - /* void __weak smp_waitloop(unsigned previous_address); */ - ENTRY(smp_waitloop) -- wfi -+ wfe - ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address - ldr r1, [r1] - cmp r0, r1 @ make sure we dont execute this code - beq smp_waitloop @ again (due to a spurious wakeup) -- mov pc, r1 -+ mov r0, r1 -+ b _do_nonsec_entry - ENDPROC(smp_waitloop) - .weak smp_waitloop - #endif - --ENTRY(_switch_to_hyp) -- mov r0, lr -- mov r1, sp @ save SVC copy of LR and SP -- isb -- hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 -- mov sp, r1 -- mov lr, r0 @ restore SVC copy of LR and SP -- -- bx lr --ENDPROC(_switch_to_hyp) -+ .popsection -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/psci.S u-boot-sunxi/arch/arm/cpu/armv7/psci.S ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/psci.S 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/psci.S 2014-03-05 23:14:47.124100564 +0100 -@@ -0,0 +1,113 @@ -+/* -+ * Copyright (C) 2013 - ARM Ltd -+ * Author: Marc Zyngier -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+ -+ .pushsection ._secure.text, "ax" -+ -+ .arch_extension sec -+ -+ .align 5 -+ .globl _psci_vectors -+_psci_vectors: -+ adr pc, . @ reset -+ adr pc, . @ undef -+ adr pc, _smc_psci @ smc -+ adr pc, . @ pabort -+ adr pc, . @ dabort -+ adr pc, . @ hyp -+ adr pc, . @ irq -+ adr pc, . @ fiq -+ -+ENTRY(psci_cpu_suspend) -+ENTRY(psci_cpu_off) -+ENTRY(psci_cpu_on) -+ENTRY(psci_migrate) -+ mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) -+ mov pc, lr -+ENDPROC(psci_migrate) -+ENDPROC(psci_cpu_on) -+ENDPROC(psci_cpu_off) -+ENDPROC(psci_cpu_suspend) -+.weak psci_cpu_suspend -+.weak psci_cpu_off -+.weak psci_cpu_on -+.weak psci_migrate -+ -+_psci_table: -+ .word ARM_PSCI_FN_CPU_SUSPEND -+ .word psci_cpu_suspend -+ .word ARM_PSCI_FN_CPU_OFF -+ .word psci_cpu_off -+ .word ARM_PSCI_FN_CPU_ON -+ .word psci_cpu_on -+ .word ARM_PSCI_FN_MIGRATE -+ .word psci_migrate -+ .word 0 -+ .word 0 -+ -+_secure_stacks: @ Enough to save 16 registers per CPU -+ .skip 16*4*CONFIG_ARMV7_PSCI_NR_CPUS -+_secure_stack_base: -+ -+_smc_psci: -+ @ Switch to secure mode -+ mrc p15, 0, sp, c1, c1, 0 -+ bic sp, sp, #1 -+ mcr p15, 0, sp, c1, c1, 0 -+ -+ adr sp, _secure_stack_base -+ mcr p15, 0, r0, c13, c0, 4 @ use TPIDRPRW as a tmp reg -+ mcr p15, 0, r1, c13, c0, 3 @ use TPIDRURO as a tmp reg -+ mrc p15, 0, r0, c0, c0, 5 @ MPIDR -+ and r1, r0, #3 @ cpu number in cluster -+ lsr r0, r0, #8 -+ and r0, r0, #3 @ cluster number -+ mul r1, r1, r0 @ absolute cpu nr -+ sbc sp, sp, r1, lsl #6 @ sp = sp_base - 64*cpunr -+ -+ mrc p15, 0, r0, c13, c0, 4 @ restore r0 -+ mrc p15, 0, r1, c13, c0, 3 @ restore r1 -+ -+ push {r4-r12,lr} -+ -+ adr r4, _psci_table -+1: ldr r5, [r4] @ Load PSCI function ID -+ ldr r6, [r4, #4] @ Load target PC -+ cmp r5, #0 @ If reach the end, bail out -+ mvneq r0, #0 @ Return -1 (Not Implemented) -+ beq 2f -+ cmp r0, r5 @ If not matching, try next entry -+ addne r4, r4, #8 -+ bne 1b -+ cmp r6, #0 @ Not implemented -+ moveq r0, #ARM_PSCI_RET_NI -+ beq 2f -+ -+ blx r6 @ Execute PSCI function -+ -+2: pop {r4-r12, lr} -+ -+ @ Back to non-secure -+ mrc p15, 0, sp, c1, c1, 0 -+ orr sp, sp, #1 -+ mcr p15, 0, sp, c1, c1, 0 -+ movs pc, lr @ Return to the kernel -+ -+ .popsection -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/board.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,158 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Some init for sunxi platform. -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_SPL_BUILD -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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, nannd 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_UART0_TX); -+ sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART0_RX); -+ sunxi_gpio_set_pull(SUNXI_GPG(4), 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, #0x40\n" -+ "mcr p15, 0, r0, c1, c0, 1\n"); -+#endif -+ -+ watchdog_init(); -+ clock_init(); -+ timer_init(); -+ gpio_init(); -+ -+#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 -+ -+ 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 -+ -+#if defined(CONFIG_SUNXI_EMAC) || defined(CONFIG_SUNXI_GMAC) -+/* -+ * Initializes on-chip ethernet controllers. -+ * to override, implement board_eth_init() -+ */ -+int cpu_eth_init(bd_t *bis) -+{ -+#ifdef CONFIG_SUNXI_EMAC -+ sunxi_emac_initialize(bis); -+#else -+ sunxi_gmac_initialize(bis); -+#endif -+ -+ return 0; -+} -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/clock.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,204 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * (C) Copyright 2013 Luke Kenneth Casson Leighton -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SPL_BUILD -+static 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 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | -+ CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg); -+ writel(0xa1005000, &ccm->pll1_cfg); -+ sdelay(200); -+ writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | -+ CPU_CLK_SRC_PLL1 << 16, &ccm->cpu_ahb_apb0_cfg); -+#ifdef CONFIG_SUN5I -+ /* Power on reset default for PLL6 is 2400 MHz, which is faster then -+ * it can reliable do :| Set it to a 600 MHz instead. */ -+ writel(0x21009911, &ccm->pll6_cfg); -+#endif -+#ifdef CONFIG_SUN7I -+ writel(0x1 << 6 | readl(&ccm->ahb_gate0), &ccm->ahb_gate0); -+ writel(0x1 << 31 | readl(&ccm->pll6_cfg), &ccm->pll6_cfg); -+#endif -+} -+#endif -+ -+int clock_init(void) -+{ -+ struct sunxi_ccm_reg *const ccm = -+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -+ -+#ifdef CONFIG_SPL_BUILD -+ clock_init_safe(); -+#endif -+ -+#if defined(CONFIG_SUN6I) -+ /* uart clock source is apb2 */ -+ sr32(&ccm->apb2_div, 24, 2, APB2_CLK_SRC_OSC24M); -+ sr32(&ccm->apb2_div, 16, 2, APB2_FACTOR_N); -+ sr32(&ccm->apb2_div, 0, 5, APB2_FACTOR_M); -+ -+ /* open the clock for uart */ -+ sr32(&ccm->apb2_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); -+#else -+ /* uart clock source is apb1 */ -+ sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M); -+ sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N); -+ sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M); -+ -+ /* open the clock for uart */ -+ sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); -+#endif -+ -+#ifdef CONFIG_NAND_SUNXI -+ /* nand clock source is osc24m */ -+ sr32(&ccm->nand_sclk_cfg, 24, 2, NAND_CLK_SRC_OSC24); -+ sr32(&ccm->nand_sclk_cfg, 16, 2, NAND_CLK_DIV_N); -+ sr32(&ccm->nand_sclk_cfg, 0, 4, NAND_CLK_DIV_M); -+ sr32(&ccm->nand_sclk_cfg, 31, 1, CLK_GATE_OPEN); -+ /* open clock for nand */ -+ sr32(&ccm->ahb_gate0, AHB_GATE_OFFSET_NAND, 1, CLK_GATE_OPEN); -+#endif -+ -+ return 0; -+} -+ -+/* Return PLL5 frequency in Hz -+ * Note: Assumes PLL5 reference is 24MHz clock -+ */ -+unsigned int clock_get_pll5(void) -+{ -+ struct sunxi_ccm_reg *const ccm = -+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -+ uint32_t rval = readl(&ccm->pll5_cfg); -+ int n = (rval >> 8) & 0x1f; -+ int k = ((rval >> 4) & 3) + 1; -+ int p = 1 << ((rval >> 16) & 3); -+ return 24000000 * n * k / p; -+} -+ -+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 apb1 clock gate for twi */ -+ sr32(&ccm->apb1_gate, 0 + port, 1, state); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SPL_BUILD -+#define PLL1_CFG(N, K, M, P) (1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \ -+ 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \ -+ (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0) -+#define RDIV(a, b) ((a + (b) - 1) / (b)) -+ -+struct { -+ u32 pll1_cfg; -+ unsigned int freq; -+} pll1_para[] = { -+ { 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}, -+ { PLL1_CFG(31, 1, 0, 0), ~0}, -+}; -+ -+void clock_set_pll1(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 = RDIV(hz, 432000000); /* Max 450MHz */ -+ ahb = RDIV(hz/axi, 204000000); /* Max 250MHz */ -+ apb0 = 2; /* Max 150MHz */ -+ -+ printf("CPU: %dHz, 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 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | -+ CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg); -+ sdelay(20); -+ -+ /* Configure sys clock divisors */ -+ writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_OSC24M << 16, -+ &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 << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_PLL1 << 16, -+ &ccm->cpu_ahb_apb0_cfg); -+ sdelay(20); -+} -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,42 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+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.01-rc1/arch/arm/cpu/armv7/sunxi/config.mk u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,8 @@ -+# Build a combined spl + u-boot image -+ifdef CONFIG_SPL -+ifndef CONFIG_SPL_BUILD -+ifndef CONFIG_SPL_FEL -+ALL-y = $(obj)u-boot-sunxi-with-spl.bin -+endif -+endif -+endif -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/cpu_info.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,47 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+#ifdef CONFIG_DISPLAY_CPUINFO -+int print_cpuinfo(void) -+{ -+#ifdef CONFIG_SUN4I -+ puts("CPU: Allwinner A10 (SUN4I)\n"); -+#elif defined CONFIG_SUN5I -+ /* TODO: Distinguish A13/A10s */ -+ puts("CPU: Allwinner A13/A10s (SUN5I)\n"); -+#elif defined CONFIG_SUN6I -+ puts("CPU: Allwinner A31 (SUN6I)\n"); -+#elif defined CONFIG_SUN7I -+ puts("CPU: Allwinner A20 (SUN7I)\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.01-rc1/arch/arm/cpu/armv7/sunxi/dram.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,679 @@ -+/* -+ * sunxi DRAM controller initialization -+ * (C) Copyright 2012 Henrik Nordstrom -+ * (C) Copyright 2013 Luke Kenneth Casson Leighton -+ * -+ * 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. -+ * Berg Xing -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+ -+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++) { -+#ifdef CONFIG_SUN7I -+ clrsetbits_le32(&dram->dllcr[i], 0xf << 14, -+#else -+ clrsetbits_le32(&dram->dllcr[i], 0x4 << 14, -+#endif -+ (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, 0x1035, -+ 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_M(CCM_PLL5_CTRL_M_X(2)); -+ reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */ -+ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); -+ reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ -+ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); -+ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ -+ 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 -+ -+ /* 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); -+ -+ /* -+ * 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 */ -+ while (readl(&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 -+} -+ -+#ifdef CONFIG_SUN4I -+static void dramc_set_autorefresh_cycle(u32 clk) -+{ -+ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; -+ u32 reg_val; -+ u32 tmp_val; -+ u32 reg_dcr; -+ -+ if (clk < 600) { -+ reg_dcr = readl(&dram->dcr); -+ if ((reg_dcr & DRAM_DCR_CHIP_DENSITY_MASK) <= -+ DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_1024M)) -+ reg_val = (131 * clk) >> 10; -+ else -+ reg_val = (336 * clk) >> 10; -+ -+ tmp_val = (7987 * clk) >> 10; -+ tmp_val = tmp_val * 9 - 200; -+ reg_val |= tmp_val << 8; -+ reg_val |= 0x8 << 24; -+ writel(reg_val, &dram->drr); -+ } else { -+ writel(0x0, &dram->drr); -+ } -+} -+#endif /* SUN4I */ -+ -+#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) -+static void dramc_set_autorefresh_cycle(u32 clk) -+{ -+ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; -+ u32 reg_val; -+ u32 tmp_val; -+ reg_val = 0x83; -+ -+ tmp_val = (7987 * clk) >> 10; -+ tmp_val = tmp_val * 9 - 200; -+ reg_val |= tmp_val << 8; -+ reg_val |= 0x8 << 24; -+ writel(reg_val, &dram->drr); -+} -+#endif /* SUN5I */ -+ -+unsigned long dramc_init(struct dram_para *para) -+{ -+ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; -+ u32 reg_val; -+ 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) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_256M); -+ else if (para->density == 512) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_512M); -+ else if (para->density == 1024) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_1024M); -+ else if (para->density == 2048) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_2048M); -+ else if (para->density == 4096) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_4096M); -+ else if (para->density == 8192) -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_8192M); -+ else -+ reg_val |= DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_256M); -+ -+ 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); -+ -+ while (readl(&dram->ccr) & DRAM_CCR_INIT); -+ -+ mctl_enable_dllx(para->tpr3); -+ -+#ifdef CONFIG_SUN4I -+ /* 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_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); -+ -+ /* 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); -+ while (readl(&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 */ -+ while (readl(&dram->dcr) & (0x1 << 31)); -+ -+ udelay(2); -+ -+ /* dram pad hold off */ -+ setbits_le32(&dram->ppwrsctl, 0x16510000); -+ -+ while (readl(&dram->ppwrsctl) & 0x1); -+ -+ /* exit self-refresh state */ -+ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); -+ -+ /* check whether command has been executed */ -+ while (readl(&dram->dcr) & (0x1 << 31)); -+ udelay(2);; -+ -+ /* issue a refresh command */ -+ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27); -+ while (readl(&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((unsigned long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/early_print.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,65 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Early uart print for debugging. -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int uart_initialized = 0; -+ -+#define UART CONFIG_CONS_INDEX-1 -+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.01-rc1/arch/arm/cpu/armv7/sunxi/key.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/key.c ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/key.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/key.c 2014-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,70 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+int sunxi_key_init(void) -+{ -+ struct sunxi_lradc *sunxi_key_base = -+ (struct sunxi_lradc *)SUNXI_LRADC_BASE; -+ -+ sr32(&sunxi_key_base->ctrl, 0, 1, LRADC_EN); -+ sr32(&sunxi_key_base->ctrl, 2, 2, LRADC_SAMPLE_RATE); -+ sr32(&sunxi_key_base->ctrl, 4, 2, LEVELB_VOL); -+ sr32(&sunxi_key_base->ctrl, 6, 1, LRADC_HOLD_EN); -+ sr32(&sunxi_key_base->ctrl, 12, 2, KEY_MODE_SELECT); -+ -+ /* disable all key irq */ -+ writel(0x0, &sunxi_key_base->intc); -+ /* clear all key pending */ -+ writel(0xffffffff, &sunxi_key_base->ints); -+ -+ return 0; -+} -+ -+u32 sunxi_read_key(void) -+{ -+ u32 ints; -+ u32 key = 0; -+ struct sunxi_lradc *sunxi_key_base = -+ (struct sunxi_lradc *)SUNXI_LRADC_BASE; -+ -+ ints = readl(&sunxi_key_base->ints); -+ -+ /* if there is already data pending, -+ read it */ -+ if (ints & ADC0_DATA_PENDING) { -+ key = readl(&sunxi_key_base->data0); -+#ifdef DEBUG -+ printf("key pressed, value=0x%x\n", key); -+#endif -+ } -+ /* clear the pending data */ -+ writel(ints, &sunxi_key_base->ints); -+ return key; -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/Makefile u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile 2014-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,56 @@ -+# -+# (C) Copyright 2012 Henrik Nordstrom -+# -+# Based on some other Makefile -+# (C) Copyright 2000-2003 -+# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+# -+# 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 -+# -+ -+obj-y += timer.o -+obj-y += board.o -+obj-y += clock.o -+obj-y += pinmux.o -+obj-y += watchdog.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 += key.o -+obj-y += cpu_info.o -+ifdef CONFIG_CMD_WATCHDOG -+obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o -+endif -+ifdef CONFIG_ARMV7_PSCI -+obj-y += psci.o -+endif -+endif -+ -+ifdef CONFIG_SPL_BUILD -+obj-y += dram.o -+ifdef CONFIG_SPL_FEL -+obj-y += start.o -+endif -+endif -+ -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/pinmux.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,96 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+int sunxi_gpio_set_cfgpin(u32 pin, u32 val) -+{ -+ u32 cfg; -+ u32 bank = GPIO_BANK(pin); -+ u32 index = GPIO_CFG_INDEX(pin); -+ u32 offset = GPIO_CFG_OFFSET(pin); -+ struct sunxi_gpio *pio = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; -+ -+ cfg = readl(&pio->cfg[0] + index); -+ cfg &= ~(0xf << offset); -+ cfg |= val << offset; -+ -+ writel(cfg, &pio->cfg[0] + index); -+ -+ 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 = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; -+ -+ cfg = readl(&pio->cfg[0] + index); -+ cfg >>= offset; -+ -+ return cfg & 0xf; -+} -+ -+int sunxi_gpio_set_drv(u32 pin, u32 val) -+{ -+ u32 drv; -+ u32 bank = GPIO_BANK(pin); -+ u32 index = GPIO_DRV_INDEX(pin); -+ u32 offset = GPIO_DRV_OFFSET(pin); -+ struct sunxi_gpio *pio = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; -+ -+ drv = readl(&pio->drv[0] + index); -+ drv &= ~(0x3 << offset); -+ drv |= val << offset; -+ -+ writel(drv, &pio->drv[0] + index); -+ -+ return 0; -+} -+ -+int sunxi_gpio_set_pull(u32 pin, u32 val) -+{ -+ u32 pull; -+ u32 bank = GPIO_BANK(pin); -+ u32 index = GPIO_PULL_INDEX(pin); -+ u32 offset = GPIO_PULL_OFFSET(pin); -+ struct sunxi_gpio *pio = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]; -+ -+ pull = readl(&pio->pull[0] + index); -+ pull &= ~(0x3 << offset); -+ pull |= val << offset; -+ -+ writel(pull, &pio->pull[0] + index); -+ -+ return 0; -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/postclk_init.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * (C) Copyright 2013 -+ * Carl van Schaik -+ * -+ * 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 -+ */ -+ -+#include -+#if defined(CONFIG_SYS_SECONDARY_ON) -+#include -+#endif -+ -+ -+int board_postclk_init(void) -+{ -+#if defined(CONFIG_SYS_SECONDARY_ON) -+ startup_secondaries(); -+#endif -+ return 0; -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/psci.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/psci.S ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/psci.S 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/psci.S 2014-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,124 @@ -+/* -+ * Copyright (C) 2013 - ARM Ltd -+ * Author: Marc Zyngier -+ * -+ * Based on code by Carl van Schaik . -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+ -+ .pushsection ._secure.text, "ax" -+ -+ .arch_extension sec -+ -+#define TEN_MS (10 * CONFIG_SYS_CLK_FREQ / 1000) -+ -+ @ r1 = target CPU -+ @ r2 = target PC -+.globl psci_cpu_on -+psci_cpu_on: -+ adr r0, _target_pc -+ str r2, [r0] -+ dsb -+ -+ movw r0, #(SUNXI_CPUCFG_BASE & 0xffff) -+ movt r0, #(SUNXI_CPUCFG_BASE >> 16) -+ -+ @ CPU mask -+ and r1, r1, #3 @ only care about first cluster -+ mov r4, #1 -+ lsl r4, r4, r1 -+ -+ adr r6, _sunxi_cpu_entry -+ str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) -+ -+ @ Assert reset on target CPU -+ mov r6, #0 -+ lsl r5, r1, #6 @ 64 bytes per CPU -+ add r5, r5, #0x40 @ Offset from base -+ add r5, r5, r0 @ CPU control block -+ str r6, [r5] @ Reset CPU -+ -+ @ l1 invalidate -+ ldr r6, [r0, #0x184] -+ bic r6, r6, r4 -+ str r6, [r0, #0x184] -+ -+ @ Lock CPU -+ ldr r6, [r0, #0x1e4] -+ bic r6, r6, r4 -+ str r6, [r0, #0x1e4] -+ -+ @ Release power clamp -+ movw r6, #0x1ff -+ movt r6, #0 -+1: lsrs r6, r6, #1 -+ str r6, [r0, #0x1b0] -+ bne 1b -+ -+ @ Write CNTP_TVAL : 10ms @ 24MHz (240000 cycles) -+ movw r1, #(TEN_MS & 0xffff) -+ movt r1, #(TEN_MS >> 16) -+ mcr p15, 0, r1, c14, c2, 0 -+ isb -+ @ Enable physical timer, mask interrupt -+ mov r1, #3 -+ mcr p15, 0, r1, c14, c2, 1 -+ @ Poll physical timer until ISTATUS is on -+1: isb -+ mrc p15, 0, r1, c14, c2, 1 -+ ands r1, r1, #4 -+ bne 1b -+ @ Disable timer -+ mov r1, #0 -+ mcr p15, 0, r1, c14, c2, 1 -+ isb -+ -+ @ Clear power gating -+ ldr r6, [r0, #0x1b4] -+ bic r6, r6, #1 -+ str r6, [r0, #0x1b4] -+ -+ @ Deassert reset on target CPU -+ mov r6, #3 -+ str r6, [r5] -+ -+ @ Unlock CPU -+ ldr r6, [r0, #0x1e4] -+ orr r6, r6, r4 -+ str r6, [r0, #0x1e4] -+ -+ mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS -+ mov pc, lr -+ -+_target_pc: -+ .word 0 -+ -+_sunxi_cpu_entry: -+ @ Set SMP bit -+ mrc p15, 0, r0, c1, c0, 1 -+ orr r0, r0, #0x40 -+ mcr p15, 0, r0, c1, c0, 1 -+ isb -+ -+ bl _nonsec_init -+ -+ adr r0, _target_pc -+ ldr r0, [r0] -+ b _do_nonsec_entry -+ -+ .popsection -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/secondary_init.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,48 @@ -+/* -+ * A lowlevel_init function that sets up the stack to call a C function to -+ * perform further init. -+ * -+ * (C) Copyright 2013 -+ * Carl van Schaik -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+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.01-rc1/arch/arm/cpu/armv7/sunxi/smp.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1,96 @@ -+/* -+ * (C) Copyright 2013 -+ * Carl van Schaik -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+ -+/* 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.01-rc1/arch/arm/cpu/armv7/sunxi/start.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.128100511 +0100 -@@ -0,0 +1 @@ -+/* Intentionally empty. Only needed to get FEL SPL link line right */ -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/timer.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,120 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+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 */ -+ -+static struct sunxi_timer *timer_base = -+ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->timer[TIMER_NUM]; -+ -+/* macro to read the 32 bit timer: since it decrements, we invert read value */ -+#define READ_TIMER() (~readl(&timer_base->val)) -+ -+/* init timer register */ -+int timer_init(void) -+{ -+ writel(TIMER_LOAD_VAL, &timer_base->inter); -+ writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN, -+ &timer_base->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) -+{ -+ ulong tbclk; -+ tbclk = CONFIG_SYS_HZ; -+ return tbclk; -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-psci.lds 2014-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,63 @@ -+/* -+ * (C) Copyright 2013 ARM Ltd -+ * Marc Zyngier -+ * -+ * Based on sunxi/u-boot-spl.lds: -+ * -+ * (C) Copyright 2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Based on omap-common/u-boot-spl.lds: -+ * -+ * (C) Copyright 2002 -+ * Gary Jennejohn, DENX Software Engineering, -+ * -+ * (C) Copyright 2010 -+ * Texas Instruments, -+ * Aneesh V -+ * -+ * 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 -+ */ -+ -+MEMORY { sram : ORIGIN = CONFIG_ARMV7_PSCI_BASE, LENGTH = 0x1000 } -+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -+OUTPUT_ARCH(arm) -+ENTRY(_start) -+SECTIONS -+{ -+ .text : -+ { -+ _start = .; -+ *(.text*) -+ } > sram -+ -+ . = ALIGN(4); -+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > sram -+ -+ . = ALIGN(4); -+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } > sram -+ -+ . = ALIGN(4); -+ _end = .; -+ -+ /DISCARD/ : { -+ *(.bss*) -+ } -+} -diff -ruN u-boot-2014.01-rc1/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.01-rc1/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-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,59 @@ -+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.01-rc1/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds ---- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,69 @@ -+/* -+ * (C) Copyright 2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Based on omap-common/u-boot-spl.lds: -+ * -+ * (C) Copyright 2002 -+ * Gary Jennejohn, DENX Software Engineering, -+ * -+ * (C) Copyright 2010 -+ * Texas Instruments, -+ * Aneesh V -+ * -+ * 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 -+ */ -+ -+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.01-rc1/arch/arm/cpu/armv7/sunxi/watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,96 @@ -+/* -+ * Watchdog driver for the Allwinner sunxi platform. -+ * Copyright (C) 2013 Oliver Schinagl -+ * http://www.linux-sunxi.org/ -+ * -+ * 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., 51 Franklin Street, Fifth Floor, Boston, -+ * MA 02110-1301, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+#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.01-rc1/arch/arm/cpu/armv7/virt-dt.c u-boot-sunxi/arch/arm/cpu/armv7/virt-dt.c ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-dt.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/virt-dt.c 2014-03-05 23:14:47.132100458 +0100 -@@ -0,0 +1,100 @@ -+/* -+ * Copyright (C) 2013 - ARM Ltd -+ * Author: Marc Zyngier -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int fdt_psci(void *fdt) -+{ -+#ifdef CONFIG_ARMV7_PSCI -+ int nodeoff; -+ int tmp; -+ -+ nodeoff = fdt_path_offset(fdt, "/cpus"); -+ if (nodeoff < 0) { -+ printf("couldn't find /cpus\n"); -+ return nodeoff; -+ } -+ -+ /* add 'enable-method = "psci"' to each cpu node */ -+ for (tmp = fdt_first_subnode(fdt, nodeoff); -+ tmp >= 0; -+ tmp = fdt_next_subnode(fdt, tmp)) { -+ const struct fdt_property *prop; -+ int len; -+ -+ prop = fdt_get_property(fdt, tmp, "device_type", &len); -+ if (!prop) -+ continue; -+ if (len < 4) -+ continue; -+ if (strcmp(prop->data, "cpu")) -+ continue; -+ -+ fdt_setprop_string(fdt, tmp, "enable-method", "psci"); -+ } -+ -+ nodeoff = fdt_path_offset(fdt, "/psci"); -+ if (nodeoff < 0) { -+ nodeoff = fdt_path_offset(fdt, "/"); -+ if (nodeoff < 0) -+ return nodeoff; -+ -+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); -+ if (nodeoff < 0) -+ return nodeoff; -+ } -+ -+ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); -+ if (tmp) -+ return tmp; -+ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); -+ if (tmp) -+ return tmp; -+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); -+ if (tmp) -+ return tmp; -+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); -+ if (tmp) -+ return tmp; -+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); -+ if (tmp) -+ return tmp; -+ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); -+ if (tmp) -+ return tmp; -+#endif -+ return 0; -+} -+ -+int armv7_update_dt(void *fdt) -+{ -+#ifndef CONFIG_ARMV7_SECURE_BASE -+ /* secure code lives in RAM, keep it alive */ -+ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, -+ __secure_end - __secure_start); -+#endif -+ -+ return fdt_psci(fdt); -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-v7.c u-boot-sunxi/arch/arm/cpu/armv7/virt-v7.c ---- u-boot-2014.01-rc1/arch/arm/cpu/armv7/virt-v7.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/armv7/virt-v7.c 2014-03-05 23:14:47.132100458 +0100 -@@ -13,17 +13,10 @@ - #include - #include - #include -+#include - - unsigned long gic_dist_addr; - --static unsigned int read_cpsr(void) --{ -- unsigned int reg; -- -- asm volatile ("mrs %0, cpsr\n" : "=r" (reg)); -- return reg; --} -- - static unsigned int read_id_pfr1(void) - { - unsigned int reg; -@@ -72,6 +65,18 @@ - #endif - } - -+static void relocate_secure_section(void) -+{ -+#ifdef CONFIG_ARMV7_SECURE_BASE -+ size_t sz = __secure_end - __secure_start; -+ -+ memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz); -+ flush_dcache_range(CONFIG_ARMV7_SECURE_BASE, -+ CONFIG_ARMV7_SECURE_BASE + sz + 1); -+ invalidate_icache_all(); -+#endif -+} -+ - static void kick_secondary_cpus_gic(unsigned long gicdaddr) - { - /* kick all CPUs (except this one) by writing to GICD_SGIR */ -@@ -83,35 +88,7 @@ - kick_secondary_cpus_gic(gic_dist_addr); - } - --int armv7_switch_hyp(void) --{ -- unsigned int reg; -- -- /* check whether we are in HYP mode already */ -- if ((read_cpsr() & 0x1f) == 0x1a) { -- debug("CPU already in HYP mode\n"); -- return 0; -- } -- -- /* check whether the CPU supports the virtualization extensions */ -- reg = read_id_pfr1(); -- if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) { -- printf("HYP mode: Virtualization extensions not implemented.\n"); -- return -1; -- } -- -- /* call the HYP switching code on this CPU also */ -- _switch_to_hyp(); -- -- if ((read_cpsr() & 0x1F) != 0x1a) { -- printf("HYP mode: switch not successful.\n"); -- return -1; -- } -- -- return 0; --} -- --int armv7_switch_nonsec(void) -+int armv7_init_nonsec(void) - { - unsigned int reg; - unsigned itlinesnr, i; -@@ -147,11 +124,13 @@ - for (i = 1; i <= itlinesnr; i++) - writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); - -- smp_set_core_boot_addr((unsigned long)_smp_pen, -1); -+#ifndef CONFIG_ARMV7_PSCI -+ smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1); - smp_kick_all_cpus(); -+#endif - - /* call the non-sec switching code on this CPU also */ -- _nonsec_init(); -- -+ relocate_secure_section(); -+ secure_ram_addr(_nonsec_init)(); - return 0; - } -diff -ruN u-boot-2014.01-rc1/arch/arm/cpu/u-boot.lds u-boot-sunxi/arch/arm/cpu/u-boot.lds ---- u-boot-2014.01-rc1/arch/arm/cpu/u-boot.lds 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/cpu/u-boot.lds 2014-03-05 23:14:47.136100405 +0100 -@@ -7,6 +7,8 @@ - * SPDX-License-Identifier: GPL-2.0+ - */ - -+#include -+ - OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") - OUTPUT_ARCH(arm) - ENTRY(_start) -@@ -22,6 +24,34 @@ - *(.text*) - } - -+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI) -+ -+#ifndef CONFIG_ARMV7_SECURE_BASE -+#define CONFIG_ARMV7_SECURE_BASE -+#endif -+ -+ .__secure_start : { -+ . = ALIGN(0x1000); -+ *(.__secure_start) -+ } -+ -+ .secure_text CONFIG_ARMV7_SECURE_BASE : -+ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) -+ { -+ *(._secure.text) -+ } -+ -+ . = LOADADDR(.__secure_start) + -+ SIZEOF(.__secure_start) + -+ SIZEOF(.secure_text); -+ -+ __secure_end_lma = .; -+ .__secure_end : AT(__secure_end_lma) { -+ *(.__secure_end) -+ LONG(0x1d1071c); /* Must output something to reset LMA */ -+ } -+#endif -+ - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/clock.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,375 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 _SUNXI_CLOCK_H -+#define _SUNXI_CLOCK_H -+ -+#include -+ -+#define CLK_GATE_OPEN 0x1 -+#define CLK_GATE_CLOSE 0x0 -+ -+/* clock control module regs definition */ -+#if defined(CONFIG_SUN6I) -+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 MBUS0 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_OSC24M 1 -+#define APB2_FACTOR_M 0 -+#define APB2_FACTOR_N 0 -+ -+#else -+ -+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 0 -+#define APB1_FACTOR_M 0 -+#define APB1_FACTOR_N 0 -+ -+/* clock divide */ -+#define CPU_CLK_SRC_OSC24M 1 -+#define CPU_CLK_SRC_PLL1 2 -+#define AXI_DIV_1 0 -+#define AXI_DIV_2 1 -+#define AXI_DIV_3 2 -+#define AXI_DIV_4 3 -+#define AHB_DIV_1 0 -+#define AHB_DIV_2 1 -+#define AHB_DIV_4 2 -+#define AHB_DIV_8 3 -+#define APB0_DIV_1 0 -+#define APB0_DIV_2 1 -+#define APB0_DIV_4 2 -+#define APB0_DIV_8 3 -+ -+#ifdef CONFIG_SUN5I -+#define AHB_CLK_SRC_AXI 0 -+#endif -+ -+/* 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_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_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_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 /* CONFIG_SUN6I */ -+ -+#ifndef __ASSEMBLY__ -+int clock_init(void); -+int clock_twi_onoff(int port, int state); -+void clock_set_pll1(int mhz); -+unsigned int clock_get_pll5(void); -+#endif -+ -+#endif /* _SUNXI_CLOCK_H */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/cpucfg.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,71 @@ -+/* -+ * (C) Copyright 2013 -+ * Carl van Schaik -+ * -+ * CPU configuration registers for the sun7i (A20). -+ * -+ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/cpu.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,147 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 _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 -+ -+/* 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 -+ -+/* 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); -+extern void sunxi_reset(void); -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* _CPU_H */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/dram.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,191 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Berg Xing -+ * Tom Cubie -+ * -+ * Sunxi platform dram register definition. -+ * -+ * 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 _SUNXI_DRAM_H -+#define _SUNXI_DRAM_H -+ -+#include -+ -+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_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.01-rc1/arch/arm/include/asm/arch-sunxi/early_print.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,74 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Early uart print for debugging. -+ * -+ * 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 _SUNXI_EARLY_PRINT_H -+#define _SUNXI_EARLY_PRINT_H -+ -+#include -+ -+#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.01-rc1/arch/arm/include/asm/arch-sunxi/gpio.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,179 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 _SUNXI_GPIO_H -+#define _SUNXI_GPIO_H -+ -+#include -+ -+/* -+ * 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 -+ -+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[9]; -+ u8 res[0xbc]; -+ struct sunxi_gpio_int gpio_int; -+}; -+ -+#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_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 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)) -+ -+/* GPIO pin function config */ -+#define SUNXI_GPIO_INPUT 0 -+#define SUNXI_GPIO_OUTPUT 1 -+ -+#define SUNXI_GPA0_ERXD3 2 -+#define SUNXI_GPA0_SPI1_CS0 3 -+#define SUNXI_GPA0_UART2_RTS 4 -+ -+#define SUNXI_GPA1_ERXD2 2 -+#define SUNXI_GPA1_SPI1_CLK 3 -+#define SUNXI_GPA1_UART2_CTS 4 -+ -+#define SUNXI_GPA2_ERXD1 2 -+#define SUNXI_GPA2_SPI1_MOSI 3 -+#define SUNXI_GPA2_UART2_TX 4 -+ -+#define SUNXI_GPA10_UART1_TX 4 -+#define SUNXI_GPA11_UART1_RX 4 -+ -+#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_UART0_TX 4 -+#define SUN5I_GPG4_UART0_RX 4 -+ -+#define SUNXI_GPC2_NCLE 2 -+#define SUNXI_GPC2_SPI0_CLK 3 -+ -+#define SUNXI_GPC6_NRB0 2 -+#define SUNXI_GPC6_SDC2_CMD 3 -+ -+#define SUNXI_GPC7_NRB1 2 -+#define SUNXI_GPC7_SDC2_CLK 3 -+ -+#define SUNXI_GPC8_NDQ0 2 -+#define SUNXI_GPC8_SDC2_D0 3 -+ -+#define SUNXI_GPC9_NDQ1 2 -+#define SUNXI_GPC9_SDC2_D1 3 -+ -+#define SUNXI_GPC10_NDQ2 2 -+#define SUNXI_GPC10_SDC2_D2 3 -+ -+#define SUNXI_GPC11_NDQ3 2 -+#define SUNXI_GPC11_SDC2_D3 3 -+ -+#define SUNXI_GPF2_SDC0_CLK 2 -+#define SUNXI_GPF2_UART0_TX 4 -+ -+#define SUNXI_GPF4_SDC0_D3 2 -+#define SUNXI_GPF4_UART0_RX 4 -+ -+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 name_to_gpio(const char *name); -+#define name_to_gpio name_to_gpio -+ -+#endif /* _SUNXI_GPIO_H */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/i2c.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,185 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * Based on sun4i linux kernle i2c.h -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * Victor Wei -+ * -+ * 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 _SUNXI_I2C_H_ -+#define _SUNXI_I2C_H_ -+ -+struct i2c { -+ u32 saddr; /* 31:8bit res,7-1bit for slave addr,0 bit for GCE */ -+ u32 xsaddr; /* 31:8bit res,7-0bit for second addr in 10bit addr */ -+ u32 data; /* 31:8bit res, 7-0bit send or receive data byte */ -+ u32 ctl; /* INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */ -+ u32 status; /* 28 interrupt types + 0xf8 normal type = 29 */ -+ u32 clkr; /* 31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */ -+ u32 reset; /* 31:1bit res;0bit,write 1 to clear 0. */ -+ u32 efr; /* 31:2bit res,1:0 bit data byte follow read comand */ -+ u32 lctl; /* 31:6bits res 5:0bit for sda&scl control */ -+}; -+ -+/* TWI address register */ -+#define TWI_GCE_EN (0x1 << 0) /* gen call addr enable slave mode */ -+#define TWI_ADDR_MASK (0x7f << 1) /* 7:1bits */ -+#define TWI_XADDR_MASK 0xff /* 7:0bits for extend slave address */ -+ -+#define TWI_DATA_MASK 0xff /* 7:0bits for send or received */ -+ -+/* TWI Control Register Bit Fields */ -+/* 1:0 bits reserved */ -+/* set 1 to send A_ACK,then low level on SDA */ -+#define TWI_CTL_ACK (0x1 << 2) -+/* INT_FLAG,interrupt status flag: set '1' when interrupt coming */ -+#define TWI_CTL_INTFLG (0x1 << 3) -+#define TWI_CTL_STP (0x1 << 4) /* M_STP,Automatic clear 0 */ -+#define TWI_CTL_STA (0x1 << 5) /* M_STA,atutomatic clear 0 */ -+#define TWI_CTL_BUSEN (0x1 << 6) /* BUS_EN, mastr mode should be set 1 */ -+#define TWI_CTL_INTEN (0x1 << 7) /* INT_EN */ -+/* 31:8 bit reserved */ -+ -+/* -+ * TWI Clock Register Bit Fields & Masks,default value:0x0000_0000 -+ * Fin is APB CLOCK INPUT; -+ * Fsample = F0 = Fin/2^CLK_N; -+ * F1 = F0/(CLK_M+1); -+ * -+ * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10); -+ * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz -+ */ -+ -+#define TWI_CLK_DIV_M (0xf << 3) /* 6:3bit */ -+#define TWI_CLK_DIV_N (0x7 << 0) /* 2:0bit */ -+#define TWI_CLK_DIV(N, M) ((((N) & 0xf) << 3) | (((M) & 0x7) << 0)) -+ -+/* TWI Soft Reset Register Bit Fields & Masks */ -+/* write 1 to clear 0, when complete soft reset clear 0 */ -+#define TWI_SRST_SRST (0x1 << 0) -+ -+/* TWI Enhance Feature Register Bit Fields & Masks */ -+/* default -- 0x0 */ -+/* 00:no,01: 1byte, 10:2 bytes, 11: 3bytes */ -+#define TWI_EFR_MASK (0x3 << 0) -+#define TWI_EFR_WARC_0 (0x0 << 0) -+#define TWI_EFR_WARC_1 (0x1 << 0) -+#define TWI_EFR_WARC_2 (0x2 << 0) -+#define TWI_EFR_WARC_3 (0x3 << 0) -+ -+/* twi line control register -default value: 0x0000_003a */ -+/* SDA line state control enable ,1:enable;0:disable */ -+#define TWI_LCR_SDA_EN (0x01 << 0) -+/* SDA line state control bit, 1:high level;0:low level */ -+#define TWI_LCR_SDA_CTL (0x01 << 1) -+/* SCL line state control enable ,1:enable;0:disable */ -+#define TWI_LCR_SCL_EN (0x01 << 2) -+/* SCL line state control bit, 1:high level;0:low level */ -+#define TWI_LCR_SCL_CTL (0x01 << 3) -+/* current state of SDA,readonly bit */ -+#define TWI_LCR_SDA_STATE_MASK (0x01 << 4) -+/* current state of SCL,readonly bit */ -+#define TWI_LCR_SCL_STATE_MASK (0x01 << 5) -+/* 31:6bits reserved */ -+#define TWI_LCR_IDLE_STATUS 0x3a -+ -+/* TWI Status Register Bit Fields & Masks */ -+#define TWI_STAT_MASK 0xff -+/* 7:0 bits use only,default is 0xf8 */ -+#define TWI_STAT_BUS_ERR 0x00 /* BUS ERROR */ -+ -+/* Master mode use only */ -+#define TWI_STAT_TX_STA 0x08 /* START condition transmitted */ -+/* Repeated START condition transmitted */ -+#define TWI_STAT_TX_RESTA 0x10 -+/* Address+Write bit transmitted, ACK received */ -+#define TWI_STAT_TX_AW_ACK 0x18 -+/* Address+Write bit transmitted, ACK not received */ -+#define TWI_STAT_TX_AW_NAK 0x20 -+/* data byte transmitted in master mode,ack received */ -+#define TWI_STAT_TXD_ACK 0x28 -+/* data byte transmitted in master mode ,ack not received */ -+#define TWI_STAT_TXD_NAK 0x30 -+/* arbitration lost in address or data byte */ -+#define TWI_STAT_ARBLOST 0x38 -+/* Address+Read bit transmitted, ACK received */ -+#define TWI_STAT_TX_AR_ACK 0x40 -+/* Address+Read bit transmitted, ACK not received */ -+#define TWI_STAT_TX_AR_NAK 0x48 -+/* Second Address byte + Write bit transmitted, ACK received */ -+#define TWI_STAT_TX_2AW_ACK 0xd0 -+/* Second Address byte + Write bit transmitted, ACK received */ -+#define TWI_STAT_TX_2AW_NAK 0xd8 -+/* data byte received in master mode ,ack transmitted */ -+#define TWI_STAT_RXD_ACK 0x50 -+/* date byte received in master mode,not ack transmitted */ -+#define TWI_STAT_RXD_NAK 0x58 -+ -+/* Slave mode use only */ -+/* Slave address+Write bit received, ACK transmitted */ -+#define TWI_STAT_RXWS_ACK 0x60 -+/* -+ * Arbitration lost in address as master, slave address + Write bit received, -+ * ACK transmitted -+ */ -+#define TWI_STAT_ARBLOST_RXWS_ACK 0x68 -+/* General Call address received, ACK transmitted */ -+#define TWI_STAT_RXGCAS_ACK 0x70 -+/* -+ * Arbitration lost in address as master, General Call address received, -+ * ACK transmitted -+ */ -+#define TWI_STAT_ARBLOST_RXGCAS_ACK 0x78 -+/* Data byte received after slave address received, ACK transmitted */ -+#define TWI_STAT_RXDS_ACK 0x80 -+/* Data byte received after slave address received, not ACK transmitted */ -+#define TWI_STAT_RXDS_NAK 0x88 -+/* Data byte received after General Call received, ACK transmitted */ -+#define TWI_STAT_RXDGCAS_ACK 0x90 -+/* Data byte received after General Call received, not ACK transmitted */ -+#define TWI_STAT_RXDGCAS_NAK 0x98 -+/* STOP or repeated START condition received in slave */ -+#define TWI_STAT_RXSTPS_RXRESTAS 0xa0 -+/* Slave address + Read bit received, ACK transmitted */ -+#define TWI_STAT_RXRS_ACK 0xa8 -+/* -+ * Arbitration lost in address as master, slave address + Read bit received, -+ * ACK transmitted -+ */ -+#define TWI_STAT_ARBLOST_SLAR_ACK 0xb0 -+/* Data byte transmitted in slave mode, ACK received */ -+#define TWI_STAT_TXDS_ACK 0xb8 -+/* Data byte transmitted in slave mode, ACK not received */ -+#define TWI_STAT_TXDS_NAK 0xc0 -+/* Last byte transmitted in slave mode, ACK received */ -+#define TWI_STAT_TXDSL_ACK 0xc8 -+ -+/* 10bit Address, second part of address */ -+/* Second Address byte+Write bit transmitted,ACK received */ -+#define TWI_STAT_TX_SAW_ACK 0xd0 -+/* Second Address byte+Write bit transmitted,ACK not received */ -+#define TWI_STAT_TX_SAW_NAK 0xd8 -+ -+/* No relevant status infomation,INT_FLAG = 0 */ -+#define TWI_STAT_IDLE 0xf8 -+ -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/key.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/key.h ---- u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/key.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/key.h 2014-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,53 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 _SUNXI_KEY_H -+#define _SUNXI_KEY_H -+ -+#include -+ -+struct sunxi_lradc { -+ u32 ctrl; /* lradc control */ -+ u32 intc; /* interrupt control */ -+ u32 ints; /* interrupt status */ -+ u32 data0; /* lradc 0 data */ -+ u32 data1; /* lradc 1 data */ -+}; -+ -+#define LRADC_EN 0x1 /* LRADC enable */ -+#define LRADC_SAMPLE_RATE 0x2 /* 32.25 Hz */ -+#define LEVELB_VOL 0x2 /* 0x33(~1.6v) */ -+#define LRADC_HOLD_EN 0x1 /* sample hold enable */ -+#define KEY_MODE_SELECT 0x0 /* normal mode */ -+ -+#define ADC0_DATA_PENDING (0x1 << 0) /* adc0 has data */ -+#define ADC0_KEYDOWN_PENDING (0x1 << 1) /* key down */ -+#define ADC0_HOLDKEY_PENDING (0x1 << 2) /* key hold */ -+#define ADC0_ALRDY_HOLD_PENDING (0x1 << 3) /* key already hold */ -+#define ADC0_KEYUP_PENDING (0x1 << 4) /* key up */ -+ -+int sunxi_key_init(void); -+u32 sunxi_read_key(void); -+ -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/mmc.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,66 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Aaron -+ * -+ * MMC register definition for allwinner sunxi platform. -+ * -+ * 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 _SUNXI_MMC_H -+#define _SUNXI_MMC_H -+ -+#include -+ -+struct sunxi_mmc { -+ u32 gctrl; /* (0x00) SMC Global Control Register */ -+ u32 clkcr; /* (0x04) SMC Clock Control Register */ -+ u32 timeout; /* (0x08) SMC Time Out Register */ -+ u32 width; /* (0x0c) SMC Bus Width Register */ -+ u32 blksz; /* (0x10) SMC Block Size Register */ -+ u32 bytecnt; /* (0x14) SMC Byte Count Register */ -+ u32 cmd; /* (0x18) SMC Command Register */ -+ u32 arg; /* (0x1c) SMC Argument Register */ -+ u32 resp0; /* (0x20) SMC Response Register 0 */ -+ u32 resp1; /* (0x24) SMC Response Register 1 */ -+ u32 resp2; /* (0x28) SMC Response Register 2 */ -+ u32 resp3; /* (0x2c) SMC Response Register 3 */ -+ u32 imask; /* (0x30) SMC Interrupt Mask Register */ -+ u32 mint; /* (0x34) SMC Masked Interrupt Status Reg */ -+ u32 rint; /* (0x38) SMC Raw Interrupt Status Register */ -+ u32 status; /* (0x3c) SMC Status Register */ -+ u32 ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Reg */ -+ u32 funcsel; /* (0x44) SMC Function Select Register */ -+ u32 cbcr; /* (0x48) SMC CIU Byte Count Register */ -+ u32 bbcr; /* (0x4c) SMC BIU Byte Count Register */ -+ u32 dbgc; /* (0x50) SMC Debug Enable Register */ -+ u32 res0[11]; /* (0x54~0x7c) */ -+ u32 dmac; /* (0x80) SMC IDMAC Control Register */ -+ u32 dlba; /* (0x84) SMC IDMAC Descr List Base Addr Reg */ -+ u32 idst; /* (0x88) SMC IDMAC Status Register */ -+ u32 idie; /* (0x8c) SMC IDMAC Interrupt Enable Register */ -+ u32 chda; /* (0x90) */ -+ u32 cbda; /* (0x94) */ -+ u32 res1[26]; /* (0x98~0xff) */ -+ u32 fifo; /* (0x100) SMC FIFO Access Address */ -+}; -+ -+int sunxi_mmc_init(int sdc_no); -+#endif /* _SUNXI_MMC_H */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/smp.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,38 @@ -+/* -+ * (C) Copyright 2013 -+ * Carl van Schaik -+ * -+ * CPU configuration registers for the sun7i (A20). -+ * -+ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/spl.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * This is a copy of omap3/spl.h: -+ * -+ * (C) Copyright 2012 -+ * Texas Instruments, -+ * -+ * 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 _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.01-rc1/arch/arm/include/asm/arch-sunxi/sys_proto.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,33 @@ -+/* -+ * (C) Copyright 2007-2012 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 _SYS_PROTO_H_ -+#define _SYS_PROTO_H_ -+ -+#include -+ -+void sr32(u32 *, u32, u32, u32); -+void sdelay(unsigned long); -+ -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/arch-sunxi/timer.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,104 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Configuration settings for the Allwinner A10-evb board. -+ * -+ * 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 _SUNXI_TIMER_H_ -+#define _SUNXI_TIMER_H_ -+ -+#ifndef __ASSEMBLY__ -+ -+#include -+ -+/* 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.01-rc1/arch/arm/include/asm/arch-sunxi/watchdog.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h ---- u-boot-2014.01-rc1/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-03-05 23:14:47.176099871 +0100 -@@ -0,0 +1,35 @@ -+/* -+ * Watchdog driver for the Allwinner sunxi platform. -+ * Copyright (C) 2013 Oliver Schinagl -+ * http://www.linux-sunxi.org/ -+ * -+ * 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., 51 Franklin Street, Fifth Floor, Boston, -+ * MA 02110-1301, USA. -+ */ -+ -+#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.01-rc1/arch/arm/include/asm/armv7.h u-boot-sunxi/arch/arm/include/asm/armv7.h ---- u-boot-2014.01-rc1/arch/arm/include/asm/armv7.h 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/include/asm/armv7.h 2014-03-05 23:14:47.184099763 +0100 -@@ -78,13 +78,18 @@ - - #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) - --int armv7_switch_nonsec(void); --int armv7_switch_hyp(void); -+int armv7_init_nonsec(void); -+int armv7_update_dt(void *fdt); - - /* defined in assembly file */ - unsigned int _nonsec_init(void); -+void _do_nonsec_entry(void *target_pc, unsigned long r0, -+ unsigned long r1, unsigned long r2); - void _smp_pen(void); --void _switch_to_hyp(void); -+ -+extern char __secure_start[]; -+extern char __secure_end[]; -+ - #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */ - - #endif /* ! __ASSEMBLY__ */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/proc-armv/ptrace.h u-boot-sunxi/arch/arm/include/asm/proc-armv/ptrace.h ---- u-boot-2014.01-rc1/arch/arm/include/asm/proc-armv/ptrace.h 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/include/asm/proc-armv/ptrace.h 2014-03-05 23:14:47.196099604 +0100 -@@ -19,12 +19,14 @@ - #define IRQ_MODE 0x12 - #define SVC_MODE 0x13 - #define ABT_MODE 0x17 -+#define HYP_MODE 0x1a - #define UND_MODE 0x1b - #define SYSTEM_MODE 0x1f - #define MODE_MASK 0x1f - #define T_BIT 0x20 - #define F_BIT 0x40 - #define I_BIT 0x80 -+#define A_BIT 0x100 - #define CC_V_BIT (1 << 28) - #define CC_C_BIT (1 << 29) - #define CC_Z_BIT (1 << 30) -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/psci.h u-boot-sunxi/arch/arm/include/asm/psci.h ---- u-boot-2014.01-rc1/arch/arm/include/asm/psci.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/include/asm/psci.h 2014-03-05 23:14:47.196099604 +0100 -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2013 - ARM Ltd -+ * Author: Marc Zyngier -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef __ARM_PSCI_H__ -+#define __ARM_PSCI_H__ -+ -+/* PSCI interface */ -+#define ARM_PSCI_FN_BASE 0x95c1ba5e -+#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n)) -+ -+#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0) -+#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1) -+#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2) -+#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3) -+ -+#define ARM_PSCI_RET_SUCCESS 0 -+#define ARM_PSCI_RET_NI (-1) -+#define ARM_PSCI_RET_INVAL (-2) -+#define ARM_PSCI_RET_DENIED (-3) -+ -+#endif /* __ARM_PSCI_H__ */ -diff -ruN u-boot-2014.01-rc1/arch/arm/include/asm/secure.h u-boot-sunxi/arch/arm/include/asm/secure.h ---- u-boot-2014.01-rc1/arch/arm/include/asm/secure.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/arch/arm/include/asm/secure.h 2014-03-05 23:14:47.196099604 +0100 -@@ -0,0 +1,26 @@ -+#ifndef __ASM_SECURE_H -+#define __ASM_SECURE_H -+ -+#include -+ -+#ifdef CONFIG_ARMV7_SECURE_BASE -+/* -+ * Warning, horror ahead. -+ * -+ * The target code lives in our "secure ram", but u-boot doesn't know -+ * that, and has blindly added reloc_off to every relocation -+ * entry. Gahh. Do the opposite conversion. This hack also prevents -+ * GCC from generating code veeners, which u-boot doesn't relocate at -+ * all... -+ */ -+#define secure_ram_addr(_fn) ({ \ -+ DECLARE_GLOBAL_DATA_PTR; \ -+ void *__fn = _fn; \ -+ typeof(_fn) *__tmp = (__fn - gd->reloc_off); \ -+ __tmp; \ -+ }) -+#else -+#define secure_ram_addr(_fn) (_fn) -+#endif -+ -+#endif -diff -ruN u-boot-2014.01-rc1/arch/arm/lib/bootm.c u-boot-sunxi/arch/arm/lib/bootm.c ---- u-boot-2014.01-rc1/arch/arm/lib/bootm.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/lib/bootm.c 2014-03-05 23:14:47.196099604 +0100 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - - #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) -@@ -185,19 +186,6 @@ - - __weak void setup_board_tags(struct tag **in_params) {} - --static void do_nonsec_virt_switch(void) --{ --#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) -- if (armv7_switch_nonsec() == 0) --#ifdef CONFIG_ARMV7_VIRT -- if (armv7_switch_hyp() == 0) -- debug("entered HYP mode\n"); --#else -- debug("entered non-secure state\n"); --#endif --#endif --} -- - /* Subcommand: PREP */ - static void boot_prep_linux(bootm_headers_t *images) - { -@@ -234,7 +222,6 @@ - printf("FDT and ATAGS support not compiled in - hanging\n"); - hang(); - } -- do_nonsec_virt_switch(); - } - - /* Subcommand: GO */ -@@ -264,8 +251,15 @@ - else - r2 = gd->bd->bi_boot_params; - -- if (!fake) -+ if (!fake) { -+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) -+ armv7_init_nonsec(); -+ secure_ram_addr(_do_nonsec_entry)(kernel_entry, -+ 0, machid, r2); -+#else - kernel_entry(0, machid, r2); -+#endif -+ } - } - - /* Main Entry point for arm bootm implementation -diff -ruN u-boot-2014.01-rc1/arch/arm/lib/bootm-fdt.c u-boot-sunxi/arch/arm/lib/bootm-fdt.c ---- u-boot-2014.01-rc1/arch/arm/lib/bootm-fdt.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/lib/bootm-fdt.c 2014-03-05 23:14:47.196099604 +0100 -@@ -17,6 +17,9 @@ - - #include - #include -+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) -+#include -+#endif - - DECLARE_GLOBAL_DATA_PTR; - -@@ -34,3 +37,18 @@ - - return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); - } -+ -+int arch_fixup_fdt(void *blob) -+{ -+ int ret; -+ -+ ret = arch_fixup_memory_node(blob); -+ if (ret) -+ return ret; -+ -+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) -+ ret = armv7_update_dt(blob); -+#endif -+ -+ return ret; -+} -diff -ruN u-boot-2014.01-rc1/arch/arm/lib/interrupts.c u-boot-sunxi/arch/arm/lib/interrupts.c ---- u-boot-2014.01-rc1/arch/arm/lib/interrupts.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/lib/interrupts.c 2014-03-05 23:14:47.196099604 +0100 -@@ -103,7 +103,7 @@ - "UK12_26", "UK13_26", "UK14_26", "UK15_26", - "USER_32", "FIQ_32", "IRQ_32", "SVC_32", - "UK4_32", "UK5_32", "UK6_32", "ABT_32", -- "UK8_32", "UK9_32", "UK10_32", "UND_32", -+ "UK8_32", "UK9_32", "HYP_32", "UND_32", - "UK12_32", "UK13_32", "UK14_32", "SYS_32", - }; - -diff -ruN u-boot-2014.01-rc1/arch/arm/lib/sections.c u-boot-sunxi/arch/arm/lib/sections.c ---- u-boot-2014.01-rc1/arch/arm/lib/sections.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/arch/arm/lib/sections.c 2014-03-05 23:14:47.196099604 +0100 -@@ -25,3 +25,5 @@ - char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); - char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); - char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); -+char __secure_start[0] __attribute__((section(".__secure_start"))); -+char __secure_end[0] __attribute__((section(".__secure_end"))); -diff -ruN u-boot-2014.01-rc1/board/sunxi/board.c u-boot-sunxi/board/sunxi/board.c ---- u-boot-2014.01-rc1/board/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/board.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,165 @@ -+/* -+ * (C) Copyright 2012-2013 Henrik Nordstrom -+ * (C) Copyright 2013 Luke Kenneth Casson Leighton -+ * -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Some board init for the Allwinner A10-evb board. -+ * -+ * 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 -+ */ -+ -+#include -+#ifdef CONFIG_AXP152_POWER -+#include -+#endif -+#ifdef CONFIG_AXP209_POWER -+#include -+#endif -+#include -+#include -+#include -+ -+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((unsigned long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_GENERIC_MMC -+int board_mmc_init(bd_t *bis) -+{ -+ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); -+#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA) -+ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); -+#endif -+ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_SPL_BUILD -+void sunxi_board_init(void) -+{ -+ int power_failed = 0; -+ unsigned long ramsize; -+ -+ printf("DRAM:"); -+ ramsize = sunxi_dram_init(); -+ if (!ramsize) { -+ printf(" ?"); -+ ramsize = sunxi_dram_init(); -+ } -+ if (!ramsize) { -+ printf(" ?"); -+ ramsize = sunxi_dram_init(); -+ } -+ printf(" %lu MiB\n", ramsize >> 20); -+ if (!ramsize) -+ hang(); -+ -+#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 -+ -+ /* -+ * Only clock up the CPU to full speed if we are reasonably -+ * assured it's being powered with suitable core voltage -+ */ -+ if (!power_failed) -+#ifdef CONFIG_SUN7I -+ clock_set_pll1(912000000); -+#else -+ clock_set_pll1(1008000000); -+#endif -+ else -+ printf("Failed to set core voltage! Can't set CPU frequency\n"); -+} -+ -+#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 -+ -+#endif -diff -ruN u-boot-2014.01-rc1/board/sunxi/dram_a10_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_a10s_olinuxino_m.c u-boot-sunxi/board/sunxi/dram_a10s_olinuxino_m.c ---- u-boot-2014.01-rc1/board/sunxi/dram_a10s_olinuxino_m.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_a10s_olinuxino_m.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_a13_mid.c u-boot-sunxi/board/sunxi/dram_a13_mid.c ---- u-boot-2014.01-rc1/board/sunxi/dram_a13_mid.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_a13_mid.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_a13_oli_micro.c u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,32 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_a13_olinuxino.c u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c ---- u-boot-2014.01-rc1/board/sunxi/dram_a13_olinuxino.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_a20_olinuxino_m.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_m.c ---- u-boot-2014.01-rc1/board/sunxi/dram_a20_olinuxino_m.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_m.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include "common.h" -+#include -+ -+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.01-rc1/board/sunxi/dram_auxtek_t003.c u-boot-sunxi/board/sunxi/dram_auxtek_t003.c ---- u-boot-2014.01-rc1/board/sunxi/dram_auxtek_t003.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_auxtek_t003.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_cubieboard2.c u-boot-sunxi/board/sunxi/dram_cubieboard2.c ---- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard2.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_cubieboard2.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_cubieboard_512.c u-boot-sunxi/board/sunxi/dram_cubieboard_512.c ---- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard_512.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_cubieboard_512.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+static struct dram_para dram_para = { -+ .clock = 480, -+ .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.01-rc1/board/sunxi/dram_cubieboard.c u-boot-sunxi/board/sunxi/dram_cubieboard.c ---- u-boot-2014.01-rc1/board/sunxi/dram_cubieboard.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_cubieboard.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_cubietruck.c u-boot-sunxi/board/sunxi/dram_cubietruck.c ---- u-boot-2014.01-rc1/board/sunxi/dram_cubietruck.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_cubietruck.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+static struct dram_para dram_para = { -+ .clock = 432, -+ .type = 3, -+ .rank_num = 1, -+ .density = 8192, -+ .io_width = 16, -+ .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.01-rc1/board/sunxi/dram_eoma68_a20.c u-boot-sunxi/board/sunxi/dram_eoma68_a20.c ---- u-boot-2014.01-rc1/board/sunxi/dram_eoma68_a20.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_eoma68_a20.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include "common.h" -+#include -+ -+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.01-rc1/board/sunxi/dram_eu3000.c u-boot-sunxi/board/sunxi/dram_eu3000.c ---- u-boot-2014.01-rc1/board/sunxi/dram_eu3000.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_eu3000.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include "common.h" -+#include -+ -+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.01-rc1/board/sunxi/dram_gooseberry_a721.c u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c ---- u-boot-2014.01-rc1/board/sunxi/dram_gooseberry_a721.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_h6.c u-boot-sunxi/board/sunxi/dram_h6.c ---- u-boot-2014.01-rc1/board/sunxi/dram_h6.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_h6.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_hackberry.c u-boot-sunxi/board/sunxi/dram_hackberry.c ---- u-boot-2014.01-rc1/board/sunxi/dram_hackberry.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_hackberry.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_inet_k70hc.c u-boot-sunxi/board/sunxi/dram_inet_k70hc.c ---- u-boot-2014.01-rc1/board/sunxi/dram_inet_k70hc.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_inet_k70hc.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_megafeis_a08.c u-boot-sunxi/board/sunxi/dram_megafeis_a08.c ---- u-boot-2014.01-rc1/board/sunxi/dram_megafeis_a08.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_megafeis_a08.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_mini_x_a10s.c u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_mk802_a10s.c u-boot-sunxi/board/sunxi/dram_mk802_a10s.c ---- u-boot-2014.01-rc1/board/sunxi/dram_mk802_a10s.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_mk802_a10s.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_mk802ii_a20.c u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c ---- u-boot-2014.01-rc1/board/sunxi/dram_mk802ii_a20.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include "common.h" -+#include -+ -+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.01-rc1/board/sunxi/dram_pov_protab2.c u-boot-sunxi/board/sunxi/dram_pov_protab2.c ---- u-boot-2014.01-rc1/board/sunxi/dram_pov_protab2.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_pov_protab2.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_pov_protab2_xxl.c u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_r7dongle.c u-boot-sunxi/board/sunxi/dram_r7dongle.c ---- u-boot-2014.01-rc1/board/sunxi/dram_r7dongle.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_r7dongle.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sanei_n90.c u-boot-sunxi/board/sunxi/dram_sanei_n90.c ---- u-boot-2014.01-rc1/board/sunxi/dram_sanei_n90.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_sanei_n90.c 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,30 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_312_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_360_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_360_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_360_512.c u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_384_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_408_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_sun4i_408_512.c u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c ---- u-boot-2014.01-rc1/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-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_wobo_i5.c u-boot-sunxi/board/sunxi/dram_wobo_i5.c ---- u-boot-2014.01-rc1/board/sunxi/dram_wobo_i5.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_wobo_i5.c 2014-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_xzpad700.c u-boot-sunxi/board/sunxi/dram_xzpad700.c ---- u-boot-2014.01-rc1/board/sunxi/dram_xzpad700.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_xzpad700.c 2014-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/dram_zatab.c u-boot-sunxi/board/sunxi/dram_zatab.c ---- u-boot-2014.01-rc1/board/sunxi/dram_zatab.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/dram_zatab.c 2014-03-05 23:14:47.912090042 +0100 -@@ -0,0 +1,31 @@ -+/* this file is generated, don't edit it yourself */ -+ -+#include -+#include -+ -+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.01-rc1/board/sunxi/Makefile u-boot-sunxi/board/sunxi/Makefile ---- u-boot-2014.01-rc1/board/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/board/sunxi/Makefile 2014-03-05 23:14:47.908090095 +0100 -@@ -0,0 +1,85 @@ -+# -+# (C) Copyright 2012 Henrik Nordstrom -+# -+# Based on some other board Makefile -+# -+# (C) Copyright 2000-2003 -+# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+# -+# 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 -+# -+ -+obj-y += board.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_a10s_olinuxino_m.o -+obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o -+obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o -+obj-$(CONFIG_A13_MID) += dram_a13_mid.o -+obj-$(CONFIG_A20_OLINUXINO_M) += dram_a20_olinuxino_m.o -+obj-$(CONFIG_AUXTEK_T003) += dram_auxtek_t003.o -+# This is not a typo, uses the same mem settings as the a10s-olinuxino-m -+obj-$(CONFIG_AUXTEK_T004) += dram_a10s_olinuxino_m.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_CUBIEBOARD_512) += dram_cubieboard_512.o -+obj-$(CONFIG_CUBIEBOARD2) += dram_cubieboard2.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_eoma68_a20.o -+obj-$(CONFIG_EU3000) += dram_eu3000.o -+obj-$(CONFIG_GOOSEBERRY_A721) += dram_gooseberry_a721.o -+obj-$(CONFIG_H6) += dram_h6.o -+obj-$(CONFIG_HACKBERRY) += dram_hackberry.o -+obj-$(CONFIG_A7HD) += dram_sun4i_360_1024_iow8.o -+obj-$(CONFIG_INTERRA3) += dram_mk802ii_a20.o -+obj-$(CONFIG_INET_86VZ) += dram_a10s_olinuxino_m.o -+obj-$(CONFIG_INET97F_II) += dram_sun4i_408_512.o -+obj-$(CONFIG_INET_K70HC) += dram_inet_k70hc.o -+obj-$(CONFIG_JESURUN_Q5) += dram_sun4i_312_1024_iow8.o -+obj-$(CONFIG_K1001L1C) += dram_a20_olinuxino_m.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_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_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_POV_PROTAB2) += dram_pov_protab2.o -+obj-$(CONFIG_POV_PROTAB2_XXL) += dram_pov_protab2_xxl.o -+obj-$(CONFIG_R7DONGLE) += dram_r7dongle.o -+obj-$(CONFIG_SANEI_N90) += dram_sanei_n90.o -+obj-$(CONFIG_UHOST_U1A) += dram_sun4i_360_1024_iow8.o -+obj-$(CONFIG_WOBO_I5) += dram_wobo_i5.o -+obj-$(CONFIG_XZPAD700) += dram_xzpad700.o -+obj-$(CONFIG_ZATAB) += dram_zatab.o -diff -ruN u-boot-2014.01-rc1/boards.cfg u-boot-sunxi/boards.cfg ---- u-boot-2014.01-rc1/boards.cfg 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/boards.cfg 2014-03-05 23:14:47.948089561 +0100 -@@ -344,6 +344,82 @@ - Active arm armv7 s5pc1xx samsung goni s5p_goni - Minkyu Kang - Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang - 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_MICRO sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_GMAC,FAST_MBUS - -+Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO_FEL sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_GMAC,FAST_MBUS - -+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 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 Colombus sun6i:COLOMBUS - -+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_512 sun4i:CUBIEBOARD_512,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - -+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 Gooseberry_A721 sun4i:GOOSEBERRY_A721,SPL - -+Active arm armv7 sunxi - sunxi H6 sun4i:H6,SPL - -+Active arm armv7 sunxi - sunxi Hackberry sun4i:HACKBERRY,SPL - -+Active arm armv7 sunxi - sunxi Hyundai_A7HD sun4i:A7HD,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 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,STATUSLED=234 - -+Active arm armv7 sunxi - sunxi Mele_A1000_FEL sun4i:MELE_A1000,SPL_FEL,SUNXI_EMAC,STATUSLED=234 - -+Active arm armv7 sunxi - sunxi Mele_A1000G sun4i:MELE_A1000G,SPL,SUNXI_EMAC,STATUSLED=234 - -+Active arm armv7 sunxi - sunxi Mele_A3700 sun4i:MELE_A3700,SPL,SUNXI_EMAC,STATUSLED=234 - -+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 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 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 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 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 uhost_u1a sun4i:UHOST_U1A,SPL,STATUSLED=34 - -+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 - 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 -diff -ruN u-boot-2014.01-rc1/common/cmd_gpio.c u-boot-sunxi/common/cmd_gpio.c ---- u-boot-2014.01-rc1/common/cmd_gpio.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/common/cmd_gpio.c 2014-03-05 23:14:47.952089507 +0100 -@@ -20,6 +20,7 @@ - GPIO_SET, - GPIO_CLEAR, - GPIO_TOGGLE, -+ GPIO_OSCILLATE, - }; - - static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -@@ -48,6 +49,7 @@ - case 's': sub_cmd = GPIO_SET; break; - case 'c': sub_cmd = GPIO_CLEAR; break; - case 't': sub_cmd = GPIO_TOGGLE; break; -+ case 'o': sub_cmd = GPIO_OSCILLATE; break; - default: goto show_usage; - } - -@@ -66,6 +68,14 @@ - if (sub_cmd == GPIO_INPUT) { - gpio_direction_input(gpio); - value = gpio_get_value(gpio); -+ } else if (sub_cmd == GPIO_OSCILLATE) { -+ int i; -+ gpio_direction_output(gpio, 0); -+ for (i = 0; i < 100000000; i++) { -+ gpio_set_value(gpio, i&1); -+ } -+ gpio_direction_input(gpio); -+ value = 0; - } else { - switch (sub_cmd) { - case GPIO_SET: value = 1; break; -diff -ruN u-boot-2014.01-rc1/common/image-fdt.c u-boot-sunxi/common/image-fdt.c ---- u-boot-2014.01-rc1/common/image-fdt.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/common/image-fdt.c 2014-03-05 23:14:47.968089294 +0100 -@@ -445,7 +445,7 @@ - return 1; - } - --__weak int arch_fixup_memory_node(void *blob) -+__weak int arch_fixup_fdt(void *blob) - { - return 0; - } -@@ -462,7 +462,10 @@ - puts(" - must RESET the board to recover.\n"); - return -1; - } -- arch_fixup_memory_node(blob); -+ if (arch_fixup_fdt(blob) < 0) { -+ puts("ERROR: arch specific fdt fixup failed"); -+ return -1; -+ } - if (IMAAGE_OF_BOARD_SETUP) - ft_board_setup(blob, gd->bd); - fdt_fixup_ethernet(blob); -diff -ruN u-boot-2014.01-rc1/common/memsize.c u-boot-sunxi/common/memsize.c ---- u-boot-2014.01-rc1/common/memsize.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/common/memsize.c 2014-03-05 23:14:47.968089294 +0100 -@@ -21,16 +21,16 @@ - * the actually available RAM size between addresses `base' and - * `base + maxsize'. - */ --long get_ram_size(long *base, long maxsize) -+unsigned long get_ram_size(unsigned long *base, unsigned long maxsize) - { -- volatile long *addr; -- long save[32]; -- long cnt; -- long val; -- long size; -- int i = 0; -+ volatile unsigned long *addr; -+ unsigned long save[32]; -+ unsigned long cnt; -+ unsigned long val; -+ unsigned long size; -+ int i = 0; - -- for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { -+ for (cnt = (maxsize / sizeof (unsigned long)) >> 1; cnt > 0; cnt >>= 1) { - addr = base + cnt; /* pointer arith! */ - sync (); - save[i++] = *addr; -@@ -50,7 +50,7 @@ - */ - sync (); - *addr = save[i]; -- for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { -+ for (cnt = 1; cnt < maxsize / sizeof(unsigned long); cnt <<= 1) { - addr = base + cnt; - sync (); - *addr = save[--i]; -@@ -58,15 +58,15 @@ - return (0); - } - -- for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { -+ for (cnt = 1; cnt < maxsize / sizeof (unsigned long); cnt <<= 1) { - addr = base + cnt; /* pointer arith! */ - val = *addr; - *addr = save[--i]; - if (val != ~cnt) { -- size = cnt * sizeof (long); -+ size = cnt * sizeof (unsigned long); - /* Restore the original data before leaving the function. - */ -- for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) { -+ for (cnt <<= 1; cnt < maxsize / sizeof (unsigned long); cnt <<= 1) { - addr = base + cnt; - *addr = save[--i]; - } -diff -ruN u-boot-2014.01-rc1/common/spl/spl_mmc.c u-boot-sunxi/common/spl/spl_mmc.c ---- u-boot-2014.01-rc1/common/spl/spl_mmc.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/common/spl/spl_mmc.c 2014-03-05 23:14:47.968089294 +0100 -@@ -30,8 +30,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.01-rc1/drivers/gpio/Makefile u-boot-sunxi/drivers/gpio/Makefile ---- u-boot-2014.01-rc1/drivers/gpio/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/gpio/Makefile 2014-03-05 23:14:47.996088920 +0100 -@@ -31,3 +31,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.01-rc1/drivers/gpio/sunxi_gpio.c u-boot-sunxi/drivers/gpio/sunxi_gpio.c ---- u-boot-2014.01-rc1/drivers/gpio/sunxi_gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/gpio/sunxi_gpio.c 2014-03-05 23:14:47.996088920 +0100 -@@ -0,0 +1,120 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: -+ * -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+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 = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[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 = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[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 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.01-rc1/drivers/i2c/Makefile u-boot-sunxi/drivers/i2c/Makefile ---- u-boot-2014.01-rc1/drivers/i2c/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/i2c/Makefile 2014-03-05 23:14:48.000088867 +0100 -@@ -16,6 +16,7 @@ - obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o - obj-$(CONFIG_U8500_I2C) += u8500_i2c.o - obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o -+obj-$(CONFIG_SUNXI_I2C) += sunxi_i2c.o - obj-$(CONFIG_SYS_I2C) += i2c_core.o - obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o - obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o -diff -ruN u-boot-2014.01-rc1/drivers/i2c/sunxi_i2c.c u-boot-sunxi/drivers/i2c/sunxi_i2c.c ---- u-boot-2014.01-rc1/drivers/i2c/sunxi_i2c.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/i2c/sunxi_i2c.c 2014-03-05 23:14:48.000088867 +0100 -@@ -0,0 +1,276 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct i2c __attribute__ ((section(".data"))) *i2c_base = -+ (struct i2c *)0x1c2ac00; -+ -+void i2c_init(int speed, int slaveaddr) -+{ -+ int timeout = 0x2ff; -+ -+ sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2); -+ sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2); -+ clock_twi_onoff(0, 1); -+ -+ /* Enable the i2c bus */ -+ writel(TWI_CTL_BUSEN, &i2c_base->ctl); -+ -+ /* 400KHz operation M=2, N=1, 24MHz APB clock */ -+ writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr); -+ writel(TWI_SRST_SRST, &i2c_base->reset); -+ -+ while ((readl(&i2c_base->reset) & TWI_SRST_SRST) && timeout--); -+} -+ -+int i2c_probe(uchar chip) -+{ -+ return -1; -+} -+ -+static int i2c_wait_ctl(int mask, int state) -+{ -+ int timeout = 0x2ff; -+ int value = state ? mask : 0; -+ -+ debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value, -+ i2c_base->ctl, i2c_base->status); -+ -+ while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0); -+ -+ debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout, -+ i2c_base->ctl, i2c_base->status); -+ -+ if (timeout != 0) -+ return 0; -+ else -+ return -1; -+} -+ -+static void i2c_clear_irq(void) -+{ -+ writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl); -+} -+ -+static int i2c_wait_irq(void) -+{ -+ return i2c_wait_ctl(TWI_CTL_INTFLG, 1); -+} -+ -+static int i2c_wait_status(int status) -+{ -+ int timeout = 0x2ff; -+ -+ while (readl(&i2c_base->status) != status && timeout-- > 0); -+ -+ if (timeout != 0) -+ return 0; -+ else -+ return -1; -+} -+ -+static int i2c_wait_irq_status(int status) -+{ -+ if (i2c_wait_irq() != 0) -+ return -1; -+ -+ if (readl(&i2c_base->status) != status) -+ return -1; -+ -+ return 0; -+} -+ -+static int i2c_wait_bus_idle(void) -+{ -+ int timeout = 0x2ff; -+ -+ while (readl(&i2c_base->lctl) != 0x3a && timeout-- > 0); -+ -+ if (timeout != 0) -+ return 0; -+ else -+ return -1; -+} -+ -+static int i2c_stop(void) -+{ -+ u32 ctl; -+ -+ ctl = readl(&i2c_base->ctl) & 0xc0; -+ ctl |= TWI_CTL_STP; -+ -+ writel(ctl, &i2c_base->ctl); -+ -+ /* dummy to delay one I/O operation to make sure it's started */ -+ (void)readl(&i2c_base->ctl); -+ -+ if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0) -+ return -1; -+ if (i2c_wait_status(TWI_STAT_IDLE)) -+ return -1; -+ if (i2c_wait_bus_idle() != 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int i2c_send_data(u8 data, u8 status) -+{ -+ debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status, -+ i2c_base->ctl, i2c_base->status); -+ -+ writel(data, &i2c_base->data); -+ i2c_clear_irq(); -+ -+ if (i2c_wait_irq_status(status) != 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int i2c_start(int status) -+{ -+ u32 ctl; -+ -+ debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl, -+ i2c_base->status); -+ /* Check that the controller is idle */ -+ if (status == TWI_STAT_TX_STA && -+ readl(&i2c_base->status) != TWI_STAT_IDLE) { -+ return -1; -+ } -+ -+ writel(0, &i2c_base->efr); -+ -+ /* Send start */ -+ ctl = readl(&i2c_base->ctl); -+ ctl |= TWI_CTL_STA; /* Set start bit */ -+ ctl &= ~TWI_CTL_INTFLG; /* Clear int flag */ -+ writel(ctl, &i2c_base->ctl); -+ -+ if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0) -+ return -1; -+ if (i2c_wait_irq_status(status) != 0) -+ return -1; -+ -+ return 0; -+} -+ -+int i2c_do_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -+{ -+ u32 status; -+ u32 ctl; -+ -+ if (i2c_start(TWI_STAT_TX_STA) != 0) -+ return -1; -+ -+ /* Send chip address */ -+ if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0) -+ return -1; -+ -+ /* Send data address */ -+ if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0) -+ return -1; -+ -+ /* Send restart for read */ -+ if (i2c_start(TWI_STAT_TX_RESTA) != 0) -+ return -1; -+ -+ /* Send chip address */ -+ if (i2c_send_data(chip << 1 | 1, TWI_STAT_TX_AR_ACK) != 0) -+ return -1; -+ -+ /* Set ACK mode */ -+ ctl = readl(&i2c_base->ctl); -+ ctl |= TWI_CTL_ACK; -+ writel(ctl, &i2c_base->ctl); -+ status = TWI_STAT_RXD_ACK; -+ -+ /* Read data */ -+ while (len > 0) { -+ if (len == 1) { -+ /* Set NACK mode (last byte) */ -+ ctl = readl(&i2c_base->ctl); -+ ctl &= ~TWI_CTL_ACK; -+ writel(ctl, &i2c_base->ctl); -+ status = TWI_STAT_RXD_NAK; -+ } -+ -+ i2c_clear_irq(); -+ if (i2c_wait_irq_status(status) != 0) -+ return -1; -+ -+ *buffer++ = readl(&i2c_base->data); -+ len--; -+ } -+ -+ return 0; -+} -+ -+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -+{ -+ int rc = i2c_do_read(chip, addr, alen, buffer, len); -+ -+ i2c_stop(); -+ -+ return rc; -+} -+ -+static int i2c_do_write(uchar chip, uint addr, int alen, uchar *buffer, -+ int len) -+{ -+ if (i2c_start(TWI_STAT_TX_STA) != 0) -+ return -1; -+ -+ /* Send chip address */ -+ if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0) -+ return -1; -+ -+ /* Send data address */ -+ if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0) -+ return -1; -+ -+ /* Send data */ -+ while (len > 0) { -+ if (i2c_send_data(*buffer++, TWI_STAT_TXD_ACK) != 0) -+ return -1; -+ len--; -+ } -+ -+ return 0; -+} -+ -+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) -+{ -+ int rc = i2c_do_write(chip, addr, alen, buffer, len); -+ -+ i2c_stop(); -+ -+ return rc; -+} -diff -ruN u-boot-2014.01-rc1/drivers/mmc/Makefile u-boot-sunxi/drivers/mmc/Makefile ---- u-boot-2014.01-rc1/drivers/mmc/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/mmc/Makefile 2014-03-05 23:14:48.004088813 +0100 -@@ -26,6 +26,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 - ifdef CONFIG_SPL_BUILD - obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o -diff -ruN u-boot-2014.01-rc1/drivers/mmc/sunxi_mmc.c u-boot-sunxi/drivers/mmc/sunxi_mmc.c ---- u-boot-2014.01-rc1/drivers/mmc/sunxi_mmc.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/mmc/sunxi_mmc.c 2014-03-05 23:14:48.008088759 +0100 -@@ -0,0 +1,660 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Aaron -+ * -+ * MMC driver for allwinner sunxi platform. -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static void dumphex32(char *name, char *base, int len) -+{ -+ __u32 i; -+ -+ debug("dump %s registers:", name); -+ for (i = 0; i < len; i += 4) { -+ if (!(i & 0xf)) -+ debug("\n0x%p : ", base + i); -+ debug("0x%08x ", readl(base + i)); -+ } -+ debug("\n"); -+} -+ -+static void dumpmmcreg(struct sunxi_mmc *reg) -+{ -+ debug("dump mmc registers:\n"); -+ debug("gctrl 0x%08x\n", reg->gctrl); -+ debug("clkcr 0x%08x\n", reg->clkcr); -+ debug("timeout 0x%08x\n", reg->timeout); -+ debug("width 0x%08x\n", reg->width); -+ debug("blksz 0x%08x\n", reg->blksz); -+ debug("bytecnt 0x%08x\n", reg->bytecnt); -+ debug("cmd 0x%08x\n", reg->cmd); -+ debug("arg 0x%08x\n", reg->arg); -+ debug("resp0 0x%08x\n", reg->resp0); -+ debug("resp1 0x%08x\n", reg->resp1); -+ debug("resp2 0x%08x\n", reg->resp2); -+ debug("resp3 0x%08x\n", reg->resp3); -+ debug("imask 0x%08x\n", reg->imask); -+ debug("mint 0x%08x\n", reg->mint); -+ debug("rint 0x%08x\n", reg->rint); -+ debug("status 0x%08x\n", reg->status); -+ debug("ftrglevel 0x%08x\n", reg->ftrglevel); -+ debug("funcsel 0x%08x\n", reg->funcsel); -+ debug("dmac 0x%08x\n", reg->dmac); -+ debug("dlba 0x%08x\n", reg->dlba); -+ debug("idst 0x%08x\n", reg->idst); -+ debug("idie 0x%08x\n", reg->idie); -+} -+ -+struct sunxi_mmc_des { -+ u32 reserved1_1:1; -+ u32 dic:1; /* disable interrupt on completion */ -+ u32 last_des:1; /* 1-this data buffer is the last buffer */ -+ u32 first_des:1; /* 1-data buffer is the first buffer, -+ 0-data buffer contained in the next -+ descriptor is 1st buffer */ -+ u32 des_chain:1; /* 1-the 2nd address in the descriptor is the -+ next descriptor address */ -+ u32 end_of_ring:1; /* 1-last descriptor flag when using dual -+ data buffer in descriptor */ -+ u32 reserved1_2:24; -+ u32 card_err_sum:1; /* transfer error flag */ -+ u32 own:1; /* des owner:1-idma owns it, 0-host owns it */ -+#ifdef CONFIG_SUN4I -+#define SDXC_DES_NUM_SHIFT 13 -+#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) -+ u32 data_buf1_sz:13; -+ u32 data_buf2_sz:13; -+ u32 reserverd2_1:6; -+#elif defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) -+#define SDXC_DES_NUM_SHIFT 16 -+#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) -+ u32 data_buf1_sz:16; -+ u32 data_buf2_sz:16; -+#else -+#error ">>>> Wrong Platform for MMC <<<<" -+#endif -+ u32 buf_addr_ptr1; -+ u32 buf_addr_ptr2; -+}; -+ -+struct sunxi_mmc_host { -+ unsigned mmc_no; -+ uint32_t *mclkreg; -+ unsigned database; -+ unsigned fatal_err; -+ unsigned mod_clk; -+ struct sunxi_mmc *reg; -+}; -+ -+/* support 4 mmc hosts */ -+struct mmc mmc_dev[4]; -+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; -+ } -+ mmchost->database = (unsigned int)mmchost->reg + 0x100; -+ mmchost->mmc_no = sdc_no; -+ -+ return 0; -+} -+ -+static int mmc_clk_io_on(int sdc_no) -+{ -+ unsigned int rval; -+ unsigned int pll5_clk; -+ unsigned int divider; -+ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; -+ static struct sunxi_gpio *gpio_c = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_C]; -+ static struct sunxi_gpio *gpio_f = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_F]; -+#if CONFIG_MMC1_PG -+ static struct sunxi_gpio *gpio_g = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_G]; -+#endif -+ static struct sunxi_gpio *gpio_h = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_H]; -+ static struct sunxi_gpio *gpio_i = -+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_I]; -+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -+ -+ debug("init mmc %d clock and io\n", sdc_no); -+ -+ /* config gpio */ -+ switch (sdc_no) { -+ case 0: -+ /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ -+ writel(0x222222, &gpio_f->cfg[0]); -+ writel(0x555, &gpio_f->pull[0]); -+ writel(0xaaa, &gpio_f->drv[0]); -+ break; -+ -+ case 1: -+#if CONFIG_MMC1_PG -+ /* PG0-CMD, PG1-CLK, PG2~5-D0~3 : 4 */ -+ writel(0x444444, &gpio_g->cfg[0]); -+ writel(0x555, &gpio_g->pull[0]); -+ writel(0xaaa, &gpio_g->drv[0]); -+#else -+ /* PH22-CMD, PH23-CLK, PH24~27-D0~D3 : 5 */ -+ writel(0x55 << 24, &gpio_h->cfg[2]); -+ writel(0x5555, &gpio_h->cfg[3]); -+ writel(0x555 << 12, &gpio_h->pull[1]); -+ writel(0xaaa << 12, &gpio_h->drv[1]); -+#endif -+ break; -+ -+ case 2: -+ /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ -+ writel(0x33 << 24, &gpio_c->cfg[0]); -+ writel(0x3333, &gpio_c->cfg[1]); -+ writel(0x555 << 12, &gpio_c->pull[0]); -+ writel(0xaaa << 12, &gpio_c->drv[0]); -+ break; -+ -+ case 3: -+ /* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */ -+ writel(0x2222 << 16, &gpio_i->cfg[0]); -+ writel(0x22, &gpio_i->cfg[1]); -+ writel(0x555 << 8, &gpio_i->pull[0]); -+ writel(0x555 << 8, &gpio_i->drv[0]); -+ break; -+ -+ default: -+ return -1; -+ } -+ -+ /* config ahb clock */ -+ rval = readl(&ccm->ahb_gate0); -+ rval |= (1 << (8 + sdc_no)); -+ writel(rval, &ccm->ahb_gate0); -+ -+ /* config mod clock */ -+ pll5_clk = clock_get_pll5(); -+ if (pll5_clk > 400000000) -+ divider = 4; -+ else -+ divider = 3; -+ writel((0x1 << 31) | (0x2 << 24) | divider, mmchost->mclkreg); -+ mmchost->mod_clk = pll5_clk / (divider + 1); -+ -+ dumphex32("ccmu", (char *)SUNXI_CCM_BASE, 0x100); -+ dumphex32("gpio", (char *)SUNXI_PIO_BASE, 0x100); -+ dumphex32("mmc", (char *)mmchost->reg, 0x100); -+ dumpmmcreg(mmchost->reg); -+ -+ return 0; -+} -+ -+static int mmc_update_clk(struct mmc *mmc) -+{ -+ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; -+ unsigned int cmd; -+ unsigned timeout = 0xfffff; -+ -+ cmd = (0x1 << 31) | (0x1 << 21) | (0x1 << 13); -+ writel(cmd, &mmchost->reg->cmd); -+ while ((readl(&mmchost->reg->cmd) & (0x1 << 31)) && timeout--); -+ if (!timeout) -+ return -1; -+ -+ 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 = (struct sunxi_mmc_host *)mmc->priv; -+ unsigned rval = readl(&mmchost->reg->clkcr); -+ -+ /* -+ * CLKCREG[7:0]: divider -+ * CLKCREG[16]: on/off -+ * CLKCREG[17]: power save -+ */ -+ /* Disable Clock */ -+ rval &= ~(0x1 << 16); -+ writel(rval, &mmchost->reg->clkcr); -+ if (mmc_update_clk(mmc)) -+ return -1; -+ -+ /* Change Divider Factor */ -+ rval &= ~(0xff); -+ rval |= div; -+ writel(rval, &mmchost->reg->clkcr); -+ if (mmc_update_clk(mmc)) -+ return -1; -+ /* Re-enable Clock */ -+ rval |= (0x1 << 16); -+ 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 = (struct sunxi_mmc_host *)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 = (struct sunxi_mmc_host *)mmc->priv; -+ -+ /* Reset controller */ -+ writel(0x7, &mmchost->reg->gctrl); -+ -+ return 0; -+} -+ -+static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) -+{ -+ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; -+ unsigned i; -+ unsigned byte_cnt = data->blocksize * data->blocks; -+ unsigned *buff; -+ unsigned timeout = 0xfffff; -+ -+ if (data->flags & MMC_DATA_READ) { -+ buff = (unsigned int *)data->dest; -+ for (i = 0; i < (byte_cnt >> 2); i++) { -+ while (--timeout && -+ (readl(&mmchost->reg->status) & (0x1 << 2))); -+ if (timeout <= 0) -+ goto out; -+ buff[i] = readl(mmchost->database); -+ timeout = 0xfffff; -+ } -+ } else { -+ buff = (unsigned int *)data->src; -+ for (i = 0; i < (byte_cnt >> 2); i++) { -+ while (--timeout && -+ (readl(&mmchost->reg->status) & (0x1 << 3))); -+ if (timeout <= 0) -+ goto out; -+ writel(buff[i], mmchost->database); -+ timeout = 0xfffff; -+ } -+ } -+ -+out: -+ if (timeout <= 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) -+{ -+ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; -+ unsigned byte_cnt = data->blocksize * data->blocks; -+ unsigned char *buff; -+ unsigned des_idx = 0; -+ unsigned buff_frag_num = -+ (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT; -+ unsigned remain; -+ unsigned i, rval; -+ ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num); -+ -+ buff = data->flags & MMC_DATA_READ ? -+ (unsigned char *)data->dest : (unsigned char *)data->src; -+ remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1); -+ if (!remain) -+ remain = SDXC_DES_BUFFER_MAX_LEN; -+ -+ flush_cache((unsigned long)buff, (unsigned long)byte_cnt); -+ for (i = 0; i < buff_frag_num; i++, des_idx++) { -+ memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des)); -+ pdes[des_idx].des_chain = 1; -+ pdes[des_idx].own = 1; -+ pdes[des_idx].dic = 1; -+ if (buff_frag_num > 1 && i != buff_frag_num - 1) -+ pdes[des_idx].data_buf1_sz = -+ (SDXC_DES_BUFFER_MAX_LEN - -+ 1) & SDXC_DES_BUFFER_MAX_LEN; -+ else -+ pdes[des_idx].data_buf1_sz = remain; -+ -+ pdes[des_idx].buf_addr_ptr1 = -+ (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN; -+ if (i == 0) -+ pdes[des_idx].first_des = 1; -+ -+ if (i == buff_frag_num - 1) { -+ pdes[des_idx].dic = 0; -+ pdes[des_idx].last_des = 1; -+ pdes[des_idx].end_of_ring = 1; -+ pdes[des_idx].buf_addr_ptr2 = 0; -+ } else { -+ pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1]; -+ } -+ debug("frag %d, remain %d, des[%d](%08x): ", -+ i, remain, des_idx, (u32)&pdes[des_idx]); -+ debug("[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x\n", -+ (u32)((u32 *)&pdes[des_idx])[0], -+ (u32)((u32 *)&pdes[des_idx])[1], -+ (u32)((u32 *)&pdes[des_idx])[2], -+ (u32)((u32 *)&pdes[des_idx])[3]); -+ } -+ flush_cache((unsigned long)pdes, -+ sizeof(struct sunxi_mmc_des) * (des_idx + 1)); -+ -+ /* -+ * GCTRLREG -+ * GCTRL[2] : DMA reset -+ * GCTRL[5] : DMA enable -+ * -+ * IDMACREG -+ * IDMAC[0] : IDMA soft reset -+ * IDMAC[1] : IDMA fix burst flag -+ * IDMAC[7] : IDMA on -+ * -+ * IDIECREG -+ * IDIE[0] : IDMA transmit interrupt flag -+ * IDIE[1] : IDMA receive interrupt flag -+ */ -+ rval = readl(&mmchost->reg->gctrl); -+ /* Enable DMA */ -+ writel(rval | (0x1 << 5) | (0x1 << 2), &mmchost->reg->gctrl); -+ /* Reset iDMA */ -+ writel((0x1 << 0), &mmchost->reg->dmac); -+ /* Enable iDMA */ -+ writel((0x1 << 1) | (1 << 7), &mmchost->reg->dmac); -+ rval = readl(&mmchost->reg->idie) & (~3); -+ if (data->flags & MMC_DATA_WRITE) -+ rval |= (0x1 << 0); -+ else -+ rval |= (0x1 << 1); -+ writel(rval, &mmchost->reg->idie); -+ writel((u32) pdes, &mmchost->reg->dlba); -+ writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), -+ &mmchost->reg->ftrglevel); -+ -+ return 0; -+} -+ -+static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, -+ struct mmc_data *data) -+{ -+ struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv; -+ unsigned int cmdval = 0x80000000; -+ signed int timeout = 0; -+ int error = 0; -+ unsigned int status = 0; -+ unsigned int usedma = 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; -+ -+ /* -+ * CMDREG -+ * CMD[5:0] : Command index -+ * CMD[6] : Has response -+ * CMD[7] : Long response -+ * CMD[8] : Check response CRC -+ * CMD[9] : Has data -+ * CMD[10] : Write -+ * CMD[11] : Steam mode -+ * CMD[12] : Auto stop -+ * CMD[13] : Wait previous over -+ * CMD[14] : About cmd -+ * CMD[15] : Send initialization -+ * CMD[21] : Update clock -+ * CMD[31] : Load cmd -+ */ -+ if (!cmd->cmdidx) -+ cmdval |= (0x1 << 15); -+ if (cmd->resp_type & MMC_RSP_PRESENT) -+ cmdval |= (0x1 << 6); -+ if (cmd->resp_type & MMC_RSP_136) -+ cmdval |= (0x1 << 7); -+ if (cmd->resp_type & MMC_RSP_CRC) -+ cmdval |= (0x1 << 8); -+ -+ if (data) { -+ if ((u32) data->dest & 0x3) { -+ error = -1; -+ goto out; -+ } -+ -+ cmdval |= (0x1 << 9) | (0x1 << 13); -+ if (data->flags & MMC_DATA_WRITE) -+ cmdval |= (0x1 << 10); -+ if (data->blocks > 1) -+ cmdval |= (0x1 << 12); -+ 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); -+#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD) -+ if (bytecnt > 64) { -+#else -+ if (0) { -+#endif -+ usedma = 1; -+ writel(readl(&mmchost->reg->gctrl) & ~(0x1 << 31), -+ &mmchost->reg->gctrl); -+ ret = mmc_trans_data_by_dma(mmc, data); -+ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); -+ } else { -+ writel(readl(&mmchost->reg->gctrl) | 0x1 << 31, -+ &mmchost->reg->gctrl); -+ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); -+ ret = mmc_trans_data_by_cpu(mmc, data); -+ } -+ if (ret) { -+ error = readl(&mmchost->reg->rint) & 0xbfc2; -+ error = TIMEOUT; -+ goto out; -+ } -+ } -+ -+ timeout = 0xfffff; -+ do { -+ status = readl(&mmchost->reg->rint); -+ if (!timeout-- || (status & 0xbfc2)) { -+ error = status & 0xbfc2; -+ debug("cmd timeout %x\n", error); -+ error = TIMEOUT; -+ goto out; -+ } -+ } while (!(status & 0x4)); -+ -+ if (data) { -+ unsigned done = 0; -+ timeout = usedma ? 0xffff * bytecnt : 0xffff; -+ debug("cacl timeout %x\n", timeout); -+ do { -+ status = readl(&mmchost->reg->rint); -+ if (!timeout-- || (status & 0xbfc2)) { -+ error = status & 0xbfc2; -+ debug("data timeout %x\n", error); -+ error = TIMEOUT; -+ goto out; -+ } -+ if (data->blocks > 1) -+ done = status & (0x1 << 14); -+ else -+ done = status & (0x1 << 3); -+ } while (!done); -+ } -+ -+ if (cmd->resp_type & MMC_RSP_BUSY) { -+ timeout = 0xfffff; -+ do { -+ status = readl(&mmchost->reg->status); -+ if (!timeout--) { -+ debug("busy timeout\n"); -+ error = TIMEOUT; -+ goto out; -+ } -+ } while (status & (1 << 9)); -+ } -+ -+ 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 (data && usedma) { -+ /* IDMASTAREG -+ * IDST[0] : idma tx int -+ * IDST[1] : idma rx int -+ * IDST[2] : idma fatal bus error -+ * IDST[4] : idma descriptor invalid -+ * IDST[5] : idma error summary -+ * IDST[8] : idma normal interrupt sumary -+ * IDST[9] : idma abnormal interrupt sumary -+ */ -+ status = readl(&mmchost->reg->idst); -+ writel(status, &mmchost->reg->idst); -+ writel(0, &mmchost->reg->idie); -+ writel(0, &mmchost->reg->dmac); -+ writel(readl(&mmchost->reg->gctrl) & ~(0x1 << 5), -+ &mmchost->reg->gctrl); -+ } -+ if (error < 0) { -+ writel(0x7, &mmchost->reg->gctrl); -+ mmc_update_clk(mmc); -+ } -+ writel(0xffffffff, &mmchost->reg->rint); -+ writel(readl(&mmchost->reg->gctrl) | (1 << 1), &mmchost->reg->gctrl); -+ -+ return error; -+} -+ -+int sunxi_mmc_init(int sdc_no) -+{ -+ struct mmc *mmc; -+ -+ memset(&mmc_dev[sdc_no], 0, sizeof(struct mmc)); -+ memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); -+ mmc = &mmc_dev[sdc_no]; -+ -+ sprintf(mmc->name, "SUNXI SD/MMC"); -+ mmc->priv = &mmc_host[sdc_no]; -+ mmc->send_cmd = mmc_send_cmd; -+ mmc->set_ios = mmc_set_ios; -+ mmc->init = mmc_core_init; -+ -+ mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; -+ mmc->host_caps = MMC_MODE_4BIT; -+ mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; -+ -+ mmc->f_min = 400000; -+ mmc->f_max = 52000000; -+ -+ mmc_resource_init(sdc_no); -+ mmc_clk_io_on(sdc_no); -+ -+ mmc_register(mmc); -+ -+ return 0; -+} -diff -ruN u-boot-2014.01-rc1/drivers/net/designware.c u-boot-sunxi/drivers/net/designware.c ---- u-boot-2014.01-rc1/drivers/net/designware.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/net/designware.c 2014-03-05 23:14:48.024088546 +0100 -@@ -154,7 +154,7 @@ - /* Resore the HW MAC address as it has been lost during MAC reset */ - dw_write_hwaddr(dev); - -- writel(FIXEDBURST | PRIORXTX_41 | BURST_16, -+ writel(FIXEDBURST | PRIORXTX_41 | BURST_8, - &dma_p->busmode); - - writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD | -diff -ruN u-boot-2014.01-rc1/drivers/net/Makefile u-boot-sunxi/drivers/net/Makefile ---- u-boot-2014.01-rc1/drivers/net/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/net/Makefile 2014-03-05 23:14:48.020088600 +0100 -@@ -50,7 +50,8 @@ - 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_SUNXI_GMAC) += sunxi_gmac.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.01-rc1/drivers/net/sunxi_emac.c u-boot-sunxi/drivers/net/sunxi_emac.c ---- u-boot-2014.01-rc1/drivers/net/sunxi_emac.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/net/sunxi_emac.c 2014-03-05 23:14:48.056088119 +0100 -@@ -0,0 +1,521 @@ -+/* -+ * sunxi_emac.c -- Allwinner A10 ethernet driver -+ * -+ * (C) Copyright 2012, Stefan Roese -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* EMAC register */ -+struct emac_regs { -+ u32 ctl; /* 0x00 */ -+ u32 tx_mode; /* 0x04 */ -+ u32 tx_flow; /* 0x08 */ -+ u32 tx_ctl0; /* 0x0c */ -+ u32 tx_ctl1; /* 0x10 */ -+ u32 tx_ins; /* 0x14 */ -+ u32 tx_pl0; /* 0x18 */ -+ u32 tx_pl1; /* 0x1c */ -+ u32 tx_sta; /* 0x20 */ -+ u32 tx_io_data; /* 0x24 */ -+ u32 tx_io_data1;/* 0x28 */ -+ u32 tx_tsvl0; /* 0x2c */ -+ u32 tx_tsvh0; /* 0x30 */ -+ u32 tx_tsvl1; /* 0x34 */ -+ u32 tx_tsvh1; /* 0x38 */ -+ u32 rx_ctl; /* 0x3c */ -+ u32 rx_hash0; /* 0x40 */ -+ u32 rx_hash1; /* 0x44 */ -+ u32 rx_sta; /* 0x48 */ -+ u32 rx_io_data; /* 0x4c */ -+ u32 rx_fbc; /* 0x50 */ -+ u32 int_ctl; /* 0x54 */ -+ u32 int_sta; /* 0x58 */ -+ u32 mac_ctl0; /* 0x5c */ -+ u32 mac_ctl1; /* 0x60 */ -+ u32 mac_ipgt; /* 0x64 */ -+ u32 mac_ipgr; /* 0x68 */ -+ u32 mac_clrt; /* 0x6c */ -+ u32 mac_maxf; /* 0x70 */ -+ u32 mac_supp; /* 0x74 */ -+ u32 mac_test; /* 0x78 */ -+ u32 mac_mcfg; /* 0x7c */ -+ u32 mac_mcmd; /* 0x80 */ -+ u32 mac_madr; /* 0x84 */ -+ u32 mac_mwtd; /* 0x88 */ -+ u32 mac_mrdd; /* 0x8c */ -+ u32 mac_mind; /* 0x90 */ -+ u32 mac_ssrr; /* 0x94 */ -+ u32 mac_a0; /* 0x98 */ -+ u32 mac_a1; /* 0x9c */ -+}; -+ -+/* SRAMC register */ -+struct sunxi_sramc_regs { -+ u32 ctrl0; -+ u32 ctrl1; -+}; -+ -+/* 0: Disable 1: Aborted frame enable(default) */ -+#define EMAC_TX_AB_M (0x1 << 0) -+/* 0: CPU 1: DMA(default) */ -+#define EMAC_TX_TM (0x1 << 1) -+ -+#define EMAC_TX_SETUP (0) -+ -+/* 0: DRQ asserted 1: DRQ automatically(default) */ -+#define EMAC_RX_DRQ_MODE (0x1 << 1) -+/* 0: CPU 1: DMA(default) */ -+#define EMAC_RX_TM (0x1 << 2) -+/* 0: Normal(default) 1: Pass all Frames */ -+#define EMAC_RX_PA (0x1 << 4) -+/* 0: Normal(default) 1: Pass Control Frames */ -+#define EMAC_RX_PCF (0x1 << 5) -+/* 0: Normal(default) 1: Pass Frames with CRC Error */ -+#define EMAC_RX_PCRCE (0x1 << 6) -+/* 0: Normal(default) 1: Pass Frames with Length Error */ -+#define EMAC_RX_PLE (0x1 << 7) -+/* 0: Normal 1: Pass Frames length out of range(default) */ -+#define EMAC_RX_POR (0x1 << 8) -+/* 0: Not accept 1: Accept unicast Packets(default) */ -+#define EMAC_RX_UCAD (0x1 << 16) -+/* 0: Normal(default) 1: DA Filtering */ -+#define EMAC_RX_DAF (0x1 << 17) -+/* 0: Not accept 1: Accept multicast Packets(default) */ -+#define EMAC_RX_MCO (0x1 << 20) -+/* 0: Disable(default) 1: Enable Hash filter */ -+#define EMAC_RX_MHF (0x1 << 21) -+/* 0: Not accept 1: Accept Broadcast Packets(default) */ -+#define EMAC_RX_BCO (0x1 << 22) -+/* 0: Disable(default) 1: Enable SA Filtering */ -+#define EMAC_RX_SAF (0x1 << 24) -+/* 0: Normal(default) 1: Inverse Filtering */ -+#define EMAC_RX_SAIF (0x1 << 25) -+ -+#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ -+ EMAC_RX_MCO | EMAC_RX_BCO) -+ -+/* 0: Disable 1: Enable Receive Flow Control(default) */ -+#define EMAC_MAC_CTL0_RFC (0x1 << 2) -+/* 0: Disable 1: Enable Transmit Flow Control(default) */ -+#define EMAC_MAC_CTL0_TFC (0x1 << 3) -+ -+#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) -+ -+/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ -+#define EMAC_MAC_CTL1_FLC (0x1 << 1) -+/* 0: Disable(default) 1: Enable Huge Frame */ -+#define EMAC_MAC_CTL1_HF (0x1 << 2) -+/* 0: Disable(default) 1: Enable MAC Delayed CRC */ -+#define EMAC_MAC_CTL1_DCRC (0x1 << 3) -+/* 0: Disable 1: Enable MAC CRC(default) */ -+#define EMAC_MAC_CTL1_CRC (0x1 << 4) -+/* 0: Disable 1: Enable MAC PAD Short frames(default) */ -+#define EMAC_MAC_CTL1_PC (0x1 << 5) -+/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ -+#define EMAC_MAC_CTL1_VC (0x1 << 6) -+/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ -+#define EMAC_MAC_CTL1_ADP (0x1 << 7) -+/* 0: Disable(default) 1: Enable */ -+#define EMAC_MAC_CTL1_PRE (0x1 << 8) -+/* 0: Disable(default) 1: Enable */ -+#define EMAC_MAC_CTL1_LPE (0x1 << 9) -+/* 0: Disable(default) 1: Enable no back off */ -+#define EMAC_MAC_CTL1_NB (0x1 << 12) -+/* 0: Disable(default) 1: Enable */ -+#define EMAC_MAC_CTL1_BNB (0x1 << 13) -+/* 0: Disable(default) 1: Enable */ -+#define EMAC_MAC_CTL1_ED (0x1 << 14) -+ -+#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ -+ EMAC_MAC_CTL1_PC) -+ -+#define EMAC_MAC_IPGT 0x15 -+ -+#define EMAC_MAC_NBTB_IPG1 0xc -+#define EMAC_MAC_NBTB_IPG2 0x12 -+ -+#define EMAC_MAC_CW 0x37 -+#define EMAC_MAC_RM 0xf -+ -+#define EMAC_MAC_MFL 0x0600 -+ -+/* Receive status */ -+#define EMAC_CRCERR (0x1 << 4) -+#define EMAC_LENERR (0x3 << 5) -+ -+#define DMA_CPU_TRRESHOLD 2000 -+ -+struct emac_eth_dev { -+ u32 speed; -+ u32 duplex; -+ u32 phy_configured; -+ int link_printed; -+}; -+ -+struct emac_rxhdr { -+ s16 rx_len; -+ u16 rx_status; -+}; -+ -+static void emac_inblk_32bit(void *reg, void *data, int count) -+{ -+ int cnt = (count + 3) >> 2; -+ -+ if (cnt) { -+ u32 *buf = data; -+ -+ do { -+ u32 x = readl(reg); -+ *buf++ = x; -+ } while (--cnt); -+ } -+} -+ -+static void emac_outblk_32bit(void *reg, void *data, int count) -+{ -+ int cnt = (count + 3) >> 2; -+ -+ if (cnt) { -+ const u32 *buf = data; -+ -+ do { -+ writel(*buf++, reg); -+ } while (--cnt); -+ } -+} -+ -+/* Read a word from phyxcer */ -+static int emac_phy_read(const char *devname, unsigned char addr, -+ unsigned char reg, unsigned short *value) -+{ -+ struct eth_device *dev = eth_get_dev_by_name(devname); -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ -+ /* issue the phy address and reg */ -+ writel(addr << 8 | reg, ®s->mac_madr); -+ -+ /* pull up the phy io line */ -+ writel(0x1, ®s->mac_mcmd); -+ -+ /* Wait read complete */ -+ mdelay(1); -+ -+ /* push down the phy io line */ -+ writel(0x0, ®s->mac_mcmd); -+ -+ /* and write data */ -+ *value = readl(®s->mac_mrdd); -+ -+ return 0; -+} -+ -+/* Write a word to phyxcer */ -+static int emac_phy_write(const char *devname, unsigned char addr, -+ unsigned char reg, unsigned short value) -+{ -+ struct eth_device *dev = eth_get_dev_by_name(devname); -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ -+ /* issue the phy address and reg */ -+ writel(addr << 8 | reg, ®s->mac_madr); -+ -+ /* pull up the phy io line */ -+ writel(0x1, ®s->mac_mcmd); -+ -+ /* Wait write complete */ -+ mdelay(1); -+ -+ /* push down the phy io line */ -+ writel(0x0, ®s->mac_mcmd); -+ -+ /* and write data */ -+ writel(value, ®s->mac_mwtd); -+ -+ return 0; -+} -+ -+static void emac_setup(struct eth_device *dev) -+{ -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ u32 reg_val; -+ u16 phy_val; -+ u32 duplex_flag; -+ -+ /* Set up TX */ -+ writel(EMAC_TX_SETUP, ®s->tx_mode); -+ -+ /* Set up RX */ -+ writel(EMAC_RX_SETUP, ®s->rx_ctl); -+ -+ /* Set MAC */ -+ /* Set MAC CTL0 */ -+ writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); -+ -+ /* Set MAC CTL1 */ -+ emac_phy_read(dev->name, 1, 0, &phy_val); -+ debug("PHY SETUP, reg 0 value: %x\n", phy_val); -+ duplex_flag = !!(phy_val & (1 << 8)); -+ -+ reg_val = 0; -+ if (duplex_flag) -+ reg_val = (0x1 << 0); -+ writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); -+ -+ /* Set up IPGT */ -+ writel(EMAC_MAC_IPGT, ®s->mac_ipgt); -+ -+ /* Set up IPGR */ -+ writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); -+ -+ /* Set up Collison window */ -+ writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); -+ -+ /* Set up Max Frame Length */ -+ writel(EMAC_MAC_MFL, ®s->mac_maxf); -+} -+ -+static void emac_reset(struct eth_device *dev) -+{ -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ -+ debug("resetting device\n"); -+ -+ /* RESET device */ -+ writel(0, ®s->ctl); -+ udelay(200); -+ -+ writel(1, ®s->ctl); -+ udelay(200); -+} -+ -+static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) -+{ -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ struct emac_eth_dev *priv = dev->priv; -+ u16 phy_reg; -+ -+ /* Init EMAC */ -+ -+ /* Flush RX FIFO */ -+ setbits_le32(®s->rx_ctl, 0x8); -+ udelay(1); -+ -+ /* Init MAC */ -+ -+ /* Soft reset MAC */ -+ clrbits_le32(®s->mac_ctl0, 0x1 << 15); -+ -+ /* Clear RX counter */ -+ writel(0x0, ®s->rx_fbc); -+ udelay(1); -+ -+ /* Set up EMAC */ -+ emac_setup(dev); -+ -+ writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | -+ dev->enetaddr[2], ®s->mac_a1); -+ writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | -+ dev->enetaddr[5], ®s->mac_a0); -+ -+ mdelay(1); -+ -+ emac_reset(dev); -+ -+ /* PHY POWER UP */ -+ emac_phy_read(dev->name, 1, 0, &phy_reg); -+ emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); -+ mdelay(1); -+ -+ emac_phy_read(dev->name, 1, 0, &phy_reg); -+ -+ priv->speed = miiphy_speed(dev->name, 0); -+ priv->duplex = miiphy_duplex(dev->name, 0); -+ -+ /* Print link status only once */ -+ if (!priv->link_printed) { -+ printf("ENET Speed is %d Mbps - %s duplex connection\n", -+ priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); -+ priv->link_printed = 1; -+ } -+ -+ /* Set EMAC SPEED depend on PHY */ -+ clrsetbits_le32(®s->mac_supp, 1 << 8, -+ ((phy_reg & (0x1 << 13)) >> 13) << 8); -+ -+ /* Set duplex depend on phy */ -+ clrsetbits_le32(®s->mac_ctl1, 1 << 0, -+ ((phy_reg & (0x1 << 8)) >> 8) << 0); -+ -+ /* Enable RX/TX */ -+ setbits_le32(®s->ctl, 0x7); -+ -+ return 0; -+} -+ -+static void sunxi_emac_eth_halt(struct eth_device *dev) -+{ -+ /* Nothing to do here */ -+} -+ -+static int sunxi_emac_eth_recv(struct eth_device *dev) -+{ -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ struct emac_rxhdr rxhdr; -+ u32 rxcount; -+ u32 reg_val; -+ int rx_len; -+ int rx_status; -+ int good_packet; -+ -+ /* Check packet ready or not */ -+ -+ /* Race warning: The first packet might arrive with -+ * the interrupts disabled, but the second will fix -+ */ -+ rxcount = readl(®s->rx_fbc); -+ if (!rxcount) { -+ /* Had one stuck? */ -+ rxcount = readl(®s->rx_fbc); -+ if (!rxcount) -+ return 0; -+ } -+ -+ reg_val = readl(®s->rx_io_data); -+ if (reg_val != 0x0143414d) { -+ /* Disable RX */ -+ clrbits_le32(®s->ctl, 0x1 << 2); -+ -+ /* Flush RX FIFO */ -+ setbits_le32(®s->rx_ctl, 0x1 << 3); -+ while (readl(®s->rx_ctl) & (0x1 << 3)) -+ ; -+ -+ /* Enable RX */ -+ setbits_le32(®s->ctl, 0x1 << 2); -+ -+ return 0; -+ } -+ -+ /* A packet ready now -+ * Get status/length -+ */ -+ good_packet = 1; -+ -+ emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); -+ -+ rx_len = rxhdr.rx_len; -+ rx_status = rxhdr.rx_status; -+ -+ /* Packet Status check */ -+ if (rx_len < 0x40) { -+ good_packet = 0; -+ debug("RX: Bad Packet (runt)\n"); -+ } -+ -+ /* rx_status is identical to RSR register. */ -+ if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { -+ good_packet = 0; -+ if (rx_status & EMAC_CRCERR) -+ printf("crc error\n"); -+ if (rx_status & EMAC_LENERR) -+ printf("length error\n"); -+ } -+ -+ /* Move data from EMAC */ -+ if (good_packet) { -+ if (rx_len > DMA_CPU_TRRESHOLD) { -+ printf("Received packet is too big (len=%d)\n", rx_len); -+ } else { -+ emac_inblk_32bit((void *)®s->rx_io_data, -+ NetRxPackets[0], rx_len); -+ -+ /* Pass to upper layer */ -+ NetReceive(NetRxPackets[0], rx_len); -+ return rx_len; -+ } -+ } -+ -+ return 0; -+} -+ -+static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) -+{ -+ struct emac_regs *regs = (struct emac_regs *)dev->iobase; -+ -+ /* Select channel 0 */ -+ writel(0, ®s->tx_ins); -+ -+ /* Write packet */ -+ emac_outblk_32bit((void *)®s->tx_io_data, packet, len); -+ -+ /* Set TX len */ -+ writel(len, ®s->tx_pl0); -+ -+ /* Start translate from fifo to phy */ -+ setbits_le32(®s->tx_ctl0, 1); -+ -+ return 0; -+} -+ -+int sunxi_emac_initialize(void) -+{ -+ struct sunxi_ccm_reg *const ccm = -+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -+ struct sunxi_sramc_regs *sram = -+ (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; -+ struct emac_regs *regs = -+ (struct emac_regs *)SUNXI_EMAC_BASE; -+ struct eth_device *dev; -+ struct emac_eth_dev *priv; -+ int pin; -+ -+ dev = malloc(sizeof(*dev)); -+ if (dev == NULL) -+ return -ENOMEM; -+ -+ priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); -+ if (!priv) { -+ free(dev); -+ return -ENOMEM; -+ } -+ -+ memset(dev, 0, sizeof(*dev)); -+ memset(priv, 0, sizeof(struct emac_eth_dev)); -+ -+ /* Map SRAM to EMAC */ -+ setbits_le32(&sram->ctrl1, 0x5 << 2); -+ -+ /* Configure pin mux settings for MII Ethernet */ -+ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) -+ sunxi_gpio_set_cfgpin(pin, 2); -+ -+ /* Set up clock gating */ -+ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); -+ -+ /* Set MII clock */ -+ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); -+ -+ dev->iobase = (int)regs; -+ dev->priv = priv; -+ dev->init = sunxi_emac_eth_init; -+ dev->halt = sunxi_emac_eth_halt; -+ dev->send = sunxi_emac_eth_send; -+ dev->recv = sunxi_emac_eth_recv; -+ strcpy(dev->name, "emac"); -+ -+ eth_register(dev); -+ -+ miiphy_register(dev->name, emac_phy_read, emac_phy_write); -+ -+ return 0; -+} -diff -ruN u-boot-2014.01-rc1/drivers/net/sunxi_gmac.c u-boot-sunxi/drivers/net/sunxi_gmac.c ---- u-boot-2014.01-rc1/drivers/net/sunxi_gmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/net/sunxi_gmac.c 2014-03-05 23:14:48.056088119 +0100 -@@ -0,0 +1,45 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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, 5); -+ sunxi_gpio_set_drv(pin, 3); -+ } -+ -+#ifdef CONFIG_RGMII -+ designware_initialize(0, SUNXI_GMAC_BASE, 0x1, PHY_INTERFACE_MODE_RGMII); -+#else -+ designware_initialize(0, SUNXI_GMAC_BASE, 0x1, PHY_INTERFACE_MODE_MII); -+#endif -+ -+ return 0; -+} -diff -ruN u-boot-2014.01-rc1/drivers/net/sunxi_wemac.c u-boot-sunxi/drivers/net/sunxi_wemac.c ---- u-boot-2014.01-rc1/drivers/net/sunxi_wemac.c 2013-11-25 22:49:32.000000000 +0100 -+++ 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 -- * -- * SPDX-License-Identifier: GPL-2.0+ -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --/* EMAC register */ --struct wemac_regs { -- u32 ctl; /* 0x00 */ -- u32 tx_mode; /* 0x04 */ -- u32 tx_flow; /* 0x08 */ -- u32 tx_ctl0; /* 0x0c */ -- u32 tx_ctl1; /* 0x10 */ -- u32 tx_ins; /* 0x14 */ -- u32 tx_pl0; /* 0x18 */ -- u32 tx_pl1; /* 0x1c */ -- u32 tx_sta; /* 0x20 */ -- u32 tx_io_data; /* 0x24 */ -- u32 tx_io_data1; /* 0x28 */ -- u32 tx_tsvl0; /* 0x2c */ -- u32 tx_tsvh0; /* 0x30 */ -- u32 tx_tsvl1; /* 0x34 */ -- u32 tx_tsvh1; /* 0x38 */ -- u32 rx_ctl; /* 0x3c */ -- u32 rx_hash0; /* 0x40 */ -- u32 rx_hash1; /* 0x44 */ -- u32 rx_sta; /* 0x48 */ -- u32 rx_io_data; /* 0x4c */ -- u32 rx_fbc; /* 0x50 */ -- u32 int_ctl; /* 0x54 */ -- u32 int_sta; /* 0x58 */ -- u32 mac_ctl0; /* 0x5c */ -- u32 mac_ctl1; /* 0x60 */ -- u32 mac_ipgt; /* 0x64 */ -- u32 mac_ipgr; /* 0x68 */ -- u32 mac_clrt; /* 0x6c */ -- u32 mac_maxf; /* 0x70 */ -- u32 mac_supp; /* 0x74 */ -- u32 mac_test; /* 0x78 */ -- u32 mac_mcfg; /* 0x7c */ -- u32 mac_mcmd; /* 0x80 */ -- u32 mac_madr; /* 0x84 */ -- u32 mac_mwtd; /* 0x88 */ -- u32 mac_mrdd; /* 0x8c */ -- u32 mac_mind; /* 0x90 */ -- u32 mac_ssrr; /* 0x94 */ -- u32 mac_a0; /* 0x98 */ -- u32 mac_a1; /* 0x9c */ --}; -- --/* SRAMC register */ --struct sunxi_sramc_regs { -- u32 ctrl0; -- u32 ctrl1; --}; -- --/* 0: Disable 1: Aborted frame enable(default) */ --#define EMAC_TX_AB_M (0x1 << 0) --/* 0: CPU 1: DMA(default) */ --#define EMAC_TX_TM (0x1 << 1) -- --#define EMAC_TX_SETUP (0) -- --/* 0: DRQ asserted 1: DRQ automatically(default) */ --#define EMAC_RX_DRQ_MODE (0x1 << 1) --/* 0: CPU 1: DMA(default) */ --#define EMAC_RX_TM (0x1 << 2) --/* 0: Normal(default) 1: Pass all Frames */ --#define EMAC_RX_PA (0x1 << 4) --/* 0: Normal(default) 1: Pass Control Frames */ --#define EMAC_RX_PCF (0x1 << 5) --/* 0: Normal(default) 1: Pass Frames with CRC Error */ --#define EMAC_RX_PCRCE (0x1 << 6) --/* 0: Normal(default) 1: Pass Frames with Length Error */ --#define EMAC_RX_PLE (0x1 << 7) --/* 0: Normal 1: Pass Frames length out of range(default) */ --#define EMAC_RX_POR (0x1 << 8) --/* 0: Not accept 1: Accept unicast Packets(default) */ --#define EMAC_RX_UCAD (0x1 << 16) --/* 0: Normal(default) 1: DA Filtering */ --#define EMAC_RX_DAF (0x1 << 17) --/* 0: Not accept 1: Accept multicast Packets(default) */ --#define EMAC_RX_MCO (0x1 << 20) --/* 0: Disable(default) 1: Enable Hash filter */ --#define EMAC_RX_MHF (0x1 << 21) --/* 0: Not accept 1: Accept Broadcast Packets(default) */ --#define EMAC_RX_BCO (0x1 << 22) --/* 0: Disable(default) 1: Enable SA Filtering */ --#define EMAC_RX_SAF (0x1 << 24) --/* 0: Normal(default) 1: Inverse Filtering */ --#define EMAC_RX_SAIF (0x1 << 25) -- --#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ -- EMAC_RX_MCO | EMAC_RX_BCO) -- --/* 0: Disable 1: Enable Receive Flow Control(default) */ --#define EMAC_MAC_CTL0_RFC (0x1 << 2) --/* 0: Disable 1: Enable Transmit Flow Control(default) */ --#define EMAC_MAC_CTL0_TFC (0x1 << 3) -- --#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) -- --/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ --#define EMAC_MAC_CTL1_FLC (0x1 << 1) --/* 0: Disable(default) 1: Enable Huge Frame */ --#define EMAC_MAC_CTL1_HF (0x1 << 2) --/* 0: Disable(default) 1: Enable MAC Delayed CRC */ --#define EMAC_MAC_CTL1_DCRC (0x1 << 3) --/* 0: Disable 1: Enable MAC CRC(default) */ --#define EMAC_MAC_CTL1_CRC (0x1 << 4) --/* 0: Disable 1: Enable MAC PAD Short frames(default) */ --#define EMAC_MAC_CTL1_PC (0x1 << 5) --/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ --#define EMAC_MAC_CTL1_VC (0x1 << 6) --/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ --#define EMAC_MAC_CTL1_ADP (0x1 << 7) --/* 0: Disable(default) 1: Enable */ --#define EMAC_MAC_CTL1_PRE (0x1 << 8) --/* 0: Disable(default) 1: Enable */ --#define EMAC_MAC_CTL1_LPE (0x1 << 9) --/* 0: Disable(default) 1: Enable no back off */ --#define EMAC_MAC_CTL1_NB (0x1 << 12) --/* 0: Disable(default) 1: Enable */ --#define EMAC_MAC_CTL1_BNB (0x1 << 13) --/* 0: Disable(default) 1: Enable */ --#define EMAC_MAC_CTL1_ED (0x1 << 14) -- --#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ -- EMAC_MAC_CTL1_PC) -- --#define EMAC_MAC_IPGT 0x15 -- --#define EMAC_MAC_NBTB_IPG1 0xC --#define EMAC_MAC_NBTB_IPG2 0x12 -- --#define EMAC_MAC_CW 0x37 --#define EMAC_MAC_RM 0xF -- --#define EMAC_MAC_MFL 0x0600 -- --/* Receive status */ --#define EMAC_CRCERR (1 << 4) --#define EMAC_LENERR (3 << 5) -- --#define DMA_CPU_TRRESHOLD 2000 -- --struct wemac_eth_dev { -- u32 speed; -- u32 duplex; -- u32 phy_configured; -- int link_printed; --}; -- --struct wemac_rxhdr { -- s16 rx_len; -- u16 rx_status; --}; -- --static void wemac_inblk_32bit(void *reg, void *data, int count) --{ -- int cnt = (count + 3) >> 2; -- -- if (cnt) { -- u32 *buf = data; -- -- do { -- u32 x = readl(reg); -- *buf++ = x; -- } while (--cnt); -- } --} -- --static void wemac_outblk_32bit(void *reg, void *data, int count) --{ -- int cnt = (count + 3) >> 2; -- -- if (cnt) { -- const u32 *buf = data; -- -- do { -- writel(*buf++, reg); -- } while (--cnt); -- } --} -- --/* -- * Read a word from phyxcer -- */ --static int wemac_phy_read(const char *devname, unsigned char addr, -- unsigned char reg, unsigned short *value) --{ -- struct eth_device *dev = eth_get_dev_by_name(devname); -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- -- /* issue the phy address and reg */ -- writel(addr << 8 | reg, ®s->mac_madr); -- -- /* pull up the phy io line */ -- writel(0x1, ®s->mac_mcmd); -- -- /* Wait read complete */ -- mdelay(1); -- -- /* push down the phy io line */ -- writel(0x0, ®s->mac_mcmd); -- -- /* and write data */ -- *value = readl(®s->mac_mrdd); -- -- return 0; --} -- --/* -- * Write a word to phyxcer -- */ --static int wemac_phy_write(const char *devname, unsigned char addr, -- unsigned char reg, unsigned short value) --{ -- struct eth_device *dev = eth_get_dev_by_name(devname); -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- -- /* issue the phy address and reg */ -- writel(addr << 8 | reg, ®s->mac_madr); -- -- /* pull up the phy io line */ -- writel(0x1, ®s->mac_mcmd); -- -- /* Wait write complete */ -- mdelay(1); -- -- /* push down the phy io line */ -- writel(0x0, ®s->mac_mcmd); -- -- /* and write data */ -- writel(value, ®s->mac_mwtd); -- -- return 0; --} -- --static void emac_setup(struct eth_device *dev) --{ -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- u32 reg_val; -- u16 phy_val; -- u32 duplex_flag; -- -- /* Set up TX */ -- writel(EMAC_TX_SETUP, ®s->tx_mode); -- -- /* Set up RX */ -- writel(EMAC_RX_SETUP, ®s->rx_ctl); -- -- /* Set MAC */ -- /* Set MAC CTL0 */ -- writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); -- -- /* Set MAC CTL1 */ -- wemac_phy_read(dev->name, 1, 0, &phy_val); -- debug("PHY SETUP, reg 0 value: %x\n", phy_val); -- duplex_flag = !!(phy_val & (1 << 8)); -- -- reg_val = 0; -- if (duplex_flag) -- reg_val = (0x1 << 0); -- writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); -- -- /* Set up IPGT */ -- writel(EMAC_MAC_IPGT, ®s->mac_ipgt); -- -- /* Set up IPGR */ -- writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); -- -- /* Set up Collison window */ -- writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); -- -- /* Set up Max Frame Length */ -- writel(EMAC_MAC_MFL, ®s->mac_maxf); --} -- --static void wemac_reset(struct eth_device *dev) --{ -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- -- debug("resetting device\n"); -- -- /* RESET device */ -- writel(0, ®s->ctl); -- udelay(200); -- -- writel(1, ®s->ctl); -- udelay(200); --} -- --static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) --{ -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- struct wemac_eth_dev *priv = dev->priv; -- u16 phy_reg; -- -- /* Init EMAC */ -- -- /* Flush RX FIFO */ -- setbits_le32(®s->rx_ctl, 0x8); -- udelay(1); -- -- /* Init MAC */ -- -- /* Soft reset MAC */ -- clrbits_le32(®s->mac_ctl0, 1 << 15); -- -- /* Set MII clock */ -- clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); -- -- /* Clear RX counter */ -- writel(0x0, ®s->rx_fbc); -- udelay(1); -- -- /* Set up EMAC */ -- emac_setup(dev); -- -- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | -- dev->enetaddr[2], ®s->mac_a1); -- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | -- dev->enetaddr[5], ®s->mac_a0); -- -- mdelay(1); -- -- wemac_reset(dev); -- -- /* PHY POWER UP */ -- wemac_phy_read(dev->name, 1, 0, &phy_reg); -- wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); -- mdelay(1); -- -- wemac_phy_read(dev->name, 1, 0, &phy_reg); -- -- priv->speed = miiphy_speed(dev->name, 0); -- priv->duplex = miiphy_duplex(dev->name, 0); -- -- /* Print link status only once */ -- if (!priv->link_printed) { -- printf("ENET Speed is %d Mbps - %s duplex connection\n", -- priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); -- priv->link_printed = 1; -- } -- -- /* Set EMAC SPEED depend on PHY */ -- clrsetbits_le32(®s->mac_supp, 1 << 8, -- ((phy_reg & (1 << 13)) >> 13) << 8); -- -- /* Set duplex depend on phy */ -- clrsetbits_le32(®s->mac_ctl1, 1 << 0, -- ((phy_reg & (1 << 8)) >> 8) << 0); -- -- /* Enable RX/TX */ -- setbits_le32(®s->ctl, 0x7); -- -- return 0; --} -- --static void sunxi_wemac_eth_halt(struct eth_device *dev) --{ -- /* Nothing to do here */ --} -- --static int sunxi_wemac_eth_recv(struct eth_device *dev) --{ -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- struct wemac_rxhdr rxhdr; -- u32 rxcount; -- u32 reg_val; -- int rx_len; -- int rx_status; -- int good_packet; -- -- /* Check packet ready or not */ -- -- /* -- * Race warning: The first packet might arrive with -- * the interrupts disabled, but the second will fix -- */ -- rxcount = readl(®s->rx_fbc); -- if (!rxcount) { -- /* Had one stuck? */ -- rxcount = readl(®s->rx_fbc); -- if (!rxcount) -- return 0; -- } -- -- reg_val = readl(®s->rx_io_data); -- if (reg_val != 0x0143414d) { -- /* Disable RX */ -- clrbits_le32(®s->ctl, 1 << 2); -- -- /* Flush RX FIFO */ -- setbits_le32(®s->rx_ctl, 1 << 3); -- while (readl(®s->rx_ctl) & (1 << 3)) -- ; -- -- /* Enable RX */ -- setbits_le32(®s->ctl, 1 << 2); -- -- return 0; -- } -- -- /* -- * A packet ready now -- * Get status/length -- */ -- good_packet = 1; -- -- wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); -- -- rx_len = rxhdr.rx_len; -- rx_status = rxhdr.rx_status; -- -- /* Packet Status check */ -- if (rx_len < 0x40) { -- good_packet = 0; -- debug("RX: Bad Packet (runt)\n"); -- } -- -- /* rx_status is identical to RSR register. */ -- if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { -- good_packet = 0; -- if (rx_status & EMAC_CRCERR) -- printf("crc error\n"); -- if (rx_status & EMAC_LENERR) -- printf("length error\n"); -- } -- -- /* Move data from WEMAC */ -- if (good_packet) { -- if (rx_len > DMA_CPU_TRRESHOLD) { -- printf("Received packet is too big (len=%d)\n", rx_len); -- } else { -- wemac_inblk_32bit((void *)®s->rx_io_data, -- NetRxPackets[0], rx_len); -- -- /* Pass to upper layer */ -- NetReceive(NetRxPackets[0], rx_len); -- return rx_len; -- } -- } -- -- return 0; --} -- --static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) --{ -- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; -- -- /* Select channel 0 */ -- writel(0, ®s->tx_ins); -- -- /* Write packet */ -- wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); -- -- /* Set TX len */ -- writel(len, ®s->tx_pl0); -- -- /* Start translate from fifo to phy */ -- setbits_le32(®s->tx_ctl0, 1); -- -- return 0; --} -- --int sunxi_wemac_initialize(void) --{ -- struct sunxi_ccm_reg *const ccm = -- (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -- struct sunxi_sramc_regs *sram = -- (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; -- struct eth_device *dev; -- struct wemac_eth_dev *priv; -- int pin; -- -- dev = malloc(sizeof(*dev)); -- if (dev == NULL) -- return -ENOMEM; -- -- priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); -- if (!priv) { -- free(dev); -- return -ENOMEM; -- } -- -- memset(dev, 0, sizeof(*dev)); -- memset(priv, 0, sizeof(struct wemac_eth_dev)); -- -- /* Map SRAM to EMAC */ -- setbits_le32(&sram->ctrl1, 0x5 << 2); -- -- /* Configure pin mux settings for MII Ethernet */ -- for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) -- sunxi_gpio_set_cfgpin(pin, 2); -- -- /* Set up clock gating */ -- setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); -- -- dev->iobase = SUNXI_EMAC_BASE; -- dev->priv = priv; -- dev->init = sunxi_wemac_eth_init; -- dev->halt = sunxi_wemac_eth_halt; -- dev->send = sunxi_wemac_eth_send; -- dev->recv = sunxi_wemac_eth_recv; -- strcpy(dev->name, "wemac"); -- -- eth_register(dev); -- -- miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); -- -- return 0; --} -diff -ruN u-boot-2014.01-rc1/drivers/power/axp152.c u-boot-sunxi/drivers/power/axp152.c ---- u-boot-2014.01-rc1/drivers/power/axp152.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/power/axp152.c 2014-03-05 23:14:48.060088066 +0100 -@@ -0,0 +1,138 @@ -+/* -+ * (C) Copyright 2012 -+ * Henrik Nordstrom -+ * -+ * 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 -+ */ -+#include -+#include -+#include -+ -+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, -+}; -+ -+int axp152_write(enum axp152_reg reg, u8 val) -+{ -+ return i2c_write(0x30, reg, 1, &val, 1); -+} -+ -+int axp152_read(enum axp152_reg reg, u8 *val) -+{ -+ return i2c_read(0x30, reg, 1, val, 1); -+} -+ -+int axp152_set_dcdc2(int mvolt) -+{ -+ int target = (mvolt - 700) / 25; -+ int rc; -+ u8 current; -+ -+ if (target < 0) -+ target = 0; -+ if (target > (1<<6)-1) -+ target = (1<<6)-1; -+ /* Do we really need to be this gentle? It has built-in voltage slope */ -+ while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && -+ current != target) { -+ if (current < target) -+ current++; -+ else -+ current--; -+ rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); -+ if (rc) -+ break; -+ } -+ return rc; -+} -+ -+int axp152_set_dcdc3(int mvolt) -+{ -+ int target = (mvolt - 700) / 50; -+ u8 reg; -+ int rc; -+ -+ if (target < 0) -+ target = 0; -+ if (target > (1<<6)-1) -+ target = (1<<6)-1; -+ rc = axp152_write(AXP152_DCDC3_VOLTAGE, target); -+ rc |= axp152_read(AXP152_DCDC3_VOLTAGE, ®); -+ return rc; -+} -+ -+int axp152_set_dcdc4(int mvolt) -+{ -+ int target = (mvolt - 700) / 25; -+ u8 reg; -+ int rc; -+ -+ if (target < 0) -+ target = 0; -+ if (target > (1<<7)-1) -+ target = (1<<7)-1; -+ rc = axp152_write(AXP152_DCDC4_VOLTAGE, target); -+ rc |= axp152_read(AXP152_DCDC4_VOLTAGE, ®); -+ return rc; -+} -+ -+int axp152_set_ldo2(int mvolt) -+{ -+ int target = (mvolt - 700) / 100; -+ int rc; -+ u8 reg; -+ -+ if (target < 0) -+ target = 0; -+ if (target > 31) -+ target = 31; -+ rc = axp152_write(AXP152_LDO2_VOLTAGE, target); -+ rc |= axp152_read(AXP152_LDO2_VOLTAGE, ®); -+ return rc; -+} -+ -+void axp152_poweroff(void) -+{ -+ u8 val; -+ -+ if (axp152_read(AXP152_SHUTDOWN, &val) != 0) -+ return; -+ val |= 1 << 7; -+ 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.01-rc1/drivers/power/axp209.c u-boot-sunxi/drivers/power/axp209.c ---- u-boot-2014.01-rc1/drivers/power/axp209.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/drivers/power/axp209.c 2014-03-05 23:14:48.060088066 +0100 -@@ -0,0 +1,215 @@ -+/* -+ * (C) Copyright 2012 -+ * Henrik Nordstrom -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+ -+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_STATUS3 = 0x4a, -+ AXP209_IRQ_STATUS5 = 0x4c, -+ AXP209_SHUTDOWN = 0x32, -+}; -+ -+#define AXP209_POWER_STATUS_ON_BY_DC (1<<0) -+ -+#define AXP209_IRQ3_PEK_SHORT (1<<1) -+#define AXP209_IRQ3_PEK_LONG (1<<0) -+ -+#define AXP209_IRQ5_PEK_UP (1<<6) -+#define AXP209_IRQ5_PEK_DOWN (1<<5) -+ -+int axp209_write(enum axp209_reg reg, u8 val) -+{ -+ return i2c_write(0x34, reg, 1, &val, 1); -+} -+ -+int axp209_read(enum axp209_reg reg, u8 *val) -+{ -+ return i2c_read(0x34, reg, 1, val, 1); -+} -+ -+int axp209_set_dcdc2(int mvolt) -+{ -+ int cfg = (mvolt - 700) / 25; -+ int rc; -+ u8 current; -+ -+ if (cfg < 0) -+ cfg = 0; -+ if (cfg > (1 << 6) - 1) -+ cfg = (1 << 6) - 1; -+ -+ /* Do we really need to be this gentle? It has built-in voltage slope */ -+ while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 && -+ current != cfg) { -+ if (current < cfg) -+ current++; -+ else -+ current--; -+ -+ rc = axp209_write(AXP209_DCDC2_VOLTAGE, current); -+ if (rc) -+ break; -+ } -+ -+ return rc; -+} -+ -+int axp209_set_dcdc3(int mvolt) -+{ -+ int cfg = (mvolt - 700) / 25; -+ u8 reg; -+ int rc; -+ -+ if (cfg < 0) -+ cfg = 0; -+ if (cfg > (1 << 7) - 1) -+ cfg = (1 << 7) - 1; -+ -+ rc = axp209_write(AXP209_DCDC3_VOLTAGE, cfg); -+ rc |= axp209_read(AXP209_DCDC3_VOLTAGE, ®); -+ -+ return rc; -+} -+ -+int axp209_set_ldo2(int mvolt) -+{ -+ int cfg = (mvolt - 1800) / 100; -+ int rc; -+ u8 reg; -+ -+ if (cfg < 0) -+ cfg = 0; -+ if (cfg > 15) -+ cfg = 15; -+ -+ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); -+ if (rc) -+ return rc; -+ -+ reg = (reg & 0x0f) | (cfg << 4); -+ rc = axp209_write(AXP209_LDO24_VOLTAGE, reg); -+ if (rc) -+ return rc; -+ -+ return 0; -+} -+ -+int axp209_set_ldo3(int mvolt) -+{ -+ int cfg = (mvolt - 700) / 25; -+ -+ if (cfg < 0) -+ cfg = 0; -+ if (cfg > 127) -+ cfg = 127; -+ if (mvolt == -1) -+ cfg = 0x80; /* detemined by LDO3IN pin */ -+ -+ return axp209_write(AXP209_LDO3_VOLTAGE, cfg); -+} -+ -+int axp209_set_ldo4(int mvolt) -+{ -+ int cfg = (mvolt - 1800) / 100; -+ int 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 = 0; mvolt < vindex[cfg] && cfg < 15; cfg++); -+ -+ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); -+ if (rc) -+ return rc; -+ -+ /* LDO4 configuration is in lower 4 bits */ -+ reg = (reg & 0xf0) | (cfg << 0); -+ rc = axp209_write(AXP209_LDO24_VOLTAGE, reg); -+ if (rc) -+ return rc; -+ -+ return 0; -+} -+ -+void axp209_poweroff(void) -+{ -+ u8 val; -+ -+ if (axp209_read(AXP209_SHUTDOWN, &val) != 0) -+ return; -+ -+ val |= 1 << 7; -+ -+ 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.01-rc1/drivers/power/Makefile u-boot-sunxi/drivers/power/Makefile ---- u-boot-2014.01-rc1/drivers/power/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/power/Makefile 2014-03-05 23:14:48.060088066 +0100 -@@ -5,6 +5,8 @@ - # SPDX-License-Identifier: GPL-2.0+ - # - -+obj-$(CONFIG_AXP152_POWER) += axp152.o -+obj-$(CONFIG_AXP209_POWER) += axp209.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.01-rc1/drivers/serial/arm_dcc.c u-boot-sunxi/drivers/serial/arm_dcc.c ---- u-boot-2014.01-rc1/drivers/serial/arm_dcc.c 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/drivers/serial/arm_dcc.c 2014-03-05 23:14:48.068087958 +0100 -@@ -29,7 +29,7 @@ - #include - #include - --#if defined(CONFIG_CPU_V6) -+#if defined(CONFIG_CPU_V6) || 1 - /* - * ARMV6 - */ -diff -ruN u-boot-2014.01-rc1/.git/config u-boot-sunxi/.git/config ---- u-boot-2014.01-rc1/.git/config 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/config 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1,11 @@ -+[core] -+ repositoryformatversion = 0 -+ filemode = true -+ bare = false -+ logallrefupdates = true -+[remote "origin"] -+ fetch = +refs/heads/*:refs/remotes/origin/* -+ url = https://bitbucket.org/zuperman/u-boot-sunxi.git -+[branch "sunxi-openwrt"] -+ remote = origin -+ merge = refs/heads/sunxi-openwrt -diff -ruN u-boot-2014.01-rc1/.git/description u-boot-sunxi/.git/description ---- u-boot-2014.01-rc1/.git/description 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/description 2014-03-05 23:14:20.056462031 +0100 -@@ -0,0 +1 @@ -+Unnamed repository; edit this file 'description' to name the repository. -diff -ruN u-boot-2014.01-rc1/.git/HEAD u-boot-sunxi/.git/HEAD ---- u-boot-2014.01-rc1/.git/HEAD 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/HEAD 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1 @@ -+ref: refs/heads/sunxi-openwrt -diff -ruN u-boot-2014.01-rc1/.git/hooks/applypatch-msg.sample u-boot-sunxi/.git/hooks/applypatch-msg.sample ---- u-boot-2014.01-rc1/.git/hooks/applypatch-msg.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/applypatch-msg.sample 2014-03-05 23:14:20.072461819 +0100 -@@ -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.01-rc1/.git/hooks/commit-msg.sample u-boot-sunxi/.git/hooks/commit-msg.sample ---- u-boot-2014.01-rc1/.git/hooks/commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/commit-msg.sample 2014-03-05 23:14:20.064461925 +0100 -@@ -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.01-rc1/.git/hooks/post-update.sample u-boot-sunxi/.git/hooks/post-update.sample ---- u-boot-2014.01-rc1/.git/hooks/post-update.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/post-update.sample 2014-03-05 23:14:20.076461764 +0100 -@@ -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.01-rc1/.git/hooks/pre-applypatch.sample u-boot-sunxi/.git/hooks/pre-applypatch.sample ---- u-boot-2014.01-rc1/.git/hooks/pre-applypatch.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/pre-applypatch.sample 2014-03-05 23:14:20.072461819 +0100 -@@ -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.01-rc1/.git/hooks/pre-commit.sample u-boot-sunxi/.git/hooks/pre-commit.sample ---- u-boot-2014.01-rc1/.git/hooks/pre-commit.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/pre-commit.sample 2014-03-05 23:14:20.076461764 +0100 -@@ -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.01-rc1/.git/hooks/prepare-commit-msg.sample u-boot-sunxi/.git/hooks/prepare-commit-msg.sample ---- u-boot-2014.01-rc1/.git/hooks/prepare-commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/prepare-commit-msg.sample 2014-03-05 23:14:20.076461764 +0100 -@@ -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.01-rc1/.git/hooks/pre-rebase.sample u-boot-sunxi/.git/hooks/pre-rebase.sample ---- u-boot-2014.01-rc1/.git/hooks/pre-rebase.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/pre-rebase.sample 2014-03-05 23:14:20.076461764 +0100 -@@ -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.01-rc1/.git/hooks/update.sample u-boot-sunxi/.git/hooks/update.sample ---- u-boot-2014.01-rc1/.git/hooks/update.sample 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/hooks/update.sample 2014-03-05 23:14:20.068461872 +0100 -@@ -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 )" >&2 -+ exit 1 -+fi -+ -+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then -+ echo "Usage: $0 " >&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.01-rc1/.git/index and u-boot-sunxi/.git/index differ -diff -ruN u-boot-2014.01-rc1/.git/info/exclude u-boot-sunxi/.git/info/exclude ---- u-boot-2014.01-rc1/.git/info/exclude 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/info/exclude 2014-03-05 23:14:20.064461925 +0100 -@@ -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.01-rc1/.git/logs/HEAD u-boot-sunxi/.git/logs/HEAD ---- u-boot-2014.01-rc1/.git/logs/HEAD 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/logs/HEAD 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1 @@ -+0000000000000000000000000000000000000000 d57e8f49a52e59486f49346975c826cf4c298d7e root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git -diff -ruN u-boot-2014.01-rc1/.git/logs/refs/heads/sunxi-openwrt u-boot-sunxi/.git/logs/refs/heads/sunxi-openwrt ---- u-boot-2014.01-rc1/.git/logs/refs/heads/sunxi-openwrt 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/logs/refs/heads/sunxi-openwrt 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1 @@ -+0000000000000000000000000000000000000000 d57e8f49a52e59486f49346975c826cf4c298d7e root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git -diff -ruN u-boot-2014.01-rc1/.git/logs/refs/remotes/origin/HEAD u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD ---- u-boot-2014.01-rc1/.git/logs/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1 @@ -+0000000000000000000000000000000000000000 a13f6664d65ce9bc68f05f8ecd10333ea9bcb012 root 1394057686 +0100 clone: from https://bitbucket.org/zuperman/u-boot-sunxi.git -Binary files u-boot-2014.01-rc1/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.idx and u-boot-sunxi/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.idx differ -Binary files u-boot-2014.01-rc1/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.pack and u-boot-sunxi/.git/objects/pack/pack-a93dd7b045423458e5011dfb898f9ee89cdb5828.pack differ -diff -ruN u-boot-2014.01-rc1/.git/packed-refs u-boot-sunxi/.git/packed-refs ---- u-boot-2014.01-rc1/.git/packed-refs 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/packed-refs 2014-03-05 23:14:46.760105425 +0100 -@@ -0,0 +1,6 @@ -+# pack-refs with: peeled -+b83a10f893c1b36b878a4dc992a68879f2d98153 refs/remotes/origin/sunxi-3.12 -+d57e8f49a52e59486f49346975c826cf4c298d7e refs/remotes/origin/sunxi-openwrt -+a13f6664d65ce9bc68f05f8ecd10333ea9bcb012 refs/remotes/origin/sunxi-test -+adc9e13225d092362dea4e83c03ee161859f3a94 refs/tags/sunxi-openwrt-1 -+^d57e8f49a52e59486f49346975c826cf4c298d7e -diff -ruN u-boot-2014.01-rc1/.git/refs/heads/sunxi-openwrt u-boot-sunxi/.git/refs/heads/sunxi-openwrt ---- u-boot-2014.01-rc1/.git/refs/heads/sunxi-openwrt 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/refs/heads/sunxi-openwrt 2014-03-05 23:14:46.924103235 +0100 -@@ -0,0 +1 @@ -+d57e8f49a52e59486f49346975c826cf4c298d7e -diff -ruN u-boot-2014.01-rc1/.git/refs/remotes/origin/HEAD u-boot-sunxi/.git/refs/remotes/origin/HEAD ---- u-boot-2014.01-rc1/.git/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/.git/refs/remotes/origin/HEAD 2014-03-05 23:14:46.852104197 +0100 -@@ -0,0 +1 @@ -+ref: refs/remotes/origin/sunxi-test -diff -ruN u-boot-2014.01-rc1/include/axp152.h u-boot-sunxi/include/axp152.h ---- u-boot-2014.01-rc1/include/axp152.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/axp152.h 2014-03-05 23:14:48.156086783 +0100 -@@ -0,0 +1,27 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * 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 -+ */ -+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.01-rc1/include/axp209.h u-boot-sunxi/include/axp209.h ---- u-boot-2014.01-rc1/include/axp209.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/axp209.h 2014-03-05 23:14:48.156086783 +0100 -@@ -0,0 +1,31 @@ -+/* -+ * (C) Copyright 2012 Henrik Nordstrom -+ * -+ * 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 -+ */ -+ -+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.01-rc1/include/common.h u-boot-sunxi/include/common.h ---- u-boot-2014.01-rc1/include/common.h 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/include/common.h 2014-03-05 23:14:48.160086731 +0100 -@@ -453,7 +453,7 @@ - void api_init (void); - - /* common/memsize.c */ --long get_ram_size (long *, long); -+unsigned long get_ram_size (unsigned long *, unsigned long); - - /* $(BOARD)/$(BOARD).c */ - void reset_phy (void); -diff -ruN u-boot-2014.01-rc1/include/config_fallbacks.h u-boot-sunxi/include/config_fallbacks.h ---- u-boot-2014.01-rc1/include/config_fallbacks.h 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/include/config_fallbacks.h 2014-03-05 23:14:48.160086731 +0100 -@@ -54,6 +54,10 @@ - #define HAVE_BLOCK_DEVICE - #endif - -+#ifndef CONFIG_SYS_BOARD_NAME -+#define CONFIG_SYS_BOARD_NAME CONFIG_SYS_TARGET -+#endif -+ - #ifndef CONFIG_SYS_PROMPT - #define CONFIG_SYS_PROMPT "=> " - #endif -diff -ruN u-boot-2014.01-rc1/include/configs/sun4i.h u-boot-sunxi/include/configs/sun4i.h ---- u-boot-2014.01-rc1/include/configs/sun4i.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/configs/sun4i.h 2014-03-05 23:14:48.236085715 +0100 -@@ -0,0 +1,41 @@ -+/* -+ * (C) Copyright 2012-2013 Henrik Nordstrom -+ * -+ * Configuration settings for the Allwinner A10 (sun4i) 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 -+ -+/* -+ * A10 specific configuration -+ */ -+#define CONFIG_SUN4I /* sun4i SoC generation */ -+ -+#define CONFIG_SYS_PROMPT "sun4i# " -+#define CONFIG_MACH_TYPE 4104 -+ -+/* -+ * Include common sunxi configuration where most the settings are -+ */ -+#include -+ -+#endif /* __CONFIG_H */ -diff -ruN u-boot-2014.01-rc1/include/configs/sun5i.h u-boot-sunxi/include/configs/sun5i.h ---- u-boot-2014.01-rc1/include/configs/sun5i.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/configs/sun5i.h 2014-03-05 23:14:48.236085715 +0100 -@@ -0,0 +1,41 @@ -+/* -+ * (C) Copyright 2012-2013 Henrik Nordstrom -+ * -+ * Configuration settings for the Allwinner A13 (sun5i) 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 -+ -+/* -+ * High Level Configuration Options -+ */ -+#define CONFIG_SUN5I /* sun5i SoC generation */ -+ -+#define CONFIG_SYS_PROMPT "sun5i# " -+#define CONFIG_MACH_TYPE 4138 -+ -+/* -+ * Include common sunxi configuration where most the settings are -+ */ -+#include -+ -+#endif /* __CONFIG_H */ -diff -ruN u-boot-2014.01-rc1/include/configs/sun6i.h u-boot-sunxi/include/configs/sun6i.h ---- u-boot-2014.01-rc1/include/configs/sun6i.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/configs/sun6i.h 2014-03-05 23:14:48.236085715 +0100 -@@ -0,0 +1,43 @@ -+/* -+ * (C) Copyright 2012-2013 Henrik Nordstrom -+ * (C) Copyright 2013 Luke Kenneth Casson Leighton -+ * (C) Copyright 2013 Maxime Ripard -+ * -+ * 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 -+ -+#endif /* __CONFIG_H */ -diff -ruN u-boot-2014.01-rc1/include/configs/sun7i.h u-boot-sunxi/include/configs/sun7i.h ---- u-boot-2014.01-rc1/include/configs/sun7i.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/configs/sun7i.h 2014-03-05 23:14:48.236085715 +0100 -@@ -0,0 +1,53 @@ -+/* -+ * (C) Copyright 2012-2013 Henrik Nordstrom -+ * (C) Copyright 2013 Luke Kenneth Casson Leighton -+ * -+ * Configuration settings for the Allwinner A20 (sun7i) 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 -+ -+/* -+ * A20 specific configuration -+ */ -+#define CONFIG_SUN7I /* sun7i SoC generation */ -+ -+#define CONFIG_SYS_PROMPT "sun7i# " -+#define CONFIG_MACH_TYPE 4283 -+ -+#if defined(CONFIG_SYS_SECONDARY_ON) -+#define CONFIG_BOARD_POSTCLK_INIT 1 -+#endif -+ -+#define CONFIG_ARMV7_VIRT 1 -+#define CONFIG_ARMV7_NONSEC 1 -+#define CONFIG_ARMV7_PSCI 1 -+#define CONFIG_ARMV7_PSCI_NR_CPUS 2 -+#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE -+#define CONFIG_SYS_CLK_FREQ 24000000 -+ -+/* -+ * Include common sunxi configuration where most the settings are -+ */ -+#include -+ -+#endif /* __CONFIG_H */ -diff -ruN u-boot-2014.01-rc1/include/configs/sunxi-common.h u-boot-sunxi/include/configs/sunxi-common.h ---- u-boot-2014.01-rc1/include/configs/sunxi-common.h 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/include/configs/sunxi-common.h 2014-03-05 23:14:48.236085715 +0100 -@@ -0,0 +1,478 @@ -+/* -+ * (C) Copyright 2012-2012 Henrik Nordstrom -+ * -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * Configuration settings for the Allwinner sunxi series of boards. -+ * -+ * 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 _SUNXI_COMMON_CONFIG_H -+#define _SUNXI_COMMON_CONFIG_H -+ -+/* -+ * High Level Configuration Options -+ */ -+#define CONFIG_ALLWINNER /* It's a Allwinner chip */ -+#define CONFIG_SUNXI /* which is 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 /* 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 -+ -+/* 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 -+#ifdef 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 -+#define CONFIG_CMDLINE_EDITING -+ -+/* mmc config */ -+/* Can't use MMC slot 0 if the UART is directed there */ -+#ifndef CONFIG_SUN6I -+#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_MMC_SUNXI_USE_DMA -+#define CONFIG_ENV_IS_IN_MMC -+#define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ -+#endif -+#endif -+ -+/* -+ * Size of malloc() pool -+ * 1MB = 0x100000, 0x100000 = 1024 * 1024 -+ */ -+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) -+ -+/* Flat Device Tree (FDT/DT) support */ -+#define CONFIG_OF_LIBFDT -+#define CONFIG_SYS_BOOTMAPSZ (16 << 20) -+ -+/* -+ * Miscellaneous configurable options -+ */ -+#define CONFIG_SYS_LONGHELP /* undef to save memory */ -+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ -+#define CONFIG_CMD_ECHO -+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " -+#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 */ -+ -+/* Boot Argument Buffer Size */ -+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE -+ -+/* memtest works on */ -+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE -+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + (256 << 20)) -+#define CONFIG_SYS_LOAD_ADDR 0x50000000 /* default load address */ -+ -+/* standalone support */ -+#define CONFIG_STANDALONE_LOAD_ADDR 0x50000000 -+ -+#define CONFIG_SYS_HZ 1000 -+ -+/* valid baudrates */ -+#define CONFIG_BAUDRATE 115200 -+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 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 \ -+ "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_BOOTDELAY 3 -+#define CONFIG_SYS_BOOT_GET_CMDLINE -+#define CONFIG_AUTO_COMPLETE -+ -+#include -+ -+/* Accept zimage + raw ramdisk without mkimage headers */ -+#define CONFIG_CMD_BOOTZ -+#define CONFIG_SUPPORT_RAW_INITRD -+ -+#define CONFIG_DOS_PARTITION -+#define CONFIG_CMD_FAT /* with this we can access fat bootfs */ -+#define CONFIG_FAT_WRITE /* enable write access */ -+#define CONFIG_CMD_EXT2 /* with this we can access ext2 bootfs */ -+#define CONFIG_CMD_EXT4 /* with this we can access ext4 bootfs */ -+ -+#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 0x50000000 -+#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 -+#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK -+ -+#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 */ -+#define CONFIG_SPL_I2C_SUPPORT -+#define CONFIG_SYS_I2C_SPEED 400000 -+#define CONFIG_HARD_I2C -+#define CONFIG_SUNXI_I2C -+#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_NO_AXP -+#define CONFIG_AXP209_POWER -+#endif -+#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_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 */ -+#define CONFIG_CMD_MII -+#define CONFIG_CMD_NET -+#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_SYS_DCACHE_OFF /* dw driver doesn't support dcache */ -+#define CONFIG_MII /* MII PHY management */ -+#define CONFIG_CMD_MII -+#define CONFIG_CMD_NET -+#endif -+ -+#ifdef CONFIG_CMD_NET -+#define CONFIG_CMD_PING -+#define CONFIG_CMD_DHCP -+#define CONFIG_CMD_NFS -+#define CONFIG_CMD_SNTP -+#define CONFIG_TIMESTAMP /* Needed by SNTP */ -+#define CONFIG_CMD_DNS -+#define CONFIG_NETCONSOLE -+#define CONFIG_BOOTP_SUBNETMASK -+#define CONFIG_BOOTP_GATEWAY -+#define CONFIG_BOOTP_HOSTNAME -+#define CONFIG_BOOTP_NISDOMAIN -+#define CONFIG_BOOTP_BOOTPATH -+#define CONFIG_BOOTP_BOOTFILESIZE -+#define CONFIG_BOOTP_DNS -+#define CONFIG_BOOTP_DNS2 -+#define CONFIG_BOOTP_SEND_HOSTNAME -+#define CONFIG_BOOTP_NTPSERVER -+#define CONFIG_BOOTP_TIMEOFFSET -+#define CONFIG_BOOTP_MAY_FAIL -+#define CONFIG_BOOTP_SERVERIP -+#define CONFIG_BOOTP_DHCP_REQUEST_DELAY 50000 -+#define CONFIG_CMD_ELF -+#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 -+ -+#endif /* _SUNXI_COMMON_CONFIG_H */ -diff -ruN u-boot-2014.01-rc1/include/netdev.h u-boot-sunxi/include/netdev.h ---- u-boot-2014.01-rc1/include/netdev.h 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/include/netdev.h 2014-03-05 23:14:48.264085341 +0100 -@@ -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.01-rc1/Makefile u-boot-sunxi/Makefile ---- u-boot-2014.01-rc1/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/Makefile 2014-03-05 23:14:46.988102381 +0100 -@@ -486,6 +486,16 @@ - conv=notrunc 2>/dev/null - cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@ - -+# sunxi: Combined object with SPL U-Boot with sunxi header (sunxi-spl.bin) -+# and the full-blown U-Boot attached to it -+$(obj)u-boot-sunxi-with-spl.bin: $(obj)spl/sunxi-spl.bin $(obj)u-boot.img -+ tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \ -+ of=$(obj)spl/sunxi-spl-pad.bin 2>/dev/null -+ dd if=$(obj)spl/sunxi-spl.bin of=$(obj)spl/sunxi-spl-pad.bin \ -+ conv=notrunc 2>/dev/null -+ cat $(obj)spl/sunxi-spl-pad.bin $(obj)u-boot.img > $@ -+ rm $(obj)spl/sunxi-spl-pad.bin -+ - ifneq ($(CONFIG_TEGRA),) - $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin - $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin -@@ -566,6 +576,9 @@ - $(obj)tpl/u-boot-tpl.bin: $(SUBDIR_TOOLS) depend - $(MAKE) -C spl all CONFIG_TPL_BUILD=y - -+$(obj)spl/sunxi-spl.bin: $(SUBDIR_TOOLS) depend -+ $(MAKE) -C spl all -+ - # Explicitly make _depend in subdirs containing multiple targets to prevent - # parallel sub-makes creating .depend files simultaneously. - depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) \ -@@ -775,6 +788,8 @@ - sinclude $(obj).boards.depend - $(obj).boards.depend: boards.cfg - @awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE)" }' $< > $@ -+ @awk '(NF && $$1 !~ /^#/ && tolower($$7) != $$7) { print tolower($$7) ": " $$7 "_config; $$(MAKE)" }' $< >> $@ -+ @awk '(NF && $$1 !~ /^#/ && tolower($$7) != $$7) { print ".PHONY: " tolower($$7) "_config"; print tolower($$7)"_config: " $$7 "_config" }' $< >> $@ - - ######################################################################### - ######################################################################### -@@ -798,6 +813,7 @@ - $(obj)tools/gen_eth_addr $(obj)tools/img2srec \ - $(obj)tools/mk{env,}image $(obj)tools/mpc86x_clk \ - $(obj)tools/mk{$(BOARD),}spl \ -+ $(obj)tools/mksunxiboot \ - $(obj)tools/mxsboot \ - $(obj)tools/ncb $(obj)tools/ubsha1 \ - $(obj)tools/kernel-doc/docproc \ -@@ -857,6 +873,7 @@ - @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f - @rm -f $(obj)dts/*.tmp - @rm -f $(obj)spl/u-boot-spl{,-pad}.ais -+ @rm -f $(obj)spl/sun?i-spl.bin - - mrproper \ - distclean: clobber unconfig -diff -ruN u-boot-2014.01-rc1/mkconfig u-boot-sunxi/mkconfig ---- u-boot-2014.01-rc1/mkconfig 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/mkconfig 2014-03-05 23:14:48.292084967 +0100 -@@ -165,6 +165,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.01-rc1/snapshot.commit u-boot-sunxi/snapshot.commit ---- u-boot-2014.01-rc1/snapshot.commit 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/snapshot.commit 2014-03-05 23:14:48.300084861 +0100 -@@ -1 +1 @@ --d19ad726bcd5d9106f7ba9c750462fcc369f1020 Mon, 25 Nov 2013 16:49:32 -0500 -+$Format:%H %cD$ -diff -ruN u-boot-2014.01-rc1/spl/Makefile u-boot-sunxi/spl/Makefile ---- u-boot-2014.01-rc1/spl/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/spl/Makefile 2014-03-05 23:14:48.300084861 +0100 -@@ -162,6 +162,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 -@@ -169,6 +175,12 @@ - $(OBJTREE)/tools/mk$(BOARD)spl $< $@ - endif - -+ifdef CONFIG_SUNXI -+$(obj)sunxi-spl.bin: $(obj)u-boot-spl.bin -+ $(OBJTREE)/tools/mksunxiboot \ -+ $(obj)u-boot-spl.bin $(obj)sunxi-spl.bin -+endif -+ - $(obj)$(SPL_BIN).bin: $(obj)$(SPL_BIN) - $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ - -diff -ruN u-boot-2014.01-rc1/tools/.gitignore u-boot-sunxi/tools/.gitignore ---- u-boot-2014.01-rc1/tools/.gitignore 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/tools/.gitignore 2014-03-05 23:14:48.300084861 +0100 -@@ -7,6 +7,7 @@ - /mkimage - /mpc86x_clk - /mxsboot -+/mksunxiboot - /ncb - /ncp - /proftool -diff -ruN u-boot-2014.01-rc1/tools/Makefile u-boot-sunxi/tools/Makefile ---- u-boot-2014.01-rc1/tools/Makefile 2013-11-25 22:49:32.000000000 +0100 -+++ u-boot-sunxi/tools/Makefile 2014-03-05 23:14:48.300084861 +0100 -@@ -54,6 +54,7 @@ - BIN_FILES-y += mkimage$(SFX) - BIN_FILES-$(CONFIG_EXYNOS5250) += mk$(BOARD)spl$(SFX) - BIN_FILES-$(CONFIG_MX23) += mxsboot$(SFX) -+BIN_FILES-$(CONFIG_SUNXI) += mksunxiboot$(SFX) - BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX) - BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX) - BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) -@@ -91,6 +92,7 @@ - OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o - OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o - OBJ_FILES-$(CONFIG_MX23) += mxsboot.o -+OBJ_FILES-$(CONFIG_SUNXI) += mksunxiboot.o - OBJ_FILES-$(CONFIG_MX28) += mxsboot.o - OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o - OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o -@@ -235,6 +237,10 @@ - $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ - $(HOSTSTRIP) $@ - -+$(obj)mksunxiboot$(SFX): $(obj)mksunxiboot.o -+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ -+ $(HOSTSTRIP) $@ -+ - $(obj)mxsboot$(SFX): $(obj)mxsboot.o - $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ - $(HOSTSTRIP) $@ -diff -ruN u-boot-2014.01-rc1/tools/mksunxiboot.c u-boot-sunxi/tools/mksunxiboot.c ---- u-boot-2014.01-rc1/tools/mksunxiboot.c 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/tools/mksunxiboot.c 2014-03-05 23:14:48.312084700 +0100 -@@ -0,0 +1,163 @@ -+/* -+ * (C) Copyright 2007-2011 -+ * Allwinner Technology Co., Ltd. -+ * Tom Cubie -+ * -+ * a simple tool to generate bootable image for sunxi platform. -+ * -+ * 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+typedef unsigned char u8; -+typedef unsigned int u32; -+ -+/* boot head definition from sun4i boot code */ -+struct boot_file_head { -+ u32 jump_instruction; /* one intruction jumping to real code */ -+ u8 magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ -+ u32 check_sum; /* generated by PC */ -+ u32 length; /* generated by PC */ -+#if 1 -+ /* We use a simplified header, only filling in what is needed by the -+ * boot ROM. To be compatible with Allwinner tools the larger header -+ * below should be used, followed by a custom header if desired. */ -+ u8 pad[12]; /* align to 32 bytes */ -+#else -+ u32 pub_head_size; /* the size of boot_file_head */ -+ u8 pub_head_vsn[4]; /* the version of boot_file_head */ -+ u8 file_head_vsn[4]; /* the version of boot0_file_head or -+ boot1_file_head */ -+ u8 Boot_vsn[4]; /* Boot version */ -+ u8 eGON_vsn[4]; /* eGON version */ -+ u8 platform[8]; /* platform information */ -+#endif -+}; -+ -+#define BOOT0_MAGIC "eGON.BT0" -+#define STAMP_VALUE 0x5F0A6C39 -+ -+/* check sum functon from sun4i boot code */ -+int gen_check_sum(void *boot_buf) -+{ -+ struct boot_file_head *head_p; -+ u32 length; -+ u32 *buf; -+ u32 loop; -+ u32 i; -+ u32 sum; -+ -+ head_p = (struct boot_file_head *)boot_buf; -+ length = head_p->length; -+ if ((length & 0x3) != 0) /* must 4-byte-aligned */ -+ return -1; -+ buf = (u32 *)boot_buf; -+ 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, load_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((void *)img.pad, 0, BLOCK_SIZE); -+ -+ /* get input file size */ -+ file_size = lseek(fd_in, 0, SEEK_END); -+ printf("File size: 0x%x\n", file_size); -+ -+ if (file_size > SRAM_LOAD_MAX_SIZE) { -+ fprintf(stderr, "ERROR: File too large!\n"); -+ return EXIT_FAILURE; -+ } else -+ load_size = ALIGN(file_size, sizeof(int)); -+ printf("Load size: 0x%x\n", load_size); -+ -+ 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, load_size); -+ printf("Read 0x%x bytes\n", count); -+ -+ /* fill the header */ -+ img.header.jump_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(load_size + sizeof(struct boot_file_head), BLOCK_SIZE); -+ gen_check_sum((void *)&img); -+ -+ count = write(fd_out, (void *)&img, img.header.length); -+ printf("Write 0x%x bytes\n", count); -+ -+ close(fd_in); -+ close(fd_out); -+ -+ return EXIT_SUCCESS; -+} -diff -ruN u-boot-2014.01-rc1/tools/mksunxiboot.README u-boot-sunxi/tools/mksunxiboot.README ---- u-boot-2014.01-rc1/tools/mksunxiboot.README 1970-01-01 01:00:00.000000000 +0100 -+++ u-boot-sunxi/tools/mksunxiboot.README 2014-03-05 23:14:48.312084700 +0100 -@@ -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.