2018-05-06 21:58:06 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2003-10-15 23:53:47 +00:00
|
|
|
/*
|
2011-01-19 07:16:27 +00:00
|
|
|
* Copyright 2004,2007-2011 Freescale Semiconductor, Inc.
|
2003-10-15 23:53:47 +00:00
|
|
|
* (C) Copyright 2002, 2003 Motorola Inc.
|
|
|
|
* Xianghua Xiao (X.Xiao@motorola.com)
|
|
|
|
*
|
|
|
|
* (C) Copyright 2000
|
|
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
|
|
*/
|
|
|
|
|
2008-08-31 21:33:26 +00:00
|
|
|
#include <config.h>
|
2003-10-15 23:53:47 +00:00
|
|
|
#include <common.h>
|
2019-11-14 19:57:09 +00:00
|
|
|
#include <cpu_func.h>
|
2020-05-10 17:40:02 +00:00
|
|
|
#include <init.h>
|
2019-11-14 19:57:42 +00:00
|
|
|
#include <irq_func.h>
|
2020-05-10 17:40:05 +00:00
|
|
|
#include <log.h>
|
2019-12-28 17:44:59 +00:00
|
|
|
#include <time.h>
|
2019-11-14 19:57:20 +00:00
|
|
|
#include <vsprintf.h>
|
2003-10-15 23:53:47 +00:00
|
|
|
#include <watchdog.h>
|
|
|
|
#include <command.h>
|
2008-10-30 21:51:33 +00:00
|
|
|
#include <fsl_esdhc.h>
|
2003-10-15 23:53:47 +00:00
|
|
|
#include <asm/cache.h>
|
2020-10-31 03:38:53 +00:00
|
|
|
#include <asm/global_data.h>
|
2008-06-06 13:42:40 +00:00
|
|
|
#include <asm/io.h>
|
2010-06-17 16:37:25 +00:00
|
|
|
#include <asm/mmu.h>
|
2013-10-22 19:39:02 +00:00
|
|
|
#include <fsl_ifc.h>
|
2010-06-17 16:37:25 +00:00
|
|
|
#include <asm/fsl_law.h>
|
2010-12-17 23:17:56 +00:00
|
|
|
#include <asm/fsl_lbc.h>
|
2010-09-28 22:20:33 +00:00
|
|
|
#include <post.h>
|
|
|
|
#include <asm/processor.h>
|
2013-09-30 16:22:09 +00:00
|
|
|
#include <fsl_ddr_sdram.h>
|
2017-07-13 13:09:54 +00:00
|
|
|
#include <asm/ppc.h>
|
2020-05-10 17:40:11 +00:00
|
|
|
#include <linux/delay.h>
|
2003-10-15 23:53:47 +00:00
|
|
|
|
2008-02-08 22:44:53 +00:00
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
2011-11-21 21:20:32 +00:00
|
|
|
/*
|
|
|
|
* Default board reset function
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
__board_reset(void)
|
|
|
|
{
|
|
|
|
/* Do nothing */
|
|
|
|
}
|
|
|
|
void board_reset(void) __attribute__((weak, alias("__board_reset")));
|
|
|
|
|
2003-10-15 23:53:47 +00:00
|
|
|
int checkcpu (void)
|
|
|
|
{
|
2004-06-09 00:34:46 +00:00
|
|
|
sys_info_t sysinfo;
|
|
|
|
uint pvr, svr;
|
|
|
|
uint ver;
|
|
|
|
uint major, minor;
|
2008-06-10 21:53:46 +00:00
|
|
|
struct cpu_type *cpu;
|
2008-10-19 00:35:49 +00:00
|
|
|
char buf1[32], buf2[32];
|
2013-06-25 18:37:43 +00:00
|
|
|
#if defined(CONFIG_DDR_CLK_FREQ) || defined(CONFIG_FSL_CORENET)
|
|
|
|
ccsr_gur_t __iomem *gur =
|
|
|
|
(void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
|
|
|
#endif
|
2012-10-08 07:44:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2009-03-19 07:46:19 +00:00
|
|
|
#ifdef CONFIG_FSL_CORENET
|
2012-10-08 07:44:16 +00:00
|
|
|
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
|
2012-10-08 07:44:31 +00:00
|
|
|
u32 ddr_sync = 0; /* only async mode is supported */
|
2012-10-08 07:44:16 +00:00
|
|
|
#else
|
2012-10-08 07:44:31 +00:00
|
|
|
u32 ddr_sync = ((gur->rcwsr[5]) & FSL_CORENET_RCWSR5_DDR_SYNC)
|
2010-02-10 09:32:43 +00:00
|
|
|
>> FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT;
|
2012-10-08 07:44:16 +00:00
|
|
|
#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
|
2012-10-08 07:44:31 +00:00
|
|
|
#else /* CONFIG_FSL_CORENET */
|
|
|
|
#ifdef CONFIG_DDR_CLK_FREQ
|
|
|
|
u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
|
|
|
|
>> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
|
2008-05-29 06:21:24 +00:00
|
|
|
#else
|
|
|
|
u32 ddr_ratio = 0;
|
2009-03-19 07:46:19 +00:00
|
|
|
#endif /* CONFIG_DDR_CLK_FREQ */
|
2012-10-08 07:44:31 +00:00
|
|
|
#endif /* CONFIG_FSL_CORENET */
|
|
|
|
|
2011-08-05 21:15:24 +00:00
|
|
|
unsigned int i, core, nr_cores = cpu_numcores();
|
|
|
|
u32 mask = cpu_mask();
|
2004-06-09 00:34:46 +00:00
|
|
|
|
powerpc/mpc85xx: Add DSP side awareness for Freescale Heterogeneous SoCs
The code provides framework for heterogeneous multicore chips based on StarCore
and Power Architecture which are chasis-2 compliant, like B4860 and B4420
It will make u-boot recognize all non-ppc cores and peripherals like
SC3900/DSP CPUs, MAPLE, CPRI and print their configuration in u-boot logs.
Example boot logs of B4860QDS:
U-Boot 2015.01-00232-geef6e36-dirty (Jan 19 2015 - 11:58:45)
CPU0: B4860E, Version: 2.2, (0x86880022)
Core: e6500, Version: 2.0, (0x80400120)
Clock Configuration:
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
CCB:666.667 MHz,
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
CPRI:600 MHz
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz
FMAN1: 666.667 MHz
QMAN: 333.333 MHz
Top level changes include:
(1) Top level CONFIG to identify HETEROGENUOUS clusters
(2) CONFIGS for SC3900/DSP components
(3) Global structures like "cpu_type" and "MPC85xx_SYS_INFO"
updated for dsp cores and other components
(3) APIs to get DSP num cores and their Mask like:
cpu_dsp_mask, cpu_num_dspcores etc same as that of PowerPC
(5) Code to fetch and print SC cores and other heterogenous
device's frequencies
(6) README added for the same
Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
2015-01-19 07:16:54 +00:00
|
|
|
#ifdef CONFIG_HETROGENOUS_CLUSTERS
|
|
|
|
unsigned int j, dsp_core, dsp_numcores = cpu_num_dspcores();
|
|
|
|
u32 dsp_mask = cpu_dsp_mask();
|
|
|
|
#endif
|
|
|
|
|
2004-06-09 00:34:46 +00:00
|
|
|
svr = get_svr();
|
|
|
|
major = SVR_MAJ(svr);
|
|
|
|
minor = SVR_MIN(svr);
|
2003-10-15 23:53:47 +00:00
|
|
|
|
2014-04-25 08:31:22 +00:00
|
|
|
#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
|
|
|
|
if (SVR_SOC_VER(svr) == SVR_T4080) {
|
|
|
|
ccsr_rcpm_t *rcpm =
|
|
|
|
(void __iomem *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);
|
|
|
|
|
|
|
|
setbits_be32(&gur->devdisr2, FSL_CORENET_DEVDISR2_DTSEC1_6 ||
|
|
|
|
FSL_CORENET_DEVDISR2_DTSEC1_9);
|
|
|
|
setbits_be32(&gur->devdisr3, FSL_CORENET_DEVDISR3_PCIE3);
|
|
|
|
setbits_be32(&gur->devdisr5, FSL_CORENET_DEVDISR5_DDR3);
|
|
|
|
|
|
|
|
/* It needs SW to disable core4~7 as HW design sake on T4080 */
|
|
|
|
for (i = 4; i < 8; i++)
|
|
|
|
cpu_disable(i);
|
|
|
|
|
|
|
|
/* request core4~7 into PH20 state, prior to entering PCL10
|
|
|
|
* state, all cores in cluster should be placed in PH20 state.
|
|
|
|
*/
|
|
|
|
setbits_be32(&rcpm->pcph20setr, 0xf0);
|
|
|
|
|
|
|
|
/* put the 2nd cluster into PCL10 state */
|
|
|
|
setbits_be32(&rcpm->clpcl10setr, 1 << 1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-31 06:38:14 +00:00
|
|
|
if (cpu_numcores() > 1) {
|
2009-09-03 14:12:40 +00:00
|
|
|
#ifndef CONFIG_MP
|
|
|
|
puts("Unicore software on multiprocessor system!!\n"
|
|
|
|
"To enable mutlticore build define CONFIG_MP\n");
|
|
|
|
#endif
|
2010-08-09 23:39:57 +00:00
|
|
|
volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
|
2009-07-31 06:38:14 +00:00
|
|
|
printf("CPU%d: ", pic->whoami);
|
|
|
|
} else {
|
|
|
|
puts("CPU: ");
|
|
|
|
}
|
2008-02-06 07:19:40 +00:00
|
|
|
|
2012-12-13 20:48:48 +00:00
|
|
|
cpu = gd->arch.cpu;
|
2008-02-06 07:19:40 +00:00
|
|
|
|
2009-09-02 08:05:21 +00:00
|
|
|
puts(cpu->name);
|
|
|
|
if (IS_E_PROCESSOR(svr))
|
|
|
|
puts("E");
|
2008-02-06 07:19:40 +00:00
|
|
|
|
2004-06-09 00:34:46 +00:00
|
|
|
printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
|
|
|
|
|
2005-03-15 22:56:53 +00:00
|
|
|
pvr = get_pvr();
|
|
|
|
ver = PVR_VER(pvr);
|
|
|
|
major = PVR_MAJ(pvr);
|
|
|
|
minor = PVR_MIN(pvr);
|
|
|
|
|
|
|
|
printf("Core: ");
|
2011-07-25 14:28:39 +00:00
|
|
|
switch(ver) {
|
|
|
|
case PVR_VER_E500_V1:
|
|
|
|
case PVR_VER_E500_V2:
|
2013-04-21 16:11:02 +00:00
|
|
|
puts("e500");
|
2011-07-25 14:28:39 +00:00
|
|
|
break;
|
|
|
|
case PVR_VER_E500MC:
|
2013-04-21 16:11:02 +00:00
|
|
|
puts("e500mc");
|
2011-07-25 14:28:39 +00:00
|
|
|
break;
|
|
|
|
case PVR_VER_E5500:
|
2013-04-21 16:11:02 +00:00
|
|
|
puts("e5500");
|
2011-07-25 14:28:39 +00:00
|
|
|
break;
|
2012-08-17 08:20:23 +00:00
|
|
|
case PVR_VER_E6500:
|
2013-04-21 16:11:02 +00:00
|
|
|
puts("e6500");
|
2012-08-17 08:20:23 +00:00
|
|
|
break;
|
2011-07-25 14:28:39 +00:00
|
|
|
default:
|
2009-10-21 18:23:54 +00:00
|
|
|
puts("Unknown");
|
2011-07-25 14:28:39 +00:00
|
|
|
break;
|
2005-03-15 22:56:53 +00:00
|
|
|
}
|
2008-10-23 06:47:38 +00:00
|
|
|
|
2005-03-15 22:56:53 +00:00
|
|
|
printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
|
|
|
|
|
2012-10-08 07:44:10 +00:00
|
|
|
if (nr_cores > CONFIG_MAX_CPUS) {
|
|
|
|
panic("\nUnexpected number of cores: %d, max is %d\n",
|
|
|
|
nr_cores, CONFIG_MAX_CPUS);
|
|
|
|
}
|
|
|
|
|
2004-06-09 00:34:46 +00:00
|
|
|
get_sys_info(&sysinfo);
|
|
|
|
|
2014-04-15 06:04:12 +00:00
|
|
|
#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
|
|
|
|
if (sysinfo.diff_sysclk == 1)
|
|
|
|
puts("Single Source Clock Configuration\n");
|
|
|
|
#endif
|
|
|
|
|
2009-02-04 15:35:57 +00:00
|
|
|
puts("Clock Configuration:");
|
2011-08-05 21:15:24 +00:00
|
|
|
for_each_cpu(i, core, nr_cores, mask) {
|
2009-02-18 23:41:08 +00:00
|
|
|
if (!(i & 3))
|
|
|
|
printf ("\n ");
|
2011-08-05 21:15:24 +00:00
|
|
|
printf("CPU%d:%-4s MHz, ", core,
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_processor[core]));
|
2009-02-04 15:35:57 +00:00
|
|
|
}
|
powerpc/mpc85xx: Add DSP side awareness for Freescale Heterogeneous SoCs
The code provides framework for heterogeneous multicore chips based on StarCore
and Power Architecture which are chasis-2 compliant, like B4860 and B4420
It will make u-boot recognize all non-ppc cores and peripherals like
SC3900/DSP CPUs, MAPLE, CPRI and print their configuration in u-boot logs.
Example boot logs of B4860QDS:
U-Boot 2015.01-00232-geef6e36-dirty (Jan 19 2015 - 11:58:45)
CPU0: B4860E, Version: 2.2, (0x86880022)
Core: e6500, Version: 2.0, (0x80400120)
Clock Configuration:
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
CCB:666.667 MHz,
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
CPRI:600 MHz
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz
FMAN1: 666.667 MHz
QMAN: 333.333 MHz
Top level changes include:
(1) Top level CONFIG to identify HETEROGENUOUS clusters
(2) CONFIGS for SC3900/DSP components
(3) Global structures like "cpu_type" and "MPC85xx_SYS_INFO"
updated for dsp cores and other components
(3) APIs to get DSP num cores and their Mask like:
cpu_dsp_mask, cpu_num_dspcores etc same as that of PowerPC
(5) Code to fetch and print SC cores and other heterogenous
device's frequencies
(6) README added for the same
Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
2015-01-19 07:16:54 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_HETROGENOUS_CLUSTERS
|
|
|
|
for_each_cpu(j, dsp_core, dsp_numcores, dsp_mask) {
|
|
|
|
if (!(j & 3))
|
|
|
|
printf("\n ");
|
|
|
|
printf("DSP CPU%d:%-4s MHz, ", j,
|
|
|
|
strmhz(buf1, sysinfo.freq_processor_dsp[dsp_core]));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-08-16 09:22:26 +00:00
|
|
|
printf("\n CCB:%-4s MHz,", strmhz(buf1, sysinfo.freq_systembus));
|
|
|
|
printf("\n");
|
2008-05-29 06:21:24 +00:00
|
|
|
|
2009-03-19 07:46:19 +00:00
|
|
|
#ifdef CONFIG_FSL_CORENET
|
|
|
|
if (ddr_sync == 1) {
|
|
|
|
printf(" DDR:%-4s MHz (%s MT/s data rate) "
|
|
|
|
"(Synchronous), ",
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_ddrbus/2),
|
|
|
|
strmhz(buf2, sysinfo.freq_ddrbus));
|
2009-03-19 07:46:19 +00:00
|
|
|
} else {
|
|
|
|
printf(" DDR:%-4s MHz (%s MT/s data rate) "
|
|
|
|
"(Asynchronous), ",
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_ddrbus/2),
|
|
|
|
strmhz(buf2, sysinfo.freq_ddrbus));
|
2009-03-19 07:46:19 +00:00
|
|
|
}
|
|
|
|
#else
|
2007-12-07 10:59:26 +00:00
|
|
|
switch (ddr_ratio) {
|
|
|
|
case 0x0:
|
2008-10-19 00:35:49 +00:00
|
|
|
printf(" DDR:%-4s MHz (%s MT/s data rate), ",
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_ddrbus/2),
|
|
|
|
strmhz(buf2, sysinfo.freq_ddrbus));
|
2007-12-07 10:59:26 +00:00
|
|
|
break;
|
|
|
|
case 0x7:
|
2009-03-19 07:46:19 +00:00
|
|
|
printf(" DDR:%-4s MHz (%s MT/s data rate) "
|
|
|
|
"(Synchronous), ",
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_ddrbus/2),
|
|
|
|
strmhz(buf2, sysinfo.freq_ddrbus));
|
2007-12-07 10:59:26 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-03-19 07:46:19 +00:00
|
|
|
printf(" DDR:%-4s MHz (%s MT/s data rate) "
|
|
|
|
"(Asynchronous), ",
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_ddrbus/2),
|
|
|
|
strmhz(buf2, sysinfo.freq_ddrbus));
|
2007-12-07 10:59:26 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-03-19 07:46:19 +00:00
|
|
|
#endif
|
2004-06-09 00:34:46 +00:00
|
|
|
|
2011-01-19 07:16:27 +00:00
|
|
|
#if defined(CONFIG_FSL_LBC)
|
2013-08-16 09:22:26 +00:00
|
|
|
if (sysinfo.freq_localbus > LCRR_CLKDIV) {
|
|
|
|
printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
|
2009-03-19 07:46:19 +00:00
|
|
|
} else {
|
mpc8[56]xx: Put localbus clock in sysinfo and gd
Currently MPC85xx and MPC86xx boards just calculate the localbus frequency
and print it out, but don't save it.
This changes where its calculated and stored to be more consistent with the
CPU, CCB, TB, and DDR frequencies and the MPC83xx localbus clock.
The localbus frequency is added to sysinfo and calculated when sysinfo is
set up, in cpu/mpc8[56]xx/speed.c, the same as the other frequencies are.
get_clocks() copies the frequency into the global data, as the other
frequencies are, into a new field that is only enabled for MPC85xx and
MPC86xx.
checkcpu() in cpu/mpc8[56]xx/cpu.c will print out the local bus frequency
from sysinfo, like the other frequencies, instead of calculating it on the
spot.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Jon Loeliger <jdl@freescale.com>
2008-12-03 23:16:37 +00:00
|
|
|
printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n",
|
2013-08-16 09:22:26 +00:00
|
|
|
sysinfo.freq_localbus);
|
2009-03-19 07:46:19 +00:00
|
|
|
}
|
2011-01-19 07:16:27 +00:00
|
|
|
#endif
|
2003-10-15 23:53:47 +00:00
|
|
|
|
2012-10-08 07:44:06 +00:00
|
|
|
#if defined(CONFIG_FSL_IFC)
|
2013-08-16 09:22:26 +00:00
|
|
|
printf("IFC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
|
2012-10-08 07:44:06 +00:00
|
|
|
#endif
|
|
|
|
|
2008-02-06 07:19:40 +00:00
|
|
|
#ifdef CONFIG_CPM2
|
2013-08-16 09:22:26 +00:00
|
|
|
printf("CPM: %s MHz\n", strmhz(buf1, sysinfo.freq_systembus));
|
2008-02-06 07:19:40 +00:00
|
|
|
#endif
|
2004-06-09 00:34:46 +00:00
|
|
|
|
2009-05-20 16:30:29 +00:00
|
|
|
#ifdef CONFIG_QE
|
2013-08-16 09:22:26 +00:00
|
|
|
printf(" QE:%-4s MHz\n", strmhz(buf1, sysinfo.freq_qe));
|
2009-05-20 16:30:29 +00:00
|
|
|
#endif
|
|
|
|
|
powerpc/mpc85xx: Add DSP side awareness for Freescale Heterogeneous SoCs
The code provides framework for heterogeneous multicore chips based on StarCore
and Power Architecture which are chasis-2 compliant, like B4860 and B4420
It will make u-boot recognize all non-ppc cores and peripherals like
SC3900/DSP CPUs, MAPLE, CPRI and print their configuration in u-boot logs.
Example boot logs of B4860QDS:
U-Boot 2015.01-00232-geef6e36-dirty (Jan 19 2015 - 11:58:45)
CPU0: B4860E, Version: 2.2, (0x86880022)
Core: e6500, Version: 2.0, (0x80400120)
Clock Configuration:
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
CCB:666.667 MHz,
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
CPRI:600 MHz
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz
FMAN1: 666.667 MHz
QMAN: 333.333 MHz
Top level changes include:
(1) Top level CONFIG to identify HETEROGENUOUS clusters
(2) CONFIGS for SC3900/DSP components
(3) Global structures like "cpu_type" and "MPC85xx_SYS_INFO"
updated for dsp cores and other components
(3) APIs to get DSP num cores and their Mask like:
cpu_dsp_mask, cpu_num_dspcores etc same as that of PowerPC
(5) Code to fetch and print SC cores and other heterogenous
device's frequencies
(6) README added for the same
Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
2015-01-19 07:16:54 +00:00
|
|
|
#if defined(CONFIG_SYS_CPRI)
|
|
|
|
printf(" ");
|
|
|
|
printf("CPRI:%-4s MHz", strmhz(buf1, sysinfo.freq_cpri));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_SYS_MAPLE)
|
|
|
|
printf("\n ");
|
|
|
|
printf("MAPLE:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple));
|
|
|
|
printf("MAPLE-ULB:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple_ulb));
|
|
|
|
printf("MAPLE-eTVPE:%-4s MHz\n",
|
|
|
|
strmhz(buf1, sysinfo.freq_maple_etvpe));
|
|
|
|
#endif
|
|
|
|
|
2009-03-19 07:46:19 +00:00
|
|
|
#ifdef CONFIG_SYS_DPAA_FMAN
|
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) {
|
2010-06-17 05:08:29 +00:00
|
|
|
printf(" FMAN%d: %s MHz\n", i + 1,
|
2013-08-16 09:22:26 +00:00
|
|
|
strmhz(buf1, sysinfo.freq_fman[i]));
|
2009-03-19 07:46:19 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-10-11 07:13:39 +00:00
|
|
|
#ifdef CONFIG_SYS_DPAA_QBMAN
|
2013-08-16 09:22:26 +00:00
|
|
|
printf(" QMAN: %s MHz\n", strmhz(buf1, sysinfo.freq_qman));
|
2012-10-11 07:13:39 +00:00
|
|
|
#endif
|
|
|
|
|
2009-03-19 07:46:19 +00:00
|
|
|
#ifdef CONFIG_SYS_DPAA_PME
|
2013-08-16 09:22:26 +00:00
|
|
|
printf(" PME: %s MHz\n", strmhz(buf1, sysinfo.freq_pme));
|
2009-03-19 07:46:19 +00:00
|
|
|
#endif
|
|
|
|
|
2013-08-15 16:25:38 +00:00
|
|
|
puts("L1: D-cache 32 KiB enabled\n I-cache 32 KiB enabled\n");
|
2003-10-15 23:53:47 +00:00
|
|
|
|
2013-06-25 18:37:43 +00:00
|
|
|
#ifdef CONFIG_FSL_CORENET
|
|
|
|
/* Display the RCW, so that no one gets confused as to what RCW
|
|
|
|
* we're actually using for this boot.
|
|
|
|
*/
|
|
|
|
puts("Reset Configuration Word (RCW):");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
|
|
|
|
u32 rcw = in_be32(&gur->rcwsr[i]);
|
|
|
|
|
|
|
|
if ((i % 4) == 0)
|
|
|
|
printf("\n %08x:", i * 4);
|
|
|
|
printf(" %08x", rcw);
|
|
|
|
}
|
|
|
|
puts("\n");
|
|
|
|
#endif
|
|
|
|
|
2003-10-15 23:53:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
2020-05-10 17:40:03 +00:00
|
|
|
int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
2003-10-15 23:53:47 +00:00
|
|
|
{
|
2009-09-08 18:46:46 +00:00
|
|
|
/* Everything after the first generation of PQ3 parts has RSTCR */
|
2021-05-15 01:34:21 +00:00
|
|
|
#if defined(CONFIG_ARCH_MPC8540) || defined(CONFIG_ARCH_MPC8560)
|
2008-05-08 12:17:08 +00:00
|
|
|
unsigned long val, msr;
|
|
|
|
|
2003-10-15 23:53:47 +00:00
|
|
|
/*
|
|
|
|
* Initiate hard reset in debug control register DBCR0
|
2009-09-08 18:46:46 +00:00
|
|
|
* Make sure MSR[DE] = 1. This only resets the core.
|
2003-10-15 23:53:47 +00:00
|
|
|
*/
|
2008-05-08 12:17:08 +00:00
|
|
|
msr = mfmsr ();
|
|
|
|
msr |= MSR_DE;
|
|
|
|
mtmsr (msr);
|
|
|
|
|
|
|
|
val = mfspr(DBCR0);
|
|
|
|
val |= 0x70000000;
|
|
|
|
mtspr(DBCR0,val);
|
2009-09-08 18:46:46 +00:00
|
|
|
#else
|
|
|
|
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
2011-11-21 21:20:32 +00:00
|
|
|
|
|
|
|
/* Attempt board-specific reset */
|
|
|
|
board_reset();
|
|
|
|
|
|
|
|
/* Next try asserting HRESET_REQ */
|
|
|
|
out_be32(&gur->rstcr, 0x2);
|
2009-09-08 18:46:46 +00:00
|
|
|
udelay(100);
|
|
|
|
#endif
|
2007-09-24 17:32:13 +00:00
|
|
|
|
2003-10-15 23:53:47 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get timebase clock frequency
|
|
|
|
*/
|
2011-02-18 11:40:54 +00:00
|
|
|
#ifndef CONFIG_SYS_FSL_TBCLK_DIV
|
|
|
|
#define CONFIG_SYS_FSL_TBCLK_DIV 8
|
|
|
|
#endif
|
2019-12-28 17:44:59 +00:00
|
|
|
__weak unsigned long get_tbclk(void)
|
2003-10-15 23:53:47 +00:00
|
|
|
{
|
2011-02-18 11:40:54 +00:00
|
|
|
unsigned long tbclk_div = CONFIG_SYS_FSL_TBCLK_DIV;
|
|
|
|
|
|
|
|
return (gd->bus_clk + (tbclk_div >> 1)) / tbclk_div;
|
2003-10-15 23:53:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_WATCHDOG)
|
2014-06-03 07:05:14 +00:00
|
|
|
#define WATCHDOG_MASK (TCR_WP(63) | TCR_WRC(3) | TCR_WIE)
|
|
|
|
void
|
|
|
|
init_85xx_watchdog(void)
|
|
|
|
{
|
|
|
|
mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WATCHDOG_MASK) |
|
|
|
|
TCR_WP(CONFIG_WATCHDOG_PRESC) | TCR_WRC(CONFIG_WATCHDOG_RC));
|
|
|
|
}
|
|
|
|
|
2003-10-15 23:53:47 +00:00
|
|
|
void
|
|
|
|
reset_85xx_watchdog(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Clear TSR(WIS) bit by writing 1
|
|
|
|
*/
|
2012-09-09 23:06:03 +00:00
|
|
|
mtspr(SPRN_TSR, TSR_WIS);
|
2003-10-15 23:53:47 +00:00
|
|
|
}
|
2013-03-13 10:14:05 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
watchdog_reset(void)
|
|
|
|
{
|
|
|
|
int re_enable = disable_interrupts();
|
|
|
|
|
|
|
|
reset_85xx_watchdog();
|
|
|
|
if (re_enable)
|
|
|
|
enable_interrupts();
|
|
|
|
}
|
2003-10-15 23:53:47 +00:00
|
|
|
#endif /* CONFIG_WATCHDOG */
|
|
|
|
|
2008-10-30 21:51:33 +00:00
|
|
|
/*
|
|
|
|
* Initializes on-chip MMC controllers.
|
|
|
|
* to override, implement board_mmc_init()
|
|
|
|
*/
|
2020-06-26 06:13:33 +00:00
|
|
|
int cpu_mmc_init(struct bd_info *bis)
|
2008-10-30 21:51:33 +00:00
|
|
|
{
|
|
|
|
#ifdef CONFIG_FSL_ESDHC
|
|
|
|
return fsl_esdhc_mmc_init(bis);
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
2010-06-17 16:37:25 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Print out the state of various machine registers.
|
2011-01-20 10:59:35 +00:00
|
|
|
* Currently prints out LAWs, BR0/OR0 for LBC, CSPR/CSOR/Timing
|
|
|
|
* parameters for IFC and TLBs
|
2010-06-17 16:37:25 +00:00
|
|
|
*/
|
2017-07-13 13:09:54 +00:00
|
|
|
void print_reginfo(void)
|
2010-06-17 16:37:25 +00:00
|
|
|
{
|
|
|
|
print_tlbcam();
|
2021-02-25 09:22:27 +00:00
|
|
|
#ifdef CONFIG_FSL_LAW
|
2010-06-17 16:37:25 +00:00
|
|
|
print_laws();
|
2021-02-25 09:22:27 +00:00
|
|
|
#endif
|
2011-01-19 07:16:27 +00:00
|
|
|
#if defined(CONFIG_FSL_LBC)
|
2010-06-17 16:37:25 +00:00
|
|
|
print_lbc_regs();
|
2011-01-19 07:16:27 +00:00
|
|
|
#endif
|
2011-01-20 10:59:35 +00:00
|
|
|
#ifdef CONFIG_FSL_IFC
|
|
|
|
print_ifc_regs();
|
|
|
|
#endif
|
2011-01-19 07:16:27 +00:00
|
|
|
|
2010-06-17 16:37:25 +00:00
|
|
|
}
|
2010-09-28 22:20:33 +00:00
|
|
|
|
2010-12-17 23:17:56 +00:00
|
|
|
/* Common ddr init for non-corenet fsl 85xx platforms */
|
|
|
|
#ifndef CONFIG_FSL_CORENET
|
2012-09-21 00:02:18 +00:00
|
|
|
#if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \
|
|
|
|
!defined(CONFIG_SYS_INIT_L2_ADDR)
|
2017-04-06 18:47:05 +00:00
|
|
|
int dram_init(void)
|
2011-01-28 09:58:37 +00:00
|
|
|
{
|
2014-04-11 15:09:45 +00:00
|
|
|
#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD) || \
|
2016-11-18 20:29:51 +00:00
|
|
|
defined(CONFIG_ARCH_QEMU_E500)
|
2017-03-31 14:40:25 +00:00
|
|
|
gd->ram_size = fsl_ddr_sdram_size();
|
2011-01-28 09:58:37 +00:00
|
|
|
#else
|
2017-03-31 14:40:25 +00:00
|
|
|
gd->ram_size = (phys_size_t)CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
|
2011-01-28 09:58:37 +00:00
|
|
|
#endif
|
2017-03-31 14:40:25 +00:00
|
|
|
|
|
|
|
return 0;
|
2011-01-28 09:58:37 +00:00
|
|
|
}
|
|
|
|
#else /* CONFIG_SYS_RAMBOOT */
|
2017-04-06 18:47:05 +00:00
|
|
|
int dram_init(void)
|
2010-12-17 23:17:56 +00:00
|
|
|
{
|
|
|
|
phys_size_t dram_size = 0;
|
|
|
|
|
2010-12-17 23:17:58 +00:00
|
|
|
#if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN)
|
2010-12-17 23:17:56 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
|
2011-06-07 01:42:16 +00:00
|
|
|
#if defined(CONFIG_SPD_EEPROM) || \
|
|
|
|
defined(CONFIG_DDR_SPD) || \
|
|
|
|
defined(CONFIG_SYS_DDR_RAW_TIMING)
|
2010-12-17 23:17:56 +00:00
|
|
|
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
|
|
|
|
|
2011-01-19 07:16:27 +00:00
|
|
|
#if defined(CONFIG_FSL_LBC)
|
2010-12-17 23:17:56 +00:00
|
|
|
/* Some boards also have sdram on the lbc */
|
2010-12-17 23:17:57 +00:00
|
|
|
lbc_sdram_init();
|
2011-01-19 07:16:27 +00:00
|
|
|
#endif
|
2010-12-17 23:17:56 +00:00
|
|
|
|
2011-07-25 08:13:53 +00:00
|
|
|
debug("DDR: ");
|
2017-03-31 14:40:25 +00:00
|
|
|
gd->ram_size = dram_size;
|
|
|
|
|
|
|
|
return 0;
|
2010-12-17 23:17:56 +00:00
|
|
|
}
|
2011-01-28 09:58:37 +00:00
|
|
|
#endif /* CONFIG_SYS_RAMBOOT */
|
2010-12-17 23:17:56 +00:00
|
|
|
#endif
|
|
|
|
|
2010-09-28 22:20:33 +00:00
|
|
|
#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,
|
2014-08-01 22:51:00 +00:00
|
|
|
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
|
2010-09-28 22:20:33 +00:00
|
|
|
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);
|
|
|
|
|
2011-07-18 23:49:15 +00:00
|
|
|
void clear_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);
|
|
|
|
|
2010-09-28 22:20:33 +00:00
|
|
|
static void dump_spd_ddr_reg(void)
|
|
|
|
{
|
|
|
|
int i, j, k, m;
|
|
|
|
u8 *p_8;
|
|
|
|
u32 *p_32;
|
2016-12-28 16:43:45 +00:00
|
|
|
struct ccsr_ddr __iomem *ddr[CONFIG_SYS_NUM_DDR_CTLRS];
|
2010-09-28 22:20:33 +00:00
|
|
|
generic_spd_eeprom_t
|
2016-12-28 16:43:45 +00:00
|
|
|
spd[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR];
|
2010-09-28 22:20:33 +00:00
|
|
|
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++)
|
2014-08-01 22:51:00 +00:00
|
|
|
fsl_ddr_get_spd(spd[i], i, CONFIG_DIMM_SLOTS_PER_CTLR);
|
2010-09-28 22:20:33 +00:00
|
|
|
|
2016-09-07 18:27:59 +00:00
|
|
|
puts("SPD data of all dimms (zero value is omitted)...\n");
|
2010-09-28 22:20:33 +00:00
|
|
|
puts("Byte (hex) ");
|
|
|
|
k = 1;
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
|
2010-09-28 22:20:33 +00:00
|
|
|
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);
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
|
2010-09-28 22:20:33 +00:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
|
2010-09-28 22:20:33 +00:00
|
|
|
switch (i) {
|
|
|
|
case 0:
|
2013-09-30 16:22:09 +00:00
|
|
|
ddr[i] = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
2010-09-28 22:20:33 +00:00
|
|
|
break;
|
2016-12-28 16:43:45 +00:00
|
|
|
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
|
2010-09-28 22:20:33 +00:00
|
|
|
case 1:
|
2013-09-30 16:22:09 +00:00
|
|
|
ddr[i] = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
|
2010-09-28 22:20:33 +00:00
|
|
|
break;
|
2012-08-17 08:22:39 +00:00
|
|
|
#endif
|
2016-12-28 16:43:45 +00:00
|
|
|
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
|
2012-08-17 08:22:39 +00:00
|
|
|
case 2:
|
2013-09-30 16:22:09 +00:00
|
|
|
ddr[i] = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
|
2012-08-17 08:22:39 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2016-12-28 16:43:45 +00:00
|
|
|
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
|
2012-08-17 08:22:39 +00:00
|
|
|
case 3:
|
2013-09-30 16:22:09 +00:00
|
|
|
ddr[i] = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
|
2012-08-17 08:22:39 +00:00
|
|
|
break;
|
2010-09-28 22:20:33 +00:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
printf("%s unexpected controller number = %u\n",
|
|
|
|
__func__, i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("DDR registers dump for all controllers "
|
2016-09-07 18:27:59 +00:00
|
|
|
"(zero value is omitted)...\n");
|
2010-09-28 22:20:33 +00:00
|
|
|
puts("Offset (hex) ");
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++)
|
2010-09-28 22:20:33 +00:00
|
|
|
printf(" Base + 0x%04x", (u32)ddr[i] & 0xFFFF);
|
|
|
|
puts("\n");
|
2013-11-18 18:29:32 +00:00
|
|
|
for (k = 0; k < sizeof(struct ccsr_ddr)/4; k++) {
|
2010-09-28 22:20:33 +00:00
|
|
|
m = 0;
|
|
|
|
printf("%6d (0x%04x)", k * 4, k * 4);
|
2016-12-28 16:43:45 +00:00
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
|
2010-09-28 22:20:33 +00:00
|
|
|
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;
|
|
|
|
|
2011-07-18 23:49:15 +00:00
|
|
|
clear_ddr_tlbs_phys(p_addr, size>>20);
|
2010-09-28 22:20:33 +00:00
|
|
|
|
|
|
|
/* 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
|