diff options
Diffstat (limited to 'arch/powerpc')
33 files changed, 2277 insertions, 192 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index fe851f15d..b7c027210 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -64,12 +64,20 @@ COBJS-$(CONFIG_PPC_P5020)	+= ddr-gen3.o  COBJS-$(CONFIG_CPM2)	+= ether_fcc.o  COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +COBJS-$(CONFIG_FSL_CORENET) += liodn.o  COBJS-$(CONFIG_MP)	+= mp.o  COBJS-$(CONFIG_MPC8536) += mpc8536_serdes.o  COBJS-$(CONFIG_P1022)	+= p1022_serdes.o  COBJS-$(CONFIG_PCI)	+= pci.o +COBJS-$(CONFIG_FSL_CORENET) += portals.o + +# various SoC specific assignments +COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o +  COBJS-$(CONFIG_QE)	+= qe_io.o  COBJS-$(CONFIG_CPM2)	+= serial_scc.o +COBJS-$(CONFIG_FSL_CORENET) += fsl_corenet_serdes.o +COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o  COBJS	= $(COBJS-y)  COBJS	+= cpu.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index d7835c8d6..d73f3d7f1 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -41,6 +41,12 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	}  #endif +#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8) +	puts("Work-around for Erratum SERDES8 enabled\n"); +#endif +#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) +	puts("Work-around for Erratum CPU22 enabled\n"); +#endif  	return 0;  } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 5d5b4c296..2c3be6dd0 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -32,6 +32,7 @@  #include <ioports.h>  #include <sata.h>  #include <asm/io.h> +#include <asm/cache.h>  #include <asm/mmu.h>  #include <asm/fsl_law.h>  #include <asm/fsl_serdes.h> @@ -127,6 +128,44 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm)  }  #endif +#ifdef CONFIG_SYS_FSL_CPC +static void enable_cpc(void) +{ +	int i; +	u32 size = 0; + +	cpc_corenet_t *cpc = (cpc_corenet_t *)CONFIG_SYS_FSL_CPC_ADDR; + +	for (i = 0; i < CONFIG_SYS_NUM_CPC; i++, cpc++) { +		u32 cpccfg0 = in_be32(&cpc->cpccfg0); +		size += CPC_CFG0_SZ_K(cpccfg0); + +		out_be32(&cpc->cpccsr0, CPC_CSR0_CE | CPC_CSR0_PE); +		/* Read back to sync write */ +		in_be32(&cpc->cpccsr0); + +	} + +	printf("Corenet Platform Cache: %d KB enabled\n", size); +} + +void invalidate_cpc(void) +{ +	int i; +	cpc_corenet_t *cpc = (cpc_corenet_t *)CONFIG_SYS_FSL_CPC_ADDR; + +	for (i = 0; i < CONFIG_SYS_NUM_CPC; i++, cpc++) { +		/* Flash invalidate the CPC and clear all the locks */ +		out_be32(&cpc->cpccsr0, CPC_CSR0_FI | CPC_CSR0_LFC); +		while (in_be32(&cpc->cpccsr0) & (CPC_CSR0_FI | CPC_CSR0_LFC)) +			; +	} +} +#else +#define enable_cpc() +#define invalidate_cpc() +#endif /* CONFIG_SYS_FSL_CPC */ +  /*   * Breathe some life into the CPU...   * @@ -188,6 +227,9 @@ void cpu_init_f (void)  	corenet_tb_init();  #endif  	init_used_tlb_cams(); + +	/* Invalidate the CPC before DDR gets enabled */ +	invalidate_cpc();  } @@ -198,13 +240,18 @@ void cpu_init_f (void)   * use the same bit-encoding as the older 8555, etc, parts.   *   */ -  int cpu_init_r(void)  {  #ifdef CONFIG_SYS_LBC_LCRR  	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;  #endif +#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) +	flush_dcache(); +	mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS)); +	sync(); +#endif +  	puts ("L2:    ");  #if defined(CONFIG_L2_CACHE) @@ -319,6 +366,9 @@ int cpu_init_r(void)  #else  	puts("disabled\n");  #endif + +	enable_cpc(); +  #ifdef CONFIG_QE  	uint qe_base = CONFIG_SYS_IMMR + 0x00080000; /* QE immr base */  	qe_init(qe_base); diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 0691ca455..e46dcb704 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -33,6 +33,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  		return;  	} +	out_be32(&ddr->eor, regs->ddr_eor); +  	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 932466e88..8e7b827ff 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -28,6 +28,8 @@  #include <fdt_support.h>  #include <asm/processor.h>  #include <linux/ctype.h> +#include <asm/io.h> +#include <asm/fsl_portals.h>  #ifdef CONFIG_FSL_ESDHC  #include <fsl_esdhc.h>  #endif @@ -80,7 +82,30 @@ void ft_fixup_cpu(void *blob, u64 memory_limit)  }  #endif +#ifdef CONFIG_SYS_FSL_CPC +static inline void ft_fixup_l3cache(void *blob, int off) +{ +	u32 line_size, num_ways, size, num_sets; +	cpc_corenet_t *cpc = (void *)CONFIG_SYS_FSL_CPC_ADDR; +	u32 cfg0 = in_be32(&cpc->cpccfg0); + +	size = CPC_CFG0_SZ_K(cfg0) * 1024 * CONFIG_SYS_NUM_CPC; +	num_ways = CPC_CFG0_NUM_WAYS(cfg0); +	line_size = CPC_CFG0_LINE_SZ(cfg0); +	num_sets = size / (line_size * num_ways); + +	fdt_setprop(blob, off, "cache-unified", NULL, 0); +	fdt_setprop_cell(blob, off, "cache-block-size", line_size); +	fdt_setprop_cell(blob, off, "cache-size", size); +	fdt_setprop_cell(blob, off, "cache-sets", num_sets); +	fdt_setprop_cell(blob, off, "cache-level", 3); +#ifdef CONFIG_SYS_CACHE_STASHING +	fdt_setprop_cell(blob, off, "cache-stash-id", 1); +#endif +} +#else  #define ft_fixup_l3cache(x, y) +#endif  #if defined(CONFIG_L2_CACHE)  /* return size in kilobytes */ @@ -422,4 +447,18 @@ void ft_cpu_setup(void *blob, bd_t *bd)  #endif  	ft_fixup_dpaa_clks(blob); + +#if defined(CONFIG_SYS_BMAN_MEM_PHYS) +	fdt_portal(blob, "fsl,bman-portal", "bman-portals", +			(u64)CONFIG_SYS_BMAN_MEM_PHYS, +			CONFIG_SYS_BMAN_MEM_SIZE); +#endif + +#if defined(CONFIG_SYS_QMAN_MEM_PHYS) +	fdt_portal(blob, "fsl,qman-portal", "qman-portals", +			(u64)CONFIG_SYS_QMAN_MEM_PHYS, +			CONFIG_SYS_QMAN_MEM_SIZE); + +	fdt_fixup_qportals(blob); +#endif  } diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c new file mode 100644 index 000000000..5bcf91abf --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -0,0 +1,495 @@ +/* + * Copyright 2009-2010 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> +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +#include <hwconfig.h> +#endif +#include <asm/fsl_serdes.h> +#include <asm/immap_85xx.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/fsl_law.h> +#include "fsl_corenet_serdes.h" + +static u32 serdes_prtcl_map; + +#ifdef DEBUG +static const char *serdes_prtcl_str[] = { +	[NONE] = "NA", +	[PCIE1] = "PCIE1", +	[PCIE2] = "PCIE2", +	[PCIE3] = "PCIE3", +	[PCIE4] = "PCIE4", +	[SATA1] = "SATA1", +	[SATA2] = "SATA2", +	[SRIO1] = "SRIO1", +	[SRIO2] = "SRIO2", +	[SGMII_FM1_DTSEC1] = "SGMII_FM1_DTSEC1", +	[SGMII_FM1_DTSEC2] = "SGMII_FM1_DTSEC2", +	[SGMII_FM1_DTSEC3] = "SGMII_FM1_DTSEC3", +	[SGMII_FM1_DTSEC4] = "SGMII_FM1_DTSEC4", +	[SGMII_FM1_DTSEC5] = "SGMII_FM1_DTSEC5", +	[SGMII_FM2_DTSEC1] = "SGMII_FM2_DTSEC1", +	[SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2", +	[SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3", +	[SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4", +	[XAUI_FM1] = "XAUI_FM1", +	[XAUI_FM2] = "XAUI_FM2", +	[AURORA] = "DEBUG", +}; +#endif + +static const struct { +	int idx; +	unsigned int lpd; /* RCW lane powerdown bit */ +	int bank; +} lanes[SRDS_MAX_LANES] = { +	{ 0, 152, FSL_SRDS_BANK_1 }, +	{ 1, 153, FSL_SRDS_BANK_1 }, +	{ 2, 154, FSL_SRDS_BANK_1 }, +	{ 3, 155, FSL_SRDS_BANK_1 }, +	{ 4, 156, FSL_SRDS_BANK_1 }, +	{ 5, 157, FSL_SRDS_BANK_1 }, +	{ 6, 158, FSL_SRDS_BANK_1 }, +	{ 7, 159, FSL_SRDS_BANK_1 }, +	{ 8, 160, FSL_SRDS_BANK_1 }, +	{ 9, 161, FSL_SRDS_BANK_1 }, +	{ 16, 162, FSL_SRDS_BANK_2 }, +	{ 17, 163, FSL_SRDS_BANK_2 }, +	{ 18, 164, FSL_SRDS_BANK_2 }, +	{ 19, 165, FSL_SRDS_BANK_2 }, +	{ 20, 170, FSL_SRDS_BANK_3 }, +	{ 21, 171, FSL_SRDS_BANK_3 }, +	{ 22, 172, FSL_SRDS_BANK_3 }, +	{ 23, 173, FSL_SRDS_BANK_3 }, +}; + +int serdes_get_lane_idx(int lane) +{ +	return lanes[lane].idx; +} + +int serdes_get_bank(int lane) +{ +	return lanes[lane].bank; +} + +int serdes_lane_enabled(int lane) +{ +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; + +	int bank = lanes[lane].bank; +	int word = lanes[lane].lpd / 32; +	int bit = lanes[lane].lpd % 32; + +	if (in_be32(®s->bank[bank].rstctl) & SRDS_RSTCTL_SDPD) +		return 0; + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +	if (!IS_SVR_REV(get_svr(), 1, 0)) +		if (bank > 0) +			return !(srds_lpd_b[bank] & +					(8 >> (lane - (6 + 4 * bank)))); +#endif + +	return !(in_be32(&gur->rcwsr[word]) & (0x80000000 >> bit)); +} + +int is_serdes_configured(enum srds_prtcl device) +{ +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + +	/* Is serdes enabled at all? */ +	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN)) +		return 0; + +	return (1 << device) & serdes_prtcl_map; +} + +#ifndef CONFIG_SYS_DCSRBAR_PHYS +#define CONFIG_SYS_DCSRBAR_PHYS	0x80000000 /* Must be 1GB-aligned for rev1.0 */ +#define CONFIG_SYS_DCSRBAR	0x80000000 +#define __DCSR_NOT_DEFINED_BY_CONFIG +#endif + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +static void enable_bank(ccsr_gur_t *gur, int bank) +{ +	u32 rcw5; + +	/* +	 * Enable the lanes SRDS_LPD_Bn.  The RCW bits are read-only in +	 * CCSR, and read/write in DSCR. +	 */ +	rcw5 = in_be32(gur->rcwsr + 5); +	if (bank == FSL_SRDS_BANK_2) { +		rcw5 &= ~FSL_CORENET_RCWSRn_SRDS_LPD_B2; +		rcw5 |= srds_lpd_b[bank] << 26; +	} else if (bank == FSL_SRDS_BANK_3) { +		rcw5 &= ~FSL_CORENET_RCWSRn_SRDS_LPD_B3; +		rcw5 |= srds_lpd_b[bank] << 18; +	} else { +		printf("SERDES: enable_bank: bad bank %d\n", bank + 1); +		return; +	} + +	/* See similar code in cpu/mpc85xx/cpu_init.c for an explanation +	 * of the DCSR mapping. +	 */ +	{ +#ifdef __DCSR_NOT_DEFINED_BY_CONFIG +		struct law_entry law = find_law(CONFIG_SYS_DCSRBAR_PHYS); +		int law_index; +		if (law.index == -1) +			law_index = set_next_law(CONFIG_SYS_DCSRBAR_PHYS, +						 LAW_SIZE_1M, LAW_TRGT_IF_DCSR); +		else +			set_law(law.index, CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_1M, +				LAW_TRGT_IF_DCSR); +#endif +		u32 *p = (void *)CONFIG_SYS_DCSRBAR + 0x20114; +		out_be32(p, rcw5); +#ifdef __DCSR_NOT_DEFINED_BY_CONFIG +		if (law.index == -1) +			disable_law(law_index); +		else +			set_law(law.index, law.addr, law.size, law.trgt_id); +#endif +	} +} + +/* + * To avoid problems with clock jitter, rev 2 p4080 uses the pll from + * bank 3 to clock banks 2 and 3, as well as a limited selection of + * protocol configurations.  This requires that banks 2 and 3's lanes be + * disabled in the RCW, and enabled with some fixup here to re-enable + * them, and to configure bank 2's clock parameters in bank 3's pll in + * cases where they differ. + */ +static void p4080_erratum_serdes8(serdes_corenet_t *regs, ccsr_gur_t *gur, +				  u32 devdisr, u32 devdisr2, int cfg) +{ +	int srds_ratio_b2; +	int rfck_sel; + +	/* +	 * The disabled lanes of bank 2 will cause the associated +	 * logic blocks to be disabled in DEVDISR.  We reverse that here. +	 * +	 * Note that normally it is not permitted to clear DEVDISR bits +	 * once the device has been disabled, but the hardware people +	 * say that this special case is OK. +	 */ +	clrbits_be32(&gur->devdisr, devdisr); +	clrbits_be32(&gur->devdisr2, devdisr2); + +	/* +	 * Some protocols require special handling.  There are a few +	 * additional protocol configurations that can be used, which are +	 * not listed here.  See app note 4065 for supported protocol +	 * configurations. +	 */ +	switch (cfg) { +	case 0x19: +		/* +		 * Bank 2 has PCIe which wants BWSEL -- tell bank 3's PLL. +		 * SGMII on bank 3 should still be usable. +		 */ +		setbits_be32(®s->bank[FSL_SRDS_BANK_3].pllcr1, +			     SRDS_PLLCR1_PLL_BWSEL); + +		enable_bank(gur, FSL_SRDS_BANK_3); +		break; + +	case 0x0f: +	case 0x10: +		/* +		 * Banks 2 (XAUI) and 3 (SGMII) have different clocking +		 * requirements in these configurations.  Bank 3 cannot +		 * be used and should have its lanes (but not the bank +		 * itself) disabled in the RCW.  We set up bank 3's pll +		 * for bank 2's needs here. +		 */ +		srds_ratio_b2 = (in_be32(&gur->rcwsr[4]) >> 13) & 7; + +		/* Determine refclock from XAUI ratio */ +		switch (srds_ratio_b2) { +		case 1: /* 20:1 */ +			rfck_sel = SRDS_PLLCR0_RFCK_SEL_156_25; +			break; +		case 2: /* 25:1 */ +			rfck_sel = SRDS_PLLCR0_RFCK_SEL_125; +			break; +		default: +			printf("SERDES: bad SRDS_RATIO_B2 %d\n", +			       srds_ratio_b2); +			return; +		} + +		clrsetbits_be32(®s->bank[FSL_SRDS_BANK_3].pllcr0, +				SRDS_PLLCR0_RFCK_SEL_MASK, rfck_sel); + +		clrsetbits_be32(®s->bank[FSL_SRDS_BANK_3].pllcr0, +				SRDS_PLLCR0_FRATE_SEL_MASK, +				SRDS_PLLCR0_FRATE_SEL_6_25); +		break; +	default: +		enable_bank(gur, FSL_SRDS_BANK_3); +	} + +} +#endif + +void fsl_serdes_init(void) +{ +	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	int cfg; +	serdes_corenet_t *srds_regs; +	int lane, bank, idx; +	enum srds_prtcl lane_prtcl; +	long long end_tick; +	int have_bank[SRDS_MAX_BANK] = {}; +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +	u32 serdes8_devdisr = 0; +	u32 serdes8_devdisr2 = 0; +	char srds_lpd_opt[16]; +	const char *srds_lpd_arg; +	size_t arglen; +#endif + +	/* Is serdes enabled at all? */ +	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN)) +		return; + +	srds_regs = (void *)(CONFIG_SYS_FSL_CORENET_SERDES_ADDR); +	cfg = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; +	debug("Using SERDES configuration 0x%x, lane settings:\n", cfg); + +	if (!is_serdes_prtcl_valid(cfg)) { +		printf("SERDES[PRTCL] = 0x%x is not valid\n", cfg); +		return; +	} + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +	if (!IS_SVR_REV(get_svr(), 1, 0)) +		for (bank = 1; bank < ARRAY_SIZE(srds_lpd_b); bank++) { +			sprintf(srds_lpd_opt, "fsl_srds_lpd_b%u", bank + 1); +			srds_lpd_arg = hwconfig_subarg("serdes", srds_lpd_opt, +						       &arglen); +			if (srds_lpd_arg) +				srds_lpd_b[bank] = simple_strtoul(srds_lpd_arg, +								  NULL, 0); +		} +#endif + +	/* Look for banks with all lanes disabled, and power down the bank. */ +	for (lane = 0; lane < SRDS_MAX_LANES; lane++) { +		enum srds_prtcl lane_prtcl = serdes_get_prtcl(cfg, lane); +		if (serdes_lane_enabled(lane)) { +			have_bank[serdes_get_bank(lane)] = 1; +			serdes_prtcl_map |= (1 << lane_prtcl); +		} +	} + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +	if (IS_SVR_REV(get_svr(), 1, 0)) { +		/* At least one bank must be disabled due to SERDES8.  If +		 * no bank is found to be disabled based on lane +		 * disables, disable bank 3 because we can't turn off its +		 * lanes in the RCW without disabling MDIO due to erratum +		 * GEN8. +		 * +		 * This means that if you are relying on bank 3 being +		 * disabled to avoid SERDES8, in some cases you cannot +		 * also disable all lanes of another bank, or else bank +		 * 3 won't be disabled, leaving you with a configuration +		 * that isn't valid according to SERDES8 (e.g. if banks +		 * 2 and 3 have the same clock, and bank 1 is disabled +		 * instead of 3). +		 */ +		for (bank = 0; bank < SRDS_MAX_BANK; bank++) { +			if (!have_bank[bank]) +				break; +		} + +		if (bank == SRDS_MAX_BANK) +			have_bank[FSL_SRDS_BANK_3] = 0; +	} else { +		if (have_bank[FSL_SRDS_BANK_2]) +			have_bank[FSL_SRDS_BANK_3] = 1; +	} +#endif + +	for (bank = 0; bank < SRDS_MAX_BANK; bank++) { +		if (!have_bank[bank]) { +			printf("SERDES: bank %d disabled\n", bank + 1); +			setbits_be32(&srds_regs->bank[bank].rstctl, +				     SRDS_RSTCTL_SDPD); +		} +	} + +	for (lane = 0; lane < SRDS_MAX_LANES; lane++) { +		idx = serdes_get_lane_idx(lane); +		lane_prtcl = serdes_get_prtcl(cfg, lane); + +#ifdef DEBUG +		switch (lane) { +		case 0: +			puts("Bank1: "); +			break; +		case 10: +			puts("\nBank2: "); +			break; +		case 14: +			puts("\nBank3: "); +			break; +		default: +			break; +		} + +		printf("%s ", serdes_prtcl_str[lane_prtcl]); +#endif + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +		switch (lane_prtcl) { +		case PCIE1: +		case PCIE2: +		case PCIE3: +			serdes8_devdisr |= FSL_CORENET_DEVDISR_PCIE1 >> +					   (lane_prtcl - PCIE1); +			break; +		case SRIO1: +		case SRIO2: +			serdes8_devdisr |= FSL_CORENET_DEVDISR_SRIO1 >> +					   (lane_prtcl - SRIO1); +			break; +		case SGMII_FM1_DTSEC1: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | +					    FSL_CORENET_DEVDISR2_DTSEC1_1; +			break; +		case SGMII_FM1_DTSEC2: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | +					    FSL_CORENET_DEVDISR2_DTSEC1_2; +			break; +		case SGMII_FM1_DTSEC3: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | +					    FSL_CORENET_DEVDISR2_DTSEC1_3; +			break; +		case SGMII_FM1_DTSEC4: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | +					    FSL_CORENET_DEVDISR2_DTSEC1_4; +			break; +		case SGMII_FM2_DTSEC1: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | +					    FSL_CORENET_DEVDISR2_DTSEC2_1; +			break; +		case SGMII_FM2_DTSEC2: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | +					    FSL_CORENET_DEVDISR2_DTSEC2_2; +			break; +		case SGMII_FM2_DTSEC3: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | +					    FSL_CORENET_DEVDISR2_DTSEC2_3; +			break; +		case SGMII_FM2_DTSEC4: +			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | +					    FSL_CORENET_DEVDISR2_DTSEC2_4; +			break; +		case XAUI_FM1: +		case XAUI_FM2: +			if (lane_prtcl == XAUI_FM1) +				serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1	| +						    FSL_CORENET_DEVDISR2_10GEC1; +			else +				serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2	| +						    FSL_CORENET_DEVDISR2_10GEC2; +			break; +		case AURORA: +			break; +		default: +			break; +		} + +#endif +	} + +#ifdef DEBUG +	puts("\n"); +#endif + +	for (idx = 0; idx < SRDS_MAX_BANK; idx++) { +		u32 rstctl; + +		bank = idx; + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +		if (!IS_SVR_REV(get_svr(), 1, 0)) { +			/* +			 * Change bank init order to 0, 2, 1, so that the +			 * third bank's PLL is established before we +			 * start the second bank which shares the third +			 * bank's PLL. +			 */ + +			if (idx == 1) +				bank = FSL_SRDS_BANK_3; +			else if (idx == 2) +				bank = FSL_SRDS_BANK_2; +		} +#endif + +		/* Skip disabled banks */ +		if (!have_bank[bank]) +			continue; + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +		if (!IS_SVR_REV(get_svr(), 1, 0)) { +			if (idx == 1) { +				p4080_erratum_serdes8(srds_regs, gur, +						      serdes8_devdisr, +						      serdes8_devdisr2, cfg); +			} else if (idx == 2) { +				enable_bank(gur, FSL_SRDS_BANK_2); +			} +		} +#endif + +		/* reset banks for errata */ +		setbits_be32(&srds_regs->bank[bank].rstctl, SRDS_RSTCTL_RST); + +		/* wait for reset complete or 1-second timeout */ +		end_tick = usec2ticks(1000000) + get_ticks(); +		do { +			rstctl = in_be32(&srds_regs->bank[bank].rstctl); +			if (rstctl & SRDS_RSTCTL_RSTDONE) +				break; +		} while (end_tick > get_ticks()); + +		if (!(rstctl & SRDS_RSTCTL_RSTDONE)) { +			printf("SERDES: timeout resetting bank %d\n", +			       bank + 1); +			continue; +		} +	} +} diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h new file mode 100644 index 000000000..42d771e09 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * Author: Roy Zang <tie-fei.zang@freescale.com> + * + * 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 + */ + +#ifndef __FSL_CORENET_SERDES_H +#define __FSL_CORENET_SERDES_H + +#define SRDS_MAX_LANES		18 +#define SRDS_MAX_BANK		3 + +enum srds_bank { +	FSL_SRDS_BANK_1  = 0, +	FSL_SRDS_BANK_2  = 1, +	FSL_SRDS_BANK_3  = 2, +}; + +int is_serdes_prtcl_valid(u32 prtcl); +int serdes_get_lane_idx(int lane); +int serdes_get_bank(int lane); +int serdes_lane_enabled(int lane); +enum srds_prtcl serdes_get_prtcl(int cfg, int lane); + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +extern uint16_t srds_lpd_b[SRDS_MAX_BANK]; +#endif + +#endif /* __FSL_CORENET_SERDES_H */ diff --git a/arch/powerpc/cpu/mpc85xx/liodn.c b/arch/powerpc/cpu/mpc85xx/liodn.c new file mode 100644 index 000000000..bd1909471 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/liodn.c @@ -0,0 +1,187 @@ +/* + * Copyright 2008-2010 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 <libfdt.h> +#include <fdt_support.h> + +#include <asm/immap_85xx.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> + +int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev, u32 *liodns, int liodn_offset) +{ +	liodns[0] = liodn_bases[dpaa_dev].id[0] + liodn_offset; + +	if (liodn_bases[dpaa_dev].num_ids == 2) +		liodns[1] = liodn_bases[dpaa_dev].id[1] + liodn_offset; + +	return liodn_bases[dpaa_dev].num_ids; +} + +static void set_liodn(struct liodn_id_table *tbl, int size) +{ +	int i; + +	for (i = 0; i < size; i++) { +		u32 liodn; +		if (tbl[i].num_ids == 2) { +			liodn = (tbl[i].id[0] << 16) | tbl[i].id[1]; +		} else { +			liodn = tbl[i].id[0]; +		} + +		out_be32((volatile u32 *)(tbl[i].reg_offset), liodn); +	} +} + +static void setup_sec_liodn_base(void) +{ +	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR; +	u32 base; + +	if (!IS_E_PROCESSOR(get_svr())) +		return; + +	/* QILCR[QSLOM] */ +	out_be32(&sec->qilcr_ms, 0x3ff<<16); + +	base = (liodn_bases[FSL_HW_PORTAL_SEC].id[0] << 16) | +		liodn_bases[FSL_HW_PORTAL_SEC].id[1]; + +	out_be32(&sec->qilcr_ls, base); +} + +#ifdef CONFIG_SYS_DPAA_FMAN +static void setup_fman_liodn_base(enum fsl_dpaa_dev dev, +				  struct liodn_id_table *tbl, int size) +{ +	int i; +	ccsr_fman_t *fm; +	u32 base; + +	switch(dev) { +	case FSL_HW_PORTAL_FMAN1: +		fm = (void *)CONFIG_SYS_FSL_FM1_ADDR; +		break; + +#if (CONFIG_SYS_NUM_FMAN == 2) +	case FSL_HW_PORTAL_FMAN2: +		fm = (void *)CONFIG_SYS_FSL_FM2_ADDR; +		break; +#endif +	default: +		printf("Error: Invalid device type to %s\n", __FUNCTION__); +		return ; +	} + +	base = (liodn_bases[dev].id[0] << 16) | liodn_bases[dev].id[0]; + +	/* setup all bases the same */ +	for (i = 0; i < 32; i++) { +		out_be32(&fm->fm_dma.fmdmplr[i], base); +	} + +	/* update tbl to ... */ +	for (i = 0; i < size; i++) +		tbl[i].id[0] += liodn_bases[dev].id[0]; +} +#endif + +static void setup_pme_liodn_base(void) +{ +#ifdef CONFIG_SYS_DPAA_PME +	ccsr_pme_t *pme = (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR; +	u32 base = (liodn_bases[FSL_HW_PORTAL_PME].id[0] << 16) | +			liodn_bases[FSL_HW_PORTAL_PME].id[1]; + +	out_be32(&pme->liodnbr, base); +#endif +} + +void set_liodns(void) +{ +	/* setup general liodn offsets */ +	set_liodn(liodn_tbl, liodn_tbl_sz); + +	/* setup SEC block liodn bases & offsets if we have one */ +	if (IS_E_PROCESSOR(get_svr())) { +		set_liodn(sec_liodn_tbl, sec_liodn_tbl_sz); +		setup_sec_liodn_base(); +	} + +	/* setup FMAN block(s) liodn bases & offsets if we have one */ +#ifdef CONFIG_SYS_DPAA_FMAN +	set_liodn(fman1_liodn_tbl, fman1_liodn_tbl_sz); +	setup_fman_liodn_base(FSL_HW_PORTAL_FMAN1, fman1_liodn_tbl, +				fman1_liodn_tbl_sz); + +#if (CONFIG_SYS_NUM_FMAN == 2) +	set_liodn(fman2_liodn_tbl, fman2_liodn_tbl_sz); +	setup_fman_liodn_base(FSL_HW_PORTAL_FMAN2, fman2_liodn_tbl, +				fman2_liodn_tbl_sz); +#endif +#endif +	/* setup PME liodn base */ +	setup_pme_liodn_base(); +} + +static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) +{ +	int i; + +	for (i = 0; i < sz; i++) { +		int off; + +		if (tbl[i].compat == NULL) +			continue; + +		off = fdt_node_offset_by_compat_reg(blob, +				tbl[i].compat, tbl[i].compat_offset); +		if (off >= 0) { +			off = fdt_setprop(blob, off, "fsl,liodn", +				&tbl[i].id[0], +				sizeof(u32) * tbl[i].num_ids); +			if (off > 0) +				printf("WARNING unable to set fsl,liodn for " +					"%s: %s\n", +					tbl[i].compat, fdt_strerror(off)); +		} else { +			debug("WARNING: could not set fsl,liodn for %s: %s.\n", +					tbl[i].compat, fdt_strerror(off)); +		} +	} +} + +void fdt_fixup_liodn(void *blob) +{ +	fdt_fixup_liodn_tbl(blob, liodn_tbl, liodn_tbl_sz); +#ifdef CONFIG_SYS_DPAA_FMAN +	fdt_fixup_liodn_tbl(blob, fman1_liodn_tbl, fman1_liodn_tbl_sz); +#if (CONFIG_SYS_NUM_FMAN == 2) +	fdt_fixup_liodn_tbl(blob, fman2_liodn_tbl, fman2_liodn_tbl_sz); +#endif +#endif +	fdt_fixup_liodn_tbl(blob, sec_liodn_tbl, sec_liodn_tbl_sz); +} diff --git a/arch/powerpc/cpu/mpc85xx/p4080_ids.c b/arch/powerpc/cpu/mpc85xx/p4080_ids.c new file mode 100644 index 000000000..3861146b8 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p4080_ids.c @@ -0,0 +1,115 @@ +/* + * Copyright 2010 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> + +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 */ +}; + +struct liodn_id_table liodn_tbl[] = { +	SET_USB_LIODN(1, "fsl-usb2-mph", 127), +	SET_USB_LIODN(2, "fsl-usb2-dr", 157), + +	SET_SDHC_LIODN(1, 156), + +	SET_PCI_LIODN(1, 193), +	SET_PCI_LIODN(2, 194), +	SET_PCI_LIODN(3, 195), + +	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), + +	SET_QMAN_LIODN(31), +	SET_BMAN_LIODN(32), +	SET_PME_LIODN(128), +}; + +#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), +	SET_FMAN_RX_10G_LIODN(1, 0, 15), +}; + +#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), +	SET_FMAN_RX_10G_LIODN(2, 0, 20), +}; +#endif +#endif + +struct liodn_id_table sec_liodn_tbl[] = { +	SET_SEC_JQ_LIODN_ENTRY(0, 146, 154), +	SET_SEC_JQ_LIODN_ENTRY(1, 147, 155), +	SET_SEC_JQ_LIODN_ENTRY(2, 178, 186), +	SET_SEC_JQ_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), +}; + +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 +}; + +int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); +int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); +int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); +int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); diff --git a/arch/powerpc/cpu/mpc85xx/p4080_serdes.c b/arch/powerpc/cpu/mpc85xx/p4080_serdes.c new file mode 100644 index 000000000..87bd79529 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p4080_serdes.c @@ -0,0 +1,98 @@ +/* + * Copyright 2009-2010 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] = { +	[0x2] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0x5] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0x8] = {PCIE1, PCIE1, PCIE3, PCIE3, PCIE2, PCIE2, PCIE2, PCIE2, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0xd] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, SGMII_FM2_DTSEC3, +		SGMII_FM2_DTSEC4, AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM2, XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0xe] = {PCIE1, PCIE1, PCIE3, PCIE3, PCIE2, PCIE2, SGMII_FM2_DTSEC3, +		SGMII_FM2_DTSEC4, AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM2, XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0xf] = {PCIE1, PCIE1, PCIE1, PCIE1, SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2, +		SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, AURORA, AURORA, XAUI_FM2, +		XAUI_FM2, XAUI_FM2, XAUI_FM2, NONE, NONE, NONE, NONE}, +	[0x10] = {PCIE1, PCIE1, PCIE3, PCIE3, SGMII_FM2_DTSEC1, +		SGMII_FM2_DTSEC2, SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		NONE, NONE, NONE, NONE}, +	[0x13] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, +		AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2, +		SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC1, +		SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4}, +	[0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, +		AURORA, AURORA, PCIE3, PCIE3, PCIE3, PCIE3, SGMII_FM1_DTSEC1, +		SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4}, +	[0x1d] = {PCIE1, PCIE1, PCIE3, PCIE3, NONE, SRIO2, NONE, SRIO1, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0x22] = {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +	[0x25] = {PCIE1, PCIE1, PCIE3, PCIE3, SRIO1, SRIO1, SRIO1, SRIO1, +		AURORA, AURORA, XAUI_FM2, XAUI_FM2, XAUI_FM2, XAUI_FM2, +		XAUI_FM1, XAUI_FM1, XAUI_FM1, XAUI_FM1}, +}; + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 +uint16_t srds_lpd_b[SRDS_MAX_BANK]; +#endif + +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; +} diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c new file mode 100644 index 000000000..01aec6e79 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/portals.c @@ -0,0 +1,238 @@ +/* + * Copyright 2008-2010 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 <libfdt.h> +#include <fdt_support.h> + +#include <asm/processor.h> +#include <asm/io.h> + +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> + +static ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_CORENET_QMAN_ADDR; + +void setup_portals(void) +{ +	int i; + +	/* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */ +#ifdef CONFIG_PHYS_64BIT +	out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32)); +#endif +	out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS); + +	for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) { +		u8 sdest = qp_info[i].sdest; +		u16 fliodn = qp_info[i].fliodn; +		u16 dliodn = qp_info[i].dliodn; +		u16 liodn_off = qp_info[i].liodn_offset; + +		out_be32(&qman->qcsp[i].qcsp_lio_cfg, (liodn_off << 16) | +					dliodn); +		/* set frame liodn */ +		out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn); +	} +} + +/* Update portal containter to match LAW setup of portal in phy map */ +void fdt_portal(void *blob, const char *compat, const char *container, +			u64 addr, u32 size) +{ +	int off; + +	off = fdt_node_offset_by_compatible(blob, -1, compat); +	if (off < 0) +		return ; + +	off = fdt_parent_offset(blob, off); +	/* if non-zero assume we have a container */ +	if (off > 0) { +		char buf[60]; +		const char *p, *name; +		u32 *range; +		int len; + +		/* fixup ranges */ +		range = fdt_getprop_w(blob, off, "ranges", &len); +		if (range == NULL) { +			printf("ERROR: container for %s has no ranges", compat); +			return ; +		} + +		range[0] = 0; +		if (len == 16) { +			range[1] = addr >> 32; +			range[2] = addr & 0xffffffff; +			range[3] = size; +		} else { +			range[1] = addr & 0xffffffff; +			range[2] = size; +		} +		fdt_setprop_inplace(blob, off, "ranges", range, len); + +		/* fixup the name */ +		name = fdt_get_name(blob, off, &len); +		p = memchr(name, '@', len); + +		if (p) +			len = p - name; + +		/* if we are given a container name check it +		 * against what we found, if it doesnt match exit out */ +		if (container && (memcmp(container, name, len))) { +			printf("WARNING: container names didn't match %s %s\n", +				container, name); +			return ; +		} + +		memcpy(&buf, name, len); +		len += sprintf(&buf[len], "@%llx", addr); +		fdt_set_name(blob, off, buf); +		return ; +	} + +	printf("ERROR: %s isn't in a container.  Not supported\n", compat); +} + +static int fdt_qportal(void *blob, int off, int id, char *name, +		       enum fsl_dpaa_dev dev, int create) +{ +	int childoff, dev_off, num, ret = 0; +	uint32_t dev_handle; +	u32 liodns[2]; + +	childoff = fdt_subnode_offset(blob, off, name); +	if (create) { +		if (childoff <= 0) +			childoff = fdt_add_subnode(blob, off, name); + +		if (childoff > 0) { +			char handle[64], *p; + +			strncpy(handle, name, sizeof(handle)); +			p = strchr(handle, '@'); +			if (!strncmp(name, "fman", 4)) { +				*p = *(p + 1); +				p++; +			} +			*p = '\0'; + +			dev_off = fdt_path_offset(blob, handle); +			if (dev_off < 0) +				return dev_off; + +			dev_handle = fdt_get_phandle(blob, dev_off); +			if (dev_handle <= 0) { +				dev_handle = fdt_alloc_phandle(blob); +				fdt_setprop_cell(blob, dev_off, +					"linux,phandle", dev_handle); +			} + +			ret = fdt_setprop(blob, childoff, "dev-handle", +					  &dev_handle, sizeof(dev_handle)); +			if (ret < 0) +				return ret; + +			num = get_dpaa_liodn(dev, &liodns[0], id); +			ret = fdt_setprop(blob, childoff, "fsl,liodn", +					  &liodns[0], sizeof(u32) * num); +		} else { +			return childoff; +		} +	} else { +		if (childoff > 0) +			ret = fdt_del_node(blob, childoff); +	} + +	return ret; +} + +void fdt_fixup_qportals(void *blob) +{ +	int off, err; +	unsigned int maj, min; +	u32 rev_1 = in_be32(&qman->ip_rev_1); +	char compat[64]; +	int compat_len; + +	maj = (rev_1 >> 8) & 0xff; +	min = rev_1 & 0xff; + +	compat_len = sprintf(compat, "fsl,qman-portal-%u.%u", maj, min) + 1; +	compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1; + +	off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal"); +	while (off != -FDT_ERR_NOTFOUND) { +		u32 liodns[2]; +		const int *ci = fdt_getprop(blob, off, "cell-index", NULL); +		int j, i = *ci; + +		err = fdt_setprop(blob, off, "compatible", compat, compat_len); +		if (err < 0) +			goto err; + +		liodns[0] = qp_info[i].dliodn; +		liodns[1] = qp_info[i].fliodn; + +		err = fdt_setprop(blob, off, "fsl,liodn", +				  &liodns, sizeof(u32) * 2); +		if (err < 0) +			goto err; + +		i++; + +		err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC, +				  IS_E_PROCESSOR(get_svr())); +		if (err < 0) +			goto err; + +#ifdef CONFIG_SYS_DPAA_PME +		err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1); +		if (err < 0) +			goto err; +#else +		fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0); +#endif +#ifdef CONFIG_SYS_DPAA_FMAN +		for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) { +			char name[] = "fman@0"; + +			name[sizeof(name) - 2] = '0' + j; +			err = fdt_qportal(blob, off, i, name, +					  FSL_HW_PORTAL_FMAN1 + j, 1); +			if (err < 0) +				goto err; +		} +#endif + +err: +		if (err < 0) { +			printf("ERROR: unable to create props for %s: %s\n", +				fdt_get_name(blob, off, NULL), fdt_strerror(err)); +			return; +		} + +		off = fdt_node_offset_by_compatible(blob, off, "fsl,qman-portal"); +	} +} diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 0b5b9da03..53cefaf00 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -136,6 +136,12 @@ __secondary_start_page:  	mtspr	L1CSR2,r8  #endif +#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) +	mfspr	r8,L1CSR2 +	oris	r8,r8,(L1CSR2_DCWS)@h +	mtspr	L1CSR2,r8 +#endif +  #ifdef CONFIG_BACKSIDE_L2_CACHE  	/* Enable/invalidate the L2 cache */  	msync diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index b3cb56a5b..3278b109f 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -330,8 +330,18 @@ _start_e500:  	lis     r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h  	ori     r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l +#if defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW) && \ +    defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH) +	lis     r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, +				(MAS3_SX|MAS3_SW|MAS3_SR))@h +	ori     r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, +				(MAS3_SX|MAS3_SW|MAS3_SR))@l +	li      r10,CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH +	mtspr	MAS7,r10 +#else  	lis     r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h  	ori     r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l +#endif  	mtspr   MAS0,r6  	mtspr   MAS1,r7 diff --git a/arch/powerpc/cpu/mpc8xx/speed.c b/arch/powerpc/cpu/mpc8xx/speed.c index f309f29c0..6e13e5de0 100644 --- a/arch/powerpc/cpu/mpc8xx/speed.c +++ b/arch/powerpc/cpu/mpc8xx/speed.c @@ -266,7 +266,7 @@ int get_clocks_866 (void)  	long		  cpuclk = 0;  	long		  sccr_reg; -	if (getenv_r ("cpuclk", tmp, sizeof (tmp)) > 0) +	if (getenv_f("cpuclk", tmp, sizeof (tmp)) > 0)  		cpuclk = simple_strtoul (tmp, NULL, 10) * 1000000;  	if ((CONFIG_SYS_8xx_CPUCLK_MIN > cpuclk) || (CONFIG_SYS_8xx_CPUCLK_MAX < cpuclk)) diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index dc3da1689..97a94f4cd 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -110,8 +110,14 @@ struct cpu_type *identify_cpu(u32 ver)  }  int cpu_numcores() { -	struct cpu_type *cpu; -	cpu = gd->cpu; +	ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC85xx_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) & MPC85xx_PICFRR_NCPU_MASK) >> +			MPC85xx_PICFRR_NCPU_SHIFT) + 1; +  	return cpu->num_cores;  } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h b/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h index 5aea517f2..06706ed78 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h +++ b/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h @@ -48,6 +48,9 @@ typedef struct {  	unsigned long long total_mem;  	unsigned long long base_address; + +	/* DDR3 RDIMM */ +	unsigned char rcw[16];	/* Register Control Word 0-15 */  } common_timing_params_t;  #endif diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 4a282bc52..dccb7aa14 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -93,7 +93,7 @@ static inline unsigned int compute_cas_write_latency(void)  }  /* Chip Select Configuration (CSn_CONFIG) */ -static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr, +static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,  			       const memctl_options_t *popts,  			       const dimm_params_t *dimm_params)  { @@ -106,28 +106,49 @@ static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr,  	unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */  	unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */  	unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */ +	int go_config = 0;  	/* Compute CS_CONFIG only for existing ranks of each DIMM.  */ -	if ((((i&1) == 0) -	    && (dimm_params[i/2].n_ranks == 1)) -	    || (dimm_params[i/2].n_ranks == 2)) { -		unsigned int n_banks_per_sdram_device; -		cs_n_en = 1; -		if (i == 0) { +	switch (i) { +	case 0: +		if (dimm_params[dimm_number].n_ranks > 0) { +			go_config = 1;  			/* These fields only available in CS0_CONFIG */  			intlv_en = popts->memctl_interleaving;  			intlv_ctl = popts->memctl_interleaving_mode;  		} +		break; +	case 1: +		if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \ +		    (dimm_number == 1 && dimm_params[1].n_ranks > 0)) +			go_config = 1; +		break; +	case 2: +		if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ +		   (dimm_number > 1 && dimm_params[dimm_number].n_ranks > 0)) +			go_config = 1; +		break; +	case 3: +		if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \ +		    (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \ +		    (dimm_number == 3 && dimm_params[3].n_ranks > 0)) +			go_config = 1; +		break; +	default: +		break; +	} +	if (go_config) { +		unsigned int n_banks_per_sdram_device; +		cs_n_en = 1;  		ap_n_en = popts->cs_local_opts[i].auto_precharge;  		odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;  		odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;  		n_banks_per_sdram_device -			= dimm_params[i/2].n_banks_per_sdram_device; +			= dimm_params[dimm_number].n_banks_per_sdram_device;  		ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; -		row_bits_cs_n = dimm_params[i/2].n_row_addr - 12; -		col_bits_cs_n = dimm_params[i/2].n_col_addr - 8; +		row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12; +		col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8;  	} -  	ddr->cs[i].config = (0  		| ((cs_n_en & 0x1) << 31)  		| ((intlv_en & 0x3) << 29) @@ -178,7 +199,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)  	unsigned char act_pd_exit_mclk;  	/* Precharge powerdown exit timing (tXP). */  	unsigned char pre_pd_exit_mclk; -	/* Precharge powerdown exit timing (tAXPD). */ +	/* ODT powerdown exit timing (tAXPD). */  	unsigned char taxpd_mclk;  	/* Mode register set cycle time (tMRD). */  	unsigned char tmrd_mclk; @@ -190,13 +211,13 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)  	 * we use the tXP instead of it.  	 * tXP=max(3nCK, 7.5ns) for DDR3.  	 * spec has not the tAXPD, we use -	 * tAXPD=8, need design to confirm. +	 * tAXPD=1, need design to confirm.  	 */  	int tXP = max((get_memory_clk_period_ps() * 3), 7500); /* unit=ps */  	act_pd_exit_mclk = picos_to_mclk(tXP);  	/* Mode register MR0[A12] is '1' - fast exit */  	pre_pd_exit_mclk = act_pd_exit_mclk; -	taxpd_mclk = 8; +	taxpd_mclk = 1;  	tmrd_mclk = 4;  	/* set the turnaround time */  	trwt_mclk = 1; @@ -427,6 +448,35 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,  	debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);  } +/* DDR SDRAM Register Control Word */ +static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, +			       const common_timing_params_t *common_dimm) +{ +	if (common_dimm->all_DIMMs_registered +		&& !common_dimm->all_DIMMs_unbuffered) { +		ddr->ddr_sdram_rcw_1 = +			common_dimm->rcw[0] << 28 | \ +			common_dimm->rcw[1] << 24 | \ +			common_dimm->rcw[2] << 20 | \ +			common_dimm->rcw[3] << 16 | \ +			common_dimm->rcw[4] << 12 | \ +			common_dimm->rcw[5] << 8 | \ +			common_dimm->rcw[6] << 4 | \ +			common_dimm->rcw[7]; +		ddr->ddr_sdram_rcw_2 = +			common_dimm->rcw[8] << 28 | \ +			common_dimm->rcw[9] << 24 | \ +			common_dimm->rcw[10] << 20 | \ +			common_dimm->rcw[11] << 16 | \ +			common_dimm->rcw[12] << 12 | \ +			common_dimm->rcw[13] << 8 | \ +			common_dimm->rcw[14] << 4 | \ +			common_dimm->rcw[15]; +		debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); +		debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); +	} +} +  /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */  static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,  			       const memctl_options_t *popts, @@ -521,6 +571,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,  	unsigned int d_init;		/* DRAM data initialization */  	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 */  	dll_rst_dis = 1;	/* Make this configurable */  	dqs_cfg = popts->DQS_config; @@ -562,6 +613,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,  #if defined(CONFIG_FSL_DDR3)  	md_en = popts->mirrored_dimm;  #endif +	qd_en = popts->quad_rank_present ? 1 : 0;  	ddr->ddr_sdram_cfg_2 = (0  		| ((frc_sr & 0x1) << 31)  		| ((sr_ie & 0x1) << 30) @@ -569,6 +621,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,  		| ((dqs_cfg & 0x3) << 26)  		| ((odt_cfg & 0x3) << 21)  		| ((num_pr & 0xf) << 12) +		| (qd_en << 9)  		| ((obc_cfg & 0x1) << 6)  		| ((ap_en & 0x1) << 5)  		| ((d_init & 0x1) << 4) @@ -914,6 +967,7 @@ static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,  	clk_adjust = popts->clk_adjust;  	ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23; +	debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);  }  /* DDR Initialization Address (DDR_INIT_ADDR) */ @@ -977,9 +1031,9 @@ static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr)  	unsigned int wodt_off = 0;	/* Write to ODT off */  #if defined(CONFIG_FSL_DDR3) -	rodt_on = 3;	/*  2 clocks */ +	rodt_on = 2;	/*  2 clocks */  	rodt_off = 4;	/*  4 clocks */ -	wodt_on = 2;	/*  1 clocks */ +	wodt_on = 1;	/*  1 clocks */  	wodt_off = 4;	/*  4 clocks */  #endif @@ -1052,9 +1106,9 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,  		/*  		 * Write leveling repetition time  		 * at least tWLO + 6 clocks clocks -		 * we set it 32 +		 * we set it 64  		 */ -		wrlvl_wlr = 0x5; +		wrlvl_wlr = 0x6;  		/*  		 * Write leveling start time  		 * The value use for the DQS_ADJUST for the first sample @@ -1089,52 +1143,12 @@ static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)  	ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;  } -/* DDR SDRAM Register Control Word 1 (DDR_SDRAM_RCW_1) */ -static void set_ddr_sdram_rcw_1(fsl_ddr_cfg_regs_t *ddr) -{ -	unsigned int rcw0 = 0;	/* RCW0: Register Control Word 0 */ -	unsigned int rcw1 = 0;	/* RCW1: Register Control Word 1 */ -	unsigned int rcw2 = 0;	/* RCW2: Register Control Word 2 */ -	unsigned int rcw3 = 0;	/* RCW3: Register Control Word 3 */ -	unsigned int rcw4 = 0;	/* RCW4: Register Control Word 4 */ -	unsigned int rcw5 = 0;	/* RCW5: Register Control Word 5 */ -	unsigned int rcw6 = 0;	/* RCW6: Register Control Word 6 */ -	unsigned int rcw7 = 0;	/* RCW7: Register Control Word 7 */ - -	ddr->ddr_sdram_rcw_1 = (0 -				| ((rcw0 & 0xF) << 28) -				| ((rcw1 & 0xF) << 24) -				| ((rcw2 & 0xF) << 20) -				| ((rcw3 & 0xF) << 16) -				| ((rcw4 & 0xF) << 12) -				| ((rcw5 & 0xF) << 8) -				| ((rcw6 & 0xF) << 4) -				| ((rcw7 & 0xF) << 0) -				); -} - -/* DDR SDRAM Register Control Word 2 (DDR_SDRAM_RCW_2) */ -static void set_ddr_sdram_rcw_2(fsl_ddr_cfg_regs_t *ddr) +static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)  { -	unsigned int rcw8 = 0;	/* RCW0: Register Control Word 8 */ -	unsigned int rcw9 = 0;	/* RCW1: Register Control Word 9 */ -	unsigned int rcw10 = 0;	/* RCW2: Register Control Word 10 */ -	unsigned int rcw11 = 0;	/* RCW3: Register Control Word 11 */ -	unsigned int rcw12 = 0;	/* RCW4: Register Control Word 12 */ -	unsigned int rcw13 = 0;	/* RCW5: Register Control Word 13 */ -	unsigned int rcw14 = 0;	/* RCW6: Register Control Word 14 */ -	unsigned int rcw15 = 0;	/* RCW7: Register Control Word 15 */ - -	ddr->ddr_sdram_rcw_2 = (0 -				| ((rcw8 & 0xF) << 28) -				| ((rcw9 & 0xF) << 24) -				| ((rcw10 & 0xF) << 20) -				| ((rcw11 & 0xF) << 16) -				| ((rcw12 & 0xF) << 12) -				| ((rcw13 & 0xF) << 8) -				| ((rcw14 & 0xF) << 4) -				| ((rcw15 & 0xF) << 0) -				); +	if (popts->addr_hash) { +		ddr->ddr_eor = 0x40000000;	/* address hash enable */ +		puts("Addess hashing enabled.\n"); +	}  }  unsigned int @@ -1201,37 +1215,63 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  	/* Chip Select Memory Bounds (CSn_BNDS) */  	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {  		unsigned long long ea = 0, sa = 0; +		unsigned int cs_per_dimm +			= CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; +		unsigned int dimm_number +			= i / cs_per_dimm; +		unsigned long long rank_density +			= dimm_params[dimm_number].rank_density; -		if (popts->ba_intlv_ctl && (i > 0) && -			((popts->ba_intlv_ctl & 0x60) != FSL_DDR_CS2_CS3 )) { -			/* Don't set up boundaries for other CS -			 * other than CS0, if bank interleaving -			 * is enabled and not CS2+CS3 interleaved. +		if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) || +			((i == 2) && (popts->ba_intlv_ctl & 0x04)) || +			((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) { +			/* +			 * Don't set up boundaries for unused CS +			 * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 +			 * cs2 for cs0_cs1_cs2_cs3 +			 * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3  			 * But we need to set the ODT_RD_CFG and  			 * ODT_WR_CFG for CS1_CONFIG here.  			 */ -			set_csn_config(i, ddr, popts, dimm_params); -			break; +			set_csn_config(dimm_number, i, ddr, popts, dimm_params); +			continue;  		} - -		if (dimm_params[i/2].n_ranks == 0) { +		if (dimm_params[dimm_number].n_ranks == 0) {  			debug("Skipping setup of CS%u " -				"because n_ranks on DIMM %u is 0\n", i, i/2); +				"because n_ranks on DIMM %u is 0\n", i, dimm_number);  			continue;  		}  		if (popts->memctl_interleaving && popts->ba_intlv_ctl) {  			/*  			 * This works superbank 2CS -			 * There are 2 memory controllers configured +			 * There are 2 or more memory controllers configured  			 * identically, memory is interleaved between them,  			 * and each controller uses rank interleaving within  			 * itself. Therefore the starting and ending address  			 * on each controller is twice the amount present on  			 * each controller.  			 */ -			unsigned long long rank_density -					= dimm_params[0].capacity; -			ea = (2 * (rank_density >> dbw_cap_adj)) - 1; +			unsigned long long ctlr_density = 0; +			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { +			case FSL_DDR_CS0_CS1: +			case FSL_DDR_CS0_CS1_AND_CS2_CS3: +				ctlr_density = dimm_params[0].rank_density * 2; +				break; +			case FSL_DDR_CS2_CS3: +				ctlr_density = dimm_params[0].rank_density; +				break; +			case FSL_DDR_CS0_CS1_CS2_CS3: +				/* +				 * The four CS interleaving should have been verified by +				 * populate_memctl_options() +				 */ +				ctlr_density = dimm_params[0].rank_density * 4; +				break; +			default: +				break; +			} +			ea = (CONFIG_NUM_DDR_CONTROLLERS * +				(ctlr_density >> dbw_cap_adj)) - 1;  		}  		else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) {  			/* @@ -1243,8 +1283,6 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  			 * controller needs to be programmed into its  			 * respective CS0_BNDS.  			 */ -			unsigned long long rank_density -						= dimm_params[i/2].rank_density;  			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {  			case FSL_DDR_CS0_CS1_CS2_CS3:  				/* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS @@ -1257,9 +1295,13 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  				/* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS  				 * and CS2_CNDS need to be set.  				 */ -				if (!(i&1)) { -					sa = dimm_params[i/2].base_address; -					ea = sa + (i * (rank_density >> +				if ((i == 2) && (dimm_number == 0)) { +					sa = dimm_params[dimm_number].base_address + +					      2 * (rank_density >> dbw_cap_adj); +					ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1; +				} else { +					sa = dimm_params[dimm_number].base_address; +					ea = sa + (2 * (rank_density >>  						dbw_cap_adj)) - 1;  				}  				break; @@ -1267,16 +1309,31 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  				/* CS0+CS1 interleaving, CS0_CNDS needs  				 * to be set  				 */ -				sa = common_dimm->base_address; -				ea = sa + (2 * (rank_density >> dbw_cap_adj))-1; +				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { +					sa = dimm_params[dimm_number].base_address; +					ea = sa + (rank_density >> dbw_cap_adj) - 1; +					sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +					ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +				} else { +					sa = 0; +					ea = 0; +				} +				if (i == 0) +					ea += (rank_density >> dbw_cap_adj);  				break;  			case FSL_DDR_CS2_CS3:  				/* CS2+CS3 interleaving*/ -				if (i == 2) { -					sa = dimm_params[i/2].base_address; -					ea = sa + (2 * (rank_density >> -						dbw_cap_adj)) - 1; +				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { +					sa = dimm_params[dimm_number].base_address; +					ea = sa + (rank_density >> dbw_cap_adj) - 1; +					sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +					ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +				} else { +					sa = 0; +					ea = 0;  				} +				if (i == 2) +					ea += (rank_density >> dbw_cap_adj);  				break;  			default:  /* No bank(chip-select) interleaving */  				break; @@ -1292,8 +1349,6 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  			 * memory in the two CS0 ranks.  			 */  			if (i == 0) { -				unsigned long long rank_density -						= dimm_params[0].rank_density;  				ea = (2 * (rank_density >> dbw_cap_adj)) - 1;  			} @@ -1303,20 +1358,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  			 * No rank interleaving and no memory controller  			 * interleaving.  			 */ -			unsigned long long rank_density -						= dimm_params[i/2].rank_density; -			sa = dimm_params[i/2].base_address; +			sa = dimm_params[dimm_number].base_address;  			ea = sa + (rank_density >> dbw_cap_adj) - 1; -			if (i&1) { -				if ((dimm_params[i/2].n_ranks == 1)) { -					/* Odd chip select, single-rank dimm */ -					sa = 0; -					ea = 0; -				} else { -					/* Odd chip select, dual-rank DIMM */ -					sa += rank_density >> dbw_cap_adj; -					ea += rank_density >> dbw_cap_adj; -				} +			if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { +				sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +				ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); +			} else { +				sa = 0; +				ea = 0;  			}  		} @@ -1329,10 +1378,12 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  			);  		debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); -		set_csn_config(i, ddr, popts, dimm_params); +		set_csn_config(dimm_number, i, ddr, popts, dimm_params);  		set_csn_config_2(i, ddr);  	} +	set_ddr_eor(ddr, popts); +  #if !defined(CONFIG_FSL_DDR1)  	set_timing_cfg_0(ddr);  #endif @@ -1361,8 +1412,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,  	set_ddr_sr_cntr(ddr, sr_it); -	set_ddr_sdram_rcw_1(ddr); -	set_ddr_sdram_rcw_2(ddr); +	set_ddr_sdram_rcw(ddr, common_dimm);  	return check_fsl_memctl_config_regs(ddr);  } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h index f1220750d..98acb8dd5 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h @@ -73,6 +73,7 @@ extern unsigned int populate_memctl_options(int all_DIMMs_registered,  				memctl_options_t *popts,  				dimm_params_t *pdimm,  				unsigned int ctrl_num); +extern void check_interleaving_options(fsl_ddr_info_t *pinfo);  extern unsigned int mclk_to_picos(unsigned int mclk);  extern unsigned int get_memory_clk_period_ps(void); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index d4199baa8..29cea5326 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,  {  	unsigned int retval;  	unsigned int mtb_ps; +	int i;  	if (spd->mem_type) {  		if (spd->mem_type != SPD_MEMTYPE_DDR3) { @@ -131,8 +132,11 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,  	case 0x01:	/* RDIMM */  	case 0x05:	/* Mini-RDIMM */  		pdimm->registered_dimm = 1; /* register buffered */ +		for (i = 0; i < 16; i += 2) { +			pdimm->rcw[i] = spd->mod_section.registered.rcw[i/2] & 0x0F; +			pdimm->rcw[i+1] = (spd->mod_section.registered.rcw[i/2] >> 4) & 0x0F; +		}  		break; -  	case 0x02:	/* UDIMM */  	case 0x03:	/* SO-DIMM */  	case 0x04:	/* Micro-DIMM */ 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 e888e3ea5..029e566b6 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -76,7 +76,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,  				      common_timing_params_t *outpdimm,  				      unsigned int number_of_dimms)  { -	unsigned int i; +	unsigned int i, j;  	unsigned int tCKmin_X_ps = 0;  	unsigned int tCKmax_ps = 0xFFFFFFFF; @@ -98,7 +98,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,  	unsigned int tDQSQ_max_ps = 0;  	unsigned int tQHS_ps = 0; -	unsigned int temp1, temp2; +	unsigned int temp1, temp2, temp3;  	unsigned int additive_latency = 0;  #if !defined(CONFIG_FSL_DDR3)  	const unsigned int mclk_ps = get_memory_clk_period_ps(); @@ -118,6 +118,18 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,  			temp1++;  			continue;  		} +		if (dimm_params[i].n_ranks == 4 && i != 0) { +			printf("Found Quad-rank DIMM in wrong bank, ignored." +				" Software may not run as expected.\n"); +			temp1++; +			continue; +		} +		if (dimm_params[i].n_ranks == 4 && \ +		  CONFIG_CHIP_SELECTS_PER_CTRL/CONFIG_DIMM_SLOTS_PER_CTLR < 4) { +			printf("Found Quad-rank DIMM, not able to support."); +			temp1++; +			continue; +		}  		/*  		 * Find minimum tCKmax_ps to find fastest slow speed, @@ -219,6 +231,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,  				"DIMMs detected!\n");  	} +	temp1 = 0; +	if (outpdimm->all_DIMMs_registered) +		for (j = 0; j < 16; j++) { +			outpdimm->rcw[j] = dimm_params[0].rcw[j]; +			for (i = 1; i < number_of_dimms; i++) +				if (dimm_params[i].rcw[j] != dimm_params[0].rcw[j]) { +					temp3 = 1; +					break; +				} +		} + +	if (temp1 != 0) +		printf("ERROR: Mix different RDIMM detected!\n"); +  #if defined(CONFIG_FSL_DDR3)  	if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms))  		return 1; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index faa1af95e..6d582e97d 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -100,8 +100,8 @@ const char * step_to_string(unsigned int step) {  int step_assign_addresses(fsl_ddr_info_t *pinfo,  			  unsigned int dbw_cap_adj[], -			  unsigned int *memctl_interleaving, -			  unsigned int *rank_interleaving) +			  unsigned int *all_memctl_interleaving, +			  unsigned int *all_ctlr_rank_interleaving)  {  	int i, j; @@ -152,30 +152,30 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,  		}  	} -	/* -	 * Check if all controllers are configured for memory -	 * controller interleaving. -	 */  	j = 0; -	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { -		if (pinfo->memctl_opts[i].memctl_interleaving) { +	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) +		if (pinfo->memctl_opts[i].memctl_interleaving)  			j++; -		} -	} -	if (j == 2) -		*memctl_interleaving = 1; +	/* +	 * Not support less than all memory controllers interleaving +	 * if more than two controllers +	 */ +	if (j == CONFIG_NUM_DDR_CONTROLLERS) +		*all_memctl_interleaving = 1;  	/* Check that all controllers are rank interleaving. */  	j = 0; -	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { -		if (pinfo->memctl_opts[i].ba_intlv_ctl) { +	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) +		if (pinfo->memctl_opts[i].ba_intlv_ctl)  			j++; -		} -	} -	if (j == 2) -		*rank_interleaving = 1; +	/* +	 * All memory controllers must be populated to qualify for +	 * all controller rank interleaving +	 */ +	 if (j == CONFIG_NUM_DDR_CONTROLLERS) +		*all_ctlr_rank_interleaving = 1; -	if (*memctl_interleaving) { +	if (*all_memctl_interleaving) {  		unsigned long long addr, total_mem_per_ctlr = 0;  		/*  		 * If interleaving between memory controllers, @@ -316,7 +316,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)  					&pinfo->memctl_opts[i],  					pinfo->dimm_params[i], i);  		} - +		check_interleaving_options(pinfo);  	case STEP_ASSIGN_ADDRESSES:  		/* STEP 5:  Assign addresses to chip selects */  		step_assign_addresses(pinfo, diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 46731c815..774c0e4b4 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -8,6 +8,7 @@   */  #include <common.h> +#include <hwconfig.h>  #include <asm/fsl_ddr_sdram.h>  #include "ddr.h" @@ -23,7 +24,6 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  			unsigned int ctrl_num)  {  	unsigned int i; -	const char *p;  	/* Chip select options. */ @@ -204,6 +204,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  	 * meet the tQDSS under different loading.  	 */  	popts->wrlvl_en = 1; +	popts->zq_en = 1;  	popts->wrlvl_override = 0;  #endif @@ -212,78 +213,128 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  	 * Please refer to doc/README.fsl-ddr for the detail.  	 *  	 * If memory controller interleaving is enabled, then the data -	 * bus widths must be programmed identically for the 2 memory -	 * controllers. +	 * bus widths must be programmed identically for all memory controllers.  	 * -	 * XXX: Attempt to set both controllers to the same chip select +	 * XXX: Attempt to set all controllers to the same chip select  	 * interleaving mode. It will do a best effort to get the  	 * requested ranks interleaved together such that the result  	 * should be a subset of the requested configuration.  	 */  #if (CONFIG_NUM_DDR_CONTROLLERS > 1) -	if ((p = getenv("memctl_intlv_ctl")) != NULL) { +	if (hwconfig_sub("fsl_ddr", "ctlr_intlv")) {  		if (pdimm[0].n_ranks == 0) { -			printf("There is no rank on CS0. Because only rank on " -				"CS0 and ranks chip-select interleaved with CS0" +			printf("There is no rank on CS0 for controller %d. Because only" +				" rank on CS0 and ranks chip-select interleaved with CS0"  				" are controller interleaved, force non memory " -				"controller interleaving\n"); +				"controller interleaving\n", ctrl_num);  			popts->memctl_interleaving = 0;  		} else {  			popts->memctl_interleaving = 1; -			if (strcmp(p, "cacheline") == 0) +			/* +			 * test null first. if CONFIG_HWCONFIG is not defined +			 * hwconfig_arg_cmp returns non-zero +			 */ +			if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "null")) { +				popts->memctl_interleaving = 0; +				debug("memory controller interleaving disabled.\n"); +			} else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "cacheline"))  				popts->memctl_interleaving_mode =  					FSL_DDR_CACHE_LINE_INTERLEAVING; -			else if (strcmp(p, "page") == 0) +			else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "page"))  				popts->memctl_interleaving_mode =  					FSL_DDR_PAGE_INTERLEAVING; -			else if (strcmp(p, "bank") == 0) +			else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "bank"))  				popts->memctl_interleaving_mode =  					FSL_DDR_BANK_INTERLEAVING; -			else if (strcmp(p, "superbank") == 0) +			else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "superbank"))  				popts->memctl_interleaving_mode =  					FSL_DDR_SUPERBANK_INTERLEAVING; -			else -				popts->memctl_interleaving_mode = -						simple_strtoul(p, NULL, 0); +			else { +				popts->memctl_interleaving = 0; +				printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); +			}  		}  	}  #endif - -	if( ((p = getenv("ba_intlv_ctl")) != NULL) && +	if ((hwconfig_sub("fsl_ddr", "bank_intlv")) &&  		(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { -		if (strcmp(p, "cs0_cs1") == 0) +		/* test null first. if CONFIG_HWCONFIG is not defined, +		 * hwconfig_arg_cmp returns non-zero */ +		if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "null")) +			debug("bank interleaving disabled.\n"); +		else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1"))  			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1; -		else if (strcmp(p, "cs2_cs3") == 0) +		else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs2_cs3"))  			popts->ba_intlv_ctl = FSL_DDR_CS2_CS3; -		else if (strcmp(p, "cs0_cs1_and_cs2_cs3") == 0) +		else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1_and_cs2_cs3"))  			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3; -		else if (strcmp(p, "cs0_cs1_cs2_cs3") == 0) +		else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1_cs2_cs3"))  			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;  		else -			popts->ba_intlv_ctl = simple_strtoul(p, NULL, 0); - +			printf("hwconfig has unrecognized parameter for bank_intlv.\n");  		switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {  		case FSL_DDR_CS0_CS1_CS2_CS3: +#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +			if (pdimm[0].n_ranks < 4) { +				popts->ba_intlv_ctl = 0; +				printf("Not enough bank(chip-select) for " +					"CS0+CS1+CS2+CS3 on controller %d, " +					"force non-interleaving!\n", ctrl_num); +			} +#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +			if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { +				popts->ba_intlv_ctl = 0; +				printf("Not enough bank(chip-select) for " +					"CS0+CS1+CS2+CS3 on controller %d, " +					"force non-interleaving!\n", ctrl_num); +			} +			if (pdimm[0].capacity != pdimm[1].capacity) { +				popts->ba_intlv_ctl = 0; +				printf("Not identical DIMM size for " +					"CS0+CS1+CS2+CS3 on controller %d, " +					"force non-interleaving!\n", ctrl_num); +			} +#endif +			break;  		case FSL_DDR_CS0_CS1: -			if (pdimm[0].n_ranks != 2) { +			if (pdimm[0].n_ranks < 2) {  				popts->ba_intlv_ctl = 0;  				printf("Not enough bank(chip-select) for " -					"CS0+CS1, force non-interleaving!\n"); +					"CS0+CS1 on controller %d, " +					"force non-interleaving!\n", ctrl_num);  			}  			break;  		case FSL_DDR_CS2_CS3: -			if (pdimm[1].n_ranks !=2){ +#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +			if (pdimm[0].n_ranks < 4) { +				popts->ba_intlv_ctl = 0; +				printf("Not enough bank(chip-select) for CS2+CS3 " +					"on controller %d, force non-interleaving!\n", ctrl_num); +			} +#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +			if (pdimm[1].n_ranks < 2) {  				popts->ba_intlv_ctl = 0; -				printf("Not enough bank(CS) for CS2+CS3, " -					"force non-interleaving!\n"); +				printf("Not enough bank(chip-select) for CS2+CS3 " +					"on controller %d, force non-interleaving!\n", ctrl_num);  			} +#endif  			break;  		case FSL_DDR_CS0_CS1_AND_CS2_CS3: -			if ((pdimm[0].n_ranks != 2)||(pdimm[1].n_ranks != 2)) { +#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +			if (pdimm[0].n_ranks < 4) { +				popts->ba_intlv_ctl = 0; +				printf("Not enough bank(CS) for CS0+CS1 and " +					"CS2+CS3 on controller %d, " +					"force non-interleaving!\n", ctrl_num); +			} +#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +			if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {  				popts->ba_intlv_ctl = 0; -				printf("Not enough bank(CS) for CS0+CS1 or " -					"CS2+CS3, force non-interleaving!\n"); +				printf("Not enough bank(CS) for CS0+CS1 and " +					"CS2+CS3 on controller %d, " +					"force non-interleaving!\n", ctrl_num);  			} +#endif  			break;  		default:  			popts->ba_intlv_ctl = 0; @@ -291,7 +342,48 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,  		}  	} +	if (hwconfig_sub("fsl_ddr", "addr_hash")) { +		if (hwconfig_subarg_cmp("fsl_ddr", "addr_hash", "null")) +			popts->addr_hash = 0; +		else if (hwconfig_subarg_cmp("fsl_ddr", "addr_hash", "true")) +			popts->addr_hash = 1; +	} + +	if (pdimm[0].n_ranks == 4) +		popts->quad_rank_present = 1; +  	fsl_ddr_board_options(popts, pdimm, ctrl_num);  	return 0;  } + +void check_interleaving_options(fsl_ddr_info_t *pinfo) +{ +	int i, j, check_n_ranks, intlv_fixed = 0; +	unsigned long long check_rank_density; +	/* +	 * Check if all controllers are configured for memory +	 * controller interleaving. Identical dimms are recommended. At least +	 * the size should be checked. +	 */ +	j = 0; +	check_n_ranks = pinfo->dimm_params[0][0].n_ranks; +	check_rank_density = pinfo->dimm_params[0][0].rank_density; +	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { +		if ((pinfo->memctl_opts[i].memctl_interleaving) && \ +		    (check_rank_density == pinfo->dimm_params[i][0].rank_density) && \ +		    (check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) { +			j++; +		} +	} +	if (j != CONFIG_NUM_DDR_CONTROLLERS) { +		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) +			if (pinfo->memctl_opts[i].memctl_interleaving) { +				pinfo->memctl_opts[i].memctl_interleaving = 0; +				intlv_fixed = 1; +			} +		if (intlv_fixed) +			printf("Not all DIMMs are identical in size. " +				"Memory controller interleaving disabled.\n"); +	} +} diff --git a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c index 2fee99569..2cfc37f75 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c @@ -985,7 +985,7 @@ u32 DQS_autocalibration(void)  	puts(str);  #if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION) -	i = getenv_r("autocalib", tmp, sizeof(tmp)); +	i = getenv_f("autocalib", tmp, sizeof(tmp));  	if (i < 0)  		strcpy(tmp, CONFIG_AUTOCALIB); diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h index 55923e09b..be8260277 100644 --- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h +++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h @@ -81,6 +81,9 @@ typedef struct dimm_params_s {  	unsigned int tRTP_ps;	/* byte 38, spd->trtp */  	unsigned int tDQSQ_max_ps;	/* byte 44, spd->tdqsq */  	unsigned int tQHS_ps;	/* byte 45, spd->tqhs */ + +	/* DDR3 RDIMM */ +	unsigned char rcw[16];	/* Register Control Word 0-15 */  } dimm_params_t;  extern unsigned int ddr_compute_dimm_parameters( diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 02920dbfd..d576eb85e 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -119,6 +119,7 @@ typedef struct fsl_ddr_cfg_regs_s {  	unsigned int ddr_sr_cntr;  	unsigned int ddr_sdram_rcw_1;  	unsigned int ddr_sdram_rcw_2; +	unsigned int ddr_eor;  } fsl_ddr_cfg_regs_t;  typedef struct memctl_options_partial_s { @@ -156,6 +157,7 @@ typedef struct memctl_options_s {  	unsigned int memctl_interleaving;  	unsigned int memctl_interleaving_mode;  	unsigned int ba_intlv_ctl; +	unsigned int addr_hash;  	/* Operational mode parameters */  	unsigned int ECC_mode;	 /* Use ECC? */ @@ -172,6 +174,7 @@ typedef struct memctl_options_s {  	unsigned int OTF_burst_chop_en;  	/* mirrior DIMMs for DDR3 */  	unsigned int mirrored_dimm; +	unsigned int quad_rank_present;  	/* Global Timing Parameters */  	unsigned int cas_latency_override; diff --git a/arch/powerpc/include/asm/fsl_fman.h b/arch/powerpc/include/asm/fsl_fman.h new file mode 100644 index 000000000..6c01ffc41 --- /dev/null +++ b/arch/powerpc/include/asm/fsl_fman.h @@ -0,0 +1,212 @@ +/* + * MPC85xx Internal Memory Map + * + * Copyright 2010 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 + */ + +#ifndef __FSL_FMAN_H__ +#define __FSL_FMAN_H__ + +#include <asm/types.h> + +typedef struct fm_bmi_common { +	u32	fmbm_init;	/* BMI initialization */ +	u32	fmbm_cfg1;	/* BMI configuration1 */ +	u32	fmbm_cfg2;	/* BMI configuration2 */ +	u32	res0[0x5]; +	u32	fmbm_ievr;	/* interrupt event register */ +	u32	fmbm_ier;	/* interrupt enable register */ +	u32	fmbm_ifr;	/* interrupt force register */ +	u32	res1[0x5]; +	u32	fmbm_arb[0x8];	/* BMI arbitration */ +	u32	res2[0x28]; +	u32	fmbm_gde;	/* global debug enable */ +	u32	fmbm_pp[0x3f];	/* BMI port parameters */ +	u32	res3; +	u32	fmbm_pfs[0x3f];	/* BMI port FIFO size */ +	u32	res4; +	u32	fmbm_ppid[0x3f];/* port partition ID */ +} fm_bmi_common_t; + +typedef struct fm_qmi_common { +	u32	fmqm_gc;	/* general configuration register */ +	u32	res0; +	u32	fmqm_eie;	/* error interrupt event register */ +	u32	fmqm_eien;	/* error interrupt enable register */ +	u32	fmqm_eif;	/* error interrupt force register */ +	u32	fmqm_ie;	/* interrupt event register */ +	u32	fmqm_ien;	/* interrupt enable register */ +	u32	fmqm_if;	/* interrupt force register */ +	u32	fmqm_gs;	/* global status register */ +	u32	fmqm_ts;	/* task status register */ +	u32	fmqm_etfc;	/* enqueue total frame counter */ +	u32	fmqm_dtfc;	/* dequeue total frame counter */ +	u32	fmqm_dc0;	/* dequeue counter 0 */ +	u32	fmqm_dc1;	/* dequeue counter 1 */ +	u32	fmqm_dc2;	/* dequeue counter 2 */ +	u32	fmqm_dc3;	/* dequeue counter 3 */ +	u32	fmqm_dfnoc;	/* dequeue FQID not override counter */ +	u32	fmqm_dfcc;	/* dequeue FQID from context counter */ +	u32	fmqm_dffc;	/* dequeue FQID from FD counter */ +	u32	fmqm_dcc;	/* dequeue confirm counter */ +	u32	res1[0xc]; +	u32	fmqm_dtrc;	/* debug trap configuration register */ +	u32	fmqm_efddd;	/* enqueue frame descriptor dynamic debug */ +	u32	res3[0x2]; +	u32	res4[0xdc];	/* missing debug regs */ +} fm_qmi_common_t; + +typedef struct fm_bmi { +	u8	res[1024]; +} fm_bmi_t; + +typedef struct fm_qmi { +	u8	res[1024]; +} fm_qmi_t; + +typedef struct fm_parser { +	u8	res[1024]; +} fm_parser_t; + +typedef struct fm_policer { +	u8	res[4*1024]; +} fm_policer_t; + +typedef struct fm_keygen { +	u8	res[4*1024]; +} fm_keygen_t; + +typedef struct fm_dma { +	u32	fmdmsr;		/* status register */ +	u32	fmdmmr;		/* mode register */ +	u32	fmdmtr;		/* bus threshold register */ +	u32	fmdmhy;		/* bus hysteresis register */ +	u32	fmdmsetr;	/* SOS emergency threshold register */ +	u32	fmdmtah;	/* transfer bus address high register */ +	u32	fmdmtal;	/* transfer bus address low register */ +	u32	fmdmtcid;	/* transfer bus communication ID register */ +	u32	fmdmra;		/* DMA bus internal ram address register */ +	u32	fmdmrd;		/* DMA bus internal ram data register */ +	u32	res0[0xb]; +	u32	fmdmdcr;	/* debug counter */ +	u32	fmdmemsr;	/* emrgency smoother register */ +	u32	res1; +	u32	fmdmplr[32];	/* FM DMA PID-LIODN # register */ +	u32	res[0x3c8]; +} fm_dma_t; + +typedef struct fm_fpm { +	u32	fpmtnc;		/* TNUM control */ +	u32	fpmprc;		/* Port_ID control */ +	u32	res0; +	u32	fpmflc;		/* flush control */ +	u32	fpmdis1;	/* dispatch thresholds1 */ +	u32	fpmdis2;	/* dispatch thresholds2 */ +	u32	fmepi;		/* error pending interrupts */ +	u32	fmrie;		/* rams interrupt enable */ +	u32	fpmfcevent[0x4];/* FMan controller event 0-3 */ +	u32	res1[0x4]; +	u32	fpmfcmask[0x4];	/* FMan controller mask 0-3 */ +	u32	res2[0x4]; +	u32	fpmtsc1;	/* timestamp control1 */ +	u32	fpmtsc2;	/* timestamp control2 */ +	u32	fpmtsp;		/* time stamp */ +	u32	fpmtsf;		/* time stamp fraction */ +	u32	fpmrcr;		/* rams control and event */ +	u32	res3[0x3]; +	u32	fpmdrd[0x4];	/* data_ram data 0-3 */ +	u32	res4[0xc]; +	u32	fpmdra;		/* data ram access */ +	u32	fm_ip_rev_1;	/* IP block revision 1 */ +	u32	fm_ip_rev_2;	/* IP block revision 2 */ +	u32	fmrstc;		/* reset command */ +	u32	fmcld;		/* classifier debug control */ +	u32	fmnpi;		/* normal pending interrupts */ +	u32	res5; +	u32	fmnee;		/* event and enable */ +	u32	fpmcev[0x4];	/* CPU event 0-3 */ +	u32	res6[0x4]; +	u32	fmfp_ps[0x40];	/* port status */ +	u32	res7[0x260]; +	u32	fpmts[0x80];	/* task status */ +	u32	res8[0xa0]; +} fm_fpm_t; + +typedef struct fm_imem { +	u8	res[4*1024]; +} fm_imem_t; + +typedef struct fm_soft_parser { +	u8	res[4*1024]; +} fm_soft_parser_t; + +typedef struct fm_dtesc { +	u8	res[4*1024]; +} fm_dtsec_t; + +typedef struct fm_mdio { +	u8	res[4*1024]; +} fm_mdio_t; + +typedef struct fm_10gec { +	u8	res[4*1024]; +} fm_10gec_t; + +typedef struct fm_10gec_mdio { +	u8	res[4*1024]; +} fm_10gec_mdio_t; + +typedef struct fm_1588 { +	u8	res[4*1024]; +} fm_1588_t; + +typedef struct ccsr_fman { +	u8			muram[0x80000]; +	fm_bmi_common_t		fm_bmi_common; +	fm_qmi_common_t		fm_qmi_common; +	u8			res0[2048]; +	struct { +		fm_bmi_t	fm_bmi; +		fm_qmi_t	fm_qmi; +		fm_parser_t	fm_parser; +		u8		res[1024]; +	} port[63]; +	fm_policer_t		fm_policer; +	fm_keygen_t		fm_keygen; +	fm_dma_t		fm_dma; +	fm_fpm_t		fm_fpm; +	fm_imem_t		fm_imem; +	u8			res1[8*1024]; +	fm_soft_parser_t	fm_soft_parser; +	u8			res2[96*1024]; +	struct { +		fm_dtsec_t	fm_dtesc; +		fm_mdio_t	fm_mdio; +	} mac[4]; +	u8			res3[32*1024]; +	fm_10gec_t		fm_10gec; +	fm_10gec_mdio_t		fm_10gec_mdio; +	u8			res4[48*1024]; +	fm_1588_t		fm_1588; +	u8			res5[4*1024]; +} ccsr_fman_t; + +#endif /*__FSL_FMAN_H__*/ diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h index 12ba1a6a0..0e255ffce 100644 --- a/arch/powerpc/include/asm/fsl_law.h +++ b/arch/powerpc/include/asm/fsl_law.h @@ -1,5 +1,5 @@  /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2008-2010 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 @@ -54,6 +54,7 @@ enum law_trgt_if {  	LAW_TRGT_IF_PCIE_1 = 0x00,  	LAW_TRGT_IF_PCIE_2 = 0x01,  	LAW_TRGT_IF_PCIE_3 = 0x02, +	LAW_TRGT_IF_PCIE_4 = 0x03,  	LAW_TRGT_IF_RIO_1 = 0x08,  	LAW_TRGT_IF_RIO_2 = 0x09, diff --git a/arch/powerpc/include/asm/fsl_liodn.h b/arch/powerpc/include/asm/fsl_liodn.h new file mode 100644 index 000000000..acdc99aee --- /dev/null +++ b/arch/powerpc/include/asm/fsl_liodn.h @@ -0,0 +1,142 @@ +/* + * Copyright 2009-2010 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 + */ + +#ifndef _FSL_LIODN_H_ +#define _FSL_LIODN_H_ + +#include <asm/types.h> + +struct liodn_id_table { +	const char * compat; +	u32 id[2]; +	u8 num_ids; +	phys_addr_t compat_offset; +	unsigned long reg_offset; +}; + +extern u32 get_ppid_liodn(int ppid_tbl_idx, int ppid); +extern void set_liodns(void); +extern void fdt_fixup_liodn(void *blob); + +#define SET_LIODN_BASE_1(idA) \ +	{ .id = { idA }, .num_ids = 1, } + +#define SET_LIODN_BASE_2(idA, idB) \ +	{ .id = { idA, idB }, .num_ids = 2 } + +#define SET_LIODN_ENTRY_1(name, idA, off, compatoff) \ +	{ .compat = name, \ +	  .id = { idA }, .num_ids = 1, \ +	  .reg_offset = off + CONFIG_SYS_CCSRBAR, \ +	  .compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \ +	} + +#define SET_LIODN_ENTRY_2(name, idA, idB, off, compatoff) \ +	{ .compat = name, \ +	  .id = { idA, idB }, .num_ids = 2, \ +	  .reg_offset = off + CONFIG_SYS_CCSRBAR, \ +	  .compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \ +	} + +#define SET_GUTS_LIODN(compat, liodn, name, compatoff) \ +	SET_LIODN_ENTRY_1(compat, liodn, \ +		offsetof(ccsr_gur_t, name) + CONFIG_SYS_MPC85xx_GUTS_OFFSET, \ +		compatoff) + +#define SET_USB_LIODN(usbNum, compat, liodn) \ +	SET_GUTS_LIODN(compat, liodn, usb##usbNum##liodnr,\ +		CONFIG_SYS_MPC85xx_USB##usbNum##_OFFSET) + +#define SET_SATA_LIODN(sataNum, liodn) \ +	SET_GUTS_LIODN("fsl,pq-sata-v2", liodn, sata##sataNum##liodnr,\ +		CONFIG_SYS_MPC85xx_SATA##sataNum##_OFFSET) + +#define SET_PCI_LIODN(pciNum, liodn) \ +	SET_GUTS_LIODN("fsl,p4080-pcie", liodn, pex##pciNum##liodnr,\ +		CONFIG_SYS_MPC85xx_PCIE##pciNum##_OFFSET) + +/* reg nodes for DMA start @ 0x300 */ +#define SET_DMA_LIODN(dmaNum, liodn) \ +	SET_GUTS_LIODN("fsl,eloplus-dma", liodn, dma##dmaNum##liodnr,\ +		CONFIG_SYS_MPC85xx_DMA##dmaNum##_OFFSET + 0x300) + +#define SET_SDHC_LIODN(sdhcNum, liodn) \ +	SET_GUTS_LIODN("fsl,esdhc", liodn, sdmmc##sdhcNum##liodnr,\ +		CONFIG_SYS_MPC85xx_ESDHC_OFFSET) + +#define SET_QMAN_LIODN(liodn) \ +	SET_LIODN_ENTRY_1("fsl,qman", liodn, offsetof(ccsr_qman_t, liodnr) + \ +		CONFIG_SYS_FSL_CORENET_QMAN_OFFSET, \ +		CONFIG_SYS_FSL_CORENET_QMAN_OFFSET) + +#define SET_BMAN_LIODN(liodn) \ +	SET_LIODN_ENTRY_1("fsl,bman", liodn, offsetof(ccsr_bman_t, liodnr) + \ +		CONFIG_SYS_FSL_CORENET_BMAN_OFFSET, \ +		CONFIG_SYS_FSL_CORENET_BMAN_OFFSET) + +#define SET_PME_LIODN(liodn) \ +	SET_LIODN_ENTRY_1("fsl,pme", liodn, offsetof(ccsr_pme_t, liodnr) + \ +		CONFIG_SYS_FSL_CORENET_PME_OFFSET, \ +		CONFIG_SYS_FSL_CORENET_PME_OFFSET) + +/* -1 from portID due to how immap has the registers */ +#define FM_PPID_RX_PORT_OFFSET(fmNum, portID) \ +	CONFIG_SYS_FSL_FM##fmNum##_OFFSET + \ +	offsetof(struct ccsr_fman, fm_bmi_common.fmbm_ppid[portID - 1]) + +/* enetNum is 0, 1, 2... so we + 8 for 1g to get to HW Port ID */ +#define SET_FMAN_RX_1G_LIODN(fmNum, enetNum, liodn) \ +	SET_LIODN_ENTRY_1("fsl,fman-port-1g-rx", liodn, \ +		FM_PPID_RX_PORT_OFFSET(fmNum, enetNum + 8), \ +		CONFIG_SYS_FSL_FM##fmNum##_RX##enetNum##_1G_OFFSET) \ + +/* enetNum is 0, 1, 2... so we + 16 for 10g to get to HW Port ID */ +#define SET_FMAN_RX_10G_LIODN(fmNum, enetNum, liodn) \ +	SET_LIODN_ENTRY_1("fsl,fman-port-10g-rx", liodn, \ +		FM_PPID_RX_PORT_OFFSET(fmNum, enetNum + 16), \ +		CONFIG_SYS_FSL_FM##fmNum##_RX##enetNum##_10G_OFFSET) \ + +#define SET_SEC_JQ_LIODN_ENTRY(jqNum, liodnA, liodnB) \ +	SET_LIODN_ENTRY_2("fsl,sec4.0-job-queue", liodnA, liodnB,\ +		offsetof(ccsr_sec_t, jqliodnr[jqNum].ls) + \ +		CONFIG_SYS_FSL_SEC_OFFSET, \ +		CONFIG_SYS_FSL_SEC_OFFSET + 0x1000 + 0x1000 * jqNum) + +/* This is a bit evil since we treat rtic param as both a string & hex value */ +#define SET_SEC_RTIC_LIODN_ENTRY(rtic, liodnA) \ +	SET_LIODN_ENTRY_1("fsl,sec4.0-rtic-memory", \ +		liodnA,	\ +		offsetof(ccsr_sec_t, rticliodnr[0x##rtic-0xa].ls) + \ +		CONFIG_SYS_FSL_SEC_OFFSET, \ +		CONFIG_SYS_FSL_SEC_OFFSET + 0x6100 + 0x20 * (0x##rtic-0xa)) + +#define SET_SEC_DECO_LIODN_ENTRY(num, liodnA, liodnB) \ +	SET_LIODN_ENTRY_2(NULL, liodnA, liodnB, \ +		offsetof(ccsr_sec_t, decoliodnr[num].ls) + \ +		CONFIG_SYS_FSL_SEC_OFFSET, 0) + +extern struct liodn_id_table liodn_tbl[], liodn_bases[], sec_liodn_tbl[]; +extern struct liodn_id_table fman1_liodn_tbl[], fman2_liodn_tbl[]; +extern int liodn_tbl_sz, sec_liodn_tbl_sz; +extern int fman1_liodn_tbl_sz, fman2_liodn_tbl_sz; + +#endif diff --git a/arch/powerpc/include/asm/fsl_portals.h b/arch/powerpc/include/asm/fsl_portals.h new file mode 100644 index 000000000..cb32927a8 --- /dev/null +++ b/arch/powerpc/include/asm/fsl_portals.h @@ -0,0 +1,59 @@ +/* + * Copyright 2009-2010 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 + */ + +#ifndef _FSL_PORTALS_H_ +#define _FSL_PORTALS_H_ + +/* entries must be in order and contiguous */ +enum fsl_dpaa_dev { +	FSL_HW_PORTAL_SEC, +#ifdef CONFIG_SYS_DPAA_FMAN +	FSL_HW_PORTAL_FMAN1, +#if (CONFIG_SYS_NUM_FMAN == 2) +	FSL_HW_PORTAL_FMAN2, +#endif +#endif +#ifdef CONFIG_SYS_DPAA_PME +	FSL_HW_PORTAL_PME, +#endif +}; + +struct qportal_info { +	u16	dliodn;	/* DQRR LIODN */ +	u16	fliodn;	/* frame data LIODN */ +	u16	liodn_offset; +	u8	sdest; +}; + +#define SET_QP_INFO(dqrr, fdata, off, dest) \ +	{ .dliodn = dqrr, .fliodn = fdata, .liodn_offset = off, .sdest = dest } + +extern int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev, +			  u32 *liodns, int liodn_offset); +extern void setup_portals(void); +extern void fdt_fixup_qportals(void *blob); + +extern struct qportal_info qp_info[]; +extern void fdt_portal(void *blob, const char *compat, const char *container, +			u64 addr, u32 size); + +#endif diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index c7877b91a..85518eb6e 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -32,8 +32,15 @@ enum srds_prtcl {  	SATA2,  	SRIO1,  	SRIO2, -	SGMII_FM1, -	SGMII_FM2, +	SGMII_FM1_DTSEC1, +	SGMII_FM1_DTSEC2, +	SGMII_FM1_DTSEC3, +	SGMII_FM1_DTSEC4, +	SGMII_FM1_DTSEC5, +	SGMII_FM2_DTSEC1, +	SGMII_FM2_DTSEC2, +	SGMII_FM2_DTSEC3, +	SGMII_FM2_DTSEC4,  	SGMII_TSEC1,  	SGMII_TSEC2,  	SGMII_TSEC3, diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index b1d219b7a..c1382c8c5 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -32,6 +32,7 @@  #include <asm/fsl_dma.h>  #include <asm/fsl_i2c.h>  #include <asm/fsl_lbc.h> +#include <asm/fsl_fman.h>  typedef struct ccsr_local {  	u32	ccsrbarh;	/* CCSR Base Addr High */ @@ -172,7 +173,17 @@ typedef struct ccsr_ddr {  	u32	ddr_sr_cntr;		/* self refresh counter */  	u32	ddr_sdram_rcw_1;	/* Control Words 1 */  	u32	ddr_sdram_rcw_2;	/* Control Words 2 */ -	u8	res8_1b[2456]; +	u8	reg_1ab[8]; +	u32	ddr_wrlvl_cntl_2;	/* write leveling control 2 */ +	u32	ddr_wrlvl_cntl_3;	/* write leveling control 3 */ +	u8	res8_1b[104]; +	u32	sdram_mode_3;		/* SDRAM Mode Configuration 3 */ +	u32	sdram_mode_4;		/* SDRAM Mode Configuration 4 */ +	u32	sdram_mode_5;		/* SDRAM Mode Configuration 5 */ +	u32	sdram_mode_6;		/* SDRAM Mode Configuration 6 */ +	u32	sdram_mode_7;		/* SDRAM Mode Configuration 7 */ +	u32	sdram_mode_8;		/* SDRAM Mode Configuration 8 */ +	u8	res8_1ba[0x908];  	u32	ddr_dsr1;		/* Debug Status 1 */  	u32	ddr_dsr2;		/* Debug Status 2 */  	u32	ddr_cdr1;		/* Control Driver 1 */ @@ -180,7 +191,21 @@ typedef struct ccsr_ddr {  	u8	res8_1c[200];  	u32	ip_rev1;		/* IP Block Revision 1 */  	u32	ip_rev2;		/* IP Block Revision 2 */ -	u8	res8_2[512]; +	u32	eor;			/* Enhanced Optimization Register */ +	u8	res8_2[252]; +	u32	mtcr;			/* Memory Test Control Register */ +	u8	res8_3[28]; +	u32	mtp1;			/* Memory Test Pattern 1 */ +	u32	mtp2;			/* Memory Test Pattern 2 */ +	u32	mtp3;			/* Memory Test Pattern 3 */ +	u32	mtp4;			/* Memory Test Pattern 4 */ +	u32	mtp5;			/* Memory Test Pattern 5 */ +	u32	mtp6;			/* Memory Test Pattern 6 */ +	u32	mtp7;			/* Memory Test Pattern 7 */ +	u32	mtp8;			/* Memory Test Pattern 8 */ +	u32	mtp9;			/* Memory Test Pattern 9 */ +	u32	mtp10;			/* Memory Test Pattern 10 */ +	u8	res8_4[184];  	u32	data_err_inject_hi;	/* Data Path Err Injection Mask High */  	u32	data_err_inject_lo;	/* Data Path Err Injection Mask Low */  	u32	ecc_err_inject;		/* Data Path Err Injection Mask ECC */ @@ -218,6 +243,9 @@ typedef struct ccsr_ddr {  	u8	res12[184];  } ccsr_ddr_t; +#define DDR_EOR_RD_BDW_OPT_DIS	0x80000000 /* Read BDW Opt. disable */ +#define DDR_EOR_ADDR_HASH_EN	0x40000000 /* Address hash enabled */ +  /* I2C Registers */  typedef struct ccsr_i2c {  	struct fsl_i2c	i2c[1]; @@ -732,6 +760,8 @@ typedef struct ccsr_pic {  	u32	eoi;		/* End Of IRQ */  	u8	res9[3916];  	u32	frr;		/* Feature Reporting */ +#define MPC85xx_PICFRR_NCPU_MASK	0x00001f00 +#define MPC85xx_PICFRR_NCPU_SHIFT	8  	u8	res10[28];  	u32	gcr;		/* Global Configuration */  #define MPC85xx_PICGCR_RST	0x80000000 @@ -1609,6 +1639,7 @@ typedef struct ccsr_gur {  #define FSL_CORENET_DEVDISR_PCIE1	0x80000000  #define FSL_CORENET_DEVDISR_PCIE2	0x40000000  #define FSL_CORENET_DEVDISR_PCIE3	0x20000000 +#define FSL_CORENET_DEVDISR_PCIE4	0x10000000  #define FSL_CORENET_DEVDISR_RMU		0x08000000  #define FSL_CORENET_DEVDISR_SRIO1	0x04000000  #define FSL_CORENET_DEVDISR_SRIO2	0x02000000 @@ -1618,6 +1649,8 @@ typedef struct ccsr_gur {  #define FSL_CORENET_DEVDISR_DDR2	0x00080000  #define FSL_CORENET_DEVDISR_DBG		0x00010000  #define FSL_CORENET_DEVDISR_NAL		0x00008000 +#define FSL_CORENET_DEVDISR_SATA1	0x00004000 +#define FSL_CORENET_DEVDISR_SATA2	0x00002000  #define FSL_CORENET_DEVDISR_ELBC	0x00001000  #define FSL_CORENET_DEVDISR_USB1	0x00000800  #define FSL_CORENET_DEVDISR_USB2	0x00000400 @@ -1638,12 +1671,14 @@ typedef struct ccsr_gur {  #define FSL_CORENET_DEVDISR2_DTSEC1_2	0x00400000  #define FSL_CORENET_DEVDISR2_DTSEC1_3	0x00200000  #define FSL_CORENET_DEVDISR2_DTSEC1_4	0x00100000 +#define FSL_CORENET_DEVDISR2_DTSEC1_5	0x00080000  #define FSL_CORENET_DEVDISR2_FM2	0x00020000  #define FSL_CORENET_DEVDISR2_10GEC2	0x00010000  #define FSL_CORENET_DEVDISR2_DTSEC2_1	0x00008000  #define FSL_CORENET_DEVDISR2_DTSEC2_2	0x00004000  #define FSL_CORENET_DEVDISR2_DTSEC2_3	0x00002000  #define FSL_CORENET_DEVDISR2_DTSEC2_4	0x00001000 +#define FSL_CORENET_NUM_DEVDISR		2  	u8	res7[8];  	u32	powmgtcsr;	/* Power management status & control */  	u8	res8[12]; @@ -1672,9 +1707,18 @@ typedef struct ccsr_gur {  #define FSL_CORENET_RCWSR5_DDR_SYNC		0x00000080  #define FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT		 7  #define FSL_CORENET_RCWSR5_SRDS_EN		0x00002000 +#define FSL_CORENET_RCWSRn_SRDS_LPD_B2		0x3c000000 /* bits 162..165 */ +#define FSL_CORENET_RCWSRn_SRDS_LPD_B3		0x003c0000 /* bits 170..173 */  #define FSL_CORENET_RCWSR7_MCK_TO_PLAT_RAT	0x00400000  #define FSL_CORENET_RCWSR8_HOST_AGT_B1		0x00e00000  #define FSL_CORENET_RCWSR8_HOST_AGT_B2		0x00100000 +#define FSL_CORENET_RCWSR11_EC1			0x00c00000 /* bits 360..361 */ +#define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1	0x00000000 +#define FSL_CORENET_RCWSR11_EC1_FM1_USB1	0x00800000 +#define FSL_CORENET_RCWSR11_EC2			0x001c0000 /* bits 363..365 */ +#define FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1	0x00000000 +#define FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2	0x00080000 +#define FSL_CORENET_RCWSR11_EC2_USB2		0x00100000  	u8	res18[192];  	u32	scratchrw[4];	/* Scratch Read/Write */  	u8	res19[240]; @@ -1698,10 +1742,15 @@ typedef struct ccsr_gur {  	u32	sdmmc2liodnr;	/* SD/MMC 2 LIODN */  	u32	sdmmc3liodnr;	/* SD/MMC 3 LIODN */  	u32	sdmmc4liodnr;	/* SD/MMC 4 LIODN */ -	u32	rmuliodnr;	/* RIO Message Unit LIODN */ -	u32	rduliodnr;	/* RIO Doorbell Unit LIODN */ -	u32	rpwuliodnr;	/* RIO Port Write Unit LIODN */ -	u8	res22[52]; +	u32	rio1maintliodnr;/* RIO 1 Maintenance LIODN */ +	u32	rio2maintliodnr;/* RIO 2 Maintenance LIODN */ +	u32	rio3maintliodnr;/* RIO 3 Maintenance LIODN */ +	u32	rio4maintliodnr;/* RIO 4 Maintenance LIODN */ +	u32	sata1liodnr;	/* SATA 1 LIODN */ +	u32	sata2liodnr;	/* SATA 2 LIODN */ +	u32	sata3liodnr;	/* SATA 3 LIODN */ +	u32	sata4liodnr;	/* SATA 4 LIODN */ +	u8	res22[32];  	u32	dma1liodnr;	/* DMA 1 LIODN */  	u32	dma2liodnr;	/* DMA 2 LIODN */  	u32	dma3liodnr;	/* DMA 3 LIODN */ @@ -1736,6 +1785,12 @@ typedef struct ccsr_gur {  	u8	res37[380];  } ccsr_gur_t; +/* + * On p4080 we have an LIODN for msg unit (rmu) but not maintenance + * everything after has RMan thus msg unit LIODN is used for maintenance + */ +#define rmuliodnr rio1maintliodnr +  typedef struct ccsr_clk {  	u32	clkc0csr;	/* Core 0 Clock control/status */  	u8	res1[0x1c]; @@ -2004,38 +2059,125 @@ enum {  /* Security Engine Block (MS = Most Sig., LS = Least Sig.) */  #if CONFIG_SYS_FSL_SEC_COMPAT >= 4  typedef struct ccsr_sec { -	u8	res1[0xfa0]; +	u32	res0; +	u32	mcfgr;		/* Master CFG Register */ +	u8	res1[0x8]; +	struct { +		u32	ms;	/* Job Ring LIODN Register, MS */ +		u32	ls;	/* Job Ring LIODN Register, LS */ +	} jqliodnr[4]; +	u8	res2[0x30]; +	struct { +		u32	ms;	/* RTIC LIODN Register, MS */ +		u32	ls;	/* RTIC LIODN Register, LS */ +	} rticliodnr[4]; +	u8	res3[0x1c]; +	u32	decorr;		/* DECO Request Register */ +	struct { +		u32	ms;	/* DECO LIODN Register, MS */ +		u32	ls;	/* DECO LIODN Register, LS */ +	} decoliodnr[5]; +	u8	res4[0x58]; +	u32	dar;		/* DECO Avail Register */ +	u32	drr;		/* DECO Reset Register */ +	u8	res5[0xe78];  	u32	crnr_ms;	/* CHA Revision Number Register, MS */  	u32	crnr_ls;	/* CHA Revision Number Register, LS */  	u32	ctpr_ms;	/* Compile Time Parameters Register, MS */ -#define SEC_CTPR_MS_AXI_LIODN		0x08000000 -#define SEC_CTPR_MS_QI			0x02000000  	u32	ctpr_ls;	/* Compile Time Parameters Register, LS */ -	u8	res2[0x10]; +	u8	res6[0x10];  	u32	far_ms;		/* Fault Address Register, MS */  	u32	far_ls;		/* Fault Address Register, LS */  	u32	falr;		/* Fault Address LIODN Register */  	u32	fadr;		/* Fault Address Detail Register */ -	u8	res3[0x4]; +	u8	res7[0x4];  	u32	csta;		/* CAAM Status Register */ -	u8	res4[0x8]; +	u8	res8[0x8];  	u32	rvid;		/* Run Time Integrity Checking Version ID Reg.*/ -#define SEC_RVID_MA			0x0f000000  	u32	ccbvid;		/* CHA Cluster Block Version ID Register */  	u32	chavid_ms;	/* CHA Version ID Register, MS */  	u32	chavid_ls;	/* CHA Version ID Register, LS */  	u32	chanum_ms;	/* CHA Number Register, MS */ +	u32	chanum_ls;	/* CHA Number Register, LS */ +	u32	secvid_ms;	/* SEC Version ID Register, MS */ +	u32	secvid_ls;	/* SEC Version ID Register, LS */ +	u8	res9[0x6020]; +	u32	qilcr_ms;	/* Queue Interface LIODN CFG Register, MS */ +	u32	qilcr_ls;	/* Queue Interface LIODN CFG Register, LS */ +	u8	res10[0x8fd8]; +} ccsr_sec_t; + +#define SEC_CTPR_MS_AXI_LIODN		0x08000000 +#define SEC_CTPR_MS_QI			0x02000000 +#define SEC_RVID_MA			0x0f000000  #define SEC_CHANUM_MS_JQNUM_MASK	0xf0000000  #define SEC_CHANUM_MS_JQNUM_SHIFT	28  #define SEC_CHANUM_MS_DECONUM_MASK	0x0f000000  #define SEC_CHANUM_MS_DECONUM_SHIFT	24 -	u32	chanum_ls;	/* CHA Number Register, LS */ -	u32	caamvid_ms;	/* CAAM Version ID Register, MS */ -	u32	caamvid_ls;	/* CAAM Version ID Register, LS */ -	u8	res5[0xf000]; -} ccsr_sec_t;  #endif +typedef struct ccsr_qman { +	struct { +		u32	qcsp_lio_cfg;	/* 0x0 - SW Portal n LIO cfg */ +		u32	qcsp_io_cfg;	/* 0x4 - SW Portal n IO cfg */ +		u32	res; +		u32	qcsp_dd_cfg;	/* 0xc - SW Portal n Dynamic Debug cfg */ +	} qcsp[32]; + +	/* Not actually reserved, but irrelevant to u-boot */ +	u8	res[0xbf8 - 0x200]; +	u32	ip_rev_1; +	u32	ip_rev_2; +	u32	fqd_bare;	/* FQD Extended Base Addr Register */ +	u32	fqd_bar;	/* FQD Base Addr Register */ +	u8	res1[0x8]; +	u32	fqd_ar;		/* FQD Attributes Register */ +	u8	res2[0xc]; +	u32	pfdr_bare;	/* PFDR Extended Base Addr Register */ +	u32	pfdr_bar;	/* PFDR Base Addr Register */ +	u8	res3[0x8]; +	u32	pfdr_ar;	/* PFDR Attributes Register */ +	u8	res4[0x4c]; +	u32	qcsp_bare;	/* QCSP Extended Base Addr Register */ +	u32	qcsp_bar;	/* QCSP Base Addr Register */ +	u8	res5[0x78]; +	u32	ci_sched_cfg;	/* Initiator Scheduling Configuration */ +	u32	srcidr;		/* Source ID Register */ +	u32	liodnr;		/* LIODN Register */ +	u8	res6[4]; +	u32	ci_rlm_cfg;	/* Initiator Read Latency Monitor Cfg */ +	u32	ci_rlm_avg;	/* Initiator Read Latency Monitor Avg */ +	u8	res7[0x2e8]; +} ccsr_qman_t; + +typedef struct ccsr_bman { +	/* Not actually reserved, but irrelevant to u-boot */ +	u8	res[0xbf8]; +	u32	ip_rev_1; +	u32	ip_rev_2; +	u32	fbpr_bare;	/* FBPR Extended Base Addr Register */ +	u32	fbpr_bar;	/* FBPR Base Addr Register */ +	u8	res1[0x8]; +	u32	fbpr_ar;	/* FBPR Attributes Register */ +	u8	res2[0xf0]; +	u32	srcidr;		/* Source ID Register */ +	u32	liodnr;		/* LIODN Register */ +	u8	res7[0x2f4]; +} ccsr_bman_t; + +typedef struct ccsr_pme { +	u8	res0[0x804]; +	u32	liodnbr;	/* LIODN Base Register */ +	u8	res1[0x1f8]; +	u32	srcidr;		/* Source ID Register */ +	u8	res2[8]; +	u32	liodnr;		/* LIODN Register */ +	u8	res3[0x1e8]; +	u32	pm_ip_rev_1;	/* PME IP Block Revision Reg 1*/ +	u32	pm_ip_rev_2;	/* PME IP Block Revision Reg 1*/ +	u8	res4[0x400]; +} ccsr_pme_t; +  #ifdef CONFIG_FSL_CORENET  #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET	0x0000  #define CONFIG_SYS_MPC85xx_DDR_OFFSET		0x8000 @@ -2044,16 +2186,41 @@ typedef struct ccsr_sec {  #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET	0xE2000  #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET	0xEA000  #define CONFIG_SYS_FSL_CPC_OFFSET		0x10000 -#define CONFIG_SYS_MPC85xx_DMA_OFFSET		0x100000 +#define CONFIG_SYS_MPC85xx_DMA1_OFFSET		0x100000 +#define CONFIG_SYS_MPC85xx_DMA2_OFFSET		0x101000 +#define CONFIG_SYS_MPC85xx_DMA_OFFSET		CONFIG_SYS_MPC85xx_DMA1_OFFSET  #define CONFIG_SYS_MPC85xx_ESPI_OFFSET		0x110000  #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET		0x114000  #define CONFIG_SYS_MPC85xx_LBC_OFFSET		0x124000  #define CONFIG_SYS_MPC85xx_GPIO_OFFSET		0x130000 -#define CONFIG_SYS_MPC85xx_USB_OFFSET		0x210000 +#define CONFIG_SYS_MPC85xx_PCIE1_OFFSET		0x200000 +#define CONFIG_SYS_MPC85xx_PCIE2_OFFSET		0x201000 +#define CONFIG_SYS_MPC85xx_PCIE3_OFFSET		0x202000 +#define CONFIG_SYS_MPC85xx_PCIE4_OFFSET		0x203000 +#define CONFIG_SYS_MPC85xx_USB1_OFFSET		0x210000 +#define CONFIG_SYS_MPC85xx_USB2_OFFSET		0x211000 +#define CONFIG_SYS_MPC85xx_USB_OFFSET		CONFIG_SYS_MPC85xx_USB1_OFFSET +#define CONFIG_SYS_MPC85xx_SATA1_OFFSET		0x220000 +#define CONFIG_SYS_MPC85xx_SATA2_OFFSET		0x221000  #define CONFIG_SYS_FSL_SEC_OFFSET		0x300000 +#define CONFIG_SYS_FSL_CORENET_PME_OFFSET	0x316000  #define CONFIG_SYS_FSL_CORENET_QMAN_OFFSET	0x318000  #define CONFIG_SYS_FSL_CORENET_BMAN_OFFSET	0x31a000 -#define CONFIG_SYS_TSEC1_OFFSET			0x4e0000 /* FM1@DTSEC0 */ +#define CONFIG_SYS_FSL_FM1_OFFSET		0x400000 +#define CONFIG_SYS_FSL_FM1_RX0_1G_OFFSET	0x488000 +#define CONFIG_SYS_FSL_FM1_RX1_1G_OFFSET	0x489000 +#define CONFIG_SYS_FSL_FM1_RX2_1G_OFFSET	0x48a000 +#define CONFIG_SYS_FSL_FM1_RX3_1G_OFFSET	0x48b000 +#define CONFIG_SYS_FSL_FM1_RX4_1G_OFFSET	0x48c000 +#define CONFIG_SYS_FSL_FM1_RX0_10G_OFFSET	0x490000 +#define CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET	0x4e0000 +#define CONFIG_SYS_FSL_FM2_OFFSET		0x500000 +#define CONFIG_SYS_FSL_FM2_RX0_1G_OFFSET	0x588000 +#define CONFIG_SYS_FSL_FM2_RX1_1G_OFFSET	0x589000 +#define CONFIG_SYS_FSL_FM2_RX2_1G_OFFSET	0x58a000 +#define CONFIG_SYS_FSL_FM2_RX3_1G_OFFSET	0x58b000 +#define CONFIG_SYS_FSL_FM2_RX4_1G_OFFSET	0x58c000 +#define CONFIG_SYS_FSL_FM2_RX0_10G_OFFSET	0x590000  #else  #define CONFIG_SYS_MPC85xx_ECM_OFFSET		0x0000  #define CONFIG_SYS_MPC85xx_DDR_OFFSET		0x2000 @@ -2098,6 +2265,8 @@ typedef struct ccsr_sec {  	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CORENET_QMAN_OFFSET)  #define CONFIG_SYS_FSL_CORENET_BMAN_ADDR \  	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CORENET_BMAN_OFFSET) +#define CONFIG_SYS_FSL_CORENET_PME_ADDR \ +	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CORENET_PME_OFFSET)  #define CONFIG_SYS_MPC85xx_GUTS_ADDR \  	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_GUTS_OFFSET)  #define CONFIG_SYS_FSL_CORENET_CCM_ADDR \ @@ -2146,6 +2315,12 @@ typedef struct ccsr_sec {  	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_USB_OFFSET)  #define CONFIG_SYS_FSL_SEC_ADDR \  	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_SEC_OFFSET) +#define CONFIG_SYS_FSL_FM1_ADDR \ +	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_FM1_OFFSET) +#define CONFIG_SYS_FSL_FM1_DTSEC1_ADDR \ +	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET) +#define CONFIG_SYS_FSL_FM2_ADDR \ +	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_FM2_OFFSET)  #define CONFIG_SYS_PCI1_ADDR \  	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCI1_OFFSET) @@ -2157,6 +2332,8 @@ typedef struct ccsr_sec {  	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE2_OFFSET)  #define CONFIG_SYS_PCIE3_ADDR \  	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE3_OFFSET) +#define CONFIG_SYS_PCIE4_ADDR \ +	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE4_OFFSET)  #define TSEC_BASE_ADDR		(CONFIG_SYS_IMMR + CONFIG_SYS_TSEC1_OFFSET)  #define MDIO_BASE_ADDR		(CONFIG_SYS_IMMR + CONFIG_SYS_MDIO1_OFFSET) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 89f283a6c..84a1e2ec0 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -495,6 +495,7 @@  #define   L1CSR1_ICFI		0x00000002	/* Instruction Cache Flash Invalidate */  #define   L1CSR1_ICE		0x00000001	/* Instruction Cache Enable */  #define SPRN_L1CSR2	0x25e	/* L1 Data Cache Control and Status Register 2 */ +#define   L1CSR2_DCWS		0x40000000	/* Data Cache Write Shadow */  #define SPRN_L2CSR0	0x3f9	/* L2 Data Cache Control and Status Register 0 */  #define   L2CSR0_L2E		0x80000000	/* L2 Cache Enable */  #define   L2CSR0_L2PE		0x40000000	/* L2 Cache Parity/ECC Enable */ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 7b09fb51e..0e00d8619 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -169,7 +169,7 @@ typedef int (init_fnc_t) (void);  static int init_baudrate (void)  {  	char tmp[64];	/* long enough for environment variables */ -	int i = getenv_r ("baudrate", tmp, sizeof (tmp)); +	int i = getenv_f("baudrate", tmp, sizeof (tmp));  	gd->baudrate = (i > 0)  			? (int) simple_strtoul (tmp, NULL, 10) @@ -442,7 +442,7 @@ void board_init_f (ulong bootflag)  	/*  	 * reserve protected RAM  	 */ -	i = getenv_r ("pram", (char *)tmp, sizeof (tmp)); +	i = getenv_f("pram", (char *)tmp, sizeof (tmp));  	reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM;  	addr -= (reg << 10);		/* size is in kB */  	debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); @@ -790,7 +790,7 @@ void board_init_r (gd_t *id, ulong dest_addr)  	 * Fill in missing fields of bd_info.  	 * We do this here, where we have "normal" access to the  	 * environment; we used to do this still running from ROM, -	 * where had to use getenv_r(), which can be pretty slow when +	 * where had to use getenv_f(), which can be pretty slow when  	 * the environment is in EEPROM.  	 */  |