From mboxrd@z Thu Jan 1 00:00:00 1970 From: Albert ARIBAUD Date: Sat, 5 Jul 2014 00:22:05 +0200 Subject: [U-Boot] [PATCH v6] arm: ep9315: Return back Cirrus Logic EDB9315A board support In-Reply-To: <1403725469-4358-1-git-send-email-sergey.kostanbaev@gmail.com> References: <1403725469-4358-1-git-send-email-sergey.kostanbaev@gmail.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Sergey, On Wed, 25 Jun 2014 23:44:29 +0400, Sergey Kostanbev wrote: > This patch returns back support for old ep93xx processors family > > Signed-off-by: Sergey Kostanbaev > Cc: albert.u.boot at 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 > + * Copyright (C) 2013 > + * Sergey Kostanabev fairwaves.ru> > * > * Copyright (C) 2006 Dominic Rath > + * 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 > -#include > +#include > +#include > + > +/* > +/* 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 fairwaves.ru> > + * > * Copyright (C) 2009 > * Matthias Kaehlcke > * > @@ -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 fairwaves.ru> > +# > +# (C) Copyright 2003-2006 > +# Wolfgang Denk, DENX Software Engineering, wd 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 fairwaves.ru> > + * > + * Copyright (C) 2009 > + * Matthias Kaehlcke kaehlcke.net> > + * > + * (C) Copyright 2002 2003 > + * Network Audio Technologies, Inc. > + * Adam Bezanson netaudiotech.com> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +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(""); > + 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 > + > +/* > + * 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(®s->padr) | (1<padr); > + else > + writel(readl(®s->pbdr) | (1<<(num-8)), ®s->pbdr); > +} > + > +static void ep93xx_clear_epgio(unsigned num) > +{ > + struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; > + if (num < 8) > + writel(readl(®s->padr) & (~(1<padr); > + else > + writel(readl(®s->pbdr) & (~(1<<(num-8))), ®s->pbdr); > +} > + > +static void ep93xx_dir_epgio_out(unsigned num) > +{ > + struct gpio_regs *regs = (struct gpio_regs *)GPIO_BASE; > + if (num < 8) > + writel(readl(®s->paddr) | (1<paddr); > + else > + writel(readl(®s->pbddr) | (1<<(num-8)), ®s->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 > + > +#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 fairwaves.ru> > + * > + * Copyright (c) 2004-2008 Texas Instruments > + * > + * (C) Copyright 2002 > + * Gary Jennejohn, DENX Software Engineering, > + * > + * 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 > Active arm arm920t s3c24x0 samsung - smdk2410 - David M?ller > +Active arm arm920t ep93xx cirrus edb93xx edb9315a edb93xx:MK_edb9315a Sergey Kostanbaev > Active arm arm926ejs - armltd integrator integratorap_cm926ejs integratorap:CM926EJ_S Linus Walleij > Active arm arm926ejs - armltd integrator integratorcp_cm926ejs integratorcp:CM924EJ_S Linus Walleij > Active arm arm926ejs armada100 Marvell - aspenite - Prafulla Wadaskar > 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 fairwaves.ru> > + * > + * Inspired form linux kernel driver and atmel uboot driver > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > + > +#include > + > +#include > + > + > +#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 fairwaves.ru > > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > + > +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) > +#include > +#include > + > +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 > +#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, -- Albert.