summaryrefslogtreecommitdiff
path: root/board/microchip/mpfs_generic
diff options
context:
space:
mode:
Diffstat (limited to 'board/microchip/mpfs_generic')
-rw-r--r--board/microchip/mpfs_generic/Kconfig67
-rw-r--r--board/microchip/mpfs_generic/MAINTAINERS7
-rw-r--r--board/microchip/mpfs_generic/Makefile7
-rw-r--r--board/microchip/mpfs_generic/mpfs_generic.c206
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;
+}