All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Add new equipment from CSSI
@ 2023-01-30 14:33 Christophe Leroy
  2023-01-30 14:34 ` [PATCH 1/7] board: MCR3000: Use lowercase filename Christophe Leroy
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:33 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot

This series adds a new CPU board called CMPC885 which
is used on two equipments called MCR3000 second generation
and MIAE/VGoIP devices, manufactured by former CSSI company
now called CS GROUP France.

This new board has a mpc 885 cpu.

The three first patches of the series update the already
included MCR3000 board in order to get more similarities.

Christophe Leroy (7):
  board: MCR3000: Use lowercase filename
  board: MCR3000: Modernise the settings to properly work on lastest
    u-boot version
  board: MCR3000: Remove update of non-existing e1-wan DT node
  driver, gpio: Add support for MPC 8xx CPU ports
  spi, mpc8xx: Add support for chipselect via GPIO and fixups
  board: cssi: Add new board MCR3000_2G
  board: cssi: Add MIAE & VGoIP devices

 arch/powerpc/Kconfig                          |    1 +
 arch/powerpc/cpu/mpc8xx/Kconfig               |    4 +
 arch/powerpc/dts/Makefile                     |    1 +
 arch/powerpc/dts/cmpc885.dts                  |   94 ++
 arch/powerpc/include/asm/arch-mpc8xx/gpio.h   |   12 +
 board/cssi/CMPC885/Kconfig                    |   23 +
 board/cssi/{MCR3000 => CMPC885}/Makefile      |    6 +-
 board/cssi/CMPC885/cmpc885.c                  | 1106 +++++++++++++++++
 board/cssi/CMPC885/nand.c                     |   47 +
 board/cssi/CMPC885/sdram.c                    |  107 ++
 board/cssi/CMPC885/u-boot.lds                 |   95 ++
 board/cssi/MAINTAINERS                        |    2 +
 board/cssi/MCR3000/Makefile                   |    2 +-
 board/cssi/MCR3000/{MCR3000.c => mcr3000.c}   |   12 -
 .../{MCR3000_defconfig => CMPC885_defconfig}  |   83 +-
 configs/MCR3000_defconfig                     |    8 +-
 drivers/gpio/Kconfig                          |    7 +
 drivers/gpio/Makefile                         |    1 +
 drivers/gpio/mpc8xx_gpio.c                    |  351 ++++++
 drivers/spi/mpc8xx_spi.c                      |   96 +-
 include/configs/CMPC885.h                     |   69 +
 include/configs/MCR3000.h                     |   42 +-
 22 files changed, 2056 insertions(+), 113 deletions(-)
 create mode 100644 arch/powerpc/dts/cmpc885.dts
 create mode 100644 arch/powerpc/include/asm/arch-mpc8xx/gpio.h
 create mode 100644 board/cssi/CMPC885/Kconfig
 copy board/cssi/{MCR3000 => CMPC885}/Makefile (52%)
 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
 rename board/cssi/MCR3000/{MCR3000.c => mcr3000.c} (90%)
 copy configs/{MCR3000_defconfig => CMPC885_defconfig} (52%)
 create mode 100644 drivers/gpio/mpc8xx_gpio.c
 create mode 100644 include/configs/CMPC885.h

-- 
2.38.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] board: MCR3000: Use lowercase filename
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 14:34 ` [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version Christophe Leroy
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot

Rename MCR3000.c to mcr3000.c to be more in line with
other boards.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 board/cssi/MCR3000/Makefile                 | 2 +-
 board/cssi/MCR3000/{MCR3000.c => mcr3000.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename board/cssi/MCR3000/{MCR3000.c => mcr3000.c} (100%)

diff --git a/board/cssi/MCR3000/Makefile b/board/cssi/MCR3000/Makefile
index 68d6812a89a..7803016af3a 100644
--- a/board/cssi/MCR3000/Makefile
+++ b/board/cssi/MCR3000/Makefile
@@ -4,5 +4,5 @@
 # Christophe Leroy <christophe.leroy@c-s.fr>
 #
 
-obj-y += MCR3000.o
+obj-y += mcr3000.o
 obj-$(CONFIG_CMD_NAND) += nand.o
diff --git a/board/cssi/MCR3000/MCR3000.c b/board/cssi/MCR3000/mcr3000.c
similarity index 100%
rename from board/cssi/MCR3000/MCR3000.c
rename to board/cssi/MCR3000/mcr3000.c
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
  2023-01-30 14:34 ` [PATCH 1/7] board: MCR3000: Use lowercase filename Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 17:23   ` Tom Rini
  2023-01-30 14:34 ` [PATCH 3/7] board: MCR3000: Remove update of non-existing e1-wan DT node Christophe Leroy
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

Both U-boot and Linux kernel have grown over the last releases
and don't fit anymore in the 2M EPROM of the board.

So, rework the setup to allow storing the Linux kernel image
on the UBIFS NAND Flash.

Also add support to FIT images as this is what the Linux kernel
look like nowadays.

Also increase CONFIG_SYS_BOOTMAPSZ to 32Mbytes and define
CONFIG_SYS_BOOTM_LEN with the same value, otherwise it defaults
to 8M which is not sufficient anymore with nowadays Linux kernels.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
---
 configs/MCR3000_defconfig |  8 ++++++--
 include/configs/MCR3000.h | 42 ++++++++++++++++++---------------------
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig
index 6c41d7c88d1..2e9d8c24329 100644
--- a/configs/MCR3000_defconfig
+++ b/configs/MCR3000_defconfig
@@ -20,6 +20,7 @@ CONFIG_SYS_SCCR=0x00C20000
 CONFIG_SYS_SCCR_MASK=0x60000000
 CONFIG_SYS_DER=0x2002000F
 CONFIG_SYS_MONITOR_LEN=327680
+CONFIG_FIT=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_MONITOR_BASE=0x04000000
 CONFIG_BOOTDELAY=5
@@ -35,11 +36,12 @@ CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PBSIZE=278
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
-CONFIG_SYS_BOOTM_LEN=0x800000
+CONFIG_SYS_BOOTM_LEN=0x2000000
 # CONFIG_CMD_IMI 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_ECHO is not set
 # CONFIG_CMD_ITEST is not set
@@ -50,6 +52,8 @@ 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_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
@@ -80,6 +84,7 @@ CONFIG_SYS_BR7_PRELIM=0x1C000001
 CONFIG_SYS_OR7_PRELIM=0xFFFF810A
 # 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
@@ -89,5 +94,4 @@ CONFIG_MPC8XX_FEC=y
 # CONFIG_PCI is not set
 CONFIG_DM_SERIAL=y
 CONFIG_WDT=y
-CONFIG_SHA256=y
 CONFIG_LZMA=y
diff --git a/include/configs/MCR3000.h b/include/configs/MCR3000.h
index b0809332bb5..62c3404415c 100644
--- a/include/configs/MCR3000.h
+++ b/include/configs/MCR3000.h
@@ -12,45 +12,40 @@
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	"sdram_type=SDRAM\0"						\
 	"flash_type=AM29LV160DB\0"					\
-	"loadaddr=0x400000\0"						\
-	"filename=uImage.lzma\0"					\
-	"nfsroot=/opt/ofs\0"						\
+	"loadaddr=0x1200000\0"						\
+	"filename=mcr3000.itb\0"					\
 	"dhcp_ip=ip=:::::eth0:dhcp\0"					\
 	"console_args=console=ttyCPM0,115200N8\0"			\
+	"loadkernel=ubi part nand0;ubifsmount ubi0;"			\
+		"ubifsload ${loadaddr} /boot/${filename};"		\
+		"ubifsumount; ubi detach\0"				\
+	"bootcmd=run flashboot\0" 					\
 	"flashboot=setenv bootargs "					\
 		"${console_args} "					\
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
 		"mcr3k:eth0:off;"					\
 		"${ofl_args}; "						\
-		"bootm 0x04060000 - 0x04050000\0"			\
+		"run loadkernel; "					\
+		"bootm ${loadaddr}\0"                                   \
 	"tftpboot=setenv bootargs "					\
 		"${console_args} "					\
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
 		"mcr3k:eth0:off "					\
 		"${ofl_args}; "						\
 		"tftp ${loadaddr} ${filename};"				\
-		"tftp 0xf00000 mcr3000.dtb;"				\
-		"bootm ${loadaddr} - 0xf00000\0"			\
-	"netboot=dhcp ${loadaddr} ${filename};"				\
-		"tftp 0xf00000 mcr3000.dtb;"				\
-		"setenv bootargs "					\
-		"root=/dev/nfs rw "					\
-		"${console_args} "					\
-		"${dhcp_ip};"						\
-		"bootm ${loadaddr} - 0xf00000\0"			\
-	"nfsboot=setenv bootargs "					\
-		"root=/dev/nfs rw nfsroot=${serverip}:${nfsroot} "	\
-		"${console_args} "					\
-		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
-		"mcr3k:eth0:off;"					\
-		"bootm 0x04060000 - 0x04050000\0"			\
+		"bootm ${loadaddr}\0"                                   \
 	"dhcpboot=dhcp ${loadaddr} ${filename};"			\
-		"tftp 0xf00000 mcr3000.dtb;"				\
 		"setenv bootargs "					\
 		"${console_args} "					\
 		"${dhcp_ip} "						\
 		"${ofl_args}; "						\
-		"bootm ${loadaddr} - 0xf00000\0"
+		"bootm ${loadaddr}\0"					\
+	"update=echo 'Updating ubi image'; "				\
+		"if tftp 0x2000 $ubifile; then "			\
+		"nand erase.chip; "					\
+		"nand write 0x2000 0x00 $filesize; "			\
+		"fi;\0 "
+
 
 #define CONFIG_IPADDR			192.168.0.3
 #define CONFIG_SERVERIP			192.168.0.1
@@ -70,10 +65,11 @@
 
 /*
  * For booting Linux, the board info and command line data
- * have to be in the first 8 MB of memory, since this is
+ * have to be in the first 32 MB of memory, since this is
  * the maximum mapped by the Linux kernel during initialization.
  */
-#define	CONFIG_SYS_BOOTMAPSZ		(8 << 20)
+#define	CONFIG_SYS_BOOTMAPSZ		(32 << 20)
+
 
 /* Environment Configuration */
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] board: MCR3000: Remove update of non-existing e1-wan DT node
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
  2023-01-30 14:34 ` [PATCH 1/7] board: MCR3000: Use lowercase filename Christophe Leroy
  2023-01-30 14:34 ` [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 14:34 ` [PATCH 4/7] driver, gpio: Add support for MPC 8xx CPU ports Christophe Leroy
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

e1-wan device-tree node doesn't exist. Remove related update
to avoid following warning at startup:

	 Loading Device Tree to 007fa000, end 007ff951 ... OK
	Unable to update property /localbus/e1-wan:data-rate, err=FDT_ERR_NOTFOUND
	Unable to update property /localbus/e1-wan:channel-phase, err=FDT_ERR_NOTFOUND
	Unable to update property /localbus/e1-wan:rising-edge-sync-pulse, err=FDT_ERR_NOTFOUND

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
---
 board/cssi/MCR3000/mcr3000.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/board/cssi/MCR3000/mcr3000.c b/board/cssi/MCR3000/mcr3000.c
index c20e8714949..ecc244cc124 100644
--- a/board/cssi/MCR3000/mcr3000.c
+++ b/board/cssi/MCR3000/mcr3000.c
@@ -58,8 +58,6 @@ static const uint cs1_dram_table_66[] = {
 
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
-	const char *sync = "receive";
-
 	ft_cpu_setup(blob, bd);
 
 	/* BRG */
@@ -72,16 +70,6 @@ int ft_board_setup(void *blob, struct bd_info *bd)
 	/* 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-wan", "data-rate", 2, 1);
-
-	/* E1 interface - Set channel phase to 0 */
-	do_fixup_by_path_u32(blob, "/localbus/e1-wan", "channel-phase", 0, 1);
-
-	/* E1 interface - rising edge sync pulse transmit */
-	do_fixup_by_path(blob, "/localbus/e1-wan", "rising-edge-sync-pulse",
-			 sync, strlen(sync), 1);
-
 	return 0;
 }
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] driver, gpio: Add support for MPC 8xx CPU ports
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
                   ` (2 preceding siblings ...)
  2023-01-30 14:34 ` [PATCH 3/7] board: MCR3000: Remove update of non-existing e1-wan DT node Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 14:34 ` [PATCH 5/7] spi, mpc8xx: Add support for chipselect via GPIO and fixups Christophe Leroy
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

Ports A, C and D are 16 bits ports.
Ports B and E are 32 bits ports.

The "compatible" is used to determine each port type.

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@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
---
 arch/powerpc/Kconfig                        |   1 +
 arch/powerpc/include/asm/arch-mpc8xx/gpio.h |  12 +
 drivers/gpio/Kconfig                        |   7 +
 drivers/gpio/Makefile                       |   1 +
 drivers/gpio/mpc8xx_gpio.c                  | 351 ++++++++++++++++++++
 5 files changed, 372 insertions(+)
 create mode 100644 arch/powerpc/include/asm/arch-mpc8xx/gpio.h
 create mode 100644 drivers/gpio/mpc8xx_gpio.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c355a954537..7238da196ec 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -28,6 +28,7 @@ config MPC85xx
 
 config MPC8xx
 	bool "MPC8xx"
+	select CREATE_ARCH_SYMLINK
 	select BOARD_EARLY_INIT_F
 	imply CMD_REGINFO
 	imply WDT_MPC8xx
diff --git a/arch/powerpc/include/asm/arch-mpc8xx/gpio.h b/arch/powerpc/include/asm/arch-mpc8xx/gpio.h
new file mode 100644
index 00000000000..6b73acbaee7
--- /dev/null
+++ b/arch/powerpc/include/asm/arch-mpc8xx/gpio.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _MPC8XX_GPIO_H_
+#define _MPC8XX_GPIO_H_
+
+struct mpc8xx_gpio_plat {
+	ulong addr;
+	unsigned long size;
+	uint ngpios;
+};
+
+#endif	/* MPC8XX_GPIO_H_ */
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ff87fbfb397..92c5d96843a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -534,6 +534,13 @@ config MPC8XXX_GPIO
 	  value setting, the open-drain feature, which can configure individual
 	  GPIOs to work as open-drain outputs, is supported.
 
+config MPC8XX_GPIO
+	bool "Freescale MPC8XX GPIO driver"
+	depends on DM_GPIO
+	help
+	  This driver supports parallel IO ports from MPC8XX CPUs.
+	  Each GPIO bank is identified by its own entry in the device tree.
+
 config MPC83XX_SPISEL_BOOT
 	bool "Freescale MPC83XX SPISEL_BOOT driver"
 	depends on DM_GPIO && ARCH_MPC830X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 7235714fcc0..baceb54d318 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_DM644X_GPIO)	+= da8xx_gpio.o
 obj-$(CONFIG_ALTERA_PIO)	+= altera_pio.o
 obj-$(CONFIG_MPC83XX_GPIO)	+= mpc83xx_gpio.o
 obj-$(CONFIG_MPC8XXX_GPIO)	+= mpc8xxx_gpio.o
+obj-$(CONFIG_MPC8XX_GPIO)	+= mpc8xx_gpio.o
 obj-$(CONFIG_MPC83XX_SPISEL_BOOT)	+= mpc83xx_spisel_boot.o
 obj-$(CONFIG_SH_GPIO_PFC)	+= sh_pfc.o
 obj-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
diff --git a/drivers/gpio/mpc8xx_gpio.c b/drivers/gpio/mpc8xx_gpio.c
new file mode 100644
index 00000000000..bf62e0757d8
--- /dev/null
+++ b/drivers/gpio/mpc8xx_gpio.c
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 CS Group
+ *	Charles Frey <charles.frey@c-s.fr>
+ *
+ * based on driver/gpio/mpc8xxx_gpio.c, which is
+ * Copyright 2016 Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ *
+ * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
+ * Copyright 2010 eXMeritus, A Boeing Company
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <asm/gpio.h>
+#include <malloc.h>
+
+enum {
+	MPC8XX_CPM1_PORTA,
+	MPC8XX_CPM1_PORTB,
+	MPC8XX_CPM1_PORTC,
+	MPC8XX_CPM1_PORTD,
+	MPC8XX_CPM1_PORTE,
+};
+
+/*
+ * The MPC885 CPU CPM has 5 I/O ports, and each ports has different
+ * register length : 16 bits for ports A,C,D and 32 bits for ports
+ * B and E.
+ *
+ * This structure allows us to select the accessors according to the
+ * port we are configuring.
+ */
+struct mpc8xx_gpio_data {
+	/* The bank's register base in memory */
+	void __iomem *base;
+	/* The address of the registers; used to identify the bank */
+	ulong addr;
+	/* The GPIO count of the bank */
+	uint gpio_count;
+	/* Type needed to use the correct accessors */
+	int type;
+};
+
+/* Structure for ports A, C, D */
+struct iop_16 {
+	u16 pdir;
+	u16 ppar;
+	u16 podr;
+	u16 pdat;
+};
+
+/* Port B */
+struct iop_32_b {
+	u32 pdir;
+	u32 ppar;
+	u32 podr;
+	u32 pdat;
+};
+
+/* Port E */
+struct iop_32_e {
+	u32 pdir;
+	u32 ppar;
+	u32 psor;
+	u32 podr;
+	u32 pdat;
+};
+
+union iop_32 {
+	struct iop_32_b b;
+	struct iop_32_e e;
+};
+
+inline u32 gpio_mask(uint gpio, int type)
+{
+	if (type == MPC8XX_CPM1_PORTB || type == MPC8XX_CPM1_PORTE)
+		return 1U << (31 - (gpio));
+	else
+		return 1U << (15 - (gpio));
+}
+
+static inline u16 gpio16_get_val(void __iomem *base, u16 mask, int type)
+{
+	struct iop_16 *regs = base;
+
+	return in_be16(&regs->pdat) & mask;
+}
+
+static inline u16 gpio16_get_dir(void __iomem *base, u16 mask, int type)
+{
+	struct iop_16 *regs = base;
+
+	return in_be16(&regs->pdir) & mask;
+}
+
+static inline void gpio16_set_in(void __iomem *base, u16 gpios, int type)
+{
+	struct iop_16 *regs = base;
+
+	clrbits_be16(&regs->pdat, gpios);
+	/* GPDIR register 0 -> input */
+	clrbits_be16(&regs->pdir, gpios);
+}
+
+static inline void gpio16_set_lo(void __iomem *base, u16 gpios, int type)
+{
+	struct iop_16 *regs = base;
+
+	clrbits_be16(&regs->pdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be16(&regs->pdir, gpios);
+}
+
+static inline void gpio16_set_hi(void __iomem *base, u16 gpios, int type)
+{
+	struct iop_16 *regs = base;
+
+	setbits_be16(&regs->pdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be16(&regs->pdir, gpios);
+}
+
+/* PORT B AND E */
+static inline u32 gpio32_get_val(void __iomem *base, u32 mask, int type)
+{
+	union iop_32 __iomem *regs = base;
+
+	if (type == MPC8XX_CPM1_PORTB)
+		return in_be32(&regs->b.pdat) & mask;
+	else
+		return in_be32(&regs->e.pdat) & mask;
+}
+
+static inline u32 gpio32_get_dir(void __iomem *base, u32 mask, int type)
+{
+	union iop_32 __iomem *regs = base;
+
+	if (type == MPC8XX_CPM1_PORTB)
+		return in_be32(&regs->b.pdir) & mask;
+	else
+		return in_be32(&regs->e.pdir) & mask;
+}
+
+static inline void gpio32_set_in(void __iomem *base, u32 gpios, int type)
+{
+	union iop_32 __iomem *regs = base;
+
+	if (type == MPC8XX_CPM1_PORTB) {
+		clrbits_be32(&regs->b.pdat, gpios);
+		/* GPDIR register 0 -> input */
+		clrbits_be32(&regs->b.pdir, gpios);
+	} else { /* Port E */
+		clrbits_be32(&regs->e.pdat, gpios);
+		/* GPDIR register 0 -> input */
+		clrbits_be32(&regs->e.pdir, gpios);
+	}
+}
+
+static inline void gpio32_set_lo(void __iomem *base, u32 gpios, int type)
+{
+	union iop_32 __iomem *regs = base;
+
+	if (type == MPC8XX_CPM1_PORTB) {
+		clrbits_be32(&regs->b.pdat, gpios);
+		/* GPDIR register 1 -> output */
+		setbits_be32(&regs->b.pdir, gpios);
+	} else {
+		clrbits_be32(&regs->e.pdat, gpios);
+		/* GPDIR register 1 -> output */
+		setbits_be32(&regs->e.pdir, gpios);
+	}
+}
+
+static inline void gpio32_set_hi(void __iomem *base, u32 gpios, int type)
+{
+	union iop_32 __iomem *regs = base;
+
+	if (type == MPC8XX_CPM1_PORTB) {
+		setbits_be32(&regs->b.pdat, gpios);
+		/* GPDIR register 1 -> output */
+		setbits_be32(&regs->b.pdir, gpios);
+	} else {
+		setbits_be32(&regs->e.pdat, gpios);
+		/* GPDIR register 1 -> output */
+		setbits_be32(&regs->e.pdir, gpios);
+	}
+}
+
+static int mpc8xx_gpio_direction_input(struct udevice *dev, uint gpio)
+{
+	struct mpc8xx_gpio_data *data = dev_get_priv(dev);
+	int type = data->type;
+
+	if (type == MPC8XX_CPM1_PORTB || type == MPC8XX_CPM1_PORTE)
+		gpio32_set_in(data->base, gpio_mask(gpio, type), type);
+	else
+		gpio16_set_in(data->base, gpio_mask(gpio, type), type);
+
+	return 0;
+}
+
+static int mpc8xx_gpio_set_value(struct udevice *dev, uint gpio, int value)
+{
+	struct mpc8xx_gpio_data *data = dev_get_priv(dev);
+	int type = data->type;
+
+	if (type == MPC8XX_CPM1_PORTB || type == MPC8XX_CPM1_PORTE) {
+		if (value)
+			gpio32_set_hi(data->base, gpio_mask(gpio, type), type);
+		else
+			gpio32_set_lo(data->base, gpio_mask(gpio, type), type);
+	} else {
+		if (value)
+			gpio16_set_hi(data->base, gpio_mask(gpio, type), type);
+		else
+			gpio16_set_lo(data->base, gpio_mask(gpio, type), type);
+	}
+
+	return 0;
+}
+
+static int mpc8xx_gpio_direction_output(struct udevice *dev, uint gpio,
+					int value)
+{
+	return mpc8xx_gpio_set_value(dev, gpio, value);
+}
+
+static int mpc8xx_gpio_get_value(struct udevice *dev, uint gpio)
+{
+	struct mpc8xx_gpio_data *data = dev_get_priv(dev);
+	int type = data->type;
+
+	/* Input -> read value from GPDAT register */
+	if (type == MPC8XX_CPM1_PORTB || type == MPC8XX_CPM1_PORTE)
+		return gpio32_get_val(data->base, gpio_mask(gpio, type), type);
+	else
+		return gpio16_get_val(data->base, gpio_mask(gpio, type), type);
+}
+
+static int mpc8xx_gpio_get_function(struct udevice *dev, uint gpio)
+{
+	struct mpc8xx_gpio_data *data = dev_get_priv(dev);
+	int type = data->type;
+	int dir;
+
+	if (type == MPC8XX_CPM1_PORTB || type == MPC8XX_CPM1_PORTE)
+		dir = gpio32_get_dir(data->base, gpio_mask(gpio, type), type);
+	else
+		dir = gpio16_get_dir(data->base, gpio_mask(gpio, type), type);
+	return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static int mpc8xx_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mpc8xx_gpio_plat *plat = dev_get_plat(dev);
+	fdt_addr_t addr;
+	u32 reg[2];
+
+	dev_read_u32_array(dev, "reg", reg, 2);
+	addr = dev_translate_address(dev, reg);
+
+	plat->addr = addr;
+	plat->size = reg[1];
+	plat->ngpios = dev_read_u32_default(dev, "ngpios", 32);
+
+	return 0;
+}
+#endif
+
+static int mpc8xx_gpio_platdata_to_priv(struct udevice *dev)
+{
+	struct mpc8xx_gpio_data *priv = dev_get_priv(dev);
+	struct mpc8xx_gpio_plat *plat = dev_get_plat(dev);
+	unsigned long size = plat->size;
+	int type;
+
+	if (size == 0)
+		size = 0x100;
+
+	priv->addr = plat->addr;
+	priv->base = map_sysmem(plat->addr, size);
+
+	if (!priv->base)
+		return -ENOMEM;
+
+	priv->gpio_count = plat->ngpios;
+
+	type = dev_get_driver_data(dev);
+
+	if ((type == MPC8XX_CPM1_PORTA || type == MPC8XX_CPM1_PORTC ||
+	     type == MPC8XX_CPM1_PORTD) && plat->ngpios == 32)
+		priv->gpio_count = 16;
+
+	priv->type = type;
+
+	return 0;
+}
+
+static int mpc8xx_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct mpc8xx_gpio_data *data = dev_get_priv(dev);
+	char name[32], *str;
+
+	mpc8xx_gpio_platdata_to_priv(dev);
+
+	snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
+	str = strdup(name);
+
+	if (!str)
+		return -ENOMEM;
+
+	uc_priv->bank_name = str;
+	uc_priv->gpio_count = data->gpio_count;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops gpio_mpc8xx_ops = {
+	.direction_input	= mpc8xx_gpio_direction_input,
+	.direction_output	= mpc8xx_gpio_direction_output,
+	.get_value		= mpc8xx_gpio_get_value,
+	.set_value		= mpc8xx_gpio_set_value,
+	.get_function		= mpc8xx_gpio_get_function,
+};
+
+static const struct udevice_id mpc8xx_gpio_ids[] = {
+	{ .compatible = "fsl,cpm1-pario-bank-a", .data = MPC8XX_CPM1_PORTA },
+	{ .compatible = "fsl,cpm1-pario-bank-b", .data = MPC8XX_CPM1_PORTB },
+	{ .compatible = "fsl,cpm1-pario-bank-c", .data = MPC8XX_CPM1_PORTC },
+	{ .compatible = "fsl,cpm1-pario-bank-d", .data = MPC8XX_CPM1_PORTD },
+	{ .compatible = "fsl,cpm1-pario-bank-e", .data = MPC8XX_CPM1_PORTE },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(gpio_mpc8xx) = {
+	.name	= "gpio_mpc8xx",
+	.id	= UCLASS_GPIO,
+	.ops	= &gpio_mpc8xx_ops,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+	.of_to_plat = mpc8xx_gpio_ofdata_to_platdata,
+	.plat_auto = sizeof(struct mpc8xx_gpio_plat),
+	.of_match = mpc8xx_gpio_ids,
+#endif
+	.probe	= mpc8xx_gpio_probe,
+	.priv_auto = sizeof(struct mpc8xx_gpio_data),
+};
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] spi, mpc8xx: Add support for chipselect via GPIO and fixups
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
                   ` (3 preceding siblings ...)
  2023-01-30 14:34 ` [PATCH 4/7] driver, gpio: Add support for MPC 8xx CPU ports Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 14:34 ` [PATCH 6/7] board: cssi: Add new board MCR3000_2G Christophe Leroy
  2023-01-30 14:34 ` [PATCH 7/7] board: cssi: Add MIAE & VGoIP devices Christophe Leroy
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

This patch fixes the mpc8xx SPI driver:
- A stub callbacks for mode and speed,
- Use chip selects defined as GPIOs,
- Write proper value to disable relocation, other it fails on mpc885,
- Don't modify ports setup, ports can be different from one board to
another and are already set by board_early_init_r().

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@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
---
 drivers/spi/mpc8xx_spi.c | 96 ++++++++++++++++++++++++----------------
 1 file changed, 59 insertions(+), 37 deletions(-)

diff --git a/drivers/spi/mpc8xx_spi.c b/drivers/spi/mpc8xx_spi.c
index 0026ad23e37..d84d7aea888 100644
--- a/drivers/spi/mpc8xx_spi.c
+++ b/drivers/spi/mpc8xx_spi.c
@@ -24,12 +24,29 @@
 
 #include <asm/cpm_8xx.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 
 #define CPM_SPI_BASE_RX	CPM_SPI_BASE
 #define CPM_SPI_BASE_TX	(CPM_SPI_BASE + sizeof(cbd_t))
 
 #define MAX_BUFFER	0x104
 
+struct mpc8xx_priv {
+	spi_t __iomem *spi;
+	struct gpio_desc gpios[16];
+	int max_cs;
+};
+
+static int mpc8xx_spi_set_mode(struct udevice *dev, uint mod)
+{
+	return 0;
+}
+
+static int mpc8xx_spi_set_speed(struct udevice *dev, uint speed)
+{
+	return 0;
+}
+
 static int mpc8xx_spi_probe(struct udevice *dev)
 {
 	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
@@ -38,42 +55,9 @@ static int mpc8xx_spi_probe(struct udevice *dev)
 	cbd_t __iomem *tbdf, *rbdf;
 
 	/* Disable relocation */
-	out_be16(&spi->spi_rpbase, 0);
+	out_be16(&spi->spi_rpbase, 0x1d80);
 
 /* 1 */
-	/* ------------------------------------------------
-	 * Initialize Port B SPI pins -> page 34-8 MPC860UM
-	 * (we are only in Master Mode !)
-	 * ------------------------------------------------ */
-
-	/* --------------------------------------------
-	 * GPIO or per. Function
-	 * PBPAR[28] = 1 [0x00000008] -> PERI: (SPIMISO)
-	 * PBPAR[29] = 1 [0x00000004] -> PERI: (SPIMOSI)
-	 * PBPAR[30] = 1 [0x00000002] -> PERI: (SPICLK)
-	 * PBPAR[31] = 0 [0x00000001] -> GPIO: (CS for PCUE/CCM-EEPROM)
-	 * -------------------------------------------- */
-	clrsetbits_be32(&cp->cp_pbpar, 0x00000001, 0x0000000E);	/* set  bits */
-
-	/* ----------------------------------------------
-	 * In/Out or per. Function 0/1
-	 * PBDIR[28] = 1 [0x00000008] -> PERI1: SPIMISO
-	 * PBDIR[29] = 1 [0x00000004] -> PERI1: SPIMOSI
-	 * PBDIR[30] = 1 [0x00000002] -> PERI1: SPICLK
-	 * PBDIR[31] = 1 [0x00000001] -> GPIO OUT: CS for PCUE/CCM-EEPROM
-	 * ---------------------------------------------- */
-	setbits_be32(&cp->cp_pbdir, 0x0000000F);
-
-	/* ----------------------------------------------
-	 * open drain or active output
-	 * PBODR[28] = 1 [0x00000008] -> open drain: SPIMISO
-	 * PBODR[29] = 0 [0x00000004] -> active output SPIMOSI
-	 * PBODR[30] = 0 [0x00000002] -> active output: SPICLK
-	 * PBODR[31] = 0 [0x00000001] -> active output GPIO OUT: CS for PCUE/CCM
-	 * ---------------------------------------------- */
-
-	clrsetbits_be16(&cp->cp_pbodr, 0x00000007, 0x00000008);
-
 	/* Initialize the parameter ram.
 	 * We need to make sure many things are initialized to zero
 	 */
@@ -143,6 +127,22 @@ static int mpc8xx_spi_probe(struct udevice *dev)
 	return 0;
 }
 
+static void mpc8xx_spi_cs_activate(struct udevice *dev)
+{
+	struct mpc8xx_priv *priv = dev_get_priv(dev->parent);
+	struct dm_spi_slave_plat *platdata = dev_get_parent_plat(dev);
+
+	dm_gpio_set_value(&priv->gpios[platdata->cs], 1);
+}
+
+static void mpc8xx_spi_cs_deactivate(struct udevice *dev)
+{
+	struct mpc8xx_priv *priv = dev_get_priv(dev->parent);
+	struct dm_spi_slave_plat *platdata = dev_get_parent_plat(dev);
+
+	dm_gpio_set_value(&priv->gpios[platdata->cs], 0);
+}
+
 static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 			    const void *dout, void *din, unsigned long flags)
 {
@@ -159,7 +159,8 @@ static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	rbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_RX];
 
 	/* Set CS for device */
-	clrbits_be32(&cp->cp_pbdat, 0x0001);
+	if (flags & SPI_XFER_BEGIN)
+		mpc8xx_spi_cs_activate(dev);
 
 	/* Setting tx bd status and data length */
 	out_be32(&tbdf->cbd_bufaddr, (ulong)dout);
@@ -186,21 +187,40 @@ static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	for (tm = 0; tm < 1000; ++tm) {
 		if (in_8(&cp->cp_spie) & SPI_TXB)	/* Tx Buffer Empty */
 			break;
+
 		if ((in_be16(&tbdf->cbd_sc) & BD_SC_READY) == 0)
 			break;
 		udelay(1000);
 	}
+
 	if (tm >= 1000)
 		printf("*** spi_xfer: Time out while xferring to/from SPI!\n");
 
 	/* Clear CS for device */
-	setbits_be32(&cp->cp_pbdat, 0x0001);
+	if (flags & SPI_XFER_END)
+		mpc8xx_spi_cs_deactivate(dev);
 
-	return count;
+	return 0;
 }
 
+static int mpc8xx_spi_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mpc8xx_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = gpio_request_list_by_name(dev, "gpios", priv->gpios,
+					ARRAY_SIZE(priv->gpios), GPIOD_IS_OUT);
+	if (ret < 0)
+		return ret;
+
+	priv->max_cs = ret;
+
+	return 0;
+}
 static const struct dm_spi_ops mpc8xx_spi_ops = {
 	.xfer		= mpc8xx_spi_xfer,
+	.set_speed	= mpc8xx_spi_set_speed,
+	.set_mode	= mpc8xx_spi_set_mode,
 };
 
 static const struct udevice_id mpc8xx_spi_ids[] = {
@@ -212,6 +232,8 @@ U_BOOT_DRIVER(mpc8xx_spi) = {
 	.name	= "mpc8xx_spi",
 	.id	= UCLASS_SPI,
 	.of_match = mpc8xx_spi_ids,
+	.of_to_plat = mpc8xx_spi_ofdata_to_platdata,
 	.ops	= &mpc8xx_spi_ops,
 	.probe	= mpc8xx_spi_probe,
+	.priv_auto = sizeof(struct mpc8xx_priv),
 };
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] board: cssi: Add new board MCR3000_2G
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
                   ` (4 preceding siblings ...)
  2023-01-30 14:34 ` [PATCH 5/7] spi, mpc8xx: Add support for chipselect via GPIO and fixups Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  2023-01-30 14:34 ` [PATCH 7/7] board: cssi: Add MIAE & VGoIP devices Christophe Leroy
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

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@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@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@0 {
+		device_type = "watchdog";
+		compatible = "fsl,pq1-wdt";
+	};
+
+	SERIAL: serial {
+		compatible = "fsl,pq1-smc";
+	};
+
+	FEC1: fec@0 {
+		compatible = "fsl,pq1-fec1";
+	};
+
+	FEC2: fec@1 {
+		compatible = "fsl,pq1-fec2";
+	};
+
+	soc: immr@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@ab8 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-b";
+			reg = <0xab8 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_D: gpio-controller@970 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-d";
+			reg = <0x970 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_A: gpio-controller@950 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-a";
+			reg = <0x950 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_C: gpio-controller@960 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-c";
+			reg = <0x960 0x10>;
+			gpio-controller;
+		};
+
+		CPM1_PIO_E: gpio-controller@ac8 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm1-pario-bank-e";
+			reg = <0xac8 0x18>;
+			gpio-controller;
+		};
+
+		spi: spi@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@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@c-s.fr>
+# Christophe Leroy <christophe.leroy@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@c-s.fr>
+ * Florent Trinh Thai <florent.trinh-thai@c-s.fr>
+ * Christophe Leroy <christophe.leroy@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@c-s.fr>
+ * Christophe Leroy <christophe.leroy@c-s.fr>
+ * Charles Frey <charles.frey@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@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@c-s.fr>
+ *
+ * (C) Copyright 2001-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Modified by Yuli Barcohen <yuli@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




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] board: cssi: Add MIAE & VGoIP devices
  2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
                   ` (5 preceding siblings ...)
  2023-01-30 14:34 ` [PATCH 6/7] board: cssi: Add new board MCR3000_2G Christophe Leroy
@ 2023-01-30 14:34 ` Christophe Leroy
  6 siblings, 0 replies; 9+ messages in thread
From: Christophe Leroy @ 2023-01-30 14:34 UTC (permalink / raw)
  To: Jagan Teki, Tom Rini; +Cc: Christophe Leroy, u-boot, FRANJOU Stephane

This adds support for the MIAE and VGoIP devices.
Those devices have the same CPU board that the MCR3000_2G board.

The devices are very modular, they are provided with
interchangeable front and back panels.

Linux kernel is shipped with a device tree which contains all
possible setups, and U-boot eliminates unrelated nodes based on
detected hardware.

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@csgroup.eu>
Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
---
 board/cssi/CMPC885/cmpc885.c | 286 ++++++++++++++++++++++++++++++++++-
 1 file changed, 281 insertions(+), 5 deletions(-)

diff --git a/board/cssi/CMPC885/cmpc885.c b/board/cssi/CMPC885/cmpc885.c
index 2c19d9b6165..367696bcdd6 100644
--- a/board/cssi/CMPC885/cmpc885.c
+++ b/board/cssi/CMPC885/cmpc885.c
@@ -29,8 +29,16 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define BOARD_CMPC885		"cmpc885"
 #define BOARD_MCR3000_2G	"mcr3k_2g"
+#define BOARD_VGOIP		"vgoip"
+#define BOARD_MIAE		"miae"
 
 #define TYPE_MCR	0x22
+#define TYPE_MIAE	0x23
+
+#define FAR_CASRSA     2
+#define FAR_VGOIP      4
+#define FAV_CLA        7
+#define FAV_SRSA       8
 
 #define ADDR_CPLD_R_RESET		((unsigned short __iomem *)CONFIG_CPLD_BASE)
 #define ADDR_CPLD_R_ETAT		((unsigned short __iomem *)(CONFIG_CPLD_BASE + 2))
@@ -38,6 +46,12 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #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 ADDR_FPGA_R_FAV			((unsigned char  __iomem *)CONFIG_FPGA_BASE + 0x44)
+
+#define PATH_PHY2			"/soc@ff000000/mdio@e00/ethernet-phy@2"
+#define PATH_PHY3			"/soc@ff000000/mdio@e00/ethernet-phy@3"
+#define PATH_ETH1			"/soc@ff000000/ethernet@1e00"
+#define FIBER_PHY PATH_PHY2
 
 #define FPGA_R_ACQ_AL_FAV	0x04
 #define R_ETAT_PRES_BASE	0x0040
@@ -45,15 +59,68 @@ DECLARE_GLOBAL_DATA_PTR;
 #define R_RESET_STATUS		0x0400
 #define R_RST_STATUS		0x0004
 
+static int fdt_set_node_and_value(void *blob, char *node, const char *prop,
+				  void *var, int size)
+{
+	int ret, off;
+
+	off = fdt_path_offset(blob, node);
+
+	if (off < 0) {
+		printf("Cannot find %s node err:%s\n", node, fdt_strerror(off));
+
+		return off;
+	}
+
+	ret = fdt_setprop(blob, off, prop, var, size);
+
+	if (ret < 0)
+		printf("Cannot set %s/%s prop err: %s\n", node, prop, fdt_strerror(ret));
+
+	return ret;
+}
+
+/* Checks front/rear id and remove unneeded nodes from the blob */
+static void ft_cleanup(void *blob, uint32_t id, const char *prop, const char *compatible)
+{
+	int off;
+
+	off = fdt_node_offset_by_compatible(blob, -1, compatible);
+
+	while (off != -FDT_ERR_NOTFOUND) {
+		const struct fdt_property *ids;
+		int nb_ids, idx;
+		int tmp = -1;
+
+		ids = fdt_get_property(blob, off, prop, &nb_ids);
+
+		for (idx = 0; idx < nb_ids; idx += 4) {
+			if (*((uint32_t *)&ids->data[idx]) == id)
+				break;
+		}
+
+		if (idx >= nb_ids)
+			fdt_del_node(blob, off);
+		else
+			tmp = off;
+
+		off = fdt_node_offset_by_compatible(blob, tmp, compatible);
+	}
+
+	fdt_set_node_and_value(blob, "/", prop, &id, sizeof(uint32_t));
+}
+
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
+	u8 fav_id, far_id;
+
 	const char *sync = "receive";
 
 	ft_cpu_setup(blob, bd);
 
 	/* BRG */
-	do_fixup_by_path_u32(blob, "/soc/cpm", "brg-frequency",
-			     bd->bi_busfreq, 1);
+	do_fixup_by_path_u32(blob, "/soc/cpm", "brg-frequency", bd->bi_busfreq, 1);
+
 	/* MAC addr */
 	fdt_fixup_ethernet(blob);
 
@@ -67,8 +134,33 @@ int ft_board_setup(void *blob, struct bd_info *bd)
 	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);
+	do_fixup_by_path(blob, "/localbus/e1", "rising-edge-sync-pulse", sync, strlen(sync), 1);
+
+	/* MIAE only */
+	if (!(in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE) || in_8(ADDR_FPGA_R_BASE) != TYPE_MIAE)
+		return 0;
+
+	far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
+	ft_cleanup(blob, (u32)far_id, "far-id", "cs,mia-far");
+
+	/*
+	 * special case, with CASRSA (far_id: 2)
+	 * FAV-SRSA register itself as FAV-CLA
+	 */
+	fav_id = in_8(ADDR_FPGA_R_BASE + 0x44) >> 5;
+
+	if (far_id == FAR_CASRSA && fav_id == FAV_CLA)
+		fav_id = FAV_SRSA;
+
+	ft_cleanup(blob, (u32)fav_id, "fav-id", "cs,mia-fav");
+
+	if (far_id == FAR_CASRSA) {
+		/* switch to phy3 with gpio, we'll only use phy3 */
+		immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+		cpm8xx_t __iomem *cp = (cpm8xx_t __iomem *)&immr->im_cpm;
+
+		setbits_be32(&cp->cp_pedat, 0x00002000);
+	}
 
 	return 0;
 }
@@ -80,8 +172,18 @@ int checkboard(void)
 	/* Is a motherboard present ? */
 	if (in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE) {
 		switch (in_8(ADDR_FPGA_R_BASE)) {
+			int far_id;
 		case TYPE_MCR:
 			printf("MCR3000_2G (CS GROUP)\n");
+			break;
+		case TYPE_MIAE:
+			far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
+
+			if (far_id == FAR_VGOIP)
+				printf("VGoIP (CS GROUP)\n");
+			else
+				printf("MIAE (CS GROUP)\n");
+
 			break;
 		default:
 			printf("Unknown\n");
@@ -149,7 +251,8 @@ static int setup_mac(void)
 
 int misc_init_r(void)
 {
-	u8 val;
+	u8 val, tmp, far_id;
+	int count = 3;
 
 	val = in_8(ADDR_FPGA_R_BASE);
 
@@ -165,6 +268,31 @@ int misc_init_r(void)
 			env_set("config", BOARD_MCR3000_2G);
 			env_set("hostname", BOARD_MCR3000_2G);
 			break;
+
+		case TYPE_MIAE:
+			do {
+				tmp = in_8(ADDR_FPGA_R_BASE + 0x41);
+				count--;
+				mdelay(10); /* 10msec wait */
+			} while (count && tmp != in_8(ADDR_FPGA_R_BASE + 0x41));
+
+			if (!count) {
+				printf("Cannot read the reset factory switch position\n");
+				hang();
+			}
+
+			if (tmp & 0x1)
+				env_set_default("Factory settings switch ON", 0);
+
+			env_set("config", BOARD_MIAE);
+			far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
+
+			if (far_id == FAR_VGOIP)
+				env_set("hostname", BOARD_VGOIP);
+			else
+				env_set("hostname", BOARD_MIAE);
+			break;
+
 		default:
 			env_set("config", BOARD_CMPC885);
 			env_set("hostname", BOARD_CMPC885);
@@ -488,6 +616,150 @@ static void iop_setup_cmpc885(void)
 	clrbits_be32(&cp->cp_peso, 0x00031980);
 }
 
+static void iop_setup_miae(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);
+
+	/* Set the front panel LED color to red */
+	clrbits_8(ADDR_FPGA_R_FAV, 0x02);
+
+	/* We must initialize data before changing direction */
+	setbits_be16(&iop->iop_pcdat, 0x0888);
+	setbits_be16(&iop->iop_pddat, 0x0201);
+	setbits_be32(&cp->cp_pbdat, 0x00021510);
+	setbits_be32(&cp->cp_pedat, 0x00000002);
+
+	/*
+	 * PAPAR[13] = 1 [0x0004] -> GPIO: (RXD2)
+	 * PAPAR[12] = 1 [0x0008] -> GPIO: (TXD2)
+	 * PAPAR[9]  = 1 [0x0040] -> GPIO: (TDM1O)
+	 * PAPAR[8]  = 1 [0x0080] -> GPIO: (TDM1I)
+	 * PAPAR[7]  = 1 [0x0100] -> GPIO: (TDM_BCLK_MPC)
+	 * PAPAR[6]  = 1 [0x0200] -> GPIO: (CLK2)
+	 */
+	setbits_be16(&iop->iop_papar, 0x03CC);
+
+	/*
+	 * PBODR[16] = 0 [0x00008000] -> GPIO: (L1ST4)
+	 */
+	clrbits_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] = 0 [0x00008000] -> GPIO: (L1ST4)
+	 * PBDIR[15] = 1 [0x00010000] -> GPIO: (BRG03)
+	 * PBDIR[14] = 1 [0x00020000] -> GPIO: (CS_TEMP)
+	 */
+	clrsetbits_be32(&cp->cp_pbdir, 0x0003A130, 0x00032130);
+
+	/*
+	 * PBPAR[20] = 1 [0x00000800] -> GPIO: (SMRXD2)
+	 * PBPAR[17] = 1 [0x00004000] -> GPIO: (L1ST3)
+	 * PBPAR[16] = 1 [0x00008000] -> GPIO: (L1ST4)
+	 */
+	setbits_be32(&cp->cp_pbpar, 0x0000C800);
+
+	/*
+	 * PCPAR[14] = 1 [0x0002] -> GPIO: (L1ST2)
+	 */
+	setbits_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] = 1 [0x00000100] -> GPIO: (L1ST1)
+	 * 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)
+	 */
+	setbits_be32(&cp->cp_pepar, 0x0003DFF0);
+
+	/*
+	 * PADIR[9]  = 1 [0x0040] -> GPIO: (TDM1O)
+	 * PADIR[8]  = 1 [0x0080] -> GPIO: (TDM1I)
+	 * PADIR[5]  = 0 [0x0400] -> GPIO: ()
+	 */
+	clrsetbits_be16(&iop->iop_padir, 0x04C0, 0x00C0);
+
+	/*
+	 * PCDIR[15] = 1 [0x0001] -> GPIO: (WP_EEPROM2)
+	 * PCDIR[14] = 1 [0x0002] -> GPIO: (L1ST2)
+	 * PCDIR[13] = 0 [0x0004] -> GPIO: ()
+	 * PCDIR[12] = 1 [0x0008] -> GPIO: (CS_EEPROM2)
+	 * PCDIR[8]  = 1 [0x0080] -> GPIO: (CS_CODEC_2)
+	 * PCDIR[4]  = 1 [0x0800] -> GPIO: (CS_CODEC_1)
+	 */
+	clrsetbits_be16(&iop->iop_pcdir, 0x088F, 0x088B);
+
+	/*
+	 * PDDIR[9]  = 1 [0x0040] -> GPIO: (TXD4)
+	 * PDDIR[6]  = 1 [0x0200] -> GPIO: (CS_CODEC_3)
+	 */
+	setbits_be16(&iop->iop_pddir, 0x0240);
+
+	/*
+	 * PEDIR[30] = 1 [0x00000002] -> GPIO: (FPGA_FIRMWARE)
+	 * PEDIR[27] = 1 [0x00000010] -> GPIO: (R2_RXER)
+	 * PEDIR[26] = 1 [0x00000020] -> GPIO: (R2_CRS_DV)
+	 * PEDIR[23] = 1 [0x00000100] -> GPIO: (L1ST1)
+	 * 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: (PE18)
+	 * PEDIR[16] = 1 [0x00008000] -> GPIO: (R2_REF_CLK)
+	 * PEDIR[15] = 1 [0x00010000] -> GPIO: (R2_TXD1)
+	 * PEDIR[14] = 1 [0x00020000] -> GPIO: (R2_TXD0)
+	 */
+	setbits_be32(&cp->cp_pedir, 0x0003B732);
+
+	/*
+	 * PAODR[10] = 1 [0x0020] -> GPIO: (INIT_FPGA_F)
+	 */
+	setbits_be16(&iop->iop_paodr, 0x0020);
+
+	/*
+	 * PEODR[30] = 1 [0x00000002] -> GPIO: (FPGA_FIRMWARE)
+	 * PEODR[18] = 0 [0x00002000] -> GPIO: (PE18)
+	 */
+	clrsetbits_be32(&cp->cp_peodr, 0x00002002, 0x00000002);
+
+	/*
+	 * PESO[24] = 1 [0x00000080] -> GPIO: (BRG01)
+	 * PESO[23] = 1 [0x00000100] -> GPIO: (L1ST1)
+	 * 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)
+	 */
+	setbits_be32(&cp->cp_peso, 0x00031980);
+}
+
 int board_early_init_f(void)
 {
 	return 0;
@@ -818,6 +1090,10 @@ int board_early_init_r(void)
 			iop_setup_mcr();
 			break;
 
+		case TYPE_MIAE:
+			iop_setup_miae();
+			break;
+
 		default:
 			break;
 		}
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version
  2023-01-30 14:34 ` [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version Christophe Leroy
@ 2023-01-30 17:23   ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2023-01-30 17:23 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: Jagan Teki, u-boot, FRANJOU Stephane

[-- Attachment #1: Type: text/plain, Size: 5066 bytes --]

On Mon, Jan 30, 2023 at 03:34:01PM +0100, Christophe Leroy wrote:

> Both U-boot and Linux kernel have grown over the last releases
> and don't fit anymore in the 2M EPROM of the board.
> 
> So, rework the setup to allow storing the Linux kernel image
> on the UBIFS NAND Flash.
> 
> Also add support to FIT images as this is what the Linux kernel
> look like nowadays.
> 
> Also increase CONFIG_SYS_BOOTMAPSZ to 32Mbytes and define
> CONFIG_SYS_BOOTM_LEN with the same value, otherwise it defaults
> to 8M which is not sufficient anymore with nowadays Linux kernels.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> Reviewed-by: FRANJOU Stephane <stephane.franjou@csgroup.eu>
> ---
>  configs/MCR3000_defconfig |  8 ++++++--
>  include/configs/MCR3000.h | 42 ++++++++++++++++++---------------------
>  2 files changed, 25 insertions(+), 25 deletions(-)
> 
> diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig
> index 6c41d7c88d1..2e9d8c24329 100644
> --- a/configs/MCR3000_defconfig
> +++ b/configs/MCR3000_defconfig
> @@ -20,6 +20,7 @@ CONFIG_SYS_SCCR=0x00C20000
>  CONFIG_SYS_SCCR_MASK=0x60000000
>  CONFIG_SYS_DER=0x2002000F
>  CONFIG_SYS_MONITOR_LEN=327680
> +CONFIG_FIT=y
>  CONFIG_OF_BOARD_SETUP=y
>  CONFIG_SYS_MONITOR_BASE=0x04000000
>  CONFIG_BOOTDELAY=5
> @@ -35,11 +36,12 @@ CONFIG_HUSH_PARSER=y
>  CONFIG_SYS_PBSIZE=278
>  # CONFIG_CMD_BDI is not set
>  # CONFIG_CMD_CONSOLE is not set
> -CONFIG_SYS_BOOTM_LEN=0x800000
> +CONFIG_SYS_BOOTM_LEN=0x2000000
>  # CONFIG_CMD_IMI 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_ECHO is not set
>  # CONFIG_CMD_ITEST is not set
> @@ -50,6 +52,8 @@ 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_OVERWRITE=y
>  CONFIG_ENV_IS_IN_FLASH=y
> @@ -80,6 +84,7 @@ CONFIG_SYS_BR7_PRELIM=0x1C000001
>  CONFIG_SYS_OR7_PRELIM=0xFFFF810A
>  # 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
> @@ -89,5 +94,4 @@ CONFIG_MPC8XX_FEC=y
>  # CONFIG_PCI is not set
>  CONFIG_DM_SERIAL=y
>  CONFIG_WDT=y
> -CONFIG_SHA256=y
>  CONFIG_LZMA=y
> diff --git a/include/configs/MCR3000.h b/include/configs/MCR3000.h
> index b0809332bb5..62c3404415c 100644
> --- a/include/configs/MCR3000.h
> +++ b/include/configs/MCR3000.h
> @@ -12,45 +12,40 @@
>  #define CONFIG_EXTRA_ENV_SETTINGS					\
>  	"sdram_type=SDRAM\0"						\
>  	"flash_type=AM29LV160DB\0"					\
> -	"loadaddr=0x400000\0"						\
> -	"filename=uImage.lzma\0"					\
> -	"nfsroot=/opt/ofs\0"						\
> +	"loadaddr=0x1200000\0"						\
> +	"filename=mcr3000.itb\0"					\
>  	"dhcp_ip=ip=:::::eth0:dhcp\0"					\
>  	"console_args=console=ttyCPM0,115200N8\0"			\
> +	"loadkernel=ubi part nand0;ubifsmount ubi0;"			\
> +		"ubifsload ${loadaddr} /boot/${filename};"		\
> +		"ubifsumount; ubi detach\0"				\
> +	"bootcmd=run flashboot\0" 					\
>  	"flashboot=setenv bootargs "					\
>  		"${console_args} "					\
>  		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
>  		"mcr3k:eth0:off;"					\
>  		"${ofl_args}; "						\
> -		"bootm 0x04060000 - 0x04050000\0"			\
> +		"run loadkernel; "					\
> +		"bootm ${loadaddr}\0"                                   \
>  	"tftpboot=setenv bootargs "					\
>  		"${console_args} "					\
>  		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
>  		"mcr3k:eth0:off "					\
>  		"${ofl_args}; "						\
>  		"tftp ${loadaddr} ${filename};"				\
> -		"tftp 0xf00000 mcr3000.dtb;"				\
> -		"bootm ${loadaddr} - 0xf00000\0"			\
> -	"netboot=dhcp ${loadaddr} ${filename};"				\
> -		"tftp 0xf00000 mcr3000.dtb;"				\
> -		"setenv bootargs "					\
> -		"root=/dev/nfs rw "					\
> -		"${console_args} "					\
> -		"${dhcp_ip};"						\
> -		"bootm ${loadaddr} - 0xf00000\0"			\
> -	"nfsboot=setenv bootargs "					\
> -		"root=/dev/nfs rw nfsroot=${serverip}:${nfsroot} "	\
> -		"${console_args} "					\
> -		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:"	\
> -		"mcr3k:eth0:off;"					\
> -		"bootm 0x04060000 - 0x04050000\0"			\
> +		"bootm ${loadaddr}\0"                                   \
>  	"dhcpboot=dhcp ${loadaddr} ${filename};"			\
> -		"tftp 0xf00000 mcr3000.dtb;"				\
>  		"setenv bootargs "					\
>  		"${console_args} "					\
>  		"${dhcp_ip} "						\
>  		"${ofl_args}; "						\
> -		"bootm ${loadaddr} - 0xf00000\0"
> +		"bootm ${loadaddr}\0"					\
> +	"update=echo 'Updating ubi image'; "				\
> +		"if tftp 0x2000 $ubifile; then "			\
> +		"nand erase.chip; "					\
> +		"nand write 0x2000 0x00 $filesize; "			\
> +		"fi;\0 "
> +

I would like to see this move instead to using the plain text
environment as can be see in commits such as 5c3f6a320678
("dragonboard410c: Migrate to using CONFIG_EXTRA_ENV_TEXT").

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-01-30 17:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-30 14:33 [PATCH 0/7] Add new equipment from CSSI Christophe Leroy
2023-01-30 14:34 ` [PATCH 1/7] board: MCR3000: Use lowercase filename Christophe Leroy
2023-01-30 14:34 ` [PATCH 2/7] board: MCR3000: Modernise the settings to properly work on lastest u-boot version Christophe Leroy
2023-01-30 17:23   ` Tom Rini
2023-01-30 14:34 ` [PATCH 3/7] board: MCR3000: Remove update of non-existing e1-wan DT node Christophe Leroy
2023-01-30 14:34 ` [PATCH 4/7] driver, gpio: Add support for MPC 8xx CPU ports Christophe Leroy
2023-01-30 14:34 ` [PATCH 5/7] spi, mpc8xx: Add support for chipselect via GPIO and fixups Christophe Leroy
2023-01-30 14:34 ` [PATCH 6/7] board: cssi: Add new board MCR3000_2G Christophe Leroy
2023-01-30 14:34 ` [PATCH 7/7] board: cssi: Add MIAE & VGoIP devices Christophe Leroy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.