📄 em86xx_dram.c
字号:
static RMuint32 TestPattern(RMuint32 gbus_src, RMuint32 nb_blocks, RMuint32 pat){ register int i; RMuint32 cmd; RMuint32 diff, tmp; RMuint32 gfx_ctrl;// RMuint32 block_offset = 1024; RMuint32 block_offset = 1028; for (i = 0; i < 256; i++) { tmp = (((i & 7) < 6) << (i >> 3)) ^ - (((0x52 >> (i & 7)) ^ pat) & 1); // See Yann for more info... if (pat==2) tmp=(i*0x01010101) ^ ((i&1)-1); //gbus_write_uint32(gbus_src + 4*i, (1 << (i >> 3)) ^ -((i^pat) & 1) ^ -((i>>2) & 1));// gbus_write_uint32(gbus_src + 4*i, tmp); gbus_write_uint32(gbus_src + (i << 2), tmp); } // Reset/unreset graphic accelerator block // JM note: we have to leave the accelerator in reset mode or else it will loose one 32 bit value the // first time we run the test! gbus_write_uint32(REG_BASE_display_block + VO_reset_datapath, (1 << VO_graph_acc_reset_bit)); gfx_ctrl = 0; RMsetConsecutiveBits(&gfx_ctrl, 0, 2, VO_graph_acc_MOVE); RMsetConsecutiveBits(&gfx_ctrl, 11, 12, 0x2); // 32 bits (bits 11,12 = 1,0), no dithering (bits 13,14 = 0,0) gbus_write_uint32(REG_BASE_display_block + VO_graph_acc_control, gfx_ctrl); gbus_write_uint32(REG_BASE_display_block + VO_graph_acc_Y_format, 0x1c); // Y format is format true color + sub format 32BPP gbus_write_uint32(REG_BASE_display_block + VIF_r10 + VIF_cnt, 1024); // Only first 13 bits are used (< 8KB) gbus_write_uint32(REG_BASE_display_block + VIF_w2 + VIF_cnt, 1024); // Only first 13 bits are used (< 8KB) // Put the accelerator in run mode now. gbus_write_uint32(REG_BASE_display_block + VO_run, (1 << VO_graph_acc_reset_bit)); cmd = VBUS_LINEAR_VOID; RMsetConsecutiveBits(&cmd, 5, 6, 2); // 32 bit transfer = 0 for (i = 0; i < (int) nb_blocks; i++) { gbus_write_uint32(REG_BASE_display_block + VIF_r10 + VIF_add, gbus_src + block_offset*i);// gbus_write_uint32(REG_BASE_display_block + VIF_r10 + VIF_add, gbus_src + (i << 10)); gbus_write_uint32(REG_BASE_display_block + VIF_w2 + VIF_add, gbus_src + block_offset*(i+1));// gbus_write_uint32(REG_BASE_display_block + VIF_w2 + VIF_add, gbus_src + ((i+1) << 10)); gbus_write_uint32(REG_BASE_display_block + VIF_w2 + VIF_cmd, cmd); gbus_write_uint32(REG_BASE_display_block + VIF_r10 + VIF_cmd, cmd); while ((gbus_read_uint32(REG_BASE_display_block + VIF_w2 + VIF_cmd) & 0xF) != 0); } diff = 0; for (i = 0; i < 256; i++) { tmp = (((i & 7) < 6) << (i >> 3)) ^ - (((0x52 >> (i & 7)) ^ pat) & 1); // See Yann for more info... if (pat==2) tmp=(i*0x01010101) ^ ((i&1)-1); //diff |= (1 << (i >> 3)) ^ -((i^pat) & 1) ^ -((i>>2) & 1) ^ gbus_read_uint32(gbus_src + 4*i + nb_blocks*1024); diff |= tmp ^ gbus_read_uint32(gbus_src + 4*i + nb_blocks*block_offset);// diff |= tmp ^ gbus_read_uint32(gbus_src + (i << 2) + (nb_blocks << 10)); } return diff;}static RMuint32 test_capdelay_1freq_dram0_gfx(RMuint32 wd, RMuint32 *size){// RMuint32 save_config; RMuint32 result; RMuint32 fail; RMuint32 rd; RMuint32 save_vbus_bandwitdh_1, save_vbus_bandwitdh_2; RMuint32 bgt_size; RMuint32 cg_size[4], bg_size[4], rdb[4]; RMint32 cg_pos[4], bg_pos[4]; int i;#ifdef DEBUG_DRAMADJUSTMENT // Remove this for boot loader uart_printf("\nWith existing system clock: %dMHz, write delay: %d\n", em86xx_getclockmhz(), (gbus_read_uint32(REG_BASE_dram_controller_0 + 4) >> 16) & 0xf); uart_printf(" 0x%08x ", (int) (gbus_read_uint32(REG_BASE_dram_controller_0))); switch (gbus_read_uint32(REG_BASE_dram_controller_0) & 0x07700000) { case 0x02100000: uart_puts("<DCL=2 CCL=2.5> "); break; case 0x02200000: uart_puts("<DCL=2 CCL=3 > "); break; case 0x06200000: uart_puts("<DCL=2.5 CCL=3 > "); break; case 0x06300000: uart_puts("<DCL=2.5 CCL=3.5> "); break; case 0x03300000: uart_puts("<DCL=3 CCL=3.5> "); break; case 0x03400000: uart_puts("<DCL=3 CCL=4 > "); break; default: uart_puts("< !!!invalid!!! > "); break; }#endif uart_printf("\n Old config = 0x%08x - ", (int) gbus_read_uint32(REG_BASE_dram_controller_0 + 4));// save_config = gbus_read_uint32(REG_BASE_dram_controller_0 + 4); save_vbus_bandwitdh_1 = gbus_read_uint32(REG_BASE_system_block + VARB_mid30_cfg); // Y channel bandwidth save_vbus_bandwitdh_2 = gbus_read_uint32(REG_BASE_system_block + VARB_mid10_cfg); // NX channel bandwidth gbus_write_uint32(REG_BASE_system_block + VARB_mid30_cfg, 0x13F08); // Max VBUS bandwidth gbus_write_uint32(REG_BASE_system_block + VARB_mid10_cfg, 0x13F08); cg_size[0] = cg_size[1] = cg_size[2] = cg_size[3] = bg_size[0] = bg_size[1] = bg_size[2] = bg_size[3] = 0; cg_pos[0] = cg_pos[1] = cg_pos[2] = cg_pos[3] = bg_pos[0] = bg_pos[1] = bg_pos[2] = bg_pos[3] = -2; *size = rdb[0] = rdb[1] = rdb[2] = rdb[3] = 0; for (rd = 0; rd < 0x10; rd++) { gbus_write_uint32(REG_BASE_dram_controller_0 + 4, wd | (rd<<12)|(rd<<8)|(rd<<4)|rd); /* insert new read delays */ result = TestPattern(MEM_BASE_dram_controller_0, 128, 0); result |= TestPattern(MEM_BASE_dram_controller_0, 128, 1); result |= TestPattern(MEM_BASE_dram_controller_0, 128, 2); fail = 0; if ((result & 0x000000FF) != 0) fail |= 1; if ((result & 0x0000FF00) != 0) fail |= 2; if ((result & 0x00FF0000) != 0) fail |= 4; if ((result & 0xFF000000) != 0) fail |= 8; for (i = 0; i < 4; i++) { if ((fail & (1 << i)) == 0) { if (cg_pos[i] < -1) { cg_pos[i] = rd; cg_size[i] = 1; } else cg_size[i]++; if (rd == 0) { cg_pos[i]--; cg_size[i]++; } } if (((fail & (1 << i)) != 0) || (rd == 0xf)) { // It fails or last one if (cg_pos[i] >= -1) { if (cg_size[i] > bg_size[i]) { // There could be ..23....11fffff, we need second good range bg_pos[i] = cg_pos[i]; bg_size[i] = cg_size[i]; } cg_pos[i] = -2; // Reset current "good" position to undefined } } }#ifdef DEBUG_DRAMADJUSTMENT if (fail == 0) { uart_putc('.'); } else { uart_printf("%x", (int)fail); }#endif } bgt_size = 0x20; for (i = 0; i < 4; i++) { rdb[i] = bg_pos[i] + ((bg_size[i] - 1) >> 1) ; if (bg_size[i] < bgt_size) bgt_size = bg_size[i]; } if (bgt_size < MIN_GOOD_SIZE) { result = *size = 0; uart_puts(" - failed\n"); } else { result = wd | (rdb[3] << 12) | (rdb[2] << 8) | (rdb[1] << 4) | (rdb[0] << 0); uart_printf(" - read delay = 0x%04x, New config = 0x%08x,", result & 0xffff, result); uart_printf(" size %d\n", bgt_size); *size = bgt_size; } // Restore system settings // Restore initial read delays// gbus_write_uint32(REG_BASE_dram_controller_0 + 4, save_config); // Restore VBUS bandwidth gbus_write_uint32(REG_BASE_system_block + VARB_mid30_cfg, save_vbus_bandwitdh_1); gbus_write_uint32(REG_BASE_system_block + VARB_mid10_cfg, save_vbus_bandwitdh_2); return(result);}#elsestatic char *uart_getstr(char *str, int len);static unsigned long str2hex(char *str, char **ptr, int max);static void uart_putstr(const char *str);void xtra_stage0(unsigned int configaddr){ char cmd[128], res[32], *ptr; unsigned long addr, val; uart_init(); uart_puts("START ..\n"); while (1) { uart_getstr(cmd, 128); if (toupper(cmd[0]) == 'G') { if (toupper(cmd[1]) == 'R') { if (cmd[3] != ' ') continue; switch(toupper(cmd[2])) { case 'B': addr = str2hex(&cmd[4], &ptr, 8); val = (unsigned long)gbus_read_uint8(addr); sprintf(res, "%lx", val); uart_putstr(res); break; case 'W': addr = str2hex(&cmd[4], &ptr, 8); val = (unsigned long)gbus_read_uint16(addr); sprintf(res, "%lx", val); uart_putstr(res); break; case 'D': addr = str2hex(&cmd[4], &ptr, 8); val = (unsigned long)gbus_read_uint32(addr); sprintf(res, "%lx", val); uart_putstr(res); break; } } else if (toupper(cmd[1]) == 'W') { if (cmd[3] != ' ') continue; switch(toupper(cmd[2])) { case 'B': addr = str2hex(&cmd[4], &ptr, 8); val = str2hex(ptr, &ptr, 8); gbus_write_uint8(addr, (RMuint8)(val & 0xff)); sprintf(res, "%lx", val); uart_putstr(res); break; case 'W': addr = str2hex(&cmd[4], &ptr, 8); val = str2hex(ptr, &ptr, 8); gbus_write_uint16(addr, (RMuint16)(val & 0xffff)); sprintf(res, "%lx", val); uart_putstr(res); break; case 'D': addr = str2hex(&cmd[4], &ptr, 8); val = str2hex(ptr, &ptr, 8); gbus_write_uint32(addr, (RMuint32)val); sprintf(res, "%lx", val); uart_putstr(res); break; } } } else if (toupper(cmd[0]) == 'Q') { break; } } return;}static int isxdigit(char c){ if (isdigit(c)) return(1); else if ((toupper(c) >= 'A') && (toupper(c) <= 'F')) return(1); else return(0);}static unsigned long str2hex(char *str, char **ptr, int max){ unsigned long val = 0; int idx = 0; while ((*str != '\0') && (idx < max)) { if (isxdigit(*str)) { if (isdigit(*str)) val = (val << 4) + (*str - '0'); else val = (val << 4) + 10 + (toupper(*str) - 'A'); } else break; str++; idx++; } str++; *ptr = str; return(val);}static void uart_putstr(const char *str){ uart_puts(str); uart_putc('\n'); uart_putc('\r');}static char *uart_getstr(char *str, int len){ int pos = 0; int ch; while (pos < len) { while ((ch = uart_peekc()) < 0); str[pos] = (char)ch; if (((char)ch == '\n') || ((char)ch == '\r')) { str[pos] = '\0'; break; } pos++; } str[len - 1] = '\0'; return(str);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -