📄 test-stage0.c
字号:
#else/* Special mode starts here */static unsigned long hexStringToULong(const char *str, int size){ unsigned long res = 0; int base = 10; int i; if ((*str == '0') && ((*(str + 1) == 'x') || (*(str + 1) == 'X'))) { base = 16; str += 2; } for (i = 0; (*str != '\0') && (i < size); str++, i++) { if ((*str >= '0') && (*str <= '9')) res = (res * base) + (*str - '0'); else if (base == 16) { if ((*str >= 'a') && (*str <= 'f')) res = (res * base) + 10 + (*str - 'a'); else if ((*str >= 'A') && (*str <= 'F')) res = (res * base) + 10 + (*str - 'A'); else return(0); } else return(0); } return(res);}static unsigned long uart_getULong(char *prompt){ unsigned long res; char buf[64]; uart_puts(prompt); uart_gets(buf, 64, 1); res = hexStringToULong(buf, 64); return(res);}unsigned long tango_get_sysclock(void){ unsigned long sys_clkgen_pll, sysclk_mux, n, m, freq; sys_clkgen_pll = gbus_read_uint32(0, REG_BASE_system_block + SYS_clkgen0_pll); sysclk_mux = gbus_read_uint32(0, REG_BASE_system_block + SYS_sysclk_mux); n = sys_clkgen_pll & 0x000003ff; m = (sys_clkgen_pll & 0x003f0000) >> 16; if (sysclk_mux & 0x1) /* PLL is used */ freq = idivide(EM86XX_EXT_CLOCK, m + 2) * (n + 2); else freq = EM86XX_EXT_CLOCK; return(freq >> 1);}static const struct bist_entry { const unsigned int addr; const char *name; unsigned long mask;} bist_table[] = { { REG_BASE_audio_engine_0, "Audio Engine 0", 0 }, #ifdef CONFIG_ARCH_MAMBO { REG_BASE_audio_engine_1, "Audio Engine 1", 0 }, /* Only Mambo has it */#endif { REG_BASE_dram_controller_0, "DRAM Controller 0", 0 },#if defined(CONFIG_ARCH_MAMBO) && (DEFAULT_DRAM1_SIZE != 0) { REG_BASE_dram_controller_1, "DRAM Controller 1", 0 }, /* Only Mambo has DRAM1 */#endif { REG_BASE_mpeg_engine_0, "MPEG Engine 0", 0 }, { REG_BASE_demux_engine, "Transport Demux Engine", 0 }, { REG_BASE_display_block, "Display Block", 0x30 /* Exclude graphic/vsync inputs as external clock needed */ }, { REG_BASE_host_interface, "Host Interface", 0 }, /* Host interface may be used for PFlash */ { REG_BASE_system_block, "System Block", 0 }, /* System block is used for clocks/pll */ { REG_BASE_cpu_block, "CPU Block", 0 }, /* CPU block is used to execute the code */// { REG_BASE_mpeg_engine_1, "MPEG Engine 1", 0 }, /* Not existed on Mambo/Tango */// { REG_BASE_dram_controller_2, "DRAM Controller 2", 0 }, /* Not existed */ { 0, NULL, 0 },};#define PBI_REGS 14#define DRAM_REGS 15#define BIST_TIMEOUT 1000 /* 1000ms */static int do_bist(const struct bist_entry *entry){ register RMuint32 i; RMuint32 mask = 0, pass = 0; RMuint32 save_regs[32]; RMuint32 org_status, busy; RMuint32 addr = entry->addr; RMuint32 bist_mask = entry->mask; int timeout; /* Save original status before BIST starts */ org_status = gbus_read_uint32(0, addr + G2L_RESET_CONTROL); if (addr == REG_BASE_dram_controller_0) { for (i = 0; i < DRAM_REGS; i++) save_regs[i] = gbus_read_uint32(0, REG_BASE_dram_controller_0 + DRAM_dunit_cfg + (i<<2)); } else if (addr == REG_BASE_host_interface) { for (i = 0; i < PBI_REGS; i++) save_regs[i] = gbus_read_uint32(0, REG_BASE_host_interface + PB_timing0 + (i<<2)); } else if (addr == REG_BASE_display_block) { save_regs[0] = gbus_read_uint32(0, REG_BASE_system_block + SYS_avclk_mux); save_regs[1] = gbus_read_uint32(0, REG_BASE_system_block + SYS_clkgen1_pll); save_regs[2] = gbus_read_uint32(0, REG_BASE_system_block + SYS_clkgen1_div); gbus_write_uint32(0, REG_BASE_display_block + G2L_RESET_CONTROL, 3); gbus_write_uint32(0, REG_BASE_display_block + G2L_RESET_CONTROL, 2); gbus_write_uint32(0, REG_BASE_display_block + VO_reset_datapath, 0x800000); gbus_write_uint32(0, REG_BASE_display_block + VO_run, 0x800000); gbus_write_uint32(0, REG_BASE_display_block + 0x3d00, 1); gbus_write_uint32(0, REG_BASE_system_block + SYS_clkgen1_pll, 0x01010016); gbus_write_uint32(0, REG_BASE_system_block + SYS_clkgen1_div, 0x208); gbus_write_uint32(0, REG_BASE_system_block + SYS_avclk_mux, 0xbbba); em86xx_msleep(30); // wait until PLL gets stable }#if (DEFAULT_DRAM1_SIZE != 0) else if (addr == REG_BASE_dram_controller_1) { for (i = 0; i < DRAM_REGS; i++) save_regs[i] = gbus_read_uint32(0, REG_BASE_dram_controller_1 + DRAM_dunit_cfg + (i<<2)); }#endif uart_printf("BIST(0x%08lx, %s): ", addr, entry->name); if ((addr == REG_BASE_cpu_block) || (addr == REG_BASE_system_block) || (addr == REG_BASE_host_interface)) { uart_printf(" => Skipped (used by stage0)\n"); return 0; } gbus_write_uint32(0, addr + G2L_RESET_CONTROL, 1); mask = gbus_read_uint32(0, addr + G2L_BIST_MASK) & ~bist_mask; /* Start BIST */ gbus_write_uint32(0, addr + G2L_BIST_BUSY, 0x80000000); /* Max. wait for 1 second */ for (timeout = 0; timeout < BIST_TIMEOUT; timeout++, em86xx_msleep(1)) { busy = gbus_read_uint32(0, addr + G2L_BIST_BUSY); if (((busy & 0x7fffffff) & (~bist_mask)) == 0) break; } pass = gbus_read_uint32(0, addr + G2L_BIST_PASS) & ~bist_mask; gbus_write_uint32(0, addr + G2L_BIST_BUSY, 0x0); em86xx_msleep(10); if (timeout >= BIST_TIMEOUT) uart_printf("BUSY=0x%lx, MASK=0x%lx, PASS=0x%lx", (busy & 0x7fffffff) & (~bist_mask), mask, pass); else uart_printf("MASK=0x%08lx, PASS=0x%08lx", mask, pass); if (addr == REG_BASE_dram_controller_0) { for (i = 0; i < DRAM_REGS; i++) gbus_write_uint32(0, REG_BASE_dram_controller_0 + DRAM_dunit_cfg + (i<<2), save_regs[i]); } else if (addr == REG_BASE_host_interface) { for (i = 0; i < PBI_REGS; i++) gbus_write_uint32(0, REG_BASE_host_interface + PB_timing0 + (i<<2), save_regs[i]); } else if (addr == REG_BASE_display_block) { gbus_write_uint32(0, REG_BASE_system_block + SYS_clkgen1_div, save_regs[2]); gbus_write_uint32(0, REG_BASE_system_block + SYS_clkgen1_pll, save_regs[1]); gbus_write_uint32(0, REG_BASE_system_block + SYS_avclk_mux, save_regs[0]); em86xx_msleep(30); // wait until PLL gets stable }#if (DEFAULT_DRAM1_SIZE != 0) else if (addr == REG_BASE_dram_controller_1) { for (i = 0; i < DRAM_REGS; i++) gbus_write_uint32(0, REG_BASE_dram_controller_1 + DRAM_dunit_cfg + (i<<2), save_regs[i]); }#endif gbus_write_uint32(0, addr + G2L_RESET_CONTROL, org_status); em86xx_msleep(10); uart_printf(" => %s\n", (timeout >= BIST_TIMEOUT) ? "Timeout\07" : ((mask == pass) ? "Passed" : "Failed\07")); return(((timeout < BIST_TIMEOUT) && (mask == pass)) ? 0 : 1); /* 0=OK, 1=Failed */}static int dcache_write_test(unsigned int dest, unsigned int size, unsigned int pattern){ register int i; volatile unsigned int *c_addr = (volatile unsigned int *)CACHED(dest); volatile unsigned int *uc_addr = (volatile unsigned int *)UNCACHED(dest); volatile unsigned int *ptr; uart_printf("D-CACHE write test: 0x%08lx, size %d, pattern 0x%x\n", dest, size, pattern); for (i = 0, ptr = c_addr; i < size / sizeof(unsigned int); i++, ptr++) *ptr = pattern; em86xx_flush_cache_data(); for (i = 0, ptr = uc_addr; i < size / sizeof(unsigned int); i++, ptr++) { if (*ptr != pattern) return 1; /* failed */ } return 0;}static int dcache_read_test(unsigned int dest, unsigned int size, unsigned int pattern){ register int i; volatile unsigned int *c_addr = (volatile unsigned int *)CACHED(dest); volatile unsigned int *uc_addr = (volatile unsigned int *)UNCACHED(dest); volatile unsigned int *ptr; uart_printf("D-CACHE read test: 0x%08lx, size %d, pattern 0x%x\n", dest, size, pattern); em86xx_flush_cache_data(); for (i = 0, ptr = uc_addr; i < size / sizeof(unsigned int); i++, ptr++) *ptr = pattern; for (i = 0, ptr = c_addr; i < size / sizeof(unsigned int); i++, ptr++) { if (*ptr != pattern) return 1; /* failed */ } return 0;}static int dcache_test(void){ const unsigned int dcache_size = 1024 * 16; /* 16KB */ unsigned int a0_status = __raw_readl(REG_BASE_audio_engine_0 + G2L_RESET_CONTROL); int ret = 0; __raw_writel(3, REG_BASE_audio_engine_0 + G2L_RESET_CONTROL); __raw_writel(2, REG_BASE_audio_engine_0 + G2L_RESET_CONTROL); __raw_writel(1, REG_BASE_audio_engine_0 + G2L_RESET_CONTROL); if (dcache_read_test(DMEM_BASE_audio_engine_0, dcache_size, 0xaaaaaaaa)) ret++; else if (dcache_read_test(DMEM_BASE_audio_engine_0, dcache_size, 0x55555555)) ret++; else if (dcache_read_test(DMEM_BASE_audio_engine_0, dcache_size, 0x0)) ret++; else if (dcache_read_test(DMEM_BASE_audio_engine_0, dcache_size, 0xffffffff)) ret++; else if (dcache_write_test(DMEM_BASE_audio_engine_0, dcache_size, 0xaaaaaaaa)) ret++; else if (dcache_write_test(DMEM_BASE_audio_engine_0, dcache_size, 0x55555555)) ret++; else if (dcache_write_test(DMEM_BASE_audio_engine_0, dcache_size, 0x0)) ret++; else if (dcache_write_test(DMEM_BASE_audio_engine_0, dcache_size, 0xffffffff)) ret++; __raw_writel(a0_status, REG_BASE_audio_engine_0 + G2L_RESET_CONTROL); return ret;}static int stage0_special_mode(void){ char c; int done = 0; int start = idivide(tango_get_sysclock(), 1000000) - 10; int end = idivide(tango_get_sysclock(), 1000000) + 10; int w_delay = DEFAULT_WRITE_DELAY; int mem_test_needed = 0; int dunit_changed = 0; int def_freq; int gsize = MIN_GOOD_SIZE; unsigned tmask = 0xffffffff; unsigned long pll;#if ((DEFAULT_DRAM0_SIZE == 7) || (DEFAULT_DRAM1_SIZE == 7)) /* 128MB */ int nblocks = 8184; int blk_size = 4100; // Set to default so that nblocks*blk_size is close but not over 32MB#elif ((DEFAULT_DRAM0_SIZE == 6) || (DEFAULT_DRAM1_SIZE == 6)) /* 64MB */ int nblocks = 4092; int blk_size = 4100; // Set to default so that nblocks*blk_size is close but not over 16MB#elif ((DEFAULT_DRAM0_SIZE == 5) || (DEFAULT_DRAM1_SIZE == 5)) /* 32MB */ int nblocks = 2046; int blk_size = 4100; // Set to default so that nblocks*blk_size is close but not over 16MB#else int nblocks = 1023; int blk_size = 4100; // Set to default so that nblocks*blk_size is close but not over 8MB#endif pll = gbus_read_uint32(0, REG_BASE_system_block + SYS_clkgen0_pll); def_freq = DEFAULT_FREQ_ALL_BIT; uart_puts("\n\n"); while (done == 0) { uart_puts("Special Mode Menu:\n"); uart_printf("\t[0] Set DRAM0 dunit_cfg (0x%08lx), DRAM0 delay (0x%08lx)\n", gbus_read_uint32(0, REG_BASE_dram_controller_0 + DRAM_dunit_cfg), gbus_read_uint32(0, REG_BASE_dram_controller_0 + DRAM_dunit_delay0_ctrl));#if (DEFAULT_DRAM1_SIZE != 0) uart_printf("\t[1] Set DRAM1 dunit_cfg (0x%08lx), DRAM1 delay (0x%08lx)\n", gbus_read_uint32(0, REG_BASE_dram_controller_1 + DRAM_dunit_cfg), gbus_read_uint32(0, REG_BASE_dram_controller_1 + DRAM_dunit_delay0_ctrl));#endif uart_printf("\t[K] Set #Block for test (%d) [Z] Set Block size for test (%d)\n", nblocks, blk_size); uart_printf("\t[G] Min. good size (%d) [M] Test Pattern Mask (0x%08x)\n", gsize, tmask); uart_printf("\t[S] Set DRAM Test start frequency (%dMHz)\n", start); uart_printf("\t[E] Set DRAM Test end frequency (%dMHz)\n", end); uart_printf("\t[L] Set DRAM Test write delay (%d)\n", w_delay); uart_puts("\t[D] All Freq Test [A] All Bit Test\n"); uart_puts("\t[P] Find Best Params [T] Start Special DRAM Test\n"); uart_puts("\t[B] BIST [C] Cache Test\n"); uart_puts("\t[3] GR32 [4] GW32\n"); uart_puts("\t[6] GR16 [7] GW16\n"); uart_puts("\t[8] GR8 [9] GW8\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -