void ddrrd(char *startaddr) { char *c; unsigned int addr; int i; if(*startaddr == 0) { printf("ddrrd <address>\n"); return; } addr = strtoul(startaddr, &c, 0); if(*c != 0) { printf("incorrect address\n"); return; } dfii_pi0_address_write(addr); dfii_pi0_baddress_write(0); command_p0(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); for(i=0;i<8;i++) printf("%02x", MMPTR(0xe0000834+4*i)); for(i=0;i<8;i++) printf("%02x", MMPTR(0xe0000884+4*i)); printf("\n"); }
void ddrwr(char *startaddr) { char *c; unsigned int addr; int i; if(*startaddr == 0) { printf("ddrrd <address>\n"); return; } addr = strtoul(startaddr, &c, 0); if(*c != 0) { printf("incorrect address\n"); return; } for(i=0;i<8;i++) { MMPTR(0xe0000814+4*i) = i; MMPTR(0xe0000864+4*i) = 0xf0 + i; } dfii_pi1_address_write(addr); dfii_pi1_baddress_write(0); command_p1(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA); }
static void edid_set_mode(const struct video_timing *mode) { unsigned char edid[128]; int i; generate_edid(&edid, "OHW", "TV", 2015, "HDMI2USB 1", mode); for(i=0;i<sizeof(edid);i++) MMPTR(CSR_HDMI_IN0_EDID_MEM_BASE+4*i) = edid[i]; generate_edid(&edid, "OHW", "TV", 2015, "HDMI2USB 2", mode); for(i=0;i<sizeof(edid);i++) MMPTR(CSR_HDMI_IN1_EDID_MEM_BASE+4*i) = edid[i]; }
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 <count>\n"); return; } _count = strtoul(count, &c, 0); if(*c != 0) { printf("incorrect count\n"); return; } for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) errs[i] = 0; for(addr=0;addr<16;addr++) { sdram_dfii_pird_address_write(addr*8); sdram_dfii_pird_baddress_write(0); command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); for(p=0;p<DFII_NPHASES;p++) for(i=0;i<DFII_PIX_DATA_SIZE;i++) prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i); for(j=0;j<_count;j++) { command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); for(p=0;p<DFII_NPHASES;p++) for(i=0;i<DFII_PIX_DATA_SIZE;i++) { unsigned char new_data; new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i); errs[p*DFII_PIX_DATA_SIZE+i] |= prev_data[p*DFII_PIX_DATA_SIZE+i] ^ new_data; prev_data[p*DFII_PIX_DATA_SIZE+i] = new_data; } } } for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) printf("%02x", errs[i]); printf("\n"); for(p=0;p<DFII_NPHASES;p++) for(i=0;i<DFII_PIX_DATA_SIZE;i++) printf("%2x", DFII_PIX_DATA_SIZE/2 - 1 - (i % (DFII_PIX_DATA_SIZE/2))); printf("\n"); }
void get_ident(char *ident) { #ifdef CSR_IDENTIFIER_MEM_BASE int len, i; len = MMPTR(CSR_IDENTIFIER_MEM_BASE); for(i=0;i<len;i++) ident[i] = MMPTR(CSR_IDENTIFIER_MEM_BASE + 4*i); ident[i] = 0; #else ident[0] = 0; #endif }
void sdrwr(char *startaddr) { char *c; unsigned int addr; int i; int p; if(*startaddr == 0) { printf("sdrrd <address>\n"); return; } addr = strtoul(startaddr, &c, 0); if(*c != 0) { printf("incorrect address\n"); return; } for(p=0;p<DFII_NPHASES;p++) for(i=0;i<DFII_PIX_DATA_SIZE;i++) MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = 0x10*p + i; sdram_dfii_piwr_address_write(addr); sdram_dfii_piwr_baddress_write(0); command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA); }
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<DFII_NPHASES;p++) for(i=first_byte;i<DFII_PIX_DATA_SIZE;i+=step) printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i)); printf("\n"); }
unsigned int encoder_read_reg(unsigned int adr) { return MMPTR(ENCODER_BASE+adr); }
void encoder_write_reg(unsigned int adr, unsigned int value) { MMPTR(ENCODER_BASE+adr) = value; }
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<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) { prv = 1664525*prv + 1013904223; prs[i] = prv; } /* Activate */ sdram_dfii_pi0_address_write(0); sdram_dfii_pi0_baddress_write(0); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS); cdelay(15); /* Write test pattern */ for(p=0;p<DFII_NPHASES;p++) for(i=0;i<DFII_PIX_DATA_SIZE;i++) MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = prs[DFII_PIX_DATA_SIZE*p+i]; sdram_dfii_piwr_address_write(0); sdram_dfii_piwr_baddress_write(0); command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA); /* Calibrate each DQ in turn */ sdram_dfii_pird_address_write(0); sdram_dfii_pird_baddress_write(0); for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) { ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE/2-i-1)); delay = 0; /* Find smallest working delay */ ddrphy_rdly_dq_rst_write(1); while(1) { command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA); cdelay(15); working = 1; for(p=0;p<DFII_NPHASES;p++) { if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i]) working = 0; if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2]) working = 0; } if(working) break; delay++; if(delay >= 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<DFII_NPHASES;p++) { if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i]) working = 0; if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2]) working = 0; } if(!working) break; delay++; if(delay >= 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"); }
static int write_level(int *delay, int *high_skew) { int i; int dq_address; unsigned char dq; int ok; printf("Write leveling: "); sdrwlon(); cdelay(100); for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) { dq_address = sdram_dfii_pix_rddata_addr[0]+4*(DFII_PIX_DATA_SIZE/2-1-i); ddrphy_dly_sel_write(1 << i); ddrphy_wdly_dq_rst_write(1); ddrphy_wdly_dqs_rst_write(1); delay[i] = 0; ddrphy_wlevel_strobe_write(1); cdelay(10); dq = MMPTR(dq_address); if(dq != 0) { /* * Assume this DQ group has between 1 and 2 bit times of skew. * Bring DQS into the CK=0 zone before continuing leveling. */ high_skew[i] = 1; 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); } } 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; }