summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mach-mpc85xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mach-mpc85xx')
-rw-r--r--arch/powerpc/mach-mpc85xx/.gitignore1
-rw-r--r--arch/powerpc/mach-mpc85xx/Kconfig104
-rw-r--r--arch/powerpc/mach-mpc85xx/Makefile14
-rw-r--r--arch/powerpc/mach-mpc85xx/barebox.lds.S152
-rw-r--r--arch/powerpc/mach-mpc85xx/cpu.c102
-rw-r--r--arch/powerpc/mach-mpc85xx/cpu_init.c218
-rw-r--r--arch/powerpc/mach-mpc85xx/cpuid.c73
-rw-r--r--arch/powerpc/mach-mpc85xx/eth-devices.c57
-rw-r--r--arch/powerpc/mach-mpc85xx/fdt.c157
-rw-r--r--arch/powerpc/mach-mpc85xx/fsl_gpio.c66
-rw-r--r--arch/powerpc/mach-mpc85xx/fsl_i2c.c253
-rw-r--r--arch/powerpc/mach-mpc85xx/fsl_law.c157
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/clock.h18
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h64
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/early_udelay.h36
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/ffs64.h20
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/fsl_i2c.h17
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/gianfar.h30
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/gpio.h15
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/immap_85xx.h202
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/mmu.h52
-rw-r--r--arch/powerpc/mach-mpc85xx/include/mach/mpc85xx.h23
-rw-r--r--arch/powerpc/mach-mpc85xx/speed.c143
-rw-r--r--arch/powerpc/mach-mpc85xx/time.c47
24 files changed, 2021 insertions, 0 deletions
diff --git a/arch/powerpc/mach-mpc85xx/.gitignore b/arch/powerpc/mach-mpc85xx/.gitignore
new file mode 100644
index 0000000000..d1165788c9
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/.gitignore
@@ -0,0 +1 @@
+barebox.lds
diff --git a/arch/powerpc/mach-mpc85xx/Kconfig b/arch/powerpc/mach-mpc85xx/Kconfig
new file mode 100644
index 0000000000..aa518b98fc
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/Kconfig
@@ -0,0 +1,104 @@
+if ARCH_MPC85XX
+
+config MMU
+ default y
+
+config BTB
+ bool
+ default y
+
+config TEXT_BASE
+ hex
+ default 0xeff80000 if P1010RDB || P2020RDB || P1022DS
+ default 0xfff80000 if DA923RC
+
+config RESET_VECTOR_ADDRESS
+ hex
+ default 0xfffffffc if DA923RC
+ default 0xeffffffc if P1010RDB || P2020RDB || P1022DS
+
+config MPC85xx
+ bool
+ default y
+
+config BOOKE
+ bool
+ default y
+
+config E500
+ bool
+ default y
+
+choice
+ prompt "Select your board"
+config P1010RDB
+ bool "P1010RDB"
+ select P1010
+ select DDR_SPD
+ select FSL_DDR3
+ help
+ Say Y here if you are using the Freescale P1010RDB
+
+config P2020RDB
+ bool "P2020RDB"
+ select P2020
+ select FSL_ELBC
+ help
+ Say Y here if you are using the Freescale P2020RDB
+
+config P1022DS
+ bool "P1022DS"
+ select P1022
+ select DDR_SPD
+ select FSL_DDR3
+ select FSL_ELBC
+ help
+ Say Y here if you are using the Freescale P1022DS
+
+config DA923RC
+ bool "DA923RC"
+ select MPC8544
+ select DDR_SPD
+ select FSL_DDR2
+ help
+ Say Y here if you are using the GE Intelligent Platforms DA923RC
+endchoice
+endif
+
+config P1010
+ select FSL_IFC
+ select FSL_ERRATUM_IFC_A002769
+ select FSL_ERRATUM_P1010_A003549
+ select FSL_ERRATUM_IFC_A003399
+ bool
+
+config P2020
+ bool
+
+config P1022
+ bool
+
+config MPC8544
+ bool
+
+config FSL_DDR2
+ bool
+
+config FSL_DDR3
+ bool
+
+config FSL_IFC
+ bool
+
+config FSL_ELBC
+ bool
+
+config FSL_ERRATUM_IFC_A002769
+ bool
+
+config FSL_ERRATUM_IFC_A003399
+ bool
+
+config FSL_ERRATUM_P1010_A003549
+ bool
+
diff --git a/arch/powerpc/mach-mpc85xx/Makefile b/arch/powerpc/mach-mpc85xx/Makefile
new file mode 100644
index 0000000000..de4f5efde2
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/Makefile
@@ -0,0 +1,14 @@
+obj-y += cpuid.o
+obj-y += cpu.o
+obj-y += cpu_init.o
+obj-y += fsl_law.o
+obj-y += speed.o
+obj-y +=time.o
+obj-y += fsl_gpio.o
+obj-y += fsl_i2c.o
+obj-$(CONFIG_MP) += mp.o
+obj-$(CONFIG_OFTREE) += fdt.o
+obj-$(CONFIG_DRIVER_NET_GIANFAR) += eth-devices.o
+obj-$(CONFIG_FSL_DDR2) += ../ddr-8xxx/
+obj-$(CONFIG_FSL_DDR3) += ../ddr-8xxx/
+extra-y += barebox.lds
diff --git a/arch/powerpc/mach-mpc85xx/barebox.lds.S b/arch/powerpc/mach-mpc85xx/barebox.lds.S
new file mode 100644
index 0000000000..2b73fda4e6
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/barebox.lds.S
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ * Copyright 2007-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
+ * 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.
+ */
+
+#include <asm-generic/barebox.lds.h>
+
+#ifdef CONFIG_RESET_VECTOR_ADDRESS
+#define RESET_VECTOR_ADDRESS CONFIG_RESET_VECTOR_ADDRESS
+#else
+#define RESET_VECTOR_ADDRESS 0xfffffffc
+#endif
+
+OUTPUT_ARCH("powerpc")
+ENTRY(_start_e500)
+
+PHDRS
+{
+ text PT_LOAD;
+ bss PT_LOAD;
+}
+
+SECTIONS
+{
+ . = TEXT_BASE;
+ _stext = .;
+ PROVIDE (stext = .);
+
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata)}
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text*)
+ *(.got1*)
+
+ } :text
+ _etext = .;
+ PROVIDE (etext = .);
+ _sdata = .;
+
+ .rodata :
+ {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ RO_DATA_SECTION
+ } :text
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ KEEP(*(.got))
+ _GOT2_TABLE_ = .;
+ KEEP(*(.got2))
+ PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+ _FIXUP_TABLE_ = .;
+ KEEP(*(.fixup))
+ }
+ __got2_entries = ((_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2);
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data*)
+ *(.data1*)
+ *(.sdata*)
+ *(.sdata2*)
+ *(.dynamic*)
+ CONSTRUCTORS
+ }
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __init_size = __init_end - _start;
+
+ .bootpg RESET_VECTOR_ADDRESS - 0xffc :
+ {
+ _text = .;
+ arch/powerpc/cpu-85xx/start.o (.bootpg)
+ } :text = 0xffff
+
+ .resetvec RESET_VECTOR_ADDRESS :
+ {
+ KEEP(*(.resetvec))
+ arch/powerpc/cpu-85xx/resetvec.o (.resetvec)
+ } :text = 0xffff
+
+ . = RESET_VECTOR_ADDRESS + 0x4;
+
+#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
+ /* This avoids wrapping around to offset 0 */
+ . |= 0x10;
+#endif
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss*) *(.scommon*)
+ *(.dynbss*)
+ *(.bss*)
+ *(COMMON)
+ } :bss
+ . = ALIGN(4);
+ __bss_stop = .;
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/arch/powerpc/mach-mpc85xx/cpu.c b/arch/powerpc/mach-mpc85xx/cpu.c
new file mode 100644
index 0000000000..42464e810c
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/cpu.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc
+ * Copyright 2004,2007-2011 Freescale Semiconductor, Inc.
+ * (C) Copyright 2002, 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <memory.h>
+#include <init.h>
+#include <restart.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm-generic/memory_layout.h>
+#include <mach/mmu.h>
+#include <mach/immap_85xx.h>
+
+static void __noreturn mpc85xx_restart_soc(struct restart_handler *rst)
+{
+ void __iomem *regs = (void __iomem *)MPC85xx_GUTS_ADDR;
+
+ /* Everything after the first generation of PQ3 parts has RSTCR */
+ out_be32(regs + MPC85xx_GUTS_RSTCR_OFFSET, 0x2); /* HRESET_REQ */
+ udelay(100);
+
+ hang();
+}
+
+static int restart_register_feature(void)
+{
+ restart_handler_register_fn(mpc85xx_restart_soc);
+
+ return 0;
+}
+coredevice_initcall(restart_register_feature);
+
+long int initdram(int board_type)
+{
+ phys_size_t dram_size = 0;
+
+ if (IS_ENABLED(CONFIG_DDR_SPD))
+ dram_size = fsl_ddr_sdram();
+ else
+ dram_size = fixed_sdram();
+ dram_size = e500_setup_ddr_tlbs(dram_size / 0x100000);
+ dram_size *= 0x100000;
+
+ return dram_size;
+}
+
+/*
+ * Return the memory size based on the configuration registers.
+ */
+phys_size_t fsl_get_effective_memsize(void)
+{
+ void __iomem *regs = (void __iomem *)(MPC85xx_DDR_ADDR);
+ phys_size_t sdram_size;
+ uint san , ean;
+ uint reg;
+ int ix;
+
+ sdram_size = 0;
+
+ for (ix = 0; ix < CFG_CHIP_SELECTS_PER_CTRL; ix++) {
+ if (in_be32(regs + DDR_OFF(CS0_CONFIG) + (ix * 4)) &
+ SDRAM_CFG_MEM_EN) {
+ reg = in_be32(regs + DDR_OFF(CS0_BNDS) + (ix * 8));
+ /* start address */
+ san = (reg & 0x0fff00000) >> 16;
+ /* end address */
+ ean = (reg & 0x00000fff);
+ sdram_size += ((ean - san + 1) << 24);
+ }
+ }
+
+ return sdram_size;
+}
+
+static int fsl_reserve_region(void)
+{
+ request_sdram_region("stack", _text_base - STACK_SIZE,
+ STACK_SIZE);
+ return 0;
+}
+coredevice_initcall(fsl_reserve_region);
diff --git a/arch/powerpc/mach-mpc85xx/cpu_init.c b/arch/powerpc/mach-mpc85xx/cpu_init.c
new file mode 100644
index 0000000000..003a5f15b4
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/cpu_init.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ *
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2003 Motorola Inc.
+ * Modified by Xianghua Xiao, X.Xiao@motorola.com
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ifc.h>
+#include <mach/mpc85xx.h>
+#include <mach/mmu.h>
+#include <mach/immap_85xx.h>
+
+/* NOR workaround for P1010 erratum A003399 */
+#if defined(CONFIG_FSL_ERRATUM_P1010_A003549)
+#define SRAM_BASE_ADDR 0x100
+void setup_ifc(void)
+{
+ u32 mas0, mas1, mas2, mas3, mas7;
+ phys_addr_t flash_phys = CFG_FLASH_BASE_PHYS;
+
+ /*
+ * Adjust the TLB we were running out of to match the phys addr of the
+ * chip select we are adjusting and will return to.
+ */
+ flash_phys += (~CFG_IFC_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_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);
+ asm volatile("isync;msync;tlbwe;isync");
+
+#if defined(PPC_E500_DEBUG_TLB)
+ /*
+ * TLB entry for debuggging in AS1
+ * Create temporary TLB entry in AS0 to handle debug exception
+ * As on debug exception MSR is cleared i.e. Address space is
+ * changed to 0. A TLB entry (in AS0) is required to handle
+ * debug exception generated * in AS1.
+ *
+ * TLB entry is created for IVPR + IVOR15 to map on valid OP
+ * code address because flash's physical address is going to
+ * change as CFG_FLASH_BASE_PHYS.
+ */
+ mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(PPC_E500_DEBUG_TLB);
+ mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_IPROT |
+ MAS1_TSIZE(BOOKE_PAGESZ_4M);
+ mas2 = FSL_BOOKE_MAS2(CONFIG_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);
+
+ asm volatile("isync;msync;tlbwe;isync");
+#endif
+ set_ifc_cspr(0, CFG_IFC_CSPR0);
+ set_ifc_csor(0, CFG_IFC_CSOR0);
+ set_ifc_amask(0, CFG_IFC_AMASK0);
+}
+
+void fsl_erratum_ifc_a003399(void)
+{
+ u32 mas0, mas1, mas2, mas3, mas7;
+ void __iomem *l2cache = IOMEM(MPC85xx_L2_ADDR);
+ void (*setup_ifc_sram)(void) = (void *)SRAM_BASE_ADDR;
+ u32 *dst, *src, ix;
+
+ /* 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);
+ e500_write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+ out_be32(l2cache + MPC85xx_L2_L2SRBAR0_OFFSET, SRAM_BASE_ADDR);
+ out_be32(l2cache + MPC85xx_L2_L2ERRDIS_OFFSET,
+ (MPC85xx_L2ERRDIS_MBECC | MPC85xx_L2ERRDIS_SBECC));
+ out_be32(l2cache + MPC85xx_L2_CTL_OFFSET,
+ (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)
+ */
+ dst = (u32 *) SRAM_BASE_ADDR;
+ src = (u32 *) setup_ifc;
+ for (ix = 0; ix < 1024; ix++)
+ *dst++ = *src++;
+ setup_ifc_sram();
+
+ clrbits_be32(l2cache + MPC85xx_L2_CTL_OFFSET,
+ (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE));
+ out_be32(l2cache + MPC85xx_L2_L2SRBAR0_OFFSET, 0x0);
+}
+#else
+void fsl_erratum_ifc_a003399(void) {}
+#endif
+
+int fsl_l2_cache_init(void)
+{
+ void __iomem *l2cache = (void __iomem *)MPC85xx_L2_ADDR;
+ uint cache_ctl;
+ uint svr, ver;
+ u32 l2siz_field;
+
+ svr = get_svr();
+ ver = SVR_SOC_VER(svr);
+
+ asm("msync;isync");
+ cache_ctl = in_be32(l2cache + MPC85xx_L2_CTL_OFFSET);
+
+ l2siz_field = (cache_ctl >> 28) & 0x3;
+
+ switch (l2siz_field) {
+ case 0x0:
+ return -1;
+ break;
+ case 0x1:
+ cache_ctl = 0xc0000000; /* set L2E=1, L2I=1, L2SRAM=0 */
+ break;
+ case 0x2:
+ /* set L2E=1, L2I=1, & L2SRAM=0 */
+ cache_ctl = 0xc0000000;
+ break;
+ case 0x3:
+ /* set L2E=1, L2I=1, & L2SRAM=0 */
+ cache_ctl = 0xc0000000;
+ break;
+ }
+
+ if (!(in_be32(l2cache + MPC85xx_L2_CTL_OFFSET) & MPC85xx_L2CTL_L2E)) {
+ asm("msync;isync");
+ /* invalidate & enable */
+ out_be32(l2cache + MPC85xx_L2_CTL_OFFSET, cache_ctl);
+ asm("msync;isync");
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_FSL_ERRATUM_P1010_A003549)
+void fsl_erratum_p1010_a003549(void)
+{
+ void __iomem *guts = IOMEM(MPC85xx_GUTS_ADDR);
+
+ setbits_be32(guts + MPC85xx_GUTS_PMUXCR_OFFSET,
+ MPC85xx_PMUXCR_LCLK_IFC_CS3);
+}
+#else
+void fsl_erratum_p1010_a003549(void) {}
+#endif
+
+void cpu_init_early_f(void)
+{
+ u32 mas0, mas1, mas2, mas3, mas7;
+
+ mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13);
+ mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS |
+ MAS1_TSIZE(BOOKE_PAGESZ_1M);
+ mas2 = FSL_BOOKE_MAS2(CFG_CCSRBAR, MAS2_I | MAS2_G);
+ mas3 = FSL_BOOKE_MAS3(CFG_CCSRBAR_PHYS, 0, MAS3_SW | MAS3_SR);
+ mas7 = FSL_BOOKE_MAS7(CFG_CCSRBAR_PHYS);
+
+ e500_write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+ fsl_erratum_p1010_a003549();
+ fsl_init_laws();
+ fsl_erratum_ifc_a003399();
+
+ e500_invalidate_tlb(1);
+ e500_init_tlbs();
+}
+
+static int cpu_init_r(void)
+{
+ e500_disable_tlb(14);
+ e500_disable_tlb(15);
+
+ return 0;
+}
+core_initcall(cpu_init_r);
diff --git a/arch/powerpc/mach-mpc85xx/cpuid.c b/arch/powerpc/mach-mpc85xx/cpuid.c
new file mode 100644
index 0000000000..1f54a2b1c9
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/cpuid.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009-2011 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
+ * cpu specific common code for 85xx/86xx processors.
+ * 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.
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <mach/immap_85xx.h>
+
+struct cpu_type cpu_type_list[] = {
+ CPU_TYPE_ENTRY(8544, 8544, 1),
+ CPU_TYPE_ENTRY(8544, 8544_E, 1),
+ CPU_TYPE_ENTRY(P1010, P1010, 1),
+ CPU_TYPE_ENTRY(P1022, P1022, 2),
+ CPU_TYPE_ENTRY(P2020, P2020, 2),
+ CPU_TYPE_ENTRY(P2020, P2020_E, 2),
+};
+
+struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 1);
+
+struct cpu_type *identify_cpu(u32 ver)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) {
+ if (cpu_type_list[i].soc_ver == ver)
+ return &cpu_type_list[i];
+ }
+ return &cpu_type_unknown;
+}
+
+int fsl_cpu_numcores(void)
+{
+ void __iomem *pic = (void __iomem *)MPC8xxx_PIC_ADDR;
+ struct cpu_type *cpu;
+ uint svr;
+ uint ver;
+ int tmp;
+
+ svr = get_svr();
+ ver = SVR_SOC_VER(svr);
+ cpu = identify_cpu(ver);
+
+ /* better to query feature reporting register than just assume 1 */
+ if (cpu == &cpu_type_unknown) {
+ tmp = in_be32(pic + MPC85xx_PIC_FRR_OFFSET);
+ tmp = (tmp & MPC8xxx_PICFRR_NCPU_MASK) >>
+ MPC8xxx_PICFRR_NCPU_SHIFT;
+ tmp += 1;
+ } else {
+ tmp = cpu->num_cores;
+ }
+
+ return tmp;
+}
diff --git a/arch/powerpc/mach-mpc85xx/eth-devices.c b/arch/powerpc/mach-mpc85xx/eth-devices.c
new file mode 100644
index 0000000000..ea5caff0c2
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/eth-devices.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, 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.
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <mach/immap_85xx.h>
+#include <mach/gianfar.h>
+
+static int fsl_phy_init(void)
+{
+ int i;
+ void __iomem *base = IOMEM(GFAR_BASE_ADDR + GFAR_TBIPA_OFFSET);
+
+ /*
+ * The TBI address must be initialised to enable the PHY to
+ * link up after the MDIO reset.
+ */
+ out_be32(base, GFAR_TBIPA_END);
+ /* All ports access external PHYs via the "gfar-mdio" device */
+ add_generic_device("gfar-mdio", 0, NULL, MDIO_BASE_ADDR,
+ 0x1000, IORESOURCE_MEM, NULL);
+
+ for (i = 1; i < FSL_NUM_TSEC; i++) {
+ out_be32(base + (i * 0x1000), GFAR_TBIPA_END - i);
+ /* Use "gfar-tbiphy" devices to access internal PHY. */
+ add_generic_device("gfar-tbiphy", i, NULL,
+ MDIO_BASE_ADDR + (i * 0x1000),
+ 0x1000, IORESOURCE_MEM, NULL);
+ }
+ return 0;
+}
+
+coredevice_initcall(fsl_phy_init);
+
+int fsl_eth_init(int num, struct gfar_info_struct *gf)
+{
+ add_generic_device("gfar", DEVICE_ID_DYNAMIC, NULL,
+ GFAR_BASE_ADDR + ((num - 1) * 0x1000), 0x1000,
+ IORESOURCE_MEM, gf);
+ return 0;
+}
diff --git a/arch/powerpc/mach-mpc85xx/fdt.c b/arch/powerpc/mach-mpc85xx/fdt.c
new file mode 100644
index 0000000000..1a2d780737
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/fdt.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ * Based on U-Boot arch/powerpc/cpu/mpc85xx/fdt.c and
+ * common/fdt_support.c - version git-2b26201.
+ */
+#include <common.h>
+#include <init.h>
+#include <errno.h>
+#include <environment.h>
+#include <asm/processor.h>
+#include <mach/clock.h>
+#include <of.h>
+
+static void of_setup_crypto_node(void *blob)
+{
+ struct device_node *crypto_node;
+
+ crypto_node = of_find_compatible_node(blob, NULL, "fsl,sec2.0");
+ if (crypto_node == NULL)
+ return;
+
+ of_delete_node(crypto_node);
+}
+
+/* These properties specify whether the hardware supports the stashing
+ * of buffer descriptors in L2 cache.
+ */
+static void fdt_add_enet_stashing(void *fdt)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(fdt, NULL, "gianfar");
+ while (node) {
+ of_set_property(node, "bd-stash", NULL, 0, 1);
+ of_property_write_u32(node, "rx-stash-len", 96);
+ of_property_write_u32(node, "rx-stash-idx", 0);
+ node = of_find_compatible_node(node, NULL, "gianfar");
+ }
+
+ node = of_find_compatible_node(fdt, NULL, "fsl,etsec2");
+ while (node) {
+ of_set_property(node, "bd-stash", NULL, 0, 1);
+ of_property_write_u32(node, "rx-stash-len", 96);
+ of_property_write_u32(node, "rx-stash-idx", 0);
+ node = of_find_compatible_node(node, NULL, "fsl,etsec2");
+ }
+}
+
+static int fdt_stdout_setup(struct device_node *blob)
+{
+ struct device_node *node, *alias;
+ char sername[9] = { 0 };
+ const char *prop;
+ struct console_device *cdev;
+ int len;
+
+ node = of_create_node(blob, "/chosen");
+ if (node == NULL) {
+ pr_err("%s: could not open /chosen node\n", __func__);
+ goto error;
+ }
+
+ cdev = console_get_first_active();
+ if (cdev)
+ sprintf(sername, "serial%d", cdev->dev->id);
+ else
+ sprintf(sername, "serial%d", 0);
+
+ alias = of_find_node_by_path_from(blob, "/aliases");
+ if (!alias) {
+ pr_err("%s: could not get aliases node.\n", __func__);
+ goto error;
+ }
+ prop = of_get_property(alias, sername, &len);
+ of_set_property(node, "linux,stdout-path", prop, len, 1);
+
+ return 0;
+error:
+ return -ENODEV;
+}
+
+static int fdt_cpu_setup(struct device_node *blob, void *unused)
+{
+ struct device_node *node;
+ struct sys_info sysinfo;
+
+ /* delete crypto node if not on an E-processor */
+ if (!IS_E_PROCESSOR(get_svr()))
+ of_setup_crypto_node(blob);
+
+ fdt_add_enet_stashing(blob);
+ fsl_get_sys_info(&sysinfo);
+
+ node = of_find_node_by_type(blob, "cpu");
+ while (node) {
+ const uint32_t *reg;
+
+ of_property_write_u32(node, "timebase-frequency",
+ fsl_get_timebase_clock());
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqSystemBus);
+ reg = of_get_property(node, "reg", NULL);
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqProcessor[*reg]);
+ node = of_find_node_by_type(node, "cpu");
+ }
+
+ node = of_find_node_by_type(blob, "soc");
+ if (node)
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqSystemBus);
+
+ node = of_find_compatible_node(blob, NULL, "fsl,elbc");
+ if (node)
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqLocalBus);
+
+ node = of_find_compatible_node(blob, NULL, "ns16550");
+ while (node) {
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqSystemBus);
+ node = of_find_compatible_node(node, NULL, "ns16550");
+ }
+
+ node = of_find_compatible_node(blob, NULL, "fsl,mpic");
+ if (node)
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqSystemBus);
+
+ fdt_stdout_setup(blob);
+
+ return 0;
+}
+
+static int of_register_mpc85xx_fixup(void)
+{
+ return of_register_fixup(fdt_cpu_setup, NULL);
+}
+late_initcall(of_register_mpc85xx_fixup);
diff --git a/arch/powerpc/mach-mpc85xx/fsl_gpio.c b/arch/powerpc/mach-mpc85xx/fsl_gpio.c
new file mode 100644
index 0000000000..468c780ff8
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/fsl_gpio.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ *
+ * 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.
+ *
+ * Minimal GPIO support.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/immap_85xx.h>
+
+#ifdef CONFIG_MPC8544
+/* Enable all GPIO output pins */
+void fsl_enable_gpiout(void)
+{
+ void __iomem *gpiocr = IOMEM(MPC85xx_GUTS_ADDR + MPC85xx_GPIOCR_OFFSET);
+
+ out_be32(gpiocr, in_be32(gpiocr) | MPC85xx_GPIOCR_GPOUT);
+}
+
+void gpio_set_value(unsigned gpio, int val)
+{
+ void __iomem *gpout = IOMEM(MPC85xx_GUTS_ADDR + MPC85xx_GPOUTDR_OFFSET);
+ int gpoutdr;
+
+ if (gpio >= 8)
+ return;
+
+ gpoutdr = in_be32(gpout);
+ if (val)
+ gpoutdr |= MPC85xx_GPIOBIT(gpio);
+ else
+ gpoutdr &= ~MPC85xx_GPIOBIT(gpio);
+ out_be32(gpout, gpoutdr);
+}
+#else
+int gpio_direction_output(unsigned gpio, int val)
+{
+ void __iomem *gpior = IOMEM(MPC85xx_GPIO_ADDR);
+
+ if (gpio >= 16)
+ return -EINVAL;
+
+ if (val)
+ setbits_be32(gpior + MPC85xx_GPIO_GPDAT_OFFSET,
+ 1 << (32 - gpio));
+ else
+ clrbits_be32(gpior + MPC85xx_GPIO_GPDAT_OFFSET,
+ 1 << (32 - gpio));
+
+ setbits_be32(gpior + MPC85xx_GPIO_GPDIR_OFFSET, 1 << (32 - gpio));
+
+ return 0;
+}
+#endif
diff --git a/arch/powerpc/mach-mpc85xx/fsl_i2c.c b/arch/powerpc/mach-mpc85xx/fsl_i2c.c
new file mode 100644
index 0000000000..51fcc64c26
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/fsl_i2c.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc
+ * Copyright 2006,2009 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
+ * 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.
+ *
+ * Early I2C support functions to read SPD data or board
+ * information.
+ * Based on U-Boot drivers/i2c/fsl_i2c.c
+ */
+#include <common.h>
+#include <i2c/i2c.h>
+#include <mach/clock.h>
+#include <mach/immap_85xx.h>
+#include <mach/early_udelay.h>
+
+/* FSL I2C registers */
+#define FSL_I2C_ADR 0x00
+#define FSL_I2C_FDR 0x04
+#define FSL_I2C_CR 0x08
+#define FSL_I2C_SR 0x0C
+#define FSL_I2C_DR 0x10
+#define FSL_I2C_DFSRR 0x14
+
+/* Bits of FSL I2C registers */
+#define I2C_SR_RXAK 0x01
+#define I2C_SR_MIF 0x02
+#define I2C_SR_MAL 0x10
+#define I2C_SR_MBB 0x20
+#define I2C_SR_MCF 0x80
+#define I2C_CR_RSTA 0x04
+#define I2C_CR_TXAK 0x08
+#define I2C_CR_MTX 0x10
+#define I2C_CR_MSTA 0x20
+#define I2C_CR_MEN 0x80
+
+/*
+ * Set the I2C bus speed for a given I2C device
+ *
+ * parameters:
+ * - i2c: the I2C base address.
+ * - i2c_clk: I2C bus clock frequency.
+ * - speed: the desired speed of the bus.
+ *
+ * The I2C device must be stopped before calling this function.
+ *
+ * The return value is the actual bus speed that is set.
+ */
+static uint32_t fsl_set_i2c_bus_speed(const void __iomem *i2c,
+ uint32_t i2c_clk, uint32_t speed)
+{
+ uint8_t dfsr, fdr = 0x31; /* Default if no FDR found */
+ uint16_t a, b, ga, gb, bin_gb, bin_ga, divider;
+ uint32_t c_div, est_div;
+
+ divider = min((uint16_t)(i2c_clk / speed), (uint16_t) -1);
+ /* Condition 1: dfsr <= 50/T */
+ dfsr = (5 * (i2c_clk / 1000)) / 100000;
+ if (!dfsr)
+ dfsr = 1;
+ est_div = ~0;
+
+ /*
+ * Bus speed is calculated as per Freescale AN2919.
+ * a, b and dfsr matches identifiers A,B and C as in the
+ * application note.
+ */
+ for (ga = 0x4, a = 10; a <= 30; ga++, a += 2) {
+ for (gb = 0; gb < 8; gb++) {
+ b = 16 << gb;
+ c_div = b * (a + (((3 * dfsr) / b) * 2));
+
+ if ((c_div > divider) && (c_div < est_div)) {
+ est_div = c_div;
+ bin_gb = gb << 2;
+ bin_ga = (ga & 0x3) | ((ga & 0x4) << 3);
+ fdr = bin_gb | bin_ga;
+ speed = i2c_clk / est_div;
+ }
+ }
+ if (a == 20)
+ a += 2;
+ if (a == 24)
+ a += 4;
+ }
+ writeb(dfsr, i2c + FSL_I2C_DFSRR); /* set default filter */
+ writeb(fdr, i2c + FSL_I2C_FDR); /* set bus speed */
+
+ return speed;
+}
+
+void fsl_i2c_init(void __iomem *i2c, int speed, int slaveadd)
+{
+ uint32_t i2c_clk;
+
+ i2c_clk = fsl_get_i2c_freq();
+ writeb(0, i2c + FSL_I2C_CR);
+ early_udelay(5);
+
+ fsl_set_i2c_bus_speed(i2c, i2c_clk, speed);
+ writeb(slaveadd << 1, i2c + FSL_I2C_ADR);
+ writeb(0x0, i2c + FSL_I2C_SR);
+ writeb(I2C_CR_MEN, i2c + FSL_I2C_CR);
+}
+
+static uint32_t fsl_usec2ticks(uint32_t usec)
+{
+ ulong ticks;
+
+ if (usec < 1000) {
+ ticks = (usec * (fsl_get_timebase_clock() / 1000));
+ ticks = (ticks + 500) / 1000;
+ } else {
+ ticks = (usec / 10);
+ ticks *= (fsl_get_timebase_clock() / 100000);
+ }
+
+ return ticks;
+}
+
+static int fsl_i2c_wait4bus(void __iomem *i2c)
+{
+ uint64_t timeval = get_ticks();
+ const uint64_t timeout = fsl_usec2ticks(20000);
+
+ while (readb(i2c + FSL_I2C_SR) & I2C_SR_MBB)
+ if ((get_ticks() - timeval) > timeout)
+ return -1;
+
+ return 0;
+}
+
+void fsl_i2c_stop(void __iomem *i2c)
+{
+ writeb(I2C_CR_MEN, i2c + FSL_I2C_CR);
+}
+
+static int fsl_i2c_wait(void __iomem *i2c, int write)
+{
+ const uint64_t timeout = fsl_usec2ticks(100000);
+ uint64_t timeval = get_ticks();
+ int csr;
+
+ do {
+ csr = readb(i2c + FSL_I2C_SR);
+ if (csr & I2C_SR_MIF)
+ break;
+ } while ((get_ticks() - timeval) < timeout);
+
+ if ((get_ticks() - timeval) > timeout)
+ goto error;
+
+ csr = readb(i2c + FSL_I2C_SR);
+ writeb(0x0, i2c + FSL_I2C_SR);
+
+ if (csr & I2C_SR_MAL)
+ goto error;
+
+ if (!(csr & I2C_SR_MCF))
+ goto error;
+
+ if (write == 0 && (csr & I2C_SR_RXAK))
+ goto error;
+
+ return 0;
+error:
+ return -1;
+}
+
+static int __i2c_write(void __iomem *i2c, uint8_t *data, int length)
+{
+ int i;
+
+ for (i = 0; i < length; i++) {
+ writeb(data[i], i2c + FSL_I2C_DR);
+ if (fsl_i2c_wait(i2c, 0) < 0)
+ break;
+ }
+
+ return i;
+}
+
+static int __i2c_read(void __iomem *i2c, uint8_t *data, int length)
+{
+ int i;
+ uint8_t val = I2C_CR_MEN | I2C_CR_MSTA;
+
+ if (length == 1)
+ writeb(val | I2C_CR_TXAK, i2c + FSL_I2C_CR);
+ else
+ writeb(val, i2c + FSL_I2C_CR);
+
+ readb(i2c + FSL_I2C_DR);
+ for (i = 0; i < length; i++) {
+ if (fsl_i2c_wait(i2c, 1) < 0)
+ break;
+
+ /* Generate ack on last next to last byte */
+ if (i == length - 2)
+ writeb(val | I2C_CR_TXAK, i2c + FSL_I2C_CR);
+ /* Do not generate stop on last byte */
+ if (i == length - 1)
+ writeb(val | I2C_CR_MTX, i2c + FSL_I2C_CR);
+
+ data[i] = readb(i2c + FSL_I2C_DR);
+ }
+
+ return i;
+}
+
+static int
+fsl_i2c_write_addr(void __iomem *i2c, uint8_t dev, uint8_t dir, int rsta)
+{
+ uint8_t val = I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX;
+
+ if (rsta)
+ val |= I2C_CR_RSTA;
+ writeb(val, i2c + FSL_I2C_CR);
+ writeb((dev << 1) | dir, i2c + FSL_I2C_DR);
+
+ if (fsl_i2c_wait(i2c, 0) < 0)
+ return 0;
+
+ return 1;
+}
+
+int fsl_i2c_read(void __iomem *i2c, uint8_t dev, uint addr, int alen,
+ uint8_t *data, int length)
+{
+ int i = -1;
+ uint8_t *a = (uint8_t *)&addr;
+
+ if (alen && (fsl_i2c_wait4bus(i2c) >= 0) &&
+ (fsl_i2c_write_addr(i2c, dev, 0, 0) != 0) &&
+ (__i2c_write(i2c, &a[4 - alen], alen) == alen))
+ i = 0;
+
+ if (length && fsl_i2c_write_addr(i2c, dev, 1, 1) != 0)
+ i = __i2c_read(i2c, data, length);
+
+ if (i == length)
+ return 0;
+
+ return -1;
+}
diff --git a/arch/powerpc/mach-mpc85xx/fsl_law.c b/arch/powerpc/mach-mpc85xx/fsl_law.c
new file mode 100644
index 0000000000..38902e3be8
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/fsl_law.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ */
+
+#include <common.h>
+#include <asm/config.h>
+#include <asm/fsl_law.h>
+#include <mach/ffs64.h>
+
+#define FSL_HW_NUM_LAWS FSL_NUM_LAWS
+
+#define LAW_BASE (CFG_IMMR + 0xc08)
+#define LAWAR_ADDR(x) ((u32 *)LAW_BASE + 8 * (x) + 2)
+#define LAWBAR_ADDR(x) ((u32 *)LAW_BASE + 8 * (x))
+#define LAWBAR_SHIFT 12
+
+static inline phys_addr_t fsl_get_law_base_addr(int idx)
+{
+ return (phys_addr_t)in_be32(LAWBAR_ADDR(idx)) << LAWBAR_SHIFT;
+}
+
+static inline void fsl_set_law_base_addr(int idx, phys_addr_t addr)
+{
+ out_be32(LAWBAR_ADDR(idx), addr >> LAWBAR_SHIFT);
+}
+
+static void fsl_set_law(u8 idx, phys_addr_t addr, enum law_size sz,
+ enum law_trgt_if id)
+{
+ out_be32(LAWAR_ADDR(idx), 0);
+ fsl_set_law_base_addr(idx, addr);
+ out_be32(LAWAR_ADDR(idx), LAW_EN | ((u32)id << 20) | (u32)sz);
+
+ /* Read back so that we sync the writes */
+ in_be32(LAWAR_ADDR(idx));
+}
+
+static int fsl_is_free_law(int idx)
+{
+ u32 lawar;
+
+ lawar = in_be32(LAWAR_ADDR(idx));
+ if (!(lawar & LAW_EN))
+ return 1;
+
+ return 0;
+}
+
+static void fsl_set_next_law(phys_addr_t addr, enum law_size sz,
+ enum law_trgt_if id)
+{
+ u32 idx;
+
+ for (idx = 0; idx < FSL_HW_NUM_LAWS; idx++) {
+ if (fsl_is_free_law(idx)) {
+ fsl_set_law(idx, addr, sz, id);
+ break;
+ }
+ }
+
+ if (idx >= FSL_HW_NUM_LAWS)
+ panic("No more LAWS available\n");
+}
+
+static void fsl_set_last_law(phys_addr_t addr, enum law_size sz,
+ enum law_trgt_if id)
+{
+ u32 idx;
+
+ for (idx = (FSL_HW_NUM_LAWS - 1); idx >= 0; idx--) {
+ if (fsl_is_free_law(idx)) {
+ fsl_set_law(idx, addr, sz, id);
+ break;
+ }
+ }
+
+ if (idx < 0)
+ panic("No more LAWS available\n");
+}
+
+/* use up to 2 LAWs for DDR, use the last available LAWs */
+int fsl_set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
+{
+ u64 start_align, law_sz;
+ int law_sz_enc;
+
+ if (start == 0)
+ start_align = 1ull << (LAW_SIZE_32G + 1);
+ else
+ start_align = 1ull << (ffs64(start) - 1);
+
+ law_sz = min(start_align, sz);
+ law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+ fsl_set_last_law(start, law_sz_enc, id);
+
+ /* 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;
+
+ fsl_set_last_law(start, law_sz_enc, id);
+ } else {
+ return 0;
+ }
+
+ /* do we still have anything to map */
+ sz = sz - law_sz;
+ if (sz)
+ return 1;
+
+ return 0;
+}
+
+void fsl_init_laws(void)
+{
+ int i;
+
+ if (FSL_HW_NUM_LAWS > 32)
+ panic("FSL_HW_NUM_LAWS can not be > 32 w/o code changes");
+
+ for (i = 0; i < num_law_entries; i++) {
+ if (law_table[i].index == -1)
+ fsl_set_next_law(law_table[i].addr,
+ law_table[i].size,
+ law_table[i].trgt_id);
+ else
+ fsl_set_law(law_table[i].index, law_table[i].addr,
+ law_table[i].size, law_table[i].trgt_id);
+ }
+}
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/clock.h b/arch/powerpc/mach-mpc85xx/include/mach/clock.h
new file mode 100644
index 0000000000..0e68cf6667
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/clock.h
@@ -0,0 +1,18 @@
+#ifndef __ASM_ARCH_CLOCKS_H
+#define __ASM_ARCH_CLOCKS_H
+
+#include <mach/config_mpc85xx.h>
+
+struct sys_info {
+ unsigned long freqProcessor[MAX_CPUS];
+ unsigned long freqSystemBus;
+ unsigned long freqDDRBus;
+ unsigned long freqLocalBus;
+};
+
+unsigned long fsl_get_bus_freq(ulong dummy);
+unsigned long fsl_get_ddr_freq(ulong dummy);
+unsigned long fsl_get_timebase_clock(void);
+unsigned long fsl_get_i2c_freq(void);
+void fsl_get_sys_info(struct sys_info *sysInfo);
+#endif /* __ASM_ARCH_CLOCKS_H */
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h b/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h
new file mode 100644
index 0000000000..fad2c47d11
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ * 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 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.
+ *
+ */
+
+#ifndef _ASM_MPC85xx_CONFIG_H_
+#define _ASM_MPC85xx_CONFIG_H_
+
+#define RESET_VECTOR 0xfffffffc
+
+/* Number of TLB CAM entries we have on FSL Book-E chips */
+#if defined(CONFIG_E500)
+#define NUM_TLBCAMS 16
+#endif
+
+#if defined(CONFIG_P2020)
+#define MAX_CPUS 2
+#define FSL_NUM_LAWS 12
+#define FSL_SEC_COMPAT 2
+#define FSL_NUM_TSEC 3
+#define FSL_ERRATUM_A005125
+#define PPC_E500_DEBUG_TLB 2
+
+#elif defined(CONFIG_MPC8544)
+#define MAX_CPUS 1
+#define FSL_NUM_LAWS 10
+#define FSL_NUM_TSEC 2
+#define FSL_ERRATUM_A005125
+#define PPC_E500_DEBUG_TLB 0
+
+#elif defined(CONFIG_P1022)
+#define MAX_CPUS 2
+#define FSL_NUM_LAWS 12
+#define FSL_NUM_TSEC 2
+#define FSL_SEC_COMPAT 2
+#define PPC_E500_DEBUG_TLB 2
+#define FSL_TSECV2
+#define FSL_ERRATUM_A005125
+
+#elif defined(CONFIG_P1010)
+#define MAX_CPUS 1
+#define FSL_NUM_LAWS 12
+#define FSL_NUM_TSEC 3
+#define FSL_SEC_COMPAT 4
+#define FSL_ERRATUM_A005125
+#define PPC_E500_DEBUG_TLB 2
+#define FSL_TSECV2
+
+#else
+#error Processor type not defined for this platform
+#endif
+
+#endif /* _ASM_MPC85xx_CONFIG_H_ */
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/early_udelay.h b/arch/powerpc/mach-mpc85xx/include/mach/early_udelay.h
new file mode 100644
index 0000000000..b8dc501251
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/early_udelay.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ *
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+
+/* early_udelay: delay execution before timers are initialized
+ *
+ * "usecs * 100" gives a time of around 1 second on a 1Ghz CPU.
+ */
+static inline void early_udelay(unsigned long usecs)
+{
+ uint64_t start;
+ uint32_t loops = usecs * 100;
+
+ start = get_ticks();
+
+ while ((get_ticks() - start) < loops)
+ ;
+}
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/ffs64.h b/arch/powerpc/mach-mpc85xx/include/mach/ffs64.h
new file mode 100644
index 0000000000..045498c513
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/ffs64.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ *
+ * 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.
+ *
+ */
+#include <linux/log2.h>
+
+static inline int ffs64(u64 x)
+{
+ return __ilog2_u64(x & -x) + 1ull;
+}
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/fsl_i2c.h b/arch/powerpc/mach-mpc85xx/include/mach/fsl_i2c.h
new file mode 100644
index 0000000000..d187c6cf49
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/fsl_i2c.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc
+ *
+ * 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.
+ */
+void fsl_i2c_init(void __iomem *i2c, int speed, int slaveadd);
+int fsl_i2c_read(void __iomem *i2c, uint8_t dev, uint addr, int alen,
+ uint8_t *data, int length);
+void fsl_i2c_stop(void __iomem *i2c);
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/gianfar.h b/arch/powerpc/mach-mpc85xx/include/mach/gianfar.h
new file mode 100644
index 0000000000..660cb1e98f
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/gianfar.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ * Copyright 2004, 2007, 2009 Freescale Semiconductor, Inc.
+ * (C) Copyright 2003, Motorola, Inc.
+ * based on tsec.h by Xianghua Xiao and Andy Fleming 2003-2009
+ *
+ * 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.
+ *
+ * Platform data for the Motorola Triple Speed Ethernet Controller
+ */
+
+#define GFAR_TBIPA_OFFSET 0x030 /* TBI PHY address */
+#define GFAR_TBIPA_END 0x1f /* Last valid PHY address */
+
+struct gfar_info_struct {
+ unsigned int phyaddr;
+ unsigned int tbiana;
+ unsigned int tbicr;
+ unsigned int mdiobus_tbi;
+};
+
+int fsl_eth_init(int num, struct gfar_info_struct *gf);
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/gpio.h b/arch/powerpc/mach-mpc85xx/include/mach/gpio.h
new file mode 100644
index 0000000000..b41ecc5214
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/gpio.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _MACH_PPC_GPIO_H
+#define _MACH_PPC_GPIO_H
+
+extern void fsl_enable_gpiout(void);
+
+#endif /* _MACH_PPC_GPIO_H */
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/immap_85xx.h b/arch/powerpc/mach-mpc85xx/include/mach/immap_85xx.h
new file mode 100644
index 0000000000..abcdb5c1e0
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/immap_85xx.h
@@ -0,0 +1,202 @@
+/*
+ * MPC85xx Internal Memory Map
+ *
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ *
+ * Copyright(c) 2002,2003 Motorola Inc.
+ * Xianghua Xiao (x.xiao@motorola.com)
+ *
+ * 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.
+ *
+ */
+
+#ifndef __IMMAP_85xx__
+#define __IMMAP_85xx__
+
+#include <asm/types.h>
+#include <asm/fsl_lbc.h>
+#include <asm/fsl_ifc.h>
+#include <asm/config.h>
+
+#define MPC85xx_LOCAL_OFFSET 0x0000
+#define MPC85xx_ECM_OFFSET 0x1000
+#define MPC85xx_DDR_OFFSET 0x2000
+#define MPC85xx_LBC_OFFSET 0x5000
+#define MPC85xx_PCI1_OFFSET 0x8000
+
+#define MPC85xx_GPIO_OFFSET 0xf000
+#define MPC85xx_IFC_OFFSET 0x1e000
+#define MPC85xx_L2_OFFSET 0x20000
+#ifdef FSL_TSECV2
+#define TSEC1_OFFSET 0xB0000
+#else
+#define TSEC1_OFFSET 0x24000
+#endif
+
+#define MPC85xx_PIC_OFFSET 0x40000
+#define MPC85xx_GUTS_OFFSET 0xe0000
+
+#define MPC85xx_LOCAL_ADDR (CFG_IMMR + MPC85xx_LOCAL_OFFSET)
+#define MPC85xx_ECM_ADDR (CFG_IMMR + MPC85xx_ECM_OFFSET)
+#define MPC85xx_GUTS_ADDR (CFG_IMMR + MPC85xx_GUTS_OFFSET)
+#define MPC85xx_DDR_ADDR (CFG_IMMR + MPC85xx_DDR_OFFSET)
+#define LBC_ADDR (CFG_IMMR + MPC85xx_LBC_OFFSET)
+#define IFC_ADDR (CFG_IMMR + MPC85xx_IFC_OFFSET)
+#define MPC85xx_GPIO_ADDR (CFG_IMMR + MPC85xx_GPIO_OFFSET)
+#define MPC85xx_L2_ADDR (CFG_IMMR + MPC85xx_L2_OFFSET)
+#define MPC8xxx_PIC_ADDR (CFG_IMMR + MPC85xx_PIC_OFFSET)
+
+/* Local-Access Registers */
+#define MPC85xx_LOCAL_BPTR_OFFSET 0x20 /* Boot Page Translation */
+
+/* ECM Registers */
+#define MPC85xx_ECM_EEBPCR_OFFSET 0x00 /* ECM CCB Port Configuration */
+#define MPC85xx_ECM_EEDR_OFFSET 0xE00 /* ECM error detect register */
+#define MPC85xx_ECM_EEER_OFFSET 0xE08 /* ECM error enable register */
+
+/*
+ * DDR Memory Controller Register Offsets
+ */
+/* Chip Select 0, 1,2, 3 Memory Bounds */
+#define MPC85xx_DDR_CS0_BNDS_OFFSET 0x000
+#define MPC85xx_DDR_CS1_BNDS_OFFSET 0x008
+#define MPC85xx_DDR_CS2_BNDS_OFFSET 0x010
+#define MPC85xx_DDR_CS3_BNDS_OFFSET 0x018
+/* Chip Select 0, 1, 2, 3 Configuration */
+#define MPC85xx_DDR_CS0_CONFIG_OFFSET 0x080
+#define MPC85xx_DDR_CS1_CONFIG_OFFSET 0x084
+#define MPC85xx_DDR_CS2_CONFIG_OFFSET 0x088
+#define MPC85xx_DDR_CS3_CONFIG_OFFSET 0x08c
+/* Chip Select 0, 1, 2, 3 Configuration 2 */
+#define MPC85xx_DDR_CS0_CONFIG_2_OFFSET 0x0c0
+#define MPC85xx_DDR_CS1_CONFIG_2_OFFSET 0x0c4
+#define MPC85xx_DDR_CS2_CONFIG_2_OFFSET 0x0c8
+#define MPC85xx_DDR_CS3_CONFIG_2_OFFSET 0x0cc
+/* SDRAM Timing Configuration 0, 1, 2, 3 */
+#define MPC85xx_DDR_TIMING_CFG_3_OFFSET 0x100
+#define MPC85xx_DDR_TIMING_CFG_0_OFFSET 0x104
+#define MPC85xx_DDR_TIMING_CFG_1_OFFSET 0x108
+#define MPC85xx_DDR_TIMING_CFG_2_OFFSET 0x10c
+/* SDRAM Control Configuration */
+#define MPC85xx_DDR_SDRAM_CFG_OFFSET 0x110
+#define MPC85xx_DDR_SDRAM_CFG_2_OFFSET 0x114
+/* SDRAM Mode Configuration */
+#define MPC85xx_DDR_SDRAM_MODE_OFFSET 0x118
+#define MPC85xx_DDR_SDRAM_MODE_2_OFFSET 0x11c
+/* SDRAM Mode Control */
+#define MPC85xx_DDR_SDRAM_MD_CNTL_OFFSET 0x120
+/* SDRAM Interval Configuration */
+#define MPC85xx_DDR_SDRAM_INTERVAL_OFFSET 0x124
+/* SDRAM Data initialization */
+#define MPC85xx_DDR_SDRAM_DATA_INIT_OFFSET 0x128
+/* SDRAM Clock Control */
+#define MPC85xx_DDR_SDRAM_CLK_CNTL_OFFSET 0x130
+/* training init and extended addr */
+#define MPC85xx_DDR_SDRAM_INIT_ADDR_OFFSET 0x148
+#define MPC85xx_DDR_SDRAM_INIT_ADDR_EXT_OFFSET 0x14c
+/* SDRAM Timing Configuration 4,5 */
+#define MPC85xx_DDR_TIMING_CFG_4_OFFSET 0x160
+#define MPC85xx_DDR_TIMING_CFG_5_OFFSET 0x164
+/* DDR ZQ calibration control */
+#define MPC85xx_DDR_ZQ_CNTL_OFFSET 0x170
+/* DDR write leveling control */
+#define MPC85xx_DDR_WRLVL_CNTL_OFFSET 0x174
+/* Self Refresh Counter */
+#define MPC85xx_DDR_SR_CNTL_OFFSET 0x17c
+/* DDR SDRAM Register Control Word */
+#define MPC85xx_DDR_SDRAM_RCW_1_OFFSET 0x180
+#define MPC85xx_DDR_SDRAM_RCW_2_OFFSET 0x184
+/* DDR write leveling control */
+#define MPC85xx_DDR_WRLVL_CNTL_2_OFFSET 0x190
+#define MPC85xx_DDR_WRLVL_CNTL_3_OFFSET 0x194
+/* DDR Control Driver */
+#define MPC85xx_DDR_DDRCDR1_OFFSET 0xb28
+#define MPC85xx_DDR_DDRCDR2_OFFSET 0xb2c
+/* DDR IP block revision */
+#define MPC85xx_DDR_IP_REV1_OFFSET 0xbf8
+#define MPC85xx_DDR_IP_REV2_OFFSET 0xbfc
+/* Memory Error Disable */
+#define MPC85xx_DDR_ERR_DISABLE_OFFSET 0xe44
+#define MPC85xx_DDR_ERR_INT_EN_OFFSET 0xe48
+
+#define DDR_OFF(REGNAME) (MPC85xx_DDR_##REGNAME##_OFFSET)
+
+/*
+ * GPIO Register Offsets
+ */
+#define MPC85xx_GPIO_GPDIR 0x00
+#define MPC85xx_GPIO_GPDAT 0x08
+#define MPC85xx_GPIO_GPDIR_OFFSET 0x00
+#define MPC85xx_GPIO_GPDAT_OFFSET 0x08
+
+/* Global Utilities Registers */
+#define MPC85xx_GPIOCR_OFFSET 0x30
+#define MPC85xx_GPIOCR_GPOUT 0x00000200
+#define MPC85xx_GPOUTDR_OFFSET 0x40
+#define MPC85xx_GPIOBIT(i) (1 << (31 - i))
+#define MPC85xx_GPINDR_OFFSET 0x50
+
+#define MPC85xx_DEVDISR_OFFSET 0x70
+#define MPC85xx_DEVDISR_TSEC1 0x00000080
+#define MPC85xx_DEVDISR_TSEC2 0x00000040
+#define MPC85xx_DEVDISR_TSEC3 0x00000020
+
+/*
+ * L2 Cache Register Offsets
+ */
+#define MPC85xx_L2_CTL_OFFSET 0x0 /* L2 configuration 0 */
+#define MPC85xx_L2CTL_L2E 0x80000000
+#define MPC85xx_L2CTL_L2SRAM_ENTIRE 0x00010000
+#define MPC85xx_L2_L2SRBAR0_OFFSET 0x100
+#define MPC85xx_L2_L2ERRDIS_OFFSET 0xe44
+#define MPC85xx_L2ERRDIS_MBECC 0x00000008
+#define MPC85xx_L2ERRDIS_SBECC 0x00000004
+
+/* PIC registers offsets */
+#define MPC85xx_PIC_WHOAMI_OFFSET 0x090
+#define MPC85xx_PIC_FRR_OFFSET 0x1000 /* Feature Reporting */
+/* PIC registers fields values and masks. */
+#define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00
+#define MPC8xxx_PICFRR_NCPU_SHIFT 8
+#define MPC85xx_PICGCR_RST 0x80000000
+#define MPC85xx_PICGCR_M 0x20000000
+
+#define MPC85xx_PIC_IACK0_OFFSET 0x600a0 /* IRQ Acknowledge for
+ Processor 0 */
+
+/* Global Utilities Register Offsets and field values */
+#define MPC85xx_GUTS_PORPLLSR_OFFSET 0x0
+#define MPC85xx_PORPLLSR_DDR_RATIO 0x00003e00
+#define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT 9
+#define MPC85xx_GUTS_PORDEVSR2_OFFSET 0x14
+#define MPC85xx_PORDEVSR2_SEC_CFG 0x00000080
+#define MPC85xx_GUTS_PMUXCR_OFFSET 0x60
+#define MPC85xx_PMUXCR_LCLK_IFC_CS3 0x000000C0
+#define MPC85xx_GUTS_PMUXCR2_OFFSET 0x64
+#define MPC85xx_GUTS_DEVDISR_OFFSET 0x70
+#define MPC85xx_DEVDISR_TB0 0x00004000
+#define MPC85xx_DEVDISR_TB1 0x00001000
+#define MPC85xx_GUTS_RSTCR_OFFSET 0xb0
+
+#define GFAR_BASE_ADDR (CFG_IMMR + TSEC1_OFFSET)
+#define MDIO_BASE_ADDR (CFG_IMMR + 0x24000)
+
+#define I2C1_BASE_ADDR (CFG_IMMR + 0x3000)
+#define I2C2_BASE_ADDR (CFG_IMMR + 0x3100)
+
+/* Global Timer Registers */
+#define MPC8xxx_PIC_TFRR_OFFSET 0x10F0
+
+#define PCI1_BASE_ADDR (CFG_IMMR + MPC85xx_PCI1_OFFSET)
+#endif /*__IMMAP_85xx__*/
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/mmu.h b/arch/powerpc/mach-mpc85xx/include/mach/mmu.h
new file mode 100644
index 0000000000..e2ecc62ef0
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/mmu.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, 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.
+ */
+
+#ifndef _MPC85XX_MMU_H_
+#define _MPC85XX_MMU_H_
+
+#ifdef CONFIG_E500
+#include <asm/mmu.h>
+
+#ifndef __ASSEMBLY__
+extern int e500_find_free_tlbcam(void);
+extern void e500_read_tlbcam_entry(int idx, u32 *valid, u32 *tsize,
+ unsigned long *epn, phys_addr_t *rpn);
+extern void e500_read_tlbcam_entry(int idx, u32 *valid, u32 *tsize,
+ unsigned long *epn, phys_addr_t *rpn);
+extern void e500_set_tlb(u8 tlb, u32 epn, u64 rpn, u8 perms, u8 wimge,
+ u8 ts, u8 esel, u8 tsize, u8 iprot);
+extern void e500_disable_tlb(u8 esel);
+extern void e500_invalidate_tlb(u8 tlb);
+extern void e500_init_tlbs(void);
+extern int e500_find_tlb_idx(void *addr, u8 tlbsel);
+extern void e500_init_used_tlb_cams(void);
+
+extern unsigned int e500_setup_ddr_tlbs(unsigned int memsize_in_meg);
+extern void e500_write_tlb(u32 _mas0, u32 _mas1, u32 _mas2, u32 _mas3,
+ u32 _mas7);
+
+#define FSL_SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz,\
+ _iprot) \
+ { .mas0 = FSL_BOOKE_MAS0(_tlb, _esel, 0), \
+ .mas1 = FSL_BOOKE_MAS1(1, _iprot, 0, _ts, _sz), \
+ .mas2 = FSL_BOOKE_MAS2(_epn, _wimge), \
+ .mas3 = FSL_BOOKE_MAS3(_rpn, 0, _perms), \
+ .mas7 = FSL_BOOKE_MAS7(_rpn), }
+
+struct fsl_e_tlb_entry {
+ u32 mas0;
+ u32 mas1;
+ u32 mas2;
+ u32 mas3;
+ u32 mas7;
+};
+extern struct fsl_e_tlb_entry tlb_table[];
+extern int num_tlb_entries;
+#endif
+#endif
+#endif /* _MPC85XX_MMU_H_ */
diff --git a/arch/powerpc/mach-mpc85xx/include/mach/mpc85xx.h b/arch/powerpc/mach-mpc85xx/include/mach/mpc85xx.h
new file mode 100644
index 0000000000..1d9993ace9
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/include/mach/mpc85xx.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2004, 2007 Freescale Semiconductor.
+ * Copyright(c) 2003 Motorola Inc.
+ */
+
+#ifndef __MPC85xx_H__
+#define __MPC85xx_H__
+
+/* define for common ppc_asm.tmpl */
+#define EXC_OFF_SYS_RESET 0x100 /* System reset */
+#define _START_OFFSET 0
+
+#ifndef __ASSEMBLY__
+int fsl_l2_cache_init(void);
+int fsl_cpu_numcores(void);
+
+phys_size_t fsl_get_effective_memsize(void);
+
+#endif /* __ASSEMBLY__ */
+
+#define END_OF_MEM (fsl_get_effective_memsize())
+
+#endif /* __MPC85xx_H__ */
diff --git a/arch/powerpc/mach-mpc85xx/speed.c b/arch/powerpc/mach-mpc85xx/speed.c
new file mode 100644
index 0000000000..610949443c
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/speed.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ *
+ * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao, (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <mach/clock.h>
+#include <mach/immap_85xx.h>
+#include <mach/mpc85xx.h>
+
+void fsl_get_sys_info(struct sys_info *sysInfo)
+{
+ void __iomem *gur = (void __iomem *)(MPC85xx_GUTS_ADDR);
+ uint plat_ratio, e500_ratio, half_freqSystemBus, lcrr_div, ccr;
+ int i;
+
+ plat_ratio = in_be32(gur + MPC85xx_GUTS_PORPLLSR_OFFSET) & 0x0000003e;
+ plat_ratio >>= 1;
+ sysInfo->freqSystemBus = plat_ratio * CFG_SYS_CLK_FREQ;
+
+ /*
+ * Divide before multiply to avoid integer
+ * overflow for processor speeds above 2GHz.
+ */
+ half_freqSystemBus = sysInfo->freqSystemBus/2;
+ for (i = 0; i < fsl_cpu_numcores(); i++) {
+ e500_ratio = (in_be32(gur + MPC85xx_GUTS_PORPLLSR_OFFSET) >>
+ (i * 8 + 16)) & 0x3f;
+ sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus;
+ }
+
+ /* Note: freqDDRBus is the MCLK frequency, not the data rate. */
+ sysInfo->freqDDRBus = sysInfo->freqSystemBus;
+
+#ifdef CFG_DDR_CLK_FREQ
+ {
+ u32 ddr_ratio = (in_be32(gur + MPC85xx_GUTS_PORPLLSR_OFFSET) &
+ MPC85xx_PORPLLSR_DDR_RATIO) >>
+ MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
+ if (ddr_ratio != 0x7)
+ sysInfo->freqDDRBus = ddr_ratio * CFG_DDR_CLK_FREQ;
+ }
+#endif
+
+ if (IS_ENABLED(CONFIG_FSL_IFC)) {
+ void __iomem *ifc = IFC_BASE_ADDR;
+
+ ccr = in_be32(ifc + FSL_IFC_CCR_OFFSET);
+ ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT);
+ sysInfo->freqLocalBus = sysInfo->freqSystemBus / (ccr + 1);
+ } else {
+ lcrr_div = in_be32(LBC_BASE_ADDR + FSL_LBC_LCCR) & LCRR_CLKDIV;
+
+ if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) {
+ /*
+ * The entire PQ38 family use the same bit
+ * representation for twice the clock divider values.
+ */
+ lcrr_div *= 2;
+
+ sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div;
+ } else {
+ /* In case anyone cares what the unknown value is */
+ sysInfo->freqLocalBus = lcrr_div;
+ }
+ }
+}
+
+unsigned long fsl_get_local_freq(void)
+{
+ struct sys_info sys_info;
+
+ fsl_get_sys_info(&sys_info);
+
+ return sys_info.freqLocalBus;
+}
+
+unsigned long fsl_get_bus_freq(ulong dummy)
+{
+ struct sys_info sys_info;
+
+ fsl_get_sys_info(&sys_info);
+
+ return sys_info.freqSystemBus;
+}
+
+unsigned long fsl_get_ddr_freq(ulong dummy)
+{
+ struct sys_info sys_info;
+
+ fsl_get_sys_info(&sys_info);
+
+ return sys_info.freqDDRBus;
+}
+
+unsigned long fsl_get_timebase_clock(void)
+{
+ struct sys_info sysinfo;
+
+ fsl_get_sys_info(&sysinfo);
+
+ return (sysinfo.freqSystemBus + 4UL)/8UL;
+}
+
+unsigned long fsl_get_i2c_freq(void)
+{
+ uint svr;
+ struct sys_info sysinfo;
+ void __iomem *gur = IOMEM(MPC85xx_GUTS_ADDR);
+
+ fsl_get_sys_info(&sysinfo);
+
+ svr = get_svr();
+ if ((svr == SVR_8544) || (svr == SVR_8544_E)) {
+ if (in_be32(gur + MPC85xx_GUTS_PORDEVSR2_OFFSET) &
+ MPC85xx_PORDEVSR2_SEC_CFG)
+ return sysinfo.freqSystemBus / 3;
+ }
+
+ return sysinfo.freqSystemBus / 2;
+}
diff --git a/arch/powerpc/mach-mpc85xx/time.c b/arch/powerpc/mach-mpc85xx/time.c
new file mode 100644
index 0000000000..9014fce194
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/time.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@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.
+ *
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <init.h>
+#include <mach/clock.h>
+
+uint64_t ppc_clocksource_read(void)
+{
+ return get_ticks();
+}
+
+static struct clocksource cs = {
+ .read = ppc_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(64),
+};
+
+static int clocksource_init(void)
+{
+ /* reset time base */
+ asm ("li 3,0 ; mttbu 3 ; mttbl 3 ;");
+
+ clocks_calc_mult_shift(&cs.mult, &cs.shift,
+ fsl_get_timebase_clock(), NSEC_PER_SEC, 10);
+
+ return init_clock(&cs);
+}
+
+core_initcall(clocksource_init);