17b3bd9a7SJ. German Rivera /* 2*42e81790SYogesh Gaur * Copyright (C) 2017 NXP Semiconductors 37b3bd9a7SJ. German Rivera * Copyright (C) 2014 Freescale Semiconductor 47b3bd9a7SJ. German Rivera * 57b3bd9a7SJ. German Rivera * SPDX-License-Identifier: GPL-2.0+ 67b3bd9a7SJ. German Rivera */ 721c69870SStuart Yoder #include <common.h> 87b3bd9a7SJ. German Rivera #include <errno.h> 984b8bf6dSMasahiro Yamada #include <linux/bug.h> 107b3bd9a7SJ. German Rivera #include <asm/io.h> 1121c69870SStuart Yoder #include <libfdt.h> 125707dfb0SBogdan Purcareata #include <net.h> 1321c69870SStuart Yoder #include <fdt_support.h> 147b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc.h> 157b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc_sys.h> 16a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_mc_private.h> 177b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_dpmng.h> 18a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dprc.h> 19a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dpio.h> 20fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/fsl_dpni.h> 21a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_qbman_portal.h> 22fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h> 237b3bd9a7SJ. German Rivera 24125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) 25125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) 26125e2bc1SJ. German Rivera #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) 27125e2bc1SJ. German Rivera 28125e2bc1SJ. German Rivera #define MC_MEM_SIZE_ENV_VAR "mcmemsize" 29125e2bc1SJ. German Rivera #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" 30125e2bc1SJ. German Rivera 317b3bd9a7SJ. German Rivera DECLARE_GLOBAL_DATA_PTR; 32fb4a87a7SPrabhakar Kushwaha static int mc_boot_status = -1; 33fb4a87a7SPrabhakar Kushwaha static int mc_dpl_applied = -1; 34fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 35fb4a87a7SPrabhakar Kushwaha static int mc_aiop_applied = -1; 36fb4a87a7SPrabhakar Kushwaha #endif 371730a17dSPrabhakar Kushwaha struct fsl_mc_io *root_mc_io = NULL; 381730a17dSPrabhakar Kushwaha struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ 391730a17dSPrabhakar Kushwaha uint16_t root_dprc_handle = 0; 40a2a55e51SPrabhakar Kushwaha uint16_t dflt_dprc_handle = 0; 411730a17dSPrabhakar Kushwaha int child_dprc_id; 42a2a55e51SPrabhakar Kushwaha struct fsl_dpbp_obj *dflt_dpbp = NULL; 43a2a55e51SPrabhakar Kushwaha struct fsl_dpio_obj *dflt_dpio = NULL; 441730a17dSPrabhakar Kushwaha struct fsl_dpni_obj *dflt_dpni = NULL; 45b7b8410aSAlexander Graf static u64 mc_lazy_dpl_addr; 467b3bd9a7SJ. German Rivera 47125e2bc1SJ. German Rivera #ifdef DEBUG 48125e2bc1SJ. German Rivera void dump_ram_words(const char *title, void *addr) 49125e2bc1SJ. German Rivera { 50125e2bc1SJ. German Rivera int i; 51125e2bc1SJ. German Rivera uint32_t *words = addr; 52125e2bc1SJ. German Rivera 53125e2bc1SJ. German Rivera printf("Dumping beginning of %s (%p):\n", title, addr); 54125e2bc1SJ. German Rivera for (i = 0; i < 16; i++) 55125e2bc1SJ. German Rivera printf("%#x ", words[i]); 56125e2bc1SJ. German Rivera 57125e2bc1SJ. German Rivera printf("\n"); 58125e2bc1SJ. German Rivera } 59125e2bc1SJ. German Rivera 60125e2bc1SJ. German Rivera void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) 61125e2bc1SJ. German Rivera { 62125e2bc1SJ. German Rivera printf("MC CCSR registers:\n" 63125e2bc1SJ. German Rivera "reg_gcr1 %#x\n" 64125e2bc1SJ. German Rivera "reg_gsr %#x\n" 65125e2bc1SJ. German Rivera "reg_sicbalr %#x\n" 66125e2bc1SJ. German Rivera "reg_sicbahr %#x\n" 67125e2bc1SJ. German Rivera "reg_sicapr %#x\n" 68125e2bc1SJ. German Rivera "reg_mcfbalr %#x\n" 69125e2bc1SJ. German Rivera "reg_mcfbahr %#x\n" 70125e2bc1SJ. German Rivera "reg_mcfapr %#x\n" 71125e2bc1SJ. German Rivera "reg_psr %#x\n", 72125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gcr1, 73125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gsr, 74125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbalr, 75125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbahr, 76125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicapr, 77125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbalr, 78125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbahr, 79125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfapr, 80125e2bc1SJ. German Rivera mc_ccsr_regs->reg_psr); 81125e2bc1SJ. German Rivera } 82125e2bc1SJ. German Rivera #else 83125e2bc1SJ. German Rivera 84125e2bc1SJ. German Rivera #define dump_ram_words(title, addr) 85125e2bc1SJ. German Rivera #define dump_mc_ccsr_regs(mc_ccsr_regs) 86125e2bc1SJ. German Rivera 87125e2bc1SJ. German Rivera #endif /* DEBUG */ 88125e2bc1SJ. German Rivera 89125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 907b3bd9a7SJ. German Rivera /** 917b3bd9a7SJ. German Rivera * Copying MC firmware or DPL image to DDR 927b3bd9a7SJ. German Rivera */ 937b3bd9a7SJ. German Rivera static int mc_copy_image(const char *title, 947b3bd9a7SJ. German Rivera u64 image_addr, u32 image_size, u64 mc_ram_addr) 957b3bd9a7SJ. German Rivera { 967b3bd9a7SJ. German Rivera debug("%s copied to address %p\n", title, (void *)mc_ram_addr); 977b3bd9a7SJ. German Rivera memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); 98125e2bc1SJ. German Rivera flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); 997b3bd9a7SJ. German Rivera return 0; 1007b3bd9a7SJ. German Rivera } 1017b3bd9a7SJ. German Rivera 1027b3bd9a7SJ. German Rivera /** 1037b3bd9a7SJ. German Rivera * MC firmware FIT image parser checks if the image is in FIT 1047b3bd9a7SJ. German Rivera * format, verifies integrity of the image and calculates 1057b3bd9a7SJ. German Rivera * raw image address and size values. 1067b3bd9a7SJ. German Rivera * Returns 0 on success and a negative errno on error. 1077b3bd9a7SJ. German Rivera * task fail. 1087b3bd9a7SJ. German Rivera **/ 109fb4a87a7SPrabhakar Kushwaha int parse_mc_firmware_fit_image(u64 mc_fw_addr, 110fb4a87a7SPrabhakar Kushwaha const void **raw_image_addr, 1117b3bd9a7SJ. German Rivera size_t *raw_image_size) 1127b3bd9a7SJ. German Rivera { 1137b3bd9a7SJ. German Rivera int format; 1147b3bd9a7SJ. German Rivera void *fit_hdr; 1157b3bd9a7SJ. German Rivera int node_offset; 1167b3bd9a7SJ. German Rivera const void *data; 1177b3bd9a7SJ. German Rivera size_t size; 1187b3bd9a7SJ. German Rivera const char *uname = "firmware"; 1197b3bd9a7SJ. German Rivera 120fb4a87a7SPrabhakar Kushwaha fit_hdr = (void *)mc_fw_addr; 1217b3bd9a7SJ. German Rivera 1227b3bd9a7SJ. German Rivera /* Check if Image is in FIT format */ 1237b3bd9a7SJ. German Rivera format = genimg_get_format(fit_hdr); 1247b3bd9a7SJ. German Rivera 1257b3bd9a7SJ. German Rivera if (format != IMAGE_FORMAT_FIT) { 126fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); 1277b3bd9a7SJ. German Rivera return -EINVAL; 1287b3bd9a7SJ. German Rivera } 1297b3bd9a7SJ. German Rivera 1307b3bd9a7SJ. German Rivera if (!fit_check_format(fit_hdr)) { 131fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); 1327b3bd9a7SJ. German Rivera return -EINVAL; 1337b3bd9a7SJ. German Rivera } 1347b3bd9a7SJ. German Rivera 1357b3bd9a7SJ. German Rivera node_offset = fit_image_get_node(fit_hdr, uname); 1367b3bd9a7SJ. German Rivera 1377b3bd9a7SJ. German Rivera if (node_offset < 0) { 138fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); 1397b3bd9a7SJ. German Rivera return -ENOENT; 1407b3bd9a7SJ. German Rivera } 1417b3bd9a7SJ. German Rivera 1427b3bd9a7SJ. German Rivera /* Verify MC firmware image */ 1437b3bd9a7SJ. German Rivera if (!(fit_image_verify(fit_hdr, node_offset))) { 144fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); 1457b3bd9a7SJ. German Rivera return -EINVAL; 1467b3bd9a7SJ. German Rivera } 1477b3bd9a7SJ. German Rivera 1487b3bd9a7SJ. German Rivera /* Get address and size of raw image */ 1497b3bd9a7SJ. German Rivera fit_image_get_data(fit_hdr, node_offset, &data, &size); 1507b3bd9a7SJ. German Rivera 1517b3bd9a7SJ. German Rivera *raw_image_addr = data; 1527b3bd9a7SJ. German Rivera *raw_image_size = size; 1537b3bd9a7SJ. German Rivera 1547b3bd9a7SJ. German Rivera return 0; 1557b3bd9a7SJ. German Rivera } 156125e2bc1SJ. German Rivera #endif 157125e2bc1SJ. German Rivera 1585707dfb0SBogdan Purcareata static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id, 1595707dfb0SBogdan Purcareata struct eth_device *eth_dev) 1605707dfb0SBogdan Purcareata { 1615707dfb0SBogdan Purcareata int nodeoffset, err = 0; 1625707dfb0SBogdan Purcareata char mac_name[10]; 1635707dfb0SBogdan Purcareata const char link_type_mode[] = "FIXED_LINK"; 1645707dfb0SBogdan Purcareata unsigned char env_enetaddr[6]; 1655707dfb0SBogdan Purcareata 1665707dfb0SBogdan Purcareata sprintf(mac_name, "mac@%d", dpmac_id); 1675707dfb0SBogdan Purcareata 1685707dfb0SBogdan Purcareata /* node not found - create it */ 1695707dfb0SBogdan Purcareata nodeoffset = fdt_subnode_offset(blob, noff, (const char *) mac_name); 1705707dfb0SBogdan Purcareata if (nodeoffset < 0) { 1715707dfb0SBogdan Purcareata err = fdt_increase_size(blob, 200); 1725707dfb0SBogdan Purcareata if (err) { 1735707dfb0SBogdan Purcareata printf("fdt_increase_size: err=%s\n", 1745707dfb0SBogdan Purcareata fdt_strerror(err)); 1755707dfb0SBogdan Purcareata return err; 1765707dfb0SBogdan Purcareata } 1775707dfb0SBogdan Purcareata 1785707dfb0SBogdan Purcareata nodeoffset = fdt_add_subnode(blob, noff, mac_name); 1795707dfb0SBogdan Purcareata 1805707dfb0SBogdan Purcareata /* add default property of fixed link */ 1815707dfb0SBogdan Purcareata err = fdt_appendprop_string(blob, nodeoffset, 1825707dfb0SBogdan Purcareata "link_type", link_type_mode); 1835707dfb0SBogdan Purcareata if (err) { 1845707dfb0SBogdan Purcareata printf("fdt_appendprop_string: err=%s\n", 1855707dfb0SBogdan Purcareata fdt_strerror(err)); 1865707dfb0SBogdan Purcareata return err; 1875707dfb0SBogdan Purcareata } 1885707dfb0SBogdan Purcareata } 1895707dfb0SBogdan Purcareata 1905707dfb0SBogdan Purcareata /* port_mac_address property present in DPC */ 1915707dfb0SBogdan Purcareata if (fdt_get_property(blob, nodeoffset, "port_mac_address", NULL)) { 1925707dfb0SBogdan Purcareata /* MAC addr randomly assigned - leave the one in DPC */ 1935707dfb0SBogdan Purcareata eth_getenv_enetaddr_by_index("eth", eth_dev->index, 1945707dfb0SBogdan Purcareata env_enetaddr); 1955707dfb0SBogdan Purcareata if (is_zero_ethaddr(env_enetaddr)) 1965707dfb0SBogdan Purcareata return err; 1975707dfb0SBogdan Purcareata 1985707dfb0SBogdan Purcareata /* replace DPC MAC address with u-boot env one */ 1995707dfb0SBogdan Purcareata err = fdt_setprop(blob, nodeoffset, "port_mac_address", 2005707dfb0SBogdan Purcareata eth_dev->enetaddr, 6); 2015707dfb0SBogdan Purcareata if (err) { 2025707dfb0SBogdan Purcareata printf("fdt_setprop mac: err=%s\n", fdt_strerror(err)); 2035707dfb0SBogdan Purcareata return err; 2045707dfb0SBogdan Purcareata } 2055707dfb0SBogdan Purcareata 2065707dfb0SBogdan Purcareata return 0; 2075707dfb0SBogdan Purcareata } 2085707dfb0SBogdan Purcareata 2095707dfb0SBogdan Purcareata /* append port_mac_address property to mac node in DPC */ 2105707dfb0SBogdan Purcareata err = fdt_increase_size(blob, 80); 2115707dfb0SBogdan Purcareata if (err) { 2125707dfb0SBogdan Purcareata printf("fdt_increase_size: err=%s\n", fdt_strerror(err)); 2135707dfb0SBogdan Purcareata return err; 2145707dfb0SBogdan Purcareata } 2155707dfb0SBogdan Purcareata 2165707dfb0SBogdan Purcareata err = fdt_appendprop(blob, nodeoffset, 2175707dfb0SBogdan Purcareata "port_mac_address", eth_dev->enetaddr, 6); 2185707dfb0SBogdan Purcareata if (err) { 2195707dfb0SBogdan Purcareata printf("fdt_appendprop: err=%s\n", fdt_strerror(err)); 2205707dfb0SBogdan Purcareata return err; 2215707dfb0SBogdan Purcareata } 2225707dfb0SBogdan Purcareata 2235707dfb0SBogdan Purcareata return err; 2245707dfb0SBogdan Purcareata } 2255707dfb0SBogdan Purcareata 22621c69870SStuart Yoder static int mc_fixup_dpc(u64 dpc_addr) 22721c69870SStuart Yoder { 22821c69870SStuart Yoder void *blob = (void *)dpc_addr; 2295707dfb0SBogdan Purcareata int nodeoffset, err = 0; 2305707dfb0SBogdan Purcareata char ethname[10]; 2315707dfb0SBogdan Purcareata struct eth_device *eth_dev; 2325707dfb0SBogdan Purcareata int i; 23321c69870SStuart Yoder 23421c69870SStuart Yoder /* delete any existing ICID pools */ 23521c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); 23621c69870SStuart Yoder if (fdt_del_node(blob, nodeoffset) < 0) 23721c69870SStuart Yoder printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); 23821c69870SStuart Yoder 23921c69870SStuart Yoder /* add a new pool */ 24021c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources"); 24121c69870SStuart Yoder if (nodeoffset < 0) { 24221c69870SStuart Yoder printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); 24321c69870SStuart Yoder return -EINVAL; 24421c69870SStuart Yoder } 24521c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); 24621c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); 24721c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 24821c69870SStuart Yoder "base_icid", FSL_DPAA2_STREAM_ID_START, 1); 24921c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 25021c69870SStuart Yoder "num", 25121c69870SStuart Yoder FSL_DPAA2_STREAM_ID_END - 25221c69870SStuart Yoder FSL_DPAA2_STREAM_ID_START + 1, 1); 25321c69870SStuart Yoder 2545707dfb0SBogdan Purcareata /* fixup MAC addresses for dpmac ports */ 2555707dfb0SBogdan Purcareata nodeoffset = fdt_path_offset(blob, "/board_info/ports"); 2565707dfb0SBogdan Purcareata if (nodeoffset < 0) 2575707dfb0SBogdan Purcareata goto out; 2585707dfb0SBogdan Purcareata 2595707dfb0SBogdan Purcareata for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { 2605707dfb0SBogdan Purcareata /* port not enabled */ 2615707dfb0SBogdan Purcareata if ((wriop_is_enabled_dpmac(i) != 1) || 2625707dfb0SBogdan Purcareata (wriop_get_phy_address(i) == -1)) 2635707dfb0SBogdan Purcareata continue; 2645707dfb0SBogdan Purcareata 2655707dfb0SBogdan Purcareata sprintf(ethname, "DPMAC%d@%s", i, 2665707dfb0SBogdan Purcareata phy_interface_strings[wriop_get_enet_if(i)]); 2675707dfb0SBogdan Purcareata 2685707dfb0SBogdan Purcareata eth_dev = eth_get_dev_by_name(ethname); 2695707dfb0SBogdan Purcareata if (eth_dev == NULL) 2705707dfb0SBogdan Purcareata continue; 2715707dfb0SBogdan Purcareata 2725707dfb0SBogdan Purcareata err = mc_fixup_dpc_mac_addr(blob, nodeoffset, i, eth_dev); 2735707dfb0SBogdan Purcareata if (err) { 2745707dfb0SBogdan Purcareata printf("mc_fixup_dpc_mac_addr failed: err=%s\n", 2755707dfb0SBogdan Purcareata fdt_strerror(err)); 2765707dfb0SBogdan Purcareata goto out; 2775707dfb0SBogdan Purcareata } 2785707dfb0SBogdan Purcareata } 2795707dfb0SBogdan Purcareata 2805707dfb0SBogdan Purcareata out: 28121c69870SStuart Yoder flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); 28221c69870SStuart Yoder 2835707dfb0SBogdan Purcareata return err; 28421c69870SStuart Yoder } 28521c69870SStuart Yoder 286fb4a87a7SPrabhakar Kushwaha static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) 287125e2bc1SJ. German Rivera { 288125e2bc1SJ. German Rivera u64 mc_dpc_offset; 289125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 290125e2bc1SJ. German Rivera int error; 291125e2bc1SJ. German Rivera void *dpc_fdt_hdr; 292125e2bc1SJ. German Rivera int dpc_size; 293125e2bc1SJ. German Rivera #endif 294125e2bc1SJ. German Rivera 295125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 296125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || 297125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); 298125e2bc1SJ. German Rivera 299125e2bc1SJ. German Rivera mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; 300125e2bc1SJ. German Rivera #else 301125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" 302125e2bc1SJ. German Rivera #endif 303125e2bc1SJ. German Rivera 304125e2bc1SJ. German Rivera /* 305125e2bc1SJ. German Rivera * Load the MC DPC blob in the MC private DRAM block: 306125e2bc1SJ. German Rivera */ 307125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 308125e2bc1SJ. German Rivera printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); 309125e2bc1SJ. German Rivera #else 310125e2bc1SJ. German Rivera /* 311125e2bc1SJ. German Rivera * Get address and size of the DPC blob stored in flash: 312125e2bc1SJ. German Rivera */ 313fb4a87a7SPrabhakar Kushwaha dpc_fdt_hdr = (void *)mc_dpc_addr; 314125e2bc1SJ. German Rivera 315125e2bc1SJ. German Rivera error = fdt_check_header(dpc_fdt_hdr); 316125e2bc1SJ. German Rivera if (error != 0) { 317125e2bc1SJ. German Rivera /* 318125e2bc1SJ. German Rivera * Don't return with error here, since the MC firmware can 319125e2bc1SJ. German Rivera * still boot without a DPC 320125e2bc1SJ. German Rivera */ 321cc088c3aSJ. German Rivera printf("\nfsl-mc: WARNING: No DPC image found"); 322125e2bc1SJ. German Rivera return 0; 323125e2bc1SJ. German Rivera } 324125e2bc1SJ. German Rivera 325125e2bc1SJ. German Rivera dpc_size = fdt_totalsize(dpc_fdt_hdr); 326125e2bc1SJ. German Rivera if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { 327cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", 328125e2bc1SJ. German Rivera dpc_size); 329125e2bc1SJ. German Rivera return -EINVAL; 330125e2bc1SJ. German Rivera } 331125e2bc1SJ. German Rivera 332125e2bc1SJ. German Rivera mc_copy_image("MC DPC blob", 333125e2bc1SJ. German Rivera (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); 334125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ 335125e2bc1SJ. German Rivera 33621c69870SStuart Yoder if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) 33721c69870SStuart Yoder return -EINVAL; 33821c69870SStuart Yoder 339125e2bc1SJ. German Rivera dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); 340125e2bc1SJ. German Rivera return 0; 341125e2bc1SJ. German Rivera } 342125e2bc1SJ. German Rivera 343fb4a87a7SPrabhakar Kushwaha static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) 344125e2bc1SJ. German Rivera { 345125e2bc1SJ. German Rivera u64 mc_dpl_offset; 346125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR 347125e2bc1SJ. German Rivera int error; 348125e2bc1SJ. German Rivera void *dpl_fdt_hdr; 349125e2bc1SJ. German Rivera int dpl_size; 350125e2bc1SJ. German Rivera #endif 351125e2bc1SJ. German Rivera 352125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 353125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || 354125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); 355125e2bc1SJ. German Rivera 356125e2bc1SJ. German Rivera mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; 357125e2bc1SJ. German Rivera #else 358125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" 359125e2bc1SJ. German Rivera #endif 360125e2bc1SJ. German Rivera 361125e2bc1SJ. German Rivera /* 362125e2bc1SJ. German Rivera * Load the MC DPL blob in the MC private DRAM block: 363125e2bc1SJ. German Rivera */ 364125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR 365125e2bc1SJ. German Rivera printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); 366125e2bc1SJ. German Rivera #else 367125e2bc1SJ. German Rivera /* 368125e2bc1SJ. German Rivera * Get address and size of the DPL blob stored in flash: 369125e2bc1SJ. German Rivera */ 370fb4a87a7SPrabhakar Kushwaha dpl_fdt_hdr = (void *)mc_dpl_addr; 371125e2bc1SJ. German Rivera 372125e2bc1SJ. German Rivera error = fdt_check_header(dpl_fdt_hdr); 373125e2bc1SJ. German Rivera if (error != 0) { 374cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); 375125e2bc1SJ. German Rivera return error; 376125e2bc1SJ. German Rivera } 377125e2bc1SJ. German Rivera 378125e2bc1SJ. German Rivera dpl_size = fdt_totalsize(dpl_fdt_hdr); 379125e2bc1SJ. German Rivera if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { 380cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", 381125e2bc1SJ. German Rivera dpl_size); 382125e2bc1SJ. German Rivera return -EINVAL; 383125e2bc1SJ. German Rivera } 384125e2bc1SJ. German Rivera 385125e2bc1SJ. German Rivera mc_copy_image("MC DPL blob", 386125e2bc1SJ. German Rivera (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); 387125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ 388125e2bc1SJ. German Rivera 389125e2bc1SJ. German Rivera dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); 390125e2bc1SJ. German Rivera return 0; 391125e2bc1SJ. German Rivera } 392125e2bc1SJ. German Rivera 393125e2bc1SJ. German Rivera /** 394125e2bc1SJ. German Rivera * Return the MC boot timeout value in milliseconds 395125e2bc1SJ. German Rivera */ 396125e2bc1SJ. German Rivera static unsigned long get_mc_boot_timeout_ms(void) 397125e2bc1SJ. German Rivera { 398125e2bc1SJ. German Rivera unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 399125e2bc1SJ. German Rivera 400125e2bc1SJ. German Rivera char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR); 401125e2bc1SJ. German Rivera 402125e2bc1SJ. German Rivera if (timeout_ms_env_var) { 403125e2bc1SJ. German Rivera timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); 404125e2bc1SJ. German Rivera if (timeout_ms == 0) { 405125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 406125e2bc1SJ. German Rivera MC_BOOT_TIMEOUT_ENV_VAR 407125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 408125e2bc1SJ. German Rivera timeout_ms); 409125e2bc1SJ. German Rivera 410125e2bc1SJ. German Rivera timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 411125e2bc1SJ. German Rivera } 412125e2bc1SJ. German Rivera } 413125e2bc1SJ. German Rivera 414125e2bc1SJ. German Rivera return timeout_ms; 415125e2bc1SJ. German Rivera } 416125e2bc1SJ. German Rivera 417fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 4183c1d218aSYork Sun 4193c1d218aSYork Sun __weak bool soc_has_aiop(void) 4203c1d218aSYork Sun { 4213c1d218aSYork Sun return false; 4223c1d218aSYork Sun } 4233c1d218aSYork Sun 424fb4a87a7SPrabhakar Kushwaha static int load_mc_aiop_img(u64 aiop_fw_addr) 425c1000c12SJ. German Rivera { 426fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 427fb4a87a7SPrabhakar Kushwaha #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 428c1000c12SJ. German Rivera void *aiop_img; 429fb4a87a7SPrabhakar Kushwaha #endif 430c1000c12SJ. German Rivera 4313c1d218aSYork Sun /* Check if AIOP is available */ 4323c1d218aSYork Sun if (!soc_has_aiop()) 4333c1d218aSYork Sun return -ENODEV; 434c1000c12SJ. German Rivera /* 435c1000c12SJ. German Rivera * Load the MC AIOP image in the MC private DRAM block: 436c1000c12SJ. German Rivera */ 437c1000c12SJ. German Rivera 438fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 439fb4a87a7SPrabhakar Kushwaha printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr + 440fb4a87a7SPrabhakar Kushwaha CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 441fb4a87a7SPrabhakar Kushwaha #else 442fb4a87a7SPrabhakar Kushwaha aiop_img = (void *)aiop_fw_addr; 443c1000c12SJ. German Rivera mc_copy_image("MC AIOP image", 444c1000c12SJ. German Rivera (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, 445c1000c12SJ. German Rivera mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 446fb4a87a7SPrabhakar Kushwaha #endif 447fb4a87a7SPrabhakar Kushwaha mc_aiop_applied = 0; 448c1000c12SJ. German Rivera 449c1000c12SJ. German Rivera return 0; 450c1000c12SJ. German Rivera } 451c1000c12SJ. German Rivera #endif 452fb4a87a7SPrabhakar Kushwaha 453125e2bc1SJ. German Rivera static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) 454125e2bc1SJ. German Rivera { 455125e2bc1SJ. German Rivera u32 reg_gsr; 456125e2bc1SJ. German Rivera u32 mc_fw_boot_status; 457125e2bc1SJ. German Rivera unsigned long timeout_ms = get_mc_boot_timeout_ms(); 458125e2bc1SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 459125e2bc1SJ. German Rivera 460125e2bc1SJ. German Rivera dmb(); 461125e2bc1SJ. German Rivera assert(timeout_ms > 0); 462125e2bc1SJ. German Rivera for (;;) { 463125e2bc1SJ. German Rivera udelay(1000); /* throttle polling */ 464125e2bc1SJ. German Rivera reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); 465125e2bc1SJ. German Rivera mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); 466125e2bc1SJ. German Rivera if (mc_fw_boot_status & 0x1) 467125e2bc1SJ. German Rivera break; 468125e2bc1SJ. German Rivera 469125e2bc1SJ. German Rivera timeout_ms--; 470125e2bc1SJ. German Rivera if (timeout_ms == 0) 471125e2bc1SJ. German Rivera break; 472125e2bc1SJ. German Rivera } 473125e2bc1SJ. German Rivera 474125e2bc1SJ. German Rivera if (timeout_ms == 0) { 475cc088c3aSJ. German Rivera printf("ERROR: timeout\n"); 476125e2bc1SJ. German Rivera 477125e2bc1SJ. German Rivera /* TODO: Get an error status from an MC CCSR register */ 478125e2bc1SJ. German Rivera return -ETIMEDOUT; 479125e2bc1SJ. German Rivera } 480125e2bc1SJ. German Rivera 481125e2bc1SJ. German Rivera if (mc_fw_boot_status != 0x1) { 482125e2bc1SJ. German Rivera /* 483125e2bc1SJ. German Rivera * TODO: Identify critical errors from the GSR register's FS 484125e2bc1SJ. German Rivera * field and for those errors, set error to -ENODEV or other 485125e2bc1SJ. German Rivera * appropriate errno, so that the status property is set to 486125e2bc1SJ. German Rivera * failure in the fsl,dprc device tree node. 487125e2bc1SJ. German Rivera */ 488cc088c3aSJ. German Rivera printf("WARNING: Firmware returned an error (GSR: %#x)\n", 489125e2bc1SJ. German Rivera reg_gsr); 490125e2bc1SJ. German Rivera } else { 491cc088c3aSJ. German Rivera printf("SUCCESS\n"); 492125e2bc1SJ. German Rivera } 493cc088c3aSJ. German Rivera 494125e2bc1SJ. German Rivera 495125e2bc1SJ. German Rivera *final_reg_gsr = reg_gsr; 496125e2bc1SJ. German Rivera return 0; 497125e2bc1SJ. German Rivera } 4987b3bd9a7SJ. German Rivera 499fb4a87a7SPrabhakar Kushwaha int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) 5007b3bd9a7SJ. German Rivera { 5017b3bd9a7SJ. German Rivera int error = 0; 502a2a55e51SPrabhakar Kushwaha int portal_id = 0; 5037b3bd9a7SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 504fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 5057b3bd9a7SJ. German Rivera u32 reg_gsr; 506125e2bc1SJ. German Rivera u32 reg_mcfbalr; 507125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 5087b3bd9a7SJ. German Rivera const void *raw_image_addr; 5097b3bd9a7SJ. German Rivera size_t raw_image_size = 0; 510125e2bc1SJ. German Rivera #endif 5117b3bd9a7SJ. German Rivera struct mc_version mc_ver_info; 512125e2bc1SJ. German Rivera u8 mc_ram_num_256mb_blocks; 513125e2bc1SJ. German Rivera size_t mc_ram_size = mc_get_dram_block_size(); 5147b3bd9a7SJ. German Rivera 515437858b6SYork Sun mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; 516437858b6SYork Sun if (mc_ram_num_256mb_blocks < 1 || mc_ram_num_256mb_blocks > 0xff) { 517437858b6SYork Sun error = -EINVAL; 518437858b6SYork Sun printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 519437858b6SYork Sun mc_ram_size); 520125e2bc1SJ. German Rivera goto out; 521437858b6SYork Sun } 522125e2bc1SJ. German Rivera 5237b3bd9a7SJ. German Rivera /* 5247b3bd9a7SJ. German Rivera * Management Complex cores should be held at reset out of POR. 525a187559eSBin Meng * U-Boot should be the first software to touch MC. To be safe, 5267b3bd9a7SJ. German Rivera * we reset all cores again by setting GCR1 to 0. It doesn't do 5277b3bd9a7SJ. German Rivera * anything if they are held at reset. After we setup the firmware 5287b3bd9a7SJ. German Rivera * we kick off MC by deasserting the reset bit for core 0, and 5297b3bd9a7SJ. German Rivera * deasserting the reset bits for Command Portal Managers. 5307b3bd9a7SJ. German Rivera * The stop bits are not touched here. They are used to stop the 5317b3bd9a7SJ. German Rivera * cores when they are active. Setting stop bits doesn't stop the 5327b3bd9a7SJ. German Rivera * cores from fetching instructions when they are released from 5337b3bd9a7SJ. German Rivera * reset. 5347b3bd9a7SJ. German Rivera */ 5357b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, 0); 5367b3bd9a7SJ. German Rivera dmb(); 5377b3bd9a7SJ. German Rivera 538125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR 539125e2bc1SJ. German Rivera printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); 540125e2bc1SJ. German Rivera #else 541fb4a87a7SPrabhakar Kushwaha error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr, 542fb4a87a7SPrabhakar Kushwaha &raw_image_size); 5437b3bd9a7SJ. German Rivera if (error != 0) 5447b3bd9a7SJ. German Rivera goto out; 5457b3bd9a7SJ. German Rivera /* 5467b3bd9a7SJ. German Rivera * Load the MC FW at the beginning of the MC private DRAM block: 5477b3bd9a7SJ. German Rivera */ 5487b3bd9a7SJ. German Rivera mc_copy_image("MC Firmware", 5497b3bd9a7SJ. German Rivera (u64)raw_image_addr, raw_image_size, mc_ram_addr); 5507b3bd9a7SJ. German Rivera #endif 551125e2bc1SJ. German Rivera dump_ram_words("firmware", (void *)mc_ram_addr); 5527b3bd9a7SJ. German Rivera 553fb4a87a7SPrabhakar Kushwaha error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr); 554125e2bc1SJ. German Rivera if (error != 0) 5557b3bd9a7SJ. German Rivera goto out; 5567b3bd9a7SJ. German Rivera 5577b3bd9a7SJ. German Rivera debug("mc_ccsr_regs %p\n", mc_ccsr_regs); 558125e2bc1SJ. German Rivera dump_mc_ccsr_regs(mc_ccsr_regs); 5597b3bd9a7SJ. German Rivera 5607b3bd9a7SJ. German Rivera /* 561125e2bc1SJ. German Rivera * Tell MC what is the address range of the DRAM block assigned to it: 5627b3bd9a7SJ. German Rivera */ 563437858b6SYork Sun reg_mcfbalr = (u32)mc_ram_addr | 564125e2bc1SJ. German Rivera (mc_ram_num_256mb_blocks - 1); 565125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); 566125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbahr, 567437858b6SYork Sun (u32)(mc_ram_addr >> 32)); 56839da644eSStuart Yoder out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); 5697b3bd9a7SJ. German Rivera 5707b3bd9a7SJ. German Rivera /* 571125e2bc1SJ. German Rivera * Tell the MC that we want delayed DPL deployment. 5727b3bd9a7SJ. German Rivera */ 573125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); 5747b3bd9a7SJ. German Rivera 575cc088c3aSJ. German Rivera printf("\nfsl-mc: Booting Management Complex ... "); 5767b3bd9a7SJ. German Rivera 5777b3bd9a7SJ. German Rivera /* 5787b3bd9a7SJ. German Rivera * Deassert reset and release MC core 0 to run 5797b3bd9a7SJ. German Rivera */ 5807b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); 581125e2bc1SJ. German Rivera error = wait_for_mc(true, ®_gsr); 582125e2bc1SJ. German Rivera if (error != 0) 5837b3bd9a7SJ. German Rivera goto out; 5847b3bd9a7SJ. German Rivera 5857b3bd9a7SJ. German Rivera /* 5867b3bd9a7SJ. German Rivera * TODO: need to obtain the portal_id for the root container from the 5877b3bd9a7SJ. German Rivera * DPL 5887b3bd9a7SJ. German Rivera */ 5897b3bd9a7SJ. German Rivera portal_id = 0; 5907b3bd9a7SJ. German Rivera 5917b3bd9a7SJ. German Rivera /* 592a2a55e51SPrabhakar Kushwaha * Initialize the global default MC portal 593a2a55e51SPrabhakar Kushwaha * And check that the MC firmware is responding portal commands: 5947b3bd9a7SJ. German Rivera */ 5951730a17dSPrabhakar Kushwaha root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 5961730a17dSPrabhakar Kushwaha if (!root_mc_io) { 597a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 598a2a55e51SPrabhakar Kushwaha return -ENOMEM; 599a2a55e51SPrabhakar Kushwaha } 6007b3bd9a7SJ. German Rivera 6011730a17dSPrabhakar Kushwaha root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); 602a2a55e51SPrabhakar Kushwaha debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", 6031730a17dSPrabhakar Kushwaha portal_id, root_mc_io->mmio_regs); 604a2a55e51SPrabhakar Kushwaha 6051730a17dSPrabhakar Kushwaha error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); 6067b3bd9a7SJ. German Rivera if (error != 0) { 6077b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", 6087b3bd9a7SJ. German Rivera error); 6097b3bd9a7SJ. German Rivera goto out; 6107b3bd9a7SJ. German Rivera } 6117b3bd9a7SJ. German Rivera 6127b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 6137b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 614125e2bc1SJ. German Rivera reg_gsr & GSR_FS_MASK); 615125e2bc1SJ. German Rivera 6167b3bd9a7SJ. German Rivera out: 6177b3bd9a7SJ. German Rivera if (error != 0) 6182b7c4a19SPrabhakar Kushwaha mc_boot_status = error; 6197b3bd9a7SJ. German Rivera else 6207b3bd9a7SJ. German Rivera mc_boot_status = 0; 6217b3bd9a7SJ. German Rivera 6227b3bd9a7SJ. German Rivera return error; 6237b3bd9a7SJ. German Rivera } 6247b3bd9a7SJ. German Rivera 625fb4a87a7SPrabhakar Kushwaha int mc_apply_dpl(u64 mc_dpl_addr) 626fb4a87a7SPrabhakar Kushwaha { 627fb4a87a7SPrabhakar Kushwaha struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 628fb4a87a7SPrabhakar Kushwaha int error = 0; 629fb4a87a7SPrabhakar Kushwaha u32 reg_gsr; 630fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 631fb4a87a7SPrabhakar Kushwaha size_t mc_ram_size = mc_get_dram_block_size(); 632fb4a87a7SPrabhakar Kushwaha 633b7b8410aSAlexander Graf if (!mc_dpl_addr) 634b7b8410aSAlexander Graf return -1; 635b7b8410aSAlexander Graf 636fb4a87a7SPrabhakar Kushwaha error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); 637fb4a87a7SPrabhakar Kushwaha if (error != 0) 638fb4a87a7SPrabhakar Kushwaha return error; 639fb4a87a7SPrabhakar Kushwaha 640fb4a87a7SPrabhakar Kushwaha /* 641fb4a87a7SPrabhakar Kushwaha * Tell the MC to deploy the DPL: 642fb4a87a7SPrabhakar Kushwaha */ 643fb4a87a7SPrabhakar Kushwaha out_le32(&mc_ccsr_regs->reg_gsr, 0x0); 644fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout ... "); 645fb4a87a7SPrabhakar Kushwaha error = wait_for_mc(false, ®_gsr); 646fb4a87a7SPrabhakar Kushwaha 647fb4a87a7SPrabhakar Kushwaha if (!error) 648fb4a87a7SPrabhakar Kushwaha mc_dpl_applied = 0; 649fb4a87a7SPrabhakar Kushwaha 650fb4a87a7SPrabhakar Kushwaha return error; 651fb4a87a7SPrabhakar Kushwaha } 652fb4a87a7SPrabhakar Kushwaha 6537b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 6547b3bd9a7SJ. German Rivera { 6557b3bd9a7SJ. German Rivera return mc_boot_status; 6567b3bd9a7SJ. German Rivera } 6577b3bd9a7SJ. German Rivera 658fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 659fb4a87a7SPrabhakar Kushwaha int get_aiop_apply_status(void) 660fb4a87a7SPrabhakar Kushwaha { 661fb4a87a7SPrabhakar Kushwaha return mc_aiop_applied; 662fb4a87a7SPrabhakar Kushwaha } 663fb4a87a7SPrabhakar Kushwaha #endif 664fb4a87a7SPrabhakar Kushwaha 665fb4a87a7SPrabhakar Kushwaha int get_dpl_apply_status(void) 666fb4a87a7SPrabhakar Kushwaha { 667fb4a87a7SPrabhakar Kushwaha return mc_dpl_applied; 668fb4a87a7SPrabhakar Kushwaha } 669fb4a87a7SPrabhakar Kushwaha 670fb4a87a7SPrabhakar Kushwaha /** 671fb4a87a7SPrabhakar Kushwaha * Return the MC address of private DRAM block. 672fb4a87a7SPrabhakar Kushwaha */ 673fb4a87a7SPrabhakar Kushwaha u64 mc_get_dram_addr(void) 674fb4a87a7SPrabhakar Kushwaha { 67536cc0de0SYork Sun return gd->arch.resv_ram; 676fb4a87a7SPrabhakar Kushwaha } 677fb4a87a7SPrabhakar Kushwaha 6787b3bd9a7SJ. German Rivera /** 6797b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 6807b3bd9a7SJ. German Rivera */ 6817b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 6827b3bd9a7SJ. German Rivera { 683125e2bc1SJ. German Rivera unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 684125e2bc1SJ. German Rivera 685125e2bc1SJ. German Rivera char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); 686125e2bc1SJ. German Rivera 687125e2bc1SJ. German Rivera if (dram_block_size_env_var) { 688125e2bc1SJ. German Rivera dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, 689125e2bc1SJ. German Rivera 10); 690125e2bc1SJ. German Rivera 691125e2bc1SJ. German Rivera if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { 692125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 693125e2bc1SJ. German Rivera MC_MEM_SIZE_ENV_VAR 694125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 695125e2bc1SJ. German Rivera dram_block_size); 696125e2bc1SJ. German Rivera 697125e2bc1SJ. German Rivera dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 698125e2bc1SJ. German Rivera } 699125e2bc1SJ. German Rivera } 700125e2bc1SJ. German Rivera 701125e2bc1SJ. German Rivera return dram_block_size; 7027b3bd9a7SJ. German Rivera } 703a2a55e51SPrabhakar Kushwaha 7041730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 7051730a17dSPrabhakar Kushwaha { 706c919ab9eSPrabhakar Kushwaha int i; 707c919ab9eSPrabhakar Kushwaha 708c919ab9eSPrabhakar Kushwaha for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) 709c919ab9eSPrabhakar Kushwaha if ((wriop_is_enabled_dpmac(i) == 1) && 710c919ab9eSPrabhakar Kushwaha (wriop_get_phy_address(i) != -1)) 711c919ab9eSPrabhakar Kushwaha ldpaa_eth_init(i, wriop_get_enet_if(i)); 7121730a17dSPrabhakar Kushwaha return 0; 7131730a17dSPrabhakar Kushwaha } 7141730a17dSPrabhakar Kushwaha 7159a696f56SPrabhakar Kushwaha static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle) 7169a696f56SPrabhakar Kushwaha { 7179a696f56SPrabhakar Kushwaha struct dprc_attributes attr; 7189a696f56SPrabhakar Kushwaha int error; 7199a696f56SPrabhakar Kushwaha 7209a696f56SPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dprc_attributes)); 7219a696f56SPrabhakar Kushwaha error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr); 7229a696f56SPrabhakar Kushwaha if (error == 0) { 7239a696f56SPrabhakar Kushwaha if ((attr.version.major != DPRC_VER_MAJOR) || 7249a696f56SPrabhakar Kushwaha (attr.version.minor != DPRC_VER_MINOR)) { 7259a696f56SPrabhakar Kushwaha printf("DPRC version mismatch found %u.%u,", 7269a696f56SPrabhakar Kushwaha attr.version.major, 7279a696f56SPrabhakar Kushwaha attr.version.minor); 7289a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 7299a696f56SPrabhakar Kushwaha DPRC_VER_MAJOR, DPRC_VER_MINOR); 7309a696f56SPrabhakar Kushwaha } 7319a696f56SPrabhakar Kushwaha } 7329a696f56SPrabhakar Kushwaha return error; 7339a696f56SPrabhakar Kushwaha } 7349a696f56SPrabhakar Kushwaha 7351730a17dSPrabhakar Kushwaha static int dpio_init(void) 736a2a55e51SPrabhakar Kushwaha { 737a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 738a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 7391730a17dSPrabhakar Kushwaha struct dpio_cfg dpio_cfg; 740a2a55e51SPrabhakar Kushwaha int err = 0; 741a2a55e51SPrabhakar Kushwaha 742a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 743a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 744a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 7451730a17dSPrabhakar Kushwaha err = -ENOMEM; 7461730a17dSPrabhakar Kushwaha goto err_malloc; 747a2a55e51SPrabhakar Kushwaha } 748a2a55e51SPrabhakar Kushwaha 7491730a17dSPrabhakar Kushwaha dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; 7501730a17dSPrabhakar Kushwaha dpio_cfg.num_priorities = 8; 751a2a55e51SPrabhakar Kushwaha 7521730a17dSPrabhakar Kushwaha err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, 7531730a17dSPrabhakar Kushwaha &dflt_dpio->dpio_handle); 7541730a17dSPrabhakar Kushwaha if (err < 0) { 7551730a17dSPrabhakar Kushwaha printf("dpio_create() failed: %d\n", err); 7561730a17dSPrabhakar Kushwaha err = -ENODEV; 7571730a17dSPrabhakar Kushwaha goto err_create; 758a2a55e51SPrabhakar Kushwaha } 759a2a55e51SPrabhakar Kushwaha 7601730a17dSPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dpio_attr)); 76187457d11SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 7621730a17dSPrabhakar Kushwaha dflt_dpio->dpio_handle, &attr); 7631730a17dSPrabhakar Kushwaha if (err < 0) { 7641730a17dSPrabhakar Kushwaha printf("dpio_get_attributes() failed: %d\n", err); 765a2a55e51SPrabhakar Kushwaha goto err_get_attr; 766a2a55e51SPrabhakar Kushwaha } 767a2a55e51SPrabhakar Kushwaha 7689a696f56SPrabhakar Kushwaha if ((attr.version.major != DPIO_VER_MAJOR) || 7699a696f56SPrabhakar Kushwaha (attr.version.minor != DPIO_VER_MINOR)) { 7709a696f56SPrabhakar Kushwaha printf("DPIO version mismatch found %u.%u,", 7719a696f56SPrabhakar Kushwaha attr.version.major, attr.version.minor); 7729a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 7739a696f56SPrabhakar Kushwaha DPIO_VER_MAJOR, DPIO_VER_MINOR); 7749a696f56SPrabhakar Kushwaha } 7759a696f56SPrabhakar Kushwaha 7761730a17dSPrabhakar Kushwaha dflt_dpio->dpio_id = attr.id; 7771730a17dSPrabhakar Kushwaha #ifdef DEBUG 7781730a17dSPrabhakar Kushwaha printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); 7791730a17dSPrabhakar Kushwaha #endif 7801730a17dSPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7811730a17dSPrabhakar Kushwaha if (err < 0) { 782a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 783a2a55e51SPrabhakar Kushwaha goto err_get_enable; 784a2a55e51SPrabhakar Kushwaha } 7851f1c25c7SPrabhakar Kushwaha debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", 7861f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ce_offset, 7871f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ci_offset, 788a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 789a2a55e51SPrabhakar Kushwaha attr.num_priorities); 790a2a55e51SPrabhakar Kushwaha 7911f1c25c7SPrabhakar Kushwaha p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7921f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ce_offset); 7931f1c25c7SPrabhakar Kushwaha p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7941f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ci_offset); 795a2a55e51SPrabhakar Kushwaha 796a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 797a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 798a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 799a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 800a2a55e51SPrabhakar Kushwaha } 801a2a55e51SPrabhakar Kushwaha return 0; 802a2a55e51SPrabhakar Kushwaha 803a2a55e51SPrabhakar Kushwaha err_get_swp_init: 8041730a17dSPrabhakar Kushwaha dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 805a2a55e51SPrabhakar Kushwaha err_get_enable: 8061730a17dSPrabhakar Kushwaha err_get_attr: 8071730a17dSPrabhakar Kushwaha dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8081730a17dSPrabhakar Kushwaha dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8091730a17dSPrabhakar Kushwaha err_create: 810cd7b3fbcSPrabhakar Kushwaha free(dflt_dpio); 8111730a17dSPrabhakar Kushwaha err_malloc: 812a2a55e51SPrabhakar Kushwaha return err; 813a2a55e51SPrabhakar Kushwaha } 814a2a55e51SPrabhakar Kushwaha 8151730a17dSPrabhakar Kushwaha static int dpio_exit(void) 816a2a55e51SPrabhakar Kushwaha { 8171730a17dSPrabhakar Kushwaha int err; 8181730a17dSPrabhakar Kushwaha 8191730a17dSPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8201730a17dSPrabhakar Kushwaha if (err < 0) { 8211730a17dSPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 8221730a17dSPrabhakar Kushwaha goto err; 8231730a17dSPrabhakar Kushwaha } 8241730a17dSPrabhakar Kushwaha 8251730a17dSPrabhakar Kushwaha err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8261730a17dSPrabhakar Kushwaha if (err < 0) { 8271730a17dSPrabhakar Kushwaha printf("dpio_destroy() failed: %d\n", err); 8281730a17dSPrabhakar Kushwaha goto err; 8291730a17dSPrabhakar Kushwaha } 8301730a17dSPrabhakar Kushwaha 8311730a17dSPrabhakar Kushwaha #ifdef DEBUG 8321730a17dSPrabhakar Kushwaha printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); 8331730a17dSPrabhakar Kushwaha #endif 8341730a17dSPrabhakar Kushwaha 8351730a17dSPrabhakar Kushwaha if (dflt_dpio) 8361730a17dSPrabhakar Kushwaha free(dflt_dpio); 8371730a17dSPrabhakar Kushwaha 8381730a17dSPrabhakar Kushwaha return 0; 8391730a17dSPrabhakar Kushwaha err: 8401730a17dSPrabhakar Kushwaha return err; 8411730a17dSPrabhakar Kushwaha } 8421730a17dSPrabhakar Kushwaha 8431730a17dSPrabhakar Kushwaha static int dprc_init(void) 8441730a17dSPrabhakar Kushwaha { 8451730a17dSPrabhakar Kushwaha int err, child_portal_id, container_id; 8461730a17dSPrabhakar Kushwaha struct dprc_cfg cfg; 8471730a17dSPrabhakar Kushwaha uint64_t mc_portal_offset; 8481730a17dSPrabhakar Kushwaha 8491730a17dSPrabhakar Kushwaha /* Open root container */ 8501730a17dSPrabhakar Kushwaha err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); 8511730a17dSPrabhakar Kushwaha if (err < 0) { 8521730a17dSPrabhakar Kushwaha printf("dprc_get_container_id(): Root failed: %d\n", err); 8531730a17dSPrabhakar Kushwaha goto err_root_container_id; 8541730a17dSPrabhakar Kushwaha } 8551730a17dSPrabhakar Kushwaha 8561730a17dSPrabhakar Kushwaha #ifdef DEBUG 8571730a17dSPrabhakar Kushwaha printf("Root container id = %d\n", container_id); 8581730a17dSPrabhakar Kushwaha #endif 8591730a17dSPrabhakar Kushwaha err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, 8601730a17dSPrabhakar Kushwaha &root_dprc_handle); 8611730a17dSPrabhakar Kushwaha if (err < 0) { 8621730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container failed: %d\n", err); 8631730a17dSPrabhakar Kushwaha goto err_root_open; 8641730a17dSPrabhakar Kushwaha } 8651730a17dSPrabhakar Kushwaha 8661730a17dSPrabhakar Kushwaha if (!root_dprc_handle) { 8671730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container Handle is not valid\n"); 8681730a17dSPrabhakar Kushwaha goto err_root_open; 8691730a17dSPrabhakar Kushwaha } 8701730a17dSPrabhakar Kushwaha 8719a696f56SPrabhakar Kushwaha err = dprc_version_check(root_mc_io, root_dprc_handle); 8729a696f56SPrabhakar Kushwaha if (err < 0) { 8739a696f56SPrabhakar Kushwaha printf("dprc_version_check() failed: %d\n", err); 8749a696f56SPrabhakar Kushwaha goto err_root_open; 8759a696f56SPrabhakar Kushwaha } 8769a696f56SPrabhakar Kushwaha 8775373b204SPrabhakar Kushwaha memset(&cfg, 0, sizeof(struct dprc_cfg)); 8781730a17dSPrabhakar Kushwaha cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | 8791730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | 8801730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_ALLOC_ALLOWED; 8811730a17dSPrabhakar Kushwaha cfg.icid = DPRC_GET_ICID_FROM_POOL; 882335b1936SPrabhakar Kushwaha cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL; 8831730a17dSPrabhakar Kushwaha err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, 8841730a17dSPrabhakar Kushwaha root_dprc_handle, 8851730a17dSPrabhakar Kushwaha &cfg, 8861730a17dSPrabhakar Kushwaha &child_dprc_id, 8871730a17dSPrabhakar Kushwaha &mc_portal_offset); 8881730a17dSPrabhakar Kushwaha if (err < 0) { 8891730a17dSPrabhakar Kushwaha printf("dprc_create_container() failed: %d\n", err); 8901730a17dSPrabhakar Kushwaha goto err_create; 8911730a17dSPrabhakar Kushwaha } 8921730a17dSPrabhakar Kushwaha 8931730a17dSPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 8941730a17dSPrabhakar Kushwaha if (!dflt_mc_io) { 8951730a17dSPrabhakar Kushwaha err = -ENOMEM; 8961730a17dSPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 8971730a17dSPrabhakar Kushwaha goto err_malloc; 8981730a17dSPrabhakar Kushwaha } 8991730a17dSPrabhakar Kushwaha 9001730a17dSPrabhakar Kushwaha child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); 9011730a17dSPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); 9021730a17dSPrabhakar Kushwaha #ifdef DEBUG 9031730a17dSPrabhakar Kushwaha printf("MC portal of child DPRC container: %d, physical addr %p)\n", 9041730a17dSPrabhakar Kushwaha child_dprc_id, dflt_mc_io->mmio_regs); 9051730a17dSPrabhakar Kushwaha #endif 9061730a17dSPrabhakar Kushwaha 9071730a17dSPrabhakar Kushwaha err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, 9081730a17dSPrabhakar Kushwaha &dflt_dprc_handle); 9091730a17dSPrabhakar Kushwaha if (err < 0) { 9101730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container failed: %d\n", err); 9111730a17dSPrabhakar Kushwaha goto err_child_open; 9121730a17dSPrabhakar Kushwaha } 9131730a17dSPrabhakar Kushwaha 9141730a17dSPrabhakar Kushwaha if (!dflt_dprc_handle) { 9151730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container Handle is not valid\n"); 9161730a17dSPrabhakar Kushwaha goto err_child_open; 9171730a17dSPrabhakar Kushwaha } 9181730a17dSPrabhakar Kushwaha 9191730a17dSPrabhakar Kushwaha return 0; 9201730a17dSPrabhakar Kushwaha err_child_open: 9211730a17dSPrabhakar Kushwaha free(dflt_mc_io); 9221730a17dSPrabhakar Kushwaha err_malloc: 9231730a17dSPrabhakar Kushwaha dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 9241730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 9251730a17dSPrabhakar Kushwaha err_create: 9261730a17dSPrabhakar Kushwaha dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 9271730a17dSPrabhakar Kushwaha err_root_open: 9281730a17dSPrabhakar Kushwaha err_root_container_id: 9291730a17dSPrabhakar Kushwaha return err; 9301730a17dSPrabhakar Kushwaha } 9311730a17dSPrabhakar Kushwaha 9321730a17dSPrabhakar Kushwaha static int dprc_exit(void) 9331730a17dSPrabhakar Kushwaha { 9341730a17dSPrabhakar Kushwaha int err; 9351730a17dSPrabhakar Kushwaha 9361730a17dSPrabhakar Kushwaha err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); 9371730a17dSPrabhakar Kushwaha if (err < 0) { 9381730a17dSPrabhakar Kushwaha printf("dprc_close(): Child failed: %d\n", err); 9391730a17dSPrabhakar Kushwaha goto err; 9401730a17dSPrabhakar Kushwaha } 9411730a17dSPrabhakar Kushwaha 9421730a17dSPrabhakar Kushwaha err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 9431730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 9441730a17dSPrabhakar Kushwaha if (err < 0) { 9451730a17dSPrabhakar Kushwaha printf("dprc_destroy_container() failed: %d\n", err); 9461730a17dSPrabhakar Kushwaha goto err; 9471730a17dSPrabhakar Kushwaha } 9481730a17dSPrabhakar Kushwaha 9491730a17dSPrabhakar Kushwaha err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 9501730a17dSPrabhakar Kushwaha if (err < 0) { 9511730a17dSPrabhakar Kushwaha printf("dprc_close(): Root failed: %d\n", err); 9521730a17dSPrabhakar Kushwaha goto err; 9531730a17dSPrabhakar Kushwaha } 9541730a17dSPrabhakar Kushwaha 9551730a17dSPrabhakar Kushwaha if (dflt_mc_io) 9561730a17dSPrabhakar Kushwaha free(dflt_mc_io); 9571730a17dSPrabhakar Kushwaha 9581730a17dSPrabhakar Kushwaha if (root_mc_io) 9591730a17dSPrabhakar Kushwaha free(root_mc_io); 9601730a17dSPrabhakar Kushwaha 9611730a17dSPrabhakar Kushwaha return 0; 9621730a17dSPrabhakar Kushwaha 9631730a17dSPrabhakar Kushwaha err: 9641730a17dSPrabhakar Kushwaha return err; 9651730a17dSPrabhakar Kushwaha } 9661730a17dSPrabhakar Kushwaha 9671730a17dSPrabhakar Kushwaha static int dpbp_init(void) 9681730a17dSPrabhakar Kushwaha { 9691730a17dSPrabhakar Kushwaha int err; 9701730a17dSPrabhakar Kushwaha struct dpbp_attr dpbp_attr; 9711730a17dSPrabhakar Kushwaha struct dpbp_cfg dpbp_cfg; 9721730a17dSPrabhakar Kushwaha 973a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 974a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 975a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 9761730a17dSPrabhakar Kushwaha err = -ENOMEM; 9771730a17dSPrabhakar Kushwaha goto err_malloc; 978a2a55e51SPrabhakar Kushwaha } 9791730a17dSPrabhakar Kushwaha 9801730a17dSPrabhakar Kushwaha dpbp_cfg.options = 512; 9811730a17dSPrabhakar Kushwaha 9821730a17dSPrabhakar Kushwaha err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, 9831730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 9841730a17dSPrabhakar Kushwaha 9851730a17dSPrabhakar Kushwaha if (err < 0) { 9861730a17dSPrabhakar Kushwaha err = -ENODEV; 9871730a17dSPrabhakar Kushwaha printf("dpbp_create() failed: %d\n", err); 9881730a17dSPrabhakar Kushwaha goto err_create; 9891730a17dSPrabhakar Kushwaha } 9901730a17dSPrabhakar Kushwaha 9911730a17dSPrabhakar Kushwaha memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); 9921730a17dSPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 9931730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 9941730a17dSPrabhakar Kushwaha &dpbp_attr); 9951730a17dSPrabhakar Kushwaha if (err < 0) { 9961730a17dSPrabhakar Kushwaha printf("dpbp_get_attributes() failed: %d\n", err); 9971730a17dSPrabhakar Kushwaha goto err_get_attr; 9981730a17dSPrabhakar Kushwaha } 9991730a17dSPrabhakar Kushwaha 10009a696f56SPrabhakar Kushwaha if ((dpbp_attr.version.major != DPBP_VER_MAJOR) || 10019a696f56SPrabhakar Kushwaha (dpbp_attr.version.minor != DPBP_VER_MINOR)) { 10029a696f56SPrabhakar Kushwaha printf("DPBP version mismatch found %u.%u,", 10039a696f56SPrabhakar Kushwaha dpbp_attr.version.major, dpbp_attr.version.minor); 10049a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 10059a696f56SPrabhakar Kushwaha DPBP_VER_MAJOR, DPBP_VER_MINOR); 10069a696f56SPrabhakar Kushwaha } 10079a696f56SPrabhakar Kushwaha 10081730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = dpbp_attr.id; 10091730a17dSPrabhakar Kushwaha #ifdef DEBUG 10101730a17dSPrabhakar Kushwaha printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 10111730a17dSPrabhakar Kushwaha #endif 10121730a17dSPrabhakar Kushwaha 10131730a17dSPrabhakar Kushwaha err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10141730a17dSPrabhakar Kushwaha if (err < 0) { 10151730a17dSPrabhakar Kushwaha printf("dpbp_close() failed: %d\n", err); 10161730a17dSPrabhakar Kushwaha goto err_close; 10171730a17dSPrabhakar Kushwaha } 1018a2a55e51SPrabhakar Kushwaha 1019a2a55e51SPrabhakar Kushwaha return 0; 10201730a17dSPrabhakar Kushwaha 10211730a17dSPrabhakar Kushwaha err_close: 10221730a17dSPrabhakar Kushwaha free(dflt_dpbp); 10231730a17dSPrabhakar Kushwaha err_get_attr: 10241730a17dSPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10251730a17dSPrabhakar Kushwaha dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10261730a17dSPrabhakar Kushwaha err_create: 10271730a17dSPrabhakar Kushwaha err_malloc: 10281730a17dSPrabhakar Kushwaha return err; 1029a2a55e51SPrabhakar Kushwaha } 1030a2a55e51SPrabhakar Kushwaha 10311730a17dSPrabhakar Kushwaha static int dpbp_exit(void) 1032a2a55e51SPrabhakar Kushwaha { 10331730a17dSPrabhakar Kushwaha int err; 10341730a17dSPrabhakar Kushwaha 10351730a17dSPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 10361730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 10371730a17dSPrabhakar Kushwaha if (err < 0) { 10381730a17dSPrabhakar Kushwaha printf("dpbp_open() failed: %d\n", err); 10391730a17dSPrabhakar Kushwaha goto err; 10401730a17dSPrabhakar Kushwaha } 10411730a17dSPrabhakar Kushwaha 10421730a17dSPrabhakar Kushwaha err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 10431730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle); 10441730a17dSPrabhakar Kushwaha if (err < 0) { 10451730a17dSPrabhakar Kushwaha printf("dpbp_destroy() failed: %d\n", err); 10461730a17dSPrabhakar Kushwaha goto err; 10471730a17dSPrabhakar Kushwaha } 10481730a17dSPrabhakar Kushwaha 10491730a17dSPrabhakar Kushwaha #ifdef DEBUG 10501730a17dSPrabhakar Kushwaha printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 10511730a17dSPrabhakar Kushwaha #endif 10521730a17dSPrabhakar Kushwaha 10531730a17dSPrabhakar Kushwaha if (dflt_dpbp) 10541730a17dSPrabhakar Kushwaha free(dflt_dpbp); 10551730a17dSPrabhakar Kushwaha return 0; 10561730a17dSPrabhakar Kushwaha 10571730a17dSPrabhakar Kushwaha err: 10581730a17dSPrabhakar Kushwaha return err; 10591730a17dSPrabhakar Kushwaha } 10601730a17dSPrabhakar Kushwaha 10611730a17dSPrabhakar Kushwaha static int dpni_init(void) 10621730a17dSPrabhakar Kushwaha { 10631730a17dSPrabhakar Kushwaha int err; 10641730a17dSPrabhakar Kushwaha struct dpni_attr dpni_attr; 1065879a59acSPrabhakar Kushwaha uint8_t ext_cfg_buf[256] = {0}; 1066879a59acSPrabhakar Kushwaha struct dpni_extended_cfg dpni_extended_cfg; 10671730a17dSPrabhakar Kushwaha struct dpni_cfg dpni_cfg; 10681730a17dSPrabhakar Kushwaha 10691730a17dSPrabhakar Kushwaha dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); 10701730a17dSPrabhakar Kushwaha if (!dflt_dpni) { 10711730a17dSPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 10721730a17dSPrabhakar Kushwaha err = -ENOMEM; 10731730a17dSPrabhakar Kushwaha goto err_malloc; 10741730a17dSPrabhakar Kushwaha } 10751730a17dSPrabhakar Kushwaha 1076879a59acSPrabhakar Kushwaha memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg)); 1077879a59acSPrabhakar Kushwaha err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]); 1078879a59acSPrabhakar Kushwaha if (err < 0) { 1079879a59acSPrabhakar Kushwaha err = -ENODEV; 1080879a59acSPrabhakar Kushwaha printf("dpni_prepare_extended_cfg() failed: %d\n", err); 1081879a59acSPrabhakar Kushwaha goto err_prepare_extended_cfg; 1082879a59acSPrabhakar Kushwaha } 1083879a59acSPrabhakar Kushwaha 10841730a17dSPrabhakar Kushwaha memset(&dpni_cfg, 0, sizeof(dpni_cfg)); 10851730a17dSPrabhakar Kushwaha dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | 10861730a17dSPrabhakar Kushwaha DPNI_OPT_MULTICAST_FILTER; 10871730a17dSPrabhakar Kushwaha 1088879a59acSPrabhakar Kushwaha dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0]; 10891730a17dSPrabhakar Kushwaha err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, 10901730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 10911730a17dSPrabhakar Kushwaha 10921730a17dSPrabhakar Kushwaha if (err < 0) { 10931730a17dSPrabhakar Kushwaha err = -ENODEV; 10941730a17dSPrabhakar Kushwaha printf("dpni_create() failed: %d\n", err); 10951730a17dSPrabhakar Kushwaha goto err_create; 10961730a17dSPrabhakar Kushwaha } 10971730a17dSPrabhakar Kushwaha 10981730a17dSPrabhakar Kushwaha memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 10991730a17dSPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 11001730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle, 11011730a17dSPrabhakar Kushwaha &dpni_attr); 11021730a17dSPrabhakar Kushwaha if (err < 0) { 11031730a17dSPrabhakar Kushwaha printf("dpni_get_attributes() failed: %d\n", err); 11041730a17dSPrabhakar Kushwaha goto err_get_attr; 11051730a17dSPrabhakar Kushwaha } 11061730a17dSPrabhakar Kushwaha 11079a696f56SPrabhakar Kushwaha if ((dpni_attr.version.major != DPNI_VER_MAJOR) || 11089a696f56SPrabhakar Kushwaha (dpni_attr.version.minor != DPNI_VER_MINOR)) { 11099a696f56SPrabhakar Kushwaha printf("DPNI version mismatch found %u.%u,", 11109a696f56SPrabhakar Kushwaha dpni_attr.version.major, dpni_attr.version.minor); 11119a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 11129a696f56SPrabhakar Kushwaha DPNI_VER_MAJOR, DPNI_VER_MINOR); 11139a696f56SPrabhakar Kushwaha } 11149a696f56SPrabhakar Kushwaha 11151730a17dSPrabhakar Kushwaha dflt_dpni->dpni_id = dpni_attr.id; 11161730a17dSPrabhakar Kushwaha #ifdef DEBUG 11171730a17dSPrabhakar Kushwaha printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); 11181730a17dSPrabhakar Kushwaha #endif 11191730a17dSPrabhakar Kushwaha 11201730a17dSPrabhakar Kushwaha err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11211730a17dSPrabhakar Kushwaha if (err < 0) { 11221730a17dSPrabhakar Kushwaha printf("dpni_close() failed: %d\n", err); 11231730a17dSPrabhakar Kushwaha goto err_close; 11241730a17dSPrabhakar Kushwaha } 1125a2a55e51SPrabhakar Kushwaha 1126fb4a87a7SPrabhakar Kushwaha return 0; 11271730a17dSPrabhakar Kushwaha 11281730a17dSPrabhakar Kushwaha err_close: 11291730a17dSPrabhakar Kushwaha err_get_attr: 11301730a17dSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11311730a17dSPrabhakar Kushwaha dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11321730a17dSPrabhakar Kushwaha err_create: 1133879a59acSPrabhakar Kushwaha err_prepare_extended_cfg: 1134879a59acSPrabhakar Kushwaha free(dflt_dpni); 11351730a17dSPrabhakar Kushwaha err_malloc: 11361730a17dSPrabhakar Kushwaha return err; 1137a2a55e51SPrabhakar Kushwaha } 1138a2a55e51SPrabhakar Kushwaha 11391730a17dSPrabhakar Kushwaha static int dpni_exit(void) 1140a2a55e51SPrabhakar Kushwaha { 11411730a17dSPrabhakar Kushwaha int err; 11421730a17dSPrabhakar Kushwaha 11431730a17dSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 11441730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 11451730a17dSPrabhakar Kushwaha if (err < 0) { 11461730a17dSPrabhakar Kushwaha printf("dpni_open() failed: %d\n", err); 11471730a17dSPrabhakar Kushwaha goto err; 11481730a17dSPrabhakar Kushwaha } 11491730a17dSPrabhakar Kushwaha 11501730a17dSPrabhakar Kushwaha err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 11511730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle); 11521730a17dSPrabhakar Kushwaha if (err < 0) { 11531730a17dSPrabhakar Kushwaha printf("dpni_destroy() failed: %d\n", err); 11541730a17dSPrabhakar Kushwaha goto err; 11551730a17dSPrabhakar Kushwaha } 11561730a17dSPrabhakar Kushwaha 11571730a17dSPrabhakar Kushwaha #ifdef DEBUG 11581730a17dSPrabhakar Kushwaha printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); 11591730a17dSPrabhakar Kushwaha #endif 11601730a17dSPrabhakar Kushwaha 11611730a17dSPrabhakar Kushwaha if (dflt_dpni) 11621730a17dSPrabhakar Kushwaha free(dflt_dpni); 11631730a17dSPrabhakar Kushwaha return 0; 11641730a17dSPrabhakar Kushwaha 11651730a17dSPrabhakar Kushwaha err: 11661730a17dSPrabhakar Kushwaha return err; 11671730a17dSPrabhakar Kushwaha } 11681730a17dSPrabhakar Kushwaha 11691730a17dSPrabhakar Kushwaha static int mc_init_object(void) 11701730a17dSPrabhakar Kushwaha { 11711730a17dSPrabhakar Kushwaha int err = 0; 11721730a17dSPrabhakar Kushwaha 11731730a17dSPrabhakar Kushwaha err = dprc_init(); 11741730a17dSPrabhakar Kushwaha if (err < 0) { 11751730a17dSPrabhakar Kushwaha printf("dprc_init() failed: %d\n", err); 11761730a17dSPrabhakar Kushwaha goto err; 11771730a17dSPrabhakar Kushwaha } 11781730a17dSPrabhakar Kushwaha 11791730a17dSPrabhakar Kushwaha err = dpbp_init(); 11801730a17dSPrabhakar Kushwaha if (err < 0) { 11811730a17dSPrabhakar Kushwaha printf("dpbp_init() failed: %d\n", err); 11821730a17dSPrabhakar Kushwaha goto err; 11831730a17dSPrabhakar Kushwaha } 11841730a17dSPrabhakar Kushwaha 11851730a17dSPrabhakar Kushwaha err = dpio_init(); 11861730a17dSPrabhakar Kushwaha if (err < 0) { 11871730a17dSPrabhakar Kushwaha printf("dpio_init() failed: %d\n", err); 11881730a17dSPrabhakar Kushwaha goto err; 11891730a17dSPrabhakar Kushwaha } 11901730a17dSPrabhakar Kushwaha 11911730a17dSPrabhakar Kushwaha err = dpni_init(); 11921730a17dSPrabhakar Kushwaha if (err < 0) { 11931730a17dSPrabhakar Kushwaha printf("dpni_init() failed: %d\n", err); 11941730a17dSPrabhakar Kushwaha goto err; 11951730a17dSPrabhakar Kushwaha } 11961730a17dSPrabhakar Kushwaha 11971730a17dSPrabhakar Kushwaha return 0; 11981730a17dSPrabhakar Kushwaha err: 11991730a17dSPrabhakar Kushwaha return err; 12001730a17dSPrabhakar Kushwaha } 12011730a17dSPrabhakar Kushwaha 12021730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_exit(bd_t *bd) 12031730a17dSPrabhakar Kushwaha { 12041730a17dSPrabhakar Kushwaha int err = 0; 1205*42e81790SYogesh Gaur bool is_dpl_apply_status = false; 12061730a17dSPrabhakar Kushwaha 1207b7b8410aSAlexander Graf if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { 1208b7b8410aSAlexander Graf mc_apply_dpl(mc_lazy_dpl_addr); 1209b7b8410aSAlexander Graf mc_lazy_dpl_addr = 0; 1210b7b8410aSAlexander Graf } 1211b7b8410aSAlexander Graf 12126dedceddSPrabhakar Kushwaha /* MC is not loaded intentionally, So return success. */ 12136dedceddSPrabhakar Kushwaha if (bd && get_mc_boot_status() != 0) 12141730a17dSPrabhakar Kushwaha return 0; 12151730a17dSPrabhakar Kushwaha 1216*42e81790SYogesh Gaur /* If DPL is deployed, set is_dpl_apply_status as TRUE. */ 1217*42e81790SYogesh Gaur if (!get_dpl_apply_status()) 1218*42e81790SYogesh Gaur is_dpl_apply_status = true; 12191730a17dSPrabhakar Kushwaha 1220*42e81790SYogesh Gaur /* 1221*42e81790SYogesh Gaur * For case MC is loaded but DPL is not deployed, return success and 1222*42e81790SYogesh Gaur * print message on console. Else FDT fix-up code execution hanged. 1223*42e81790SYogesh Gaur */ 1224*42e81790SYogesh Gaur if (bd && !get_mc_boot_status() && !is_dpl_apply_status) { 1225*42e81790SYogesh Gaur printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n"); 1226*42e81790SYogesh Gaur return 0; 1227*42e81790SYogesh Gaur } 12281730a17dSPrabhakar Kushwaha 12291730a17dSPrabhakar Kushwaha err = dpbp_exit(); 12301730a17dSPrabhakar Kushwaha if (err < 0) { 1231a2a4dc56SPrabhakar Kushwaha printf("dpbp_exit() failed: %d\n", err); 12321730a17dSPrabhakar Kushwaha goto err; 12331730a17dSPrabhakar Kushwaha } 12341730a17dSPrabhakar Kushwaha 12351730a17dSPrabhakar Kushwaha err = dpio_exit(); 12361730a17dSPrabhakar Kushwaha if (err < 0) { 12371730a17dSPrabhakar Kushwaha printf("dpio_exit() failed: %d\n", err); 12381730a17dSPrabhakar Kushwaha goto err; 12391730a17dSPrabhakar Kushwaha } 12401730a17dSPrabhakar Kushwaha 12411730a17dSPrabhakar Kushwaha err = dpni_exit(); 12421730a17dSPrabhakar Kushwaha if (err < 0) { 12431730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 12441730a17dSPrabhakar Kushwaha goto err; 12451730a17dSPrabhakar Kushwaha } 12461730a17dSPrabhakar Kushwaha 12471730a17dSPrabhakar Kushwaha err = dprc_exit(); 12481730a17dSPrabhakar Kushwaha if (err < 0) { 12491730a17dSPrabhakar Kushwaha printf("dprc_exit() failed: %d\n", err); 12501730a17dSPrabhakar Kushwaha goto err; 12511730a17dSPrabhakar Kushwaha } 12521730a17dSPrabhakar Kushwaha 12531730a17dSPrabhakar Kushwaha return 0; 12541730a17dSPrabhakar Kushwaha err: 12551730a17dSPrabhakar Kushwaha return err; 1256fb4a87a7SPrabhakar Kushwaha } 1257fb4a87a7SPrabhakar Kushwaha 1258fb4a87a7SPrabhakar Kushwaha static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1259fb4a87a7SPrabhakar Kushwaha { 1260fb4a87a7SPrabhakar Kushwaha int err = 0; 1261fb4a87a7SPrabhakar Kushwaha if (argc < 3) 1262fb4a87a7SPrabhakar Kushwaha goto usage; 1263fb4a87a7SPrabhakar Kushwaha 1264fb4a87a7SPrabhakar Kushwaha switch (argv[1][0]) { 1265fb4a87a7SPrabhakar Kushwaha case 's': { 1266fb4a87a7SPrabhakar Kushwaha char sub_cmd; 126744937214SPrabhakar Kushwaha u64 mc_fw_addr, mc_dpc_addr; 126844937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 126944937214SPrabhakar Kushwaha u64 aiop_fw_addr; 127044937214SPrabhakar Kushwaha #endif 1271fb4a87a7SPrabhakar Kushwaha 1272fb4a87a7SPrabhakar Kushwaha sub_cmd = argv[2][0]; 1273fb4a87a7SPrabhakar Kushwaha switch (sub_cmd) { 1274fb4a87a7SPrabhakar Kushwaha case 'm': 1275fb4a87a7SPrabhakar Kushwaha if (argc < 5) 1276fb4a87a7SPrabhakar Kushwaha goto usage; 1277a2a55e51SPrabhakar Kushwaha 1278125e2bc1SJ. German Rivera if (get_mc_boot_status() == 0) { 1279fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: MC is already booted"); 1280fb4a87a7SPrabhakar Kushwaha printf("\n"); 1281fb4a87a7SPrabhakar Kushwaha return err; 1282a2a55e51SPrabhakar Kushwaha } 1283fb4a87a7SPrabhakar Kushwaha mc_fw_addr = simple_strtoull(argv[3], NULL, 16); 1284fb4a87a7SPrabhakar Kushwaha mc_dpc_addr = simple_strtoull(argv[4], NULL, 1285fb4a87a7SPrabhakar Kushwaha 16); 12861730a17dSPrabhakar Kushwaha 12871730a17dSPrabhakar Kushwaha if (!mc_init(mc_fw_addr, mc_dpc_addr)) 12881730a17dSPrabhakar Kushwaha err = mc_init_object(); 1289fb4a87a7SPrabhakar Kushwaha break; 1290fb4a87a7SPrabhakar Kushwaha 1291fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 1292fb4a87a7SPrabhakar Kushwaha case 'a': 1293fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1294fb4a87a7SPrabhakar Kushwaha goto usage; 1295fb4a87a7SPrabhakar Kushwaha if (get_aiop_apply_status() == 0) { 1296fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW is already"); 1297fb4a87a7SPrabhakar Kushwaha printf(" applied\n"); 1298fb4a87a7SPrabhakar Kushwaha return err; 1299a2a55e51SPrabhakar Kushwaha } 1300a2a55e51SPrabhakar Kushwaha 1301fb4a87a7SPrabhakar Kushwaha aiop_fw_addr = simple_strtoull(argv[3], NULL, 1302fb4a87a7SPrabhakar Kushwaha 16); 1303fb4a87a7SPrabhakar Kushwaha 13043c1d218aSYork Sun /* if SoC doesn't have AIOP, err = -ENODEV */ 1305fb4a87a7SPrabhakar Kushwaha err = load_mc_aiop_img(aiop_fw_addr); 1306fb4a87a7SPrabhakar Kushwaha if (!err) 1307fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW applied\n"); 1308fb4a87a7SPrabhakar Kushwaha break; 1309fb4a87a7SPrabhakar Kushwaha #endif 1310fb4a87a7SPrabhakar Kushwaha default: 1311fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[2]); 1312fb4a87a7SPrabhakar Kushwaha goto usage; 1313fb4a87a7SPrabhakar Kushwaha 1314fb4a87a7SPrabhakar Kushwaha break; 1315fb4a87a7SPrabhakar Kushwaha } 1316fb4a87a7SPrabhakar Kushwaha } 1317fb4a87a7SPrabhakar Kushwaha break; 1318fb4a87a7SPrabhakar Kushwaha 1319b7b8410aSAlexander Graf case 'l': 1320fb4a87a7SPrabhakar Kushwaha case 'a': { 1321fb4a87a7SPrabhakar Kushwaha u64 mc_dpl_addr; 1322fb4a87a7SPrabhakar Kushwaha 1323fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1324fb4a87a7SPrabhakar Kushwaha goto usage; 1325fb4a87a7SPrabhakar Kushwaha 1326fb4a87a7SPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 1327fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: DPL already applied\n"); 1328fb4a87a7SPrabhakar Kushwaha return err; 1329125e2bc1SJ. German Rivera } 1330125e2bc1SJ. German Rivera 1331fb4a87a7SPrabhakar Kushwaha mc_dpl_addr = simple_strtoull(argv[3], NULL, 1332fb4a87a7SPrabhakar Kushwaha 16); 13331730a17dSPrabhakar Kushwaha 1334fb4a87a7SPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 1335fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout .."); 1336fb4a87a7SPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 1337fb4a87a7SPrabhakar Kushwaha return -ENODEV; 1338a2a55e51SPrabhakar Kushwaha } 13391730a17dSPrabhakar Kushwaha 1340b7b8410aSAlexander Graf if (argv[1][0] == 'l') { 1341b7b8410aSAlexander Graf /* 1342b7b8410aSAlexander Graf * We will do the actual dpaa exit and dpl apply 1343b7b8410aSAlexander Graf * later from announce_and_cleanup(). 1344b7b8410aSAlexander Graf */ 1345b7b8410aSAlexander Graf mc_lazy_dpl_addr = mc_dpl_addr; 1346b7b8410aSAlexander Graf } else { 1347b7b8410aSAlexander Graf /* The user wants it applied now */ 13481730a17dSPrabhakar Kushwaha if (!fsl_mc_ldpaa_exit(NULL)) 1349fb4a87a7SPrabhakar Kushwaha err = mc_apply_dpl(mc_dpl_addr); 1350b7b8410aSAlexander Graf } 1351fb4a87a7SPrabhakar Kushwaha break; 1352fb4a87a7SPrabhakar Kushwaha } 1353fb4a87a7SPrabhakar Kushwaha default: 1354fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[1]); 1355fb4a87a7SPrabhakar Kushwaha goto usage; 1356fb4a87a7SPrabhakar Kushwaha break; 1357fb4a87a7SPrabhakar Kushwaha } 1358fb4a87a7SPrabhakar Kushwaha return err; 1359fb4a87a7SPrabhakar Kushwaha usage: 1360fb4a87a7SPrabhakar Kushwaha return CMD_RET_USAGE; 1361fb4a87a7SPrabhakar Kushwaha } 1362fb4a87a7SPrabhakar Kushwaha 1363fb4a87a7SPrabhakar Kushwaha U_BOOT_CMD( 1364fb4a87a7SPrabhakar Kushwaha fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, 1365fb4a87a7SPrabhakar Kushwaha "DPAA2 command to manage Management Complex (MC)", 1366fb4a87a7SPrabhakar Kushwaha "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" 1367fb4a87a7SPrabhakar Kushwaha "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" 1368b7b8410aSAlexander Graf "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" 1369fb4a87a7SPrabhakar Kushwaha "fsl_mc start aiop [FW_addr] - Start AIOP\n" 1370fb4a87a7SPrabhakar Kushwaha ); 1371