summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-04-29 09:29:41 -0400
committerTom Rini <trini@konsulko.com>2023-04-29 09:29:41 -0400
commitfe3a77cb157a6210d8036845f5f80ea67c183563 (patch)
tree1d53e64cbcdf10c6e5dfb95cefd098e643820bed /board
parent076f13308c6f06e2c4feb8b408e997bc732586e1 (diff)
parent4d0c8db74d83e43dec4e7481b2d1e194f51d907b (diff)
downloadu-boot-fe3a77cb157a6210d8036845f5f80ea67c183563.tar.gz
Merge branch 'for-2023.07' of https://source.denx.de/u-boot/custodians/u-boot-mpc8xx
This pull request adds support for the last CPU board from CS GROUP France (previously CSSI). That CPU board called CMPCPRO has a mpc8321E CPU (Family PQII PRO hence its name) and can be plugged in place of the CMPC885 board. In order to support that new board, the following changes are included in this series: - Make the mpc8xx watchdog driver more generic for reusing it with mpc83xx - Fix various small problems on mpc83xx platform - Add a GPIO Driver for QE GPIOs - Add support for mpc832x into mpc83xx SPI driver - Refactor existing board code that will be shared with new board - Add the new board
Diffstat (limited to 'board')
-rw-r--r--board/cssi/MAINTAINERS2
-rw-r--r--board/cssi/cmpc885/Makefile2
-rw-r--r--board/cssi/cmpc885/cmpc885.c241
-rw-r--r--board/cssi/cmpcpro/Kconfig26
-rw-r--r--board/cssi/cmpcpro/Makefile8
-rw-r--r--board/cssi/cmpcpro/cmpcpro.c404
-rw-r--r--board/cssi/cmpcpro/cmpcpro.env8
-rw-r--r--board/cssi/cmpcpro/nand.c43
-rw-r--r--board/cssi/common/common.c219
-rw-r--r--board/cssi/common/common.h15
-rw-r--r--board/cssi/mcr3000/mcr3000.c14
11 files changed, 753 insertions, 229 deletions
diff --git a/board/cssi/MAINTAINERS b/board/cssi/MAINTAINERS
index d8e7b5e9b6..f82dd3b789 100644
--- a/board/cssi/MAINTAINERS
+++ b/board/cssi/MAINTAINERS
@@ -6,3 +6,5 @@ F: include/configs/mcr3000.h
F: configs/MCR3000_defconfig
F: include/configs/cmpc885.h
F: configs/CMPC885_defconfig
+F: include/configs/cmpcpro.h
+F: configs/CMPCPRO_defconfig
diff --git a/board/cssi/cmpc885/Makefile b/board/cssi/cmpc885/Makefile
index 6c055097cd..baf9e5ab4f 100644
--- a/board/cssi/cmpc885/Makefile
+++ b/board/cssi/cmpc885/Makefile
@@ -5,6 +5,6 @@
# Christophe Leroy <christophe.leroy@c-s.fr>
#
-obj-y += cmpc885.o
+obj-y += cmpc885.o ../common/common.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
index 5233c24aae..540b9d3c78 100644
--- a/board/cssi/cmpc885/cmpc885.c
+++ b/board/cssi/cmpc885/cmpc885.c
@@ -22,98 +22,28 @@
#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 BOARD_VGOIP "vgoip"
-#define BOARD_MIAE "miae"
+#include "../common/common.h"
-#define TYPE_MCR 0x22
-#define TYPE_MIAE 0x23
-
-#define FAR_CASRSA 2
-#define FAR_VGOIP 4
-#define FAV_CLA 7
-#define FAV_SRSA 8
+DECLARE_GLOBAL_DATA_PTR;
#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 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
#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);
@@ -137,32 +67,19 @@ int ft_board_setup(void *blob, struct bd_info *bd)
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)
+ if (!(in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE))
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;
+ return ft_board_setup_common(blob);
+}
- setbits_be32(&cp->cp_pedat, 0x00002000);
- }
+void ft_board_setup_phy3(void)
+{
+ /* 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;
- return 0;
+ setbits_be32(&cp->cp_pedat, 0x00002000);
}
int checkboard(void)
@@ -170,138 +87,47 @@ 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)) {
- 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");
- for (;;)
- ;
- break;
- }
- } else {
- printf("CMPC885 (CS GROUP)\n");
- }
+ if (in_be16(ADDR_CPLD_R_ETAT) & R_ETAT_PRES_BASE)
+ return checkboard_common();
+
+ 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
+#define EE_OFF_MAC1 0x10
+#define EE_OFF_MAC2 0x16
/* 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;
+ int 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);
+ ret = read_eeprom(din, sizeof(din));
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, tmp, far_id;
- int count = 3;
-
- 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;
-
- 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);
- break;
- }
+ misc_init_r_common();
} else {
- printf("no mother board detected");
- env_set("config", BOARD_CMPC885);
- env_set("hostname", BOARD_CMPC885);
+ env_set("config", CFG_BOARD_CMPCXXX);
+ env_set("hostname", CFG_BOARD_CMPCXXX);
}
if (setup_mac())
@@ -313,7 +139,7 @@ int misc_init_r(void)
return 0;
}
-static void iop_setup_mcr(void)
+void iop_setup_mcr(void)
{
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
iop8xx_t __iomem *iop = &immr->im_ioport;
@@ -616,7 +442,7 @@ static void iop_setup_cmpc885(void)
clrbits_be32(&cp->cp_peso, 0x00031980);
}
-static void iop_setup_miae(void)
+void iop_setup_miae(void)
{
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
iop8xx_t __iomem *iop = &immr->im_ioport;
@@ -626,7 +452,7 @@ static void iop_setup_miae(void)
udelay(100);
/* Set the front panel LED color to red */
- clrbits_8(ADDR_FPGA_R_FAV, 0x02);
+ clrbits_8((unsigned char __iomem *)CONFIG_FPGA_BASE + 0x44, 0x02);
/* We must initialize data before changing direction */
setbits_be16(&iop->iop_pcdat, 0x0888);
@@ -1084,20 +910,7 @@ int board_early_init_r(void)
mdelay(200);
}
- /* Identify the type of mother board */
- switch (in_8(ADDR_FPGA_R_BASE)) {
- case TYPE_MCR:
- iop_setup_mcr();
- break;
-
- case TYPE_MIAE:
- iop_setup_miae();
- break;
-
- default:
- break;
- }
- /* CMPC885 board alone */
+ iop_setup_common();
} else {
iop_setup_cmpc885();
}
diff --git a/board/cssi/cmpcpro/Kconfig b/board/cssi/cmpcpro/Kconfig
new file mode 100644
index 0000000000..b5d998ae5a
--- /dev/null
+++ b/board/cssi/cmpcpro/Kconfig
@@ -0,0 +1,26 @@
+if TARGET_CMPCPRO
+
+config SYS_BOARD
+ default "cmpcpro"
+
+config SYS_VENDOR
+ default "cssi"
+
+config SYS_CONFIG_NAME
+ default "cmpcpro"
+
+config TEXT_BASE
+ default 0x40000000
+
+config CPLD_BASE
+ hex
+ default 0x90000000
+
+config FPGA_BASE
+ hex
+ default 0x80000000
+
+config PCI
+ default no
+
+endif
diff --git a/board/cssi/cmpcpro/Makefile b/board/cssi/cmpcpro/Makefile
new file mode 100644
index 0000000000..73ff451ea1
--- /dev/null
+++ b/board/cssi/cmpcpro/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += cmpcpro.o nand.o ../common/common.o
diff --git a/board/cssi/cmpcpro/cmpcpro.c b/board/cssi/cmpcpro/cmpcpro.c
new file mode 100644
index 0000000000..3e9ba6a4cc
--- /dev/null
+++ b/board/cssi/cmpcpro/cmpcpro.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2006-2023 CS GROUP France
+ */
+
+#include <command.h>
+#include <common.h>
+#include <dm.h>
+#include <env.h>
+#include <env_internal.h>
+#include <eeprom.h>
+#include <fdt_support.h>
+#include <hang.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <netdev.h>
+#include <spi.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <linux/delay.h>
+#include <linux/immap_qe.h>
+#include <linux/libfdt.h>
+#include <linux/log2.h>
+#include <linux/sizes.h>
+
+#include <asm/io.h>
+#include <asm/global_data.h>
+#include <asm/mmu.h>
+
+#include <u-boot/crc.h>
+
+#include "../common/common.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ADDR_FPGA_BASE ((unsigned char __iomem *)CONFIG_CPLD_BASE)
+#define ADDR_FPGA_RESET_G (ADDR_FPGA_BASE + 0x40)
+#define ADDR_FPGA_REG_ETAT (ADDR_FPGA_BASE + 0x42)
+
+#define R_ETAT_PRES_BASE 0x01
+#define RESET_G_OK 0x08
+
+/* SPI EEPROM parameters */
+#define MAX_SPI_BYTES 0x28
+#define EE_OFF_MAC1 0x10
+#define EE_OFF_MAC2 0x16
+#define EE_OFF_MAC3 0x1C
+
+static uint upma_table[] = {
+ /* Read Single-Beat (RSS) */
+ 0x00AC0C00, 0x00FC1C40, 0x30FCE045, 0xFFFF0C00,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* Read Burst (RBS) */
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* Write Single-Beat (WSS) */
+ 0x00A30C00, 0x00F31C40, 0x3FF3C045, 0xFFFF0C00,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* Write Burst (WBS) */
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* Refresh Timer (RTS) */
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* Exception Condition (EXS) */
+ 0xFFFF0C01, 0xFFFF0C01, 0xFFFF0C01, 0xFFFF0C01,
+};
+
+const qe_iop_conf_t qe_iop_conf_tab[] = {
+ /* ETH3 */
+ {1, 0, 1, 0, 1}, /* TxD0 */
+ {1, 1, 1, 0, 1}, /* TxD1 */
+ {1, 2, 1, 0, 1}, /* TxD2 */
+ {1, 3, 1, 0, 1}, /* TxD3 */
+ {1, 9, 1, 0, 1}, /* TxER */
+ {1, 12, 1, 0, 1}, /* TxEN */
+ {3, 24, 2, 0, 1}, /* TxCLK->CLK10 */
+
+ {1, 4, 2, 0, 1}, /* RxD0 */
+ {1, 5, 2, 0, 1}, /* RxD1 */
+ {1, 6, 2, 0, 1}, /* RxD2 */
+ {1, 7, 2, 0, 1}, /* RxD3 */
+ {1, 8, 2, 0, 1}, /* RxER */
+ {1, 10, 2, 0, 1}, /* RxDV */
+ {0, 13, 2, 0, 1}, /* RxCLK->CLK9 */
+ {1, 11, 2, 0, 1}, /* COL */
+ {1, 13, 2, 0, 1}, /* CRS */
+
+ /* ETH4 */
+ {1, 18, 1, 0, 1}, /* TxD0 */
+ {1, 19, 1, 0, 1}, /* TxD1 */
+ {1, 20, 1, 0, 1}, /* TxD2 */
+ {1, 21, 1, 0, 1}, /* TxD3 */
+ {1, 27, 1, 0, 1}, /* TxER */
+ {1, 30, 1, 0, 1}, /* TxEN */
+ {3, 6, 2, 0, 1}, /* TxCLK->CLK8 */
+
+ {1, 22, 2, 0, 1}, /* RxD0 */
+ {1, 23, 2, 0, 1}, /* RxD1 */
+ {1, 24, 2, 0, 1}, /* RxD2 */
+ {1, 25, 2, 0, 1}, /* RxD3 */
+ {1, 26, 1, 0, 1}, /* RxER */
+ {1, 28, 2, 0, 1}, /* Rx_DV */
+ {3, 31, 2, 0, 1}, /* RxCLK->CLK7 */
+ {1, 29, 2, 0, 1}, /* COL */
+ {1, 31, 2, 0, 1}, /* CRS */
+
+ {3, 4, 3, 0, 2}, /* MDIO */
+ {3, 5, 1, 0, 2}, /* MDC */
+
+ {0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */
+};
+
+void iop_setup_miae(void)
+{
+ immap_t __iomem *im = (immap_t *)CONFIG_SYS_IMMR;
+
+ /* PORTA configuration */
+ out_be32(&im->qepio.ioport[0].pdat, 0x00808000);
+ out_be32(&im->qepio.ioport[0].podr, 0x00008000);
+ out_be32(&im->qepio.ioport[0].dir1, 0x40800968);
+ out_be32(&im->qepio.ioport[0].dir2, 0x650A0896);
+ out_be32(&im->qepio.ioport[0].ppar1, 0x40400204);
+ out_be32(&im->qepio.ioport[0].ppar2, 0x05050464);
+
+ /* PORTB configuration */
+ out_be32(&im->qepio.ioport[1].pdat, 0x00018000);
+ out_be32(&im->qepio.ioport[1].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[1].dir1, 0x50A08949);
+ out_be32(&im->qepio.ioport[1].dir2, 0x5C0C6890);
+ out_be32(&im->qepio.ioport[1].ppar1, 0x50504644);
+ out_be32(&im->qepio.ioport[1].ppar2, 0x080800A0);
+
+ /* PORTC configuration */
+ out_be32(&im->qepio.ioport[2].pdat, 0x3D000108);
+ out_be32(&im->qepio.ioport[2].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[2].dir1, 0x45518000);
+ out_be32(&im->qepio.ioport[2].dir2, 0xA8119561);
+ out_be32(&im->qepio.ioport[2].ppar1, 0x80008000);
+ out_be32(&im->qepio.ioport[2].ppar2, 0x00000000);
+
+ /* PORTD configuration */
+ out_be32(&im->qepio.ioport[3].pdat, 0x1000E000);
+ out_be32(&im->qepio.ioport[3].podr, 0x0000E000);
+ out_be32(&im->qepio.ioport[3].dir1, 0xFDD20800);
+ out_be32(&im->qepio.ioport[3].dir2, 0x54155228);
+ out_be32(&im->qepio.ioport[3].ppar1, 0x54A30C00);
+ out_be32(&im->qepio.ioport[3].ppar2, 0x00000100);
+}
+
+void iop_setup_mcr(void)
+{
+ immap_t __iomem *im = (immap_t *)CONFIG_SYS_IMMR;
+
+ /* PORTA configuration */
+ out_be32(&im->qepio.ioport[0].pdat, 0x00808004);
+ out_be32(&im->qepio.ioport[0].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[0].dir1, 0x40800A68);
+ out_be32(&im->qepio.ioport[0].dir2, 0x650A0896);
+ out_be32(&im->qepio.ioport[0].ppar1, 0x40400004);
+ out_be32(&im->qepio.ioport[0].ppar2, 0x05050444);
+
+ /* PORTB configuration */
+ out_be32(&im->qepio.ioport[1].pdat, 0x00008000);
+ out_be32(&im->qepio.ioport[1].podr, 0x00000004);
+ out_be32(&im->qepio.ioport[1].dir1, 0x50A08A4A);
+ out_be32(&im->qepio.ioport[1].dir2, 0x5C0C6890);
+ out_be32(&im->qepio.ioport[1].ppar1, 0x50504444);
+ out_be32(&im->qepio.ioport[1].ppar2, 0x08080080);
+
+ /* PORTC configuration */
+ out_be32(&im->qepio.ioport[2].pdat, 0x3D000018);
+ out_be32(&im->qepio.ioport[2].podr, 0x00000400);
+ out_be32(&im->qepio.ioport[2].dir1, 0x45518000);
+ out_be32(&im->qepio.ioport[2].dir2, 0xA8129561);
+ out_be32(&im->qepio.ioport[2].ppar1, 0x80008000);
+ out_be32(&im->qepio.ioport[2].ppar2, 0x00000000);
+
+ /* PORTD configuration */
+ out_be32(&im->qepio.ioport[3].pdat, 0x1000E000);
+ out_be32(&im->qepio.ioport[3].podr, 0x0000E000);
+ out_be32(&im->qepio.ioport[3].dir1, 0xFDD20800);
+ out_be32(&im->qepio.ioport[3].dir2, 0x54155228);
+ out_be32(&im->qepio.ioport[3].ppar1, 0x54A30C00);
+ out_be32(&im->qepio.ioport[3].ppar2, 0x00000100);
+}
+
+static void iop_setup_cmpcpro(void)
+{
+ immap_t __iomem *im = (immap_t *)CONFIG_SYS_IMMR;
+
+ /* PORTA configuration */
+ out_be32(&im->qepio.ioport[0].pdat, 0x00000000);
+ out_be32(&im->qepio.ioport[0].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[0].dir1, 0x50A84020);
+ out_be32(&im->qepio.ioport[0].dir2, 0x00000000);
+ out_be32(&im->qepio.ioport[0].ppar1, 0xF0FCC000);
+ out_be32(&im->qepio.ioport[0].ppar2, 0x00000000);
+
+ /* PORTB configuration */
+ out_be32(&im->qepio.ioport[1].pdat, 0x00000000);
+ out_be32(&im->qepio.ioport[1].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[1].dir1, 0x00000000);
+ out_be32(&im->qepio.ioport[1].dir2, 0x00006800);
+ out_be32(&im->qepio.ioport[1].ppar1, 0x00000000);
+ out_be32(&im->qepio.ioport[1].ppar2, 0x00000000);
+
+ /* PORTC configuration */
+ out_be32(&im->qepio.ioport[2].pdat, 0x19000000);
+ out_be32(&im->qepio.ioport[2].podr, 0x00000000);
+ out_be32(&im->qepio.ioport[2].dir1, 0x01410000);
+ out_be32(&im->qepio.ioport[2].dir2, 0xA8009400);
+ out_be32(&im->qepio.ioport[2].ppar1, 0x00000000);
+ out_be32(&im->qepio.ioport[2].ppar2, 0x00000000);
+
+ /* PORTD configuration */
+ out_be32(&im->qepio.ioport[3].pdat, 0x1000E000);
+ out_be32(&im->qepio.ioport[3].podr, 0x0000E000);
+ out_be32(&im->qepio.ioport[3].dir1, 0xFD020000);
+ out_be32(&im->qepio.ioport[3].dir2, 0x54055000);
+ out_be32(&im->qepio.ioport[3].ppar1, 0x54030000);
+ out_be32(&im->qepio.ioport[3].ppar2, 0x00000000);
+}
+
+int board_early_init_r(void)
+{
+ immap_t __iomem *im = (immap_t *)CONFIG_SYS_IMMR;
+ fsl_lbc_t *lbus = &im->im_lbc;
+
+ upmconfig(UPMA, upma_table, ARRAY_SIZE(upma_table));
+
+ out_be32(&lbus->mamr, 0x00044440);
+
+ /* configure LBCR register */
+ out_be32(&lbus->lbcr, 0x00000500);
+ sync();
+
+ if (in_8(ADDR_FPGA_REG_ETAT) & R_ETAT_PRES_BASE) {
+ int i;
+
+ /* Initialize signal PROG_FPGA_FIRMWARE */
+ setbits_be32(&im->qepio.ioport[0].pdat, 0x00008000);
+ setbits_be32(&im->qepio.ioport[0].dir2, 0x60000002);
+ setbits_be32(&im->qepio.ioport[0].podr, 0x00008000);
+
+ mdelay(1);
+
+ /* Now read CPDATA[31] to check if FPGA is loaded */
+ if (!in_be32(&im->qepio.ioport[0].pdat) & 0x00000001) {
+ printf("Reloading FPGA firmware.\n");
+
+ clrbits_be32(&im->qepio.ioport[0].pdat, 0x00008000);
+ udelay(1);
+ setbits_be32(&im->qepio.ioport[0].pdat, 0x00008000);
+
+ /* Wait 200 msec and check DONE_FPGA_FIRMWARE */
+ mdelay(200);
+ if (!(in_be32(&im->qepio.ioport[0].pdat) & 0x00000001)) {
+ for (;;) {
+ printf("error loading firmware.\n");
+ mdelay(500);
+ }
+ }
+
+ /* Send a reset signal and wait for 20 msec */
+ out_8(ADDR_FPGA_RESET_G, in_8(ADDR_FPGA_RESET_G) | RESET_G_OK);
+ mdelay(20);
+ out_8(ADDR_FPGA_RESET_G, in_8(ADDR_FPGA_RESET_G) & ~RESET_G_OK);
+ }
+
+ /* Wait 300 msec and check the reset state */
+ mdelay(300);
+ for (i = 0; !(in_8(ADDR_FPGA_REG_ETAT) & RESET_G_OK); i++) {
+ for (;;) {
+ printf("Could not reset FPGA.\n");
+ mdelay(500);
+ }
+ }
+
+ iop_setup_common();
+
+ /* clocks configuration */
+ out_be32(&qe_immr->qmx.cmxsi1cr_l, 0x00040004);
+ out_be32(&qe_immr->qmx.cmxsi1syr, 0x00000000);
+ } else {
+ iop_setup_cmpcpro();
+ }
+
+ return 0;
+}
+
+int dram_init(int board_type)
+{
+ immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+ out_be32(&im->sysconf.ddrlaw[0].bar, CFG_SYS_DDR_SDRAM_BASE & LAWBAR_BAR);
+ out_be32(&im->sysconf.ddrlaw[0].ar, LAWAR_EN | ((ilog2(SZ_512M) - 1) & LAWAR_SIZE));
+
+ out_be32(&im->ddr.sdram_clk_cntl, CFG_SYS_DDR_CLK_CNTL);
+ out_be32(&im->ddr.csbnds[0].csbnds, CFG_SYS_DDR_CS0_BNDS);
+ out_be32(&im->ddr.cs_config[0], CFG_SYS_DDR_CS0_CONFIG);
+
+ out_be32(&im->ddr.timing_cfg_0, CFG_SYS_DDR_TIMING_0);
+ out_be32(&im->ddr.timing_cfg_1, CFG_SYS_DDR_TIMING_1);
+ out_be32(&im->ddr.timing_cfg_2, CFG_SYS_DDR_TIMING_2);
+ out_be32(&im->ddr.timing_cfg_3, CFG_SYS_DDR_TIMING_3);
+ out_be32(&im->ddr.sdram_cfg, CFG_SYS_DDR_SDRAM_CFG);
+ out_be32(&im->ddr.sdram_cfg2, CFG_SYS_DDR_SDRAM_CFG2);
+ out_be32(&im->ddr.sdram_mode, CFG_SYS_DDR_MODE);
+ out_be32(&im->ddr.sdram_mode2, CFG_SYS_DDR_MODE2);
+ out_be32(&im->ddr.sdram_interval, CFG_SYS_DDR_INTERVAL);
+ udelay(200);
+
+ setbits_be32(&im->ddr.sdram_cfg, SDRAM_CFG_MEM_EN);
+
+ gd->ram_size = SZ_512M;
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ printf("Board: ");
+
+ /* Is a motherboard present ? */
+ if (in_8(ADDR_FPGA_REG_ETAT) & R_ETAT_PRES_BASE)
+ return checkboard_common();
+
+ printf("CMPCPRO (CS GROUP)\n");
+
+ return 0;
+}
+
+/* Reads MAC addresses from SPI EEPROM */
+static int setup_mac(void)
+{
+ uchar din[MAX_SPI_BYTES];
+ int ret;
+ unsigned long ident = 0x08005120;
+
+ ret = read_eeprom(din, sizeof(din));
+ if (ret)
+ return ret;
+
+ if (memcmp(din + EE_OFF_MAC1, &ident, sizeof(ident)) == 0) {
+ eth_env_set_enetaddr("ethaddr", din + EE_OFF_MAC1);
+ eth_env_set_enetaddr("eth3addr", din + EE_OFF_MAC1);
+ }
+
+ if (memcmp(din + EE_OFF_MAC2, &ident, sizeof(ident)) == 0)
+ eth_env_set_enetaddr("eth1addr", din + EE_OFF_MAC2);
+
+ if (memcmp(din + EE_OFF_MAC3, &ident, sizeof(ident)) == 0)
+ eth_env_set_enetaddr("eth2addr", din + EE_OFF_MAC3);
+
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ /* we do not modify environment variable area if CRC is false */
+ /* Verify if mother board is present */
+ if (in_8(ADDR_FPGA_REG_ETAT) & R_ETAT_PRES_BASE) {
+ misc_init_r_common();
+ } else {
+ env_set("config", CFG_BOARD_CMPCXXX);
+ env_set("hostname", CFG_BOARD_CMPCXXX);
+ }
+
+ if (setup_mac())
+ printf("Error retrieving mac addresses\n");
+
+ return 0;
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ ft_cpu_setup(blob, bd);
+
+ /* MIAE only */
+ if (!(in_8(ADDR_FPGA_REG_ETAT) & R_ETAT_PRES_BASE))
+ return 0;
+
+ return ft_board_setup_common(blob);
+}
+
+void ft_board_setup_phy3(void)
+{
+ /* switch to phy3 with gpio, we'll only use phy3 */
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+
+ setbits_be32(&immr->qepio.ioport[2].pdat, 0x00000400);
+}
+
+#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)
+
diff --git a/board/cssi/cmpcpro/cmpcpro.env b/board/cssi/cmpcpro/cmpcpro.env
new file mode 100644
index 0000000000..7394b8386e
--- /dev/null
+++ b/board/cssi/cmpcpro/cmpcpro.env
@@ -0,0 +1,8 @@
+loadaddr=0x1a00000
+filename=cmpcpro.itb
+netdev=eth0
+console_args=console=ttyS0,115200N8
+loadkernel=ubi part nand0;ubifsmount ubi0; ubifsload ${loadaddr} /boot/${filename}; ubifsumount; ubi detach
+flashboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm $loadaddr#$config
+tftpboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename}; bootm $loadaddr#$config
+update=echo 'Updating ubi image'; mw.w 90000040 0x000E 1; if tftp $loadaddr $ubifile; then nand erase.chip; nand write $loadaddr 0x00 $filesize; fi;
diff --git a/board/cssi/cmpcpro/nand.c b/board/cssi/cmpcpro/nand.c
new file mode 100644
index 0000000000..d8b4197314
--- /dev/null
+++ b/board/cssi/cmpcpro/nand.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010-2023 CS GROUP France
+ * Florent TRINH THAI (florent.trinh-thai@csgroup.eu)
+ * Stephane FRANJOU (stephane.franjou@csgroup.eu)
+ */
+
+#include <config.h>
+#include <nand.h>
+#include <linux/bitops.h>
+#include <linux/mtd/rawnand.h>
+#include <asm/io.h>
+
+#define BIT_CLE BIT(6)
+#define BIT_ALE BIT(5)
+
+static u32 nand_mask(unsigned int ctrl)
+{
+ return ((ctrl & NAND_CLE) ? BIT_CLE : 0) |
+ ((ctrl & NAND_ALE) ? BIT_ALE : 0);
+}
+
+static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
+{
+ immap_t __iomem *immr = (immap_t *)CONFIG_SYS_IMMR;
+ struct nand_chip *chip = mtd_to_nand(mtdinfo);
+
+ if (ctrl & NAND_CTRL_CHANGE)
+ clrsetbits_be32(&immr->qepio.ioport[2].pdat,
+ BIT_CLE | BIT_ALE, nand_mask(ctrl));
+
+ if (cmd != NAND_CMD_NONE)
+ out_8(chip->IO_ADDR_W, cmd);
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ nand->chip_delay = 60;
+ nand->ecc.mode = NAND_ECC_SOFT;
+ nand->cmd_ctrl = nand_hwcontrol;
+
+ return 0;
+}
diff --git a/board/cssi/common/common.c b/board/cssi/common/common.c
new file mode 100644
index 0000000000..7ecf772620
--- /dev/null
+++ b/board/cssi/common/common.c
@@ -0,0 +1,219 @@
+// 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>
+ *
+ * Common specific routines for the CS Group boards
+ */
+
+#include <dm.h>
+#include <env.h>
+#include <fdt_support.h>
+#include <hang.h>
+#include <spi.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include "common.h"
+
+#define ADDR_FPGA_R_BASE ((unsigned char __iomem *)CONFIG_FPGA_BASE)
+
+#define FPGA_R_ACQ_AL_FAV 0x04
+
+#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 SPI_EEPROM_READ 0x03
+
+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, unsigned long 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 read_eeprom(u8 *din, int len)
+{
+ struct udevice *eeprom;
+ struct spi_slave *slave;
+ uchar dout[3] = {SPI_EEPROM_READ, 0, 0};
+ int ret;
+
+ ret = uclass_get_device(UCLASS_SPI, 0, &eeprom);
+ if (ret)
+ return ret;
+
+ ret = _spi_get_bus_and_cs(0, 0, 1000000, 0, "spi_generic_drv",
+ "generic_0:0", &eeprom, &slave);
+ if (ret)
+ return ret;
+
+ ret = spi_claim_bus(slave);
+
+ ret = spi_xfer(slave, sizeof(dout) << 3, dout, NULL, SPI_XFER_BEGIN);
+ if (ret)
+ return ret;
+
+ ret = spi_xfer(slave, len << 3, NULL, din, SPI_XFER_END);
+ if (ret)
+ return ret;
+
+ spi_release_bus(slave);
+
+ return 0;
+}
+
+int ft_board_setup_common(void *blob)
+{
+ u8 far_id, fav_id;
+
+ if (in_8(ADDR_FPGA_R_BASE) != TYPE_MIAE)
+ return 0;
+
+ far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
+ ft_cleanup(blob, far_id, "far-id", "cs,mia-far");
+
+ 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, fav_id, "fav-id", "cs,mia-fav");
+
+ if (far_id == FAR_CASRSA)
+ ft_board_setup_phy3();
+
+ return 0;
+}
+
+int checkboard_common(void)
+{
+ 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");
+ for (;;)
+ ;
+ break;
+ }
+ return 0;
+}
+
+void misc_init_r_common(void)
+{
+ u8 tmp, far_id;
+ int count = 3;
+
+ switch (in_8(ADDR_FPGA_R_BASE)) {
+ case TYPE_MCR:
+ /* if at boot alarm button is pressed, delay boot */
+ if ((in_8(ADDR_FPGA_R_BASE + 0x31) & FPGA_R_ACQ_AL_FAV) == 0)
+ env_set("bootdelay", "60");
+
+ env_set("config", CFG_BOARD_MCR3000_2G);
+ env_set("hostname", CFG_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", CFG_BOARD_MIAE);
+ far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
+
+ if (far_id == FAR_VGOIP)
+ env_set("hostname", CFG_BOARD_VGOIP);
+ else
+ env_set("hostname", CFG_BOARD_MIAE);
+ break;
+
+ default:
+ env_set("config", CFG_BOARD_CMPCXXX);
+ env_set("hostname", CFG_BOARD_CMPCXXX);
+ break;
+ }
+}
+
+void iop_setup_common(void)
+{
+ u8 type = in_8(ADDR_FPGA_R_BASE);
+
+ if (type == TYPE_MCR)
+ iop_setup_mcr();
+ else if (type == TYPE_MIAE)
+ iop_setup_miae();
+}
diff --git a/board/cssi/common/common.h b/board/cssi/common/common.h
new file mode 100644
index 0000000000..c5ecb038c9
--- /dev/null
+++ b/board/cssi/common/common.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _BOARD_CSSI_COMMON_H
+#define _BOARD_CSSI_COMMON_H
+
+int read_eeprom(u8 *din, int len);
+int ft_board_setup_common(void *blob);
+void ft_board_setup_phy3(void);
+int checkboard_common(void);
+void misc_init_r_common(void);
+void iop_setup_common(void);
+void iop_setup_mcr(void);
+void iop_setup_miae(void);
+
+#endif /* _BOARD_CSSI_COMMON_H */
diff --git a/board/cssi/mcr3000/mcr3000.c b/board/cssi/mcr3000/mcr3000.c
index 7b3ab12bd5..3514f67490 100644
--- a/board/cssi/mcr3000/mcr3000.c
+++ b/board/cssi/mcr3000/mcr3000.c
@@ -138,17 +138,3 @@ int board_early_init_f(void)
return 0;
}
-
-int board_early_init_r(void)
-{
- struct udevice *watchdog_dev = NULL;
-
- if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
- puts("Cannot find watchdog!\n");
- } else {
- puts("Enabling watchdog.\n");
- wdt_start(watchdog_dev, 0xffff, 0);
- }
-
- return 0;
-}