mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 12:08:19 +00:00 
			
		
		
		
	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
		
			
				
	
	
		
			459 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			459 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * 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 <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:
 | |
| 
 | |
| 	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
 | |
| 
 | |
| 
 | |
| ep93xx_sdram_done:
 | |
| 	ldr	r1, =EP93XX_LED_DATA
 | |
| 	ldr	r0, [r1]
 | |
| 	bic	r0, r0, #EP93XX_LED_RED_ON
 | |
| 	str	r0, [r1]
 | |
| 
 | |
| 	/* Determine the size of the SDRAM. */
 | |
| 	mov	r0, r11
 | |
| 	bl	ep93xx_sdram_size
 | |
| 
 | |
| 	/* Save the SDRAM characteristics. */
 | |
| 	mov	r8, r0
 | |
| 	mov	r9, r1
 | |
| 	mov	r10, r2
 | |
| 
 | |
| 	/* 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
 | |
| 
 | |
| 	/* 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
 | |
| 
 | |
| #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]
 | |
| 
 | |
| 	/* Save the memory configuration information. */
 | |
| 	orr	r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE
 | |
| 	stmia	r0, {r8-r11}
 | |
| 
 | |
| 	mov	lr, r6
 | |
| 	mov	pc, lr
 |