📄 sdram.c
字号:
debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X); debug("dll_dqs_delay_X window = %d - %d\n", dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window); /* * De-assert 'start' parameter. */ mtdcr(ddrcfga, DDR0_02); val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF; mtdcr(ddrcfgd, val); /* * Set 'wr_dqs_shift' */ mtdcr(ddrcfga, DDR0_09); val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift); mtdcr(ddrcfgd, val); debug("DDR0_09=0x%08lx\n", val); /* * Set 'dqs_out_shift' = wr_dqs_shift + 32 */ dqs_out_shift = wr_dqs_shift + 32; mtdcr(ddrcfga, DDR0_22); val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift); mtdcr(ddrcfgd, val); debug("DDR0_22=0x%08lx\n", val); /* * Set 'dll_dqs_delay_X'. */ /* dll_dqs_delay_0 */ mtdcr(ddrcfga, DDR0_17); val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK) | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X); mtdcr(ddrcfgd, val); debug("DDR0_17=0x%08lx\n", val); /* dll_dqs_delay_1 to dll_dqs_delay_4 */ mtdcr(ddrcfga, DDR0_18); val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK) | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X) | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X) | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X) | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X); mtdcr(ddrcfgd, val); debug("DDR0_18=0x%08lx\n", val); /* dll_dqs_delay_5 to dll_dqs_delay_8 */ mtdcr(ddrcfga, DDR0_19); val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK) | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X) | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X) | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X) | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X); mtdcr(ddrcfgd, val); debug("DDR0_19=0x%08lx\n", val); /* * Assert 'start' parameter. */ mtdcr(ddrcfga, DDR0_02); val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON; mtdcr(ddrcfgd, val); ppcMsync(); ppcMbar(); /* * Wait for the DCC master delay line to finish calibration */ if (wait_for_dlllock() != 0) { printf("dlllock did not occur !!!\n"); hang(); } ppcMsync(); ppcMbar(); if (wait_for_dram_init_complete() != 0) { printf("dram init complete did not occur !!!\n"); hang(); } udelay(100); /* wait 100us to ensure init is really completed !!! */}#endif /* CONFIG_DDR_DATA_EYE */#ifdef CONFIG_DDR_ECCstatic void wait_ddr_idle(void){ /* * Controller idle status cannot be determined for Denali * DDR2 code. Just return here. */}static void blank_string(int size){ int i; for (i=0; i<size; i++) putc('\b'); for (i=0; i<size; i++) putc(' '); for (i=0; i<size; i++) putc('\b');}static void program_ecc(u32 start_address, u32 num_bytes, u32 tlb_word2_i_value){ u32 current_address; u32 end_address; u32 address_increment; u32 val; char str[] = "ECC generation -"; char slash[] = "\\|/-\\|/-"; int loop = 0; int loopi = 0; current_address = start_address; sync(); eieio(); wait_ddr_idle(); if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) { /* ECC bit set method for non-cached memory */ address_increment = 4; end_address = current_address + num_bytes; puts(str); while (current_address < end_address) { *((u32 *)current_address) = 0x00000000; current_address += address_increment; if ((loop++ % (2 << 20)) == 0) { putc('\b'); putc(slash[loopi++ % 8]); } } blank_string(strlen(str)); } else { /* ECC bit set method for cached memory */#if 0 /* test-only: will remove this define later, when ECC problems are solved! */ /* * Some boards (like lwmon5) need to preserve the memory * content upon ECC generation (for the log-buffer). * Therefore we don't fill the memory with a pattern or * just zero it, but write the same values back that are * already in the memory cells. */ address_increment = CFG_CACHELINE_SIZE; end_address = current_address + num_bytes; current_address = start_address; while (current_address < end_address) { /* * TODO: Th following sequence doesn't work correctly. * Just invalidating and flushing the cache doesn't * seem to trigger the re-write of the memory. */ ppcDcbi(current_address); ppcDcbf(current_address); current_address += CFG_CACHELINE_SIZE; }#else dcbz_area(start_address, num_bytes); dflush();#endif } sync(); eieio(); wait_ddr_idle(); /* Clear error status */ mfsdram(DDR0_00, val); mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); /* Set 'int_mask' parameter to functionnal value */ mfsdram(DDR0_01, val); mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF)); sync(); eieio(); wait_ddr_idle();}#endif/************************************************************************* * * initdram -- 440EPx's DDR controller is a DENALI Core * ************************************************************************/long int initdram (int board_type){#if 0 /* test-only: will remove this define later, when ECC problems are solved! */ /* CL=3 */ mtsdram(DDR0_02, 0x00000000); mtsdram(DDR0_00, 0x0000190A); mtsdram(DDR0_01, 0x01000000); mtsdram(DDR0_03, 0x02030603); /* A suitable burst length was taken. CAS is right for our board */ mtsdram(DDR0_04, 0x0A030300); mtsdram(DDR0_05, 0x02020308); mtsdram(DDR0_06, 0x0103C812); mtsdram(DDR0_07, 0x00090100); mtsdram(DDR0_08, 0x02c80001); mtsdram(DDR0_09, 0x00011D5F); mtsdram(DDR0_10, 0x00000300); mtsdram(DDR0_11, 0x000CC800); mtsdram(DDR0_12, 0x00000003); mtsdram(DDR0_14, 0x00000000); mtsdram(DDR0_17, 0x1e000000); mtsdram(DDR0_18, 0x1e1e1e1e); mtsdram(DDR0_19, 0x1e1e1e1e); mtsdram(DDR0_20, 0x0B0B0B0B); mtsdram(DDR0_21, 0x0B0B0B0B);#ifdef CONFIG_DDR_ECC mtsdram(DDR0_22, 0x00267F0B | DDR0_22_CTRL_RAW_ECC_ENABLE); /* enable ECC */#else mtsdram(DDR0_22, 0x00267F0B);#endif mtsdram(DDR0_23, 0x01000000); mtsdram(DDR0_24, 0x01010001); mtsdram(DDR0_26, 0x2D93028A); mtsdram(DDR0_27, 0x0784682B); mtsdram(DDR0_28, 0x00000080); mtsdram(DDR0_31, 0x00000000); mtsdram(DDR0_42, 0x01000006); mtsdram(DDR0_43, 0x030A0200); mtsdram(DDR0_44, 0x00000003); mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */#else /* CL=4 */ mtsdram(DDR0_02, 0x00000000); mtsdram(DDR0_00, 0x0000190A); mtsdram(DDR0_01, 0x01000000); mtsdram(DDR0_03, 0x02040803); /* A suitable burst length was taken. CAS is right for our board */ mtsdram(DDR0_04, 0x0B030300); mtsdram(DDR0_05, 0x02020308); mtsdram(DDR0_06, 0x0003C812); mtsdram(DDR0_07, 0x00090100); mtsdram(DDR0_08, 0x03c80001); mtsdram(DDR0_09, 0x00011D5F); mtsdram(DDR0_10, 0x00000300); mtsdram(DDR0_11, 0x000CC800); mtsdram(DDR0_12, 0x00000003); mtsdram(DDR0_14, 0x00000000); mtsdram(DDR0_17, 0x1e000000); mtsdram(DDR0_18, 0x1e1e1e1e); mtsdram(DDR0_19, 0x1e1e1e1e); mtsdram(DDR0_20, 0x0B0B0B0B); mtsdram(DDR0_21, 0x0B0B0B0B);#ifdef CONFIG_DDR_ECC mtsdram(DDR0_22, 0x00267F0B | DDR0_22_CTRL_RAW_ECC_ENABLE); /* enable ECC */#else mtsdram(DDR0_22, 0x00267F0B);#endif mtsdram(DDR0_23, 0x01000000); mtsdram(DDR0_24, 0x01010001); mtsdram(DDR0_26, 0x2D93028A); mtsdram(DDR0_27, 0x0784682B); mtsdram(DDR0_28, 0x00000080); mtsdram(DDR0_31, 0x00000000); mtsdram(DDR0_42, 0x01000008); mtsdram(DDR0_43, 0x050A0200); mtsdram(DDR0_44, 0x00000005); mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */#endif wait_for_dlllock(); /* * Program tlb entries for this size (dynamic) */ program_tlb(0, 0, CFG_MBYTES_SDRAM << 20, MY_TLB_WORD2_I_ENABLE); /* * Setup 2nd TLB with same physical address but different virtual address * with cache enabled. This is done for fast ECC generation. */ program_tlb(0, CFG_DDR_CACHED_ADDR, CFG_MBYTES_SDRAM << 20, 0);#ifdef CONFIG_DDR_DATA_EYE /* * Perform data eye search if requested. */ denali_core_search_data_eye(CFG_DDR_CACHED_ADDR, CFG_MBYTES_SDRAM << 20);#endif#ifdef CONFIG_DDR_ECC /* * If ECC is enabled, initialize the parity bits. */ program_ecc(CFG_DDR_CACHED_ADDR, CFG_MBYTES_SDRAM << 20, 0);#endif /* * Clear possible errors resulting from data-eye-search. * If not done, then we could get an interrupt later on when * exceptions are enabled. */ set_mcsr(get_mcsr()); return (CFG_MBYTES_SDRAM << 20);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -