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

📄 sb1250_draminit.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
	    loopcs->cols  = cs->cols;	    loopcs->banks = cs->banks;	    loopcs->flags = CS_PRESENT;	    loopcs->spd_dramtype   = spd[JEDEC_SPD_MEMTYPE];	    loopcs->spd_tCK_25     = spd[JEDEC_SPD_tCK25];	    loopcs->spd_tCK_20     = spd[JEDEC_SPD_tCK20];	    loopcs->spd_tCK_10     = spd[JEDEC_SPD_tCK10];	    loopcs->spd_rfsh       = spd[JEDEC_SPD_RFSH];	    loopcs->spd_caslatency = spd[JEDEC_SPD_CASLATENCIES];	    loopcs->spd_attributes = spd[JEDEC_SPD_ATTRIBUTES];	    loopcs->spd_tRAS       = spd[JEDEC_SPD_tRAS];	    loopcs->spd_tRP        = spd[JEDEC_SPD_tRP];	    loopcs->spd_tRRD       = spd[JEDEC_SPD_tRRD];	    loopcs->spd_tRCD       = spd[JEDEC_SPD_tRCD];	    loopcs->spd_tRFC       = spd[JEDEC_SPD_tRFC];	    loopcs->spd_tRC        = spd[JEDEC_SPD_tRC];	    }	}}/*  *********************************************************************    *  SB1250_DRAM_READPARAMS(d,init)    *      *  Read all the parameters from the user parameter table and    *  digest them into our local data structure.  This routine basically    *  walks the table and calls the routine above to handle each    *  entry.    *      *  Input parameters:     *  	   d - our data structure (our RAM data)    *  	   init - pointer to user config table    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sb1250_dram_readparams(initdata_t *d,const draminittab_t *init){    mcdata_t *mc;    csdata_t *cs;    uint64_t sysrev;    sysrev = READCSR(PHYS_TO_K1(A_SCD_SYSTEM_REVISION));    /*     * Assume we're starting on the first channel.  We should have a CHCFG record     * to set the initial channel number, this is just in case.     */    mc = &(d->mc[d->firstchan]);    /* Default clock config unless overridden */    if (G_SYS_REVISION(sysrev) >= K_SYS_REVISION_PASS1 &&	G_SYS_REVISION(sysrev) < K_SYS_REVISION_PASS2) {	/* pass1 */	mc->clkconfig = V_MC_CLKCONFIG_VALUE_PASS1;	}    else {	/* pass2 */	mc->clkconfig = V_MC_CLKCONFIG_VALUE;	}    cs = &(mc->csdata[0]);    while (init->mcr.mcr_type != MCR_EOT) {#ifdef _MCSTANDALONE_NOISY_	printf("DRAM: Processing record '%s'\n",sb1250_rectypes[init->mcr.mcr_type]);#endif	switch (init->mcr.mcr_type) {	    case MCR_GLOBALS:		if (init->gbl.gbl_intlv_ch) d->flags |= M_MCINIT_TRYPINTLV;		break;	    case MCR_CHCFG:		mc = &(d->mc[init->cfg.cfg_chan]);		mc->mintmemclk = DECTO10THS(init->cfg.cfg_mintmemclk);		mc->dramtype   = init->cfg.cfg_dramtype;		mc->pagepolicy = init->cfg.cfg_pagepolicy;		mc->blksize    = init->cfg.cfg_blksize;		mc->cfgcsint   = init->cfg.cfg_intlv_cs;		/* Default clock config unless overridden */		if (G_SYS_REVISION(sysrev) >= K_SYS_REVISION_PASS1 &&		    G_SYS_REVISION(sysrev) < K_SYS_REVISION_PASS2) {		    /* pass1 */		    mc->clkconfig = V_MC_CLKCONFIG_VALUE_PASS1;		    }		else {		    /* pass2 */		    mc->clkconfig = V_MC_CLKCONFIG_VALUE;		    }		mc->flags = (init->cfg.cfg_ecc & MCFLG_ECC_ENABLE) |		    (init->cfg.cfg_flags & (MCFLG_FORCEREG | MCFLG_BIGMEM));		mc->roundtrip  = DECTO10THS(init->cfg.cfg_roundtrip);		if (mc->roundtrip == 0 && mc->dramtype != DRAM_TYPE_SPD) {		    /* 		     * Only set default roundtrip if mem type is specified, else wait		     * to get type from SPD 		     */		    mc->roundtrip = (mc->dramtype == FCRAM) ?			DEFAULT_MEMORY_ROUNDTRIP_TIME_FCRAM : DEFAULT_MEMORY_ROUNDTRIP_TIME;		    }		if (mc->dramtype == FCRAM) mc->pagepolicy = CLOSED; 	/*FCRAM must be closed page policy*/		cs = &(mc->csdata[0]);		break;	    case MCR_TIMING:		cs->spd_tCK_25 = init->tmg.tmg_tCK;		cs->spd_tCK_20 = 0;		cs->spd_tCK_10 = 0;		cs->spd_rfsh = init->tmg.tmg_rfsh;		cs->spd_caslatency = init->tmg.tmg_caslatency;		cs->spd_attributes = init->tmg.tmg_attributes;		cs->spd_tRAS = init->tmg.tmg_tRAS;		cs->spd_tRP = init->tmg.tmg_tRP;		cs->spd_tRRD = init->tmg.tmg_tRRD;		cs->spd_tRCD = init->tmg.tmg_tRCD;		cs->spd_tRFC = init->tmg.tmg_tRFC;		cs->spd_tRC = init->tmg.tmg_tRC;		break;			    case MCR_CLKCFG:		mc->clkconfig = 		    V_MC_ADDR_SKEW((uint64_t)(init->clk.clk_addrskew)) | 		    V_MC_DQO_SKEW((uint64_t)(init->clk.clk_dqoskew)) | 		    V_MC_DQI_SKEW((uint64_t)(init->clk.clk_dqiskew)) | 		    V_MC_ADDR_DRIVE((uint64_t)(init->clk.clk_addrdrive)) | 		    V_MC_DATA_DRIVE((uint64_t)(init->clk.clk_datadrive)) | 		    V_MC_CLOCK_DRIVE((uint64_t)(init->clk.clk_clkdrive)); 		break;	    case MCR_GEOM:		cs = &(mc->csdata[init->geom.geom_csel]);		cs->rows = init->geom.geom_rows;		cs->cols = init->geom.geom_cols;		cs->banks = init->geom.geom_banks;		cs->flags |= CS_PRESENT;			break;	    case MCR_SPD:		cs = &(mc->csdata[init->spd.spd_csel]);		sb1250_dram_getinfo(init->spd.spd_smbuschan,				    init->spd.spd_smbusdev,				    mc,				    init->spd.spd_csel);		if (mc->dramtype == DRAM_TYPE_SPD) {		    /* Use the DRAM type we get from the SPD */		    if (cs->spd_dramtype == SPD_MEMTYPE_FCRAM){			mc->dramtype = FCRAM;			mc->pagepolicy = CLOSED;			if (mc->roundtrip == 0) mc->roundtrip = DEFAULT_MEMORY_ROUNDTRIP_TIME_FCRAM;			}		    else {			mc->dramtype = JEDEC;			if (mc->roundtrip == 0) mc->roundtrip = DEFAULT_MEMORY_ROUNDTRIP_TIME;					}		    }		/* 		 * The line below lets you put a MCR_MANTIMING record		 * before an MCR_SPD to work around some missing information		 * on certain DIMMs.   Normally you have only one or the		 * other.  		 */		mc->rfsh = cs->spd_rfsh;		/* XXX flags ignored */		break;	    case MCR_MANTIMING:		/* Manual timing - pick record up as bytes because we cannot		   guarantee the alignment of the "mtm_timing" field in our		   structure -- each row is 12 bytes, not good */		mc->rfsh = (uint16_t) init->mtm.mtm_rfsh;	/* units: JEDEC refresh value */		mc->tCK  = (uint16_t) init->mtm.mtm_tCK;	/* units: BCD, like SPD */		mc->mantiming =		    (((uint64_t) init->mtm.mtm_timing[0]) << 56) |		    (((uint64_t) init->mtm.mtm_timing[1]) << 48) |		    (((uint64_t) init->mtm.mtm_timing[2]) << 40) |		    (((uint64_t) init->mtm.mtm_timing[3]) << 32) |		    (((uint64_t) init->mtm.mtm_timing[4]) << 24) |		    (((uint64_t) init->mtm.mtm_timing[5]) << 16) |		    (((uint64_t) init->mtm.mtm_timing[6]) << 8) |		    (((uint64_t) init->mtm.mtm_timing[7]) << 0);		break;	    default:		break;	    }	init++;	}    /*     * Okay, now we've internalized all the data from the SPDs     * and/or the init table.     */    }/*  *********************************************************************    *  SB1250_DRAMINIT_DELAY    *      *  This little routine delays at least 200 microseconds.    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing.    *  	       *  Registers used:    *  	   tmp0,tmp1    ********************************************************************* *//* 200 microseconds = 5KHz, so delay 1GHz/5Khz = 200,000 cycles */#ifdef _FASTEMUL_#define DRAMINIT_DELAY_CNT	"50"#else#define DRAMINIT_DELAY_CNT	 "(1000000000/5000)"#endif#if defined(_MCSTANDALONE_)#define DRAMINIT_DELAY()		/* not running on a 1250, no delays */#else#define DRAMINIT_DELAY() sb1250_draminit_delay()static void sb1250_draminit_delay(void){    __asm("     li $9," DRAMINIT_DELAY_CNT " ; "	  "     mtc0 $0,$9 ; "	  "1:   mfc0 $8,$9 ; "	  "     .set push ; .set mips64 ; ssnop ; ssnop ; .set pop ;"	  "     blt $8,$9,1b ;");}#endif/*  *********************************************************************    *  MAKEDRAMMASK(dest,width,pos)    *      *  Create a 64-bit mask for the DRAM config registers    *      *  Input parameters:     *  	   width - number of '1' bits to set    *  	   pos - position (from the right) of the first '1' bit    *  	       *  Return value:    *  	   mask with specified with at specified position     ********************************************************************* */#define MAKEDRAMMASK(width,pos) _SB_MAKEMASK(width,pos)/*  *********************************************************************    *  SB1250_JEDEC_INITCMDS    *      *  Issue the sequence of DRAM init commands (JEDEC SDRAMs)    *      *  Input parameters:     *      mcnum - memory controller index (0/1)    *  	   mc - pointer to data for this memory controller    *	   csel - which chip select to send init commands for    *      lmbank - for largemem systems, the cs qualifiers to be    *		    output on CS[2:3]    *      tdata - chip select to use as a template for timing data    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sb1250_jedec_initcmds(int mcnum,mcdata_t *mc,int csel,				  int lmbank,csdata_t *tdata){    uint64_t csmask;    sbport_t cmd;    sbport_t mode;    uint64_t modebits;    uint64_t casbits;    csmask = M_MC_CS0 << csel;		/* convert chip select # to mask */    if (mc->flags & MCFLG_BIGMEM) {	/* 	 * so that the banks will all get their precharge signals,	 * put the CS qualifiers out on CS[2:3].	 */	   	csmask |= (uint64_t)(lmbank << 6);	}    cmd  = (sbport_t) PHYS_TO_K1(A_MC_REGISTER(mcnum,R_MC_DRAMCMD));    mode = (sbport_t) PHYS_TO_K1(A_MC_REGISTER(mcnum,R_MC_DRAMMODE));    /*     * Using the data in the timing template, figure out which     * CAS latency command to issue.     */    switch (tdata->flags & CS_CASLAT_MASK) {	case CS_CASLAT_30:	    casbits = V_MC_MODE(JEDEC_SDRAM_MRVAL_CAS3);	    break;	default:	case CS_CASLAT_25:	    casbits = V_MC_MODE(JEDEC_SDRAM_MRVAL_CAS25);	    break;	case CS_CASLAT_20:	    casbits = V_MC_MODE(JEDEC_SDRAM_MRVAL_CAS2);	    break;	case CS_CASLAT_15:	    casbits = V_MC_MODE(JEDEC_SDRAM_MRVAL_CAS15);	    break;	}    /*     * Set up for doing mode register writes to the SDRAMs     *      * First time, we set bit 8 to reset the DLL     */    modebits = V_MC_EMODE(JEDEC_SDRAM_EMRVAL) |	     V_MC_MODE(JEDEC_SDRAM_MRVAL_RESETDLL) | 	     V_MC_DRAM_TYPE(JEDEC);    /*     * Writing to mode regsiter will start clock.  Need delay     * before issuing commands.     */    WRITECSR(mode,modebits | casbits);    DRAMINIT_DELAY();        /*      * Clear power-down without CS assertion to assert CKE.     */    WRITECSR(cmd,V_MC_COMMAND_CLRPWRDN);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_CLRPWRDN);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_PRE);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_EMRS);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_MRS);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_PRE);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_AR);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_AR);    DRAMINIT_DELAY();    /*     * This time, clear bit 8 to start the DLL     */    modebits = V_MC_EMODE(JEDEC_SDRAM_EMRVAL) |	V_MC_DRAM_TYPE(JEDEC);    WRITECSR(mode,modebits | casbits);    WRITECSR(cmd,csmask | V_MC_COMMAND_MRS);    DRAMINIT_DELAY();}/*  *********************************************************************    *  SB1250_SGRAM_INITCMDS    *      *  Issue the sequence of DRAM init commands. (SGRAMs)    *  Note: this routine does not support "big memory" (external decode)    *      *  Input parameters:     *      mcnum - memory controller index (0/1)    *  	   mc - pointer to data for this memory controller    *	   csel - which chip select to send init commands for    *      tdata - chip select to use as a template for timing data    *  	       *  Return value:    *  	   nothing    ********************************************************************* */static void sb1250_sgram_initcmds(int mcnum,mcdata_t *mc,int csel,csdata_t *tdata){    uint64_t csmask;    sbport_t cmd;    sbport_t mode;    csmask = M_MC_CS0 << csel;		/* convert chip select # to mask */    cmd  = (sbport_t) PHYS_TO_K1(A_MC_REGISTER(mcnum,R_MC_DRAMCMD));    mode = (sbport_t) PHYS_TO_K1(A_MC_REGISTER(mcnum,R_MC_DRAMMODE));    WRITECSR(cmd,csmask | V_MC_COMMAND_CLRPWRDN);    DRAMINIT_DELAY();    WRITECSR(cmd,csmask | V_MC_COMMAND_PRE);    DRAMINIT_DELAY();    /*     * Set up for doing mode register writes to the SDRAMs     *      * mode 0x62 is "sequential 4-byte bursts, CAS Latency 2.5"     * mode 0x22 is "sequential 4-byte bursts, CAS Latency 2"     *     * First time, we set bit 8 to reset t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -