#include #ifdef CSR_SDRAM_BASE #include #include #include #include #include #include "sdram.h" static void cdelay(int i) { while(i > 0) { #if defined (__lm32__) __asm__ volatile("nop"); #elif defined (__or1k__) __asm__ volatile("l.nop"); #else #error Unsupported architecture #endif i--; } } void sdrsw(void) { sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N); printf("SDRAM now under software control\n"); } void sdrhw(void) { sdram_dfii_control_write(DFII_CONTROL_SEL); printf("SDRAM now under hardware control\n"); } void sdrrow(char *_row) { char *c; unsigned int row; if(*_row == 0) { sdram_dfii_pi0_address_write(0x0000); sdram_dfii_pi0_baddress_write(0); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); cdelay(15); printf("Precharged\n"); } else { row = strtoul(_row, &c, 0); if(*c != 0) { printf("incorrect row\n"); return; } sdram_dfii_pi0_address_write(row); sdram_dfii_pi0_baddress_write(0); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS); cdelay(15); printf("Activated row %d\n", row); } } void sdrrdbuf(int dq) { int i, p; int first_byte, step; if(dq < 0) { first_byte = 0; step = 1; } else { first_byte = DFII_PIX_DATA_SIZE/2 - 1 - dq; step = DFII_PIX_DATA_SIZE/2; } for(p=0;p\n"); return; } addr = strtoul(startaddr, &c, 0); if(*c != 0) { printf("incorrect address\n"); return; } if(*dq == 0) _dq = -1; else { _dq = strtoul(dq, &c, 0); if(*c != 0) { printf("incorrect DQ\n"); return; } } sdram_dfii_pird_address_write(addr); sdram_dfii_pird_baddress_write(0); command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); sdrrdbuf(_dq); } void sdrrderr(char *count) { int addr; char *c; int _count; int i, j, p; unsigned char prev_data[DFII_NPHASES*DFII_PIX_DATA_SIZE]; unsigned char errs[DFII_NPHASES*DFII_PIX_DATA_SIZE]; if(*count == 0) { printf("sdrrderr \n"); return; } _count = strtoul(count, &c, 0); if(*c != 0) { printf("incorrect count\n"); return; } for(i=0;i\n"); return; } addr = strtoul(startaddr, &c, 0); if(*c != 0) { printf("incorrect address\n"); return; } for(p=0;p= ERR_DDRPHY_DELAY) break; ddrphy_wdly_dq_inc_write(1); ddrphy_wdly_dqs_inc_write(1); ddrphy_wlevel_strobe_write(1); cdelay(10); dq = MMPTR(dq_address); } } else high_skew[i] = 0; while(dq == 0) { delay[i]++; if(delay[i] >= ERR_DDRPHY_DELAY) break; ddrphy_wdly_dq_inc_write(1); ddrphy_wdly_dqs_inc_write(1); ddrphy_wlevel_strobe_write(1); cdelay(10); dq = MMPTR(dq_address); } } sdrwloff(); ok = 1; for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--) { printf("%2d%c ", delay[i], high_skew[i] ? '*' : ' '); if(delay[i] >= ERR_DDRPHY_DELAY) ok = 0; } if(ok) printf("completed\n"); else printf("failed\n"); return ok; } static void read_bitslip(int *delay, int *high_skew) { int bitslip_thr; int i; bitslip_thr = 0x7fffffff; for(i=0;i=0;i--) if(delay[i] > bitslip_thr) { ddrphy_dly_sel_write(1 << i); /* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */ ddrphy_rdly_dq_bitslip_write(1); ddrphy_rdly_dq_bitslip_write(1); ddrphy_rdly_dq_bitslip_write(1); printf("%d ", i); } printf("\n"); } static void read_delays(void) { unsigned int prv; unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE]; int p, i, j; int working; int delay, delay_min, delay_max; printf("Read delays: "); /* Generate pseudo-random sequence */ prv = 42; for(i=0;i= ERR_DDRPHY_DELAY) break; ddrphy_rdly_dq_inc_write(1); } delay_min = delay; /* Get a bit further into the working zone */ delay++; ddrphy_rdly_dq_inc_write(1); /* Find largest working delay */ while(1) { command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); working = 1; for(p=0;p= ERR_DDRPHY_DELAY) break; ddrphy_rdly_dq_inc_write(1); } delay_max = delay; printf("%d:%02d-%02d ", DFII_PIX_DATA_SIZE/2-i-1, delay_min, delay_max); /* Set delay to the middle */ ddrphy_rdly_dq_rst_write(1); for(j=0;j<(delay_min+delay_max)/2;j++) ddrphy_rdly_dq_inc_write(1); } /* Precharge */ sdram_dfii_pi0_address_write(0); sdram_dfii_pi0_baddress_write(0); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); cdelay(15); printf("completed\n"); } int sdrlevel(void) { int delay[DFII_PIX_DATA_SIZE/2]; int high_skew[DFII_PIX_DATA_SIZE/2]; if(!write_level(delay, high_skew)) return 0; read_bitslip(delay, high_skew); read_delays(); return 1; } #endif /* CSR_DDRPHY_BASE */ #define TEST_SIZE (2*1024*1024) int memtest_silent(void) { volatile unsigned int *array = (unsigned int *)SDRAM_BASE; int i; unsigned int prv; unsigned int error_cnt; for(i=0;i