Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 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; } |