📄 mem285.s
字号:
// #========================================================================
// #
// # mem285.S
// #
// # StrongARM EBSA-285 memory setup
// #
// #========================================================================
// ####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Red Hat eCos Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.redhat.com/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations under
// the License.
//
// The Original Code is eCos - Embedded Configurable Operating System,
// released September 30, 1998.
//
// The Initial Developer of the Original Code is Red Hat.
// Portions created by Red Hat are
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
// All Rights Reserved.
// -------------------------------------------
//
// ####COPYRIGHTEND####
// #========================================================================
// ######DESCRIPTIONBEGIN####
// #
// # Author(s): Red Hat, hmt
// # Contributors: Red Hat, hmt
// # Date: 1999-07-05
// # Purpose: StrongARM EBSA-285 SDRAM initialization
// # Description: SDRAM Initialization for Intel(R) SA-110 21285 Companion
// # Chip
// # Intel is a Registered Trademark of Intel Corporation.
// # Other Brands and Trademarks are the property of their
// # respective owners.
// #
// #####DESCRIPTIONEND####
// #
// #========================================================================
.file "mem285.S"
.title "SDRAM Init for Intel(R) SA-110 21285 Companion Chip"
#include <cyg/hal/hal_ebsa285.h>
#include <pkgconf/system.h>
.text
.align 4
#define ARRAY_0_MODE_REGISTER (SA110_SDRAM_ARRAY_0_MODE_REGISTER_BASE)
#define ARRAY_1_MODE_REGISTER (SA110_SDRAM_ARRAY_1_MODE_REGISTER_BASE)
#define MODE_REGISTER_STEP (ARRAY_1_MODE_REGISTER - ARRAY_0_MODE_REGISTER)
// [6:4] /CAS Latency is 2 (2)
// [ 3 ] Burst Type is 0, Sequential
// [2:0] Burst Length is 2, meaning 4
#define SDRAM_MODE_REGISTER_SETUP 0x22
// Shifted left 2 because this is a word-address-offset!
#define SDRAM_MODE_REGISTER_SETUP_OFFSET ((SDRAM_MODE_REGISTER_SETUP) << 2)
#define SDRAM_TIMING_VALUE (SA110_SDRAM_ROW_PRECHARGE_2_CYCLES | \
SA110_SDRAM_LAST_DATA_IN_3_CYCLES | \
SA110_SDRAM_RAS_TO_CAS_DELAY_2_CYCLES | \
SA110_SDRAM_CAS_LATENCY_2_CYCLES | \
SA110_SDRAM_ROW_CYCLE_TIME_4_CYCLES | \
SA110_SDRAM_COMMAND_DRIVE_SAME_CYCLE)
#define SDRAM_TIMING_VALUE_MIN (SDRAM_TIMING_VALUE | \
SA110_SDRAM_REFRESH_INTERVAL_MIN)
#define SDRAM_TIMING_VALUE_NORMAL (SDRAM_TIMING_VALUE | \
SA110_SDRAM_REFRESH_INTERVAL_NORMAL)
/*
* This subroutine sizes and configures up to four banks of SDRAM DIMMs.
* It runs early without a stack.
*
* R0 - R9 are destroyed. All others preserved.
* Except r11 which is also destroyed.
*
*/
.global __mem285_init
__mem285_init:
/*
* First we find out whether the SDRAMs are already initialized,
* and if so, leave them alone. RAM start implies just do the
* sizing sums to return top of memory.
*/
ldr r0, =SA110_CONTROL_STATUS_BASE
#ifndef CYG_HAL_STARTUP_RAM
// This is conditional even in ROM start for
// a) testing ROM images eg. stubs in RAM really
// b) cooperation with eg. POST code, so we are not really at reset
ldr r0, =SA110_CONTROL_STATUS_BASE
ldr r1, [r0, #SA110_SDRAM_TIMING_o]
ldr r2, =SDRAM_TIMING_VALUE_NORMAL
cmps r1, r2
movne r11, #0
bne 12f
#endif // ! defined CYG_HAL_STARTUP_RAM
// Add up the sizes and return in r0:
mov r1, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o
mov r2, #0
mov r3, #1
1:
ldr r4, [r0, r1]
ands r4, r4, #7 // if zero, no mem here
addne r2, r2, r3, asl r4 // tot up array sizes (in 1/2 Megs)
add r1, r1, #4
cmps r1, #(SA110_SDRAM_ADDRESS_SIZE_ARRAY_3_o + 4)
blt 1b
mov r0, r2, asl #19 // get size into Mb
mov pc, lr
#ifndef CYG_HAL_STARTUP_RAM
12:
/*
* Write to the SDRAM Timing Register in the 21285. Disable
* refresh totally.
*/
mov r1, #0
str r1, [r0, #SA110_SDRAM_TIMING_o]
// Disable each array
mov r1, #0
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_1_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_2_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_3_o]
// Wait for 8 refresh cycles to complete
mov r1, #(9 * 32)
1: subs r1, r1, #1
bpl 1b
/*
* Force an all-banks recharge on all four SDRAM arrays
*
* This code came from the SA-IOP ver 1.0 (3-16-98) spec pg 22
*
* You must access all four arrays regardless of whether there is
* memory there because the 21285 counts the precharge accesses and
* inhibits access to the SDRAM until all four have been done.
*
* An all banks rechargs is initiated by a read from any address
* in the mode register space.
*/
mov r1, #3
mov r0, #ARRAY_0_MODE_REGISTER
1:
ldr r2, [r0]
add r0, r0, #MODE_REGISTER_STEP
subs r1, r1, #1
bpl 1b
/*
* Now we need to write to the SDRAM Mode Register.
* The address is important, not the data. The mode register
* should be configured for a burst size of 4 with linear addressing
*/
mov r1, #3
mov r0, #ARRAY_0_MODE_REGISTER
1:
str r0, [r0, #SDRAM_MODE_REGISTER_SETUP_OFFSET]
add r0, r0, #MODE_REGISTER_STEP
subs r1, r1, #1
bpl 1b
/*
* Write to the SDRAM Timing Register in the 21285. Set the
* refresh interval to the minimum because we have to wait for
* 8 refresh cycles to complete before we can rely on the SDRAMs
* to be operating normally
*/
ldr r0, =SA110_CONTROL_STATUS_BASE
ldr r1, =SDRAM_TIMING_VALUE_MIN
str r1, [r0, #SA110_SDRAM_TIMING_o]
// Disable each array
mov r1, #0
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_1_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_2_o]
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_3_o]
// Wait for 8 refresh cycles to complete
mov r1, #(9 * 32)
1: subs r1, r1, #1
bpl 1b
// Now reset the Refresh interval to a sensible value
ldr r1, =SDRAM_TIMING_VALUE_NORMAL
str r1, [r0, #SA110_SDRAM_TIMING_o]
/* start out assuming 64M part with MUX mode 2 */
mov r1, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE2)
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o]
add r1, r1, #(64 << 20) // Add 64Mb
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_1_o]
add r1, r1, #(64 << 20) // Add 64Mb again
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_2_o]
add r1, r1, #(64 << 20) // Add 64Mb and again
str r1, [r0, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_3_o]
/*
* First, try to figure out which banks are populated and
* the real mux mode for those banks.
*
* At this point:
* r0 - Base of control/status registers
*
* Register usage:
* r8 - offset to SDRAM addr/size register
* r5 - pattern
* r4 - inverse pattern
* r3 - scratch/mux mode output
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -