[PATCH 6/7] board: cssi: Add new board MCR3000_2G

Christophe Leroy christophe.leroy at csgroup.eu
Mon Jan 30 15:34:05 CET 2023


This adds a new board from CS GROUP. The board is called
MCR3000_2G, and has a CPU board called CMPC885.

That CPU board is shared with another equipment that will
be added in a later patch.

That board stores Ethernet MAC addresses in an EEPROM which
is accessed using SPI bus.

This patch was originally written by Charles Frey who's
email address is not valid anymore as he left the company.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou at csgroup.eu>
---
 arch/powerpc/cpu/mpc8xx/Kconfig |   4 +
 arch/powerpc/dts/Makefile       |   1 +
 arch/powerpc/dts/cmpc885.dts    |  94 ++++
 board/cssi/CMPC885/Kconfig      |  23 +
 board/cssi/CMPC885/Makefile     |  10 +
 board/cssi/CMPC885/cmpc885.c    | 830 ++++++++++++++++++++++++++++++++
 board/cssi/CMPC885/nand.c       |  47 ++
 board/cssi/CMPC885/sdram.c      | 107 ++++
 board/cssi/CMPC885/u-boot.lds   |  95 ++++
 board/cssi/MAINTAINERS          |   2 +
 configs/CMPC885_defconfig       | 104 ++++
 include/configs/CMPC885.h       |  69 +++
 12 files changed, 1386 insertions(+)
 create mode 100644 arch/powerpc/dts/cmpc885.dts
 create mode 100644 board/cssi/CMPC885/Kconfig
 create mode 100644 board/cssi/CMPC885/Makefile
 create mode 100644 board/cssi/CMPC885/cmpc885.c
 create mode 100644 board/cssi/CMPC885/nand.c
 create mode 100644 board/cssi/CMPC885/sdram.c
 create mode 100644 board/cssi/CMPC885/u-boot.lds
 create mode 100644 configs/CMPC885_defconfig
 create mode 100644 include/configs/CMPC885.h

diff --git a/arch/powerpc/cpu/mpc8xx/Kconfig b/arch/powerpc/cpu/mpc8xx/Kconfig
index d63071104c4..9ea59b01eb9 100644
--- a/arch/powerpc/cpu/mpc8xx/Kconfig
+++ b/arch/powerpc/cpu/mpc8xx/Kconfig
@@ -11,6 +11,9 @@ choice
 config TARGET_MCR3000
 	bool "Support MCR3000 board from CSSI"
 
+config TARGET_CMPC885
+	bool "Support CMPC885 board from CSSI"
+
 endchoice
 
 choice
@@ -86,4 +89,5 @@ config SYS_DER
 
 source "board/cssi/MCR3000/Kconfig"
 
+source "board/cssi/CMPC885/Kconfig"
 endmenu
diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
index a4b0d7ddc4f..26b592b85db 100644
--- a/arch/powerpc/dts/Makefile
+++ b/arch/powerpc/dts/Makefile
@@ -29,6 +29,7 @@ dtb-$(CONFIG_TARGET_TUGE1) += kmtuge1.dtb
 dtb-$(CONFIG_TARGET_TUXX1) += kmtuxa1.dtb
 dtb-$(CONFIG_TARGET_MCR3000) += mcr3000.dtb
 dtb-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.dtb
+dtb-$(CONFIG_TARGET_CMPC885) += cmpc885.dtb
 
 include $(srctree)/scripts/Makefile.dts
 
diff --git a/arch/powerpc/dts/cmpc885.dts b/arch/powerpc/dts/cmpc885.dts
new file mode 100644
index 00000000000..adda0f3e9dd
--- /dev/null
+++ b/arch/powerpc/dts/cmpc885.dts
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CMPC885 Device Tree Source
+ *
+ * Copyright 2020 CS Group
+ *
+ */
+
+/dts-v1/;
+
+/ {
+	model = "CMPC885";
+	compatible = "fsl, cmpc885", "fsl,mod885";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen {
+		stdout-path = &SERIAL;
+	};
+
+	WDT: watchdog at 0 {
+		device_type = "watchdog";
+		compatible = "fsl,pq1-wdt";
+	};
+
+	SERIAL: serial {
+		compatible = "fsl,pq1-smc";
+	};
+
+	FEC1: fec at 0 {
+		compatible = "fsl,pq1-fec1";
+	};
+
+	FEC2: fec at 1 {
+		compatible = "fsl,pq1-fec2";
+	};
+
+	soc: immr at ff000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device-type = "soc";
+		compatible = "simple-bus";
+		ranges = <0 0xff000000 0x4000>;
+		reg = <0xff000000 0x00000200>;
+
+		CPM1_PIO_B: gpio-controller at ab8 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-b";
+			reg = <0xab8 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_D: gpio-controller at 970 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-d";
+			reg = <0x970 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_A: gpio-controller at 950 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-a";
+			reg = <0x950 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_C: gpio-controller at 960 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-c";
+			reg = <0x960 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_E: gpio-controller at ac8 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-e";
+			reg = <0xac8 0x18>;
+			gpio-controller;
+		};
+
+		spi: spi at aa0 {
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			compatible = "fsl,mpc8xx-spi";
+			gpios = <&CPM1_PIO_B 21 1>; /* /EEPROM_CS ACTIVE_LOW */
+
+			eeprom at 0 {
+				cell-index = <1>;
+			};
+		};
+	};
+};
diff --git a/board/cssi/CMPC885/Kconfig b/board/cssi/CMPC885/Kconfig
new file mode 100644
index 00000000000..50902a64bbb
--- /dev/null
+++ b/board/cssi/CMPC885/Kconfig
@@ -0,0 +1,23 @@
+if TARGET_CMPC885
+
+config SYS_BOARD
+	default "CMPC885"
+
+config SYS_VENDOR
+	default "cssi"
+
+config SYS_CONFIG_NAME
+	default "CMPC885"
+
+config TEXT_BASE
+	default 0x40000000
+
+config CPLD_BASE
+	hex
+	default 0xc8000000
+
+config FPGA_BASE
+	hex
+	default 0xd0000000
+
+endif
diff --git a/board/cssi/CMPC885/Makefile b/board/cssi/CMPC885/Makefile
new file mode 100644
index 00000000000..6c055097cdd
--- /dev/null
+++ b/board/cssi/CMPC885/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2010-2020 CS Group
+# Charles Frey <charles.frey at c-s.fr>
+# Christophe Leroy <christophe.leroy at c-s.fr>
+#
+
+obj-y += cmpc885.o
+obj-y += sdram.o
+obj-$(CONFIG_CMD_NAND) += nand.o
diff --git a/board/cssi/CMPC885/cmpc885.c b/board/cssi/CMPC885/cmpc885.c
new file mode 100644
index 00000000000..2c19d9b6165
--- /dev/null
+++ b/board/cssi/CMPC885/cmpc885.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010-2020 CS Group
+ * Charles Frey <charles.frey at c-s.fr>
+ * Florent Trinh Thai <florent.trinh-thai at c-s.fr>
+ * Christophe Leroy <christophe.leroy at c-s.fr>
+ *
+ * Board specific routines for the CMPC885 board
+ */
+
+#include <env.h>
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <watchdog.h>
+#include <serial.h>
+#include <hang.h>
+#include <flash.h>
+#include <init.h>
+#include <fdt_support.h>
+#include <linux/delay.h>
+
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BOARD_CMPC885		"cmpc885"
+#define BOARD_MCR3000_2G	"mcr3k_2g"
+
+#define TYPE_MCR	0x22
+
+#define ADDR_CPLD_R_RESET		((unsigned short __iomem *)CONFIG_CPLD_BASE)
+#define ADDR_CPLD_R_ETAT		((unsigned short __iomem *)(CONFIG_CPLD_BASE + 2))
+#define ADDR_CPLD_R_TYPE		((unsigned char  __iomem *)(CONFIG_CPLD_BASE + 3))
+
+#define ADDR_FPGA_R_BASE		((unsigned char  __iomem *)CONFIG_FPGA_BASE)
+#define ADDR_FPGA_R_ALARMES_IN		((unsigned char  __iomem *)CONFIG_FPGA_BASE + 0x31)
+
+#define FPGA_R_ACQ_AL_FAV	0x04
+#define R_ETAT_PRES_BASE	0x0040
+
+#define R_RESET_STATUS		0x0400
+#define R_RST_STATUS		0x0004
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	const char *sync = "receive";
+
+	ft_cpu_setup(blob, bd);
+
+	/* BRG */
+	do_fixup_by_path_u32(blob, "/soc/cpm", "brg-frequency",
+			     bd->bi_busfreq, 1);
+	/* MAC addr */
+	fdt_fixup_ethernet(blob);
+
+	/* Bus Frequency for CPM */
+	do_fixup_by_path_u32(blob, "/soc", "bus-frequency", bd->bi_busfreq, 1);
+
+	/* E1 interface - Set data rate */
+	do_fixup_by_path_u32(blob, "/localbus/e1", "data-rate", 2, 1);
+
+	/* E1 interface - Set channel phase to 0 */
+	do_fixup_by_path_u32(blob, "/localbus/e1", "channel-phase", 0, 1);
+
+	/* E1 interface - rising edge sync pulse transmit */
+	do_fixup_by_path(blob, "/localbus/e1", "rising-edge-sync-pulse",
+			 sync, strlen(sync), 1);
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	serial_puts("Board: ");
+
+	/* Is a motherboard present ? */
+	if (in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE) {
+		switch (in_8(ADDR_FPGA_R_BASE)) {
+		case TYPE_MCR:
+			printf("MCR3000_2G (CS GROUP)\n");
+			break;
+		default:
+			printf("Unknown\n");
+			for (;;)
+				;
+			break;
+		}
+	} else {
+		printf("CMPC885 (CS GROUP)\n");
+	}
+	return 0;
+}
+
+#define SPI_EEPROM_READ	0x03
+#define MAX_SPI_BYTES	0x20
+
+#define EE_OFF_MAC1	0x13
+#define EE_OFF_MAC2	0x19
+
+/* Reads MAC addresses from SPI EEPROM */
+static int setup_mac(void)
+{
+	struct udevice *eeprom;
+	struct spi_slave *slave;
+	char name[30], *str;
+	uchar din[MAX_SPI_BYTES];
+	uchar dout[MAX_SPI_BYTES] = {SPI_EEPROM_READ, 0, 0};
+	int bitlen = 256, cs = 0, mode = 0, bus = 0, ret;
+	unsigned long ident = 0x08005120;
+
+	snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
+
+	str = strdup(name);
+	if (!str)
+		return -1;
+
+	ret = uclass_get_device(UCLASS_SPI, 0, &eeprom);
+	if (ret) {
+		printf("Could not enable Serial Peripheral Interface (SPI).\n");
+		return -1;
+	}
+
+	ret = _spi_get_bus_and_cs(bus, cs, 1000000, mode, "spi_generic_drv", str, &eeprom, &slave);
+	if (ret)
+		return ret;
+
+	ret = spi_claim_bus(slave);
+
+	ret = spi_xfer(slave, bitlen, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
+	if (ret) {
+		printf("Error %d during SPI transaction\n", ret);
+		return ret;
+	}
+
+	if (memcmp(din + EE_OFF_MAC1, &ident, sizeof(ident)) == 0)
+		eth_env_set_enetaddr("ethaddr", din + EE_OFF_MAC1);
+
+	if (memcmp(din + EE_OFF_MAC2, &ident, sizeof(ident)) == 0)
+		eth_env_set_enetaddr("eth1addr", din + EE_OFF_MAC2);
+
+	spi_release_bus(slave);
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	u8 val;
+
+	val = in_8(ADDR_FPGA_R_BASE);
+
+	/* Verify mother board presence */
+	if (in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE) {
+		/* identify the type of mother board */
+		switch (val) {
+		case TYPE_MCR:
+			/* if at boot alarm button is pressed, delay boot */
+			if ((in_8(ADDR_FPGA_R_ALARMES_IN) & FPGA_R_ACQ_AL_FAV) == 0)
+				env_set("bootdelay", "60");
+
+			env_set("config", BOARD_MCR3000_2G);
+			env_set("hostname", BOARD_MCR3000_2G);
+			break;
+		default:
+			env_set("config", BOARD_CMPC885);
+			env_set("hostname", BOARD_CMPC885);
+			break;
+		}
+	} else {
+		printf("no mother board detected");
+		env_set("config", BOARD_CMPC885);
+		env_set("hostname", BOARD_CMPC885);
+	}
+
+	if (setup_mac())
+		printf("Error retrieving mac addresses\n");
+
+	/* Protection ON by default */
+	flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE, 0xffffffff, &flash_info[0]);
+
+	return 0;
+}
+
+static void iop_setup_mcr(void)
+{
+	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	iop8xx_t __iomem *iop = &immr->im_ioport;
+	cpm8xx_t __iomem *cp = &immr->im_cpm;
+
+	/* Wait reset on FPGA_F */
+	udelay(100);
+
+	/* We must initialize data before changing direction */
+	setbits_be16(&iop->iop_pcdat, 0x088E);
+	setbits_be16(&iop->iop_pddat, 0x0001);
+	setbits_be32(&cp->cp_pbdat, 0x00029510);
+	setbits_be32(&cp->cp_pedat, 0x00000002);
+
+	/*
+	 * PAPAR[13] = 0 [0x0004] -> GPIO: ()
+	 * PAPAR[12] = 0 [0x0008] -> GPIO: ()
+	 * PAPAR[9]  = 1 [0x0040] -> GPIO: (PCM_IN_12_MPC)
+	 * PAPAR[8]  = 1 [0x0080] -> GPIO: (PCM_OUT_12_MPC)
+	 * PAPAR[7]  = 1 [0x0100] -> GPIO: (TDM_BCLK_MPC)
+	 * PAPAR[6]  = 1 [0x0200] -> GPIO: (CLK2)
+	 */
+	clrsetbits_be16(&iop->iop_papar, 0x03CC, 0x03C0);
+
+	/*
+	 * PBODR[16] = 1 [0x00008000] -> GPIO: (PROG_FPGA_MEZZ)
+	 */
+	setbits_be16(&cp->cp_pbodr, 0x00008000);
+
+	/*
+	 * PBDIR[27] = 1 [0x00000010] -> GPIO: (WR_TEMP2)
+	 * PBDIR[26] = 1 [0x00000020] -> GPIO: (BRG02)
+	 * PBDIR[23] = 1 [0x00000100] -> GPIO: (CS_TEMP2)
+	 * PBDIR[18] = 1 [0x00002000] -> GPIO: (RTS2)
+	 * PBDIR[16] = 1 [0x00008000] -> GPIO: (PROG_FPGA_MEZZ)
+	 * PBDIR[15] = 1 [0x00010000] -> GPIO: (BRG03)
+	 * PBDIR[14] = 1 [0x00020000] -> GPIO: (CS_TEMP)
+	 */
+	setbits_be32(&cp->cp_pbdir, 0x0003A130);
+
+	/*
+	 * PBPAR[20] = 1 [0x00000800] -> GPIO: (SMRXD2)
+	 * PBPAR[17] = 0 [0x00004000] -> GPIO: (DONE_FPGA_MEZZ)
+	 * PBPAR[16] = 0 [0x00008000] -> GPIO: (PROG_FPGA_MEZZ)
+	 */
+	clrsetbits_be32(&cp->cp_pbpar, 0x0000C800, 0x00000800);
+
+	/*
+	 * PCPAR[14] = 0 [0x0002] -> GPIO: (CS_POT2)
+	 */
+	clrbits_be16(&iop->iop_pcpar, 0x0002);
+
+	/*
+	 * PDPAR[14] = 1 [0x0002] -> GPIO: (TDM_FS_MPC)
+	 * PDPAR[11] = 1 [0x0010] -> GPIO: (RXD3)
+	 * PDPAR[10] = 1 [0x0020] -> GPIO: (TXD3)
+	 * PDPAR[9]  = 1 [0x0040] -> GPIO: (TXD4)
+	 * PDPAR[7]  = 1 [0x0100] -> GPIO: (RTS3)
+	 * PDPAR[5]  = 1 [0x0400] -> GPIO: (CLK8)
+	 * PDPAR[3]  = 1 [0x1000] -> GPIO: (CLK7)
+	 */
+	setbits_be16(&iop->iop_pdpar, 0x1572);
+
+	/*
+	 * PEPAR[27] = 1 [0x00000010] -> GPIO: (R2_RXER)
+	 * PEPAR[26] = 1 [0x00000020] -> GPIO: (R2_CRS_DV)
+	 * PEPAR[25] = 1 [0x00000040] -> GPIO: (RXD4)
+	 * PEPAR[24] = 1 [0x00000080] -> GPIO: (BRG01)
+	 * PEPAR[23] = 0 [0x00000100] -> GPIO: (DONE_FPGA_RADIO)
+	 * PEPAR[22] = 1 [0x00000200] -> GPIO: (R2_RXD1)
+	 * PEPAR[21] = 1 [0x00000400] -> GPIO: (R2_RXD0)
+	 * PEPAR[20] = 1 [0x00000800] -> GPIO: (SMTXD2)
+	 * PEPAR[19] = 1 [0x00001000] -> GPIO: (R2_TXEN)
+	 * PEPAR[17] = 1 [0x00004000] -> GPIO: (CLK5)
+	 * PEPAR[16] = 1 [0x00008000] -> GPIO: (R2_REF_CLK)
+	 * PEPAR[15] = 1 [0x00010000] -> GPIO: (R2_TXD1)
+	 * PEPAR[14] = 1 [0x00020000] -> GPIO: (R2_TXD0)
+	 */
+	clrsetbits_be32(&cp->cp_pepar, 0x0003DFF0, 0x0003DEF0);
+
+	/*
+	 * PADIR[9]  = 1 [0x0040] -> GPIO: (PCM_IN_12_MPC)
+	 * PADIR[8]  = 1 [0x0080] -> GPIO: (PCM_OUT_12_MPC)
+	 * PADIR[5]  = 1 [0x0400] -> GPIO: ()
+	 */
+	setbits_be16(&iop->iop_padir, 0x04C0);
+
+	/*
+	 * PCDIR[15] = 1 [0x0001] -> GPIO: (WP_EEPROM2)
+	 * PCDIR[14] = 1 [0x0002] -> GPIO: (CS_POT2)
+	 * PCDIR[13] = 1 [0x0004] -> GPIO: (CS_POT1)
+	 * PCDIR[12] = 1 [0x0008] -> GPIO: (CS_EEPROM2)
+	 * PCDIR[8]  = 1 [0x0080] -> GPIO: (CS_CODEC_FAV)
+	 * PCDIR[4]  = 1 [0x0800] -> GPIO: (CS_CODEC_RADIO)
+	 */
+	setbits_be16(&iop->iop_pcdir, 0x088F);
+
+	/*
+	 * PDDIR[9]  = 1 [0x0040] -> GPIO: (TXD4)
+	 * PDDIR[6]  = 0 [0x0200] -> GPIO: (INIT_FPGA_RADIO)
+	 * PDDIR[2]  = x [0x2000] -> Reserved
+	 * PDDIR[1]  = 0 [0x4000] -> ODR for PD10 : (TXD3)
+	 * PDDIR[0]  = 0 [0x8000] -> ODR for PD8  : (R_MDC)
+	 */
+	clrsetbits_be16(&iop->iop_pddir, 0xC240, 0x0040);
+
+	/*
+	 * PEDIR[30] = 1 [0x00000002] -> GPIO: (FPGA_FIRMWARE)
+	 * PEDIR[27] = 1 [0x00000010] -> GPIO: (R2_RXER)
+	 * PEDIR[26] = 1 [0x00000020] -> GPIO: (R2_CRS_DV)
+	 * PEDIR[23] = 0 [0x00000100] -> GPIO: (DONE_FPGA_RADIO)
+	 * PEDIR[22] = 1 [0x00000200] -> GPIO: (R2_RXD1)
+	 * PEDIR[21] = 1 [0x00000400] -> GPIO: (R2_RXD0)
+	 * PEDIR[19] = 1 [0x00001000] -> GPIO: (R2_TXEN)
+	 * PEDIR[18] = 1 [0x00002000] -> GPIO: (PROG_FPGA_RADIO)
+	 * PEDIR[16] = 1 [0x00008000] -> GPIO: (R2_REF_CLK)
+	 * PEDIR[15] = 1 [0x00010000] -> GPIO: (R2_TXD1)
+	 * PEDIR[14] = 1 [0x00020000] -> GPIO: (R2_TXD0)
+	 */
+	clrsetbits_be32(&cp->cp_pedir, 0x0003B732, 0x0003B632);
+
+	/*
+	 * PAODR[10] = 1 [0x0020] -> GPIO: (INIT_FPGA_F)
+	 */
+	setbits_be16(&iop->iop_paodr, 0x0020); // set_bit
+
+	/*
+	 * PEODR[30] = 1 [0x00000002] -> GPIO: (FPGA_FIRMWARE)
+	 * PEODR[18] = 1 [0x00002000] -> GPIO: (FPGA_RADIO)
+	 */
+	setbits_be32(&cp->cp_peodr, 0x00002002);
+
+	/*
+	 * PESO[24] = 1 [0x00000080] -> GPIO: (BRG01)
+	 * PESO[23] = 0 [0x00000100] -> GPIO: (DONE_FPGA_RADIO)
+	 * PESO[20] = 1 [0x00000800] -> GPIO: (SMTXD2)
+	 * PESO[19] = 1 [0x00001000] -> GPIO: (R2_TXEN)
+	 * PESO[15] = 1 [0x00010000] -> GPIO: (R2_TXD1)
+	 * PESO[14] = 1 [0x00020000] -> GPIO: (R2_TXD0)
+	 */
+	clrsetbits_be32(&cp->cp_peso, 0x00031980, 0x00031880);
+
+	/* Disable CS for device */
+	/* PROGFPGA down */
+	clrbits_be32(&cp->cp_pbdat, 0x00008000);
+
+	/* PROGFPGA down */
+	clrbits_be32(&cp->cp_pedat, 0x00002000);
+	udelay(1);	/* Wait more than 300ns */
+
+	/*
+	 * We do not set the PROG signal of the C4E1 because
+	 * there is a conflic with the CS of the EEPROM.
+	 * I don't know why there is not the same problem
+	 * with the FPGA_R
+	 */
+
+	/* PROGFPGA up	*/
+	setbits_be32(&cp->cp_pedat, 0x00002000);
+}
+
+static void iop_setup_cmpc885(void)
+{
+	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	iop8xx_t __iomem *iop = &immr->im_ioport;
+	cpm8xx_t __iomem *cp = &immr->im_cpm;
+
+	/* We must initialize data before changing direction */
+	out_be16(&iop->iop_pcdat, 0x0000);
+	out_be16(&iop->iop_pddat, 0x0001);
+
+	out_be32(&cp->cp_pbdat, 0x00021400);
+	out_be32(&cp->cp_pedat, 0x00000000);
+
+	/*
+	 * PAPAR[13] = 0 [0x0004] -> GPIO: ()
+	 * PAPAR[12] = 0 [0x0008] -> GPIO: ()
+	 * PAPAR[9]  = 0 [0x0040] -> GPIO: ()
+	 * PAPAR[8]  = 0 [0x0080] -> GPIO: ()
+	 * PAPAR[7]  = 0 [0x0100] -> GPIO: ()
+	 * PAPAR[6]  = 0 [0x0200] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_papar, 0x03CC);
+
+	/*
+	 * PBPAR[20] = 0 [0x00000800] -> GPIO: ()
+	 * PBPAR[17] = 0 [0x00004000] -> GPIO: ()
+	 * PBPAR[16] = 0 [0x00008000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_pbpar, 0x0000C800);
+
+	/*
+	 * PCPAR[14] = 0 [0x0002] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_pcpar, 0x0002);
+
+	/*
+	 * PDPAR[14] = 0 [0x0002] -> GPIO: ()
+	 * PDPAR[11] = 0 [0x0010] -> GPIO: ()
+	 * PDPAR[10] = 0 [0x0020] -> GPIO: ()
+	 * PDPAR[9]  = 0 [0x0040] -> GPIO: ()
+	 * PDPAR[7]  = 0 [0x0100] -> GPIO: ()
+	 * PDPAR[5]  = 0 [0x0400] -> GPIO: ()
+	 * PDPAR[3]  = 0 [0x1000] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_pdpar, 0x1572);
+
+	/*
+	 * PEPAR[27] = 0 [0x00000010] -> GPIO: ()
+	 * PEPAR[26] = 0 [0x00000020] -> GPIO: ()
+	 * PEPAR[25] = 0 [0x00000040] -> GPIO: ()
+	 * PEPAR[24] = 0 [0x00000080] -> GPIO: ()
+	 * PEPAR[23] = 0 [0x00000100] -> GPIO: ()
+	 * PEPAR[22] = 0 [0x00000200] -> GPIO: ()
+	 * PEPAR[21] = 0 [0x00000400] -> GPIO: ()
+	 * PEPAR[20] = 0 [0x00000800] -> GPIO: ()
+	 * PEPAR[19] = 0 [0x00001000] -> GPIO: ()
+	 * PEPAR[17] = 0 [0x00004000] -> GPIO: ()
+	 * PEPAR[16] = 0 [0x00008000] -> GPIO: ()
+	 * PEPAR[15] = 0 [0x00010000] -> GPIO: ()
+	 * PEPAR[14] = 0 [0x00020000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_pepar, 0x0003DFF0);
+
+	/*
+	 * PADIR[9]  = 0 [0x0040] -> GPIO: ()
+	 * PADIR[8]  = 0 [0x0080] -> GPIO: ()
+	 * PADIR[5]  = 0 [0x0400] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_padir, 0x04C0);
+
+	/*
+	 * In/Out or per. Function 0/1
+	 * PBDIR[27] = 0 [0x00000010] -> GPIO: ()
+	 * PBDIR[26] = 0 [0x00000020] -> GPIO: ()
+	 * PBDIR[23] = 0 [0x00000100] -> GPIO: ()
+	 * PBDIR[17] = 0 [0x00004000] -> GPIO: ()
+	 * PBDIR[16] = 0 [0x00008000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_pbdir, 0x0000C130);
+
+	/*
+	 * PCDIR[15] = 0 [0x0001] -> GPIO: ()
+	 * PCDIR[14] = 0 [0x0002] -> GPIO: ()
+	 * PCDIR[13] = 0 [0x0004] -> GPIO: ()
+	 * PCDIR[12] = 0 [0x0008] -> GPIO: ()
+	 * PCDIR[8]  = 0 [0x0080] -> GPIO: ()
+	 * PCDIR[4]  = 0 [0x0800] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_pcdir, 0x088F);
+
+	/*
+	 * PDDIR[9]  = 0 [0x0040] -> GPIO: ()
+	 * PDDIR[6]  = 0 [0x0200] -> GPIO: ()
+	 * PDDIR[2]  = x [0x2000] -> Reserved
+	 * PDDIR[1]  = 0 [0x4000] -> ODR for PD10 : ()
+	 * PDDIR[0]  = 0 [0x8000] -> ODR for PD8  : (R_MDC)
+	 */
+	clrbits_be16(&iop->iop_pddir, 0xC240);
+
+	/*
+	 * PEDIR[30] = 0 [0x00000002] -> GPIO: ()
+	 * PEDIR[27] = 0 [0x00000010] -> GPIO: ()
+	 * PEDIR[26] = 0 [0x00000020] -> GPIO: ()
+	 * PEDIR[23] = 0 [0x00000100] -> GPIO: ()
+	 * PEDIR[22] = 0 [0x00000200] -> GPIO: ()
+	 * PEDIR[21] = 0 [0x00000400] -> GPIO: ()
+	 * PEDIR[19] = 0 [0x00001000] -> GPIO: ()
+	 * PEDIR[18] = 0 [0x00002000] -> GPIO: ()
+	 * PEDIR[16] = 0 [0x00008000] -> GPIO: ()
+	 * PEDIR[15] = 0 [0x00010000] -> GPIO: ()
+	 * PEDIR[14] = 0 [0x00020000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_pedir, 0x0003B732);
+
+	/*
+	 * PAODR[10] = 0 [0x0020] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_paodr, 0x0020);
+
+	/*
+	 * PBODR[16] = 0 [0x00008000] -> GPIO: ()
+	 */
+	clrbits_be16(&cp->cp_pbodr, 0x00008000);
+
+	/*
+	 * PEODR[30] = 0 [0x00000002] -> GPIO: ()
+	 * PEODR[18] = 0 [0x00002000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_peodr, 0x00002002);
+
+	/*
+	 * PESO[24] = 0 [0x00000080] -> GPIO: ()
+	 * PESO[23] = 0 [0x00000100] -> GPIO: ()
+	 * PESO[20] = 0 [0x00000800] -> GPIO: ()
+	 * PESO[19] = 0 [0x00001000] -> GPIO: ()
+	 * PESO[15] = 0 [0x00010000] -> GPIO: ()
+	 * PESO[14] = 0 [0x00020000] -> GPIO: ()
+	 */
+	clrbits_be32(&cp->cp_peso, 0x00031980);
+}
+
+int board_early_init_f(void)
+{
+	return 0;
+}
+
+/* Specific board initialization */
+int board_early_init_r(void)
+{
+	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	iop8xx_t __iomem *iop = &immr->im_ioport;
+	cpm8xx_t __iomem *cp = &immr->im_cpm;
+
+	/* MPC885 Port settings common to all boards */
+	setbits_be16(&iop->iop_padat, 0x0000);
+
+	/* Port A (MPC885 reference manual - 34.2) */
+	/*
+	 * In/Out or per. Function 0/1
+	 * PADIR[15] = 0 [0x0001] -> GPIO: (USB_RXD)
+	 * PADIR[14] = 0 [0x0002] -> GPIO: (USB_OE)
+	 * PADIR[13] = 0 [0x0004] -> GPIO: ()
+	 * PADIR[12] = 0 [0x0008] -> GPIO: ()
+	 * PADIR[11] = 1 [0x0010] -> GPIO: (R1_TXD0)
+	 * PADIR[10] = 0 [0x0020] -> GPIO: ()
+	 * PADIR[7]  = 0 [0x0100] -> GPIO: ()
+	 * PADIR[6]  = 0 [0x0200] -> GPIO: ()
+	 * PADIR[4]  = 1 [0x0800] -> GPIO: (R1_TXD1)
+	 * PADIR[3]  = 0 [0x1000] -> GPIO: (R1_RXER)
+	 * PADIR[2]  = 0 [0x2000] -> GPIO: (R1_CRS_DV)
+	 * PADIR[1]  = 0 [0x4000] -> GPIO: (R1_RXD0)
+	 * PADIR[0]  = 0 [0x8000] -> GPIO: (R1_RXD1)
+	 */
+	clrsetbits_be16(&iop->iop_padir, 0xFB3F, 0x0810);
+
+	/*
+	 * Open drain or active output
+	 * PAODR[15] = x [0x0001]
+	 * PAODR[14] = 0 [0x0002]
+	 * PAODR[13] = x [0x0004]
+	 * PAODR[12] = 0 [0x0008]
+	 * PAODR[11] = 0 [0x0010]
+	 * PAODR[9]  = 0 [0x0040]
+	 * PAODR[8]  = 0 [0x0080]
+	 * PAODR[7]  = 0 [0x0100]
+	 */
+	clrbits_be16(&iop->iop_paodr, 0x01DF);
+
+	/*
+	 * GPIO or per. Function
+	 * PAPAR[15] = 1 [0x0001] -> GPIO: (USB_RXD)
+	 * PAPAR[14] = 1 [0x0002] -> GPIO: (USB_OE)
+	 * PAPAR[11] = 1 [0x0010] -> GPIO: (R1_TXD0)
+	 * PAPAR[10] = 0 [0x0020] -> GPIO: (INIT_FPGA_F)
+	 * PAPAR[5]  = 0 [0x0400] -> GPIO: ()
+	 * PAPAR[4]  = 1 [0x0800] -> GPIO: (R1_TXD1)
+	 * PAPAR[3]  = 1 [0x1000] -> GPIO: (R1_RXER)
+	 * PAPAR[2]  = 1 [0x2000] -> GPIO: (R1_CRS_DV)
+	 * PAPAR[1]  = 1 [0x4000] -> GPIO: (R1_RXD0)
+	 * PAPAR[0]  = 1 [0x8000] -> GPIO: (R1_RXD1)
+	 */
+	clrsetbits_be16(&iop->iop_papar, 0xFC33, 0xF813);
+
+	/* Port B (MPC885 reference manual - 34.3) */
+	/*
+	 * In/Out or per. Function 0/1
+	 * PBDIR[31] = 0 [0x00000001] -> GPIO: (R1_REF_CLK)
+	 * PBDIR[30] = 1 [0x00000002] -> GPIO: (CLK)
+	 * PBDIR[29] = 1 [0x00000004] -> GPIO: (MOSI)
+	 * PBDIR[28] = 1 [0x00000008] -> GPIO: (MISO)
+	 * PBDIR[25] = 0 [0x00000040] -> GPIO: (SMTXD1)
+	 * PBDIR[24] = 0 [0x00000080] -> GPIO: (SMRXD1)
+	 * PBDIR[22] = 0 [0x00000200] -> GPIO: (INIT_FPGA_MEZZ)
+	 * PBDIR[21] = 1 [0x00000400] -> GPIO: (CS_EEPROM)
+	 * PBDIR[20] = 0 [0x00000800] -> GPIO: (SMRXD2)
+	 * PBDIR[19] = 1 [0x00001000] -> GPIO: (WR_TEMP)
+	 * PBDIR[17] = 0 [0x00004000] -> GPIO: (DONE_FPGA_MEZZ)
+	 */
+	clrsetbits_be32(&cp->cp_pbdir, 0x00005ECF, 0x0000140E);
+
+	/*
+	 * Open drain or active output
+	 * PBODR[31] = 0 [0x00000001] -> GPIO: (R1_REF_CLK)
+	 * PBODR[30] = 0 [0x00000002] -> GPIO: (CLK)
+	 * PBODR[29] = 0 [0x00000004] -> GPIO: (MOSI)
+	 * PBODR[28] = 0 [0x00000008] -> GPIO: (MISO)
+	 * PBODR[27] = 0 [0x00000010] -> GPIO: (WR_TEMP2)
+	 * PBODR[26] = 0 [0x00000020] -> GPIO: (BRG02)
+	 * PBODR[25] = 0 [0x00000040] -> GPIO: (SMTXD1)
+	 * PBODR[24] = 0 [0x00000080] -> GPIO: (SMRXD1)
+	 * PBODR[23] = 0 [0x00000100] -> GPIO: (CS_TEMP2)
+	 * PBODR[22] = 0 [0x00000200] -> GPIO: (INIT_FPGA_MEZZ)
+	 * PBODR[21] = 0 [0x00000400] -> GPIO: (CS_EEPROM)
+	 * PBODR[20] = 0 [0x00000800] -> GPIO: (SMRXD2)
+	 * PBODR[19] = 0 [0x00001000] -> GPIO: (WR_TEMP)
+	 * PBODR[18] = 0 [0x00002000] -> GPIO: (RTS2)
+	 * PBODR[17] = 0 [0x00004000] -> GPIO: (DONE_FPGA_MEZZ)
+	 */
+	clrbits_be16(&cp->cp_pbodr, 0x00007FFF);
+
+	/*
+	 * GPIO or per. Function
+	 * PBPAR[31] = 1 [0x00000001] -> GPIO: (R1_REF_CLK)
+	 * PBPAR[30] = 1 [0x00000002] -> GPIO: (CLK)
+	 * PBPAR[29] = 1 [0x00000004] -> GPIO: (MOSI)
+	 * PBPAR[28] = 1 [0x00000008] -> GPIO: (MISO)
+	 * PBPAR[27] = 0 [0x00000010] -> GPIO: (WR_TEMP2)
+	 * PBPAR[26] = 0 [0x00000020] -> GPIO: (BRG02)
+	 * PBPAR[25] = 1 [0x00000040] -> GPIO: (SMTXD1)
+	 * PBPAR[24] = 1 [0x00000080] -> GPIO: (SMRXD1)
+	 * PBPAR[23] = 0 [0x00000100] -> GPIO: (CS_TEMP2)
+	 * PBPAR[22] = 0 [0x00000200] -> GPIO: (INIT_FPGA_MEZZ)
+	 * PBPAR[21] = 0 [0x00000400] -> GPIO: (CS_EEPROM)
+	 * PBPAR[19] = 0 [0x00001000] -> GPIO: (WR_TEMP)
+	 * PBPAR[18] = 0 [0x00002000] -> GPIO: (RTS2)
+	 * PBPAR[15] = 0 [0x00010000] -> GPIO: (BRG03)
+	 * PBPAR[14] = 0 [0x00020000] -> GPIO: (CS_TEMP)
+	 */
+	clrsetbits_be32(&cp->cp_pbpar, 0x000337FF, 0x000000CF);
+
+	/* Port C (MPC885 Reference Manual - 34.4) */
+	/*
+	 * In/Out or per. Function 0/1
+	 * PCDIR[11] = 0 [0x0010] -> GPIO: (USB_RXP)
+	 * PCDIR[10] = 0 [0x0020] -> GPIO: (USB_RXN)
+	 * PCDIR[9]  = 0 [0x0040] -> GPIO: (CTS2)
+	 * PCDIR[7]  = 1 [0x0100] -> GPIO: (USB_TXP)
+	 * PCDIR[6]  = 1 [0x0200] -> GPIO: (USB_TXN)
+	 * PCDIR[5]  = 0 [0x0400] -> GPIO: (CTS3)
+	 */
+	clrsetbits_be16(&iop->iop_pcdir, 0x0770, 0x0300);
+
+	/*
+	 * GPIO or per. Function
+	 * PCPAR[15] = 0 [0x0001] -> GPIO: (WP_EEPROM2)
+	 * PCPAR[13] = 0 [0x0004] -> GPIO: (CS_POT1)
+	 * PCPAR[12] = 0 [0x0008] -> GPIO: (CS_EEPROM2)
+	 * PCPAR[11] = 0 [0x0010] -> GPIO: (USB_RXP)
+	 * PCPAR[10] = 0 [0x0020] -> GPIO: (USB_RXN)
+	 * PCPAR[9]  = 0 [0x0040] -> GPIO: (CTS2)
+	 * PCPAR[8]  = 0 [0x0080] -> GPIO: (CS_CODEC_FAV)
+	 * PCPAR[7]  = 1 [0x0100] -> GPIO: (USB_TXP)
+	 * PCPAR[6]  = 1 [0x0200] -> GPIO: (USB_TXN)
+	 * PCPAR[5]  = 0 [0x0400] -> GPIO: (CTS3)
+	 * PCPAR[4]  = 0 [0x0800] -> GPIO: (CS_CODEC_RADIO)
+	 */
+	clrsetbits_be16(&iop->iop_pcpar, 0x0FFD, 0x0300);
+
+	/*
+	 * Special Option register
+	 * PCSO[15] = 0 [0x0001] -> GPIO: (WP_EEPROM2)
+	 * PCSO[14] = 0 [0x0002] -> GPIO: (CS_POT2)
+	 * PCSO[13] = x [0x0004] -> Reserved
+	 * PCSO[12] = x [0x0008] -> Reserved
+	 * PCSO[11] = 1 [0x0010] -> GPIO: (USB_RXP)
+	 * PCSO[10] = 1 [0x0020] -> GPIO: (USB_RXN)
+	 * PCSO[9]  = 1 [0x0040] -> GPIO: (CTS2)
+	 * PCSO[8]  = 0 [0x0080] -> GPIO: (CS_CODEC_FAV)
+	 * PCSO[7]  = 0 [0x0100] -> GPIO: (USB_TXP)
+	 * PCSO[6]  = 0 [0x0200] -> GPIO: (USB_TXN)
+	 * PCSO[5]  = 1 [0x0400] -> GPIO: (CTS3)
+	 * PCSO[4]  = 0 [0x0800] -> GPIO: (CS_CODEC_RADIO)
+	 */
+	clrsetbits_be16(&iop->iop_pcso, 0x0FF3, 0x0470);
+
+	/*
+	 * Interrupt or IO
+	 * PCINT[15] = 0 [0x0001] -> GPIO: ()
+	 * PCINT[14] = 0 [0x0002] -> GPIO: ()
+	 * PCINT[13] = 0 [0x0004] -> GPIO: ()
+	 * PCINT[12] = 0 [0x0008] -> GPIO: ()
+	 * PCINT[11] = 0 [0x0010] -> GPIO: (USB_RXP)
+	 * PCINT[10] = 0 [0x0020] -> GPIO: (USB_RXN)
+	 * PCINT[9]  = 0 [0x0040] -> GPIO: ()
+	 * PCINT[8]  = 0 [0x0080] -> GPIO: ()
+	 * PCINT[7]  = 0 [0x0100] -> GPIO: (USB_TXP)
+	 * PCINT[6]  = 0 [0x0200] -> GPIO: (USB_TXN)
+	 * PCINT[5]  = 0 [0x0400] -> GPIO: ()
+	 * PCINT[4]  = 0 [0x0800] -> GPIO: ()
+	 */
+	clrbits_be16(&iop->iop_pcint, 0x0FFF);
+
+	/* Port D (MPC885 Reference Manual - 34.5) */
+	/*
+	 * In/Out or per. Function 0/1
+	 * PDDIR[15] = 1 [0x0001] -> GPIO: (CS_NAND)
+	 * PDDIR[14] = 0 [0x0002] -> GPIO: (TDM_FS_MPC)
+	 * PDDIR[13] = 1 [0x0004] -> GPIO: (ALE_NAND)
+	 * PDDIR[12] = 1 [0x0008] -> GPIO: (CLE_NAND)
+	 * PDDIR[11] = 0 [0x0010] -> GPIO: (RXD3)
+	 * PDDIR[10] = 0 [0x0020] -> GPIO: (TXD3)
+	 * PDDIR[9]  = 1 [0x0040] -> GPIO: (TXD4)
+	 * PDDIR[8]  = 0 [0x0080] -> GPIO: (R_MDC)
+	 * PDDIR[7]  = 0 [0x0100] -> GPIO: (RTS3)
+	 * PDDIR[5]  = 0 [0x0400] -> GPIO: (CLK8)
+	 * PDDIR[4]  = 0 [0x0800] -> GPIO: (CLK4)
+	 * PDDIR[3]  = 0 [0x1000] -> GPIO: (CLK7)
+	 */
+	clrsetbits_be16(&iop->iop_pddir, 0x1DFF, 0x004D);
+
+	/*
+	 * GPIO or per. Function
+	 * PDPAR[15] = 0 [0x0001] -> GPIO: (CS_NAND)
+	 * PDPAR[13] = 0 [0x0004] -> GPIO: (ALE_NAND)
+	 * PDPAR[12] = 0 [0x0008] -> GPIO: (CLE_NAND)
+	 * PDPAR[8]  = 1 [0x0080] -> GPIO: (R_MDC)
+	 * PDPAR[6]  = 0 [0x0200] -> GPIO: (INIT_FPGA_RADIO)
+	 * PDPAR[4]  = 1 [0x0800] -> GPIO: (CLK4)
+	 */
+	clrsetbits_be16(&iop->iop_pdpar, 0x0A8D, 0x0880);
+
+	/* Port E (MPC885 Reference Manual - 34.6) */
+	/*
+	 * In/Out or per. Function 0/1
+	 * PEDIR[31] = 0 [0x00000001] -> GPIO: (DONE_FPGA_FIRMWARE)
+	 * PEDIR[29] = 1 [0x00000004] -> GPIO: (USB_SPEED)
+	 * PEDIR[28] = 1 [0x00000008] -> GPIO: (USB_SUSPEND)
+	 * PEDIR[25] = 0 [0x00000040] -> GPIO: (RXD4)
+	 * PEDIR[24] = 0 [0x00000080] -> GPIO: (BRG01)
+	 * PEDIR[20] = 0 [0x00000800] -> GPIO: (SMTXD2)
+	 * PEDIR[17] = 0 [0x00004000] -> GPIO: (CLK5)
+	 */
+	clrsetbits_be32(&cp->cp_pedir, 0x000048CD, 0x0000000C);
+
+	/*
+	 * open drain or active output
+	 * PEODR[31] = 0 [0x00000001] -> GPIO: (DONE_FPGA_FIRMWARE)
+	 * PEODR[29] = 0 [0x00000004] -> GPIO: (USB_SPEED)
+	 * PEODR[28] = 1 [0x00000008] -> GPIO: (USB_SUSPEND)
+	 * PEODR[27] = 0 [0x00000010] -> GPIO: (R2_RXER)
+	 * PEODR[26] = 0 [0x00000020] -> GPIO: (R2_CRS_DV)
+	 * PEODR[25] = 0 [0x00000040] -> GPIO: (RXD4)
+	 * PEODR[24] = 0 [0x00000080] -> GPIO: (BRG01)
+	 * PEODR[23] = 0 [0x00000100] -> GPIO: (DONE_FPGA_RADIO)
+	 * PEODR[22] = 0 [0x00000200] -> GPIO: (R2_RXD1)
+	 * PEODR[21] = 0 [0x00000400] -> GPIO: (R2_RXD0)
+	 * PEODR[20] = 0 [0x00000800] -> GPIO: (SMTXD2)
+	 * PEODR[19] = 0 [0x00001000] -> GPIO: (R2_TXEN)
+	 * PEODR[17] = 0 [0x00004000] -> GPIO: (CLK5)
+	 * PEODR[16] = 0 [0x00008000] -> GPIO: (R2_REF_CLK)
+	 */
+	clrsetbits_be32(&cp->cp_peodr, 0x0000DFFD, 0x00000008);
+
+	/*
+	 * GPIO or per. Function
+	 * PEPAR[31] = 0 [0x00000001] -> GPIO: (DONE_FPGA_FIRMWARE)
+	 * PEPAR[30] = 0 [0x00000002] -> GPIO: (PROG_FPGA_FIRMWARE)
+	 * PEPAR[29] = 0 [0x00000004] -> GPIO: (USB_SPEED)
+	 * PEPAR[28] = 0 [0x00000008] -> GPIO: (USB_SUSPEND)
+	 * PEPAR[18] = 0 [0x00002000] -> GPIO: (PROG_FPGA_RADIO)
+	 */
+	clrbits_be32(&cp->cp_pepar, 0x0000200F);
+
+	/*
+	 * Special Option register
+	 * PESO[31] = 0 [0x00000001] -> GPIO: (DONE_FPGA_FIRMWARE)
+	 * PESO[30] = 0 [0x00000002] -> GPIO: (PROG_FPGA_FIRMWARE)
+	 * PESO[29] = 0 [0x00000004] -> GPIO: (USB_SPEED)
+	 * PESO[28] = 0 [0x00000008] -> GPIO: (USB_SUSPEND)
+	 * PESO[27] = 0 [0x00000010] -> GPIO: (R2_RXER)
+	 * PESO[26] = 0 [0x00000020] -> GPIO: (R2_CRS_DV)
+	 * PESO[25] = 0 [0x00000040] -> GPIO: (RXD4)
+	 * PESO[22] = 0 [0x00000200] -> GPIO: (R2_RXD1)
+	 * PESO[21] = 0 [0x00000400] -> GPIO: (R2_RXD0)
+	 * PESO[18] = 0 [0x00002000] -> GPIO: (PROG_FPGA_RADIO)
+	 * PESO[17] = 0 [0x00004000] -> GPIO: (CLK5)
+	 * PESO[16] = 0 [0x00008000] -> GPIO: (R2_REF_CLK)
+	 */
+	clrbits_be32(&cp->cp_peso, 0x0000E67F);
+
+	/* Is a motherboard present ? */
+	if (in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE) {
+		/* Initialize signal PROG_FPGA_FIRMWARE */
+		out_be32(&cp->cp_pedat, 0x00000002);
+		out_be32(&cp->cp_peodr, 0x00000002);
+		out_be32(&cp->cp_pedir, 0x00000002);
+
+		/* Check if fpga firmware is loaded */
+		if (!(in_be32(&cp->cp_pedat) & 0x00000001)) {
+			printf("Reloading FPGA firmware.\n");
+
+			/* Load fpga firmware */
+			/* Activate PROG_FPGA_FIRMWARE for 1 usec */
+			clrbits_be32(&cp->cp_pedat, 0x00000002);
+			udelay(1);
+			setbits_be32(&cp->cp_pedat, 0x00000002);
+
+			/* Wait 200 msec and check DONE_FPGA_FIRMWARE */
+			mdelay(200);
+			if (!(in_be32(&cp->cp_pedat) & 0x00000001)) {
+				for (;;) {
+					printf("error loading firmware.\n");
+					mdelay(500);
+				}
+			}
+
+			/* Send a reset signal and wait for 20 msec */
+			clrbits_be16(ADDR_CPLD_R_RESET, R_RST_STATUS);
+			mdelay(20);
+			setbits_be16(ADDR_CPLD_R_RESET, R_RST_STATUS);
+		}
+
+		/* Wait 300 msec and check the reset state */
+		mdelay(300);
+		if (!(in_be16(ADDR_CPLD_R_RESET) & R_RESET_STATUS)) {
+			for (;;) {
+				printf("Could not reset FPGA.\n");
+				mdelay(500);
+			}
+		}
+
+		/* is FPGA firmware loaded ? */
+		if (!(in_be32(&cp->cp_pedat) & 0x00000001)) {
+			printf("Reloading FPGA firmware\n");
+
+			/* Load FPGA firmware */
+			/* Activate PROG_FPGA_FIRMWARE for 1 usec */
+			clrbits_be32(&cp->cp_pedat, 0x00000002);
+			udelay(1);
+			setbits_be32(&cp->cp_pedat, 0x00000002);
+
+			/* Wait 200ms before checking DONE_FPGA_FIRMWARE */
+			mdelay(200);
+		}
+
+		/* Identify the type of mother board */
+		switch (in_8(ADDR_FPGA_R_BASE)) {
+		case TYPE_MCR:
+			iop_setup_mcr();
+			break;
+
+		default:
+			break;
+		}
+	/* CMPC885 board alone */
+	} else {
+		iop_setup_cmpc885();
+	}
+
+	return 0;
+}
diff --git a/board/cssi/CMPC885/nand.c b/board/cssi/CMPC885/nand.c
new file mode 100644
index 00000000000..38100046df8
--- /dev/null
+++ b/board/cssi/CMPC885/nand.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010-2020 CS Group
+ * Florent Trinh Thai <florent.trinh-thai at c-s.fr>
+ * Christophe Leroy <christophe.leroy at c-s.fr>
+ * Charles Frey <charles.frey at c-s.fr>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <nand.h>
+#include <linux/bitops.h>
+#include <linux/mtd/rawnand.h>
+#include <asm/io.h>
+
+#define BIT_CLE		BIT(3)
+#define BIT_ALE		BIT(2)
+#define BIT_NCE		BIT(0)
+
+static u32 nand_mask(unsigned int ctrl)
+{
+	return ((ctrl & NAND_CLE) ? BIT_CLE : 0) |
+	       ((ctrl & NAND_ALE) ? BIT_ALE : 0) |
+	       (!(ctrl & NAND_NCE) ? BIT_NCE : 0);
+}
+
+static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
+{
+	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	struct nand_chip *chip = mtd_to_nand(mtdinfo);
+
+	if (ctrl & NAND_CTRL_CHANGE)
+		clrsetbits_be16(&immr->im_ioport.iop_pddat,
+				BIT_CLE | BIT_ALE | BIT_NCE, nand_mask(ctrl));
+
+	if (cmd != NAND_CMD_NONE)
+		out_8(chip->IO_ADDR_W, cmd);
+}
+
+int board_nand_init(struct nand_chip *chip)
+{
+	chip->chip_delay	= 60;
+	chip->ecc.mode		= NAND_ECC_SOFT;
+	chip->cmd_ctrl		= nand_hwcontrol;
+
+	return 0;
+}
diff --git a/board/cssi/CMPC885/sdram.c b/board/cssi/CMPC885/sdram.c
new file mode 100644
index 00000000000..1a4daf066de
--- /dev/null
+++ b/board/cssi/CMPC885/sdram.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 CS Group
+ * Charles Frey <charles.frey at c-s.fr>
+ */
+
+#include <common.h>
+#include <linux/sizes.h>
+#include <linux/delay.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mpc8xx.h>
+#include <watchdog.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ADDR_CPLD_R_TYPE	((unsigned char __iomem *)CONFIG_CPLD_BASE + 3)
+
+#define _NOT_USED_  0xFFFFEC04
+
+static const uint sdram_table[] = {
+	/* DRAM - single read. (offset 0 in upm RAM) */
+	0x0F0CEC04, 0x0FFFEC04, 0x00AF2C04, 0x0FFFEC00,
+	0x0FFCE004, 0xFFFFEC05, _NOT_USED_, _NOT_USED_,
+
+	/* DRAM - burst read. (offset 8 in upm RAM) */
+	0x0F0CEC04, 0x0FFFEC04, 0x00AF2C04, 0x00FFEC00,
+	0x00FFEC00, 0x00FFEC00, 0x0FFCE000, 0x1FFFEC05,
+
+	/* DRAM - Precharge all banks. (offset 16 in upm RAM) */
+	_NOT_USED_, 0x0FFCE004, 0x1FFFEC05, _NOT_USED_,
+
+	/* DRAM - NOP. (offset 20 in upm RAM) */
+	0x1FFFEC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* DRAM - single write. (offset 24 in upm RAM) */
+	0x0F0CEC04, 0x0FFFEC00, 0x00AF2004, 0x0FFFEC04,
+	0x0FFCE004, 0x0FFFEC04, 0xFFFFEC05, _NOT_USED_,
+
+	/* DRAM - burst write. (offset 32 in upm RAM) */
+	0x0F0CEC04, 0x0FFFEC00, 0x00AF2000, 0x00FFEC00,
+	0x00FFEC00, 0x00FFEC04, 0x0FFFEC04, 0x0FFCE004,
+	0x1FFFEC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* refresh  (offset 48 in upm RAM) */
+	0x0FFDE404, 0x0FFEAC04, 0x0FFD6C84, 0x0FFFEC04,
+	0x0FFFEC04, 0x0FFFEC04, 0x0FFFEC04, 0x1FFFEC85,
+
+	/* init (offset 56 in upm RAM) */
+	0x0FEEA874, 0x0FBD6474, 0x1FFFEC45, _NOT_USED_,
+
+	/* exception. (offset 60 in upm RAM) */
+	0x0FFCE004, 0xFFFFEC05, _NOT_USED_, _NOT_USED_
+};
+
+/* SDRAM initialization */
+int dram_init(void)
+{
+	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	memctl8xx_t __iomem *memctl = &immap->im_memctl;
+	u32 max_size, mamr;
+	u8 val;
+
+	printf("UPMA init for SDRAM (CAS latency 2), ");
+	printf("init address 0x%08x, size ", (int)dram_init);
+
+	/* Verify the SDRAM size of the board */
+	val = (in_8(ADDR_CPLD_R_TYPE) & 0x30) >> 4;
+
+	if (val == 0x03 || val == 0x00) {
+		max_size	= 64	* SZ_1M;	/* 64 Mo of SDRAM */
+		mamr		= 0x20104000;
+	} else {
+		max_size	= 128	* SZ_1M;	/* 128 Mo of SDRAM */
+		mamr		= 0x20206000;
+	}
+
+	/* Configure CS1 */
+	out_be32(&memctl->memc_or1,
+		 ~(max_size - 1) | OR_CSNT_SAM | OR_ACS_DIV2);
+	out_be32(&memctl->memc_br1, CONFIG_SYS_SDRAM_BASE | BR_MS_UPMA | BR_V);
+
+	/* Configure UPMA for CS1 */
+	upmconfig(UPMA, (uint *)sdram_table, ARRAY_SIZE(sdram_table));
+
+	out_be16(&memctl->memc_mptpr, MPTPR_PTP_DIV32);
+	/* disable refresh */
+	out_be32(&memctl->memc_mamr, mamr);
+	udelay(100);
+
+	/* NOP to maintain DQM high */
+	out_be32(&memctl->memc_mcr, 0x80002114);
+	udelay(200);
+
+	out_be32(&memctl->memc_mcr, 0x80002111); /* PRECHARGE cmd */
+	out_be32(&memctl->memc_mcr, 0x80002830); /* AUTO REFRESH cmd */
+	out_be32(&memctl->memc_mar, 0x00000088);
+	out_be32(&memctl->memc_mcr, 0x80002138);
+
+	/* Enable refresh */
+	setbits_be32(&memctl->memc_mamr, MAMR_PTAE);
+
+	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, max_size);
+
+	return 0;
+}
diff --git a/board/cssi/CMPC885/u-boot.lds b/board/cssi/CMPC885/u-boot.lds
new file mode 100644
index 00000000000..53f616fcfe1
--- /dev/null
+++ b/board/cssi/CMPC885/u-boot.lds
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2010-2020 CS Group
+ * Christophe Leroy <christophe.leroy at c-s.fr>
+ *
+ * (C) Copyright 2001-2003
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * Modified by Yuli Barcohen <yuli at arabellasw.com>
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+	/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.text          :
+	{
+		arch/powerpc/cpu/mpc8xx/start.o	(.text)
+		arch/powerpc/cpu/mpc8xx/traps.o	(.text*)
+		arch/powerpc/lib/built-in.o		(.text*)
+		drivers/net/built-in.o		(.text*)
+
+		. = DEFINED(env_offset) ? env_offset : .;
+		env/embedded.o			(.text.environment)
+
+		*(.text)
+	}
+	_etext = .;
+	PROVIDE (etext = .);
+	.rodata    :
+	{
+		*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+	}
+
+	/* Read-write section, merged into data segment: */
+	. = (. + 0x0FFF) & 0xFFFFF000;
+	_erotext = .;
+	PROVIDE (erotext = .);
+	.reloc   :
+	{
+		_GOT2_TABLE_ = .;
+		KEEP(*(.got2))
+		KEEP(*(.got))
+		_FIXUP_TABLE_ = .;
+		KEEP(*(.fixup))
+	}
+	__got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
+	__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+	.data    :
+	{
+		*(.data*)
+		*(.sdata*)
+	}
+	_edata  =  .;
+	PROVIDE (edata = .);
+
+	. = .;
+
+	. = ALIGN(4);
+	__u_boot_list : {
+		KEEP(*(SORT(__u_boot_list*)));
+	}
+
+	. = .;
+	__start___ex_table = .;
+	__ex_table : { *(__ex_table) }
+	__stop___ex_table = .;
+
+	/*
+	 * _end - This is end of u-boot.bin image.
+	 * dtb will be appended here to make u-boot-dtb.bin
+	 */
+	_end = .;
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss (NOLOAD)       :
+	{
+		*(.bss*)
+		*(.sbss*)
+		*(COMMON)
+		. = ALIGN(4);
+	}
+	__bss_end = . ;
+	PROVIDE (end = .);
+}
+ENTRY(_start)
diff --git a/board/cssi/MAINTAINERS b/board/cssi/MAINTAINERS
index 7d237b0b209..8dac30653e5 100644
--- a/board/cssi/MAINTAINERS
+++ b/board/cssi/MAINTAINERS
@@ -4,3 +4,5 @@ S:	Maintained
 F:	board/cssi/
 F:	include/configs/MCR3000.h
 F:	configs/MCR3000_defconfig
+F:	include/configs/CMPC885.h
+F:	configs/CMPC885_defconfig
diff --git a/configs/CMPC885_defconfig b/configs/CMPC885_defconfig
new file mode 100644
index 00000000000..0546c302b59
--- /dev/null
+++ b/configs/CMPC885_defconfig
@@ -0,0 +1,104 @@
+CONFIG_PPC=y
+CONFIG_ENV_SIZE=0x2000
+CONFIG_ENV_SECT_SIZE=0x2000
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="cmpc885"
+CONFIG_SYS_PROMPT="S3K> "
+CONFIG_ENV_ADDR=0x40004000
+CONFIG_MPC8xx=y
+CONFIG_TARGET_CMPC885=y
+CONFIG_MPC885=y
+CONFIG_8xx_GCLK_FREQ=132000000
+CONFIG_CMD_IMMAP=y
+CONFIG_SYS_SIUMCR=0x00620000
+CONFIG_SYS_SYPCR=0xFFFFFF8F
+CONFIG_SYS_TBSCR=0x00C3
+CONFIG_SYS_PISCR=0x0000
+CONFIG_SYS_PLPRCR_BOOL=y
+CONFIG_SYS_PLPRCR=0x374d4000
+CONFIG_SYS_SCCR=0x00420000
+CONFIG_SYS_SCCR_MASK=0x00000000
+CONFIG_SYS_DER=0x2002000F
+CONFIG_SYS_MONITOR_LEN=327680
+CONFIG_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_BOOTDELAY=5
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="\nEnter password - autoboot in %d sec...\n"
+CONFIG_AUTOBOOT_DELAY_STR="root"
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="run flashboot"
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_MISC_INIT_R=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+CONFIG_SYS_BOOTM_LEN=0x2000000
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_ASKENV=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_NAND=y
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_MII_INIT=y
+CONFIG_CMD_PING=y
+# CONFIG_CMD_SLEEP is not set
+CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_FLASH=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_SYS_BR0_PRELIM_BOOL=y
+CONFIG_SYS_BR0_PRELIM=0x40000801
+CONFIG_SYS_OR0_PRELIM=0xFFC00924
+CONFIG_SYS_BR1_PRELIM_BOOL=y
+CONFIG_SYS_BR1_PRELIM=0x00000081
+CONFIG_SYS_OR1_PRELIM=0xFC000E00
+CONFIG_SYS_BR2_PRELIM_BOOL=y
+CONFIG_SYS_BR2_PRELIM=0xC0000401
+CONFIG_SYS_OR2_PRELIM=0xFFFF8142
+CONFIG_SYS_BR3_PRELIM_BOOL=y
+CONFIG_SYS_BR3_PRELIM=0xE0000801
+CONFIG_SYS_OR3_PRELIM=0xFF00010A
+CONFIG_SYS_BR4_PRELIM_BOOL=y
+CONFIG_SYS_BR4_PRELIM=0xD0000801
+CONFIG_SYS_OR4_PRELIM=0xFC000D08
+CONFIG_SYS_BR5_PRELIM_BOOL=y
+CONFIG_SYS_BR5_PRELIM=0xC8000801
+CONFIG_SYS_OR5_PRELIM=0xFFFF8D10
+CONFIG_SYS_BR6_PRELIM_BOOL=y
+CONFIG_SYS_BR6_PRELIM=0x80000801
+CONFIG_SYS_OR6_PRELIM=0xFFFF8908
+CONFIG_SYS_BR7_PRELIM_BOOL=y
+CONFIG_SYS_BR7_PRELIM=0xF0000001
+CONFIG_SYS_OR7_PRELIM=0xFFFF810A
+CONFIG_MPC8XX_GPIO=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SYS_MAX_FLASH_SECT=71
+CONFIG_MTD_RAW_NAND=y
+CONFIG_RMII=y
+CONFIG_MPC8XX_FEC=y
+CONFIG_FEC1_PHY=1
+CONFIG_FEC2_PHY=2
+# CONFIG_PCI is not set
+CONFIG_DM_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MPC8XX_SPI=y
+CONFIG_WDT=y
+# CONFIG_REGEX is not set
+CONFIG_LZMA=y
diff --git a/include/configs/CMPC885.h b/include/configs/CMPC885.h
new file mode 100644
index 00000000000..99c9abdf82a
--- /dev/null
+++ b/include/configs/CMPC885.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 CS Group
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* High Level Configuration Options */
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"loadaddr=0x1a00000\0"						\
+	"filename=cmpc885.itb\0"					\
+	"console_args=console=ttyCPM0,115200N8\0"			\
+	"loadkernel=ubi part nand0;ubifsmount ubi0;"			\
+		"ubifsload ${loadaddr} /boot/${filename};"		\
+		"ubifsumount; ubi detach\0"				\
+	"flashboot=setenv bootargs "					\
+		"${console_args} "					\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
+		"${hostname}:eth0:off "					\
+		"${ofl_args}; "						\
+		"run loadkernel; "					\
+		"bootm $loadaddr#$config\0"				\
+	"tftpboot=setenv bootargs "					\
+		"${console_args} "					\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
+		"${hostname}:eth0:off "					\
+		"${ofl_args}; "						\
+		"tftp ${loadaddr} ${filename};"				\
+		"bootm $loadaddr#$config\0"				\
+	"update=echo 'Updating ubi image'; "				\
+		"if tftp $loadaddr $ubifile; then "			\
+			"nand erase.chip; "				\
+			"nand write $loadaddr 0x00 $filesize; "		\
+		"fi;\0 "
+
+#define CONFIG_IPADDR		192.168.0.3
+#define CONFIG_SERVERIP		192.168.0.1
+#define CONFIG_NETMASK		255.255.255.0
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
+
+/* Miscellaneous configurable options */
+
+/* Definitions for initial stack pointer and data area (in DPRAM) */
+#define CONFIG_SYS_INIT_RAM_ADDR	(CONFIG_SYS_IMMR + 0x2800)
+#define CONFIG_SYS_INIT_RAM_SIZE	(0x2e00 - 0x2800)
+
+/* RAM configuration (note that CONFIG_SYS_SDRAM_BASE must be zero) */
+#define CONFIG_SYS_SDRAM_BASE		0x00000000
+
+/* FLASH Configuration */
+#define CONFIG_SYS_FLASH_BASE		0x40000000
+#define CONFIG_SYS_FLASH_CFI		1
+
+#define CONFIG_SYS_FSL_SFP_LE
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 24 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ		(32 << 20)
+
+/* NAND configuration part */
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_BASE		0xC0000000
+
+#endif /* __CONFIG_H */
-- 
2.38.1





More information about the U-Boot mailing list