summaryrefslogtreecommitdiffstats
path: root/board/freescale/common
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineering.com>2017-08-23 15:54:21 -0500
committerTimothy Pearson <tpearson@raptorengineering.com>2017-08-23 15:54:21 -0500
commit0223e595f4033e91e93403a7317bcc9e47676b8f (patch)
tree2ccd7127bc343f82456b76eeb0da2d380f6eaf65 /board/freescale/common
downloadast2050-uboot-0223e595f4033e91e93403a7317bcc9e47676b8f.zip
ast2050-uboot-0223e595f4033e91e93403a7317bcc9e47676b8f.tar.gz
Initial import of modified u-boot tree
Original upstream URL: git://git.denx.de/u-boot.git Original upstream GIT hash: 62c175fbb8a0f9a926c88294ea9f7e88eb898f6c
Diffstat (limited to 'board/freescale/common')
-rw-r--r--board/freescale/common/Makefile100
-rw-r--r--board/freescale/common/cadmus.c95
-rw-r--r--board/freescale/common/cadmus.h54
-rw-r--r--board/freescale/common/cds_pci_ft.c91
-rw-r--r--board/freescale/common/cds_via.c109
-rw-r--r--board/freescale/common/eeprom.h50
-rw-r--r--board/freescale/common/fman.c100
-rw-r--r--board/freescale/common/fman.h28
-rw-r--r--board/freescale/common/ics307_clk.c162
-rw-r--r--board/freescale/common/ics307_clk.h32
-rw-r--r--board/freescale/common/ngpixis.c253
-rw-r--r--board/freescale/common/ngpixis.h64
-rw-r--r--board/freescale/common/p_corenet/Makefile31
-rw-r--r--board/freescale/common/p_corenet/law.c53
-rw-r--r--board/freescale/common/p_corenet/pci.c39
-rw-r--r--board/freescale/common/p_corenet/tlb.c162
-rw-r--r--board/freescale/common/pixis.c558
-rw-r--r--board/freescale/common/pixis.h182
-rw-r--r--board/freescale/common/pq-mds-pib.c102
-rw-r--r--board/freescale/common/pq-mds-pib.h9
-rw-r--r--board/freescale/common/qixis.c235
-rw-r--r--board/freescale/common/qixis.h112
-rw-r--r--board/freescale/common/sdhc_boot.c63
-rw-r--r--board/freescale/common/sgmii_riser.c129
-rw-r--r--board/freescale/common/sgmii_riser.h16
-rw-r--r--board/freescale/common/sys_eeprom.c554
-rw-r--r--board/freescale/common/via.h18
-rw-r--r--board/freescale/common/vsc3316_3308.c184
-rw-r--r--board/freescale/common/vsc3316_3308.h34
29 files changed, 3619 insertions, 0 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
new file mode 100644
index 0000000..37236d0
--- /dev/null
+++ b/board/freescale/common/Makefile
@@ -0,0 +1,100 @@
+#
+# (C) Copyright 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
+
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)board/freescale/common)
+endif
+
+LIB = $(obj)libfreescale.o
+
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifndef MINIMAL
+COBJS-$(CONFIG_FSL_CADMUS) += cadmus.o
+COBJS-$(CONFIG_FSL_VIA) += cds_via.o
+COBJS-$(CONFIG_FMAN_ENET) += fman.o
+COBJS-$(CONFIG_FSL_PIXIS) += pixis.o
+ifndef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_FSL_NGPIXIS) += ngpixis.o
+endif
+COBJS-$(CONFIG_FSL_QIXIS) += qixis.o
+COBJS-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o
+ifndef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_ID_EEPROM) += sys_eeprom.o
+endif
+COBJS-$(CONFIG_FSL_SGMII_RISER) += sgmii_riser.o
+ifndef CONFIG_RAMBOOT_PBL
+COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION) += sdhc_boot.o
+endif
+
+COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+
+COBJS-$(CONFIG_MPC8536DS) += ics307_clk.o
+COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o
+ifndef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_P1022DS) += ics307_clk.o
+endif
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
+COBJS-$(CONFIG_P3041DS) += ics307_clk.o
+COBJS-$(CONFIG_P4080DS) += ics307_clk.o
+COBJS-$(CONFIG_P5020DS) += ics307_clk.o
+COBJS-$(CONFIG_P5040DS) += ics307_clk.o
+COBJS-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o
+
+# deal with common files for P-series corenet based devices
+SUBLIB-$(CONFIG_P2041RDB) += p_corenet/libp_corenet.o
+SUBLIB-$(CONFIG_P3041DS) += p_corenet/libp_corenet.o
+SUBLIB-$(CONFIG_P4080DS) += p_corenet/libp_corenet.o
+SUBLIB-$(CONFIG_P5020DS) += p_corenet/libp_corenet.o
+SUBLIB-$(CONFIG_P5040DS) += p_corenet/libp_corenet.o
+endif
+
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+SUBLIB := $(addprefix $(obj),$(SUBLIB-y))
+
+$(LIB): $(obj).depend $(OBJS) $(SUBLIB)
+ $(call cmd_link_o_target, $(OBJS) $(SUBLIB))
+
+$(SUBLIB): $(obj).depend
+ $(MAKE) -C $(dir $(subst $(obj),,$@))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/freescale/common/cadmus.c b/board/freescale/common/cadmus.c
new file mode 100644
index 0000000..50b6e9f
--- /dev/null
+++ b/board/freescale/common/cadmus.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2004, 2011 Freescale Semiconductor.
+ *
+ * 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>
+
+
+/*
+ * CADMUS Board System Registers
+ */
+#ifndef CONFIG_SYS_CADMUS_BASE_REG
+#define CONFIG_SYS_CADMUS_BASE_REG (CADMUS_BASE_ADDR + 0x4000)
+#endif
+
+typedef struct cadmus_reg {
+ u_char cm_ver; /* Board version */
+ u_char cm_csr; /* General control/status */
+ u_char cm_rst; /* Reset control */
+ u_char cm_hsclk; /* High speed clock */
+ u_char cm_hsxclk; /* High speed clock extended */
+ u_char cm_led; /* LED data */
+ u_char cm_pci; /* PCI control/status */
+ u_char cm_dma; /* DMA control */
+ u_char cm_reserved[248]; /* Total 256 bytes */
+} cadmus_reg_t;
+
+
+unsigned int
+get_board_version(void)
+{
+ volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
+
+ return cadmus->cm_ver;
+}
+
+
+unsigned long
+get_clock_freq(void)
+{
+ volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
+
+ uint pci1_speed = (cadmus->cm_pci >> 2) & 0x3; /* PSPEED in [4:5] */
+
+ if (pci1_speed == 0) {
+ return 33333333;
+ } else if (pci1_speed == 1) {
+ return 66666666;
+ } else {
+ /* Really, unknown. Be safe? */
+ return 33333333;
+ }
+}
+
+
+unsigned int
+get_pci_slot(void)
+{
+ volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
+
+ /*
+ * PCI slot in USER bits CSR[6:7] by convention.
+ */
+ return ((cadmus->cm_csr >> 6) & 0x3) + 1;
+}
+
+
+unsigned int
+get_pci_dual(void)
+{
+ volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
+
+ /*
+ * PCI DUAL in CM_PCI[3]
+ */
+ return cadmus->cm_pci & 0x10;
+}
diff --git a/board/freescale/common/cadmus.h b/board/freescale/common/cadmus.h
new file mode 100644
index 0000000..217ea64
--- /dev/null
+++ b/board/freescale/common/cadmus.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * 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 __CADMUS_H_
+#define __CADMUS_H_
+
+
+/*
+ * CADMUS Board System Register interface.
+ */
+
+/*
+ * Returns board version register.
+ */
+extern unsigned int get_board_version(void);
+
+/*
+ * Returns either 33000000 or 66000000 as the SYS_CLK_FREQ.
+ */
+extern unsigned long get_clock_freq(void);
+
+
+/*
+ * Returns 1 - 4, as found in the USER CSR[6:7] bits.
+ */
+extern unsigned int get_pci_slot(void);
+
+
+/*
+ * Returns PCI DUAL as found in CM_PCI[3].
+ */
+extern unsigned int get_pci_dual(void);
+
+
+#endif /* __CADMUS_H_ */
diff --git a/board/freescale/common/cds_pci_ft.c b/board/freescale/common/cds_pci_ft.c
new file mode 100644
index 0000000..32233db
--- /dev/null
+++ b/board/freescale/common/cds_pci_ft.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * 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 "cadmus.h"
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+static void cds_pci_fixup(void *blob)
+{
+ int node;
+ const char *path;
+ int len, slot, i;
+ u32 *map = NULL, *piccells = NULL;
+ int off, cells;
+
+ node = fdt_path_offset(blob, "/aliases");
+ if (node >= 0) {
+ path = fdt_getprop(blob, node, "pci0", NULL);
+ if (path) {
+ node = fdt_path_offset(blob, path);
+ if (node >= 0) {
+ map = fdt_getprop_w(blob, node, "interrupt-map", &len);
+ }
+ /* Each item in "interrupt-map" property is translated with
+ * following cells:
+ * PCI #address-cells, PCI #interrupt-cells,
+ * PIC address, PIC #address-cells, PIC #interrupt-cells.
+ */
+ cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
+ cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
+ off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
+ if (off <= 0)
+ return;
+ cells += 1;
+ piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
+ if (piccells == NULL)
+ return;
+ cells += *piccells;
+ piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
+ if (piccells == NULL)
+ return;
+ cells += *piccells;
+ }
+ }
+
+ if (map) {
+ len /= sizeof(u32);
+
+ slot = get_pci_slot();
+
+ for (i=0;i<len;i+=cells) {
+ /* We rotate the interrupt pins so that the mapping
+ * changes depending on the slot the carrier card is in.
+ */
+ map[3] = ((map[3] + slot - 2) % 4) + 1;
+ map+=cells;
+ }
+ }
+}
+
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ ft_cpu_setup(blob, bd);
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+ cds_pci_fixup(blob);
+#endif
+}
+#endif
diff --git a/board/freescale/common/cds_via.c b/board/freescale/common/cds_via.c
new file mode 100644
index 0000000..4a63d77
--- /dev/null
+++ b/board/freescale/common/cds_via.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2006 Freescale Semiconductor.
+ *
+ * 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 <pci.h>
+
+/* Config the VIA chip */
+void mpc85xx_config_via(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pci_dev_t bridge;
+ unsigned int cmdstat;
+
+ /* Enable USB and IDE functions */
+ pci_hose_write_config_byte(hose, dev, 0x48, 0x08);
+
+ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+ cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY| PCI_COMMAND_MASTER;
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+
+ /*
+ * Force the backplane P2P bridge to have a window
+ * open from 0x00000000-0x00001fff in PCI I/O space.
+ * This allows legacy I/O (i8259, etc) on the VIA
+ * southbridge to be accessed.
+ */
+ bridge = PCI_BDF(0,BRIDGE_ID,0);
+ pci_hose_write_config_byte(hose, bridge, PCI_IO_BASE, 0);
+ pci_hose_write_config_word(hose, bridge, PCI_IO_BASE_UPPER16, 0);
+ pci_hose_write_config_byte(hose, bridge, PCI_IO_LIMIT, 0x10);
+ pci_hose_write_config_word(hose, bridge, PCI_IO_LIMIT_UPPER16, 0);
+}
+
+/* Function 1, IDE */
+void mpc85xx_config_via_usbide(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pciauto_config_device(hose, dev);
+ /*
+ * Since the P2P window was forced to cover the fixed
+ * legacy I/O addresses, it is necessary to manually
+ * place the base addresses for the IDE and USB functions
+ * within this window.
+ */
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1ff8);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1ff4);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1fe8);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_3, 0x1fe4);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fd0);
+}
+
+/* Function 2, USB ports 0-1 */
+void mpc85xx_config_via_usb(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pciauto_config_device(hose, dev);
+
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fa0);
+}
+
+/* Function 3, USB ports 2-3 */
+void mpc85xx_config_via_usb2(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pciauto_config_device(hose, dev);
+
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1f80);
+}
+
+/* Function 5, Power Management */
+void mpc85xx_config_via_power(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pciauto_config_device(hose, dev);
+
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1e00);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1dfc);
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1df8);
+}
+
+/* Function 6, AC97 Interface */
+void mpc85xx_config_via_ac97(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *tab)
+{
+ pciauto_config_device(hose, dev);
+
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1c00);
+}
diff --git a/board/freescale/common/eeprom.h b/board/freescale/common/eeprom.h
new file mode 100644
index 0000000..12a0789
--- /dev/null
+++ b/board/freescale/common/eeprom.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * 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 __EEPROM_H_
+#define __EEPROM_H_
+
+
+/*
+ * EEPROM Board System Register interface.
+ */
+
+
+/*
+ * CPU Board Revision
+ */
+#define MPC85XX_CPU_BOARD_REV(maj, min) ((((maj)&0xff) << 8) | ((min) & 0xff))
+#define MPC85XX_CPU_BOARD_MAJOR(rev) (((rev) >> 8) & 0xff)
+#define MPC85XX_CPU_BOARD_MINOR(rev) ((rev) & 0xff)
+
+#define MPC85XX_CPU_BOARD_REV_UNKNOWN MPC85XX_CPU_BOARD_REV(0,0)
+#define MPC85XX_CPU_BOARD_REV_1_0 MPC85XX_CPU_BOARD_REV(1,0)
+#define MPC85XX_CPU_BOARD_REV_1_1 MPC85XX_CPU_BOARD_REV(1,1)
+
+/*
+ * Returns CPU board revision register as a 16-bit value with
+ * the Major in the high byte, and Minor in the low byte.
+ */
+extern unsigned int get_cpu_board_revision(void);
+
+
+#endif /* __CADMUS_H_ */
diff --git a/board/freescale/common/fman.c b/board/freescale/common/fman.c
new file mode 100644
index 0000000..3ef4936
--- /dev/null
+++ b/board/freescale/common/fman.c
@@ -0,0 +1,100 @@
+/*
+ * 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 <libfdt.h>
+#include <libfdt_env.h>
+#include <fdt_support.h>
+
+#include <fm_eth.h>
+#include <asm/fsl_serdes.h>
+
+/*
+ * Given the following ...
+ *
+ * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
+ * compatible string and 'addr' physical address)
+ *
+ * 2) The name of an alias that points to the ethernet-phy node (usually inside
+ * a virtual MDIO node)
+ *
+ * ... update that Ethernet node's phy-handle property to point to the
+ * ethernet-phy node. This is how we link an Ethernet node to its PHY, so each
+ * PHY in a virtual MDIO node must have an alias.
+ *
+ * Returns 0 on success, or a negative FDT error code on error.
+ */
+int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr,
+ const char *alias)
+{
+ int offset;
+ unsigned int ph;
+ const char *path;
+
+ /* Get a path to the node that 'alias' points to */
+ path = fdt_get_alias(fdt, alias);
+ if (!path)
+ return -FDT_ERR_BADPATH;
+
+ /* Get the offset of that node */
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ return offset;
+
+ ph = fdt_create_phandle(fdt, offset);
+ if (!ph)
+ return -FDT_ERR_BADPHANDLE;
+
+ offset = fdt_node_offset_by_compat_reg(fdt, compat, addr);
+ if (offset < 0)
+ return offset;
+
+ return fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph));
+}
+
+/*
+ * Return the SerDes device enum for a given Fman port
+ *
+ * This function just maps the fm_port namespace to the srds_prtcl namespace.
+ */
+enum srds_prtcl serdes_device_from_fm_port(enum fm_port port)
+{
+ static const enum srds_prtcl srds_table[] = {
+ [FM1_DTSEC1] = SGMII_FM1_DTSEC1,
+ [FM1_DTSEC2] = SGMII_FM1_DTSEC2,
+ [FM1_DTSEC3] = SGMII_FM1_DTSEC3,
+ [FM1_DTSEC4] = SGMII_FM1_DTSEC4,
+ [FM1_DTSEC5] = SGMII_FM1_DTSEC5,
+ [FM1_10GEC1] = XAUI_FM1,
+ [FM2_DTSEC1] = SGMII_FM2_DTSEC1,
+ [FM2_DTSEC2] = SGMII_FM2_DTSEC2,
+ [FM2_DTSEC3] = SGMII_FM2_DTSEC3,
+ [FM2_DTSEC4] = SGMII_FM2_DTSEC4,
+ [FM2_DTSEC5] = SGMII_FM2_DTSEC5,
+ [FM2_10GEC1] = XAUI_FM2,
+ };
+
+ if ((port < FM1_DTSEC1) || (port > FM2_10GEC1))
+ return NONE;
+ else
+ return srds_table[port];
+}
diff --git a/board/freescale/common/fman.h b/board/freescale/common/fman.h
new file mode 100644
index 0000000..734b1da
--- /dev/null
+++ b/board/freescale/common/fman.h
@@ -0,0 +1,28 @@
+/*
+ * 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 __FMAN_BOARD_HELPER__
+#define __FMAN_BOARD_HELPER__
+
+int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr,
+ const char *alias);
+
+enum srds_prtcl serdes_device_from_fm_port(enum fm_port port);
+
+#endif
diff --git a/board/freescale/common/ics307_clk.c b/board/freescale/common/ics307_clk.c
new file mode 100644
index 0000000..95a3cd7
--- /dev/null
+++ b/board/freescale/common/ics307_clk.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include "ics307_clk.h"
+
+#if defined(CONFIG_FSL_NGPIXIS)
+#include "ngpixis.h"
+#define fpga_reg pixis
+#elif defined(CONFIG_FSL_QIXIS)
+#include "qixis.h"
+#define fpga_reg ((struct qixis *)QIXIS_BASE)
+#else
+#include "pixis.h"
+#define fpga_reg pixis
+#endif
+
+/* define for SYS CLK or CLK1Frequency */
+#define TTL 1
+#define CLK2 0
+#define CRYSTAL 0
+#define MAX_VDW (511 + 8)
+#define MAX_RDW (127 + 2)
+#define MIN_VDW (4 + 8)
+#define MIN_RDW (1 + 2)
+#define NUM_OD_SETTING 8
+/*
+ * These defines cover the industrial temperature range part,
+ * for commercial, change below to 400000 and 55000, respectively
+ */
+#define MAX_VCO 360000
+#define MIN_VCO 60000
+
+/* decode S[0-2] to Output Divider (OD) */
+static u8 ics307_s_to_od[] = {
+ 10, 2, 8, 4, 5, 7, 3, 6
+};
+
+/*
+ * Find one solution to generate required frequency for SYSCLK
+ * out_freq: KHz, required frequency to the SYSCLK
+ * the result will be retuned with component RDW, VDW, OD, TTL,
+ * CLK2 and crystal
+ */
+unsigned long ics307_sysclk_calculator(unsigned long out_freq)
+{
+ const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
+ unsigned long vdw, rdw, odp, s_vdw = 0, s_rdw = 0, s_odp = 0, od;
+ unsigned long tmp_out, diff, result = 0;
+ int found = 0;
+
+ for (odp = 0; odp < NUM_OD_SETTING; odp++) {
+ od = ics307_s_to_od[odp];
+ if (od * out_freq < MIN_VCO || od * out_freq > MAX_VCO)
+ continue;
+ for (rdw = MIN_RDW; rdw <= MAX_RDW; rdw++) {
+ /* Calculate the VDW */
+ vdw = out_freq * 1000 * od * rdw / (input_freq * 2);
+ if (vdw > MAX_VDW)
+ vdw = MAX_VDW;
+ if (vdw < MIN_VDW)
+ continue;
+ /* Calculate the temp out frequency */
+ tmp_out = input_freq * 2 * vdw / (rdw * od * 1000);
+ diff = MAX(out_freq, tmp_out) - MIN(out_freq, tmp_out);
+ /*
+ * calculate the percent, the precision is 1/1000
+ * If greater than 1/1000, continue
+ * otherwise, we think the solution is we required
+ */
+ if (diff * 1000 / out_freq > 1)
+ continue;
+ else {
+ s_vdw = vdw;
+ s_rdw = rdw;
+ s_odp = odp;
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ result = (s_rdw - 2) | (s_vdw - 8) << 7 | s_odp << 16 |
+ CLK2 << 19 | TTL << 21 | CRYSTAL << 22;
+
+ debug("ICS307-02: RDW: %ld, VDW: %ld, OD: %d\n", s_rdw - 2, s_vdw - 8,
+ ics307_s_to_od[s_odp]);
+ return result;
+}
+
+/*
+ * Calculate frequency being generated by ICS307-02 clock chip based upon
+ * the control bytes being programmed into it.
+ */
+static unsigned long ics307_clk_freq(u8 cw0, u8 cw1, u8 cw2)
+{
+ const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
+ unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
+ unsigned long rdw = cw2 & 0x7F;
+ unsigned long od = ics307_s_to_od[cw0 & 0x7];
+ unsigned long freq;
+
+ /*
+ * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD)
+ *
+ * cw0: C1 C0 TTL F1 F0 S2 S1 S0
+ * cw1: V8 V7 V6 V5 V4 V3 V2 V1
+ * cw2: V0 R6 R5 R4 R3 R2 R1 R0
+ *
+ * R6:R0 = Reference Divider Word (RDW)
+ * V8:V0 = VCO Divider Word (VDW)
+ * S2:S0 = Output Divider Select (OD)
+ * F1:F0 = Function of CLK2 Output
+ * TTL = duty cycle
+ * C1:C0 = internal load capacitance for cyrstal
+ *
+ */
+
+ freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od);
+
+ debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2,
+ freq);
+ return freq;
+}
+
+unsigned long get_board_sys_clk(void)
+{
+ return ics307_clk_freq(
+ in_8(&fpga_reg->sclk[0]),
+ in_8(&fpga_reg->sclk[1]),
+ in_8(&fpga_reg->sclk[2]));
+}
+
+unsigned long get_board_ddr_clk(void)
+{
+ return ics307_clk_freq(
+ in_8(&fpga_reg->dclk[0]),
+ in_8(&fpga_reg->dclk[1]),
+ in_8(&fpga_reg->dclk[2]));
+}
diff --git a/board/freescale/common/ics307_clk.h b/board/freescale/common/ics307_clk.h
new file mode 100644
index 0000000..3757912
--- /dev/null
+++ b/board/freescale/common/ics307_clk.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-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
+ */
+#ifndef __ICS_CLK_H_
+#define __ICS_CLK_H_ 1
+
+#ifndef __ASSEMBLY__
+
+extern unsigned long get_board_sys_clk(void);
+extern unsigned long get_board_ddr_clk(void);
+extern unsigned long ics307_sysclk_calculator(unsigned long out_freq);
+#endif
+
+#endif /* __ICS_CLK_H_ */
diff --git a/board/freescale/common/ngpixis.c b/board/freescale/common/ngpixis.c
new file mode 100644
index 0000000..3c75028
--- /dev/null
+++ b/board/freescale/common/ngpixis.c
@@ -0,0 +1,253 @@
+/**
+ * Copyright 2010-2011 Freescale Semiconductor
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This file provides support for the ngPIXIS, a board-specific FPGA used on
+ * some Freescale reference boards.
+ *
+ * A "switch" is black rectangular block on the motherboard. It contains
+ * eight "bits". The ngPIXIS has a set of memory-mapped registers (SWx) that
+ * shadow the actual physical switches. There is also another set of
+ * registers (ENx) that tell the ngPIXIS which bits of SWx should actually be
+ * used to override the values of the bits in the physical switches.
+ *
+ * The following macros need to be defined:
+ *
+ * PIXIS_BASE - The virtual address of the base of the PIXIS register map
+ *
+ * PIXIS_LBMAP_SWITCH - The switch number (i.e. the "x" in "SWx"). This value
+ * is used in the PIXIS_SW() macro to determine which offset in
+ * the PIXIS register map corresponds to the physical switch that controls
+ * the boot bank.
+ *
+ * PIXIS_LBMAP_MASK - A bit mask the defines which bits in SWx to use.
+ *
+ * PIXIS_LBMAP_SHIFT - The shift value that corresponds to PIXIS_LBMAP_MASK.
+ *
+ * PIXIS_LBMAP_ALTBANK - The value to program into SWx to tell the ngPIXIS to
+ * boot from the alternate bank.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+
+#include "ngpixis.h"
+
+static u8 __pixis_read(unsigned int reg)
+{
+ void *p = (void *)PIXIS_BASE;
+
+ return in_8(p + reg);
+}
+u8 pixis_read(unsigned int reg) __attribute__((weak, alias("__pixis_read")));
+
+static void __pixis_write(unsigned int reg, u8 value)
+{
+ void *p = (void *)PIXIS_BASE;
+
+ out_8(p + reg, value);
+}
+void pixis_write(unsigned int reg, u8 value)
+ __attribute__((weak, alias("__pixis_write")));
+
+/*
+ * Reset the board. This ignores the ENx registers.
+ */
+void __pixis_reset(void)
+{
+ PIXIS_WRITE(rst, 0);
+
+ while (1);
+}
+void pixis_reset(void) __attribute__((weak, alias("__pixis_reset")));
+
+/*
+ * Reset the board. Like pixis_reset(), but it honors the ENx registers.
+ */
+void __pixis_bank_reset(void)
+{
+ PIXIS_WRITE(vctl, 0);
+ PIXIS_WRITE(vctl, 1);
+
+ while (1);
+}
+void pixis_bank_reset(void) __attribute__((weak, alias("__pixis_bank_reset")));
+
+/**
+ * Set the boot bank to the power-on default bank
+ */
+void __clear_altbank(void)
+{
+ u8 reg;
+
+ /* Tell the ngPIXIS to use this the bits in the physical switch for the
+ * boot bank value, instead of the SWx register. We need to be careful
+ * only to set the bits in SWx that correspond to the boot bank.
+ */
+ reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en);
+ reg &= ~PIXIS_LBMAP_MASK;
+ PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg);
+}
+void clear_altbank(void) __attribute__((weak, alias("__clear_altbank")));
+
+/**
+ * Set the boot bank to the alternate bank
+ */
+void __set_altbank(void)
+{
+ u8 reg;
+
+ /* Program the alternate bank number into the SWx register.
+ */
+ reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].sw);
+ reg = (reg & ~PIXIS_LBMAP_MASK) | PIXIS_LBMAP_ALTBANK;
+ PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].sw, reg);
+
+ /* Tell the ngPIXIS to use this the bits in the SWx register for the
+ * boot bank value, instead of the physical switch. We need to be
+ * careful only to set the bits in SWx that correspond to the boot bank.
+ */
+ reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en);
+ reg |= PIXIS_LBMAP_MASK;
+ PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg);
+}
+void set_altbank(void) __attribute__((weak, alias("__set_altbank")));
+
+#ifdef DEBUG
+static void pixis_dump_regs(void)
+{
+ unsigned int i;
+
+ printf("id=%02x\n", PIXIS_READ(id));
+ printf("arch=%02x\n", PIXIS_READ(arch));
+ printf("scver=%02x\n", PIXIS_READ(scver));
+ printf("csr=%02x\n", PIXIS_READ(csr));
+ printf("rst=%02x\n", PIXIS_READ(rst));
+ printf("aux=%02x\n", PIXIS_READ(aux));
+ printf("spd=%02x\n", PIXIS_READ(spd));
+ printf("brdcfg0=%02x\n", PIXIS_READ(brdcfg0));
+ printf("brdcfg1=%02x\n", PIXIS_READ(brdcfg1));
+ printf("addr=%02x\n", PIXIS_READ(addr));
+ printf("data=%02x\n", PIXIS_READ(data));
+ printf("led=%02x\n", PIXIS_READ(led));
+ printf("vctl=%02x\n", PIXIS_READ(vctl));
+ printf("vstat=%02x\n", PIXIS_READ(vstat));
+ printf("vcfgen0=%02x\n", PIXIS_READ(vcfgen0));
+ printf("ocmcsr=%02x\n", PIXIS_READ(ocmcsr));
+ printf("ocmmsg=%02x\n", PIXIS_READ(ocmmsg));
+ printf("gmdbg=%02x\n", PIXIS_READ(gmdbg));
+ printf("sclk=%02x%02x%02x\n",
+ PIXIS_READ(sclk[0]), PIXIS_READ(sclk[1]), PIXIS_READ(sclk[2]));
+ printf("dclk=%02x%02x%02x\n",
+ PIXIS_READ(dclk[0]), PIXIS_READ(dclk[1]), PIXIS_READ(dclk[2]));
+ printf("watch=%02x\n", PIXIS_READ(watch));
+
+ for (i = 0; i < 8; i++) {
+ printf("SW%u=%02x/%02x ", i + 1,
+ PIXIS_READ(s[i].sw), PIXIS_READ(s[i].en));
+ }
+ putc('\n');
+}
+#endif
+
+void pixis_sysclk_set(unsigned long sysclk)
+{
+ unsigned long freq_word;
+ u8 sclk0, sclk1, sclk2;
+
+ freq_word = ics307_sysclk_calculator(sysclk);
+ sclk2 = freq_word & 0xff;
+ sclk1 = (freq_word >> 8) & 0xff;
+ sclk0 = (freq_word >> 16) & 0xff;
+
+ /* set SYSCLK enable bit */
+ PIXIS_WRITE(vcfgen0, 0x01);
+
+ /* SYSCLK to required frequency */
+ PIXIS_WRITE(sclk[0], sclk0);
+ PIXIS_WRITE(sclk[1], sclk1);
+ PIXIS_WRITE(sclk[2], sclk2);
+}
+
+int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned int i;
+ unsigned long sysclk;
+ char *p_altbank = NULL;
+#ifdef DEBUG
+ char *p_dump = NULL;
+#endif
+ char *unknown_param = NULL;
+
+ /* No args is a simple reset request.
+ */
+ if (argc <= 1)
+ pixis_reset();
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "altbank") == 0) {
+ p_altbank = argv[i];
+ continue;
+ }
+
+#ifdef DEBUG
+ if (strcmp(argv[i], "dump") == 0) {
+ p_dump = argv[i];
+ continue;
+ }
+#endif
+ if (strcmp(argv[i], "sysclk") == 0) {
+ sysclk = simple_strtoul(argv[i + 1], NULL, 0);
+ i += 1;
+ pixis_sysclk_set(sysclk);
+ continue;
+ }
+
+ unknown_param = argv[i];
+ }
+
+ if (unknown_param) {
+ printf("Invalid option: %s\n", unknown_param);
+ return 1;
+ }
+
+#ifdef DEBUG
+ if (p_dump) {
+ pixis_dump_regs();
+
+ /* 'dump' ignores other commands */
+ return 0;
+ }
+#endif
+
+ if (p_altbank)
+ set_altbank();
+ else
+ clear_altbank();
+
+ pixis_bank_reset();
+
+ /* Shouldn't be reached. */
+ return 0;
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char pixis_help_text[] =
+ "- hard reset to default bank\n"
+ "pixis_reset altbank - reset to alternate bank\n"
+#ifdef DEBUG
+ "pixis_reset dump - display the PIXIS registers\n"
+#endif
+ "pixis_reset sysclk <SYSCLK_freq> - reset with SYSCLK frequency(KHz)\n";
+#endif
+
+U_BOOT_CMD(
+ pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
+ "Reset the board using the FPGA sequencer", pixis_help_text
+ );
diff --git a/board/freescale/common/ngpixis.h b/board/freescale/common/ngpixis.h
new file mode 100644
index 0000000..a239ee3
--- /dev/null
+++ b/board/freescale/common/ngpixis.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2010-2011 Freescale Semiconductor
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This file provides support for the ngPIXIS, a board-specific FPGA used on
+ * some Freescale reference boards.
+ */
+
+/* ngPIXIS register set. Hopefully, this won't change too much over time.
+ * Feel free to add board-specific #ifdefs where necessary.
+ */
+typedef struct ngpixis {
+ u8 id;
+ u8 arch;
+ u8 scver;
+ u8 csr;
+ u8 rst;
+ u8 serclk;
+ u8 aux;
+ u8 spd;
+ u8 brdcfg0;
+ u8 brdcfg1; /* On some boards, this register is called 'dma' */
+ u8 addr;
+ u8 brdcfg2;
+ u8 gpiodir;
+ u8 data;
+ u8 led;
+ u8 tag;
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 res4;
+ u8 ocmcsr;
+ u8 ocmmsg;
+ u8 gmdbg;
+ u8 res5[2];
+ u8 sclk[3];
+ u8 dclk[3];
+ u8 watch;
+ struct {
+ u8 sw;
+ u8 en;
+ } s[9]; /* s[0]..s[7] is SW1..SW8, and s[8] is SW11 */
+} __attribute__ ((packed)) ngpixis_t;
+
+/* Pointer to the PIXIS register set */
+#define pixis ((ngpixis_t *)PIXIS_BASE)
+
+/* The PIXIS SW register that corresponds to board switch X, where x >= 1 */
+#define PIXIS_SW(x) (pixis->s[(x) - 1].sw)
+
+/* The PIXIS EN register that corresponds to board switch X, where x >= 1 */
+#define PIXIS_EN(x) (pixis->s[(x) - 1].en)
+
+u8 pixis_read(unsigned int reg);
+void pixis_write(unsigned int reg, u8 value);
+
+#define PIXIS_READ(reg) pixis_read(offsetof(ngpixis_t, reg))
+#define PIXIS_WRITE(reg, value) pixis_write(offsetof(ngpixis_t, reg), value)
diff --git a/board/freescale/common/p_corenet/Makefile b/board/freescale/common/p_corenet/Makefile
new file mode 100644
index 0000000..a76f590
--- /dev/null
+++ b/board/freescale/common/p_corenet/Makefile
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2002-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 = libp_corenet.o
+
+COBJS-y += law.o
+COBJS-$(CONFIG_PCI) += pci.o
+COBJS-y += tlb.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/board/freescale/common/p_corenet/law.c b/board/freescale/common/p_corenet/law.c
new file mode 100644
index 0000000..09ef561
--- /dev/null
+++ b/board/freescale/common/p_corenet/law.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_law.h>
+#include <asm/mmu.h>
+
+struct law_entry law_table[] = {
+ SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
+#ifdef CONFIG_SYS_BMAN_MEM_PHYS
+ SET_LAW(CONFIG_SYS_BMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_BMAN),
+#endif
+#ifdef CONFIG_SYS_QMAN_MEM_PHYS
+ SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_QMAN),
+#endif
+#ifdef PIXIS_BASE_PHYS
+ SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
+#endif
+#ifdef CPLD_BASE_PHYS
+ SET_LAW(CPLD_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
+#endif
+#ifdef CONFIG_SYS_DCSRBAR_PHYS
+ /* Limit DCSR to 32M to access NPC Trace Buffer */
+ SET_LAW(CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_DCSR),
+#endif
+#ifdef CONFIG_SYS_NAND_BASE_PHYS
+ SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC),
+#endif
+};
+
+int num_law_entries = ARRAY_SIZE(law_table);
diff --git a/board/freescale/common/p_corenet/pci.c b/board/freescale/common/p_corenet/pci.c
new file mode 100644
index 0000000..18a75de
--- /dev/null
+++ b/board/freescale/common/p_corenet/pci.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007-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 <pci.h>
+#include <asm/fsl_pci.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <asm/fsl_serdes.h>
+
+void pci_init_board(void)
+{
+ fsl_pcie_init_board(0);
+}
+
+void pci_of_setup(void *blob, bd_t *bd)
+{
+ FT_FSL_PCI_SETUP;
+}
diff --git a/board/freescale/common/p_corenet/tlb.c b/board/freescale/common/p_corenet/tlb.c
new file mode 100644
index 0000000..e5cf208
--- /dev/null
+++ b/board/freescale/common/p_corenet/tlb.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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/mmu.h>
+
+struct fsl_e_tlb_entry tlb_table[] = {
+ /* TLB 0 - for temp stack in cache */
+ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR,
+ CONFIG_SYS_INIT_RAM_ADDR_PHYS,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024,
+ CONFIG_SYS_INIT_RAM_ADDR_PHYS + 4 * 1024,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024,
+ CONFIG_SYS_INIT_RAM_ADDR_PHYS + 8 * 1024,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024,
+ CONFIG_SYS_INIT_RAM_ADDR_PHYS + 12 * 1024,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+#ifdef CPLD_BASE
+ SET_TLB_ENTRY(0, CPLD_BASE, CPLD_BASE_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+#endif
+
+#ifdef PIXIS_BASE
+ SET_TLB_ENTRY(0, PIXIS_BASE, PIXIS_BASE_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_4K, 0),
+#endif
+
+ /* TLB 1 */
+ /* *I*** - Covers boot page */
+#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR)
+ /*
+ * *I*G - L3SRAM. When L3 is used as 1M SRAM, the address of the
+ * SRAM is at 0xfff00000, it covered the 0xfffff000.
+ */
+ SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_1M, 1),
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+ /*
+ * SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
+ * space is at 0xfff00000, it covered the 0xfffff000.
+ */
+ SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR,
+ CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_1M, 1),
+#else
+ SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_4K, 1),
+#endif
+
+ /* *I*G* - CCSRBAR */
+ SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 1, BOOKE_PAGESZ_16M, 1),
+
+ /* *I*G* - Flash, localbus */
+ /* This will be changed to *I*G* after relocation to RAM. */
+ SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
+ MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
+ 0, 2, BOOKE_PAGESZ_256M, 1),
+
+ /* *I*G* - PCI */
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 3, BOOKE_PAGESZ_1G, 1),
+
+ /* *I*G* - PCI */
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x40000000,
+ CONFIG_SYS_PCIE1_MEM_PHYS + 0x40000000,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 4, BOOKE_PAGESZ_256M, 1),
+
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x50000000,
+ CONFIG_SYS_PCIE1_MEM_PHYS + 0x50000000,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 5, BOOKE_PAGESZ_256M, 1),
+
+ /* *I*G* - PCI I/O */
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 6, BOOKE_PAGESZ_256K, 1),
+
+ /* Bman/Qman */
+#ifdef CONFIG_SYS_BMAN_MEM_PHYS
+ SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE, CONFIG_SYS_BMAN_MEM_PHYS,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 9, BOOKE_PAGESZ_1M, 1),
+ SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x00100000,
+ CONFIG_SYS_BMAN_MEM_PHYS + 0x00100000,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 10, BOOKE_PAGESZ_1M, 1),
+#endif
+#ifdef CONFIG_SYS_QMAN_MEM_PHYS
+ SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS,
+ MAS3_SW|MAS3_SR, 0,
+ 0, 11, BOOKE_PAGESZ_1M, 1),
+ SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x00100000,
+ CONFIG_SYS_QMAN_MEM_PHYS + 0x00100000,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 12, BOOKE_PAGESZ_1M, 1),
+#endif
+#ifdef CONFIG_SYS_DCSRBAR_PHYS
+ SET_TLB_ENTRY(1, CONFIG_SYS_DCSRBAR, CONFIG_SYS_DCSRBAR_PHYS,
+ MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 13, BOOKE_PAGESZ_4M, 1),
+#endif
+#ifdef CONFIG_SYS_NAND_BASE
+ /*
+ * *I*G - NAND
+ * entry 14 and 15 has been used hard coded, they will be disabled
+ * in cpu_init_f, so we use entry 16 for nand.
+ */
+ SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 16, BOOKE_PAGESZ_1M, 1),
+#endif
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+ /*
+ * SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for
+ * fetching ucode and ENV from master
+ */
+ SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR,
+ CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
+ 0, 17, BOOKE_PAGESZ_1M, 1),
+#endif
+};
+
+int num_tlb_entries = ARRAY_SIZE(tlb_table);
diff --git a/board/freescale/common/pixis.c b/board/freescale/common/pixis.c
new file mode 100644
index 0000000..fbb709d
--- /dev/null
+++ b/board/freescale/common/pixis.c
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2006,2010 Freescale Semiconductor
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 <asm/io.h>
+
+#define pixis_base (u8 *)PIXIS_BASE
+
+/*
+ * Simple board reset.
+ */
+void pixis_reset(void)
+{
+ out_8(pixis_base + PIXIS_RST, 0);
+
+ while (1);
+}
+
+/*
+ * Per table 27, page 58 of MPC8641HPCN spec.
+ */
+static int set_px_sysclk(unsigned long sysclk)
+{
+ u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
+
+ switch (sysclk) {
+ case 33:
+ sysclk_s = 0x04;
+ sysclk_r = 0x04;
+ sysclk_v = 0x07;
+ sysclk_aux = 0x00;
+ break;
+ case 40:
+ sysclk_s = 0x01;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x20;
+ sysclk_aux = 0x01;
+ break;
+ case 50:
+ sysclk_s = 0x01;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x2A;
+ sysclk_aux = 0x02;
+ break;
+ case 66:
+ sysclk_s = 0x01;
+ sysclk_r = 0x04;
+ sysclk_v = 0x04;
+ sysclk_aux = 0x03;
+ break;
+ case 83:
+ sysclk_s = 0x01;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x4B;
+ sysclk_aux = 0x04;
+ break;
+ case 100:
+ sysclk_s = 0x01;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x5C;
+ sysclk_aux = 0x05;
+ break;
+ case 134:
+ sysclk_s = 0x06;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x3B;
+ sysclk_aux = 0x06;
+ break;
+ case 166:
+ sysclk_s = 0x06;
+ sysclk_r = 0x1F;
+ sysclk_v = 0x4B;
+ sysclk_aux = 0x07;
+ break;
+ default:
+ printf("Unsupported SYSCLK frequency.\n");
+ return 0;
+ }
+
+ vclkh = (sysclk_s << 5) | sysclk_r;
+ vclkl = sysclk_v;
+
+ out_8(pixis_base + PIXIS_VCLKH, vclkh);
+ out_8(pixis_base + PIXIS_VCLKL, vclkl);
+
+ out_8(pixis_base + PIXIS_AUX, sysclk_aux);
+
+ return 1;
+}
+
+/* Set the CFG_SYSPLL bits
+ *
+ * This only has effect if PX_VCFGEN0[SYSPLL]=1, which is true if
+ * read_from_px_regs() is called.
+ */
+static int set_px_mpxpll(unsigned long mpxpll)
+{
+ switch (mpxpll) {
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ case 16:
+ clrsetbits_8(pixis_base + PIXIS_VSPEED1, 0x1F, mpxpll);
+ return 1;
+ }
+
+ printf("Unsupported MPXPLL ratio.\n");
+ return 0;
+}
+
+static int set_px_corepll(unsigned long corepll)
+{
+ u8 val;
+
+ switch (corepll) {
+ case 20:
+ val = 0x08;
+ break;
+ case 25:
+ val = 0x0C;
+ break;
+ case 30:
+ val = 0x10;
+ break;
+ case 35:
+ val = 0x1C;
+ break;
+ case 40:
+ val = 0x14;
+ break;
+ case 45:
+ val = 0x0E;
+ break;
+ default:
+ printf("Unsupported COREPLL ratio.\n");
+ return 0;
+ }
+
+ clrsetbits_8(pixis_base + PIXIS_VSPEED0, 0x1F, val);
+ return 1;
+}
+
+#ifndef CONFIG_SYS_PIXIS_VCFGEN0_ENABLE
+#define CONFIG_SYS_PIXIS_VCFGEN0_ENABLE 0x1C
+#endif
+
+/* Tell the PIXIS where to find the COREPLL, MPXPLL, SYSCLK values
+ *
+ * The PIXIS can be programmed to look at either the on-board dip switches
+ * or various other PIXIS registers to determine the values for COREPLL,
+ * MPXPLL, and SYSCLK.
+ *
+ * CONFIG_SYS_PIXIS_VCFGEN0_ENABLE is the value to write to the PIXIS_VCFGEN0
+ * register that tells the pixis to use the various PIXIS register.
+ */
+static void read_from_px_regs(int set)
+{
+ u8 tmp = in_8(pixis_base + PIXIS_VCFGEN0);
+
+ if (set)
+ tmp = tmp | CONFIG_SYS_PIXIS_VCFGEN0_ENABLE;
+ else
+ tmp = tmp & ~CONFIG_SYS_PIXIS_VCFGEN0_ENABLE;
+
+ out_8(pixis_base + PIXIS_VCFGEN0, tmp);
+}
+
+/* CONFIG_SYS_PIXIS_VBOOT_ENABLE is the value to write to the PX_VCFGEN1
+ * register that tells the pixis to use the PX_VBOOT[LBMAP] register.
+ */
+#ifndef CONFIG_SYS_PIXIS_VBOOT_ENABLE
+#define CONFIG_SYS_PIXIS_VBOOT_ENABLE 0x04
+#endif
+
+/* Configure the source of the boot location
+ *
+ * The PIXIS can be programmed to look at either the on-board dip switches
+ * or the PX_VBOOT[LBMAP] register to determine where we should boot.
+ *
+ * If we want to boot from the alternate boot bank, we need to tell the PIXIS
+ * to ignore the on-board dip switches and use the PX_VBOOT[LBMAP] instead.
+ */
+static void read_from_px_regs_altbank(int set)
+{
+ u8 tmp = in_8(pixis_base + PIXIS_VCFGEN1);
+
+ if (set)
+ tmp = tmp | CONFIG_SYS_PIXIS_VBOOT_ENABLE;
+ else
+ tmp = tmp & ~CONFIG_SYS_PIXIS_VBOOT_ENABLE;
+
+ out_8(pixis_base + PIXIS_VCFGEN1, tmp);
+}
+
+/* CONFIG_SYS_PIXIS_VBOOT_MASK contains the bits to set in VBOOT register that
+ * tells the PIXIS what the alternate flash bank is.
+ *
+ * Note that it's not really a mask. It contains the actual LBMAP bits that
+ * must be set to select the alternate bank. This code assumes that the
+ * primary bank has these bits set to 0, and the alternate bank has these
+ * bits set to 1.
+ */
+#ifndef CONFIG_SYS_PIXIS_VBOOT_MASK
+#define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40)
+#endif
+
+/* Tell the PIXIS to boot from the default flash bank
+ *
+ * Program the default flash bank into the VBOOT register. This register is
+ * used only if PX_VCFGEN1[FLASH]=1.
+ */
+static void clear_altbank(void)
+{
+ clrbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK);
+}
+
+/* Tell the PIXIS to boot from the alternate flash bank
+ *
+ * Program the alternate flash bank into the VBOOT register. This register is
+ * used only if PX_VCFGEN1[FLASH]=1.
+ */
+static void set_altbank(void)
+{
+ setbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK);
+}
+
+/* Reset the board with watchdog disabled.
+ *
+ * This respects the altbank setting.
+ */
+static void set_px_go(void)
+{
+ /* Disable the VELA sequencer and watchdog */
+ clrbits_8(pixis_base + PIXIS_VCTL, 9);
+
+ /* Reboot by starting the VELA sequencer */
+ setbits_8(pixis_base + PIXIS_VCTL, 0x1);
+
+ while (1);
+}
+
+/* Reset the board with watchdog enabled.
+ *
+ * This respects the altbank setting.
+ */
+static void set_px_go_with_watchdog(void)
+{
+ /* Disable the VELA sequencer */
+ clrbits_8(pixis_base + PIXIS_VCTL, 1);
+
+ /* Enable the watchdog and reboot by starting the VELA sequencer */
+ setbits_8(pixis_base + PIXIS_VCTL, 0x9);
+
+ while (1);
+}
+
+/* Disable the watchdog
+ *
+ */
+static int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ /* Disable the VELA sequencer and the watchdog */
+ clrbits_8(pixis_base + PIXIS_VCTL, 9);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ diswd, 1, 0, pixis_disable_watchdog_cmd,
+ "Disable watchdog timer",
+ ""
+);
+
+#ifdef CONFIG_PIXIS_SGMII_CMD
+
+/* Enable or disable SGMII mode for a TSEC
+ */
+static int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int which_tsec = -1;
+ unsigned char mask;
+ unsigned char switch_mask;
+
+ if ((argc > 2) && (strcmp(argv[1], "all") != 0))
+ which_tsec = simple_strtoul(argv[1], NULL, 0);
+
+ switch (which_tsec) {
+#ifdef CONFIG_TSEC1
+ case 1:
+ mask = PIXIS_VSPEED2_TSEC1SER;
+ switch_mask = PIXIS_VCFGEN1_TSEC1SER;
+ break;
+#endif
+#ifdef CONFIG_TSEC2
+ case 2:
+ mask = PIXIS_VSPEED2_TSEC2SER;
+ switch_mask = PIXIS_VCFGEN1_TSEC2SER;
+ break;
+#endif
+#ifdef CONFIG_TSEC3
+ case 3:
+ mask = PIXIS_VSPEED2_TSEC3SER;
+ switch_mask = PIXIS_VCFGEN1_TSEC3SER;
+ break;
+#endif
+#ifdef CONFIG_TSEC4
+ case 4:
+ mask = PIXIS_VSPEED2_TSEC4SER;
+ switch_mask = PIXIS_VCFGEN1_TSEC4SER;
+ break;
+#endif
+ default:
+ mask = PIXIS_VSPEED2_MASK;
+ switch_mask = PIXIS_VCFGEN1_MASK;
+ break;
+ }
+
+ /* Toggle whether the switches or FPGA control the settings */
+ if (!strcmp(argv[argc - 1], "switch"))
+ clrbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
+ else
+ setbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
+
+ /* If it's not the switches, enable or disable SGMII, as specified */
+ if (!strcmp(argv[argc - 1], "on"))
+ clrbits_8(pixis_base + PIXIS_VSPEED2, mask);
+ else if (!strcmp(argv[argc - 1], "off"))
+ setbits_8(pixis_base + PIXIS_VSPEED2, mask);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, pixis_set_sgmii,
+ "pixis_set_sgmii"
+ " - Enable or disable SGMII mode for a given TSEC \n",
+ "\npixis_set_sgmii [TSEC num] <on|off|switch>\n"
+ " TSEC num: 1,2,3,4 or 'all'. 'all' is default.\n"
+ " on - enables SGMII\n"
+ " off - disables SGMII\n"
+ " switch - use switch settings"
+);
+
+#endif
+
+/*
+ * This function takes the non-integral cpu:mpx pll ratio
+ * and converts it to an integer that can be used to assign
+ * FPGA register values.
+ * input: strptr i.e. argv[2]
+ */
+static unsigned long strfractoint(char *strptr)
+{
+ int i, j;
+ int mulconst;
+ int no_dec = 0;
+ unsigned long intval = 0, decval = 0;
+ char intarr[3], decarr[3];
+
+ /* Assign the integer part to intarr[]
+ * If there is no decimal point i.e.
+ * if the ratio is an integral value
+ * simply create the intarr.
+ */
+ i = 0;
+ while (strptr[i] != '.') {
+ if (strptr[i] == 0) {
+ no_dec = 1;
+ break;
+ }
+ intarr[i] = strptr[i];
+ i++;
+ }
+
+ intarr[i] = '\0';
+
+ if (no_dec) {
+ /* Currently needed only for single digit corepll ratios */
+ mulconst = 10;
+ decval = 0;
+ } else {
+ j = 0;
+ i++; /* Skipping the decimal point */
+ while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
+ decarr[j] = strptr[i];
+ i++;
+ j++;
+ }
+
+ decarr[j] = '\0';
+
+ mulconst = 1;
+ for (i = 0; i < j; i++)
+ mulconst *= 10;
+ decval = simple_strtoul(decarr, NULL, 10);
+ }
+
+ intval = simple_strtoul(intarr, NULL, 10);
+ intval = intval * mulconst;
+
+ return intval + decval;
+}
+
+static int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned int i;
+ char *p_cf = NULL;
+ char *p_cf_sysclk = NULL;
+ char *p_cf_corepll = NULL;
+ char *p_cf_mpxpll = NULL;
+ char *p_altbank = NULL;
+ char *p_wd = NULL;
+ int unknown_param = 0;
+
+ /*
+ * No args is a simple reset request.
+ */
+ if (argc <= 1) {
+ pixis_reset();
+ /* not reached */
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "cf") == 0) {
+ p_cf = argv[i];
+ if (i + 3 >= argc) {
+ break;
+ }
+ p_cf_sysclk = argv[i+1];
+ p_cf_corepll = argv[i+2];
+ p_cf_mpxpll = argv[i+3];
+ i += 3;
+ continue;
+ }
+
+ if (strcmp(argv[i], "altbank") == 0) {
+ p_altbank = argv[i];
+ continue;
+ }
+
+ if (strcmp(argv[i], "wd") == 0) {
+ p_wd = argv[i];
+ continue;
+ }
+
+ unknown_param = 1;
+ }
+
+ /*
+ * Check that cf has all required parms
+ */
+ if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
+ || unknown_param) {
+#ifdef CONFIG_SYS_LONGHELP
+ puts(cmdtp->help);
+ putc('\n');
+#endif
+ return 1;
+ }
+
+ /*
+ * PIXIS seems to be sensitive to the ordering of
+ * the registers that are touched.
+ */
+ read_from_px_regs(0);
+
+ if (p_altbank)
+ read_from_px_regs_altbank(0);
+
+ clear_altbank();
+
+ /*
+ * Clock configuration specified.
+ */
+ if (p_cf) {
+ unsigned long sysclk;
+ unsigned long corepll;
+ unsigned long mpxpll;
+
+ sysclk = simple_strtoul(p_cf_sysclk, NULL, 10);
+ corepll = strfractoint(p_cf_corepll);
+ mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10);
+
+ if (!(set_px_sysclk(sysclk)
+ && set_px_corepll(corepll)
+ && set_px_mpxpll(mpxpll))) {
+#ifdef CONFIG_SYS_LONGHELP
+ puts(cmdtp->help);
+ putc('\n');
+#endif
+ return 1;
+ }
+ read_from_px_regs(1);
+ }
+
+ /*
+ * Altbank specified
+ *
+ * NOTE CHANGE IN BEHAVIOR: previous code would default
+ * to enabling watchdog if altbank is specified.
+ * Now the watchdog must be enabled explicitly using 'wd'.
+ */
+ if (p_altbank) {
+ set_altbank();
+ read_from_px_regs_altbank(1);
+ }
+
+ /*
+ * Reset with watchdog specified.
+ */
+ if (p_wd)
+ set_px_go_with_watchdog();
+ else
+ set_px_go();
+
+ /*
+ * Shouldn't be reached.
+ */
+ return 0;
+}
+
+
+U_BOOT_CMD(
+ pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
+ "Reset the board using the FPGA sequencer",
+ " pixis_reset\n"
+ " pixis_reset [altbank]\n"
+ " pixis_reset altbank wd\n"
+ " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
+ " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>"
+);
diff --git a/board/freescale/common/pixis.h b/board/freescale/common/pixis.h
new file mode 100644
index 0000000..7f86de7
--- /dev/null
+++ b/board/freescale/common/pixis.h
@@ -0,0 +1,182 @@
+/*
+ * 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 __PIXIS_H_
+#define __PIXIS_H_ 1
+
+/* PIXIS register set. */
+#if defined(CONFIG_MPC8536DS)
+typedef struct pixis {
+ u8 id;
+ u8 ver;
+ u8 pver;
+ u8 csr;
+ u8 rst;
+ u8 rst2;
+ u8 aux1;
+ u8 spd;
+ u8 aux2;
+ u8 csr2;
+ u8 watch;
+ u8 led;
+ u8 pwr;
+ u8 res[3];
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 vcfgen1;
+ u8 vcore0;
+ u8 res1;
+ u8 vboot;
+ u8 vspeed[3];
+ u8 sclk[3];
+ u8 dclk[3];
+ u8 i2cdacr;
+ u8 vcoreacc[4];
+ u8 vcorecnt[3];
+ u8 vcoremax[2];
+ u8 vplatacc[4];
+ u8 vplatcnt[3];
+ u8 vplatmax[2];
+ u8 vtempacc[4];
+ u8 vtempcnt[3];
+ u8 vtempmax[2];
+ u8 res2[4];
+} __attribute__ ((packed)) pixis_t;
+
+#elif defined(CONFIG_MPC8544DS)
+typedef struct pixis {
+ u8 id;
+ u8 ver;
+ u8 pver;
+ u8 csr;
+ u8 rst;
+ u8 pwr;
+ u8 aux1;
+ u8 spd;
+ u8 res[8];
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 vcfgen1;
+ u8 vcore0;
+ u8 res1;
+ u8 vboot;
+ u8 vspeed[2];
+ u8 vclkh;
+ u8 vclkl;
+ u8 watch;
+ u8 led;
+ u8 vspeed2;
+ u8 res2[34];
+} __attribute__ ((packed)) pixis_t;
+
+#elif defined(CONFIG_MPC8572DS)
+typedef struct pixis {
+ u8 id;
+ u8 ver;
+ u8 pver;
+ u8 csr;
+ u8 rst;
+ u8 pwr1;
+ u8 aux1;
+ u8 spd;
+ u8 aux2;
+ u8 res[7];
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 vcfgen1;
+ u8 vcore0;
+ u8 res1;
+ u8 vboot;
+ u8 vspeed[3];
+ u8 res2[2];
+ u8 sclk[3];
+ u8 dclk[3];
+ u8 res3[2];
+ u8 watch;
+ u8 led;
+ u8 res4[25];
+} __attribute__ ((packed)) pixis_t;
+
+#elif defined(CONFIG_MPC8610HPCD)
+typedef struct pixis {
+ u8 id;
+ u8 ver; /* also called arch */
+ u8 pver;
+ u8 csr;
+ u8 rst;
+ u8 pwr;
+ u8 aux;
+ u8 spd;
+ u8 brdcfg0;
+ u8 brdcfg1;
+ u8 res[4];
+ u8 led;
+ u8 serno;
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 vcfgen1;
+ u8 vcore0;
+ u8 res1;
+ u8 vboot;
+ u8 vspeed[2];
+ u8 res2;
+ u8 sclk[3];
+ u8 res3;
+ u8 watch;
+ u8 res4[33];
+} __attribute__ ((packed)) pixis_t;
+
+#elif defined(CONFIG_MPC8641HPCN)
+typedef struct pixis {
+ u8 id;
+ u8 ver;
+ u8 pver;
+ u8 csr;
+ u8 rst;
+ u8 pwr;
+ u8 aux;
+ u8 spd;
+ u8 res[8];
+ u8 vctl;
+ u8 vstat;
+ u8 vcfgen0;
+ u8 vcfgen1;
+ u8 vcore0;
+ u8 res1;
+ u8 vboot;
+ u8 vspeed[2];
+ u8 vclkh;
+ u8 vclkl;
+ u8 watch;
+ u8 res3[36];
+} __attribute__ ((packed)) pixis_t;
+#else
+#error Need to define pixis_t for this board
+#endif
+
+/* Pointer to the PIXIS register set */
+#define pixis ((pixis_t *)PIXIS_BASE)
+
+#endif /* __PIXIS_H_ */
diff --git a/board/freescale/common/pq-mds-pib.c b/board/freescale/common/pq-mds-pib.c
new file mode 100644
index 0000000..5f7a67d
--- /dev/null
+++ b/board/freescale/common/pq-mds-pib.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ *
+ * Tony Li <tony.li@freescale.com>
+ *
+ * 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 <asm/io.h>
+
+#include "pq-mds-pib.h"
+
+int pib_init(void)
+{
+ u8 val8;
+ u8 orig_i2c_bus;
+
+ /* Switch temporarily to I2C bus #2 */
+ orig_i2c_bus = i2c_get_bus_num();
+ i2c_set_bus_num(1);
+
+ val8 = 0;
+#if defined(CONFIG_PCI) && !defined(CONFIG_PCISLAVE)
+ /* Assign PIB PMC slot to desired PCI bus */
+ i2c_write(0x23, 0x6, 1, &val8, 1);
+ i2c_write(0x23, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x23, 0x2, 1, &val8, 1);
+ i2c_write(0x23, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x26, 0x6, 1, &val8, 1);
+ val8 = 0x34;
+ i2c_write(0x26, 0x7, 1, &val8, 1);
+#if defined(CONFIG_MPC832XEMDS)
+ val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */
+#else
+ val8 = 0xf3; /* PMC1, PMC2, PMC3 slot to PCI bus */
+#endif
+ i2c_write(0x26, 0x2, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x26, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x27, 0x6, 1, &val8, 1);
+ i2c_write(0x27, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x27, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ i2c_write(0x27, 0x3, 1, &val8, 1);
+
+ eieio();
+
+#if defined(CONFIG_MPC832XEMDS)
+ printf("PCI 32bit bus on PMC2 &PMC3\n");
+#else
+ printf("PCI 32bit bus on PMC1 & PMC2 &PMC3\n");
+#endif
+#endif
+
+#if defined(CONFIG_PQ_MDS_PIB_ATM)
+#if defined(CONFIG_MPC8360EMDS) || defined(CONFIG_MPC8569MDS)
+ val8 = 0;
+ i2c_write(0x20, 0x6, 1, &val8, 1);
+ i2c_write(0x20, 0x7, 1, &val8, 1);
+
+ val8 = 0xdf;
+ i2c_write(0x20, 0x2, 1, &val8, 1);
+ val8 = 0xf7;
+ i2c_write(0x20, 0x3, 1, &val8, 1);
+
+ eieio();
+
+ printf("QOC3 ATM card on PMC0\n");
+#elif defined(CONFIG_MPC832XEMDS)
+ val8 = 0;
+ i2c_write(0x26, 0x7, 1, &val8, 1);
+ val8 = 0xf7;
+ i2c_write(0x26, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x21, 0x6, 1, &val8, 1);
+ i2c_write(0x21, 0x7, 1, &val8, 1);
+
+ val8 = 0xdf;
+ i2c_write(0x21, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ i2c_write(0x21, 0x3, 1, &val8, 1);
+
+ eieio();
+
+ printf("QOC3 ATM card on PMC1\n");
+#endif
+#endif
+ /* Reset to original I2C bus */
+ i2c_set_bus_num(orig_i2c_bus);
+ return 0;
+}
diff --git a/board/freescale/common/pq-mds-pib.h b/board/freescale/common/pq-mds-pib.h
new file mode 100644
index 0000000..67066fd
--- /dev/null
+++ b/board/freescale/common/pq-mds-pib.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2007 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;
+ */
+
+extern int pib_init(void);
diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c
new file mode 100644
index 0000000..2b74d02
--- /dev/null
+++ b/board/freescale/common/qixis.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2011 Freescale Semiconductor
+ * Author: Shengzhou Liu <Shengzhou.Liu@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 file provides support for the QIXIS of some Freescale reference boards.
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <linux/time.h>
+#include <i2c.h>
+#include "qixis.h"
+
+#ifdef CONFIG_SYS_I2C_FPGA_ADDR
+u8 qixis_read_i2c(unsigned int reg)
+{
+ return i2c_reg_read(CONFIG_SYS_I2C_FPGA_ADDR, reg);
+}
+
+void qixis_write_i2c(unsigned int reg, u8 value)
+{
+ u8 val = value;
+ i2c_reg_write(CONFIG_SYS_I2C_FPGA_ADDR, reg, val);
+}
+#endif
+
+u8 qixis_read(unsigned int reg)
+{
+ void *p = (void *)QIXIS_BASE;
+
+ return in_8(p + reg);
+}
+
+void qixis_write(unsigned int reg, u8 value)
+{
+ void *p = (void *)QIXIS_BASE;
+
+ out_8(p + reg, value);
+}
+
+u16 qixis_read_minor(void)
+{
+ u16 minor;
+
+ /* this data is in little endian */
+ QIXIS_WRITE(tagdata, 5);
+ minor = QIXIS_READ(tagdata);
+ QIXIS_WRITE(tagdata, 6);
+ minor += QIXIS_READ(tagdata) << 8;
+
+ return minor;
+}
+
+char *qixis_read_time(char *result)
+{
+ time_t time = 0;
+ int i;
+
+ /* timestamp is in 32-bit big endian */
+ for (i = 8; i <= 11; i++) {
+ QIXIS_WRITE(tagdata, i);
+ time = (time << 8) + QIXIS_READ(tagdata);
+ }
+
+ return ctime_r(&time, result);
+}
+
+char *qixis_read_tag(char *buf)
+{
+ int i;
+ char tag, *ptr = buf;
+
+ for (i = 16; i <= 63; i++) {
+ QIXIS_WRITE(tagdata, i);
+ tag = QIXIS_READ(tagdata);
+ *(ptr++) = tag;
+ if (!tag)
+ break;
+ }
+ if (i > 63)
+ *ptr = '\0';
+
+ return buf;
+}
+
+/*
+ * return the string of binary of u8 in the format of
+ * 1010 10_0. The masked bit is filled as underscore.
+ */
+const char *byte_to_binary_mask(u8 val, u8 mask, char *buf)
+{
+ char *ptr;
+ int i;
+
+ ptr = buf;
+ for (i = 0x80; i > 0x08 ; i >>= 1, ptr++)
+ *ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
+ *(ptr++) = ' ';
+ for (i = 0x08; i > 0 ; i >>= 1, ptr++)
+ *ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
+
+ *ptr = '\0';
+
+ return buf;
+}
+
+void qixis_reset(void)
+{
+ QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET);
+}
+
+void qixis_bank_reset(void)
+{
+ QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
+ QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
+}
+
+/* Set the boot bank to the power-on default bank */
+void clear_altbank(void)
+{
+ u8 reg;
+
+ reg = QIXIS_READ(brdcfg[0]);
+ reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_DFLTBANK;
+ QIXIS_WRITE(brdcfg[0], reg);
+}
+
+/* Set the boot bank to the alternate bank */
+void set_altbank(void)
+{
+ u8 reg;
+
+ reg = QIXIS_READ(brdcfg[0]);
+ reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_ALTBANK;
+ QIXIS_WRITE(brdcfg[0], reg);
+}
+
+static void qixis_dump_regs(void)
+{
+ int i;
+
+ printf("id = %02x\n", QIXIS_READ(id));
+ printf("arch = %02x\n", QIXIS_READ(arch));
+ printf("scver = %02x\n", QIXIS_READ(scver));
+ printf("model = %02x\n", QIXIS_READ(model));
+ printf("rst_ctl = %02x\n", QIXIS_READ(rst_ctl));
+ printf("aux = %02x\n", QIXIS_READ(aux));
+ for (i = 0; i < 16; i++)
+ printf("brdcfg%02d = %02x\n", i, QIXIS_READ(brdcfg[i]));
+ for (i = 0; i < 16; i++)
+ printf("dutcfg%02d = %02x\n", i, QIXIS_READ(dutcfg[i]));
+ printf("sclk = %02x%02x%02x\n", QIXIS_READ(sclk[0]),
+ QIXIS_READ(sclk[1]), QIXIS_READ(sclk[2]));
+ printf("dclk = %02x%02x%02x\n", QIXIS_READ(dclk[0]),
+ QIXIS_READ(dclk[1]), QIXIS_READ(dclk[2]));
+ printf("aux = %02x\n", QIXIS_READ(aux));
+ printf("watch = %02x\n", QIXIS_READ(watch));
+ printf("ctl_sys = %02x\n", QIXIS_READ(ctl_sys));
+ printf("rcw_ctl = %02x\n", QIXIS_READ(rcw_ctl));
+ printf("present = %02x\n", QIXIS_READ(present));
+ printf("present2 = %02x\n", QIXIS_READ(present2));
+ printf("clk_spd = %02x\n", QIXIS_READ(clk_spd));
+ printf("stat_dut = %02x\n", QIXIS_READ(stat_dut));
+ printf("stat_sys = %02x\n", QIXIS_READ(stat_sys));
+ printf("stat_alrm = %02x\n", QIXIS_READ(stat_alrm));
+}
+
+static void __qixis_dump_switch(void)
+{
+ puts("Reverse engineering switch is not implemented for this board\n");
+}
+
+void qixis_dump_switch(void)
+ __attribute__((weak, alias("__qixis_dump_switch")));
+
+int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int i;
+
+ if (argc <= 1) {
+ clear_altbank();
+ qixis_reset();
+ } else if (strcmp(argv[1], "altbank") == 0) {
+ set_altbank();
+ qixis_bank_reset();
+ } else if (strcmp(argv[1], "watchdog") == 0) {
+ static char *period[9] = {"2s", "4s", "8s", "16s", "32s",
+ "1min", "2min", "4min", "8min"};
+ u8 rcfg = QIXIS_READ(rcfg_ctl);
+
+ if (argv[2] == NULL) {
+ printf("qixis watchdog <watchdog_period>\n");
+ return 0;
+ }
+ for (i = 0; i < ARRAY_SIZE(period); i++) {
+ if (strcmp(argv[2], period[i]) == 0) {
+ /* disable watchdog */
+ QIXIS_WRITE(rcfg_ctl,
+ rcfg & ~QIXIS_RCFG_CTL_WATCHDOG_ENBLE);
+ QIXIS_WRITE(watch, ((i<<2) - 1));
+ QIXIS_WRITE(rcfg_ctl, rcfg);
+ return 0;
+ }
+ }
+ } else if (strcmp(argv[1], "dump") == 0) {
+ qixis_dump_regs();
+ return 0;
+ } else if (strcmp(argv[1], "switch") == 0) {
+ qixis_dump_switch();
+ return 0;
+ } else {
+ printf("Invalid option: %s\n", argv[1]);
+ return 1;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ qixis_reset, CONFIG_SYS_MAXARGS, 1, qixis_reset_cmd,
+ "Reset the board using the FPGA sequencer",
+ "- hard reset to default bank\n"
+ "qixis_reset altbank - reset to alternate bank\n"
+ "qixis watchdog <watchdog_period> - set the watchdog period\n"
+ " period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n"
+ "qixis_reset dump - display the QIXIS registers\n"
+ "qixis_reset switch - display switch\n"
+ );
diff --git a/board/freescale/common/qixis.h b/board/freescale/common/qixis.h
new file mode 100644
index 0000000..2cf8738
--- /dev/null
+++ b/board/freescale/common/qixis.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2011 Freescale Semiconductor
+ * Author: Shengzhou Liu <Shengzhou.Liu@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 file provides support for the QIXIS of some Freescale reference boards.
+ */
+
+#ifndef __QIXIS_H_
+#define __QIXIS_H_
+
+struct qixis {
+ u8 id; /* ID value uniquely identifying each QDS board type */
+ u8 arch; /* Board version information */
+ u8 scver; /* QIXIS Version Register */
+ u8 model; /* Information of software programming model version */
+ u8 tagdata;
+ u8 ctl_sys;
+ u8 aux; /* Auxiliary Register,0x06 */
+ u8 clk_spd;
+ u8 stat_dut;
+ u8 stat_sys;
+ u8 stat_alrm;
+ u8 present;
+ u8 present2; /* Presence Status Register 2,0x0c */
+ u8 rcw_ctl;
+ u8 ctl_led;
+ u8 i2cblk;
+ u8 rcfg_ctl; /* Reconfig Control Register,0x10 */
+ u8 rcfg_st;
+ u8 dcm_ad;
+ u8 dcm_da;
+ u8 dcmd;
+ u8 dmsg;
+ u8 gdc;
+ u8 gdd; /* DCM Debug Data Register,0x17 */
+ u8 dmack;
+ u8 res1[6];
+ u8 watch; /* Watchdog Register,0x1F */
+ u8 pwr_ctl[2]; /* Power Control Register,0x20 */
+ u8 res2[2];
+ u8 pwr_stat[4]; /* Power Status Register,0x24 */
+ u8 res3[8];
+ u8 clk_spd2[2]; /* SYSCLK clock Speed Register,0x30 */
+ u8 res4[2];
+ u8 sclk[3]; /* Clock Configuration Registers,0x34 */
+ u8 res5;
+ u8 dclk[3];
+ u8 res6;
+ u8 clk_dspd[3];
+ u8 res7;
+ u8 rst_ctl; /* Reset Control Register,0x40 */
+ u8 rst_stat; /* Reset Status Register */
+ u8 rst_rsn; /* Reset Reason Register */
+ u8 rst_frc[2]; /* Reset Force Registers,0x43 */
+ u8 res8[11];
+ u8 brdcfg[16]; /* Board Configuration Register,0x50 */
+ u8 dutcfg[16];
+ u8 rcw_ad[2]; /* RCW SRAM Address Registers,0x70 */
+ u8 rcw_data;
+ u8 res9[5];
+ u8 post_ctl;
+ u8 post_stat;
+ u8 post_dat[2];
+ u8 pi_d[4];
+ u8 gpio_io[4];
+ u8 gpio_dir[4];
+ u8 res10[20];
+ u8 rjtag_ctl;
+ u8 rjtag_dat;
+ u8 res11[2];
+ u8 trig_src[4];
+ u8 trig_dst[4];
+ u8 trig_stat;
+ u8 res12[3];
+ u8 trig_ctr[4];
+ u8 res13[16];
+ u8 clk_freq[6]; /* Clock Measurement Registers */
+ u8 res_c6[8];
+ u8 clk_base[2]; /* Clock Frequency Base Reg */
+ u8 res_d0[16];
+ u8 aux2[4]; /* Auxiliary Registers,0xE0 */
+ u8 res14[10];
+ u8 aux_ad;
+ u8 aux_da;
+ u8 res15[16];
+};
+
+u8 qixis_read(unsigned int reg);
+void qixis_write(unsigned int reg, u8 value);
+u16 qixis_read_minor(void);
+char *qixis_read_time(char *result);
+char *qixis_read_tag(char *buf);
+const char *byte_to_binary_mask(u8 val, u8 mask, char *buf);
+#ifdef CONFIG_SYS_I2C_FPGA_ADDR
+u8 qixis_read_i2c(unsigned int reg);
+void qixis_write_i2c(unsigned int reg, u8 value);
+#endif
+
+#define QIXIS_READ(reg) qixis_read(offsetof(struct qixis, reg))
+#define QIXIS_WRITE(reg, value) qixis_write(offsetof(struct qixis, reg), value)
+#ifdef CONFIG_SYS_I2C_FPGA_ADDR
+#define QIXIS_READ_I2C(reg) qixis_read_i2c(offsetof(struct qixis, reg))
+#define QIXIS_WRITE_I2C(reg, value) \
+ qixis_write_i2c(offsetof(struct qixis, reg), value)
+#endif
+
+#endif
diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c
new file mode 100644
index 0000000..fd0e910
--- /dev/null
+++ b/board/freescale/common/sdhc_boot.c
@@ -0,0 +1,63 @@
+/*
+ * 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 <mmc.h>
+#include <malloc.h>
+
+/*
+ * The environment variables are written to just after the u-boot image
+ * on SDCard, so we must read the MBR to get the start address and code
+ * length of the u-boot image, then calculate the address of the env.
+ */
+#define ESDHC_BOOT_IMAGE_SIZE 0x48
+#define ESDHC_BOOT_IMAGE_ADDR 0x50
+
+int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
+{
+ u8 *tmp_buf;
+ u32 blklen, code_offset, code_len, n;
+
+ blklen = mmc->read_bl_len;
+ tmp_buf = malloc(blklen);
+ if (!tmp_buf)
+ return 1;
+
+ /* read out the first block, get the config data information */
+ n = mmc->block_dev.block_read(mmc->block_dev.dev, 0, 1, tmp_buf);
+ if (!n) {
+ free(tmp_buf);
+ return 1;
+ }
+
+ /* Get the Source Address, from offset 0x50 */
+ code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR);
+
+ /* Get the code size from offset 0x48 */
+ code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
+
+ *env_addr = code_offset + code_len;
+
+ free(tmp_buf);
+
+ return 0;
+}
diff --git a/board/freescale/common/sgmii_riser.c b/board/freescale/common/sgmii_riser.c
new file mode 100644
index 0000000..5c3c593
--- /dev/null
+++ b/board/freescale/common/sgmii_riser.c
@@ -0,0 +1,129 @@
+/*
+ * Freescale SGMII Riser Card
+ *
+ * This driver supports the SGMII Riser card found on the
+ * "DS" style of development board from Freescale.
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <libfdt.h>
+#include <tsec.h>
+#include <fdt_support.h>
+
+void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (tsec_info[i].flags & TSEC_SGMII)
+ tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
+}
+
+void fsl_sgmii_riser_fdt_fixup(void *fdt)
+{
+ struct eth_device *dev;
+ int node;
+ int mdio_node;
+ int i = -1;
+ int etsec_num = 0;
+
+ node = fdt_path_offset(fdt, "/aliases");
+ if (node < 0)
+ return;
+
+ while ((dev = eth_get_dev_by_index(++i)) != NULL) {
+ struct tsec_private *priv;
+ int phy_node;
+ int enet_node;
+ uint32_t ph;
+ char sgmii_phy[16];
+ char enet[16];
+ const u32 *phyh;
+ const char *model;
+ const char *path;
+
+ if (!strstr(dev->name, "eTSEC"))
+ continue;
+
+ priv = dev->priv;
+ if (!(priv->flags & TSEC_SGMII)) {
+ etsec_num++;
+ continue;
+ }
+
+ mdio_node = fdt_node_offset_by_compatible(fdt, -1,
+ "fsl,gianfar-mdio");
+ if (mdio_node < 0)
+ return;
+
+ sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
+ phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
+ if (phy_node > 0) {
+ fdt_increase_size(fdt, 32);
+ ph = fdt_create_phandle(fdt, phy_node);
+ if (!ph)
+ continue;
+ }
+
+ sprintf(enet, "ethernet%d", etsec_num++);
+ path = fdt_getprop(fdt, node, enet, NULL);
+ if (!path) {
+ debug("No alias for %s\n", enet);
+ continue;
+ }
+
+ enet_node = fdt_path_offset(fdt, path);
+ if (enet_node < 0)
+ continue;
+
+ model = fdt_getprop(fdt, enet_node, "model", NULL);
+
+ /*
+ * We only want to do this to eTSECs. On some platforms
+ * there are more than one type of gianfar-style ethernet
+ * controller, and as we are creating an implicit connection
+ * between ethernet nodes and eTSEC devices, it is best to
+ * make the connection use as much explicit information
+ * as exists.
+ */
+ if (!strstr(model, "TSEC"))
+ continue;
+
+ if (phy_node < 0) {
+ /*
+ * This part is only for old device tree without
+ * sgmii_phy nodes. It's kept just for compatible
+ * reason. Soon to be deprecated if all device tree
+ * get updated.
+ */
+ phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
+ if (!phyh)
+ continue;
+
+ phy_node = fdt_node_offset_by_phandle(fdt,
+ fdt32_to_cpu(*phyh));
+
+ priv = dev->priv;
+
+ if (priv->flags & TSEC_SGMII)
+ fdt_setprop_cell(fdt, phy_node, "reg",
+ priv->phyaddr);
+ } else {
+ fdt_setprop(fdt, enet_node, "phy-handle", &ph,
+ sizeof(ph));
+ fdt_setprop_string(fdt, enet_node,
+ "phy-connection-type",
+ phy_string_for_interface(
+ PHY_INTERFACE_MODE_SGMII));
+ }
+ }
+}
diff --git a/board/freescale/common/sgmii_riser.h b/board/freescale/common/sgmii_riser.h
new file mode 100644
index 0000000..e1fcc85
--- /dev/null
+++ b/board/freescale/common/sgmii_riser.h
@@ -0,0 +1,16 @@
+/*
+ * Freescale SGMII Riser Card
+ *
+ * This driver supports the SGMII Riser card found on the
+ * "DS" style of development board from Freescale.
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ */
+
+void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num);
+void fsl_sgmii_riser_fdt_fixup(void *fdt);
diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c
new file mode 100644
index 0000000..d2ed036
--- /dev/null
+++ b/board/freescale/common/sys_eeprom.c
@@ -0,0 +1,554 @@
+/*
+ * Copyright 2006, 2008-2009, 2011 Freescale Semiconductor
+ * York Sun (yorksun@freescale.com)
+ * Haiying Wang (haiying.wang@freescale.com)
+ * Timur Tabi (timur@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 <i2c.h>
+#include <linux/ctype.h>
+
+#ifdef CONFIG_SYS_I2C_EEPROM_CCID
+#include "../common/eeprom.h"
+#define MAX_NUM_PORTS 8
+#endif
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+#define MAX_NUM_PORTS 23
+#define NXID_VERSION 1
+#endif
+
+/**
+ * static eeprom: EEPROM layout for CCID or NXID formats
+ *
+ * See application note AN3638 for details.
+ */
+static struct __attribute__ ((__packed__)) eeprom {
+#ifdef CONFIG_SYS_I2C_EEPROM_CCID
+ u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'CCID' */
+ u8 major; /* 0x04 Board revision, major */
+ u8 minor; /* 0x05 Board revision, minor */
+ u8 sn[10]; /* 0x06 - 0x0F Serial Number*/
+ u8 errata[2]; /* 0x10 - 0x11 Errata Level */
+ u8 date[6]; /* 0x12 - 0x17 Build Date */
+ u8 res_0[40]; /* 0x18 - 0x3f Reserved */
+ u8 mac_count; /* 0x40 Number of MAC addresses */
+ u8 mac_flag; /* 0x41 MAC table flags */
+ u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0x71 MAC addresses */
+ u32 crc; /* 0x72 CRC32 checksum */
+#endif
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */
+ u8 sn[12]; /* 0x04 - 0x0F Serial Number */
+ u8 errata[5]; /* 0x10 - 0x14 Errata Level */
+ u8 date[6]; /* 0x15 - 0x1a Build Date */
+ u8 res_0; /* 0x1b Reserved */
+ u32 version; /* 0x1c - 0x1f NXID Version */
+ u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */
+ u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
+ u8 tempcalflags; /* 0x2a Temperature Calibration Flags */
+ u8 res_1[21]; /* 0x2b - 0x3f Reserved */
+ u8 mac_count; /* 0x40 Number of MAC addresses */
+ u8 mac_flag; /* 0x41 MAC table flags */
+ u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - x MAC addresses */
+ u32 crc; /* x+1 CRC32 checksum */
+#endif
+} e;
+
+/* Set to 1 if we've read EEPROM into memory */
+static int has_been_read = 0;
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+/* Is this a valid NXID EEPROM? */
+#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \
+ (e.id[2] == 'I') || (e.id[3] == 'D'))
+#endif
+
+#ifdef CONFIG_SYS_I2C_EEPROM_CCID
+/* Is this a valid CCID EEPROM? */
+#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \
+ (e.id[2] == 'I') || (e.id[3] == 'D'))
+#endif
+
+/**
+ * show_eeprom - display the contents of the EEPROM
+ */
+static void show_eeprom(void)
+{
+ int i;
+ unsigned int crc;
+
+ /* EEPROM tag ID, either CCID or NXID */
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
+ be32_to_cpu(e.version));
+#else
+ printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
+#endif
+
+ /* Serial number */
+ printf("SN: %s\n", e.sn);
+
+ /* Errata level. */
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ printf("Errata: %s\n", e.errata);
+#else
+ printf("Errata: %c%c\n",
+ e.errata[0] ? e.errata[0] : '.',
+ e.errata[1] ? e.errata[1] : '.');
+#endif
+
+ /* Build date, BCD date values, as YYMMDDhhmmss */
+ printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n",
+ e.date[0], e.date[1], e.date[2],
+ e.date[3] & 0x7F, e.date[4], e.date[5],
+ e.date[3] & 0x80 ? "PM" : "");
+
+ /* Show MAC addresses */
+ for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) {
+
+ u8 *p = e.mac[i];
+
+ printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i,
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ }
+
+ crc = crc32(0, (void *)&e, sizeof(e) - 4);
+
+ if (crc == be32_to_cpu(e.crc))
+ printf("CRC: %08x\n", be32_to_cpu(e.crc));
+ else
+ printf("CRC: %08x (should be %08x)\n",
+ be32_to_cpu(e.crc), crc);
+
+#ifdef DEBUG
+ printf("EEPROM dump: (0x%x bytes)\n", sizeof(e));
+ for (i = 0; i < sizeof(e); i++) {
+ if ((i % 16) == 0)
+ printf("%02X: ", i);
+ printf("%02X ", ((u8 *)&e)[i]);
+ if (((i % 16) == 15) || (i == sizeof(e) - 1))
+ printf("\n");
+ }
+#endif
+}
+
+/**
+ * read_eeprom - read the EEPROM into memory
+ */
+static int read_eeprom(void)
+{
+ int ret;
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ unsigned int bus;
+#endif
+
+ if (has_been_read)
+ return 0;
+
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ bus = i2c_get_bus_num();
+ i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
+#endif
+
+ ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+ (void *)&e, sizeof(e));
+
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ i2c_set_bus_num(bus);
+#endif
+
+#ifdef DEBUG
+ show_eeprom();
+#endif
+
+ has_been_read = (ret == 0) ? 1 : 0;
+
+ return ret;
+}
+
+/**
+ * update_crc - update the CRC
+ *
+ * This function should be called after each update to the EEPROM structure,
+ * to make sure the CRC is always correct.
+ */
+static void update_crc(void)
+{
+ u32 crc;
+
+ crc = crc32(0, (void *)&e, sizeof(e) - 4);
+ e.crc = cpu_to_be32(crc);
+}
+
+/**
+ * prog_eeprom - write the EEPROM from memory
+ */
+static int prog_eeprom(void)
+{
+ int ret = 0;
+ int i;
+ void *p;
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ unsigned int bus;
+#endif
+
+ /* Set the reserved values to 0xFF */
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ e.res_0 = 0xFF;
+ memset(e.res_1, 0xFF, sizeof(e.res_1));
+#else
+ memset(e.res_0, 0xFF, sizeof(e.res_0));
+#endif
+ update_crc();
+
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ bus = i2c_get_bus_num();
+ i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
+#endif
+
+ /*
+ * The AT24C02 datasheet says that data can only be written in page
+ * mode, which means 8 bytes at a time, and it takes up to 5ms to
+ * complete a given write.
+ */
+ for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
+ ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+ p, min((sizeof(e) - i), 8));
+ if (ret)
+ break;
+ udelay(5000); /* 5ms write cycle timing */
+ }
+
+ if (!ret) {
+ /* Verify the write by reading back the EEPROM and comparing */
+ struct eeprom e2;
+
+ ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (void *)&e2, sizeof(e2));
+ if (!ret && memcmp(&e, &e2, sizeof(e)))
+ ret = -1;
+ }
+
+#ifdef CONFIG_SYS_EEPROM_BUS_NUM
+ i2c_set_bus_num(bus);
+#endif
+
+ if (ret) {
+ printf("Programming failed.\n");
+ has_been_read = 0;
+ return -1;
+ }
+
+ printf("Programming passed.\n");
+ return 0;
+}
+
+/**
+ * h2i - converts hex character into a number
+ *
+ * This function takes a hexadecimal character (e.g. '7' or 'C') and returns
+ * the integer equivalent.
+ */
+static inline u8 h2i(char p)
+{
+ if ((p >= '0') && (p <= '9'))
+ return p - '0';
+
+ if ((p >= 'A') && (p <= 'F'))
+ return (p - 'A') + 10;
+
+ if ((p >= 'a') && (p <= 'f'))
+ return (p - 'a') + 10;
+
+ return 0;
+}
+
+/**
+ * set_date - stores the build date into the EEPROM
+ *
+ * This function takes a pointer to a string in the format "YYMMDDhhmmss"
+ * (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string,
+ * and stores it in the build date field of the EEPROM local copy.
+ */
+static void set_date(const char *string)
+{
+ unsigned int i;
+
+ if (strlen(string) != 12) {
+ printf("Usage: mac date YYMMDDhhmmss\n");
+ return;
+ }
+
+ for (i = 0; i < 6; i++)
+ e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
+
+ update_crc();
+}
+
+/**
+ * set_mac_address - stores a MAC address into the EEPROM
+ *
+ * This function takes a pointer to MAC address string
+ * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and
+ * stores it in one of the MAC address fields of the EEPROM local copy.
+ */
+static void set_mac_address(unsigned int index, const char *string)
+{
+ char *p = (char *) string;
+ unsigned int i;
+
+ if ((index >= MAX_NUM_PORTS) || !string) {
+ printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n");
+ return;
+ }
+
+ for (i = 0; *p && (i < 6); i++) {
+ e.mac[index][i] = simple_strtoul(p, &p, 16);
+ if (*p == ':')
+ p++;
+ }
+
+ update_crc();
+}
+
+int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char cmd;
+
+ if (argc == 1) {
+ show_eeprom();
+ return 0;
+ }
+
+ cmd = argv[1][0];
+
+ if (cmd == 'r') {
+ read_eeprom();
+ return 0;
+ }
+
+ if (cmd == 'i') {
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ memcpy(e.id, "NXID", sizeof(e.id));
+ e.version = NXID_VERSION;
+#else
+ memcpy(e.id, "CCID", sizeof(e.id));
+#endif
+ update_crc();
+ return 0;
+ }
+
+ if (!is_valid) {
+ printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n");
+ return 0;
+ }
+
+ if (argc == 2) {
+ switch (cmd) {
+ case 's': /* save */
+ prog_eeprom();
+ break;
+ default:
+ return cmd_usage(cmdtp);
+ }
+
+ return 0;
+ }
+
+ /* We know we have at least one parameter */
+
+ switch (cmd) {
+ case 'n': /* serial number */
+ memset(e.sn, 0, sizeof(e.sn));
+ strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
+ update_crc();
+ break;
+ case 'e': /* errata */
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ memset(e.errata, 0, 5);
+ strncpy((char *)e.errata, argv[2], 4);
+#else
+ e.errata[0] = argv[2][0];
+ e.errata[1] = argv[2][1];
+#endif
+ update_crc();
+ break;
+ case 'd': /* date BCD format YYMMDDhhmmss */
+ set_date(argv[2]);
+ break;
+ case 'p': /* MAC table size */
+ e.mac_count = simple_strtoul(argv[2], NULL, 16);
+ update_crc();
+ break;
+ case '0' ... '9': /* "mac 0" through "mac 22" */
+ set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]);
+ break;
+ case 'h': /* help */
+ default:
+ return cmd_usage(cmdtp);
+ }
+
+ return 0;
+}
+
+/**
+ * mac_read_from_eeprom - read the MAC addresses from EEPROM
+ *
+ * This function reads the MAC addresses from EEPROM and sets the
+ * appropriate environment variables for each one read.
+ *
+ * The environment variables are only set if they haven't been set already.
+ * This ensures that any user-saved variables are never overwritten.
+ *
+ * This function must be called after relocation.
+ *
+ * For NXID v1 EEPROMs, we support loading and up-converting the older NXID v0
+ * format. In a v0 EEPROM, there are only eight MAC addresses and the CRC is
+ * located at a different offset.
+ */
+int mac_read_from_eeprom(void)
+{
+ unsigned int i;
+ u32 crc, crc_offset = offsetof(struct eeprom, crc);
+ u32 *crcp; /* Pointer to the CRC in the data read from the EEPROM */
+
+ puts("EEPROM: ");
+
+ if (read_eeprom()) {
+ printf("Read failed.\n");
+ return -1;
+ }
+
+ if (!is_valid) {
+ printf("Invalid ID (%02x %02x %02x %02x)\n",
+ e.id[0], e.id[1], e.id[2], e.id[3]);
+ return -1;
+ }
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ /*
+ * If we've read an NXID v0 EEPROM, then we need to set the CRC offset
+ * to where it is in v0.
+ */
+ if (e.version == 0)
+ crc_offset = 0x72;
+#endif
+
+ crc = crc32(0, (void *)&e, crc_offset);
+ crcp = (void *)&e + crc_offset;
+ if (crc != be32_to_cpu(*crcp)) {
+ printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc));
+ return -1;
+ }
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ /*
+ * MAC address #9 in v1 occupies the same position as the CRC in v0.
+ * Erase it so that it's not mistaken for a MAC address. We'll
+ * update the CRC later.
+ */
+ if (e.version == 0)
+ memset(e.mac[8], 0xff, 6);
+#endif
+
+ for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) {
+ if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
+ memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
+ char ethaddr[18];
+ char enetvar[9];
+
+ sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
+ e.mac[i][0],
+ e.mac[i][1],
+ e.mac[i][2],
+ e.mac[i][3],
+ e.mac[i][4],
+ e.mac[i][5]);
+ sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
+ /* Only initialize environment variables that are blank
+ * (i.e. have not yet been set)
+ */
+ if (!getenv(enetvar))
+ setenv(enetvar, ethaddr);
+ }
+ }
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
+ be32_to_cpu(e.version));
+#else
+ printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
+#endif
+
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+ /*
+ * Now we need to upconvert the data into v1 format. We do this last so
+ * that at boot time, U-Boot will still say "NXID v0".
+ */
+ if (e.version == 0) {
+ e.version = NXID_VERSION;
+ update_crc();
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_SYS_I2C_EEPROM_CCID
+
+/**
+ * get_cpu_board_revision - get the CPU board revision on 85xx boards
+ *
+ * Read the EEPROM to determine the board revision.
+ *
+ * This function is called before relocation, so we need to read a private
+ * copy of the EEPROM into a local variable on the stack.
+ *
+ * Also, we assume that CONFIG_SYS_EEPROM_BUS_NUM == CONFIG_SYS_SPD_BUS_NUM. The global
+ * variable i2c_bus_num must be compile-time initialized to CONFIG_SYS_SPD_BUS_NUM,
+ * so that the SPD code will work. This means that all pre-relocation I2C
+ * operations can only occur on the CONFIG_SYS_SPD_BUS_NUM bus. So if
+ * CONFIG_SYS_EEPROM_BUS_NUM != CONFIG_SYS_SPD_BUS_NUM, then we can't read the EEPROM when
+ * this function is called. Oh well.
+ */
+unsigned int get_cpu_board_revision(void)
+{
+ struct board_eeprom {
+ u32 id; /* 0x00 - 0x03 EEPROM Tag 'CCID' */
+ u8 major; /* 0x04 Board revision, major */
+ u8 minor; /* 0x05 Board revision, minor */
+ } be;
+
+ i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+ (void *)&be, sizeof(be));
+
+ if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D'))
+ return MPC85XX_CPU_BOARD_REV(0, 0);
+
+ if ((be.major == 0xff) && (be.minor == 0xff))
+ return MPC85XX_CPU_BOARD_REV(0, 0);
+
+ return MPC85XX_CPU_BOARD_REV(be.major, be.minor);
+}
+#endif
diff --git a/board/freescale/common/via.h b/board/freescale/common/via.h
new file mode 100644
index 0000000..77cfacc
--- /dev/null
+++ b/board/freescale/common/via.h
@@ -0,0 +1,18 @@
+#ifndef _MPC85xx_VIA_H
+void mpc85xx_config_via(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+
+/* Function 1, IDE */
+void mpc85xx_config_via_usbide(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+
+/* Function 2, USB ports 0-1 */
+void mpc85xx_config_via_usb(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+
+/* Function 3, USB ports 2-3 */
+void mpc85xx_config_via_usb2(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+
+/* Function 5, Power Management */
+void mpc85xx_config_via_power(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+
+/* Function 6, AC97 Interface */
+void mpc85xx_config_via_ac97(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
+#endif /* _MPC85xx_VIA_H */
diff --git a/board/freescale/common/vsc3316_3308.c b/board/freescale/common/vsc3316_3308.c
new file mode 100644
index 0000000..7868565
--- /dev/null
+++ b/board/freescale/common/vsc3316_3308.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2012 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 "vsc3316_3308.h"
+
+#define REVISION_ID_REG 0x7E
+#define INTERFACE_MODE_REG 0x79
+#define CURRENT_PAGE_REGISTER 0x7F
+#define CONNECTION_CONFIG_PAGE 0x00
+#define INPUT_STATE_REG 0x13
+#define GLOBAL_INPUT_ISE1 0x51
+#define GLOBAL_INPUT_ISE2 0x52
+#define GLOBAL_INPUT_LOS 0x55
+#define GLOBAL_CORE_CNTRL 0x5D
+#define OUTPUT_MODE_PAGE 0x23
+#define CORE_CONTROL_PAGE 0x25
+#define CORE_CONFIG_REG 0x75
+
+int vsc_if_enable(unsigned int vsc_addr)
+{
+ u8 data;
+
+ debug("VSC:Configuring VSC at I2C address 0x%2x"
+ " for 2-wire interface\n", vsc_addr);
+
+ /* enable 2-wire Serial InterFace (I2C) */
+ data = 0x02;
+ return i2c_write(vsc_addr, INTERFACE_MODE_REG, 1, &data, 1);
+}
+
+int vsc3316_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+ unsigned int num_con)
+{
+ unsigned int i;
+ u8 rev_id = 0;
+ int ret;
+
+ debug("VSC:Initializing VSC3316 at I2C address 0x%2x"
+ " for Tx\n", vsc_addr);
+
+ ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
+ if (ret < 0) {
+ printf("VSC:0x%x could not read REV_ID from device.\n",
+ vsc_addr);
+ return ret;
+ }
+
+ if (rev_id != 0xab) {
+ printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+ vsc_addr);
+ return -ENODEV;
+ }
+
+ ret = vsc_if_enable(vsc_addr);
+ if (ret) {
+ printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+ vsc_addr);
+ return ret;
+ }
+
+ /* config connections - page 0x00 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+ /* Making crosspoint connections, by connecting required
+ * input to output */
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
+
+ /* input state - page 0x13 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+ /* Configuring the required input of the switch */
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][0], 0x80);
+
+ /* Setting Global Input LOS threshold value */
+ i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
+
+ /* config output mode - page 0x23 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+ /* Turn ON the Output driver correspond to required output*/
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][1], 0);
+
+ /* configure global core control register, Turn on Global core power */
+ i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
+
+ vsc_wp_config(vsc_addr);
+
+ return 0;
+}
+
+int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+ unsigned int num_con)
+{
+ unsigned int i;
+ u8 rev_id = 0;
+ int ret;
+
+ debug("VSC:Initializing VSC3308 at I2C address 0x%x"
+ " for Tx\n", vsc_addr);
+
+ ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
+ if (ret < 0) {
+ printf("VSC:0x%x could not read REV_ID from device.\n",
+ vsc_addr);
+ return ret;
+ }
+
+ if (rev_id != 0xab) {
+ printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+ vsc_addr);
+ return -ENODEV;
+ }
+
+ ret = vsc_if_enable(vsc_addr);
+ if (ret) {
+ printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+ vsc_addr);
+ return ret;
+ }
+
+ /* config connections - page 0x00 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+ /* Making crosspoint connections, by connecting required
+ * input to output */
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
+
+ /*Configure Global Input ISE and gain */
+ i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0x12);
+ i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0x12);
+
+ /* input state - page 0x13 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+ /* Turning ON the required input of the switch */
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][0], 0);
+
+ /* Setting Global Input LOS threshold value */
+ i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
+
+ /* config output mode - page 0x23 */
+ i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+ /* Turn ON the Output driver correspond to required output*/
+ for (i = 0; i < num_con ; i++)
+ i2c_reg_write(vsc_addr, con_arr[i][1], 0);
+
+ /* configure global core control register, Turn on Global core power */
+ i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
+
+ vsc_wp_config(vsc_addr);
+
+ return 0;
+}
+
+void vsc_wp_config(unsigned int vsc_addr)
+{
+ debug("VSC:Configuring VSC at address:0x%x for WP\n", vsc_addr);
+
+ /* For new crosspoint configuration to occur, WP bit of
+ * CORE_CONFIG_REG should be set 1 and then reset to 0 */
+ i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x01);
+ i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x0);
+}
diff --git a/board/freescale/common/vsc3316_3308.h b/board/freescale/common/vsc3316_3308.h
new file mode 100644
index 0000000..effd66d
--- /dev/null
+++ b/board/freescale/common/vsc3316_3308.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 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 __VSC_CROSSBAR_H_
+#define __VSC_CROSSBAR_H 1_
+
+#include <common.h>
+#include <i2c.h>
+#include <errno.h>
+
+int vsc_if_enable(unsigned int vsc_addr);
+int vsc3316_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+ unsigned int num_con);
+int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+ unsigned int num_con);
+void vsc_wp_config(unsigned int vsc_addr);
+
+#endif /* __VSC_CROSSBAR_H_ */
OpenPOWER on IntegriCloud