Patchwork [U-Boot,v6] arm: ep9315: Return back Cirrus Logic EDB9315A board support

login
register
mail settings
Submitter Sergey Kostanbaev
Date June 25, 2014, 7:44 p.m.
Message ID <1403725469-4358-1-git-send-email-sergey.kostanbaev@gmail.com>
Download mbox | patch
Permalink /patch/364131/
State Accepted
Delegated to: Albert ARIBAUD
Headers show

Comments

Sergey Kostanbaev - June 25, 2014, 7:44 p.m.
This patch returns back support for old ep93xx processors family

Signed-off-by: Sergey Kostanbaev <sergey.kostanbaev@gmail.com>
Cc: albert.u.boot@aribaud.net
---
Changes for v6:
    - Update patch to cleanly apply

Changes for v5:
    - Fix license that dropped during merge
    - Better formatting
    - Update loader script

Changes for v4:
    - Update patch to cleanly apply

Changes for v3:
    - Update makefiles to the new style

Changes for v2:
    - Replace constants in lowlevel_init.S to defines
    - Add more coments in non-trivial places in lowlevel_init.S
    - Get rid of ep93xx_sdram_find_bank in lowlevel_init.S and
      move it to dram_fill_bank_addr in edb93xx.c. This procedure
      may be executed later at any time, so no need to be in lowlevel

 arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S | 465 ++++++++++++++++++++++++++--
 arch/arm/include/asm/arch-ep93xx/ep93xx.h   |  86 +++++
 board/cirrus/edb93xx/Makefile               |  37 +++
 board/cirrus/edb93xx/edb93xx.c              | 382 +++++++++++++++++++++++
 board/cirrus/edb93xx/u-boot.lds             | 106 +++++++
 boards.cfg                                  |   1 +
 drivers/spi/Makefile                        |   1 +
 drivers/spi/ep93xx_spi.c                    | 274 ++++++++++++++++
 drivers/usb/host/Makefile                   |   1 +
 drivers/usb/host/ohci-ep93xx.c              |  38 +++
 include/configs/edb93xx.h                   | 292 +++++++++++++++++
 11 files changed, 1654 insertions(+), 29 deletions(-)
 create mode 100644 board/cirrus/edb93xx/Makefile
 create mode 100644 board/cirrus/edb93xx/edb93xx.c
 create mode 100644 board/cirrus/edb93xx/u-boot.lds
 create mode 100644 drivers/spi/ep93xx_spi.c
 create mode 100644 drivers/usb/host/ohci-ep93xx.c
 create mode 100644 include/configs/edb93xx.h
Albert ARIBAUD - July 4, 2014, 10:22 p.m.
Hi Sergey,

On Wed, 25 Jun 2014 23:44:29 +0400, Sergey Kostanbev
<sergey.kostanbaev@gmail.com> wrote:

