static void program_ecc(u32 start_address, u32 num_bytes, u32 tlb_word2_i_value) { u32 val; u32 current_addr = start_address; u32 size; int bytes_remaining; sync(); wait_ddr_idle(); /* * Because of 440EPx errata CHIP 11, we don't touch the last 256 * bytes of SDRAM. */ bytes_remaining = num_bytes - CONFIG_SYS_MEM_TOP_HIDE; /* * We have to write the ECC bytes by zeroing and flushing in smaller * steps, since the whole 256MByte takes too long for the external * watchdog. */ while (bytes_remaining > 0) { size = min((64 << 20), bytes_remaining); /* Write zero's to SDRAM */ dcbz_area(current_addr, size); /* Write modified dcache lines back to memory */ clean_dcache_range(current_addr, current_addr + size); current_addr += 64 << 20; bytes_remaining -= 64 << 20; WATCHDOG_RESET(); } sync(); wait_ddr_idle(); /* Clear error status */ mfsdram(DDR0_00, val); mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); /* Set 'int_mask' parameter to functionnal value */ mfsdram(DDR0_01, val); mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF)); sync(); wait_ddr_idle(); }
static void program_ecc_addr(unsigned long start_address, unsigned long num_bytes, unsigned long tlb_word2_i_value) { unsigned long current_address; unsigned long end_address; unsigned long address_increment; unsigned long mcopt1; char str[] = "ECC generation -"; char slash[] = "\\|/-\\|/-"; int loop = 0; int loopi = 0; current_address = start_address; mfsdram(SDRAM_MCOPT1, mcopt1); if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) { mtsdram(SDRAM_MCOPT1, (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN); sync(); eieio(); wait_ddr_idle(); puts(str); #ifdef CONFIG_440 if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) { #endif /* ECC bit set method for non-cached memory */ if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) address_increment = 4; else address_increment = SDRAM_DATA_ALT_WIDTH; end_address = current_address + num_bytes; while (current_address < end_address) { *((unsigned long *)current_address) = 0; current_address += address_increment; if ((loop++ % (2 << 20)) == 0) { putc('\b'); putc(slash[loopi++ % 8]); } } #ifdef CONFIG_440 } else { /* ECC bit set method for cached memory */ dcbz_area(start_address, num_bytes); /* Write modified dcache lines back to memory */ clean_dcache_range(start_address, start_address + num_bytes); } #endif /* CONFIG_440 */ blank_string(strlen(str)); sync(); eieio(); wait_ddr_idle(); /* clear ECC error repoting registers */ mtsdram(SDRAM_ECCES, 0xffffffff); mtdcr(0x4c, 0xffffffff); mtsdram(SDRAM_MCOPT1, (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP); sync(); eieio(); wait_ddr_idle(); } }
static void program_ecc(u32 start_address, u32 num_bytes, u32 tlb_word2_i_value) { u32 current_address; u32 end_address; u32 address_increment; u32 val; char str[] = "ECC generation -"; char slash[] = "\\|/-\\|/-"; int loop = 0; int loopi = 0; current_address = start_address; sync(); eieio(); wait_ddr_idle(); if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) { /* ECC bit set method for non-cached memory */ address_increment = 4; end_address = current_address + num_bytes; puts(str); while (current_address < end_address) { *((u32 *)current_address) = 0x00000000; current_address += address_increment; if ((loop++ % (2 << 20)) == 0) { putc('\b'); putc(slash[loopi++ % 8]); } } blank_string(strlen(str)); } else { /* ECC bit set method for cached memory */ #if 0 /* test-only: will remove this define later, when ECC problems are solved! */ /* * Some boards (like lwmon5) need to preserve the memory * content upon ECC generation (for the log-buffer). * Therefore we don't fill the memory with a pattern or * just zero it, but write the same values back that are * already in the memory cells. */ address_increment = CFG_CACHELINE_SIZE; end_address = current_address + num_bytes; current_address = start_address; while (current_address < end_address) { /* * TODO: Th following sequence doesn't work correctly. * Just invalidating and flushing the cache doesn't * seem to trigger the re-write of the memory. */ ppcDcbi(current_address); ppcDcbf(current_address); current_address += CFG_CACHELINE_SIZE; } #else dcbz_area(start_address, num_bytes); dflush(); #endif } sync(); eieio(); wait_ddr_idle(); /* Clear error status */ mfsdram(DDR0_00, val); mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); /* Set 'int_mask' parameter to functionnal value */ mfsdram(DDR0_01, val); mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF)); sync(); eieio(); wait_ddr_idle(); }