xref: /rk3399_rockchip-uboot/drivers/net/fsl-mc/mc.c (revision cc088c3ac63e3decca1a84c7e64cb31b863bc111)
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, &reg_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, &reg_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