> This patch returns back support for old ep93xx processors family
> 
> Signed-off-by: Sergey Kostanbaev <sergey.kostanbaev@gmail.com>
> Cc: albert.u.boot@aribaud.net
> ---
> Changes for v6:
>     - Update patch to cleanly apply
> 
> Changes for v5:
>     - Fix license that dropped during merge
>     - Better formatting
>     - Update loader script
> 
> Changes for v4:
>     - Update patch to cleanly apply
> 
> Changes for v3:
>     - Update makefiles to the new style
> 
> Changes for v2:
>     - Replace constants in lowlevel_init.S to defines
>     - Add more coments in non-trivial places in lowlevel_init.S
>     - Get rid of ep93xx_sdram_find_bank in lowlevel_init.S and
>       move it to dram_fill_bank_addr in edb93xx.c. This procedure
>       may be executed later at any time, so no need to be in lowlevel
> 
>  arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S | 465 ++++++++++++++++++++++++++--
>  arch/arm/include/asm/arch-ep93xx/ep93xx.h   |  86 +++++
>  board/cirrus/edb93xx/Makefile               |  37 +++
>  board/cirrus/edb93xx/edb93xx.c              | 382 +++++++++++++++++++++++
>  board/cirrus/edb93xx/u-boot.lds             | 106 +++++++
>  boards.cfg                                  |   1 +
>  drivers/spi/Makefile                        |   1 +
>  drivers/spi/ep93xx_spi.c                    | 274 ++++++++++++++++
>  drivers/usb/host/Makefile                   |   1 +
>  drivers/usb/host/ohci-ep93xx.c              |  38 +++
>  include/configs/edb93xx.h                   | 292 +++++++++++++++++
>  11 files changed, 1654 insertions(+), 29 deletions(-)
>  create mode 100644 board/cirrus/edb93xx/Makefile
>  create mode 100644 board/cirrus/edb93xx/edb93xx.c
>  create mode 100644 board/cirrus/edb93xx/u-boot.lds
>  create mode 100644 drivers/spi/ep93xx_spi.c
>  create mode 100644 drivers/usb/host/ohci-ep93xx.c
>  create mode 100644 include/configs/edb93xx.h
> 
> diff --git a/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
> index bf2fa2a..3ac0f88 100644
> --- a/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
> +++ b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
> @@ -1,49 +1,458 @@
>  /*
>   * Low-level initialization for EP93xx
>   *
>   * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
> + * Copyright (C) 2013
> + * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
>   *
>   * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de>
> + * Copyright (C) 2006 Cirrus Logic Inc.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
>   *
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> -#include <version.h>
> -#include <asm/arch/ep93xx.h>
> +#include <config.h>
> +#include <asm/arch-ep93xx/ep93xx.h>
> +
> +/*
> +/* Configure the SDRAM based on the supplied settings.
> + *
> + * Input:	r0 - SDRAM DEVCFG register
> + *		r2 - configuration for SDRAM chips
> + * Output:	none
> + * Modifies:	r3, r4
> + */
> +ep93xx_sdram_config:
> +	/* Program the SDRAM device configuration register. */
> +	ldr	r3, =SDRAM_BASE
> +#ifdef CONFIG_EDB93XX_SDCS0
> +	str	r0, [r3, #SDRAM_OFF_DEVCFG0]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS1
> +	str	r0, [r3, #SDRAM_OFF_DEVCFG1]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS2
> +	str	r0, [r3, #SDRAM_OFF_DEVCFG2]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS3
> +	str	r0, [r3, #SDRAM_OFF_DEVCFG3]
> +#endif
> +
> +	/* Set the Initialize and MRS bits (issue continuous NOP commands
> +	 * (INIT & MRS set))
> +	 */
> +	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
> +			EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \
> +			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
> +	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
> +
> +	/* Delay for 200us. */
> +	mov	r4, #0x3000
> +delay1:
> +	subs	r4, r4, #1
> +	bne	delay1
> +
> +	/* Clear the MRS bit to issue a precharge all. */
> +	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
> +			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
> +	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
> +
> +	/* Temporarily set the refresh timer to 0x10. Make it really low so
> +	 * that refresh cycles are generated.
> +	 */
> +	ldr	r4, =0x10
> +	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
> +
> +	/* Delay for at least 80 SDRAM clock cycles. */
> +	mov	r4, #80
> +delay2:
> +	subs	r4, r4, #1
> +	bne	delay2
> +
> +	/* Set the refresh timer to the fastest required for any device
> +	 * that might be used. Set 9.6 ms refresh time.
> +	 */
> +	ldr	r4, =0x01e0
> +	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
> +
> +	/* Select mode register update mode. */
> +	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \
> +			EP93XX_SDRAMCTRL_GLOBALCFG_MRS)
> +	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
> +
> +	/* Program the mode register on the SDRAM by performing fake read */
> +	ldr	r4, [r2]
> +
> +	/* Select normal operating mode. */
> +	ldr	r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE
> +	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
> +
> +	/* Return to the caller. */
> +	mov	pc, lr
> +
> +/*
> + * Test to see if the SDRAM has been configured in a usable mode.
> + *
> + * Input:	r0 - Test address of SDRAM
> + * Output:	r0 - 0 -- Test OK, -1 -- Failed
> + * Modifies:	r0-r5
> + */
> +ep93xx_sdram_test:
> +	/* Load the test patterns to be written to SDRAM. */
> +	ldr	r1, =0xf00dface
> +	ldr	r2, =0xdeadbeef
> +	ldr	r3, =0x08675309
> +	ldr	r4, =0xdeafc0ed
> +
> +	/* Store the test patterns to SDRAM. */
> +	stmia	r0, {r1-r4}
> +
> +	/* Load the test patterns from SDRAM one at a time and compare them
> +	 * to the actual pattern.
> +	 */
> +	ldr	r5, [r0]
> +	cmp	r5, r1
> +	ldreq	r5, [r0, #0x0004]
> +	cmpeq	r5, r2
> +	ldreq	r5, [r0, #0x0008]
> +	cmpeq	r5, r3
> +	ldreq	r5, [r0, #0x000c]
> +	cmpeq	r5, r4
> +
> +	/* Return -1 if a mismatch was encountered, 0 otherwise. */
> +	mvnne	r0, #0xffffffff
> +	moveq	r0, #0x00000000
> +
> +	/* Return to the caller. */
> +	mov	pc, lr
> +
> +/*
> + * Determine the size of the SDRAM. Use data=address for the scan.
> + *
> + * Input:	r0 - Start SDRAM address
> + * Return:	r0 - Single block size
> + *		r1 - Valid block mask
> + *		r2 - Total block count
> + * Modifies:	r0-r5
> + */
> +ep93xx_sdram_size:
> +	/* Store zero at offset zero. */
> +	str	r0, [r0]
> +
> +	/* Start checking for an alias at 1MB into SDRAM. */
> +	ldr	r1, =0x00100000
> +
> +	/* Store the offset at the current offset. */
> +check_block_size:
> +	str	r1, [r0, r1]
> +
> +	/* Read back from zero. */
> +	ldr	r2, [r0]
> +
> +	/* Stop searching of an alias was found. */
> +	cmp	r1, r2
> +	beq	found_block_size
> +
> +	/* Advance to the next power of two boundary. */
> +	mov	r1, r1, lsl #1
> +
> +	/* Loop back if the size has not reached 256MB. */
> +	cmp	r1, #0x10000000
> +	bne	check_block_size
> +
> +	/* A full 256MB of memory was found, so return it now. */
> +	ldr	r0, =0x10000000
> +	ldr	r1, =0x00000000
> +	ldr	r2, =0x00000001
> +	mov	pc, lr
> +
> +	/* An alias was found. See if the first block is 128MB in size. */
> +found_block_size:
> +	cmp	r1, #0x08000000
> +
> +	/* The first block is 128MB, so there is no further memory. Return it
> +	 * now.
> +	 */
> +	ldreq	r0, =0x08000000
> +	ldreq	r1, =0x00000000
> +	ldreq	r2, =0x00000001
> +	moveq	pc, lr
> +
> +	/* Save the block size, set the block address bits to zero, and
> +	 * initialize the block count to one.
> +	 */
> +	mov	r3, r1
> +	ldr	r4, =0x00000000
> +	ldr	r5, =0x00000001
> +
> +	/* Look for additional blocks of memory by searching for non-aliases. */
> +find_blocks:
> +	/* Store zero back to address zero. It may be overwritten. */
> +	str	r0, [r0]
> +
> +	/* Advance to the next power of two boundary. */
> +	mov	r1, r1, lsl #1
> +
> +	/* Store the offset at the current offset. */
> +	str	r1, [r0, r1]
> +
> +	/* Read back from zero. */
> +	ldr	r2, [r0]
> +
> +	/* See if a non-alias was found. */
> +	cmp	r1, r2
> +
> +	/* If a non-alias was found, then or in the block address bit and
> +	 * multiply the block count by two (since there are two unique
> +	 * blocks, one with this bit zero and one with it one).
> +	 */
> +	orrne	r4, r4, r1
> +	movne	r5, r5, lsl #1
> +
> +	/* Continue searching if there are more address bits to check. */
> +	cmp	r1, #0x08000000
> +	bne	find_blocks
> +
> +	/* Return the block size, address mask, and count. */
> +	mov	r0, r3
> +	mov	r1, r4
> +	mov	r2, r5
> +
> +	/* Return to the caller. */
> +	mov	pc, lr
> +
>  
>  .globl lowlevel_init
>  lowlevel_init:
> -	/* backup return address */
> -	ldr r1, =SYSCON_SCRATCH0
> -	str lr, [r1]
>  
> -	/* Turn on both LEDs */
> -	bl red_led_on
> -	bl green_led_on
> +	mov	r6, lr
> +
> +	/* Make sure caches are off and invalidated. */
> +	ldr	r0, =0x00000000
> +	mcr	p15, 0, r0, c1, c0, 0
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +
> +	/* Turn off the green LED and turn on the red LED. If the red LED
> +	 * is left on for too long, the external reset circuit described
> +	 * by application note AN258 will cause the system to reset.
> +	 */
> +	ldr	r1, =EP93XX_LED_DATA
> +	ldr	r0, [r1]
> +	bic	r0, r0, #EP93XX_LED_GREEN_ON
> +	orr	r0, r0, #EP93XX_LED_RED_ON
> +	str	r0, [r1]
> +
> +	/* Undo the silly static memory controller programming performed
> +	 * by the boot rom.
> +	 */
> +	ldr	r0, =SMC_BASE
> +
> +	/* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */
> +	ldr	r1, =0x0000fbe0
> +
> +	/* Reset EP93XX_OFF_SMCBCR0 */
> +	ldr	r2, [r0]
> +	orr	r2, r2, r1
> +	str	r2, [r0]
> +
> +	ldr	r2, [r0, #EP93XX_OFF_SMCBCR1]
> +	orr	r2, r2, r1
> +	str	r2, [r0, #EP93XX_OFF_SMCBCR1]
> +
> +	ldr	r2, [r0, #EP93XX_OFF_SMCBCR2]
> +	orr	r2, r2, r1
> +	str	r2, [r0, #EP93XX_OFF_SMCBCR2]
> +
> +	ldr	r2, [r0, #EP93XX_OFF_SMCBCR3]
> +	orr	r2, r2, r1
> +	str	r2, [r0, #EP93XX_OFF_SMCBCR3]
> +
> +	ldr	r2, [r0, #EP93XX_OFF_SMCBCR6]
> +	orr	r2, r2, r1
> +	str	r2, [r0, #EP93XX_OFF_SMCBCR6]
> +
> +	ldr	r2, [r0, #EP93XX_OFF_SMCBCR7]
> +	orr	r2, r2, r1
> +	str	r2, [r0, #EP93XX_OFF_SMCBCR7]
> +
> +	/* Set the PLL1 and processor clock. */
> +	ldr	r0, =SYSCON_BASE
> +#ifdef CONFIG_EDB9301
> +	/* 332MHz, giving a 166MHz processor clock. */
> +	ldr	r1, = 0x02b49907
> +#else
> +
> +#ifdef CONFIG_EDB93XX_INDUSTRIAL
> +	/* 384MHz, giving a 196MHz processor clock. */
> +	ldr	r1, =0x02a4bb38
> +#else
> +	/* 400MHz, giving a 200MHz processor clock. */
> +	ldr	r1, =0x02a4e39e
> +#endif
> +#endif
> +	str	r1, [r0, #SYSCON_OFF_CLKSET1]
> +
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +
> +	/* Need to make sure that SDRAM is configured correctly before
> +	 * coping the code into it.
> +	 */
> +
> +#ifdef CONFIG_EDB93XX_SDCS0
> +	mov	r11, #SDRAM_DEVCFG0_BASE
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS1
> +	mov	r11, #SDRAM_DEVCFG1_BASE
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS2
> +	mov	r11, #SDRAM_DEVCFG2_BASE
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS3
> +	ldr	r0, =SYSCON_BASE
> +	ldr	r0, [r0, #SYSCON_OFF_SYSCFG]
> +	ands	r0, r0, #SYSCON_SYSCFG_LASDO
> +	moveq	r11, #SDRAM_DEVCFG3_ASD0_BASE
> +	movne	r11, #SDRAM_DEVCFG3_ASD1_BASE
> +#endif
> +	/* See Table 13-5 in EP93xx datasheet for more info about DRAM
> +	 * register mapping */
> +
> +	/* Try a 32-bit wide configuration of SDRAM. */
> +	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
> +			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
> +			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
> +			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2)
> +
> +	/* Set burst count: 4 and CAS: 2
> +	 * Burst mode [A11:A10]; CAS [A16:A14]
> +	 */
> +	orr	r2, r11, #0x00008800
> +	bl	ep93xx_sdram_config
> +
> +	/* Test the SDRAM. */
> +	mov	r0, r11
> +	bl	ep93xx_sdram_test
> +	cmp	r0, #0x00000000
> +	beq	ep93xx_sdram_done
> +
> +	/* Try a 16-bit wide configuration of SDRAM. */
> +	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
> +			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
> +			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
> +			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \
> +			EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH)
> +
> +	/* Set burst count: 8, CAS: 2, sequential burst
> +	 * Accoring to Table 13-3 for 16bit operations mapping must be shifted.
> +	 * Burst mode [A10:A9]; CAS [A15:A13]
> +	 */
> +	orr	r2, r11, #0x00004600
> +	bl	ep93xx_sdram_config
> +
> +	/* Test the SDRAM. */
> +	mov	r0, r11
> +	bl	ep93xx_sdram_test
> +	cmp	r0, #0x00000000
> +	beq	ep93xx_sdram_done
> +
> +	/* Turn off the red LED. */
> +	ldr	r0, =EP93XX_LED_DATA
> +	ldr	r1, [r0]
> +	bic	r1, r1, #EP93XX_LED_RED_ON
> +	str	r1, [r0]
> +
> +	/* There is no SDRAM so flash the green LED. */
> +flash_green:
> +	orr	r1, r1, #EP93XX_LED_GREEN_ON
> +	str	r1, [r0]
> +	ldr	r2, =0x00010000
> +flash_green_delay_1:
> +	subs	r2, r2, #1
> +	bne	flash_green_delay_1
> +	bic	r1, r1, #EP93XX_LED_GREEN_ON
> +	str	r1, [r0]
> +	ldr	r2, =0x00010000
> +flash_green_delay_2:
> +	subs	r2, r2, #1
> +	bne	flash_green_delay_2
> +	orr	r1, r1, #EP93XX_LED_GREEN_ON
> +	str	r1, [r0]
> +	ldr	r2, =0x00010000
> +flash_green_delay_3:
> +	subs	r2, r2, #1
> +	bne	flash_green_delay_3
> +	bic	r1, r1, #EP93XX_LED_GREEN_ON
> +	str	r1, [r0]
> +	ldr	r2, =0x00050000
> +flash_green_delay_4:
> +	subs	r2, r2, #1
> +	bne	flash_green_delay_4
> +	b	flash_green
> +
>  
> -	/* Configure flash wait states before we switch to the PLL */
> -	bl flash_cfg
> +ep93xx_sdram_done:
> +	ldr	r1, =EP93XX_LED_DATA
> +	ldr	r0, [r1]
> +	bic	r0, r0, #EP93XX_LED_RED_ON
> +	str	r0, [r1]
>  
> -	/* Set up PLL */
> -	bl pll_cfg
> +	/* Determine the size of the SDRAM. */
> +	mov	r0, r11
> +	bl	ep93xx_sdram_size
>  
> -	/* Turn off the Green LED and leave the Red LED on */
> -	bl green_led_off
> +	/* Save the SDRAM characteristics. */
> +	mov	r8, r0
> +	mov	r9, r1
> +	mov	r10, r2
>  
> -	/* Setup SDRAM */
> -	bl sdram_cfg
> +	/* Compute total memory size into r1 */
> +	mul	r1, r8, r10
> +#ifdef CONFIG_EDB93XX_SDCS0
> +	ldr	r2, [r0, #SDRAM_OFF_DEVCFG0]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS1
> +	ldr	r2, [r0, #SDRAM_OFF_DEVCFG1]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS2
> +	ldr	r2, [r0, #SDRAM_OFF_DEVCFG2]
> +#endif
> +#ifdef CONFIG_EDB93XX_SDCS3
> +	ldr	r2, [r0, #SDRAM_OFF_DEVCFG3]
> +#endif
>  
> -	/* Turn on Green LED, Turn off the Red LED */
> -	bl green_led_on
> -	bl red_led_off
> +	/* Consider small DRAM size as:
> +	 * < 32Mb for 32bit bus
> +	 * < 64Mb for 16bit bus
> +	 */
> +	tst	r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH
> +	moveq	r1, r1, lsr #1
> +	cmp	r1, #0x02000000
>  
> -	/* FIXME: we use async mode for now */
> -	mrc p15, 0, r0, c1, c0, 0
> -	orr r0, r0, #0xc0000000
> -	mcr p15, 0, r0, c1, c0, 0
> +#if defined(CONFIG_EDB9301)
> +	/* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */
> +	movlt	r1, #0x03f0
> +	movge	r1, #0x01e0
> +#else
> +	/* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */
> +	movlt	r1, #0x0600
> +	movge	r1, #0x2f0
> +#endif
> +	str	r1, [r0, #SDRAM_OFF_REFRSHTIMR]
>  
> -	/* restore return address */
> -	ldr r1, =SYSCON_SCRATCH0
> -	ldr lr, [r1]
> +	/* Save the memory configuration information. */
> +	orr	r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE
> +	stmia	r0, {r8-r11}
>  
> -	mov pc, lr
> +	mov	lr, r6
> +	mov	pc, lr
> diff --git a/arch/arm/include/asm/arch-ep93xx/ep93xx.h b/arch/arm/include/asm/arch-ep93xx/ep93xx.h
> index 9e7f2f3..71aa601 100644
> --- a/arch/arm/include/asm/arch-ep93xx/ep93xx.h
> +++ b/arch/arm/include/asm/arch-ep93xx/ep93xx.h
> @@ -1,6 +1,9 @@
>  /*
>   * Cirrus Logic EP93xx register definitions.
>   *
> + * Copyright (C) 2013
> + * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
> + *
>   * Copyright (C) 2009
>   * Matthias Kaehlcke <matthias@kaehlcke.net>
>   *
> @@ -287,6 +290,20 @@ struct sdram_regs {
>  #define SDRAM_DEVCFG_CASLAT_2		0x00010000
>  #define SDRAM_DEVCFG_RASTOCAS_2		0x00200000
>  
> +#define SDRAM_OFF_GLCONFIG		0x0004
> +#define SDRAM_OFF_REFRSHTIMR		0x0008
> +
> +#define SDRAM_OFF_DEVCFG0		0x0010
> +#define SDRAM_OFF_DEVCFG1		0x0014
> +#define SDRAM_OFF_DEVCFG2		0x0018
> +#define SDRAM_OFF_DEVCFG3		0x001C
> +
> +#define SDRAM_DEVCFG0_BASE		0xC0000000
> +#define SDRAM_DEVCFG1_BASE		0xD0000000
> +#define SDRAM_DEVCFG2_BASE		0xE0000000
> +#define SDRAM_DEVCFG3_ASD0_BASE		0xF0000000
> +#define SDRAM_DEVCFG3_ASD1_BASE		0x00000000
> +
>  #define GLCONFIG_INIT			(1 << 0)
>  #define GLCONFIG_MRS			(1 << 1)
>  #define GLCONFIG_SMEMBUSY		(1 << 5)
> @@ -295,6 +312,43 @@ struct sdram_regs {
>  #define GLCONFIG_CLKSHUTDOWN		(1 << 30)
>  #define GLCONFIG_CKE			(1 << 31)
>  
> +#define EP93XX_SDRAMCTRL			0x80060000
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_INIT		0x00000001
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_MRS		0x00000002
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_SMEMBUSY	0x00000020
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_LCR		0x00000040
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_REARBEN	0x00000080
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_CLKSHUTDOWN	0x40000000
> +#define EP93XX_SDRAMCTRL_GLOBALCFG_CKE		0x80000000
> +
> +#define EP93XX_SDRAMCTRL_REFRESH_MASK		0x0000FFFF
> +
> +#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_32	0x00000002
> +#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_16	0x00000001
> +#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_8	0x00000000
> +#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_MASK	0x00000003
> +#define EP93XX_SDRAMCTRL_BOOTSTATUS_MEDIA	0x00000004
> +
> +#define EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH	0x00000004
> +#define EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT	0x00000008
> +#define EP93XX_SDRAMCTRL_DEVCFG_SROM512		0x00000010
> +#define EP93XX_SDRAMCTRL_DEVCFG_SROMLL		0x00000020
> +#define EP93XX_SDRAMCTRL_DEVCFG_2KPAGE		0x00000040
> +#define EP93XX_SDRAMCTRL_DEVCFG_SFCONFIGADDR	0x00000080
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_MASK	0x00070000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2	0x00010000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_3	0x00020000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_4	0x00030000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_5	0x00040000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_6	0x00050000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_7	0x00060000
> +#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_8	0x00070000
> +#define EP93XX_SDRAMCTRL_DEVCFG_WBL		0x00080000
> +#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_MASK	0x00300000
> +#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2	0x00200000
> +#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_3	0x00300000
> +#define EP93XX_SDRAMCTRL_DEVCFG_AUTOPRECHARGE	0x01000000
> +
>  /*
>   * 0x80070000 - 0x8007FFFF: Reserved
>   */
> @@ -324,6 +378,13 @@ struct smc_regs {
>  };
>  #endif
>  
> +#define EP93XX_OFF_SMCBCR0		0x00
> +#define EP93XX_OFF_SMCBCR1		0x04
> +#define EP93XX_OFF_SMCBCR2		0x08
> +#define EP93XX_OFF_SMCBCR3		0x0C
> +#define EP93XX_OFF_SMCBCR6		0x18
> +#define EP93XX_OFF_SMCBCR7		0x1C
> +
>  #define SMC_BCR_IDCY_SHIFT	0
>  #define SMC_BCR_WST1_SHIFT	5
>  #define SMC_BCR_BLE		(1 << 10)
> @@ -445,6 +506,14 @@ struct gpio_regs {
>  };
>  #endif
>  
> +#define EP93XX_LED_DATA		0x80840020
> +#define EP93XX_LED_GREEN_ON	0x0001
> +#define EP93XX_LED_RED_ON	0x0002
> +
> +#define EP93XX_LED_DDR		0x80840024
> +#define EP93XX_LED_GREEN_ENABLE	0x0001
> +#define EP93XX_LED_RED_ENABLE	0x00020000
> +
>  /*
>   * 0x80850000 - 0x8087FFFF: Reserved
>   */
> @@ -519,6 +588,9 @@ struct gpio_regs {
>  #define SYSCON_OFFSET		0x930000
>  #define SYSCON_BASE		(EP93XX_APB_BASE | SYSCON_OFFSET)
>  
> +/* Security */
> +#define SECURITY_EXTENSIONID	0x80832714
> +
>  #ifndef __ASSEMBLY__
>  struct syscon_regs {
>  	uint32_t pwrsts;
> @@ -553,7 +625,11 @@ struct syscon_regs {
>  #define SYSCON_SCRATCH0		(SYSCON_BASE + 0x0040)
>  #endif
>  
> +#define SYSCON_OFF_CLKSET1			0x0020
> +#define SYSCON_OFF_SYSCFG			0x009c
> +
>  #define SYSCON_PWRCNT_UART_BAUD			(1 << 29)
> +#define SYSCON_PWRCNT_USH_EN			(1 << 28)
>  
>  #define SYSCON_CLKSET_PLL_X2IPD_SHIFT		0
>  #define SYSCON_CLKSET_PLL_X2FBD2_SHIFT		5
> @@ -571,6 +647,8 @@ struct syscon_regs {
>  #define SYSCON_CHIPID_REV_MASK			0xF0000000
>  #define SYSCON_DEVICECFG_SWRST			(1 << 31)
>  
> +#define SYSCON_SYSCFG_LASDO			0x00000020
> +
>  /*
>   * 0x80930000 - 0x8093FFFF: Watchdog Timer
>   */
> @@ -580,3 +658,10 @@ struct syscon_regs {
>  /*
>   * 0x80950000 - 0x9000FFFF: Reserved
>   */
> +
> +/*
> + * During low_level init we store memory layout in memory at specific location
> + */
> +#define UBOOT_MEMORYCNF_BANK_SIZE		0x2000
> +#define UBOOT_MEMORYCNF_BANK_MASK		0x2004
> +#define UBOOT_MEMORYCNF_BANK_COUNT		0x2008
> diff --git a/board/cirrus/edb93xx/Makefile b/board/cirrus/edb93xx/Makefile
> new file mode 100644
> index 0000000..d03c498
> --- /dev/null
> +++ b/board/cirrus/edb93xx/Makefile
> @@ -0,0 +1,11 @@
> +#
> +# (C) Copyright 2013
> +# Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
> +#
> +# (C) Copyright 2003-2006
> +# Wolfgang Denk, DENX Software Engineering, wd <at> denx.de.
> +#
> +# * SPDX-License-Identifier:	GPL-2.0+
> +#
> +
> +obj-y	:= edb93xx.o
> diff --git a/board/cirrus/edb93xx/edb93xx.c b/board/cirrus/edb93xx/edb93xx.c
> new file mode 100644
> index 0000000..8963d3a
> --- /dev/null
> +++ b/board/cirrus/edb93xx/edb93xx.c
> @@ -0,0 +1,382 @@
> +/*
> + * Board initialization for EP93xx
> + *
> + * Copyright (C) 2013
> + * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
> + *
> + * Copyright (C) 2009
> + * Matthias Kaehlcke <matthias <at> kaehlcke.net>
> + *
> + * (C) Copyright 2002 2003
> + * Network Audio Technologies, Inc. <www.netaudiotech.com>
> + * Adam Bezanson <bezanson <at> netaudiotech.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +#include <netdev.h>
> +#include <asm/io.h>
> +#include <asm/arch/ep93xx.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * usb_div: 4, nbyp2: 1, pll2_en: 1
> + * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000,
> + * pll2_x2: 384000000.000000, pll2_out: 192000000.000000
> + */
> +#define CLKSET2_VAL	(23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT |	\
> +			24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT |	\
> +			24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT |	\
> +			1 << SYSCON_CLKSET_PLL_PS_SHIFT |	\
> +			SYSCON_CLKSET2_PLL2_EN |		\
> +			SYSCON_CLKSET2_NBYP2 |			\
> +			3 << SYSCON_CLKSET2_USB_DIV_SHIFT)
> +
> +#define SMC_BCR6_VALUE	(2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
> +			SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \
> +			1 << SMC_BCR_MW_SHIFT)
> +
> +/* delay execution before timers are initialized */
> +static inline void early_udelay(uint32_t usecs)
> +{
> +	/* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */
> +	register uint32_t loops = (usecs * 1000) / 20;
> +
> +	__asm__ volatile ("1:\n"
> +			"subs %0, %1, #1\n"
> +			"bne 1b" : "=r" (loops) : "0" (loops));
> +}
> +
> +#ifndef CONFIG_EP93XX_NO_FLASH_CFG
> +static void flash_cfg(void)
> +{
> +	struct smc_regs *smc = (struct smc_regs *)SMC_BASE;
> +
> +	writel(SMC_BCR6_VALUE, &smc->bcr6);
> +}
> +#else
> +#define flash_cfg()
> +#endif
> +
> +int board_init(void)
> +{
> +	/*
> +	 * Setup PLL2, PPL1 has been set during lowlevel init
> +	 */
> +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
> +	writel(CLKSET2_VAL, &syscon->clkset2);
> +
> +	/*
> +	 * the user's guide recommends to wait at least 1 ms for PLL2 to
> +	 * stabilize
> +	 */
> +	early_udelay(1000);
> +
> +	/* Go to Async mode */
> +	__asm__ volatile ("mrc p15, 0, r0, c1, c0, 0");
> +	__asm__ volatile ("orr r0, r0, #0xc0000000");
> +	__asm__ volatile ("mcr p15, 0, r0, c1, c0, 0");
> +
> +	icache_enable();
> +
> +#ifdef USE_920T_MMU
> +	dcache_enable();
> +#endif
> +
> +	/* Machine number, as defined in linux/arch/arm/tools/mach-types */
> +	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
> +
> +	/* adress of boot parameters */
> +	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
> +
> +	/* We have a console */
> +	gd->have_console = 1;
> +
> +	enable_interrupts();
> +
> +	flash_cfg();
> +
> +	green_led_on();
> +	red_led_off();
> +
> +	return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +	/*
> +	 * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of
> +	 * 14.7456/2 MHz
> +	 */
> +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
> +	writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt);
> +	return 0;
> +}
> +
> +int board_eth_init(bd_t *bd)
> +{
> +	return ep93xx_eth_initialize(0, MAC_BASE);
> +}
> +
> +static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt,
> +				unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS])
> +{
> +	if (dram_bank_cnt == 1) {
> +		dram_bank_base[0] = PHYS_SDRAM_1;
> +	} else {
> +		/* Table lookup for holes in address space. Maximum memory
> +		 * for the single SDCS may be up to 256Mb. We start scanning
> +		 * banks from 1Mb, so it could be up to 128 banks theoretically.
> +		 * We need at maximum 7 bits for the loockup, 8 slots is
> +		 * enough for the worst case.
> +		 */
> +		unsigned tbl[8];
> +		unsigned i = dram_bank_cnt / 2;
> +		unsigned j = 0x00100000; /* 1 Mb */
> +		unsigned *ptbl = tbl;
> +		do {
> +			while (!(dram_addr_mask & j)) {
> +				j <<= 1;
> +			}
> +			*ptbl++ = j;
> +			j <<= 1;
> +			i >>= 1;
> +		} while (i != 0);
> +
> +		for (i = dram_bank_cnt, j = 0;
> +		     (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) {
> +			unsigned addr = PHYS_SDRAM_1;
> +			unsigned k;
> +			unsigned bit;
> +
> +			for (k = 0, bit = 1; k < 8; k++, bit <<= 1) {
> +				if (bit & j)
> +					addr |= tbl[k];
> +			}
> +
> +			dram_bank_base[j] = addr;
> +		}
> +	}
> +}
> +
> +/* called in board_init_f (before relocation) */
> +static unsigned dram_init_banksize_int(int print)
> +{
> +	/*
> +	 * Collect information of banks that has been filled during lowlevel
> +	 * initialization
> +	 */
> +	unsigned i;
> +	unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS];
> +	unsigned dram_total = 0;
> +	unsigned dram_bank_size = *(unsigned *)
> +				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE);
> +	unsigned dram_addr_mask = *(unsigned *)
> +				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK);
> +	unsigned dram_bank_cnt = *(unsigned *)
> +				 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT);
> +
> +	dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base);
> +
> +	for (i = 0; i < dram_bank_cnt; i++) {
> +		gd->bd->bi_dram[i].start = dram_bank_base[i];
> +		gd->bd->bi_dram[i].size = dram_bank_size;
> +		dram_total += dram_bank_size;
> +	}
> +	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
> +		gd->bd->bi_dram[i].start = 0;
> +		gd->bd->bi_dram[i].size = 0;
> +	}
> +
> +	if (print) {
> +		printf("DRAM mask: %08x\n", dram_addr_mask);
> +		printf("DRAM total %u banks:\n", dram_bank_cnt);
> +		printf("bank          base-address          size\n");
> +
> +		if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) {
> +			printf("WARNING! UBoot was configured for %u banks,\n"
> +				"but %u has been found. "
> +				"Supressing extra memory banks\n",
> +				 CONFIG_NR_DRAM_BANKS, dram_bank_cnt);
> +			dram_bank_cnt = CONFIG_NR_DRAM_BANKS;
> +		}
> +
> +		for (i = 0; i < dram_bank_cnt; i++) {
> +			printf("  %u             %08x            %08x\n",
> +			       i, dram_bank_base[i], dram_bank_size);
> +		}
> +		printf("  ------------------------------------------\n"
> +			"Total                              %9d\n\n",
> +			dram_total);
> +	}
> +
> +	return dram_total;
> +}
> +
> +void dram_init_banksize(void)
> +{
> +	dram_init_banksize_int(0);
> +}
> +
> +/* called in board_init_f (before relocation) */
> +int dram_init(void)
> +{
> +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
> +	unsigned sec_id = readl(SECURITY_EXTENSIONID);
> +	unsigned chip_id = readl(&syscon->chipid);
> +
> +	printf("CPU: Cirrus Logic ");
> +	switch (sec_id & 0x000001FE) {
> +	case 0x00000008:
> +		printf("EP9301");
> +		break;
> +	case 0x00000004:
> +		printf("EP9307");
> +		break;
> +	case 0x00000002:
> +		printf("EP931x");
> +		break;
> +	case 0x00000000:
> +		printf("EP9315");
> +		break;
> +	default:
> +		printf("<unknown>");
> +		break;
> +	}
> +
> +	printf(" - Rev. ");
> +	switch (chip_id & 0xF0000000) {
> +	case 0x00000000:
> +		printf("A");
> +		break;
> +	case 0x10000000:
> +		printf("B");
> +		break;
> +	case 0x20000000:
> +		printf("C");
> +		break;
> +	case 0x30000000:
> +		printf("D0");
> +		break;
> +	case 0x40000000:
> +		printf("D1");
> +		break;
> +	case 0x50000000:
> +		printf("E0");
> +		break;
> +	case 0x60000000:
> +		printf("E1");
> +		break;
> +	case 0x70000000:
> +		printf("E2");
> +		break;
> +	default:
> +		printf("?");
> +		break;
> +	}
> +	printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id);
> +
> +	gd->ram_size = dram_init_banksize_int(1);
> +	return 0;
> +}
> +
> +
> +#ifdef CONFIG_EP93XX_SPI
> +#include <spi.h>
> +
> +/*
> + * EGIO0-EGIPO7 -> port A
> + * EGIO8-EGIP15 -> port B
> + */
> +
> +static void ep93xx_set_epgio(unsigned num)
> +{
> +	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
> +	if (num < 8)
> +		writel(readl(&regs->padr) | (1<<num), &regs->padr);
> +	else
> +		writel(readl(&regs->pbdr) | (1<<(num-8)), &regs->pbdr);
> +}
> +
> +static void ep93xx_clear_epgio(unsigned num)
> +{
> +	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
> +	if (num < 8)
> +		writel(readl(&regs->padr) & (~(1<<num)), &regs->padr);
> +	else
> +		writel(readl(&regs->pbdr) & (~(1<<(num-8))), &regs->pbdr);
> +}
> +
> +static void ep93xx_dir_epgio_out(unsigned num)
> +{
> +	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
> +	if (num < 8)
> +		writel(readl(&regs->paddr) | (1<<num), &regs->paddr);
> +	else
> +		writel(readl(&regs->pbddr) | (1<<(num-8)), &regs->pbddr);
> +}
> +
> +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
> +{
> +	if (bus == 0 && cs < 16)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +void spi_cs_activate(struct spi_slave *slave)
> +{
> +	ep93xx_clear_epgio(slave->cs);
> +}
> +
> +void spi_cs_deactivate(struct spi_slave *slave)
> +{
> +	ep93xx_set_epgio(slave->cs);
> +}
> +
> +#ifdef CONFIG_MMC_SPI
> +#include <mmc.h>
> +
> +#ifndef CONFIG_MMC_SPI_CS_EPGIO
> +# define CONFIG_MMC_SPI_CS_EPGIO	4
> +#endif
> +
> +#ifndef CONFIG_MMC_SPI_SPEED
> +# define CONFIG_MMC_SPI_SPEED		25000000
> +#endif
> +
> +#ifndef CONFIG_MMC_SPI_MODE
> +# define CONFIG_MMC_SPI_MODE		SPI_MODE_0
> +#endif
> +
> +int board_mmc_init(bd_t *bis)
> +{
> +	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
> +
> +	ep93xx_set_epgio(CONFIG_MMC_SPI_CS_EPGIO);
> +	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_CS_EPGIO);
> +
> +#ifdef CONFIG_MMC_SPI_POWER_EGPIO
> +	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_POWER_EGPIO);
> +	ep93xx_set_epgio(CONFIG_MMC_SPI_POWER_EGPIO);
> +#elif defined(CONFIG_MMC_SPI_NPOWER_EGPIO)
> +	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_NPOWER_EGPIO);
> +	ep93xx_clear_epgio(CONFIG_MMC_SPI_NPOWER_EGPIO);
> +#endif
> +	struct mmc *mmc = mmc_spi_init(0, CONFIG_MMC_SPI_CS_EPGIO,
> +				CONFIG_MMC_SPI_SPEED, CONFIG_MMC_SPI_MODE);
> +
> +	if (!mmc) {
> +		printf("Failed to create MMC Device\n");
> +		return 1;
> +	}
> +	mmc_init(mmc);
> +	return 0;
> +}
> +
> +
> +#endif /* CONFIG_MMC_SPI */
> +#endif /* CONFIG_EP93XX_SPI */
> diff --git a/board/cirrus/edb93xx/u-boot.lds b/board/cirrus/edb93xx/u-boot.lds
> new file mode 100644
> index 0000000..e61aa36
> --- /dev/null
> +++ b/board/cirrus/edb93xx/u-boot.lds
> @@ -0,0 +1,115 @@
> +/*
> + *
> + * Copyright (C) 2013
> + * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
> + *
> + * Copyright (c) 2004-2008 Texas Instruments
> + *
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> +OUTPUT_ARCH(arm)
> +ENTRY(_start)
> +SECTIONS
> +{
> +	. = 0x00000000;
> +
> +	. = ALIGN(4);
> +	.text : {
> +		*(.__image_copy_start)
> +		arch/arm/cpu/arm920t/start.o (.text*)
> +		. = 0x1000;
> +
> +		LONG(0x53555243)
> +		*(.text*)
> +	}
> +
> +	. = ALIGN(4);
> +	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
> +
> +	. = ALIGN(4);
> +	.data : {
> +		*(.data*)
> +	}
> +
> +	. = ALIGN(4);
> +
> +	. = .;
> +
> +	. = ALIGN(4);
> +	.u_boot_list : {
> +		KEEP(*(SORT(.u_boot_list*)));
> +	}
> +
> +	. = ALIGN(4);
> +
> +	.image_copy_end :
> +	{
> +		*(.__image_copy_end)
> +	}
> +
> +	.rel_dyn_start :
> +	{
> +		*(.__rel_dyn_start)
> +	}
> +
> +	.rel.dyn : {
> +		*(.rel*)
> +	}
> +
> +	.rel_dyn_end :
> +	{
> +		*(.__rel_dyn_end)
> +	}
> +
> +	.end :
> +	{
> +		*(.__end)
> +	}
> +
> +	_image_binary_end = .;
> +
> +	/*
> +	 * Deprecated: this MMU section is used by pxa at present but
> +	 * should not be used by new boards/CPUs.
> +	 */
> +	. = ALIGN(4096);
> +	.mmutable : {
> +		*(.mmutable)
> +	}
> +
> +/*
> + * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
> + * __bss_base and __bss_limit are for linker only (overlay ordering)
> + */
> +
> +	.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));
> +	}
> +
> +	.dynsym _image_binary_end : { *(.dynsym) }
> +	.dynbss : { *(.dynbss) }
> +	.dynstr : { *(.dynstr*) }
> +	.dynamic : { *(.dynamic*) }
> +	.plt : { *(.plt*) }
> +	.interp : { *(.interp*) }
> +	.gnu.hash : { *(.gnu.hash) }
> +	.gnu : { *(.gnu*) }
> +	.ARM.exidx : { *(.ARM.exidx*) }
> +	.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
> +}
> diff --git a/boards.cfg b/boards.cfg
> index 2128996..4c5f1b8 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -74,6 +74,7 @@ Active  arm         arm920t        ks8695      -               -
>  Active  arm         arm920t        ks8695      -               -                   cm41xx                                -                                                                                                                                 -
>  Active  arm         arm920t        s3c24x0     mpl             vcma9               VCMA9                                 -                                                                                                                                 David Müller <d.mueller@elsoft.ch>
>  Active  arm         arm920t        s3c24x0     samsung         -                   smdk2410                              -                                                                                                                                 David Müller <d.mueller@elsoft.ch>
> +Active  arm         arm920t        ep93xx      cirrus          edb93xx             edb9315a                              edb93xx:MK_edb9315a                                                                                                               Sergey Kostanbaev <sergey.kostanbaev@fairwaves.ru>
>  Active  arm         arm926ejs      -           armltd          integrator          integratorap_cm926ejs                 integratorap:CM926EJ_S                                                                                                            Linus Walleij <linus.walleij@linaro.org>
>  Active  arm         arm926ejs      -           armltd          integrator          integratorcp_cm926ejs                 integratorcp:CM924EJ_S                                                                                                            Linus Walleij <linus.walleij@linaro.org>
>  Active  arm         arm926ejs      armada100   Marvell         -                   aspenite                              -                                                                                                                                 Prafulla Wadaskar <prafulla@marvell.com>
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index ed4ecd7..c5d6c6a 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -8,6 +8,7 @@
>  # There are many options which enable SPI, so make this library available
>  obj-y += spi.o
>  
> +obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o
>  obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
>  obj-$(CONFIG_ANDES_SPI) += andes_spi.o
>  obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
> diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c
> new file mode 100644
> index 0000000..235557e
> --- /dev/null
> +++ b/drivers/spi/ep93xx_spi.c
> @@ -0,0 +1,274 @@
> +/*
> + * SPI Driver for EP93xx
> + *
> + * Copyright (C) 2013 Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
> + *
> + * Inspired form linux kernel driver and atmel uboot driver
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <spi.h>
> +#include <malloc.h>
> +
> +#include <asm/io.h>
> +
> +#include <asm/arch/ep93xx.h>
> +
> +
> +#define BIT(x)			(1<<(x))
> +#define SSPBASE			SPI_BASE
> +
> +#define SSPCR0			0x0000
> +#define SSPCR0_MODE_SHIFT	6
> +#define SSPCR0_SCR_SHIFT	8
> +#define SSPCR0_SPH		BIT(7)
> +#define SSPCR0_SPO		BIT(6)
> +#define SSPCR0_FRF_SPI		0
> +#define SSPCR0_DSS_8BIT		7
> +
> +#define SSPCR1			0x0004
> +#define SSPCR1_RIE		BIT(0)
> +#define SSPCR1_TIE		BIT(1)
> +#define SSPCR1_RORIE		BIT(2)
> +#define SSPCR1_LBM		BIT(3)
> +#define SSPCR1_SSE		BIT(4)
> +#define SSPCR1_MS		BIT(5)
> +#define SSPCR1_SOD		BIT(6)
> +
> +#define SSPDR			0x0008
> +
> +#define SSPSR			0x000c
> +#define SSPSR_TFE		BIT(0)
> +#define SSPSR_TNF		BIT(1)
> +#define SSPSR_RNE		BIT(2)
> +#define SSPSR_RFF		BIT(3)
> +#define SSPSR_BSY		BIT(4)
> +#define SSPCPSR			0x0010
> +
> +#define SSPIIR			0x0014
> +#define SSPIIR_RIS		BIT(0)
> +#define SSPIIR_TIS		BIT(1)
> +#define SSPIIR_RORIS		BIT(2)
> +#define SSPICR			SSPIIR
> +
> +#define SSPCLOCK		14745600
> +#define SSP_MAX_RATE		(SSPCLOCK / 2)
> +#define SSP_MIN_RATE		(SSPCLOCK / (254 * 256))
> +
> +/* timeout in milliseconds */
> +#define SPI_TIMEOUT		5
> +/* maximum depth of RX/TX FIFO */
> +#define SPI_FIFO_SIZE		8
> +
> +struct ep93xx_spi_slave {
> +	struct spi_slave slave;
> +
> +	unsigned sspcr0;
> +	unsigned sspcpsr;
> +};
> +
> +static inline struct ep93xx_spi_slave *to_ep93xx_spi(struct spi_slave *slave)
> +{
> +	return container_of(slave, struct ep93xx_spi_slave, slave);
> +}
> +
> +void spi_init()
> +{
> +}
> +
> +static inline void ep93xx_spi_write_u8(u16 reg, u8 value)
> +{
> +	writel(value, (unsigned int *)(SSPBASE + reg));
> +}
> +
> +static inline u8 ep93xx_spi_read_u8(u16 reg)
> +{
> +	return readl((unsigned int *)(SSPBASE + reg));
> +}
> +
> +static inline void ep93xx_spi_write_u16(u16 reg, u16 value)
> +{
> +	writel(value, (unsigned int *)(SSPBASE + reg));
> +}
> +
> +static inline u16 ep93xx_spi_read_u16(u16 reg)
> +{
> +	return (u16)readl((unsigned int *)(SSPBASE + reg));
> +}
> +
> +static int ep93xx_spi_init_hw(unsigned int rate, unsigned int mode,
> +				struct ep93xx_spi_slave *slave)
> +{
> +	unsigned cpsr, scr;
> +
> +	if (rate > SSP_MAX_RATE)
> +		rate = SSP_MAX_RATE;
> +
> +	if (rate < SSP_MIN_RATE)
> +		return -1;
> +
> +	/* Calculate divisors so that we can get speed according the
> +	 * following formula:
> +	 *	rate = spi_clock_rate / (cpsr * (1 + scr))
> +	 *
> +	 * cpsr must be even number and starts from 2, scr can be any number
> +	 * between 0 and 255.
> +	 */
> +	for (cpsr = 2; cpsr <= 254; cpsr += 2) {
> +		for (scr = 0; scr <= 255; scr++) {
> +			if ((SSPCLOCK / (cpsr * (scr + 1))) <= rate) {
> +				/* Set CHPA and CPOL, SPI format and 8bit */
> +				unsigned sspcr0 = (scr << SSPCR0_SCR_SHIFT) |
> +					SSPCR0_FRF_SPI | SSPCR0_DSS_8BIT;
> +				if (mode & SPI_CPHA)
> +					sspcr0 |= SSPCR0_SPH;
> +				if (mode & SPI_CPOL)
> +					sspcr0 |= SSPCR0_SPO;
> +
> +				slave->sspcr0 = sspcr0;
> +				slave->sspcpsr = cpsr;
> +				return 0;
> +			}
> +		}
> +	}
> +
> +	return -1;
> +}
> +
> +void spi_set_speed(struct spi_slave *slave, unsigned int hz)
> +{
> +	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
> +
> +	unsigned int mode = 0;
> +	if (as->sspcr0 & SSPCR0_SPH)
> +		mode |= SPI_CPHA;
> +	if (as->sspcr0 & SSPCR0_SPO)
> +		mode |= SPI_CPOL;
> +
> +	ep93xx_spi_init_hw(hz, mode, as);
> +}
> +
> +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
> +			unsigned int max_hz, unsigned int mode)
> +{
> +	struct ep93xx_spi_slave	*as;
> +
> +	if (!spi_cs_is_valid(bus, cs))
> +		return NULL;
> +
> +	as = spi_alloc_slave(struct ep93xx_spi_slave, bus, cs);
> +	if (!as)
> +		return NULL;
> +
> +	if (ep93xx_spi_init_hw(max_hz, mode, as)) {
> +		free(as);
> +		return NULL;
> +	}
> +
> +	return &as->slave;
> +}
> +
> +void spi_free_slave(struct spi_slave *slave)
> +{
> +	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
> +
> +	free(as);
> +}
> +
> +int spi_claim_bus(struct spi_slave *slave)
> +{
> +	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
> +
> +	/* Enable the SPI hardware */
> +	ep93xx_spi_write_u8(SSPCR1, SSPCR1_SSE);
> +
> +
> +	ep93xx_spi_write_u8(SSPCPSR, as->sspcpsr);
> +	ep93xx_spi_write_u16(SSPCR0, as->sspcr0);
> +
> +	debug("Select CS:%d SSPCPSR=%02x SSPCR0=%04x\n",
> +	      slave->cs, as->sspcpsr, as->sspcr0);
> +	return 0;
> +}
> +
> +void spi_release_bus(struct spi_slave *slave)
> +{
> +	/* Disable the SPI hardware */
> +	ep93xx_spi_write_u8(SSPCR1, 0);
> +}
> +
> +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
> +		const void *dout, void *din, unsigned long flags)
> +{
> +	unsigned int	len_tx;
> +	unsigned int	len_rx;
> +	unsigned int	len;
> +	u32		status;
> +	const u8	*txp = dout;
> +	u8		*rxp = din;
> +	u8		value;
> +
> +	debug("spi_xfer: slave %u:%u dout %p din %p bitlen %u\n",
> +	      slave->bus, slave->cs, (uint *)dout, (uint *)din, bitlen);
> +
> +
> +	if (bitlen == 0)
> +		/* Finish any previously submitted transfers */
> +		goto out;
> +
> +	if (bitlen % 8) {
> +		/* Errors always terminate an ongoing transfer */
> +		flags |= SPI_XFER_END;
> +		goto out;
> +	}
> +
> +	len = bitlen / 8;
> +
> +
> +	if (flags & SPI_XFER_BEGIN) {
> +		/* Empty RX FIFO */
> +		while ((ep93xx_spi_read_u8(SSPSR) & SSPSR_RNE))
> +			ep93xx_spi_read_u8(SSPDR);
> +
> +		spi_cs_activate(slave);
> +	}
> +
> +	for (len_tx = 0, len_rx = 0; len_rx < len; ) {
> +		status = ep93xx_spi_read_u8(SSPSR);
> +
> +		if ((len_tx < len) && (status & SSPSR_TNF)) {
> +			if (txp)
> +				value = *txp++;
> +			else
> +				value = 0xff;
> +
> +			ep93xx_spi_write_u8(SSPDR, value);
> +			len_tx++;
> +		}
> +
> +		if (status & SSPSR_RNE) {
> +			value = ep93xx_spi_read_u8(SSPDR);
> +
> +			if (rxp)
> +				*rxp++ = value;
> +			len_rx++;
> +		}
> +	}
> +
> +out:
> +	if (flags & SPI_XFER_END) {
> +		/*
> +		 * Wait until the transfer is completely done before
> +		 * we deactivate CS.
> +		 */
> +		do {
> +			status = ep93xx_spi_read_u8(SSPSR);
> +		} while (status & SSPSR_BSY);
> +
> +		spi_cs_deactivate(slave);
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 1417028..5cab359 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
>  obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
>  obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o
>  obj-$(CONFIG_USB_OHCI_S3C24XX) += ohci-s3c24xx.o
> +obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o
>  
>  # echi
>  obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
> diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
> new file mode 100644
> index 0000000..8fb4aba
> --- /dev/null
> +++ b/drivers/usb/host/ohci-ep93xx.c
> @@ -0,0 +1,38 @@
> +/*
> + * (C) Copyright 2013
> + * Sergey Kostanbaev < sergey.kostanbaev <at> fairwaves.ru >
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +
> +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
> +#include <asm/io.h>
> +#include <asm/arch/ep93xx.h>
> +
> +int usb_cpu_init(void)
> +{
> +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
> +	unsigned long pwr = readl(&syscon->pwrcnt);
> +	writel(pwr | SYSCON_PWRCNT_USH_EN, &syscon->pwrcnt);
> +
> +	return 0;
> +}
> +
> +int usb_cpu_stop(void)
> +{
> +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
> +	unsigned long pwr = readl(&syscon->pwrcnt);
> +	writel(pwr &  ~SYSCON_PWRCNT_USH_EN, &syscon->pwrcnt);
> +
> +	return 0;
> +}
> +
> +int usb_cpu_init_fail(void)
> +{
> +	return usb_cpu_stop();
> +}
> +
> +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */
> diff --git a/include/configs/edb93xx.h b/include/configs/edb93xx.h
> new file mode 100644
> index 0000000..37bdcc0
> --- /dev/null
> +++ b/include/configs/edb93xx.h
> @@ -0,0 +1,292 @@
> +/*
> + * U-boot - Configuration file for Cirrus Logic EDB93xx boards
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#ifdef CONFIG_MK_edb9301
> +#define CONFIG_EDB9301
> +#elif defined(CONFIG_MK_edb9302)
> +#define CONFIG_EDB9302
> +#elif defined(CONFIG_MK_edb9302a)
> +#define CONFIG_EDB9302A
> +#elif defined(CONFIG_MK_edb9307)
> +#define CONFIG_EDB9307
> +#elif defined(CONFIG_MK_edb9307a)
> +#define CONFIG_EDB9307A
> +#elif defined(CONFIG_MK_edb9312)
> +#define CONFIG_EDB9312
> +#elif defined(CONFIG_MK_edb9315)
> +#define CONFIG_EDB9315
> +#elif defined(CONFIG_MK_edb9315a)
> +#define CONFIG_EDB9315A
> +#else
> +#error "no board defined"
> +#endif
> +
> +/* Initial environment and monitor configuration options. */
> +#define CONFIG_BOOTDELAY		2
> +#define CONFIG_CMDLINE_TAG		1
> +#define CONFIG_INITRD_TAG		1
> +#define CONFIG_SETUP_MEMORY_TAGS	1
> +#define CONFIG_BOOTARGS		"root=/dev/nfs console=ttyAM0,115200 ip=dhcp"
> +#define CONFIG_BOOTFILE		"edb93xx.img"
> +
> +#define CONFIG_SYS_HUSH_PARSER		1
> +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
> +
> +
> +#define CONFIG_SYS_LDSCRIPT	"board/cirrus/edb93xx/u-boot.lds"
> +
> +
> +#ifdef CONFIG_EDB9301
> +#define CONFIG_EP9301
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9301
> +#define CONFIG_SYS_PROMPT		"EDB9301> "
> +#define CONFIG_ENV_SECT_SIZE		0x00020000
> +#elif defined(CONFIG_EDB9302)
> +#define CONFIG_EP9302
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9302
> +#define CONFIG_SYS_PROMPT		"EDB9302> "
> +#define CONFIG_ENV_SECT_SIZE		0x00020000
> +#elif defined(CONFIG_EDB9302A)
> +#define CONFIG_EP9302
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9302A
> +#define CONFIG_SYS_PROMPT		"EDB9302A> "
> +#define CONFIG_ENV_SECT_SIZE		0x00020000
> +#elif defined(CONFIG_EDB9307)
> +#define CONFIG_EP9307
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9307
> +#define CONFIG_SYS_PROMPT		"EDB9307> "
> +#define CONFIG_ENV_SECT_SIZE		0x00040000
> +#elif defined(CONFIG_EDB9307A)
> +#define CONFIG_EP9307
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9307A
> +#define CONFIG_SYS_PROMPT		"EDB9307A> "
> +#define CONFIG_ENV_SECT_SIZE		0x00020000
> +#elif defined(CONFIG_EDB9312)
> +#define CONFIG_EP9312
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9312
> +#define CONFIG_SYS_PROMPT		"EDB9312> "
> +#define CONFIG_ENV_SECT_SIZE		0x00040000
> +#elif defined(CONFIG_EDB9315)
> +#define CONFIG_EP9315
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9315
> +#define CONFIG_SYS_PROMPT		"EDB9315> "
> +#define CONFIG_ENV_SECT_SIZE		0x00040000
> +#elif defined(CONFIG_EDB9315A)
> +#define CONFIG_EP9315
> +#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9315A
> +#define CONFIG_SYS_PROMPT		"EDB9315A> "
> +#define CONFIG_ENV_SECT_SIZE		0x00020000
> +#else
> +#error "no board defined"
> +#endif
> +
> +/* High-level configuration options */
> +#define CONFIG_ARM920T		1		/* This is an ARM920T core... */
> +#define CONFIG_EP93XX		1		/* in a Cirrus Logic 93xx SoC */
> +
> +#define CONFIG_SYS_CLK_FREQ	14745600	/* EP93xx has a 14.7456 clock */
> +#define CONFIG_SYS_HZ		1000		/* decr freq: 1 ms ticks */
> +#undef CONFIG_USE_IRQ				/* Don't need IRQ/FIQ */
> +
> +/* Monitor configuration */
> +#include <config_cmd_default.h>
> +#undef CONFIG_CMD_FPGA
> +#undef CONFIG_CMD_SETGETDCR
> +#undef CONFIG_CMD_XIMG
> +
> +#undef CONFIG_CMD_DATE
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_JFFS2
> +
> +#define CONFIG_SYS_LONGHELP			/* Enable "long" help in mon */
> +#define CONFIG_SYS_CBSIZE		1024	/* Console I/O buffer size */
> +/* Print buffer size */
> +#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
> +/* Boot argument buffer size */
> +#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
> +#define CONFIG_SYS_MAXARGS	16		/* Max number of command args */
> +
> +/* Serial port hardware configuration */
> +#define CONFIG_PL010_SERIAL
> +#define CONFIG_CONS_INDEX		0
> +#define CONFIG_BAUDRATE			115200
> +#define CONFIG_SYS_BAUDRATE_TABLE	{9600, 19200, 38400, 57600, \
> +                        115200, 230400}
> +#define CONFIG_SYS_SERIAL0		0x808C0000
> +#define CONFIG_SYS_SERIAL1		0x808D0000
> +/*#define CONFIG_PL01x_PORTS	{(void *)CONFIG_SYS_SERIAL0, \
> +            (void *)CONFIG_SYS_SERIAL1} */
> +
> +#define CONFIG_PL01x_PORTS	{(void *)CONFIG_SYS_SERIAL0}
> +
> +/* Status LED */
> +#define CONFIG_STATUS_LED		1 /* Status LED enabled	*/
> +#define CONFIG_BOARD_SPECIFIC_LED	1
> +#define STATUS_LED_GREEN		0
> +#define STATUS_LED_RED			1
> +/* Green */
> +#define STATUS_LED_BIT			STATUS_LED_GREEN
> +#define STATUS_LED_STATE		STATUS_LED_ON
> +#define STATUS_LED_PERIOD		(CONFIG_SYS_HZ / 2)
> +/* Red */
> +#define STATUS_LED_BIT1			STATUS_LED_RED
> +#define STATUS_LED_STATE1		STATUS_LED_OFF
> +#define STATUS_LED_PERIOD1		(CONFIG_SYS_HZ / 2)
> +/* Optional value */
> +#define STATUS_LED_BOOT			STATUS_LED_BIT
> +
> +/* Network hardware configuration */
> +#define CONFIG_DRIVER_EP93XX_MAC
> +#define CONFIG_MII_SUPPRESS_PREAMBLE
> +#define CONFIG_MII
> +#define CONFIG_PHY_ADDR		1
> +#define CONFIG_NET_MULTI
> +#undef CONFIG_NETCONSOLE
> +
> +/* SDRAM configuration */
> +#if defined(CONFIG_EDB9301) || defined(CONFIG_EDB9302) || \
> +    defined(CONFIG_EDB9307) || defined CONFIG_EDB9312 || \
> +    defined(CONFIG_EDB9315)
> +/*
> + * EDB9301/2 has 4 banks of SDRAM consisting of 1x Samsung K4S561632E-TC75
> + * 256 Mbit SDRAM on a 16-bit data bus, for a total of 32MB of SDRAM. We set
> + * the SROMLL bit on the processor, resulting in this non-contiguous memory map.
> + *
> + * The EDB9307, EDB9312, and EDB9315 have 2 banks of SDRAM consisting of
> + * 2x Samsung K4S561632E-TC75 256 Mbit on a 32-bit data bus, for a total of
> + * 64 MB of SDRAM.
> + */
> +
> +#define CONFIG_EDB93XX_SDCS3
> +
> +#elif defined(CONFIG_EDB9302A) || \
> +    defined(CONFIG_EDB9307A) || defined(CONFIG_EDB9315A)
> +/*
> + * EDB9302a has 4 banks of SDRAM consisting of 1x Samsung K4S561632E-TC75
> + * 256 Mbit SDRAM on a 16-bit data bus, for a total of 32MB of SDRAM. We set
> + * the SROMLL bit on the processor, resulting in this non-contiguous memory map.
> + *
> + * The EDB9307A and EDB9315A have 2 banks of SDRAM consisting of 2x Samsung
> + * K4S561632E-TC75 256 Mbit on a 32-bit data bus, for a total of 64 MB of SDRAM.
> + */
> +#define CONFIG_EDB93XX_SDCS0
> +
> +#else
> +#error "no SDCS configuration for this board"
> +#endif
> +
> +
> +#if defined(CONFIG_EDB93XX_SDCS3)
> +#define CONFIG_SYS_LOAD_ADDR	0x01000000	/* Default load address	*/
> +#define PHYS_SDRAM_1		0x00000000
> +#elif defined(CONFIG_EDB93XX_SDCS0)
> +#define CONFIG_SYS_LOAD_ADDR	0xc1000000	/* Default load address	*/
> +#define PHYS_SDRAM_1		0xc0000000
> +#endif
> +
> +#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
> +#define CONFIG_NR_DRAM_BANKS		8
> +
> +#define CONFIG_SYS_INIT_SP_ADDR \
> +    (CONFIG_SYS_SDRAM_BASE + 32*1024 - GENERATED_GBL_DATA_SIZE)
> +
> +
> +/* Must match kernel config */
> +#define LINUX_BOOT_PARAM_ADDR	(PHYS_SDRAM_1 + 0x100)
> +
> +/* Run-time memory allocatons */
> +#define CONFIG_SYS_GBL_DATA_SIZE	128
> +#define CONFIG_STACKSIZE		(128 * 1024)
> +
> +#if defined(CONFIG_USE_IRQ)
> +#define CONFIG_STACKSIZE_IRQ	(4 * 1024)
> +#define CONFIG_STACKSIZE_FIQ	(4 * 1024)
> +#endif
> +
> +#define CONFIG_SYS_MALLOC_LEN		(512 * 1024)
> +
> +/* -----------------------------------------------------------------------------
> + * FLASH and environment organization
> + *
> + * The EDB9301, EDB9302(a), EDB9307a, EDB9315a have 1 bank of flash memory at
> + * 0x60000000 consisting of 1x Intel TE28F128J3C-150 128 Mbit flash on a 16-bit
> + * data bus, for a total of 16 MB of CFI-compatible flash.
> + *
> + * The EDB9307, EDB9312, and EDB9315 have 1 bank of flash memory at
> + * 0x60000000 consisting of 2x Micron MT28F128J3-12 128 Mbit flash on a 32-bit
> + * data bus, for a total of 32 MB of CFI-compatible flash.
> + *
> + *
> + *                            EDB9301/02(a)7a/15a    EDB9307/12/15
> + * 0x60000000 - 0x0003FFFF    u-boot                 u-boot
> + * 0x60040000 - 0x0005FFFF    environment #1         environment #1
> + * 0x60060000 - 0x0007FFFF    environment #2         environment #1 (continued)
> + * 0x60080000 - 0x0009FFFF    unused                 environment #2
> + * 0x600A0000 - 0x000BFFFF    unused                 environment #2 (continued)
> + * 0x600C0000 - 0x00FFFFFF    unused                 unused
> + * 0x61000000 - 0x01FFFFFF    not present            unused
> + */
> +#define CONFIG_SYS_FLASH_CFI
> +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
> +
> +
> +#define CONFIG_SYS_FLASH_PROTECTION
> +#define CONFIG_FLASH_CFI_DRIVER
> +#define CONFIG_SYS_MAX_FLASH_BANKS	1
> +#define CONFIG_SYS_MAX_FLASH_SECT	(256+8)
> +
> +#define CONFIG_SYS_TEXT_BASE		0x60000000
> +#define PHYS_FLASH_1			CONFIG_SYS_TEXT_BASE
> +#define CONFIG_SYS_FLASH_BASE		CONFIG_SYS_TEXT_BASE
> +
> +#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_FLASH_BASE
> +#define CONFIG_SYS_MONITOR_LEN		(256 * 1024)
> +
> +#define CONFIG_ENV_OVERWRITE		/* Vendor params unprotected */
> +#define CONFIG_ENV_IS_IN_FLASH
> +
> +#define CONFIG_ENV_ADDR			0x60040000
> +#define CONFIG_ENV_ADDR_REDUND		(CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
> +
> +#define CONFIG_ENV_SIZE			CONFIG_ENV_SECT_SIZE
> +#define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
> +
> +/* Define to enable MMC on SPI support */
> +/* #define CONFIG_EP93XX_SPI_MMC */
> +
> +#ifdef CONFIG_EP93XX_SPI_MMC
> +#define CONFIG_EP93XX_SPI
> +#define CONFIG_MMC
> +#define CONFIG_GENERIC_MMC
> +#define CONFIG_MMC_SPI
> +#define CONFIG_CMD_MMC
> +#define CONFIG_MMC_SPI_NPOWER_EGPIO	9
> +#endif
> +
> +#define CONFIG_USB_STORAGE
> +#define CONFIG_USB_OHCI_NEW
> +#define CONFIG_USB_OHCI_EP93XX
> +#define CONFIG_SYS_USB_OHCI_CPU_INIT
> +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	3
> +#define CONFIG_SYS_USB_OHCI_SLOT_NAME		"ep93xx-ohci"
> +#define CONFIG_SYS_USB_OHCI_REGS_BASE		0x80020000
> +
> +#define CONFIG_CMD_EXT2
> +#define CONFIG_CMD_EXT4
> +#define CONFIG_CMD_FAT
> +#define CONFIG_CMD_USB
> +
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_CMD_BOOTZ
> +
> +/* Define to disable flash configuration*/
> +/* #define CONFIG_EP93XX_NO_FLASH_CFG */
> +
> +/* Define this for indusrial rated chips */
> +/* #define CONFIG_EDB93XX_INDUSTRIAL */
> +
> +#endif /* !defined (__CONFIG_H) */

Applied to u-boot-arm/master, thanks!

Amicalement,
Masahiro Yamada - July 7, 2014, 10:57 a.m.
Hi. Sergey, Arbert.


On Sat, 5 Jul 2014 00:22:05 +0200
Albert ARIBAUD <albert.u.boot@aribaud.net> wrote:

> Hi Sergey,
> 
> On Wed, 25 Jun 2014 23:44:29 +0400, Sergey Kostanbev
> <sergey.kostanbaev@gmail.com> wrote:
> 
> > This patch returns back support for old ep93xx processors family
> > 
> > Signed-off-by: Sergey Kostanbaev <sergey.kostanbaev@gmail.com>
> > Cc: albert.u.boot@aribaud.net
> > ---
[snip]
> 
> Applied to u-boot-arm/master, thanks!
> 
> Amicalement,
> -- 
> Albert.




I have two questions:

[1] Is this board really working?

This patch added a linker script
board/cirrus/edb93xx/u-boot.lds

But '.vectors' section is missing from it.

In my understanding, commit 41623c91b0 expects '.vectors'
section handling for all ARM linker scripts.


[2] Why was board/cirrus/edb93xx/u-boot.lds added
instead of re-using (or modifying) arch/arm/cpu/arm920t/ep93xx/u-boot.lds ?


'edb9315a' is the only one board with 'ep93xx' SoC.

It means, if you add 'board/cirrus/edb93xx/u-boot.lds',
'arch/arm/cpu/arm920t/ep93xx/u-boot.lds' is never used.

Please delete either of them.




Best Regards
Masahiro Yamada

Patch

diff --git a/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
index bf2fa2a..3ac0f88 100644
--- a/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
+++ b/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
@@ -1,49 +1,458 @@ 
 /*
  * Low-level initialization for EP93xx
  *
  * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ * Copyright (C) 2013
+ * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
  *
  * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de>
+ * Copyright (C) 2006 Cirrus Logic Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#include <version.h>
-#include <asm/arch/ep93xx.h>
+#include <config.h>
+#include <asm/arch-ep93xx/ep93xx.h>
+
+/*
+/* Configure the SDRAM based on the supplied settings.
+ *
+ * Input:	r0 - SDRAM DEVCFG register
+ *		r2 - configuration for SDRAM chips
+ * Output:	none
+ * Modifies:	r3, r4
+ */
+ep93xx_sdram_config:
+	/* Program the SDRAM device configuration register. */
+	ldr	r3, =SDRAM_BASE
+#ifdef CONFIG_EDB93XX_SDCS0
+	str	r0, [r3, #SDRAM_OFF_DEVCFG0]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+	str	r0, [r3, #SDRAM_OFF_DEVCFG1]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+	str	r0, [r3, #SDRAM_OFF_DEVCFG2]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+	str	r0, [r3, #SDRAM_OFF_DEVCFG3]
+#endif
+
+	/* Set the Initialize and MRS bits (issue continuous NOP commands
+	 * (INIT & MRS set))
+	 */
+	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
+			EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \
+			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
+	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+	/* Delay for 200us. */
+	mov	r4, #0x3000
+delay1:
+	subs	r4, r4, #1
+	bne	delay1
+
+	/* Clear the MRS bit to issue a precharge all. */
+	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
+			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
+	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+	/* Temporarily set the refresh timer to 0x10. Make it really low so
+	 * that refresh cycles are generated.
+	 */
+	ldr	r4, =0x10
+	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
+
+	/* Delay for at least 80 SDRAM clock cycles. */
+	mov	r4, #80
+delay2:
+	subs	r4, r4, #1
+	bne	delay2
+
+	/* Set the refresh timer to the fastest required for any device
+	 * that might be used. Set 9.6 ms refresh time.
+	 */
+	ldr	r4, =0x01e0
+	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
+
+	/* Select mode register update mode. */
+	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \
+			EP93XX_SDRAMCTRL_GLOBALCFG_MRS)
+	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+	/* Program the mode register on the SDRAM by performing fake read */
+	ldr	r4, [r2]
+
+	/* Select normal operating mode. */
+	ldr	r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE
+	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+	/* Return to the caller. */
+	mov	pc, lr
+
+/*
+ * Test to see if the SDRAM has been configured in a usable mode.
+ *
+ * Input:	r0 - Test address of SDRAM
+ * Output:	r0 - 0 -- Test OK, -1 -- Failed
+ * Modifies:	r0-r5
+ */
+ep93xx_sdram_test:
+	/* Load the test patterns to be written to SDRAM. */
+	ldr	r1, =0xf00dface
+	ldr	r2, =0xdeadbeef
+	ldr	r3, =0x08675309
+	ldr	r4, =0xdeafc0ed
+
+	/* Store the test patterns to SDRAM. */
+	stmia	r0, {r1-r4}
+
+	/* Load the test patterns from SDRAM one at a time and compare them
+	 * to the actual pattern.
+	 */
+	ldr	r5, [r0]
+	cmp	r5, r1
+	ldreq	r5, [r0, #0x0004]
+	cmpeq	r5, r2
+	ldreq	r5, [r0, #0x0008]
+	cmpeq	r5, r3
+	ldreq	r5, [r0, #0x000c]
+	cmpeq	r5, r4
+
+	/* Return -1 if a mismatch was encountered, 0 otherwise. */
+	mvnne	r0, #0xffffffff
+	moveq	r0, #0x00000000
+
+	/* Return to the caller. */
+	mov	pc, lr
+
+/*
+ * Determine the size of the SDRAM. Use data=address for the scan.
+ *
+ * Input:	r0 - Start SDRAM address
+ * Return:	r0 - Single block size
+ *		r1 - Valid block mask
+ *		r2 - Total block count
+ * Modifies:	r0-r5
+ */
+ep93xx_sdram_size:
+	/* Store zero at offset zero. */
+	str	r0, [r0]
+
+	/* Start checking for an alias at 1MB into SDRAM. */
+	ldr	r1, =0x00100000
+
+	/* Store the offset at the current offset. */
+check_block_size:
+	str	r1, [r0, r1]
+
+	/* Read back from zero. */
+	ldr	r2, [r0]
+
+	/* Stop searching of an alias was found. */
+	cmp	r1, r2
+	beq	found_block_size
+
+	/* Advance to the next power of two boundary. */
+	mov	r1, r1, lsl #1
+
+	/* Loop back if the size has not reached 256MB. */
+	cmp	r1, #0x10000000
+	bne	check_block_size
+
+	/* A full 256MB of memory was found, so return it now. */
+	ldr	r0, =0x10000000
+	ldr	r1, =0x00000000
+	ldr	r2, =0x00000001
+	mov	pc, lr
+
+	/* An alias was found. See if the first block is 128MB in size. */
+found_block_size:
+	cmp	r1, #0x08000000
+
+	/* The first block is 128MB, so there is no further memory. Return it
+	 * now.
+	 */
+	ldreq	r0, =0x08000000
+	ldreq	r1, =0x00000000
+	ldreq	r2, =0x00000001
+	moveq	pc, lr
+
+	/* Save the block size, set the block address bits to zero, and
+	 * initialize the block count to one.
+	 */
+	mov	r3, r1
+	ldr	r4, =0x00000000
+	ldr	r5, =0x00000001
+
+	/* Look for additional blocks of memory by searching for non-aliases. */
+find_blocks:
+	/* Store zero back to address zero. It may be overwritten. */
+	str	r0, [r0]
+
+	/* Advance to the next power of two boundary. */
+	mov	r1, r1, lsl #1
+
+	/* Store the offset at the current offset. */
+	str	r1, [r0, r1]
+
+	/* Read back from zero. */
+	ldr	r2, [r0]
+
+	/* See if a non-alias was found. */
+	cmp	r1, r2
+
+	/* If a non-alias was found, then or in the block address bit and
+	 * multiply the block count by two (since there are two unique
+	 * blocks, one with this bit zero and one with it one).
+	 */
+	orrne	r4, r4, r1
+	movne	r5, r5, lsl #1
+
+	/* Continue searching if there are more address bits to check. */
+	cmp	r1, #0x08000000
+	bne	find_blocks
+
+	/* Return the block size, address mask, and count. */
+	mov	r0, r3
+	mov	r1, r4
+	mov	r2, r5
+
+	/* Return to the caller. */
+	mov	pc, lr
+
 
 .globl lowlevel_init
 lowlevel_init:
-	/* backup return address */
-	ldr r1, =SYSCON_SCRATCH0
-	str lr, [r1]
 
-	/* Turn on both LEDs */
-	bl red_led_on
-	bl green_led_on
+	mov	r6, lr
+
+	/* Make sure caches are off and invalidated. */
+	ldr	r0, =0x00000000
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* Turn off the green LED and turn on the red LED. If the red LED
+	 * is left on for too long, the external reset circuit described
+	 * by application note AN258 will cause the system to reset.
+	 */
+	ldr	r1, =EP93XX_LED_DATA
+	ldr	r0, [r1]
+	bic	r0, r0, #EP93XX_LED_GREEN_ON
+	orr	r0, r0, #EP93XX_LED_RED_ON
+	str	r0, [r1]
+
+	/* Undo the silly static memory controller programming performed
+	 * by the boot rom.
+	 */
+	ldr	r0, =SMC_BASE
+
+	/* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */
+	ldr	r1, =0x0000fbe0
+
+	/* Reset EP93XX_OFF_SMCBCR0 */
+	ldr	r2, [r0]
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r2, [r0, #EP93XX_OFF_SMCBCR1]
+	orr	r2, r2, r1
+	str	r2, [r0, #EP93XX_OFF_SMCBCR1]
+
+	ldr	r2, [r0, #EP93XX_OFF_SMCBCR2]
+	orr	r2, r2, r1
+	str	r2, [r0, #EP93XX_OFF_SMCBCR2]
+
+	ldr	r2, [r0, #EP93XX_OFF_SMCBCR3]
+	orr	r2, r2, r1
+	str	r2, [r0, #EP93XX_OFF_SMCBCR3]
+
+	ldr	r2, [r0, #EP93XX_OFF_SMCBCR6]
+	orr	r2, r2, r1
+	str	r2, [r0, #EP93XX_OFF_SMCBCR6]
+
+	ldr	r2, [r0, #EP93XX_OFF_SMCBCR7]
+	orr	r2, r2, r1
+	str	r2, [r0, #EP93XX_OFF_SMCBCR7]
+
+	/* Set the PLL1 and processor clock. */
+	ldr	r0, =SYSCON_BASE
+#ifdef CONFIG_EDB9301
+	/* 332MHz, giving a 166MHz processor clock. */
+	ldr	r1, = 0x02b49907
+#else
+
+#ifdef CONFIG_EDB93XX_INDUSTRIAL
+	/* 384MHz, giving a 196MHz processor clock. */
+	ldr	r1, =0x02a4bb38
+#else
+	/* 400MHz, giving a 200MHz processor clock. */
+	ldr	r1, =0x02a4e39e
+#endif
+#endif
+	str	r1, [r0, #SYSCON_OFF_CLKSET1]
+
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* Need to make sure that SDRAM is configured correctly before
+	 * coping the code into it.
+	 */
+
+#ifdef CONFIG_EDB93XX_SDCS0
+	mov	r11, #SDRAM_DEVCFG0_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+	mov	r11, #SDRAM_DEVCFG1_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+	mov	r11, #SDRAM_DEVCFG2_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+	ldr	r0, =SYSCON_BASE
+	ldr	r0, [r0, #SYSCON_OFF_SYSCFG]
+	ands	r0, r0, #SYSCON_SYSCFG_LASDO
+	moveq	r11, #SDRAM_DEVCFG3_ASD0_BASE
+	movne	r11, #SDRAM_DEVCFG3_ASD1_BASE
+#endif
+	/* See Table 13-5 in EP93xx datasheet for more info about DRAM
+	 * register mapping */
+
+	/* Try a 32-bit wide configuration of SDRAM. */
+	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
+			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
+			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
+			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2)
+
+	/* Set burst count: 4 and CAS: 2
+	 * Burst mode [A11:A10]; CAS [A16:A14]
+	 */
+	orr	r2, r11, #0x00008800
+	bl	ep93xx_sdram_config
+
+	/* Test the SDRAM. */
+	mov	r0, r11
+	bl	ep93xx_sdram_test
+	cmp	r0, #0x00000000
+	beq	ep93xx_sdram_done
+
+	/* Try a 16-bit wide configuration of SDRAM. */
+	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
+			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
+			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
+			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \
+			EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH)
+
+	/* Set burst count: 8, CAS: 2, sequential burst
+	 * Accoring to Table 13-3 for 16bit operations mapping must be shifted.
+	 * Burst mode [A10:A9]; CAS [A15:A13]
+	 */
+	orr	r2, r11, #0x00004600
+	bl	ep93xx_sdram_config
+
+	/* Test the SDRAM. */
+	mov	r0, r11
+	bl	ep93xx_sdram_test
+	cmp	r0, #0x00000000
+	beq	ep93xx_sdram_done
+
+	/* Turn off the red LED. */
+	ldr	r0, =EP93XX_LED_DATA
+	ldr	r1, [r0]
+	bic	r1, r1, #EP93XX_LED_RED_ON
+	str	r1, [r0]
+
+	/* There is no SDRAM so flash the green LED. */
+flash_green:
+	orr	r1, r1, #EP93XX_LED_GREEN_ON
+	str	r1, [r0]
+	ldr	r2, =0x00010000
+flash_green_delay_1:
+	subs	r2, r2, #1
+	bne	flash_green_delay_1
+	bic	r1, r1, #EP93XX_LED_GREEN_ON
+	str	r1, [r0]
+	ldr	r2, =0x00010000
+flash_green_delay_2:
+	subs	r2, r2, #1
+	bne	flash_green_delay_2
+	orr	r1, r1, #EP93XX_LED_GREEN_ON
+	str	r1, [r0]
+	ldr	r2, =0x00010000
+flash_green_delay_3:
+	subs	r2, r2, #1
+	bne	flash_green_delay_3
+	bic	r1, r1, #EP93XX_LED_GREEN_ON
+	str	r1, [r0]
+	ldr	r2, =0x00050000
+flash_green_delay_4:
+	subs	r2, r2, #1
+	bne	flash_green_delay_4
+	b	flash_green
+
 
-	/* Configure flash wait states before we switch to the PLL */
-	bl flash_cfg
+ep93xx_sdram_done:
+	ldr	r1, =EP93XX_LED_DATA
+	ldr	r0, [r1]
+	bic	r0, r0, #EP93XX_LED_RED_ON
+	str	r0, [r1]
 
-	/* Set up PLL */
-	bl pll_cfg
+	/* Determine the size of the SDRAM. */
+	mov	r0, r11
+	bl	ep93xx_sdram_size
 
-	/* Turn off the Green LED and leave the Red LED on */
-	bl green_led_off
+	/* Save the SDRAM characteristics. */
+	mov	r8, r0
+	mov	r9, r1
+	mov	r10, r2
 
-	/* Setup SDRAM */
-	bl sdram_cfg
+	/* Compute total memory size into r1 */
+	mul	r1, r8, r10
+#ifdef CONFIG_EDB93XX_SDCS0
+	ldr	r2, [r0, #SDRAM_OFF_DEVCFG0]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+	ldr	r2, [r0, #SDRAM_OFF_DEVCFG1]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+	ldr	r2, [r0, #SDRAM_OFF_DEVCFG2]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+	ldr	r2, [r0, #SDRAM_OFF_DEVCFG3]
+#endif
 
-	/* Turn on Green LED, Turn off the Red LED */
-	bl green_led_on
-	bl red_led_off
+	/* Consider small DRAM size as:
+	 * < 32Mb for 32bit bus
+	 * < 64Mb for 16bit bus
+	 */
+	tst	r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH
+	moveq	r1, r1, lsr #1
+	cmp	r1, #0x02000000
 
-	/* FIXME: we use async mode for now */
-	mrc p15, 0, r0, c1, c0, 0
-	orr r0, r0, #0xc0000000
-	mcr p15, 0, r0, c1, c0, 0
+#if defined(CONFIG_EDB9301)
+	/* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */
+	movlt	r1, #0x03f0
+	movge	r1, #0x01e0
+#else
+	/* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */
+	movlt	r1, #0x0600
+	movge	r1, #0x2f0
+#endif
+	str	r1, [r0, #SDRAM_OFF_REFRSHTIMR]
 
-	/* restore return address */
-	ldr r1, =SYSCON_SCRATCH0
-	ldr lr, [r1]
+	/* Save the memory configuration information. */
+	orr	r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE
+	stmia	r0, {r8-r11}
 
-	mov pc, lr
+	mov	lr, r6
+	mov	pc, lr
diff --git a/arch/arm/include/asm/arch-ep93xx/ep93xx.h b/arch/arm/include/asm/arch-ep93xx/ep93xx.h
index 9e7f2f3..71aa601 100644
--- a/arch/arm/include/asm/arch-ep93xx/ep93xx.h
+++ b/arch/arm/include/asm/arch-ep93xx/ep93xx.h
@@ -1,6 +1,9 @@ 
 /*
  * Cirrus Logic EP93xx register definitions.
  *
+ * Copyright (C) 2013
+ * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
+ *
  * Copyright (C) 2009
  * Matthias Kaehlcke <matthias@kaehlcke.net>
  *
@@ -287,6 +290,20 @@  struct sdram_regs {
 #define SDRAM_DEVCFG_CASLAT_2		0x00010000
 #define SDRAM_DEVCFG_RASTOCAS_2		0x00200000
 
+#define SDRAM_OFF_GLCONFIG		0x0004
+#define SDRAM_OFF_REFRSHTIMR		0x0008
+
+#define SDRAM_OFF_DEVCFG0		0x0010
+#define SDRAM_OFF_DEVCFG1		0x0014
+#define SDRAM_OFF_DEVCFG2		0x0018
+#define SDRAM_OFF_DEVCFG3		0x001C
+
+#define SDRAM_DEVCFG0_BASE		0xC0000000
+#define SDRAM_DEVCFG1_BASE		0xD0000000
+#define SDRAM_DEVCFG2_BASE		0xE0000000
+#define SDRAM_DEVCFG3_ASD0_BASE		0xF0000000
+#define SDRAM_DEVCFG3_ASD1_BASE		0x00000000
+
 #define GLCONFIG_INIT			(1 << 0)
 #define GLCONFIG_MRS			(1 << 1)
 #define GLCONFIG_SMEMBUSY		(1 << 5)
@@ -295,6 +312,43 @@  struct sdram_regs {
 #define GLCONFIG_CLKSHUTDOWN		(1 << 30)
 #define GLCONFIG_CKE			(1 << 31)
 
+#define EP93XX_SDRAMCTRL			0x80060000
+#define EP93XX_SDRAMCTRL_GLOBALCFG_INIT		0x00000001
+#define EP93XX_SDRAMCTRL_GLOBALCFG_MRS		0x00000002
+#define EP93XX_SDRAMCTRL_GLOBALCFG_SMEMBUSY	0x00000020
+#define EP93XX_SDRAMCTRL_GLOBALCFG_LCR		0x00000040
+#define EP93XX_SDRAMCTRL_GLOBALCFG_REARBEN	0x00000080
+#define EP93XX_SDRAMCTRL_GLOBALCFG_CLKSHUTDOWN	0x40000000
+#define EP93XX_SDRAMCTRL_GLOBALCFG_CKE		0x80000000
+
+#define EP93XX_SDRAMCTRL_REFRESH_MASK		0x0000FFFF
+
+#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_32	0x00000002
+#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_16	0x00000001
+#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_8	0x00000000
+#define EP93XX_SDRAMCTRL_BOOTSTATUS_WIDTH_MASK	0x00000003
+#define EP93XX_SDRAMCTRL_BOOTSTATUS_MEDIA	0x00000004
+
+#define EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH	0x00000004
+#define EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT	0x00000008
+#define EP93XX_SDRAMCTRL_DEVCFG_SROM512		0x00000010
+#define EP93XX_SDRAMCTRL_DEVCFG_SROMLL		0x00000020
+#define EP93XX_SDRAMCTRL_DEVCFG_2KPAGE		0x00000040
+#define EP93XX_SDRAMCTRL_DEVCFG_SFCONFIGADDR	0x00000080
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_MASK	0x00070000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2	0x00010000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_3	0x00020000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_4	0x00030000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_5	0x00040000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_6	0x00050000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_7	0x00060000
+#define EP93XX_SDRAMCTRL_DEVCFG_CASLAT_8	0x00070000
+#define EP93XX_SDRAMCTRL_DEVCFG_WBL		0x00080000
+#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_MASK	0x00300000
+#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2	0x00200000
+#define EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_3	0x00300000
+#define EP93XX_SDRAMCTRL_DEVCFG_AUTOPRECHARGE	0x01000000
+
 /*
  * 0x80070000 - 0x8007FFFF: Reserved
  */
@@ -324,6 +378,13 @@  struct smc_regs {
 };
 #endif
 
+#define EP93XX_OFF_SMCBCR0		0x00
+#define EP93XX_OFF_SMCBCR1		0x04
+#define EP93XX_OFF_SMCBCR2		0x08
+#define EP93XX_OFF_SMCBCR3		0x0C
+#define EP93XX_OFF_SMCBCR6		0x18
+#define EP93XX_OFF_SMCBCR7		0x1C
+
 #define SMC_BCR_IDCY_SHIFT	0
 #define SMC_BCR_WST1_SHIFT	5
 #define SMC_BCR_BLE		(1 << 10)
@@ -445,6 +506,14 @@  struct gpio_regs {
 };
 #endif
 
+#define EP93XX_LED_DATA		0x80840020
+#define EP93XX_LED_GREEN_ON	0x0001
+#define EP93XX_LED_RED_ON	0x0002
+
+#define EP93XX_LED_DDR		0x80840024
+#define EP93XX_LED_GREEN_ENABLE	0x0001
+#define EP93XX_LED_RED_ENABLE	0x00020000
+
 /*
  * 0x80850000 - 0x8087FFFF: Reserved
  */
@@ -519,6 +588,9 @@  struct gpio_regs {
 #define SYSCON_OFFSET		0x930000
 #define SYSCON_BASE		(EP93XX_APB_BASE | SYSCON_OFFSET)
 
+/* Security */
+#define SECURITY_EXTENSIONID	0x80832714
+
 #ifndef __ASSEMBLY__
 struct syscon_regs {
 	uint32_t pwrsts;
@@ -553,7 +625,11 @@  struct syscon_regs {
 #define SYSCON_SCRATCH0		(SYSCON_BASE + 0x0040)
 #endif
 
+#define SYSCON_OFF_CLKSET1			0x0020
+#define SYSCON_OFF_SYSCFG			0x009c
+
 #define SYSCON_PWRCNT_UART_BAUD			(1 << 29)
+#define SYSCON_PWRCNT_USH_EN			(1 << 28)
 
 #define SYSCON_CLKSET_PLL_X2IPD_SHIFT		0
 #define SYSCON_CLKSET_PLL_X2FBD2_SHIFT		5
@@ -571,6 +647,8 @@  struct syscon_regs {
 #define SYSCON_CHIPID_REV_MASK			0xF0000000
 #define SYSCON_DEVICECFG_SWRST			(1 << 31)
 
+#define SYSCON_SYSCFG_LASDO			0x00000020
+
 /*
  * 0x80930000 - 0x8093FFFF: Watchdog Timer
  */
@@ -580,3 +658,10 @@  struct syscon_regs {
 /*
  * 0x80950000 - 0x9000FFFF: Reserved
  */
+
+/*
+ * During low_level init we store memory layout in memory at specific location
+ */
+#define UBOOT_MEMORYCNF_BANK_SIZE		0x2000
+#define UBOOT_MEMORYCNF_BANK_MASK		0x2004
+#define UBOOT_MEMORYCNF_BANK_COUNT		0x2008
diff --git a/board/cirrus/edb93xx/Makefile b/board/cirrus/edb93xx/Makefile
new file mode 100644
index 0000000..d03c498
--- /dev/null
+++ b/board/cirrus/edb93xx/Makefile
@@ -0,0 +1,11 @@ 
+#
+# (C) Copyright 2013
+# Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd <at> denx.de.
+#
+# * SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= edb93xx.o
diff --git a/board/cirrus/edb93xx/edb93xx.c b/board/cirrus/edb93xx/edb93xx.c
new file mode 100644
index 0000000..8963d3a
--- /dev/null
+++ b/board/cirrus/edb93xx/edb93xx.c
@@ -0,0 +1,382 @@ 
+/*
+ * Board initialization for EP93xx
+ *
+ * Copyright (C) 2013
+ * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
+ *
+ * Copyright (C) 2009
+ * Matthias Kaehlcke <matthias <at> kaehlcke.net>
+ *
+ * (C) Copyright 2002 2003
+ * Network Audio Technologies, Inc. <www.netaudiotech.com>
+ * Adam Bezanson <bezanson <at> netaudiotech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/arch/ep93xx.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * usb_div: 4, nbyp2: 1, pll2_en: 1
+ * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000,
+ * pll2_x2: 384000000.000000, pll2_out: 192000000.000000
+ */
+#define CLKSET2_VAL	(23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT |	\
+			24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT |	\
+			24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT |	\
+			1 << SYSCON_CLKSET_PLL_PS_SHIFT |	\
+			SYSCON_CLKSET2_PLL2_EN |		\
+			SYSCON_CLKSET2_NBYP2 |			\
+			3 << SYSCON_CLKSET2_USB_DIV_SHIFT)
+
+#define SMC_BCR6_VALUE	(2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
+			SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \
+			1 << SMC_BCR_MW_SHIFT)
+
+/* delay execution before timers are initialized */
+static inline void early_udelay(uint32_t usecs)
+{
+	/* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */
+	register uint32_t loops = (usecs * 1000) / 20;
+
+	__asm__ volatile ("1:\n"
+			"subs %0, %1, #1\n"
+			"bne 1b" : "=r" (loops) : "0" (loops));
+}
+
+#ifndef CONFIG_EP93XX_NO_FLASH_CFG
+static void flash_cfg(void)
+{
+	struct smc_regs *smc = (struct smc_regs *)SMC_BASE;
+
+	writel(SMC_BCR6_VALUE, &smc->bcr6);
+}
+#else
+#define flash_cfg()
+#endif
+
+int board_init(void)
+{
+	/*
+	 * Setup PLL2, PPL1 has been set during lowlevel init
+	 */
+	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+	writel(CLKSET2_VAL, &syscon->clkset2);
+
+	/*
+	 * the user's guide recommends to wait at least 1 ms for PLL2 to
+	 * stabilize
+	 */
+	early_udelay(1000);
+
+	/* Go to Async mode */
+	__asm__ volatile ("mrc p15, 0, r0, c1, c0, 0");
+	__asm__ volatile ("orr r0, r0, #0xc0000000");
+	__asm__ volatile ("mcr p15, 0, r0, c1, c0, 0");
+
+	icache_enable();
+
+#ifdef USE_920T_MMU
+	dcache_enable();
+#endif
+
+	/* Machine number, as defined in linux/arch/arm/tools/mach-types */
+	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	/* We have a console */
+	gd->have_console = 1;
+
+	enable_interrupts();
+
+	flash_cfg();
+
+	green_led_on();
+	red_led_off();
+
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	/*
+	 * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of
+	 * 14.7456/2 MHz
+	 */
+	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+	writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt);
+	return 0;
+}
+
+int board_eth_init(bd_t *bd)
+{
+	return ep93xx_eth_initialize(0, MAC_BASE);
+}
+
+static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt,
+				unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS])
+{
+	if (dram_bank_cnt == 1) {
+		dram_bank_base[0] = PHYS_SDRAM_1;
+	} else {
+		/* Table lookup for holes in address space. Maximum memory
+		 * for the single SDCS may be up to 256Mb. We start scanning
+		 * banks from 1Mb, so it could be up to 128 banks theoretically.
+		 * We need at maximum 7 bits for the loockup, 8 slots is
+		 * enough for the worst case.
+		 */
+		unsigned tbl[8];
+		unsigned i = dram_bank_cnt / 2;
+		unsigned j = 0x00100000; /* 1 Mb */
+		unsigned *ptbl = tbl;
+		do {
+			while (!(dram_addr_mask & j)) {
+				j <<= 1;
+			}
+			*ptbl++ = j;
+			j <<= 1;
+			i >>= 1;
+		} while (i != 0);
+
+		for (i = dram_bank_cnt, j = 0;
+		     (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) {
+			unsigned addr = PHYS_SDRAM_1;
+			unsigned k;
+			unsigned bit;
+
+			for (k = 0, bit = 1; k < 8; k++, bit <<= 1) {
+				if (bit & j)
+					addr |= tbl[k];
+			}
+
+			dram_bank_base[j] = addr;
+		}
+	}
+}
+
+/* called in board_init_f (before relocation) */
+static unsigned dram_init_banksize_int(int print)
+{
+	/*
+	 * Collect information of banks that has been filled during lowlevel
+	 * initialization
+	 */
+	unsigned i;
+	unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS];
+	unsigned dram_total = 0;
+	unsigned dram_bank_size = *(unsigned *)
+				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE);
+	unsigned dram_addr_mask = *(unsigned *)
+				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK);
+	unsigned dram_bank_cnt = *(unsigned *)
+				 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT);
+
+	dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base);
+
+	for (i = 0; i < dram_bank_cnt; i++) {
+		gd->bd->bi_dram[i].start = dram_bank_base[i];
+		gd->bd->bi_dram[i].size = dram_bank_size;
+		dram_total += dram_bank_size;
+	}
+	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
+		gd->bd->bi_dram[i].start = 0;
+		gd->bd->bi_dram[i].size = 0;
+	}
+
+	if (print) {
+		printf("DRAM mask: %08x\n", dram_addr_mask);
+		printf("DRAM total %u banks:\n", dram_bank_cnt);
+		printf("bank          base-address          size\n");
+
+		if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) {
+			printf("WARNING! UBoot was configured for %u banks,\n"
+				"but %u has been found. "
+				"Supressing extra memory banks\n",
+				 CONFIG_NR_DRAM_BANKS, dram_bank_cnt);
+			dram_bank_cnt = CONFIG_NR_DRAM_BANKS;
+		}
+
+		for (i = 0; i < dram_bank_cnt; i++) {
+			printf("  %u             %08x            %08x\n",
+			       i, dram_bank_base[i], dram_bank_size);
+		}
+		printf("  ------------------------------------------\n"
+			"Total                              %9d\n\n",
+			dram_total);
+	}
+
+	return dram_total;
+}
+
+void dram_init_banksize(void)
+{
+	dram_init_banksize_int(0);
+}
+
+/* called in board_init_f (before relocation) */
+int dram_init(void)
+{
+	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+	unsigned sec_id = readl(SECURITY_EXTENSIONID);
+	unsigned chip_id = readl(&syscon->chipid);
+
+	printf("CPU: Cirrus Logic ");
+	switch (sec_id & 0x000001FE) {
+	case 0x00000008:
+		printf("EP9301");
+		break;
+	case 0x00000004:
+		printf("EP9307");
+		break;
+	case 0x00000002:
+		printf("EP931x");
+		break;
+	case 0x00000000:
+		printf("EP9315");
+		break;
+	default:
+		printf("<unknown>");
+		break;
+	}
+
+	printf(" - Rev. ");
+	switch (chip_id & 0xF0000000) {
+	case 0x00000000:
+		printf("A");
+		break;
+	case 0x10000000:
+		printf("B");
+		break;
+	case 0x20000000:
+		printf("C");
+		break;
+	case 0x30000000:
+		printf("D0");
+		break;
+	case 0x40000000:
+		printf("D1");
+		break;
+	case 0x50000000:
+		printf("E0");
+		break;
+	case 0x60000000:
+		printf("E1");
+		break;
+	case 0x70000000:
+		printf("E2");
+		break;
+	default:
+		printf("?");
+		break;
+	}
+	printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id);
+
+	gd->ram_size = dram_init_banksize_int(1);
+	return 0;
+}
+
+
+#ifdef CONFIG_EP93XX_SPI
+#include <spi.h>
+
+/*
+ * EGIO0-EGIPO7 -> port A
+ * EGIO8-EGIP15 -> port B
+ */
+
+static void ep93xx_set_epgio(unsigned num)
+{
+	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
+	if (num < 8)
+		writel(readl(&regs->padr) | (1<<num), &regs->padr);
+	else
+		writel(readl(&regs->pbdr) | (1<<(num-8)), &regs->pbdr);
+}
+
+static void ep93xx_clear_epgio(unsigned num)
+{
+	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
+	if (num < 8)
+		writel(readl(&regs->padr) & (~(1<<num)), &regs->padr);
+	else
+		writel(readl(&regs->pbdr) & (~(1<<(num-8))), &regs->pbdr);
+}
+
+static void ep93xx_dir_epgio_out(unsigned num)
+{
+	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
+	if (num < 8)
+		writel(readl(&regs->paddr) | (1<<num), &regs->paddr);
+	else
+		writel(readl(&regs->pbddr) | (1<<(num-8)), &regs->pbddr);
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	if (bus == 0 && cs < 16)
+		return 1;
+
+	return 0;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+	ep93xx_clear_epgio(slave->cs);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	ep93xx_set_epgio(slave->cs);
+}
+
+#ifdef CONFIG_MMC_SPI
+#include <mmc.h>
+
+#ifndef CONFIG_MMC_SPI_CS_EPGIO
+# define CONFIG_MMC_SPI_CS_EPGIO	4
+#endif
+
+#ifndef CONFIG_MMC_SPI_SPEED
+# define CONFIG_MMC_SPI_SPEED		25000000
+#endif
+
+#ifndef CONFIG_MMC_SPI_MODE
+# define CONFIG_MMC_SPI_MODE		SPI_MODE_0
+#endif
+
+int board_mmc_init(bd_t *bis)
+{
+	struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE;
+
+	ep93xx_set_epgio(CONFIG_MMC_SPI_CS_EPGIO);
+	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_CS_EPGIO);
+
+#ifdef CONFIG_MMC_SPI_POWER_EGPIO
+	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_POWER_EGPIO);
+	ep93xx_set_epgio(CONFIG_MMC_SPI_POWER_EGPIO);
+#elif defined(CONFIG_MMC_SPI_NPOWER_EGPIO)
+	ep93xx_dir_epgio_out(CONFIG_MMC_SPI_NPOWER_EGPIO);
+	ep93xx_clear_epgio(CONFIG_MMC_SPI_NPOWER_EGPIO);
+#endif
+	struct mmc *mmc = mmc_spi_init(0, CONFIG_MMC_SPI_CS_EPGIO,
+				CONFIG_MMC_SPI_SPEED, CONFIG_MMC_SPI_MODE);
+
+	if (!mmc) {
+		printf("Failed to create MMC Device\n");
+		return 1;
+	}
+	mmc_init(mmc);
+	return 0;
+}
+
+
+#endif /* CONFIG_MMC_SPI */
+#endif /* CONFIG_EP93XX_SPI */
diff --git a/board/cirrus/edb93xx/u-boot.lds b/board/cirrus/edb93xx/u-boot.lds
new file mode 100644
index 0000000..e61aa36
--- /dev/null
+++ b/board/cirrus/edb93xx/u-boot.lds
@@ -0,0 +1,115 @@ 
+/*
+ *
+ * Copyright (C) 2013
+ * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
+ *
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text : {
+		*(.__image_copy_start)
+		arch/arm/cpu/arm920t/start.o (.text*)
+		. = 0x1000;
+
+		LONG(0x53555243)
+		*(.text*)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data : {
+		*(.data*)
+	}
+
+	. = ALIGN(4);
+
+	. = .;
+
+	. = ALIGN(4);
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	}
+
+	. = ALIGN(4);
+
+	.image_copy_end :
+	{
+		*(.__image_copy_end)
+	}
+
+	.rel_dyn_start :
+	{
+		*(.__rel_dyn_start)
+	}
+
+	.rel.dyn : {
+		*(.rel*)
+	}
+
+	.rel_dyn_end :
+	{
+		*(.__rel_dyn_end)
+	}
+
+	.end :
+	{
+		*(.__end)
+	}
+
+	_image_binary_end = .;
+
+	/*
+	 * Deprecated: this MMU section is used by pxa at present but
+	 * should not be used by new boards/CPUs.
+	 */
+	. = ALIGN(4096);
+	.mmutable : {
+		*(.mmutable)
+	}
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+	.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));
+	}
+
+	.dynsym _image_binary_end : { *(.dynsym) }
+	.dynbss : { *(.dynbss) }
+	.dynstr : { *(.dynstr*) }
+	.dynamic : { *(.dynamic*) }
+	.plt : { *(.plt*) }
+	.interp : { *(.interp*) }
+	.gnu.hash : { *(.gnu.hash) }
+	.gnu : { *(.gnu*) }
+	.ARM.exidx : { *(.ARM.exidx*) }
+	.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
+}
diff --git a/boards.cfg b/boards.cfg
index 2128996..4c5f1b8 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -74,6 +74,7 @@  Active  arm         arm920t        ks8695      -               -
 Active  arm         arm920t        ks8695      -               -                   cm41xx                                -                                                                                                                                 -
 Active  arm         arm920t        s3c24x0     mpl             vcma9               VCMA9                                 -                                                                                                                                 David Müller <d.mueller@elsoft.ch>
 Active  arm         arm920t        s3c24x0     samsung         -                   smdk2410                              -                                                                                                                                 David Müller <d.mueller@elsoft.ch>
+Active  arm         arm920t        ep93xx      cirrus          edb93xx             edb9315a                              edb93xx:MK_edb9315a                                                                                                               Sergey Kostanbaev <sergey.kostanbaev@fairwaves.ru>
 Active  arm         arm926ejs      -           armltd          integrator          integratorap_cm926ejs                 integratorap:CM926EJ_S                                                                                                            Linus Walleij <linus.walleij@linaro.org>
 Active  arm         arm926ejs      -           armltd          integrator          integratorcp_cm926ejs                 integratorcp:CM924EJ_S                                                                                                            Linus Walleij <linus.walleij@linaro.org>
 Active  arm         arm926ejs      armada100   Marvell         -                   aspenite                              -                                                                                                                                 Prafulla Wadaskar <prafulla@marvell.com>
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ed4ecd7..c5d6c6a 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -8,6 +8,7 @@ 
 # There are many options which enable SPI, so make this library available
 obj-y += spi.o
 
+obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o
 obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
 obj-$(CONFIG_ANDES_SPI) += andes_spi.o
 obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c
new file mode 100644
index 0000000..235557e
--- /dev/null
+++ b/drivers/spi/ep93xx_spi.c
@@ -0,0 +1,274 @@ 
+/*
+ * SPI Driver for EP93xx
+ *
+ * Copyright (C) 2013 Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
+ *
+ * Inspired form linux kernel driver and atmel uboot driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <malloc.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/ep93xx.h>
+
+
+#define BIT(x)			(1<<(x))
+#define SSPBASE			SPI_BASE
+
+#define SSPCR0			0x0000
+#define SSPCR0_MODE_SHIFT	6
+#define SSPCR0_SCR_SHIFT	8
+#define SSPCR0_SPH		BIT(7)
+#define SSPCR0_SPO		BIT(6)
+#define SSPCR0_FRF_SPI		0
+#define SSPCR0_DSS_8BIT		7
+
+#define SSPCR1			0x0004
+#define SSPCR1_RIE		BIT(0)
+#define SSPCR1_TIE		BIT(1)
+#define SSPCR1_RORIE		BIT(2)
+#define SSPCR1_LBM		BIT(3)
+#define SSPCR1_SSE		BIT(4)
+#define SSPCR1_MS		BIT(5)
+#define SSPCR1_SOD		BIT(6)
+
+#define SSPDR			0x0008
+
+#define SSPSR			0x000c
+#define SSPSR_TFE		BIT(0)
+#define SSPSR_TNF		BIT(1)
+#define SSPSR_RNE		BIT(2)
+#define SSPSR_RFF		BIT(3)
+#define SSPSR_BSY		BIT(4)
+#define SSPCPSR			0x0010
+
+#define SSPIIR			0x0014
+#define SSPIIR_RIS		BIT(0)
+#define SSPIIR_TIS		BIT(1)
+#define SSPIIR_RORIS		BIT(2)
+#define SSPICR			SSPIIR
+
+#define SSPCLOCK		14745600
+#define SSP_MAX_RATE		(SSPCLOCK / 2)
+#define SSP_MIN_RATE		(SSPCLOCK / (254 * 256))
+
+/* timeout in milliseconds */
+#define SPI_TIMEOUT		5
+/* maximum depth of RX/TX FIFO */
+#define SPI_FIFO_SIZE		8
+
+struct ep93xx_spi_slave {
+	struct spi_slave slave;
+
+	unsigned sspcr0;
+	unsigned sspcpsr;
+};
+
+static inline struct ep93xx_spi_slave *to_ep93xx_spi(struct spi_slave *slave)
+{
+	return container_of(slave, struct ep93xx_spi_slave, slave);
+}
+
+void spi_init()
+{
+}
+
+static inline void ep93xx_spi_write_u8(u16 reg, u8 value)
+{
+	writel(value, (unsigned int *)(SSPBASE + reg));
+}
+
+static inline u8 ep93xx_spi_read_u8(u16 reg)
+{
+	return readl((unsigned int *)(SSPBASE + reg));
+}
+
+static inline void ep93xx_spi_write_u16(u16 reg, u16 value)
+{
+	writel(value, (unsigned int *)(SSPBASE + reg));
+}
+
+static inline u16 ep93xx_spi_read_u16(u16 reg)
+{
+	return (u16)readl((unsigned int *)(SSPBASE + reg));
+}
+
+static int ep93xx_spi_init_hw(unsigned int rate, unsigned int mode,
+				struct ep93xx_spi_slave *slave)
+{
+	unsigned cpsr, scr;
+
+	if (rate > SSP_MAX_RATE)
+		rate = SSP_MAX_RATE;
+
+	if (rate < SSP_MIN_RATE)
+		return -1;
+
+	/* Calculate divisors so that we can get speed according the
+	 * following formula:
+	 *	rate = spi_clock_rate / (cpsr * (1 + scr))
+	 *
+	 * cpsr must be even number and starts from 2, scr can be any number
+	 * between 0 and 255.
+	 */
+	for (cpsr = 2; cpsr <= 254; cpsr += 2) {
+		for (scr = 0; scr <= 255; scr++) {
+			if ((SSPCLOCK / (cpsr * (scr + 1))) <= rate) {
+				/* Set CHPA and CPOL, SPI format and 8bit */
+				unsigned sspcr0 = (scr << SSPCR0_SCR_SHIFT) |
+					SSPCR0_FRF_SPI | SSPCR0_DSS_8BIT;
+				if (mode & SPI_CPHA)
+					sspcr0 |= SSPCR0_SPH;
+				if (mode & SPI_CPOL)
+					sspcr0 |= SSPCR0_SPO;
+
+				slave->sspcr0 = sspcr0;
+				slave->sspcpsr = cpsr;
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
+void spi_set_speed(struct spi_slave *slave, unsigned int hz)
+{
+	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
+
+	unsigned int mode = 0;
+	if (as->sspcr0 & SSPCR0_SPH)
+		mode |= SPI_CPHA;
+	if (as->sspcr0 & SSPCR0_SPO)
+		mode |= SPI_CPOL;
+
+	ep93xx_spi_init_hw(hz, mode, as);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+			unsigned int max_hz, unsigned int mode)
+{
+	struct ep93xx_spi_slave	*as;
+
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	as = spi_alloc_slave(struct ep93xx_spi_slave, bus, cs);
+	if (!as)
+		return NULL;
+
+	if (ep93xx_spi_init_hw(max_hz, mode, as)) {
+		free(as);
+		return NULL;
+	}
+
+	return &as->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
+
+	free(as);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct ep93xx_spi_slave *as = to_ep93xx_spi(slave);
+
+	/* Enable the SPI hardware */
+	ep93xx_spi_write_u8(SSPCR1, SSPCR1_SSE);
+
+
+	ep93xx_spi_write_u8(SSPCPSR, as->sspcpsr);
+	ep93xx_spi_write_u16(SSPCR0, as->sspcr0);
+
+	debug("Select CS:%d SSPCPSR=%02x SSPCR0=%04x\n",
+	      slave->cs, as->sspcpsr, as->sspcr0);
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	/* Disable the SPI hardware */
+	ep93xx_spi_write_u8(SSPCR1, 0);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+		const void *dout, void *din, unsigned long flags)
+{
+	unsigned int	len_tx;
+	unsigned int	len_rx;
+	unsigned int	len;
+	u32		status;
+	const u8	*txp = dout;
+	u8		*rxp = din;
+	u8		value;
+
+	debug("spi_xfer: slave %u:%u dout %p din %p bitlen %u\n",
+	      slave->bus, slave->cs, (uint *)dout, (uint *)din, bitlen);
+
+
+	if (bitlen == 0)
+		/* Finish any previously submitted transfers */
+		goto out;
+
+	if (bitlen % 8) {
+		/* Errors always terminate an ongoing transfer */
+		flags |= SPI_XFER_END;
+		goto out;
+	}
+
+	len = bitlen / 8;
+
+
+	if (flags & SPI_XFER_BEGIN) {
+		/* Empty RX FIFO */
+		while ((ep93xx_spi_read_u8(SSPSR) & SSPSR_RNE))
+			ep93xx_spi_read_u8(SSPDR);
+
+		spi_cs_activate(slave);
+	}
+
+	for (len_tx = 0, len_rx = 0; len_rx < len; ) {
+		status = ep93xx_spi_read_u8(SSPSR);
+
+		if ((len_tx < len) && (status & SSPSR_TNF)) {
+			if (txp)
+				value = *txp++;
+			else
+				value = 0xff;
+
+			ep93xx_spi_write_u8(SSPDR, value);
+			len_tx++;
+		}
+
+		if (status & SSPSR_RNE) {
+			value = ep93xx_spi_read_u8(SSPDR);
+
+			if (rxp)
+				*rxp++ = value;
+			len_rx++;
+		}
+	}
+
+out:
+	if (flags & SPI_XFER_END) {
+		/*
+		 * Wait until the transfer is completely done before
+		 * we deactivate CS.
+		 */
+		do {
+			status = ep93xx_spi_read_u8(SSPSR);
+		} while (status & SSPSR_BSY);
+
+		spi_cs_deactivate(slave);
+	}
+
+	return 0;
+}
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 1417028..5cab359 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -13,6 +13,7 @@  obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
 obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o
 obj-$(CONFIG_USB_OHCI_S3C24XX) += ohci-s3c24xx.o
+obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o
 
 # echi
 obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
new file mode 100644
index 0000000..8fb4aba
--- /dev/null
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -0,0 +1,38 @@ 
+/*
+ * (C) Copyright 2013
+ * Sergey Kostanbaev < sergey.kostanbaev <at> fairwaves.ru >
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
+#include <asm/io.h>
+#include <asm/arch/ep93xx.h>
+
+int usb_cpu_init(void)
+{
+	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+	unsigned long pwr = readl(&syscon->pwrcnt);
+	writel(pwr | SYSCON_PWRCNT_USH_EN, &syscon->pwrcnt);
+
+	return 0;
+}
+
+int usb_cpu_stop(void)
+{
+	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+	unsigned long pwr = readl(&syscon->pwrcnt);
+	writel(pwr &  ~SYSCON_PWRCNT_USH_EN, &syscon->pwrcnt);
+
+	return 0;
+}
+
+int usb_cpu_init_fail(void)
+{
+	return usb_cpu_stop();
+}
+
+#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */
diff --git a/include/configs/edb93xx.h b/include/configs/edb93xx.h
new file mode 100644
index 0000000..37bdcc0
--- /dev/null
+++ b/include/configs/edb93xx.h
@@ -0,0 +1,292 @@ 
+/*
+ * U-boot - Configuration file for Cirrus Logic EDB93xx boards
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#ifdef CONFIG_MK_edb9301
+#define CONFIG_EDB9301
+#elif defined(CONFIG_MK_edb9302)
+#define CONFIG_EDB9302
+#elif defined(CONFIG_MK_edb9302a)
+#define CONFIG_EDB9302A
+#elif defined(CONFIG_MK_edb9307)
+#define CONFIG_EDB9307
+#elif defined(CONFIG_MK_edb9307a)
+#define CONFIG_EDB9307A
+#elif defined(CONFIG_MK_edb9312)
+#define CONFIG_EDB9312
+#elif defined(CONFIG_MK_edb9315)
+#define CONFIG_EDB9315
+#elif defined(CONFIG_MK_edb9315a)
+#define CONFIG_EDB9315A
+#else
+#error "no board defined"
+#endif
+
+/* Initial environment and monitor configuration options. */
+#define CONFIG_BOOTDELAY		2
+#define CONFIG_CMDLINE_TAG		1
+#define CONFIG_INITRD_TAG		1
+#define CONFIG_SETUP_MEMORY_TAGS	1
+#define CONFIG_BOOTARGS		"root=/dev/nfs console=ttyAM0,115200 ip=dhcp"
+#define CONFIG_BOOTFILE		"edb93xx.img"
+
+#define CONFIG_SYS_HUSH_PARSER		1
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+
+
+#define CONFIG_SYS_LDSCRIPT	"board/cirrus/edb93xx/u-boot.lds"
+
+
+#ifdef CONFIG_EDB9301
+#define CONFIG_EP9301
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9301
+#define CONFIG_SYS_PROMPT		"EDB9301> "
+#define CONFIG_ENV_SECT_SIZE		0x00020000
+#elif defined(CONFIG_EDB9302)
+#define CONFIG_EP9302
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9302
+#define CONFIG_SYS_PROMPT		"EDB9302> "
+#define CONFIG_ENV_SECT_SIZE		0x00020000
+#elif defined(CONFIG_EDB9302A)
+#define CONFIG_EP9302
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9302A
+#define CONFIG_SYS_PROMPT		"EDB9302A> "
+#define CONFIG_ENV_SECT_SIZE		0x00020000
+#elif defined(CONFIG_EDB9307)
+#define CONFIG_EP9307
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9307
+#define CONFIG_SYS_PROMPT		"EDB9307> "
+#define CONFIG_ENV_SECT_SIZE		0x00040000
+#elif defined(CONFIG_EDB9307A)
+#define CONFIG_EP9307
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9307A
+#define CONFIG_SYS_PROMPT		"EDB9307A> "
+#define CONFIG_ENV_SECT_SIZE		0x00020000
+#elif defined(CONFIG_EDB9312)
+#define CONFIG_EP9312
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9312
+#define CONFIG_SYS_PROMPT		"EDB9312> "
+#define CONFIG_ENV_SECT_SIZE		0x00040000
+#elif defined(CONFIG_EDB9315)
+#define CONFIG_EP9315
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9315
+#define CONFIG_SYS_PROMPT		"EDB9315> "
+#define CONFIG_ENV_SECT_SIZE		0x00040000
+#elif defined(CONFIG_EDB9315A)
+#define CONFIG_EP9315
+#define CONFIG_MACH_TYPE		MACH_TYPE_EDB9315A
+#define CONFIG_SYS_PROMPT		"EDB9315A> "
+#define CONFIG_ENV_SECT_SIZE		0x00020000
+#else
+#error "no board defined"
+#endif
+
+/* High-level configuration options */
+#define CONFIG_ARM920T		1		/* This is an ARM920T core... */
+#define CONFIG_EP93XX		1		/* in a Cirrus Logic 93xx SoC */
+
+#define CONFIG_SYS_CLK_FREQ	14745600	/* EP93xx has a 14.7456 clock */
+#define CONFIG_SYS_HZ		1000		/* decr freq: 1 ms ticks */
+#undef CONFIG_USE_IRQ				/* Don't need IRQ/FIQ */
+
+/* Monitor configuration */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#undef CONFIG_CMD_XIMG
+
+#undef CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_JFFS2
+
+#define CONFIG_SYS_LONGHELP			/* Enable "long" help in mon */
+#define CONFIG_SYS_CBSIZE		1024	/* Console I/O buffer size */
+/* Print buffer size */
+#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+/* Boot argument buffer size */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_MAXARGS	16		/* Max number of command args */
+
+/* Serial port hardware configuration */
+#define CONFIG_PL010_SERIAL
+#define CONFIG_CONS_INDEX		0
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{9600, 19200, 38400, 57600, \
+                        115200, 230400}
+#define CONFIG_SYS_SERIAL0		0x808C0000
+#define CONFIG_SYS_SERIAL1		0x808D0000
+/*#define CONFIG_PL01x_PORTS	{(void *)CONFIG_SYS_SERIAL0, \
+            (void *)CONFIG_SYS_SERIAL1} */
+
+#define CONFIG_PL01x_PORTS	{(void *)CONFIG_SYS_SERIAL0}
+
+/* Status LED */
+#define CONFIG_STATUS_LED		1 /* Status LED enabled	*/
+#define CONFIG_BOARD_SPECIFIC_LED	1
+#define STATUS_LED_GREEN		0
+#define STATUS_LED_RED			1
+/* Green */
+#define STATUS_LED_BIT			STATUS_LED_GREEN
+#define STATUS_LED_STATE		STATUS_LED_ON
+#define STATUS_LED_PERIOD		(CONFIG_SYS_HZ / 2)
+/* Red */
+#define STATUS_LED_BIT1			STATUS_LED_RED
+#define STATUS_LED_STATE1		STATUS_LED_OFF
+#define STATUS_LED_PERIOD1		(CONFIG_SYS_HZ / 2)
+/* Optional value */
+#define STATUS_LED_BOOT			STATUS_LED_BIT
+
+/* Network hardware configuration */
+#define CONFIG_DRIVER_EP93XX_MAC
+#define CONFIG_MII_SUPPRESS_PREAMBLE
+#define CONFIG_MII
+#define CONFIG_PHY_ADDR		1
+#define CONFIG_NET_MULTI
+#undef CONFIG_NETCONSOLE
+
+/* SDRAM configuration */
+#if defined(CONFIG_EDB9301) || defined(CONFIG_EDB9302) || \
+    defined(CONFIG_EDB9307) || defined CONFIG_EDB9312 || \
+    defined(CONFIG_EDB9315)
+/*
+ * EDB9301/2 has 4 banks of SDRAM consisting of 1x Samsung K4S561632E-TC75
+ * 256 Mbit SDRAM on a 16-bit data bus, for a total of 32MB of SDRAM. We set
+ * the SROMLL bit on the processor, resulting in this non-contiguous memory map.
+ *
+ * The EDB9307, EDB9312, and EDB9315 have 2 banks of SDRAM consisting of
+ * 2x Samsung K4S561632E-TC75 256 Mbit on a 32-bit data bus, for a total of
+ * 64 MB of SDRAM.
+ */
+
+#define CONFIG_EDB93XX_SDCS3
+
+#elif defined(CONFIG_EDB9302A) || \
+    defined(CONFIG_EDB9307A) || defined(CONFIG_EDB9315A)
+/*
+ * EDB9302a has 4 banks of SDRAM consisting of 1x Samsung K4S561632E-TC75
+ * 256 Mbit SDRAM on a 16-bit data bus, for a total of 32MB of SDRAM. We set
+ * the SROMLL bit on the processor, resulting in this non-contiguous memory map.
+ *
+ * The EDB9307A and EDB9315A have 2 banks of SDRAM consisting of 2x Samsung
+ * K4S561632E-TC75 256 Mbit on a 32-bit data bus, for a total of 64 MB of SDRAM.
+ */
+#define CONFIG_EDB93XX_SDCS0
+
+#else
+#error "no SDCS configuration for this board"
+#endif
+
+
+#if defined(CONFIG_EDB93XX_SDCS3)
+#define CONFIG_SYS_LOAD_ADDR	0x01000000	/* Default load address	*/
+#define PHYS_SDRAM_1		0x00000000
+#elif defined(CONFIG_EDB93XX_SDCS0)
+#define CONFIG_SYS_LOAD_ADDR	0xc1000000	/* Default load address	*/
+#define PHYS_SDRAM_1		0xc0000000
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS		8
+
+#define CONFIG_SYS_INIT_SP_ADDR \
+    (CONFIG_SYS_SDRAM_BASE + 32*1024 - GENERATED_GBL_DATA_SIZE)
+
+
+/* Must match kernel config */
+#define LINUX_BOOT_PARAM_ADDR	(PHYS_SDRAM_1 + 0x100)
+
+/* Run-time memory allocatons */
+#define CONFIG_SYS_GBL_DATA_SIZE	128
+#define CONFIG_STACKSIZE		(128 * 1024)
+
+#if defined(CONFIG_USE_IRQ)
+#define CONFIG_STACKSIZE_IRQ	(4 * 1024)
+#define CONFIG_STACKSIZE_FIQ	(4 * 1024)
+#endif
+
+#define CONFIG_SYS_MALLOC_LEN		(512 * 1024)
+
+/* -----------------------------------------------------------------------------
+ * FLASH and environment organization
+ *
+ * The EDB9301, EDB9302(a), EDB9307a, EDB9315a have 1 bank of flash memory at
+ * 0x60000000 consisting of 1x Intel TE28F128J3C-150 128 Mbit flash on a 16-bit
+ * data bus, for a total of 16 MB of CFI-compatible flash.
+ *
+ * The EDB9307, EDB9312, and EDB9315 have 1 bank of flash memory at
+ * 0x60000000 consisting of 2x Micron MT28F128J3-12 128 Mbit flash on a 32-bit
+ * data bus, for a total of 32 MB of CFI-compatible flash.
+ *
+ *
+ *                            EDB9301/02(a)7a/15a    EDB9307/12/15
+ * 0x60000000 - 0x0003FFFF    u-boot                 u-boot
+ * 0x60040000 - 0x0005FFFF    environment #1         environment #1
+ * 0x60060000 - 0x0007FFFF    environment #2         environment #1 (continued)
+ * 0x60080000 - 0x0009FFFF    unused                 environment #2
+ * 0x600A0000 - 0x000BFFFF    unused                 environment #2 (continued)
+ * 0x600C0000 - 0x00FFFFFF    unused                 unused
+ * 0x61000000 - 0x01FFFFFF    not present            unused
+ */
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+
+
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+#define CONFIG_SYS_MAX_FLASH_SECT	(256+8)
+
+#define CONFIG_SYS_TEXT_BASE		0x60000000
+#define PHYS_FLASH_1			CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_FLASH_BASE		CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_MONITOR_LEN		(256 * 1024)
+
+#define CONFIG_ENV_OVERWRITE		/* Vendor params unprotected */
+#define CONFIG_ENV_IS_IN_FLASH
+
+#define CONFIG_ENV_ADDR			0x60040000
+#define CONFIG_ENV_ADDR_REDUND		(CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
+
+#define CONFIG_ENV_SIZE			CONFIG_ENV_SECT_SIZE
+#define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
+
+/* Define to enable MMC on SPI support */
+/* #define CONFIG_EP93XX_SPI_MMC */
+
+#ifdef CONFIG_EP93XX_SPI_MMC
+#define CONFIG_EP93XX_SPI
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MMC_SPI
+#define CONFIG_CMD_MMC
+#define CONFIG_MMC_SPI_NPOWER_EGPIO	9
+#endif
+
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_USB_OHCI_EP93XX
+#define CONFIG_SYS_USB_OHCI_CPU_INIT
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	3
+#define CONFIG_SYS_USB_OHCI_SLOT_NAME		"ep93xx-ohci"
+#define CONFIG_SYS_USB_OHCI_REGS_BASE		0x80020000
+
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_USB
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_CMD_BOOTZ
+
+/* Define to disable flash configuration*/
+/* #define CONFIG_EP93XX_NO_FLASH_CFG */
+
+/* Define this for indusrial rated chips */
+/* #define CONFIG_EDB93XX_INDUSTRIAL */
+
+#endif /* !defined (__CONFIG_H) */