⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcm1480_draminit.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  *********************************************************************    *  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 + -