📄 sb1250_draminit.c
字号:
/* ********************************************************************* * SB1250 Board Support Package * * DRAM Startup Module File: sb1250_draminit.c * * This module contains code to initialize and start the DRAM * controller on the SB1250. * * This is the fancy new init module, written in "C". * * Author: Mitch Lichtenberg * ********************************************************************* * * Copyright 2000,2001,2002,2003 * 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. ********************************************************************* *//* * This code can be linked into non-CFE, non-SB1250 things like SOCVIEW, a JTAG * tool. In that case it's not even running on a 1250, but we can * borrow the code to generate timing values for us. * * The _MCSTANDALONE_ ifdef is normally turned *off* for firmware use, * but programs like "memconfig" (CFE host tool) or SOCVIEW use it * to allow us to run the memory initialization outside a 1250. */#ifdef _MCSTANDALONE_#include <stdio.h>#else#include "sbmips.h"#endif#include "sb1250_regs.h"#include "sb1250_mc.h"#include "sb1250_smbus.h"#include "sb1250_scd.h"/* * Uncomment to use data mover to zero memory * Note: this is not a good idea in Pass1, since we'll * be running cacheable noncoherent at this point in the * CFE init sequence. *//* #define _DMZERO_ */#ifdef _DMZERO_#include "sb1250_dma.h"#endif/* ********************************************************************* * Magic Constants ********************************************************************* *//* * This constant represents the "round trip" time of your board. * Measured from the pins on the BCM1250, it is the time from the * rising edge of the MCLK pin to the rising edge of the DQS coming * back from the memory. * * It is used in the calculation of which cycle responses are expected * from the memory for a given request. The units are in tenths of * nanoseconds. */#define DEFAULT_MEMORY_ROUNDTRIP_TIME 25 /* 2.5ns (default) */#define DEFAULT_MEMORY_ROUNDTRIP_TIME_FCRAM 20 /* 2.0ns for FCRAM */#define PASS1_DLL_SCALE_NUMERATOR 30 /* 30/400 = 0.075 */#define PASS1_DLL_SCALE_DENOMINATOR 400#define PASS1_DLL_OFFSET 63 /* 63/400 = 0.1575 */#define PASS2_DLL_SCALE_NUMERATOR 30 /* 30/400 = 0.075 */#define PASS2_DLL_SCALE_DENOMINATOR 400#define PASS2_DLL_OFFSET 63 /* 63/400 = 0.1575 *//* * The constants below were created by careful measurement of * BCM1250 parts. The units are in tenths of nanoseconds * to be compatible with the rest of the calculations in sb1250_auto_timing. */#define SB1250_MIN_R2W_TIME 30 /* 3.0 ns */#define SB1250_MIN_DQS_MARGIN 25#define SB1250_WINDOW_OPEN_OFFSET 18#define SB1250_CLOSE_01_OFFSET 34#define SB1250_CLOSE_02_OFFSET 22#define SB1250_CLOSE_12_OFFSET 24#define BURSTLEN 4 /* always 4 per burst *//* ********************************************************************* * Basic types ********************************************************************* */#ifdef _CFE_#include "lib_types.h"#elsetypedef unsigned char uint8_t;typedef unsigned short uint16_t;typedef unsigned int uint32_t;typedef unsigned long long uint64_t;#endif/* * For SOCVIEW and non-CFE, non-MIPS stuff, make sure the "port" * data type is 64 bits. Otherwise we take our cue from 'long' * which will be pointer-sized. */#if defined(_MCSTANDALONE_)typedef long long sbport_t;#elsetypedef long sbport_t;#endif#ifdef _CFE_#include "bsp_config.h"#endif#define TRUE 1#define FALSE 0/* ********************************************************************* * Configuration ********************************************************************* *//* * This module needs to be compiled with mips64 to ensure that 64-bit * values are in 64-bit registers and that reads/writes of 64-bit numbers * are done with the ld/sd instructions. */#if !defined(__mips64) && !defined(_MCSTANDALONE_)#error "This module MUST be compiled with __mips64. See the comments for details."#endif/* * Configure some stuff here if not running under the firmware. */#ifndef _CFE_#define CFG_DRAM_ECC 0#define CFG_DRAM_SMBUS_CHANNEL 0#define CFG_DRAM_SMBUS_BASE 0x54#define CFG_DRAM_BLOCK_SIZE 32#endif/* * Clock configuration parameters, except for the MCLK ratio * which is set according to the value of the PLL divide ratio. */#define V_MC_CLKCONFIG_VALUE_PASS1 V_MC_ADDR_SKEW(0x0F) | \ V_MC_DQO_SKEW(0x8) | \ V_MC_DQI_SKEW(0x8) | \ V_MC_ADDR_DRIVE(0xF) | \ V_MC_DATA_DRIVE(0xF) | \ V_MC_CLOCK_DRIVE(0) #define V_MC_CLKCONFIG_VALUE V_MC_ADDR_SKEW(0x08) | \ V_MC_DQO_SKEW(0x8) | \ V_MC_DQI_SKEW(0x8) | \ V_MC_ADDR_DRIVE(0xF) | \ V_MC_DATA_DRIVE(0xF) | \ V_MC_CLOCK_DRIVE(0xF) /* * These belong in some SB1250-specific file I'm sure. */#define MC_CHANNELS 2 /* we have two channels */#define MC_CHIPSELS 4 /* and four chipsels per channel *//* ********************************************************************* * Reference Clock ********************************************************************* */#ifdef _MAGICWID_ /* * You really don't want to know about this. During testing, we futz * with the 100mhz clock and store the actual speed of the clock * in the PromICE so we can make the calculations work out correctly * (and automatically) */ #define SB1250_REFCLK (*((uint64_t *) PHYS_TO_K1(0x1FC00018))) #undef K_SMB_FREQ_100KHZ #define K_SMB_FREQ_100KHZ ((SB1250_REFCLK*10)/8)#else /* * If non-CFE, non-MIPS, make the refclk an input parameter. */ #if defined(_MCSTANDALONE_) int sb1250_refclk = 100; int dram_cas_latency; int dram_tMemClk; #define SB1250_REFCLK sb1250_refclk #endif#endif/* * Define our reference clock. The default is 100MHz unless * overridden. You can override this in your bsp_config.h file. */#ifdef SB1250_REFCLK_HZ #define SB1250_REFCLK ((SB1250_REFCLK_HZ)/1000000)#endif#ifndef SB1250_REFCLK #define SB1250_REFCLK 100 /* speed of refclk, in Mhz */#endif/* ********************************************************************* * Macros ********************************************************************* *//* * For the general case, reads/writes to MC CSRs are just pointer * references. In SOCVIEW and other non-CFE, non-MIPS programs, we hook the * read/write calls to let us supply the data from somewhere else. */#if defined(_MCSTANDALONE_) #define PHYS_TO_K1(x) (x) #define WRITECSR(csr,val) sbwritecsr(csr,val) #define READCSR(csr) sbreadcsr(csr) extern void sbwritecsr(uint64_t,uint64_t); extern uint64_t sbreadcsr(uint64_t);#else /* normal case */ #define WRITECSR(csr,val) *((volatile uint64_t *) (csr)) = (val) #define READCSR(csr) (*((volatile uint64_t *) (csr)))#endif/* ********************************************************************* * JEDEC values ********************************************************************* */#define JEDEC_SDRAM_MRVAL_CAS15 0x52 /* 4-byte bursts, sequential, CAS 1.5 */#define JEDEC_SDRAM_MRVAL_CAS2 0x22 /* 4-byte bursts, sequential, CAS 2 */#define JEDEC_SDRAM_MRVAL_CAS25 0x62 /* 4-byte bursts, sequential, CAS 2.5 */#define JEDEC_SDRAM_MRVAL_CAS3 0x32 /* 4-byte bursts, sequential, CAS 3 */#define JEDEC_SDRAM_MRVAL_CAS35 0x72 /* 4-byte bursts, sequential, CAS 3.5 */#define JEDEC_SDRAM_MRVAL_RESETDLL 0x100#define JEDEC_SDRAM_EMRVAL 0x00#define FCRAM_MRVAL 0x32#define FCRAM_EMRVAL 0#define SGRAM_MRVAL 0x32 /* 4-byte bursts, sequential, CAS 3 */#define SGRAM_MRVAL_RESETDLL 0x400#define SGRAM_EMRVAL 0x02/* * DECTO10THS(x) - this converts a BCD-style number found in * JEDEC SPDs to a regular number. So, 0x75 might mean "7.5ns" * and we convert this into tenths (75 decimal). Many of the * calculations for the timing are done in terms of tenths of nanoseconds */#define DECTO10THS(x) ((((x) >> 4)*10)+((x) & 0x0F))/* ********************************************************************* * Configuration parameter values ********************************************************************* */#ifndef CFG_DRAM_MIN_tMEMCLK#define CFG_DRAM_MIN_tMEMCLK DRT10(8,0) /* 8 ns, 125Mhz */#endif#ifndef CFG_DRAM_INTERLEAVE#define CFG_DRAM_INTERLEAVE 0#endif#ifndef CFG_DRAM_SMBUS_CHANNEL#define CFG_DRAM_SMBUS_CHANNEL 0#endif#ifndef CFG_DRAM_SMBUS_BASE#define CFG_DRAM_SMBUS_BASE 0x54#endif#ifndef CFG_DRAM_ECC#define CFG_DRAM_ECC 0#endif#ifndef CFG_DRAM_BLOCK_SIZE#define CFG_DRAM_BLOCK_SIZE 32#endif#ifndef CFG_DRAM_CSINTERLEAVE#define CFG_DRAM_CSINTERLEAVE 0#endif/* ********************************************************************* * Memory region sizes (SB1250-specific) ********************************************************************* */#define REGION0_LOC 0x0000#define REGION0_SIZE 256#define REGION1_LOC 0x0800#define REGION1_SIZE 512#define REGION2_LOC 0x0C00#define REGION2_SIZE 256#define REGION3_LOC 0x1000#define REGION3_SIZE (508*1024) /* 508 GB! *//* ********************************************************************* * Global Data structure * * This is a hideous hack. We're going to actually use "memory" * before it is configured. The L1 DCache will be clean before * we get here, so we'll just locate this structure in memory * (at 0, for example) and "hope" we don't need to evict anything. * If we keep the data below 256 cache lines, we'll only use one way * of each cache line. That's 8K, more than enough. * * This data structure needs to be used both for our data and the * "C" stack, so be careful when you edit it! ********************************************************************* */typedef struct csdata_s { /* Geometry information from table */ uint8_t rows; /* or SMBbus */ uint8_t cols; uint8_t banks; uint8_t flags; uint8_t spd_dramtype; /* SPD[2] */ uint8_t spd_tCK_25; /* SPD[9] tCK @ CAS 2.5 */ uint8_t spd_tCK_20; /* SPD[23] tCK @ CAS 2.0 */ uint8_t spd_tCK_10; /* SPD[25] tCK @ CAS 1.0 */ uint8_t spd_rfsh; /* SPD[12] Refresh Rate */ uint8_t spd_caslatency; /* SPD[18] CAS Latencies Supported */ uint8_t spd_attributes; /* SPD[21] Attributes */ uint8_t spd_tRAS; /* SPD[30] */ uint8_t spd_tRP; /* SPD[27] */ uint8_t spd_tRRD; /* SPD[28] */ uint8_t spd_tRCD; /* SPD[29] */ uint8_t spd_tRFC; /* SPD[42] */ uint8_t spd_tRC; /* SPD[41] */} csdata_t; /* total size: 16 bytes */#define CS_PRESENT 1 /* chipsel is present (in use) */#define CS_AUTO_TIMING 2 /* chipsel has timing information */#define CS_CASLAT_10 0x20 /* upper four bits are the CAS latency */#define CS_CASLAT_15 0x30 /* we selected. bits 7..5 are the */#define CS_CASLAT_20 0x40 /* whole number and bit 4 is the */#define CS_CASLAT_25 0x50 /* fraction. */#define CS_CASLAT_30 0x60#define CS_CASLAT_MASK 0xF0#define CS_CASLAT_SHIFT 4typedef struct mcdata_s { /* Information per memory controller */ uint32_t cfgcsint; /* try to interleave this many CS bits */ uint32_t csint; /* # of chip select interleave bits */ uint16_t mintmemclk; /* minimum tMemClk */ uint16_t roundtrip; /* Round trip time from CLK to returned DQS at BCM1250 pin */ uint32_t dramtype; /* DRAM Type */ uint32_t pagepolicy; /* Page policy */ uint32_t blksize; /* Block Size */ uint32_t flags; /* ECC enabled */ uint16_t tCK; /* tCK for manual timing */ uint16_t rfsh; /* refresh rate for manual timing */ uint64_t clkconfig; /* default clock config */ uint64_t mantiming; /* manual timing */ csdata_t csdata[MC_CHIPSELS]; /* Total size: 48 + 16*4 = 112 bytes */} mcdata_t;typedef struct initdata_s { uint64_t dscr[4]; /* Data Mover descriptor (one cache line)*/ uint32_t flags; /* various flags */ uint32_t inuse; /* indicates MC is in use */ uint32_t pintbit; /* port interleave bit */ uint16_t firstchan; /* first channel */ uint16_t soctype; /* SOC type */ uint64_t ttlbytes; /* total bytes */ mcdata_t mc[MC_CHANNELS]; /* data per memory controller */} initdata_t; /* Total size: 56 + 112*2 = 280 bytes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -