diff options
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu.c | 9 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/mp.c | 27 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/speed.c | 7 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc8xxx/cpu.c | 36 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc8xxx/fdt.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/processor.h | 6 | ||||
| -rw-r--r-- | common/cmd_mp.c | 5 | ||||
| -rw-r--r-- | include/common.h | 15 | 
8 files changed, 78 insertions, 29 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 22fa4615c..f51829e0f 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -64,7 +64,8 @@ int checkcpu (void)  	u32 ddr_ratio = 0;  #endif /* CONFIG_FSL_CORENET */  #endif /* CONFIG_DDR_CLK_FREQ */ -	int i; +	unsigned int i, core, nr_cores = cpu_numcores(); +	u32 mask = cpu_mask();  	svr = get_svr();  	major = SVR_MAJ(svr); @@ -119,11 +120,11 @@ int checkcpu (void)  	get_sys_info(&sysinfo);  	puts("Clock Configuration:"); -	for (i = 0; i < cpu_numcores(); i++) { +	for_each_cpu(i, core, nr_cores, mask) {  		if (!(i & 3))  			printf ("\n       "); -		printf("CPU%d:%-4s MHz, ", -				i,strmhz(buf1, sysinfo.freqProcessor[i])); +		printf("CPU%d:%-4s MHz, ", core, +			strmhz(buf1, sysinfo.freqProcessor[core]));  	}  	printf("\n       CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus)); diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 758e6d704..ffc2a9ad6 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -221,14 +221,14 @@ ulong get_spin_virt_addr(void)  #ifdef CONFIG_FSL_CORENET  static void plat_mp_up(unsigned long bootpg)  { -	u32 up, cpu_up_mask, whoami; +	u32 cpu_up_mask, whoami;  	u32 *table = (u32 *)get_spin_virt_addr();  	volatile ccsr_gur_t *gur;  	volatile ccsr_local_t *ccm;  	volatile ccsr_rcpm_t *rcpm;  	volatile ccsr_pic_t *pic;  	int timeout = 10; -	u32 nr_cpus; +	u32 mask = cpu_mask();  	struct law_entry e;  	gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -236,8 +236,6 @@ static void plat_mp_up(unsigned long bootpg)  	rcpm = (void *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);  	pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); -	nr_cpus = ((in_be32(&pic->frr) >> 8) & 0xff) + 1; -  	whoami = in_be32(&pic->whoami);  	cpu_up_mask = 1 << whoami;  	out_be32(&ccm->bstrl, bootpg); @@ -251,19 +249,18 @@ static void plat_mp_up(unsigned long bootpg)  	/* disable time base at the platform */  	out_be32(&rcpm->ctbenrl, cpu_up_mask); -	/* release the hounds */ -	up = ((1 << nr_cpus) - 1); -	out_be32(&gur->brrl, up); +	out_be32(&gur->brrl, mask);  	/* wait for everyone */  	while (timeout) { -		int i; -		for (i = 0; i < nr_cpus; i++) { -			if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER]) -				cpu_up_mask |= (1 << i); -		}; +		unsigned int i, cpu, nr_cpus = cpu_numcores(); -		if ((cpu_up_mask & up) == up) +		for_each_cpu(i, cpu, nr_cpus, mask) { +			if (table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER]) +				cpu_up_mask |= (1 << cpu); +		} + +		if ((cpu_up_mask & mask) == mask)  			break;  		udelay(100); @@ -272,7 +269,7 @@ static void plat_mp_up(unsigned long bootpg)  	if (timeout == 0)  		printf("CPU up timeout. CPU up mask is %x should be %x\n", -			cpu_up_mask, up); +			cpu_up_mask, mask);  	/* enable time base at the platform */  	out_be32(&rcpm->ctbenrl, 0); @@ -283,7 +280,7 @@ static void plat_mp_up(unsigned long bootpg)  	mtspr(SPRN_TBWU, 0);  	mtspr(SPRN_TBWL, 0); -	out_be32(&rcpm->ctbenrl, (1 << nr_cpus) - 1); +	out_be32(&rcpm->ctbenrl, mask);  #ifdef CONFIG_MPC8xxx_DISABLE_BPTR  	/* diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index a83dfeb84..ce4753245 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -41,6 +41,7 @@ void get_sys_info (sys_info_t * sysInfo)  	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  #ifdef CONFIG_FSL_CORENET  	volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR); +	unsigned int cpu;  	const u8 core_cplx_PLL[16] = {  		[ 0] = 0,	/* CC1 PPL / 1 */ @@ -97,11 +98,11 @@ void get_sys_info (sys_info_t * sysInfo)  			freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i];  	}  	rcw_tmp = in_be32(&gur->rcwsr[3]); -	for (i = 0; i < cpu_numcores(); i++) { -		u32 c_pll_sel = (in_be32(&clk->clkc0csr + i*8) >> 27) & 0xf; +	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { +		u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf;  		u32 cplx_pll = core_cplx_PLL[c_pll_sel]; -		sysInfo->freqProcessor[i] = +		sysInfo->freqProcessor[cpu] =  			 freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel];  	} diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 767bc524d..bb572cfff 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -129,13 +129,33 @@ struct cpu_type *identify_cpu(u32 ver)  	return &cpu_type_unknown;  } +#define MPC8xxx_PICFRR_NCPU_MASK  0x00001f00 +#define MPC8xxx_PICFRR_NCPU_SHIFT 8 + +/* + * Return a 32-bit mask indicating which cores are present on this SOC. + */ +u32 cpu_mask() +{ +	ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; +	struct cpu_type *cpu = gd->cpu; + +	/* better to query feature reporting register than just assume 1 */ +	if (cpu == &cpu_type_unknown) +	return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> +			MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + +	return cpu->mask; +} + +/* + * Return the number of cores on this SOC. + */  int cpu_numcores() {  	ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR;  	struct cpu_type *cpu = gd->cpu;  	/* better to query feature reporting register than just assume 1 */ -#define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 -#define MPC8xxx_PICFRR_NCPU_SHIFT 8  	if (cpu == &cpu_type_unknown)  		return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >>  			MPC8xxx_PICFRR_NCPU_SHIFT) + 1; @@ -143,6 +163,18 @@ int cpu_numcores() {  	return cpu->num_cores;  } +/* + * Check if the given core ID is valid + * + * Returns zero if it isn't, 1 if it is. + */ +int is_core_valid(unsigned int core) +{ +	struct cpu_type *cpu = gd->cpu; + +	return !!((1 << core) & cpu->mask); +} +  int probecpu (void)  {  	uint svr; diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 285051d96..5bb9f5354 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -63,7 +63,7 @@ void ft_fixup_num_cores(void *blob) {  	while (off != -FDT_ERR_NOTFOUND) {  		u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); -		if ((*reg > num_cores-1) || (is_core_disabled(*reg))) { +		if (!is_core_valid(*reg) || is_core_disabled(*reg)) {  			int ph = fdt_get_phandle(blob, off);  			/* Delete the cpu node once there are no cpu handles */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 0c4cc2554..50af6e7fc 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1176,13 +1176,17 @@ struct cpu_type {  	char name[15];  	u32 soc_ver;  	u32 num_cores; +	u32 mask;	/* which cpu(s) actually exist */  };  struct cpu_type *identify_cpu(u32 ver);  #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)  #define CPU_TYPE_ENTRY(n, v, nc) \ -	{ .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), } +	{ .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), \ +	  .mask = (1 << (nc)) - 1 } +#define CPU_TYPE_ENTRY_MASK(n, v, nc, m) \ +	{ .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), .mask = (m) }  #else  #if defined(CONFIG_MPC83xx)  #define CPU_TYPE_ENTRY(x) {#x, SPR_##x} diff --git a/common/cmd_mp.c b/common/cmd_mp.c index f19bf41f8..b115b5913 100644 --- a/common/cmd_mp.c +++ b/common/cmd_mp.c @@ -32,9 +32,8 @@ cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		return cmd_usage(cmdtp);  	cpuid = simple_strtoul(argv[1], NULL, 10); -	if (cpuid >= cpu_numcores()) { -		printf ("Core num: %lu is out of range[0..%d]\n", -				cpuid, cpu_numcores() - 1); +	if (!is_core_valid(cpuid)) { +		printf ("Core num: %lu is not valid\n",	cpuid);  		return 1;  	} diff --git a/include/common.h b/include/common.h index d244bd40b..05e2f728e 100644 --- a/include/common.h +++ b/include/common.h @@ -485,7 +485,22 @@ void ddr_enable_ecc(unsigned int dram_size);  #endif  /* $(CPU)/cpu.c */ +static inline int cpumask_next(int cpu, unsigned int mask) +{ +	for (cpu++; !((1 << cpu) & mask); cpu++) +		; + +	return cpu; +} + +#define for_each_cpu(iter, cpu, num_cpus, mask) \ +	for (iter = 0, cpu = cpumask_next(-1, mask); \ +		iter < num_cpus; \ +		iter++, cpu = cpumask_next(cpu, mask)) \ +  int	cpu_numcores  (void); +u32	cpu_mask      (void); +int	is_core_valid (unsigned int);  int	probecpu      (void);  int	checkcpu      (void);  int	checkicache   (void); |