1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2018, 2021 NXP
4 */
5
6#include <common.h>
7#include <clk.h>
8#include <cpu.h>
9#include <cpu_func.h>
10#include <dm.h>
11#include <event.h>
12#include <init.h>
13#include <log.h>
14#include <asm/cache.h>
15#include <asm/global_data.h>
16#include <dm/device-internal.h>
17#include <dm/lists.h>
18#include <dm/uclass.h>
19#include <errno.h>
20#include <spl.h>
21#include <thermal.h>
22#include <firmware/imx/sci/sci.h>
23#include <asm/arch/sys_proto.h>
24#include <asm/arch-imx/cpu.h>
25#include <asm/armv8/cpu.h>
26#include <asm/armv8/mmu.h>
27#include <asm/setup.h>
28#include <asm/mach-imx/boot_mode.h>
29#include <power-domain.h>
30#include <elf.h>
31#include <spl.h>
32
33DECLARE_GLOBAL_DATA_PTR;
34
35#define BT_PASSOVER_TAG	0x504F
36struct pass_over_info_t *get_pass_over_info(void)
37{
38	struct pass_over_info_t *p =
39		(struct pass_over_info_t *)PASS_OVER_INFO_ADDR;
40
41	if (p->barker != BT_PASSOVER_TAG ||
42	    p->len != sizeof(struct pass_over_info_t))
43		return NULL;
44
45	return p;
46}
47
48static char *get_reset_cause(void)
49{
50	sc_pm_reset_reason_t reason;
51
52	if (sc_pm_reset_reason(-1, &reason) != SC_ERR_NONE)
53		return "Unknown reset";
54
55	switch (reason) {
56	case SC_PM_RESET_REASON_POR:
57		return "POR";
58	case SC_PM_RESET_REASON_JTAG:
59		return "JTAG reset ";
60	case SC_PM_RESET_REASON_SW:
61		return "Software reset";
62	case SC_PM_RESET_REASON_WDOG:
63		return "Watchdog reset";
64	case SC_PM_RESET_REASON_LOCKUP:
65		return "SCU lockup reset";
66	case SC_PM_RESET_REASON_SNVS:
67		return "SNVS reset";
68	case SC_PM_RESET_REASON_TEMP:
69		return "Temp panic reset";
70	case SC_PM_RESET_REASON_MSI:
71		return "MSI reset";
72	case SC_PM_RESET_REASON_UECC:
73		return "ECC reset";
74	case SC_PM_RESET_REASON_SCFW_WDOG:
75		return "SCFW watchdog reset";
76	case SC_PM_RESET_REASON_ROM_WDOG:
77		return "SCU ROM watchdog reset";
78	case SC_PM_RESET_REASON_SECO:
79		return "SECO reset";
80	case SC_PM_RESET_REASON_SCFW_FAULT:
81		return "SCFW fault reset";
82	default:
83		return "Unknown reset";
84	}
85}
86
87__weak void reset_cpu(void)
88{
89}
90
91int arch_cpu_init(void)
92{
93#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION)
94	spl_save_restore_data();
95#endif
96
97#ifdef CONFIG_SPL_BUILD
98	struct pass_over_info_t *pass_over;
99
100	if (is_soc_rev(CHIP_REV_A)) {
101		pass_over = get_pass_over_info();
102		if (pass_over && pass_over->g_ap_mu == 0) {
103			/*
104			 * When ap_mu is 0, means the U-Boot booted
105			 * from first container
106			 */
107			sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS);
108		}
109	}
110#endif
111
112	return 0;
113}
114
115static int imx8_init_mu(void)
116{
117	struct udevice *devp;
118	int node, ret;
119
120	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu");
121
122	ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp);
123	if (ret) {
124		printf("could not get scu %d\n", ret);
125		return ret;
126	}
127
128	if (is_imx8qm()) {
129		ret = sc_pm_set_resource_power_mode(-1, SC_R_SMMU,
130						    SC_PM_PW_MODE_ON);
131		if (ret)
132			return ret;
133	}
134
135	return 0;
136}
137EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, imx8_init_mu);
138
139#if defined(CONFIG_ARCH_MISC_INIT)
140int arch_misc_init(void)
141{
142	if (IS_ENABLED(CONFIG_FSL_CAAM)) {
143		struct udevice *dev;
144		int ret;
145
146		ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
147		if (ret)
148			printf("Failed to initialize caam_jr: %d\n", ret);
149	}
150
151	return 0;
152}
153#endif
154
155#ifdef CONFIG_IMX_BOOTAUX
156
157#ifdef CONFIG_IMX8QM
158int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
159{
160	sc_rsrc_t core_rsrc, mu_rsrc;
161	sc_faddr_t tcml_addr;
162	u32 tcml_size = SZ_128K;
163	ulong addr;
164
165	switch (core_id) {
166	case 0:
167		core_rsrc = SC_R_M4_0_PID0;
168		tcml_addr = 0x34FE0000;
169		mu_rsrc = SC_R_M4_0_MU_1A;
170		break;
171	case 1:
172		core_rsrc = SC_R_M4_1_PID0;
173		tcml_addr = 0x38FE0000;
174		mu_rsrc = SC_R_M4_1_MU_1A;
175		break;
176	default:
177		printf("Not support this core boot up, ID:%u\n", core_id);
178		return -EINVAL;
179	}
180
181	addr = (sc_faddr_t)boot_private_data;
182
183	if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) {
184		printf("Wrong image address 0x%lx, should not in TCML\n",
185		       addr);
186		return -EINVAL;
187	}
188
189	printf("Power on M4 and MU\n");
190
191	if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
192		return -EIO;
193
194	if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
195		return -EIO;
196
197	printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr);
198
199	if (addr != tcml_addr)
200		memcpy((void *)tcml_addr, (void *)addr, tcml_size);
201
202	printf("Start M4 %u\n", core_id);
203	if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE)
204		return -EIO;
205
206	printf("bootaux complete\n");
207	return 0;
208}
209#endif
210
211#ifdef CONFIG_IMX8QXP
212int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
213{
214	sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE;
215	sc_faddr_t aux_core_ram;
216	u32 size;
217	ulong addr;
218
219	switch (core_id) {
220	case 0:
221		core_rsrc = SC_R_M4_0_PID0;
222		aux_core_ram = 0x34FE0000;
223		mu_rsrc = SC_R_M4_0_MU_1A;
224		size = SZ_128K;
225		break;
226	case 1:
227		core_rsrc = SC_R_DSP;
228		aux_core_ram = 0x596f8000;
229		size = SZ_2K;
230		break;
231	default:
232		printf("Not support this core boot up, ID:%u\n", core_id);
233		return -EINVAL;
234	}
235
236	addr = (sc_faddr_t)boot_private_data;
237
238	if (addr >= aux_core_ram && addr <= aux_core_ram + size) {
239		printf("Wrong image address 0x%lx, should not in aux core ram\n",
240		       addr);
241		return -EINVAL;
242	}
243
244	printf("Power on aux core %d\n", core_id);
245
246	if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
247		return -EIO;
248
249	if (mu_rsrc != SC_R_NONE) {
250		if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
251			return -EIO;
252	}
253
254	if (core_id == 1) {
255		struct power_domain pd;
256
257		if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) {
258			printf("Error enable clock\n");
259			return -EIO;
260		}
261
262		if (!power_domain_lookup_name("audio_sai0", &pd)) {
263			if (power_domain_on(&pd)) {
264				printf("Error power on SAI0\n");
265				return -EIO;
266			}
267		}
268
269		if (!power_domain_lookup_name("audio_ocram", &pd)) {
270			if (power_domain_on(&pd)) {
271				printf("Error power on HIFI RAM\n");
272				return -EIO;
273			}
274		}
275	}
276
277	printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram);
278	if (core_id == 0) {
279		/* M4 use bin file */
280		memcpy((void *)aux_core_ram, (void *)addr, size);
281	} else {
282		/* HIFI use elf file */
283		if (!valid_elf_image(addr))
284			return -1;
285		addr = load_elf_image_shdr(addr);
286	}
287
288	printf("Start %s\n", core_id == 0 ? "M4" : "HIFI");
289
290	if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE)
291		return -EIO;
292
293	printf("bootaux complete\n");
294	return 0;
295}
296#endif
297
298int arch_auxiliary_core_check_up(u32 core_id)
299{
300	sc_rsrc_t core_rsrc;
301	sc_pm_power_mode_t power_mode;
302
303	switch (core_id) {
304	case 0:
305		core_rsrc = SC_R_M4_0_PID0;
306		break;
307#ifdef CONFIG_IMX8QM
308	case 1:
309		core_rsrc = SC_R_M4_1_PID0;
310		break;
311#endif
312	default:
313		printf("Not support this core, ID:%u\n", core_id);
314		return 0;
315	}
316
317	if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE)
318		return 0;
319
320	if (power_mode != SC_PM_PW_MODE_OFF)
321		return 1;
322
323	return 0;
324}
325#endif
326
327int print_bootinfo(void)
328{
329	enum boot_device bt_dev = get_boot_device();
330
331	puts("Boot:  ");
332	switch (bt_dev) {
333	case SD1_BOOT:
334		puts("SD0\n");
335		break;
336	case SD2_BOOT:
337		puts("SD1\n");
338		break;
339	case SD3_BOOT:
340		puts("SD2\n");
341		break;
342	case MMC1_BOOT:
343		puts("MMC0\n");
344		break;
345	case MMC2_BOOT:
346		puts("MMC1\n");
347		break;
348	case MMC3_BOOT:
349		puts("MMC2\n");
350		break;
351	case FLEXSPI_BOOT:
352		puts("FLEXSPI\n");
353		break;
354	case SATA_BOOT:
355		puts("SATA\n");
356		break;
357	case NAND_BOOT:
358		puts("NAND\n");
359		break;
360	case USB_BOOT:
361		puts("USB\n");
362		break;
363	default:
364		printf("Unknown device %u\n", bt_dev);
365		break;
366	}
367
368	printf("Reset cause: %s\n", get_reset_cause());
369
370	return 0;
371}
372
373enum boot_device get_boot_device(void)
374{
375	enum boot_device boot_dev = SD1_BOOT;
376
377	sc_rsrc_t dev_rsrc;
378
379	sc_misc_get_boot_dev(-1, &dev_rsrc);
380
381	switch (dev_rsrc) {
382	case SC_R_SDHC_0:
383		boot_dev = MMC1_BOOT;
384		break;
385	case SC_R_SDHC_1:
386		boot_dev = SD2_BOOT;
387		break;
388	case SC_R_SDHC_2:
389		boot_dev = SD3_BOOT;
390		break;
391	case SC_R_NAND:
392		boot_dev = NAND_BOOT;
393		break;
394	case SC_R_FSPI_0:
395		boot_dev = FLEXSPI_BOOT;
396		break;
397	case SC_R_SATA_0:
398		boot_dev = SATA_BOOT;
399		break;
400	case SC_R_USB_0:
401	case SC_R_USB_1:
402	case SC_R_USB_2:
403		boot_dev = USB_BOOT;
404		break;
405	default:
406		break;
407	}
408
409	return boot_dev;
410}
411
412#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
413#define FUSE_UNIQUE_ID_WORD0 16
414#define FUSE_UNIQUE_ID_WORD1 17
415void get_board_serial(struct tag_serialnr *serialnr)
416{
417	int err;
418	u32 val1 = 0, val2 = 0;
419	u32 word1, word2;
420
421	if (!serialnr)
422		return;
423
424	word1 = FUSE_UNIQUE_ID_WORD0;
425	word2 = FUSE_UNIQUE_ID_WORD1;
426
427	err = sc_misc_otp_fuse_read(-1, word1, &val1);
428	if (err) {
429		printf("%s fuse %d read error: %d\n", __func__, word1, err);
430		return;
431	}
432
433	err = sc_misc_otp_fuse_read(-1, word2, &val2);
434	if (err) {
435		printf("%s fuse %d read error: %d\n", __func__, word2, err);
436		return;
437	}
438	serialnr->low = val1;
439	serialnr->high = val2;
440}
441#endif /*CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG*/
442
443#ifdef CONFIG_ENV_IS_IN_MMC
444__weak int board_mmc_get_env_dev(int devno)
445{
446	return CONFIG_SYS_MMC_ENV_DEV;
447}
448
449int mmc_get_env_dev(void)
450{
451	sc_rsrc_t dev_rsrc;
452	int devno;
453
454	sc_misc_get_boot_dev(-1, &dev_rsrc);
455
456	switch (dev_rsrc) {
457	case SC_R_SDHC_0:
458		devno = 0;
459		break;
460	case SC_R_SDHC_1:
461		devno = 1;
462		break;
463	case SC_R_SDHC_2:
464		devno = 2;
465		break;
466	default:
467		/* If not boot from sd/mmc, use default value */
468		return CONFIG_SYS_MMC_ENV_DEV;
469	}
470
471	return board_mmc_get_env_dev(devno);
472}
473#endif
474
475#define MEMSTART_ALIGNMENT  SZ_2M /* Align the memory start with 2MB */
476
477static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start,
478			    sc_faddr_t *addr_end)
479{
480	sc_faddr_t start, end;
481	int ret;
482	bool owned;
483
484	owned = sc_rm_is_memreg_owned(-1, mr);
485	if (owned) {
486		ret = sc_rm_get_memreg_info(-1, mr, &start, &end);
487		if (ret) {
488			printf("Memreg get info failed, %d\n", ret);
489			return -EINVAL;
490		}
491		debug("0x%llx -- 0x%llx\n", start, end);
492		*addr_start = start;
493		*addr_end = end;
494
495		return 0;
496	}
497
498	return -EINVAL;
499}
500
501__weak void board_mem_get_layout(u64 *phys_sdram_1_start,
502				 u64 *phys_sdram_1_size,
503				 u64 *phys_sdram_2_start,
504				 u64 *phys_sdram_2_size)
505{
506	*phys_sdram_1_start = PHYS_SDRAM_1;
507	*phys_sdram_1_size = PHYS_SDRAM_1_SIZE;
508	*phys_sdram_2_start = PHYS_SDRAM_2;
509	*phys_sdram_2_size = PHYS_SDRAM_2_SIZE;
510}
511
512phys_size_t get_effective_memsize(void)
513{
514	sc_rm_mr_t mr;
515	sc_faddr_t start, end, end1, start_aligned;
516	u64 phys_sdram_1_start, phys_sdram_1_size;
517	u64 phys_sdram_2_start, phys_sdram_2_size;
518	int err;
519
520	board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size,
521			     &phys_sdram_2_start, &phys_sdram_2_size);
522
523
524	end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size;
525	for (mr = 0; mr < 64; mr++) {
526		err = get_owned_memreg(mr, &start, &end);
527		if (!err) {
528			start_aligned = roundup(start, MEMSTART_ALIGNMENT);
529			/* Too small memory region, not use it */
530			if (start_aligned > end)
531				continue;
532
533			/* Find the memory region runs the U-Boot */
534			if (start >= phys_sdram_1_start && start <= end1 &&
535			    (start <= CONFIG_TEXT_BASE &&
536			    end >= CONFIG_TEXT_BASE)) {
537				if ((end + 1) <=
538				    ((sc_faddr_t)phys_sdram_1_start +
539				    phys_sdram_1_size))
540					return (end - phys_sdram_1_start + 1);
541				else
542					return phys_sdram_1_size;
543			}
544		}
545	}
546
547	return phys_sdram_1_size;
548}
549
550int dram_init(void)
551{
552	sc_rm_mr_t mr;
553	sc_faddr_t start, end, end1, end2;
554	u64 phys_sdram_1_start, phys_sdram_1_size;
555	u64 phys_sdram_2_start, phys_sdram_2_size;
556	int err;
557
558	board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size,
559			     &phys_sdram_2_start, &phys_sdram_2_size);
560
561	end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size;
562	end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size;
563	for (mr = 0; mr < 64; mr++) {
564		err = get_owned_memreg(mr, &start, &end);
565		if (!err) {
566			start = roundup(start, MEMSTART_ALIGNMENT);
567			/* Too small memory region, not use it */
568			if (start > end)
569				continue;
570
571			if (start >= phys_sdram_1_start && start <= end1) {
572				if ((end + 1) <= end1)
573					gd->ram_size += end - start + 1;
574				else
575					gd->ram_size += end1 - start;
576			} else if (start >= phys_sdram_2_start &&
577				   start <= end2) {
578				if ((end + 1) <= end2)
579					gd->ram_size += end - start + 1;
580				else
581					gd->ram_size += end2 - start;
582			}
583		}
584	}
585
586	/* If error, set to the default value */
587	if (!gd->ram_size) {
588		gd->ram_size = phys_sdram_1_size;
589		gd->ram_size += phys_sdram_2_size;
590	}
591	return 0;
592}
593
594static void dram_bank_sort(int current_bank)
595{
596	phys_addr_t start;
597	phys_size_t size;
598
599	while (current_bank > 0) {
600		if (gd->bd->bi_dram[current_bank - 1].start >
601		    gd->bd->bi_dram[current_bank].start) {
602			start = gd->bd->bi_dram[current_bank - 1].start;
603			size = gd->bd->bi_dram[current_bank - 1].size;
604
605			gd->bd->bi_dram[current_bank - 1].start =
606				gd->bd->bi_dram[current_bank].start;
607			gd->bd->bi_dram[current_bank - 1].size =
608				gd->bd->bi_dram[current_bank].size;
609
610			gd->bd->bi_dram[current_bank].start = start;
611			gd->bd->bi_dram[current_bank].size = size;
612		}
613		current_bank--;
614	}
615}
616
617int dram_init_banksize(void)
618{
619	sc_rm_mr_t mr;
620	sc_faddr_t start, end, end1, end2;
621	int i = 0;
622	u64 phys_sdram_1_start, phys_sdram_1_size;
623	u64 phys_sdram_2_start, phys_sdram_2_size;
624	int err;
625
626	board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size,
627			     &phys_sdram_2_start, &phys_sdram_2_size);
628
629	end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size;
630	end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size;
631	for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) {
632		err = get_owned_memreg(mr, &start, &end);
633		if (!err) {
634			start = roundup(start, MEMSTART_ALIGNMENT);
635			if (start > end) /* Small memory region, no use it */
636				continue;
637
638			if (start >= phys_sdram_1_start && start <= end1) {
639				gd->bd->bi_dram[i].start = start;
640
641				if ((end + 1) <= end1)
642					gd->bd->bi_dram[i].size =
643						end - start + 1;
644				else
645					gd->bd->bi_dram[i].size = end1 - start;
646
647				dram_bank_sort(i);
648				i++;
649			} else if (start >= phys_sdram_2_start && start <= end2) {
650				gd->bd->bi_dram[i].start = start;
651
652				if ((end + 1) <= end2)
653					gd->bd->bi_dram[i].size =
654						end - start + 1;
655				else
656					gd->bd->bi_dram[i].size = end2 - start;
657
658				dram_bank_sort(i);
659				i++;
660			}
661		}
662	}
663
664	/* If error, set to the default value */
665	if (!i) {
666		gd->bd->bi_dram[0].start = phys_sdram_1_start;
667		gd->bd->bi_dram[0].size = phys_sdram_1_size;
668		gd->bd->bi_dram[1].start = phys_sdram_2_start;
669		gd->bd->bi_dram[1].size = phys_sdram_2_size;
670	}
671
672	return 0;
673}
674
675static u64 get_block_attrs(sc_faddr_t addr_start)
676{
677	u64 attr = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE |
678		PTE_BLOCK_PXN | PTE_BLOCK_UXN;
679	u64 phys_sdram_1_start, phys_sdram_1_size;
680	u64 phys_sdram_2_start, phys_sdram_2_size;
681
682	board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size,
683			     &phys_sdram_2_start, &phys_sdram_2_size);
684
685	if ((addr_start >= phys_sdram_1_start &&
686	     addr_start <= ((sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size)) ||
687	    (addr_start >= phys_sdram_2_start &&
688	     addr_start <= ((sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size)))
689		return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE);
690
691	return attr;
692}
693
694static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end)
695{
696	sc_faddr_t end1, end2;
697	u64 phys_sdram_1_start, phys_sdram_1_size;
698	u64 phys_sdram_2_start, phys_sdram_2_size;
699
700	board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size,
701			     &phys_sdram_2_start, &phys_sdram_2_size);
702
703
704	end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size;
705	end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size;
706
707	if (addr_start >= phys_sdram_1_start && addr_start <= end1) {
708		if ((addr_end + 1) > end1)
709			return end1 - addr_start;
710	} else if (addr_start >= phys_sdram_2_start && addr_start <= end2) {
711		if ((addr_end + 1) > end2)
712			return end2 - addr_start;
713	}
714
715	return (addr_end - addr_start + 1);
716}
717
718#define MAX_PTE_ENTRIES 512
719#define MAX_MEM_MAP_REGIONS 16
720
721static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS];
722struct mm_region *mem_map = imx8_mem_map;
723
724void enable_caches(void)
725{
726	sc_rm_mr_t mr;
727	sc_faddr_t start, end;
728	int err, i;
729
730	/* Create map for registers access from 0x1c000000 to 0x80000000*/
731	imx8_mem_map[0].virt = 0x1c000000UL;
732	imx8_mem_map[0].phys = 0x1c000000UL;
733	imx8_mem_map[0].size = 0x64000000UL;
734	imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
735			 PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
736
737	i = 1;
738	for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) {
739		err = get_owned_memreg(mr, &start, &end);
740		if (!err) {
741			imx8_mem_map[i].virt = start;
742			imx8_mem_map[i].phys = start;
743			imx8_mem_map[i].size = get_block_size(start, end);
744			imx8_mem_map[i].attrs = get_block_attrs(start);
745			i++;
746		}
747	}
748
749	if (i < MAX_MEM_MAP_REGIONS) {
750		imx8_mem_map[i].size = 0;
751		imx8_mem_map[i].attrs = 0;
752	} else {
753		puts("Error, need more MEM MAP REGIONS reserved\n");
754		icache_enable();
755		return;
756	}
757
758	for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) {
759		debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n",
760		      i, imx8_mem_map[i].virt, imx8_mem_map[i].phys,
761		      imx8_mem_map[i].size, imx8_mem_map[i].attrs);
762	}
763
764	icache_enable();
765	dcache_enable();
766}
767
768#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
769u64 get_page_table_size(void)
770{
771	u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
772	u64 size = 0;
773
774	/*
775	 * For each memory region, the max table size:
776	 * 2 level 3 tables + 2 level 2 tables + 1 level 1 table
777	 */
778	size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt;
779
780	/*
781	 * We need to duplicate our page table once to have an emergency pt to
782	 * resort to when splitting page tables later on
783	 */
784	size *= 2;
785
786	/*
787	 * We may need to split page tables later on if dcache settings change,
788	 * so reserve up to 4 (random pick) page tables for that.
789	 */
790	size += one_pt * 4;
791
792	return size;
793}
794#endif
795
796#if defined(CONFIG_IMX8QM)
797#define FUSE_MAC0_WORD0 452
798#define FUSE_MAC0_WORD1 453
799#define FUSE_MAC1_WORD0 454
800#define FUSE_MAC1_WORD1 455
801#elif defined(CONFIG_IMX8QXP)
802#define FUSE_MAC0_WORD0 708
803#define FUSE_MAC0_WORD1 709
804#define FUSE_MAC1_WORD0 710
805#define FUSE_MAC1_WORD1 711
806#endif
807
808void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
809{
810	u32 word[2], val[2] = {};
811	int i, ret;
812
813	if (dev_id == 0) {
814		word[0] = FUSE_MAC0_WORD0;
815		word[1] = FUSE_MAC0_WORD1;
816	} else {
817		word[0] = FUSE_MAC1_WORD0;
818		word[1] = FUSE_MAC1_WORD1;
819	}
820
821	for (i = 0; i < 2; i++) {
822		ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]);
823		if (ret < 0)
824			goto err;
825	}
826
827	mac[0] = val[0];
828	mac[1] = val[0] >> 8;
829	mac[2] = val[0] >> 16;
830	mac[3] = val[0] >> 24;
831	mac[4] = val[1];
832	mac[5] = val[1] >> 8;
833
834	debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n",
835	      __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
836	return;
837err:
838	printf("%s: fuse %d, err: %d\n", __func__, word[i], ret);
839}
840
841u32 get_cpu_rev(void)
842{
843	u32 id = 0, rev = 0;
844	int ret;
845
846	ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id);
847	if (ret)
848		return 0;
849
850	rev = (id >> 5)  & 0xf;
851	id = (id & 0x1f) + MXC_SOC_IMX8;  /* Dummy ID for chip */
852
853	return (id << 12) | rev;
854}
855
856void board_boot_order(u32 *spl_boot_list)
857{
858	spl_boot_list[0] = spl_boot_device();
859
860	if (spl_boot_list[0] == BOOT_DEVICE_SPI) {
861		/* Check whether we own the flexspi0, if not, use NOR boot */
862		if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0))
863			spl_boot_list[0] = BOOT_DEVICE_NOR;
864	}
865}
866
867bool m4_parts_booted(void)
868{
869	sc_rm_pt_t m4_parts[2];
870	int err;
871
872	err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]);
873	if (err) {
874		printf("%s get resource [%d] owner error: %d\n", __func__,
875		       SC_R_M4_0_PID0, err);
876		return false;
877	}
878
879	if (sc_pm_is_partition_started(-1, m4_parts[0]))
880		return true;
881
882	if (is_imx8qm()) {
883		err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]);
884		if (err) {
885			printf("%s get resource [%d] owner error: %d\n",
886			       __func__, SC_R_M4_1_PID0, err);
887			return false;
888		}
889
890		if (sc_pm_is_partition_started(-1, m4_parts[1]))
891			return true;
892	}
893
894	return false;
895}
896