|
Hi folks, I have my first prototype in house (for a couple of months) with an AT91SAM9G45 (CU 1026 Date Code) with a 2Gx16 Low Power DDR1-SDRAM IC.
1 Board with Micron MT46H128M16LFCK-5 IT:A 4 Boards with Hynix H5MS2G62MFR-J3M
At 100 MHz DDR bus frequency, all boards run typically for hours before a bad memory hit causes u-boot "mtest" to fail or Linux to "Oops". At 133 Mhz DDR bus frequency, all boards typically run for minutes before a bad memory hit causes u-boot "mtest" to fail or Linux to "Oops". Our AT91SAM9G45EKES evaluation board can run without issue at 133 MHz.
My circuit board layout was done by routing the AT91SAM9G45 to the DDR first using the best routes I could come up with (8 layer pcb) and making sure the clock differential pair was the absolute first traces routed (top layer only).
My question: Does anyone have ideas for me to look into. I have included the init DDR code just in case but I have checked this probably a dozen times. I am adding more caps to bypass the 1.8V supply but that looks pretty good as well. Has anyone used this memory config and have some ideas.
Thanks, Gary
// ENABLE DDR clock writel(AT91C_PMC_DDR, PMC_SCER + AT91C_BASE_PMC);
// Step 1: Program the memory device type // Configure the DDR controller // Note: 100 MHz bus clock makes memory less efficient 7.5ns really is 10ns cr = (AT91C_DDRC2_DBW_16_BITS | AT91C_DDRC2_MD_LP_DDR_SDRAM); write_ddramc(HDDRSDRC2_MDR, cr);
// Step 2: Program the DDR Controller cr = (AT91C_DDRC2_NC_DDR11_SDR10 | // 11 column bits (1K) AT91C_DDRC2_NR_14 | // 14 row bits (8K) AT91C_DDRC2_CAS_3 | // CAS Latency 3 AT91C_DDRC2_OCD); // OCD Cal Default write_ddramc(HDDRSDRC2_CR, cr);
cr = (AT91C_DDRC2_TRAS_6 | // 6 * 7.5 = 45 ns AT91C_DDRC2_TRCD_3 | // 3 * 7.5 = 22.5 ns AT91C_DDRC2_TWR_2 | // 2 * 7.5 = 15 ns AT91C_DDRC2_TRC_9 | // 9 * 7.5 = 67.5 ns AT91C_DDRC2_TRP_3 | // 3 * 7.5 = 22.5 ns AT91C_DDRC2_TRRD_2 | // 2 * 7.5 = 15 ns AT91C_DDRC2_TWTR_1 | // 2 clock cycles AT91C_DDRC2_TMRD_2); // 2 clock cycles write_ddramc(HDDRSDRC2_T0PR, cr);
cr = (AT91C_DDRC2_TXP_2 | // 2 clock cycles AT91C_DDRC2_TXSRD_16 | // 16 * 7.5 = 120 ns AT91C_DDRC2_TXSNR_16 | // 16 * 7.5 = 120 ns AT91C_DDRC2_TRFC_16); // 16 * 7.5 = 120 ns write_ddramc(HDDRSDRC2_T1PR, cr);
cr = (AT91C_DDRC2_TRTP_2 | // 2 clock cycles AT91C_DDRC2_TRPA_0 | // 0 clock cycles AT91C_DDRC2_TXARDS_0 | // 0 clock cycles AT91C_DDRC2_TXARD_0), // 0 clock cycles write_ddramc(HDDRSDRC2_T2PR, cr);
// Step 3: Program Low Power Register cr = ((0 << 10) | // Drive Strength (0 = FULL) AT91C_DDRC2_TIMEOUT_64 | // Wait 64 Clocks before LP Mode AT91C_DDRC2_CLK_FR_SELFREFRESH | // Frozen Clock AT91C_DDRC2_LPCB_SELFREFRESH); // Self Refresh write_ddramc(HDDRSDRC2_LPR, cr);
// Initialization Step 4: NOP command -> allow to enable clk write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_NOP_CMD); *((unsigned volatile int*) AT91C_DDR2) = 0;
// Initialization Step 4 (must wait 200 us) (6 core cycles per iteration, core is at 396MHz: min 13200 loops) for (i = 0; i < 13300; i++) { asm(" nop"); }
// Initialization Step 5: Set All Bank Precharge write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_PRCGALL_CMD); *((unsigned volatile int*) AT91C_DDR2) = 0;
// wait 400 ns min for (i = 0; i < 100; i++) { asm(" nop"); }
// Initialization Step 6: Two auto-refresh (CBR) cycles are provided. Program the auto refresh command (CBR) into the Mode Register. write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_RFSH_CMD); *(((unsigned volatile int*) AT91C_DDR2)) = 0;
// wait 10 cycles min for (i = 0; i < 100; i++) { asm(" nop"); }
// Set 2nd CBR write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_RFSH_CMD); *(((unsigned volatile int*) AT91C_DDR2)) = 0;
// wait 10 cycles min for (i = 0; i < 100; i++) { asm(" nop"); }
// Initialization Step 7: Set EMR operation (EMRS1) write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_EXT_LMR_CMD); *((unsigned int *)(AT91C_DDR2 + 0x8000000)) = 0;
// wait 2 cycles min for (i = 0; i < 100; i++) { asm(" nop"); }
// Step 8: A Mode Register set (MRS) cycle is issued to program the parameters of the DDR2-SDRAM devices. write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_LMR_CMD); *(((unsigned volatile int*) AT91C_DDR2)) = 0;
// wait 2 cycles min for (i = 0; i < 100; i++) { asm(" nop"); }
// Step 9: A mode Normal command is provided. Program the Normal mode into Mode Register. write_ddramc(HDDRSDRC2_MR, AT91C_DDRC2_MODE_NORMAL_CMD); *(((unsigned volatile int*) AT91C_DDR2)) = 0;
// Set Refresh timer // The DRAM need all rows refreshed every 64 msec at a Refresh Count of 8192 // 7.81 usec per Refresh * (slowest clock = 98 MHz) = 765 = 2Fd read_ddramc(HDDRSDRC2_RTR); write_ddramc(HDDRSDRC2_RTR, 0x2Fd);
// OK now we are ready to work on the DDRSDR but we need to wait for end of calibration for (i = 0; i < 500; i++) { asm(" nop"); }
|