Commit 033c538e567aca5f0876f2504b5e278c2a0f83a8
Committed by
York Sun
1 parent
c055cee195
Exists in
smarc_8mq_lf_v2020.04
and in
20 other branches
drivers:net:fsl-mc: Update MC address calculation
Update MC address calculation as per MC design requirement of address as least significant 512MB address of MC private allocated memory, i.e. address should point to end address masked with 512MB offset in private DRAM block. Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com> Signed-off-by: Ashish Kumar <ashish.kumar@nxp.com> [YS: reformatted commit message] Reviewed-by: York Sun <york.sun@nxp.com>
Showing 1 changed file with 9 additions and 2 deletions Inline Diff
drivers/net/fsl-mc/mc.c
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2017 NXP Semiconductors | 2 | * Copyright (C) 2017 NXP Semiconductors |
| 3 | * Copyright (C) 2014 Freescale Semiconductor | 3 | * Copyright (C) 2014 Freescale Semiconductor |
| 4 | * | 4 | * |
| 5 | * SPDX-License-Identifier: GPL-2.0+ | 5 | * SPDX-License-Identifier: GPL-2.0+ |
| 6 | */ | 6 | */ |
| 7 | #include <common.h> | 7 | #include <common.h> |
| 8 | #include <errno.h> | 8 | #include <errno.h> |
| 9 | #include <linux/bug.h> | 9 | #include <linux/bug.h> |
| 10 | #include <asm/io.h> | 10 | #include <asm/io.h> |
| 11 | #include <libfdt.h> | 11 | #include <libfdt.h> |
| 12 | #include <net.h> | 12 | #include <net.h> |
| 13 | #include <fdt_support.h> | 13 | #include <fdt_support.h> |
| 14 | #include <fsl-mc/fsl_mc.h> | 14 | #include <fsl-mc/fsl_mc.h> |
| 15 | #include <fsl-mc/fsl_mc_sys.h> | 15 | #include <fsl-mc/fsl_mc_sys.h> |
| 16 | #include <fsl-mc/fsl_mc_private.h> | 16 | #include <fsl-mc/fsl_mc_private.h> |
| 17 | #include <fsl-mc/fsl_dpmng.h> | 17 | #include <fsl-mc/fsl_dpmng.h> |
| 18 | #include <fsl-mc/fsl_dprc.h> | 18 | #include <fsl-mc/fsl_dprc.h> |
| 19 | #include <fsl-mc/fsl_dpio.h> | 19 | #include <fsl-mc/fsl_dpio.h> |
| 20 | #include <fsl-mc/fsl_dpni.h> | 20 | #include <fsl-mc/fsl_dpni.h> |
| 21 | #include <fsl-mc/fsl_qbman_portal.h> | 21 | #include <fsl-mc/fsl_qbman_portal.h> |
| 22 | #include <fsl-mc/ldpaa_wriop.h> | 22 | #include <fsl-mc/ldpaa_wriop.h> |
| 23 | 23 | ||
| 24 | #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) | 24 | #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) |
| 25 | #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) | 25 | #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) |
| 26 | #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) | 26 | #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) |
| 27 | 27 | ||
| 28 | #define MC_MEM_SIZE_ENV_VAR "mcmemsize" | 28 | #define MC_MEM_SIZE_ENV_VAR "mcmemsize" |
| 29 | #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" | 29 | #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" |
| 30 | #define MC_BOOT_ENV_VAR "mcinitcmd" | 30 | #define MC_BOOT_ENV_VAR "mcinitcmd" |
| 31 | 31 | ||
| 32 | DECLARE_GLOBAL_DATA_PTR; | 32 | DECLARE_GLOBAL_DATA_PTR; |
| 33 | static int mc_boot_status = -1; | 33 | static int mc_boot_status = -1; |
| 34 | static int mc_dpl_applied = -1; | 34 | static int mc_dpl_applied = -1; |
| 35 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET | 35 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET |
| 36 | static int mc_aiop_applied = -1; | 36 | static int mc_aiop_applied = -1; |
| 37 | #endif | 37 | #endif |
| 38 | struct fsl_mc_io *root_mc_io = NULL; | 38 | struct fsl_mc_io *root_mc_io = NULL; |
| 39 | struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ | 39 | struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ |
| 40 | uint16_t root_dprc_handle = 0; | 40 | uint16_t root_dprc_handle = 0; |
| 41 | uint16_t dflt_dprc_handle = 0; | 41 | uint16_t dflt_dprc_handle = 0; |
| 42 | int child_dprc_id; | 42 | int child_dprc_id; |
| 43 | struct fsl_dpbp_obj *dflt_dpbp = NULL; | 43 | struct fsl_dpbp_obj *dflt_dpbp = NULL; |
| 44 | struct fsl_dpio_obj *dflt_dpio = NULL; | 44 | struct fsl_dpio_obj *dflt_dpio = NULL; |
| 45 | struct fsl_dpni_obj *dflt_dpni = NULL; | 45 | struct fsl_dpni_obj *dflt_dpni = NULL; |
| 46 | static u64 mc_lazy_dpl_addr; | 46 | static u64 mc_lazy_dpl_addr; |
| 47 | 47 | ||
| 48 | #ifdef DEBUG | 48 | #ifdef DEBUG |
| 49 | void dump_ram_words(const char *title, void *addr) | 49 | void dump_ram_words(const char *title, void *addr) |
| 50 | { | 50 | { |
| 51 | int i; | 51 | int i; |
| 52 | uint32_t *words = addr; | 52 | uint32_t *words = addr; |
| 53 | 53 | ||
| 54 | printf("Dumping beginning of %s (%p):\n", title, addr); | 54 | printf("Dumping beginning of %s (%p):\n", title, addr); |
| 55 | for (i = 0; i < 16; i++) | 55 | for (i = 0; i < 16; i++) |
| 56 | printf("%#x ", words[i]); | 56 | printf("%#x ", words[i]); |
| 57 | 57 | ||
| 58 | printf("\n"); | 58 | printf("\n"); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) | 61 | void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) |
| 62 | { | 62 | { |
| 63 | printf("MC CCSR registers:\n" | 63 | printf("MC CCSR registers:\n" |
| 64 | "reg_gcr1 %#x\n" | 64 | "reg_gcr1 %#x\n" |
| 65 | "reg_gsr %#x\n" | 65 | "reg_gsr %#x\n" |
| 66 | "reg_sicbalr %#x\n" | 66 | "reg_sicbalr %#x\n" |
| 67 | "reg_sicbahr %#x\n" | 67 | "reg_sicbahr %#x\n" |
| 68 | "reg_sicapr %#x\n" | 68 | "reg_sicapr %#x\n" |
| 69 | "reg_mcfbalr %#x\n" | 69 | "reg_mcfbalr %#x\n" |
| 70 | "reg_mcfbahr %#x\n" | 70 | "reg_mcfbahr %#x\n" |
| 71 | "reg_mcfapr %#x\n" | 71 | "reg_mcfapr %#x\n" |
| 72 | "reg_psr %#x\n", | 72 | "reg_psr %#x\n", |
| 73 | mc_ccsr_regs->reg_gcr1, | 73 | mc_ccsr_regs->reg_gcr1, |
| 74 | mc_ccsr_regs->reg_gsr, | 74 | mc_ccsr_regs->reg_gsr, |
| 75 | mc_ccsr_regs->reg_sicbalr, | 75 | mc_ccsr_regs->reg_sicbalr, |
| 76 | mc_ccsr_regs->reg_sicbahr, | 76 | mc_ccsr_regs->reg_sicbahr, |
| 77 | mc_ccsr_regs->reg_sicapr, | 77 | mc_ccsr_regs->reg_sicapr, |
| 78 | mc_ccsr_regs->reg_mcfbalr, | 78 | mc_ccsr_regs->reg_mcfbalr, |
| 79 | mc_ccsr_regs->reg_mcfbahr, | 79 | mc_ccsr_regs->reg_mcfbahr, |
| 80 | mc_ccsr_regs->reg_mcfapr, | 80 | mc_ccsr_regs->reg_mcfapr, |
| 81 | mc_ccsr_regs->reg_psr); | 81 | mc_ccsr_regs->reg_psr); |
| 82 | } | 82 | } |
| 83 | #else | 83 | #else |
| 84 | 84 | ||
| 85 | #define dump_ram_words(title, addr) | 85 | #define dump_ram_words(title, addr) |
| 86 | #define dump_mc_ccsr_regs(mc_ccsr_regs) | 86 | #define dump_mc_ccsr_regs(mc_ccsr_regs) |
| 87 | 87 | ||
| 88 | #endif /* DEBUG */ | 88 | #endif /* DEBUG */ |
| 89 | 89 | ||
| 90 | #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR | 90 | #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR |
| 91 | /** | 91 | /** |
| 92 | * Copying MC firmware or DPL image to DDR | 92 | * Copying MC firmware or DPL image to DDR |
| 93 | */ | 93 | */ |
| 94 | static int mc_copy_image(const char *title, | 94 | static int mc_copy_image(const char *title, |
| 95 | u64 image_addr, u32 image_size, u64 mc_ram_addr) | 95 | u64 image_addr, u32 image_size, u64 mc_ram_addr) |
| 96 | { | 96 | { |
| 97 | debug("%s copied to address %p\n", title, (void *)mc_ram_addr); | 97 | debug("%s copied to address %p\n", title, (void *)mc_ram_addr); |
| 98 | memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); | 98 | memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); |
| 99 | flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); | 99 | flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); |
| 100 | return 0; | 100 | return 0; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /** | 103 | /** |
| 104 | * MC firmware FIT image parser checks if the image is in FIT | 104 | * MC firmware FIT image parser checks if the image is in FIT |
| 105 | * format, verifies integrity of the image and calculates | 105 | * format, verifies integrity of the image and calculates |
| 106 | * raw image address and size values. | 106 | * raw image address and size values. |
| 107 | * Returns 0 on success and a negative errno on error. | 107 | * Returns 0 on success and a negative errno on error. |
| 108 | * task fail. | 108 | * task fail. |
| 109 | **/ | 109 | **/ |
| 110 | int parse_mc_firmware_fit_image(u64 mc_fw_addr, | 110 | int parse_mc_firmware_fit_image(u64 mc_fw_addr, |
| 111 | const void **raw_image_addr, | 111 | const void **raw_image_addr, |
| 112 | size_t *raw_image_size) | 112 | size_t *raw_image_size) |
| 113 | { | 113 | { |
| 114 | int format; | 114 | int format; |
| 115 | void *fit_hdr; | 115 | void *fit_hdr; |
| 116 | int node_offset; | 116 | int node_offset; |
| 117 | const void *data; | 117 | const void *data; |
| 118 | size_t size; | 118 | size_t size; |
| 119 | const char *uname = "firmware"; | 119 | const char *uname = "firmware"; |
| 120 | 120 | ||
| 121 | fit_hdr = (void *)mc_fw_addr; | 121 | fit_hdr = (void *)mc_fw_addr; |
| 122 | 122 | ||
| 123 | /* Check if Image is in FIT format */ | 123 | /* Check if Image is in FIT format */ |
| 124 | format = genimg_get_format(fit_hdr); | 124 | format = genimg_get_format(fit_hdr); |
| 125 | 125 | ||
| 126 | if (format != IMAGE_FORMAT_FIT) { | 126 | if (format != IMAGE_FORMAT_FIT) { |
| 127 | printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); | 127 | printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); |
| 128 | return -EINVAL; | 128 | return -EINVAL; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | if (!fit_check_format(fit_hdr)) { | 131 | if (!fit_check_format(fit_hdr)) { |
| 132 | printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); | 132 | printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); |
| 133 | return -EINVAL; | 133 | return -EINVAL; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | node_offset = fit_image_get_node(fit_hdr, uname); | 136 | node_offset = fit_image_get_node(fit_hdr, uname); |
| 137 | 137 | ||
| 138 | if (node_offset < 0) { | 138 | if (node_offset < 0) { |
| 139 | printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); | 139 | printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); |
| 140 | return -ENOENT; | 140 | return -ENOENT; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | /* Verify MC firmware image */ | 143 | /* Verify MC firmware image */ |
| 144 | if (!(fit_image_verify(fit_hdr, node_offset))) { | 144 | if (!(fit_image_verify(fit_hdr, node_offset))) { |
| 145 | printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); | 145 | printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); |
| 146 | return -EINVAL; | 146 | return -EINVAL; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | /* Get address and size of raw image */ | 149 | /* Get address and size of raw image */ |
| 150 | fit_image_get_data(fit_hdr, node_offset, &data, &size); | 150 | fit_image_get_data(fit_hdr, node_offset, &data, &size); |
| 151 | 151 | ||
| 152 | *raw_image_addr = data; | 152 | *raw_image_addr = data; |
| 153 | *raw_image_size = size; | 153 | *raw_image_size = size; |
| 154 | 154 | ||
| 155 | return 0; | 155 | return 0; |
| 156 | } | 156 | } |
| 157 | #endif | 157 | #endif |
| 158 | 158 | ||
| 159 | #define MC_DT_INCREASE_SIZE 64 | 159 | #define MC_DT_INCREASE_SIZE 64 |
| 160 | 160 | ||
| 161 | enum mc_fixup_type { | 161 | enum mc_fixup_type { |
| 162 | MC_FIXUP_DPL, | 162 | MC_FIXUP_DPL, |
| 163 | MC_FIXUP_DPC | 163 | MC_FIXUP_DPC |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | static int mc_fixup_mac_addr(void *blob, int nodeoffset, | 166 | static int mc_fixup_mac_addr(void *blob, int nodeoffset, |
| 167 | const char *propname, struct eth_device *eth_dev, | 167 | const char *propname, struct eth_device *eth_dev, |
| 168 | enum mc_fixup_type type) | 168 | enum mc_fixup_type type) |
| 169 | { | 169 | { |
| 170 | int err = 0, len = 0, size, i; | 170 | int err = 0, len = 0, size, i; |
| 171 | unsigned char env_enetaddr[ARP_HLEN]; | 171 | unsigned char env_enetaddr[ARP_HLEN]; |
| 172 | unsigned int enetaddr_32[ARP_HLEN]; | 172 | unsigned int enetaddr_32[ARP_HLEN]; |
| 173 | void *val = NULL; | 173 | void *val = NULL; |
| 174 | 174 | ||
| 175 | switch (type) { | 175 | switch (type) { |
| 176 | case MC_FIXUP_DPL: | 176 | case MC_FIXUP_DPL: |
| 177 | /* DPL likes its addresses on 32 * ARP_HLEN bits */ | 177 | /* DPL likes its addresses on 32 * ARP_HLEN bits */ |
| 178 | for (i = 0; i < ARP_HLEN; i++) | 178 | for (i = 0; i < ARP_HLEN; i++) |
| 179 | enetaddr_32[i] = cpu_to_fdt32(eth_dev->enetaddr[i]); | 179 | enetaddr_32[i] = cpu_to_fdt32(eth_dev->enetaddr[i]); |
| 180 | val = enetaddr_32; | 180 | val = enetaddr_32; |
| 181 | len = sizeof(enetaddr_32); | 181 | len = sizeof(enetaddr_32); |
| 182 | break; | 182 | break; |
| 183 | 183 | ||
| 184 | case MC_FIXUP_DPC: | 184 | case MC_FIXUP_DPC: |
| 185 | val = eth_dev->enetaddr; | 185 | val = eth_dev->enetaddr; |
| 186 | len = ARP_HLEN; | 186 | len = ARP_HLEN; |
| 187 | break; | 187 | break; |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | /* MAC address property present */ | 190 | /* MAC address property present */ |
| 191 | if (fdt_get_property(blob, nodeoffset, propname, NULL)) { | 191 | if (fdt_get_property(blob, nodeoffset, propname, NULL)) { |
| 192 | /* u-boot MAC addr randomly assigned - leave the present one */ | 192 | /* u-boot MAC addr randomly assigned - leave the present one */ |
| 193 | if (!eth_env_get_enetaddr_by_index("eth", eth_dev->index, | 193 | if (!eth_env_get_enetaddr_by_index("eth", eth_dev->index, |
| 194 | env_enetaddr)) | 194 | env_enetaddr)) |
| 195 | return err; | 195 | return err; |
| 196 | } else { | 196 | } else { |
| 197 | size = MC_DT_INCREASE_SIZE + strlen(propname) + len; | 197 | size = MC_DT_INCREASE_SIZE + strlen(propname) + len; |
| 198 | /* make room for mac address property */ | 198 | /* make room for mac address property */ |
| 199 | err = fdt_increase_size(blob, size); | 199 | err = fdt_increase_size(blob, size); |
| 200 | if (err) { | 200 | if (err) { |
| 201 | printf("fdt_increase_size: err=%s\n", | 201 | printf("fdt_increase_size: err=%s\n", |
| 202 | fdt_strerror(err)); | 202 | fdt_strerror(err)); |
| 203 | return err; | 203 | return err; |
| 204 | } | 204 | } |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | err = fdt_setprop(blob, nodeoffset, propname, val, len); | 207 | err = fdt_setprop(blob, nodeoffset, propname, val, len); |
| 208 | if (err) { | 208 | if (err) { |
| 209 | printf("fdt_setprop: err=%s\n", fdt_strerror(err)); | 209 | printf("fdt_setprop: err=%s\n", fdt_strerror(err)); |
| 210 | return err; | 210 | return err; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | return err; | 213 | return err; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | #define is_dpni(s) (s != NULL ? !strncmp(s, "dpni@", 5) : 0) | 216 | #define is_dpni(s) (s != NULL ? !strncmp(s, "dpni@", 5) : 0) |
| 217 | 217 | ||
| 218 | const char *dpl_get_connection_endpoint(void *blob, char *endpoint) | 218 | const char *dpl_get_connection_endpoint(void *blob, char *endpoint) |
| 219 | { | 219 | { |
| 220 | int connoffset = fdt_path_offset(blob, "/connections"), off; | 220 | int connoffset = fdt_path_offset(blob, "/connections"), off; |
| 221 | const char *s1, *s2; | 221 | const char *s1, *s2; |
| 222 | 222 | ||
| 223 | for (off = fdt_first_subnode(blob, connoffset); | 223 | for (off = fdt_first_subnode(blob, connoffset); |
| 224 | off >= 0; | 224 | off >= 0; |
| 225 | off = fdt_next_subnode(blob, off)) { | 225 | off = fdt_next_subnode(blob, off)) { |
| 226 | s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL); | 226 | s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL); |
| 227 | s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL); | 227 | s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL); |
| 228 | 228 | ||
| 229 | if (!s1 || !s2) | 229 | if (!s1 || !s2) |
| 230 | continue; | 230 | continue; |
| 231 | 231 | ||
| 232 | if (strcmp(endpoint, s1) == 0) | 232 | if (strcmp(endpoint, s1) == 0) |
| 233 | return s2; | 233 | return s2; |
| 234 | 234 | ||
| 235 | if (strcmp(endpoint, s2) == 0) | 235 | if (strcmp(endpoint, s2) == 0) |
| 236 | return s1; | 236 | return s1; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | return NULL; | 239 | return NULL; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id, | 242 | static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id, |
| 243 | struct eth_device *eth_dev) | 243 | struct eth_device *eth_dev) |
| 244 | { | 244 | { |
| 245 | int objoff = fdt_path_offset(blob, "/objects"); | 245 | int objoff = fdt_path_offset(blob, "/objects"); |
| 246 | int dpmacoff = -1, dpnioff = -1; | 246 | int dpmacoff = -1, dpnioff = -1; |
| 247 | const char *endpoint; | 247 | const char *endpoint; |
| 248 | char mac_name[10]; | 248 | char mac_name[10]; |
| 249 | int err; | 249 | int err; |
| 250 | 250 | ||
| 251 | sprintf(mac_name, "dpmac@%d", dpmac_id); | 251 | sprintf(mac_name, "dpmac@%d", dpmac_id); |
| 252 | dpmacoff = fdt_subnode_offset(blob, objoff, mac_name); | 252 | dpmacoff = fdt_subnode_offset(blob, objoff, mac_name); |
| 253 | if (dpmacoff < 0) | 253 | if (dpmacoff < 0) |
| 254 | /* dpmac not defined in DPL, so skip it. */ | 254 | /* dpmac not defined in DPL, so skip it. */ |
| 255 | return 0; | 255 | return 0; |
| 256 | 256 | ||
| 257 | err = mc_fixup_mac_addr(blob, dpmacoff, "mac_addr", eth_dev, | 257 | err = mc_fixup_mac_addr(blob, dpmacoff, "mac_addr", eth_dev, |
| 258 | MC_FIXUP_DPL); | 258 | MC_FIXUP_DPL); |
| 259 | if (err) { | 259 | if (err) { |
| 260 | printf("Error fixing up dpmac mac_addr in DPL\n"); | 260 | printf("Error fixing up dpmac mac_addr in DPL\n"); |
| 261 | return err; | 261 | return err; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | /* now we need to figure out if there is any | 264 | /* now we need to figure out if there is any |
| 265 | * DPNI connected to this MAC, so we walk the | 265 | * DPNI connected to this MAC, so we walk the |
| 266 | * connection list | 266 | * connection list |
| 267 | */ | 267 | */ |
| 268 | endpoint = dpl_get_connection_endpoint(blob, mac_name); | 268 | endpoint = dpl_get_connection_endpoint(blob, mac_name); |
| 269 | if (!is_dpni(endpoint)) | 269 | if (!is_dpni(endpoint)) |
| 270 | return 0; | 270 | return 0; |
| 271 | 271 | ||
| 272 | /* let's see if we can fixup the DPNI as well */ | 272 | /* let's see if we can fixup the DPNI as well */ |
| 273 | dpnioff = fdt_subnode_offset(blob, objoff, endpoint); | 273 | dpnioff = fdt_subnode_offset(blob, objoff, endpoint); |
| 274 | if (dpnioff < 0) | 274 | if (dpnioff < 0) |
| 275 | /* DPNI not defined in DPL in the objects area */ | 275 | /* DPNI not defined in DPL in the objects area */ |
| 276 | return 0; | 276 | return 0; |
| 277 | 277 | ||
| 278 | return mc_fixup_mac_addr(blob, dpnioff, "mac_addr", eth_dev, | 278 | return mc_fixup_mac_addr(blob, dpnioff, "mac_addr", eth_dev, |
| 279 | MC_FIXUP_DPL); | 279 | MC_FIXUP_DPL); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id, | 282 | static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id, |
| 283 | struct eth_device *eth_dev) | 283 | struct eth_device *eth_dev) |
| 284 | { | 284 | { |
| 285 | int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff; | 285 | int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff; |
| 286 | int err = 0; | 286 | int err = 0; |
| 287 | char mac_name[10]; | 287 | char mac_name[10]; |
| 288 | const char link_type_mode[] = "MAC_LINK_TYPE_FIXED"; | 288 | const char link_type_mode[] = "MAC_LINK_TYPE_FIXED"; |
| 289 | 289 | ||
| 290 | sprintf(mac_name, "mac@%d", dpmac_id); | 290 | sprintf(mac_name, "mac@%d", dpmac_id); |
| 291 | 291 | ||
| 292 | /* node not found - create it */ | 292 | /* node not found - create it */ |
| 293 | noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name); | 293 | noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name); |
| 294 | if (noff < 0) { | 294 | if (noff < 0) { |
| 295 | err = fdt_increase_size(blob, 200); | 295 | err = fdt_increase_size(blob, 200); |
| 296 | if (err) { | 296 | if (err) { |
| 297 | printf("fdt_increase_size: err=%s\n", | 297 | printf("fdt_increase_size: err=%s\n", |
| 298 | fdt_strerror(err)); | 298 | fdt_strerror(err)); |
| 299 | return err; | 299 | return err; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | noff = fdt_add_subnode(blob, nodeoffset, mac_name); | 302 | noff = fdt_add_subnode(blob, nodeoffset, mac_name); |
| 303 | if (noff < 0) { | 303 | if (noff < 0) { |
| 304 | printf("fdt_add_subnode: err=%s\n", | 304 | printf("fdt_add_subnode: err=%s\n", |
| 305 | fdt_strerror(err)); | 305 | fdt_strerror(err)); |
| 306 | return err; | 306 | return err; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | /* add default property of fixed link */ | 309 | /* add default property of fixed link */ |
| 310 | err = fdt_appendprop_string(blob, noff, | 310 | err = fdt_appendprop_string(blob, noff, |
| 311 | "link_type", link_type_mode); | 311 | "link_type", link_type_mode); |
| 312 | if (err) { | 312 | if (err) { |
| 313 | printf("fdt_appendprop_string: err=%s\n", | 313 | printf("fdt_appendprop_string: err=%s\n", |
| 314 | fdt_strerror(err)); | 314 | fdt_strerror(err)); |
| 315 | return err; | 315 | return err; |
| 316 | } | 316 | } |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev, | 319 | return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev, |
| 320 | MC_FIXUP_DPC); | 320 | MC_FIXUP_DPC); |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type) | 323 | static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type) |
| 324 | { | 324 | { |
| 325 | int i, err = 0, ret = 0; | 325 | int i, err = 0, ret = 0; |
| 326 | char ethname[10]; | 326 | char ethname[10]; |
| 327 | struct eth_device *eth_dev; | 327 | struct eth_device *eth_dev; |
| 328 | 328 | ||
| 329 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { | 329 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { |
| 330 | /* port not enabled */ | 330 | /* port not enabled */ |
| 331 | if ((wriop_is_enabled_dpmac(i) != 1) || | 331 | if ((wriop_is_enabled_dpmac(i) != 1) || |
| 332 | (wriop_get_phy_address(i) == -1)) | 332 | (wriop_get_phy_address(i) == -1)) |
| 333 | continue; | 333 | continue; |
| 334 | 334 | ||
| 335 | sprintf(ethname, "DPMAC%d@%s", i, | 335 | sprintf(ethname, "DPMAC%d@%s", i, |
| 336 | phy_interface_strings[wriop_get_enet_if(i)]); | 336 | phy_interface_strings[wriop_get_enet_if(i)]); |
| 337 | 337 | ||
| 338 | eth_dev = eth_get_dev_by_name(ethname); | 338 | eth_dev = eth_get_dev_by_name(ethname); |
| 339 | if (eth_dev == NULL) | 339 | if (eth_dev == NULL) |
| 340 | continue; | 340 | continue; |
| 341 | 341 | ||
| 342 | switch (type) { | 342 | switch (type) { |
| 343 | case MC_FIXUP_DPL: | 343 | case MC_FIXUP_DPL: |
| 344 | err = mc_fixup_dpl_mac_addr(blob, i, eth_dev); | 344 | err = mc_fixup_dpl_mac_addr(blob, i, eth_dev); |
| 345 | break; | 345 | break; |
| 346 | case MC_FIXUP_DPC: | 346 | case MC_FIXUP_DPC: |
| 347 | err = mc_fixup_dpc_mac_addr(blob, i, eth_dev); | 347 | err = mc_fixup_dpc_mac_addr(blob, i, eth_dev); |
| 348 | break; | 348 | break; |
| 349 | default: | 349 | default: |
| 350 | break; | 350 | break; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | if (err) | 353 | if (err) |
| 354 | printf("fsl-mc: ERROR fixing mac address for %s\n", | 354 | printf("fsl-mc: ERROR fixing mac address for %s\n", |
| 355 | ethname); | 355 | ethname); |
| 356 | ret |= err; | 356 | ret |= err; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | return ret; | 359 | return ret; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | static int mc_fixup_dpc(u64 dpc_addr) | 362 | static int mc_fixup_dpc(u64 dpc_addr) |
| 363 | { | 363 | { |
| 364 | void *blob = (void *)dpc_addr; | 364 | void *blob = (void *)dpc_addr; |
| 365 | int nodeoffset, err = 0; | 365 | int nodeoffset, err = 0; |
| 366 | 366 | ||
| 367 | /* delete any existing ICID pools */ | 367 | /* delete any existing ICID pools */ |
| 368 | nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); | 368 | nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); |
| 369 | if (fdt_del_node(blob, nodeoffset) < 0) | 369 | if (fdt_del_node(blob, nodeoffset) < 0) |
| 370 | printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); | 370 | printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); |
| 371 | 371 | ||
| 372 | /* add a new pool */ | 372 | /* add a new pool */ |
| 373 | nodeoffset = fdt_path_offset(blob, "/resources"); | 373 | nodeoffset = fdt_path_offset(blob, "/resources"); |
| 374 | if (nodeoffset < 0) { | 374 | if (nodeoffset < 0) { |
| 375 | printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); | 375 | printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); |
| 376 | return -EINVAL; | 376 | return -EINVAL; |
| 377 | } | 377 | } |
| 378 | nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); | 378 | nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); |
| 379 | nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); | 379 | nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); |
| 380 | do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", | 380 | do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", |
| 381 | "base_icid", FSL_DPAA2_STREAM_ID_START, 1); | 381 | "base_icid", FSL_DPAA2_STREAM_ID_START, 1); |
| 382 | do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", | 382 | do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", |
| 383 | "num", | 383 | "num", |
| 384 | FSL_DPAA2_STREAM_ID_END - | 384 | FSL_DPAA2_STREAM_ID_END - |
| 385 | FSL_DPAA2_STREAM_ID_START + 1, 1); | 385 | FSL_DPAA2_STREAM_ID_START + 1, 1); |
| 386 | 386 | ||
| 387 | /* fixup MAC addresses for dpmac ports */ | 387 | /* fixup MAC addresses for dpmac ports */ |
| 388 | nodeoffset = fdt_path_offset(blob, "/board_info/ports"); | 388 | nodeoffset = fdt_path_offset(blob, "/board_info/ports"); |
| 389 | if (nodeoffset < 0) | 389 | if (nodeoffset < 0) |
| 390 | return 0; | 390 | return 0; |
| 391 | 391 | ||
| 392 | err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPC); | 392 | err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPC); |
| 393 | flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); | 393 | flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); |
| 394 | 394 | ||
| 395 | return err; | 395 | return err; |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) | 398 | static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) |
| 399 | { | 399 | { |
| 400 | u64 mc_dpc_offset; | 400 | u64 mc_dpc_offset; |
| 401 | #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR | 401 | #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR |
| 402 | int error; | 402 | int error; |
| 403 | void *dpc_fdt_hdr; | 403 | void *dpc_fdt_hdr; |
| 404 | int dpc_size; | 404 | int dpc_size; |
| 405 | #endif | 405 | #endif |
| 406 | 406 | ||
| 407 | #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET | 407 | #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET |
| 408 | BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || | 408 | BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || |
| 409 | CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); | 409 | CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); |
| 410 | 410 | ||
| 411 | mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; | 411 | mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; |
| 412 | #else | 412 | #else |
| 413 | #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" | 413 | #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" |
| 414 | #endif | 414 | #endif |
| 415 | 415 | ||
| 416 | /* | 416 | /* |
| 417 | * Load the MC DPC blob in the MC private DRAM block: | 417 | * Load the MC DPC blob in the MC private DRAM block: |
| 418 | */ | 418 | */ |
| 419 | #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR | 419 | #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR |
| 420 | printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); | 420 | printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); |
| 421 | #else | 421 | #else |
| 422 | /* | 422 | /* |
| 423 | * Get address and size of the DPC blob stored in flash: | 423 | * Get address and size of the DPC blob stored in flash: |
| 424 | */ | 424 | */ |
| 425 | dpc_fdt_hdr = (void *)mc_dpc_addr; | 425 | dpc_fdt_hdr = (void *)mc_dpc_addr; |
| 426 | 426 | ||
| 427 | error = fdt_check_header(dpc_fdt_hdr); | 427 | error = fdt_check_header(dpc_fdt_hdr); |
| 428 | if (error != 0) { | 428 | if (error != 0) { |
| 429 | /* | 429 | /* |
| 430 | * Don't return with error here, since the MC firmware can | 430 | * Don't return with error here, since the MC firmware can |
| 431 | * still boot without a DPC | 431 | * still boot without a DPC |
| 432 | */ | 432 | */ |
| 433 | printf("\nfsl-mc: WARNING: No DPC image found"); | 433 | printf("\nfsl-mc: WARNING: No DPC image found"); |
| 434 | return 0; | 434 | return 0; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | dpc_size = fdt_totalsize(dpc_fdt_hdr); | 437 | dpc_size = fdt_totalsize(dpc_fdt_hdr); |
| 438 | if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { | 438 | if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { |
| 439 | printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", | 439 | printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", |
| 440 | dpc_size); | 440 | dpc_size); |
| 441 | return -EINVAL; | 441 | return -EINVAL; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | mc_copy_image("MC DPC blob", | 444 | mc_copy_image("MC DPC blob", |
| 445 | (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); | 445 | (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); |
| 446 | #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ | 446 | #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ |
| 447 | 447 | ||
| 448 | if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) | 448 | if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) |
| 449 | return -EINVAL; | 449 | return -EINVAL; |
| 450 | 450 | ||
| 451 | dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); | 451 | dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); |
| 452 | return 0; | 452 | return 0; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | 455 | ||
| 456 | static int mc_fixup_dpl(u64 dpl_addr) | 456 | static int mc_fixup_dpl(u64 dpl_addr) |
| 457 | { | 457 | { |
| 458 | void *blob = (void *)dpl_addr; | 458 | void *blob = (void *)dpl_addr; |
| 459 | u32 ver = fdt_getprop_u32_default(blob, "/", "dpl-version", 0); | 459 | u32 ver = fdt_getprop_u32_default(blob, "/", "dpl-version", 0); |
| 460 | int err = 0; | 460 | int err = 0; |
| 461 | 461 | ||
| 462 | /* The DPL fixup for mac addresses is only relevant | 462 | /* The DPL fixup for mac addresses is only relevant |
| 463 | * for old-style DPLs | 463 | * for old-style DPLs |
| 464 | */ | 464 | */ |
| 465 | if (ver >= 10) | 465 | if (ver >= 10) |
| 466 | return 0; | 466 | return 0; |
| 467 | 467 | ||
| 468 | err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPL); | 468 | err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPL); |
| 469 | flush_dcache_range(dpl_addr, dpl_addr + fdt_totalsize(blob)); | 469 | flush_dcache_range(dpl_addr, dpl_addr + fdt_totalsize(blob)); |
| 470 | 470 | ||
| 471 | return err; | 471 | return err; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) | 474 | static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) |
| 475 | { | 475 | { |
| 476 | u64 mc_dpl_offset; | 476 | u64 mc_dpl_offset; |
| 477 | #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR | 477 | #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR |
| 478 | int error; | 478 | int error; |
| 479 | void *dpl_fdt_hdr; | 479 | void *dpl_fdt_hdr; |
| 480 | int dpl_size; | 480 | int dpl_size; |
| 481 | #endif | 481 | #endif |
| 482 | 482 | ||
| 483 | #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET | 483 | #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET |
| 484 | BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || | 484 | BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || |
| 485 | CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); | 485 | CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); |
| 486 | 486 | ||
| 487 | mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; | 487 | mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; |
| 488 | #else | 488 | #else |
| 489 | #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" | 489 | #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" |
| 490 | #endif | 490 | #endif |
| 491 | 491 | ||
| 492 | /* | 492 | /* |
| 493 | * Load the MC DPL blob in the MC private DRAM block: | 493 | * Load the MC DPL blob in the MC private DRAM block: |
| 494 | */ | 494 | */ |
| 495 | #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR | 495 | #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR |
| 496 | printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); | 496 | printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); |
| 497 | #else | 497 | #else |
| 498 | /* | 498 | /* |
| 499 | * Get address and size of the DPL blob stored in flash: | 499 | * Get address and size of the DPL blob stored in flash: |
| 500 | */ | 500 | */ |
| 501 | dpl_fdt_hdr = (void *)mc_dpl_addr; | 501 | dpl_fdt_hdr = (void *)mc_dpl_addr; |
| 502 | 502 | ||
| 503 | error = fdt_check_header(dpl_fdt_hdr); | 503 | error = fdt_check_header(dpl_fdt_hdr); |
| 504 | if (error != 0) { | 504 | if (error != 0) { |
| 505 | printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); | 505 | printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); |
| 506 | return error; | 506 | return error; |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | dpl_size = fdt_totalsize(dpl_fdt_hdr); | 509 | dpl_size = fdt_totalsize(dpl_fdt_hdr); |
| 510 | if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { | 510 | if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { |
| 511 | printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", | 511 | printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", |
| 512 | dpl_size); | 512 | dpl_size); |
| 513 | return -EINVAL; | 513 | return -EINVAL; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | mc_copy_image("MC DPL blob", | 516 | mc_copy_image("MC DPL blob", |
| 517 | (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); | 517 | (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); |
| 518 | #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ | 518 | #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ |
| 519 | 519 | ||
| 520 | if (mc_fixup_dpl(mc_ram_addr + mc_dpl_offset)) | 520 | if (mc_fixup_dpl(mc_ram_addr + mc_dpl_offset)) |
| 521 | return -EINVAL; | 521 | return -EINVAL; |
| 522 | dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); | 522 | dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); |
| 523 | return 0; | 523 | return 0; |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | /** | 526 | /** |
| 527 | * Return the MC boot timeout value in milliseconds | 527 | * Return the MC boot timeout value in milliseconds |
| 528 | */ | 528 | */ |
| 529 | static unsigned long get_mc_boot_timeout_ms(void) | 529 | static unsigned long get_mc_boot_timeout_ms(void) |
| 530 | { | 530 | { |
| 531 | unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; | 531 | unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; |
| 532 | 532 | ||
| 533 | char *timeout_ms_env_var = env_get(MC_BOOT_TIMEOUT_ENV_VAR); | 533 | char *timeout_ms_env_var = env_get(MC_BOOT_TIMEOUT_ENV_VAR); |
| 534 | 534 | ||
| 535 | if (timeout_ms_env_var) { | 535 | if (timeout_ms_env_var) { |
| 536 | timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); | 536 | timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); |
| 537 | if (timeout_ms == 0) { | 537 | if (timeout_ms == 0) { |
| 538 | printf("fsl-mc: WARNING: Invalid value for \'" | 538 | printf("fsl-mc: WARNING: Invalid value for \'" |
| 539 | MC_BOOT_TIMEOUT_ENV_VAR | 539 | MC_BOOT_TIMEOUT_ENV_VAR |
| 540 | "\' environment variable: %lu\n", | 540 | "\' environment variable: %lu\n", |
| 541 | timeout_ms); | 541 | timeout_ms); |
| 542 | 542 | ||
| 543 | timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; | 543 | timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; |
| 544 | } | 544 | } |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | return timeout_ms; | 547 | return timeout_ms; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET | 550 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET |
| 551 | 551 | ||
| 552 | __weak bool soc_has_aiop(void) | 552 | __weak bool soc_has_aiop(void) |
| 553 | { | 553 | { |
| 554 | return false; | 554 | return false; |
| 555 | } | 555 | } |
| 556 | 556 | ||
| 557 | static int load_mc_aiop_img(u64 aiop_fw_addr) | 557 | static int load_mc_aiop_img(u64 aiop_fw_addr) |
| 558 | { | 558 | { |
| 559 | u64 mc_ram_addr = mc_get_dram_addr(); | 559 | u64 mc_ram_addr = mc_get_dram_addr(); |
| 560 | #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR | 560 | #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR |
| 561 | void *aiop_img; | 561 | void *aiop_img; |
| 562 | #endif | 562 | #endif |
| 563 | 563 | ||
| 564 | /* Check if AIOP is available */ | 564 | /* Check if AIOP is available */ |
| 565 | if (!soc_has_aiop()) | 565 | if (!soc_has_aiop()) |
| 566 | return -ENODEV; | 566 | return -ENODEV; |
| 567 | /* | 567 | /* |
| 568 | * Load the MC AIOP image in the MC private DRAM block: | 568 | * Load the MC AIOP image in the MC private DRAM block: |
| 569 | */ | 569 | */ |
| 570 | 570 | ||
| 571 | #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR | 571 | #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR |
| 572 | printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr + | 572 | printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr + |
| 573 | CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); | 573 | CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); |
| 574 | #else | 574 | #else |
| 575 | aiop_img = (void *)aiop_fw_addr; | 575 | aiop_img = (void *)aiop_fw_addr; |
| 576 | mc_copy_image("MC AIOP image", | 576 | mc_copy_image("MC AIOP image", |
| 577 | (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, | 577 | (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, |
| 578 | mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); | 578 | mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); |
| 579 | #endif | 579 | #endif |
| 580 | mc_aiop_applied = 0; | 580 | mc_aiop_applied = 0; |
| 581 | 581 | ||
| 582 | return 0; | 582 | return 0; |
| 583 | } | 583 | } |
| 584 | #endif | 584 | #endif |
| 585 | 585 | ||
| 586 | static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) | 586 | static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) |
| 587 | { | 587 | { |
| 588 | u32 reg_gsr; | 588 | u32 reg_gsr; |
| 589 | u32 mc_fw_boot_status; | 589 | u32 mc_fw_boot_status; |
| 590 | unsigned long timeout_ms = get_mc_boot_timeout_ms(); | 590 | unsigned long timeout_ms = get_mc_boot_timeout_ms(); |
| 591 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; | 591 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; |
| 592 | 592 | ||
| 593 | dmb(); | 593 | dmb(); |
| 594 | assert(timeout_ms > 0); | 594 | assert(timeout_ms > 0); |
| 595 | for (;;) { | 595 | for (;;) { |
| 596 | udelay(1000); /* throttle polling */ | 596 | udelay(1000); /* throttle polling */ |
| 597 | reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); | 597 | reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); |
| 598 | mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); | 598 | mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); |
| 599 | if (mc_fw_boot_status & 0x1) | 599 | if (mc_fw_boot_status & 0x1) |
| 600 | break; | 600 | break; |
| 601 | 601 | ||
| 602 | timeout_ms--; | 602 | timeout_ms--; |
| 603 | if (timeout_ms == 0) | 603 | if (timeout_ms == 0) |
| 604 | break; | 604 | break; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | if (timeout_ms == 0) { | 607 | if (timeout_ms == 0) { |
| 608 | printf("ERROR: timeout\n"); | 608 | printf("ERROR: timeout\n"); |
| 609 | 609 | ||
| 610 | /* TODO: Get an error status from an MC CCSR register */ | 610 | /* TODO: Get an error status from an MC CCSR register */ |
| 611 | return -ETIMEDOUT; | 611 | return -ETIMEDOUT; |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | if (mc_fw_boot_status != 0x1) { | 614 | if (mc_fw_boot_status != 0x1) { |
| 615 | /* | 615 | /* |
| 616 | * TODO: Identify critical errors from the GSR register's FS | 616 | * TODO: Identify critical errors from the GSR register's FS |
| 617 | * field and for those errors, set error to -ENODEV or other | 617 | * field and for those errors, set error to -ENODEV or other |
| 618 | * appropriate errno, so that the status property is set to | 618 | * appropriate errno, so that the status property is set to |
| 619 | * failure in the fsl,dprc device tree node. | 619 | * failure in the fsl,dprc device tree node. |
| 620 | */ | 620 | */ |
| 621 | printf("WARNING: Firmware returned an error (GSR: %#x)\n", | 621 | printf("WARNING: Firmware returned an error (GSR: %#x)\n", |
| 622 | reg_gsr); | 622 | reg_gsr); |
| 623 | } else { | 623 | } else { |
| 624 | printf("SUCCESS\n"); | 624 | printf("SUCCESS\n"); |
| 625 | } | 625 | } |
| 626 | 626 | ||
| 627 | 627 | ||
| 628 | *final_reg_gsr = reg_gsr; | 628 | *final_reg_gsr = reg_gsr; |
| 629 | return 0; | 629 | return 0; |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) | 632 | int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) |
| 633 | { | 633 | { |
| 634 | int error = 0; | 634 | int error = 0; |
| 635 | int portal_id = 0; | 635 | int portal_id = 0; |
| 636 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; | 636 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; |
| 637 | u64 mc_ram_addr = mc_get_dram_addr(); | 637 | u64 mc_ram_addr = mc_get_dram_addr(); |
| 638 | u32 reg_gsr; | 638 | u32 reg_gsr; |
| 639 | u32 reg_mcfbalr; | 639 | u32 reg_mcfbalr; |
| 640 | #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR | 640 | #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR |
| 641 | const void *raw_image_addr; | 641 | const void *raw_image_addr; |
| 642 | size_t raw_image_size = 0; | 642 | size_t raw_image_size = 0; |
| 643 | #endif | 643 | #endif |
| 644 | struct mc_version mc_ver_info; | 644 | struct mc_version mc_ver_info; |
| 645 | u8 mc_ram_num_256mb_blocks; | 645 | u8 mc_ram_num_256mb_blocks; |
| 646 | size_t mc_ram_size = mc_get_dram_block_size(); | 646 | size_t mc_ram_size = mc_get_dram_block_size(); |
| 647 | 647 | ||
| 648 | mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; | 648 | mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; |
| 649 | if (mc_ram_num_256mb_blocks < 1 || mc_ram_num_256mb_blocks > 0xff) { | 649 | if (mc_ram_num_256mb_blocks < 1 || mc_ram_num_256mb_blocks > 0xff) { |
| 650 | error = -EINVAL; | 650 | error = -EINVAL; |
| 651 | printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", | 651 | printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", |
| 652 | mc_ram_size); | 652 | mc_ram_size); |
| 653 | goto out; | 653 | goto out; |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | /* | 656 | /* |
| 657 | * Management Complex cores should be held at reset out of POR. | 657 | * Management Complex cores should be held at reset out of POR. |
| 658 | * U-Boot should be the first software to touch MC. To be safe, | 658 | * U-Boot should be the first software to touch MC. To be safe, |
| 659 | * we reset all cores again by setting GCR1 to 0. It doesn't do | 659 | * we reset all cores again by setting GCR1 to 0. It doesn't do |
| 660 | * anything if they are held at reset. After we setup the firmware | 660 | * anything if they are held at reset. After we setup the firmware |
| 661 | * we kick off MC by deasserting the reset bit for core 0, and | 661 | * we kick off MC by deasserting the reset bit for core 0, and |
| 662 | * deasserting the reset bits for Command Portal Managers. | 662 | * deasserting the reset bits for Command Portal Managers. |
| 663 | * The stop bits are not touched here. They are used to stop the | 663 | * The stop bits are not touched here. They are used to stop the |
| 664 | * cores when they are active. Setting stop bits doesn't stop the | 664 | * cores when they are active. Setting stop bits doesn't stop the |
| 665 | * cores from fetching instructions when they are released from | 665 | * cores from fetching instructions when they are released from |
| 666 | * reset. | 666 | * reset. |
| 667 | */ | 667 | */ |
| 668 | out_le32(&mc_ccsr_regs->reg_gcr1, 0); | 668 | out_le32(&mc_ccsr_regs->reg_gcr1, 0); |
| 669 | dmb(); | 669 | dmb(); |
| 670 | 670 | ||
| 671 | #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR | 671 | #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR |
| 672 | printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); | 672 | printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); |
| 673 | #else | 673 | #else |
| 674 | error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr, | 674 | error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr, |
| 675 | &raw_image_size); | 675 | &raw_image_size); |
| 676 | if (error != 0) | 676 | if (error != 0) |
| 677 | goto out; | 677 | goto out; |
| 678 | /* | 678 | /* |
| 679 | * Load the MC FW at the beginning of the MC private DRAM block: | 679 | * Load the MC FW at the beginning of the MC private DRAM block: |
| 680 | */ | 680 | */ |
| 681 | mc_copy_image("MC Firmware", | 681 | mc_copy_image("MC Firmware", |
| 682 | (u64)raw_image_addr, raw_image_size, mc_ram_addr); | 682 | (u64)raw_image_addr, raw_image_size, mc_ram_addr); |
| 683 | #endif | 683 | #endif |
| 684 | dump_ram_words("firmware", (void *)mc_ram_addr); | 684 | dump_ram_words("firmware", (void *)mc_ram_addr); |
| 685 | 685 | ||
| 686 | error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr); | 686 | error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr); |
| 687 | if (error != 0) | 687 | if (error != 0) |
| 688 | goto out; | 688 | goto out; |
| 689 | 689 | ||
| 690 | debug("mc_ccsr_regs %p\n", mc_ccsr_regs); | 690 | debug("mc_ccsr_regs %p\n", mc_ccsr_regs); |
| 691 | dump_mc_ccsr_regs(mc_ccsr_regs); | 691 | dump_mc_ccsr_regs(mc_ccsr_regs); |
| 692 | 692 | ||
| 693 | /* | 693 | /* |
| 694 | * Tell MC what is the address range of the DRAM block assigned to it: | 694 | * Tell MC what is the address range of the DRAM block assigned to it: |
| 695 | */ | 695 | */ |
| 696 | reg_mcfbalr = (u32)mc_ram_addr | | 696 | reg_mcfbalr = (u32)mc_ram_addr | |
| 697 | (mc_ram_num_256mb_blocks - 1); | 697 | (mc_ram_num_256mb_blocks - 1); |
| 698 | out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); | 698 | out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); |
| 699 | out_le32(&mc_ccsr_regs->reg_mcfbahr, | 699 | out_le32(&mc_ccsr_regs->reg_mcfbahr, |
| 700 | (u32)(mc_ram_addr >> 32)); | 700 | (u32)(mc_ram_addr >> 32)); |
| 701 | out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); | 701 | out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); |
| 702 | 702 | ||
| 703 | /* | 703 | /* |
| 704 | * Tell the MC that we want delayed DPL deployment. | 704 | * Tell the MC that we want delayed DPL deployment. |
| 705 | */ | 705 | */ |
| 706 | out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); | 706 | out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); |
| 707 | 707 | ||
| 708 | printf("\nfsl-mc: Booting Management Complex ... "); | 708 | printf("\nfsl-mc: Booting Management Complex ... "); |
| 709 | 709 | ||
| 710 | /* | 710 | /* |
| 711 | * Deassert reset and release MC core 0 to run | 711 | * Deassert reset and release MC core 0 to run |
| 712 | */ | 712 | */ |
| 713 | out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); | 713 | out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); |
| 714 | error = wait_for_mc(true, ®_gsr); | 714 | error = wait_for_mc(true, ®_gsr); |
| 715 | if (error != 0) | 715 | if (error != 0) |
| 716 | goto out; | 716 | goto out; |
| 717 | 717 | ||
| 718 | /* | 718 | /* |
| 719 | * TODO: need to obtain the portal_id for the root container from the | 719 | * TODO: need to obtain the portal_id for the root container from the |
| 720 | * DPL | 720 | * DPL |
| 721 | */ | 721 | */ |
| 722 | portal_id = 0; | 722 | portal_id = 0; |
| 723 | 723 | ||
| 724 | /* | 724 | /* |
| 725 | * Initialize the global default MC portal | 725 | * Initialize the global default MC portal |
| 726 | * And check that the MC firmware is responding portal commands: | 726 | * And check that the MC firmware is responding portal commands: |
| 727 | */ | 727 | */ |
| 728 | root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); | 728 | root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); |
| 729 | if (!root_mc_io) { | 729 | if (!root_mc_io) { |
| 730 | printf(" No memory: malloc() failed\n"); | 730 | printf(" No memory: malloc() failed\n"); |
| 731 | return -ENOMEM; | 731 | return -ENOMEM; |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); | 734 | root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); |
| 735 | debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", | 735 | debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", |
| 736 | portal_id, root_mc_io->mmio_regs); | 736 | portal_id, root_mc_io->mmio_regs); |
| 737 | 737 | ||
| 738 | error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); | 738 | error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); |
| 739 | if (error != 0) { | 739 | if (error != 0) { |
| 740 | printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", | 740 | printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", |
| 741 | error); | 741 | error); |
| 742 | goto out; | 742 | goto out; |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", | 745 | printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", |
| 746 | mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, | 746 | mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, |
| 747 | reg_gsr & GSR_FS_MASK); | 747 | reg_gsr & GSR_FS_MASK); |
| 748 | 748 | ||
| 749 | out: | 749 | out: |
| 750 | if (error != 0) | 750 | if (error != 0) |
| 751 | mc_boot_status = error; | 751 | mc_boot_status = error; |
| 752 | else | 752 | else |
| 753 | mc_boot_status = 0; | 753 | mc_boot_status = 0; |
| 754 | 754 | ||
| 755 | return error; | 755 | return error; |
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | int mc_apply_dpl(u64 mc_dpl_addr) | 758 | int mc_apply_dpl(u64 mc_dpl_addr) |
| 759 | { | 759 | { |
| 760 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; | 760 | struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; |
| 761 | int error = 0; | 761 | int error = 0; |
| 762 | u32 reg_gsr; | 762 | u32 reg_gsr; |
| 763 | u64 mc_ram_addr = mc_get_dram_addr(); | 763 | u64 mc_ram_addr = mc_get_dram_addr(); |
| 764 | size_t mc_ram_size = mc_get_dram_block_size(); | 764 | size_t mc_ram_size = mc_get_dram_block_size(); |
| 765 | 765 | ||
| 766 | if (!mc_dpl_addr) | 766 | if (!mc_dpl_addr) |
| 767 | return -1; | 767 | return -1; |
| 768 | 768 | ||
| 769 | error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); | 769 | error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); |
| 770 | if (error != 0) | 770 | if (error != 0) |
| 771 | return error; | 771 | return error; |
| 772 | 772 | ||
| 773 | /* | 773 | /* |
| 774 | * Tell the MC to deploy the DPL: | 774 | * Tell the MC to deploy the DPL: |
| 775 | */ | 775 | */ |
| 776 | out_le32(&mc_ccsr_regs->reg_gsr, 0x0); | 776 | out_le32(&mc_ccsr_regs->reg_gsr, 0x0); |
| 777 | printf("fsl-mc: Deploying data path layout ... "); | 777 | printf("fsl-mc: Deploying data path layout ... "); |
| 778 | error = wait_for_mc(false, ®_gsr); | 778 | error = wait_for_mc(false, ®_gsr); |
| 779 | 779 | ||
| 780 | if (!error) | 780 | if (!error) |
| 781 | mc_dpl_applied = 0; | 781 | mc_dpl_applied = 0; |
| 782 | 782 | ||
| 783 | return error; | 783 | return error; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | int get_mc_boot_status(void) | 786 | int get_mc_boot_status(void) |
| 787 | { | 787 | { |
| 788 | return mc_boot_status; | 788 | return mc_boot_status; |
| 789 | } | 789 | } |
| 790 | 790 | ||
| 791 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET | 791 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET |
| 792 | int get_aiop_apply_status(void) | 792 | int get_aiop_apply_status(void) |
| 793 | { | 793 | { |
| 794 | return mc_aiop_applied; | 794 | return mc_aiop_applied; |
| 795 | } | 795 | } |
| 796 | #endif | 796 | #endif |
| 797 | 797 | ||
| 798 | int get_dpl_apply_status(void) | 798 | int get_dpl_apply_status(void) |
| 799 | { | 799 | { |
| 800 | return mc_dpl_applied; | 800 | return mc_dpl_applied; |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | /** | 803 | /* |
| 804 | * Return the MC address of private DRAM block. | 804 | * Return the MC address of private DRAM block. |
| 805 | * As per MC design document, MC initial base address | ||
| 806 | * should be least significant 512MB address of MC private | ||
| 807 | * memory, i.e. address should point to end address masked | ||
| 808 | * with 512MB offset in private DRAM block. | ||
| 805 | */ | 809 | */ |
| 806 | u64 mc_get_dram_addr(void) | 810 | u64 mc_get_dram_addr(void) |
| 807 | { | 811 | { |
| 808 | return gd->arch.resv_ram; | 812 | size_t mc_ram_size = mc_get_dram_block_size(); |
| 813 | |||
| 814 | return (gd->arch.resv_ram + mc_ram_size - 1) & | ||
| 815 | MC_RAM_BASE_ADDR_ALIGNMENT_MASK; | ||
| 809 | } | 816 | } |
| 810 | 817 | ||
| 811 | /** | 818 | /** |
| 812 | * Return the actual size of the MC private DRAM block. | 819 | * Return the actual size of the MC private DRAM block. |
| 813 | */ | 820 | */ |
| 814 | unsigned long mc_get_dram_block_size(void) | 821 | unsigned long mc_get_dram_block_size(void) |
| 815 | { | 822 | { |
| 816 | unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; | 823 | unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; |
| 817 | 824 | ||
| 818 | char *dram_block_size_env_var = env_get(MC_MEM_SIZE_ENV_VAR); | 825 | char *dram_block_size_env_var = env_get(MC_MEM_SIZE_ENV_VAR); |
| 819 | 826 | ||
| 820 | if (dram_block_size_env_var) { | 827 | if (dram_block_size_env_var) { |
| 821 | dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, | 828 | dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, |
| 822 | 10); | 829 | 10); |
| 823 | 830 | ||
| 824 | if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { | 831 | if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { |
| 825 | printf("fsl-mc: WARNING: Invalid value for \'" | 832 | printf("fsl-mc: WARNING: Invalid value for \'" |
| 826 | MC_MEM_SIZE_ENV_VAR | 833 | MC_MEM_SIZE_ENV_VAR |
| 827 | "\' environment variable: %lu\n", | 834 | "\' environment variable: %lu\n", |
| 828 | dram_block_size); | 835 | dram_block_size); |
| 829 | 836 | ||
| 830 | dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; | 837 | dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; |
| 831 | } | 838 | } |
| 832 | } | 839 | } |
| 833 | 840 | ||
| 834 | return dram_block_size; | 841 | return dram_block_size; |
| 835 | } | 842 | } |
| 836 | 843 | ||
| 837 | int fsl_mc_ldpaa_init(bd_t *bis) | 844 | int fsl_mc_ldpaa_init(bd_t *bis) |
| 838 | { | 845 | { |
| 839 | int i; | 846 | int i; |
| 840 | 847 | ||
| 841 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) | 848 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) |
| 842 | if ((wriop_is_enabled_dpmac(i) == 1) && | 849 | if ((wriop_is_enabled_dpmac(i) == 1) && |
| 843 | (wriop_get_phy_address(i) != -1)) | 850 | (wriop_get_phy_address(i) != -1)) |
| 844 | ldpaa_eth_init(i, wriop_get_enet_if(i)); | 851 | ldpaa_eth_init(i, wriop_get_enet_if(i)); |
| 845 | return 0; | 852 | return 0; |
| 846 | } | 853 | } |
| 847 | 854 | ||
| 848 | static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle) | 855 | static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle) |
| 849 | { | 856 | { |
| 850 | struct dprc_attributes attr; | 857 | struct dprc_attributes attr; |
| 851 | int error; | 858 | int error; |
| 852 | 859 | ||
| 853 | memset(&attr, 0, sizeof(struct dprc_attributes)); | 860 | memset(&attr, 0, sizeof(struct dprc_attributes)); |
| 854 | error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr); | 861 | error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr); |
| 855 | if (error == 0) { | 862 | if (error == 0) { |
| 856 | if ((attr.version.major != DPRC_VER_MAJOR) || | 863 | if ((attr.version.major != DPRC_VER_MAJOR) || |
| 857 | (attr.version.minor != DPRC_VER_MINOR)) { | 864 | (attr.version.minor != DPRC_VER_MINOR)) { |
| 858 | printf("DPRC version mismatch found %u.%u,", | 865 | printf("DPRC version mismatch found %u.%u,", |
| 859 | attr.version.major, | 866 | attr.version.major, |
| 860 | attr.version.minor); | 867 | attr.version.minor); |
| 861 | printf("supported version is %u.%u\n", | 868 | printf("supported version is %u.%u\n", |
| 862 | DPRC_VER_MAJOR, DPRC_VER_MINOR); | 869 | DPRC_VER_MAJOR, DPRC_VER_MINOR); |
| 863 | } | 870 | } |
| 864 | } | 871 | } |
| 865 | return error; | 872 | return error; |
| 866 | } | 873 | } |
| 867 | 874 | ||
| 868 | static int dpio_init(void) | 875 | static int dpio_init(void) |
| 869 | { | 876 | { |
| 870 | struct qbman_swp_desc p_des; | 877 | struct qbman_swp_desc p_des; |
| 871 | struct dpio_attr attr; | 878 | struct dpio_attr attr; |
| 872 | struct dpio_cfg dpio_cfg; | 879 | struct dpio_cfg dpio_cfg; |
| 873 | int err = 0; | 880 | int err = 0; |
| 874 | 881 | ||
| 875 | dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); | 882 | dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); |
| 876 | if (!dflt_dpio) { | 883 | if (!dflt_dpio) { |
| 877 | printf("No memory: malloc() failed\n"); | 884 | printf("No memory: malloc() failed\n"); |
| 878 | err = -ENOMEM; | 885 | err = -ENOMEM; |
| 879 | goto err_malloc; | 886 | goto err_malloc; |
| 880 | } | 887 | } |
| 881 | 888 | ||
| 882 | dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; | 889 | dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; |
| 883 | dpio_cfg.num_priorities = 8; | 890 | dpio_cfg.num_priorities = 8; |
| 884 | 891 | ||
| 885 | err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, | 892 | err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, |
| 886 | &dflt_dpio->dpio_handle); | 893 | &dflt_dpio->dpio_handle); |
| 887 | if (err < 0) { | 894 | if (err < 0) { |
| 888 | printf("dpio_create() failed: %d\n", err); | 895 | printf("dpio_create() failed: %d\n", err); |
| 889 | err = -ENODEV; | 896 | err = -ENODEV; |
| 890 | goto err_create; | 897 | goto err_create; |
| 891 | } | 898 | } |
| 892 | 899 | ||
| 893 | memset(&attr, 0, sizeof(struct dpio_attr)); | 900 | memset(&attr, 0, sizeof(struct dpio_attr)); |
| 894 | err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, | 901 | err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, |
| 895 | dflt_dpio->dpio_handle, &attr); | 902 | dflt_dpio->dpio_handle, &attr); |
| 896 | if (err < 0) { | 903 | if (err < 0) { |
| 897 | printf("dpio_get_attributes() failed: %d\n", err); | 904 | printf("dpio_get_attributes() failed: %d\n", err); |
| 898 | goto err_get_attr; | 905 | goto err_get_attr; |
| 899 | } | 906 | } |
| 900 | 907 | ||
| 901 | if ((attr.version.major != DPIO_VER_MAJOR) || | 908 | if ((attr.version.major != DPIO_VER_MAJOR) || |
| 902 | (attr.version.minor != DPIO_VER_MINOR)) { | 909 | (attr.version.minor != DPIO_VER_MINOR)) { |
| 903 | printf("DPIO version mismatch found %u.%u,", | 910 | printf("DPIO version mismatch found %u.%u,", |
| 904 | attr.version.major, attr.version.minor); | 911 | attr.version.major, attr.version.minor); |
| 905 | printf("supported version is %u.%u\n", | 912 | printf("supported version is %u.%u\n", |
| 906 | DPIO_VER_MAJOR, DPIO_VER_MINOR); | 913 | DPIO_VER_MAJOR, DPIO_VER_MINOR); |
| 907 | } | 914 | } |
| 908 | 915 | ||
| 909 | dflt_dpio->dpio_id = attr.id; | 916 | dflt_dpio->dpio_id = attr.id; |
| 910 | #ifdef DEBUG | 917 | #ifdef DEBUG |
| 911 | printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); | 918 | printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); |
| 912 | #endif | 919 | #endif |
| 913 | err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 920 | err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 914 | if (err < 0) { | 921 | if (err < 0) { |
| 915 | printf("dpio_enable() failed %d\n", err); | 922 | printf("dpio_enable() failed %d\n", err); |
| 916 | goto err_get_enable; | 923 | goto err_get_enable; |
| 917 | } | 924 | } |
| 918 | debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", | 925 | debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", |
| 919 | attr.qbman_portal_ce_offset, | 926 | attr.qbman_portal_ce_offset, |
| 920 | attr.qbman_portal_ci_offset, | 927 | attr.qbman_portal_ci_offset, |
| 921 | attr.qbman_portal_id, | 928 | attr.qbman_portal_id, |
| 922 | attr.num_priorities); | 929 | attr.num_priorities); |
| 923 | 930 | ||
| 924 | p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR | 931 | p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR |
| 925 | + attr.qbman_portal_ce_offset); | 932 | + attr.qbman_portal_ce_offset); |
| 926 | p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR | 933 | p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR |
| 927 | + attr.qbman_portal_ci_offset); | 934 | + attr.qbman_portal_ci_offset); |
| 928 | 935 | ||
| 929 | dflt_dpio->sw_portal = qbman_swp_init(&p_des); | 936 | dflt_dpio->sw_portal = qbman_swp_init(&p_des); |
| 930 | if (dflt_dpio->sw_portal == NULL) { | 937 | if (dflt_dpio->sw_portal == NULL) { |
| 931 | printf("qbman_swp_init() failed\n"); | 938 | printf("qbman_swp_init() failed\n"); |
| 932 | goto err_get_swp_init; | 939 | goto err_get_swp_init; |
| 933 | } | 940 | } |
| 934 | return 0; | 941 | return 0; |
| 935 | 942 | ||
| 936 | err_get_swp_init: | 943 | err_get_swp_init: |
| 937 | dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 944 | dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 938 | err_get_enable: | 945 | err_get_enable: |
| 939 | err_get_attr: | 946 | err_get_attr: |
| 940 | dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 947 | dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 941 | dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 948 | dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 942 | err_create: | 949 | err_create: |
| 943 | free(dflt_dpio); | 950 | free(dflt_dpio); |
| 944 | err_malloc: | 951 | err_malloc: |
| 945 | return err; | 952 | return err; |
| 946 | } | 953 | } |
| 947 | 954 | ||
| 948 | static int dpio_exit(void) | 955 | static int dpio_exit(void) |
| 949 | { | 956 | { |
| 950 | int err; | 957 | int err; |
| 951 | 958 | ||
| 952 | err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 959 | err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 953 | if (err < 0) { | 960 | if (err < 0) { |
| 954 | printf("dpio_disable() failed: %d\n", err); | 961 | printf("dpio_disable() failed: %d\n", err); |
| 955 | goto err; | 962 | goto err; |
| 956 | } | 963 | } |
| 957 | 964 | ||
| 958 | err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); | 965 | err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); |
| 959 | if (err < 0) { | 966 | if (err < 0) { |
| 960 | printf("dpio_destroy() failed: %d\n", err); | 967 | printf("dpio_destroy() failed: %d\n", err); |
| 961 | goto err; | 968 | goto err; |
| 962 | } | 969 | } |
| 963 | 970 | ||
| 964 | #ifdef DEBUG | 971 | #ifdef DEBUG |
| 965 | printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); | 972 | printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); |
| 966 | #endif | 973 | #endif |
| 967 | 974 | ||
| 968 | if (dflt_dpio) | 975 | if (dflt_dpio) |
| 969 | free(dflt_dpio); | 976 | free(dflt_dpio); |
| 970 | 977 | ||
| 971 | return 0; | 978 | return 0; |
| 972 | err: | 979 | err: |
| 973 | return err; | 980 | return err; |
| 974 | } | 981 | } |
| 975 | 982 | ||
| 976 | static int dprc_init(void) | 983 | static int dprc_init(void) |
| 977 | { | 984 | { |
| 978 | int err, child_portal_id, container_id; | 985 | int err, child_portal_id, container_id; |
| 979 | struct dprc_cfg cfg; | 986 | struct dprc_cfg cfg; |
| 980 | uint64_t mc_portal_offset; | 987 | uint64_t mc_portal_offset; |
| 981 | 988 | ||
| 982 | /* Open root container */ | 989 | /* Open root container */ |
| 983 | err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); | 990 | err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); |
| 984 | if (err < 0) { | 991 | if (err < 0) { |
| 985 | printf("dprc_get_container_id(): Root failed: %d\n", err); | 992 | printf("dprc_get_container_id(): Root failed: %d\n", err); |
| 986 | goto err_root_container_id; | 993 | goto err_root_container_id; |
| 987 | } | 994 | } |
| 988 | 995 | ||
| 989 | #ifdef DEBUG | 996 | #ifdef DEBUG |
| 990 | printf("Root container id = %d\n", container_id); | 997 | printf("Root container id = %d\n", container_id); |
| 991 | #endif | 998 | #endif |
| 992 | err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, | 999 | err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, |
| 993 | &root_dprc_handle); | 1000 | &root_dprc_handle); |
| 994 | if (err < 0) { | 1001 | if (err < 0) { |
| 995 | printf("dprc_open(): Root Container failed: %d\n", err); | 1002 | printf("dprc_open(): Root Container failed: %d\n", err); |
| 996 | goto err_root_open; | 1003 | goto err_root_open; |
| 997 | } | 1004 | } |
| 998 | 1005 | ||
| 999 | if (!root_dprc_handle) { | 1006 | if (!root_dprc_handle) { |
| 1000 | printf("dprc_open(): Root Container Handle is not valid\n"); | 1007 | printf("dprc_open(): Root Container Handle is not valid\n"); |
| 1001 | goto err_root_open; | 1008 | goto err_root_open; |
| 1002 | } | 1009 | } |
| 1003 | 1010 | ||
| 1004 | err = dprc_version_check(root_mc_io, root_dprc_handle); | 1011 | err = dprc_version_check(root_mc_io, root_dprc_handle); |
| 1005 | if (err < 0) { | 1012 | if (err < 0) { |
| 1006 | printf("dprc_version_check() failed: %d\n", err); | 1013 | printf("dprc_version_check() failed: %d\n", err); |
| 1007 | goto err_root_open; | 1014 | goto err_root_open; |
| 1008 | } | 1015 | } |
| 1009 | 1016 | ||
| 1010 | memset(&cfg, 0, sizeof(struct dprc_cfg)); | 1017 | memset(&cfg, 0, sizeof(struct dprc_cfg)); |
| 1011 | cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | | 1018 | cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | |
| 1012 | DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | | 1019 | DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | |
| 1013 | DPRC_CFG_OPT_ALLOC_ALLOWED; | 1020 | DPRC_CFG_OPT_ALLOC_ALLOWED; |
| 1014 | cfg.icid = DPRC_GET_ICID_FROM_POOL; | 1021 | cfg.icid = DPRC_GET_ICID_FROM_POOL; |
| 1015 | cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL; | 1022 | cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL; |
| 1016 | err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, | 1023 | err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, |
| 1017 | root_dprc_handle, | 1024 | root_dprc_handle, |
| 1018 | &cfg, | 1025 | &cfg, |
| 1019 | &child_dprc_id, | 1026 | &child_dprc_id, |
| 1020 | &mc_portal_offset); | 1027 | &mc_portal_offset); |
| 1021 | if (err < 0) { | 1028 | if (err < 0) { |
| 1022 | printf("dprc_create_container() failed: %d\n", err); | 1029 | printf("dprc_create_container() failed: %d\n", err); |
| 1023 | goto err_create; | 1030 | goto err_create; |
| 1024 | } | 1031 | } |
| 1025 | 1032 | ||
| 1026 | dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); | 1033 | dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); |
| 1027 | if (!dflt_mc_io) { | 1034 | if (!dflt_mc_io) { |
| 1028 | err = -ENOMEM; | 1035 | err = -ENOMEM; |
| 1029 | printf(" No memory: malloc() failed\n"); | 1036 | printf(" No memory: malloc() failed\n"); |
| 1030 | goto err_malloc; | 1037 | goto err_malloc; |
| 1031 | } | 1038 | } |
| 1032 | 1039 | ||
| 1033 | child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); | 1040 | child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); |
| 1034 | dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); | 1041 | dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); |
| 1035 | #ifdef DEBUG | 1042 | #ifdef DEBUG |
| 1036 | printf("MC portal of child DPRC container: %d, physical addr %p)\n", | 1043 | printf("MC portal of child DPRC container: %d, physical addr %p)\n", |
| 1037 | child_dprc_id, dflt_mc_io->mmio_regs); | 1044 | child_dprc_id, dflt_mc_io->mmio_regs); |
| 1038 | #endif | 1045 | #endif |
| 1039 | 1046 | ||
| 1040 | err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, | 1047 | err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, |
| 1041 | &dflt_dprc_handle); | 1048 | &dflt_dprc_handle); |
| 1042 | if (err < 0) { | 1049 | if (err < 0) { |
| 1043 | printf("dprc_open(): Child container failed: %d\n", err); | 1050 | printf("dprc_open(): Child container failed: %d\n", err); |
| 1044 | goto err_child_open; | 1051 | goto err_child_open; |
| 1045 | } | 1052 | } |
| 1046 | 1053 | ||
| 1047 | if (!dflt_dprc_handle) { | 1054 | if (!dflt_dprc_handle) { |
| 1048 | printf("dprc_open(): Child container Handle is not valid\n"); | 1055 | printf("dprc_open(): Child container Handle is not valid\n"); |
| 1049 | goto err_child_open; | 1056 | goto err_child_open; |
| 1050 | } | 1057 | } |
| 1051 | 1058 | ||
| 1052 | return 0; | 1059 | return 0; |
| 1053 | err_child_open: | 1060 | err_child_open: |
| 1054 | free(dflt_mc_io); | 1061 | free(dflt_mc_io); |
| 1055 | err_malloc: | 1062 | err_malloc: |
| 1056 | dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, | 1063 | dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, |
| 1057 | root_dprc_handle, child_dprc_id); | 1064 | root_dprc_handle, child_dprc_id); |
| 1058 | err_create: | 1065 | err_create: |
| 1059 | dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); | 1066 | dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); |
| 1060 | err_root_open: | 1067 | err_root_open: |
| 1061 | err_root_container_id: | 1068 | err_root_container_id: |
| 1062 | return err; | 1069 | return err; |
| 1063 | } | 1070 | } |
| 1064 | 1071 | ||
| 1065 | static int dprc_exit(void) | 1072 | static int dprc_exit(void) |
| 1066 | { | 1073 | { |
| 1067 | int err; | 1074 | int err; |
| 1068 | 1075 | ||
| 1069 | err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); | 1076 | err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); |
| 1070 | if (err < 0) { | 1077 | if (err < 0) { |
| 1071 | printf("dprc_close(): Child failed: %d\n", err); | 1078 | printf("dprc_close(): Child failed: %d\n", err); |
| 1072 | goto err; | 1079 | goto err; |
| 1073 | } | 1080 | } |
| 1074 | 1081 | ||
| 1075 | err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, | 1082 | err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, |
| 1076 | root_dprc_handle, child_dprc_id); | 1083 | root_dprc_handle, child_dprc_id); |
| 1077 | if (err < 0) { | 1084 | if (err < 0) { |
| 1078 | printf("dprc_destroy_container() failed: %d\n", err); | 1085 | printf("dprc_destroy_container() failed: %d\n", err); |
| 1079 | goto err; | 1086 | goto err; |
| 1080 | } | 1087 | } |
| 1081 | 1088 | ||
| 1082 | err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); | 1089 | err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); |
| 1083 | if (err < 0) { | 1090 | if (err < 0) { |
| 1084 | printf("dprc_close(): Root failed: %d\n", err); | 1091 | printf("dprc_close(): Root failed: %d\n", err); |
| 1085 | goto err; | 1092 | goto err; |
| 1086 | } | 1093 | } |
| 1087 | 1094 | ||
| 1088 | if (dflt_mc_io) | 1095 | if (dflt_mc_io) |
| 1089 | free(dflt_mc_io); | 1096 | free(dflt_mc_io); |
| 1090 | 1097 | ||
| 1091 | if (root_mc_io) | 1098 | if (root_mc_io) |
| 1092 | free(root_mc_io); | 1099 | free(root_mc_io); |
| 1093 | 1100 | ||
| 1094 | return 0; | 1101 | return 0; |
| 1095 | 1102 | ||
| 1096 | err: | 1103 | err: |
| 1097 | return err; | 1104 | return err; |
| 1098 | } | 1105 | } |
| 1099 | 1106 | ||
| 1100 | static int dpbp_init(void) | 1107 | static int dpbp_init(void) |
| 1101 | { | 1108 | { |
| 1102 | int err; | 1109 | int err; |
| 1103 | struct dpbp_attr dpbp_attr; | 1110 | struct dpbp_attr dpbp_attr; |
| 1104 | struct dpbp_cfg dpbp_cfg; | 1111 | struct dpbp_cfg dpbp_cfg; |
| 1105 | 1112 | ||
| 1106 | dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); | 1113 | dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); |
| 1107 | if (!dflt_dpbp) { | 1114 | if (!dflt_dpbp) { |
| 1108 | printf("No memory: malloc() failed\n"); | 1115 | printf("No memory: malloc() failed\n"); |
| 1109 | err = -ENOMEM; | 1116 | err = -ENOMEM; |
| 1110 | goto err_malloc; | 1117 | goto err_malloc; |
| 1111 | } | 1118 | } |
| 1112 | 1119 | ||
| 1113 | dpbp_cfg.options = 512; | 1120 | dpbp_cfg.options = 512; |
| 1114 | 1121 | ||
| 1115 | err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, | 1122 | err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, |
| 1116 | &dflt_dpbp->dpbp_handle); | 1123 | &dflt_dpbp->dpbp_handle); |
| 1117 | 1124 | ||
| 1118 | if (err < 0) { | 1125 | if (err < 0) { |
| 1119 | err = -ENODEV; | 1126 | err = -ENODEV; |
| 1120 | printf("dpbp_create() failed: %d\n", err); | 1127 | printf("dpbp_create() failed: %d\n", err); |
| 1121 | goto err_create; | 1128 | goto err_create; |
| 1122 | } | 1129 | } |
| 1123 | 1130 | ||
| 1124 | memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); | 1131 | memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); |
| 1125 | err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, | 1132 | err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, |
| 1126 | dflt_dpbp->dpbp_handle, | 1133 | dflt_dpbp->dpbp_handle, |
| 1127 | &dpbp_attr); | 1134 | &dpbp_attr); |
| 1128 | if (err < 0) { | 1135 | if (err < 0) { |
| 1129 | printf("dpbp_get_attributes() failed: %d\n", err); | 1136 | printf("dpbp_get_attributes() failed: %d\n", err); |
| 1130 | goto err_get_attr; | 1137 | goto err_get_attr; |
| 1131 | } | 1138 | } |
| 1132 | 1139 | ||
| 1133 | if ((dpbp_attr.version.major != DPBP_VER_MAJOR) || | 1140 | if ((dpbp_attr.version.major != DPBP_VER_MAJOR) || |
| 1134 | (dpbp_attr.version.minor != DPBP_VER_MINOR)) { | 1141 | (dpbp_attr.version.minor != DPBP_VER_MINOR)) { |
| 1135 | printf("DPBP version mismatch found %u.%u,", | 1142 | printf("DPBP version mismatch found %u.%u,", |
| 1136 | dpbp_attr.version.major, dpbp_attr.version.minor); | 1143 | dpbp_attr.version.major, dpbp_attr.version.minor); |
| 1137 | printf("supported version is %u.%u\n", | 1144 | printf("supported version is %u.%u\n", |
| 1138 | DPBP_VER_MAJOR, DPBP_VER_MINOR); | 1145 | DPBP_VER_MAJOR, DPBP_VER_MINOR); |
| 1139 | } | 1146 | } |
| 1140 | 1147 | ||
| 1141 | dflt_dpbp->dpbp_attr.id = dpbp_attr.id; | 1148 | dflt_dpbp->dpbp_attr.id = dpbp_attr.id; |
| 1142 | #ifdef DEBUG | 1149 | #ifdef DEBUG |
| 1143 | printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); | 1150 | printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); |
| 1144 | #endif | 1151 | #endif |
| 1145 | 1152 | ||
| 1146 | err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); | 1153 | err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); |
| 1147 | if (err < 0) { | 1154 | if (err < 0) { |
| 1148 | printf("dpbp_close() failed: %d\n", err); | 1155 | printf("dpbp_close() failed: %d\n", err); |
| 1149 | goto err_close; | 1156 | goto err_close; |
| 1150 | } | 1157 | } |
| 1151 | 1158 | ||
| 1152 | return 0; | 1159 | return 0; |
| 1153 | 1160 | ||
| 1154 | err_close: | 1161 | err_close: |
| 1155 | free(dflt_dpbp); | 1162 | free(dflt_dpbp); |
| 1156 | err_get_attr: | 1163 | err_get_attr: |
| 1157 | dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); | 1164 | dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); |
| 1158 | dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); | 1165 | dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); |
| 1159 | err_create: | 1166 | err_create: |
| 1160 | err_malloc: | 1167 | err_malloc: |
| 1161 | return err; | 1168 | return err; |
| 1162 | } | 1169 | } |
| 1163 | 1170 | ||
| 1164 | static int dpbp_exit(void) | 1171 | static int dpbp_exit(void) |
| 1165 | { | 1172 | { |
| 1166 | int err; | 1173 | int err; |
| 1167 | 1174 | ||
| 1168 | err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, | 1175 | err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, |
| 1169 | &dflt_dpbp->dpbp_handle); | 1176 | &dflt_dpbp->dpbp_handle); |
| 1170 | if (err < 0) { | 1177 | if (err < 0) { |
| 1171 | printf("dpbp_open() failed: %d\n", err); | 1178 | printf("dpbp_open() failed: %d\n", err); |
| 1172 | goto err; | 1179 | goto err; |
| 1173 | } | 1180 | } |
| 1174 | 1181 | ||
| 1175 | err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, | 1182 | err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, |
| 1176 | dflt_dpbp->dpbp_handle); | 1183 | dflt_dpbp->dpbp_handle); |
| 1177 | if (err < 0) { | 1184 | if (err < 0) { |
| 1178 | printf("dpbp_destroy() failed: %d\n", err); | 1185 | printf("dpbp_destroy() failed: %d\n", err); |
| 1179 | goto err; | 1186 | goto err; |
| 1180 | } | 1187 | } |
| 1181 | 1188 | ||
| 1182 | #ifdef DEBUG | 1189 | #ifdef DEBUG |
| 1183 | printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); | 1190 | printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); |
| 1184 | #endif | 1191 | #endif |
| 1185 | 1192 | ||
| 1186 | if (dflt_dpbp) | 1193 | if (dflt_dpbp) |
| 1187 | free(dflt_dpbp); | 1194 | free(dflt_dpbp); |
| 1188 | return 0; | 1195 | return 0; |
| 1189 | 1196 | ||
| 1190 | err: | 1197 | err: |
| 1191 | return err; | 1198 | return err; |
| 1192 | } | 1199 | } |
| 1193 | 1200 | ||
| 1194 | static int dpni_init(void) | 1201 | static int dpni_init(void) |
| 1195 | { | 1202 | { |
| 1196 | int err; | 1203 | int err; |
| 1197 | struct dpni_attr dpni_attr; | 1204 | struct dpni_attr dpni_attr; |
| 1198 | uint8_t ext_cfg_buf[256] = {0}; | 1205 | uint8_t ext_cfg_buf[256] = {0}; |
| 1199 | struct dpni_extended_cfg dpni_extended_cfg; | 1206 | struct dpni_extended_cfg dpni_extended_cfg; |
| 1200 | struct dpni_cfg dpni_cfg; | 1207 | struct dpni_cfg dpni_cfg; |
| 1201 | 1208 | ||
| 1202 | dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); | 1209 | dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); |
| 1203 | if (!dflt_dpni) { | 1210 | if (!dflt_dpni) { |
| 1204 | printf("No memory: malloc() failed\n"); | 1211 | printf("No memory: malloc() failed\n"); |
| 1205 | err = -ENOMEM; | 1212 | err = -ENOMEM; |
| 1206 | goto err_malloc; | 1213 | goto err_malloc; |
| 1207 | } | 1214 | } |
| 1208 | 1215 | ||
| 1209 | memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg)); | 1216 | memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg)); |
| 1210 | err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]); | 1217 | err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]); |
| 1211 | if (err < 0) { | 1218 | if (err < 0) { |
| 1212 | err = -ENODEV; | 1219 | err = -ENODEV; |
| 1213 | printf("dpni_prepare_extended_cfg() failed: %d\n", err); | 1220 | printf("dpni_prepare_extended_cfg() failed: %d\n", err); |
| 1214 | goto err_prepare_extended_cfg; | 1221 | goto err_prepare_extended_cfg; |
| 1215 | } | 1222 | } |
| 1216 | 1223 | ||
| 1217 | memset(&dpni_cfg, 0, sizeof(dpni_cfg)); | 1224 | memset(&dpni_cfg, 0, sizeof(dpni_cfg)); |
| 1218 | dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | | 1225 | dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | |
| 1219 | DPNI_OPT_MULTICAST_FILTER; | 1226 | DPNI_OPT_MULTICAST_FILTER; |
| 1220 | 1227 | ||
| 1221 | dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0]; | 1228 | dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0]; |
| 1222 | err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, | 1229 | err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, |
| 1223 | &dflt_dpni->dpni_handle); | 1230 | &dflt_dpni->dpni_handle); |
| 1224 | 1231 | ||
| 1225 | if (err < 0) { | 1232 | if (err < 0) { |
| 1226 | err = -ENODEV; | 1233 | err = -ENODEV; |
| 1227 | printf("dpni_create() failed: %d\n", err); | 1234 | printf("dpni_create() failed: %d\n", err); |
| 1228 | goto err_create; | 1235 | goto err_create; |
| 1229 | } | 1236 | } |
| 1230 | 1237 | ||
| 1231 | memset(&dpni_attr, 0, sizeof(struct dpni_attr)); | 1238 | memset(&dpni_attr, 0, sizeof(struct dpni_attr)); |
| 1232 | err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, | 1239 | err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, |
| 1233 | dflt_dpni->dpni_handle, | 1240 | dflt_dpni->dpni_handle, |
| 1234 | &dpni_attr); | 1241 | &dpni_attr); |
| 1235 | if (err < 0) { | 1242 | if (err < 0) { |
| 1236 | printf("dpni_get_attributes() failed: %d\n", err); | 1243 | printf("dpni_get_attributes() failed: %d\n", err); |
| 1237 | goto err_get_attr; | 1244 | goto err_get_attr; |
| 1238 | } | 1245 | } |
| 1239 | 1246 | ||
| 1240 | if ((dpni_attr.version.major != DPNI_VER_MAJOR) || | 1247 | if ((dpni_attr.version.major != DPNI_VER_MAJOR) || |
| 1241 | (dpni_attr.version.minor != DPNI_VER_MINOR)) { | 1248 | (dpni_attr.version.minor != DPNI_VER_MINOR)) { |
| 1242 | printf("DPNI version mismatch found %u.%u,", | 1249 | printf("DPNI version mismatch found %u.%u,", |
| 1243 | dpni_attr.version.major, dpni_attr.version.minor); | 1250 | dpni_attr.version.major, dpni_attr.version.minor); |
| 1244 | printf("supported version is %u.%u\n", | 1251 | printf("supported version is %u.%u\n", |
| 1245 | DPNI_VER_MAJOR, DPNI_VER_MINOR); | 1252 | DPNI_VER_MAJOR, DPNI_VER_MINOR); |
| 1246 | } | 1253 | } |
| 1247 | 1254 | ||
| 1248 | dflt_dpni->dpni_id = dpni_attr.id; | 1255 | dflt_dpni->dpni_id = dpni_attr.id; |
| 1249 | #ifdef DEBUG | 1256 | #ifdef DEBUG |
| 1250 | printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); | 1257 | printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); |
| 1251 | #endif | 1258 | #endif |
| 1252 | 1259 | ||
| 1253 | err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); | 1260 | err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); |
| 1254 | if (err < 0) { | 1261 | if (err < 0) { |
| 1255 | printf("dpni_close() failed: %d\n", err); | 1262 | printf("dpni_close() failed: %d\n", err); |
| 1256 | goto err_close; | 1263 | goto err_close; |
| 1257 | } | 1264 | } |
| 1258 | 1265 | ||
| 1259 | return 0; | 1266 | return 0; |
| 1260 | 1267 | ||
| 1261 | err_close: | 1268 | err_close: |
| 1262 | err_get_attr: | 1269 | err_get_attr: |
| 1263 | dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); | 1270 | dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); |
| 1264 | dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); | 1271 | dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); |
| 1265 | err_create: | 1272 | err_create: |
| 1266 | err_prepare_extended_cfg: | 1273 | err_prepare_extended_cfg: |
| 1267 | free(dflt_dpni); | 1274 | free(dflt_dpni); |
| 1268 | err_malloc: | 1275 | err_malloc: |
| 1269 | return err; | 1276 | return err; |
| 1270 | } | 1277 | } |
| 1271 | 1278 | ||
| 1272 | static int dpni_exit(void) | 1279 | static int dpni_exit(void) |
| 1273 | { | 1280 | { |
| 1274 | int err; | 1281 | int err; |
| 1275 | 1282 | ||
| 1276 | err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, | 1283 | err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, |
| 1277 | &dflt_dpni->dpni_handle); | 1284 | &dflt_dpni->dpni_handle); |
| 1278 | if (err < 0) { | 1285 | if (err < 0) { |
| 1279 | printf("dpni_open() failed: %d\n", err); | 1286 | printf("dpni_open() failed: %d\n", err); |
| 1280 | goto err; | 1287 | goto err; |
| 1281 | } | 1288 | } |
| 1282 | 1289 | ||
| 1283 | err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, | 1290 | err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, |
| 1284 | dflt_dpni->dpni_handle); | 1291 | dflt_dpni->dpni_handle); |
| 1285 | if (err < 0) { | 1292 | if (err < 0) { |
| 1286 | printf("dpni_destroy() failed: %d\n", err); | 1293 | printf("dpni_destroy() failed: %d\n", err); |
| 1287 | goto err; | 1294 | goto err; |
| 1288 | } | 1295 | } |
| 1289 | 1296 | ||
| 1290 | #ifdef DEBUG | 1297 | #ifdef DEBUG |
| 1291 | printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); | 1298 | printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); |
| 1292 | #endif | 1299 | #endif |
| 1293 | 1300 | ||
| 1294 | if (dflt_dpni) | 1301 | if (dflt_dpni) |
| 1295 | free(dflt_dpni); | 1302 | free(dflt_dpni); |
| 1296 | return 0; | 1303 | return 0; |
| 1297 | 1304 | ||
| 1298 | err: | 1305 | err: |
| 1299 | return err; | 1306 | return err; |
| 1300 | } | 1307 | } |
| 1301 | 1308 | ||
| 1302 | static int mc_init_object(void) | 1309 | static int mc_init_object(void) |
| 1303 | { | 1310 | { |
| 1304 | int err = 0; | 1311 | int err = 0; |
| 1305 | 1312 | ||
| 1306 | err = dprc_init(); | 1313 | err = dprc_init(); |
| 1307 | if (err < 0) { | 1314 | if (err < 0) { |
| 1308 | printf("dprc_init() failed: %d\n", err); | 1315 | printf("dprc_init() failed: %d\n", err); |
| 1309 | goto err; | 1316 | goto err; |
| 1310 | } | 1317 | } |
| 1311 | 1318 | ||
| 1312 | err = dpbp_init(); | 1319 | err = dpbp_init(); |
| 1313 | if (err < 0) { | 1320 | if (err < 0) { |
| 1314 | printf("dpbp_init() failed: %d\n", err); | 1321 | printf("dpbp_init() failed: %d\n", err); |
| 1315 | goto err; | 1322 | goto err; |
| 1316 | } | 1323 | } |
| 1317 | 1324 | ||
| 1318 | err = dpio_init(); | 1325 | err = dpio_init(); |
| 1319 | if (err < 0) { | 1326 | if (err < 0) { |
| 1320 | printf("dpio_init() failed: %d\n", err); | 1327 | printf("dpio_init() failed: %d\n", err); |
| 1321 | goto err; | 1328 | goto err; |
| 1322 | } | 1329 | } |
| 1323 | 1330 | ||
| 1324 | err = dpni_init(); | 1331 | err = dpni_init(); |
| 1325 | if (err < 0) { | 1332 | if (err < 0) { |
| 1326 | printf("dpni_init() failed: %d\n", err); | 1333 | printf("dpni_init() failed: %d\n", err); |
| 1327 | goto err; | 1334 | goto err; |
| 1328 | } | 1335 | } |
| 1329 | 1336 | ||
| 1330 | return 0; | 1337 | return 0; |
| 1331 | err: | 1338 | err: |
| 1332 | return err; | 1339 | return err; |
| 1333 | } | 1340 | } |
| 1334 | 1341 | ||
| 1335 | int fsl_mc_ldpaa_exit(bd_t *bd) | 1342 | int fsl_mc_ldpaa_exit(bd_t *bd) |
| 1336 | { | 1343 | { |
| 1337 | int err = 0; | 1344 | int err = 0; |
| 1338 | bool is_dpl_apply_status = false; | 1345 | bool is_dpl_apply_status = false; |
| 1339 | bool mc_boot_status = false; | 1346 | bool mc_boot_status = false; |
| 1340 | 1347 | ||
| 1341 | if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { | 1348 | if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { |
| 1342 | mc_apply_dpl(mc_lazy_dpl_addr); | 1349 | mc_apply_dpl(mc_lazy_dpl_addr); |
| 1343 | mc_lazy_dpl_addr = 0; | 1350 | mc_lazy_dpl_addr = 0; |
| 1344 | } | 1351 | } |
| 1345 | 1352 | ||
| 1346 | if (!get_mc_boot_status()) | 1353 | if (!get_mc_boot_status()) |
| 1347 | mc_boot_status = true; | 1354 | mc_boot_status = true; |
| 1348 | 1355 | ||
| 1349 | /* MC is not loaded intentionally, So return success. */ | 1356 | /* MC is not loaded intentionally, So return success. */ |
| 1350 | if (bd && !mc_boot_status) | 1357 | if (bd && !mc_boot_status) |
| 1351 | return 0; | 1358 | return 0; |
| 1352 | 1359 | ||
| 1353 | /* If DPL is deployed, set is_dpl_apply_status as TRUE. */ | 1360 | /* If DPL is deployed, set is_dpl_apply_status as TRUE. */ |
| 1354 | if (!get_dpl_apply_status()) | 1361 | if (!get_dpl_apply_status()) |
| 1355 | is_dpl_apply_status = true; | 1362 | is_dpl_apply_status = true; |
| 1356 | 1363 | ||
| 1357 | /* | 1364 | /* |
| 1358 | * For case MC is loaded but DPL is not deployed, return success and | 1365 | * For case MC is loaded but DPL is not deployed, return success and |
| 1359 | * print message on console. Else FDT fix-up code execution hanged. | 1366 | * print message on console. Else FDT fix-up code execution hanged. |
| 1360 | */ | 1367 | */ |
| 1361 | if (bd && mc_boot_status && !is_dpl_apply_status) { | 1368 | if (bd && mc_boot_status && !is_dpl_apply_status) { |
| 1362 | printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n"); | 1369 | printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n"); |
| 1363 | return 0; | 1370 | return 0; |
| 1364 | } | 1371 | } |
| 1365 | 1372 | ||
| 1366 | if (bd && mc_boot_status && is_dpl_apply_status) | 1373 | if (bd && mc_boot_status && is_dpl_apply_status) |
| 1367 | return 0; | 1374 | return 0; |
| 1368 | 1375 | ||
| 1369 | err = dpbp_exit(); | 1376 | err = dpbp_exit(); |
| 1370 | if (err < 0) { | 1377 | if (err < 0) { |
| 1371 | printf("dpbp_exit() failed: %d\n", err); | 1378 | printf("dpbp_exit() failed: %d\n", err); |
| 1372 | goto err; | 1379 | goto err; |
| 1373 | } | 1380 | } |
| 1374 | 1381 | ||
| 1375 | err = dpio_exit(); | 1382 | err = dpio_exit(); |
| 1376 | if (err < 0) { | 1383 | if (err < 0) { |
| 1377 | printf("dpio_exit() failed: %d\n", err); | 1384 | printf("dpio_exit() failed: %d\n", err); |
| 1378 | goto err; | 1385 | goto err; |
| 1379 | } | 1386 | } |
| 1380 | 1387 | ||
| 1381 | err = dpni_exit(); | 1388 | err = dpni_exit(); |
| 1382 | if (err < 0) { | 1389 | if (err < 0) { |
| 1383 | printf("dpni_exit() failed: %d\n", err); | 1390 | printf("dpni_exit() failed: %d\n", err); |
| 1384 | goto err; | 1391 | goto err; |
| 1385 | } | 1392 | } |
| 1386 | 1393 | ||
| 1387 | err = dprc_exit(); | 1394 | err = dprc_exit(); |
| 1388 | if (err < 0) { | 1395 | if (err < 0) { |
| 1389 | printf("dprc_exit() failed: %d\n", err); | 1396 | printf("dprc_exit() failed: %d\n", err); |
| 1390 | goto err; | 1397 | goto err; |
| 1391 | } | 1398 | } |
| 1392 | 1399 | ||
| 1393 | return 0; | 1400 | return 0; |
| 1394 | err: | 1401 | err: |
| 1395 | return err; | 1402 | return err; |
| 1396 | } | 1403 | } |
| 1397 | 1404 | ||
| 1398 | static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 1405 | static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| 1399 | { | 1406 | { |
| 1400 | int err = 0; | 1407 | int err = 0; |
| 1401 | if (argc < 3) | 1408 | if (argc < 3) |
| 1402 | goto usage; | 1409 | goto usage; |
| 1403 | 1410 | ||
| 1404 | switch (argv[1][0]) { | 1411 | switch (argv[1][0]) { |
| 1405 | case 's': { | 1412 | case 's': { |
| 1406 | char sub_cmd; | 1413 | char sub_cmd; |
| 1407 | u64 mc_fw_addr, mc_dpc_addr; | 1414 | u64 mc_fw_addr, mc_dpc_addr; |
| 1408 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET | 1415 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET |
| 1409 | u64 aiop_fw_addr; | 1416 | u64 aiop_fw_addr; |
| 1410 | #endif | 1417 | #endif |
| 1411 | 1418 | ||
| 1412 | sub_cmd = argv[2][0]; | 1419 | sub_cmd = argv[2][0]; |
| 1413 | switch (sub_cmd) { | 1420 | switch (sub_cmd) { |
| 1414 | case 'm': | 1421 | case 'm': |
| 1415 | if (argc < 5) | 1422 | if (argc < 5) |
| 1416 | goto usage; | 1423 | goto usage; |
| 1417 | 1424 | ||
| 1418 | if (get_mc_boot_status() == 0) { | 1425 | if (get_mc_boot_status() == 0) { |
| 1419 | printf("fsl-mc: MC is already booted"); | 1426 | printf("fsl-mc: MC is already booted"); |
| 1420 | printf("\n"); | 1427 | printf("\n"); |
| 1421 | return err; | 1428 | return err; |
| 1422 | } | 1429 | } |
| 1423 | mc_fw_addr = simple_strtoull(argv[3], NULL, 16); | 1430 | mc_fw_addr = simple_strtoull(argv[3], NULL, 16); |
| 1424 | mc_dpc_addr = simple_strtoull(argv[4], NULL, | 1431 | mc_dpc_addr = simple_strtoull(argv[4], NULL, |
| 1425 | 16); | 1432 | 16); |
| 1426 | 1433 | ||
| 1427 | if (!mc_init(mc_fw_addr, mc_dpc_addr)) | 1434 | if (!mc_init(mc_fw_addr, mc_dpc_addr)) |
| 1428 | err = mc_init_object(); | 1435 | err = mc_init_object(); |
| 1429 | break; | 1436 | break; |
| 1430 | 1437 | ||
| 1431 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET | 1438 | #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET |
| 1432 | case 'a': | 1439 | case 'a': |
| 1433 | if (argc < 4) | 1440 | if (argc < 4) |
| 1434 | goto usage; | 1441 | goto usage; |
| 1435 | if (get_aiop_apply_status() == 0) { | 1442 | if (get_aiop_apply_status() == 0) { |
| 1436 | printf("fsl-mc: AIOP FW is already"); | 1443 | printf("fsl-mc: AIOP FW is already"); |
| 1437 | printf(" applied\n"); | 1444 | printf(" applied\n"); |
| 1438 | return err; | 1445 | return err; |
| 1439 | } | 1446 | } |
| 1440 | 1447 | ||
| 1441 | aiop_fw_addr = simple_strtoull(argv[3], NULL, | 1448 | aiop_fw_addr = simple_strtoull(argv[3], NULL, |
| 1442 | 16); | 1449 | 16); |
| 1443 | 1450 | ||
| 1444 | /* if SoC doesn't have AIOP, err = -ENODEV */ | 1451 | /* if SoC doesn't have AIOP, err = -ENODEV */ |
| 1445 | err = load_mc_aiop_img(aiop_fw_addr); | 1452 | err = load_mc_aiop_img(aiop_fw_addr); |
| 1446 | if (!err) | 1453 | if (!err) |
| 1447 | printf("fsl-mc: AIOP FW applied\n"); | 1454 | printf("fsl-mc: AIOP FW applied\n"); |
| 1448 | break; | 1455 | break; |
| 1449 | #endif | 1456 | #endif |
| 1450 | default: | 1457 | default: |
| 1451 | printf("Invalid option: %s\n", argv[2]); | 1458 | printf("Invalid option: %s\n", argv[2]); |
| 1452 | goto usage; | 1459 | goto usage; |
| 1453 | 1460 | ||
| 1454 | break; | 1461 | break; |
| 1455 | } | 1462 | } |
| 1456 | } | 1463 | } |
| 1457 | break; | 1464 | break; |
| 1458 | 1465 | ||
| 1459 | case 'l': | 1466 | case 'l': |
| 1460 | case 'a': { | 1467 | case 'a': { |
| 1461 | u64 mc_dpl_addr; | 1468 | u64 mc_dpl_addr; |
| 1462 | 1469 | ||
| 1463 | if (argc < 4) | 1470 | if (argc < 4) |
| 1464 | goto usage; | 1471 | goto usage; |
| 1465 | 1472 | ||
| 1466 | if (get_dpl_apply_status() == 0) { | 1473 | if (get_dpl_apply_status() == 0) { |
| 1467 | printf("fsl-mc: DPL already applied\n"); | 1474 | printf("fsl-mc: DPL already applied\n"); |
| 1468 | return err; | 1475 | return err; |
| 1469 | } | 1476 | } |
| 1470 | 1477 | ||
| 1471 | mc_dpl_addr = simple_strtoull(argv[3], NULL, | 1478 | mc_dpl_addr = simple_strtoull(argv[3], NULL, |
| 1472 | 16); | 1479 | 16); |
| 1473 | 1480 | ||
| 1474 | if (get_mc_boot_status() != 0) { | 1481 | if (get_mc_boot_status() != 0) { |
| 1475 | printf("fsl-mc: Deploying data path layout .."); | 1482 | printf("fsl-mc: Deploying data path layout .."); |
| 1476 | printf("ERROR (MC is not booted)\n"); | 1483 | printf("ERROR (MC is not booted)\n"); |
| 1477 | return -ENODEV; | 1484 | return -ENODEV; |
| 1478 | } | 1485 | } |
| 1479 | 1486 | ||
| 1480 | if (argv[1][0] == 'l') { | 1487 | if (argv[1][0] == 'l') { |
| 1481 | /* | 1488 | /* |
| 1482 | * We will do the actual dpaa exit and dpl apply | 1489 | * We will do the actual dpaa exit and dpl apply |
| 1483 | * later from announce_and_cleanup(). | 1490 | * later from announce_and_cleanup(). |
| 1484 | */ | 1491 | */ |
| 1485 | mc_lazy_dpl_addr = mc_dpl_addr; | 1492 | mc_lazy_dpl_addr = mc_dpl_addr; |
| 1486 | } else { | 1493 | } else { |
| 1487 | /* The user wants it applied now */ | 1494 | /* The user wants it applied now */ |
| 1488 | if (!fsl_mc_ldpaa_exit(NULL)) | 1495 | if (!fsl_mc_ldpaa_exit(NULL)) |
| 1489 | err = mc_apply_dpl(mc_dpl_addr); | 1496 | err = mc_apply_dpl(mc_dpl_addr); |
| 1490 | } | 1497 | } |
| 1491 | break; | 1498 | break; |
| 1492 | } | 1499 | } |
| 1493 | default: | 1500 | default: |
| 1494 | printf("Invalid option: %s\n", argv[1]); | 1501 | printf("Invalid option: %s\n", argv[1]); |
| 1495 | goto usage; | 1502 | goto usage; |
| 1496 | break; | 1503 | break; |
| 1497 | } | 1504 | } |
| 1498 | return err; | 1505 | return err; |
| 1499 | usage: | 1506 | usage: |
| 1500 | return CMD_RET_USAGE; | 1507 | return CMD_RET_USAGE; |
| 1501 | } | 1508 | } |
| 1502 | 1509 | ||
| 1503 | U_BOOT_CMD( | 1510 | U_BOOT_CMD( |
| 1504 | fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, | 1511 | fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, |
| 1505 | "DPAA2 command to manage Management Complex (MC)", | 1512 | "DPAA2 command to manage Management Complex (MC)", |
| 1506 | "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" | 1513 | "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" |
| 1507 | "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" | 1514 | "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" |
| 1508 | "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" | 1515 | "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" |
| 1509 | "fsl_mc start aiop [FW_addr] - Start AIOP\n" | 1516 | "fsl_mc start aiop [FW_addr] - Start AIOP\n" |
| 1510 | ); | 1517 | ); |
| 1511 | 1518 | ||
| 1512 | void mc_env_boot(void) | 1519 | void mc_env_boot(void) |
| 1513 | { | 1520 | { |
| 1514 | #if defined(CONFIG_FSL_MC_ENET) | 1521 | #if defined(CONFIG_FSL_MC_ENET) |
| 1515 | char *mc_boot_env_var; | 1522 | char *mc_boot_env_var; |
| 1516 | /* The MC may only be initialized in the reset PHY function | 1523 | /* The MC may only be initialized in the reset PHY function |
| 1517 | * because otherwise U-Boot has not yet set up all the MAC | 1524 | * because otherwise U-Boot has not yet set up all the MAC |
| 1518 | * address info properly. Without MAC addresses, the MC code | 1525 | * address info properly. Without MAC addresses, the MC code |
| 1519 | * can not properly initialize the DPC. | 1526 | * can not properly initialize the DPC. |
| 1520 | */ | 1527 | */ |
| 1521 | mc_boot_env_var = env_get(MC_BOOT_ENV_VAR); | 1528 | mc_boot_env_var = env_get(MC_BOOT_ENV_VAR); |
| 1522 | if (mc_boot_env_var) | 1529 | if (mc_boot_env_var) |
| 1523 | run_command_list(mc_boot_env_var, -1, 0); | 1530 | run_command_list(mc_boot_env_var, -1, 0); |
| 1524 | #endif /* CONFIG_FSL_MC_ENET */ | 1531 | #endif /* CONFIG_FSL_MC_ENET */ |
| 1525 | } | 1532 | } |
| 1526 | 1533 |