[PATCH 0/7] Add new equipment from CSSI

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

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

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 */

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; " \
"tftpboot=setenv bootargs " \ "${console_args} " \ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ "mcr3k:eth0:off " \ "${ofl_args}; " \ "tftp ${loadaddr} ${filename};" \"bootm ${loadaddr}\0" \
"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" \
"dhcpboot=dhcp ${loadaddr} ${filename};" \"bootm ${loadaddr}\0" \
"setenv bootargs " \ "${console_args} " \ "${dhcp_ip} " \ "${ofl_args}; " \"tftp 0xf00000 mcr3000.dtb;" \
"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").

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; }

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(®s->pdat) & mask; +} + +static inline u16 gpio16_get_dir(void __iomem *base, u16 mask, int type) +{ + struct iop_16 *regs = base; + + return in_be16(®s->pdir) & mask; +} + +static inline void gpio16_set_in(void __iomem *base, u16 gpios, int type) +{ + struct iop_16 *regs = base; + + clrbits_be16(®s->pdat, gpios); + /* GPDIR register 0 -> input */ + clrbits_be16(®s->pdir, gpios); +} + +static inline void gpio16_set_lo(void __iomem *base, u16 gpios, int type) +{ + struct iop_16 *regs = base; + + clrbits_be16(®s->pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be16(®s->pdir, gpios); +} + +static inline void gpio16_set_hi(void __iomem *base, u16 gpios, int type) +{ + struct iop_16 *regs = base; + + setbits_be16(®s->pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be16(®s->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(®s->b.pdat) & mask; + else + return in_be32(®s->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(®s->b.pdir) & mask; + else + return in_be32(®s->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(®s->b.pdat, gpios); + /* GPDIR register 0 -> input */ + clrbits_be32(®s->b.pdir, gpios); + } else { /* Port E */ + clrbits_be32(®s->e.pdat, gpios); + /* GPDIR register 0 -> input */ + clrbits_be32(®s->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(®s->b.pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(®s->b.pdir, gpios); + } else { + clrbits_be32(®s->e.pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(®s->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(®s->b.pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(®s->b.pdir, gpios); + } else { + setbits_be32(®s->e.pdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(®s->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), +};

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), };

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 */

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; }
participants (2)
-
Christophe Leroy
-
Tom Rini