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.