From 56d83d1c046c693b65ab09c0e960d922ec639c2b Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 23 Apr 2014 18:17:51 +0200 Subject: arm: vf610: add DDR_SEL_PAD_CONTR register Set DDR_SEL_PAD_CONTR register explicitly to DDR3 which solves RAM issues with newer silicon (1.1). This register was added in revision 4 of the Vybrid Reference Manual. Signed-off-by: Stefan Agner --- board/freescale/vf610twr/vf610twr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/freescale/vf610twr/vf610twr.c b/board/freescale/vf610twr/vf610twr.c index 4ee74c0198..d64d3aa872 100644 --- a/board/freescale/vf610twr/vf610twr.c +++ b/board/freescale/vf610twr/vf610twr.c @@ -217,7 +217,8 @@ void ddr_ctrl_init(void) &ddrmr->cr[139]); writel(DDRMC_CR154_PAD_ZQ_EARLY_CMP_EN_TIMER(13) | - DDRMC_CR154_PAD_ZQ_MODE(1), &ddrmr->cr[154]); + DDRMC_CR154_PAD_ZQ_MODE(1) | + DDRMC_CR154_DDR_SEL_PAD_CONTR(3), &ddrmr->cr[154]); writel(DDRMC_CR155_AXI0_AWCACHE | DDRMC_CR155_PAD_ODT_BYTE1(2), &ddrmr->cr[155]); writel(DDRMC_CR158_TWR(6), &ddrmr->cr[158]); -- cgit v1.2.3 From cba69eeeaa67d3fb93ec6f3abab1f653abf895a9 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 5 May 2014 11:52:26 +0100 Subject: sunxi: add sun7i cpu, board and start of day support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds generic board, start of day and basic build system support for the Allwinner A20 (sun7i) processor. This code will not been compiled until the build is hooked up in a later patch. It has been split out to keep the patches manageable. Signed-off-by: Adam Sampson Signed-off-by: Aleksei Mamlin Signed-off-by: Alexandru Gagniuc Signed-off-by: Chen-Yu Tsai Signed-off-by: Emilio López Signed-off-by: Hans de Goede Signed-off-by: Henrik Nordstrom Signed-off-by: Jens Kuske Signed-off-by: Luc Verhaegen Signed-off-by: Luke Leighton Signed-off-by: Oliver Schinagl Signed-off-by: Patrick Wood Signed-off-by: Stefan Roese Signed-off-by: Wills Wang Signed-off-by: Ian Campbell Reviewed-by: Marek Vasut Cc: Tom Cubie Reviewed-by: Tom Rini --- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/sunxi/Makefile | 11 +++ arch/arm/cpu/armv7/sunxi/board.c | 88 +++++++++++++++++ arch/arm/cpu/armv7/sunxi/cpu_info.c | 19 ++++ arch/arm/cpu/armv7/sunxi/start.c | 1 + arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 77 +++++++++++++++ arch/arm/include/asm/arch-sunxi/cpu.h | 122 ++++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/spl.h | 20 ++++ board/sunxi/Makefile | 11 +++ board/sunxi/board.c | 57 +++++++++++ include/configs/sun7i.h | 24 +++++ include/configs/sunxi-common.h | 141 ++++++++++++++++++++++++++++ 12 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/board.c create mode 100644 arch/arm/cpu/armv7/sunxi/cpu_info.c create mode 100644 arch/arm/cpu/armv7/sunxi/start.c create mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds create mode 100644 arch/arm/include/asm/arch-sunxi/cpu.h create mode 100644 arch/arm/include/asm/arch-sunxi/spl.h create mode 100644 board/sunxi/Makefile create mode 100644 board/sunxi/board.c create mode 100644 include/configs/sun7i.h create mode 100644 include/configs/sunxi-common.h (limited to 'board') diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index ab869b1ee8..232118d7f4 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -12,7 +12,7 @@ obj-y += cache_v7.o obj-y += cpu.o obj-y += syslib.o -ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY),) +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),) ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) obj-y += lowlevel_init.o endif diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index d81d26cf50..a64bfa18e0 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -8,7 +8,18 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-y += timer.o +obj-y += board.o obj-y += clock.o obj-y += pinmux.o obj-$(CONFIG_SUN7I) += clock_sun4i.o + +ifndef CONFIG_SPL_BUILD +obj-y += cpu_info.o +endif + +ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SUN7I) += dram.o +ifdef CONFIG_SPL_FEL +obj-y += start.o +endif +endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c new file mode 100644 index 0000000000..b5c0cb7487 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2012 Henrik Nordstrom + * + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * Tom Cubie + * + * Some init for sunxi platform. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#ifdef CONFIG_SPL_BUILD +#include +#endif +#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, nand flash, mmc2. + * Unfortunately we can't check how SPL was loaded so assume + * it's always the first SD/MMC controller + */ +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_MMC1; +} + +/* No confirmation data available in SPL yet. Hardcode bootmode */ +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} +#endif + +int gpio_init(void) +{ + 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); + + return 0; +} + +void reset_cpu(ulong addr) +{ +} + +/* do some early init */ +void s_init(void) +{ +#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || defined CONFIG_SUN6I) + /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ + asm volatile( + "mrc p15, 0, r0, c1, c0, 1\n" + "orr r0, r0, #1 << 6\n" + "mcr p15, 0, r0, c1, c0, 1\n"); +#endif + + clock_init(); + timer_init(); + gpio_init(); + +#ifdef CONFIG_SPL_BUILD + gd = &gdata; + preloader_console_init(); + + 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 diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c new file mode 100644 index 0000000000..b4c3d5c6dd --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -0,0 +1,19 @@ +/* + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * Tom Cubie + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + puts("CPU: Allwinner A20 (SUN7I)\n"); + return 0; +} +#endif diff --git a/arch/arm/cpu/armv7/sunxi/start.c b/arch/arm/cpu/armv7/sunxi/start.c new file mode 100644 index 0000000000..6b392fa835 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/start.c @@ -0,0 +1 @@ +/* Intentionally empty. Only needed to get FEL SPL link line right */ diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds new file mode 100644 index 0000000000..364e35c32f --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2013 + * Henrik Nordstrom + * + * SPDX-License-Identifier: GPL-2.0+ + */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(s_init) +SECTIONS +{ + . = 0x00002000; + + . = ALIGN(4); + .text : + { + *(.text.s_init) + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + . = .; + + . = ALIGN(4); + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + . = ALIGN(4); + .note.gnu.build-id : + { + *(.note.gnu.build-id) + } + _end = .; + + . = ALIGN(4096); + .mmutable : { + *(.mmutable) + } + + .bss_start __rel_dyn_start (OVERLAY) : { + KEEP(*(.__bss_start)); + __bss_base = .; + } + + .bss __bss_base (OVERLAY) : { + *(.bss*) + . = ALIGN(4); + __bss_limit = .; + } + + .bss_end __bss_limit (OVERLAY) : { + KEEP(*(.__bss_end)); + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } + /DISCARD/ : { *(.note*) } +} diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h new file mode 100644 index 0000000000..a987e51d57 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * Tom Cubie + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_CPU_H +#define _SUNXI_CPU_H + +#define SUNXI_SRAM_A1_BASE 0x00000000 +#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */ + +#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */ +#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */ +#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */ +#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ +#define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ + +#define SUNXI_SRAMC_BASE 0x01c00000 +#define SUNXI_DRAMC_BASE 0x01c01000 +#define SUNXI_DMA_BASE 0x01c02000 +#define SUNXI_NFC_BASE 0x01c03000 +#define SUNXI_TS_BASE 0x01c04000 +#define SUNXI_SPI0_BASE 0x01c05000 +#define SUNXI_SPI1_BASE 0x01c06000 +#define SUNXI_MS_BASE 0x01c07000 +#define SUNXI_TVD_BASE 0x01c08000 +#define SUNXI_CSI0_BASE 0x01c09000 +#define SUNXI_TVE0_BASE 0x01c0a000 +#define SUNXI_EMAC_BASE 0x01c0b000 +#define SUNXI_LCD0_BASE 0x01c0C000 +#define SUNXI_LCD1_BASE 0x01c0d000 +#define SUNXI_VE_BASE 0x01c0e000 +#define SUNXI_MMC0_BASE 0x01c0f000 +#define SUNXI_MMC1_BASE 0x01c10000 +#define SUNXI_MMC2_BASE 0x01c11000 +#define SUNXI_MMC3_BASE 0x01c12000 +#define SUNXI_USB0_BASE 0x01c13000 +#define SUNXI_USB1_BASE 0x01c14000 +#define SUNXI_SS_BASE 0x01c15000 +#define SUNXI_HDMI_BASE 0x01c16000 +#define SUNXI_SPI2_BASE 0x01c17000 +#define SUNXI_SATA_BASE 0x01c18000 +#define SUNXI_PATA_BASE 0x01c19000 +#define SUNXI_ACE_BASE 0x01c1a000 +#define SUNXI_TVE1_BASE 0x01c1b000 +#define SUNXI_USB2_BASE 0x01c1c000 +#define SUNXI_CSI1_BASE 0x01c1d000 +#define SUNXI_TZASC_BASE 0x01c1e000 +#define SUNXI_SPI3_BASE 0x01c1f000 + +#define SUNXI_CCM_BASE 0x01c20000 +#define SUNXI_INTC_BASE 0x01c20400 +#define SUNXI_PIO_BASE 0x01c20800 +#define SUNXI_TIMER_BASE 0x01c20c00 +#define SUNXI_SPDIF_BASE 0x01c21000 +#define SUNXI_AC97_BASE 0x01c21400 +#define SUNXI_IR0_BASE 0x01c21800 +#define SUNXI_IR1_BASE 0x01c21c00 + +#define SUNXI_IIS_BASE 0x01c22400 +#define SUNXI_LRADC_BASE 0x01c22800 +#define SUNXI_AD_DA_BASE 0x01c22c00 +#define SUNXI_KEYPAD_BASE 0x01c23000 +#define SUNXI_TZPC_BASE 0x01c23400 +#define SUNXI_SID_BASE 0x01c23800 +#define SUNXI_SJTAG_BASE 0x01c23c00 + +#define SUNXI_TP_BASE 0x01c25000 +#define SUNXI_PMU_BASE 0x01c25400 +#define SUNXI_CPUCFG_BASE 0x01c25c00 + +#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__ +void sunxi_board_init(void); +void sunxi_reset(void); +#endif /* __ASSEMBLY__ */ + +#endif /* _CPU_H */ diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h new file mode 100644 index 0000000000..ff871bcaee --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -0,0 +1,20 @@ +/* + * This is a copy of omap3/spl.h: + * + * (C) Copyright 2012 + * Texas Instruments, + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_ONE_NAND 3 +#define BOOT_DEVICE_MMC2 5 /*emmc*/ +#define BOOT_DEVICE_MMC1 6 +#define BOOT_DEVICE_XIPWAIT 7 +#define BOOT_DEVICE_MMC2_2 0xff +#endif diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile new file mode 100644 index 0000000000..559112ebbd --- /dev/null +++ b/board/sunxi/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2012 Henrik Nordstrom +# +# Based on some other board Makefile +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-y += board.o diff --git a/board/sunxi/board.c b/board/sunxi/board.c new file mode 100644 index 0000000000..328334ab02 --- /dev/null +++ b/board/sunxi/board.c @@ -0,0 +1,57 @@ +/* + * (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. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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)); + } + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +void sunxi_board_init(void) +{ + unsigned long ramsize; + + printf("DRAM:"); + ramsize = sunxi_dram_init(); + printf(" %lu MiB\n", ramsize >> 20); + if (!ramsize) + hang(); +} +#endif diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h new file mode 100644 index 0000000000..9b693f7039 --- /dev/null +++ b/include/configs/sun7i.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2012-2013 Henrik Nordstrom + * (C) Copyright 2013 Luke Kenneth Casson Leighton + * + * Configuration settings for the Allwinner A20 (sun7i) CPU + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * A20 specific configuration + */ +#define CONFIG_SUN7I /* sun7i SoC generation */ + +#define CONFIG_SYS_PROMPT "sun7i# " + +/* + * Include common sunxi configuration where most the settings are + */ +#include + +#endif /* __CONFIG_H */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h new file mode 100644 index 0000000000..3f7e314a8b --- /dev/null +++ b/include/configs/sunxi-common.h @@ -0,0 +1,141 @@ +/* + * (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. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_COMMON_CONFIG_H +#define _SUNXI_COMMON_CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_SUNXI /* sunxi family */ + +#include /* get chip and board defs */ + +#define CONFIG_SYS_TEXT_BASE 0x4a000000 + +/* + * Display CPU information + */ +#define CONFIG_DISPLAY_CPUINFO + +/* 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) + +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ + +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_SETEXPR + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG + +/* 4MB of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (4 << 20)) + +/* + * Miscellaneous configurable options + */ +#define CONFIG_CMD_ECHO +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_GENERIC_BOARD + +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_SYS_LOAD_ADDR 0x48000000 /* default load address */ + +/* standalone support */ +#define CONFIG_STANDALONE_LOAD_ADDR 0x48000000 + +#define CONFIG_SYS_HZ 1000 + +/* baudrate */ +#define CONFIG_BAUDRATE 115200 + +/* The stack sizes are set up in start.S using the settings below */ +#define CONFIG_STACKSIZE (256 << 10) /* 256 KiB */ + +/* FLASH and environment organization */ + +#define CONFIG_SYS_NO_FLASH + +#define CONFIG_SYS_MONITOR_LEN (512 << 10) /* 512 KiB */ +#define CONFIG_IDENT_STRING " Allwinner Technology" + +#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x10000000\0" + +#define CONFIG_SYS_BOOT_GET_CMDLINE + +#include + +#define CONFIG_FAT_WRITE /* enable write access */ + +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT + +#define CONFIG_SPL +#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 */ +/* end of 32 KiB in sram */ +#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ +#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK +#define CONFIG_SYS_SPL_MALLOC_START 0x4ff00000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00080000 /* 512 KiB */ + +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_NET +#undef CONFIG_CMD_NFS + +#define CONFIG_CONS_INDEX 1 /* UART0 */ + +#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 + +#ifndef CONFIG_SPL_BUILD +#include +#endif + +#endif /* _SUNXI_COMMON_CONFIG_H */ -- cgit v1.2.3 From 7d20d7eb1334706546708acd966c0c7f807726e8 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 5 May 2014 11:52:27 +0100 Subject: sunxi: add support for Cubietruck booting in FEL mode Signed-off-by: Oliver Schinagl Signed-off-by: Jens Kuske Signed-off-by: Ian Campbell Reviewed-by: Tom Rini Reviewed-by: Marek Vasut --- board/sunxi/Makefile | 1 + board/sunxi/dram_cubietruck.c | 31 +++++++++++++++++++++++++++++++ boards.cfg | 1 + 3 files changed, 33 insertions(+) create mode 100644 board/sunxi/dram_cubietruck.c (limited to 'board') diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 559112ebbd..18b1e11733 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -9,3 +9,4 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-y += board.o +obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o diff --git a/board/sunxi/dram_cubietruck.c b/board/sunxi/dram_cubietruck.c new file mode 100644 index 0000000000..fbcd68771f --- /dev/null +++ b/board/sunxi/dram_cubietruck.c @@ -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 = 8, + .bus_width = 32, + .cas = 9, + .zq = 0x7f, + .odt_en = 0, + .size = 2048, + .tpr0 = 0x42d899b7, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .tpr3 = 0x0, + .tpr4 = 0x1, + .tpr5 = 0x0, + .emr1 = 0x4, + .emr2 = 0x10, + .emr3 = 0x0, +}; + +unsigned long sunxi_dram_init(void) +{ + return dramc_init(&dram_para); +} diff --git a/boards.cfg b/boards.cfg index c40937f502..db3a6aef75 100644 --- a/boards.cfg +++ b/boards.cfg @@ -379,6 +379,7 @@ Active arm armv7 rmobile renesas lager Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - +Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL - 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 -- cgit v1.2.3 From 5835823da3a357468bc90c2b74bad3193555b918 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 5 May 2014 11:52:28 +0100 Subject: sunxi: add gmac Ethernet support Add support for the GMAC Ethernet controller on Allwinner A20 (sun7i) processors. Enable for the Cubietruck. Signed-off-by: Chen-Yu Tsai Signed-off-by: Jens Kuske Signed-off-by: Ian Campbell Reviewed-by: Marek Vasut Reviewed-by: Tom Rini --- arch/arm/cpu/armv7/sunxi/board.c | 23 +++++++++++++++++++++++ board/sunxi/Makefile | 1 + board/sunxi/gmac.c | 32 ++++++++++++++++++++++++++++++++ boards.cfg | 2 +- include/configs/sunxi-common.h | 17 +++++++++++++++++ include/netdev.h | 1 + 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 board/sunxi/gmac.c (limited to 'board') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index b5c0cb7487..49c94489ee 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -11,6 +11,8 @@ */ #include +#include +#include #include #ifdef CONFIG_SPL_BUILD #include @@ -86,3 +88,24 @@ void enable_caches(void) dcache_enable(); } #endif + +#ifdef CONFIG_CMD_NET +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ + int rc; + +#ifdef CONFIG_SUNXI_GMAC + rc = sunxi_gmac_initialize(bis); + if (rc < 0) { + printf("sunxi: failed to initialize gmac\n"); + return rc; + } +#endif + + return 0; +} +#endif diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 18b1e11733..cbf8f086a9 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -9,4 +9,5 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-y += board.o +obj-$(CONFIG_SUNXI_GMAC) += gmac.o obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c new file mode 100644 index 0000000000..e48328d9e8 --- /dev/null +++ b/board/sunxi/gmac.c @@ -0,0 +1,32 @@ +#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 */ + setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | + CCM_GMAC_CTRL_GPIT_RGMII); + + /* Configure pin mux settings for GMAC */ + for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { + /* skip unused pins in RGMII mode */ + if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14)) + continue; + sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC); + sunxi_gpio_set_drv(pin, 3); + } + + return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII); +} diff --git a/boards.cfg b/boards.cfg index db3a6aef75..bc0503048f 100644 --- a/boards.cfg +++ b/boards.cfg @@ -379,7 +379,7 @@ Active arm armv7 rmobile renesas lager Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - -Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL - +Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - 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 --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 3f7e314a8b..e844110d7a 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -127,6 +127,23 @@ #define CONFIG_CONS_INDEX 1 /* UART0 */ +#ifdef CONFIG_SUNXI_GMAC +#define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ +#define CONFIG_DW_AUTONEG +#define CONFIG_PHY_GIGE /* GMAC can use gigabit PHY */ +#define CONFIG_PHY_ADDR 1 +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_PHYLIB +#endif + +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#define CONFIG_CMD_DNS +#define CONFIG_NETCONSOLE +#define CONFIG_BOOTP_DNS2 +#define CONFIG_BOOTP_SEND_HOSTNAME +#endif + #if !defined CONFIG_ENV_IS_IN_MMC && \ !defined CONFIG_ENV_IS_IN_NAND && \ !defined CONFIG_ENV_IS_IN_FAT && \ diff --git a/include/netdev.h b/include/netdev.h index e211f1841f..63481eca22 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -78,6 +78,7 @@ int sh_eth_initialize(bd_t *bis); 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_gmac_initialize(bd_t *bis); int sunxi_wemac_initialize(bd_t *bis); int tsi108_eth_initialize(bd_t *bis); int uec_standard_init(bd_t *bis); -- cgit v1.2.3 From e24ea55c04a8ee9c273dd879edda23bbde3d807a Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 5 May 2014 14:42:31 +0100 Subject: sunxi: mmc support On Mon, 2014-05-05 at 14:18 +0200, Stefan Roese wrote: > > + case 1: > > +#if CONFIG_MMC1_PG > Are you sure that this is correct and shouldn't be: > > +#ifdef CONFIG_MMC1_PG > > ? It's "correct" in so far as it works (the boards.cfg config stuff #defines things to 1), but I think you are right that it isn't the preferred style. But... > A quick scan through this patch series shows that this define > is not set at all. Perhaps its outdated? Or is it used to support > some other sunxi SoC? Not sure, perhaps it should be removed for > now. ...I had thought that it was to support some other board which wasn't being upstreamed right now, so eventually useful and harmless for now, but I've just checked and it isn't actually used by any of the boards in u-boot-sunxi.git. So rather than fix it to use #ifdef lets drop it. Rather than resend the entire series, here is v5.1 of this patch. > Other than this please add my: > > Reviewed-by: Stefan Roese Thanks! 8<--------------------------------- >From 20704e35a41664de5f516ed0e02981ac06085102 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 7 Mar 2014 04:29:39 +0000 Subject: [PATCH v5.1 7/8] sunxi: mmc support This adds support for the MMC controller on the Allwinner A20 (sun7i) processor. Signed-off-by: Henrik Nordstrom Signed-off-by: Luke Leighton Signed-off-by: Oliver Schinagl Signed-off-by: Wills Wang Signed-off-by: Ian Campbell Reviewed-by: Marek Vasut Reviewed-by: Stefan Roese Cc: Tom Cubie Cc: Aaron Maoye Cc: Pantelis Antoniou Reviewed-by: Tom Rini --- arch/arm/include/asm/arch-sunxi/mmc.h | 124 +++++++++ board/sunxi/board.c | 63 +++++ drivers/mmc/Makefile | 1 + drivers/mmc/sunxi_mmc.c | 503 ++++++++++++++++++++++++++++++++++ include/configs/sunxi-common.h | 11 + 5 files changed, 702 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/mmc.h create mode 100644 drivers/mmc/sunxi_mmc.c (limited to 'board') diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h new file mode 100644 index 0000000000..53196e3b02 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -0,0 +1,124 @@ +/* + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * Aaron + * + * MMC register definition for allwinner sunxi platform. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_MMC_H +#define _SUNXI_MMC_H + +#include + +struct sunxi_mmc { + u32 gctrl; /* 0x00 global control */ + u32 clkcr; /* 0x04 clock control */ + u32 timeout; /* 0x08 time out */ + u32 width; /* 0x0c bus width */ + u32 blksz; /* 0x10 block size */ + u32 bytecnt; /* 0x14 byte count */ + u32 cmd; /* 0x18 command */ + u32 arg; /* 0x1c argument */ + u32 resp0; /* 0x20 response 0 */ + u32 resp1; /* 0x24 response 1 */ + u32 resp2; /* 0x28 response 2 */ + u32 resp3; /* 0x2c response 3 */ + u32 imask; /* 0x30 interrupt mask */ + u32 mint; /* 0x34 masked interrupt status */ + u32 rint; /* 0x38 raw interrupt status */ + u32 status; /* 0x3c status */ + u32 ftrglevel; /* 0x40 FIFO threshold watermark*/ + u32 funcsel; /* 0x44 function select */ + u32 cbcr; /* 0x48 CIU byte count */ + u32 bbcr; /* 0x4c BIU byte count */ + u32 dbgc; /* 0x50 debug enable */ + u32 res0[11]; + u32 dmac; /* 0x80 internal DMA control */ + u32 dlba; /* 0x84 internal DMA descr list base address */ + u32 idst; /* 0x88 internal DMA status */ + u32 idie; /* 0x8c internal DMA interrupt enable */ + u32 chda; /* 0x90 */ + u32 cbda; /* 0x94 */ + u32 res1[26]; + u32 fifo; /* 0x100 FIFO access address */ +}; + +#define SUNXI_MMC_CLK_POWERSAVE (0x1 << 17) +#define SUNXI_MMC_CLK_ENABLE (0x1 << 16) +#define SUNXI_MMC_CLK_DIVIDER_MASK (0xff) + +#define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0) +#define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1) +#define SUNXI_MMC_GCTRL_DMA_RESET (0x1 << 2) +#define SUNXI_MMC_GCTRL_RESET (SUNXI_MMC_GCTRL_SOFT_RESET|\ + SUNXI_MMC_GCTRL_FIFO_RESET|\ + SUNXI_MMC_GCTRL_DMA_RESET) +#define SUNXI_MMC_GCTRL_DMA_ENABLE (0x1 << 5) +#define SUNXI_MMC_GCTRL_ACCESS_BY_AHB (0x1 << 31) + +#define SUNXI_MMC_CMD_RESP_EXPIRE (0x1 << 6) +#define SUNXI_MMC_CMD_LONG_RESPONSE (0x1 << 7) +#define SUNXI_MMC_CMD_CHK_RESPONSE_CRC (0x1 << 8) +#define SUNXI_MMC_CMD_DATA_EXPIRE (0x1 << 9) +#define SUNXI_MMC_CMD_WRITE (0x1 << 10) +#define SUNXI_MMC_CMD_AUTO_STOP (0x1 << 12) +#define SUNXI_MMC_CMD_WAIT_PRE_OVER (0x1 << 13) +#define SUNXI_MMC_CMD_SEND_INIT_SEQ (0x1 << 15) +#define SUNXI_MMC_CMD_UPCLK_ONLY (0x1 << 21) +#define SUNXI_MMC_CMD_START (0x1 << 31) + +#define SUNXI_MMC_RINT_RESP_ERROR (0x1 << 1) +#define SUNXI_MMC_RINT_COMMAND_DONE (0x1 << 2) +#define SUNXI_MMC_RINT_DATA_OVER (0x1 << 3) +#define SUNXI_MMC_RINT_TX_DATA_REQUEST (0x1 << 4) +#define SUNXI_MMC_RINT_RX_DATA_REQUEST (0x1 << 5) +#define SUNXI_MMC_RINT_RESP_CRC_ERROR (0x1 << 6) +#define SUNXI_MMC_RINT_DATA_CRC_ERROR (0x1 << 7) +#define SUNXI_MMC_RINT_RESP_TIMEOUT (0x1 << 8) +#define SUNXI_MMC_RINT_DATA_TIMEOUT (0x1 << 9) +#define SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE (0x1 << 10) +#define SUNXI_MMC_RINT_FIFO_RUN_ERROR (0x1 << 11) +#define SUNXI_MMC_RINT_HARD_WARE_LOCKED (0x1 << 12) +#define SUNXI_MMC_RINT_START_BIT_ERROR (0x1 << 13) +#define SUNXI_MMC_RINT_AUTO_COMMAND_DONE (0x1 << 14) +#define SUNXI_MMC_RINT_END_BIT_ERROR (0x1 << 15) +#define SUNXI_MMC_RINT_SDIO_INTERRUPT (0x1 << 16) +#define SUNXI_MMC_RINT_CARD_INSERT (0x1 << 30) +#define SUNXI_MMC_RINT_CARD_REMOVE (0x1 << 31) +#define SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT \ + (SUNXI_MMC_RINT_RESP_ERROR | \ + SUNXI_MMC_RINT_RESP_CRC_ERROR | \ + SUNXI_MMC_RINT_DATA_CRC_ERROR | \ + SUNXI_MMC_RINT_RESP_TIMEOUT | \ + SUNXI_MMC_RINT_DATA_TIMEOUT | \ + SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE | \ + SUNXI_MMC_RINT_FIFO_RUN_ERROR | \ + SUNXI_MMC_RINT_HARD_WARE_LOCKED | \ + SUNXI_MMC_RINT_START_BIT_ERROR | \ + SUNXI_MMC_RINT_END_BIT_ERROR) /* 0xbfc2 */ +#define SUNXI_MMC_RINT_INTERRUPT_DONE_BIT \ + (SUNXI_MMC_RINT_AUTO_COMMAND_DONE | \ + SUNXI_MMC_RINT_DATA_OVER | \ + SUNXI_MMC_RINT_COMMAND_DONE | \ + SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE) + +#define SUNXI_MMC_STATUS_RXWL_FLAG (0x1 << 0) +#define SUNXI_MMC_STATUS_TXWL_FLAG (0x1 << 1) +#define SUNXI_MMC_STATUS_FIFO_EMPTY (0x1 << 2) +#define SUNXI_MMC_STATUS_FIFO_FULL (0x1 << 3) +#define SUNXI_MMC_STATUS_CARD_PRESENT (0x1 << 8) +#define SUNXI_MMC_STATUS_CARD_DATA_BUSY (0x1 << 9) +#define SUNXI_MMC_STATUS_DATA_FSM_BUSY (0x1 << 10) + +#define SUNXI_MMC_IDMAC_RESET (0x1 << 0) +#define SUNXI_MMC_IDMAC_FIXBURST (0x1 << 1) +#define SUNXI_MMC_IDMAC_ENABLE (0x1 << 7) + +#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0) +#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1) + +int sunxi_mmc_init(int sdc_no); +#endif /* _SUNXI_MMC_H */ diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 328334ab02..b05d0b9b18 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -43,6 +45,67 @@ int dram_init(void) return 0; } +#ifdef CONFIG_GENERIC_MMC +static void mmc_pinmux_setup(int sdc) +{ + unsigned int pin; + + switch (sdc) { + case 0: + /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ + for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + break; + + case 1: + /* CMD-PH22, CLK-PH23, D0~D3-PH24~27 : 5 */ + for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN4I_GPH22_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + break; + + case 2: + /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ + for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + break; + + case 3: + /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ + for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + break; + + default: + printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); + break; + } +} + +int board_mmc_init(bd_t *bis) +{ + mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); + sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); +#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA) + mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); + sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); +#endif + + return 0; +} +#endif + #ifdef CONFIG_SPL_BUILD void sunxi_board_init(void) { diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 4c6ab9e05b..34febf52f0 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o obj-$(CONFIG_DWMMC) += dw_mmc.o obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o +obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c new file mode 100644 index 0000000000..eb7b1158d6 --- /dev/null +++ b/drivers/mmc/sunxi_mmc.c @@ -0,0 +1,503 @@ +/* + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. + * Aaron + * + * MMC driver for allwinner sunxi platform. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +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 */ +#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; + 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; + struct mmc_config cfg; +}; + +/* support 4 mmc hosts */ +struct sunxi_mmc_host mmc_host[4]; + +static int mmc_resource_init(int sdc_no) +{ + struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + debug("init mmc %d resource\n", sdc_no); + + switch (sdc_no) { + case 0: + mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; + mmchost->mclkreg = &ccm->sd0_clk_cfg; + break; + case 1: + mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; + mmchost->mclkreg = &ccm->sd1_clk_cfg; + break; + case 2: + mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; + mmchost->mclkreg = &ccm->sd2_clk_cfg; + break; + case 3: + mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; + mmchost->mclkreg = &ccm->sd3_clk_cfg; + break; + default: + printf("Wrong mmc number %d\n", sdc_no); + return -1; + } + 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 pll_clk; + unsigned int divider; + struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + debug("init mmc %d clock and io\n", sdc_no); + + /* config ahb clock */ + setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); + + /* config mod clock */ + pll_clk = clock_get_pll6(); + /* should be close to 100 MHz but no more, so round up */ + divider = ((pll_clk + 99999999) / 100000000) - 1; + writel(CCM_MMC_CTRL_ENABLE | CCM_MMC_CTRL_PLL6 | divider, + mmchost->mclkreg); + mmchost->mod_clk = pll_clk / (divider + 1); + + return 0; +} + +static int mmc_update_clk(struct mmc *mmc) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + unsigned int cmd; + unsigned timeout_msecs = 2000; + + cmd = SUNXI_MMC_CMD_START | + SUNXI_MMC_CMD_UPCLK_ONLY | + SUNXI_MMC_CMD_WAIT_PRE_OVER; + writel(cmd, &mmchost->reg->cmd); + while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) { + if (!timeout_msecs--) + return -1; + udelay(1000); + } + + /* clock update sets various irq status bits, clear these */ + writel(readl(&mmchost->reg->rint), &mmchost->reg->rint); + + return 0; +} + +static int mmc_config_clock(struct mmc *mmc, unsigned div) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + unsigned rval = readl(&mmchost->reg->clkcr); + + /* Disable Clock */ + rval &= ~SUNXI_MMC_CLK_ENABLE; + writel(rval, &mmchost->reg->clkcr); + if (mmc_update_clk(mmc)) + return -1; + + /* Change Divider Factor */ + rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; + rval |= div; + writel(rval, &mmchost->reg->clkcr); + if (mmc_update_clk(mmc)) + return -1; + /* Re-enable Clock */ + rval |= SUNXI_MMC_CLK_ENABLE; + writel(rval, &mmchost->reg->clkcr); + + if (mmc_update_clk(mmc)) + return -1; + + return 0; +} + +static void mmc_set_ios(struct mmc *mmc) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + unsigned int clkdiv = 0; + + debug("set ios: bus_width: %x, clock: %d, mod_clk: %d\n", + mmc->bus_width, mmc->clock, mmchost->mod_clk); + + /* Change clock first */ + clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2; + if (mmc->clock) { + if (mmc_config_clock(mmc, clkdiv)) { + mmchost->fatal_err = 1; + return; + } + } + + /* Change bus width */ + if (mmc->bus_width == 8) + writel(0x2, &mmchost->reg->width); + else if (mmc->bus_width == 4) + writel(0x1, &mmchost->reg->width); + else + writel(0x0, &mmchost->reg->width); +} + +static int mmc_core_init(struct mmc *mmc) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + + /* Reset controller */ + writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + + return 0; +} + +static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + const int reading = !!(data->flags & MMC_DATA_READ); + const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : + SUNXI_MMC_STATUS_FIFO_FULL; + unsigned i; + unsigned byte_cnt = data->blocksize * data->blocks; + unsigned timeout_msecs = 2000; + unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); + + for (i = 0; i < (byte_cnt >> 2); i++) { + while (readl(&mmchost->reg->status) & status_bit) { + if (!timeout_msecs--) + return -1; + udelay(1000); + } + + if (reading) + buff[i] = readl(mmchost->database); + else + writel(buff[i], mmchost->database); + } + + return 0; +} + +static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) +{ + struct sunxi_mmc_host *mmchost = 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); + + 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 = 0; /* 0 == 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]; + } + } + flush_cache((unsigned long)pdes, + sizeof(struct sunxi_mmc_des) * (des_idx + 1)); + + rval = readl(&mmchost->reg->gctrl); + /* Enable DMA */ + writel(rval | SUNXI_MMC_GCTRL_DMA_RESET | SUNXI_MMC_GCTRL_DMA_ENABLE, + &mmchost->reg->gctrl); + /* Reset iDMA */ + writel(SUNXI_MMC_IDMAC_RESET, &mmchost->reg->dmac); + /* Enable iDMA */ + writel(SUNXI_MMC_IDMAC_FIXBURST | SUNXI_MMC_IDMAC_ENABLE, + &mmchost->reg->dmac); + rval = readl(&mmchost->reg->idie) & + ~(SUNXI_MMC_IDIE_TXIRQ|SUNXI_MMC_IDIE_RXIRQ); + if (data->flags & MMC_DATA_WRITE) + rval |= SUNXI_MMC_IDIE_TXIRQ; + else + rval |= SUNXI_MMC_IDIE_RXIRQ; + writel(rval, &mmchost->reg->idie); + writel((u32) pdes, &mmchost->reg->dlba); + writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), + &mmchost->reg->ftrglevel); + + return 0; +} + +static void mmc_enable_dma_accesses(struct mmc *mmc, int dma) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + + unsigned int gctrl = readl(&mmchost->reg->gctrl); + if (dma) + gctrl &= ~SUNXI_MMC_GCTRL_ACCESS_BY_AHB; + else + gctrl |= SUNXI_MMC_GCTRL_ACCESS_BY_AHB; + writel(gctrl, &mmchost->reg->gctrl); +} + +static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, + unsigned int done_bit, const char *what) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + unsigned int status; + + do { + status = readl(&mmchost->reg->rint); + if (!timeout_msecs-- || + (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { + debug("%s timeout %x\n", what, + status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); + return TIMEOUT; + } + udelay(1000); + } while (!(status & done_bit)); + + return 0; +} + +static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + unsigned int cmdval = SUNXI_MMC_CMD_START; + unsigned int timeout_msecs; + int error = 0; + unsigned int status = 0; + unsigned int 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; + + if (!cmd->cmdidx) + cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; + if (cmd->resp_type & MMC_RSP_PRESENT) + cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE; + if (cmd->resp_type & MMC_RSP_136) + cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE; + if (cmd->resp_type & MMC_RSP_CRC) + cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; + + if (data) { + if ((u32) data->dest & 0x3) { + error = -1; + goto out; + } + + cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER; + if (data->flags & MMC_DATA_WRITE) + cmdval |= SUNXI_MMC_CMD_WRITE; + if (data->blocks > 1) + cmdval |= SUNXI_MMC_CMD_AUTO_STOP; + writel(data->blocksize, &mmchost->reg->blksz); + writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt); + } + + debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no, + cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); + writel(cmd->cmdarg, &mmchost->reg->arg); + + if (!data) + writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + + /* + * transfer data and check status + * STATREG[2] : FIFO empty + * STATREG[3] : FIFO full + */ + if (data) { + int ret = 0; + + bytecnt = data->blocksize * data->blocks; + debug("trans data %d bytes\n", bytecnt); +#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD) + if (bytecnt > 64) { +#else + if (0) { +#endif + usedma = 1; + mmc_enable_dma_accesses(mmc, 1); + ret = mmc_trans_data_by_dma(mmc, data); + writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + } else { + mmc_enable_dma_accesses(mmc, 0); + writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + ret = mmc_trans_data_by_cpu(mmc, data); + } + if (ret) { + error = readl(&mmchost->reg->rint) & \ + SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; + error = TIMEOUT; + goto out; + } + } + + error = mmc_rint_wait(mmc, 0xfffff, SUNXI_MMC_RINT_COMMAND_DONE, "cmd"); + if (error) + goto out; + + if (data) { + timeout_msecs = usedma ? 120 * bytecnt : 120; + debug("cacl timeout %x msec\n", timeout_msecs); + error = mmc_rint_wait(mmc, timeout_msecs, + data->blocks > 1 ? + SUNXI_MMC_RINT_AUTO_COMMAND_DONE : + SUNXI_MMC_RINT_DATA_OVER, + "data"); + if (error) + goto out; + } + + if (cmd->resp_type & MMC_RSP_BUSY) { + timeout_msecs = 2000; + do { + status = readl(&mmchost->reg->status); + if (!timeout_msecs--) { + debug("busy timeout\n"); + error = TIMEOUT; + goto out; + } + udelay(1000); + } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY); + } + + if (cmd->resp_type & MMC_RSP_136) { + cmd->response[0] = readl(&mmchost->reg->resp3); + cmd->response[1] = readl(&mmchost->reg->resp2); + cmd->response[2] = readl(&mmchost->reg->resp1); + cmd->response[3] = readl(&mmchost->reg->resp0); + debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", + cmd->response[3], cmd->response[2], + cmd->response[1], cmd->response[0]); + } else { + cmd->response[0] = readl(&mmchost->reg->resp0); + debug("mmc resp 0x%08x\n", cmd->response[0]); + } +out: + if (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) & ~SUNXI_MMC_GCTRL_DMA_ENABLE, + &mmchost->reg->gctrl); + } + if (error < 0) { + writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + mmc_update_clk(mmc); + } + writel(0xffffffff, &mmchost->reg->rint); + writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, + &mmchost->reg->gctrl); + + return error; +} + +static const struct mmc_ops sunxi_mmc_ops = { + .send_cmd = mmc_send_cmd, + .set_ios = mmc_set_ios, + .init = mmc_core_init, +}; + +int sunxi_mmc_init(int sdc_no) +{ + struct mmc_config *cfg = &mmc_host[sdc_no].cfg; + + memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); + + cfg->name = "SUNXI SD/MMC"; + cfg->ops = &sunxi_mmc_ops; + + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->host_caps = MMC_MODE_4BIT; + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + cfg->f_min = 400000; + cfg->f_max = 52000000; + + mmc_resource_init(sdc_no); + mmc_clk_io_on(sdc_no); + + if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) + return -1; + + return 0; +} diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index e844110d7a..42534521d6 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -59,6 +59,16 @@ #define CONFIG_CMDLINE_TAG #define CONFIG_INITRD_TAG +/* mmc config */ +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_MMC +#define CONFIG_MMC_SUNXI +#define CONFIG_MMC_SUNXI_SLOT 0 +#define CONFIG_MMC_SUNXI_USE_DMA +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ + /* 4MB of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (4 << 20)) @@ -94,6 +104,7 @@ #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 */ #define CONFIG_EXTRA_ENV_SETTINGS \ -- cgit v1.2.3 From cd23aac4bf978970bea3f460e0b55315c94c1fee Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 19 Mar 2014 14:48:45 +0800 Subject: ARM: atmel: enable SPL on sama5d3_xplained board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It supports boot from NAND and SD/MMC card. Signed-off-by: Bo Shen Signed-off-by: Andreas Bießmann --- board/atmel/sama5d3_xplained/sama5d3_xplained.c | 87 +++++++++++++++++++++++++ include/configs/sama5d3_xplained.h | 50 ++++++++++++++ 2 files changed, 137 insertions(+) (limited to 'board') diff --git a/board/atmel/sama5d3_xplained/sama5d3_xplained.c b/board/atmel/sama5d3_xplained/sama5d3_xplained.c index 39f2dc6475..92ed4e81d3 100644 --- a/board/atmel/sama5d3_xplained/sama5d3_xplained.c +++ b/board/atmel/sama5d3_xplained/sama5d3_xplained.c @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -128,3 +131,87 @@ int board_mmc_init(bd_t *bis) return 0; } #endif + +/* SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ +#ifdef CONFIG_SYS_USE_MMC + sama5d3_xplained_mci0_hw_init(); +#elif CONFIG_SYS_USE_NANDFLASH + sama5d3_xplained_nand_hw_init(); +#endif +} + +static void ddr2_conf(struct atmel_mpddr *ddr2) +{ + ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); + + ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_DDR_CAS3 | + ATMEL_MPDDRC_CR_ENRDM_ON | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_NDQS_DISABLED | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + /* + * As the DDR2-SDRAm device requires a refresh time is 7.8125us + * when DDR run at 133MHz, so it needs (7.8125us * 133MHz / 10^9) clocks + */ + ddr2->rtr = 0x411; + + ddr2->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | + 8 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); + + ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | + 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | + 28 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | + 26 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET); + + ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | + 7 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | + 8 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET); +} + +void mem_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + struct atmel_mpddr ddr2; + + ddr2_conf(&ddr2); + + /* enable MPDDR clock */ + at91_periph_clk_enable(ATMEL_ID_MPDDRC); + writel(0x4, &pmc->scer); + + /* DDRAM2 Controller initialize */ + ddr2_init(ATMEL_BASE_DDRCS, &ddr2); +} + +void at91_pmc_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = AT91_PMC_PLLAR_29 | + AT91_PMC_PLLXR_PLLCOUNT(0x3f) | + AT91_PMC_PLLXR_MUL(43) | + AT91_PMC_PLLXR_DIV(1); + at91_plla_init(tmp); + + writel(0x3 << 8, &pmc->pllicpr); + + tmp = AT91_PMC_MCKR_MDIV_4 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp); +} +#endif diff --git a/include/configs/sama5d3_xplained.h b/include/configs/sama5d3_xplained.h index 41c946d1ec..e826e2dbd2 100644 --- a/include/configs/sama5d3_xplained.h +++ b/include/configs/sama5d3_xplained.h @@ -20,7 +20,11 @@ #define CONFIG_AT91FAMILY #define CONFIG_ARCH_CPU_INIT + +#ifndef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT +#endif + #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_DISPLAY_CPUINFO @@ -74,8 +78,12 @@ #define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS #define CONFIG_SYS_SDRAM_SIZE 0x10000000 +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_INIT_SP_ADDR 0x310000 +#else #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) +#endif /* NAND flash */ #define CONFIG_CMD_NAND @@ -199,4 +207,46 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) +/* SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x300000 +#define CONFIG_SPL_MAX_SIZE 0x10000 +#define CONFIG_SPL_BSS_START_ADDR 0x20000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 +#define CONFIG_SYS_SPL_MALLOC_START 0x20080000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT + +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_MONITOR_LEN (512 << 10) + +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 +#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1 +#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img" +#define CONFIG_SPL_FAT_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT + +#elif CONFIG_SYS_USE_NANDFLASH +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_DRIVERS +#define CONFIG_SPL_NAND_BASE +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_SYS_NAND_PAGE_SIZE 0x800 +#define CONFIG_SYS_NAND_PAGE_COUNT 64 +#define CONFIG_SYS_NAND_OOBSIZE 64 +#define CONFIG_SYS_NAND_BLOCK_SIZE 0x20000 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0x0 + +#endif + #endif -- cgit v1.2.3 From cf874c190e1796a77be6661cacc43aebb94c7a57 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Wed, 21 May 2014 10:42:15 +0800 Subject: ARM: at91sam9m10g45ek: enable mci0 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also we enable the mmc command in configuration file. As both CONFIG_CMD_MMC and CONFIG_CMD_USB use the CONFIG_DOS_PARTITION, so remove the redundant CONFIG_DOS_PARTITION definition. Signed-off-by: Josh Wu Signed-off-by: Andreas Bießmann --- arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c | 17 +++++++++++++++++ board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c | 10 ++++++++++ include/configs/at91sam9m10g45ek.h | 15 ++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c index 7d7725c4b8..0e6c0da1bd 100644 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c @@ -165,3 +165,20 @@ void at91_macb_hw_init(void) #endif } #endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +void at91_mci_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* MCI0 CLK */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* MCI0 CDA */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* MCI0 DA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* MCI0 DA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* MCI0 DA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* MCI0 DA3 */ + + /* Enable clock */ + writel(1 << ATMEL_ID_MCI0, &pmc->pcer); +} +#endif diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c index b7e2efd2fc..57881164c5 100644 --- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c +++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c @@ -16,6 +16,7 @@ #include #include #include +#include #if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB) #include #endif @@ -217,6 +218,15 @@ void lcd_show_board_info(void) #endif /* CONFIG_LCD_INFO */ #endif +#ifdef CONFIG_GENERIC_ATMEL_MCI +int board_mmc_init(bd_t *bis) +{ + at91_mci_hw_init(); + + return atmel_mci_init((void *)ATMEL_BASE_MCI0); +} +#endif + int board_early_init_f(void) { at91_seriald_hw_init(); diff --git a/include/configs/at91sam9m10g45ek.h b/include/configs/at91sam9m10g45ek.h index 5d5fbe5853..61f7bc2079 100644 --- a/include/configs/at91sam9m10g45ek.h +++ b/include/configs/at91sam9m10g45ek.h @@ -116,6 +116,20 @@ #endif +/* MMC */ +#define CONFIG_CMD_MMC + +#ifdef CONFIG_CMD_MMC +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_GENERIC_ATMEL_MCI +#endif + +#if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC) +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + /* Ethernet */ #define CONFIG_MACB #define CONFIG_RMII @@ -127,7 +141,6 @@ #define CONFIG_USB_EHCI #define CONFIG_USB_EHCI_ATMEL #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 -#define CONFIG_DOS_PARTITION #define CONFIG_USB_STORAGE #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ -- cgit v1.2.3