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 #include <errno.h> 77b3bd9a7SJ. German Rivera #include <asm/io.h> 87b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc.h> 97b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc_sys.h> 10a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_mc_private.h> 117b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_dpmng.h> 12a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dprc.h> 13a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dpio.h> 14a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_qbman_portal.h> 157b3bd9a7SJ. German Rivera 16125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) 17125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) 18125e2bc1SJ. German Rivera #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) 19125e2bc1SJ. German Rivera 20125e2bc1SJ. German Rivera #define MC_MEM_SIZE_ENV_VAR "mcmemsize" 21125e2bc1SJ. German Rivera #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" 22125e2bc1SJ. German Rivera 237b3bd9a7SJ. German Rivera DECLARE_GLOBAL_DATA_PTR; 247b3bd9a7SJ. German Rivera static int mc_boot_status; 25a2a55e51SPrabhakar Kushwaha struct fsl_mc_io *dflt_mc_io = NULL; 26a2a55e51SPrabhakar Kushwaha uint16_t dflt_dprc_handle = 0; 27a2a55e51SPrabhakar Kushwaha struct fsl_dpbp_obj *dflt_dpbp = NULL; 28a2a55e51SPrabhakar Kushwaha struct fsl_dpio_obj *dflt_dpio = NULL; 29125e2bc1SJ. German Rivera uint16_t dflt_dpio_handle = 0; 307b3bd9a7SJ. German Rivera 31125e2bc1SJ. German Rivera #ifdef DEBUG 32125e2bc1SJ. German Rivera void dump_ram_words(const char *title, void *addr) 33125e2bc1SJ. German Rivera { 34125e2bc1SJ. German Rivera int i; 35125e2bc1SJ. German Rivera uint32_t *words = addr; 36125e2bc1SJ. German Rivera 37125e2bc1SJ. German Rivera printf("Dumping beginning of %s (%p):\n", title, addr); 38125e2bc1SJ. German Rivera for (i = 0; i < 16; i++) 39125e2bc1SJ. German Rivera printf("%#x ", words[i]); 40125e2bc1SJ. German Rivera 41125e2bc1SJ. German Rivera printf("\n"); 42125e2bc1SJ. German Rivera } 43125e2bc1SJ. German Rivera 44125e2bc1SJ. German Rivera void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) 45125e2bc1SJ. German Rivera { 46125e2bc1SJ. German Rivera printf("MC CCSR registers:\n" 47125e2bc1SJ. German Rivera "reg_gcr1 %#x\n" 48125e2bc1SJ. German Rivera "reg_gsr %#x\n" 49125e2bc1SJ. German Rivera "reg_sicbalr %#x\n" 50125e2bc1SJ. German Rivera "reg_sicbahr %#x\n" 51125e2bc1SJ. German Rivera "reg_sicapr %#x\n" 52125e2bc1SJ. German Rivera "reg_mcfbalr %#x\n" 53125e2bc1SJ. German Rivera "reg_mcfbahr %#x\n" 54125e2bc1SJ. German Rivera "reg_mcfapr %#x\n" 55125e2bc1SJ. German Rivera "reg_psr %#x\n", 56125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gcr1, 57125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gsr, 58125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbalr, 59125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbahr, 60125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicapr, 61125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbalr, 62125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbahr, 63125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfapr, 64125e2bc1SJ. German Rivera mc_ccsr_regs->reg_psr); 65125e2bc1SJ. German Rivera } 66125e2bc1SJ. German Rivera #else 67125e2bc1SJ. German Rivera 68125e2bc1SJ. German Rivera #define dump_ram_words(title, addr) 69125e2bc1SJ. German Rivera #define dump_mc_ccsr_regs(mc_ccsr_regs) 70125e2bc1SJ. German Rivera 71125e2bc1SJ. German Rivera #endif /* DEBUG */ 72125e2bc1SJ. German Rivera 73125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 747b3bd9a7SJ. German Rivera /** 757b3bd9a7SJ. German Rivera * Copying MC firmware or DPL image to DDR 767b3bd9a7SJ. German Rivera */ 777b3bd9a7SJ. German Rivera static int mc_copy_image(const char *title, 787b3bd9a7SJ. German Rivera u64 image_addr, u32 image_size, u64 mc_ram_addr) 797b3bd9a7SJ. German Rivera { 807b3bd9a7SJ. German Rivera debug("%s copied to address %p\n", title, (void *)mc_ram_addr); 817b3bd9a7SJ. German Rivera memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); 82125e2bc1SJ. German Rivera flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); 837b3bd9a7SJ. German Rivera return 0; 847b3bd9a7SJ. German Rivera } 857b3bd9a7SJ. German Rivera 867b3bd9a7SJ. German Rivera /** 877b3bd9a7SJ. German Rivera * MC firmware FIT image parser checks if the image is in FIT 887b3bd9a7SJ. German Rivera * format, verifies integrity of the image and calculates 897b3bd9a7SJ. German Rivera * raw image address and size values. 907b3bd9a7SJ. German Rivera * Returns 0 on success and a negative errno on error. 917b3bd9a7SJ. German Rivera * task fail. 927b3bd9a7SJ. German Rivera **/ 937b3bd9a7SJ. German Rivera int parse_mc_firmware_fit_image(const void **raw_image_addr, 947b3bd9a7SJ. German Rivera size_t *raw_image_size) 957b3bd9a7SJ. German Rivera { 967b3bd9a7SJ. German Rivera int format; 977b3bd9a7SJ. German Rivera void *fit_hdr; 987b3bd9a7SJ. German Rivera int node_offset; 997b3bd9a7SJ. German Rivera const void *data; 1007b3bd9a7SJ. German Rivera size_t size; 1017b3bd9a7SJ. German Rivera const char *uname = "firmware"; 1027b3bd9a7SJ. German Rivera 1037b3bd9a7SJ. German Rivera /* Check if the image is in NOR flash */ 1047b3bd9a7SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR 1057b3bd9a7SJ. German Rivera fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; 1067b3bd9a7SJ. German Rivera #else 1077b3bd9a7SJ. German Rivera #error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined" 1087b3bd9a7SJ. German Rivera #endif 1097b3bd9a7SJ. German Rivera 1107b3bd9a7SJ. German Rivera /* Check if Image is in FIT format */ 1117b3bd9a7SJ. German Rivera format = genimg_get_format(fit_hdr); 1127b3bd9a7SJ. German Rivera 1137b3bd9a7SJ. German Rivera if (format != IMAGE_FORMAT_FIT) { 1147b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n"); 1157b3bd9a7SJ. German Rivera return -EINVAL; 1167b3bd9a7SJ. German Rivera } 1177b3bd9a7SJ. German Rivera 1187b3bd9a7SJ. German Rivera if (!fit_check_format(fit_hdr)) { 1197b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n"); 1207b3bd9a7SJ. German Rivera return -EINVAL; 1217b3bd9a7SJ. German Rivera } 1227b3bd9a7SJ. German Rivera 1237b3bd9a7SJ. German Rivera node_offset = fit_image_get_node(fit_hdr, uname); 1247b3bd9a7SJ. German Rivera 1257b3bd9a7SJ. German Rivera if (node_offset < 0) { 1267b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n"); 1277b3bd9a7SJ. German Rivera return -ENOENT; 1287b3bd9a7SJ. German Rivera } 1297b3bd9a7SJ. German Rivera 1307b3bd9a7SJ. German Rivera /* Verify MC firmware image */ 1317b3bd9a7SJ. German Rivera if (!(fit_image_verify(fit_hdr, node_offset))) { 1327b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n"); 1337b3bd9a7SJ. German Rivera return -EINVAL; 1347b3bd9a7SJ. German Rivera } 1357b3bd9a7SJ. German Rivera 1367b3bd9a7SJ. German Rivera /* Get address and size of raw image */ 1377b3bd9a7SJ. German Rivera fit_image_get_data(fit_hdr, node_offset, &data, &size); 1387b3bd9a7SJ. German Rivera 1397b3bd9a7SJ. German Rivera *raw_image_addr = data; 1407b3bd9a7SJ. German Rivera *raw_image_size = size; 1417b3bd9a7SJ. German Rivera 1427b3bd9a7SJ. German Rivera return 0; 1437b3bd9a7SJ. German Rivera } 144125e2bc1SJ. German Rivera #endif 145125e2bc1SJ. German Rivera 146125e2bc1SJ. German Rivera /* 147125e2bc1SJ. German Rivera * Calculates the values to be used to specify the address range 148125e2bc1SJ. German Rivera * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers. 149125e2bc1SJ. German Rivera * It returns the highest 512MB-aligned address within the given 150125e2bc1SJ. German Rivera * address range, in '*aligned_base_addr', and the number of 256 MiB 151125e2bc1SJ. German Rivera * blocks in it, in 'num_256mb_blocks'. 152125e2bc1SJ. German Rivera */ 153125e2bc1SJ. German Rivera static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr, 154125e2bc1SJ. German Rivera size_t mc_ram_size, 155125e2bc1SJ. German Rivera u64 *aligned_base_addr, 156125e2bc1SJ. German Rivera u8 *num_256mb_blocks) 157125e2bc1SJ. German Rivera { 158125e2bc1SJ. German Rivera u64 addr; 159125e2bc1SJ. German Rivera u16 num_blocks; 160125e2bc1SJ. German Rivera 161125e2bc1SJ. German Rivera if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) { 162125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 163125e2bc1SJ. German Rivera mc_ram_size); 164125e2bc1SJ. German Rivera return -EINVAL; 165125e2bc1SJ. German Rivera } 166125e2bc1SJ. German Rivera 167125e2bc1SJ. German Rivera num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; 168125e2bc1SJ. German Rivera if (num_blocks < 1 || num_blocks > 0xff) { 169125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 170125e2bc1SJ. German Rivera mc_ram_size); 171125e2bc1SJ. German Rivera return -EINVAL; 172125e2bc1SJ. German Rivera } 173125e2bc1SJ. German Rivera 174125e2bc1SJ. German Rivera addr = (mc_private_ram_start_addr + mc_ram_size - 1) & 175125e2bc1SJ. German Rivera MC_RAM_BASE_ADDR_ALIGNMENT_MASK; 176125e2bc1SJ. German Rivera 177125e2bc1SJ. German Rivera if (addr < mc_private_ram_start_addr) { 178125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: bad start address %#llx\n", 179125e2bc1SJ. German Rivera mc_private_ram_start_addr); 180125e2bc1SJ. German Rivera return -EFAULT; 181125e2bc1SJ. German Rivera } 182125e2bc1SJ. German Rivera 183125e2bc1SJ. German Rivera *aligned_base_addr = addr; 184125e2bc1SJ. German Rivera *num_256mb_blocks = num_blocks; 185125e2bc1SJ. German Rivera return 0; 186125e2bc1SJ. German Rivera } 187125e2bc1SJ. German Rivera 188125e2bc1SJ. German Rivera static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) 189125e2bc1SJ. German Rivera { 190125e2bc1SJ. German Rivera u64 mc_dpc_offset; 191125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 192125e2bc1SJ. German Rivera int error; 193125e2bc1SJ. German Rivera void *dpc_fdt_hdr; 194125e2bc1SJ. German Rivera int dpc_size; 195125e2bc1SJ. German Rivera #endif 196125e2bc1SJ. German Rivera 197125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 198125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || 199125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); 200125e2bc1SJ. German Rivera 201125e2bc1SJ. German Rivera mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; 202125e2bc1SJ. German Rivera #else 203125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" 204125e2bc1SJ. German Rivera #endif 205125e2bc1SJ. German Rivera 206125e2bc1SJ. German Rivera /* 207125e2bc1SJ. German Rivera * Load the MC DPC blob in the MC private DRAM block: 208125e2bc1SJ. German Rivera */ 209125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 210125e2bc1SJ. German Rivera printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); 211125e2bc1SJ. German Rivera #else 212125e2bc1SJ. German Rivera /* 213125e2bc1SJ. German Rivera * Get address and size of the DPC blob stored in flash: 214125e2bc1SJ. German Rivera */ 215125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPC_IN_NOR 216125e2bc1SJ. German Rivera dpc_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPC_ADDR; 217125e2bc1SJ. German Rivera #else 218125e2bc1SJ. German Rivera #error "No CONFIG_SYS_LS_MC_DPC_IN_xxx defined" 219125e2bc1SJ. German Rivera #endif 220125e2bc1SJ. German Rivera 221125e2bc1SJ. German Rivera error = fdt_check_header(dpc_fdt_hdr); 222125e2bc1SJ. German Rivera if (error != 0) { 223125e2bc1SJ. German Rivera /* 224125e2bc1SJ. German Rivera * Don't return with error here, since the MC firmware can 225125e2bc1SJ. German Rivera * still boot without a DPC 226125e2bc1SJ. German Rivera */ 227*cc088c3aSJ. German Rivera printf("\nfsl-mc: WARNING: No DPC image found"); 228125e2bc1SJ. German Rivera return 0; 229125e2bc1SJ. German Rivera } 230125e2bc1SJ. German Rivera 231125e2bc1SJ. German Rivera dpc_size = fdt_totalsize(dpc_fdt_hdr); 232125e2bc1SJ. German Rivera if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { 233*cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", 234125e2bc1SJ. German Rivera dpc_size); 235125e2bc1SJ. German Rivera return -EINVAL; 236125e2bc1SJ. German Rivera } 237125e2bc1SJ. German Rivera 238125e2bc1SJ. German Rivera mc_copy_image("MC DPC blob", 239125e2bc1SJ. German Rivera (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); 240125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ 241125e2bc1SJ. German Rivera 242125e2bc1SJ. German Rivera dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); 243125e2bc1SJ. German Rivera return 0; 244125e2bc1SJ. German Rivera } 245125e2bc1SJ. German Rivera 246125e2bc1SJ. German Rivera static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size) 247125e2bc1SJ. German Rivera { 248125e2bc1SJ. German Rivera u64 mc_dpl_offset; 249125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR 250125e2bc1SJ. German Rivera int error; 251125e2bc1SJ. German Rivera void *dpl_fdt_hdr; 252125e2bc1SJ. German Rivera int dpl_size; 253125e2bc1SJ. German Rivera #endif 254125e2bc1SJ. German Rivera 255125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 256125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || 257125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); 258125e2bc1SJ. German Rivera 259125e2bc1SJ. German Rivera mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; 260125e2bc1SJ. German Rivera #else 261125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" 262125e2bc1SJ. German Rivera #endif 263125e2bc1SJ. German Rivera 264125e2bc1SJ. German Rivera /* 265125e2bc1SJ. German Rivera * Load the MC DPL blob in the MC private DRAM block: 266125e2bc1SJ. German Rivera */ 267125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR 268125e2bc1SJ. German Rivera printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); 269125e2bc1SJ. German Rivera #else 270125e2bc1SJ. German Rivera /* 271125e2bc1SJ. German Rivera * Get address and size of the DPL blob stored in flash: 272125e2bc1SJ. German Rivera */ 273125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR 274125e2bc1SJ. German Rivera dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; 275125e2bc1SJ. German Rivera #else 276125e2bc1SJ. German Rivera #error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" 277125e2bc1SJ. German Rivera #endif 278125e2bc1SJ. German Rivera 279125e2bc1SJ. German Rivera error = fdt_check_header(dpl_fdt_hdr); 280125e2bc1SJ. German Rivera if (error != 0) { 281*cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); 282125e2bc1SJ. German Rivera return error; 283125e2bc1SJ. German Rivera } 284125e2bc1SJ. German Rivera 285125e2bc1SJ. German Rivera dpl_size = fdt_totalsize(dpl_fdt_hdr); 286125e2bc1SJ. German Rivera if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { 287*cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", 288125e2bc1SJ. German Rivera dpl_size); 289125e2bc1SJ. German Rivera return -EINVAL; 290125e2bc1SJ. German Rivera } 291125e2bc1SJ. German Rivera 292125e2bc1SJ. German Rivera mc_copy_image("MC DPL blob", 293125e2bc1SJ. German Rivera (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); 294125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ 295125e2bc1SJ. German Rivera 296125e2bc1SJ. German Rivera dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); 297125e2bc1SJ. German Rivera return 0; 298125e2bc1SJ. German Rivera } 299125e2bc1SJ. German Rivera 300125e2bc1SJ. German Rivera /** 301125e2bc1SJ. German Rivera * Return the MC boot timeout value in milliseconds 302125e2bc1SJ. German Rivera */ 303125e2bc1SJ. German Rivera static unsigned long get_mc_boot_timeout_ms(void) 304125e2bc1SJ. German Rivera { 305125e2bc1SJ. German Rivera unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 306125e2bc1SJ. German Rivera 307125e2bc1SJ. German Rivera char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR); 308125e2bc1SJ. German Rivera 309125e2bc1SJ. German Rivera if (timeout_ms_env_var) { 310125e2bc1SJ. German Rivera timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); 311125e2bc1SJ. German Rivera if (timeout_ms == 0) { 312125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 313125e2bc1SJ. German Rivera MC_BOOT_TIMEOUT_ENV_VAR 314125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 315125e2bc1SJ. German Rivera timeout_ms); 316125e2bc1SJ. German Rivera 317125e2bc1SJ. German Rivera timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 318125e2bc1SJ. German Rivera } 319125e2bc1SJ. German Rivera } 320125e2bc1SJ. German Rivera 321125e2bc1SJ. German Rivera return timeout_ms; 322125e2bc1SJ. German Rivera } 323125e2bc1SJ. German Rivera 324125e2bc1SJ. German Rivera static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) 325125e2bc1SJ. German Rivera { 326125e2bc1SJ. German Rivera u32 reg_gsr; 327125e2bc1SJ. German Rivera u32 mc_fw_boot_status; 328125e2bc1SJ. German Rivera unsigned long timeout_ms = get_mc_boot_timeout_ms(); 329125e2bc1SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 330125e2bc1SJ. German Rivera 331125e2bc1SJ. German Rivera dmb(); 332125e2bc1SJ. German Rivera assert(timeout_ms > 0); 333125e2bc1SJ. German Rivera for (;;) { 334125e2bc1SJ. German Rivera udelay(1000); /* throttle polling */ 335125e2bc1SJ. German Rivera reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); 336125e2bc1SJ. German Rivera mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); 337125e2bc1SJ. German Rivera if (mc_fw_boot_status & 0x1) 338125e2bc1SJ. German Rivera break; 339125e2bc1SJ. German Rivera 340125e2bc1SJ. German Rivera timeout_ms--; 341125e2bc1SJ. German Rivera if (timeout_ms == 0) 342125e2bc1SJ. German Rivera break; 343125e2bc1SJ. German Rivera } 344125e2bc1SJ. German Rivera 345125e2bc1SJ. German Rivera if (timeout_ms == 0) { 346*cc088c3aSJ. German Rivera printf("ERROR: timeout\n"); 347125e2bc1SJ. German Rivera 348125e2bc1SJ. German Rivera /* TODO: Get an error status from an MC CCSR register */ 349125e2bc1SJ. German Rivera return -ETIMEDOUT; 350125e2bc1SJ. German Rivera } 351125e2bc1SJ. German Rivera 352125e2bc1SJ. German Rivera if (mc_fw_boot_status != 0x1) { 353125e2bc1SJ. German Rivera /* 354125e2bc1SJ. German Rivera * TODO: Identify critical errors from the GSR register's FS 355125e2bc1SJ. German Rivera * field and for those errors, set error to -ENODEV or other 356125e2bc1SJ. German Rivera * appropriate errno, so that the status property is set to 357125e2bc1SJ. German Rivera * failure in the fsl,dprc device tree node. 358125e2bc1SJ. German Rivera */ 359*cc088c3aSJ. German Rivera printf("WARNING: Firmware returned an error (GSR: %#x)\n", 360125e2bc1SJ. German Rivera reg_gsr); 361125e2bc1SJ. German Rivera } else { 362*cc088c3aSJ. German Rivera printf("SUCCESS\n"); 363125e2bc1SJ. German Rivera } 364*cc088c3aSJ. German Rivera 365125e2bc1SJ. German Rivera 366125e2bc1SJ. German Rivera *final_reg_gsr = reg_gsr; 367125e2bc1SJ. German Rivera return 0; 368125e2bc1SJ. German Rivera } 3697b3bd9a7SJ. German Rivera 370a2a55e51SPrabhakar Kushwaha int mc_init(void) 3717b3bd9a7SJ. German Rivera { 3727b3bd9a7SJ. German Rivera int error = 0; 373a2a55e51SPrabhakar Kushwaha int portal_id = 0; 3747b3bd9a7SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 3757b3bd9a7SJ. German Rivera u64 mc_ram_addr; 3767b3bd9a7SJ. German Rivera u32 reg_gsr; 377125e2bc1SJ. German Rivera u32 reg_mcfbalr; 378125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 3797b3bd9a7SJ. German Rivera const void *raw_image_addr; 3807b3bd9a7SJ. German Rivera size_t raw_image_size = 0; 381125e2bc1SJ. German Rivera #endif 3827b3bd9a7SJ. German Rivera struct mc_version mc_ver_info; 383125e2bc1SJ. German Rivera u64 mc_ram_aligned_base_addr; 384125e2bc1SJ. German Rivera u8 mc_ram_num_256mb_blocks; 385125e2bc1SJ. German Rivera size_t mc_ram_size = mc_get_dram_block_size(); 3867b3bd9a7SJ. German Rivera 3877b3bd9a7SJ. German Rivera /* 3887b3bd9a7SJ. German Rivera * The MC private DRAM block was already carved at the end of DRAM 3897b3bd9a7SJ. German Rivera * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: 3907b3bd9a7SJ. German Rivera */ 3917b3bd9a7SJ. German Rivera if (gd->bd->bi_dram[1].start) { 3927b3bd9a7SJ. German Rivera mc_ram_addr = 3937b3bd9a7SJ. German Rivera gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; 3947b3bd9a7SJ. German Rivera } else { 3957b3bd9a7SJ. German Rivera mc_ram_addr = 3967b3bd9a7SJ. German Rivera gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; 3977b3bd9a7SJ. German Rivera } 3987b3bd9a7SJ. German Rivera 399125e2bc1SJ. German Rivera error = calculate_mc_private_ram_params(mc_ram_addr, 400125e2bc1SJ. German Rivera mc_ram_size, 401125e2bc1SJ. German Rivera &mc_ram_aligned_base_addr, 402125e2bc1SJ. German Rivera &mc_ram_num_256mb_blocks); 403125e2bc1SJ. German Rivera if (error != 0) 404125e2bc1SJ. German Rivera goto out; 405125e2bc1SJ. German Rivera 4067b3bd9a7SJ. German Rivera /* 4077b3bd9a7SJ. German Rivera * Management Complex cores should be held at reset out of POR. 4087b3bd9a7SJ. German Rivera * U-boot should be the first software to touch MC. To be safe, 4097b3bd9a7SJ. German Rivera * we reset all cores again by setting GCR1 to 0. It doesn't do 4107b3bd9a7SJ. German Rivera * anything if they are held at reset. After we setup the firmware 4117b3bd9a7SJ. German Rivera * we kick off MC by deasserting the reset bit for core 0, and 4127b3bd9a7SJ. German Rivera * deasserting the reset bits for Command Portal Managers. 4137b3bd9a7SJ. German Rivera * The stop bits are not touched here. They are used to stop the 4147b3bd9a7SJ. German Rivera * cores when they are active. Setting stop bits doesn't stop the 4157b3bd9a7SJ. German Rivera * cores from fetching instructions when they are released from 4167b3bd9a7SJ. German Rivera * reset. 4177b3bd9a7SJ. German Rivera */ 4187b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, 0); 4197b3bd9a7SJ. German Rivera dmb(); 4207b3bd9a7SJ. German Rivera 421125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR 422125e2bc1SJ. German Rivera printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); 423125e2bc1SJ. German Rivera #else 4247b3bd9a7SJ. German Rivera error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size); 4257b3bd9a7SJ. German Rivera if (error != 0) 4267b3bd9a7SJ. German Rivera goto out; 4277b3bd9a7SJ. German Rivera /* 4287b3bd9a7SJ. German Rivera * Load the MC FW at the beginning of the MC private DRAM block: 4297b3bd9a7SJ. German Rivera */ 4307b3bd9a7SJ. German Rivera mc_copy_image("MC Firmware", 4317b3bd9a7SJ. German Rivera (u64)raw_image_addr, raw_image_size, mc_ram_addr); 4327b3bd9a7SJ. German Rivera #endif 433125e2bc1SJ. German Rivera dump_ram_words("firmware", (void *)mc_ram_addr); 4347b3bd9a7SJ. German Rivera 435125e2bc1SJ. German Rivera error = load_mc_dpc(mc_ram_addr, mc_ram_size); 436125e2bc1SJ. German Rivera if (error != 0) 4377b3bd9a7SJ. German Rivera goto out; 4387b3bd9a7SJ. German Rivera 439125e2bc1SJ. German Rivera error = load_mc_dpl(mc_ram_addr, mc_ram_size); 440125e2bc1SJ. German Rivera if (error != 0) 4417b3bd9a7SJ. German Rivera goto out; 4427b3bd9a7SJ. German Rivera 4437b3bd9a7SJ. German Rivera debug("mc_ccsr_regs %p\n", mc_ccsr_regs); 444125e2bc1SJ. German Rivera dump_mc_ccsr_regs(mc_ccsr_regs); 4457b3bd9a7SJ. German Rivera 4467b3bd9a7SJ. German Rivera /* 447125e2bc1SJ. German Rivera * Tell MC what is the address range of the DRAM block assigned to it: 4487b3bd9a7SJ. German Rivera */ 449125e2bc1SJ. German Rivera reg_mcfbalr = (u32)mc_ram_aligned_base_addr | 450125e2bc1SJ. German Rivera (mc_ram_num_256mb_blocks - 1); 451125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); 452125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbahr, 453125e2bc1SJ. German Rivera (u32)(mc_ram_aligned_base_addr >> 32)); 4547b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); 4557b3bd9a7SJ. German Rivera 4567b3bd9a7SJ. German Rivera /* 457125e2bc1SJ. German Rivera * Tell the MC that we want delayed DPL deployment. 4587b3bd9a7SJ. German Rivera */ 459125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); 4607b3bd9a7SJ. German Rivera 461*cc088c3aSJ. German Rivera printf("\nfsl-mc: Booting Management Complex ... "); 4627b3bd9a7SJ. German Rivera 4637b3bd9a7SJ. German Rivera /* 4647b3bd9a7SJ. German Rivera * Deassert reset and release MC core 0 to run 4657b3bd9a7SJ. German Rivera */ 4667b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); 467125e2bc1SJ. German Rivera error = wait_for_mc(true, ®_gsr); 468125e2bc1SJ. German Rivera if (error != 0) 4697b3bd9a7SJ. German Rivera goto out; 4707b3bd9a7SJ. German Rivera 4717b3bd9a7SJ. German Rivera /* 4727b3bd9a7SJ. German Rivera * TODO: need to obtain the portal_id for the root container from the 4737b3bd9a7SJ. German Rivera * DPL 4747b3bd9a7SJ. German Rivera */ 4757b3bd9a7SJ. German Rivera portal_id = 0; 4767b3bd9a7SJ. German Rivera 4777b3bd9a7SJ. German Rivera /* 478a2a55e51SPrabhakar Kushwaha * Initialize the global default MC portal 479a2a55e51SPrabhakar Kushwaha * And check that the MC firmware is responding portal commands: 4807b3bd9a7SJ. German Rivera */ 481a2a55e51SPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 482a2a55e51SPrabhakar Kushwaha if (!dflt_mc_io) { 483a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 484a2a55e51SPrabhakar Kushwaha return -ENOMEM; 485a2a55e51SPrabhakar Kushwaha } 4867b3bd9a7SJ. German Rivera 487a2a55e51SPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); 488a2a55e51SPrabhakar Kushwaha debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", 489a2a55e51SPrabhakar Kushwaha portal_id, dflt_mc_io->mmio_regs); 490a2a55e51SPrabhakar Kushwaha 491a2a55e51SPrabhakar Kushwaha error = mc_get_version(dflt_mc_io, &mc_ver_info); 4927b3bd9a7SJ. German Rivera if (error != 0) { 4937b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", 4947b3bd9a7SJ. German Rivera error); 4957b3bd9a7SJ. German Rivera goto out; 4967b3bd9a7SJ. German Rivera } 4977b3bd9a7SJ. German Rivera 4987b3bd9a7SJ. German Rivera if (MC_VER_MAJOR != mc_ver_info.major) 4997b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", 5007b3bd9a7SJ. German Rivera mc_ver_info.major, MC_VER_MAJOR); 5017b3bd9a7SJ. German Rivera 5027b3bd9a7SJ. German Rivera if (MC_VER_MINOR != mc_ver_info.minor) 5037b3bd9a7SJ. German Rivera printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", 5047b3bd9a7SJ. German Rivera mc_ver_info.minor, MC_VER_MINOR); 5057b3bd9a7SJ. German Rivera 5067b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 5077b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 508125e2bc1SJ. German Rivera reg_gsr & GSR_FS_MASK); 509125e2bc1SJ. German Rivera 510125e2bc1SJ. German Rivera /* 511125e2bc1SJ. German Rivera * Tell the MC to deploy the DPL: 512125e2bc1SJ. German Rivera */ 513125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, 0x0); 514*cc088c3aSJ. German Rivera printf("fsl-mc: Deploying data path layout ... "); 515125e2bc1SJ. German Rivera error = wait_for_mc(false, ®_gsr); 516125e2bc1SJ. German Rivera if (error != 0) 517125e2bc1SJ. German Rivera goto out; 518*cc088c3aSJ. German Rivera 5197b3bd9a7SJ. German Rivera out: 5207b3bd9a7SJ. German Rivera if (error != 0) 5217b3bd9a7SJ. German Rivera mc_boot_status = -error; 5227b3bd9a7SJ. German Rivera else 5237b3bd9a7SJ. German Rivera mc_boot_status = 0; 5247b3bd9a7SJ. German Rivera 5257b3bd9a7SJ. German Rivera return error; 5267b3bd9a7SJ. German Rivera } 5277b3bd9a7SJ. German Rivera 5287b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 5297b3bd9a7SJ. German Rivera { 5307b3bd9a7SJ. German Rivera return mc_boot_status; 5317b3bd9a7SJ. German Rivera } 5327b3bd9a7SJ. German Rivera 5337b3bd9a7SJ. German Rivera /** 5347b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 5357b3bd9a7SJ. German Rivera */ 5367b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 5377b3bd9a7SJ. German Rivera { 538125e2bc1SJ. German Rivera unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 539125e2bc1SJ. German Rivera 540125e2bc1SJ. German Rivera char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); 541125e2bc1SJ. German Rivera 542125e2bc1SJ. German Rivera if (dram_block_size_env_var) { 543125e2bc1SJ. German Rivera dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, 544125e2bc1SJ. German Rivera 10); 545125e2bc1SJ. German Rivera 546125e2bc1SJ. German Rivera if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { 547125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 548125e2bc1SJ. German Rivera MC_MEM_SIZE_ENV_VAR 549125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 550125e2bc1SJ. German Rivera dram_block_size); 551125e2bc1SJ. German Rivera 552125e2bc1SJ. German Rivera dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 553125e2bc1SJ. German Rivera } 554125e2bc1SJ. German Rivera } 555125e2bc1SJ. German Rivera 556125e2bc1SJ. German Rivera return dram_block_size; 5577b3bd9a7SJ. German Rivera } 558a2a55e51SPrabhakar Kushwaha 559a2a55e51SPrabhakar Kushwaha int dpio_init(struct dprc_obj_desc obj_desc) 560a2a55e51SPrabhakar Kushwaha { 561a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 562a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 563a2a55e51SPrabhakar Kushwaha int err = 0; 564a2a55e51SPrabhakar Kushwaha 565a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 566a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 567a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 568a2a55e51SPrabhakar Kushwaha return -ENOMEM; 569a2a55e51SPrabhakar Kushwaha } 570a2a55e51SPrabhakar Kushwaha 571a2a55e51SPrabhakar Kushwaha dflt_dpio->dpio_id = obj_desc.id; 572a2a55e51SPrabhakar Kushwaha 573a2a55e51SPrabhakar Kushwaha err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle); 574a2a55e51SPrabhakar Kushwaha if (err) { 575a2a55e51SPrabhakar Kushwaha printf("dpio_open() failed\n"); 576a2a55e51SPrabhakar Kushwaha goto err_open; 577a2a55e51SPrabhakar Kushwaha } 578a2a55e51SPrabhakar Kushwaha 579a2a55e51SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr); 580a2a55e51SPrabhakar Kushwaha if (err) { 581a2a55e51SPrabhakar Kushwaha printf("dpio_get_attributes() failed %d\n", err); 582a2a55e51SPrabhakar Kushwaha goto err_get_attr; 583a2a55e51SPrabhakar Kushwaha } 584a2a55e51SPrabhakar Kushwaha 585a2a55e51SPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, dflt_dpio_handle); 586a2a55e51SPrabhakar Kushwaha if (err) { 587a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 588a2a55e51SPrabhakar Kushwaha goto err_get_enable; 589a2a55e51SPrabhakar Kushwaha } 590a2a55e51SPrabhakar Kushwaha debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n", 591a2a55e51SPrabhakar Kushwaha attr.qbman_portal_ce_paddr, 592a2a55e51SPrabhakar Kushwaha attr.qbman_portal_ci_paddr, 593a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 594a2a55e51SPrabhakar Kushwaha attr.num_priorities); 595a2a55e51SPrabhakar Kushwaha 596a2a55e51SPrabhakar Kushwaha p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr; 597a2a55e51SPrabhakar Kushwaha p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr; 598a2a55e51SPrabhakar Kushwaha 599a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 600a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 601a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 602a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 603a2a55e51SPrabhakar Kushwaha } 604a2a55e51SPrabhakar Kushwaha return 0; 605a2a55e51SPrabhakar Kushwaha 606a2a55e51SPrabhakar Kushwaha err_get_swp_init: 607a2a55e51SPrabhakar Kushwaha err_get_enable: 608a2a55e51SPrabhakar Kushwaha dpio_disable(dflt_mc_io, dflt_dpio_handle); 609a2a55e51SPrabhakar Kushwaha err_get_attr: 610a2a55e51SPrabhakar Kushwaha dpio_close(dflt_mc_io, dflt_dpio_handle); 611a2a55e51SPrabhakar Kushwaha err_open: 612a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 613a2a55e51SPrabhakar Kushwaha return err; 614a2a55e51SPrabhakar Kushwaha } 615a2a55e51SPrabhakar Kushwaha 616a2a55e51SPrabhakar Kushwaha int dpbp_init(struct dprc_obj_desc obj_desc) 617a2a55e51SPrabhakar Kushwaha { 618a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 619a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 620a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 621a2a55e51SPrabhakar Kushwaha return -ENOMEM; 622a2a55e51SPrabhakar Kushwaha } 623a2a55e51SPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = obj_desc.id; 624a2a55e51SPrabhakar Kushwaha 625a2a55e51SPrabhakar Kushwaha return 0; 626a2a55e51SPrabhakar Kushwaha } 627a2a55e51SPrabhakar Kushwaha 628c517771aSPrabhakar Kushwaha int dprc_init_container_obj(struct dprc_obj_desc obj_desc, uint16_t dprc_handle) 629a2a55e51SPrabhakar Kushwaha { 630c517771aSPrabhakar Kushwaha int error = 0, state = 0; 631c517771aSPrabhakar Kushwaha struct dprc_endpoint dpni_endpoint, dpmac_endpoint; 632a2a55e51SPrabhakar Kushwaha if (!strcmp(obj_desc.type, "dpbp")) { 633a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 634a2a55e51SPrabhakar Kushwaha error = dpbp_init(obj_desc); 635a2a55e51SPrabhakar Kushwaha if (error < 0) 636a2a55e51SPrabhakar Kushwaha printf("dpbp_init failed\n"); 637a2a55e51SPrabhakar Kushwaha } 638a2a55e51SPrabhakar Kushwaha } else if (!strcmp(obj_desc.type, "dpio")) { 639a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 640a2a55e51SPrabhakar Kushwaha error = dpio_init(obj_desc); 641a2a55e51SPrabhakar Kushwaha if (error < 0) 642a2a55e51SPrabhakar Kushwaha printf("dpio_init failed\n"); 643a2a55e51SPrabhakar Kushwaha } 644c517771aSPrabhakar Kushwaha } else if (!strcmp(obj_desc.type, "dpni")) { 645c517771aSPrabhakar Kushwaha strcpy(dpni_endpoint.type, obj_desc.type); 646c517771aSPrabhakar Kushwaha dpni_endpoint.id = obj_desc.id; 647c517771aSPrabhakar Kushwaha error = dprc_get_connection(dflt_mc_io, dprc_handle, 648c517771aSPrabhakar Kushwaha &dpni_endpoint, &dpmac_endpoint, &state); 649c517771aSPrabhakar Kushwaha if (!strcmp(dpmac_endpoint.type, "dpmac")) 650c517771aSPrabhakar Kushwaha error = ldpaa_eth_init(obj_desc); 651c517771aSPrabhakar Kushwaha if (error < 0) 652c517771aSPrabhakar Kushwaha printf("ldpaa_eth_init failed\n"); 653a2a55e51SPrabhakar Kushwaha } 654a2a55e51SPrabhakar Kushwaha 655a2a55e51SPrabhakar Kushwaha return error; 656a2a55e51SPrabhakar Kushwaha } 657a2a55e51SPrabhakar Kushwaha 658a2a55e51SPrabhakar Kushwaha int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i) 659a2a55e51SPrabhakar Kushwaha { 660a2a55e51SPrabhakar Kushwaha int error = 0; 661a2a55e51SPrabhakar Kushwaha struct dprc_obj_desc obj_desc; 662a2a55e51SPrabhakar Kushwaha 663a2a55e51SPrabhakar Kushwaha memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc)); 664a2a55e51SPrabhakar Kushwaha 665a2a55e51SPrabhakar Kushwaha error = dprc_get_obj(dflt_mc_io, dprc_handle, 666a2a55e51SPrabhakar Kushwaha i, &obj_desc); 667a2a55e51SPrabhakar Kushwaha if (error < 0) { 668a2a55e51SPrabhakar Kushwaha printf("dprc_get_obj(i=%d) failed: %d\n", 669a2a55e51SPrabhakar Kushwaha i, error); 670a2a55e51SPrabhakar Kushwaha return error; 671a2a55e51SPrabhakar Kushwaha } 672a2a55e51SPrabhakar Kushwaha 673a2a55e51SPrabhakar Kushwaha if (!strcmp(obj_desc.type, obj_type)) { 674a2a55e51SPrabhakar Kushwaha debug("Discovered object: type %s, id %d, req %s\n", 675a2a55e51SPrabhakar Kushwaha obj_desc.type, obj_desc.id, obj_type); 676a2a55e51SPrabhakar Kushwaha 677c517771aSPrabhakar Kushwaha error = dprc_init_container_obj(obj_desc, dprc_handle); 678a2a55e51SPrabhakar Kushwaha if (error < 0) { 679a2a55e51SPrabhakar Kushwaha printf("dprc_init_container_obj(i=%d) failed: %d\n", 680a2a55e51SPrabhakar Kushwaha i, error); 681a2a55e51SPrabhakar Kushwaha return error; 682a2a55e51SPrabhakar Kushwaha } 683a2a55e51SPrabhakar Kushwaha } 684a2a55e51SPrabhakar Kushwaha 685a2a55e51SPrabhakar Kushwaha return error; 686a2a55e51SPrabhakar Kushwaha } 687a2a55e51SPrabhakar Kushwaha 688a2a55e51SPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 689a2a55e51SPrabhakar Kushwaha { 690a2a55e51SPrabhakar Kushwaha int i, error = 0; 691a2a55e51SPrabhakar Kushwaha int dprc_opened = 0, container_id; 692a2a55e51SPrabhakar Kushwaha int num_child_objects = 0; 693a2a55e51SPrabhakar Kushwaha 694a2a55e51SPrabhakar Kushwaha error = mc_init(); 695125e2bc1SJ. German Rivera if (error < 0) 696125e2bc1SJ. German Rivera goto error; 697a2a55e51SPrabhakar Kushwaha 698a2a55e51SPrabhakar Kushwaha error = dprc_get_container_id(dflt_mc_io, &container_id); 699a2a55e51SPrabhakar Kushwaha if (error < 0) { 700a2a55e51SPrabhakar Kushwaha printf("dprc_get_container_id() failed: %d\n", error); 701a2a55e51SPrabhakar Kushwaha goto error; 702a2a55e51SPrabhakar Kushwaha } 703a2a55e51SPrabhakar Kushwaha 704a2a55e51SPrabhakar Kushwaha debug("fsl-mc: Container id=0x%x\n", container_id); 705a2a55e51SPrabhakar Kushwaha 706a2a55e51SPrabhakar Kushwaha error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle); 707a2a55e51SPrabhakar Kushwaha if (error < 0) { 708a2a55e51SPrabhakar Kushwaha printf("dprc_open() failed: %d\n", error); 709a2a55e51SPrabhakar Kushwaha goto error; 710a2a55e51SPrabhakar Kushwaha } 711a2a55e51SPrabhakar Kushwaha dprc_opened = true; 712a2a55e51SPrabhakar Kushwaha 713a2a55e51SPrabhakar Kushwaha error = dprc_get_obj_count(dflt_mc_io, 714a2a55e51SPrabhakar Kushwaha dflt_dprc_handle, 715a2a55e51SPrabhakar Kushwaha &num_child_objects); 716a2a55e51SPrabhakar Kushwaha if (error < 0) { 717a2a55e51SPrabhakar Kushwaha printf("dprc_get_obj_count() failed: %d\n", error); 718a2a55e51SPrabhakar Kushwaha goto error; 719a2a55e51SPrabhakar Kushwaha } 720a2a55e51SPrabhakar Kushwaha debug("Total child in container %d = %d\n", container_id, 721a2a55e51SPrabhakar Kushwaha num_child_objects); 722a2a55e51SPrabhakar Kushwaha 723a2a55e51SPrabhakar Kushwaha if (num_child_objects != 0) { 724a2a55e51SPrabhakar Kushwaha /* 725a2a55e51SPrabhakar Kushwaha * Discover objects currently in the DPRC container in the MC: 726a2a55e51SPrabhakar Kushwaha */ 727a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 728a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 729a2a55e51SPrabhakar Kushwaha "dpbp", i); 730a2a55e51SPrabhakar Kushwaha 731a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 732a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 733a2a55e51SPrabhakar Kushwaha "dpio", i); 734a2a55e51SPrabhakar Kushwaha 735a2a55e51SPrabhakar Kushwaha for (i = 0; i < num_child_objects; i++) 736a2a55e51SPrabhakar Kushwaha error = dprc_scan_container_obj(dflt_dprc_handle, 737a2a55e51SPrabhakar Kushwaha "dpni", i); 738a2a55e51SPrabhakar Kushwaha } 739a2a55e51SPrabhakar Kushwaha error: 740a2a55e51SPrabhakar Kushwaha if (dprc_opened) 741a2a55e51SPrabhakar Kushwaha dprc_close(dflt_mc_io, dflt_dprc_handle); 742a2a55e51SPrabhakar Kushwaha 743a2a55e51SPrabhakar Kushwaha return error; 744a2a55e51SPrabhakar Kushwaha } 745a2a55e51SPrabhakar Kushwaha 746a2a55e51SPrabhakar Kushwaha void fsl_mc_ldpaa_exit(bd_t *bis) 747a2a55e51SPrabhakar Kushwaha { 748a2a55e51SPrabhakar Kushwaha int err; 749a2a55e51SPrabhakar Kushwaha 750125e2bc1SJ. German Rivera if (get_mc_boot_status() == 0) { 751a2a55e51SPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, dflt_dpio_handle); 752a2a55e51SPrabhakar Kushwaha if (err < 0) { 753a2a55e51SPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 754a2a55e51SPrabhakar Kushwaha return; 755a2a55e51SPrabhakar Kushwaha } 756a2a55e51SPrabhakar Kushwaha err = dpio_reset(dflt_mc_io, dflt_dpio_handle); 757a2a55e51SPrabhakar Kushwaha if (err < 0) { 758a2a55e51SPrabhakar Kushwaha printf("dpio_reset() failed: %d\n", err); 759a2a55e51SPrabhakar Kushwaha return; 760a2a55e51SPrabhakar Kushwaha } 761a2a55e51SPrabhakar Kushwaha err = dpio_close(dflt_mc_io, dflt_dpio_handle); 762a2a55e51SPrabhakar Kushwaha if (err < 0) { 763a2a55e51SPrabhakar Kushwaha printf("dpio_close() failed: %d\n", err); 764a2a55e51SPrabhakar Kushwaha return; 765a2a55e51SPrabhakar Kushwaha } 766a2a55e51SPrabhakar Kushwaha 767a2a55e51SPrabhakar Kushwaha free(dflt_dpio); 768a2a55e51SPrabhakar Kushwaha free(dflt_dpbp); 769125e2bc1SJ. German Rivera } 770125e2bc1SJ. German Rivera 771125e2bc1SJ. German Rivera if (dflt_mc_io) 772a2a55e51SPrabhakar Kushwaha free(dflt_mc_io); 773a2a55e51SPrabhakar Kushwaha } 774