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