diff options
Diffstat (limited to 'arch/powerpc/cpu')
34 files changed, 1040 insertions, 451 deletions
diff --git a/arch/powerpc/cpu/mpc512x/diu.c b/arch/powerpc/cpu/mpc512x/diu.c index f638c003722..9ef5609f31f 100644 --- a/arch/powerpc/cpu/mpc512x/diu.c +++ b/arch/powerpc/cpu/mpc512x/diu.c @@ -111,10 +111,8 @@ int mpc5121diu_init_show_bmp(cmd_tbl_t *cmdtp, { unsigned int addr; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if (!strncmp(argv[1], "init", 4)) { #if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) diff --git a/arch/powerpc/cpu/mpc8260/bedbug_603e.c b/arch/powerpc/cpu/mpc8260/bedbug_603e.c index 248861289bb..89193a348e0 100644 --- a/arch/powerpc/cpu/mpc8260/bedbug_603e.c +++ b/arch/powerpc/cpu/mpc8260/bedbug_603e.c @@ -71,10 +71,7 @@ void bedbug603e_do_break (cmd_tbl_t *cmdtp, int flag, int argc, /* -------------------------------------------------- */ if (argc < 2) - { - cmd_usage(cmdtp); - return; - } + return cmd_usage(cmdtp); /* Turn off a breakpoint */ @@ -118,10 +115,7 @@ void bedbug603e_do_break (cmd_tbl_t *cmdtp, int flag, int argc, if(!(( isdigit( argv[ 1 ][ 0 ] )) || (( argv[ 1 ][ 0 ] >= 'a' ) && ( argv[ 1 ][ 0 ] <= 'f' )) || (( argv[ 1 ][ 0 ] >= 'A' ) && ( argv[ 1 ][ 0 ] <= 'F' )))) - { - cmd_usage(cmdtp); - return; - } + return cmd_usage(cmdtp); addr = simple_strtoul( argv[ 1 ], NULL, 16 ); diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c index b664c641a16..663510987d3 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu.c +++ b/arch/powerpc/cpu/mpc83xx/cpu.c @@ -55,6 +55,7 @@ int checkcpu(void) char name[15]; u32 partid; } cpu_type_list [] = { + CPU_TYPE_ENTRY(8308), CPU_TYPE_ENTRY(8311), CPU_TYPE_ENTRY(8313), CPU_TYPE_ENTRY(8314), @@ -125,72 +126,6 @@ int checkcpu(void) return 0; } - -/* - * Program a UPM with the code supplied in the table. - * - * The 'dummy' variable is used to increment the MAD. 'dummy' is - * supposed to be a pointer to the memory of the device being - * programmed by the UPM. The data in the MDR is written into - * memory and the MAD is incremented every time there's a write - * to 'dummy'. Unfortunately, the current prototype for this - * function doesn't allow for passing the address of this - * device, and changing the prototype will break a number lots - * of other code, so we need to use a round-about way of finding - * the value for 'dummy'. - * - * The value can be extracted from the base address bits of the - * Base Register (BR) associated with the specific UPM. To find - * that BR, we need to scan all 8 BRs until we find the one that - * has its MSEL bits matching the UPM we want. Once we know the - * right BR, we can extract the base address bits from it. - * - * The MxMR and the BR and OR of the chosen bank should all be - * configured before calling this function. - * - * Parameters: - * upm: 0=UPMA, 1=UPMB, 2=UPMC - * table: Pointer to an array of values to program - * size: Number of elements in the array. Must be 64 or less. - */ -void upmconfig (uint upm, uint *table, uint size) -{ - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile fsl_lbus_t *lbus = &immap->lbus; - volatile uchar *dummy = NULL; - const u32 msel = (upm + 4) << BR_MSEL_SHIFT; /* What the MSEL field in BRn should be */ - volatile u32 *mxmr = &lbus->mamr + upm; /* Pointer to mamr, mbmr, or mcmr */ - uint i; - - /* Scan all the banks to determine the base address of the device */ - for (i = 0; i < 8; i++) { - if ((lbus->bank[i].br & BR_MSEL) == msel) { - dummy = (uchar *) (lbus->bank[i].br & BR_BA); - break; - } - } - - if (!dummy) { - printf("Error: %s() could not find matching BR\n", __FUNCTION__); - hang(); - } - - /* Set the OP field in the MxMR to "write" and the MAD field to 000000 */ - *mxmr = (*mxmr & 0xCFFFFFC0) | 0x10000000; - - for (i = 0; i < size; i++) { - lbus->mdr = table[i]; - __asm__ __volatile__ ("sync"); - *dummy = 0; /* Write the value to memory and increment MAD */ - __asm__ __volatile__ ("sync"); - while(((*mxmr & 0x3f) != ((i + 1) & 0x3f))); - } - - /* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */ - *mxmr &= 0xCFFFFFC0; -} - - int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c index f3b67ae2b91..83cba936057 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c @@ -236,8 +236,8 @@ void cpu_init_f (volatile immap_t * im) /* LCRR - Clock Ratio Register (10.3.1.16) * write, read, and isync per MPC8379ERM rev.1 CLKDEV field description */ - clrsetbits_be32(&im->lbus.lcrr, lcrr_mask, lcrr_val); - __raw_readl(&im->lbus.lcrr); + clrsetbits_be32(&im->im_lbc.lcrr, lcrr_mask, lcrr_val); + __raw_readl(&im->im_lbc.lcrr); isync(); /* Enable Time Base & Decrementer ( so we will have udelay() )*/ @@ -267,80 +267,41 @@ void cpu_init_f (volatile immap_t * im) /* Config QE ioports */ config_qe_ioports(); #endif + /* Set up preliminary BR/OR regs */ + init_early_memctl_regs(); - /* - * Memory Controller: - */ - - /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary - * addresses - these have to be modified later when FLASH size - * has been determined - */ - -#if defined(CONFIG_SYS_BR0_PRELIM) \ - && defined(CONFIG_SYS_OR0_PRELIM) \ - && defined(CONFIG_SYS_LBLAWBAR0_PRELIM) \ - && defined(CONFIG_SYS_LBLAWAR0_PRELIM) - im->lbus.bank[0].br = CONFIG_SYS_BR0_PRELIM; - im->lbus.bank[0].or = CONFIG_SYS_OR0_PRELIM; + /* Local Access window setup */ +#if defined(CONFIG_SYS_LBLAWBAR0_PRELIM) && defined(CONFIG_SYS_LBLAWAR0_PRELIM) im->sysconf.lblaw[0].bar = CONFIG_SYS_LBLAWBAR0_PRELIM; im->sysconf.lblaw[0].ar = CONFIG_SYS_LBLAWAR0_PRELIM; #else -#error CONFIG_SYS_BR0_PRELIM, CONFIG_SYS_OR0_PRELIM, CONFIG_SYS_LBLAWBAR0_PRELIM & CONFIG_SYS_LBLAWAR0_PRELIM must be defined +#error CONFIG_SYS_LBLAWBAR0_PRELIM & CONFIG_SYS_LBLAWAR0_PRELIM must be defined #endif -#if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) - im->lbus.bank[1].br = CONFIG_SYS_BR1_PRELIM; - im->lbus.bank[1].or = CONFIG_SYS_OR1_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR1_PRELIM) && defined(CONFIG_SYS_LBLAWAR1_PRELIM) im->sysconf.lblaw[1].bar = CONFIG_SYS_LBLAWBAR1_PRELIM; im->sysconf.lblaw[1].ar = CONFIG_SYS_LBLAWAR1_PRELIM; #endif -#if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) - im->lbus.bank[2].br = CONFIG_SYS_BR2_PRELIM; - im->lbus.bank[2].or = CONFIG_SYS_OR2_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR2_PRELIM) && defined(CONFIG_SYS_LBLAWAR2_PRELIM) im->sysconf.lblaw[2].bar = CONFIG_SYS_LBLAWBAR2_PRELIM; im->sysconf.lblaw[2].ar = CONFIG_SYS_LBLAWAR2_PRELIM; #endif -#if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) - im->lbus.bank[3].br = CONFIG_SYS_BR3_PRELIM; - im->lbus.bank[3].or = CONFIG_SYS_OR3_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR3_PRELIM) && defined(CONFIG_SYS_LBLAWAR3_PRELIM) im->sysconf.lblaw[3].bar = CONFIG_SYS_LBLAWBAR3_PRELIM; im->sysconf.lblaw[3].ar = CONFIG_SYS_LBLAWAR3_PRELIM; #endif -#if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) - im->lbus.bank[4].br = CONFIG_SYS_BR4_PRELIM; - im->lbus.bank[4].or = CONFIG_SYS_OR4_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR4_PRELIM) && defined(CONFIG_SYS_LBLAWAR4_PRELIM) im->sysconf.lblaw[4].bar = CONFIG_SYS_LBLAWBAR4_PRELIM; im->sysconf.lblaw[4].ar = CONFIG_SYS_LBLAWAR4_PRELIM; #endif -#if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) - im->lbus.bank[5].br = CONFIG_SYS_BR5_PRELIM; - im->lbus.bank[5].or = CONFIG_SYS_OR5_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR5_PRELIM) && defined(CONFIG_SYS_LBLAWAR5_PRELIM) im->sysconf.lblaw[5].bar = CONFIG_SYS_LBLAWBAR5_PRELIM; im->sysconf.lblaw[5].ar = CONFIG_SYS_LBLAWAR5_PRELIM; #endif -#if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) - im->lbus.bank[6].br = CONFIG_SYS_BR6_PRELIM; - im->lbus.bank[6].or = CONFIG_SYS_OR6_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR6_PRELIM) && defined(CONFIG_SYS_LBLAWAR6_PRELIM) im->sysconf.lblaw[6].bar = CONFIG_SYS_LBLAWBAR6_PRELIM; im->sysconf.lblaw[6].ar = CONFIG_SYS_LBLAWAR6_PRELIM; #endif -#if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) - im->lbus.bank[7].br = CONFIG_SYS_BR7_PRELIM; - im->lbus.bank[7].or = CONFIG_SYS_OR7_PRELIM; -#endif #if defined(CONFIG_SYS_LBLAWBAR7_PRELIM) && defined(CONFIG_SYS_LBLAWAR7_PRELIM) im->sysconf.lblaw[7].bar = CONFIG_SYS_LBLAWBAR7_PRELIM; im->sysconf.lblaw[7].ar = CONFIG_SYS_LBLAWAR7_PRELIM; diff --git a/arch/powerpc/cpu/mpc83xx/ecc.c b/arch/powerpc/cpu/mpc83xx/ecc.c index 8dadd64b425..f8eab96b199 100644 --- a/arch/powerpc/cpu/mpc83xx/ecc.c +++ b/arch/powerpc/cpu/mpc83xx/ecc.c @@ -118,10 +118,8 @@ int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) writeback[0] = 0x01234567UL; writeback[1] = 0x89abcdefUL; - if (argc > 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc > 4) + return cmd_usage(cmdtp); if (argc == 2) { if (strcmp(argv[1], "status") == 0) { @@ -350,8 +348,7 @@ int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 0; } } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } U_BOOT_CMD(ecc, 4, 0, do_ecc, diff --git a/arch/powerpc/cpu/mpc83xx/nand_init.c b/arch/powerpc/cpu/mpc83xx/nand_init.c index 38e141a8284..d1648b78107 100644 --- a/arch/powerpc/cpu/mpc83xx/nand_init.c +++ b/arch/powerpc/cpu/mpc83xx/nand_init.c @@ -88,8 +88,8 @@ void cpu_init_f (volatile immap_t * im) && defined(CONFIG_SYS_NAND_OR_PRELIM) \ && defined(CONFIG_SYS_NAND_LBLAWBAR_PRELIM) \ && defined(CONFIG_SYS_NAND_LBLAWAR_PRELIM) - im->lbus.bank[0].br = CONFIG_SYS_NAND_BR_PRELIM; - im->lbus.bank[0].or = CONFIG_SYS_NAND_OR_PRELIM; + set_lbc_br(0, CONFIG_SYS_NAND_BR_PRELIM); + set_lbc_or(0, CONFIG_SYS_NAND_OR_PRELIM); im->sysconf.lblaw[0].bar = CONFIG_SYS_NAND_LBLAWBAR_PRELIM; im->sysconf.lblaw[0].ar = CONFIG_SYS_NAND_LBLAWAR_PRELIM; #else diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c index b5076a9af87..93e9f1c3f9b 100644 --- a/arch/powerpc/cpu/mpc83xx/speed.c +++ b/arch/powerpc/cpu/mpc83xx/speed.c @@ -100,7 +100,8 @@ int get_clocks(void) u32 lcrr; u32 csb_clk; -#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC831x) || defined(CONFIG_MPC837x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) u32 tsec1_clk; u32 tsec2_clk; u32 usbdr_clk; @@ -132,7 +133,8 @@ int get_clocks(void) u32 qe_clk; u32 brg_clk; #endif -#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC831x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC837x) u32 pciexp1_clk; u32 pciexp2_clk; #endif @@ -164,7 +166,8 @@ int get_clocks(void) sccr = im->clk.sccr; -#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC831x) || defined(CONFIG_MPC837x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) { case 0: tsec1_clk = 0; @@ -202,7 +205,8 @@ int get_clocks(void) } #endif -#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC8315) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) { case 0: tsec2_clk = 0; @@ -319,7 +323,7 @@ int get_clocks(void) i2c1_clk = csb_clk; #elif defined(CONFIG_MPC832x) i2c1_clk = enc_clk; -#elif defined(CONFIG_MPC831x) +#elif defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) i2c1_clk = enc_clk; #elif defined(CONFIG_FSL_ESDHC) i2c1_clk = sdhc_clk; @@ -328,7 +332,8 @@ int get_clocks(void) i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */ #endif -#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC831x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC837x) switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) { case 0: pciexp1_clk = 0; @@ -388,7 +393,7 @@ int get_clocks(void) lbiu_clk = csb_clk * (1 + ((im->reset.rcwl & HRCWL_LBIUCM) >> HRCWL_LBIUCM_SHIFT)); - lcrr = (im->lbus.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT; + lcrr = (im->im_lbc.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT; switch (lcrr) { case 2: case 4: @@ -444,7 +449,8 @@ int get_clocks(void) #endif gd->csb_clk = csb_clk; -#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC831x) || defined(CONFIG_MPC837x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) gd->tsec1_clk = tsec1_clk; gd->tsec2_clk = tsec2_clk; gd->usbdr_clk = usbdr_clk; @@ -525,7 +531,8 @@ int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) #if defined(CONFIG_FSL_ESDHC) printf(" SDHC: %-4s MHz\n", strmhz(buf, gd->sdhc_clk)); #endif -#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC831x) || defined(CONFIG_MPC837x) +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) printf(" TSEC1: %-4s MHz\n", strmhz(buf, gd->tsec1_clk)); printf(" TSEC2: %-4s MHz\n", strmhz(buf, gd->tsec2_clk)); printf(" USB DR: %-4s MHz\n", strmhz(buf, gd->usbdr_clk)); diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index f064fee26b6..fe851f15dbe 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -32,6 +32,7 @@ START = start.o resetvec.o SOBJS-$(CONFIG_MP) += release.o SOBJS = $(SOBJS-y) +COBJS-$(CONFIG_CMD_ERRATA) += cmd_errata.o COBJS-$(CONFIG_CPM2) += commproc.o # supports ddr1 @@ -57,12 +58,15 @@ COBJS-$(CONFIG_P1021) += ddr-gen3.o COBJS-$(CONFIG_P1022) += ddr-gen3.o COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o +COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o +COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_CPM2) += ether_fcc.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.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_QE) += qe_io.o COBJS-$(CONFIG_CPM2) += serial_scc.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c new file mode 100644 index 00000000000..d7835c8d690 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -0,0 +1,51 @@ +/* + * 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 <command.h> +#include <linux/compiler.h> +#include <asm/processor.h> + +static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + __maybe_unused u32 svr = get_svr(); + +#if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001) + if (IS_SVR_REV(svr, 1, 0)) { + switch (SVR_SOC_VER(svr)) { + case SVR_P1013: + case SVR_P1013_E: + case SVR_P1022: + case SVR_P1022_E: + puts("Work-around for Erratum SATA A001 enabled\n"); + } + } +#endif + + return 0; +} + +U_BOOT_CMD( + errata, 1, 0, do_errata, + "Report errata workarounds", + "" +); diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 6f81fdf61b5..f15d43c38c7 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -32,6 +32,8 @@ #include <fsl_esdhc.h> #include <asm/cache.h> #include <asm/io.h> +#include <asm/mmu.h> +#include <asm/fsl_law.h> DECLARE_GLOBAL_DATA_PTR; @@ -93,18 +95,26 @@ int checkcpu (void) minor = PVR_MIN(pvr); printf("Core: "); - switch (fam) { - case PVR_FAM(PVR_85xx): - puts("E500"); - break; - default: - puts("Unknown"); - break; + if (PVR_FAM(PVR_85xx)) { + switch(PVR_MEM(pvr)) { + case 0x1: + case 0x2: + puts("E500"); + break; + case 0x3: + puts("E500MC"); + break; + case 0x4: + puts("E5500"); + break; + default: + puts("Unknown"); + break; + } + } else { + puts("Unknown"); } - if (PVR_MEM(pvr) == 0x03) - puts("MC"); - printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr); get_sys_info(&sysinfo); @@ -169,7 +179,7 @@ int checkcpu (void) #ifdef CONFIG_SYS_DPAA_FMAN for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) { - printf(" FMAN%d: %s MHz\n", i, + printf(" FMAN%d: %s MHz\n", i + 1, strmhz(buf1, sysinfo.freqFMan[i])); } #endif @@ -250,71 +260,6 @@ reset_85xx_watchdog(void) #endif /* CONFIG_WATCHDOG */ /* - * Configures a UPM. The function requires the respective MxMR to be set - * before calling this function. "size" is the number or entries, not a sizeof. - */ -void upmconfig (uint upm, uint * table, uint size) -{ - int i, mdr, mad, old_mad = 0; - volatile u32 *mxmr; - volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); - volatile u32 *brp,*orp; - volatile u8* dummy = NULL; - int upmmask; - - switch (upm) { - case UPMA: - mxmr = &lbc->mamr; - upmmask = BR_MS_UPMA; - break; - case UPMB: - mxmr = &lbc->mbmr; - upmmask = BR_MS_UPMB; - break; - case UPMC: - mxmr = &lbc->mcmr; - upmmask = BR_MS_UPMC; - break; - default: - printf("%s: Bad UPM index %d to configure\n", __FUNCTION__, upm); - hang(); - } - - /* Find the address for the dummy write transaction */ - for (brp = &lbc->br0, orp = &lbc->or0, i = 0; i < 8; - i++, brp += 2, orp += 2) { - - /* Look for a valid BR with selected UPM */ - if ((in_be32(brp) & (BR_V | BR_MSEL)) == (BR_V | upmmask)) { - dummy = (volatile u8*)(in_be32(brp) & BR_BA); - break; - } - } - - if (i == 8) { - printf("Error: %s() could not find matching BR\n", __FUNCTION__); - hang(); - } - - for (i = 0; i < size; i++) { - /* 1 */ - out_be32(mxmr, (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_WARR | i); - /* 2 */ - out_be32(&lbc->mdr, table[i]); - /* 3 */ - mdr = in_be32(&lbc->mdr); - /* 4 */ - *(volatile u8 *)dummy = 0; - /* 5 */ - do { - mad = in_be32(mxmr) & MxMR_MAD_MSK; - } while (mad <= old_mad && !(!mad && i == (size-1))); - old_mad = mad; - } - out_be32(mxmr, (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_NORM); -} - -/* * Initializes on-chip MMC controllers. * to override, implement board_mmc_init() */ @@ -326,3 +271,14 @@ int cpu_mmc_init(bd_t *bis) return 0; #endif } + +/* + * Print out the state of various machine registers. + * Currently prints out LAWs, BR0/OR0, and TLBs + */ +void mpc85xx_reginfo(void) +{ + print_tlbcam(); + print_laws(); + print_lbc_regs(); +} diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 99431dc1a76..5d5b4c29636 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -39,10 +39,6 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_MPC8536 -extern void fsl_serdes_init(void); -#endif - #ifdef CONFIG_QE extern qe_iop_conf_t qe_iop_conf_tab[]; extern void qe_config_iopin(u8 port, u8 pin, int dir, @@ -154,7 +150,6 @@ static void corenet_tb_init(void) void cpu_init_f (void) { - volatile ccsr_lbc_t *memctl = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); extern void m8560_cpm_reset (void); #ifdef CONFIG_MPC8548 ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); @@ -177,60 +172,7 @@ void cpu_init_f (void) config_8560_ioports((ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR); #endif - /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary - * addresses - these have to be modified later when FLASH size - * has been determined - */ -#if defined(CONFIG_SYS_OR0_REMAP) - out_be32(&memctl->or0, CONFIG_SYS_OR0_REMAP); -#endif -#if defined(CONFIG_SYS_OR1_REMAP) - out_be32(&memctl->or1, CONFIG_SYS_OR1_REMAP); -#endif - - /* now restrict to preliminary range */ - /* if cs1 is already set via debugger, leave cs0/cs1 alone */ - if (! memctl->br1 & 1) { -#if defined(CONFIG_SYS_BR0_PRELIM) && defined(CONFIG_SYS_OR0_PRELIM) - out_be32(&memctl->br0, CONFIG_SYS_BR0_PRELIM); - out_be32(&memctl->or0, CONFIG_SYS_OR0_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) - out_be32(&memctl->or1, CONFIG_SYS_OR1_PRELIM); - out_be32(&memctl->br1, CONFIG_SYS_BR1_PRELIM); -#endif - } - -#if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) - out_be32(&memctl->or2, CONFIG_SYS_OR2_PRELIM); - out_be32(&memctl->br2, CONFIG_SYS_BR2_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) - out_be32(&memctl->or3, CONFIG_SYS_OR3_PRELIM); - out_be32(&memctl->br3, CONFIG_SYS_BR3_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) - out_be32(&memctl->or4, CONFIG_SYS_OR4_PRELIM); - out_be32(&memctl->br4, CONFIG_SYS_BR4_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) - out_be32(&memctl->or5, CONFIG_SYS_OR5_PRELIM); - out_be32(&memctl->br5, CONFIG_SYS_BR5_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) - out_be32(&memctl->or6, CONFIG_SYS_OR6_PRELIM); - out_be32(&memctl->br6, CONFIG_SYS_BR6_PRELIM); -#endif - -#if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) - out_be32(&memctl->or7, CONFIG_SYS_OR7_PRELIM); - out_be32(&memctl->br7, CONFIG_SYS_BR7_PRELIM); -#endif + init_early_memctl_regs(); #if defined(CONFIG_CPM2) m8560_cpm_reset(); @@ -239,9 +181,6 @@ void cpu_init_f (void) /* Config QE ioports */ config_qe_ioports(); #endif -#if defined(CONFIG_MPC8536) - fsl_serdes_init(); -#endif #if defined(CONFIG_FSL_DMA) dma_init(); #endif @@ -263,7 +202,7 @@ void cpu_init_f (void) int cpu_init_r(void) { #ifdef CONFIG_SYS_LBC_LCRR - volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; #endif puts ("L2: "); @@ -386,6 +325,11 @@ int cpu_init_r(void) qe_reset(); #endif +#if defined(CONFIG_SYS_HAS_SERDES) + /* needs to be in ram since code uses global static vars */ + fsl_serdes_init(); +#endif + #if defined(CONFIG_MP) setup_mp(); #endif diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c index 184cca4c543..8fb27abc55b 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c @@ -25,7 +25,7 @@ void cpu_init_f(void) { - ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + fsl_lbc_t *lbc = LBC_BASE_ADDR; /* * LCRR - Clock Ratio Register - set up local bus timing @@ -34,8 +34,8 @@ void cpu_init_f(void) out_be32(&lbc->lcrr, LCRR_DBYP | LCRR_CLKDIV_8); #if defined(CONFIG_NAND_BR_PRELIM) && defined(CONFIG_NAND_OR_PRELIM) - out_be32(&lbc->br0, CONFIG_NAND_BR_PRELIM); - out_be32(&lbc->or0, CONFIG_NAND_OR_PRELIM); + set_lbc_br(0, CONFIG_NAND_BR_PRELIM); + set_lbc_or(0, CONFIG_NAND_OR_PRELIM); #else #error CONFIG_NAND_BR_PRELIM, CONFIG_NAND_OR_PRELIM must be defined #endif diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 1d11ab470f8..932466e883d 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -298,17 +298,17 @@ void fdt_add_enet_stashing(void *fdt) } #if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME) -static void ft_fixup_clks(void *blob, const char *alias, unsigned long freq) +static void ft_fixup_clks(void *blob, const char *compat, u32 offset, + unsigned long freq) { - const char *path = fdt_get_alias(blob, alias); - - int off = fdt_path_offset(blob, path); + phys_addr_t phys = offset + CONFIG_SYS_CCSRBAR_PHYS; + int off = fdt_node_offset_by_compat_reg(blob, compat, phys); if (off >= 0) { off = fdt_setprop_cell(blob, off, "clock-frequency", freq); if (off > 0) printf("WARNING enable to set clock-frequency " - "for %s: %s\n", alias, fdt_strerror(off)); + "for %s: %s\n", compat, fdt_strerror(off)); } } @@ -317,14 +317,17 @@ static void ft_fixup_dpaa_clks(void *blob) sys_info_t sysinfo; get_sys_info(&sysinfo); - ft_fixup_clks(blob, "fman0", sysinfo.freqFMan[0]); + ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM1_OFFSET, + sysinfo.freqFMan[0]); #if (CONFIG_SYS_NUM_FMAN == 2) - ft_fixup_clks(blob, "fman1", sysinfo.freqFMan[1]); + ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM2_OFFSET, + sysinfo.freqFMan[1]); #endif #ifdef CONFIG_SYS_DPAA_PME - ft_fixup_clks(blob, "pme", sysinfo.freqPME); + do_fixup_by_compat_u32(blob, "fsl,pme", + "clock-frequency", sysinfo.freqPME, 1); #endif } #else @@ -400,12 +403,17 @@ void ft_cpu_setup(void *blob, bd_t *bd) "clock-frequency", bd->bi_brgfreq, 1); #endif +#ifdef CONFIG_FSL_CORENET + do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0", + "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); +#endif + fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); #ifdef CONFIG_MP ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize); -#endif ft_fixup_num_cores(blob); +#endif ft_fixup_cache(blob); diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index ddbc2211c3b..e05257cf04a 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -77,6 +77,13 @@ int cpu_disable(int nr) return 0; } + +int is_core_disabled(int nr) { + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 coredisrl = in_be32(&gur->coredisrl); + + return (coredisrl & (1 << nr)); +} #else int cpu_disable(int nr) { @@ -96,6 +103,22 @@ int cpu_disable(int nr) return 0; } + +int is_core_disabled(int nr) { + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 devdisr = in_be32(&gur->devdisr); + + switch (nr) { + case 0: + return (devdisr & MPC85xx_DEVDISR_CPU0); + case 1: + return (devdisr & MPC85xx_DEVDISR_CPU1); + default: + printf("Invalid cpu number for disable %d\n", nr); + } + + return 0; +} #endif static u8 boot_entry_map[4] = { diff --git a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c index 7e72f5fb7c7..6dadeb8cabc 100644 --- a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c @@ -66,10 +66,11 @@ #define FSL_SRDSCR3_LANEE_SGMII 0x00000000 #define FSL_SRDSCR3_LANEE_SATA 0x00150005 - #define SRDS1_MAX_LANES 8 #define SRDS2_MAX_LANES 2 +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { [0x2] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, NONE, NONE}, [0x3] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1}, @@ -86,39 +87,12 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { int is_serdes_configured(enum srds_prtcl device) { - int i; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 pordevsr = in_be32(&gur->pordevsr); - u32 srds1_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> - MPC85xx_PORDEVSR_IO_SEL_SHIFT; + int ret = (1 << device) & serdes1_prtcl_map; - u32 srds2_cfg = (pordevsr & MPC85xx_PORDEVSR_SRDS2_IO_SEL) >> - GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT; - - debug("%s: dev = %d\n", __FUNCTION__, device); - debug("PORDEVSR[IO_SEL] = %x\n", srds1_cfg); - debug("PORDEVSR[SRDS2_IO_SEL] = %x\n", srds2_cfg); - - if (srds1_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) { - printf("Invalid PORDEVSR[IO_SEL] = %d\n", srds1_cfg); - return 0; - } - - if (srds2_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { - printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_cfg); - return 0; - } - - for (i = 0; i < SRDS1_MAX_LANES; i++) { - if (serdes1_cfg_tbl[srds1_cfg][i] == device) - return 1; - } - for (i = 0; i < SRDS2_MAX_LANES; i++) { - if (serdes2_cfg_tbl[srds2_cfg][i] == device) - return 1; - } + if (ret) + return ret; - return 0; + return (1 << device) & serdes2_prtcl_map; } void fsl_serdes_init(void) @@ -126,13 +100,20 @@ void fsl_serdes_init(void) void *guts = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); void *sd = (void *)CONFIG_SYS_MPC85xx_SERDES2_ADDR; u32 pordevsr = in_be32(guts + GUTS_PORDEVSR_OFFS); - u32 srds2_io_sel; + u32 srds1_io_sel, srds2_io_sel; u32 tmp; + int lane; + + srds1_io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> + MPC85xx_PORDEVSR_IO_SEL_SHIFT; /* parse the SRDS2_IO_SEL of PORDEVSR */ srds2_io_sel = (pordevsr & GUTS_PORDEVSR_SERDES2_IO_SEL) >> GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT; + debug("PORDEVSR[SRDS1_IO_SEL] = %x\n", srds1_io_sel); + debug("PORDEVSR[SRDS2_IO_SEL] = %x\n", srds2_io_sel); + switch (srds2_io_sel) { case 1: /* Lane A - SATA1, Lane E - SATA2 */ /* CR 0 */ @@ -246,4 +227,23 @@ void fsl_serdes_init(void) default: break; } + + if (srds1_io_sel > ARRAY_SIZE(serdes1_cfg_tbl)) { + printf("Invalid PORDEVSR[SRDS1_IO_SEL] = %d\n", srds1_io_sel); + return; + } + for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds1_io_sel][lane]; + serdes1_prtcl_map |= (1 << lane_prtcl); + } + + if (srds2_io_sel > ARRAY_SIZE(serdes2_cfg_tbl)) { + printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel); + return; + } + + for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds2_io_sel][lane]; + serdes2_prtcl_map |= (1 << lane_prtcl); + } } diff --git a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c new file mode 100644 index 00000000000..e4c9c221005 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c @@ -0,0 +1,114 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * Author: Timur Tabi <timur@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. + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_serdes.h> + +#define SRDS1_MAX_LANES 4 +#define SRDS2_MAX_LANES 2 + +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + +static const u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { + [0x00] = {NONE, NONE, NONE, NONE}, + [0x01] = {NONE, NONE, NONE, NONE}, + [0x02] = {NONE, NONE, NONE, NONE}, + [0x03] = {NONE, NONE, NONE, NONE}, + [0x04] = {NONE, NONE, NONE, NONE}, + [0x06] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2}, + [0x07] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2}, + [0x09] = {PCIE1, NONE, NONE, NONE}, + [0x0a] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2}, + [0x0b] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2}, + [0x0d] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2}, + [0x0e] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2}, + [0x0f] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2}, + [0x15] = {PCIE1, PCIE3, PCIE2, PCIE2}, + [0x16] = {PCIE1, PCIE3, PCIE2, PCIE2}, + [0x17] = {PCIE1, PCIE3, PCIE2, PCIE2}, + [0x18] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x19] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x1a] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x1b] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x1c] = {PCIE1, PCIE1, PCIE1, PCIE1}, + [0x1d] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x1e] = {PCIE1, PCIE1, PCIE2, PCIE2}, + [0x1f] = {PCIE1, PCIE1, PCIE2, PCIE2}, +}; + +static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { + [0x00] = {PCIE3, PCIE3}, + [0x01] = {PCIE2, PCIE3}, + [0x02] = {SATA1, SATA2}, + [0x03] = {SGMII_TSEC1, SGMII_TSEC2}, + [0x04] = {NONE, NONE}, + [0x06] = {SATA1, SATA2}, + [0x07] = {NONE, NONE}, + [0x09] = {PCIE3, PCIE2}, + [0x0a] = {SATA1, SATA2}, + [0x0b] = {NONE, NONE}, + [0x0d] = {PCIE3, PCIE2}, + [0x0e] = {SATA1, SATA2}, + [0x0f] = {NONE, NONE}, + [0x15] = {SGMII_TSEC1, SGMII_TSEC2}, + [0x16] = {SATA1, SATA2}, + [0x17] = {NONE, NONE}, + [0x18] = {PCIE3, PCIE3}, + [0x19] = {SGMII_TSEC1, SGMII_TSEC2}, + [0x1a] = {SATA1, SATA2}, + [0x1b] = {NONE, NONE}, + [0x1c] = {PCIE3, PCIE3}, + [0x1d] = {SGMII_TSEC1, SGMII_TSEC2}, + [0x1e] = {SATA1, SATA2}, + [0x1f] = {NONE, NONE}, +}; + +int is_serdes_configured(enum srds_prtcl device) +{ + int ret = (1 << device) & serdes1_prtcl_map; + + if (ret) + return ret; + + return (1 << device) & serdes2_prtcl_map; +} + +void fsl_serdes_init(void) +{ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + u32 pordevsr = in_be32(&gur->pordevsr); + u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> + MPC85xx_PORDEVSR_IO_SEL_SHIFT; + int lane; + + debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg); + + if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) { + printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); + return; + } + for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane]; + serdes1_prtcl_map |= (1 << lane_prtcl); + } + + if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { + printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); + return; + } + + for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane]; + serdes2_prtcl_map |= (1 << lane_prtcl); + } +} diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 8132115fca6..dd4c6b3e984 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -172,10 +172,7 @@ void get_sys_info (sys_info_t * sysInfo) /* We will program LCRR to this value later */ lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; #else - { - volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); - lcrr_div = in_be32(&lbc->lcrr) & LCRR_CLKDIV; - } + lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV; #endif if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { #if defined(CONFIG_FSL_CORENET) diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index b3037aceaf0..f2833a5df70 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -55,7 +55,45 @@ void init_tlbs(void) return ; } +void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn, + phys_addr_t *rpn) +{ + u32 _mas1; + + mtspr(MAS0, FSL_BOOKE_MAS0(1, idx, 0)); + asm volatile("tlbre;isync"); + _mas1 = mfspr(MAS1); + + *valid = (_mas1 & MAS1_VALID); + *tsize = (_mas1 >> 8) & 0xf; + *epn = mfspr(MAS2) & MAS2_EPN; + *rpn = mfspr(MAS3) & MAS3_RPN; +#ifdef CONFIG_ENABLE_36BIT_PHYS + *rpn |= ((u64)mfspr(MAS7)) << 32; +#endif +} + #ifndef CONFIG_NAND_SPL +void print_tlbcam(void) +{ + int i; + unsigned int num_cam = mfspr(SPRN_TLB1CFG) & 0xfff; + + /* walk all the entries */ + printf("TLBCAM entries\n"); + for (i = 0; i < num_cam; i++) { + unsigned long epn; + u32 tsize, valid; + phys_addr_t rpn; + + read_tlbcam_entry(i, &valid, &tsize, &epn, &rpn); + printf("entry %02d: V: %d EPN 0x%08x RPN 0x%08llx size:", + i, (valid == 0) ? 0 : 1, (unsigned int)epn, + (unsigned long long)rpn); + print_size(TSIZE_TO_BYTES(tsize), "\n"); + } +} + static inline void use_tlb_cam(u8 idx) { int i = idx / 32; @@ -82,15 +120,9 @@ void init_used_tlb_cams(void) /* walk all the entries */ for (i = 0; i < num_cam; i++) { - u32 _mas1; - mtspr(MAS0, FSL_BOOKE_MAS0(1, i, 0)); - asm volatile("tlbre;isync"); - _mas1 = mfspr(MAS1); - - /* if the entry isn't valid skip it */ - if ((_mas1 & MAS1_VALID)) + if (mfspr(MAS1) & MAS1_VALID) use_tlb_cam(i); } } @@ -134,7 +166,7 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn, #ifdef CONFIG_ADDR_MAP if ((tlb == 1) && (gd->flags & GD_FLG_RELOC)) - addrmap_set_entry(epn, rpn, (1UL << ((tsize * 2) + 10)), esel); + addrmap_set_entry(epn, rpn, TSIZE_TO_BYTES(tsize), esel); #endif } @@ -201,26 +233,12 @@ void init_addr_map(void) /* walk all the entries */ for (i = 0; i < num_cam; i++) { unsigned long epn; - u32 tsize, _mas1; + u32 tsize, valid; phys_addr_t rpn; - mtspr(MAS0, FSL_BOOKE_MAS0(1, i, 0)); - - asm volatile("tlbre;isync"); - _mas1 = mfspr(MAS1); - - /* if the entry isn't valid skip it */ - if (!(_mas1 & MAS1_VALID)) - continue; - - tsize = (_mas1 >> 8) & 0xf; - epn = mfspr(MAS2) & MAS2_EPN; - rpn = mfspr(MAS3) & MAS3_RPN; -#ifdef CONFIG_ENABLE_36BIT_PHYS - rpn |= ((phys_addr_t)mfspr(MAS7)) << 32; -#endif - - addrmap_set_entry(epn, rpn, (1UL << ((tsize * 2) + 10)), i); + read_tlbcam_entry(i, &valid, &tsize, &epn, &rpn); + if (valid & MAS1_VALID) + addrmap_set_entry(epn, rpn, TSIZE_TO_BYTES(tsize), i); } return ; diff --git a/arch/powerpc/cpu/mpc86xx/cpu.c b/arch/powerpc/cpu/mpc86xx/cpu.c index 9064e780374..4e90fd22037 100644 --- a/arch/powerpc/cpu/mpc86xx/cpu.c +++ b/arch/powerpc/cpu/mpc86xx/cpu.c @@ -180,22 +180,9 @@ watchdog_reset(void) */ void mpc86xx_reginfo(void) { - immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; - ccsr_lbc_t *lbc = &immap->im_lbc; - print_bats(); print_laws(); - - printf ("Local Bus Controller Registers\n" - "\tBR0\t0x%08X\tOR0\t0x%08X \n", in_be32(&lbc->br0), in_be32(&lbc->or0)); - printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", in_be32(&lbc->br1), in_be32(&lbc->or1)); - printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", in_be32(&lbc->br2), in_be32(&lbc->or2)); - printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", in_be32(&lbc->br3), in_be32(&lbc->or3)); - printf("\tBR4\t0x%08X\tOR4\t0x%08X \n", in_be32(&lbc->br4), in_be32(&lbc->or4)); - printf("\tBR5\t0x%08X\tOR5\t0x%08X \n", in_be32(&lbc->br5), in_be32(&lbc->or5)); - printf("\tBR6\t0x%08X\tOR6\t0x%08X \n", in_be32(&lbc->br6), in_be32(&lbc->or6)); - printf("\tBR7\t0x%08X\tOR7\t0x%08X \n", in_be32(&lbc->br7), in_be32(&lbc->or7)); - + print_lbc_regs(); } /* diff --git a/arch/powerpc/cpu/mpc86xx/cpu_init.c b/arch/powerpc/cpu/mpc86xx/cpu_init.c index b4f047d85d0..82c216ba5d1 100644 --- a/arch/powerpc/cpu/mpc86xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc86xx/cpu_init.c @@ -46,9 +46,6 @@ DECLARE_GLOBAL_DATA_PTR; void cpu_init_f(void) { - volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; - volatile ccsr_lbc_t *memctl = &immap->im_lbc; - /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -61,58 +58,8 @@ void cpu_init_f(void) setup_bats(); - /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary - * addresses - these have to be modified later when FLASH size - * has been determined - */ - -#if defined(CONFIG_SYS_OR0_REMAP) - memctl->or0 = CONFIG_SYS_OR0_REMAP; -#endif -#if defined(CONFIG_SYS_OR1_REMAP) - memctl->or1 = CONFIG_SYS_OR1_REMAP; -#endif - - /* now restrict to preliminary range */ -#if defined(CONFIG_SYS_BR0_PRELIM) && defined(CONFIG_SYS_OR0_PRELIM) - memctl->br0 = CONFIG_SYS_BR0_PRELIM; - memctl->or0 = CONFIG_SYS_OR0_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) - memctl->or1 = CONFIG_SYS_OR1_PRELIM; - memctl->br1 = CONFIG_SYS_BR1_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) - memctl->or2 = CONFIG_SYS_OR2_PRELIM; - memctl->br2 = CONFIG_SYS_BR2_PRELIM; -#endif + init_early_memctl_regs(); -#if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) - memctl->or3 = CONFIG_SYS_OR3_PRELIM; - memctl->br3 = CONFIG_SYS_BR3_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) - memctl->or4 = CONFIG_SYS_OR4_PRELIM; - memctl->br4 = CONFIG_SYS_BR4_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) - memctl->or5 = CONFIG_SYS_OR5_PRELIM; - memctl->br5 = CONFIG_SYS_BR5_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) - memctl->or6 = CONFIG_SYS_OR6_PRELIM; - memctl->br6 = CONFIG_SYS_BR6_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) - memctl->or7 = CONFIG_SYS_OR7_PRELIM; - memctl->br7 = CONFIG_SYS_BR7_PRELIM; -#endif #if defined(CONFIG_FSL_DMA) dma_init(); #endif diff --git a/arch/powerpc/cpu/mpc86xx/fdt.c b/arch/powerpc/cpu/mpc86xx/fdt.c index 51f3f4c2203..ff89ee554c4 100644 --- a/arch/powerpc/cpu/mpc86xx/fdt.c +++ b/arch/powerpc/cpu/mpc86xx/fdt.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 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 @@ -55,6 +55,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) off = fdt_add_mem_rsv(blob, bootpg, (u64)4096); if (off < 0) printf("%s: %s\n", __FUNCTION__, fdt_strerror(off)); -#endif + ft_fixup_num_cores(blob); +#endif } diff --git a/arch/powerpc/cpu/mpc86xx/mp.c b/arch/powerpc/cpu/mpc86xx/mp.c index 24eb30aaaa6..30c99ebc56e 100644 --- a/arch/powerpc/cpu/mpc86xx/mp.c +++ b/arch/powerpc/cpu/mpc86xx/mp.c @@ -66,6 +66,23 @@ int cpu_disable(int nr) return 0; } +int is_core_disabled(int nr) { + immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; + ccsr_gur_t *gur = &immap->im_gur; + u32 devdisr = in_be32(&gur->devdisr); + + switch (nr) { + case 0: + return (devdisr & MPC86xx_DEVDISR_CPU0); + case 1: + return (devdisr & MPC86xx_DEVDISR_CPU1); + default: + printf("Invalid cpu number for disable %d\n", nr); + } + + return 0; +} + int cpu_release(int nr, int argc, char * const argv[]) { /* dummy function so common/cmd_mp.c will build diff --git a/arch/powerpc/cpu/mpc86xx/speed.c b/arch/powerpc/cpu/mpc86xx/speed.c index 64a3479d7e5..a2d0a8ac6eb 100644 --- a/arch/powerpc/cpu/mpc86xx/speed.c +++ b/arch/powerpc/cpu/mpc86xx/speed.c @@ -97,10 +97,7 @@ void get_sys_info(sys_info_t *sysInfo) /* We will program LCRR to this value later */ lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; #else - { - volatile ccsr_lbc_t *lbc = &immap->im_lbc; - lcrr_div = in_be32(&lbc->lcrr) & LCRR_CLKDIV; - } + lcrr_div = in_be32(&immap->im_lbc.lcrr) & LCRR_CLKDIV; #endif if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { sysInfo->freqLocalBus = sysInfo->freqSystemBus / (lcrr_div * 2); diff --git a/arch/powerpc/cpu/mpc8xx/bedbug_860.c b/arch/powerpc/cpu/mpc8xx/bedbug_860.c index 9deda6c2a08..83db035ab51 100644 --- a/arch/powerpc/cpu/mpc8xx/bedbug_860.c +++ b/arch/powerpc/cpu/mpc8xx/bedbug_860.c @@ -70,10 +70,7 @@ void bedbug860_do_break (cmd_tbl_t *cmdtp, int flag, int argc, /* -------------------------------------------------- */ if (argc < 2) - { - cmd_usage(cmdtp); - return; - } + return cmd_usage(cmdtp); /* Turn off a breakpoint */ @@ -121,10 +118,7 @@ void bedbug860_do_break (cmd_tbl_t *cmdtp, int flag, int argc, /* Set a breakpoint at the address */ if( !isdigit( argv[ 1 ][ 0 ])) - { - cmd_usage(cmdtp); - return; - } + return cmd_usage(cmdtp); addr = simple_strtoul( argv[ 1 ], NULL, 16 ) & 0xfffffffc; diff --git a/arch/powerpc/cpu/mpc8xx/cpu_init.c b/arch/powerpc/cpu/mpc8xx/cpu_init.c index eb0091bdb30..e97ae68c49d 100644 --- a/arch/powerpc/cpu/mpc8xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc8xx/cpu_init.c @@ -149,8 +149,7 @@ void cpu_init_f (volatile immap_t * immr) * I owe him a free beer. - wd] */ -#if defined(CONFIG_GTH) || \ - defined(CONFIG_HERMES) || \ +#if defined(CONFIG_HERMES) || \ defined(CONFIG_ICU862) || \ defined(CONFIG_IP860) || \ defined(CONFIG_IVML24) || \ diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile index 481f9e541dc..ea5122289e2 100644 --- a/arch/powerpc/cpu/mpc8xxx/Makefile +++ b/arch/powerpc/cpu/mpc8xxx/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2009 Freescale Semiconductor, Inc. +# Copyright 2009-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 @@ -10,9 +10,13 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib8xxx.a +ifneq ($(CPU),mpc83xx) COBJS-y += cpu.o -COBJS-$(CONFIG_OF_LIBFDT) += fdt.o COBJS-$(CONFIG_PCI) += pci_cfg.o +endif + +COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +COBJS-$(CONFIG_FSL_LBC) += fsl_lbc.o SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 22f34237231..dc3da1689f9 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -80,10 +80,16 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2010, P2010_E, 1), CPU_TYPE_ENTRY(P2020, P2020, 2), CPU_TYPE_ENTRY(P2020, P2020_E, 2), + CPU_TYPE_ENTRY(P3041, P3041, 4), + CPU_TYPE_ENTRY(P3041, P3041_E, 4), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4040, P4040_E, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), CPU_TYPE_ENTRY(P4080, P4080_E, 8), + CPU_TYPE_ENTRY(P5010, P5010, 1), + CPU_TYPE_ENTRY(P5010, P5010_E, 1), + CPU_TYPE_ENTRY(P5020, P5020, 2), + CPU_TYPE_ENTRY(P5020, P5020_E, 2), #elif defined(CONFIG_MPC86xx) CPU_TYPE_ENTRY(8610, 8610, 1), CPU_TYPE_ENTRY(8641, 8641, 2), diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index ccefaf57160..88c47d1aede 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Freescale Semiconductor, Inc. + * Copyright 2009-2010 Freescale Semiconductor, Inc. * * This file is derived from arch/powerpc/cpu/mpc85xx/cpu.c and * arch/powerpc/cpu/mpc86xx/cpu.c. Basically this file contains @@ -26,6 +26,27 @@ #include <common.h> #include <libfdt.h> #include <fdt_support.h> +#include <asm/mp.h> + +#if defined(CONFIG_MP) && (defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)) +static int ft_del_cpuhandle(void *blob, int cpuhandle) +{ + int off, ret = -FDT_ERR_NOTFOUND; + + /* if we find a match, we'll delete at it which point the offsets are + * invalid so we start over from the beginning + */ + off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle", + &cpuhandle, 4); + while (off != -FDT_ERR_NOTFOUND) { + fdt_delprop(blob, off, "cpu-handle"); + ret = 1; + off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle", + &cpuhandle, 4); + } + + return ret; +} void ft_fixup_num_cores(void *blob) { int off, num_cores, del_cores; @@ -37,13 +58,18 @@ void ft_fixup_num_cores(void *blob) { while (off != -FDT_ERR_NOTFOUND) { u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); - /* if we find a cpu node outside of what we expect delete it - * and reset the offset back to the start since we can't - * trust the offsets anymore - */ - if (*reg > num_cores-1) { - fdt_del_node(blob, off); - del_cores++; + if ((*reg > num_cores-1) || (is_core_disabled(*reg))) { + int ph = fdt_get_phandle(blob, off); + + /* Delete the cpu node once there are no cpu handles */ + if (-FDT_ERR_NOTFOUND == ft_del_cpuhandle(blob, ph)) { + fdt_del_node(blob, off); + del_cores++; + } + /* either we deleted some cpu handles or the cpu node + * so we reset the offset back to the start since we + * can't trust the offsets anymore + */ off = -1; } off = fdt_node_offset_by_prop_value(blob, off, @@ -53,3 +79,139 @@ void ft_fixup_num_cores(void *blob) { debug ("deleted %d extra core entry entries from device tree\n", del_cores); } +#endif /* defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) */ + +#ifdef CONFIG_HAS_FSL_DR_USB +void fdt_fixup_dr_usb(void *blob, bd_t *bd) +{ + char *mode; + char *type; + const char *compat = "fsl-usb2-dr"; + const char *prop_mode = "dr_mode"; + const char *prop_type = "phy_type"; + int node_offset; + int err; + + mode = getenv("usb_dr_mode"); + type = getenv("usb_phy_type"); + if (!mode && !type) + return; + + node_offset = fdt_node_offset_by_compatible(blob, 0, compat); + if (node_offset < 0) { + printf("WARNING: could not find compatible node %s: %s.\n", + compat, fdt_strerror(node_offset)); + return; + } + + if (mode) { + err = fdt_setprop(blob, node_offset, prop_mode, mode, + strlen(mode) + 1); + if (err < 0) + printf("WARNING: could not set %s for %s: %s.\n", + prop_mode, compat, fdt_strerror(err)); + } + + if (type) { + err = fdt_setprop(blob, node_offset, prop_type, type, + strlen(type) + 1); + if (err < 0) + printf("WARNING: could not set %s for %s: %s.\n", + prop_type, compat, fdt_strerror(err)); + } +} +#endif /* CONFIG_HAS_FSL_DR_USB */ + +/* + * update crypto node properties to a specified revision of the SEC + * called with sec_rev == 0 if not on an E processor + */ +#if CONFIG_SYS_FSL_SEC_COMPAT == 2 /* SEC 2.x/3.x */ +void fdt_fixup_crypto_node(void *blob, int sec_rev) +{ + const struct sec_rev_prop { + u32 sec_rev; + u32 num_channels; + u32 channel_fifo_len; + u32 exec_units_mask; + u32 descriptor_types_mask; + } sec_rev_prop_list [] = { + { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */ + { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */ + { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */ + { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */ + { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */ + { 0x0301, 4, 24, 0xbfe, 0x03ab0ebf }, /* SEC 3.1 */ + { 0x0303, 4, 24, 0x97c, 0x03a30abf }, /* SEC 3.3 */ + }; + char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) * + sizeof("fsl,secX.Y")]; + int crypto_node, sec_idx, err; + char *p; + u32 val; + + /* locate crypto node based on lowest common compatible */ + crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0"); + if (crypto_node == -FDT_ERR_NOTFOUND) + return; + + /* delete it if not on an E-processor */ + if (crypto_node > 0 && !sec_rev) { + fdt_del_node(blob, crypto_node); + return; + } + + /* else we got called for possible uprev */ + for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++) + if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev) + break; + + if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) { + puts("warning: unknown SEC revision number\n"); + return; + } + + val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].num_channels); + err = fdt_setprop(blob, crypto_node, "fsl,num-channels", &val, 4); + if (err < 0) + printf("WARNING: could not set crypto property: %s\n", + fdt_strerror(err)); + + val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].descriptor_types_mask); + err = fdt_setprop(blob, crypto_node, "fsl,descriptor-types-mask", &val, 4); + if (err < 0) + printf("WARNING: could not set crypto property: %s\n", + fdt_strerror(err)); + + val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].exec_units_mask); + err = fdt_setprop(blob, crypto_node, "fsl,exec-units-mask", &val, 4); + if (err < 0) + printf("WARNING: could not set crypto property: %s\n", + fdt_strerror(err)); + + val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].channel_fifo_len); + err = fdt_setprop(blob, crypto_node, "fsl,channel-fifo-len", &val, 4); + if (err < 0) + printf("WARNING: could not set crypto property: %s\n", + fdt_strerror(err)); + + val = 0; + while (sec_idx >= 0) { + p = compat_strlist + val; + val += sprintf(p, "fsl,sec%d.%d", + (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8, + sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1; + sec_idx--; + } + err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist, val); + if (err < 0) + printf("WARNING: could not set crypto property: %s\n", + fdt_strerror(err)); +} +#elif CONFIG_SYS_FSL_SEC_COMPAT >= 4 /* SEC4 */ +void fdt_fixup_crypto_node(void *blob, int sec_rev) +{ + if (!sec_rev) + fdt_del_node_and_alias(blob, "crypto"); +} +#endif diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c b/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c new file mode 100644 index 00000000000..fcef40c5b8b --- /dev/null +++ b/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c @@ -0,0 +1,134 @@ +/* + * Copyright 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 + * Version 2 as published by the Free Software Foundation. + */ + +#include <common.h> +#include <asm/fsl_lbc.h> + +void print_lbc_regs(void) +{ + int i; + + printf("\nLocal Bus Controller Registers\n"); + for (i = 0; i < 8; i++) { + printf("BR%d\t0x%08X\tOR%d\t0x%08X\n", + i, get_lbc_br(i), i, get_lbc_or(i)); + } +} + +void init_early_memctl_regs(void) +{ + uint init_br1 = 1; + +#ifdef CONFIG_MPC85xx + /* if cs1 is already set via debugger, leave cs0/cs1 alone */ + if (get_lbc_br(1) & BR_V) + init_br1 = 0; +#endif + + /* + * Map banks 0 (and maybe 1) to the FLASH banks 0 (and 1) at + * preliminary addresses - these have to be modified later + * when FLASH size has been determined + */ +#if defined(CONFIG_SYS_OR0_REMAP) + set_lbc_or(0, CONFIG_SYS_OR0_REMAP); +#endif +#if defined(CONFIG_SYS_OR1_REMAP) + set_lbc_or(1, CONFIG_SYS_OR1_REMAP); +#endif + /* now restrict to preliminary range */ + if (init_br1) { + set_lbc_br(0, CONFIG_SYS_BR0_PRELIM); + set_lbc_or(0, CONFIG_SYS_OR0_PRELIM); + +#if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) + set_lbc_or(1, CONFIG_SYS_OR1_PRELIM); + set_lbc_br(1, CONFIG_SYS_BR1_PRELIM); +#endif + } + +#if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) + set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); + set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); +#endif + +#if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) + set_lbc_or(3, CONFIG_SYS_OR3_PRELIM); + set_lbc_br(3, CONFIG_SYS_BR3_PRELIM); +#endif + +#if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) + set_lbc_or(4, CONFIG_SYS_OR4_PRELIM); + set_lbc_br(4, CONFIG_SYS_BR4_PRELIM); +#endif + +#if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) + set_lbc_or(5, CONFIG_SYS_OR5_PRELIM); + set_lbc_br(5, CONFIG_SYS_BR5_PRELIM); +#endif + +#if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) + set_lbc_or(6, CONFIG_SYS_OR6_PRELIM); + set_lbc_br(6, CONFIG_SYS_BR6_PRELIM); +#endif + +#if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) + set_lbc_or(7, CONFIG_SYS_OR7_PRELIM); + set_lbc_br(7, CONFIG_SYS_BR7_PRELIM); +#endif +} + +/* + * Configures a UPM. The function requires the respective MxMR to be set + * before calling this function. "size" is the number or entries, not a sizeof. + */ +void upmconfig(uint upm, uint *table, uint size) +{ + fsl_lbc_t *lbc = LBC_BASE_ADDR; + int i, mdr, mad, old_mad = 0; + u32 mask = (~MxMR_OP_MSK & ~MxMR_MAD_MSK); + u32 msel = BR_UPMx_TO_MSEL(upm); + u32 *mxmr = &lbc->mamr + upm; + volatile u8 *dummy = NULL; + + if (upm < UPMA || upm > UPMC) { + printf("Error: %s() Bad UPM index %d\n", __func__, upm); + hang(); + } + + /* + * Find the address for the dummy write - scan all of the BRs until we + * find one matching the UPM and extract the base address bits from it. + */ + for (i = 0; i < 8; i++) { + if ((get_lbc_br(i) & (BR_V | BR_MSEL)) == (BR_V | msel)) { + dummy = (volatile u8 *)(get_lbc_br(i) & BR_BA); + break; + } + } + + if (!dummy) { + printf("Error: %s() No matching BR\n", __func__); + hang(); + } + + /* Program UPM using steps outlined by the reference manual */ + for (i = 0; i < size; i++) { + out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_WARR | i); + out_be32(&lbc->mdr, table[i]); + mdr = in_be32(&lbc->mdr); + *dummy = 0; + do { + mad = in_be32(mxmr) & MxMR_MAD_MSK; + } while (mad <= old_mad && !(!mad && i == (size-1))); + old_mad = mad; + } + + /* Return to normal operation */ + out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_NORM); +} diff --git a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c index 0f69ef97eeb..2fee9956905 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c @@ -767,6 +767,13 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal) debug("\n\n"); +#if defined(CONFIG_DDR_RFDC_FIXED) + mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED); + size = 512; + rffd_average = CONFIG_DDR_RFDC_FIXED & SDRAM_RFDC_RFFD_MASK; + mfsdram(SDRAM_RDCC, rdcc); /* record this value */ + cal->rdcc = rdcc; +#else /* CONFIG_DDR_RFDC_FIXED */ in_window = 0; rdcc = 0; @@ -830,6 +837,7 @@ static u32 DQS_calibration_methodB(struct ddrautocal *cal) rffd_average = SDRAM_RFDC_RFFD_MAX; mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average)); +#endif /* CONFIG_DDR_RFDC_FIXED */ rffd = rffd_average; in_window = 0; @@ -1211,10 +1219,14 @@ u32 DQS_autocalibration(void) debug("*** best_result: read value SDRAM_RQDC 0x%08x\n", rqdc_reg); +#if defined(CONFIG_DDR_RFDC_FIXED) + mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED); +#else /* CONFIG_DDR_RFDC_FIXED */ mfsdram(SDRAM_RFDC, rfdc_reg); rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK); mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(tcal.autocal.rffd)); +#endif /* CONFIG_DDR_RFDC_FIXED */ mfsdram(SDRAM_RFDC, rfdc_reg); debug("*** best_result: read value SDRAM_RFDC 0x%08x\n", diff --git a/arch/powerpc/cpu/ppc4xx/Makefile b/arch/powerpc/cpu/ppc4xx/Makefile index 88d53fbb1a9..c9c1a331ff4 100644 --- a/arch/powerpc/cpu/ppc4xx/Makefile +++ b/arch/powerpc/cpu/ppc4xx/Makefile @@ -51,6 +51,9 @@ COBJS += cpu_init.o COBJS += denali_data_eye.o COBJS += denali_spd_ddr2.o COBJS += ecc.o +ifdef CONFIG_CMD_ECCTEST +COBJS += cmd_ecctest.o +endif COBJS += fdt.o COBJS += interrupts.o COBJS += iop480_uart.o diff --git a/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c b/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c new file mode 100644 index 00000000000..b4eac405740 --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c @@ -0,0 +1,284 @@ +/* + * (C) Copyright 2010 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * 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 <ppc4xx.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/cache.h> + +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \ + defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) +#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) + +#if defined(CONFIG_405EX) +/* + * Currently only 405EX uses 16bit data bus width as an alternative + * option to 32bit data width (SDRAM0_MCOPT1_WDTH) + */ +#define SDRAM_DATA_ALT_WIDTH 2 +#else +#define SDRAM_DATA_ALT_WIDTH 8 +#endif + +#if defined(CONFIG_SYS_OCM_BASE) +#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_OCM_BASE +#endif + +#if defined(CONFIG_SYS_ISRAM_BASE) +#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_ISRAM_BASE +#endif + +#if !defined(CONFIG_FUNC_ISRAM_ADDR) +#error "No internal SRAM/OCM provided!" +#endif + +#define force_inline inline __attribute__ ((always_inline)) + +static inline void machine_check_disable(void) +{ + mtmsr(mfmsr() & ~MSR_ME); +} + +static inline void machine_check_enable(void) +{ + mtmsr(mfmsr() | MSR_ME); +} + +/* + * These helper functions need to be inlined, since they + * are called from the functions running from internal SRAM. + * SDRAM operation is forbidden at that time, so calling + * functions in SDRAM has to be avoided. + */ +static force_inline void wait_ddr_idle(void) +{ + u32 val; + + do { + mfsdram(SDRAM_MCSTAT, val); + } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT); +} + +static force_inline void recalibrate_ddr(void) +{ + u32 val; + + /* + * Rewrite RQDC & RFDC to calibrate again. If this is not + * done, the SDRAM controller is working correctly after + * changing the MCOPT1_MCHK bits. + */ + mfsdram(SDRAM_RQDC, val); + mtsdram(SDRAM_RQDC, val); + mfsdram(SDRAM_RFDC, val); + mtsdram(SDRAM_RFDC, val); +} + +static force_inline void set_mcopt1_mchk(u32 bits) +{ + u32 val; + + wait_ddr_idle(); + mfsdram(SDRAM_MCOPT1, val); + mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | bits); + recalibrate_ddr(); +} + +/* + * The next 2 functions are copied to internal SRAM/OCM and run + * there. No function calls allowed here. No SDRAM acitivity should + * be done here. + */ +static void inject_ecc_error(void *ptr, int par) +{ + u32 val; + + /* + * Taken from PPC460EX/EXr/GT users manual (Rev 1.21) + * 22.2.17.13 ECC Diagnostics + * + * Items 1 ... 5 are already done by now, running from RAM + * with ECC enabled + */ + + out_be32(ptr, 0x00000000); + val = in_be32(ptr); + + /* 6. Set memory controller to no error checking */ + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_NON); + + /* 7. Modify one or two bits for error simulation */ + if (par == 1) + out_be32(ptr, in_be32(ptr) ^ 0x00000001); + else + out_be32(ptr, in_be32(ptr) ^ 0x00000003); + + /* 8. Wait for SDRAM idle */ + val = in_be32(ptr); + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); + + /* Wait for SDRAM idle */ + wait_ddr_idle(); + + /* Continue with 9. in calling function... */ +} + +static void rewrite_ecc_parity(void *ptr, int par) +{ + u32 current_address = (u32)ptr; + u32 end_address; + u32 address_increment; + u32 mcopt1; + u32 val; + + /* + * Fill ECC parity byte again. Otherwise further accesses to + * the failure address will result in exceptions. + */ + + /* Wait for SDRAM idle */ + val = in_be32(0x00000000); + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_GEN); + + /* ECC bit set method for non-cached memory */ + mfsdram(SDRAM_MCOPT1, mcopt1); + if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) + address_increment = 4; + else + address_increment = SDRAM_DATA_ALT_WIDTH; + end_address = current_address + CONFIG_SYS_CACHELINE_SIZE; + + while (current_address < end_address) { + *((unsigned long *)current_address) = 0; + current_address += address_increment; + } + + set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); + + /* Wait for SDRAM idle */ + wait_ddr_idle(); +} + +static int do_ecctest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 old_val; + u32 val; + u32 *ptr; + void (*sram_func)(u32 *, int); + int error; + + if (argc < 3) { + cmd_usage(cmdtp); + return 1; + } + + ptr = (u32 *)simple_strtoul(argv[1], NULL, 16); + error = simple_strtoul(argv[2], NULL, 16); + if ((error < 1) || (error > 2)) { + cmd_usage(cmdtp); + return 1; + } + + printf("Using address %p for %d bit ECC error injection\n", + ptr, error); + + /* + * Save value to restore it later on + */ + old_val = in_be32(ptr); + + /* + * Copy ECC injection function into internal SRAM/OCM + */ + sram_func = (void *)CONFIG_FUNC_ISRAM_ADDR; + memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, inject_ecc_error, 0x10000); + + /* + * Disable interrupts and exceptions before calling this + * function in internal SRAM/OCM + */ + disable_interrupts(); + machine_check_disable(); + eieio(); + + /* + * Jump to ECC simulation function in internal SRAM/OCM + */ + (*sram_func)(ptr, error); + + /* 10. Read the corresponding address */ + val = in_be32(ptr); + + /* + * Read and print ECC status register/info: + * The faulting address is only known upon uncorrectable ECC + * errors. + */ + mfsdram(SDRAM_ECCES, val); + if (val & SDRAM_ECCES_CE) + printf("ECC: Correctable error\n"); + if (val & SDRAM_ECCES_UE) { + printf("ECC: Uncorrectable error at 0x%02x%08x\n", + mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL)); + } + + /* + * Clear pending interrupts/exceptions + */ + mtsdram(SDRAM_ECCES, 0xffffffff); + mtdcr(SDRAM_ERRSTATLL, 0xff000000); + set_mcsr(get_mcsr()); + + /* Now enable interrupts and exceptions again */ + eieio(); + machine_check_enable(); + enable_interrupts(); + + /* + * The ECC parity byte need to be re-written for the + * corresponding address. Otherwise future accesses to it + * will result in exceptions. + * + * Jump to ECC parity generation function + */ + memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, rewrite_ecc_parity, 0x10000); + (*sram_func)(ptr, 0); + + /* + * Restore value in corresponding address + */ + out_be32(ptr, old_val); + + return 0; +} + +U_BOOT_CMD( + ecctest, 3, 0, do_ecctest, + "Test ECC by single and double error bit injection", + "address 1/2" +); + +#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */ +#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */ diff --git a/arch/powerpc/cpu/ppc4xx/ecc.c b/arch/powerpc/cpu/ppc4xx/ecc.c index f105605459d..49f28d93e0e 100644 --- a/arch/powerpc/cpu/ppc4xx/ecc.c +++ b/arch/powerpc/cpu/ppc4xx/ecc.c @@ -130,7 +130,26 @@ static void program_ecc_addr(unsigned long start_address, /* clear ECC error repoting registers */ mtsdram(SDRAM_ECCES, 0xffffffff); - mtdcr(0x4c, 0xffffffff); +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) + /* + * IBM DDR(1) core (440GX): + * Clear Mx bits in SDRAM0_BESR0/1 + */ + mtsdram(SDRAM0_BESR0, 0xffffffff); + mtsdram(SDRAM0_BESR1, 0xffffffff); +#elif defined(CONFIG_440) + /* + * 440/460 DDR2 core: + * Clear EMID (Error PLB Master ID) in MQ0_ESL + */ + mtdcr(SDRAM_ERRSTATLL, 0xfff00000); +#else + /* + * 405EX(r) DDR2 core: + * Clear M0ID (Error PLB Master ID) in SDRAM_BESR + */ + mtsdram(SDRAM_BESR, 0xf0000000); +#endif mtsdram(SDRAM_MCOPT1, (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP); diff --git a/arch/powerpc/cpu/ppc4xx/traps.c b/arch/powerpc/cpu/ppc4xx/traps.c index 1616772f0f9..b5562ad9788 100644 --- a/arch/powerpc/cpu/ppc4xx/traps.c +++ b/arch/powerpc/cpu/ppc4xx/traps.c @@ -209,6 +209,22 @@ MachineCheckException(struct pt_regs *regs) /* Clear MCSR */ mtspr(SPRN_MCSR, val); } + +#if defined(CONFIG_DDR_ECC) && defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) + /* + * Read and print ECC status register/info: + * The faulting address is only known upon uncorrectable ECC + * errors. + */ + mfsdram(SDRAM_ECCES, val); + if (val & SDRAM_ECCES_CE) + printf("ECC: Correctable error\n"); + if (val & SDRAM_ECCES_UE) { + printf("ECC: Uncorrectable error at 0x%02x%08x\n", + mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL)); + } +#endif /* CONFIG_DDR_ECC ... */ + #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) mfsdram(DDR0_00, val) ; printf("DDR0: DDR0_00 %lx\n", val); |