📄 sbmemc.s
字号:
/* ********************************************************************* * Broadcom Common Firmware Environment (CFE) * * SDRAM init module File: sbmemc.S * * BCM5836 Sonics SiliconBackplane MEMC core initialization * ********************************************************************* * * Copyright 2002,2003,2004 * Broadcom Corporation. All rights reserved. * * This software is furnished under license and may be used and * copied only in accordance with the following terms and * conditions. Subject to these conditions, you may download, * copy, install, use, modify and distribute modified or unmodified * copies of this software in source and/or binary form. No title * or ownership is transferred hereby. * * 1) Any source code used, modified or distributed must reproduce * and retain this copyright notice and list of conditions * as they appear in the source file. * * 2) No right is granted to use any trade name, trademark, or * logo of Broadcom Corporation. The "Broadcom Corporation" * name may not be used to endorse or promote products derived * from this software without the prior written permission of * Broadcom Corporation. * * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************* */#include "sbmips32.h"#include "bsp_config.h"#include "sb_bp.h"#include "sbmemc.h"/* * LEAF - declare leaf routine */#undef LEAF#define LEAF(symbol) \ .globl symbol; \ .align 2; \ .type symbol,@function; \ .ent symbol,0; \symbol: .frame sp,0,ra/* * END - mark end of function */#undef END#define END(function) \ .end function; \ .size function,.-functionLEAF(board_draminfo) /* * XXX - in the future, v0 could return the address of the * PROM SDRAM table. */ move v0,zero # auto configure j raEND(board_draminfo)/* * Register usage within this file: * * top ncdlsearch test_mem Xdr_do_init sb_core_reset * v0: retval retval * v1: corerev - - corerev - * a0: coreptr coreptr - coreptr coreptr * a1: x x x sdr/ddr flag * a2: x * a3: x * t0: - - config * t1: - - mode * t2: - wr/strm off wr/strm * t3: - rd/strd rd/strd * t4: - g/clkd g/clkd * t5: x * t6: retaddr - - - * t7: - - retaddr - * s0: pass_count - - * s1: wrsum/clkdsum - - * s2: rdsum/pass_countmax - - * s3: gsum/strmmax - - * s4: wrlim/stdmmax - - * s5: rdlim/clkdmax - - * s6: glim/clkdlim - - * s7: dll - - * t8: - - x tmp * t9: - - x retaddr * k0: trace trace trace - - * k1: trace trace trace - - * gp: * sp: * s8: - step - - * ra: */LEAF(board_draminit) .set noreorder /* Save return address */ move t6,ra /* Scan for a MEMC controller (a0) */ li a0,PHYS_TO_K1(SB_ENUM_BASE)1: lw v1,R_SBIDHIGH(a0) and a1,v1,M_SBID_CR srl a1,a1,S_SBID_CR beq a1,K_CR_MEMC,read_nvram nop addu a0,SB_CORE_SIZE bne a1,(M_SBID_CR >> S_SBID_CR),1b # XXX No bus error? nop /* No MEMC controller */ jr t6 li v0, 0read_nvram: /* Isolate corerev in v1 */ and v1,v1,M_SBID_RV#ifdef BCM5365 li v1,1 # chip mis-id, per HNBU#endif#if 0 /* XXX Force defaults */ /* Find NVRAM (a2) */ li t0,PHYS_TO_K1(SB_ENUM_BASE) # Is it a chipcommon core? lw t1,R_SBIDHIGH(t0) and t1,t1,M_SBID_CR srl t1,t1,S_SBID_CR bne t1,K_CR_CHIP_COMMON,notcc nop /* If it is a chipcommon core, use the 32MB window */ li t2,(CC_FLASH_BASE - NVRAM_SPACE) li t4,CC_FLASH_MAX b find_nvram nopnotcc: /* else use the 4MB window */ li t2,(FLASH_BASE - NVRAM_SPACE) li t4,FLASH_MAXfind_nvram: li t3,FLASH_MIN li t0, NVRAM_MAGIC1: add a2,t2,t3 lw t1, 0(a2) beq t0,t1,read_parms nop sll t3,t3,1 ble t3,t4,1b nop /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ li a2,(FLASH_BASE + 0x1000) lw t1,0(a2) beq t0,t1,read_parms nop li a2,(FLASH_BASE + 0x400) lw t1,0(a2) beq t0,t1,read_parms nop#endif /* XXX */ b init # No NVRAM li a2, 0read_parms: /* Get SDRAM parameters (t0, t1, t2) from NVRAM (a2) */ lw t0, 8(a2) # SDRAM init srl t0, 16 lw t2, 12(a2) andi t1, t2, 0xffff # SDRAM config srl t2, 16 # SDRAM refresh lw t3,16(a2) # SDRAM ncdlinit:memc_init: bnez a2,1f # Already have the parms in t0, t1, t2, t3 nop /* No nvram parms: get configured values (sbmemc.h) */#ifdef MEMSDR li t0,MEMC_SDR_INIT li t1,MEMC_SDR_MODE li t3,MEMC_SDR_NCDL # If rev0, 2: bne v1,1,1f nop li t3,MEMC_SDR1_NCDL # rev1:1:#else li t0,MEMC_DDR_INIT li t1,MEMC_DDR_MODE li t3,MEMC_DDR_NCDL # If rev0, 2: bne v1,1,1f nop li t3,MEMC_DDR1_NCDL # rev1:1:#endif andi a3,t0,MEMC_CONFIG_DDR # Low bit of init selects ddr or sdr beqz a3,memc_sdr_init nop/* * Routines for initializing DDR SDRAM */ memc_ddr_init: beqz t3,ddr_find_ncdl # Do we have ncdl values? (0s) nop li t4,-1 # or ffs bne t3,t4,break_ddr_ncdl nopddr_find_ncdl:/* Register usage */#define pass_count s0#define wrsum s1#define rdsum s2#define gsum s3#define wrlim s4#define rdlim s5#define glim s6#define dll s7#define step s8#define wr t2#define rd t3#define g t4 /* Initialize counter & accumulators */ move pass_count,zero move wrsum,zero move rdsum,zero move gsum,zero /* Initialize with default values */ li wr,5 li rd,5 bal ddr_do_init li g,10 /* Read dll value */ lw dll,MEMC_NCDLCTL(a0) andi dll,dll,0xfe srl dll,dll,1 beqz dll,szmem # If zero, leave the default values nop move wrlim,dll # dll value is lim for wr, rd and g move rdlim,dll move glim,dll addi step,dll,15 # step = (dll + 16 - 1) / 16 srl step,step,4 sub wr,zero,dll # Negate dll as initial value move rd,wr move g,wr /* Inner loop: call ddr_do_init to re-initialize and the test mem */loop: bal ddr_do_init nop bal test_mem nop beqz v0,nextg nop /* Memory is ok */ addi pass_count,1 add wrsum,wrsum,wr add rdsum,rdsum,rd add gsum,gsum,g bne wr,dll,1f nop sll wrlim,dll,11: bne rd,dll,2f nop sll rdlim,dll,12: bne g,dll,nextg nop sll glim,dll,1nextg: add g,g,step ble g,glim,loop nop sub g,zero,dll move glim,dll /* nextrd: */ add rd,rd,step ble rd,rdlim,loop nop sub rd,zero,dll move rdlim,dll /* nextwr: */ add wr,wr,step ble wr,wrlim,loop nop /* All done, calculate average values and program them */ beqz pass_count,1f nop div zero,wrsum,pass_count mflo wr div zero,rdsum,pass_count mflo rd div zero,gsum,pass_count mflo g b ddr_got_ncdl nop /* No passing values, panic! (use defaults) */1:#ifdef MEMSDR li t3,MEMC_SDR_NCDL # If rev0, 2: bne v1,1,2f nop li t3,MEMC_SDR1_NCDL # rev1:#else li t3,MEMC_DDR_NCDL # If rev0, 2: bne v1,1,2f nop li t3,MEMC_DDR1_NCDL # rev1:#endif2:break_ddr_ncdl: andi t4,t3,0xff # t4: g srl t2,t3,16 # t2: wr andi t2,t2,0xff srl t3,t3,8 # t3: rd andi t3,t3,0xffddr_got_ncdl: bal ddr_do_init nop b szmem nop /* Do an init of the memc core for ddr * a0: memc core pointer * t0: memc config value * t1: memc mode value * t2: memc wr ncdl value * t3: memc rd ncdl value * t4: memc g ncdl value * * Uses a1, t7, t8, t9 (here and by calling sb_core_reset) */ddr_do_init: /* Save return address */ move t7,ra bal sb_core_reset li a1,0 li a1,MEMC_CONFIG_INIT or a1,a1,t0 sw a1,MEMC_CONFIG(a0) li a1,MEMC_DRAMTIM25_INIT # Assume CAS latency of 2.5 andi t8,t1,0xf0 # Find out the CAS latency bne t8,0x20,1f nop li a1,MEMC_DRAMTIM2_INIT # CAS latency is 21: sw a1,MEMC_DRAMTIM(a0) andi t8,t3,0xff sll a1,t8,8 # Replicate rd ncdl 4 times or a1,a1,t8 sll t8,a1,16 or t8,t8,a1 li a1,MEMC_RDNCDLCOR_INIT or a1,a1,t8 sw a1,MEMC_RDNCDLCOR(a0) li a1,MEMC_WRNCDLCOR_INIT # If rev0, 2: bne v1,1,1f nop li a1,MEMC_1_WRNCDLCOR_INIT # rev11: andi t8,t2,0xff or a1,a1,t8 sw a1,MEMC_WRNCDLCOR(a0) li a1,MEMC_DQSGATENCDL_INIT andi t8,t4,0xff or a1,a1,t8 sw a1,MEMC_DQSGATENCDL(a0) li a1,MEMC_MISCDLYCTL_INIT # If rev0, 2: bne v1,1,2f nop li a1,MEMC_1_MISCDLYCTL_INIT # rev12: sw a1,MEMC_MISCDLYCTL(a0) li a1,MEMC_NCDLCTL_INIT sw a1,MEMC_NCDLCTL(a0) li a1,MEMC_CONTROL_INIT0 sw a1,MEMC_CONTROL(a0) li a1,MEMC_CONTROL_INIT1 sw a1,MEMC_CONTROL(a0) li a1,MEMC_MODEBUF_INIT0 sw a1,MEMC_MODEBUF(a0) li a1,MEMC_CONTROL_INIT2 sw a1,MEMC_CONTROL(a0) li a1,MEMC_MODEBUF_INIT1 or a1,a1,t1 sw a1,MEMC_MODEBUF(a0) li a1,MEMC_CONTROL_INIT3 sw a1,MEMC_CONTROL(a0) li a1,MEMC_CONTROL_INIT4 sw a1,MEMC_CONTROL(a0) li a1,MEMC_CONTROL_INIT5 sw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) li a1,MEMC_CONTROL_INIT5 sw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) lw a1,MEMC_CONTROL(a0) li a1,MEMC_REFRESH_INIT sw a1,MEMC_REFRESH(a0) li a1,MEMC_MODEBUF_INIT2 or a1,a1,t1 sw a1,MEMC_MODEBUF(a0) li a1,MEMC_CONTROL_INIT6 sw a1,MEMC_CONTROL(a0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -