cpu.c 14.6 KB
Newer Older
W
wdenk 已提交
1
/*
2
 * Copyright 2004,2007-2011 Freescale Semiconductor, Inc.
W
wdenk 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 * (C) Copyright 2002, 2003 Motorola Inc.
 * Xianghua Xiao (X.Xiao@motorola.com)
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

28
#include <config.h>
W
wdenk 已提交
29 30 31
#include <common.h>
#include <watchdog.h>
#include <command.h>
32
#include <fsl_esdhc.h>
W
wdenk 已提交
33
#include <asm/cache.h>
34
#include <asm/io.h>
B
Becky Bruce 已提交
35
#include <asm/mmu.h>
36
#include <asm/fsl_ifc.h>
B
Becky Bruce 已提交
37
#include <asm/fsl_law.h>
38
#include <asm/fsl_lbc.h>
39 40 41
#include <post.h>
#include <asm/processor.h>
#include <asm/fsl_ddr_sdram.h>
W
wdenk 已提交
42

43 44
DECLARE_GLOBAL_DATA_PTR;

45 46 47 48 49 50 51 52 53 54
/*
 * Default board reset function
 */
static void
__board_reset(void)
{
	/* Do nothing */
}
void board_reset(void) __attribute__((weak, alias("__board_reset")));

W
wdenk 已提交
55 56
int checkcpu (void)
{
57 58 59 60
	sys_info_t sysinfo;
	uint pvr, svr;
	uint ver;
	uint major, minor;
K
Kumar Gala 已提交
61
	struct cpu_type *cpu;
62
	char buf1[32], buf2[32];
63 64
#if (defined(CONFIG_DDR_CLK_FREQ) || \
	defined(CONFIG_FSL_CORENET)) && !defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2)
65
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
K
Kumar Gala 已提交
66
#endif /* CONFIG_FSL_CORENET */
67 68 69 70 71 72

	/*
	 * Cornet platforms use ddr sync bit in RCW to indicate sync vs async
	 * mode. Previous platform use ddr ratio to do the same. This
	 * information is only for display here.
	 */
73
#ifdef CONFIG_FSL_CORENET
74
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
75
	u32 ddr_sync = 0;	/* only async mode is supported */
76
#else
77
	u32 ddr_sync = ((gur->rcwsr[5]) & FSL_CORENET_RCWSR5_DDR_SYNC)
78
		>> FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT;
79
#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
80 81 82 83
#else	/* CONFIG_FSL_CORENET */
#ifdef CONFIG_DDR_CLK_FREQ
	u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
		>> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
84 85
#else
	u32 ddr_ratio = 0;
86
#endif /* CONFIG_DDR_CLK_FREQ */
87 88
#endif /* CONFIG_FSL_CORENET */

89 90
	unsigned int i, core, nr_cores = cpu_numcores();
	u32 mask = cpu_mask();
91 92 93 94

	svr = get_svr();
	major = SVR_MAJ(svr);
	minor = SVR_MIN(svr);
W
wdenk 已提交
95

96
	if (cpu_numcores() > 1) {
97 98 99 100
#ifndef CONFIG_MP
		puts("Unicore software on multiprocessor system!!\n"
		     "To enable mutlticore build define CONFIG_MP\n");
#endif
101
		volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
102 103 104 105
		printf("CPU%d:  ", pic->whoami);
	} else {
		puts("CPU:   ");
	}
106

107
	cpu = gd->cpu;
108

109 110 111
	puts(cpu->name);
	if (IS_E_PROCESSOR(svr))
		puts("E");
112

113 114
	printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);

115 116 117 118 119 120
	pvr = get_pvr();
	ver = PVR_VER(pvr);
	major = PVR_MAJ(pvr);
	minor = PVR_MIN(pvr);

	printf("Core:  ");
121 122 123 124 125 126 127 128 129 130 131
	switch(ver) {
	case PVR_VER_E500_V1:
	case PVR_VER_E500_V2:
		puts("E500");
		break;
	case PVR_VER_E500MC:
		puts("E500MC");
		break;
	case PVR_VER_E5500:
		puts("E5500");
		break;
K
Kumar Gala 已提交
132 133 134
	case PVR_VER_E6500:
		puts("E6500");
		break;
135
	default:
136
		puts("Unknown");
137
		break;
138
	}
K
Kumar Gala 已提交
139

140 141
	printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);

Y
York Sun 已提交
142 143 144 145 146
	if (nr_cores > CONFIG_MAX_CPUS) {
		panic("\nUnexpected number of cores: %d, max is %d\n",
			nr_cores, CONFIG_MAX_CPUS);
	}

147 148
	get_sys_info(&sysinfo);

149
	puts("Clock Configuration:");
150
	for_each_cpu(i, core, nr_cores, mask) {
151 152
		if (!(i & 3))
			printf ("\n       ");
153 154
		printf("CPU%d:%-4s MHz, ", core,
			strmhz(buf1, sysinfo.freqProcessor[core]));
155 156
	}
	printf("\n       CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus));
157

158 159 160 161 162 163 164 165 166 167 168 169 170
#ifdef CONFIG_FSL_CORENET
	if (ddr_sync == 1) {
		printf("       DDR:%-4s MHz (%s MT/s data rate) "
			"(Synchronous), ",
			strmhz(buf1, sysinfo.freqDDRBus/2),
			strmhz(buf2, sysinfo.freqDDRBus));
	} else {
		printf("       DDR:%-4s MHz (%s MT/s data rate) "
			"(Asynchronous), ",
			strmhz(buf1, sysinfo.freqDDRBus/2),
			strmhz(buf2, sysinfo.freqDDRBus));
	}
#else
K
Kumar Gala 已提交
171 172
	switch (ddr_ratio) {
	case 0x0:
173 174 175
		printf("       DDR:%-4s MHz (%s MT/s data rate), ",
			strmhz(buf1, sysinfo.freqDDRBus/2),
			strmhz(buf2, sysinfo.freqDDRBus));
K
Kumar Gala 已提交
176 177
		break;
	case 0x7:
178 179
		printf("       DDR:%-4s MHz (%s MT/s data rate) "
			"(Synchronous), ",
180 181
			strmhz(buf1, sysinfo.freqDDRBus/2),
			strmhz(buf2, sysinfo.freqDDRBus));
K
Kumar Gala 已提交
182 183
		break;
	default:
184 185
		printf("       DDR:%-4s MHz (%s MT/s data rate) "
			"(Asynchronous), ",
186 187
			strmhz(buf1, sysinfo.freqDDRBus/2),
			strmhz(buf2, sysinfo.freqDDRBus));
K
Kumar Gala 已提交
188 189
		break;
	}
190
#endif
191

192
#if defined(CONFIG_FSL_LBC)
193
	if (sysinfo.freqLocalBus > LCRR_CLKDIV) {
194
		printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus));
195
	} else {
196 197
		printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n",
		       sysinfo.freqLocalBus);
198
	}
199
#endif
W
wdenk 已提交
200

201 202 203 204
#if defined(CONFIG_FSL_IFC)
	printf("IFC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus));
#endif

205
#ifdef CONFIG_CPM2
206
	printf("CPM:   %s MHz\n", strmhz(buf1, sysinfo.freqSystemBus));
207
#endif
208

H
Haiying Wang 已提交
209 210 211 212
#ifdef CONFIG_QE
	printf("       QE:%-4s MHz\n", strmhz(buf1, sysinfo.freqQE));
#endif

213 214
#ifdef CONFIG_SYS_DPAA_FMAN
	for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) {
215
		printf("       FMAN%d: %s MHz\n", i + 1,
216 217 218 219
			strmhz(buf1, sysinfo.freqFMan[i]));
	}
#endif

220 221 222 223
#ifdef CONFIG_SYS_DPAA_QBMAN
	printf("       QMAN:  %s MHz\n", strmhz(buf1, sysinfo.freqQMAN));
#endif

224 225 226 227
#ifdef CONFIG_SYS_DPAA_PME
	printf("       PME:   %s MHz\n", strmhz(buf1, sysinfo.freqPME));
#endif

228
	puts("L1:    D-cache 32 kB enabled\n       I-cache 32 kB enabled\n");
W
wdenk 已提交
229 230 231 232 233 234 235

	return 0;
}


/* ------------------------------------------------------------------------- */

236
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
W
wdenk 已提交
237
{
K
Kumar Gala 已提交
238 239 240
/* Everything after the first generation of PQ3 parts has RSTCR */
#if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
    defined(CONFIG_MPC8555) || defined(CONFIG_MPC8560)
S
Sergei Poselenov 已提交
241 242
	unsigned long val, msr;

W
wdenk 已提交
243 244
	/*
	 * Initiate hard reset in debug control register DBCR0
K
Kumar Gala 已提交
245
	 * Make sure MSR[DE] = 1.  This only resets the core.
W
wdenk 已提交
246
	 */
S
Sergei Poselenov 已提交
247 248 249 250 251 252 253
	msr = mfmsr ();
	msr |= MSR_DE;
	mtmsr (msr);

	val = mfspr(DBCR0);
	val |= 0x70000000;
	mtspr(DBCR0,val);
K
Kumar Gala 已提交
254 255
#else
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
256 257 258 259 260 261

	/* Attempt board-specific reset */
	board_reset();

	/* Next try asserting HRESET_REQ */
	out_be32(&gur->rstcr, 0x2);
K
Kumar Gala 已提交
262 263
	udelay(100);
#endif
264

W
wdenk 已提交
265 266 267 268 269 270 271
	return 1;
}


/*
 * Get timebase clock frequency
 */
272 273 274
#ifndef CONFIG_SYS_FSL_TBCLK_DIV
#define CONFIG_SYS_FSL_TBCLK_DIV 8
#endif
W
wdenk 已提交
275 276
unsigned long get_tbclk (void)
{
277 278 279
	unsigned long tbclk_div = CONFIG_SYS_FSL_TBCLK_DIV;

	return (gd->bus_clk + (tbclk_div >> 1)) / tbclk_div;
W
wdenk 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
}


#if defined(CONFIG_WATCHDOG)
void
watchdog_reset(void)
{
	int re_enable = disable_interrupts();
	reset_85xx_watchdog();
	if (re_enable) enable_interrupts();
}

void
reset_85xx_watchdog(void)
{
	/*
	 * Clear TSR(WIS) bit by writing 1
	 */
298
	mtspr(SPRN_TSR, TSR_WIS);
W
wdenk 已提交
299 300 301
}
#endif	/* CONFIG_WATCHDOG */

302 303 304 305 306 307 308 309 310 311 312 313
/*
 * Initializes on-chip MMC controllers.
 * to override, implement board_mmc_init()
 */
int cpu_mmc_init(bd_t *bis)
{
#ifdef CONFIG_FSL_ESDHC
	return fsl_esdhc_mmc_init(bis);
#else
	return 0;
#endif
}
B
Becky Bruce 已提交
314 315 316

/*
 * Print out the state of various machine registers.
317 318
 * Currently prints out LAWs, BR0/OR0 for LBC, CSPR/CSOR/Timing
 * parameters for IFC and TLBs
B
Becky Bruce 已提交
319 320 321 322 323
 */
void mpc85xx_reginfo(void)
{
	print_tlbcam();
	print_laws();
324
#if defined(CONFIG_FSL_LBC)
B
Becky Bruce 已提交
325
	print_lbc_regs();
326
#endif
327 328 329
#ifdef CONFIG_FSL_IFC
	print_ifc_regs();
#endif
330

B
Becky Bruce 已提交
331
}
332

333 334
/* Common ddr init for non-corenet fsl 85xx platforms */
#ifndef CONFIG_FSL_CORENET
S
Scott Wood 已提交
335 336
#if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \
	!defined(CONFIG_SYS_INIT_L2_ADDR)
337 338 339 340 341 342 343 344 345
phys_size_t initdram(int board_type)
{
#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD)
	return fsl_ddr_sdram_size();
#else
	return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
#endif
}
#else /* CONFIG_SYS_RAMBOOT */
346 347 348 349
phys_size_t initdram(int board_type)
{
	phys_size_t dram_size = 0;

350
#if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN)
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
	{
		ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
		unsigned int x = 10;
		unsigned int i;

		/*
		 * Work around to stabilize DDR DLL
		 */
		out_be32(&gur->ddrdllcr, 0x81000000);
		asm("sync;isync;msync");
		udelay(200);
		while (in_be32(&gur->ddrdllcr) != 0x81000100) {
			setbits_be32(&gur->devdisr, 0x00010000);
			for (i = 0; i < x; i++)
				;
			clrbits_be32(&gur->devdisr, 0x00010000);
			x++;
		}
	}
#endif

372 373 374
#if	defined(CONFIG_SPD_EEPROM)	|| \
	defined(CONFIG_DDR_SPD)		|| \
	defined(CONFIG_SYS_DDR_RAW_TIMING)
375 376 377 378 379 380 381 382 383 384 385 386 387 388
	dram_size = fsl_ddr_sdram();
#else
	dram_size = fixed_sdram();
#endif
	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
	dram_size *= 0x100000;

#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
	/*
	 * Initialize and enable DDR ECC.
	 */
	ddr_enable_ecc(dram_size);
#endif

389
#if defined(CONFIG_FSL_LBC)
390
	/* Some boards also have sdram on the lbc */
391
	lbc_sdram_init();
392
#endif
393

394
	debug("DDR: ");
395 396
	return dram_size;
}
397
#endif /* CONFIG_SYS_RAMBOOT */
398 399
#endif

400 401 402 403 404 405 406 407 408 409
#if CONFIG_POST & CONFIG_SYS_POST_MEMORY

/* Board-specific functions defined in each board's ddr.c */
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
	unsigned int ctrl_num);
void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
		       phys_addr_t *rpn);
unsigned int
	setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);

410 411
void clear_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);

412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
static void dump_spd_ddr_reg(void)
{
	int i, j, k, m;
	u8 *p_8;
	u32 *p_32;
	ccsr_ddr_t *ddr[CONFIG_NUM_DDR_CONTROLLERS];
	generic_spd_eeprom_t
		spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR];

	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
		fsl_ddr_get_spd(spd[i], i);

	puts("SPD data of all dimms (zero vaule is omitted)...\n");
	puts("Byte (hex)  ");
	k = 1;
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++)
			printf("Dimm%d ", k++);
	}
	puts("\n");
	for (k = 0; k < sizeof(generic_spd_eeprom_t); k++) {
		m = 0;
		printf("%3d (0x%02x)  ", k, k);
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
				p_8 = (u8 *) &spd[i][j];
				if (p_8[k]) {
					printf("0x%02x  ", p_8[k]);
					m++;
				} else
					puts("      ");
			}
		}
		if (m)
			puts("\n");
		else
			puts("\r");
	}

	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		switch (i) {
		case 0:
			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
			break;
456
#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
457 458 459
		case 1:
			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
			break;
460 461 462 463 464 465 466 467 468 469
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
		case 2:
			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
			break;
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
		case 3:
			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
			break;
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
#endif
		default:
			printf("%s unexpected controller number = %u\n",
				__func__, i);
			return;
		}
	}
	printf("DDR registers dump for all controllers "
		"(zero vaule is omitted)...\n");
	puts("Offset (hex)   ");
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
		printf("     Base + 0x%04x", (u32)ddr[i] & 0xFFFF);
	puts("\n");
	for (k = 0; k < sizeof(ccsr_ddr_t)/4; k++) {
		m = 0;
		printf("%6d (0x%04x)", k * 4, k * 4);
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			p_32 = (u32 *) ddr[i];
			if (p_32[k]) {
				printf("        0x%08x", p_32[k]);
				m++;
			} else
				puts("                  ");
		}
		if (m)
			puts("\n");
		else
			puts("\r");
	}
	puts("\n");
}

/* invalid the TLBs for DDR and setup new ones to cover p_addr */
static int reset_tlb(phys_addr_t p_addr, u32 size, phys_addr_t *phys_offset)
{
	u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE;
	unsigned long epn;
	u32 tsize, valid, ptr;
	int ddr_esel;

510
	clear_ddr_tlbs_phys(p_addr, size>>20);
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616

	/* Setup new tlb to cover the physical address */
	setup_ddr_tlbs_phys(p_addr, size>>20);

	ptr = vstart;
	ddr_esel = find_tlb_idx((void *)ptr, 1);
	if (ddr_esel != -1) {
		read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, phys_offset);
	} else {
		printf("TLB error in function %s\n", __func__);
		return -1;
	}

	return 0;
}

/*
 * slide the testing window up to test another area
 * for 32_bit system, the maximum testable memory is limited to
 * CONFIG_MAX_MEM_MAPPED
 */
int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
{
	phys_addr_t test_cap, p_addr;
	phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);

#if !defined(CONFIG_PHYS_64BIT) || \
    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
	(CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
		test_cap = p_size;
#else
		test_cap = gd->ram_size;
#endif
	p_addr = (*vstart) + (*size) + (*phys_offset);
	if (p_addr < test_cap - 1) {
		p_size = min(test_cap - p_addr, CONFIG_MAX_MEM_MAPPED);
		if (reset_tlb(p_addr, p_size, phys_offset) == -1)
			return -1;
		*vstart = CONFIG_SYS_DDR_SDRAM_BASE;
		*size = (u32) p_size;
		printf("Testing 0x%08llx - 0x%08llx\n",
			(u64)(*vstart) + (*phys_offset),
			(u64)(*vstart) + (*phys_offset) + (*size) - 1);
	} else
		return 1;

	return 0;
}

/* initialization for testing area */
int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
{
	phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);

	*vstart = CONFIG_SYS_DDR_SDRAM_BASE;
	*size = (u32) p_size;	/* CONFIG_MAX_MEM_MAPPED < 4G */
	*phys_offset = 0;

#if !defined(CONFIG_PHYS_64BIT) || \
    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
	(CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
		if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
			puts("Cannot test more than ");
			print_size(CONFIG_MAX_MEM_MAPPED,
				" without proper 36BIT support.\n");
		}
#endif
	printf("Testing 0x%08llx - 0x%08llx\n",
		(u64)(*vstart) + (*phys_offset),
		(u64)(*vstart) + (*phys_offset) + (*size) - 1);

	return 0;
}

/* invalid TLBs for DDR and remap as normal after testing */
int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
{
	unsigned long epn;
	u32 tsize, valid, ptr;
	phys_addr_t rpn = 0;
	int ddr_esel;

	/* disable the TLBs for this testing */
	ptr = *vstart;

	while (ptr < (*vstart) + (*size)) {
		ddr_esel = find_tlb_idx((void *)ptr, 1);
		if (ddr_esel != -1) {
			read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
			disable_tlb(ddr_esel);
		}
		ptr += TSIZE_TO_BYTES(tsize);
	}

	puts("Remap DDR ");
	setup_ddr_tlbs(gd->ram_size>>20);
	puts("\n");

	return 0;
}

void arch_memory_failure_handle(void)
{
	dump_spd_ddr_reg();
}
#endif