summaryrefslogtreecommitdiff
path: root/board/freescale/p3060qds
diff options
context:
space:
mode:
authorShengzhou Liu <Shengzhou.Liu@freescale.com>2011-11-22 16:51:13 +0800
committerKumar Gala <galak@kernel.crashing.org>2011-11-29 08:48:06 -0600
commitae6b03fefc1a8b27d834ef12e0a586f4237fdb1f (patch)
tree4eefe39f8dc470c3caaa36ec3327328aa126951f /board/freescale/p3060qds
parentf2717b47eac74fe262d89c6d8f6bb5a047a77229 (diff)
downloadu-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.zip
u-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.tar.gz
u-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.tar.bz2
powerpc/p3060qds: Add board related support for P3060QDS platform
The P3060QDS is a Freescale reference board for the six-core P3060 SOC. P3060QDS Board Overview: Memory subsystem: - 2G Bytes unbuffered DDR3 SDRAM SO-DIMM(64bit bus) - 128M Bytes NOR flash single-chip memory - 16M Bytes SPI flash - 8K Bytes AT24C64 I2C EEPROM for RCW Ethernet: - Eight Ethernet controllers (4x1G + 4x1G/2.5G) - Three VSC8641 PHYs on board (2xRGMII + 1xMII) - Suport multiple Vitesse VSC8234 SGMII Cards in Slot1/2/3 PCIe: Two PCI Express 2.0 controllers/ports USB: Two USB2.0, USB1(TYPE-A) and USB2(TYPE-AB) on board I2C: Four I2C controllers UART: Supports two dUARTs up to 115200 bps for console RapidIO: Two RapidIO, sRIO1 and sRIO2 Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com> Signed-off-by: York Sun <yorksun@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'board/freescale/p3060qds')
-rw-r--r--board/freescale/p3060qds/Makefile54
-rw-r--r--board/freescale/p3060qds/ddr.c248
-rw-r--r--board/freescale/p3060qds/eth.c482
-rw-r--r--board/freescale/p3060qds/fixed_ddr.c214
-rw-r--r--board/freescale/p3060qds/p3060qds.c341
-rw-r--r--board/freescale/p3060qds/p3060qds.h30
-rw-r--r--board/freescale/p3060qds/p3060qds_qixis.h74
7 files changed, 1443 insertions, 0 deletions
diff --git a/board/freescale/p3060qds/Makefile b/board/freescale/p3060qds/Makefile
new file mode 100644
index 0000000..ae136f4
--- /dev/null
+++ b/board/freescale/p3060qds/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright 2011 Freescale Semiconductor, Inc.
+# (C) Copyright 2001-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS-y += $(BOARD).o
+COBJS-y += ddr.o
+COBJS-y += eth.o
+COBJS-y += fixed_ddr.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+clean:
+ rm -f $(OBJS) $(SOBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/freescale/p3060qds/ddr.c b/board/freescale/p3060qds/ddr.c
new file mode 100644
index 0000000..9affbf0
--- /dev/null
+++ b/board/freescale/p3060qds/ddr.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <hwconfig.h>
+#include <asm/mmu.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/fsl_ddr_dimm_params.h>
+#include <asm/fsl_law.h>
+
+#include "p3060qds.h"
+
+/*
+ * Fixed sdram init -- doesn't use serial presence detect.
+ */
+
+phys_size_t fixed_sdram(void)
+{
+ int i;
+ char buf[32];
+ fsl_ddr_cfg_regs_t ddr_cfg_regs;
+ phys_size_t ddr_size;
+ unsigned int lawbar1_target_id;
+ ulong ddr_freq, ddr_freq_mhz;
+
+ ddr_freq = get_ddr_freq(0);
+ ddr_freq_mhz = ddr_freq / 1000000;
+
+ printf("Configuring DDR for %s MT/s data rate\n",
+ strmhz(buf, ddr_freq));
+
+ for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) {
+ if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) &&
+ (ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) {
+ memcpy(&ddr_cfg_regs,
+ fixed_ddr_parm_0[i].ddr_settings,
+ sizeof(ddr_cfg_regs));
+ break;
+ }
+ }
+
+ if (fixed_ddr_parm_0[i].max_freq == 0)
+ panic("Unsupported DDR data rate %s MT/s data rate\n",
+ strmhz(buf, ddr_freq));
+
+ ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
+ ddr_cfg_regs.ddr_cdr1 = DDR_CDR1_DHC_EN;
+ fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0);
+
+ /*
+ * setup laws for DDR. If not interleaving, presuming half memory on
+ * DDR1 and the other half on DDR2
+ */
+ if (fixed_ddr_parm_0[i].ddr_settings->cs[0].config & 0x20000000) {
+ if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
+ ddr_size,
+ LAW_TRGT_IF_DDR_INTRLV) < 0) {
+ printf("ERROR setting Local Access Windows for DDR\n");
+ return 0;
+ }
+ } else {
+ lawbar1_target_id = LAW_TRGT_IF_DDR_1;
+ if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
+ ddr_size,
+ lawbar1_target_id) < 0) {
+ printf("ERROR setting Local Access Windows for DDR\n");
+ return 0;
+ }
+ }
+ return ddr_size;
+}
+
+struct board_specific_params {
+ u32 n_ranks;
+ u32 datarate_mhz_high;
+ u32 clk_adjust;
+ u32 wrlvl_start;
+ u32 cpo;
+ u32 write_data_delay;
+ u32 force_2T;
+};
+
+/*
+ * This table contains all valid speeds we want to override with board
+ * specific parameters. datarate_mhz_high values need to be in ascending order
+ * for each n_ranks group.
+ */
+static const struct board_specific_params udimm[] = {
+ /*
+ * memory controller 0
+ * num| hi| clk| wrlvl | cpo |wrdata|2T
+ * ranks| mhz|adjst| start | |delay |
+ */
+ {4, 850, 4, 6, 0xff, 2, 0},
+ {4, 950, 5, 7, 0xff, 2, 0},
+ {4, 1050, 5, 8, 0xff, 2, 0},
+ {4, 1250, 5, 10, 0xff, 2, 0},
+ {4, 1350, 5, 11, 0xff, 2, 0},
+ {4, 1666, 5, 12, 0xff, 2, 0},
+ {2, 850, 5, 6, 0xff, 2, 0},
+ {2, 950, 5, 7, 0xff, 2, 0},
+ {2, 1250, 4, 6, 0xff, 2, 0},
+ {2, 1350, 5, 7, 0xff, 2, 0},
+ {2, 1666, 5, 8, 0xff, 2, 0},
+ {1, 850, 4, 5, 0xff, 2, 0},
+ {1, 950, 4, 7, 0xff, 2, 0},
+ {1, 1666, 4, 8, 0xff, 2, 0},
+ {}
+};
+
+static const struct board_specific_params rdimm[] = {
+ /*
+ * memory controller 0
+ * num| hi| clk| wrlvl | cpo |wrdata|2T
+ * ranks| mhz|adjst| start | |delay |
+ */
+ {4, 850, 4, 6, 0xff, 2, 0},
+ {4, 950, 5, 7, 0xff, 2, 0},
+ {4, 1050, 5, 8, 0xff, 2, 0},
+ {4, 1250, 5, 10, 0xff, 2, 0},
+ {4, 1350, 5, 11, 0xff, 2, 0},
+ {4, 1666, 5, 12, 0xff, 2, 0},
+ {2, 850, 4, 6, 0xff, 2, 0},
+ {2, 1050, 4, 7, 0xff, 2, 0},
+ {2, 1666, 4, 8, 0xff, 2, 0},
+ {1, 850, 4, 5, 0xff, 2, 0},
+ {1, 950, 4, 7, 0xff, 2, 0},
+ {1, 1666, 4, 8, 0xff, 2, 0},
+ {}
+};
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+ dimm_params_t *pdimm,
+ unsigned int ctrl_num)
+{
+ const struct board_specific_params *pbsp, *pbsp_highest = NULL;
+ ulong ddr_freq;
+
+ if (ctrl_num) {
+ printf("Wrong parameter for controller number %d", ctrl_num);
+ return;
+ }
+ if (!pdimm->n_ranks)
+ return;
+
+ if (popts->registered_dimm_en)
+ pbsp = rdimm;
+ else
+ pbsp = udimm;
+
+ /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
+ * freqency and n_banks specified in board_specific_parameters table.
+ */
+ ddr_freq = get_ddr_freq(0) / 1000000;
+ while (pbsp->datarate_mhz_high) {
+ if (pbsp->n_ranks == pdimm->n_ranks) {
+ if (ddr_freq <= pbsp->datarate_mhz_high) {
+ popts->cpo_override = pbsp->cpo;
+ popts->write_data_delay =
+ pbsp->write_data_delay;
+ popts->clk_adjust = pbsp->clk_adjust;
+ popts->wrlvl_start = pbsp->wrlvl_start;
+ popts->twoT_en = pbsp->force_2T;
+ goto found;
+ }
+ pbsp_highest = pbsp;
+ }
+ pbsp++;
+ }
+
+ if (pbsp_highest) {
+ printf("Error: board specific timing not found "
+ "for data rate %lu MT/s!\n"
+ "Trying to use the highest speed (%u) parameters\n",
+ ddr_freq, pbsp_highest->datarate_mhz_high);
+ popts->cpo_override = pbsp_highest->cpo;
+ popts->write_data_delay = pbsp_highest->write_data_delay;
+ popts->clk_adjust = pbsp_highest->clk_adjust;
+ popts->wrlvl_start = pbsp_highest->wrlvl_start;
+ popts->twoT_en = pbsp_highest->force_2T;
+ } else {
+ panic("DIMM is not supported by this board");
+ }
+
+
+found:
+
+ /*
+ * The datasheet of HMT125U7BFR8C-H9 blocks CL=7 as reservered.
+ * However SPD still claims CL=7 is supported. Extensive tests
+ * confirmed this board cannot work stably with CL=7 with this
+ * particular DIMM.
+ */
+ if (ddr_freq >= 800 && ddr_freq < 1066 && \
+ !strncmp(pdimm[0].mpart, "HMT125U7BFR8C-H9", 16)) {
+ popts->cas_latency_override = 1;
+ popts->cas_latency_override_value = 8;
+ debug("Override CL to 8\n");
+ }
+ /*
+ * Factors to consider for half-strength driver enable:
+ * - number of DIMMs installed
+ */
+ popts->half_strength_driver_enable = 0;
+ /*
+ * Write leveling override
+ */
+ popts->wrlvl_override = 1;
+ popts->wrlvl_sample = 0xf;
+
+ /*
+ * Rtt and Rtt_WR override
+ */
+ popts->rtt_override = 0;
+
+ /* Enable ZQ calibration */
+ popts->zq_en = 1;
+
+ /* DHC_EN =1, ODT = 60 Ohm */
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN;
+}
+
+phys_size_t initdram(int board_type)
+{
+ phys_size_t dram_size;
+
+ puts("Initializing....");
+
+ if (fsl_use_spd()) {
+ puts("using SPD\n");
+ dram_size = fsl_ddr_sdram();
+ } else {
+ puts("using fixed parameters\n");
+ dram_size = fixed_sdram();
+ }
+
+ dram_size = setup_ddr_tlbs(dram_size / 0x100000);
+ dram_size *= 0x100000;
+
+ debug(" DDR: ");
+ return dram_size;
+}
diff --git a/board/freescale/p3060qds/eth.c b/board/freescale/p3060qds/eth.c
new file mode 100644
index 0000000..3f812db
--- /dev/null
+++ b/board/freescale/p3060qds/eth.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/fsl_serdes.h>
+#include <asm/fsl_portals.h>
+#include <asm/fsl_liodn.h>
+#include <malloc.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/fsl_dtsec.h>
+
+#include "../common/qixis.h"
+#include "../common/fman.h"
+
+#include "p3060qds_qixis.h"
+
+#define EMI_NONE 0xffffffff
+#define EMI1_RGMII1 0
+#define EMI1_SLOT1 1
+#define EMI1_SLOT2 2
+#define EMI1_SLOT3 3
+#define EMI1_RGMII2 4
+
+static int mdio_mux[NUM_FM_PORTS];
+
+static char *mdio_names[5] = {
+ "P3060QDS_MDIO0",
+ "P3060QDS_MDIO1",
+ "P3060QDS_MDIO2",
+ "P3060QDS_MDIO3",
+ "P3060QDS_MDIO4",
+};
+
+/*
+ * Mapping of all 18 SERDES lanes to board slots.
+ * A value of '0' here means that the mapping must be determined
+ * dynamically, Lane 8/9/16/17 map to Slot1 or Aurora debug
+ */
+static u8 lane_to_slot[] = {
+ 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0
+};
+
+static char *p3060qds_mdio_name_for_muxval(u32 muxval)
+{
+ return mdio_names[muxval];
+}
+
+struct mii_dev *mii_dev_for_muxval(u32 muxval)
+{
+ struct mii_dev *bus;
+ char *name = p3060qds_mdio_name_for_muxval(muxval);
+
+ if (!name) {
+ printf("No bus for muxval %x\n", muxval);
+ return NULL;
+ }
+
+ bus = miiphy_get_dev_by_name(name);
+
+ if (!bus) {
+ printf("No bus by name %s\n", name);
+ return NULL;
+ }
+
+ return bus;
+}
+
+struct p3060qds_mdio {
+ u32 muxval;
+ struct mii_dev *realbus;
+};
+
+static void p3060qds_mux_mdio(u32 muxval)
+{
+ u8 brdcfg4;
+
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
+ brdcfg4 |= (muxval << 4);
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+}
+
+static int p3060qds_mdio_read(struct mii_dev *bus, int addr, int devad,
+ int regnum)
+{
+ struct p3060qds_mdio *priv = bus->priv;
+
+ p3060qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->read(priv->realbus, addr, devad, regnum);
+}
+
+static int p3060qds_mdio_write(struct mii_dev *bus, int addr, int devad,
+ int regnum, u16 value)
+{
+ struct p3060qds_mdio *priv = bus->priv;
+
+ p3060qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
+}
+
+static int p3060qds_mdio_reset(struct mii_dev *bus)
+{
+ struct p3060qds_mdio *priv = bus->priv;
+
+ return priv->realbus->reset(priv->realbus);
+}
+
+static int p3060qds_mdio_init(char *realbusname, u32 muxval)
+{
+ struct p3060qds_mdio *pmdio;
+ struct mii_dev *bus = mdio_alloc();
+
+ if (!bus) {
+ printf("Failed to allocate P3060QDS MDIO bus\n");
+ return -1;
+ }
+
+ pmdio = malloc(sizeof(*pmdio));
+ if (!pmdio) {
+ printf("Failed to allocate P3060QDS private data\n");
+ free(bus);
+ return -1;
+ }
+
+ bus->read = p3060qds_mdio_read;
+ bus->write = p3060qds_mdio_write;
+ bus->reset = p3060qds_mdio_reset;
+ sprintf(bus->name, p3060qds_mdio_name_for_muxval(muxval));
+
+ pmdio->realbus = miiphy_get_dev_by_name(realbusname);
+
+ if (!pmdio->realbus) {
+ printf("No bus with name %s\n", realbusname);
+ free(bus);
+ free(pmdio);
+ return -1;
+ }
+
+ pmdio->muxval = muxval;
+ bus->priv = pmdio;
+
+ return mdio_register(bus);
+}
+
+void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
+ enum fm_port port, int offset)
+{
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int srds_prtcl = (in_be32(&gur->rcwsr[4]) &
+ FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
+
+ if (mdio_mux[port] == EMI1_RGMII1)
+ fdt_set_phy_handle(blob, prop, pa, "phy_rgmii1");
+
+ if (mdio_mux[port] == EMI1_RGMII2)
+ fdt_set_phy_handle(blob, prop, pa, "phy_rgmii2");
+
+ if ((mdio_mux[port] == EMI1_SLOT1) && ((srds_prtcl == 0x3)
+ || (srds_prtcl == 0x6))) {
+ switch (port) {
+ case FM2_DTSEC4:
+ fdt_set_phy_handle(blob, prop, pa, "phy2_slot1");
+ break;
+ case FM1_DTSEC4:
+ fdt_set_phy_handle(blob, prop, pa, "phy3_slot1");
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (mdio_mux[port] == EMI1_SLOT3) {
+ switch (port) {
+ case FM2_DTSEC3:
+ fdt_set_phy_handle(blob, prop, pa, "phy0_slot3");
+ break;
+ case FM1_DTSEC3:
+ fdt_set_phy_handle(blob, prop, pa, "phy1_slot3");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void fdt_fixup_board_enet(void *fdt)
+{
+ int i, lane, idx;
+
+ for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
+ idx = i - FM1_DTSEC1;
+ switch (fm_info_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_SGMII:
+ lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
+ if (lane < 0)
+ break;
+
+ switch (mdio_mux[i]) {
+ case EMI1_SLOT1:
+ if (lane >= 14) {
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot1");
+ fdt_status_disabled_by_alias(fdt,
+ "emi1_slot1_bk1");
+ } else {
+ fdt_status_disabled_by_alias(fdt,
+ "emi1_slot1");
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot1_bk1");
+ }
+ break;
+ case EMI1_SLOT2:
+ fdt_status_okay_by_alias(fdt, "emi1_slot2");
+ break;
+ case EMI1_SLOT3:
+ fdt_status_okay_by_alias(fdt, "emi1_slot3");
+ break;
+ }
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ if (i == FM1_DTSEC1)
+ fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
+
+ if (i == FM1_DTSEC2)
+ fdt_status_okay_by_alias(fdt, "emi1_rgmii2");
+ break;
+ default:
+ break;
+ }
+ }
+#if (CONFIG_SYS_NUM_FMAN == 2)
+ for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
+ idx = i - FM2_DTSEC1;
+ switch (fm_info_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_SGMII:
+ lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
+ if (lane >= 0) {
+ switch (mdio_mux[i]) {
+ case EMI1_SLOT1:
+ if (lane >= 14)
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot1");
+ else
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot1_bk1");
+ break;
+ case EMI1_SLOT2:
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot2");
+ break;
+ case EMI1_SLOT3:
+ fdt_status_okay_by_alias(fdt,
+ "emi1_slot3");
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+}
+
+static void initialize_lane_to_slot(void)
+{
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int sdprtl = (in_be32(&gur->rcwsr[4]) &
+ FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
+
+ switch (sdprtl) {
+ case 0x03:
+ case 0x06:
+ lane_to_slot[8] = 1;
+ lane_to_slot[9] = lane_to_slot[8];
+ lane_to_slot[16] = 5;
+ lane_to_slot[17] = lane_to_slot[16];
+ break;
+ case 0x16:
+ case 0x19:
+ case 0x1C:
+ lane_to_slot[8] = 5;
+ lane_to_slot[9] = lane_to_slot[8];
+ lane_to_slot[16] = 1;
+ lane_to_slot[17] = lane_to_slot[16];
+ break;
+ default:
+ puts("Invalid SerDes protocol for P3060QDS\n");
+ break;
+ }
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_FMAN_ENET
+ struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR;
+ int i;
+ struct fsl_pq_mdio_info dtsec_mdio_info;
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int srds_cfg = (in_be32(&gur->rcwsr[4]) &
+ FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
+
+ initialize_lane_to_slot();
+
+ /*
+ * Set TBIPA on FM1@DTSEC1. This is needed for configurations
+ * where FM1@DTSEC1 isn't used directly, since it provides
+ * MDIO for other ports.
+ */
+ out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE);
+
+ /* Initialize the mdio_mux array so we can recognize empty elements */
+ for (i = 0; i < NUM_FM_PORTS; i++)
+ mdio_mux[i] = EMI_NONE;
+
+ dtsec_mdio_info.regs =
+ (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
+ dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
+
+ /* Register the 1G MDIO bus */
+ fsl_pq_mdio_init(bis, &dtsec_mdio_info);
+
+ /* Register the 5 muxing front-ends to the MDIO buses */
+ if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII)
+ p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
+
+ if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII)
+ p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
+ p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
+ p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
+ p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
+
+ if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII)
+ fm_info_set_phy_address(FM1_DTSEC1, 1); /* RGMII1 */
+ else if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII)
+ fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT2_PHY_ADDR);
+
+ if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII)
+ fm_info_set_phy_address(FM1_DTSEC2, 2); /* RGMII2 */
+ else if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_SGMII)
+ fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
+
+ fm_info_set_phy_address(FM2_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
+ fm_info_set_phy_address(FM2_DTSEC2, SGMII_CARD_PORT3_PHY_ADDR);
+
+ switch (srds_cfg) {
+ case 0x03:
+ case 0x06:
+ fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT3_PHY_ADDR);
+ fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT4_PHY_ADDR);
+ fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT1_PHY_ADDR);
+ fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT2_PHY_ADDR);
+ break;
+ case 0x16:
+ case 0x19:
+ case 0x1C:
+ fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR);
+ fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT2_PHY_ADDR);
+ fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT3_PHY_ADDR);
+ fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT4_PHY_ADDR);
+ break;
+ default:
+ puts("Invalid SerDes protocol for P3060QDS\n");
+ break;
+ }
+
+ for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
+ int idx = i - FM1_DTSEC1, lane, slot;
+ switch (fm_info_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_SGMII:
+ lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
+ if (lane < 0)
+ break;
+ slot = lane_to_slot[lane];
+ if (QIXIS_READ(present) & (1 << (slot - 1)))
+ fm_disable_port(i);
+ switch (slot) {
+ case 1:
+ mdio_mux[i] = EMI1_SLOT1;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ case 2:
+ mdio_mux[i] = EMI1_SLOT2;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ case 3:
+ mdio_mux[i] = EMI1_SLOT3;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ };
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ if (i == FM1_DTSEC1) {
+ mdio_mux[i] = EMI1_RGMII1;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ } else if (i == FM1_DTSEC2) {
+ mdio_mux[i] = EMI1_RGMII2;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+ for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
+ int idx = i - FM2_DTSEC1, lane, slot;
+ switch (fm_info_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_SGMII:
+ lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
+ if (lane < 0)
+ break;
+ slot = lane_to_slot[lane];
+ if (QIXIS_READ(present) & (1 << (slot - 1)))
+ fm_disable_port(i);
+ switch (slot) {
+ case 1:
+ mdio_mux[i] = EMI1_SLOT1;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ case 2:
+ mdio_mux[i] = EMI1_SLOT2;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ case 3:
+ mdio_mux[i] = EMI1_SLOT3;
+ fm_info_set_mdio(i,
+ mii_dev_for_muxval(mdio_mux[i]));
+ break;
+ };
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* CONFIG_SYS_NUM_FMAN */
+
+ cpu_eth_init(bis);
+#endif /* CONFIG_FMAN_ENET */
+
+ return pci_eth_init(bis);
+}
diff --git a/board/freescale/p3060qds/fixed_ddr.c b/board/freescale/p3060qds/fixed_ddr.c
new file mode 100644
index 0000000..125988d
--- /dev/null
+++ b/board/freescale/p3060qds/fixed_ddr.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <asm/fsl_ddr_sdram.h>
+
+#define CONFIG_SYS_DDR_TIMING_3_1200 0x01030000
+#define CONFIG_SYS_DDR_TIMING_0_1200 0xCC550104
+#define CONFIG_SYS_DDR_TIMING_1_1200 0x868FAA45
+#define CONFIG_SYS_DDR_TIMING_2_1200 0x0FB8A912
+#define CONFIG_SYS_DDR_MODE_1_1200 0x00441A40
+#define CONFIG_SYS_DDR_MODE_2_1200 0x00100000
+#define CONFIG_SYS_DDR_INTERVAL_1200 0x12480100
+#define CONFIG_SYS_DDR_CLK_CTRL_1200 0x02800000
+
+#define CONFIG_SYS_DDR_TIMING_3_1000 0x00020000
+#define CONFIG_SYS_DDR_TIMING_0_1000 0xCC440104
+#define CONFIG_SYS_DDR_TIMING_1_1000 0x727DF944
+#define CONFIG_SYS_DDR_TIMING_2_1000 0x0FB088CF
+#define CONFIG_SYS_DDR_MODE_1_1000 0x00441830
+#define CONFIG_SYS_DDR_MODE_2_1000 0x00080000
+#define CONFIG_SYS_DDR_INTERVAL_1000 0x0F3C0100
+#define CONFIG_SYS_DDR_CLK_CTRL_1000 0x02800000
+
+#define CONFIG_SYS_DDR_TIMING_3_900 0x00020000
+#define CONFIG_SYS_DDR_TIMING_0_900 0xCC440104
+#define CONFIG_SYS_DDR_TIMING_1_900 0x616ba844
+#define CONFIG_SYS_DDR_TIMING_2_900 0x0fb088ce
+#define CONFIG_SYS_DDR_MODE_1_900 0x00441620
+#define CONFIG_SYS_DDR_MODE_2_900 0x00080000
+#define CONFIG_SYS_DDR_INTERVAL_900 0x0db60100
+#define CONFIG_SYS_DDR_CLK_CTRL_900 0x02800000
+
+#define CONFIG_SYS_DDR_TIMING_3_800 0x00020000
+#define CONFIG_SYS_DDR_TIMING_0_800 0xcc330104
+#define CONFIG_SYS_DDR_TIMING_1_800 0x6f6b4744
+#define CONFIG_SYS_DDR_TIMING_2_800 0x0fa888cc
+#define CONFIG_SYS_DDR_MODE_1_800 0x00441420
+#define CONFIG_SYS_DDR_MODE_2_800 0x00000000
+#define CONFIG_SYS_DDR_INTERVAL_800 0x0c300100
+#define CONFIG_SYS_DDR_CLK_CTRL_800 0x02800000
+
+#define CONFIG_SYS_DDR_CS0_BNDS 0x000000FF
+#define CONFIG_SYS_DDR_CS1_BNDS 0x00000000
+#define CONFIG_SYS_DDR_CS2_BNDS 0x000000FF
+#define CONFIG_SYS_DDR_CS3_BNDS 0x000000FF
+#define CONFIG_SYS_DDR2_CS0_BNDS 0x000000FF
+#define CONFIG_SYS_DDR2_CS1_BNDS 0x00000000
+#define CONFIG_SYS_DDR2_CS2_BNDS 0x000000FF
+#define CONFIG_SYS_DDR2_CS3_BNDS 0x000000FF
+#define CONFIG_SYS_DDR_CS0_CONFIG 0xA0044202
+#define CONFIG_SYS_DDR_CS0_CONFIG_2 0x00000000
+#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202
+#define CONFIG_SYS_DDR_CS2_CONFIG 0x00000000
+#define CONFIG_SYS_DDR_CS3_CONFIG 0x00000000
+#define CONFIG_SYS_DDR2_CS0_CONFIG 0x80044202
+#define CONFIG_SYS_DDR2_CS1_CONFIG 0x80004202
+#define CONFIG_SYS_DDR2_CS2_CONFIG 0x00000000
+#define CONFIG_SYS_DDR2_CS3_CONFIG 0x00000000
+#define CONFIG_SYS_DDR_INIT_ADDR 0x00000000
+#define CONFIG_SYS_DDR_INIT_EXT_ADDR 0x00000000
+#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202
+#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef
+#define CONFIG_SYS_DDR_TIMING_4 0x00000001
+#define CONFIG_SYS_DDR_TIMING_5 0x02401400
+#define CONFIG_SYS_DDR_MODE_CONTROL 0x00000000
+#define CONFIG_SYS_DDR_ZQ_CNTL 0x89080600
+#define CONFIG_SYS_DDR_WRLVL_CNTL 0x8675F607
+#define CONFIG_SYS_DDR_SDRAM_CFG 0xE7044000
+#define CONFIG_SYS_DDR_SDRAM_CFG2 0x24401031
+#define CONFIG_SYS_DDR_RCW_1 0x00000000
+#define CONFIG_SYS_DDR_RCW_2 0x00000000
+#define CONFIG_MEM_INIT_VALUE 0xdeadbeef
+
+fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = {
+ .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
+ .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS,
+ .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS,
+ .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS,
+ .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
+ .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
+ .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG,
+ .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG,
+ .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG,
+ .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800,
+ .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800,
+ .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800,
+ .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800,
+ .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG,
+ .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2,
+ .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800,
+ .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800,
+ .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
+ .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800,
+ .ddr_data_init = CONFIG_MEM_INIT_VALUE,
+ .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800,
+ .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
+ .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
+ .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
+ .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
+ .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL,
+ .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL,
+ .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
+ .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
+};
+
+fsl_ddr_cfg_regs_t ddr_cfg_regs_900 = {
+ .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
+ .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS,
+ .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS,
+ .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS,
+ .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
+ .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
+ .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG,
+ .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG,
+ .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG,
+ .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_900,
+ .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_900,
+ .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_900,
+ .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_900,
+ .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG,
+ .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2,
+ .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_900,
+ .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_900,
+ .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
+ .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_900,
+ .ddr_data_init = CONFIG_MEM_INIT_VALUE,
+ .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_900,
+ .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
+ .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
+ .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
+ .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
+ .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL,
+ .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL,
+ .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
+ .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
+};
+
+fsl_ddr_cfg_regs_t ddr_cfg_regs_1000 = {
+ .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
+ .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS,
+ .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS,
+ .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS,
+ .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
+ .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
+ .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG,
+ .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG,
+ .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG,
+ .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1000,
+ .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1000,
+ .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1000,
+ .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1000,
+ .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG,
+ .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2,
+ .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1000,
+ .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1000,
+ .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
+ .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1000,
+ .ddr_data_init = CONFIG_MEM_INIT_VALUE,
+ .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1000,
+ .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
+ .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
+ .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
+ .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
+ .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL,
+ .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL,
+ .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
+ .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
+};
+
+fsl_ddr_cfg_regs_t ddr_cfg_regs_1200 = {
+ .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
+ .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS,
+ .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS,
+ .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS,
+ .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
+ .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
+ .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG,
+ .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG,
+ .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG,
+ .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1200,
+ .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1200,
+ .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1200,
+ .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1200,
+ .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG,
+ .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2,
+ .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1200,
+ .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1200,
+ .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
+ .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1200,
+ .ddr_data_init = CONFIG_MEM_INIT_VALUE,
+ .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1200,
+ .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
+ .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
+ .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
+ .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
+ .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL,
+ .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL,
+ .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
+ .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
+};
+
+fixed_ddr_parm_t fixed_ddr_parm_0[] = {
+ {750, 850, &ddr_cfg_regs_800},
+ {850, 950, &ddr_cfg_regs_900},
+ {950, 1050, &ddr_cfg_regs_1000},
+ {1050, 1250, &ddr_cfg_regs_1200},
+ {0, 0, NULL}
+};
diff --git a/board/freescale/p3060qds/p3060qds.c b/board/freescale/p3060qds/p3060qds.c
new file mode 100644
index 0000000..c6c74f2
--- /dev/null
+++ b/board/freescale/p3060qds/p3060qds.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <linux/compiler.h>
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_serdes.h>
+#include <asm/fsl_portals.h>
+#include <asm/fsl_liodn.h>
+#include <fm_eth.h>
+#include <configs/P3060QDS.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+
+#include "../common/qixis.h"
+#include "p3060qds.h"
+#include "p3060qds_qixis.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int checkboard(void)
+{
+ u8 sw;
+ struct cpu_type *cpu = gd->cpu;
+ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+ unsigned int i;
+
+ printf("Board: %s", cpu->name);
+ puts("QDS, ");
+
+ printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
+ QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver));
+
+ sw = QIXIS_READ(brdcfg[0]);
+ sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
+
+ if (sw < 0x8)
+ printf("vBank: %d\n", sw);
+ else if (sw == 0x8)
+ puts("Promjet\n");
+ else if (sw == 0x9)
+ puts("NAND\n");
+ else
+ printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH);
+
+#ifdef CONFIG_PHYS_64BIT
+ puts("36-bit Addressing\n");
+#endif
+ puts("Reset Configuration Word (RCW):");
+ for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
+ u32 rcw = in_be32(&gur->rcwsr[i]);
+
+ if ((i % 4) == 0)
+ printf("\n %08x:", i * 4);
+ printf(" %08x", rcw);
+ }
+ puts("\n");
+
+ puts("SERDES Reference Clocks: ");
+ sw = QIXIS_READ(brdcfg[2]);
+ for (i = 0; i < 3; i++) {
+ static const char * const freq[] = {"100", "125", "Reserved",
+ "156.25"};
+ unsigned int clock = (sw >> (2 * i)) & 3;
+
+ printf("Bank%u=%sMhz ", i+1, freq[clock]);
+ }
+ puts("\n");
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+ /* only single DDR controller on QDS board, disable DDR1_MCK4/5 */
+ setbits_be32(&gur->ddrclkdr, 0x00030000);
+
+ return 0;
+}
+
+void board_config_serdes_mux(void)
+{
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int cfg = (in_be32(&gur->rcwsr[4]) &
+ FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
+
+ switch (cfg) {
+ case 0x03:
+ case 0x06:
+ /* set Lane I,J as SGMII */
+ QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_B | BRDCFG6_SD3MX_A |
+ BRDCFG6_SD2MX_B | BRDCFG6_SD1MX_A);
+ break;
+ case 0x16:
+ case 0x19:
+ case 0x1c:
+ /* set Lane I,J as Aurora Debug */
+ QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_A | BRDCFG6_SD3MX_B |
+ BRDCFG6_SD2MX_A | BRDCFG6_SD1MX_B);
+ break;
+ default:
+ puts("Invalid SerDes protocol for P3060QDS\n");
+ break;
+ }
+}
+
+void board_config_usb_mux(void)
+{
+ u8 brdcfg4, brdcfg5, brdcfg7;
+ ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+ u32 ec1 = rcwsr11 & FSL_CORENET_RCWSR11_EC1;
+ u32 ec2 = rcwsr11 & FSL_CORENET_RCWSR11_EC2;
+
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_EC_MODE_MASK;
+ if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) &&
+ (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) {
+ brdcfg4 |= BRDCFG4_EC2_USB_EC1_USB;
+
+ } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) &&
+ ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) ||
+ (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) {
+ brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_USB;
+
+ } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) &&
+ (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) {
+ brdcfg4 |= BRDCFG4_EC2_USB_EC1_RGMII;
+
+ } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) &&
+ ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) ||
+ (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) {
+ brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_RGMII;
+ } else {
+ brdcfg4 |= BRDCFG4_EC2_MII_EC1_MII;
+ }
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+
+ brdcfg5 = QIXIS_READ(brdcfg[5]);
+ brdcfg5 &= ~(BRDCFG5_USB1ID_MASK | BRDCFG5_USB2ID_MASK);
+ brdcfg5 |= (BRDCFG5_USB1ID_CTRL | BRDCFG5_USB2ID_CTRL);
+ QIXIS_WRITE(brdcfg[5], brdcfg5);
+
+ brdcfg7 = BRDCFG7_JTAGMX_COP_JTAG | BRDCFG7_IQ1MX_IRQ_EVT |
+ BRDCFG7_G1MX_USB1 | BRDCFG7_D1MX_TSEC3USB | BRDCFG7_I3MX_USB1;
+ QIXIS_WRITE(brdcfg[7], brdcfg7);
+}
+
+int board_early_init_r(void)
+{
+ const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
+ const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
+
+ /*
+ * Remap Boot flash + PROMJET region to caching-inhibited
+ * so that flash can be erased properly.
+ */
+
+ /* Flush d-cache and invalidate i-cache of any FLASH data */
+ flush_dcache();
+ invalidate_icache();
+
+ /* invalidate existing TLB entry for flash + promjet */
+ disable_tlb(flash_esel);
+
+ set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, flash_esel, BOOKE_PAGESZ_256M, 1);
+
+ set_liodns();
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ setup_portals();
+#endif
+ board_config_serdes_mux();
+ board_config_usb_mux();
+
+ return 0;
+}
+
+static const char *serdes_clock_to_string(u32 clock)
+{
+ switch (clock) {
+ case SRDS_PLLCR0_RFCK_SEL_100:
+ return "100";
+ case SRDS_PLLCR0_RFCK_SEL_125:
+ return "125";
+ case SRDS_PLLCR0_RFCK_SEL_156_25:
+ return "156.25";
+ default:
+ return "150";
+ }
+}
+
+#define NUM_SRDS_BANKS 3
+
+int misc_init_r(void)
+{
+ serdes_corenet_t *srds_regs;
+ u32 actual[NUM_SRDS_BANKS];
+ unsigned int i;
+ u8 sw;
+
+ sw = QIXIS_READ(brdcfg[2]);
+ for (i = 0; i < 3; i++) {
+ unsigned int clock = (sw >> (2 * i)) & 3;
+ switch (clock) {
+ case 0:
+ actual[i] = SRDS_PLLCR0_RFCK_SEL_100;
+ break;
+ case 1:
+ actual[i] = SRDS_PLLCR0_RFCK_SEL_125;
+ break;
+ case 3:
+ actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25;
+ break;
+ default:
+ printf("Warning: SDREFCLK%u switch setting of '10' is "
+ "unsupported\n", i + 1);
+ break;
+ }
+ }
+
+ srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
+ for (i = 0; i < NUM_SRDS_BANKS; i++) {
+ u32 pllcr0 = in_be32(&srds_regs->bank[i].pllcr0);
+ u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
+ if (expected != actual[i]) {
+ printf("Warning: SERDES bank %u expects reference clock"
+ " %sMHz, but actual is %sMHz\n", i + 1,
+ serdes_clock_to_string(expected),
+ serdes_clock_to_string(actual[i]));
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This is map of CVDD values. 33 means CVDD is 3.3v, 25 means CVDD is 2.5v,
+ * 18 means CVDD is 1.8v.
+ */
+static u8 IO_VSEL[] = {
+ 33, 33, 33, 25, 25, 25, 18, 18, 18,
+ 33, 33, 33, 25, 25, 25, 18, 18, 18,
+ 33, 33, 33, 25, 25, 25, 18, 18, 18,
+ 33, 33, 33, 33, 33
+};
+
+#define IO_VSEL_MASK 0x1f
+
+/*
+ * different CVDD selects diffenert spi flashs, read dutcfg[3] to get CVDD,
+ * then set status of spi flash nodes to 'disabled' according to CVDD.
+ * CVDD '33' will select spi flash0 and flash1, CVDD '25' will select spi
+ * flash2, CVDD '18' will select spi flash3.
+ */
+void fdt_fixup_board_spi(void *blob)
+{
+ u8 sw5 = QIXIS_READ(dutcfg[3]);
+
+ switch (IO_VSEL[sw5 & IO_VSEL_MASK]) {
+ /* 3.3v */
+ case 33:
+ do_fixup_by_compat(blob, "atmel,at45db081d", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ do_fixup_by_compat(blob, "spansion,sst25wf040", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ break;
+ /* 2.5v */
+ case 25:
+ do_fixup_by_compat(blob, "spansion,s25sl12801", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ do_fixup_by_compat(blob, "spansion,en25q32", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ do_fixup_by_compat(blob, "spansion,sst25wf040", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ break;
+ /* 1.8v */
+ case 18:
+ do_fixup_by_compat(blob, "spansion,s25sl12801", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ do_fixup_by_compat(blob, "spansion,en25q32", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ do_fixup_by_compat(blob, "atmel,at45db081d", "status",
+ "disabled", strlen("disabled") + 1, 1);
+ break;
+ }
+}
+
+void ft_board_setup(void *blob, bd_t *bd)
+{
+ phys_addr_t base;
+ phys_size_t size;
+
+ ft_cpu_setup(blob, bd);
+
+ base = getenv_bootm_low();
+ size = getenv_bootm_size();
+
+ fdt_fixup_memory(blob, (u64)base, (u64)size);
+
+#ifdef CONFIG_PCI
+ pci_of_setup(blob, bd);
+#endif
+
+ fdt_fixup_liodn(blob);
+ fdt_fixup_dr_usb(blob, bd);
+ fdt_fixup_board_spi(blob);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+ fdt_fixup_fman_ethernet(blob);
+ fdt_fixup_board_enet(blob);
+#endif
+}
diff --git a/board/freescale/p3060qds/p3060qds.h b/board/freescale/p3060qds/p3060qds.h
new file mode 100644
index 0000000..3da6815
--- /dev/null
+++ b/board/freescale/p3060qds/p3060qds.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 __P3060QDS_H__
+#define __P3060QDS_H__
+
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/u-boot.h>
+
+void fdt_fixup_board_enet(void *blob);
+void pci_of_setup(void *blob, bd_t *bd);
+extern fixed_ddr_parm_t fixed_ddr_parm_0[];
+
+#endif
diff --git a/board/freescale/p3060qds/p3060qds_qixis.h b/board/freescale/p3060qds/p3060qds_qixis.h
new file mode 100644
index 0000000..4d5d6a2
--- /dev/null
+++ b/board/freescale/p3060qds/p3060qds_qixis.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 __P3060QDS_QIXIS_H__
+#define __P3060QDS_QIXIS_H__
+
+/* Definitions of QIXIS Registers for P3060QDS */
+
+/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */
+#define BRDCFG4_EC_MODE_MASK 0x0F
+#define BRDCFG4_EC2_MII_EC1_MII 0x00
+#define BRDCFG4_EC2_MII_EC1_USB 0x03
+#define BRDCFG4_EC2_USB_EC1_MII 0x0C
+#define BRDCFG4_EC2_USB_EC1_USB 0x0F
+#define BRDCFG4_EC2_USB_EC1_RGMII 0x0E
+#define BRDCFG4_EC2_RGMII_EC1_USB 0x0B
+#define BRDCFG4_EC2_RGMII_EC1_RGMII 0x0A
+#define BRDCFG4_EMISEL_MASK 0xF0
+
+#define BRDCFG5_ECLKS_MASK 0x80
+#define BRDCFG5_USB1ID_MASK 0x40
+#define BRDCFG5_USB2ID_MASK 0x20
+#define BRDCFG5_GC2MX_MASK 0x0C
+#define BRDCFG5_T15MX_MASK 0x03
+#define BRDCFG5_ECLKS_IEEE1588_CM 0x80
+#define BRDCFG5_USB1ID_CTRL 0x40
+#define BRDCFG5_USB2ID_CTRL 0x20
+
+#define BRDCFG6_SD1MX_A 0x01
+#define BRDCFG6_SD1MX_B 0x00
+#define BRDCFG6_SD2MX_A 0x02
+#define BRDCFG6_SD2MX_B 0x00
+#define BRDCFG6_SD3MX_A 0x04
+#define BRDCFG6_SD3MX_B 0x00
+#define BRDCFG6_SD4MX_A 0x08
+#define BRDCFG6_SD4MX_B 0x00
+
+#define BRDCFG7_JTAGMX_MASK 0xC0
+#define BRDCFG7_IQ1MX_MASK 0x20
+#define BRDCFG7_G1MX_MASK 0x10
+#define BRDCFG7_D1MX_MASK 0x0C
+#define BRDCFG7_I3MX_MASK 0x03
+#define BRDCFG7_JTAGMX_AURORA 0x00
+#define BRDCFG7_JTAGMX_FPGA 0x80
+#define BRDCFG7_JTAGMX_COP_JTAG 0xC0
+#define BRDCFG7_IQ1MX_IRQ_EVT 0x00
+#define BRDCFG7_IQ1MX_USB2 0x20
+#define BRDCFG7_G1MX_USB1 0x00
+#define BRDCFG7_G1MX_TSEC3 0x10
+#define BRDCFG7_D1MX_DMA 0x00
+#define BRDCFG7_D1MX_TSEC3USB 0x04
+#define BRDCFG7_D1MX_HDLC2 0x08
+#define BRDCFG7_I3MX_UART2_I2C34 0x00
+#define BRDCFG7_I3MX_GPIO_EVT 0x01
+#define BRDCFG7_I3MX_USB1 0x02
+#define BRDCFG7_I3MX_TSEC3 0x03
+
+#endif