diff options
Diffstat (limited to 'board/microchip/mpfs_generic')
-rw-r--r-- | board/microchip/mpfs_generic/Kconfig | 67 | ||||
-rw-r--r-- | board/microchip/mpfs_generic/MAINTAINERS | 7 | ||||
-rw-r--r-- | board/microchip/mpfs_generic/Makefile | 7 | ||||
-rw-r--r-- | board/microchip/mpfs_generic/mpfs_generic.c | 206 |
4 files changed, 287 insertions, 0 deletions
diff --git a/board/microchip/mpfs_generic/Kconfig b/board/microchip/mpfs_generic/Kconfig new file mode 100644 index 00000000000..8dcf55a0311 --- /dev/null +++ b/board/microchip/mpfs_generic/Kconfig @@ -0,0 +1,67 @@ +if TARGET_MICROCHIP_GENERIC + +config SYS_BOARD + default "mpfs_generic" + +config SYS_VENDOR + default "microchip" + +config SYS_CPU + default "generic" + +config SYS_CONFIG_NAME + default "microchip_mpfs_generic" + +config TEXT_BASE + default 0x80000000 if !RISCV_SMODE + default 0x80200000 if RISCV_SMODE + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select GENERIC_RISCV + select BOARD_EARLY_INIT_F + select BOARD_LATE_INIT + imply SMP + imply CLK_CCF + imply CLK_MPFS + imply REGMAP + imply SYSCON + imply SYS_NS16550 + imply CMD_DHCP + imply CMD_EXT2 + imply CMD_EXT4 + imply CMD_FAT + imply CMD_FS_GENERIC + imply CMD_NET + imply CMD_PING + imply CMD_MMC + imply DOS_PARTITION + imply EFI_PARTITION + imply IP_DYN + imply ISO_PARTITION + imply MACB + imply MII + imply PHY_LIB + imply PHY_VITESSE + imply MMC + imply MMC_WRITE + imply MMC_SDHCI + imply MMC_SDHCI_CADENCE + imply MMC_SDHCI_ADMA + imply MMC_HS200_SUPPORT + imply CMD_I2C + imply DM_I2C + imply SYS_I2C_MICROCHIP + imply MTD + imply SPI + imply DM_SPI + imply MICROCHIP_COREQSPI + imply MTD_SPI_NAND + imply CMD_MTD + imply CMD_MTDPARTS + imply DM_MAILBOX + imply MPFS_MBOX + imply MISC + imply MPFS_SYSCONTROLLER + +endif diff --git a/board/microchip/mpfs_generic/MAINTAINERS b/board/microchip/mpfs_generic/MAINTAINERS new file mode 100644 index 00000000000..3de99144c41 --- /dev/null +++ b/board/microchip/mpfs_generic/MAINTAINERS @@ -0,0 +1,7 @@ +Microchip MPFS Generic +M: Conor Dooley <conor.dooley@microchip.com> +M: Jamie Gibbons <jamie.gibbons@microchip.com> +S: Maintained +F: board/microchip/mpfs_generic/ +F: include/configs/microchip_mpfs_generic.h +F: configs/microchip_mpfs_generic_defconfig diff --git a/board/microchip/mpfs_generic/Makefile b/board/microchip/mpfs_generic/Makefile new file mode 100644 index 00000000000..dfe4b2634e6 --- /dev/null +++ b/board/microchip/mpfs_generic/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Microchip Technology Inc. +# Padmarao Begari <padmarao.begari@microchip.com> +# + +obj-y += mpfs_generic.o diff --git a/board/microchip/mpfs_generic/mpfs_generic.c b/board/microchip/mpfs_generic/mpfs_generic.c new file mode 100644 index 00000000000..f57f5f4046b --- /dev/null +++ b/board/microchip/mpfs_generic/mpfs_generic.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ + +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/sections.h> +#include <dm.h> +#include <dm/devres.h> +#include <env.h> +#include <linux/compat.h> +#include <mpfs-mailbox.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088) +#define PERIPH_RESET_VALUE 0x1e8u + +static unsigned char mac_addr[6]; + +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + const void *fdt; + int list_len; + + /* + * If there's not a HSS provided dtb, there's no point re-selecting + * since we'd just end up re-selecting the same dtb again. + */ + if (!gd->arch.firmware_fdt_addr) + return -EINVAL; + + fdt = (void *)gd->arch.firmware_fdt_addr; + + list_len = fdt_stringlist_count(fdt, 0, "compatible"); + if (list_len < 1) + return -EINVAL; + + for (int i = 0; i < list_len; i++) { + int len, match; + const char *compat; + char copy[64]; + char *devendored; + + compat = fdt_stringlist_get(fdt, 0, "compatible", i, &len); + if (!compat) + return -EINVAL; + + /* + * The naming scheme for compatibles doesn't produce anything + * close to this long. + */ + if (len >= 64) + return -EINVAL; + + strncpy(copy, compat, 64); + strtok(copy, ","); + + devendored = strtok(NULL, ","); + if (!devendored) + return -EINVAL; + + match = strcmp(devendored, name); + if (!match) + return 0; + } + + return -EINVAL; +} +#endif + +int board_fdt_blob_setup(void **fdtp) +{ + *fdtp = (void *)_end; + + /* + * The devicetree provided by the previous stage is very minimal due to + * severe space constraints. The firmware performs no fixups etc. + * U-Boot, if providing a devicetree, almost certainly has a better + * more complete one than the firmware so that provided by the firmware + * is ignored for OF_SEPARATE. + */ + if (IS_ENABLED(CONFIG_OF_BOARD) && !IS_ENABLED(CONFIG_MULTI_DTB_FIT)) { + if (gd->arch.firmware_fdt_addr) + *fdtp = (void *)(uintptr_t)gd->arch.firmware_fdt_addr; + } + + return 0; +} + +int board_init(void) +{ + /* For now nothing to do here. */ + + return 0; +} + +int board_early_init_f(void) +{ + unsigned int val; + + /* Reset uart, mmc peripheral */ + val = readl(MPFS_SYSREG_SOFT_RESET); + val = (val & ~(PERIPH_RESET_VALUE)); + writel(val, MPFS_SYSREG_SOFT_RESET); + + return 0; +} + +int board_late_init(void) +{ + u32 ret; + int node; + u8 device_serial_number[16] = {0}; + void *blob = (void *)gd->fdt_blob; + struct udevice *dev; + struct mpfs_sys_serv *sys_serv_priv; + + ret = uclass_get_device_by_name(UCLASS_MISC, "syscontroller", &dev); + if (ret) { + debug("%s: system controller setup failed\n", __func__); + return ret; + } + + sys_serv_priv = kzalloc(sizeof(*sys_serv_priv), GFP_KERNEL); + if (!sys_serv_priv) + return -ENOMEM; + + sys_serv_priv->dev = dev; + + sys_serv_priv->sys_controller = mpfs_syscontroller_get(dev); + ret = IS_ERR(sys_serv_priv->sys_controller); + if (ret) { + debug("%s: Failed to register system controller sub device ret=%d\n", __func__, ret); + return -ENODEV; + } + + ret = mpfs_syscontroller_read_sernum(sys_serv_priv, device_serial_number); + if (ret) { + printf("Cannot read device serial number\n"); + return -EINVAL; + } + + /* Update MAC address with device serial number */ + mac_addr[0] = 0x00; + mac_addr[1] = 0x04; + mac_addr[2] = 0xA3; + mac_addr[3] = device_serial_number[2]; + mac_addr[4] = device_serial_number[1]; + mac_addr[5] = device_serial_number[0]; + + node = fdt_path_offset(blob, "/soc/ethernet@20112000"); + if (node >= 0) { + ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("Error setting local-mac-address property for ethernet@20112000\n"); + return -ENODEV; + } + } + + mac_addr[5] = device_serial_number[0] + 1; + + node = fdt_path_offset(blob, "/soc/ethernet@20110000"); + if (node >= 0) { + ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("Error setting local-mac-address property for ethernet@20110000\n"); + return -ENODEV; + } + } + + mpfs_syscontroller_process_dtbo(sys_serv_priv); + + return 0; +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + u32 ret; + int node; + + node = fdt_path_offset(blob, "/soc/ethernet@20110000"); + if (node >= 0) { + ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("Error setting local-mac-address property for ethernet@20110000\n"); + return -ENODEV; + } + } + + mac_addr[5] -= 1; + + node = fdt_path_offset(blob, "/soc/ethernet@20112000"); + if (node >= 0) { + ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("Error setting local-mac-address property for ethernet@20112000\n"); + return -ENODEV; + } + } + + return 0; +} |