diff options
author | Wolfgang Denk <wd@denx.de> | 2011-10-04 22:08:13 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2011-10-04 22:08:13 +0200 |
commit | 1fed668b3fb9c35932f58af00ff5539239fa4e1d (patch) | |
tree | eaaaead8ca19924af1823caae040f504be9b6d98 /arch/powerpc/cpu | |
parent | c52575350fd6e794717f6bee4f81dbb8038fe22e (diff) | |
parent | 6d7b061af153bc5beb633c3bd15348284716a067 (diff) | |
download | u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.zip u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.tar.gz u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
* 'master' of git://git.denx.de/u-boot-mpc85xx:
powerpc/p3060: Add SoC related support for P3060 platform
powerpc/85xx: Add support for setting up RAID engine liodns on P5020
powerpc/85xx: Refactor some defines out of corenet_ds.h
fm-eth: Add ability for board code to disable a port
powerpc/mpc8548: Add workaround for erratum NMG_LBC103
powerpc/mpc8548: Add workaround for erratum NMG_DDR120
powerpc/mpc85xxcds: Fix PCI speed
powerpc/mpc8548cds: Fix booting message
powerpc/p4080: Add support for secure boot flow
powerpc/85xx: Add Secure Boot support on P1010RDB for NOR, NAND & SPIFLASH
powerpc/85xx: Add PBL & SECUREBOOT support on P3041/P5020DS boards
powerpc/p2041rdb: remove watch dog related codes
powerpc/p2041rdb: updated description of cpld command
powerpc/p2041rdb: add more ddr frequencies support
powerpc/p2041rdb: set sysclk according to status of physical switch SW1
powerpc/p2041rdb: update cpld reset command according to CPLD 2.0
powerpc/mpc8349emds: Migrate from spd_sdram to unified DDR driver
powerpc/mpc83xx: Migrate from spd_sdram to unified DDR driver
powerpc/mpc8xxx: Add DDR2 to unified DDR driver
powerpc/mpc8xxx: Fix picos_to_mclk() and get_memory_clk_period_ps()
powerpc/mpc8xxx: Add SPD EEPROM address for single controller 2 slots
powerpc/mpc8xxx: Fix DDR code for empty first DIMM slot and enable DQS_en
powerpc/85xx: Refactor P2041RDB to use common p_corenet files
powerpc/85xx: refactor common P-Series CoreNet files for FSL boards
powerpc/85xx: Enable CMD_REGINFO on corenet boards
powerpc/85xx: p2041rdb - Remove unused 'execute' perm in TLB entries
powerpc/85xx: Fix USB protocol definitions for P1020RDB
powerpc/corenet_ds: Use separated speed tables for UDIMM and RDIMM
powerpc/mpc8xxx: Move DDR RCW overriding to common code
powerpc/mpc8xxx: Extend CWL table
powerpc/85xx: Cleanup how SVR_MAJ() is defined on MPC8536
powerpc/85xx: Cleanup extern in corenet_ds board code
powerpc/p2041rdb: Add ethernet support on P2041RDB board
powerpc/85xx: Add networking support to P1023RDS
powerpc/hydra: Add ethernet support on P5020/P3041 DS boards
powerpc/85xx: Add FMan ethernet support to P4080DS
powerpc/85xx: Add support for FMan ethernet in Independent mode
powerpc/mpc8548cds: Cleanup mpc8548cds.c
powerpc/mp: add support for discontiguous cores
powerpc/85xx: corenet_ds - Remove unused 'execute' perm in TLB entries
fdt: Add new fdt_create_phandle helper
fdt: Rename fdt_create_phandle to fdt_set_phandle
powerpc/85xx: Fix compile warnings/errors if CONFIG_SYS_DPAA_FMAN isn't set
fsl_ifc: Add the workaround for erratum IFC A-003399(enabled on P1010)
powerpc/P1010: Add workaround for erratum P1010-A003549 (related to IFC)
fsl_ifc: Add the workaround for erratum IFC-A002769 (enable on P1010)
powerpc/85xx: Expanding the window of CCSRBAR in AS=1 from 4k to 1M
powerpc/85xx: Add NAND/NAND_SPL support to P1010RDB
nand: Freescale Integrated Flash Controller NAND support
powerpc/85xx: Add basic support for P1010RDB
powerpc/85xx: Add support for new P102x/P2020 RDB style boards
powerpc/85xx: relocate CCSR before creating the initial RAM area
powerpc/85xx: introduce and document CONFIG_SYS_CCSRBAR macros
powerpc/85xx: Enable internal USB UTMI PHY on p204x/p3041/p50x0
powerpc/85xx: Add ULPI and UTMI USB Phy support for P1010/P1014
Diffstat (limited to 'arch/powerpc/cpu')
30 files changed, 1247 insertions, 145 deletions
diff --git a/arch/powerpc/cpu/mpc83xx/Makefile b/arch/powerpc/cpu/mpc83xx/Makefile index 3979b6f..b353036 100644 --- a/arch/powerpc/cpu/mpc83xx/Makefile +++ b/arch/powerpc/cpu/mpc83xx/Makefile @@ -34,7 +34,6 @@ COBJS-y += cpu.o COBJS-y += cpu_init.o COBJS-y += speed.o COBJS-y += interrupts.o -COBJS-y += spd_sdram.o COBJS-y += ecc.o COBJS-$(CONFIG_QE) += qe_io.o COBJS-$(CONFIG_FSL_SERDES) += serdes.o @@ -42,6 +41,13 @@ COBJS-$(CONFIG_PCI) += pci.o COBJS-$(CONFIG_PCIE) += pcie.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +ifdef CONFIG_FSL_DDR2 +COBJS-$(CONFIG_MPC8349) += ddr-gen2.o +else +COBJS-y += spd_sdram.o +endif +COBJS-$(CONFIG_FSL_DDR2) += law.o + COBJS := $(COBJS-y) SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -52,6 +58,18 @@ all: $(obj).depend $(START) $(LIB) $(LIB): $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(obj)ddr-gen1.c: + @rm -f $(obj)ddr-gen1.c + ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen1.c $(obj)ddr-gen1.c + +$(obj)ddr-gen2.c: + @rm -f $(obj)ddr-gen2.c + ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen2.c $(obj)ddr-gen2.c + +$(obj)ddr-gen3.c: + @rm -f $(obj)ddr-gen3.c + ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen3.c $(obj)ddr-gen3.c + ######################################################################### # defines $(obj).depend target diff --git a/arch/powerpc/cpu/mpc83xx/ecc.c b/arch/powerpc/cpu/mpc83xx/ecc.c index f8eab96..717365c 100644 --- a/arch/powerpc/cpu/mpc83xx/ecc.c +++ b/arch/powerpc/cpu/mpc83xx/ecc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Freescale Semiconductor, Inc. + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. * * Dave Liu <daveliu@freescale.com> * based on the contribution of Marian Balakowicz <m8@semihalf.com> @@ -20,8 +20,12 @@ #if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) void ecc_print_status(void) { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ddr83xx_t *ddr = &immap->ddr; + immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +#ifdef CONFIG_FSL_DDR2 + ccsr_ddr_t *ddr = &immap->ddr; +#else + ddr83xx_t *ddr = &immap->ddr; +#endif printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF"); @@ -100,8 +104,12 @@ void ecc_print_status(void) int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ddr83xx_t *ddr = &immap->ddr; + immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +#ifdef CONFIG_FSL_DDR2 + ccsr_ddr_t *ddr = &immap->ddr; +#else + ddr83xx_t *ddr = &immap->ddr; +#endif volatile u32 val; u64 *addr; u32 count; diff --git a/arch/powerpc/cpu/mpc83xx/law.c b/arch/powerpc/cpu/mpc83xx/law.c new file mode 100644 index 0000000..66c88b6 --- /dev/null +++ b/arch/powerpc/cpu/mpc83xx/law.c @@ -0,0 +1,61 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include <common.h> +#include <asm/fsl_law.h> +#include <asm/mmu.h> + +int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) +{ + immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; + law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; + u64 start_align, law_sz; + int law_sz_enc; + + if (start == 0) + start_align = 1ull << (LAW_SIZE_2G + 1); + else + start_align = 1ull << (ffs64(start) - 1); + law_sz = min(start_align, sz); + law_sz_enc = __ilog2_u64(law_sz) - 1; + + /* + * Set up LAWBAR for all of DDR. + */ + ecm->bar = start & 0xfffff000; + ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); + debug("DDR:bar=0x%08x\n", ecm->bar); + debug("DDR:ar=0x%08x\n", ecm->ar); + + /* recalculate size based on what was actually covered by the law */ + law_sz = 1ull << __ilog2_u64(law_sz); + + /* do we still have anything to map */ + sz = sz - law_sz; + if (sz) { + start += law_sz; + + start_align = 1ull << (ffs64(start) - 1); + law_sz = min(start_align, sz); + law_sz_enc = __ilog2_u64(law_sz) - 1; + ecm = &immap->sysconf.ddrlaw[1]; + ecm->bar = start & 0xfffff000; + ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); + debug("DDR:bar=0x%08x\n", ecm->bar); + debug("DDR:ar=0x%08x\n", ecm->ar); + } else { + return 0; + } + + /* do we still have anything to map */ + sz = sz - law_sz; + if (sz) + return 1; + + return 0; +} diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c index 4542ab1..f78099d 100644 --- a/arch/powerpc/cpu/mpc83xx/speed.c +++ b/arch/powerpc/cpu/mpc83xx/speed.c @@ -507,6 +507,15 @@ ulong get_bus_freq(ulong dummy) return gd->csb_clk; } +/******************************************** + * get_ddr_freq + * return ddr bus freq in Hz + *********************************************/ +ulong get_ddr_freq(ulong dummy) +{ + return gd->mem_clk; +} + int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { char buf[32]; diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 7026bca..058d609 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -67,6 +67,7 @@ COBJS-$(CONFIG_P2020) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2040) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o +COBJS-$(CONFIG_PPC_P3060) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o @@ -81,6 +82,7 @@ COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o +COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o @@ -114,6 +116,7 @@ COBJS-$(CONFIG_P2020) += p2020_serdes.o COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o +COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 7b9f773..a09eb91 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -87,6 +87,22 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) puts("Work-around for Erratum DDR111 enabled\n"); puts("Work-around for Erratum DDR134 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 + puts("Work-around for Erratum IFC-A002769 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + puts("Work-around for Erratum P1010-A003549 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 + puts("Work-around for Erratum IFC A-003399 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 + if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) + puts("Work-around for Erratum NMG DDR120 enabled\n"); +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 + puts("Work-around for Erratum NMG_LBC103 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 22fa461..49c0551 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -64,13 +64,11 @@ int checkcpu (void) u32 ddr_ratio = 0; #endif /* CONFIG_FSL_CORENET */ #endif /* CONFIG_DDR_CLK_FREQ */ - int i; + unsigned int i, core, nr_cores = cpu_numcores(); + u32 mask = cpu_mask(); svr = get_svr(); major = SVR_MAJ(svr); -#ifdef CONFIG_MPC8536 - major &= 0x7; /* the msb of this nibble is a mfg code */ -#endif minor = SVR_MIN(svr); if (cpu_numcores() > 1) { @@ -119,11 +117,11 @@ int checkcpu (void) get_sys_info(&sysinfo); puts("Clock Configuration:"); - for (i = 0; i < cpu_numcores(); i++) { + for_each_cpu(i, core, nr_cores, mask) { if (!(i & 3)) printf ("\n "); - printf("CPU%d:%-4s MHz, ", - i,strmhz(buf1, sysinfo.freqProcessor[i])); + printf("CPU%d:%-4s MHz, ", core, + strmhz(buf1, sysinfo.freqProcessor[core])); } printf("\n CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus)); diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 6aca166..0a4ce53 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -31,6 +31,7 @@ #include <asm/processor.h> #include <ioports.h> #include <sata.h> +#include <fm_eth.h> #include <asm/io.h> #include <asm/cache.h> #include <asm/mmu.h> @@ -225,7 +226,9 @@ void cpu_init_f (void) #ifdef CONFIG_SYS_DCSRBAR_PHYS ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif - +#if defined(CONFIG_SECURE_BOOT) + struct law_entry law; +#endif #ifdef CONFIG_MPC8548 ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); uint svr = get_svr(); @@ -243,6 +246,13 @@ void cpu_init_f (void) disable_tlb(14); disable_tlb(15); +#if defined(CONFIG_SECURE_BOOT) + /* Disable the LAW created for NOR flash by the PBI commands */ + law = find_law(CONFIG_SYS_PBI_FLASH_BASE); + if (law.index != -1) + disable_law(law.index); +#endif + #ifdef CONFIG_CPM2 config_8560_ioports((ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR); #endif @@ -453,6 +463,9 @@ skip_l2: clrsetbits_be32(&lbc->lcrr, LCRR_CLKDIV, CONFIG_SYS_LBC_LCRR); __raw_readl(&lbc->lcrr); isync(); +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 + udelay(100); +#endif #endif #ifdef CONFIG_SYS_FSL_USB1_PHY_ENABLE @@ -472,6 +485,10 @@ skip_l2: } #endif +#ifdef CONFIG_FMAN_ENET + fman_enet_init(); +#endif + return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 32aa94b..4ef3c9a 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Freescale Semiconductor, Inc + * Copyright 2009-2011 Freescale Semiconductor, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,59 +21,59 @@ #include <asm/processor.h> #include <asm/mmu.h> #include <asm/fsl_law.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; -#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) -#ifdef CONFIG_FSL_CORENET -static void setup_ccsrbar(void) +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +void setup_ifc(void) { - u32 temp; - volatile u32 *ccsr_virt = (volatile u32 *)(CONFIG_SYS_CCSRBAR + 0x1000); - volatile ccsr_local_t *ccm; + struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + u32 _mas0, _mas1, _mas2, _mas3, _mas7; + phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS; /* - * We can't call set_law() because we haven't moved - * CCSR yet. + * Adjust the TLB we were running out of to match the phys addr of the + * chip select we are adjusting and will return to. */ - ccm = (void *)ccsr_virt; - - out_be32(&ccm->law[0].lawbarh, - (u64)CONFIG_SYS_CCSRBAR_PHYS >> 32); - out_be32(&ccm->law[0].lawbarl, (u32)CONFIG_SYS_CCSRBAR_PHYS); - out_be32(&ccm->law[0].lawar, - LAW_EN | (0x1e << 20) | LAW_SIZE_4K); - - in_be32((u32 *)(ccsr_virt + 0)); - in_be32((u32 *)(ccsr_virt + 1)); - isync(); - - ccm = (void *)CONFIG_SYS_CCSRBAR; - /* Now use the temporary LAW to move CCSR */ - out_be32(&ccm->ccsrbarh, (u64)CONFIG_SYS_CCSRBAR_PHYS >> 32); - out_be32(&ccm->ccsrbarl, (u32)CONFIG_SYS_CCSRBAR_PHYS); - out_be32(&ccm->ccsrar, CCSRAR_C); - temp = in_be32(&ccm->ccsrar); - disable_law(0); -} -#else -static void setup_ccsrbar(void) -{ - u32 temp; - volatile u32 *ccsr_virt = (volatile u32 *)(CONFIG_SYS_CCSRBAR + 0x1000); + flash_phys += (~CONFIG_SYS_AMASK0) + 1 - 4*1024*1024; + + _mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(15); + _mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_IPROT | + MAS1_TSIZE(BOOKE_PAGESZ_4M); + _mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_TEXT_BASE, MAS2_I|MAS2_G); + _mas3 = FSL_BOOKE_MAS3(flash_phys, 0, MAS3_SW|MAS3_SR|MAS3_SX); + _mas7 = FSL_BOOKE_MAS7(flash_phys); + + mtspr(MAS0, _mas0); + mtspr(MAS1, _mas1); + mtspr(MAS2, _mas2); + mtspr(MAS3, _mas3); + mtspr(MAS7, _mas7); - temp = in_be32(ccsr_virt); - out_be32(ccsr_virt, CONFIG_SYS_CCSRBAR_PHYS >> 12); - temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR); + asm volatile("isync;msync;tlbwe;isync"); + + out_be32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0); + out_be32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0); + out_be32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0); + + return ; } #endif -#endif /* We run cpu_init_early_f in AS = 1 */ void cpu_init_early_f(void) { u32 mas0, mas1, mas2, mas3, mas7; int i; +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) + ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; + u32 *l2srbar, *dst, *src; + void (*setup_ifc_sram)(void); +#endif /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -85,28 +85,77 @@ void cpu_init_early_f(void) for (i = 0; i < sizeof(gd_t); i++) ((char *)gd)[i] = 0; - mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0); - mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M); mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G); mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR); mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_PHYS); write_tlb(mas0, mas1, mas2, mas3, mas7); - /* set up CCSR if we want it moved */ -#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) - mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(1); - /* mas1 is the same as above */ - mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G); - mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, MAS3_SW|MAS3_SR); - mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_DEFAULT); +/* + * Work Around for IFC Erratum A-003549. This issue is P1010 + * specific. LCLK(a free running clk signal) is muxed with IFC_CS3 on P1010 SOC + * Hence specifically selecting CS3. + */ +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_LCLK_IFC_CS3); +#endif + + init_laws(); + +/* + * Work Around for IFC Erratum A003399, issue will hit only when execution + * from NOR Flash + */ +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +#define SRAM_BASE_ADDR (0x00000000) + /* TLB for SRAM */ + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(9); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | + MAS1_TSIZE(BOOKE_PAGESZ_1M); + mas2 = FSL_BOOKE_MAS2(SRAM_BASE_ADDR, MAS2_I); + mas3 = FSL_BOOKE_MAS3(SRAM_BASE_ADDR, 0, MAS3_SX|MAS3_SW|MAS3_SR); + mas7 = FSL_BOOKE_MAS7(0); write_tlb(mas0, mas1, mas2, mas3, mas7); - setup_ccsrbar(); + out_be32(&l2cache->l2srbar0, SRAM_BASE_ADDR); + + out_be32(&l2cache->l2errdis, + (MPC85xx_L2ERRDIS_MBECC | MPC85xx_L2ERRDIS_SBECC)); + + out_be32(&l2cache->l2ctl, + (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE)); + + /* + * Copy the code in setup_ifc to L2SRAM. Do a word copy + * because NOR Flash on P1010 does not support byte + * access (Erratum IFC-A002769) + */ + setup_ifc_sram = (void *)SRAM_BASE_ADDR; + dst = (u32 *) SRAM_BASE_ADDR; + src = (u32 *) setup_ifc; + for (i = 0; i < 1024; i++) + *l2srbar++ = *src++; + + setup_ifc_sram(); + + /* CLEANUP */ + clrbits_be32(&l2cache->l2ctl, + (MPC85xx_L2CTL_L2E | + MPC85xx_L2CTL_L2SRAM_ENTIRE)); + out_be32(&l2cache->l2srbar0, 0x0); +#endif + + invalidate_tlb(1); + +#if defined(CONFIG_SECURE_BOOT) + /* Disable the TLBs created by ISBC */ + for (i = CONFIG_SYS_ISBC_START_TLB; + i < CONFIG_SYS_ISBC_START_TLB + CONFIG_SYS_ISBC_NUM_TLBS; i++) + disable_tlb(i); #endif - init_laws(); - invalidate_tlb(0); init_tlbs(); } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c index 796d398..f33db02 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c @@ -21,10 +21,12 @@ */ #include <common.h> +#include <asm/fsl_ifc.h> #include <asm/io.h> void cpu_init_f(void) { +#ifdef CONFIG_FSL_LBC fsl_lbc_t *lbc = LBC_BASE_ADDR; /* @@ -39,6 +41,16 @@ void cpu_init_f(void) #else #error CONFIG_SYS_NAND_BR_PRELIM, CONFIG_SYS_NAND_OR_PRELIM must be defined #endif +#endif +#ifdef CONFIG_FSL_IFC +#ifndef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 +#if defined(CONFIG_SYS_CSPR0) && defined(CONFIG_SYS_CSOR0) + set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); + set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); + set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); +#endif +#endif +#endif #if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR) ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c index 655f99c..49000a1 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2008-2011 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -8,6 +8,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/processor.h> #include <asm/fsl_ddr_sdram.h> #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) @@ -18,13 +19,36 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, unsigned int ctrl_num) { unsigned int i; - volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; +#ifdef CONFIG_MPC83xx + ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC83xx_DDR_ADDR; +#else + ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + uint svr; +#endif +#endif if (ctrl_num) { printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); return; } +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 + /* + * Set the DDR IO receiver to an acceptable bias point. + * Fixed in Rev 2.1. + */ + svr = get_svr(); + if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) { + if ((regs->ddr_sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) == + SDRAM_CFG_SDRAM_TYPE_DDR2) + out_be32(&gur->ddrioovcr, 0x90000000); + else + out_be32(&gur->ddrioovcr, 0xA8000000); + } +#endif + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (i == 0) { out_be32(&ddr->cs0_bnds, regs->cs[i].bnds); diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 8f13cd8..d20c94c 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -361,6 +361,7 @@ void fdt_add_enet_stashing(void *fdt) } #if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME) +#ifdef CONFIG_SYS_DPAA_FMAN static void ft_fixup_clks(void *blob, const char *compat, u32 offset, unsigned long freq) { @@ -374,12 +375,14 @@ static void ft_fixup_clks(void *blob, const char *compat, u32 offset, "for %s: %s\n", compat, fdt_strerror(off)); } } +#endif static void ft_fixup_dpaa_clks(void *blob) { sys_info_t sysinfo; get_sys_info(&sysinfo); +#ifdef CONFIG_SYS_DPAA_FMAN ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM1_OFFSET, sysinfo.freqFMan[0]); @@ -387,6 +390,7 @@ static void ft_fixup_dpaa_clks(void *blob) ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM2_OFFSET, sysinfo.freqFMan[1]); #endif +#endif #ifdef CONFIG_SYS_DPAA_PME do_fixup_by_compat_u32(blob, "fsl,pme", diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 4307a4c..07e58ed 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -482,6 +482,13 @@ static void wait_for_rstdone(unsigned int bank) printf("SERDES: timeout resetting bank %u\n", bank + 1); } + +void __soc_serdes_init(void) +{ + /* Allow for SoC-specific initialization in <SOC>_serdes.c */ +}; +void soc_serdes_init(void) __attribute__((weak, alias("__soc_serdes_init"))); + void fsl_serdes_init(void) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -570,6 +577,8 @@ void fsl_serdes_init(void) } } + soc_serdes_init(); + #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 /* * Bank two uses the clock from bank three, so if bank two is enabled, diff --git a/arch/powerpc/cpu/mpc85xx/liodn.c b/arch/powerpc/cpu/mpc85xx/liodn.c index bd19094..e0ea502 100644 --- a/arch/powerpc/cpu/mpc85xx/liodn.c +++ b/arch/powerpc/cpu/mpc85xx/liodn.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 Freescale Semiconductor, Inc. + * Copyright 2008-2011 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -120,6 +120,19 @@ static void setup_pme_liodn_base(void) #endif } +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +static void setup_raide_liodn_base(void) +{ + struct ccsr_raide *raide = (void *)CONFIG_SYS_FSL_RAID_ENGINE_ADDR; + + /* setup raid engine liodn base for data/desc ; both set to 47 */ + u32 base = (liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0] << 16) | + liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0]; + + out_be32(&raide->liodnbr, base); +} +#endif + void set_liodns(void) { /* setup general liodn offsets */ @@ -145,6 +158,12 @@ void set_liodns(void) #endif /* setup PME liodn base */ setup_pme_liodn_base(); + +#ifdef CONFIG_SYS_FSL_RAID_ENGINE + /* raid engine ccr addr code for liodn */ + set_liodn(raide_liodn_tbl, raide_liodn_tbl_sz); + setup_raide_liodn_base(); +#endif } static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) @@ -184,4 +203,8 @@ void fdt_fixup_liodn(void *blob) #endif #endif fdt_fixup_liodn_tbl(blob, sec_liodn_tbl, sec_liodn_tbl_sz); + +#ifdef CONFIG_SYS_FSL_RAID_ENGINE + fdt_fixup_liodn_tbl(blob, raide_liodn_tbl, raide_liodn_tbl_sz); +#endif } diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 758e6d7..ffc2a9a 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -221,14 +221,14 @@ ulong get_spin_virt_addr(void) #ifdef CONFIG_FSL_CORENET static void plat_mp_up(unsigned long bootpg) { - u32 up, cpu_up_mask, whoami; + u32 cpu_up_mask, whoami; u32 *table = (u32 *)get_spin_virt_addr(); volatile ccsr_gur_t *gur; volatile ccsr_local_t *ccm; volatile ccsr_rcpm_t *rcpm; volatile ccsr_pic_t *pic; int timeout = 10; - u32 nr_cpus; + u32 mask = cpu_mask(); struct law_entry e; gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -236,8 +236,6 @@ static void plat_mp_up(unsigned long bootpg) rcpm = (void *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR); pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); - nr_cpus = ((in_be32(&pic->frr) >> 8) & 0xff) + 1; - whoami = in_be32(&pic->whoami); cpu_up_mask = 1 << whoami; out_be32(&ccm->bstrl, bootpg); @@ -251,19 +249,18 @@ static void plat_mp_up(unsigned long bootpg) /* disable time base at the platform */ out_be32(&rcpm->ctbenrl, cpu_up_mask); - /* release the hounds */ - up = ((1 << nr_cpus) - 1); - out_be32(&gur->brrl, up); + out_be32(&gur->brrl, mask); /* wait for everyone */ while (timeout) { - int i; - for (i = 0; i < nr_cpus; i++) { - if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER]) - cpu_up_mask |= (1 << i); - }; + unsigned int i, cpu, nr_cpus = cpu_numcores(); - if ((cpu_up_mask & up) == up) + for_each_cpu(i, cpu, nr_cpus, mask) { + if (table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER]) + cpu_up_mask |= (1 << cpu); + } + + if ((cpu_up_mask & mask) == mask) break; udelay(100); @@ -272,7 +269,7 @@ static void plat_mp_up(unsigned long bootpg) if (timeout == 0) printf("CPU up timeout. CPU up mask is %x should be %x\n", - cpu_up_mask, up); + cpu_up_mask, mask); /* enable time base at the platform */ out_be32(&rcpm->ctbenrl, 0); @@ -283,7 +280,7 @@ static void plat_mp_up(unsigned long bootpg) mtspr(SPRN_TBWU, 0); mtspr(SPRN_TBWL, 0); - out_be32(&rcpm->ctbenrl, (1 << nr_cpus) - 1); + out_be32(&rcpm->ctbenrl, mask); #ifdef CONFIG_MPC8xxx_DISABLE_BPTR /* diff --git a/arch/powerpc/cpu/mpc85xx/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c new file mode 100644 index 0000000..07703d4 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p3060_ids.c @@ -0,0 +1,113 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> + +#ifdef CONFIG_SYS_DPAA_QBMAN +struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { + /* dqrr liodn, frame data liodn, liodn off, sdest */ + SET_QP_INFO( 1, 2, 1, 0), + SET_QP_INFO( 3, 4, 2, 1), + SET_QP_INFO( 5, 6, 3, 2), + SET_QP_INFO( 7, 8, 4, 3), + SET_QP_INFO( 9, 10, 5, 4), + SET_QP_INFO(11, 12, 6, 5), + SET_QP_INFO(13, 14, 7, 6), + SET_QP_INFO(15, 16, 8, 7), + SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ + SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ +}; +#endif + +struct liodn_id_table liodn_tbl[] = { + SET_USB_LIODN(1, "fsl-usb2-mph", 127), + SET_USB_LIODN(2, "fsl-usb2-dr", 157), + + SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193), + SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194), + + SET_DMA_LIODN(1, 196), + SET_DMA_LIODN(2, 197), + + SET_GUTS_LIODN("fsl,rapidio-delta", 198, rio1liodnr, 0), + SET_GUTS_LIODN(NULL, 199, rio2liodnr, 0), + SET_GUTS_LIODN(NULL, 200, rmuliodnr, 0), + +#ifdef CONFIG_SYS_DPAA_QBMAN + SET_QMAN_LIODN(31), + SET_BMAN_LIODN(32), +#endif + SET_PME_LIODN(128), +}; +int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); + +#ifdef CONFIG_SYS_DPAA_FMAN +struct liodn_id_table fman1_liodn_tbl[] = { + SET_FMAN_RX_1G_LIODN(1, 0, 11), + SET_FMAN_RX_1G_LIODN(1, 1, 12), + SET_FMAN_RX_1G_LIODN(1, 2, 13), + SET_FMAN_RX_1G_LIODN(1, 3, 14), +}; +int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); + +#if (CONFIG_SYS_NUM_FMAN == 2) +struct liodn_id_table fman2_liodn_tbl[] = { + SET_FMAN_RX_1G_LIODN(2, 0, 16), + SET_FMAN_RX_1G_LIODN(2, 1, 17), + SET_FMAN_RX_1G_LIODN(2, 2, 18), + SET_FMAN_RX_1G_LIODN(2, 3, 19), +}; +int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); +#endif +#endif + +struct liodn_id_table sec_liodn_tbl[] = { + SET_SEC_JR_LIODN_ENTRY(0, 146, 154), + SET_SEC_JR_LIODN_ENTRY(1, 147, 155), + SET_SEC_JR_LIODN_ENTRY(2, 178, 186), + SET_SEC_JR_LIODN_ENTRY(3, 179, 187), + SET_SEC_RTIC_LIODN_ENTRY(a, 144), + SET_SEC_RTIC_LIODN_ENTRY(b, 145), + SET_SEC_RTIC_LIODN_ENTRY(c, 176), + SET_SEC_RTIC_LIODN_ENTRY(d, 177), + SET_SEC_DECO_LIODN_ENTRY(0, 129, 161), + SET_SEC_DECO_LIODN_ENTRY(1, 130, 162), + SET_SEC_DECO_LIODN_ENTRY(2, 131, 163), + SET_SEC_DECO_LIODN_ENTRY(3, 132, 164), + SET_SEC_DECO_LIODN_ENTRY(4, 133, 165), +}; +int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); + +struct liodn_id_table liodn_bases[] = { + [FSL_HW_PORTAL_SEC] = SET_LIODN_BASE_2(96, 106), +#ifdef CONFIG_SYS_DPAA_FMAN + [FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32), +#if (CONFIG_SYS_NUM_FMAN == 2) + [FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64), +#endif +#endif +#ifdef CONFIG_SYS_DPAA_PME + [FSL_HW_PORTAL_PME] = SET_LIODN_BASE_2(116, 133), +#endif +}; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c new file mode 100644 index 0000000..6387276 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c @@ -0,0 +1,138 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/fsl_serdes.h> +#include <asm/processor.h> +#include <asm/io.h> +#include "fsl_corenet_serdes.h" + +static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { + [0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, + SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1, + SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, + NONE, NONE, AURORA, AURORA}, + [0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3, + SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, + SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, + SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA}, + [0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, + AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, + SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, + SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, + [0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, + AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3, + SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, + [0x1c] = {NONE, NONE, SRIO1, SRIO2, NONE, NONE, NONE, NONE, + AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, + SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, + SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, +}; + +enum srds_prtcl serdes_get_prtcl(int cfg, int lane) +{ + if (!serdes_lane_enabled(lane)) + return NONE; + + return serdes_cfg_tbl[cfg][lane]; +} + +int is_serdes_prtcl_valid(u32 prtcl) +{ + int i; + + if (prtcl > ARRAY_SIZE(serdes_cfg_tbl)) + return 0; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_cfg_tbl[prtcl][i] != NONE) + return 1; + } + + return 0; +} + +void soc_serdes_init(void) +{ + /* + * On the P3060 the devdisr2 register does not correctly reflect + * the state of the MACs based on the RCW fields. So disable the MACs + * based on the srds_prtcl and ec1, ec2, ec3 fields + */ + + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 devdisr2 = in_be32(&gur->devdisr2); + u32 rcwsr11 = in_be32(&gur->rcwsr[11]); + u32 rcwsr13 = in_be32(&gur->rcwsr[13]); + u32 ec1_ext, ec2_ext; + + /* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */ + + if (!is_serdes_configured(SGMII_FM1_DTSEC3)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3; + + if (!is_serdes_configured(SGMII_FM1_DTSEC4)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4; + + if (!is_serdes_configured(SGMII_FM2_DTSEC1)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1; + + if (!is_serdes_configured(SGMII_FM2_DTSEC2)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2; + + if (!is_serdes_configured(SGMII_FM2_DTSEC3)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3; + + if (!is_serdes_configured(SGMII_FM2_DTSEC4)) + devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4; + + if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == + FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) { + devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2; + } + + if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == + FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) { + devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1; + } + + ec1_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC1_EXT; + if (ec1_ext) { + if ((ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_RGMII) || + (ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_MII)) + devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_4; + } + + ec2_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC2_EXT; + if (ec2_ext) { + if ((ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_RGMII) || + (ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_MII)) + devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4; + } + + if ((rcwsr13 & FSL_CORENET_RCWSR13_EC3) == + FSL_CORENET_RCWSR13_EC3_FM2_DTSEC4_MII) + devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4; + + out_be32(&gur->devdisr2, devdisr2); +} diff --git a/arch/powerpc/cpu/mpc85xx/p5020_ids.c b/arch/powerpc/cpu/mpc85xx/p5020_ids.c index 9836588..2911c13 100644 --- a/arch/powerpc/cpu/mpc85xx/p5020_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p5020_ids.c @@ -97,6 +97,16 @@ struct liodn_id_table sec_liodn_tbl[] = { }; int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); +#ifdef CONFIG_SYS_FSL_RAID_ENGINE +struct liodn_id_table raide_liodn_tbl[] = { + SET_RAID_ENGINE_JQ_LIODN_ENTRY(0, 0, 60), + SET_RAID_ENGINE_JQ_LIODN_ENTRY(0, 1, 61), + SET_RAID_ENGINE_JQ_LIODN_ENTRY(1, 0, 62), + SET_RAID_ENGINE_JQ_LIODN_ENTRY(1, 1, 63), +}; +int raide_liodn_tbl_sz = ARRAY_SIZE(raide_liodn_tbl); +#endif + struct liodn_id_table liodn_bases[] = { [FSL_HW_PORTAL_SEC] = SET_LIODN_BASE_2(64, 100), #ifdef CONFIG_SYS_DPAA_FMAN @@ -105,4 +115,7 @@ struct liodn_id_table liodn_bases[] = { #ifdef CONFIG_SYS_DPAA_PME [FSL_HW_PORTAL_PME] = SET_LIODN_BASE_2(136, 172), #endif +#ifdef CONFIG_SYS_FSL_RAID_ENGINE + [FSL_HW_PORTAL_RAID_ENGINE] = SET_LIODN_BASE_1(47), +#endif }; diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c index ecaa30d..418dd9d 100644 --- a/arch/powerpc/cpu/mpc85xx/portals.c +++ b/arch/powerpc/cpu/mpc85xx/portals.c @@ -151,7 +151,7 @@ static int fdt_qportal(void *blob, int off, int id, char *name, dev_handle = fdt_get_phandle(blob, dev_off); if (dev_handle <= 0) { dev_handle = fdt_alloc_phandle(blob); - ret = fdt_create_phandle(blob, dev_off, + ret = fdt_set_phandle(blob, dev_off, dev_handle); if (ret < 0) return ret; @@ -198,7 +198,10 @@ void fdt_fixup_qportals(void *blob) u32 liodns[2]; #endif const int *ci = fdt_getprop(blob, off, "cell-index", NULL); - int j, i = *ci; + int i = *ci; +#ifdef CONFIG_SYS_DPAA_FMAN + int j; +#endif err = fdt_setprop(blob, off, "compatible", compat, compat_len); if (err < 0) diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index a83dfeb..ce47532 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -41,6 +41,7 @@ void get_sys_info (sys_info_t * sysInfo) volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #ifdef CONFIG_FSL_CORENET volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR); + unsigned int cpu; const u8 core_cplx_PLL[16] = { [ 0] = 0, /* CC1 PPL / 1 */ @@ -97,11 +98,11 @@ void get_sys_info (sys_info_t * sysInfo) freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i]; } rcw_tmp = in_be32(&gur->rcwsr[3]); - for (i = 0; i < cpu_numcores(); i++) { - u32 c_pll_sel = (in_be32(&clk->clkc0csr + i*8) >> 27) & 0xf; + for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { + u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; u32 cplx_pll = core_cplx_PLL[c_pll_sel]; - sysInfo->freqProcessor[i] = + sysInfo->freqProcessor[cpu] = freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; } diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 878a3d6..5e0d78d 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -83,6 +83,45 @@ _start_e500: +#if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) + /* ISBC uses L2 as stack. + * Disable L2 cache here so that u-boot can enable it later + * as part of it's normal flow + */ + + /* Check if L2 is enabled */ + mfspr r3, SPRN_L2CSR0 + lis r2, L2CSR0_L2E@h + ori r2, r2, L2CSR0_L2E@l + and. r4, r3, r2 + beq l2_disabled + + mfspr r3, SPRN_L2CSR0 + /* Flush L2 cache */ + lis r2,(L2CSR0_L2FL)@h + ori r2, r2, (L2CSR0_L2FL)@l + or r3, r2, r3 + sync + isync + mtspr SPRN_L2CSR0,r3 + isync +1: + mfspr r3, SPRN_L2CSR0 + and. r1, r3, r2 + bne 1b + + mfspr r3, SPRN_L2CSR0 + lis r2, L2CSR0_L2E@h + ori r2, r2, L2CSR0_L2E@l + andc r4, r3, r2 + sync + isync + mtspr SPRN_L2CSR0,r4 + isync + +l2_disabled: +#endif + /* clear registers/arrays not reset by hardware */ /* L1 */ @@ -279,10 +318,244 @@ _start_e500: #endif /* CONFIG_MPC8569 */ +/* + * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default + * location is not where we want it. This typically happens on a 36-bit + * system, where we want to move CCSR to near the top of 36-bit address space. + * + * To move CCSR, we create two temporary TLBs, one for the old location, and + * another for the new location. On CoreNet systems, we also need to create + * a special, temporary LAW. + * + * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for + * long-term TLBs, so we use TLB0 here. + */ +#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) + +#if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW) +#error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." +#endif + +purge_old_ccsr_tlb: + lis r8, CONFIG_SYS_CCSRBAR@h + ori r8, r8, CONFIG_SYS_CCSRBAR@l + lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h + ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l + + /* + * In a multi-stage boot (e.g. NAND boot), a previous stage may have + * created a TLB for CCSR, which will interfere with our relocation + * code. Since we're going to create a new TLB for CCSR anyway, + * it should be safe to delete this old TLB here. We have to search + * for it, though. + */ + + li r1, 0 + mtspr MAS6, r1 /* Search the current address space and PID */ + tlbsx 0, r8 + mfspr r1, MAS1 + andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ + beq 1f /* Skip if no TLB found */ + + rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ + mtspr MAS1, r1 + tlbwe +1: + +create_ccsr_new_tlb: + /* + * Create a TLB for the new location of CCSR. Register R8 is reserved + * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). + */ + lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h + ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l + lis r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l + lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h + ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l + lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h + ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l + lis r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r7, r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r7 + isync + msync + tlbwe + + /* + * Create a TLB for the old location of CCSR. Register R9 is reserved + * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). + */ +create_ccsr_old_tlb: + lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h + ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l + lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h + ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l + lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@h + ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@l + li r7, 0 /* The default CCSR address is always a 32-bit number */ + mtspr MAS0, r0 + /* MAS1 is the same as above */ + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r7 + isync + msync + tlbwe + +#ifdef CONFIG_FSL_CORENET + +#define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) +#define LAW_EN 0x80000000 +#define LAW_SIZE_4K 0xb +#define CCSRBAR_LAWAR (LAW_EN | (0x1e << 20) | LAW_SIZE_4K) +#define CCSRAR_C 0x80000000 /* Commit */ + +create_temp_law: + /* + * On CoreNet systems, we create the temporary LAW using a special LAW + * target ID of 0x1e. LAWBARH is at offset 0xc00 in CCSR. + */ + lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h + ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l + lis r2, CCSRBAR_LAWAR@h + ori r2, r2, CCSRBAR_LAWAR@l + + stw r0, 0xc00(r9) /* LAWBARH0 */ + stw r1, 0xc04(r9) /* LAWBARL0 */ + sync + stw r2, 0xc08(r9) /* LAWAR0 */ + + /* + * Read back from LAWAR to ensure the update is complete. e500mc + * cores also require an isync. + */ + lwz r0, 0xc08(r9) /* LAWAR0 */ + isync + + /* + * Read the current CCSRBARH and CCSRBARL using load word instructions. + * Follow this with an isync instruction. This forces any outstanding + * accesses to configuration space to completion. + */ +read_old_ccsrbar: + lwz r0, 0(r9) /* CCSRBARH */ + lwz r0, 4(r9) /* CCSRBARH */ + isync + + /* + * Write the new values for CCSRBARH and CCSRBARL to their old + * locations. The CCSRBARH has a shadow register. When the CCSRBARH + * has a new value written it loads a CCSRBARH shadow register. When + * the CCSRBARL is written, the CCSRBARH shadow register contents + * along with the CCSRBARL value are loaded into the CCSRBARH and + * CCSRBARL registers, respectively. Follow this with a sync + * instruction. + */ +write_new_ccsrbar: + lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h + ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l + lis r2, CCSRAR_C@h + ori r2, r2, CCSRAR_C@l + + stw r0, 0(r9) /* Write to CCSRBARH */ + sync /* Make sure we write to CCSRBARH first */ + stw r1, 4(r9) /* Write to CCSRBARL */ + sync + + /* + * Write a 1 to the commit bit (C) of CCSRAR at the old location. + * Follow this with a sync instruction. + */ + stw r2, 8(r9) + sync + + /* Delete the temporary LAW */ +delete_temp_law: + li r1, 0 + stw r1, 0xc08(r8) + sync + stw r1, 0xc00(r8) + stw r1, 0xc04(r8) + sync + +#else /* #ifdef CONFIG_FSL_CORENET */ + +write_new_ccsrbar: + /* + * Read the current value of CCSRBAR using a load word instruction + * followed by an isync. This forces all accesses to configuration + * space to complete. + */ + sync + lwz r0, 0(r9) + isync + +/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */ +#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \ + (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12)) + + /* Write the new value to CCSRBAR. */ + lis r0, CCSRBAR_PHYS_RS12@h + ori r0, r0, CCSRBAR_PHYS_RS12@l + stw r0, 0(r9) + sync + + /* + * The manual says to perform a load of an address that does not + * access configuration space or the on-chip SRAM using an existing TLB, + * but that doesn't appear to be necessary. We will do the isync, + * though. + */ + isync + + /* + * Read the contents of CCSRBAR from its new location, followed by + * another isync. + */ + lwz r0, 0(r8) + isync + +#endif /* #ifdef CONFIG_FSL_CORENET */ + + /* Delete the temporary TLBs */ +delete_temp_tlbs: + lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h + ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l + li r1, 0 + lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h + ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + isync + msync + tlbwe + + lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h + ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l + lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h + ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l + mtspr MAS0, r0 + mtspr MAS2, r2 + isync + msync + tlbwe +#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ + +create_init_ram_area: lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l -#ifndef CONFIG_SYS_RAMBOOT +#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT) /* create a temp mapping in AS=1 to the 4M boot window */ lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l @@ -293,6 +566,20 @@ _start_e500: /* The 85xx has the default boot window 0xff800000 - 0xffffffff */ lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l +#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) + /* create a temp mapping in AS = 1 for Flash mapping + * created by PBL for ISBC code + */ + lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h + ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l + + lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h + ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l + + lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, + (MAS3_SX|MAS3_SW|MAS3_SR))@h + ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, + (MAS3_SX|MAS3_SW|MAS3_SR))@l #else /* * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds index 8410bd7..852f9aa 100644 --- a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds +++ b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds @@ -23,6 +23,8 @@ * MA 02111-1307 USA */ +#include "config.h" /* CONFIG_BOARDDIR */ + OUTPUT_ARCH(powerpc) SECTIONS { @@ -52,8 +54,18 @@ SECTIONS . = ALIGN(8); __init_begin = .; __init_end = .; - - .resetvec ADDR(.text) + 0xffc : { +#if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */ + .bootpg ADDR(.text) + 0x1000 : + { + start.o (.bootpg) + } +#define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */ +#elif defined(CONFIG_FSL_ELBC) +#define RESET_VECTOR_OFFSET 0xffc /* LBC has 4k sram */ +#else +#error unknown NAND controller +#endif + .resetvec ADDR(.text) + RESET_VECTOR_OFFSET : { KEEP(*(.resetvec)) } = 0xffff @@ -64,4 +76,4 @@ SECTIONS } __bss_end__ = .; } -ASSERT(__init_end <= 0xfff00ffc, "NAND bootstrap too big"); +ASSERT(__init_end <= (0xfff00000 + RESET_VECTOR_OFFSET), "NAND bootstrap too big"); diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 767bc52..0365ca8 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -27,6 +27,7 @@ #include <common.h> #include <command.h> #include <tsec.h> +#include <fm_eth.h> #include <netdev.h> #include <asm/cache.h> #include <asm/io.h> @@ -102,6 +103,8 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2041, P2041_E, 4), CPU_TYPE_ENTRY(P3041, P3041, 4), CPU_TYPE_ENTRY(P3041, P3041_E, 4), + CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3), + CPU_TYPE_ENTRY_MASK(P3060, P3060_E, 6, 0xf3), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4040, P4040_E, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), @@ -129,13 +132,33 @@ struct cpu_type *identify_cpu(u32 ver) return &cpu_type_unknown; } +#define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 +#define MPC8xxx_PICFRR_NCPU_SHIFT 8 + +/* + * Return a 32-bit mask indicating which cores are present on this SOC. + */ +u32 cpu_mask() +{ + ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; + struct cpu_type *cpu = gd->cpu; + + /* better to query feature reporting register than just assume 1 */ + if (cpu == &cpu_type_unknown) + return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> + MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + + return cpu->mask; +} + +/* + * Return the number of cores on this SOC. + */ int cpu_numcores() { ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; struct cpu_type *cpu = gd->cpu; /* better to query feature reporting register than just assume 1 */ -#define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 -#define MPC8xxx_PICFRR_NCPU_SHIFT 8 if (cpu == &cpu_type_unknown) return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> MPC8xxx_PICFRR_NCPU_SHIFT) + 1; @@ -143,6 +166,18 @@ int cpu_numcores() { return cpu->num_cores; } +/* + * Check if the given core ID is valid + * + * Returns zero if it isn't, 1 if it is. + */ +int is_core_valid(unsigned int core) +{ + struct cpu_type *cpu = gd->cpu; + + return !!((1 << core) & cpu->mask); +} + int probecpu (void) { uint svr; @@ -174,5 +209,8 @@ int cpu_eth_init(bd_t *bis) tsec_standard_init(bis); #endif +#ifdef CONFIG_FMAN_ENET + fm_standard_init(bis); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 3824aad..15cd375 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -18,7 +18,9 @@ #include "ddr.h" -#ifdef CONFIG_MPC85xx +#ifdef CONFIG_MPC83xx + #define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR +#elif defined(CONFIG_MPC85xx) #define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR #elif defined(CONFIG_MPC86xx) #define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR @@ -94,6 +96,10 @@ static inline int fsl_ddr_get_rtt(void) * 6 if 2.5ns > tCK >= 1.875ns * 7 if 1.875ns > tCK >= 1.5ns * 8 if 1.5ns > tCK >= 1.25ns + * 9 if 1.25ns > tCK >= 1.07ns + * 10 if 1.07ns > tCK >= 0.935ns + * 11 if 0.935ns > tCK >= 0.833ns + * 12 if 0.833ns > tCK >= 0.75ns */ static inline unsigned int compute_cas_write_latency(void) { @@ -108,8 +114,18 @@ static inline unsigned int compute_cas_write_latency(void) cwl = 7; else if (mclk_ps >= 1250) cwl = 8; - else - cwl = 8; + else if (mclk_ps >= 1070) + cwl = 9; + else if (mclk_ps >= 935) + cwl = 10; + else if (mclk_ps >= 833) + cwl = 11; + else if (mclk_ps >= 750) + cwl = 12; + else { + cwl = 12; + printf("Warning: CWL is out of range\n"); + } return cwl; } @@ -146,7 +162,7 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, break; case 2: if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ - (dimm_number > 1 && dimm_params[dimm_number].n_ranks > 0)) + (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0)) go_config = 1; break; case 3: @@ -617,7 +633,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ unsigned int dll_rst_dis; /* DLL reset disable */ unsigned int dqs_cfg; /* DQS configuration */ - unsigned int odt_cfg; /* ODT configuration */ + unsigned int odt_cfg = 0; /* ODT configuration */ unsigned int num_pr; /* Number of posted refreshes */ unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ unsigned int ap_en; /* Address Parity Enable */ @@ -625,15 +641,16 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, unsigned int rcw_en = 0; /* Register Control Word Enable */ unsigned int md_en = 0; /* Mirrored DIMM Enable */ unsigned int qd_en = 0; /* quad-rank DIMM Enable */ + int i; dll_rst_dis = 1; /* Make this configurable */ dqs_cfg = popts->DQS_config; - if (popts->cs_local_opts[0].odt_rd_cfg - || popts->cs_local_opts[0].odt_wr_cfg) { - /* FIXME */ - odt_cfg = 2; - } else { - odt_cfg = 0; + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + if (popts->cs_local_opts[i].odt_rd_cfg + || popts->cs_local_opts[i].odt_wr_cfg) { + odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; + break; + } } num_pr = 1; /* Make this configurable */ @@ -1018,7 +1035,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #if defined(CONFIG_FSL_DDR2) const unsigned int mclk_ps = get_memory_clk_period_ps(); #endif - + dqs_en = !popts->DQS_config; rtt = fsl_ddr_get_rtt(); al = additive_latency; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 8132e68..20c7db0 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -448,7 +448,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, #if defined(CONFIG_FSL_DDR2) if (lowest_good_caslat < 4) { - additive_latency = picos_to_mclk(tRCD_ps) - lowest_good_caslat; + additive_latency = (picos_to_mclk(tRCD_ps) > lowest_good_caslat) + ? picos_to_mclk(tRCD_ps) - lowest_good_caslat : 0; if (mclk_to_picos(additive_latency) > tRCD_ps) { additive_latency = picos_to_mclk(tRCD_ps); debug("setting additive_latency to %u because it was " diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index 249fd7d..5699b0c 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -34,14 +34,17 @@ extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS, }; -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ +}; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ }; -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index bd9c466..4dc748b 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -26,14 +26,15 @@ extern void fsl_ddr_board_options(memctl_options_t *popts, dimm_params_t *pdimm, unsigned int ctrl_num); -typedef struct { +struct dynamic_odt { unsigned int odt_rd_cfg; unsigned int odt_wr_cfg; unsigned int odt_rtt_norm; unsigned int odt_rtt_wr; -} dynamic_odt_t; +}; -static const dynamic_odt_t single_Q[4] = { +#ifdef CONFIG_FSL_DDR3 +static const struct dynamic_odt single_Q[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS_AND_OTHER_DIMM, @@ -60,7 +61,7 @@ static const dynamic_odt_t single_Q[4] = { } }; -static const dynamic_odt_t single_D[4] = { +static const struct dynamic_odt single_D[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -77,7 +78,7 @@ static const dynamic_odt_t single_D[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t single_S[4] = { +static const struct dynamic_odt single_S[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -89,7 +90,7 @@ static const dynamic_odt_t single_S[4] = { {0, 0, 0, 0}, }; -static const dynamic_odt_t dual_DD[4] = { +static const struct dynamic_odt dual_DD[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -116,7 +117,7 @@ static const dynamic_odt_t dual_DD[4] = { } }; -static const dynamic_odt_t dual_DS[4] = { +static const struct dynamic_odt dual_DS[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -137,7 +138,7 @@ static const dynamic_odt_t dual_DS[4] = { }, {0, 0, 0, 0} }; -static const dynamic_odt_t dual_SD[4] = { +static const struct dynamic_odt dual_SD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -159,7 +160,7 @@ static const dynamic_odt_t dual_SD[4] = { } }; -static const dynamic_odt_t dual_SS[4] = { +static const struct dynamic_odt dual_SS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -176,7 +177,7 @@ static const dynamic_odt_t dual_SS[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t dual_D0[4] = { +static const struct dynamic_odt dual_D0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -193,7 +194,7 @@ static const dynamic_odt_t dual_D0[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t dual_0D[4] = { +static const struct dynamic_odt dual_0D[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -210,7 +211,7 @@ static const dynamic_odt_t dual_0D[4] = { } }; -static const dynamic_odt_t dual_S0[4] = { +static const struct dynamic_odt dual_S0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -223,7 +224,7 @@ static const dynamic_odt_t dual_S0[4] = { }; -static const dynamic_odt_t dual_0S[4] = { +static const struct dynamic_odt dual_0S[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -236,7 +237,7 @@ static const dynamic_odt_t dual_0S[4] = { }; -static const dynamic_odt_t odt_unknown[4] = { +static const struct dynamic_odt odt_unknown[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -262,7 +263,218 @@ static const dynamic_odt_t odt_unknown[4] = { DDR3_RTT_OFF } }; +#else /* CONFIG_FSL_DDR3 */ +static const struct dynamic_odt single_Q[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt single_D[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +static const struct dynamic_odt single_S[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, +}; + +static const struct dynamic_odt dual_DD[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; + +static const struct dynamic_odt dual_DS[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_SD[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; + +static const struct dynamic_odt dual_SS[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_D0[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_0D[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; + +static const struct dynamic_odt dual_S0[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + +}; + +static const struct dynamic_odt dual_0S[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} + +}; + +static const struct dynamic_odt odt_unknown[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; +#endif unsigned int populate_memctl_options(int all_DIMMs_registered, memctl_options_t *popts, dimm_params_t *pdimm, @@ -271,7 +483,8 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, unsigned int i; char buffer[HWCONFIG_BUFFER_SIZE]; char *buf = NULL; - const dynamic_odt_t *pdodt = odt_unknown; + const struct dynamic_odt *pdodt = odt_unknown; + ulong ddr_freq; /* * Extract hwconfig from environment since we have not properly setup @@ -336,7 +549,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, /* Pick chip-select local options. */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { -#if defined(CONFIG_FSL_DDR3) +#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2) popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; @@ -716,6 +929,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, if (pdimm[0].n_ranks == 4) popts->quad_rank_present = 1; + ddr_freq = get_ddr_freq(0) / 1000000; + if (popts->registered_dimm_en) { + popts->rcw_override = 1; + popts->rcw_1 = 0x000a5a00; + if (ddr_freq <= 800) + popts->rcw_2 = 0x00000000; + else if (ddr_freq <= 1066) + popts->rcw_2 = 0x00100000; + else if (ddr_freq <= 1333) + popts->rcw_2 = 0x00200000; + else + popts->rcw_2 = 0x00300000; + } + fsl_ddr_board_options(popts, pdimm, ctrl_num); return 0; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c index 104d360..eb6a17a 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c @@ -20,7 +20,8 @@ #define ULL_8FS 0xFFFFFFFFULL /* - * Round mclk_ps to nearest 10 ps in memory controller code. + * Round up mclk_ps to nearest 1 ps in memory controller code + * if the error is 0.5ps or more. * * If an imprecise data rate is too high due to rounding error * propagation, compute a suitably rounded mclk_ps to compute @@ -32,42 +33,37 @@ unsigned int get_memory_clk_period_ps(void) unsigned int result; /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ - unsigned long long mclk_ps = ULL_2E12; - - /* Add 5*data_rate, for rounding */ - mclk_ps += 5*(unsigned long long)data_rate; + unsigned long long rem, mclk_ps = ULL_2E12; /* Now perform the big divide, the result fits in 32-bits */ - do_div(mclk_ps, data_rate); - result = mclk_ps; + rem = do_div(mclk_ps, data_rate); + result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; - /* We still need to round to 10ps */ - return 10 * (result/10); + return result; } /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ unsigned int picos_to_mclk(unsigned int picos) { unsigned long long clks, clks_rem; + unsigned long data_rate = get_ddr_freq(0); /* Short circuit for zero picos */ if (!picos) return 0; /* First multiply the time by the data rate (32x32 => 64) */ - clks = picos * (unsigned long long)get_ddr_freq(0); - + clks = picos * (unsigned long long)data_rate; /* * Now divide by 5^12 and track the 32-bit remainder, then divide * by 2*(2^12) using shifts (and updating the remainder). */ clks_rem = do_div(clks, UL_5POW12); - clks_rem <<= 13; - clks_rem |= clks & (UL_2POW13-1); + clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12; clks >>= 13; - /* If we had a remainder, then round up */ - if (clks_rem) + /* If we had a remainder greater than the 1ps error, then round up */ + if (clks_rem > data_rate) clks++; /* Clamp to the maximum representable value */ @@ -133,10 +129,13 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, void board_add_ram_info(int use_default) { -#if defined(CONFIG_MPC85xx) - volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); +#if defined(CONFIG_MPC83xx) + immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + ccsr_ddr_t *ddr = (void *)&immap->ddr; +#elif defined(CONFIG_MPC85xx) + ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); #elif defined(CONFIG_MPC86xx) - volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); + ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); #endif #if (CONFIG_NUM_DDR_CONTROLLERS > 1) uint32_t cs0_config = in_be32(&ddr->cs0_config); diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 285051d..5bb9f53 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -63,7 +63,7 @@ void ft_fixup_num_cores(void *blob) { while (off != -FDT_ERR_NOTFOUND) { u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); - if ((*reg > num_cores-1) || (is_core_disabled(*reg))) { + if (!is_core_valid(*reg) || is_core_disabled(*reg)) { int ph = fdt_get_phandle(blob, off); /* Delete the cpu node once there are no cpu handles */ diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index e794821..6682496 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -43,10 +43,12 @@ void init_early_memctl_regs(void) set_ifc_ftim(IFC_CS0, IFC_FTIM2, CONFIG_SYS_CS0_FTIM2); set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3); +#if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT) set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif +#endif #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1) set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); |