I am working on board with an OMAP L138 connected to a DDR. I am using the gel script for configuring the ddr controller. I think it is set up correctly except that I have one issue. If I write to a memory location, I cannot read back from the same location until I repeat the read command multiple times. So if I write to one location and read from that location multiple times, I see that every 4th read iteration yields the data that I wrote. Below is my gel script along with a link to the DDR2 memory I am using. I am running at a clock rate of 150MHz.
Link to DDR2 Memory
http://download.micron.com/pdf/datasheets/dram/ddr2/512MbDDR2.pdf
Exact Part Number: MT47H32M16 -25E IT
Any help is appreciated.
DEVICE_DDRConfig(unsigned int freq) { GEL_TextOut("\t\t\tDDR initialization entering DDRConfig()....\n","Output",1,1,1); /*Enable the Clock to EMIF3A SDRAM*/ PSC1_LPSC_enable(PD0, LPSC_DDR); /*If VTP caliberation enabled , then skip the VTP calibration*/ if((VTPIO_CTL & 0x00000040)) { // Begin VTP Calibration VTPIO_CTL |= (0x00004000); // Set IOPWRDN bit to enable input buffer powerdown enable mode VTPIO_CTL &= ~(0x00000040); // Clear POWERDN bit (enable VTP) // Pulse (low) CLRZ to initiate VTP IO Calibration VTPIO_CTL |= (0x00002000); // Set CLRZ bit VTPIO_CTL &= ~(0x00002000); // Clear CLRZ bit (CLRZ should be low for at least 2ns) VTPIO_CTL |= 0x00002000; // Set CLRZ bit // Polling READY bit to see when VTP calibration is done while(!((VTPIO_CTL & 0x00008000)>>15)) {} VTPIO_CTL |= 0x00000080; // Set LOCK bit for static mode VTPIO_CTL |= 0x00000100; // Set PWRSAVE bit to save power VTPIO_CTL |= 0x00000040; // Set POWERDN bit to power down VTP module // End VTP Calibration } EMIF3A_SDCR |= 0x00800000; // Set BOOTUNLOCK // ********************************************************************************************** // Setting based on MT47H32M16 – 8 Meg x 16 x 4 banks // Config DDR timings GEL_TextOut("\t\t\tStarting DDRCTL Config....\n","Output",1,1,1); DDRCTL = (0x0 << 8) | // Reserved (0x1 << 7) | // EXT_STRBEN (0x1 << 6) | // PWRDNEN (0x0 << 3) | // Reserved (0x4 << 0); // RL GEL_TextOut("\t\t\tStarting EMIF3A_SDCR Config....\n","Output",1,1,1); EMIF3A_SDCR = (EMIF3A_SDCR & 0xF0000000) | // Reserved (0x0 << 27) | // DDR2TERM1 (0x1 << 26) | // IBANK_POS (0x0 << 25) | // MSDRAMEN (0x0 << 24) | // DDRDRIVE1 (0x0 << 23) | // BOOTUNLOCK (0x0 << 22) | // DDR2DDQS (0x0 << 21) | // DDR2TERM0 (0x1 << 20) | // DDR2EN (0x0 << 19) | // DDRDLL_DIS (0x1 << 18) | // DDRDRIVE0 (0x1 << 17) | // DDREN (0x1 << 16) | // SDRAMEN (0x1 << 15) | // TIMUNLOCK (0x1 << 14) | // NM (0x0 << 12) | // Reserved (0x5 << 9) | // CL //CL=5 Based on DDR (0x0 << 7) | // Reserved (0x2 << 4) | // IBANK (0x0 << 3) | // Reserved (0x2 << 0); // PAGESIZE GEL_TextOut("\t\t\tStarting EMIF3A_SDTIMR1 Config....\n","Output",1,1,1); // Subtracting 0.5 instead of 1 so that the int is rounded up after truncating a real value EMIF3A_SDTIMR1 = (((unsigned int) ((105.0 * freq / 1000) - 1)) << 25)| // tRFC (((unsigned int) ((12.5 * freq / 1000) - 1)) << 22) | // tRP (((unsigned int) ((12.5 * freq / 1000) - 1)) << 19) | // tRCD (((unsigned int) ((15.0 * freq / 1000) - 1)) << 16) | // tWR (((unsigned int) ((40.0 * freq / 1000) - 1)) << 11) | // tRAS (((unsigned int) ((55.0 * freq / 1000) - 1)) << 6) | // tRC (((unsigned int) ((7.5 * freq / 1000) - 1)) << 3) | // tRRD (EMIF3A_SDTIMR1 & 0x4) | // Reserved (((unsigned int) ((7.5 * freq / 1000) - 1)) << 0); // tWTR // Subtracting 0.5 instead of 1 so that the int is rounded up after truncating a real value // tRASMAX is rounded down so subtracting 1 // CAS/CL = 3 GEL_TextOut("\t\t\tStarting EMIF3A_SDTIMR2 Config....\n","Output",1,1,1); EMIF3A_SDTIMR2 = (EMIF3A_SDTIMR2 & 0x80000000) | // Reserved (((unsigned int) ((70000 / 7812.5) - 1)) << 27) | // tRASMAX [(70us/7.8125us)-1] (0x2 << 25) | // tXP //Check what value this should be -MS (0x0 << 23) | // tODT (Not supported) (((unsigned int) ((115.0 * freq / 1000) - 1)) << 16) | // tXSNR ((200 - 1) << 8) | // tXSRD (200 Cycles) -MS ((1 - 1) << 5) | // tRTP (1 Cycle) -MS (0x2 << 0); // tCKE //min 3 -MS GEL_TextOut("\t\t\tStarting EMIF3A_SDCR Config....\n","Output",1,1,1); EMIF3A_SDCR &= ~0x00008000; // Clear TIMUNLOCK GEL_TextOut("\t\t\tStarting EMIF3A_SDCR2 Config....\n","Output",1,1,1); //EMIF3A_SDCR2 = 0x00000004; // IBANK_POS set to 0 so this register does not apply EMIF3A_SDCR2 = (0x4 << 0) | // 13 row address lines (0x0 << 16); // 4 banks will be refreshed EMIF3A_SDRCR = (0x1 << 31) | // LPMODEN (0x1 << 30) | // MCLKSTOPEN (0x0 << 24) | // Reserved (0x1 << 23) | // SR_PD (0x0 << 16) | // Reserved (((unsigned int) ((7.8125 * freq))) << 0); // RR GEL_TextOut("\t\t\tReady to SyncReset the Clock to EMIF3A SDRAM....\n","Output",1,1,1); /*SyncReset the Clock to EMIF3A SDRAM*/ PSC1_LPSC_SyncReset(PD0, LPSC_DDR); GEL_TextOut("\t\t\tReady to Enable the Clock to EMIF3A SDRAM....\n","Output",1,1,1); /*Enable the Clock to EMIF3A SDRAM*/ PSC1_LPSC_enable(PD0, LPSC_DDR); EMIF3A_SDRCR &= ~0xC0000000; // disable self-refresh GEL_TextOut("\t\t\tCompleted Configuration of all DDR2 registers....\n","Output",1,1,1); }
Link to DDR2 memory
-Manas