From 2eed0c25f613b707a36600496fe0219d235238bb Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Sat, 28 Jan 2023 13:53:10 +0100 Subject: [PATCH 1/9] powerpc/mpc8xx: Zero boot_flags arg for calling board_init_f() Copied from e83a7e94532 ("powerpc/mpc83xx: Zero boot_flags arg for calling board_init_f()") The argument boot_flags of board_init_f() is not used at all in the powerpc specific board.c init sequence. Now with the generic init sequence, this boot_flags arg is used by board_init_f(). This patch sets the r3 register that is used to pass the boot_flags argument from the start.S board_init_f() call to 0 prior to the function call to avoid unknown content to end up in gd->flags. Signed-off-by: Christophe Leroy Fixes: 09f3ca3dd53 ("arm, powerpc: select SYS_GENERIC_BOARD") --- arch/powerpc/cpu/mpc8xx/start.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/cpu/mpc8xx/start.S b/arch/powerpc/cpu/mpc8xx/start.S index 1f1107e61d5..0aa73fca125 100644 --- a/arch/powerpc/cpu/mpc8xx/start.S +++ b/arch/powerpc/cpu/mpc8xx/start.S @@ -171,6 +171,7 @@ in_flash: lis r3, CONFIG_SYS_IMMR@h bl cpu_init_f /* run low-level CPU init code (from Flash) */ + li r3, 0 /* clear boot_flag for calling board_init_f */ bl board_init_f /* run 1st part of board init code (from Flash) */ /* NOTREACHED - board_init_f() does not return */ From d8809bac482508ea7a961c12f64311d12e8f5594 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 30 Jan 2023 09:11:03 +0100 Subject: [PATCH 2/9] board: MCR3000: Use lowercase filenames Rename MCR3000.* to mcr3000.* to be more in line with other boards. Signed-off-by: Christophe Leroy --- arch/powerpc/cpu/mpc8xx/Kconfig | 2 +- board/cssi/MAINTAINERS | 2 +- board/cssi/{MCR3000 => mcr3000}/Kconfig | 4 ++-- board/cssi/{MCR3000 => mcr3000}/Makefile | 2 +- board/cssi/{MCR3000/MCR3000.c => mcr3000/mcr3000.c} | 0 board/cssi/{MCR3000 => mcr3000}/nand.c | 0 board/cssi/{MCR3000 => mcr3000}/u-boot.lds | 0 include/configs/{MCR3000.h => mcr3000.h} | 0 8 files changed, 5 insertions(+), 5 deletions(-) rename board/cssi/{MCR3000 => mcr3000}/Kconfig (78%) rename board/cssi/{MCR3000 => mcr3000}/Makefile (90%) rename board/cssi/{MCR3000/MCR3000.c => mcr3000/mcr3000.c} (100%) rename board/cssi/{MCR3000 => mcr3000}/nand.c (100%) rename board/cssi/{MCR3000 => mcr3000}/u-boot.lds (100%) rename include/configs/{MCR3000.h => mcr3000.h} (100%) diff --git a/arch/powerpc/cpu/mpc8xx/Kconfig b/arch/powerpc/cpu/mpc8xx/Kconfig index d63071104c4..65293ae728c 100644 --- a/arch/powerpc/cpu/mpc8xx/Kconfig +++ b/arch/powerpc/cpu/mpc8xx/Kconfig @@ -84,6 +84,6 @@ config SYS_DER help Debug Event Register (37-47) -source "board/cssi/MCR3000/Kconfig" +source "board/cssi/mcr3000/Kconfig" endmenu diff --git a/board/cssi/MAINTAINERS b/board/cssi/MAINTAINERS index 7d237b0b209..e1c0baa7082 100644 --- a/board/cssi/MAINTAINERS +++ b/board/cssi/MAINTAINERS @@ -2,5 +2,5 @@ BOARDS from CS GROUP France M: Christophe Leroy S: Maintained F: board/cssi/ -F: include/configs/MCR3000.h +F: include/configs/mcr3000.h F: configs/MCR3000_defconfig diff --git a/board/cssi/MCR3000/Kconfig b/board/cssi/mcr3000/Kconfig similarity index 78% rename from board/cssi/MCR3000/Kconfig rename to board/cssi/mcr3000/Kconfig index dbe2d5f0a3a..ea073d9140d 100644 --- a/board/cssi/MCR3000/Kconfig +++ b/board/cssi/mcr3000/Kconfig @@ -1,13 +1,13 @@ if TARGET_MCR3000 config SYS_BOARD - default "MCR3000" + default "mcr3000" config SYS_VENDOR default "cssi" config SYS_CONFIG_NAME - default "MCR3000" + default "mcr3000" config TEXT_BASE default 0x04000000 diff --git a/board/cssi/MCR3000/Makefile b/board/cssi/mcr3000/Makefile similarity index 90% rename from board/cssi/MCR3000/Makefile rename to board/cssi/mcr3000/Makefile index 68d6812a89a..7803016af3a 100644 --- a/board/cssi/MCR3000/Makefile +++ b/board/cssi/mcr3000/Makefile @@ -4,5 +4,5 @@ # Christophe Leroy # -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 diff --git a/board/cssi/MCR3000/nand.c b/board/cssi/mcr3000/nand.c similarity index 100% rename from board/cssi/MCR3000/nand.c rename to board/cssi/mcr3000/nand.c diff --git a/board/cssi/MCR3000/u-boot.lds b/board/cssi/mcr3000/u-boot.lds similarity index 100% rename from board/cssi/MCR3000/u-boot.lds rename to board/cssi/mcr3000/u-boot.lds diff --git a/include/configs/MCR3000.h b/include/configs/mcr3000.h similarity index 100% rename from include/configs/MCR3000.h rename to include/configs/mcr3000.h From d126006635aa345269d8502a90f634e89742ae85 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 6 Feb 2023 19:17:24 +0100 Subject: [PATCH 3/9] board: MCR3000: Migrate to using CONFIG_EXTRA_ENV_TEXT We can move all of the environment changes to come from CONFIG_EXTRA_ENV_TEXT. Suggested-by: Tom Rini Signed-off-by: Christophe Leroy --- board/cssi/mcr3000/mcr3000.env | 14 +++++++++++ include/configs/mcr3000.h | 43 ---------------------------------- 2 files changed, 14 insertions(+), 43 deletions(-) create mode 100644 board/cssi/mcr3000/mcr3000.env diff --git a/board/cssi/mcr3000/mcr3000.env b/board/cssi/mcr3000/mcr3000.env new file mode 100644 index 00000000000..542d90e3ae3 --- /dev/null +++ b/board/cssi/mcr3000/mcr3000.env @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +sdram_type=SDRAM +flash_type=AM29LV160DB +loadaddr=0x400000 +filename=uImage.lzma +nfsroot=/opt/ofs +dhcp_ip=ip=:::::eth0:dhcp +console_args=console=ttyCPM0,115200N8 +flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;${ofl_args}; bootm 0x04060000 - 0x04050000 +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 +netboot=dhcp ${loadaddr} ${filename};tftp 0xf00000 mcr3000.dtb;setenv bootargs root=/dev/nfs rw ${console_args} ${dhcp_ip};bootm ${loadaddr} - 0xf00000 +nfsboot=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${nfsroot} ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;bootm 0x04060000 - 0x04050000 +dhcpboot=dhcp ${loadaddr} ${filename};tftp 0xf00000 mcr3000.dtb;setenv bootargs ${console_args} ${dhcp_ip} ${ofl_args}; bootm ${loadaddr} - 0xf00000 diff --git a/include/configs/mcr3000.h b/include/configs/mcr3000.h index c6929c1b987..8d78fd362a9 100644 --- a/include/configs/mcr3000.h +++ b/include/configs/mcr3000.h @@ -9,49 +9,6 @@ /* High Level Configuration Options */ -#define CFG_EXTRA_ENV_SETTINGS \ - "sdram_type=SDRAM\0" \ - "flash_type=AM29LV160DB\0" \ - "loadaddr=0x400000\0" \ - "filename=uImage.lzma\0" \ - "nfsroot=/opt/ofs\0" \ - "dhcp_ip=ip=:::::eth0:dhcp\0" \ - "console_args=console=ttyCPM0,115200N8\0" \ - "flashboot=setenv bootargs " \ - "${console_args} " \ - "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ - "mcr3k:eth0:off;" \ - "${ofl_args}; " \ - "bootm 0x04060000 - 0x04050000\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" \ - "dhcpboot=dhcp ${loadaddr} ${filename};" \ - "tftp 0xf00000 mcr3000.dtb;" \ - "setenv bootargs " \ - "${console_args} " \ - "${dhcp_ip} " \ - "${ofl_args}; " \ - "bootm ${loadaddr} - 0xf00000\0" - /* Miscellaneous configurable options */ /* Definitions for initial stack pointer and data area (in DPRAM) */ From 7df55bb9b58b325b2aaa902c724826e4c30492f1 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 6 Feb 2023 19:33:53 +0100 Subject: [PATCH 4/9] board: MCR3000: Modernise the settings to properly work on lastest u-boot version 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 CFG_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. And set the netmask to 255.255.255.0 as a class C address is used. Signed-off-by: Christophe Leroy Reviewed-by: FRANJOU Stephane --- board/cssi/mcr3000/mcr3000.env | 16 ++++++++-------- configs/MCR3000_defconfig | 10 +++++++--- include/configs/mcr3000.h | 4 ++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/board/cssi/mcr3000/mcr3000.env b/board/cssi/mcr3000/mcr3000.env index 542d90e3ae3..372ab09094d 100644 --- a/board/cssi/mcr3000/mcr3000.env +++ b/board/cssi/mcr3000/mcr3000.env @@ -2,13 +2,13 @@ sdram_type=SDRAM flash_type=AM29LV160DB -loadaddr=0x400000 -filename=uImage.lzma -nfsroot=/opt/ofs +loadaddr=0x1200000 +filename=mcr3000.itb dhcp_ip=ip=:::::eth0:dhcp console_args=console=ttyCPM0,115200N8 -flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;${ofl_args}; bootm 0x04060000 - 0x04050000 -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 -netboot=dhcp ${loadaddr} ${filename};tftp 0xf00000 mcr3000.dtb;setenv bootargs root=/dev/nfs rw ${console_args} ${dhcp_ip};bootm ${loadaddr} - 0xf00000 -nfsboot=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${nfsroot} ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;bootm 0x04060000 - 0x04050000 -dhcpboot=dhcp ${loadaddr} ${filename};tftp 0xf00000 mcr3000.dtb;setenv bootargs ${console_args} ${dhcp_ip} ${ofl_args}; bootm ${loadaddr} - 0xf00000 +loadkernel=ubi part nand0;ubifsmount ubi0;ubifsload ${loadaddr} /boot/${filename};ubifsumount; ubi detach +bootcmd=run flashboot +flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;${ofl_args}; run loadkernel; bootm ${loadaddr} +tftpboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename}; bootm ${loadaddr} +dhcpboot=dhcp ${loadaddr} ${filename};setenv bootargs ${console_args} ${dhcp_ip} ${ofl_args}; bootm ${loadaddr} +update=echo 'Updating ubi image'; if tftp 0x2000 $ubifile; then nand erase.chip; nand write 0x2000 0x00 $filesize; fi diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig index 3e16ffc2ef2..f96e9f06e1e 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 @@ -36,11 +37,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 @@ -51,6 +53,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 @@ -58,7 +62,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_USE_IPADDR=y CONFIG_IPADDR="192.168.0.3" CONFIG_USE_NETMASK=y -CONFIG_NETMASK="255.0.0.0" +CONFIG_NETMASK="255.255.255.0" CONFIG_USE_SERVERIP=y CONFIG_SERVERIP="192.168.0.1" CONFIG_SYS_BR0_PRELIM_BOOL=y @@ -87,6 +91,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_FLASH_SHOW_PROGRESS=0 @@ -97,5 +102,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 8d78fd362a9..6b16b050ff3 100644 --- a/include/configs/mcr3000.h +++ b/include/configs/mcr3000.h @@ -23,10 +23,10 @@ /* * 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 CFG_SYS_BOOTMAPSZ (8 << 20) +#define CFG_SYS_BOOTMAPSZ (32 << 20) /* Environment Configuration */ From 19a68636b40d12dd73b92adc13bc3d8fdd53c03c Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 15 Sep 2022 08:54:59 +0200 Subject: [PATCH 5/9] board: MCR3000: Remove update of non-existing e1-wan DT node 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 Reviewed-by: FRANJOU Stephane --- 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 e95e04a30a6..7b3ab12bd5c 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; } From 02239394988d363b65234be9f7ca75f864e523b3 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Oct 2022 10:01:41 +0200 Subject: [PATCH 6/9] driver, gpio: Add support for MPC 8xx CPU ports 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 Reviewed-by: FRANJOU Stephane --- 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 | 347 ++++++++++++++++++++ 5 files changed, 368 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 e0801c25941..bee59c3bea4 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 365615a53f7..7d5ddbdee0c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -547,6 +547,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..2f653465331 --- /dev/null +++ b/drivers/gpio/mpc8xx_gpio.c @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 CS Group + * Charles Frey + * + * 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 +#include +#include +#include +#include +#include + +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; +} + +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; +} + +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, + .of_to_plat = mpc8xx_gpio_ofdata_to_platdata, + .plat_auto = sizeof(struct mpc8xx_gpio_plat), + .of_match = mpc8xx_gpio_ids, + .probe = mpc8xx_gpio_probe, + .priv_auto = sizeof(struct mpc8xx_gpio_data), +}; From 773ad4ebb1d68471fda34352fce2970352be05a0 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Oct 2022 09:14:44 +0200 Subject: [PATCH 7/9] spi, mpc8xx: Add support for chipselect via GPIO and fixups 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 Reviewed-by: FRANJOU Stephane --- 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 #include +#include #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), }; From dac3c6f625e03be0b5017b0d436c73aeeb1a673e Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Oct 2022 12:54:50 +0200 Subject: [PATCH 8/9] board: cssi: Add new board MCR3000_2G 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 Reviewed-by: FRANJOU Stephane --- arch/powerpc/cpu/mpc8xx/Kconfig | 4 + arch/powerpc/dts/Makefile | 1 + arch/powerpc/dts/cmpc885.dts | 94 ++++ board/cssi/MAINTAINERS | 2 + board/cssi/cmpc885/Kconfig | 23 + board/cssi/cmpc885/Makefile | 10 + board/cssi/cmpc885/cmpc885.c | 830 ++++++++++++++++++++++++++++++++ board/cssi/cmpc885/cmpc885.env | 7 + board/cssi/cmpc885/nand.c | 47 ++ board/cssi/cmpc885/sdram.c | 107 ++++ board/cssi/cmpc885/u-boot.lds | 95 ++++ configs/CMPC885_defconfig | 110 +++++ include/configs/cmpc885.h | 29 ++ 13 files changed, 1359 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/cmpc885.env 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 65293ae728c..628d3617bc8 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/MAINTAINERS b/board/cssi/MAINTAINERS index e1c0baa7082..d8e7b5e9b63 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/board/cssi/cmpc885/Kconfig b/board/cssi/cmpc885/Kconfig new file mode 100644 index 00000000000..4a23f89aa1d --- /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 +# Christophe Leroy +# + +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..cde9a558efc --- /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 + * Florent Trinh Thai + * Christophe Leroy + * + * Board specific routines for the CMPC885 board + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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, CFG_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/cmpc885.env b/board/cssi/cmpc885/cmpc885.env new file mode 100644 index 00000000000..51ab5ce2cfc --- /dev/null +++ b/board/cssi/cmpc885/cmpc885.env @@ -0,0 +1,7 @@ +loadaddr=0x1a00000 +filename=cmpc885.itb +console_args=console=ttyCPM0,115200N8 +loadkernel=ubi part nand0;ubifsmount ubi0;ubifsload ${loadaddr} /boot/${filename};ubifsumount; ubi detach +flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm $loadaddr#$config +tftpboot=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'; if tftp $loadaddr $ubifile; then nand erase.chip; nand write $loadaddr 0x00 $filesize; fi; 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 + * Christophe Leroy + * Charles Frey + */ + +#include +#include +#include +#include +#include +#include + +#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..7349b85ed2a --- /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 + */ + +#include +#include +#include +#include +#include +#include +#include + +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, CFG_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 *)CFG_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 + * + * (C) Copyright 2001-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Modified by Yuli Barcohen + */ + +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/configs/CMPC885_defconfig b/configs/CMPC885_defconfig new file mode 100644 index 00000000000..7dff6ff270d --- /dev/null +++ b/configs/CMPC885_defconfig @@ -0,0 +1,110 @@ +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_USE_IPADDR=y +CONFIG_IPADDR="192.168.0.3" +CONFIG_USE_NETMASK=y +CONFIG_NETMASK="255.255.255.0" +CONFIG_USE_SERVERIP=y +CONFIG_SERVERIP="192.168.0.1" +# 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..4ce580cd142 --- /dev/null +++ b/include/configs/cmpc885.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022 CS Group + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* Definitions for initial stack pointer and data area (in DPRAM) */ +#define CFG_SYS_INIT_RAM_ADDR (CONFIG_SYS_IMMR + 0x2800) +#define CFG_SYS_INIT_RAM_SIZE (0x2e00 - 0x2800) + +/* RAM configuration (note that CFG_SYS_SDRAM_BASE must be zero) */ +#define CFG_SYS_SDRAM_BASE 0x00000000 + +/* FLASH Configuration */ +#define CFG_SYS_FLASH_BASE 0x40000000 + +/* + * 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 CFG_SYS_BOOTMAPSZ (32 << 20) + +/* NAND configuration part */ +#define CFG_SYS_NAND_BASE 0xC0000000 + +#endif /* __CONFIG_H */ From 6a8c36b936ab69a7521ec1ecfd20f7b85f7f59c5 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 30 Jan 2023 09:07:38 +0100 Subject: [PATCH 9/9] board: cssi: Add MIAE & VGoIP devices 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 Reviewed-by: FRANJOU Stephane --- 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 cde9a558efc..5233c24aae3 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; }