diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx')
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/fdt.c | 22 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/mp.c | 31 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/mp.h | 1 | 
3 files changed, 51 insertions, 3 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 45403641c..53e059655 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -48,6 +48,7 @@ void ft_fixup_cpu(void *blob, u64 memory_limit)  	ulong spin_tbl_addr = get_spin_phys_addr();  	u32 bootpg = determine_mp_bootpg();  	u32 id = get_my_id(); +	const char *enable_method;  	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);  	while (off != -FDT_ERR_NOTFOUND) { @@ -63,10 +64,25 @@ void ft_fixup_cpu(void *blob, u64 memory_limit)  				fdt_setprop_string(blob, off, "status",  								"disabled");  			} + +			if (hold_cores_in_reset(0)) { +#ifdef CONFIG_FSL_CORENET +				/* Cores held in reset, use BRR to release */ +				enable_method = "fsl,brr-holdoff"; +#else +				/* Cores held in reset, use EEBPCR to release */ +				enable_method = "fsl,eebpcr-holdoff"; +#endif +			} else { +				/* Cores out of reset and in a spin-loop */ +				enable_method = "spin-table"; + +				fdt_setprop(blob, off, "cpu-release-addr", +						&val, sizeof(val)); +			} +  			fdt_setprop_string(blob, off, "enable-method", -							"spin-table"); -			fdt_setprop(blob, off, "cpu-release-addr", -					&val, sizeof(val)); +							enable_method);  		} else {  			printf ("cpu NULL\n");  		} diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 603baef1b..a019b1bdb 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -36,6 +36,27 @@ u32 get_my_id()  	return mfspr(SPRN_PIR);  } +/* + * Determine if U-Boot should keep secondary cores in reset, or let them out + * of reset and hold them in a spinloop + */ +int hold_cores_in_reset(int verbose) +{ +	const char *s = getenv("mp_holdoff"); + +	/* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */ +	if (s && (*s == 'y' || *s == 'Y' || *s == '1')) { +		if (verbose) { +			puts("Secondary cores are being held in reset.\n"); +			puts("See 'mp_holdoff' environment variable\n"); +		} + +		return 1; +	} + +	return 0; +} +  int cpu_reset(int nr)  {  	volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); @@ -51,6 +72,9 @@ int cpu_status(int nr)  {  	u32 *table, id = get_my_id(); +	if (hold_cores_in_reset(1)) +		return 0; +  	if (nr == id) {  		table = (u32 *)get_spin_virt_addr();  		printf("table base @ 0x%p\n", table); @@ -133,6 +157,9 @@ int cpu_release(int nr, int argc, char * const argv[])  	u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;  	u64 boot_addr; +	if (hold_cores_in_reset(1)) +		return 0; +  	if (nr == get_my_id()) {  		printf("Invalid to release the boot core.\n\n");  		return 1; @@ -353,6 +380,10 @@ void setup_mp(void)  	ulong fixup = (ulong)&__secondary_start_page;  	u32 bootpg = determine_mp_bootpg(); +	/* Some OSes expect secondary cores to be held in reset */ +	if (hold_cores_in_reset(0)) +		return; +  	/* Store the bootpg's SDRAM address for use by secondary CPU cores */  	__bootpg_addr = bootpg; diff --git a/arch/powerpc/cpu/mpc85xx/mp.h b/arch/powerpc/cpu/mpc85xx/mp.h index 3422cc107..87bac3715 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.h +++ b/arch/powerpc/cpu/mpc85xx/mp.h @@ -6,6 +6,7 @@  ulong get_spin_phys_addr(void);  ulong get_spin_virt_addr(void);  u32 get_my_id(void); +int hold_cores_in_reset(int verbose);  #define BOOT_ENTRY_ADDR_UPPER	0  #define BOOT_ENTRY_ADDR_LOWER	1 |