📄 bcm1480_draminit.c
字号:
/* ********************************************************************* * BCM1280/BCM1480 Board Support Package * * DRAM Startup Module File: bcm1480_draminit.c * * This module contains code to initialize and start the DRAM * controller on the BCM1255/BCM1280/BCM1455/BCM1480. * * 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-BCM1480 things like * SOCVIEW, a JTAG tool. In that case it's not even running on a * 1400, 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 1400. */#ifdef _MCSTANDALONE_#include <stdio.h>#else#include "sbmips.h"#endif#include "bcm1480_regs.h"#include "bcm1480_mc.h"#include "bcm1480_scd.h"#include "sb1250_smbus.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 "bcm1250_dma.h"#endif/* ********************************************************************* * Magic Constants ********************************************************************* *//* * This constant represents the "round trip" time of your board. * Measured from the pins on the BCM1480, it is the time from the * rising edge of the MCLK pin to the rising edge of the DQS coming * back from the memory. (Note: 1250 values used for now.) * * 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 DLL_SCALE_NUMERATOR 30 /* 30/400 = 0.075 */#define DLL_SCALE_DENOMINATOR 400#define 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 bcm1480_auto_timing. */#define BCM1480_MIN_R2W_TIME 30 /* 3.0 ns */#define BCM1480_MIN_DQS_MARGIN 25#define BCM1480_WINDOW_OPEN_OFFSET 18#define BCM1480_CLOSE_01_OFFSET 34#define BCM1480_CLOSE_02_OFFSET 22#define BCM1480_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, data, and address class for memory drive config register. * Set all three to 1 as default. */#define V_MC_DRVCONFIG_CLASS_DEFAULT M_BCM1480_MC_CLK_CLASS | \ M_BCM1480_MC_DATA_CLASS | \ M_BCM1480_MC_ADDR_CLASS/* * Address, DQI, and DQO coarse/fine adjustments. */#define V_MC_DLLCONFIG_ADJ_DEFAULT V_BCM1480_MC_ADDR_COARSE_ADJ(0) | \ V_BCM1480_MC_ADDR_FINE_ADJ(0x8) | \ V_BCM1480_MC_DQI_COARSE_ADJ(0) | \ V_BCM1480_MC_DQI_FINE_ADJ(0x8) | \ V_BCM1480_MC_DQO_COARSE_ADJ(0) | \ V_BCM1480_MC_DQO_FINE_ADJ(0x8) | \ V_BCM1480_MC_DLL_DEFAULT_DEFAULT | \ V_BCM1480_MC_DLL_STEP_SIZE_DEFAULT/* * These belong in some BCM1480-specific file I'm sure. */#define MC_32BIT_CHANNELS 4 /* There are 4 32-bit channels */#define MC_32BIT_CHIPSELS 4 /* Each channel has 4 chip selects */#define MC_64BIT_CHANNELS 2 /* There are 2 64-bit channels */ #define MC_64BIT_CHIPSELS 8 /* Each channel has 8 chip selects */ #define MC_MAX_CHANNELS 4 #define MC_MAX_CHIPSELS 8#define MC_FIRSTCHANNEL 0/* ********************************************************************* * 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 BCM1480_REFCLK (*((uint64_t *) PHYS_TO_K1(0x1FC00018))) #undef K_SMB_FREQ_100KHZ #define K_SMB_FREQ_100KHZ ((BCM1480_REFCLK*10)/8)#else /* * If non-CFE, non-MIPS, make the refclk an input parameter. */ #if defined(_MCSTANDALONE_) int bcm1480_refclk = 100; int dram_cas_latency; int dram_tMemClk; #define BCM1480_REFCLK bcm1480_refclk #endif#endif/* * Define our reference clock. The default is 100MHz unless * overridden. You can override this in your bsp_config.h file. */#ifdef BCM1480_REFCLK_HZ #define BCM1480_REFCLK ((BCM1480_REFCLK_HZ)/1000000)#endif#ifndef BCM1480_REFCLK #define BCM1480_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_BL8 0x53 /* 8-byte bursts, sequential, CAS 1.5 */#define JEDEC_SDRAM_MRVAL_CAS2_BL8 0x23 /* 8-byte bursts, sequential, CAS 2 */#define JEDEC_SDRAM_MRVAL_CAS25_BL8 0x63 /* 8-byte bursts, sequential, CAS 2.5 */#define JEDEC_SDRAM_MRVAL_CAS3_BL8 0x33 /* 8-byte bursts, sequential, CAS 3 */#define JEDEC_SDRAM_MRVAL_CAS35_BL8 0x73 /* 8-byte bursts, sequential, CAS 3.5 */#define JEDEC_SDRAM_MRVAL_CAS4_BL8 0x43 /* 8-byte bursts, sequential, CAS 4.0 */#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_CAS4 0x42 /* 4-byte bursts, sequential, CAS 4.0 */#define JEDEC_SDRAM_MRVAL_RESETDLL 0x100#define JEDEC_SDRAM_MRVAL_WR_2 0x200#define JEDEC_SDRAM_MRVAL_WR_3 0x400#define JEDEC_SDRAM_MRVAL_WR_4 0x600#define JEDEC_SDRAM_MRVAL_WR_5 0x800#define JEDEC_SDRAM_MRVAL_WR_6 0xA00#define JEDEC_SDRAM_EMRVAL 0x000#define JEDEC_SDRAM_EMRVAL_OCD_DEFAULT 0x380#define JEDEC_SDRAM_EMRVAL_DQS_DISABLE 0x400#define JEDEC_SDRAM_EMRVAL_RDQS_ENABLE 0x800#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))/* ********************************************************************* * Memory region sizes (BCM1480-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 0x1400#define REGION3_SIZE (59*1024)/* ********************************************************************* * 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 info from table or SMbus */ uint8_t rows; /* 0: */ uint8_t cols; /* 1: */ uint8_t banks; /* 2: */ uint8_t flags; /* 3: */ uint8_t spd_dramtype; /* 4: SPD[2] */ uint8_t spd_tCK_25; /* 5: SPD[9] tCK @ CAS 2.5 */ uint8_t spd_tCK_20; /* 6: SPD[23] tCK @ CAS 2.0 */ uint8_t spd_tCK_10; /* 7: SPD[25] tCK @ CAS 1.0 */ uint8_t spd_rfsh; /* 8: SPD[12] Refresh Rate */ uint8_t spd_caslatency; /* 9: SPD[18] CAS Latencies Supported */ uint8_t spd_attributes; /* 10: SPD[21] Attributes */ uint8_t spd_tRAS; /* 11: SPD[30] */ uint8_t spd_tRP; /* 12: SPD[27] */ uint8_t spd_tRRD; /* 13: SPD[28] */ uint8_t spd_tRCD; /* 14: SPD[29] */ uint8_t spd_tRFC; /* 15: SPD[42] */ uint8_t spd_tRC; /* 16: SPD[41] */} csdata_t; /* total size: 17 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_40 0x80#define CS_CASLAT_MASK 0xF0#define CS_CASLAT_SHIFT 4typedef struct mcdata_s { /* Information per MC channel */ uint32_t cfgcsint; /* 0: try to interleave this many CS bits */ uint32_t csint; /* 4: # of chip select interleave bits */ uint32_t highest_cs_present; /* 8: Highest chip select being used. */ uint16_t mintmemclk; /* 12: minimum tMemClk */ uint16_t roundtrip; /* 14: Round trip time from CLK to returned DQS at BCM1250 pin */ uint16_t dramtype; /* 16: DRAM Type */ uint16_t clk_ratio; /* 18: clock ratio for delay loops */ uint32_t pagepolicy; /* 20: Page policy */ uint32_t chantype; /* 24: Channel type 32-bit or 64-bit */ uint32_t chanintlvint; /* 28: # of channel interleave bits */ uint32_t flags; /* 32: ECC enabled */ uint16_t tCK; /* 36: tCK for manual timing */ uint16_t rfsh; /* 38: refresh rate for manual timing */ uint16_t tWR; /* 40: Write recovery. DDR2 Mode Register field */ uint64_t dllcfg; /* 42: default dll config */ uint64_t drvcfg; /* 50: default drive config */ uint64_t mantiming; /* 58: manual timing */ uint64_t modebits; /* 66: mode bits (for ganged channels) */ csdata_t csdata[MC_MAX_CHIPSELS]; /* 74: per-chipsel data (8 * 17) */} mcdata_t; /* total size: 210 bytes */typedef struct initdata_s { uint64_t dscr[4]; /* 0: DMover descriptor (one cache line) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -