17b3bd9a7SJ. German Rivera /* 27b3bd9a7SJ. German Rivera * Copyright (C) 2014 Freescale Semiconductor 37b3bd9a7SJ. German Rivera * 47b3bd9a7SJ. German Rivera * SPDX-License-Identifier: GPL-2.0+ 57b3bd9a7SJ. German Rivera */ 621c69870SStuart Yoder #include <common.h> 77b3bd9a7SJ. German Rivera #include <errno.h> 87b3bd9a7SJ. German Rivera #include <asm/io.h> 921c69870SStuart Yoder #include <libfdt.h> 1021c69870SStuart Yoder #include <fdt_support.h> 117b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc.h> 127b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc_sys.h> 13a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_mc_private.h> 147b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_dpmng.h> 15a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dprc.h> 16a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dpio.h> 17fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/fsl_dpni.h> 18a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_qbman_portal.h> 19fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h> 207b3bd9a7SJ. German Rivera 21125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) 22125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) 23125e2bc1SJ. German Rivera #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) 24125e2bc1SJ. German Rivera 25125e2bc1SJ. German Rivera #define MC_MEM_SIZE_ENV_VAR "mcmemsize" 26125e2bc1SJ. German Rivera #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" 27125e2bc1SJ. German Rivera 287b3bd9a7SJ. German Rivera DECLARE_GLOBAL_DATA_PTR; 29fb4a87a7SPrabhakar Kushwaha static int mc_boot_status = -1; 30fb4a87a7SPrabhakar Kushwaha static int mc_dpl_applied = -1; 31fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 32fb4a87a7SPrabhakar Kushwaha static int mc_aiop_applied = -1; 33fb4a87a7SPrabhakar Kushwaha #endif 341730a17dSPrabhakar Kushwaha struct fsl_mc_io *root_mc_io = NULL; 351730a17dSPrabhakar Kushwaha struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ 361730a17dSPrabhakar Kushwaha uint16_t root_dprc_handle = 0; 37a2a55e51SPrabhakar Kushwaha uint16_t dflt_dprc_handle = 0; 381730a17dSPrabhakar Kushwaha int child_dprc_id; 39a2a55e51SPrabhakar Kushwaha struct fsl_dpbp_obj *dflt_dpbp = NULL; 40a2a55e51SPrabhakar Kushwaha struct fsl_dpio_obj *dflt_dpio = NULL; 411730a17dSPrabhakar Kushwaha struct fsl_dpni_obj *dflt_dpni = NULL; 427b3bd9a7SJ. German Rivera 43125e2bc1SJ. German Rivera #ifdef DEBUG 44125e2bc1SJ. German Rivera void dump_ram_words(const char *title, void *addr) 45125e2bc1SJ. German Rivera { 46125e2bc1SJ. German Rivera int i; 47125e2bc1SJ. German Rivera uint32_t *words = addr; 48125e2bc1SJ. German Rivera 49125e2bc1SJ. German Rivera printf("Dumping beginning of %s (%p):\n", title, addr); 50125e2bc1SJ. German Rivera for (i = 0; i < 16; i++) 51125e2bc1SJ. German Rivera printf("%#x ", words[i]); 52125e2bc1SJ. German Rivera 53125e2bc1SJ. German Rivera printf("\n"); 54125e2bc1SJ. German Rivera } 55125e2bc1SJ. German Rivera 56125e2bc1SJ. German Rivera void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) 57125e2bc1SJ. German Rivera { 58125e2bc1SJ. German Rivera printf("MC CCSR registers:\n" 59125e2bc1SJ. German Rivera "reg_gcr1 %#x\n" 60125e2bc1SJ. German Rivera "reg_gsr %#x\n" 61125e2bc1SJ. German Rivera "reg_sicbalr %#x\n" 62125e2bc1SJ. German Rivera "reg_sicbahr %#x\n" 63125e2bc1SJ. German Rivera "reg_sicapr %#x\n" 64125e2bc1SJ. German Rivera "reg_mcfbalr %#x\n" 65125e2bc1SJ. German Rivera "reg_mcfbahr %#x\n" 66125e2bc1SJ. German Rivera "reg_mcfapr %#x\n" 67125e2bc1SJ. German Rivera "reg_psr %#x\n", 68125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gcr1, 69125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gsr, 70125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbalr, 71125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbahr, 72125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicapr, 73125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbalr, 74125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbahr, 75125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfapr, 76125e2bc1SJ. German Rivera mc_ccsr_regs->reg_psr); 77125e2bc1SJ. German Rivera } 78125e2bc1SJ. German Rivera #else 79125e2bc1SJ. German Rivera 80125e2bc1SJ. German Rivera #define dump_ram_words(title, addr) 81125e2bc1SJ. German Rivera #define dump_mc_ccsr_regs(mc_ccsr_regs) 82125e2bc1SJ. German Rivera 83125e2bc1SJ. German Rivera #endif /* DEBUG */ 84125e2bc1SJ. German Rivera 85125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 867b3bd9a7SJ. German Rivera /** 877b3bd9a7SJ. German Rivera * Copying MC firmware or DPL image to DDR 887b3bd9a7SJ. German Rivera */ 897b3bd9a7SJ. German Rivera static int mc_copy_image(const char *title, 907b3bd9a7SJ. German Rivera u64 image_addr, u32 image_size, u64 mc_ram_addr) 917b3bd9a7SJ. German Rivera { 927b3bd9a7SJ. German Rivera debug("%s copied to address %p\n", title, (void *)mc_ram_addr); 937b3bd9a7SJ. German Rivera memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); 94125e2bc1SJ. German Rivera flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); 957b3bd9a7SJ. German Rivera return 0; 967b3bd9a7SJ. German Rivera } 977b3bd9a7SJ. German Rivera 987b3bd9a7SJ. German Rivera /** 997b3bd9a7SJ. German Rivera * MC firmware FIT image parser checks if the image is in FIT 1007b3bd9a7SJ. German Rivera * format, verifies integrity of the image and calculates 1017b3bd9a7SJ. German Rivera * raw image address and size values. 1027b3bd9a7SJ. German Rivera * Returns 0 on success and a negative errno on error. 1037b3bd9a7SJ. German Rivera * task fail. 1047b3bd9a7SJ. German Rivera **/ 105fb4a87a7SPrabhakar Kushwaha int parse_mc_firmware_fit_image(u64 mc_fw_addr, 106fb4a87a7SPrabhakar Kushwaha const void **raw_image_addr, 1077b3bd9a7SJ. German Rivera size_t *raw_image_size) 1087b3bd9a7SJ. German Rivera { 1097b3bd9a7SJ. German Rivera int format; 1107b3bd9a7SJ. German Rivera void *fit_hdr; 1117b3bd9a7SJ. German Rivera int node_offset; 1127b3bd9a7SJ. German Rivera const void *data; 1137b3bd9a7SJ. German Rivera size_t size; 1147b3bd9a7SJ. German Rivera const char *uname = "firmware"; 1157b3bd9a7SJ. German Rivera 116fb4a87a7SPrabhakar Kushwaha fit_hdr = (void *)mc_fw_addr; 1177b3bd9a7SJ. German Rivera 1187b3bd9a7SJ. German Rivera /* Check if Image is in FIT format */ 1197b3bd9a7SJ. German Rivera format = genimg_get_format(fit_hdr); 1207b3bd9a7SJ. German Rivera 1217b3bd9a7SJ. German Rivera if (format != IMAGE_FORMAT_FIT) { 122fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); 1237b3bd9a7SJ. German Rivera return -EINVAL; 1247b3bd9a7SJ. German Rivera } 1257b3bd9a7SJ. German Rivera 1267b3bd9a7SJ. German Rivera if (!fit_check_format(fit_hdr)) { 127fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); 1287b3bd9a7SJ. German Rivera return -EINVAL; 1297b3bd9a7SJ. German Rivera } 1307b3bd9a7SJ. German Rivera 1317b3bd9a7SJ. German Rivera node_offset = fit_image_get_node(fit_hdr, uname); 1327b3bd9a7SJ. German Rivera 1337b3bd9a7SJ. German Rivera if (node_offset < 0) { 134fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); 1357b3bd9a7SJ. German Rivera return -ENOENT; 1367b3bd9a7SJ. German Rivera } 1377b3bd9a7SJ. German Rivera 1387b3bd9a7SJ. German Rivera /* Verify MC firmware image */ 1397b3bd9a7SJ. German Rivera if (!(fit_image_verify(fit_hdr, node_offset))) { 140fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); 1417b3bd9a7SJ. German Rivera return -EINVAL; 1427b3bd9a7SJ. German Rivera } 1437b3bd9a7SJ. German Rivera 1447b3bd9a7SJ. German Rivera /* Get address and size of raw image */ 1457b3bd9a7SJ. German Rivera fit_image_get_data(fit_hdr, node_offset, &data, &size); 1467b3bd9a7SJ. German Rivera 1477b3bd9a7SJ. German Rivera *raw_image_addr = data; 1487b3bd9a7SJ. German Rivera *raw_image_size = size; 1497b3bd9a7SJ. German Rivera 1507b3bd9a7SJ. German Rivera return 0; 1517b3bd9a7SJ. German Rivera } 152125e2bc1SJ. German Rivera #endif 153125e2bc1SJ. German Rivera 154125e2bc1SJ. German Rivera /* 155125e2bc1SJ. German Rivera * Calculates the values to be used to specify the address range 156125e2bc1SJ. German Rivera * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers. 157125e2bc1SJ. German Rivera * It returns the highest 512MB-aligned address within the given 158125e2bc1SJ. German Rivera * address range, in '*aligned_base_addr', and the number of 256 MiB 159125e2bc1SJ. German Rivera * blocks in it, in 'num_256mb_blocks'. 160125e2bc1SJ. German Rivera */ 161125e2bc1SJ. German Rivera static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr, 162125e2bc1SJ. German Rivera size_t mc_ram_size, 163125e2bc1SJ. German Rivera u64 *aligned_base_addr, 164125e2bc1SJ. German Rivera u8 *num_256mb_blocks) 165125e2bc1SJ. German Rivera { 166125e2bc1SJ. German Rivera u64 addr; 167125e2bc1SJ. German Rivera u16 num_blocks; 168125e2bc1SJ. German Rivera 169125e2bc1SJ. German Rivera if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) { 170125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 171125e2bc1SJ. German Rivera mc_ram_size); 172125e2bc1SJ. German Rivera return -EINVAL; 173125e2bc1SJ. German Rivera } 174125e2bc1SJ. German Rivera 175125e2bc1SJ. German Rivera num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; 176125e2bc1SJ. German Rivera if (num_blocks < 1 || num_blocks > 0xff) { 177125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 178125e2bc1SJ. German Rivera mc_ram_size); 179125e2bc1SJ. German Rivera return -EINVAL; 180125e2bc1SJ. German Rivera } 181125e2bc1SJ. German Rivera 182125e2bc1SJ. German Rivera addr = (mc_private_ram_start_addr + mc_ram_size - 1) & 183125e2bc1SJ. German Rivera MC_RAM_BASE_ADDR_ALIGNMENT_MASK; 184125e2bc1SJ. German Rivera 185125e2bc1SJ. German Rivera if (addr < mc_private_ram_start_addr) { 186125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: bad start address %#llx\n", 187125e2bc1SJ. German Rivera mc_private_ram_start_addr); 188125e2bc1SJ. German Rivera return -EFAULT; 189125e2bc1SJ. German Rivera } 190125e2bc1SJ. German Rivera 191125e2bc1SJ. German Rivera *aligned_base_addr = addr; 192125e2bc1SJ. German Rivera *num_256mb_blocks = num_blocks; 193125e2bc1SJ. German Rivera return 0; 194125e2bc1SJ. German Rivera } 195125e2bc1SJ. German Rivera 19621c69870SStuart Yoder static int mc_fixup_dpc(u64 dpc_addr) 19721c69870SStuart Yoder { 19821c69870SStuart Yoder void *blob = (void *)dpc_addr; 19921c69870SStuart Yoder int nodeoffset; 20021c69870SStuart Yoder 20121c69870SStuart Yoder /* delete any existing ICID pools */ 20221c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); 20321c69870SStuart Yoder if (fdt_del_node(blob, nodeoffset) < 0) 20421c69870SStuart Yoder printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); 20521c69870SStuart Yoder 20621c69870SStuart Yoder /* add a new pool */ 20721c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources"); 20821c69870SStuart Yoder if (nodeoffset < 0) { 20921c69870SStuart Yoder printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); 21021c69870SStuart Yoder return -EINVAL; 21121c69870SStuart Yoder } 21221c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); 21321c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); 21421c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 21521c69870SStuart Yoder "base_icid", FSL_DPAA2_STREAM_ID_START, 1); 21621c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 21721c69870SStuart Yoder "num", 21821c69870SStuart Yoder FSL_DPAA2_STREAM_ID_END - 21921c69870SStuart Yoder FSL_DPAA2_STREAM_ID_START + 1, 1); 22021c69870SStuart Yoder 22121c69870SStuart Yoder flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); 22221c69870SStuart Yoder 22321c69870SStuart Yoder return 0; 22421c69870SStuart Yoder } 22521c69870SStuart Yoder 226fb4a87a7SPrabhakar Kushwaha static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) 227125e2bc1SJ. German Rivera { 228125e2bc1SJ. German Rivera u64 mc_dpc_offset; 229125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 230125e2bc1SJ. German Rivera int error; 231125e2bc1SJ. German Rivera void *dpc_fdt_hdr; 232125e2bc1SJ. German Rivera int dpc_size; 233125e2bc1SJ. German Rivera #endif 234125e2bc1SJ. German Rivera 235125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 236125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || 237125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); 238125e2bc1SJ. German Rivera 239125e2bc1SJ. German Rivera mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; 240125e2bc1SJ. German Rivera #else 241125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" 242125e2bc1SJ. German Rivera #endif 243125e2bc1SJ. German Rivera 244125e2bc1SJ. German Rivera /* 245125e2bc1SJ. German Rivera * Load the MC DPC blob in the MC private DRAM block: 246125e2bc1SJ. German Rivera */ 247125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 248125e2bc1SJ. German Rivera printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); 249125e2bc1SJ. German Rivera #else 250125e2bc1SJ. German Rivera /* 251125e2bc1SJ. German Rivera * Get address and size of the DPC blob stored in flash: 252125e2bc1SJ. German Rivera */ 253fb4a87a7SPrabhakar Kushwaha dpc_fdt_hdr = (void *)mc_dpc_addr; 254125e2bc1SJ. German Rivera 255125e2bc1SJ. German Rivera error = fdt_check_header(dpc_fdt_hdr); 256125e2bc1SJ. German Rivera if (error != 0) { 257125e2bc1SJ. German Rivera /* 258125e2bc1SJ. German Rivera * Don't return with error here, since the MC firmware can 259125e2bc1SJ. German Rivera * still boot without a DPC 260125e2bc1SJ. German Rivera */ 261cc088c3aSJ. German Rivera printf("\nfsl-mc: WARNING: No DPC image found"); 262125e2bc1SJ. German Rivera return 0; 263125e2bc1SJ. German Rivera } 264125e2bc1SJ. German Rivera 265125e2bc1SJ. German Rivera dpc_size = fdt_totalsize(dpc_fdt_hdr); 266125e2bc1SJ. German Rivera if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { 267cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", 268125e2bc1SJ. German Rivera dpc_size); 269125e2bc1SJ. German Rivera return -EINVAL; 270125e2bc1SJ. German Rivera } 271125e2bc1SJ. German Rivera 272125e2bc1SJ. German Rivera mc_copy_image("MC DPC blob", 273125e2bc1SJ. German Rivera (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); 274125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ 275125e2bc1SJ. German Rivera 27621c69870SStuart Yoder if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) 27721c69870SStuart Yoder return -EINVAL; 27821c69870SStuart Yoder 279125e2bc1SJ. German Rivera dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); 280125e2bc1SJ. German Rivera return 0; 281125e2bc1SJ. German Rivera } 282125e2bc1SJ. German Rivera 283fb4a87a7SPrabhakar Kushwaha static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) 284125e2bc1SJ. German Rivera { 285125e2bc1SJ. German Rivera u64 mc_dpl_offset; 286125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR 287125e2bc1SJ. German Rivera int error; 288125e2bc1SJ. German Rivera void *dpl_fdt_hdr; 289125e2bc1SJ. German Rivera int dpl_size; 290125e2bc1SJ. German Rivera #endif 291125e2bc1SJ. German Rivera 292125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 293125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || 294125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); 295125e2bc1SJ. German Rivera 296125e2bc1SJ. German Rivera mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; 297125e2bc1SJ. German Rivera #else 298125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" 299125e2bc1SJ. German Rivera #endif 300125e2bc1SJ. German Rivera 301125e2bc1SJ. German Rivera /* 302125e2bc1SJ. German Rivera * Load the MC DPL blob in the MC private DRAM block: 303125e2bc1SJ. German Rivera */ 304125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR 305125e2bc1SJ. German Rivera printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); 306125e2bc1SJ. German Rivera #else 307125e2bc1SJ. German Rivera /* 308125e2bc1SJ. German Rivera * Get address and size of the DPL blob stored in flash: 309125e2bc1SJ. German Rivera */ 310fb4a87a7SPrabhakar Kushwaha dpl_fdt_hdr = (void *)mc_dpl_addr; 311125e2bc1SJ. German Rivera 312125e2bc1SJ. German Rivera error = fdt_check_header(dpl_fdt_hdr); 313125e2bc1SJ. German Rivera if (error != 0) { 314cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); 315125e2bc1SJ. German Rivera return error; 316125e2bc1SJ. German Rivera } 317125e2bc1SJ. German Rivera 318125e2bc1SJ. German Rivera dpl_size = fdt_totalsize(dpl_fdt_hdr); 319125e2bc1SJ. German Rivera if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { 320cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", 321125e2bc1SJ. German Rivera dpl_size); 322125e2bc1SJ. German Rivera return -EINVAL; 323125e2bc1SJ. German Rivera } 324125e2bc1SJ. German Rivera 325125e2bc1SJ. German Rivera mc_copy_image("MC DPL blob", 326125e2bc1SJ. German Rivera (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); 327125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ 328125e2bc1SJ. German Rivera 329125e2bc1SJ. German Rivera dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); 330125e2bc1SJ. German Rivera return 0; 331125e2bc1SJ. German Rivera } 332125e2bc1SJ. German Rivera 333125e2bc1SJ. German Rivera /** 334125e2bc1SJ. German Rivera * Return the MC boot timeout value in milliseconds 335125e2bc1SJ. German Rivera */ 336125e2bc1SJ. German Rivera static unsigned long get_mc_boot_timeout_ms(void) 337125e2bc1SJ. German Rivera { 338125e2bc1SJ. German Rivera unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 339125e2bc1SJ. German Rivera 340125e2bc1SJ. German Rivera char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR); 341125e2bc1SJ. German Rivera 342125e2bc1SJ. German Rivera if (timeout_ms_env_var) { 343125e2bc1SJ. German Rivera timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); 344125e2bc1SJ. German Rivera if (timeout_ms == 0) { 345125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 346125e2bc1SJ. German Rivera MC_BOOT_TIMEOUT_ENV_VAR 347125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 348125e2bc1SJ. German Rivera timeout_ms); 349125e2bc1SJ. German Rivera 350125e2bc1SJ. German Rivera timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 351125e2bc1SJ. German Rivera } 352125e2bc1SJ. German Rivera } 353125e2bc1SJ. German Rivera 354125e2bc1SJ. German Rivera return timeout_ms; 355125e2bc1SJ. German Rivera } 356125e2bc1SJ. German Rivera 357fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 358fb4a87a7SPrabhakar Kushwaha static int load_mc_aiop_img(u64 aiop_fw_addr) 359c1000c12SJ. German Rivera { 360fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 361fb4a87a7SPrabhakar Kushwaha #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 362c1000c12SJ. German Rivera void *aiop_img; 363fb4a87a7SPrabhakar Kushwaha #endif 364c1000c12SJ. German Rivera 365c1000c12SJ. German Rivera /* 366c1000c12SJ. German Rivera * Load the MC AIOP image in the MC private DRAM block: 367c1000c12SJ. German Rivera */ 368c1000c12SJ. German Rivera 369fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 370fb4a87a7SPrabhakar Kushwaha printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr + 371fb4a87a7SPrabhakar Kushwaha CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 372fb4a87a7SPrabhakar Kushwaha #else 373fb4a87a7SPrabhakar Kushwaha aiop_img = (void *)aiop_fw_addr; 374c1000c12SJ. German Rivera mc_copy_image("MC AIOP image", 375c1000c12SJ. German Rivera (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, 376c1000c12SJ. German Rivera mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 377fb4a87a7SPrabhakar Kushwaha #endif 378fb4a87a7SPrabhakar Kushwaha mc_aiop_applied = 0; 379c1000c12SJ. German Rivera 380c1000c12SJ. German Rivera return 0; 381c1000c12SJ. German Rivera } 382c1000c12SJ. German Rivera #endif 383fb4a87a7SPrabhakar Kushwaha 384125e2bc1SJ. German Rivera static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) 385125e2bc1SJ. German Rivera { 386125e2bc1SJ. German Rivera u32 reg_gsr; 387125e2bc1SJ. German Rivera u32 mc_fw_boot_status; 388125e2bc1SJ. German Rivera unsigned long timeout_ms = get_mc_boot_timeout_ms(); 389125e2bc1SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 390125e2bc1SJ. German Rivera 391125e2bc1SJ. German Rivera dmb(); 392125e2bc1SJ. German Rivera assert(timeout_ms > 0); 393125e2bc1SJ. German Rivera for (;;) { 394125e2bc1SJ. German Rivera udelay(1000); /* throttle polling */ 395125e2bc1SJ. German Rivera reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); 396125e2bc1SJ. German Rivera mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); 397125e2bc1SJ. German Rivera if (mc_fw_boot_status & 0x1) 398125e2bc1SJ. German Rivera break; 399125e2bc1SJ. German Rivera 400125e2bc1SJ. German Rivera timeout_ms--; 401125e2bc1SJ. German Rivera if (timeout_ms == 0) 402125e2bc1SJ. German Rivera break; 403125e2bc1SJ. German Rivera } 404125e2bc1SJ. German Rivera 405125e2bc1SJ. German Rivera if (timeout_ms == 0) { 406cc088c3aSJ. German Rivera printf("ERROR: timeout\n"); 407125e2bc1SJ. German Rivera 408125e2bc1SJ. German Rivera /* TODO: Get an error status from an MC CCSR register */ 409125e2bc1SJ. German Rivera return -ETIMEDOUT; 410125e2bc1SJ. German Rivera } 411125e2bc1SJ. German Rivera 412125e2bc1SJ. German Rivera if (mc_fw_boot_status != 0x1) { 413125e2bc1SJ. German Rivera /* 414125e2bc1SJ. German Rivera * TODO: Identify critical errors from the GSR register's FS 415125e2bc1SJ. German Rivera * field and for those errors, set error to -ENODEV or other 416125e2bc1SJ. German Rivera * appropriate errno, so that the status property is set to 417125e2bc1SJ. German Rivera * failure in the fsl,dprc device tree node. 418125e2bc1SJ. German Rivera */ 419cc088c3aSJ. German Rivera printf("WARNING: Firmware returned an error (GSR: %#x)\n", 420125e2bc1SJ. German Rivera reg_gsr); 421125e2bc1SJ. German Rivera } else { 422cc088c3aSJ. German Rivera printf("SUCCESS\n"); 423125e2bc1SJ. German Rivera } 424cc088c3aSJ. German Rivera 425125e2bc1SJ. German Rivera 426125e2bc1SJ. German Rivera *final_reg_gsr = reg_gsr; 427125e2bc1SJ. German Rivera return 0; 428125e2bc1SJ. German Rivera } 4297b3bd9a7SJ. German Rivera 430fb4a87a7SPrabhakar Kushwaha int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) 4317b3bd9a7SJ. German Rivera { 4327b3bd9a7SJ. German Rivera int error = 0; 433a2a55e51SPrabhakar Kushwaha int portal_id = 0; 4347b3bd9a7SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 435fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 4367b3bd9a7SJ. German Rivera u32 reg_gsr; 437125e2bc1SJ. German Rivera u32 reg_mcfbalr; 438125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 4397b3bd9a7SJ. German Rivera const void *raw_image_addr; 4407b3bd9a7SJ. German Rivera size_t raw_image_size = 0; 441125e2bc1SJ. German Rivera #endif 4427b3bd9a7SJ. German Rivera struct mc_version mc_ver_info; 443125e2bc1SJ. German Rivera u64 mc_ram_aligned_base_addr; 444125e2bc1SJ. German Rivera u8 mc_ram_num_256mb_blocks; 445125e2bc1SJ. German Rivera size_t mc_ram_size = mc_get_dram_block_size(); 4467b3bd9a7SJ. German Rivera 4477b3bd9a7SJ. German Rivera 448125e2bc1SJ. German Rivera error = calculate_mc_private_ram_params(mc_ram_addr, 449125e2bc1SJ. German Rivera mc_ram_size, 450125e2bc1SJ. German Rivera &mc_ram_aligned_base_addr, 451125e2bc1SJ. German Rivera &mc_ram_num_256mb_blocks); 452125e2bc1SJ. German Rivera if (error != 0) 453125e2bc1SJ. German Rivera goto out; 454125e2bc1SJ. German Rivera 4557b3bd9a7SJ. German Rivera /* 4567b3bd9a7SJ. German Rivera * Management Complex cores should be held at reset out of POR. 4577b3bd9a7SJ. German Rivera * U-boot should be the first software to touch MC. To be safe, 4587b3bd9a7SJ. German Rivera * we reset all cores again by setting GCR1 to 0. It doesn't do 4597b3bd9a7SJ. German Rivera * anything if they are held at reset. After we setup the firmware 4607b3bd9a7SJ. German Rivera * we kick off MC by deasserting the reset bit for core 0, and 4617b3bd9a7SJ. German Rivera * deasserting the reset bits for Command Portal Managers. 4627b3bd9a7SJ. German Rivera * The stop bits are not touched here. They are used to stop the 4637b3bd9a7SJ. German Rivera * cores when they are active. Setting stop bits doesn't stop the 4647b3bd9a7SJ. German Rivera * cores from fetching instructions when they are released from 4657b3bd9a7SJ. German Rivera * reset. 4667b3bd9a7SJ. German Rivera */ 4677b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, 0); 4687b3bd9a7SJ. German Rivera dmb(); 4697b3bd9a7SJ. German Rivera 470125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR 471125e2bc1SJ. German Rivera printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); 472125e2bc1SJ. German Rivera #else 473fb4a87a7SPrabhakar Kushwaha error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr, 474fb4a87a7SPrabhakar Kushwaha &raw_image_size); 4757b3bd9a7SJ. German Rivera if (error != 0) 4767b3bd9a7SJ. German Rivera goto out; 4777b3bd9a7SJ. German Rivera /* 4787b3bd9a7SJ. German Rivera * Load the MC FW at the beginning of the MC private DRAM block: 4797b3bd9a7SJ. German Rivera */ 4807b3bd9a7SJ. German Rivera mc_copy_image("MC Firmware", 4817b3bd9a7SJ. German Rivera (u64)raw_image_addr, raw_image_size, mc_ram_addr); 4827b3bd9a7SJ. German Rivera #endif 483125e2bc1SJ. German Rivera dump_ram_words("firmware", (void *)mc_ram_addr); 4847b3bd9a7SJ. German Rivera 485fb4a87a7SPrabhakar Kushwaha error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr); 486125e2bc1SJ. German Rivera if (error != 0) 4877b3bd9a7SJ. German Rivera goto out; 4887b3bd9a7SJ. German Rivera 4897b3bd9a7SJ. German Rivera debug("mc_ccsr_regs %p\n", mc_ccsr_regs); 490125e2bc1SJ. German Rivera dump_mc_ccsr_regs(mc_ccsr_regs); 4917b3bd9a7SJ. German Rivera 4927b3bd9a7SJ. German Rivera /* 493125e2bc1SJ. German Rivera * Tell MC what is the address range of the DRAM block assigned to it: 4947b3bd9a7SJ. German Rivera */ 495125e2bc1SJ. German Rivera reg_mcfbalr = (u32)mc_ram_aligned_base_addr | 496125e2bc1SJ. German Rivera (mc_ram_num_256mb_blocks - 1); 497125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); 498125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbahr, 499125e2bc1SJ. German Rivera (u32)(mc_ram_aligned_base_addr >> 32)); 50039da644eSStuart Yoder out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); 5017b3bd9a7SJ. German Rivera 5027b3bd9a7SJ. German Rivera /* 503125e2bc1SJ. German Rivera * Tell the MC that we want delayed DPL deployment. 5047b3bd9a7SJ. German Rivera */ 505125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); 5067b3bd9a7SJ. German Rivera 507cc088c3aSJ. German Rivera printf("\nfsl-mc: Booting Management Complex ... "); 5087b3bd9a7SJ. German Rivera 5097b3bd9a7SJ. German Rivera /* 5107b3bd9a7SJ. German Rivera * Deassert reset and release MC core 0 to run 5117b3bd9a7SJ. German Rivera */ 5127b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); 513125e2bc1SJ. German Rivera error = wait_for_mc(true, ®_gsr); 514125e2bc1SJ. German Rivera if (error != 0) 5157b3bd9a7SJ. German Rivera goto out; 5167b3bd9a7SJ. German Rivera 5177b3bd9a7SJ. German Rivera /* 5187b3bd9a7SJ. German Rivera * TODO: need to obtain the portal_id for the root container from the 5197b3bd9a7SJ. German Rivera * DPL 5207b3bd9a7SJ. German Rivera */ 5217b3bd9a7SJ. German Rivera portal_id = 0; 5227b3bd9a7SJ. German Rivera 5237b3bd9a7SJ. German Rivera /* 524a2a55e51SPrabhakar Kushwaha * Initialize the global default MC portal 525a2a55e51SPrabhakar Kushwaha * And check that the MC firmware is responding portal commands: 5267b3bd9a7SJ. German Rivera */ 5271730a17dSPrabhakar Kushwaha root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 5281730a17dSPrabhakar Kushwaha if (!root_mc_io) { 529a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 530a2a55e51SPrabhakar Kushwaha return -ENOMEM; 531a2a55e51SPrabhakar Kushwaha } 5327b3bd9a7SJ. German Rivera 5331730a17dSPrabhakar Kushwaha root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); 534a2a55e51SPrabhakar Kushwaha debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", 5351730a17dSPrabhakar Kushwaha portal_id, root_mc_io->mmio_regs); 536a2a55e51SPrabhakar Kushwaha 5371730a17dSPrabhakar Kushwaha error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); 5387b3bd9a7SJ. German Rivera if (error != 0) { 5397b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", 5407b3bd9a7SJ. German Rivera error); 5417b3bd9a7SJ. German Rivera goto out; 5427b3bd9a7SJ. German Rivera } 5437b3bd9a7SJ. German Rivera 5447b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 5457b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 546125e2bc1SJ. German Rivera reg_gsr & GSR_FS_MASK); 547125e2bc1SJ. German Rivera 5487b3bd9a7SJ. German Rivera out: 5497b3bd9a7SJ. German Rivera if (error != 0) 5502b7c4a19SPrabhakar Kushwaha mc_boot_status = error; 5517b3bd9a7SJ. German Rivera else 5527b3bd9a7SJ. German Rivera mc_boot_status = 0; 5537b3bd9a7SJ. German Rivera 5547b3bd9a7SJ. German Rivera return error; 5557b3bd9a7SJ. German Rivera } 5567b3bd9a7SJ. German Rivera 557fb4a87a7SPrabhakar Kushwaha int mc_apply_dpl(u64 mc_dpl_addr) 558fb4a87a7SPrabhakar Kushwaha { 559fb4a87a7SPrabhakar Kushwaha struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 560fb4a87a7SPrabhakar Kushwaha int error = 0; 561fb4a87a7SPrabhakar Kushwaha u32 reg_gsr; 562fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 563fb4a87a7SPrabhakar Kushwaha size_t mc_ram_size = mc_get_dram_block_size(); 564fb4a87a7SPrabhakar Kushwaha 565fb4a87a7SPrabhakar Kushwaha error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); 566fb4a87a7SPrabhakar Kushwaha if (error != 0) 567fb4a87a7SPrabhakar Kushwaha return error; 568fb4a87a7SPrabhakar Kushwaha 569fb4a87a7SPrabhakar Kushwaha /* 570fb4a87a7SPrabhakar Kushwaha * Tell the MC to deploy the DPL: 571fb4a87a7SPrabhakar Kushwaha */ 572fb4a87a7SPrabhakar Kushwaha out_le32(&mc_ccsr_regs->reg_gsr, 0x0); 573fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout ... "); 574fb4a87a7SPrabhakar Kushwaha error = wait_for_mc(false, ®_gsr); 575fb4a87a7SPrabhakar Kushwaha 576fb4a87a7SPrabhakar Kushwaha if (!error) 577fb4a87a7SPrabhakar Kushwaha mc_dpl_applied = 0; 578fb4a87a7SPrabhakar Kushwaha 579fb4a87a7SPrabhakar Kushwaha return error; 580fb4a87a7SPrabhakar Kushwaha } 581fb4a87a7SPrabhakar Kushwaha 5827b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 5837b3bd9a7SJ. German Rivera { 5847b3bd9a7SJ. German Rivera return mc_boot_status; 5857b3bd9a7SJ. German Rivera } 5867b3bd9a7SJ. German Rivera 587fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 588fb4a87a7SPrabhakar Kushwaha int get_aiop_apply_status(void) 589fb4a87a7SPrabhakar Kushwaha { 590fb4a87a7SPrabhakar Kushwaha return mc_aiop_applied; 591fb4a87a7SPrabhakar Kushwaha } 592fb4a87a7SPrabhakar Kushwaha #endif 593fb4a87a7SPrabhakar Kushwaha 594fb4a87a7SPrabhakar Kushwaha int get_dpl_apply_status(void) 595fb4a87a7SPrabhakar Kushwaha { 596fb4a87a7SPrabhakar Kushwaha return mc_dpl_applied; 597fb4a87a7SPrabhakar Kushwaha } 598fb4a87a7SPrabhakar Kushwaha 599fb4a87a7SPrabhakar Kushwaha /** 600fb4a87a7SPrabhakar Kushwaha * Return the MC address of private DRAM block. 601fb4a87a7SPrabhakar Kushwaha */ 602fb4a87a7SPrabhakar Kushwaha u64 mc_get_dram_addr(void) 603fb4a87a7SPrabhakar Kushwaha { 604fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr; 605fb4a87a7SPrabhakar Kushwaha 606fb4a87a7SPrabhakar Kushwaha /* 607fb4a87a7SPrabhakar Kushwaha * The MC private DRAM block was already carved at the end of DRAM 608fb4a87a7SPrabhakar Kushwaha * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: 609fb4a87a7SPrabhakar Kushwaha */ 610fb4a87a7SPrabhakar Kushwaha if (gd->bd->bi_dram[1].start) { 611fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 612fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; 613fb4a87a7SPrabhakar Kushwaha } else { 614fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 615fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; 616fb4a87a7SPrabhakar Kushwaha } 617fb4a87a7SPrabhakar Kushwaha 618fb4a87a7SPrabhakar Kushwaha return mc_ram_addr; 619fb4a87a7SPrabhakar Kushwaha } 620fb4a87a7SPrabhakar Kushwaha 6217b3bd9a7SJ. German Rivera /** 6227b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 6237b3bd9a7SJ. German Rivera */ 6247b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 6257b3bd9a7SJ. German Rivera { 626125e2bc1SJ. German Rivera unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 627125e2bc1SJ. German Rivera 628125e2bc1SJ. German Rivera char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); 629125e2bc1SJ. German Rivera 630125e2bc1SJ. German Rivera if (dram_block_size_env_var) { 631125e2bc1SJ. German Rivera dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, 632125e2bc1SJ. German Rivera 10); 633125e2bc1SJ. German Rivera 634125e2bc1SJ. German Rivera if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { 635125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 636125e2bc1SJ. German Rivera MC_MEM_SIZE_ENV_VAR 637125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 638125e2bc1SJ. German Rivera dram_block_size); 639125e2bc1SJ. German Rivera 640125e2bc1SJ. German Rivera dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 641125e2bc1SJ. German Rivera } 642125e2bc1SJ. German Rivera } 643125e2bc1SJ. German Rivera 644125e2bc1SJ. German Rivera return dram_block_size; 6457b3bd9a7SJ. German Rivera } 646a2a55e51SPrabhakar Kushwaha 6471730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 6481730a17dSPrabhakar Kushwaha { 649c919ab9eSPrabhakar Kushwaha int i; 650c919ab9eSPrabhakar Kushwaha 651c919ab9eSPrabhakar Kushwaha for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) 652c919ab9eSPrabhakar Kushwaha if ((wriop_is_enabled_dpmac(i) == 1) && 653c919ab9eSPrabhakar Kushwaha (wriop_get_phy_address(i) != -1)) 654c919ab9eSPrabhakar Kushwaha ldpaa_eth_init(i, wriop_get_enet_if(i)); 6551730a17dSPrabhakar Kushwaha return 0; 6561730a17dSPrabhakar Kushwaha } 6571730a17dSPrabhakar Kushwaha 658*9a696f56SPrabhakar Kushwaha static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle) 659*9a696f56SPrabhakar Kushwaha { 660*9a696f56SPrabhakar Kushwaha struct dprc_attributes attr; 661*9a696f56SPrabhakar Kushwaha int error; 662*9a696f56SPrabhakar Kushwaha 663*9a696f56SPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dprc_attributes)); 664*9a696f56SPrabhakar Kushwaha error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr); 665*9a696f56SPrabhakar Kushwaha if (error == 0) { 666*9a696f56SPrabhakar Kushwaha if ((attr.version.major != DPRC_VER_MAJOR) || 667*9a696f56SPrabhakar Kushwaha (attr.version.minor != DPRC_VER_MINOR)) { 668*9a696f56SPrabhakar Kushwaha printf("DPRC version mismatch found %u.%u,", 669*9a696f56SPrabhakar Kushwaha attr.version.major, 670*9a696f56SPrabhakar Kushwaha attr.version.minor); 671*9a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 672*9a696f56SPrabhakar Kushwaha DPRC_VER_MAJOR, DPRC_VER_MINOR); 673*9a696f56SPrabhakar Kushwaha } 674*9a696f56SPrabhakar Kushwaha } 675*9a696f56SPrabhakar Kushwaha return error; 676*9a696f56SPrabhakar Kushwaha } 677*9a696f56SPrabhakar Kushwaha 6781730a17dSPrabhakar Kushwaha static int dpio_init(void) 679a2a55e51SPrabhakar Kushwaha { 680a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 681a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 6821730a17dSPrabhakar Kushwaha struct dpio_cfg dpio_cfg; 683a2a55e51SPrabhakar Kushwaha int err = 0; 684a2a55e51SPrabhakar Kushwaha 685a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 686a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 687a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 6881730a17dSPrabhakar Kushwaha err = -ENOMEM; 6891730a17dSPrabhakar Kushwaha goto err_malloc; 690a2a55e51SPrabhakar Kushwaha } 691a2a55e51SPrabhakar Kushwaha 6921730a17dSPrabhakar Kushwaha dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; 6931730a17dSPrabhakar Kushwaha dpio_cfg.num_priorities = 8; 694a2a55e51SPrabhakar Kushwaha 6951730a17dSPrabhakar Kushwaha err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, 6961730a17dSPrabhakar Kushwaha &dflt_dpio->dpio_handle); 6971730a17dSPrabhakar Kushwaha if (err < 0) { 6981730a17dSPrabhakar Kushwaha printf("dpio_create() failed: %d\n", err); 6991730a17dSPrabhakar Kushwaha err = -ENODEV; 7001730a17dSPrabhakar Kushwaha goto err_create; 701a2a55e51SPrabhakar Kushwaha } 702a2a55e51SPrabhakar Kushwaha 7031730a17dSPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dpio_attr)); 70487457d11SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 7051730a17dSPrabhakar Kushwaha dflt_dpio->dpio_handle, &attr); 7061730a17dSPrabhakar Kushwaha if (err < 0) { 7071730a17dSPrabhakar Kushwaha printf("dpio_get_attributes() failed: %d\n", err); 708a2a55e51SPrabhakar Kushwaha goto err_get_attr; 709a2a55e51SPrabhakar Kushwaha } 710a2a55e51SPrabhakar Kushwaha 711*9a696f56SPrabhakar Kushwaha if ((attr.version.major != DPIO_VER_MAJOR) || 712*9a696f56SPrabhakar Kushwaha (attr.version.minor != DPIO_VER_MINOR)) { 713*9a696f56SPrabhakar Kushwaha printf("DPIO version mismatch found %u.%u,", 714*9a696f56SPrabhakar Kushwaha attr.version.major, attr.version.minor); 715*9a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 716*9a696f56SPrabhakar Kushwaha DPIO_VER_MAJOR, DPIO_VER_MINOR); 717*9a696f56SPrabhakar Kushwaha } 718*9a696f56SPrabhakar Kushwaha 7191730a17dSPrabhakar Kushwaha dflt_dpio->dpio_id = attr.id; 7201730a17dSPrabhakar Kushwaha #ifdef DEBUG 7211730a17dSPrabhakar Kushwaha printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); 7221730a17dSPrabhakar Kushwaha #endif 7231730a17dSPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7241730a17dSPrabhakar Kushwaha if (err < 0) { 725a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 726a2a55e51SPrabhakar Kushwaha goto err_get_enable; 727a2a55e51SPrabhakar Kushwaha } 7281f1c25c7SPrabhakar Kushwaha debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", 7291f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ce_offset, 7301f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ci_offset, 731a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 732a2a55e51SPrabhakar Kushwaha attr.num_priorities); 733a2a55e51SPrabhakar Kushwaha 7341f1c25c7SPrabhakar Kushwaha p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7351f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ce_offset); 7361f1c25c7SPrabhakar Kushwaha p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7371f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ci_offset); 738a2a55e51SPrabhakar Kushwaha 739a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 740a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 741a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 742a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 743a2a55e51SPrabhakar Kushwaha } 744a2a55e51SPrabhakar Kushwaha return 0; 745a2a55e51SPrabhakar Kushwaha 746a2a55e51SPrabhakar Kushwaha err_get_swp_init: 7471730a17dSPrabhakar Kushwaha dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 748a2a55e51SPrabhakar Kushwaha err_get_enable: 749a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 7501730a17dSPrabhakar Kushwaha err_get_attr: 7511730a17dSPrabhakar Kushwaha dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7521730a17dSPrabhakar Kushwaha dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7531730a17dSPrabhakar Kushwaha err_create: 7541730a17dSPrabhakar Kushwaha err_malloc: 755a2a55e51SPrabhakar Kushwaha return err; 756a2a55e51SPrabhakar Kushwaha } 757a2a55e51SPrabhakar Kushwaha 7581730a17dSPrabhakar Kushwaha static int dpio_exit(void) 759a2a55e51SPrabhakar Kushwaha { 7601730a17dSPrabhakar Kushwaha int err; 7611730a17dSPrabhakar Kushwaha 7621730a17dSPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7631730a17dSPrabhakar Kushwaha if (err < 0) { 7641730a17dSPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 7651730a17dSPrabhakar Kushwaha goto err; 7661730a17dSPrabhakar Kushwaha } 7671730a17dSPrabhakar Kushwaha 7681730a17dSPrabhakar Kushwaha err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7691730a17dSPrabhakar Kushwaha if (err < 0) { 7701730a17dSPrabhakar Kushwaha printf("dpio_destroy() failed: %d\n", err); 7711730a17dSPrabhakar Kushwaha goto err; 7721730a17dSPrabhakar Kushwaha } 7731730a17dSPrabhakar Kushwaha 7741730a17dSPrabhakar Kushwaha #ifdef DEBUG 7751730a17dSPrabhakar Kushwaha printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); 7761730a17dSPrabhakar Kushwaha #endif 7771730a17dSPrabhakar Kushwaha 7781730a17dSPrabhakar Kushwaha if (dflt_dpio) 7791730a17dSPrabhakar Kushwaha free(dflt_dpio); 7801730a17dSPrabhakar Kushwaha 7811730a17dSPrabhakar Kushwaha return 0; 7821730a17dSPrabhakar Kushwaha err: 7831730a17dSPrabhakar Kushwaha return err; 7841730a17dSPrabhakar Kushwaha } 7851730a17dSPrabhakar Kushwaha 7861730a17dSPrabhakar Kushwaha static int dprc_init(void) 7871730a17dSPrabhakar Kushwaha { 7881730a17dSPrabhakar Kushwaha int err, child_portal_id, container_id; 7891730a17dSPrabhakar Kushwaha struct dprc_cfg cfg; 7901730a17dSPrabhakar Kushwaha uint64_t mc_portal_offset; 7911730a17dSPrabhakar Kushwaha 7921730a17dSPrabhakar Kushwaha /* Open root container */ 7931730a17dSPrabhakar Kushwaha err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); 7941730a17dSPrabhakar Kushwaha if (err < 0) { 7951730a17dSPrabhakar Kushwaha printf("dprc_get_container_id(): Root failed: %d\n", err); 7961730a17dSPrabhakar Kushwaha goto err_root_container_id; 7971730a17dSPrabhakar Kushwaha } 7981730a17dSPrabhakar Kushwaha 7991730a17dSPrabhakar Kushwaha #ifdef DEBUG 8001730a17dSPrabhakar Kushwaha printf("Root container id = %d\n", container_id); 8011730a17dSPrabhakar Kushwaha #endif 8021730a17dSPrabhakar Kushwaha err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, 8031730a17dSPrabhakar Kushwaha &root_dprc_handle); 8041730a17dSPrabhakar Kushwaha if (err < 0) { 8051730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container failed: %d\n", err); 8061730a17dSPrabhakar Kushwaha goto err_root_open; 8071730a17dSPrabhakar Kushwaha } 8081730a17dSPrabhakar Kushwaha 8091730a17dSPrabhakar Kushwaha if (!root_dprc_handle) { 8101730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container Handle is not valid\n"); 8111730a17dSPrabhakar Kushwaha goto err_root_open; 8121730a17dSPrabhakar Kushwaha } 8131730a17dSPrabhakar Kushwaha 814*9a696f56SPrabhakar Kushwaha err = dprc_version_check(root_mc_io, root_dprc_handle); 815*9a696f56SPrabhakar Kushwaha if (err < 0) { 816*9a696f56SPrabhakar Kushwaha printf("dprc_version_check() failed: %d\n", err); 817*9a696f56SPrabhakar Kushwaha goto err_root_open; 818*9a696f56SPrabhakar Kushwaha } 819*9a696f56SPrabhakar Kushwaha 8201730a17dSPrabhakar Kushwaha cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | 8211730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | 8221730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_ALLOC_ALLOWED; 8231730a17dSPrabhakar Kushwaha cfg.icid = DPRC_GET_ICID_FROM_POOL; 8241730a17dSPrabhakar Kushwaha cfg.portal_id = 250; 8251730a17dSPrabhakar Kushwaha err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, 8261730a17dSPrabhakar Kushwaha root_dprc_handle, 8271730a17dSPrabhakar Kushwaha &cfg, 8281730a17dSPrabhakar Kushwaha &child_dprc_id, 8291730a17dSPrabhakar Kushwaha &mc_portal_offset); 8301730a17dSPrabhakar Kushwaha if (err < 0) { 8311730a17dSPrabhakar Kushwaha printf("dprc_create_container() failed: %d\n", err); 8321730a17dSPrabhakar Kushwaha goto err_create; 8331730a17dSPrabhakar Kushwaha } 8341730a17dSPrabhakar Kushwaha 8351730a17dSPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 8361730a17dSPrabhakar Kushwaha if (!dflt_mc_io) { 8371730a17dSPrabhakar Kushwaha err = -ENOMEM; 8381730a17dSPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 8391730a17dSPrabhakar Kushwaha goto err_malloc; 8401730a17dSPrabhakar Kushwaha } 8411730a17dSPrabhakar Kushwaha 8421730a17dSPrabhakar Kushwaha child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); 8431730a17dSPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); 8441730a17dSPrabhakar Kushwaha #ifdef DEBUG 8451730a17dSPrabhakar Kushwaha printf("MC portal of child DPRC container: %d, physical addr %p)\n", 8461730a17dSPrabhakar Kushwaha child_dprc_id, dflt_mc_io->mmio_regs); 8471730a17dSPrabhakar Kushwaha #endif 8481730a17dSPrabhakar Kushwaha 8491730a17dSPrabhakar Kushwaha err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, 8501730a17dSPrabhakar Kushwaha &dflt_dprc_handle); 8511730a17dSPrabhakar Kushwaha if (err < 0) { 8521730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container failed: %d\n", err); 8531730a17dSPrabhakar Kushwaha goto err_child_open; 8541730a17dSPrabhakar Kushwaha } 8551730a17dSPrabhakar Kushwaha 8561730a17dSPrabhakar Kushwaha if (!dflt_dprc_handle) { 8571730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container Handle is not valid\n"); 8581730a17dSPrabhakar Kushwaha goto err_child_open; 8591730a17dSPrabhakar Kushwaha } 8601730a17dSPrabhakar Kushwaha 8611730a17dSPrabhakar Kushwaha return 0; 8621730a17dSPrabhakar Kushwaha err_child_open: 8631730a17dSPrabhakar Kushwaha free(dflt_mc_io); 8641730a17dSPrabhakar Kushwaha err_malloc: 8651730a17dSPrabhakar Kushwaha dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 8661730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 8671730a17dSPrabhakar Kushwaha err_create: 8681730a17dSPrabhakar Kushwaha dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 8691730a17dSPrabhakar Kushwaha err_root_open: 8701730a17dSPrabhakar Kushwaha err_root_container_id: 8711730a17dSPrabhakar Kushwaha return err; 8721730a17dSPrabhakar Kushwaha } 8731730a17dSPrabhakar Kushwaha 8741730a17dSPrabhakar Kushwaha static int dprc_exit(void) 8751730a17dSPrabhakar Kushwaha { 8761730a17dSPrabhakar Kushwaha int err; 8771730a17dSPrabhakar Kushwaha 8781730a17dSPrabhakar Kushwaha err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); 8791730a17dSPrabhakar Kushwaha if (err < 0) { 8801730a17dSPrabhakar Kushwaha printf("dprc_close(): Child failed: %d\n", err); 8811730a17dSPrabhakar Kushwaha goto err; 8821730a17dSPrabhakar Kushwaha } 8831730a17dSPrabhakar Kushwaha 8841730a17dSPrabhakar Kushwaha err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 8851730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 8861730a17dSPrabhakar Kushwaha if (err < 0) { 8871730a17dSPrabhakar Kushwaha printf("dprc_destroy_container() failed: %d\n", err); 8881730a17dSPrabhakar Kushwaha goto err; 8891730a17dSPrabhakar Kushwaha } 8901730a17dSPrabhakar Kushwaha 8911730a17dSPrabhakar Kushwaha err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 8921730a17dSPrabhakar Kushwaha if (err < 0) { 8931730a17dSPrabhakar Kushwaha printf("dprc_close(): Root failed: %d\n", err); 8941730a17dSPrabhakar Kushwaha goto err; 8951730a17dSPrabhakar Kushwaha } 8961730a17dSPrabhakar Kushwaha 8971730a17dSPrabhakar Kushwaha if (dflt_mc_io) 8981730a17dSPrabhakar Kushwaha free(dflt_mc_io); 8991730a17dSPrabhakar Kushwaha 9001730a17dSPrabhakar Kushwaha if (root_mc_io) 9011730a17dSPrabhakar Kushwaha free(root_mc_io); 9021730a17dSPrabhakar Kushwaha 9031730a17dSPrabhakar Kushwaha return 0; 9041730a17dSPrabhakar Kushwaha 9051730a17dSPrabhakar Kushwaha err: 9061730a17dSPrabhakar Kushwaha return err; 9071730a17dSPrabhakar Kushwaha } 9081730a17dSPrabhakar Kushwaha 9091730a17dSPrabhakar Kushwaha static int dpbp_init(void) 9101730a17dSPrabhakar Kushwaha { 9111730a17dSPrabhakar Kushwaha int err; 9121730a17dSPrabhakar Kushwaha struct dpbp_attr dpbp_attr; 9131730a17dSPrabhakar Kushwaha struct dpbp_cfg dpbp_cfg; 9141730a17dSPrabhakar Kushwaha 915a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 916a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 917a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 9181730a17dSPrabhakar Kushwaha err = -ENOMEM; 9191730a17dSPrabhakar Kushwaha goto err_malloc; 920a2a55e51SPrabhakar Kushwaha } 9211730a17dSPrabhakar Kushwaha 9221730a17dSPrabhakar Kushwaha dpbp_cfg.options = 512; 9231730a17dSPrabhakar Kushwaha 9241730a17dSPrabhakar Kushwaha err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, 9251730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 9261730a17dSPrabhakar Kushwaha 9271730a17dSPrabhakar Kushwaha if (err < 0) { 9281730a17dSPrabhakar Kushwaha err = -ENODEV; 9291730a17dSPrabhakar Kushwaha printf("dpbp_create() failed: %d\n", err); 9301730a17dSPrabhakar Kushwaha goto err_create; 9311730a17dSPrabhakar Kushwaha } 9321730a17dSPrabhakar Kushwaha 9331730a17dSPrabhakar Kushwaha memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); 9341730a17dSPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 9351730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 9361730a17dSPrabhakar Kushwaha &dpbp_attr); 9371730a17dSPrabhakar Kushwaha if (err < 0) { 9381730a17dSPrabhakar Kushwaha printf("dpbp_get_attributes() failed: %d\n", err); 9391730a17dSPrabhakar Kushwaha goto err_get_attr; 9401730a17dSPrabhakar Kushwaha } 9411730a17dSPrabhakar Kushwaha 942*9a696f56SPrabhakar Kushwaha if ((dpbp_attr.version.major != DPBP_VER_MAJOR) || 943*9a696f56SPrabhakar Kushwaha (dpbp_attr.version.minor != DPBP_VER_MINOR)) { 944*9a696f56SPrabhakar Kushwaha printf("DPBP version mismatch found %u.%u,", 945*9a696f56SPrabhakar Kushwaha dpbp_attr.version.major, dpbp_attr.version.minor); 946*9a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 947*9a696f56SPrabhakar Kushwaha DPBP_VER_MAJOR, DPBP_VER_MINOR); 948*9a696f56SPrabhakar Kushwaha } 949*9a696f56SPrabhakar Kushwaha 9501730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = dpbp_attr.id; 9511730a17dSPrabhakar Kushwaha #ifdef DEBUG 9521730a17dSPrabhakar Kushwaha printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 9531730a17dSPrabhakar Kushwaha #endif 9541730a17dSPrabhakar Kushwaha 9551730a17dSPrabhakar Kushwaha err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9561730a17dSPrabhakar Kushwaha if (err < 0) { 9571730a17dSPrabhakar Kushwaha printf("dpbp_close() failed: %d\n", err); 9581730a17dSPrabhakar Kushwaha goto err_close; 9591730a17dSPrabhakar Kushwaha } 960a2a55e51SPrabhakar Kushwaha 961a2a55e51SPrabhakar Kushwaha return 0; 9621730a17dSPrabhakar Kushwaha 9631730a17dSPrabhakar Kushwaha err_close: 9641730a17dSPrabhakar Kushwaha free(dflt_dpbp); 9651730a17dSPrabhakar Kushwaha err_get_attr: 9661730a17dSPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9671730a17dSPrabhakar Kushwaha dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9681730a17dSPrabhakar Kushwaha err_create: 9691730a17dSPrabhakar Kushwaha err_malloc: 9701730a17dSPrabhakar Kushwaha return err; 971a2a55e51SPrabhakar Kushwaha } 972a2a55e51SPrabhakar Kushwaha 9731730a17dSPrabhakar Kushwaha static int dpbp_exit(void) 974a2a55e51SPrabhakar Kushwaha { 9751730a17dSPrabhakar Kushwaha int err; 9761730a17dSPrabhakar Kushwaha 9771730a17dSPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 9781730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 9791730a17dSPrabhakar Kushwaha if (err < 0) { 9801730a17dSPrabhakar Kushwaha printf("dpbp_open() failed: %d\n", err); 9811730a17dSPrabhakar Kushwaha goto err; 9821730a17dSPrabhakar Kushwaha } 9831730a17dSPrabhakar Kushwaha 9841730a17dSPrabhakar Kushwaha err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 9851730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle); 9861730a17dSPrabhakar Kushwaha if (err < 0) { 9871730a17dSPrabhakar Kushwaha printf("dpbp_destroy() failed: %d\n", err); 9881730a17dSPrabhakar Kushwaha goto err; 9891730a17dSPrabhakar Kushwaha } 9901730a17dSPrabhakar Kushwaha 9911730a17dSPrabhakar Kushwaha #ifdef DEBUG 9921730a17dSPrabhakar Kushwaha printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 9931730a17dSPrabhakar Kushwaha #endif 9941730a17dSPrabhakar Kushwaha 9951730a17dSPrabhakar Kushwaha if (dflt_dpbp) 9961730a17dSPrabhakar Kushwaha free(dflt_dpbp); 9971730a17dSPrabhakar Kushwaha return 0; 9981730a17dSPrabhakar Kushwaha 9991730a17dSPrabhakar Kushwaha err: 10001730a17dSPrabhakar Kushwaha return err; 10011730a17dSPrabhakar Kushwaha } 10021730a17dSPrabhakar Kushwaha 10031730a17dSPrabhakar Kushwaha static int dpni_init(void) 10041730a17dSPrabhakar Kushwaha { 10051730a17dSPrabhakar Kushwaha int err; 10061730a17dSPrabhakar Kushwaha struct dpni_attr dpni_attr; 10071730a17dSPrabhakar Kushwaha struct dpni_cfg dpni_cfg; 10081730a17dSPrabhakar Kushwaha 10091730a17dSPrabhakar Kushwaha dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); 10101730a17dSPrabhakar Kushwaha if (!dflt_dpni) { 10111730a17dSPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 10121730a17dSPrabhakar Kushwaha err = -ENOMEM; 10131730a17dSPrabhakar Kushwaha goto err_malloc; 10141730a17dSPrabhakar Kushwaha } 10151730a17dSPrabhakar Kushwaha 10161730a17dSPrabhakar Kushwaha memset(&dpni_cfg, 0, sizeof(dpni_cfg)); 10171730a17dSPrabhakar Kushwaha dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | 10181730a17dSPrabhakar Kushwaha DPNI_OPT_MULTICAST_FILTER; 10191730a17dSPrabhakar Kushwaha 10201730a17dSPrabhakar Kushwaha err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, 10211730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 10221730a17dSPrabhakar Kushwaha 10231730a17dSPrabhakar Kushwaha if (err < 0) { 10241730a17dSPrabhakar Kushwaha err = -ENODEV; 10251730a17dSPrabhakar Kushwaha printf("dpni_create() failed: %d\n", err); 10261730a17dSPrabhakar Kushwaha goto err_create; 10271730a17dSPrabhakar Kushwaha } 10281730a17dSPrabhakar Kushwaha 10291730a17dSPrabhakar Kushwaha memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 10301730a17dSPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 10311730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle, 10321730a17dSPrabhakar Kushwaha &dpni_attr); 10331730a17dSPrabhakar Kushwaha if (err < 0) { 10341730a17dSPrabhakar Kushwaha printf("dpni_get_attributes() failed: %d\n", err); 10351730a17dSPrabhakar Kushwaha goto err_get_attr; 10361730a17dSPrabhakar Kushwaha } 10371730a17dSPrabhakar Kushwaha 1038*9a696f56SPrabhakar Kushwaha if ((dpni_attr.version.major != DPNI_VER_MAJOR) || 1039*9a696f56SPrabhakar Kushwaha (dpni_attr.version.minor != DPNI_VER_MINOR)) { 1040*9a696f56SPrabhakar Kushwaha printf("DPNI version mismatch found %u.%u,", 1041*9a696f56SPrabhakar Kushwaha dpni_attr.version.major, dpni_attr.version.minor); 1042*9a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 1043*9a696f56SPrabhakar Kushwaha DPNI_VER_MAJOR, DPNI_VER_MINOR); 1044*9a696f56SPrabhakar Kushwaha } 1045*9a696f56SPrabhakar Kushwaha 10461730a17dSPrabhakar Kushwaha dflt_dpni->dpni_id = dpni_attr.id; 10471730a17dSPrabhakar Kushwaha #ifdef DEBUG 10481730a17dSPrabhakar Kushwaha printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); 10491730a17dSPrabhakar Kushwaha #endif 10501730a17dSPrabhakar Kushwaha 10511730a17dSPrabhakar Kushwaha err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10521730a17dSPrabhakar Kushwaha if (err < 0) { 10531730a17dSPrabhakar Kushwaha printf("dpni_close() failed: %d\n", err); 10541730a17dSPrabhakar Kushwaha goto err_close; 10551730a17dSPrabhakar Kushwaha } 1056a2a55e51SPrabhakar Kushwaha 1057fb4a87a7SPrabhakar Kushwaha return 0; 10581730a17dSPrabhakar Kushwaha 10591730a17dSPrabhakar Kushwaha err_close: 10601730a17dSPrabhakar Kushwaha free(dflt_dpni); 10611730a17dSPrabhakar Kushwaha err_get_attr: 10621730a17dSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10631730a17dSPrabhakar Kushwaha dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10641730a17dSPrabhakar Kushwaha err_create: 10651730a17dSPrabhakar Kushwaha err_malloc: 10661730a17dSPrabhakar Kushwaha return err; 1067a2a55e51SPrabhakar Kushwaha } 1068a2a55e51SPrabhakar Kushwaha 10691730a17dSPrabhakar Kushwaha static int dpni_exit(void) 1070a2a55e51SPrabhakar Kushwaha { 10711730a17dSPrabhakar Kushwaha int err; 10721730a17dSPrabhakar Kushwaha 10731730a17dSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 10741730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 10751730a17dSPrabhakar Kushwaha if (err < 0) { 10761730a17dSPrabhakar Kushwaha printf("dpni_open() failed: %d\n", err); 10771730a17dSPrabhakar Kushwaha goto err; 10781730a17dSPrabhakar Kushwaha } 10791730a17dSPrabhakar Kushwaha 10801730a17dSPrabhakar Kushwaha err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 10811730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle); 10821730a17dSPrabhakar Kushwaha if (err < 0) { 10831730a17dSPrabhakar Kushwaha printf("dpni_destroy() failed: %d\n", err); 10841730a17dSPrabhakar Kushwaha goto err; 10851730a17dSPrabhakar Kushwaha } 10861730a17dSPrabhakar Kushwaha 10871730a17dSPrabhakar Kushwaha #ifdef DEBUG 10881730a17dSPrabhakar Kushwaha printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); 10891730a17dSPrabhakar Kushwaha #endif 10901730a17dSPrabhakar Kushwaha 10911730a17dSPrabhakar Kushwaha if (dflt_dpni) 10921730a17dSPrabhakar Kushwaha free(dflt_dpni); 10931730a17dSPrabhakar Kushwaha return 0; 10941730a17dSPrabhakar Kushwaha 10951730a17dSPrabhakar Kushwaha err: 10961730a17dSPrabhakar Kushwaha return err; 10971730a17dSPrabhakar Kushwaha } 10981730a17dSPrabhakar Kushwaha 10991730a17dSPrabhakar Kushwaha static int mc_init_object(void) 11001730a17dSPrabhakar Kushwaha { 11011730a17dSPrabhakar Kushwaha int err = 0; 11021730a17dSPrabhakar Kushwaha 11031730a17dSPrabhakar Kushwaha err = dprc_init(); 11041730a17dSPrabhakar Kushwaha if (err < 0) { 11051730a17dSPrabhakar Kushwaha printf("dprc_init() failed: %d\n", err); 11061730a17dSPrabhakar Kushwaha goto err; 11071730a17dSPrabhakar Kushwaha } 11081730a17dSPrabhakar Kushwaha 11091730a17dSPrabhakar Kushwaha err = dpbp_init(); 11101730a17dSPrabhakar Kushwaha if (err < 0) { 11111730a17dSPrabhakar Kushwaha printf("dpbp_init() failed: %d\n", err); 11121730a17dSPrabhakar Kushwaha goto err; 11131730a17dSPrabhakar Kushwaha } 11141730a17dSPrabhakar Kushwaha 11151730a17dSPrabhakar Kushwaha err = dpio_init(); 11161730a17dSPrabhakar Kushwaha if (err < 0) { 11171730a17dSPrabhakar Kushwaha printf("dpio_init() failed: %d\n", err); 11181730a17dSPrabhakar Kushwaha goto err; 11191730a17dSPrabhakar Kushwaha } 11201730a17dSPrabhakar Kushwaha 11211730a17dSPrabhakar Kushwaha err = dpni_init(); 11221730a17dSPrabhakar Kushwaha if (err < 0) { 11231730a17dSPrabhakar Kushwaha printf("dpni_init() failed: %d\n", err); 11241730a17dSPrabhakar Kushwaha goto err; 11251730a17dSPrabhakar Kushwaha } 11261730a17dSPrabhakar Kushwaha 11271730a17dSPrabhakar Kushwaha return 0; 11281730a17dSPrabhakar Kushwaha err: 11291730a17dSPrabhakar Kushwaha return err; 11301730a17dSPrabhakar Kushwaha } 11311730a17dSPrabhakar Kushwaha 11321730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_exit(bd_t *bd) 11331730a17dSPrabhakar Kushwaha { 11341730a17dSPrabhakar Kushwaha int err = 0; 11351730a17dSPrabhakar Kushwaha 11361730a17dSPrabhakar Kushwaha if (bd && get_mc_boot_status() == -1) 11371730a17dSPrabhakar Kushwaha return 0; 11381730a17dSPrabhakar Kushwaha 11391730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && get_dpl_apply_status() == -1) { 11401730a17dSPrabhakar Kushwaha printf("ERROR: fsl-mc: DPL is not applied\n"); 11411730a17dSPrabhakar Kushwaha err = -ENODEV; 11421730a17dSPrabhakar Kushwaha return err; 11431730a17dSPrabhakar Kushwaha } 11441730a17dSPrabhakar Kushwaha 11451730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && !get_dpl_apply_status()) 11461730a17dSPrabhakar Kushwaha return err; 11471730a17dSPrabhakar Kushwaha 11481730a17dSPrabhakar Kushwaha err = dpbp_exit(); 11491730a17dSPrabhakar Kushwaha if (err < 0) { 11501730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 11511730a17dSPrabhakar Kushwaha goto err; 11521730a17dSPrabhakar Kushwaha } 11531730a17dSPrabhakar Kushwaha 11541730a17dSPrabhakar Kushwaha err = dpio_exit(); 11551730a17dSPrabhakar Kushwaha if (err < 0) { 11561730a17dSPrabhakar Kushwaha printf("dpio_exit() failed: %d\n", err); 11571730a17dSPrabhakar Kushwaha goto err; 11581730a17dSPrabhakar Kushwaha } 11591730a17dSPrabhakar Kushwaha 11601730a17dSPrabhakar Kushwaha err = dpni_exit(); 11611730a17dSPrabhakar Kushwaha if (err < 0) { 11621730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 11631730a17dSPrabhakar Kushwaha goto err; 11641730a17dSPrabhakar Kushwaha } 11651730a17dSPrabhakar Kushwaha 11661730a17dSPrabhakar Kushwaha err = dprc_exit(); 11671730a17dSPrabhakar Kushwaha if (err < 0) { 11681730a17dSPrabhakar Kushwaha printf("dprc_exit() failed: %d\n", err); 11691730a17dSPrabhakar Kushwaha goto err; 11701730a17dSPrabhakar Kushwaha } 11711730a17dSPrabhakar Kushwaha 11721730a17dSPrabhakar Kushwaha return 0; 11731730a17dSPrabhakar Kushwaha err: 11741730a17dSPrabhakar Kushwaha return err; 1175fb4a87a7SPrabhakar Kushwaha } 1176fb4a87a7SPrabhakar Kushwaha 1177fb4a87a7SPrabhakar Kushwaha static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1178fb4a87a7SPrabhakar Kushwaha { 1179fb4a87a7SPrabhakar Kushwaha int err = 0; 1180fb4a87a7SPrabhakar Kushwaha if (argc < 3) 1181fb4a87a7SPrabhakar Kushwaha goto usage; 1182fb4a87a7SPrabhakar Kushwaha 1183fb4a87a7SPrabhakar Kushwaha switch (argv[1][0]) { 1184fb4a87a7SPrabhakar Kushwaha case 's': { 1185fb4a87a7SPrabhakar Kushwaha char sub_cmd; 118644937214SPrabhakar Kushwaha u64 mc_fw_addr, mc_dpc_addr; 118744937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 118844937214SPrabhakar Kushwaha u64 aiop_fw_addr; 118944937214SPrabhakar Kushwaha #endif 1190fb4a87a7SPrabhakar Kushwaha 1191fb4a87a7SPrabhakar Kushwaha sub_cmd = argv[2][0]; 1192fb4a87a7SPrabhakar Kushwaha switch (sub_cmd) { 1193fb4a87a7SPrabhakar Kushwaha case 'm': 1194fb4a87a7SPrabhakar Kushwaha if (argc < 5) 1195fb4a87a7SPrabhakar Kushwaha goto usage; 1196a2a55e51SPrabhakar Kushwaha 1197125e2bc1SJ. German Rivera if (get_mc_boot_status() == 0) { 1198fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: MC is already booted"); 1199fb4a87a7SPrabhakar Kushwaha printf("\n"); 1200fb4a87a7SPrabhakar Kushwaha return err; 1201a2a55e51SPrabhakar Kushwaha } 1202fb4a87a7SPrabhakar Kushwaha mc_fw_addr = simple_strtoull(argv[3], NULL, 16); 1203fb4a87a7SPrabhakar Kushwaha mc_dpc_addr = simple_strtoull(argv[4], NULL, 1204fb4a87a7SPrabhakar Kushwaha 16); 12051730a17dSPrabhakar Kushwaha 12061730a17dSPrabhakar Kushwaha if (!mc_init(mc_fw_addr, mc_dpc_addr)) 12071730a17dSPrabhakar Kushwaha err = mc_init_object(); 1208fb4a87a7SPrabhakar Kushwaha break; 1209fb4a87a7SPrabhakar Kushwaha 1210fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 1211fb4a87a7SPrabhakar Kushwaha case 'a': 1212fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1213fb4a87a7SPrabhakar Kushwaha goto usage; 1214fb4a87a7SPrabhakar Kushwaha if (get_aiop_apply_status() == 0) { 1215fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW is already"); 1216fb4a87a7SPrabhakar Kushwaha printf(" applied\n"); 1217fb4a87a7SPrabhakar Kushwaha return err; 1218a2a55e51SPrabhakar Kushwaha } 1219a2a55e51SPrabhakar Kushwaha 1220fb4a87a7SPrabhakar Kushwaha aiop_fw_addr = simple_strtoull(argv[3], NULL, 1221fb4a87a7SPrabhakar Kushwaha 16); 1222fb4a87a7SPrabhakar Kushwaha 1223fb4a87a7SPrabhakar Kushwaha err = load_mc_aiop_img(aiop_fw_addr); 1224fb4a87a7SPrabhakar Kushwaha if (!err) 1225fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW applied\n"); 1226fb4a87a7SPrabhakar Kushwaha break; 1227fb4a87a7SPrabhakar Kushwaha #endif 1228fb4a87a7SPrabhakar Kushwaha default: 1229fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[2]); 1230fb4a87a7SPrabhakar Kushwaha goto usage; 1231fb4a87a7SPrabhakar Kushwaha 1232fb4a87a7SPrabhakar Kushwaha break; 1233fb4a87a7SPrabhakar Kushwaha } 1234fb4a87a7SPrabhakar Kushwaha } 1235fb4a87a7SPrabhakar Kushwaha break; 1236fb4a87a7SPrabhakar Kushwaha 1237fb4a87a7SPrabhakar Kushwaha case 'a': { 1238fb4a87a7SPrabhakar Kushwaha u64 mc_dpl_addr; 1239fb4a87a7SPrabhakar Kushwaha 1240fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1241fb4a87a7SPrabhakar Kushwaha goto usage; 1242fb4a87a7SPrabhakar Kushwaha 1243fb4a87a7SPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 1244fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: DPL already applied\n"); 1245fb4a87a7SPrabhakar Kushwaha return err; 1246125e2bc1SJ. German Rivera } 1247125e2bc1SJ. German Rivera 1248fb4a87a7SPrabhakar Kushwaha mc_dpl_addr = simple_strtoull(argv[3], NULL, 1249fb4a87a7SPrabhakar Kushwaha 16); 12501730a17dSPrabhakar Kushwaha 1251fb4a87a7SPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 1252fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout .."); 1253fb4a87a7SPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 1254fb4a87a7SPrabhakar Kushwaha return -ENODEV; 1255a2a55e51SPrabhakar Kushwaha } 12561730a17dSPrabhakar Kushwaha 12571730a17dSPrabhakar Kushwaha if (!fsl_mc_ldpaa_exit(NULL)) 1258fb4a87a7SPrabhakar Kushwaha err = mc_apply_dpl(mc_dpl_addr); 1259fb4a87a7SPrabhakar Kushwaha break; 1260fb4a87a7SPrabhakar Kushwaha } 1261fb4a87a7SPrabhakar Kushwaha default: 1262fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[1]); 1263fb4a87a7SPrabhakar Kushwaha goto usage; 1264fb4a87a7SPrabhakar Kushwaha break; 1265fb4a87a7SPrabhakar Kushwaha } 1266fb4a87a7SPrabhakar Kushwaha return err; 1267fb4a87a7SPrabhakar Kushwaha usage: 1268fb4a87a7SPrabhakar Kushwaha return CMD_RET_USAGE; 1269fb4a87a7SPrabhakar Kushwaha } 1270fb4a87a7SPrabhakar Kushwaha 1271fb4a87a7SPrabhakar Kushwaha U_BOOT_CMD( 1272fb4a87a7SPrabhakar Kushwaha fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, 1273fb4a87a7SPrabhakar Kushwaha "DPAA2 command to manage Management Complex (MC)", 1274fb4a87a7SPrabhakar Kushwaha "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" 1275fb4a87a7SPrabhakar Kushwaha "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" 1276fb4a87a7SPrabhakar Kushwaha "fsl_mc start aiop [FW_addr] - Start AIOP\n" 1277fb4a87a7SPrabhakar Kushwaha ); 1278