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

📄 spd_sdram.c.svn-base

📁 u-boot for S3c2443 processor
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
    case 8:	tr0 |= SDRAM_TR0_SDRA_8_CLK;	break;    case 9:	tr0 |= SDRAM_TR0_SDRA_9_CLK;	break;    case 10:	tr0 |= SDRAM_TR0_SDRA_10_CLK;	break;    case 11:	tr0 |= SDRAM_TR0_SDRA_11_CLK;	break;    case 12:	tr0 |= SDRAM_TR0_SDRA_12_CLK;	break;    default:	tr0 |= SDRAM_TR0_SDRA_13_CLK;	break;    }    /*     * Program SD_RCD field     */    t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;    plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;    if (sys_info.freqPLB != plb_check) {	t_rcd_clk++;    }    switch (t_rcd_clk) {    case 0:    case 1:    case 2:	tr0 |= SDRAM_TR0_SDRD_2_CLK;	break;    case 3:	tr0 |= SDRAM_TR0_SDRD_3_CLK;	break;    default:	tr0 |= SDRAM_TR0_SDRD_4_CLK;	break;    }#if 0    printf("tr0: %x\n", tr0);#endif    mtsdram(mem_tr0, tr0);}void program_tr1 (void){    unsigned long tr0;    unsigned long tr1;    unsigned long cfg0;    unsigned long ecc_temp;    unsigned long dlycal;    unsigned long dly_val;    unsigned long i, j, k;    unsigned long bxcr_num;    unsigned long max_pass_length;    unsigned long current_pass_length;    unsigned long current_fail_length;    unsigned long current_start;    unsigned long rdclt;    unsigned long rdclt_offset;    long max_start;    long max_end;    long rdclt_average;    unsigned char window_found;    unsigned char fail_found;    unsigned char pass_found;    unsigned long * membase;    PPC440_SYS_INFO sys_info;    /*     * get the board info     */    get_sys_info(&sys_info);    /*     * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits     */    mfsdram(mem_tr1, tr1);    tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK |	     SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);    mfsdram(mem_tr0, tr0);    if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) &&       (sys_info.freqPLB > 100000000)) {	tr1 |= SDRAM_TR1_RDSS_TR2;	tr1 |= SDRAM_TR1_RDSL_STAGE3;	tr1 |= SDRAM_TR1_RDCD_RCD_1_2;    }    else {	tr1 |= SDRAM_TR1_RDSS_TR1;	tr1 |= SDRAM_TR1_RDSL_STAGE2;	tr1 |= SDRAM_TR1_RDCD_RCD_0_0;    }    /*     * save CFG0 ECC setting to a temporary variable and turn ECC off     */    mfsdram(mem_cfg0, cfg0);    ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);    /*     * get the delay line calibration register value     */    mfsdram(mem_dlycal, dlycal);    dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;    max_pass_length = 0;    max_start = 0;    max_end = 0;    current_pass_length = 0;    current_fail_length = 0;    current_start = 0;    rdclt_offset = 0;    window_found = FALSE;    fail_found = FALSE;    pass_found = FALSE;#ifdef DEBUG    printf("Starting memory test ");#endif    for (k = 0; k < NUMHALFCYCLES; k++) {	for (rdclt = 0; rdclt < dly_val; rdclt++)  {	    /*	     * Set the timing reg for the test.	     */	    mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));	    for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {		mtdcr(memcfga, mem_b0cr + (bxcr_num<<2));		if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {		    /* Bank is enabled */		    membase = (unsigned long*)			(mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);		    /*		     * Run the short memory test		     */		    for (i = 0; i < NUMMEMTESTS; i++) {			for (j = 0; j < NUMMEMWORDS; j++) {			    membase[j] = test[i][j];			    ppcDcbf((unsigned long)&(membase[j]));			}			for (j = 0; j < NUMMEMWORDS; j++) {			    if (membase[j] != test[i][j]) {				ppcDcbf((unsigned long)&(membase[j]));				break;			    }			    ppcDcbf((unsigned long)&(membase[j]));			}			if (j < NUMMEMWORDS) {			    break;			}		    }		    /*		     * see if the rdclt value passed		     */		    if (i < NUMMEMTESTS) {			break;		    }		}	    }	    if (bxcr_num == MAXBXCR) {		if (fail_found == TRUE) {		    pass_found = TRUE;		    if (current_pass_length == 0) {			current_start = rdclt_offset + rdclt;		    }		    current_fail_length = 0;		    current_pass_length++;		    if (current_pass_length > max_pass_length) {			max_pass_length = current_pass_length;			max_start = current_start;			max_end = rdclt_offset + rdclt;		    }		}	    }	    else {		current_pass_length = 0;		current_fail_length++;		if (current_fail_length >= (dly_val>>2)) {		    if (fail_found == FALSE) {			fail_found = TRUE;		    }		    else if (pass_found == TRUE) {			window_found = TRUE;			break;		    }		}	    }	}#ifdef DEBUG	printf(".");#endif	if (window_found == TRUE) {	    break;	}	tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;	rdclt_offset += dly_val;    }#ifdef DEBUG    printf("\n");#endif    /*     * make sure we find the window     */    if (window_found == FALSE) {       printf("ERROR: Cannot determine a common read delay.\n");       hang();    }    /*     * restore the orignal ECC setting     */    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);    /*     * set the SDRAM TR1 RDCD value     */    tr1 &= ~SDRAM_TR1_RDCD_MASK;    if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {	tr1 |= SDRAM_TR1_RDCD_RCD_1_2;    }    else {	tr1 |= SDRAM_TR1_RDCD_RCD_0_0;    }    /*     * set the SDRAM TR1 RDCLT value     */    tr1 &= ~SDRAM_TR1_RDCT_MASK;    while (max_end >= (dly_val<<1)) {	max_end -= (dly_val<<1);	max_start -= (dly_val<<1);    }    rdclt_average = ((max_start + max_end) >> 1);    if (rdclt_average >= 0x60)	while(1);    if (rdclt_average < 0) {	rdclt_average = 0;    }    if (rdclt_average >= dly_val) {	rdclt_average -= dly_val;	tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;    }    tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);#if 0    printf("tr1: %x\n", tr1);#endif    /*     * program SDRAM Timing Register 1 TR1     */    mtsdram(mem_tr1, tr1);}unsigned long program_bxcr(unsigned long* dimm_populated,			   unsigned char* iic0_dimm_addr,			   unsigned long  num_dimm_banks){    unsigned long dimm_num;    unsigned long bxcr_num;    unsigned long bank_base_addr;    unsigned long bank_size_bytes;    unsigned long cr;    unsigned long i;    unsigned long temp;    unsigned char num_row_addr;    unsigned char num_col_addr;    unsigned char num_banks;    unsigned char bank_size_id;    /*     * Set the BxCR regs.  First, wipe out the bank config registers.     */    for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {	mtdcr(memcfga, mem_b0cr + (bxcr_num << 2));	mtdcr(memcfgd, 0x00000000);    }    /*     * reset the bank_base address     */    bank_base_addr = CFG_SDRAM_BASE;    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {	if (dimm_populated[dimm_num] == TRUE) {	    num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);	    num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);	    num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5);	    bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);	    /*	     * Set the SDRAM0_BxCR regs	     */	    cr = 0;	    bank_size_bytes = 4 * 1024 * 1024 * bank_size_id;	    switch (bank_size_id) {	    case 0x02:		cr |= SDRAM_BXCR_SDSZ_8;		break;	    case 0x04:		cr |= SDRAM_BXCR_SDSZ_16;		break;	    case 0x08:		cr |= SDRAM_BXCR_SDSZ_32;		break;	    case 0x10:		cr |= SDRAM_BXCR_SDSZ_64;		break;	    case 0x20:		cr |= SDRAM_BXCR_SDSZ_128;		break;	    case 0x40:		cr |= SDRAM_BXCR_SDSZ_256;		break;	    case 0x80:		cr |= SDRAM_BXCR_SDSZ_512;		break;	    default:		printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",		    dimm_num);		printf("ERROR: Unsupported value for the banksize: %d.\n",		   bank_size_id);		printf("Replace the DIMM module with a supported DIMM.\n\n");		hang();	    }	    switch (num_col_addr) {	    case 0x08:		cr |= SDRAM_BXCR_SDAM_1;		break;	    case 0x09:		cr |= SDRAM_BXCR_SDAM_2;		break;	    case 0x0A:		cr |= SDRAM_BXCR_SDAM_3;		break;	    case 0x0B:		cr |= SDRAM_BXCR_SDAM_4;		break;	    default:		printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",		   dimm_num);		printf("ERROR: Unsupported value for number of "		   "column addresses: %d.\n", num_col_addr);		printf("Replace the DIMM module with a supported DIMM.\n\n");		hang();	    }	    /*	     * enable the bank	     */	    cr |= SDRAM_BXCR_SDBE;	    /*------------------------------------------------------------------	    | This next section is hardware dependent and must be programmed	    | to match the hardware.	    +-----------------------------------------------------------------*/	    if (dimm_num == 0) {		for (i = 0; i < num_banks; i++) {		    mtdcr(memcfga, mem_b0cr + (i << 2));		    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK |					      SDRAM_BXCR_SDSZ_MASK |					      SDRAM_BXCR_SDAM_MASK |					      SDRAM_BXCR_SDBE);		    cr |= temp;		    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK;		    mtdcr(memcfgd, cr);		    bank_base_addr += bank_size_bytes;		}	    }	    else {		for (i = 0; i < num_banks; i++) {		    mtdcr(memcfga, mem_b2cr + (i << 2));		    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK |					      SDRAM_BXCR_SDSZ_MASK |					      SDRAM_BXCR_SDAM_MASK |					      SDRAM_BXCR_SDBE);		    cr |= temp;		    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK;		    mtdcr(memcfgd, cr);		    bank_base_addr += bank_size_bytes;		}	    }	}    }    return(bank_base_addr);}void program_ecc (unsigned long  num_bytes){    unsigned long bank_base_addr;    unsigned long current_address;    unsigned long end_address;    unsigned long address_increment;    unsigned long cfg0;    /*     * get Memory Controller Options 0 data     */    mfsdram(mem_cfg0, cfg0);    /*     * reset the bank_base address     */    bank_base_addr = CFG_SDRAM_BASE;    if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |	    SDRAM_CFG0_MCHK_GEN);	if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) {	    address_increment = 4;	}	else {	    address_increment = 8;	}	current_address = (unsigned long)(bank_base_addr);	end_address = (unsigned long)(bank_base_addr) + num_bytes;	while (current_address < end_address) {	    *((unsigned long*)current_address) = 0x00000000;	    current_address += address_increment;	}	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |	    SDRAM_CFG0_MCHK_CHK);    }}#endif /* CONFIG_440 */#endif /* CONFIG_SPD_EEPROM */

⌨️ 快捷键说明

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