diff options
Diffstat (limited to 'arch/powerpc/cpu')
30 files changed, 1247 insertions, 145 deletions
| diff --git a/arch/powerpc/cpu/mpc83xx/Makefile b/arch/powerpc/cpu/mpc83xx/Makefile index 3979b6fbab6..b3530361843 100644 --- a/arch/powerpc/cpu/mpc83xx/Makefile +++ b/arch/powerpc/cpu/mpc83xx/Makefile @@ -34,7 +34,6 @@ COBJS-y += cpu.o  COBJS-y += cpu_init.o  COBJS-y += speed.o  COBJS-y += interrupts.o -COBJS-y += spd_sdram.o  COBJS-y += ecc.o  COBJS-$(CONFIG_QE) += qe_io.o  COBJS-$(CONFIG_FSL_SERDES) += serdes.o @@ -42,6 +41,13 @@ COBJS-$(CONFIG_PCI) += pci.o  COBJS-$(CONFIG_PCIE) += pcie.o  COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +ifdef CONFIG_FSL_DDR2 +COBJS-$(CONFIG_MPC8349) += ddr-gen2.o +else +COBJS-y += spd_sdram.o +endif +COBJS-$(CONFIG_FSL_DDR2) += law.o +  COBJS	:= $(COBJS-y)  SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -52,6 +58,18 @@ all:	$(obj).depend $(START) $(LIB)  $(LIB):	$(OBJS)  	$(call cmd_link_o_target, $(OBJS)) +$(obj)ddr-gen1.c: +	@rm -f $(obj)ddr-gen1.c +	ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen1.c $(obj)ddr-gen1.c + +$(obj)ddr-gen2.c: +	@rm -f $(obj)ddr-gen2.c +	ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen2.c $(obj)ddr-gen2.c + +$(obj)ddr-gen3.c: +	@rm -f $(obj)ddr-gen3.c +	ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen3.c $(obj)ddr-gen3.c +  #########################################################################  # defines $(obj).depend target diff --git a/arch/powerpc/cpu/mpc83xx/ecc.c b/arch/powerpc/cpu/mpc83xx/ecc.c index f8eab96b199..717365c8d19 100644 --- a/arch/powerpc/cpu/mpc83xx/ecc.c +++ b/arch/powerpc/cpu/mpc83xx/ecc.c @@ -1,5 +1,5 @@  /* - * Copyright (C) 2007 Freescale Semiconductor, Inc. + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc.   *   * Dave Liu <daveliu@freescale.com>   * based on the contribution of Marian Balakowicz <m8@semihalf.com> @@ -20,8 +20,12 @@  #if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)  void ecc_print_status(void)  { -	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; -	volatile ddr83xx_t *ddr = &immap->ddr; +	immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +#ifdef CONFIG_FSL_DDR2 +	ccsr_ddr_t *ddr = &immap->ddr; +#else +	ddr83xx_t *ddr = &immap->ddr; +#endif  	printf("\nECC mode: %s\n\n",  	       (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF"); @@ -100,8 +104,12 @@ void ecc_print_status(void)  int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  { -	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; -	volatile ddr83xx_t *ddr = &immap->ddr; +	immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +#ifdef CONFIG_FSL_DDR2 +	ccsr_ddr_t *ddr = &immap->ddr; +#else +	ddr83xx_t *ddr = &immap->ddr; +#endif  	volatile u32 val;  	u64 *addr;  	u32 count; diff --git a/arch/powerpc/cpu/mpc83xx/law.c b/arch/powerpc/cpu/mpc83xx/law.c new file mode 100644 index 00000000000..66c88b697e8 --- /dev/null +++ b/arch/powerpc/cpu/mpc83xx/law.c @@ -0,0 +1,61 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include <common.h> +#include <asm/fsl_law.h> +#include <asm/mmu.h> + +int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) +{ +	immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; +	law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; +	u64 start_align, law_sz; +	int law_sz_enc; + +	if (start == 0) +		start_align = 1ull << (LAW_SIZE_2G + 1); +	else +		start_align = 1ull << (ffs64(start) - 1); +	law_sz = min(start_align, sz); +	law_sz_enc = __ilog2_u64(law_sz) - 1; + +	/* +	 * Set up LAWBAR for all of DDR. +	 */ +	ecm->bar = start & 0xfffff000; +	ecm->ar  = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); +	debug("DDR:bar=0x%08x\n", ecm->bar); +	debug("DDR:ar=0x%08x\n", ecm->ar); + +	/* recalculate size based on what was actually covered by the law */ +	law_sz = 1ull << __ilog2_u64(law_sz); + +	/* do we still have anything to map */ +	sz = sz - law_sz; +	if (sz) { +		start += law_sz; + +		start_align = 1ull << (ffs64(start) - 1); +		law_sz = min(start_align, sz); +		law_sz_enc = __ilog2_u64(law_sz) - 1; +		ecm = &immap->sysconf.ddrlaw[1]; +		ecm->bar = start & 0xfffff000; +		ecm->ar  = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); +		debug("DDR:bar=0x%08x\n", ecm->bar); +		debug("DDR:ar=0x%08x\n", ecm->ar); +	} else { +		return 0; +	} + +	/* do we still have anything to map */ +	sz = sz - law_sz; +	if (sz) +		return 1; + +	return 0; +} diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c index 4542ab1ac46..f78099d2feb 100644 --- a/arch/powerpc/cpu/mpc83xx/speed.c +++ b/arch/powerpc/cpu/mpc83xx/speed.c @@ -507,6 +507,15 @@ ulong get_bus_freq(ulong dummy)  	return gd->csb_clk;  } +/******************************************** + * get_ddr_freq + * return ddr bus freq in Hz + *********************************************/ +ulong get_ddr_freq(ulong dummy) +{ +	return gd->mem_clk; +} +  int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	char buf[32]; diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 7026bca6097..058d609f170 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -67,6 +67,7 @@ COBJS-$(CONFIG_P2020)	+= ddr-gen3.o  COBJS-$(CONFIG_PPC_P2040)	+= ddr-gen3.o  COBJS-$(CONFIG_PPC_P2041)	+= ddr-gen3.o  COBJS-$(CONFIG_PPC_P3041)	+= ddr-gen3.o +COBJS-$(CONFIG_PPC_P3060)	+= ddr-gen3.o  COBJS-$(CONFIG_PPC_P4080)	+= ddr-gen3.o  COBJS-$(CONFIG_PPC_P5020)	+= ddr-gen3.o @@ -81,6 +82,7 @@ COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o  COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o  COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o  COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o +COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o  COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o  COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o @@ -114,6 +116,7 @@ COBJS-$(CONFIG_P2020)	+= p2020_serdes.o  COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o  COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o  COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o +COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o  COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o  COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 7b9f77362c4..a09eb914068 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -87,6 +87,22 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	puts("Work-around for Erratum DDR111 enabled\n");  	puts("Work-around for Erratum DDR134 enabled\n");  #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 +	puts("Work-around for Erratum IFC-A002769 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 +	puts("Work-around for Erratum P1010-A003549 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 +	puts("Work-around for Erratum IFC A-003399 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 +	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) +		puts("Work-around for Erratum NMG DDR120 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 +	puts("Work-around for Erratum NMG_LBC103 enabled\n"); +#endif  	return 0;  } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 22fa4615cbd..49c05516929 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -64,13 +64,11 @@ 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); -#ifdef CONFIG_MPC8536 -	major &= 0x7; /* the msb of this nibble is a mfg code */ -#endif  	minor = SVR_MIN(svr);  	if (cpu_numcores() > 1) { @@ -119,11 +117,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/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 6aca166a98e..0a4ce538f3b 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -31,6 +31,7 @@  #include <asm/processor.h>  #include <ioports.h>  #include <sata.h> +#include <fm_eth.h>  #include <asm/io.h>  #include <asm/cache.h>  #include <asm/mmu.h> @@ -225,7 +226,9 @@ void cpu_init_f (void)  #ifdef CONFIG_SYS_DCSRBAR_PHYS  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  #endif - +#if defined(CONFIG_SECURE_BOOT) +	struct law_entry law; +#endif  #ifdef CONFIG_MPC8548  	ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);  	uint svr = get_svr(); @@ -243,6 +246,13 @@ void cpu_init_f (void)  	disable_tlb(14);  	disable_tlb(15); +#if defined(CONFIG_SECURE_BOOT) +	/* Disable the LAW created for NOR flash by the PBI commands */ +	law = find_law(CONFIG_SYS_PBI_FLASH_BASE); +	if (law.index != -1) +		disable_law(law.index); +#endif +  #ifdef CONFIG_CPM2  	config_8560_ioports((ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR);  #endif @@ -453,6 +463,9 @@ skip_l2:  	clrsetbits_be32(&lbc->lcrr, LCRR_CLKDIV, CONFIG_SYS_LBC_LCRR);  	__raw_readl(&lbc->lcrr);  	isync(); +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 +	udelay(100); +#endif  #endif  #ifdef CONFIG_SYS_FSL_USB1_PHY_ENABLE @@ -472,6 +485,10 @@ skip_l2:  	}  #endif +#ifdef CONFIG_FMAN_ENET +	fman_enet_init(); +#endif +  	return 0;  } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 32aa94b612c..4ef3c9a8a5f 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -1,5 +1,5 @@  /* - * Copyright 2009 Freescale Semiconductor, Inc + * Copyright 2009-2011 Freescale Semiconductor, Inc   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License as @@ -21,59 +21,59 @@  #include <asm/processor.h>  #include <asm/mmu.h>  #include <asm/fsl_law.h> +#include <asm/io.h>  DECLARE_GLOBAL_DATA_PTR; -#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) -#ifdef CONFIG_FSL_CORENET -static void setup_ccsrbar(void) +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +void setup_ifc(void)  { -	u32 temp; -	volatile u32 *ccsr_virt = (volatile u32 *)(CONFIG_SYS_CCSRBAR + 0x1000); -	volatile ccsr_local_t *ccm; +	struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; +	u32 _mas0, _mas1, _mas2, _mas3, _mas7; +	phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS;  	/* -	 * We can't call set_law() because we haven't moved -	 * CCSR yet. +	 * Adjust the TLB we were running out of to match the phys addr of the +	 * chip select we are adjusting and will return to.  	 */ -	ccm = (void *)ccsr_virt; - -	out_be32(&ccm->law[0].lawbarh, -		(u64)CONFIG_SYS_CCSRBAR_PHYS >> 32); -	out_be32(&ccm->law[0].lawbarl, (u32)CONFIG_SYS_CCSRBAR_PHYS); -	out_be32(&ccm->law[0].lawar, -		LAW_EN | (0x1e << 20) | LAW_SIZE_4K); - -	in_be32((u32 *)(ccsr_virt + 0)); -	in_be32((u32 *)(ccsr_virt + 1)); -	isync(); - -	ccm = (void *)CONFIG_SYS_CCSRBAR; -	/* Now use the temporary LAW to move CCSR */ -	out_be32(&ccm->ccsrbarh, (u64)CONFIG_SYS_CCSRBAR_PHYS >> 32); -	out_be32(&ccm->ccsrbarl, (u32)CONFIG_SYS_CCSRBAR_PHYS); -	out_be32(&ccm->ccsrar, CCSRAR_C); -	temp = in_be32(&ccm->ccsrar); -	disable_law(0); -} -#else -static void setup_ccsrbar(void) -{ -	u32 temp; -	volatile u32 *ccsr_virt = (volatile u32 *)(CONFIG_SYS_CCSRBAR + 0x1000); +	flash_phys += (~CONFIG_SYS_AMASK0) + 1 - 4*1024*1024; + +	_mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(15); +	_mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_IPROT | +			MAS1_TSIZE(BOOKE_PAGESZ_4M); +	_mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_TEXT_BASE, MAS2_I|MAS2_G); +	_mas3 = FSL_BOOKE_MAS3(flash_phys, 0, MAS3_SW|MAS3_SR|MAS3_SX); +	_mas7 = FSL_BOOKE_MAS7(flash_phys); + +	mtspr(MAS0, _mas0); +	mtspr(MAS1, _mas1); +	mtspr(MAS2, _mas2); +	mtspr(MAS3, _mas3); +	mtspr(MAS7, _mas7); -	temp = in_be32(ccsr_virt); -	out_be32(ccsr_virt, CONFIG_SYS_CCSRBAR_PHYS >> 12); -	temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR); +	asm volatile("isync;msync;tlbwe;isync"); + +	out_be32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0); +	out_be32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0); +	out_be32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0); + +	return ;  }  #endif -#endif  /* We run cpu_init_early_f in AS = 1 */  void cpu_init_early_f(void)  {  	u32 mas0, mas1, mas2, mas3, mas7;  	int i; +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +	ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; +	u32  *l2srbar, *dst, *src; +	void (*setup_ifc_sram)(void); +#endif  	/* Pointer is writable since we allocated a register for it */  	gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -85,28 +85,77 @@ void cpu_init_early_f(void)  	for (i = 0; i < sizeof(gd_t); i++)  		((char *)gd)[i] = 0; -	mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0); -	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); +	mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13); +	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M);  	mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G);  	mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR);  	mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_PHYS);  	write_tlb(mas0, mas1, mas2, mas3, mas7); -	/* set up CCSR if we want it moved */ -#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) -	mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(1); -	/* mas1 is the same as above */ -	mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G); -	mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, MAS3_SW|MAS3_SR); -	mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_DEFAULT); +/* + * Work Around for IFC Erratum A-003549. This issue is P1010 + * specific. LCLK(a free running clk signal) is muxed with IFC_CS3 on P1010 SOC + * Hence specifically selecting CS3. + */ +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 +	setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_LCLK_IFC_CS3); +#endif + +	init_laws(); + +/* + * Work Around for IFC Erratum A003399, issue will hit only when execution + * from NOR Flash + */ +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +#define SRAM_BASE_ADDR	(0x00000000) +	/* TLB for SRAM */ +	mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(9); +	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | +		MAS1_TSIZE(BOOKE_PAGESZ_1M); +	mas2 = FSL_BOOKE_MAS2(SRAM_BASE_ADDR, MAS2_I); +	mas3 = FSL_BOOKE_MAS3(SRAM_BASE_ADDR, 0, MAS3_SX|MAS3_SW|MAS3_SR); +	mas7 = FSL_BOOKE_MAS7(0);  	write_tlb(mas0, mas1, mas2, mas3, mas7); -	setup_ccsrbar(); +	out_be32(&l2cache->l2srbar0, SRAM_BASE_ADDR); + +	out_be32(&l2cache->l2errdis, +		(MPC85xx_L2ERRDIS_MBECC | MPC85xx_L2ERRDIS_SBECC)); + +	out_be32(&l2cache->l2ctl, +		(MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE)); + +	/* +	 * Copy the code in setup_ifc to L2SRAM. Do a word copy +	 * because NOR Flash on P1010 does not support byte +	 * access (Erratum IFC-A002769) +	 */ +	setup_ifc_sram = (void *)SRAM_BASE_ADDR; +	dst = (u32 *) SRAM_BASE_ADDR; +	src = (u32 *) setup_ifc; +	for (i = 0; i < 1024; i++) +		*l2srbar++ = *src++; + +	setup_ifc_sram(); + +	/* CLEANUP */ +	clrbits_be32(&l2cache->l2ctl, +			(MPC85xx_L2CTL_L2E | +			 MPC85xx_L2CTL_L2SRAM_ENTIRE)); +	out_be32(&l2cache->l2srbar0, 0x0); +#endif + +	invalidate_tlb(1); + +#if defined(CONFIG_SECURE_BOOT) +	/* Disable the TLBs created by ISBC */ +	for (i = CONFIG_SYS_ISBC_START_TLB; +	     i < CONFIG_SYS_ISBC_START_TLB + CONFIG_SYS_ISBC_NUM_TLBS; i++) +			disable_tlb(i);  #endif -	init_laws(); -	invalidate_tlb(0);  	init_tlbs();  } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c index 796d3984261..f33db021f1e 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c @@ -21,10 +21,12 @@   */  #include <common.h> +#include <asm/fsl_ifc.h>  #include <asm/io.h>  void cpu_init_f(void)  { +#ifdef CONFIG_FSL_LBC  	fsl_lbc_t *lbc = LBC_BASE_ADDR;  	/* @@ -39,6 +41,16 @@ void cpu_init_f(void)  #else  #error  CONFIG_SYS_NAND_BR_PRELIM, CONFIG_SYS_NAND_OR_PRELIM must be defined  #endif +#endif +#ifdef CONFIG_FSL_IFC +#ifndef	CONFIG_SYS_FSL_ERRATUM_IFC_A003399 +#if defined(CONFIG_SYS_CSPR0) && defined(CONFIG_SYS_CSOR0) +	set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); +	set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); +	set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); +#endif +#endif +#endif  #if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR)  	ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c index 655f99c028e..49000a19e83 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c @@ -1,5 +1,5 @@  /* - * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2008-2011 Freescale Semiconductor, Inc.   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -8,6 +8,7 @@  #include <common.h>  #include <asm/io.h> +#include <asm/processor.h>  #include <asm/fsl_ddr_sdram.h>  #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) @@ -18,13 +19,36 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  			     unsigned int ctrl_num)  {  	unsigned int i; -	volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; +#ifdef CONFIG_MPC83xx +	ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC83xx_DDR_ADDR; +#else +	ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	uint svr; +#endif +#endif  	if (ctrl_num) {  		printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);  		return;  	} +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 +	/* +	 * Set the DDR IO receiver to an acceptable bias point. +	 * Fixed in Rev 2.1. +	 */ +	svr = get_svr(); +	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) { +		if ((regs->ddr_sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) == +		   SDRAM_CFG_SDRAM_TYPE_DDR2) +			out_be32(&gur->ddrioovcr, 0x90000000); +		else +			out_be32(&gur->ddrioovcr, 0xA8000000); +	} +#endif +  	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {  		if (i == 0) {  			out_be32(&ddr->cs0_bnds, regs->cs[i].bnds); diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 8f13cd8ebf6..d20c94c0f7c 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -361,6 +361,7 @@ void fdt_add_enet_stashing(void *fdt)  }  #if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME) +#ifdef CONFIG_SYS_DPAA_FMAN  static void ft_fixup_clks(void *blob, const char *compat, u32 offset,  			  unsigned long freq)  { @@ -374,12 +375,14 @@ static void ft_fixup_clks(void *blob, const char *compat, u32 offset,  				"for %s: %s\n", compat, fdt_strerror(off));  	}  } +#endif  static void ft_fixup_dpaa_clks(void *blob)  {  	sys_info_t sysinfo;  	get_sys_info(&sysinfo); +#ifdef CONFIG_SYS_DPAA_FMAN  	ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM1_OFFSET,  			sysinfo.freqFMan[0]); @@ -387,6 +390,7 @@ static void ft_fixup_dpaa_clks(void *blob)  	ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM2_OFFSET,  			sysinfo.freqFMan[1]);  #endif +#endif  #ifdef CONFIG_SYS_DPAA_PME  	do_fixup_by_compat_u32(blob, "fsl,pme", diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 4307a4ccbb5..07e58ed024a 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -482,6 +482,13 @@ static void wait_for_rstdone(unsigned int bank)  		printf("SERDES: timeout resetting bank %u\n", bank + 1);  } + +void __soc_serdes_init(void) +{ +	/* Allow for SoC-specific initialization in <SOC>_serdes.c  */ +}; +void soc_serdes_init(void) __attribute__((weak, alias("__soc_serdes_init"))); +  void fsl_serdes_init(void)  {  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -570,6 +577,8 @@ void fsl_serdes_init(void)  		}  	} +	soc_serdes_init(); +  #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8  	/*  	 * Bank two uses the clock from bank three, so if bank two is enabled, diff --git a/arch/powerpc/cpu/mpc85xx/liodn.c b/arch/powerpc/cpu/mpc85xx/liodn.c index bd1909471c1..e0ea502a05f 100644 --- a/arch/powerpc/cpu/mpc85xx/liodn.c +++ b/arch/powerpc/cpu/mpc85xx/liodn.c @@ -1,5 +1,5 @@  /* - * Copyright 2008-2010 Freescale Semiconductor, Inc. + * Copyright 2008-2011 Freescale Semiconductor, Inc.   *   * See file CREDITS for list of people who contributed to this   * project. @@ -120,6 +120,19 @@ static void setup_pme_liodn_base(void)  #endif  } +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +static void setup_raide_liodn_base(void) +{ +	struct ccsr_raide *raide = (void *)CONFIG_SYS_FSL_RAID_ENGINE_ADDR; + +	/* setup raid engine liodn base for data/desc ; both set to 47 */ +	u32 base = (liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0] << 16) | +			liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0]; + +	out_be32(&raide->liodnbr, base); +} +#endif +  void set_liodns(void)  {  	/* setup general liodn offsets */ @@ -145,6 +158,12 @@ void set_liodns(void)  #endif  	/* setup PME liodn base */  	setup_pme_liodn_base(); + +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +	/* raid engine ccr addr code for liodn */ +	set_liodn(raide_liodn_tbl, raide_liodn_tbl_sz); +	setup_raide_liodn_base(); +#endif  }  static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) @@ -184,4 +203,8 @@ void fdt_fixup_liodn(void *blob)  #endif  #endif  	fdt_fixup_liodn_tbl(blob, sec_liodn_tbl, sec_liodn_tbl_sz); + +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +	fdt_fixup_liodn_tbl(blob, raide_liodn_tbl, raide_liodn_tbl_sz); +#endif  } diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 758e6d7045f..ffc2a9ad65d 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/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c new file mode 100644 index 00000000000..07703d44eba --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p3060_ids.c @@ -0,0 +1,113 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * 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 + */ + +#include <common.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> + +#ifdef CONFIG_SYS_DPAA_QBMAN +struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { +	/* dqrr liodn, frame data liodn, liodn off, sdest */ +	SET_QP_INFO( 1,  2,  1, 0), +	SET_QP_INFO( 3,  4,  2, 1), +	SET_QP_INFO( 5,  6,  3, 2), +	SET_QP_INFO( 7,  8,  4, 3), +	SET_QP_INFO( 9, 10,  5, 4), +	SET_QP_INFO(11, 12,  6, 5), +	SET_QP_INFO(13, 14,  7, 6), +	SET_QP_INFO(15, 16,  8, 7), +	SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */ +	SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ +}; +#endif + +struct liodn_id_table liodn_tbl[] = { +	SET_USB_LIODN(1, "fsl-usb2-mph", 127), +	SET_USB_LIODN(2, "fsl-usb2-dr", 157), + +	SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193), +	SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194), + +	SET_DMA_LIODN(1, 196), +	SET_DMA_LIODN(2, 197), + +	SET_GUTS_LIODN("fsl,rapidio-delta", 198, rio1liodnr, 0), +	SET_GUTS_LIODN(NULL, 199, rio2liodnr, 0), +	SET_GUTS_LIODN(NULL, 200, rmuliodnr, 0), + +#ifdef CONFIG_SYS_DPAA_QBMAN +	SET_QMAN_LIODN(31), +	SET_BMAN_LIODN(32), +#endif +	SET_PME_LIODN(128), +}; +int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); + +#ifdef CONFIG_SYS_DPAA_FMAN +struct liodn_id_table fman1_liodn_tbl[] = { +	SET_FMAN_RX_1G_LIODN(1, 0, 11), +	SET_FMAN_RX_1G_LIODN(1, 1, 12), +	SET_FMAN_RX_1G_LIODN(1, 2, 13), +	SET_FMAN_RX_1G_LIODN(1, 3, 14), +}; +int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); + +#if (CONFIG_SYS_NUM_FMAN == 2) +struct liodn_id_table fman2_liodn_tbl[] = { +	SET_FMAN_RX_1G_LIODN(2, 0, 16), +	SET_FMAN_RX_1G_LIODN(2, 1, 17), +	SET_FMAN_RX_1G_LIODN(2, 2, 18), +	SET_FMAN_RX_1G_LIODN(2, 3, 19), +}; +int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); +#endif +#endif + +struct liodn_id_table sec_liodn_tbl[] = { +	SET_SEC_JR_LIODN_ENTRY(0, 146, 154), +	SET_SEC_JR_LIODN_ENTRY(1, 147, 155), +	SET_SEC_JR_LIODN_ENTRY(2, 178, 186), +	SET_SEC_JR_LIODN_ENTRY(3, 179, 187), +	SET_SEC_RTIC_LIODN_ENTRY(a, 144), +	SET_SEC_RTIC_LIODN_ENTRY(b, 145), +	SET_SEC_RTIC_LIODN_ENTRY(c, 176), +	SET_SEC_RTIC_LIODN_ENTRY(d, 177), +	SET_SEC_DECO_LIODN_ENTRY(0, 129, 161), +	SET_SEC_DECO_LIODN_ENTRY(1, 130, 162), +	SET_SEC_DECO_LIODN_ENTRY(2, 131, 163), +	SET_SEC_DECO_LIODN_ENTRY(3, 132, 164), +	SET_SEC_DECO_LIODN_ENTRY(4, 133, 165), +}; +int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); + +struct liodn_id_table liodn_bases[] = { +	[FSL_HW_PORTAL_SEC]  = SET_LIODN_BASE_2(96, 106), +#ifdef CONFIG_SYS_DPAA_FMAN +	[FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32), +#if (CONFIG_SYS_NUM_FMAN == 2) +	[FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64), +#endif +#endif +#ifdef CONFIG_SYS_DPAA_PME +	[FSL_HW_PORTAL_PME]   = SET_LIODN_BASE_2(116, 133), +#endif +}; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c new file mode 100644 index 00000000000..6387276babd --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c @@ -0,0 +1,138 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * 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 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/fsl_serdes.h> +#include <asm/processor.h> +#include <asm/io.h> +#include "fsl_corenet_serdes.h" + +static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { +	[0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, +		  SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1, +		  SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, +		  NONE, NONE, AURORA, AURORA}, +	[0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3, +		  SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, +		  SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, +		  SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA}, +	[0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, +		  AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, +		  SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, +		  SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, +	[0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, +		  AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3, +		  SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, +	[0x1c] = {NONE, NONE, SRIO1, SRIO2,  NONE, NONE, NONE, NONE, +		  AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, +		  SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, +		  SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, +}; + +enum srds_prtcl serdes_get_prtcl(int cfg, int lane) +{ +	if (!serdes_lane_enabled(lane)) +		return NONE; + +	return serdes_cfg_tbl[cfg][lane]; +} + +int is_serdes_prtcl_valid(u32 prtcl) +{ +	int i; + +	if (prtcl > ARRAY_SIZE(serdes_cfg_tbl)) +		return 0; + +	for (i = 0; i < SRDS_MAX_LANES; i++) { +		if (serdes_cfg_tbl[prtcl][i] != NONE) +			return 1; +	} + +	return 0; +} + +void soc_serdes_init(void) +{ +	/* +	 * On the P3060 the devdisr2 register does not correctly reflect +	 * the state of the MACs based on the RCW fields. So disable the MACs +	 * based on the srds_prtcl and ec1, ec2, ec3 fields +	 */ + +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	u32 devdisr2 = in_be32(&gur->devdisr2); +	u32 rcwsr11 = in_be32(&gur->rcwsr[11]); +	u32 rcwsr13 = in_be32(&gur->rcwsr[13]); +	u32 ec1_ext, ec2_ext; + +	/* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */ + +	if (!is_serdes_configured(SGMII_FM1_DTSEC3)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3; + +	if (!is_serdes_configured(SGMII_FM1_DTSEC4)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4; + +	if (!is_serdes_configured(SGMII_FM2_DTSEC1)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1; + +	if (!is_serdes_configured(SGMII_FM2_DTSEC2)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2; + +	if (!is_serdes_configured(SGMII_FM2_DTSEC3)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3; + +	if (!is_serdes_configured(SGMII_FM2_DTSEC4)) +		devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4; + +	if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == +		FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) { +		devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2; +	} + +	if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == +		FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) { +		devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1; +	} + +	ec1_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC1_EXT; +	if (ec1_ext) { +		if ((ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_RGMII) || +			(ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_MII)) +			devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_4; +	} + +	ec2_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC2_EXT; +	if (ec2_ext) { +		if ((ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_RGMII) || +			(ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_MII)) +			devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4; +	} + +	if ((rcwsr13 & FSL_CORENET_RCWSR13_EC3) == +		FSL_CORENET_RCWSR13_EC3_FM2_DTSEC4_MII) +		devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4; + +	out_be32(&gur->devdisr2, devdisr2); +} diff --git a/arch/powerpc/cpu/mpc85xx/p5020_ids.c b/arch/powerpc/cpu/mpc85xx/p5020_ids.c index 98365888ae9..2911c13884c 100644 --- a/arch/powerpc/cpu/mpc85xx/p5020_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p5020_ids.c @@ -97,6 +97,16 @@ struct liodn_id_table sec_liodn_tbl[] = {  };  int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +struct liodn_id_table raide_liodn_tbl[] = { +	SET_RAID_ENGINE_JQ_LIODN_ENTRY(0, 0, 60), +	SET_RAID_ENGINE_JQ_LIODN_ENTRY(0, 1, 61), +	SET_RAID_ENGINE_JQ_LIODN_ENTRY(1, 0, 62), +	SET_RAID_ENGINE_JQ_LIODN_ENTRY(1, 1, 63), +}; +int raide_liodn_tbl_sz = ARRAY_SIZE(raide_liodn_tbl); +#endif +  struct liodn_id_table liodn_bases[] = {  	[FSL_HW_PORTAL_SEC]  = SET_LIODN_BASE_2(64, 100),  #ifdef CONFIG_SYS_DPAA_FMAN @@ -105,4 +115,7 @@ struct liodn_id_table liodn_bases[] = {  #ifdef CONFIG_SYS_DPAA_PME  	[FSL_HW_PORTAL_PME]   = SET_LIODN_BASE_2(136, 172),  #endif +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +	[FSL_HW_PORTAL_RAID_ENGINE]  = SET_LIODN_BASE_1(47), +#endif  }; diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c index ecaa30de84b..418dd9d9ead 100644 --- a/arch/powerpc/cpu/mpc85xx/portals.c +++ b/arch/powerpc/cpu/mpc85xx/portals.c @@ -151,7 +151,7 @@ static int fdt_qportal(void *blob, int off, int id, char *name,  			dev_handle = fdt_get_phandle(blob, dev_off);  			if (dev_handle <= 0) {  				dev_handle = fdt_alloc_phandle(blob); -				ret = fdt_create_phandle(blob, dev_off, +				ret = fdt_set_phandle(blob, dev_off,  							 dev_handle);  				if (ret < 0)  					return ret; @@ -198,7 +198,10 @@ void fdt_fixup_qportals(void *blob)  		u32 liodns[2];  #endif  		const int *ci = fdt_getprop(blob, off, "cell-index", NULL); -		int j, i = *ci; +		int i = *ci; +#ifdef CONFIG_SYS_DPAA_FMAN +		int j; +#endif  		err = fdt_setprop(blob, off, "compatible", compat, compat_len);  		if (err < 0) diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index a83dfeb84cf..ce475324550 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/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 878a3d67e82..5e0d78d0064 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -83,6 +83,45 @@  _start_e500: +#if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) +	/* ISBC uses L2 as stack. +	 * Disable L2 cache here so that u-boot can enable it later +	 * as part of it's normal flow +	*/ + +	/* Check if L2 is enabled */ +	mfspr	r3, SPRN_L2CSR0 +	lis	r2, L2CSR0_L2E@h +	ori	r2, r2, L2CSR0_L2E@l +	and.	r4, r3, r2 +	beq	l2_disabled + +	mfspr r3, SPRN_L2CSR0 +	/* Flush L2 cache */ +	lis     r2,(L2CSR0_L2FL)@h +	ori     r2, r2, (L2CSR0_L2FL)@l +	or      r3, r2, r3 +	sync +	isync +	mtspr   SPRN_L2CSR0,r3 +	isync +1: +	mfspr r3, SPRN_L2CSR0 +	and. r1, r3, r2 +	bne 1b + +	mfspr r3, SPRN_L2CSR0 +	lis r2, L2CSR0_L2E@h +	ori r2, r2, L2CSR0_L2E@l +	andc r4, r3, r2 +	sync +	isync +	mtspr SPRN_L2CSR0,r4 +	isync + +l2_disabled: +#endif +  /* clear registers/arrays not reset by hardware */  	/* L1 */ @@ -279,10 +318,244 @@ _start_e500:  #endif /* CONFIG_MPC8569 */ +/* + * Relocate CCSR, if necessary.  We relocate CCSR if (obviously) the default + * location is not where we want it.  This typically happens on a 36-bit + * system, where we want to move CCSR to near the top of 36-bit address space. + * + * To move CCSR, we create two temporary TLBs, one for the old location, and + * another for the new location.  On CoreNet systems, we also need to create + * a special, temporary LAW. + * + * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for + * long-term TLBs, so we use TLB0 here. + */ +#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) + +#if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW) +#error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." +#endif + +purge_old_ccsr_tlb: +	lis	r8, CONFIG_SYS_CCSRBAR@h +	ori	r8, r8, CONFIG_SYS_CCSRBAR@l +	lis	r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h +	ori	r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l + +	/* +	 * In a multi-stage boot (e.g. NAND boot), a previous stage may have +	 * created a TLB for CCSR, which will interfere with our relocation +	 * code.  Since we're going to create a new TLB for CCSR anyway, +	 * it should be safe to delete this old TLB here.  We have to search +	 * for it, though. +	 */ + +	li	r1, 0 +	mtspr	MAS6, r1	/* Search the current address space and PID */ +	tlbsx	0, r8 +	mfspr	r1, MAS1 +	andis.  r2, r1, MAS1_VALID@h	/* Check for the Valid bit */ +	beq     1f			/* Skip if no TLB found */ + +	rlwinm	r1, r1, 0, 1, 31	/* Clear Valid bit */ +	mtspr	MAS1, r1 +	tlbwe +1: + +create_ccsr_new_tlb: +	/* +	 * Create a TLB for the new location of CCSR.  Register R8 is reserved +	 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). +	 */ +	lis     r0, FSL_BOOKE_MAS0(0, 0, 0)@h +	ori     r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l +	lis     r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h +	ori     r1, r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l +	lis     r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h +	ori     r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l +	lis     r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h +	ori     r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l +	lis	r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h +	ori	r7, r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l +	mtspr   MAS0, r0 +	mtspr   MAS1, r1 +	mtspr   MAS2, r2 +	mtspr   MAS3, r3 +	mtspr   MAS7, r7 +	isync +	msync +	tlbwe + +	/* +	 * Create a TLB for the old location of CCSR.  Register R9 is reserved +	 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). +	 */ +create_ccsr_old_tlb: +	lis     r0, FSL_BOOKE_MAS0(0, 1, 0)@h +	ori     r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l +	lis     r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h +	ori     r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l +	lis     r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@h +	ori     r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@l +	li	r7, 0	/* The default CCSR address is always a 32-bit number */ +	mtspr   MAS0, r0 +	/* MAS1 is the same as above */ +	mtspr   MAS2, r2 +	mtspr   MAS3, r3 +	mtspr   MAS7, r7 +	isync +	msync +	tlbwe + +#ifdef CONFIG_FSL_CORENET + +#define CCSR_LAWBARH0	(CONFIG_SYS_CCSRBAR + 0x1000) +#define LAW_EN		0x80000000 +#define LAW_SIZE_4K	0xb +#define CCSRBAR_LAWAR	(LAW_EN | (0x1e << 20) | LAW_SIZE_4K) +#define CCSRAR_C	0x80000000	/* Commit */ + +create_temp_law: +	/* +	 * On CoreNet systems, we create the temporary LAW using a special LAW +	 * target ID of 0x1e.  LAWBARH is at offset 0xc00 in CCSR. +	 */ +	lis     r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h +	ori     r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l +	lis     r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h +	ori     r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l +	lis     r2, CCSRBAR_LAWAR@h +	ori     r2, r2, CCSRBAR_LAWAR@l + +	stw     r0, 0xc00(r9)	/* LAWBARH0 */ +	stw     r1, 0xc04(r9)	/* LAWBARL0 */ +	sync +	stw     r2, 0xc08(r9)	/* LAWAR0 */ + +	/* +	 * Read back from LAWAR to ensure the update is complete.  e500mc +	 * cores also require an isync. +	 */ +	lwz	r0, 0xc08(r9)	/* LAWAR0 */ +	isync + +	/* +	 * Read the current CCSRBARH and CCSRBARL using load word instructions. +	 * Follow this with an isync instruction. This forces any outstanding +	 * accesses to configuration space to completion. +	 */ +read_old_ccsrbar: +	lwz	r0, 0(r9)	/* CCSRBARH */ +	lwz	r0, 4(r9)	/* CCSRBARH */ +	isync + +	/* +	 * Write the new values for CCSRBARH and CCSRBARL to their old +	 * locations.  The CCSRBARH has a shadow register. When the CCSRBARH +	 * has a new value written it loads a CCSRBARH shadow register. When +	 * the CCSRBARL is written, the CCSRBARH shadow register contents +	 * along with the CCSRBARL value are loaded into the CCSRBARH and +	 * CCSRBARL registers, respectively.  Follow this with a sync +	 * instruction. +	 */ +write_new_ccsrbar: +	lis	r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h +	ori	r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l +	lis	r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h +	ori	r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l +	lis	r2, CCSRAR_C@h +	ori	r2, r2, CCSRAR_C@l + +	stw	r0, 0(r9)	/* Write to CCSRBARH */ +	sync			/* Make sure we write to CCSRBARH first */ +	stw	r1, 4(r9)	/* Write to CCSRBARL */ +	sync + +	/* +	 * Write a 1 to the commit bit (C) of CCSRAR at the old location. +	 * Follow this with a sync instruction. +	 */ +	stw	r2, 8(r9) +	sync + +	/* Delete the temporary LAW */ +delete_temp_law: +	li	r1, 0 +	stw	r1, 0xc08(r8) +	sync +	stw	r1, 0xc00(r8) +	stw	r1, 0xc04(r8) +	sync + +#else /* #ifdef CONFIG_FSL_CORENET */ + +write_new_ccsrbar: +	/* +	 * Read the current value of CCSRBAR using a load word instruction +	 * followed by an isync. This forces all accesses to configuration +	 * space to complete. +	 */ +	sync +	lwz	r0, 0(r9) +	isync + +/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */ +#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \ +			   (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12)) + +	/* Write the new value to CCSRBAR. */ +	lis	r0, CCSRBAR_PHYS_RS12@h +	ori	r0, r0, CCSRBAR_PHYS_RS12@l +	stw	r0, 0(r9) +	sync + +	/* +	 * The manual says to perform a load of an address that does not +	 * access configuration space or the on-chip SRAM using an existing TLB, +	 * but that doesn't appear to be necessary.  We will do the isync, +	 * though. +	 */ +	isync + +	/* +	 * Read the contents of CCSRBAR from its new location, followed by +	 * another isync. +	 */ +	lwz	r0, 0(r8) +	isync + +#endif  /* #ifdef CONFIG_FSL_CORENET */ + +	/* Delete the temporary TLBs */ +delete_temp_tlbs: +	lis     r0, FSL_BOOKE_MAS0(0, 0, 0)@h +	ori     r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l +	li	r1, 0 +	lis     r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h +	ori     r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l +	mtspr   MAS0, r0 +	mtspr   MAS1, r1 +	mtspr   MAS2, r2 +	isync +	msync +	tlbwe + +	lis     r0, FSL_BOOKE_MAS0(0, 1, 0)@h +	ori     r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l +	lis     r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h +	ori     r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l +	mtspr   MAS0, r0 +	mtspr   MAS2, r2 +	isync +	msync +	tlbwe +#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ + +create_init_ram_area:  	lis     r6,FSL_BOOKE_MAS0(1, 15, 0)@h  	ori     r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l -#ifndef CONFIG_SYS_RAMBOOT +#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)  	/* create a temp mapping in AS=1 to the 4M boot window */  	lis     r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h  	ori     r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l @@ -293,6 +566,20 @@ _start_e500:  	/* The 85xx has the default boot window 0xff800000 - 0xffffffff */  	lis     r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h  	ori     r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l +#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) +	/* create a temp mapping in AS = 1 for Flash mapping +	 * created by PBL for ISBC code +	*/ +	lis     r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h +	ori     r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l + +	lis     r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h +	ori     r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l + +	lis     r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, +						(MAS3_SX|MAS3_SW|MAS3_SR))@h +	ori     r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, +						(MAS3_SX|MAS3_SW|MAS3_SR))@l  #else  	/*  	 * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds index 8410bd79793..852f9aa4a39 100644 --- a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds +++ b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds @@ -23,6 +23,8 @@   * MA 02111-1307 USA   */ +#include "config.h"	/* CONFIG_BOARDDIR */ +  OUTPUT_ARCH(powerpc)  SECTIONS  { @@ -52,8 +54,18 @@ SECTIONS  	. = ALIGN(8);  	__init_begin = .;  	__init_end = .; - -	.resetvec ADDR(.text) + 0xffc : { +#if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */ +	.bootpg ADDR(.text) + 0x1000 : +	{ +		start.o	(.bootpg) +	} +#define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */ +#elif defined(CONFIG_FSL_ELBC) +#define RESET_VECTOR_OFFSET 0xffc /* LBC has 4k sram */ +#else +#error unknown NAND controller +#endif +	.resetvec ADDR(.text) + RESET_VECTOR_OFFSET : {  		KEEP(*(.resetvec))  	} = 0xffff @@ -64,4 +76,4 @@ SECTIONS  	}  	__bss_end__ = .;  } -ASSERT(__init_end <= 0xfff00ffc, "NAND bootstrap too big"); +ASSERT(__init_end <= (0xfff00000 + RESET_VECTOR_OFFSET), "NAND bootstrap too big"); diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 767bc524d1c..0365ca8aa23 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -27,6 +27,7 @@  #include <common.h>  #include <command.h>  #include <tsec.h> +#include <fm_eth.h>  #include <netdev.h>  #include <asm/cache.h>  #include <asm/io.h> @@ -102,6 +103,8 @@ struct cpu_type cpu_type_list [] = {  	CPU_TYPE_ENTRY(P2041, P2041_E, 4),  	CPU_TYPE_ENTRY(P3041, P3041, 4),  	CPU_TYPE_ENTRY(P3041, P3041_E, 4), +	CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3), +	CPU_TYPE_ENTRY_MASK(P3060, P3060_E, 6, 0xf3),  	CPU_TYPE_ENTRY(P4040, P4040, 4),  	CPU_TYPE_ENTRY(P4040, P4040_E, 4),  	CPU_TYPE_ENTRY(P4080, P4080, 8), @@ -129,13 +132,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 +166,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; @@ -174,5 +209,8 @@ int cpu_eth_init(bd_t *bis)  	tsec_standard_init(bis);  #endif +#ifdef CONFIG_FMAN_ENET +	fm_standard_init(bis); +#endif  	return 0;  } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 3824aade89d..15cd375ae36 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -18,7 +18,9 @@  #include "ddr.h" -#ifdef CONFIG_MPC85xx +#ifdef CONFIG_MPC83xx +	#define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR +#elif defined(CONFIG_MPC85xx)  	#define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR  #elif defined(CONFIG_MPC86xx)  	#define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR @@ -94,6 +96,10 @@ static inline int fsl_ddr_get_rtt(void)   *       6 if 2.5ns > tCK >= 1.875ns   *       7 if 1.875ns > tCK >= 1.5ns   *       8 if 1.5ns > tCK >= 1.25ns + *       9 if 1.25ns > tCK >= 1.07ns + *       10 if 1.07ns > tCK >= 0.935ns + *       11 if 0.935ns > tCK >= 0.833ns + *       12 if 0.833ns > tCK >= 0.75ns   */  static inline unsigned int compute_cas_write_latency(void)  { @@ -108,8 +114,18 @@ static inline unsigned int compute_cas_write_latency(void)  		cwl = 7;  	else if (mclk_ps >= 1250)  		cwl = 8; -	else -		cwl = 8; +	else if (mclk_ps >= 1070) +		cwl = 9; +	else if (mclk_ps >= 935) +		cwl = 10; +	else if (mclk_ps >= 833) +		cwl = 11; +	else if (mclk_ps >= 750) +		cwl = 12; +	else { +		cwl = 12; +		printf("Warning: CWL is out of range\n"); +	}  	return cwl;  } @@ -146,7 +162,7 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,  		break;  	case 2:  		if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ -		   (dimm_number > 1 && dimm_params[dimm_number].n_ranks > 0)) +		   (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0))  			go_config = 1;  		break;  	case 3: @@ -617,7 +633,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,  	unsigned int sr_ie = 0;		/* Self-refresh interrupt enable */  	unsigned int dll_rst_dis;	/* DLL reset disable */  	unsigned int dqs_cfg;		/* DQS configuration */ -	unsigned int odt_cfg;		/* ODT configuration */ +	unsigned int odt_cfg = 0;	/* ODT configuration */  	unsigned int num_pr;		/* Number of posted refreshes */  	unsigned int obc_cfg;		/* On-The-Fly Burst Chop Cfg */  	unsigned int ap_en;		/* Address Parity Enable */ @@ -625,15 +641,16 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,  	unsigned int rcw_en = 0;	/* Register Control Word Enable */  	unsigned int md_en = 0;		/* Mirrored DIMM Enable */  	unsigned int qd_en = 0;		/* quad-rank DIMM Enable */ +	int i;  	dll_rst_dis = 1;	/* Make this configurable */  	dqs_cfg = popts->DQS_config; -	if (popts->cs_local_opts[0].odt_rd_cfg -	    || popts->cs_local_opts[0].odt_wr_cfg) { -		/* FIXME */ -		odt_cfg = 2; -	} else { -		odt_cfg = 0; +	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { +		if (popts->cs_local_opts[i].odt_rd_cfg +			|| popts->cs_local_opts[i].odt_wr_cfg) { +			odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; +			break; +		}  	}  	num_pr = 1;	/* Make this configurable */ @@ -1018,7 +1035,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,  #if defined(CONFIG_FSL_DDR2)  	const unsigned int mclk_ps = get_memory_clk_period_ps();  #endif - +	dqs_en = !popts->DQS_config;  	rtt = fsl_ddr_get_rtt();  	al = additive_latency; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 8132e68d9d6..20c7db03ede 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -448,7 +448,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,  #if defined(CONFIG_FSL_DDR2)  	if (lowest_good_caslat < 4) { -		additive_latency = picos_to_mclk(tRCD_ps) - lowest_good_caslat; +		additive_latency = (picos_to_mclk(tRCD_ps) > lowest_good_caslat) +			? picos_to_mclk(tRCD_ps) - lowest_good_caslat : 0;  		if (mclk_to_picos(additive_latency) > tRCD_ps) {  			additive_latency = picos_to_mclk(tRCD_ps);  			debug("setting additive_latency to %u because it was " diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index 249fd7dfb36..5699b0c2cc9 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -34,14 +34,17 @@ extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {  	[0][0] = SPD_EEPROM_ADDRESS,  }; -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +	[0][0] = SPD_EEPROM_ADDRESS1,	/* controller 1 */ +	[0][1] = SPD_EEPROM_ADDRESS2,	/* controller 1 */ +}; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)  u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {  	[0][0] = SPD_EEPROM_ADDRESS1,	/* controller 1 */  	[1][0] = SPD_EEPROM_ADDRESS2,	/* controller 2 */  }; -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)  u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {  	[0][0] = SPD_EEPROM_ADDRESS1,	/* controller 1 */  	[0][1] = SPD_EEPROM_ADDRESS2,	/* controller 1 */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index bd9c4663e79..4dc748b9510 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -26,14 +26,15 @@ extern void fsl_ddr_board_options(memctl_options_t *popts,  		dimm_params_t *pdimm,  		unsigned int ctrl_num); -typedef struct { +struct dynamic_odt {  	unsigned int odt_rd_cfg;  	unsigned int odt_wr_cfg;  	unsigned int odt_rtt_norm;  	unsigned int odt_rtt_wr; -} dynamic_odt_t; +}; -static const dynamic_odt_t single_Q[4] = { +#ifdef CONFIG_FSL_DDR3 +static const struct dynamic_odt single_Q[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_CS_AND_OTHER_DIMM, @@ -60,7 +61,7 @@ static const dynamic_odt_t single_Q[4] = {  	}  }; -static const dynamic_odt_t single_D[4] = { +static const struct dynamic_odt single_D[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_ALL, @@ -77,7 +78,7 @@ static const dynamic_odt_t single_D[4] = {  	{0, 0, 0, 0}  }; -static const dynamic_odt_t single_S[4] = { +static const struct dynamic_odt single_S[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_ALL, @@ -89,7 +90,7 @@ static const dynamic_odt_t single_S[4] = {  	{0, 0, 0, 0},  }; -static const dynamic_odt_t dual_DD[4] = { +static const struct dynamic_odt dual_DD[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_SAME_DIMM, @@ -116,7 +117,7 @@ static const dynamic_odt_t dual_DD[4] = {  	}  }; -static const dynamic_odt_t dual_DS[4] = { +static const struct dynamic_odt dual_DS[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_SAME_DIMM, @@ -137,7 +138,7 @@ static const dynamic_odt_t dual_DS[4] = {  	},  	{0, 0, 0, 0}  }; -static const dynamic_odt_t dual_SD[4] = { +static const struct dynamic_odt dual_SD[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_OTHER_DIMM,  		FSL_DDR_ODT_ALL, @@ -159,7 +160,7 @@ static const dynamic_odt_t dual_SD[4] = {  	}  }; -static const dynamic_odt_t dual_SS[4] = { +static const struct dynamic_odt dual_SS[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_OTHER_DIMM,  		FSL_DDR_ODT_ALL, @@ -176,7 +177,7 @@ static const dynamic_odt_t dual_SS[4] = {  	{0, 0, 0, 0}  }; -static const dynamic_odt_t dual_D0[4] = { +static const struct dynamic_odt dual_D0[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_SAME_DIMM, @@ -193,7 +194,7 @@ static const dynamic_odt_t dual_D0[4] = {  	{0, 0, 0, 0}  }; -static const dynamic_odt_t dual_0D[4] = { +static const struct dynamic_odt dual_0D[4] = {  	{0, 0, 0, 0},  	{0, 0, 0, 0},  	{	/* cs2 */ @@ -210,7 +211,7 @@ static const dynamic_odt_t dual_0D[4] = {  	}  }; -static const dynamic_odt_t dual_S0[4] = { +static const struct dynamic_odt dual_S0[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_CS, @@ -223,7 +224,7 @@ static const dynamic_odt_t dual_S0[4] = {  }; -static const dynamic_odt_t dual_0S[4] = { +static const struct dynamic_odt dual_0S[4] = {  	{0, 0, 0, 0},  	{0, 0, 0, 0},  	{	/* cs2 */ @@ -236,7 +237,7 @@ static const dynamic_odt_t dual_0S[4] = {  }; -static const dynamic_odt_t odt_unknown[4] = { +static const struct dynamic_odt odt_unknown[4] = {  	{	/* cs0 */  		FSL_DDR_ODT_NEVER,  		FSL_DDR_ODT_CS, @@ -262,7 +263,218 @@ static const dynamic_odt_t odt_unknown[4] = {  		DDR3_RTT_OFF  	}  }; +#else	/* CONFIG_FSL_DDR3 */ +static const struct dynamic_odt single_Q[4] = { +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0} +}; + +static const struct dynamic_odt single_D[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_ALL, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs1 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0} +}; +static const struct dynamic_odt single_S[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_ALL, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +}; + +static const struct dynamic_odt dual_DD[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs1 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	}, +	{	/* cs2 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs3 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	} +}; + +static const struct dynamic_odt dual_DS[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs1 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	}, +	{	/* cs2 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_SD[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{	/* cs2 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs3 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	} +}; + +static const struct dynamic_odt dual_SS[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{	/* cs2 */ +		FSL_DDR_ODT_OTHER_DIMM, +		FSL_DDR_ODT_OTHER_DIMM, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_D0[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_ALL, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs1 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_0D[4] = { +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{	/* cs2 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_ALL, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs3 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	} +}; + +static const struct dynamic_odt dual_S0[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_CS, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{0, 0, 0, 0} + +}; + +static const struct dynamic_odt dual_0S[4] = { +	{0, 0, 0, 0}, +	{0, 0, 0, 0}, +	{	/* cs2 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_CS, +		DDR2_RTT_150_OHM, +		DDR2_RTT_OFF +	}, +	{0, 0, 0, 0} + +}; + +static const struct dynamic_odt odt_unknown[4] = { +	{	/* cs0 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_CS, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs1 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	}, +	{	/* cs2 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_CS, +		DDR2_RTT_75_OHM, +		DDR2_RTT_OFF +	}, +	{	/* cs3 */ +		FSL_DDR_ODT_NEVER, +		FSL_DDR_ODT_NEVER, +		DDR2_RTT_OFF, +		DDR2_RTT_OFF +	} +}; +#endif  unsigned int populate_memctl_options(int all_DIMMs_registered,  			memctl_options_t *popts,  			dimm_params_t *pdimm, @@ -271,7 +483,8 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  	unsigned int i;  	char buffer[HWCONFIG_BUFFER_SIZE];  	char *buf = NULL; -	const dynamic_odt_t *pdodt = odt_unknown; +	const struct dynamic_odt *pdodt = odt_unknown; +	ulong ddr_freq;  	/*  	 * Extract hwconfig from environment since we have not properly setup @@ -336,7 +549,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  	/* Pick chip-select local options. */  	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { -#if defined(CONFIG_FSL_DDR3) +#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2)  		popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;  		popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;  		popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; @@ -716,6 +929,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  	if (pdimm[0].n_ranks == 4)  		popts->quad_rank_present = 1; +	ddr_freq = get_ddr_freq(0) / 1000000; +	if (popts->registered_dimm_en) { +		popts->rcw_override = 1; +		popts->rcw_1 = 0x000a5a00; +		if (ddr_freq <= 800) +			popts->rcw_2 = 0x00000000; +		else if (ddr_freq <= 1066) +			popts->rcw_2 = 0x00100000; +		else if (ddr_freq <= 1333) +			popts->rcw_2 = 0x00200000; +		else +			popts->rcw_2 = 0x00300000; +	} +  	fsl_ddr_board_options(popts, pdimm, ctrl_num);  	return 0; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c index 104d360a5f1..eb6a17a8503 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c @@ -20,7 +20,8 @@  #define ULL_8FS 0xFFFFFFFFULL  /* - * Round mclk_ps to nearest 10 ps in memory controller code. + * Round up mclk_ps to nearest 1 ps in memory controller code + * if the error is 0.5ps or more.   *   * If an imprecise data rate is too high due to rounding error   * propagation, compute a suitably rounded mclk_ps to compute @@ -32,42 +33,37 @@ unsigned int get_memory_clk_period_ps(void)  	unsigned int result;  	/* Round to nearest 10ps, being careful about 64-bit multiply/divide */ -	unsigned long long mclk_ps = ULL_2E12; - -	/* Add 5*data_rate, for rounding */ -	mclk_ps += 5*(unsigned long long)data_rate; +	unsigned long long rem, mclk_ps = ULL_2E12;  	/* Now perform the big divide, the result fits in 32-bits */ -	do_div(mclk_ps, data_rate); -	result = mclk_ps; +	rem = do_div(mclk_ps, data_rate); +	result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; -	/* We still need to round to 10ps */ -	return 10 * (result/10); +	return result;  }  /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */  unsigned int picos_to_mclk(unsigned int picos)  {  	unsigned long long clks, clks_rem; +	unsigned long data_rate = get_ddr_freq(0);  	/* Short circuit for zero picos */  	if (!picos)  		return 0;  	/* First multiply the time by the data rate (32x32 => 64) */ -	clks = picos * (unsigned long long)get_ddr_freq(0); - +	clks = picos * (unsigned long long)data_rate;  	/*  	 * Now divide by 5^12 and track the 32-bit remainder, then divide  	 * by 2*(2^12) using shifts (and updating the remainder).  	 */  	clks_rem = do_div(clks, UL_5POW12); -	clks_rem <<= 13; -	clks_rem |= clks & (UL_2POW13-1); +	clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12;  	clks >>= 13; -	/* If we had a remainder, then round up */ -	if (clks_rem) +	/* If we had a remainder greater than the 1ps error, then round up */ +	if (clks_rem > data_rate)  		clks++;  	/* Clamp to the maximum representable value */ @@ -133,10 +129,13 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,  void board_add_ram_info(int use_default)  { -#if defined(CONFIG_MPC85xx) -	volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); +#if defined(CONFIG_MPC83xx) +	immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +	ccsr_ddr_t *ddr = (void *)&immap->ddr; +#elif defined(CONFIG_MPC85xx) +	ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);  #elif defined(CONFIG_MPC86xx) -	volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); +	ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);  #endif  #if (CONFIG_NUM_DDR_CONTROLLERS > 1)  	uint32_t cs0_config = in_be32(&ddr->cs0_config); diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 285051d96c1..5bb9f535422 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/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index e79482130e8..66824960d3f 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -43,10 +43,12 @@ void init_early_memctl_regs(void)  	set_ifc_ftim(IFC_CS0, IFC_FTIM2, CONFIG_SYS_CS0_FTIM2);  	set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3); +#if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT)  	set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0);  	set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0);  	set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0);  #endif +#endif  #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1)  	set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); | 
