diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/fdt.c')
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/fdt.c | 98 | 
1 files changed, 90 insertions, 8 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 812bb3f87..8f13cd8eb 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -228,6 +228,12 @@ static inline void ft_fixup_l2cache(void *blob)  	u32 *ph;  	u32 l2cfg0 = mfspr(SPRN_L2CFG0);  	u32 size, line_size, num_ways, num_sets; +	int has_l2 = 1; + +	/* P2040/P2040E has no L2, so dont set any L2 props */ +	if ((SVR_SOC_VER(get_svr()) == SVR_P2040) || +	    (SVR_SOC_VER(get_svr()) == SVR_P2040_E)) +		has_l2 = 0;  	size = (l2cfg0 & 0x3fff) * 64 * 1024;  	num_ways = ((l2cfg0 >> 14) & 0x1f) + 1; @@ -250,21 +256,22 @@ static inline void ft_fixup_l2cache(void *blob)  			goto next;  		} +		if (has_l2) {  #ifdef CONFIG_SYS_CACHE_STASHING -		{  			u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);  			if (reg)  				fdt_setprop_cell(blob, l2_off, "cache-stash-id",  					 (*reg * 2) + 32 + 1); -		}  #endif -		fdt_setprop(blob, l2_off, "cache-unified", NULL, 0); -		fdt_setprop_cell(blob, l2_off, "cache-block-size", line_size); -		fdt_setprop_cell(blob, l2_off, "cache-size", size); -		fdt_setprop_cell(blob, l2_off, "cache-sets", num_sets); -		fdt_setprop_cell(blob, l2_off, "cache-level", 2); -		fdt_setprop(blob, l2_off, "compatible", "cache", 6); +			fdt_setprop(blob, l2_off, "cache-unified", NULL, 0); +			fdt_setprop_cell(blob, l2_off, "cache-block-size", +						line_size); +			fdt_setprop_cell(blob, l2_off, "cache-size", size); +			fdt_setprop_cell(blob, l2_off, "cache-sets", num_sets); +			fdt_setprop_cell(blob, l2_off, "cache-level", 2); +			fdt_setprop(blob, l2_off, "compatible", "cache", 6); +		}  		if (l3_off < 0) {  			ph = (u32 *)fdt_getprop(blob, l2_off, "next-level-cache", 0); @@ -628,4 +635,79 @@ void ft_cpu_setup(void *blob, bd_t *bd)  	 */  	do_fixup_by_compat_u32(blob, "fsl,gianfar-ptp-timer",  			"timer-frequency", gd->bus_clk/2, 1); + +	do_fixup_by_compat_u32(blob, "fsl,flexcan-v1.0", +			"clock_freq", gd->bus_clk, 1); +} + +/* + * For some CCSR devices, we only have the virtual address, not the physical + * address.  This is because we map CCSR as a whole, so we typically don't need + * a macro for the physical address of any device within CCSR.  In this case, + * we calculate the physical address of that device using it's the difference + * between the virtual address of the device and the virtual address of the + * beginning of CCSR. + */ +#define CCSR_VIRT_TO_PHYS(x) \ +	(CONFIG_SYS_CCSRBAR_PHYS + ((x) - CONFIG_SYS_CCSRBAR)) + +/* + * Verify the device tree + * + * This function compares several CONFIG_xxx macros that contain physical + * addresses with the corresponding nodes in the device tree, to see if + * the physical addresses are all correct.  For example, if + * CONFIG_SYS_NS16550_COM1 is defined, then it contains the virtual address + * of the first UART.  We convert this to a physical address and compare + * that with the physical address of the first ns16550-compatible node + * in the device tree.  If they don't match, then we display a warning. + * + * Returns 1 on success, 0 on failure + */ +int ft_verify_fdt(void *fdt) +{ +	uint64_t ccsr = 0; +	int aliases; +	int off; + +	/* First check the CCSR base address */ +	off = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "soc", 4); +	if (off > 0) +		ccsr = fdt_get_base_address(fdt, off); + +	if (!ccsr) { +		printf("Warning: could not determine base CCSR address in " +		       "device tree\n"); +		/* No point in checking anything else */ +		return 0; +	} + +	if (ccsr != CONFIG_SYS_CCSRBAR_PHYS) { +		printf("Warning: U-Boot configured CCSR at address %llx,\n" +		       "but the device tree has it at %llx\n", +		       (uint64_t) CONFIG_SYS_CCSRBAR_PHYS, ccsr); +		/* No point in checking anything else */ +		return 0; +	} + +	/* +	 * Get the 'aliases' node.  If there isn't one, then there's nothing +	 * left to do. +	 */ +	aliases = fdt_path_offset(fdt, "/aliases"); +	if (aliases > 0) { +#ifdef CONFIG_SYS_NS16550_COM1 +		if (!fdt_verify_alias_address(fdt, aliases, "serial0", +			CCSR_VIRT_TO_PHYS(CONFIG_SYS_NS16550_COM1))) +			return 0; +#endif + +#ifdef CONFIG_SYS_NS16550_COM2 +		if (!fdt_verify_alias_address(fdt, aliases, "serial1", +			CCSR_VIRT_TO_PHYS(CONFIG_SYS_NS16550_COM2))) +			return 0; +#endif +	} + +	return 1;  } |