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 5442b7c4a19SPrabhakar Kushwaha if (MC_VER_MAJOR != mc_ver_info.major) { 5457b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", 5467b3bd9a7SJ. German Rivera mc_ver_info.major, MC_VER_MAJOR); 5472b7c4a19SPrabhakar Kushwaha printf("fsl-mc: Update the Management Complex firmware\n"); 5482b7c4a19SPrabhakar Kushwaha 5492b7c4a19SPrabhakar Kushwaha error = -ENODEV; 5502b7c4a19SPrabhakar Kushwaha goto out; 5512b7c4a19SPrabhakar Kushwaha } 5527b3bd9a7SJ. German Rivera 5537b3bd9a7SJ. German Rivera if (MC_VER_MINOR != mc_ver_info.minor) 5547b3bd9a7SJ. German Rivera printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", 5557b3bd9a7SJ. German Rivera mc_ver_info.minor, MC_VER_MINOR); 5567b3bd9a7SJ. German Rivera 5577b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 5587b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 559125e2bc1SJ. German Rivera reg_gsr & GSR_FS_MASK); 560125e2bc1SJ. German Rivera 5617b3bd9a7SJ. German Rivera out: 5627b3bd9a7SJ. German Rivera if (error != 0) 5632b7c4a19SPrabhakar Kushwaha mc_boot_status = error; 5647b3bd9a7SJ. German Rivera else 5657b3bd9a7SJ. German Rivera mc_boot_status = 0; 5667b3bd9a7SJ. German Rivera 5677b3bd9a7SJ. German Rivera return error; 5687b3bd9a7SJ. German Rivera } 5697b3bd9a7SJ. German Rivera 570fb4a87a7SPrabhakar Kushwaha int mc_apply_dpl(u64 mc_dpl_addr) 571fb4a87a7SPrabhakar Kushwaha { 572fb4a87a7SPrabhakar Kushwaha struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 573fb4a87a7SPrabhakar Kushwaha int error = 0; 574fb4a87a7SPrabhakar Kushwaha u32 reg_gsr; 575fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 576fb4a87a7SPrabhakar Kushwaha size_t mc_ram_size = mc_get_dram_block_size(); 577fb4a87a7SPrabhakar Kushwaha 578fb4a87a7SPrabhakar Kushwaha error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); 579fb4a87a7SPrabhakar Kushwaha if (error != 0) 580fb4a87a7SPrabhakar Kushwaha return error; 581fb4a87a7SPrabhakar Kushwaha 582fb4a87a7SPrabhakar Kushwaha /* 583fb4a87a7SPrabhakar Kushwaha * Tell the MC to deploy the DPL: 584fb4a87a7SPrabhakar Kushwaha */ 585fb4a87a7SPrabhakar Kushwaha out_le32(&mc_ccsr_regs->reg_gsr, 0x0); 586fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout ... "); 587fb4a87a7SPrabhakar Kushwaha error = wait_for_mc(false, ®_gsr); 588fb4a87a7SPrabhakar Kushwaha 589fb4a87a7SPrabhakar Kushwaha if (!error) 590fb4a87a7SPrabhakar Kushwaha mc_dpl_applied = 0; 591fb4a87a7SPrabhakar Kushwaha 592fb4a87a7SPrabhakar Kushwaha return error; 593fb4a87a7SPrabhakar Kushwaha } 594fb4a87a7SPrabhakar Kushwaha 5957b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 5967b3bd9a7SJ. German Rivera { 5977b3bd9a7SJ. German Rivera return mc_boot_status; 5987b3bd9a7SJ. German Rivera } 5997b3bd9a7SJ. German Rivera 600fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 601fb4a87a7SPrabhakar Kushwaha int get_aiop_apply_status(void) 602fb4a87a7SPrabhakar Kushwaha { 603fb4a87a7SPrabhakar Kushwaha return mc_aiop_applied; 604fb4a87a7SPrabhakar Kushwaha } 605fb4a87a7SPrabhakar Kushwaha #endif 606fb4a87a7SPrabhakar Kushwaha 607fb4a87a7SPrabhakar Kushwaha int get_dpl_apply_status(void) 608fb4a87a7SPrabhakar Kushwaha { 609fb4a87a7SPrabhakar Kushwaha return mc_dpl_applied; 610fb4a87a7SPrabhakar Kushwaha } 611fb4a87a7SPrabhakar Kushwaha 612fb4a87a7SPrabhakar Kushwaha /** 613fb4a87a7SPrabhakar Kushwaha * Return the MC address of private DRAM block. 614fb4a87a7SPrabhakar Kushwaha */ 615fb4a87a7SPrabhakar Kushwaha u64 mc_get_dram_addr(void) 616fb4a87a7SPrabhakar Kushwaha { 617fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr; 618fb4a87a7SPrabhakar Kushwaha 619fb4a87a7SPrabhakar Kushwaha /* 620fb4a87a7SPrabhakar Kushwaha * The MC private DRAM block was already carved at the end of DRAM 621fb4a87a7SPrabhakar Kushwaha * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: 622fb4a87a7SPrabhakar Kushwaha */ 623fb4a87a7SPrabhakar Kushwaha if (gd->bd->bi_dram[1].start) { 624fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 625fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; 626fb4a87a7SPrabhakar Kushwaha } else { 627fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 628fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; 629fb4a87a7SPrabhakar Kushwaha } 630fb4a87a7SPrabhakar Kushwaha 631fb4a87a7SPrabhakar Kushwaha return mc_ram_addr; 632fb4a87a7SPrabhakar Kushwaha } 633fb4a87a7SPrabhakar Kushwaha 6347b3bd9a7SJ. German Rivera /** 6357b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 6367b3bd9a7SJ. German Rivera */ 6377b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 6387b3bd9a7SJ. German Rivera { 639125e2bc1SJ. German Rivera unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 640125e2bc1SJ. German Rivera 641125e2bc1SJ. German Rivera char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); 642125e2bc1SJ. German Rivera 643125e2bc1SJ. German Rivera if (dram_block_size_env_var) { 644125e2bc1SJ. German Rivera dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, 645125e2bc1SJ. German Rivera 10); 646125e2bc1SJ. German Rivera 647125e2bc1SJ. German Rivera if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { 648125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 649125e2bc1SJ. German Rivera MC_MEM_SIZE_ENV_VAR 650125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 651125e2bc1SJ. German Rivera dram_block_size); 652125e2bc1SJ. German Rivera 653125e2bc1SJ. German Rivera dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 654125e2bc1SJ. German Rivera } 655125e2bc1SJ. German Rivera } 656125e2bc1SJ. German Rivera 657125e2bc1SJ. German Rivera return dram_block_size; 6587b3bd9a7SJ. German Rivera } 659a2a55e51SPrabhakar Kushwaha 6601730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 6611730a17dSPrabhakar Kushwaha { 662c919ab9eSPrabhakar Kushwaha int i; 663c919ab9eSPrabhakar Kushwaha 664c919ab9eSPrabhakar Kushwaha for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) 665c919ab9eSPrabhakar Kushwaha if ((wriop_is_enabled_dpmac(i) == 1) && 666c919ab9eSPrabhakar Kushwaha (wriop_get_phy_address(i) != -1)) 667c919ab9eSPrabhakar Kushwaha ldpaa_eth_init(i, wriop_get_enet_if(i)); 6681730a17dSPrabhakar Kushwaha return 0; 6691730a17dSPrabhakar Kushwaha } 6701730a17dSPrabhakar Kushwaha 6711730a17dSPrabhakar Kushwaha static int dpio_init(void) 672a2a55e51SPrabhakar Kushwaha { 673a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 674a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 6751730a17dSPrabhakar Kushwaha struct dpio_cfg dpio_cfg; 676a2a55e51SPrabhakar Kushwaha int err = 0; 677a2a55e51SPrabhakar Kushwaha 678a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 679a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 680a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 6811730a17dSPrabhakar Kushwaha err = -ENOMEM; 6821730a17dSPrabhakar Kushwaha goto err_malloc; 683a2a55e51SPrabhakar Kushwaha } 684a2a55e51SPrabhakar Kushwaha 6851730a17dSPrabhakar Kushwaha dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; 6861730a17dSPrabhakar Kushwaha dpio_cfg.num_priorities = 8; 687a2a55e51SPrabhakar Kushwaha 6881730a17dSPrabhakar Kushwaha err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, 6891730a17dSPrabhakar Kushwaha &dflt_dpio->dpio_handle); 6901730a17dSPrabhakar Kushwaha if (err < 0) { 6911730a17dSPrabhakar Kushwaha printf("dpio_create() failed: %d\n", err); 6921730a17dSPrabhakar Kushwaha err = -ENODEV; 6931730a17dSPrabhakar Kushwaha goto err_create; 694a2a55e51SPrabhakar Kushwaha } 695a2a55e51SPrabhakar Kushwaha 6961730a17dSPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dpio_attr)); 69787457d11SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 6981730a17dSPrabhakar Kushwaha dflt_dpio->dpio_handle, &attr); 6991730a17dSPrabhakar Kushwaha if (err < 0) { 7001730a17dSPrabhakar Kushwaha printf("dpio_get_attributes() failed: %d\n", err); 701a2a55e51SPrabhakar Kushwaha goto err_get_attr; 702a2a55e51SPrabhakar Kushwaha } 703a2a55e51SPrabhakar Kushwaha 7041730a17dSPrabhakar Kushwaha dflt_dpio->dpio_id = attr.id; 7051730a17dSPrabhakar Kushwaha #ifdef DEBUG 7061730a17dSPrabhakar Kushwaha printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); 7071730a17dSPrabhakar Kushwaha #endif 7081730a17dSPrabhakar Kushwaha 7091730a17dSPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7101730a17dSPrabhakar Kushwaha if (err < 0) { 711a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 712a2a55e51SPrabhakar Kushwaha goto err_get_enable; 713a2a55e51SPrabhakar Kushwaha } 7141f1c25c7SPrabhakar Kushwaha debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", 7151f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ce_offset, 7161f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ci_offset, 717a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 718a2a55e51SPrabhakar Kushwaha attr.num_priorities); 719a2a55e51SPrabhakar Kushwaha 7201f1c25c7SPrabhakar Kushwaha p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7211f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ce_offset); 7221f1c25c7SPrabhakar Kushwaha p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 7231f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ci_offset); 724a2a55e51SPrabhakar Kushwaha 725a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 726a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 727a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 728a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 729a2a55e51SPrabhakar Kushwaha } 730a2a55e51SPrabhakar Kushwaha return 0; 731a2a55e51SPrabhakar Kushwaha 732a2a55e51SPrabhakar Kushwaha err_get_swp_init: 7331730a17dSPrabhakar Kushwaha dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 734a2a55e51SPrabhakar Kushwaha err_get_enable: 735a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 7361730a17dSPrabhakar Kushwaha err_get_attr: 7371730a17dSPrabhakar Kushwaha dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7381730a17dSPrabhakar Kushwaha dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7391730a17dSPrabhakar Kushwaha err_create: 7401730a17dSPrabhakar Kushwaha err_malloc: 741a2a55e51SPrabhakar Kushwaha return err; 742a2a55e51SPrabhakar Kushwaha } 743a2a55e51SPrabhakar Kushwaha 7441730a17dSPrabhakar Kushwaha static int dpio_exit(void) 745a2a55e51SPrabhakar Kushwaha { 7461730a17dSPrabhakar Kushwaha int err; 7471730a17dSPrabhakar Kushwaha 7481730a17dSPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7491730a17dSPrabhakar Kushwaha if (err < 0) { 7501730a17dSPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 7511730a17dSPrabhakar Kushwaha goto err; 7521730a17dSPrabhakar Kushwaha } 7531730a17dSPrabhakar Kushwaha 7541730a17dSPrabhakar Kushwaha err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 7551730a17dSPrabhakar Kushwaha if (err < 0) { 7561730a17dSPrabhakar Kushwaha printf("dpio_destroy() failed: %d\n", err); 7571730a17dSPrabhakar Kushwaha goto err; 7581730a17dSPrabhakar Kushwaha } 7591730a17dSPrabhakar Kushwaha 7601730a17dSPrabhakar Kushwaha #ifdef DEBUG 7611730a17dSPrabhakar Kushwaha printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); 7621730a17dSPrabhakar Kushwaha #endif 7631730a17dSPrabhakar Kushwaha 7641730a17dSPrabhakar Kushwaha if (dflt_dpio) 7651730a17dSPrabhakar Kushwaha free(dflt_dpio); 7661730a17dSPrabhakar Kushwaha 7671730a17dSPrabhakar Kushwaha return 0; 7681730a17dSPrabhakar Kushwaha err: 7691730a17dSPrabhakar Kushwaha return err; 7701730a17dSPrabhakar Kushwaha } 7711730a17dSPrabhakar Kushwaha 7721730a17dSPrabhakar Kushwaha static int dprc_init(void) 7731730a17dSPrabhakar Kushwaha { 7741730a17dSPrabhakar Kushwaha int err, child_portal_id, container_id; 7751730a17dSPrabhakar Kushwaha struct dprc_cfg cfg; 7761730a17dSPrabhakar Kushwaha uint64_t mc_portal_offset; 7771730a17dSPrabhakar Kushwaha 7781730a17dSPrabhakar Kushwaha /* Open root container */ 7791730a17dSPrabhakar Kushwaha err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); 7801730a17dSPrabhakar Kushwaha if (err < 0) { 7811730a17dSPrabhakar Kushwaha printf("dprc_get_container_id(): Root failed: %d\n", err); 7821730a17dSPrabhakar Kushwaha goto err_root_container_id; 7831730a17dSPrabhakar Kushwaha } 7841730a17dSPrabhakar Kushwaha 7851730a17dSPrabhakar Kushwaha #ifdef DEBUG 7861730a17dSPrabhakar Kushwaha printf("Root container id = %d\n", container_id); 7871730a17dSPrabhakar Kushwaha #endif 7881730a17dSPrabhakar Kushwaha err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, 7891730a17dSPrabhakar Kushwaha &root_dprc_handle); 7901730a17dSPrabhakar Kushwaha if (err < 0) { 7911730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container failed: %d\n", err); 7921730a17dSPrabhakar Kushwaha goto err_root_open; 7931730a17dSPrabhakar Kushwaha } 7941730a17dSPrabhakar Kushwaha 7951730a17dSPrabhakar Kushwaha if (!root_dprc_handle) { 7961730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container Handle is not valid\n"); 7971730a17dSPrabhakar Kushwaha goto err_root_open; 7981730a17dSPrabhakar Kushwaha } 7991730a17dSPrabhakar Kushwaha 8001730a17dSPrabhakar Kushwaha cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | 8011730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | 8021730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_ALLOC_ALLOWED; 8031730a17dSPrabhakar Kushwaha cfg.icid = DPRC_GET_ICID_FROM_POOL; 8041730a17dSPrabhakar Kushwaha cfg.portal_id = 250; 8051730a17dSPrabhakar Kushwaha err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, 8061730a17dSPrabhakar Kushwaha root_dprc_handle, 8071730a17dSPrabhakar Kushwaha &cfg, 8081730a17dSPrabhakar Kushwaha &child_dprc_id, 8091730a17dSPrabhakar Kushwaha &mc_portal_offset); 8101730a17dSPrabhakar Kushwaha if (err < 0) { 8111730a17dSPrabhakar Kushwaha printf("dprc_create_container() failed: %d\n", err); 8121730a17dSPrabhakar Kushwaha goto err_create; 8131730a17dSPrabhakar Kushwaha } 8141730a17dSPrabhakar Kushwaha 8151730a17dSPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 8161730a17dSPrabhakar Kushwaha if (!dflt_mc_io) { 8171730a17dSPrabhakar Kushwaha err = -ENOMEM; 8181730a17dSPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 8191730a17dSPrabhakar Kushwaha goto err_malloc; 8201730a17dSPrabhakar Kushwaha } 8211730a17dSPrabhakar Kushwaha 8221730a17dSPrabhakar Kushwaha child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); 8231730a17dSPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); 8241730a17dSPrabhakar Kushwaha #ifdef DEBUG 8251730a17dSPrabhakar Kushwaha printf("MC portal of child DPRC container: %d, physical addr %p)\n", 8261730a17dSPrabhakar Kushwaha child_dprc_id, dflt_mc_io->mmio_regs); 8271730a17dSPrabhakar Kushwaha #endif 8281730a17dSPrabhakar Kushwaha 8291730a17dSPrabhakar Kushwaha err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, 8301730a17dSPrabhakar Kushwaha &dflt_dprc_handle); 8311730a17dSPrabhakar Kushwaha if (err < 0) { 8321730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container failed: %d\n", err); 8331730a17dSPrabhakar Kushwaha goto err_child_open; 8341730a17dSPrabhakar Kushwaha } 8351730a17dSPrabhakar Kushwaha 8361730a17dSPrabhakar Kushwaha if (!dflt_dprc_handle) { 8371730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container Handle is not valid\n"); 8381730a17dSPrabhakar Kushwaha goto err_child_open; 8391730a17dSPrabhakar Kushwaha } 8401730a17dSPrabhakar Kushwaha 8411730a17dSPrabhakar Kushwaha return 0; 8421730a17dSPrabhakar Kushwaha err_child_open: 8431730a17dSPrabhakar Kushwaha free(dflt_mc_io); 8441730a17dSPrabhakar Kushwaha err_malloc: 8451730a17dSPrabhakar Kushwaha dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 8461730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 8471730a17dSPrabhakar Kushwaha err_create: 8481730a17dSPrabhakar Kushwaha dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 8491730a17dSPrabhakar Kushwaha err_root_open: 8501730a17dSPrabhakar Kushwaha err_root_container_id: 8511730a17dSPrabhakar Kushwaha return err; 8521730a17dSPrabhakar Kushwaha } 8531730a17dSPrabhakar Kushwaha 8541730a17dSPrabhakar Kushwaha static int dprc_exit(void) 8551730a17dSPrabhakar Kushwaha { 8561730a17dSPrabhakar Kushwaha int err; 8571730a17dSPrabhakar Kushwaha 8581730a17dSPrabhakar Kushwaha err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); 8591730a17dSPrabhakar Kushwaha if (err < 0) { 8601730a17dSPrabhakar Kushwaha printf("dprc_close(): Child failed: %d\n", err); 8611730a17dSPrabhakar Kushwaha goto err; 8621730a17dSPrabhakar Kushwaha } 8631730a17dSPrabhakar Kushwaha 8641730a17dSPrabhakar Kushwaha err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 8651730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 8661730a17dSPrabhakar Kushwaha if (err < 0) { 8671730a17dSPrabhakar Kushwaha printf("dprc_destroy_container() failed: %d\n", err); 8681730a17dSPrabhakar Kushwaha goto err; 8691730a17dSPrabhakar Kushwaha } 8701730a17dSPrabhakar Kushwaha 8711730a17dSPrabhakar Kushwaha err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 8721730a17dSPrabhakar Kushwaha if (err < 0) { 8731730a17dSPrabhakar Kushwaha printf("dprc_close(): Root failed: %d\n", err); 8741730a17dSPrabhakar Kushwaha goto err; 8751730a17dSPrabhakar Kushwaha } 8761730a17dSPrabhakar Kushwaha 8771730a17dSPrabhakar Kushwaha if (dflt_mc_io) 8781730a17dSPrabhakar Kushwaha free(dflt_mc_io); 8791730a17dSPrabhakar Kushwaha 8801730a17dSPrabhakar Kushwaha if (root_mc_io) 8811730a17dSPrabhakar Kushwaha free(root_mc_io); 8821730a17dSPrabhakar Kushwaha 8831730a17dSPrabhakar Kushwaha return 0; 8841730a17dSPrabhakar Kushwaha 8851730a17dSPrabhakar Kushwaha err: 8861730a17dSPrabhakar Kushwaha return err; 8871730a17dSPrabhakar Kushwaha } 8881730a17dSPrabhakar Kushwaha 8891730a17dSPrabhakar Kushwaha static int dpbp_init(void) 8901730a17dSPrabhakar Kushwaha { 8911730a17dSPrabhakar Kushwaha int err; 8921730a17dSPrabhakar Kushwaha struct dpbp_attr dpbp_attr; 8931730a17dSPrabhakar Kushwaha struct dpbp_cfg dpbp_cfg; 8941730a17dSPrabhakar Kushwaha 895a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 896a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 897a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 8981730a17dSPrabhakar Kushwaha err = -ENOMEM; 8991730a17dSPrabhakar Kushwaha goto err_malloc; 900a2a55e51SPrabhakar Kushwaha } 9011730a17dSPrabhakar Kushwaha 9021730a17dSPrabhakar Kushwaha dpbp_cfg.options = 512; 9031730a17dSPrabhakar Kushwaha 9041730a17dSPrabhakar Kushwaha err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, 9051730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 9061730a17dSPrabhakar Kushwaha 9071730a17dSPrabhakar Kushwaha if (err < 0) { 9081730a17dSPrabhakar Kushwaha err = -ENODEV; 9091730a17dSPrabhakar Kushwaha printf("dpbp_create() failed: %d\n", err); 9101730a17dSPrabhakar Kushwaha goto err_create; 9111730a17dSPrabhakar Kushwaha } 9121730a17dSPrabhakar Kushwaha 9131730a17dSPrabhakar Kushwaha memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); 9141730a17dSPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 9151730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 9161730a17dSPrabhakar Kushwaha &dpbp_attr); 9171730a17dSPrabhakar Kushwaha if (err < 0) { 9181730a17dSPrabhakar Kushwaha printf("dpbp_get_attributes() failed: %d\n", err); 9191730a17dSPrabhakar Kushwaha goto err_get_attr; 9201730a17dSPrabhakar Kushwaha } 9211730a17dSPrabhakar Kushwaha 9221730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = dpbp_attr.id; 9231730a17dSPrabhakar Kushwaha #ifdef DEBUG 9241730a17dSPrabhakar Kushwaha printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 9251730a17dSPrabhakar Kushwaha #endif 9261730a17dSPrabhakar Kushwaha 9271730a17dSPrabhakar Kushwaha err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9281730a17dSPrabhakar Kushwaha if (err < 0) { 9291730a17dSPrabhakar Kushwaha printf("dpbp_close() failed: %d\n", err); 9301730a17dSPrabhakar Kushwaha goto err_close; 9311730a17dSPrabhakar Kushwaha } 932a2a55e51SPrabhakar Kushwaha 933a2a55e51SPrabhakar Kushwaha return 0; 9341730a17dSPrabhakar Kushwaha 9351730a17dSPrabhakar Kushwaha err_close: 9361730a17dSPrabhakar Kushwaha free(dflt_dpbp); 9371730a17dSPrabhakar Kushwaha err_get_attr: 9381730a17dSPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9391730a17dSPrabhakar Kushwaha dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 9401730a17dSPrabhakar Kushwaha err_create: 9411730a17dSPrabhakar Kushwaha err_malloc: 9421730a17dSPrabhakar Kushwaha return err; 943a2a55e51SPrabhakar Kushwaha } 944a2a55e51SPrabhakar Kushwaha 9451730a17dSPrabhakar Kushwaha static int dpbp_exit(void) 946a2a55e51SPrabhakar Kushwaha { 9471730a17dSPrabhakar Kushwaha int err; 9481730a17dSPrabhakar Kushwaha 9491730a17dSPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 9501730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 9511730a17dSPrabhakar Kushwaha if (err < 0) { 9521730a17dSPrabhakar Kushwaha printf("dpbp_open() failed: %d\n", err); 9531730a17dSPrabhakar Kushwaha goto err; 9541730a17dSPrabhakar Kushwaha } 9551730a17dSPrabhakar Kushwaha 9561730a17dSPrabhakar Kushwaha err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 9571730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle); 9581730a17dSPrabhakar Kushwaha if (err < 0) { 9591730a17dSPrabhakar Kushwaha printf("dpbp_destroy() failed: %d\n", err); 9601730a17dSPrabhakar Kushwaha goto err; 9611730a17dSPrabhakar Kushwaha } 9621730a17dSPrabhakar Kushwaha 9631730a17dSPrabhakar Kushwaha #ifdef DEBUG 9641730a17dSPrabhakar Kushwaha printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 9651730a17dSPrabhakar Kushwaha #endif 9661730a17dSPrabhakar Kushwaha 9671730a17dSPrabhakar Kushwaha if (dflt_dpbp) 9681730a17dSPrabhakar Kushwaha free(dflt_dpbp); 9691730a17dSPrabhakar Kushwaha return 0; 9701730a17dSPrabhakar Kushwaha 9711730a17dSPrabhakar Kushwaha err: 9721730a17dSPrabhakar Kushwaha return err; 9731730a17dSPrabhakar Kushwaha } 9741730a17dSPrabhakar Kushwaha 9751730a17dSPrabhakar Kushwaha static int dpni_init(void) 9761730a17dSPrabhakar Kushwaha { 9771730a17dSPrabhakar Kushwaha int err; 9781730a17dSPrabhakar Kushwaha struct dpni_attr dpni_attr; 9791730a17dSPrabhakar Kushwaha struct dpni_cfg dpni_cfg; 9801730a17dSPrabhakar Kushwaha 9811730a17dSPrabhakar Kushwaha dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); 9821730a17dSPrabhakar Kushwaha if (!dflt_dpni) { 9831730a17dSPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 9841730a17dSPrabhakar Kushwaha err = -ENOMEM; 9851730a17dSPrabhakar Kushwaha goto err_malloc; 9861730a17dSPrabhakar Kushwaha } 9871730a17dSPrabhakar Kushwaha 9881730a17dSPrabhakar Kushwaha memset(&dpni_cfg, 0, sizeof(dpni_cfg)); 9891730a17dSPrabhakar Kushwaha dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | 9901730a17dSPrabhakar Kushwaha DPNI_OPT_MULTICAST_FILTER; 9911730a17dSPrabhakar Kushwaha 9921730a17dSPrabhakar Kushwaha err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, 9931730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 9941730a17dSPrabhakar Kushwaha 9951730a17dSPrabhakar Kushwaha if (err < 0) { 9961730a17dSPrabhakar Kushwaha err = -ENODEV; 9971730a17dSPrabhakar Kushwaha printf("dpni_create() failed: %d\n", err); 9981730a17dSPrabhakar Kushwaha goto err_create; 9991730a17dSPrabhakar Kushwaha } 10001730a17dSPrabhakar Kushwaha 10011730a17dSPrabhakar Kushwaha memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 10021730a17dSPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 10031730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle, 10041730a17dSPrabhakar Kushwaha &dpni_attr); 10051730a17dSPrabhakar Kushwaha if (err < 0) { 10061730a17dSPrabhakar Kushwaha printf("dpni_get_attributes() failed: %d\n", err); 10071730a17dSPrabhakar Kushwaha goto err_get_attr; 10081730a17dSPrabhakar Kushwaha } 10091730a17dSPrabhakar Kushwaha 10101730a17dSPrabhakar Kushwaha dflt_dpni->dpni_id = dpni_attr.id; 10111730a17dSPrabhakar Kushwaha #ifdef DEBUG 10121730a17dSPrabhakar Kushwaha printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); 10131730a17dSPrabhakar Kushwaha #endif 10141730a17dSPrabhakar Kushwaha 10151730a17dSPrabhakar Kushwaha err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10161730a17dSPrabhakar Kushwaha if (err < 0) { 10171730a17dSPrabhakar Kushwaha printf("dpni_close() failed: %d\n", err); 10181730a17dSPrabhakar Kushwaha goto err_close; 10191730a17dSPrabhakar Kushwaha } 1020a2a55e51SPrabhakar Kushwaha 1021fb4a87a7SPrabhakar Kushwaha return 0; 10221730a17dSPrabhakar Kushwaha 10231730a17dSPrabhakar Kushwaha err_close: 10241730a17dSPrabhakar Kushwaha free(dflt_dpni); 10251730a17dSPrabhakar Kushwaha err_get_attr: 10261730a17dSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10271730a17dSPrabhakar Kushwaha dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 10281730a17dSPrabhakar Kushwaha err_create: 10291730a17dSPrabhakar Kushwaha err_malloc: 10301730a17dSPrabhakar Kushwaha return err; 1031a2a55e51SPrabhakar Kushwaha } 1032a2a55e51SPrabhakar Kushwaha 10331730a17dSPrabhakar Kushwaha static int dpni_exit(void) 1034a2a55e51SPrabhakar Kushwaha { 10351730a17dSPrabhakar Kushwaha int err; 10361730a17dSPrabhakar Kushwaha 10371730a17dSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 10381730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 10391730a17dSPrabhakar Kushwaha if (err < 0) { 10401730a17dSPrabhakar Kushwaha printf("dpni_open() failed: %d\n", err); 10411730a17dSPrabhakar Kushwaha goto err; 10421730a17dSPrabhakar Kushwaha } 10431730a17dSPrabhakar Kushwaha 10441730a17dSPrabhakar Kushwaha err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 10451730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle); 10461730a17dSPrabhakar Kushwaha if (err < 0) { 10471730a17dSPrabhakar Kushwaha printf("dpni_destroy() failed: %d\n", err); 10481730a17dSPrabhakar Kushwaha goto err; 10491730a17dSPrabhakar Kushwaha } 10501730a17dSPrabhakar Kushwaha 10511730a17dSPrabhakar Kushwaha #ifdef DEBUG 10521730a17dSPrabhakar Kushwaha printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); 10531730a17dSPrabhakar Kushwaha #endif 10541730a17dSPrabhakar Kushwaha 10551730a17dSPrabhakar Kushwaha if (dflt_dpni) 10561730a17dSPrabhakar Kushwaha free(dflt_dpni); 10571730a17dSPrabhakar Kushwaha return 0; 10581730a17dSPrabhakar Kushwaha 10591730a17dSPrabhakar Kushwaha err: 10601730a17dSPrabhakar Kushwaha return err; 10611730a17dSPrabhakar Kushwaha } 10621730a17dSPrabhakar Kushwaha 10631730a17dSPrabhakar Kushwaha static int mc_init_object(void) 10641730a17dSPrabhakar Kushwaha { 10651730a17dSPrabhakar Kushwaha int err = 0; 10661730a17dSPrabhakar Kushwaha 10671730a17dSPrabhakar Kushwaha err = dprc_init(); 10681730a17dSPrabhakar Kushwaha if (err < 0) { 10691730a17dSPrabhakar Kushwaha printf("dprc_init() failed: %d\n", err); 10701730a17dSPrabhakar Kushwaha goto err; 10711730a17dSPrabhakar Kushwaha } 10721730a17dSPrabhakar Kushwaha 10731730a17dSPrabhakar Kushwaha err = dpbp_init(); 10741730a17dSPrabhakar Kushwaha if (err < 0) { 10751730a17dSPrabhakar Kushwaha printf("dpbp_init() failed: %d\n", err); 10761730a17dSPrabhakar Kushwaha goto err; 10771730a17dSPrabhakar Kushwaha } 10781730a17dSPrabhakar Kushwaha 10791730a17dSPrabhakar Kushwaha err = dpio_init(); 10801730a17dSPrabhakar Kushwaha if (err < 0) { 10811730a17dSPrabhakar Kushwaha printf("dpio_init() failed: %d\n", err); 10821730a17dSPrabhakar Kushwaha goto err; 10831730a17dSPrabhakar Kushwaha } 10841730a17dSPrabhakar Kushwaha 10851730a17dSPrabhakar Kushwaha err = dpni_init(); 10861730a17dSPrabhakar Kushwaha if (err < 0) { 10871730a17dSPrabhakar Kushwaha printf("dpni_init() failed: %d\n", err); 10881730a17dSPrabhakar Kushwaha goto err; 10891730a17dSPrabhakar Kushwaha } 10901730a17dSPrabhakar Kushwaha 10911730a17dSPrabhakar Kushwaha return 0; 10921730a17dSPrabhakar Kushwaha err: 10931730a17dSPrabhakar Kushwaha return err; 10941730a17dSPrabhakar Kushwaha } 10951730a17dSPrabhakar Kushwaha 10961730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_exit(bd_t *bd) 10971730a17dSPrabhakar Kushwaha { 10981730a17dSPrabhakar Kushwaha int err = 0; 10991730a17dSPrabhakar Kushwaha 11001730a17dSPrabhakar Kushwaha if (bd && get_mc_boot_status() == -1) 11011730a17dSPrabhakar Kushwaha return 0; 11021730a17dSPrabhakar Kushwaha 11031730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && get_dpl_apply_status() == -1) { 11041730a17dSPrabhakar Kushwaha printf("ERROR: fsl-mc: DPL is not applied\n"); 11051730a17dSPrabhakar Kushwaha err = -ENODEV; 11061730a17dSPrabhakar Kushwaha return err; 11071730a17dSPrabhakar Kushwaha } 11081730a17dSPrabhakar Kushwaha 11091730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && !get_dpl_apply_status()) 11101730a17dSPrabhakar Kushwaha return err; 11111730a17dSPrabhakar Kushwaha 11121730a17dSPrabhakar Kushwaha err = dpbp_exit(); 11131730a17dSPrabhakar Kushwaha if (err < 0) { 11141730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 11151730a17dSPrabhakar Kushwaha goto err; 11161730a17dSPrabhakar Kushwaha } 11171730a17dSPrabhakar Kushwaha 11181730a17dSPrabhakar Kushwaha err = dpio_exit(); 11191730a17dSPrabhakar Kushwaha if (err < 0) { 11201730a17dSPrabhakar Kushwaha printf("dpio_exit() failed: %d\n", err); 11211730a17dSPrabhakar Kushwaha goto err; 11221730a17dSPrabhakar Kushwaha } 11231730a17dSPrabhakar Kushwaha 11241730a17dSPrabhakar Kushwaha err = dpni_exit(); 11251730a17dSPrabhakar Kushwaha if (err < 0) { 11261730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 11271730a17dSPrabhakar Kushwaha goto err; 11281730a17dSPrabhakar Kushwaha } 11291730a17dSPrabhakar Kushwaha 11301730a17dSPrabhakar Kushwaha err = dprc_exit(); 11311730a17dSPrabhakar Kushwaha if (err < 0) { 11321730a17dSPrabhakar Kushwaha printf("dprc_exit() failed: %d\n", err); 11331730a17dSPrabhakar Kushwaha goto err; 11341730a17dSPrabhakar Kushwaha } 11351730a17dSPrabhakar Kushwaha 11361730a17dSPrabhakar Kushwaha return 0; 11371730a17dSPrabhakar Kushwaha err: 11381730a17dSPrabhakar Kushwaha return err; 1139fb4a87a7SPrabhakar Kushwaha } 1140fb4a87a7SPrabhakar Kushwaha 1141fb4a87a7SPrabhakar Kushwaha static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1142fb4a87a7SPrabhakar Kushwaha { 1143fb4a87a7SPrabhakar Kushwaha int err = 0; 1144fb4a87a7SPrabhakar Kushwaha if (argc < 3) 1145fb4a87a7SPrabhakar Kushwaha goto usage; 1146fb4a87a7SPrabhakar Kushwaha 1147fb4a87a7SPrabhakar Kushwaha switch (argv[1][0]) { 1148fb4a87a7SPrabhakar Kushwaha case 's': { 1149fb4a87a7SPrabhakar Kushwaha char sub_cmd; 1150*44937214SPrabhakar Kushwaha u64 mc_fw_addr, mc_dpc_addr; 1151*44937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 1152*44937214SPrabhakar Kushwaha u64 aiop_fw_addr; 1153*44937214SPrabhakar Kushwaha #endif 1154fb4a87a7SPrabhakar Kushwaha 1155fb4a87a7SPrabhakar Kushwaha sub_cmd = argv[2][0]; 1156fb4a87a7SPrabhakar Kushwaha switch (sub_cmd) { 1157fb4a87a7SPrabhakar Kushwaha case 'm': 1158fb4a87a7SPrabhakar Kushwaha if (argc < 5) 1159fb4a87a7SPrabhakar Kushwaha goto usage; 1160a2a55e51SPrabhakar Kushwaha 1161125e2bc1SJ. German Rivera if (get_mc_boot_status() == 0) { 1162fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: MC is already booted"); 1163fb4a87a7SPrabhakar Kushwaha printf("\n"); 1164fb4a87a7SPrabhakar Kushwaha return err; 1165a2a55e51SPrabhakar Kushwaha } 1166fb4a87a7SPrabhakar Kushwaha mc_fw_addr = simple_strtoull(argv[3], NULL, 16); 1167fb4a87a7SPrabhakar Kushwaha mc_dpc_addr = simple_strtoull(argv[4], NULL, 1168fb4a87a7SPrabhakar Kushwaha 16); 11691730a17dSPrabhakar Kushwaha 11701730a17dSPrabhakar Kushwaha if (!mc_init(mc_fw_addr, mc_dpc_addr)) 11711730a17dSPrabhakar Kushwaha err = mc_init_object(); 1172fb4a87a7SPrabhakar Kushwaha break; 1173fb4a87a7SPrabhakar Kushwaha 1174fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 1175fb4a87a7SPrabhakar Kushwaha case 'a': 1176fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1177fb4a87a7SPrabhakar Kushwaha goto usage; 1178fb4a87a7SPrabhakar Kushwaha if (get_aiop_apply_status() == 0) { 1179fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW is already"); 1180fb4a87a7SPrabhakar Kushwaha printf(" applied\n"); 1181fb4a87a7SPrabhakar Kushwaha return err; 1182a2a55e51SPrabhakar Kushwaha } 1183a2a55e51SPrabhakar Kushwaha 1184fb4a87a7SPrabhakar Kushwaha aiop_fw_addr = simple_strtoull(argv[3], NULL, 1185fb4a87a7SPrabhakar Kushwaha 16); 1186fb4a87a7SPrabhakar Kushwaha 1187fb4a87a7SPrabhakar Kushwaha err = load_mc_aiop_img(aiop_fw_addr); 1188fb4a87a7SPrabhakar Kushwaha if (!err) 1189fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW applied\n"); 1190fb4a87a7SPrabhakar Kushwaha break; 1191fb4a87a7SPrabhakar Kushwaha #endif 1192fb4a87a7SPrabhakar Kushwaha default: 1193fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[2]); 1194fb4a87a7SPrabhakar Kushwaha goto usage; 1195fb4a87a7SPrabhakar Kushwaha 1196fb4a87a7SPrabhakar Kushwaha break; 1197fb4a87a7SPrabhakar Kushwaha } 1198fb4a87a7SPrabhakar Kushwaha } 1199fb4a87a7SPrabhakar Kushwaha break; 1200fb4a87a7SPrabhakar Kushwaha 1201fb4a87a7SPrabhakar Kushwaha case 'a': { 1202fb4a87a7SPrabhakar Kushwaha u64 mc_dpl_addr; 1203fb4a87a7SPrabhakar Kushwaha 1204fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1205fb4a87a7SPrabhakar Kushwaha goto usage; 1206fb4a87a7SPrabhakar Kushwaha 1207fb4a87a7SPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 1208fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: DPL already applied\n"); 1209fb4a87a7SPrabhakar Kushwaha return err; 1210125e2bc1SJ. German Rivera } 1211125e2bc1SJ. German Rivera 1212fb4a87a7SPrabhakar Kushwaha mc_dpl_addr = simple_strtoull(argv[3], NULL, 1213fb4a87a7SPrabhakar Kushwaha 16); 12141730a17dSPrabhakar Kushwaha 1215fb4a87a7SPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 1216fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout .."); 1217fb4a87a7SPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 1218fb4a87a7SPrabhakar Kushwaha return -ENODEV; 1219a2a55e51SPrabhakar Kushwaha } 12201730a17dSPrabhakar Kushwaha 12211730a17dSPrabhakar Kushwaha if (!fsl_mc_ldpaa_exit(NULL)) 1222fb4a87a7SPrabhakar Kushwaha err = mc_apply_dpl(mc_dpl_addr); 1223fb4a87a7SPrabhakar Kushwaha break; 1224fb4a87a7SPrabhakar Kushwaha } 1225fb4a87a7SPrabhakar Kushwaha default: 1226fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[1]); 1227fb4a87a7SPrabhakar Kushwaha goto usage; 1228fb4a87a7SPrabhakar Kushwaha break; 1229fb4a87a7SPrabhakar Kushwaha } 1230fb4a87a7SPrabhakar Kushwaha return err; 1231fb4a87a7SPrabhakar Kushwaha usage: 1232fb4a87a7SPrabhakar Kushwaha return CMD_RET_USAGE; 1233fb4a87a7SPrabhakar Kushwaha } 1234fb4a87a7SPrabhakar Kushwaha 1235fb4a87a7SPrabhakar Kushwaha U_BOOT_CMD( 1236fb4a87a7SPrabhakar Kushwaha fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, 1237fb4a87a7SPrabhakar Kushwaha "DPAA2 command to manage Management Complex (MC)", 1238fb4a87a7SPrabhakar Kushwaha "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" 1239fb4a87a7SPrabhakar Kushwaha "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" 1240fb4a87a7SPrabhakar Kushwaha "fsl_mc start aiop [FW_addr] - Start AIOP\n" 1241fb4a87a7SPrabhakar Kushwaha ); 1242