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 */ 67b3bd9a7SJ. German Rivera 77b3bd9a7SJ. German Rivera #include <errno.h> 87b3bd9a7SJ. German Rivera #include <asm/io.h> 97b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc.h> 107b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc_sys.h> 11*a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_mc_private.h> 127b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_dpmng.h> 13422cb08aSBhupesh Sharma #include <fsl_debug_server.h> 14*a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dprc.h> 15*a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dpio.h> 16*a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_qbman_portal.h> 177b3bd9a7SJ. German Rivera 187b3bd9a7SJ. German Rivera DECLARE_GLOBAL_DATA_PTR; 197b3bd9a7SJ. German Rivera static int mc_boot_status; 20*a2a55e51SPrabhakar Kushwaha struct fsl_mc_io *dflt_mc_io = NULL; 21*a2a55e51SPrabhakar Kushwaha uint16_t dflt_dprc_handle = 0; 22*a2a55e51SPrabhakar Kushwaha struct fsl_dpbp_obj *dflt_dpbp = NULL; 23*a2a55e51SPrabhakar Kushwaha struct fsl_dpio_obj *dflt_dpio = NULL; 24*a2a55e51SPrabhakar Kushwaha uint16_t dflt_dpio_handle = NULL; 257b3bd9a7SJ. German Rivera 267b3bd9a7SJ. German Rivera /** 277b3bd9a7SJ. German Rivera * Copying MC firmware or DPL image to DDR 287b3bd9a7SJ. German Rivera */ 297b3bd9a7SJ. German Rivera static int mc_copy_image(const char *title, 307b3bd9a7SJ. German Rivera u64 image_addr, u32 image_size, u64 mc_ram_addr) 317b3bd9a7SJ. German Rivera { 327b3bd9a7SJ. German Rivera debug("%s copied to address %p\n", title, (void *)mc_ram_addr); 337b3bd9a7SJ. German Rivera memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); 347b3bd9a7SJ. German Rivera return 0; 357b3bd9a7SJ. German Rivera } 367b3bd9a7SJ. German Rivera 377b3bd9a7SJ. German Rivera /** 387b3bd9a7SJ. German Rivera * MC firmware FIT image parser checks if the image is in FIT 397b3bd9a7SJ. German Rivera * format, verifies integrity of the image and calculates 407b3bd9a7SJ. German Rivera * raw image address and size values. 417b3bd9a7SJ. German Rivera * Returns 0 on success and a negative errno on error. 427b3bd9a7SJ. German Rivera * task fail. 437b3bd9a7SJ. German Rivera **/ 447b3bd9a7SJ. German Rivera int parse_mc_firmware_fit_image(const void **raw_image_addr, 457b3bd9a7SJ. German Rivera size_t *raw_image_size) 467b3bd9a7SJ. German Rivera { 477b3bd9a7SJ. German Rivera int format; 487b3bd9a7SJ. German Rivera void *fit_hdr; 497b3bd9a7SJ. German Rivera int node_offset; 507b3bd9a7SJ. German Rivera const void *data; 517b3bd9a7SJ. German Rivera size_t size; 527b3bd9a7SJ. German Rivera const char *uname = "firmware"; 537b3bd9a7SJ. German Rivera 547b3bd9a7SJ. German Rivera /* Check if the image is in NOR flash */ 557b3bd9a7SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR 567b3bd9a7SJ. German Rivera fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; 577b3bd9a7SJ. German Rivera #else 587b3bd9a7SJ. German Rivera #error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined" 597b3bd9a7SJ. German Rivera #endif 607b3bd9a7SJ. German Rivera 617b3bd9a7SJ. German Rivera /* Check if Image is in FIT format */ 627b3bd9a7SJ. German Rivera format = genimg_get_format(fit_hdr); 637b3bd9a7SJ. German Rivera 647b3bd9a7SJ. German Rivera if (format != IMAGE_FORMAT_FIT) { 657b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n"); 667b3bd9a7SJ. German Rivera return -EINVAL; 677b3bd9a7SJ. German Rivera } 687b3bd9a7SJ. German Rivera 697b3bd9a7SJ. German Rivera if (!fit_check_format(fit_hdr)) { 707b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n"); 717b3bd9a7SJ. German Rivera return -EINVAL; 727b3bd9a7SJ. German Rivera } 737b3bd9a7SJ. German Rivera 747b3bd9a7SJ. German Rivera node_offset = fit_image_get_node(fit_hdr, uname); 757b3bd9a7SJ. German Rivera 767b3bd9a7SJ. German Rivera if (node_offset < 0) { 777b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n"); 787b3bd9a7SJ. German Rivera return -ENOENT; 797b3bd9a7SJ. German Rivera } 807b3bd9a7SJ. German Rivera 817b3bd9a7SJ. German Rivera /* Verify MC firmware image */ 827b3bd9a7SJ. German Rivera if (!(fit_image_verify(fit_hdr, node_offset))) { 837b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n"); 847b3bd9a7SJ. German Rivera return -EINVAL; 857b3bd9a7SJ. German Rivera } 867b3bd9a7SJ. German Rivera 877b3bd9a7SJ. German Rivera /* Get address and size of raw image */ 887b3bd9a7SJ. German Rivera fit_image_get_data(fit_hdr, node_offset, &data, &size); 897b3bd9a7SJ. German Rivera 907b3bd9a7SJ. German Rivera *raw_image_addr = data; 917b3bd9a7SJ. German Rivera *raw_image_size = size; 927b3bd9a7SJ. German Rivera 937b3bd9a7SJ. German Rivera return 0; 947b3bd9a7SJ. German Rivera } 957b3bd9a7SJ. German Rivera 96*a2a55e51SPrabhakar Kushwaha int mc_init(void) 977b3bd9a7SJ. German Rivera { 987b3bd9a7SJ. German Rivera int error = 0; 997b3bd9a7SJ. German Rivera int timeout = 200000; 100*a2a55e51SPrabhakar Kushwaha int portal_id = 0; 1017b3bd9a7SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 1027b3bd9a7SJ. German Rivera u64 mc_ram_addr; 1037b3bd9a7SJ. German Rivera u64 mc_dpl_offset; 1047b3bd9a7SJ. German Rivera u32 reg_gsr; 1057b3bd9a7SJ. German Rivera u32 mc_fw_boot_status; 1067b3bd9a7SJ. German Rivera void *dpl_fdt_hdr; 1077b3bd9a7SJ. German Rivera int dpl_size; 1087b3bd9a7SJ. German Rivera const void *raw_image_addr; 1097b3bd9a7SJ. German Rivera size_t raw_image_size = 0; 1107b3bd9a7SJ. German Rivera struct mc_version mc_ver_info; 1117b3bd9a7SJ. German Rivera 1127b3bd9a7SJ. German Rivera /* 1137b3bd9a7SJ. German Rivera * The MC private DRAM block was already carved at the end of DRAM 1147b3bd9a7SJ. German Rivera * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: 1157b3bd9a7SJ. German Rivera */ 1167b3bd9a7SJ. German Rivera if (gd->bd->bi_dram[1].start) { 1177b3bd9a7SJ. German Rivera mc_ram_addr = 1187b3bd9a7SJ. German Rivera gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; 1197b3bd9a7SJ. German Rivera } else { 1207b3bd9a7SJ. German Rivera mc_ram_addr = 1217b3bd9a7SJ. German Rivera gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; 1227b3bd9a7SJ. German Rivera } 1237b3bd9a7SJ. German Rivera 124422cb08aSBhupesh Sharma #ifdef CONFIG_FSL_DEBUG_SERVER 125422cb08aSBhupesh Sharma mc_ram_addr -= debug_server_get_dram_block_size(); 126422cb08aSBhupesh Sharma #endif 1277b3bd9a7SJ. German Rivera /* 1287b3bd9a7SJ. German Rivera * Management Complex cores should be held at reset out of POR. 1297b3bd9a7SJ. German Rivera * U-boot should be the first software to touch MC. To be safe, 1307b3bd9a7SJ. German Rivera * we reset all cores again by setting GCR1 to 0. It doesn't do 1317b3bd9a7SJ. German Rivera * anything if they are held at reset. After we setup the firmware 1327b3bd9a7SJ. German Rivera * we kick off MC by deasserting the reset bit for core 0, and 1337b3bd9a7SJ. German Rivera * deasserting the reset bits for Command Portal Managers. 1347b3bd9a7SJ. German Rivera * The stop bits are not touched here. They are used to stop the 1357b3bd9a7SJ. German Rivera * cores when they are active. Setting stop bits doesn't stop the 1367b3bd9a7SJ. German Rivera * cores from fetching instructions when they are released from 1377b3bd9a7SJ. German Rivera * reset. 1387b3bd9a7SJ. German Rivera */ 1397b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, 0); 1407b3bd9a7SJ. German Rivera dmb(); 1417b3bd9a7SJ. German Rivera 1427b3bd9a7SJ. German Rivera error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size); 1437b3bd9a7SJ. German Rivera if (error != 0) 1447b3bd9a7SJ. German Rivera goto out; 1457b3bd9a7SJ. German Rivera /* 1467b3bd9a7SJ. German Rivera * Load the MC FW at the beginning of the MC private DRAM block: 1477b3bd9a7SJ. German Rivera */ 1487b3bd9a7SJ. German Rivera mc_copy_image("MC Firmware", 1497b3bd9a7SJ. German Rivera (u64)raw_image_addr, raw_image_size, mc_ram_addr); 1507b3bd9a7SJ. German Rivera 1517b3bd9a7SJ. German Rivera /* 1527b3bd9a7SJ. German Rivera * Get address and size of the DPL blob stored in flash: 1537b3bd9a7SJ. German Rivera */ 1547b3bd9a7SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR 1557b3bd9a7SJ. German Rivera dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; 1567b3bd9a7SJ. German Rivera #else 1577b3bd9a7SJ. German Rivera #error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" 1587b3bd9a7SJ. German Rivera #endif 1597b3bd9a7SJ. German Rivera 1607b3bd9a7SJ. German Rivera error = fdt_check_header(dpl_fdt_hdr); 1617b3bd9a7SJ. German Rivera if (error != 0) { 1627b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); 1637b3bd9a7SJ. German Rivera goto out; 1647b3bd9a7SJ. German Rivera } 1657b3bd9a7SJ. German Rivera 1667b3bd9a7SJ. German Rivera dpl_size = fdt_totalsize(dpl_fdt_hdr); 1677b3bd9a7SJ. German Rivera if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { 1687b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", 1697b3bd9a7SJ. German Rivera dpl_size); 1707b3bd9a7SJ. German Rivera error = -EINVAL; 1717b3bd9a7SJ. German Rivera goto out; 1727b3bd9a7SJ. German Rivera } 1737b3bd9a7SJ. German Rivera 1747b3bd9a7SJ. German Rivera /* 1757b3bd9a7SJ. German Rivera * Calculate offset in the MC private DRAM block at which the MC DPL 1767b3bd9a7SJ. German Rivera * blob is to be placed: 1777b3bd9a7SJ. German Rivera */ 1787b3bd9a7SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 1797b3bd9a7SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || 1807b3bd9a7SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); 1817b3bd9a7SJ. German Rivera 1827b3bd9a7SJ. German Rivera mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; 1837b3bd9a7SJ. German Rivera #else 1847b3bd9a7SJ. German Rivera mc_dpl_offset = mc_get_dram_block_size() - 1857b3bd9a7SJ. German Rivera roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096); 1867b3bd9a7SJ. German Rivera 1877b3bd9a7SJ. German Rivera if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) { 1887b3bd9a7SJ. German Rivera printf("%s: Invalid MC DPL offset: %llu\n", 1897b3bd9a7SJ. German Rivera __func__, mc_dpl_offset); 1907b3bd9a7SJ. German Rivera error = -EINVAL; 1917b3bd9a7SJ. German Rivera goto out; 1927b3bd9a7SJ. German Rivera } 1937b3bd9a7SJ. German Rivera #endif 1947b3bd9a7SJ. German Rivera 1957b3bd9a7SJ. German Rivera /* 1967b3bd9a7SJ. German Rivera * Load the MC DPL blob at the far end of the MC private DRAM block: 1977b3bd9a7SJ. German Rivera * 1987b3bd9a7SJ. German Rivera * TODO: Should we place the DPL at a different location to match 1997b3bd9a7SJ. German Rivera * assumptions of MC firmware about its memory layout? 2007b3bd9a7SJ. German Rivera */ 2017b3bd9a7SJ. German Rivera mc_copy_image("MC DPL blob", 2027b3bd9a7SJ. German Rivera (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); 2037b3bd9a7SJ. German Rivera 2047b3bd9a7SJ. German Rivera debug("mc_ccsr_regs %p\n", mc_ccsr_regs); 2057b3bd9a7SJ. German Rivera 2067b3bd9a7SJ. German Rivera /* 2077b3bd9a7SJ. German Rivera * Tell MC where the MC Firmware image was loaded in DDR: 2087b3bd9a7SJ. German Rivera */ 2097b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr); 2107b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32)); 2117b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); 2127b3bd9a7SJ. German Rivera 2137b3bd9a7SJ. German Rivera /* 2147b3bd9a7SJ. German Rivera * Tell MC where the DPL blob was loaded in DDR, by indicating 2157b3bd9a7SJ. German Rivera * its offset relative to the beginning of the DDR block 2167b3bd9a7SJ. German Rivera * allocated to the MC firmware. The MC firmware is responsible 2177b3bd9a7SJ. German Rivera * for checking that there is no overlap between the DPL blob 2187b3bd9a7SJ. German Rivera * and the runtime heap and stack of the MC firmware itself. 2197b3bd9a7SJ. German Rivera * 2207b3bd9a7SJ. German Rivera * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of 2217b3bd9a7SJ. German Rivera * the GSR MC CCSR register. So, this offset is assumed to be 4-byte 2227b3bd9a7SJ. German Rivera * aligned. 2237b3bd9a7SJ. German Rivera * Care must be taken not to write 1s into bits 31 and 30 of the GSR in 2247b3bd9a7SJ. German Rivera * this case as the SoC COP or PIC will be signaled. 2257b3bd9a7SJ. German Rivera */ 2267b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2)); 2277b3bd9a7SJ. German Rivera 2287b3bd9a7SJ. German Rivera printf("\nfsl-mc: Booting Management Complex ...\n"); 2297b3bd9a7SJ. German Rivera 2307b3bd9a7SJ. German Rivera /* 2317b3bd9a7SJ. German Rivera * Deassert reset and release MC core 0 to run 2327b3bd9a7SJ. German Rivera */ 2337b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); 2347b3bd9a7SJ. German Rivera dmb(); 2357b3bd9a7SJ. German Rivera debug("Polling mc_ccsr_regs->reg_gsr ...\n"); 2367b3bd9a7SJ. German Rivera 2377b3bd9a7SJ. German Rivera for (;;) { 2387b3bd9a7SJ. German Rivera reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); 2397b3bd9a7SJ. German Rivera mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); 2407b3bd9a7SJ. German Rivera if (mc_fw_boot_status & 0x1) 2417b3bd9a7SJ. German Rivera break; 2427b3bd9a7SJ. German Rivera 2437b3bd9a7SJ. German Rivera udelay(1000); /* throttle polling */ 2447b3bd9a7SJ. German Rivera if (timeout-- <= 0) 2457b3bd9a7SJ. German Rivera break; 2467b3bd9a7SJ. German Rivera } 2477b3bd9a7SJ. German Rivera 2487b3bd9a7SJ. German Rivera if (timeout <= 0) { 2497b3bd9a7SJ. German Rivera printf("fsl-mc: timeout booting management complex firmware\n"); 2507b3bd9a7SJ. German Rivera 2517b3bd9a7SJ. German Rivera /* TODO: Get an error status from an MC CCSR register */ 2527b3bd9a7SJ. German Rivera error = -ETIMEDOUT; 2537b3bd9a7SJ. German Rivera goto out; 2547b3bd9a7SJ. German Rivera } 2557b3bd9a7SJ. German Rivera 2567b3bd9a7SJ. German Rivera if (mc_fw_boot_status != 0x1) { 2577b3bd9a7SJ. German Rivera /* 2587b3bd9a7SJ. German Rivera * TODO: Identify critical errors from the GSR register's FS 2597b3bd9a7SJ. German Rivera * field and for those errors, set error to -ENODEV or other 2607b3bd9a7SJ. German Rivera * appropriate errno, so that the status property is set to 2617b3bd9a7SJ. German Rivera * failure in the fsl,dprc device tree node. 2627b3bd9a7SJ. German Rivera */ 2637b3bd9a7SJ. German Rivera printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", 2647b3bd9a7SJ. German Rivera reg_gsr); 2657b3bd9a7SJ. German Rivera } 2667b3bd9a7SJ. German Rivera 2677b3bd9a7SJ. German Rivera /* 2687b3bd9a7SJ. German Rivera * TODO: need to obtain the portal_id for the root container from the 2697b3bd9a7SJ. German Rivera * DPL 2707b3bd9a7SJ. German Rivera */ 2717b3bd9a7SJ. German Rivera portal_id = 0; 2727b3bd9a7SJ. German Rivera 2737b3bd9a7SJ. German Rivera /* 274*a2a55e51SPrabhakar Kushwaha * Initialize the global default MC portal 275*a2a55e51SPrabhakar Kushwaha * And check that the MC firmware is responding portal commands: 2767b3bd9a7SJ. German Rivera */ 277*a2a55e51SPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 278*a2a55e51SPrabhakar Kushwaha if (!dflt_mc_io) { 279*a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 280*a2a55e51SPrabhakar Kushwaha return -ENOMEM; 281*a2a55e51SPrabhakar Kushwaha } 2827b3bd9a7SJ. German Rivera 283*a2a55e51SPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); 284*a2a55e51SPrabhakar Kushwaha debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", 285*a2a55e51SPrabhakar Kushwaha portal_id, dflt_mc_io->mmio_regs); 286*a2a55e51SPrabhakar Kushwaha 287*a2a55e51SPrabhakar Kushwaha error = mc_get_version(dflt_mc_io, &mc_ver_info); 2887b3bd9a7SJ. German Rivera if (error != 0) { 2897b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", 2907b3bd9a7SJ. German Rivera error); 2917b3bd9a7SJ. German Rivera goto out; 2927b3bd9a7SJ. German Rivera } 2937b3bd9a7SJ. German Rivera 2947b3bd9a7SJ. German Rivera if (MC_VER_MAJOR != mc_ver_info.major) 2957b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", 2967b3bd9a7SJ. German Rivera mc_ver_info.major, MC_VER_MAJOR); 2977b3bd9a7SJ. German Rivera 2987b3bd9a7SJ. German Rivera if (MC_VER_MINOR != mc_ver_info.minor) 2997b3bd9a7SJ. German Rivera printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", 3007b3bd9a7SJ. German Rivera mc_ver_info.minor, MC_VER_MINOR); 3017b3bd9a7SJ. German Rivera 3027b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 3037b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 3047b3bd9a7SJ. German Rivera mc_fw_boot_status); 3057b3bd9a7SJ. German Rivera out: 3067b3bd9a7SJ. German Rivera if (error != 0) 3077b3bd9a7SJ. German Rivera mc_boot_status = -error; 3087b3bd9a7SJ. German Rivera else 3097b3bd9a7SJ. German Rivera mc_boot_status = 0; 3107b3bd9a7SJ. German Rivera 3117b3bd9a7SJ. German Rivera return error; 3127b3bd9a7SJ. German Rivera } 3137b3bd9a7SJ. German Rivera 3147b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 3157b3bd9a7SJ. German Rivera { 3167b3bd9a7SJ. German Rivera return mc_boot_status; 3177b3bd9a7SJ. German Rivera } 3187b3bd9a7SJ. German Rivera 3197b3bd9a7SJ. German Rivera /** 3207b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 3217b3bd9a7SJ. German Rivera * 3227b3bd9a7SJ. German Rivera * NOTE: For now this function always returns the minimum required size, 3237b3bd9a7SJ. German Rivera * However, in the future, the actual size may be obtained from an environment 3247b3bd9a7SJ. German Rivera * variable. 3257b3bd9a7SJ. German Rivera */ 3267b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 3277b3bd9a7SJ. German Rivera { 3287b3bd9a7SJ. German Rivera return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 3297b3bd9a7SJ. German Rivera } 330*a2a55e51SPrabhakar Kushwaha 331*a2a55e51SPrabhakar Kushwaha int dpio_init(struct dprc_obj_desc obj_desc) 332*a2a55e51SPrabhakar Kushwaha { 333*a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 334*a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 335*a2a55e51SPrabhakar Kushwaha int err = 0; 336*a2a55e51SPrabhakar Kushwaha 337*a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 338*a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 339*a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 340*a2a55e51SPrabhakar Kushwaha return -ENOMEM; 341*a2a55e51SPrabhakar Kushwaha } 342*a2a55e51SPrabhakar Kushwaha 343*a2a55e51SPrabhakar Kushwaha dflt_dpio->dpio_id = obj_desc.id; 344*a2a55e51SPrabhakar Kushwaha 345*a2a55e51SPrabhakar Kushwaha err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle); 346*a2a55e51SPrabhakar Kushwaha if (err) { 347*a2a55e51SPrabhakar Kushwaha printf("dpio_open() failed\n"); 348*a2a55e51SPrabhakar Kushwaha goto err_open; 349*a2a55e51SPrabhakar Kushwaha } 350*a2a55e51SPrabhakar Kushwaha 351*a2a55e51SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr); 352*a2a55e51SPrabhakar Kushwaha if (err) { 353*a2a55e51SPrabhakar Kushwaha printf("dpio_get_attributes() failed %d\n", err); 354*a2a55e51SPrabhakar Kushwaha goto err_get_attr; 355*a2a55e51SPrabhakar Kushwaha } 356*a2a55e51SPrabhakar Kushwaha 357*a2a55e51SPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, dflt_dpio_handle); 358*a2a55e51SPrabhakar Kushwaha if (err) { 359*a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 360*a2a55e51SPrabhakar Kushwaha goto err_get_enable; 361*a2a55e51SPrabhakar Kushwaha } 362*a2a55e51SPrabhakar Kushwaha debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n", 363*a2a55e51SPrabhakar Kushwaha attr.qbman_portal_ce_paddr, 364*a2a55e51SPrabhakar Kushwaha attr.qbman_portal_ci_paddr, 365*a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 366*a2a55e51SPrabhakar Kushwaha attr.num_priorities); 367*a2a55e51SPrabhakar Kushwaha 368*a2a55e51SPrabhakar Kushwaha p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr; 369*a2a55e51SPrabhakar Kushwaha p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr; 370*a2a55e51SPrabhakar Kushwaha 371*a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 372*a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 373*a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 374*a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 375*a2a55e51SPrabhakar Kushwaha } 376*a2a55e51SPrabhakar Kushwaha return 0; 377*a2a55e51SPrabhakar Kushwaha 378*a2a55e51SPrabhakar Kushwaha err_get_swp_init: 379*a2a55e51SPrabhakar Kushwaha err_get_enable: 380*a2a55e51SPrabhakar Kushwaha dpio_disable(dflt_mc_io, dflt_dpio_handle); 381*a2a55e51SPrabhakar Kushwaha err_get_attr: 382*a2a55e51SPrabhakar Kushwaha dpio_close(dflt_mc_io, dflt_dpio_handle); 383*a2a55e51SPrabhakar Kushwaha err_open: 384*a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 385*a2a55e51SPrabhakar Kushwaha return err; 386*a2a55e51SPrabhakar Kushwaha } 387*a2a55e51SPrabhakar Kushwaha 388*a2a55e51SPrabhakar Kushwaha int dpbp_init(struct dprc_obj_desc obj_desc) 389*a2a55e51SPrabhakar Kushwaha { 390*a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 391*a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 392*a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 393*a2a55e51SPrabhakar Kushwaha return -ENOMEM; 394*a2a55e51SPrabhakar Kushwaha } 395*a2a55e51SPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = obj_desc.id; 396*a2a55e51SPrabhakar Kushwaha 397*a2a55e51SPrabhakar Kushwaha return 0; 398*a2a55e51SPrabhakar Kushwaha } 399*a2a55e51SPrabhakar Kushwaha 400*a2a55e51SPrabhakar Kushwaha int dprc_init_container_obj(struct dprc_obj_desc obj_desc) 401*a2a55e51SPrabhakar Kushwaha { 402*a2a55e51SPrabhakar Kushwaha int error = 0; 403*a2a55e51SPrabhakar Kushwaha if (!strcmp(obj_desc.type, "dpbp")) { 404*a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 405*a2a55e51SPrabhakar Kushwaha error = dpbp_init(obj_desc); 406*a2a55e51SPrabhakar Kushwaha if (error < 0) 407*a2a55e51SPrabhakar Kushwaha printf("dpbp_init failed\n"); 408*a2a55e51SPrabhakar Kushwaha } 409*a2a55e51SPrabhakar Kushwaha } else if (!strcmp(obj_desc.type, "dpio")) { 410*a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 411*a2a55e51SPrabhakar Kushwaha error = dpio_init(obj_desc); 412*a2a55e51SPrabhakar Kushwaha if (error < 0) 413*a2a55e51SPrabhakar Kushwaha printf("dpio_init failed\n"); 414*a2a55e51SPrabhakar Kushwaha } 415*a2a55e51SPrabhakar Kushwaha } 416*a2a55e51SPrabhakar Kushwaha 417*a2a55e51SPrabhakar Kushwaha return error; 418*a2a55e51SPrabhakar Kushwaha } 419*a2a55e51SPrabhakar Kushwaha 420*a2a55e51SPrabhakar Kushwaha int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i) 421*a2a55e51SPrabhakar Kushwaha { 422*a2a55e51SPrabhakar Kushwaha int error = 0; 423*a2a55e51SPrabhakar Kushwaha struct dprc_obj_desc obj_desc; 424*a2a55e51SPrabhakar Kushwaha 425*a2a55e51SPrabhakar Kushwaha memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc)); 426*a2a55e51SPrabhakar Kushwaha 427*a2a55e51SPrabhakar Kushwaha error = dprc_get_obj(dflt_mc_io, dprc_handle, 428*a2a55e51SPrabhakar Kushwaha i, &obj_desc); 429*a2a55e51SPrabhakar Kushwaha if (error < 0) { 430*a2a55e51SPrabhakar Kushwaha printf("dprc_get_obj(i=%d) failed: %d\n", 431*a2a55e51SPrabhakar Kushwaha i, error); 432*a2a55e51SPrabhakar Kushwaha return error; 433*a2a55e51SPrabhakar Kushwaha } 434*a2a55e51SPrabhakar Kushwaha 435*a2a55e51SPrabhakar Kushwaha if (!strcmp(obj_desc.type, obj_type)) { 436*a2a55e51SPrabhakar Kushwaha debug("Discovered object: type %s, id %d, req %s\n", 437*a2a55e51SPrabhakar Kushwaha obj_desc.type, obj_desc.id, obj_type); 438*a2a55e51SPrabhakar Kushwaha 439*a2a55e51SPrabhakar Kushwaha error = dprc_init_container_obj(obj_desc); 440*a2a55e51SPrabhakar Kushwaha if (error < 0) { 441*a2a55e51SPrabhakar Kushwaha printf("dprc_init_container_obj(i=%d) failed: %d\n", 442*a2a55e51SPrabhakar Kushwaha i, error); 443*a2a55e51SPrabhakar Kushwaha return error; 444*a2a55e51SPrabhakar Kushwaha } 445*a2a55e51SPrabhakar Kushwaha } 446*a2a55e51SPrabhakar Kushwaha 447*a2a55e51SPrabhakar Kushwaha return error; 448*a2a55e51SPrabhakar Kushwaha } 449*a2a55e51SPrabhakar Kushwaha 450*a2a55e51SPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 451*a2a55e51SPrabhakar Kushwaha { 452*a2a55e51SPrabhakar Kushwaha int i, error = 0; 453*a2a55e51SPrabhakar Kushwaha int dprc_opened = 0, container_id; 454*a2a55e51SPrabhakar Kushwaha int num_child_objects = 0; 455*a2a55e51SPrabhakar Kushwaha 456*a2a55e51SPrabhakar Kushwaha error = mc_init(); 457*a2a55e51SPrabhakar Kushwaha 458*a2a55e51SPrabhakar Kushwaha error = dprc_get_container_id(dflt_mc_io, &container_id); 459*a2a55e51SPrabhakar Kushwaha if (error < 0) { 460*a2a55e51SPrabhakar Kushwaha printf("dprc_get_container_id() failed: %d\n", error); 461*a2a55e51SPrabhakar Kushwaha goto error; 462*a2a55e51SPrabhakar Kushwaha } 463*a2a55e51SPrabhakar Kushwaha 464*a2a55e51SPrabhakar Kushwaha debug("fsl-mc: Container id=0x%x\n", container_id); 465*a2a55e51SPrabhakar Kushwaha 466*a2a55e51SPrabhakar Kushwaha error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle); 467*a2a55e51SPrabhakar Kushwaha if (error < 0) { 468*a2a55e51SPrabhakar Kushwaha printf("dprc_open() failed: %d\n", error); 469*a2a55e51SPrabhakar Kushwaha goto error; 470*a2a55e51SPrabhakar Kushwaha } 471*a2a55e51SPrabhakar Kushwaha dprc_opened = true; 472*a2a55e51SPrabhakar Kushwaha 473*a2a55e51SPrabhakar Kushwaha error = dprc_get_obj_count(dflt_mc_io, 474*a2a55e51SPrabhakar Kushwaha dflt_dprc_handle, 475*a2a55e51SPrabhakar Kushwaha &num_child_objects); 476*a2a55e51SPrabhakar Kushwaha if (error < 0) { 477*a2a55e51SPrabhakar Kushwaha printf("dprc_get_obj_count() failed: %d\n", error); 478*a2a55e51SPrabhakar Kushwaha goto error; 479*a2a55e51SPrabhakar Kushwaha } 480*a2a55e51SPrabhakar Kushwaha debug("Total child in container %d = %d\n", container_id, 481*a2a55e51SPrabhakar Kushwaha num_child_objects); 482*a2a55e51SPrabhakar Kushwaha 483*a2a55e51SPrabhakar Kushwaha if (num_child_objects != 0) { 484*a2a55e51SPrabhakar Kushwaha /* 485*a2a55e51SPrabhakar Kushwaha * Discover objects currently in the DPRC container in the MC: 486*a2a55e51SPrabhakar Kushwaha */ 487*a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 488*a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 489*a2a55e51SPrabhakar Kushwaha "dpbp", i); 490*a2a55e51SPrabhakar Kushwaha 491*a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 492*a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 493*a2a55e51SPrabhakar Kushwaha "dpio", i); 494*a2a55e51SPrabhakar Kushwaha 495*a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 496*a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 497*a2a55e51SPrabhakar Kushwaha "dpni", i); 498*a2a55e51SPrabhakar Kushwaha } 499*a2a55e51SPrabhakar Kushwaha error: 500*a2a55e51SPrabhakar Kushwaha if (dprc_opened) 501*a2a55e51SPrabhakar Kushwaha dprc_close(dflt_mc_io, dflt_dprc_handle); 502*a2a55e51SPrabhakar Kushwaha 503*a2a55e51SPrabhakar Kushwaha return error; 504*a2a55e51SPrabhakar Kushwaha } 505*a2a55e51SPrabhakar Kushwaha 506*a2a55e51SPrabhakar Kushwaha void fsl_mc_ldpaa_exit(bd_t *bis) 507*a2a55e51SPrabhakar Kushwaha { 508*a2a55e51SPrabhakar Kushwaha int err; 509*a2a55e51SPrabhakar Kushwaha 510*a2a55e51SPrabhakar Kushwaha 511*a2a55e51SPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, dflt_dpio_handle); 512*a2a55e51SPrabhakar Kushwaha if (err < 0) { 513*a2a55e51SPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 514*a2a55e51SPrabhakar Kushwaha return; 515*a2a55e51SPrabhakar Kushwaha } 516*a2a55e51SPrabhakar Kushwaha err = dpio_reset(dflt_mc_io, dflt_dpio_handle); 517*a2a55e51SPrabhakar Kushwaha if (err < 0) { 518*a2a55e51SPrabhakar Kushwaha printf("dpio_reset() failed: %d\n", err); 519*a2a55e51SPrabhakar Kushwaha return; 520*a2a55e51SPrabhakar Kushwaha } 521*a2a55e51SPrabhakar Kushwaha err = dpio_close(dflt_mc_io, dflt_dpio_handle); 522*a2a55e51SPrabhakar Kushwaha if (err < 0) { 523*a2a55e51SPrabhakar Kushwaha printf("dpio_close() failed: %d\n", err); 524*a2a55e51SPrabhakar Kushwaha return; 525*a2a55e51SPrabhakar Kushwaha } 526*a2a55e51SPrabhakar Kushwaha 527*a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 528*a2a55e51SPrabhakar Kushwaha free(dflt_dpbp); 529*a2a55e51SPrabhakar Kushwaha free(dflt_mc_io); 530*a2a55e51SPrabhakar Kushwaha } 531