📄 sb1250_draminit.c
字号:
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 + -