Commit ec1f64b420c7a5c6dc6435fa98735b694720e26c
1 parent
873587f1c0
Exists in
smarc_8mq_lf_v2020.04
and in
4 other branches
MLK-25291-1 iMX8MQ: Recognize the B2 revision
i.MX8MQ B2 is using same value in OCOTP_READ_FUSE_DATA like B1, so we have to check the ROM verision to distinguish the revision. As we have checked the B1 rev for sticky bits work around in secure boot. So it won't apply on B2. Signed-off-by: Ye Li <ye.li@nxp.com> Reviewed-by: Peng Fan <peng.fan@nxp.com> (cherry picked from commit 1ac96bde4920fa3e2a3bb4a79b342ca4f5adb4a5)
Showing 2 changed files with 11 additions and 1 deletions Inline Diff
arch/arm/include/asm/arch-imx/cpu.h
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* | 2 | /* |
3 | * (C) Copyright 2014 Freescale Semiconductor, Inc. | 3 | * (C) Copyright 2014 Freescale Semiconductor, Inc. |
4 | * Copyright 2018-2020 NXP | 4 | * Copyright 2018-2020 NXP |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #define MXC_CPU_MX23 0x23 | 7 | #define MXC_CPU_MX23 0x23 |
8 | #define MXC_CPU_MX25 0x25 | 8 | #define MXC_CPU_MX25 0x25 |
9 | #define MXC_CPU_MX27 0x27 | 9 | #define MXC_CPU_MX27 0x27 |
10 | #define MXC_CPU_MX28 0x28 | 10 | #define MXC_CPU_MX28 0x28 |
11 | #define MXC_CPU_MX31 0x31 | 11 | #define MXC_CPU_MX31 0x31 |
12 | #define MXC_CPU_MX35 0x35 | 12 | #define MXC_CPU_MX35 0x35 |
13 | #define MXC_CPU_MX51 0x51 | 13 | #define MXC_CPU_MX51 0x51 |
14 | #define MXC_CPU_MX53 0x53 | 14 | #define MXC_CPU_MX53 0x53 |
15 | #define MXC_CPU_MX6SL 0x60 | 15 | #define MXC_CPU_MX6SL 0x60 |
16 | #define MXC_CPU_MX6DL 0x61 | 16 | #define MXC_CPU_MX6DL 0x61 |
17 | #define MXC_CPU_MX6SX 0x62 | 17 | #define MXC_CPU_MX6SX 0x62 |
18 | #define MXC_CPU_MX6Q 0x63 | 18 | #define MXC_CPU_MX6Q 0x63 |
19 | #define MXC_CPU_MX6UL 0x64 | 19 | #define MXC_CPU_MX6UL 0x64 |
20 | #define MXC_CPU_MX6ULL 0x65 | 20 | #define MXC_CPU_MX6ULL 0x65 |
21 | #define MXC_CPU_MX6ULZ 0x6B | 21 | #define MXC_CPU_MX6ULZ 0x6B |
22 | #define MXC_CPU_MX6SOLO 0x66 /* dummy */ | 22 | #define MXC_CPU_MX6SOLO 0x66 /* dummy */ |
23 | #define MXC_CPU_MX6SLL 0x67 | 23 | #define MXC_CPU_MX6SLL 0x67 |
24 | #define MXC_CPU_MX6D 0x6A | 24 | #define MXC_CPU_MX6D 0x6A |
25 | #define MXC_CPU_MX6DP 0x68 | 25 | #define MXC_CPU_MX6DP 0x68 |
26 | #define MXC_CPU_MX6QP 0x69 | 26 | #define MXC_CPU_MX6QP 0x69 |
27 | #define MXC_CPU_MX7S 0x71 /* dummy ID */ | 27 | #define MXC_CPU_MX7S 0x71 /* dummy ID */ |
28 | #define MXC_CPU_MX7D 0x72 | 28 | #define MXC_CPU_MX7D 0x72 |
29 | #define MXC_CPU_IMX8MQ 0x82 | 29 | #define MXC_CPU_IMX8MQ 0x82 |
30 | #define MXC_CPU_IMX8MD 0x83 /* dummy ID */ | 30 | #define MXC_CPU_IMX8MD 0x83 /* dummy ID */ |
31 | #define MXC_CPU_IMX8MQL 0x84 /* dummy ID */ | 31 | #define MXC_CPU_IMX8MQL 0x84 /* dummy ID */ |
32 | #define MXC_CPU_IMX8MM 0x85 /* dummy ID */ | 32 | #define MXC_CPU_IMX8MM 0x85 /* dummy ID */ |
33 | #define MXC_CPU_IMX8MML 0x86 /* dummy ID */ | 33 | #define MXC_CPU_IMX8MML 0x86 /* dummy ID */ |
34 | #define MXC_CPU_IMX8MMD 0x87 /* dummy ID */ | 34 | #define MXC_CPU_IMX8MMD 0x87 /* dummy ID */ |
35 | #define MXC_CPU_IMX8MMDL 0x88 /* dummy ID */ | 35 | #define MXC_CPU_IMX8MMDL 0x88 /* dummy ID */ |
36 | #define MXC_CPU_IMX8MMS 0x89 /* dummy ID */ | 36 | #define MXC_CPU_IMX8MMS 0x89 /* dummy ID */ |
37 | #define MXC_CPU_IMX8MMSL 0x8a /* dummy ID */ | 37 | #define MXC_CPU_IMX8MMSL 0x8a /* dummy ID */ |
38 | #define MXC_CPU_IMX8MN 0x8b /* dummy ID */ | 38 | #define MXC_CPU_IMX8MN 0x8b /* dummy ID */ |
39 | #define MXC_CPU_IMX8MND 0x8c /* dummy ID */ | 39 | #define MXC_CPU_IMX8MND 0x8c /* dummy ID */ |
40 | #define MXC_CPU_IMX8MNS 0x8d /* dummy ID */ | 40 | #define MXC_CPU_IMX8MNS 0x8d /* dummy ID */ |
41 | #define MXC_CPU_IMX8MNL 0x8e /* dummy ID */ | 41 | #define MXC_CPU_IMX8MNL 0x8e /* dummy ID */ |
42 | #define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */ | 42 | #define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */ |
43 | #define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */ | 43 | #define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */ |
44 | #define MXC_CPU_IMX8MNUQ 0x182 /* dummy ID */ | 44 | #define MXC_CPU_IMX8MNUQ 0x182 /* dummy ID */ |
45 | #define MXC_CPU_IMX8MNUD 0x183 /* dummy ID */ | 45 | #define MXC_CPU_IMX8MNUD 0x183 /* dummy ID */ |
46 | #define MXC_CPU_IMX8MNUS 0x184 /* dummy ID */ | 46 | #define MXC_CPU_IMX8MNUS 0x184 /* dummy ID */ |
47 | #define MXC_CPU_IMX8MP 0x185/* dummy ID */ | 47 | #define MXC_CPU_IMX8MP 0x185/* dummy ID */ |
48 | #define MXC_CPU_IMX8MP6 0x186 /* dummy ID */ | 48 | #define MXC_CPU_IMX8MP6 0x186 /* dummy ID */ |
49 | #define MXC_CPU_IMX8MPL 0x187 /* dummy ID */ | 49 | #define MXC_CPU_IMX8MPL 0x187 /* dummy ID */ |
50 | #define MXC_CPU_IMX8MPD 0x188 /* dummy ID */ | 50 | #define MXC_CPU_IMX8MPD 0x188 /* dummy ID */ |
51 | #define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ | 51 | #define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ |
52 | #define MXC_CPU_IMX8QM 0x91 /* dummy ID */ | 52 | #define MXC_CPU_IMX8QM 0x91 /* dummy ID */ |
53 | #define MXC_CPU_IMX8QXP 0x92 /* dummy ID */ | 53 | #define MXC_CPU_IMX8QXP 0x92 /* dummy ID */ |
54 | #define MXC_CPU_IMX8DXL 0x9E /* dummy ID */ | 54 | #define MXC_CPU_IMX8DXL 0x9E /* dummy ID */ |
55 | #define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */ | 55 | #define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */ |
56 | #define MXC_CPU_VF610 0xF6 /* dummy ID */ | 56 | #define MXC_CPU_VF610 0xF6 /* dummy ID */ |
57 | 57 | ||
58 | #define MXC_SOC_MX6 0x60 | 58 | #define MXC_SOC_MX6 0x60 |
59 | #define MXC_SOC_MX7 0x70 | 59 | #define MXC_SOC_MX7 0x70 |
60 | #define MXC_SOC_IMX8M 0x80 | 60 | #define MXC_SOC_IMX8M 0x80 |
61 | #define MXC_SOC_IMX8 0x90 /* dummy */ | 61 | #define MXC_SOC_IMX8 0x90 /* dummy */ |
62 | #define MXC_SOC_MX7ULP 0xE0 /* dummy */ | 62 | #define MXC_SOC_MX7ULP 0xE0 /* dummy */ |
63 | 63 | ||
64 | #define CHIP_REV_1_0 0x10 | 64 | #define CHIP_REV_1_0 0x10 |
65 | #define CHIP_REV_1_1 0x11 | 65 | #define CHIP_REV_1_1 0x11 |
66 | #define CHIP_REV_1_2 0x12 | 66 | #define CHIP_REV_1_2 0x12 |
67 | #define CHIP_REV_1_3 0x13 | 67 | #define CHIP_REV_1_3 0x13 |
68 | #define CHIP_REV_1_5 0x15 | 68 | #define CHIP_REV_1_5 0x15 |
69 | #define CHIP_REV_2_0 0x20 | 69 | #define CHIP_REV_2_0 0x20 |
70 | #define CHIP_REV_2_1 0x21 | 70 | #define CHIP_REV_2_1 0x21 |
71 | #define CHIP_REV_2_2 0x22 | ||
71 | #define CHIP_REV_2_5 0x25 | 72 | #define CHIP_REV_2_5 0x25 |
72 | #define CHIP_REV_3_0 0x30 | 73 | #define CHIP_REV_3_0 0x30 |
73 | 74 | ||
74 | #define CHIP_REV_A 0x0 | 75 | #define CHIP_REV_A 0x0 |
75 | #define CHIP_REV_B 0x1 | 76 | #define CHIP_REV_B 0x1 |
76 | #define CHIP_REV_C 0x2 | 77 | #define CHIP_REV_C 0x2 |
77 | #define CHIP_REV_A1 0x11 | 78 | #define CHIP_REV_A1 0x11 |
78 | #define CHIP_REV_A2 0x12 | 79 | #define CHIP_REV_A2 0x12 |
79 | 80 | ||
80 | #define BOARD_REV_1_0 0x0 | 81 | #define BOARD_REV_1_0 0x0 |
81 | #define BOARD_REV_2_0 0x1 | 82 | #define BOARD_REV_2_0 0x1 |
82 | #define BOARD_VER_OFFSET 0x8 | 83 | #define BOARD_VER_OFFSET 0x8 |
83 | 84 | ||
84 | #define CS0_128 0 | 85 | #define CS0_128 0 |
85 | #define CS0_64M_CS1_64M 1 | 86 | #define CS0_64M_CS1_64M 1 |
86 | #define CS0_64M_CS1_32M_CS2_32M 2 | 87 | #define CS0_64M_CS1_32M_CS2_32M 2 |
87 | #define CS0_32M_CS1_32M_CS2_32M_CS3_32M 3 | 88 | #define CS0_32M_CS1_32M_CS2_32M_CS3_32M 3 |
88 | 89 | ||
89 | u32 get_imx_reset_cause(void); | 90 | u32 get_imx_reset_cause(void); |
90 | ulong get_systemPLLCLK(void); | 91 | ulong get_systemPLLCLK(void); |
91 | ulong get_FCLK(void); | 92 | ulong get_FCLK(void); |
92 | ulong get_HCLK(void); | 93 | ulong get_HCLK(void); |
93 | ulong get_BCLK(void); | 94 | ulong get_BCLK(void); |
94 | ulong get_PERCLK1(void); | 95 | ulong get_PERCLK1(void); |
95 | ulong get_PERCLK2(void); | 96 | ulong get_PERCLK2(void); |
96 | ulong get_PERCLK3(void); | 97 | ulong get_PERCLK3(void); |
97 | 98 |
arch/arm/mach-imx/imx8m/soc.c
1 | // SPDX-License-Identifier: GPL-2.0+ | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | 2 | /* |
3 | * Copyright 2017-2019 NXP | 3 | * Copyright 2017-2019 NXP |
4 | * | 4 | * |
5 | * Peng Fan <peng.fan@nxp.com> | 5 | * Peng Fan <peng.fan@nxp.com> |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <cpu_func.h> | 9 | #include <cpu_func.h> |
10 | #include <asm/arch/imx-regs.h> | 10 | #include <asm/arch/imx-regs.h> |
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | #include <asm/arch/clock.h> | 12 | #include <asm/arch/clock.h> |
13 | #include <asm/arch/sys_proto.h> | 13 | #include <asm/arch/sys_proto.h> |
14 | #include <asm/mach-imx/hab.h> | 14 | #include <asm/mach-imx/hab.h> |
15 | #include <asm/mach-imx/boot_mode.h> | 15 | #include <asm/mach-imx/boot_mode.h> |
16 | #include <asm/mach-imx/optee.h> | 16 | #include <asm/mach-imx/optee.h> |
17 | #include <asm/mach-imx/syscounter.h> | 17 | #include <asm/mach-imx/syscounter.h> |
18 | #include <asm/armv8/mmu.h> | 18 | #include <asm/armv8/mmu.h> |
19 | #include <dm/uclass.h> | 19 | #include <dm/uclass.h> |
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | #include <fdt_support.h> | 21 | #include <fdt_support.h> |
22 | #include <fdtdec.h> | 22 | #include <fdtdec.h> |
23 | #include <fsl_wdog.h> | 23 | #include <fsl_wdog.h> |
24 | #include <imx_sip.h> | 24 | #include <imx_sip.h> |
25 | #include <generated/version_autogenerated.h> | 25 | #include <generated/version_autogenerated.h> |
26 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
27 | #include <asm/bootm.h> | 27 | #include <asm/bootm.h> |
28 | #ifdef CONFIG_IMX_SEC_INIT | 28 | #ifdef CONFIG_IMX_SEC_INIT |
29 | #include <fsl_caam.h> | 29 | #include <fsl_caam.h> |
30 | #endif | 30 | #endif |
31 | #include <env.h> | 31 | #include <env.h> |
32 | #include <env_internal.h> | 32 | #include <env_internal.h> |
33 | #include <efi_loader.h> | 33 | #include <efi_loader.h> |
34 | 34 | ||
35 | DECLARE_GLOBAL_DATA_PTR; | 35 | DECLARE_GLOBAL_DATA_PTR; |
36 | 36 | ||
37 | #if defined(CONFIG_IMX_HAB) || defined(CONFIG_AVB_ATX) || defined(CONFIG_IMX_TRUSTY_OS) | 37 | #if defined(CONFIG_IMX_HAB) || defined(CONFIG_AVB_ATX) || defined(CONFIG_IMX_TRUSTY_OS) |
38 | struct imx_sec_config_fuse_t const imx_sec_config_fuse = { | 38 | struct imx_sec_config_fuse_t const imx_sec_config_fuse = { |
39 | .bank = 1, | 39 | .bank = 1, |
40 | .word = 3, | 40 | .word = 3, |
41 | }; | 41 | }; |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | int timer_init(void) | 44 | int timer_init(void) |
45 | { | 45 | { |
46 | #ifdef CONFIG_SPL_BUILD | 46 | #ifdef CONFIG_SPL_BUILD |
47 | struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR; | 47 | struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR; |
48 | unsigned long freq = readl(&sctr->cntfid0); | 48 | unsigned long freq = readl(&sctr->cntfid0); |
49 | 49 | ||
50 | /* Update with accurate clock frequency */ | 50 | /* Update with accurate clock frequency */ |
51 | asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory"); | 51 | asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory"); |
52 | 52 | ||
53 | clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1, | 53 | clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1, |
54 | SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG); | 54 | SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG); |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | gd->arch.tbl = 0; | 57 | gd->arch.tbl = 0; |
58 | gd->arch.tbu = 0; | 58 | gd->arch.tbu = 0; |
59 | 59 | ||
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | void enable_tzc380(void) | 63 | void enable_tzc380(void) |
64 | { | 64 | { |
65 | struct iomuxc_gpr_base_regs *gpr = | 65 | struct iomuxc_gpr_base_regs *gpr = |
66 | (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; | 66 | (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; |
67 | 67 | ||
68 | /* Enable TZASC and lock setting */ | 68 | /* Enable TZASC and lock setting */ |
69 | setbits_le32(&gpr->gpr[10], GPR_TZASC_EN); | 69 | setbits_le32(&gpr->gpr[10], GPR_TZASC_EN); |
70 | setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK); | 70 | setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK); |
71 | if (is_imx8mm() || is_imx8mn() || is_imx8mp()) | 71 | if (is_imx8mm() || is_imx8mn() || is_imx8mp()) |
72 | setbits_le32(&gpr->gpr[10], BIT(1)); | 72 | setbits_le32(&gpr->gpr[10], BIT(1)); |
73 | /* | 73 | /* |
74 | * set Region 0 attribute to allow secure and non-secure | 74 | * set Region 0 attribute to allow secure and non-secure |
75 | * read/write permission. Found some masters like usb dwc3 | 75 | * read/write permission. Found some masters like usb dwc3 |
76 | * controllers can't work with secure memory. | 76 | * controllers can't work with secure memory. |
77 | */ | 77 | */ |
78 | writel(0xf0000000, TZASC_BASE_ADDR + 0x108); | 78 | writel(0xf0000000, TZASC_BASE_ADDR + 0x108); |
79 | } | 79 | } |
80 | 80 | ||
81 | void set_wdog_reset(struct wdog_regs *wdog) | 81 | void set_wdog_reset(struct wdog_regs *wdog) |
82 | { | 82 | { |
83 | /* | 83 | /* |
84 | * Output WDOG_B signal to reset external pmic or POR_B decided by | 84 | * Output WDOG_B signal to reset external pmic or POR_B decided by |
85 | * the board design. Without external reset, the peripherals/DDR/ | 85 | * the board design. Without external reset, the peripherals/DDR/ |
86 | * PMIC are not reset, that may cause system working abnormal. | 86 | * PMIC are not reset, that may cause system working abnormal. |
87 | * WDZST bit is write-once only bit. Align this bit in kernel, | 87 | * WDZST bit is write-once only bit. Align this bit in kernel, |
88 | * otherwise kernel code will have no chance to set this bit. | 88 | * otherwise kernel code will have no chance to set this bit. |
89 | */ | 89 | */ |
90 | setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK); | 90 | setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK); |
91 | } | 91 | } |
92 | 92 | ||
93 | static struct mm_region imx8m_mem_map[] = { | 93 | static struct mm_region imx8m_mem_map[] = { |
94 | { | 94 | { |
95 | /* ROM */ | 95 | /* ROM */ |
96 | .virt = 0x0UL, | 96 | .virt = 0x0UL, |
97 | .phys = 0x0UL, | 97 | .phys = 0x0UL, |
98 | .size = 0x100000UL, | 98 | .size = 0x100000UL, |
99 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | 99 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
100 | PTE_BLOCK_OUTER_SHARE | 100 | PTE_BLOCK_OUTER_SHARE |
101 | }, { | 101 | }, { |
102 | /* CAAM */ | 102 | /* CAAM */ |
103 | .virt = 0x100000UL, | 103 | .virt = 0x100000UL, |
104 | .phys = 0x100000UL, | 104 | .phys = 0x100000UL, |
105 | .size = 0x8000UL, | 105 | .size = 0x8000UL, |
106 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 106 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
107 | PTE_BLOCK_NON_SHARE | | 107 | PTE_BLOCK_NON_SHARE | |
108 | PTE_BLOCK_PXN | PTE_BLOCK_UXN | 108 | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
109 | }, { | 109 | }, { |
110 | /* TCM */ | 110 | /* TCM */ |
111 | .virt = 0x7C0000UL, | 111 | .virt = 0x7C0000UL, |
112 | .phys = 0x7C0000UL, | 112 | .phys = 0x7C0000UL, |
113 | .size = 0x80000UL, | 113 | .size = 0x80000UL, |
114 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 114 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
115 | PTE_BLOCK_NON_SHARE | | 115 | PTE_BLOCK_NON_SHARE | |
116 | PTE_BLOCK_PXN | PTE_BLOCK_UXN | 116 | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
117 | }, { | 117 | }, { |
118 | /* OCRAM */ | 118 | /* OCRAM */ |
119 | .virt = 0x900000UL, | 119 | .virt = 0x900000UL, |
120 | .phys = 0x900000UL, | 120 | .phys = 0x900000UL, |
121 | .size = 0x200000UL, | 121 | .size = 0x200000UL, |
122 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | 122 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
123 | PTE_BLOCK_OUTER_SHARE | 123 | PTE_BLOCK_OUTER_SHARE |
124 | }, { | 124 | }, { |
125 | /* AIPS */ | 125 | /* AIPS */ |
126 | .virt = 0xB00000UL, | 126 | .virt = 0xB00000UL, |
127 | .phys = 0xB00000UL, | 127 | .phys = 0xB00000UL, |
128 | .size = 0x3f500000UL, | 128 | .size = 0x3f500000UL, |
129 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 129 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
130 | PTE_BLOCK_NON_SHARE | | 130 | PTE_BLOCK_NON_SHARE | |
131 | PTE_BLOCK_PXN | PTE_BLOCK_UXN | 131 | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
132 | }, { | 132 | }, { |
133 | /* DRAM1 */ | 133 | /* DRAM1 */ |
134 | .virt = 0x40000000UL, | 134 | .virt = 0x40000000UL, |
135 | .phys = 0x40000000UL, | 135 | .phys = 0x40000000UL, |
136 | .size = PHYS_SDRAM_SIZE, | 136 | .size = PHYS_SDRAM_SIZE, |
137 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | 137 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
138 | #ifdef CONFIG_IMX_TRUSTY_OS | 138 | #ifdef CONFIG_IMX_TRUSTY_OS |
139 | PTE_BLOCK_INNER_SHARE | 139 | PTE_BLOCK_INNER_SHARE |
140 | #else | 140 | #else |
141 | PTE_BLOCK_OUTER_SHARE | 141 | PTE_BLOCK_OUTER_SHARE |
142 | #endif | 142 | #endif |
143 | #ifdef PHYS_SDRAM_2_SIZE | 143 | #ifdef PHYS_SDRAM_2_SIZE |
144 | }, { | 144 | }, { |
145 | /* DRAM2 */ | 145 | /* DRAM2 */ |
146 | .virt = 0x100000000UL, | 146 | .virt = 0x100000000UL, |
147 | .phys = 0x100000000UL, | 147 | .phys = 0x100000000UL, |
148 | .size = PHYS_SDRAM_2_SIZE, | 148 | .size = PHYS_SDRAM_2_SIZE, |
149 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | 149 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
150 | #ifdef CONFIG_IMX_TRUSTY_OS | 150 | #ifdef CONFIG_IMX_TRUSTY_OS |
151 | PTE_BLOCK_INNER_SHARE | 151 | PTE_BLOCK_INNER_SHARE |
152 | #else | 152 | #else |
153 | PTE_BLOCK_OUTER_SHARE | 153 | PTE_BLOCK_OUTER_SHARE |
154 | #endif | 154 | #endif |
155 | #endif | 155 | #endif |
156 | }, { | 156 | }, { |
157 | /* empty entrie to split table entry 5 | 157 | /* empty entrie to split table entry 5 |
158 | * if needed when TEEs are used | 158 | * if needed when TEEs are used |
159 | */ | 159 | */ |
160 | 0, | 160 | 0, |
161 | }, { | 161 | }, { |
162 | /* List terminator */ | 162 | /* List terminator */ |
163 | 0, | 163 | 0, |
164 | } | 164 | } |
165 | }; | 165 | }; |
166 | 166 | ||
167 | struct mm_region *mem_map = imx8m_mem_map; | 167 | struct mm_region *mem_map = imx8m_mem_map; |
168 | 168 | ||
169 | void enable_caches(void) | 169 | void enable_caches(void) |
170 | { | 170 | { |
171 | /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */ | 171 | /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */ |
172 | if (rom_pointer[1]) { | 172 | if (rom_pointer[1]) { |
173 | 173 | ||
174 | /* TEE are loaded, So the ddr bank structures | 174 | /* TEE are loaded, So the ddr bank structures |
175 | * have been modified update mmu table accordingly | 175 | * have been modified update mmu table accordingly |
176 | */ | 176 | */ |
177 | int i = 0; | 177 | int i = 0; |
178 | /* please make sure that entry initial value matches | 178 | /* please make sure that entry initial value matches |
179 | * imx8m_mem_map for DRAM1 | 179 | * imx8m_mem_map for DRAM1 |
180 | */ | 180 | */ |
181 | int entry = 5; | 181 | int entry = 5; |
182 | u64 attrs = imx8m_mem_map[entry].attrs; | 182 | u64 attrs = imx8m_mem_map[entry].attrs; |
183 | while (i < CONFIG_NR_DRAM_BANKS && entry < 8) { | 183 | while (i < CONFIG_NR_DRAM_BANKS && entry < 8) { |
184 | if (gd->bd->bi_dram[i].start == 0) | 184 | if (gd->bd->bi_dram[i].start == 0) |
185 | break; | 185 | break; |
186 | imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start; | 186 | imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start; |
187 | imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start; | 187 | imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start; |
188 | imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size; | 188 | imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size; |
189 | imx8m_mem_map[entry].attrs = attrs; | 189 | imx8m_mem_map[entry].attrs = attrs; |
190 | debug("Added memory mapping (%d): %llx %llx\n", entry, | 190 | debug("Added memory mapping (%d): %llx %llx\n", entry, |
191 | imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size); | 191 | imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size); |
192 | i++;entry++; | 192 | i++;entry++; |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | icache_enable(); | 196 | icache_enable(); |
197 | dcache_enable(); | 197 | dcache_enable(); |
198 | } | 198 | } |
199 | 199 | ||
200 | __weak int board_phys_sdram_size(phys_size_t *size) | 200 | __weak int board_phys_sdram_size(phys_size_t *size) |
201 | { | 201 | { |
202 | if (!size) | 202 | if (!size) |
203 | return -EINVAL; | 203 | return -EINVAL; |
204 | 204 | ||
205 | *size = PHYS_SDRAM_SIZE; | 205 | *size = PHYS_SDRAM_SIZE; |
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
208 | 208 | ||
209 | int dram_init(void) | 209 | int dram_init(void) |
210 | { | 210 | { |
211 | phys_size_t sdram_size; | 211 | phys_size_t sdram_size; |
212 | int ret; | 212 | int ret; |
213 | 213 | ||
214 | ret = board_phys_sdram_size(&sdram_size); | 214 | ret = board_phys_sdram_size(&sdram_size); |
215 | if (ret) | 215 | if (ret) |
216 | return ret; | 216 | return ret; |
217 | 217 | ||
218 | /* rom_pointer[1] contains the size of TEE occupies */ | 218 | /* rom_pointer[1] contains the size of TEE occupies */ |
219 | if (rom_pointer[1]) | 219 | if (rom_pointer[1]) |
220 | gd->ram_size = sdram_size - rom_pointer[1]; | 220 | gd->ram_size = sdram_size - rom_pointer[1]; |
221 | else | 221 | else |
222 | gd->ram_size = sdram_size; | 222 | gd->ram_size = sdram_size; |
223 | 223 | ||
224 | #ifdef PHYS_SDRAM_2_SIZE | 224 | #ifdef PHYS_SDRAM_2_SIZE |
225 | gd->ram_size += PHYS_SDRAM_2_SIZE; | 225 | gd->ram_size += PHYS_SDRAM_2_SIZE; |
226 | #endif | 226 | #endif |
227 | 227 | ||
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
230 | 230 | ||
231 | int dram_init_banksize(void) | 231 | int dram_init_banksize(void) |
232 | { | 232 | { |
233 | int bank = 0; | 233 | int bank = 0; |
234 | int ret; | 234 | int ret; |
235 | phys_size_t sdram_size; | 235 | phys_size_t sdram_size; |
236 | 236 | ||
237 | ret = board_phys_sdram_size(&sdram_size); | 237 | ret = board_phys_sdram_size(&sdram_size); |
238 | if (ret) | 238 | if (ret) |
239 | return ret; | 239 | return ret; |
240 | 240 | ||
241 | gd->bd->bi_dram[bank].start = PHYS_SDRAM; | 241 | gd->bd->bi_dram[bank].start = PHYS_SDRAM; |
242 | if (rom_pointer[1]) { | 242 | if (rom_pointer[1]) { |
243 | phys_addr_t optee_start = (phys_addr_t)rom_pointer[0]; | 243 | phys_addr_t optee_start = (phys_addr_t)rom_pointer[0]; |
244 | phys_size_t optee_size = (size_t)rom_pointer[1]; | 244 | phys_size_t optee_size = (size_t)rom_pointer[1]; |
245 | 245 | ||
246 | gd->bd->bi_dram[bank].size = optee_start -gd->bd->bi_dram[bank].start; | 246 | gd->bd->bi_dram[bank].size = optee_start -gd->bd->bi_dram[bank].start; |
247 | if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) { | 247 | if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) { |
248 | if ( ++bank >= CONFIG_NR_DRAM_BANKS) { | 248 | if ( ++bank >= CONFIG_NR_DRAM_BANKS) { |
249 | puts("CONFIG_NR_DRAM_BANKS is not enough\n"); | 249 | puts("CONFIG_NR_DRAM_BANKS is not enough\n"); |
250 | return -1; | 250 | return -1; |
251 | } | 251 | } |
252 | 252 | ||
253 | gd->bd->bi_dram[bank].start = optee_start + optee_size; | 253 | gd->bd->bi_dram[bank].start = optee_start + optee_size; |
254 | gd->bd->bi_dram[bank].size = PHYS_SDRAM + | 254 | gd->bd->bi_dram[bank].size = PHYS_SDRAM + |
255 | sdram_size - gd->bd->bi_dram[bank].start; | 255 | sdram_size - gd->bd->bi_dram[bank].start; |
256 | } | 256 | } |
257 | } else { | 257 | } else { |
258 | gd->bd->bi_dram[bank].size = sdram_size; | 258 | gd->bd->bi_dram[bank].size = sdram_size; |
259 | } | 259 | } |
260 | 260 | ||
261 | #ifdef PHYS_SDRAM_2_SIZE | 261 | #ifdef PHYS_SDRAM_2_SIZE |
262 | if ( ++bank >= CONFIG_NR_DRAM_BANKS) { | 262 | if ( ++bank >= CONFIG_NR_DRAM_BANKS) { |
263 | puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n"); | 263 | puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n"); |
264 | return -1; | 264 | return -1; |
265 | } | 265 | } |
266 | gd->bd->bi_dram[bank].start = PHYS_SDRAM_2; | 266 | gd->bd->bi_dram[bank].start = PHYS_SDRAM_2; |
267 | gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE; | 267 | gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE; |
268 | #endif | 268 | #endif |
269 | 269 | ||
270 | return 0; | 270 | return 0; |
271 | } | 271 | } |
272 | 272 | ||
273 | phys_size_t get_effective_memsize(void) | 273 | phys_size_t get_effective_memsize(void) |
274 | { | 274 | { |
275 | /* return the first bank as effective memory */ | 275 | /* return the first bank as effective memory */ |
276 | if (rom_pointer[1]) | 276 | if (rom_pointer[1]) |
277 | return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM); | 277 | return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM); |
278 | 278 | ||
279 | #ifdef PHYS_SDRAM_2_SIZE | 279 | #ifdef PHYS_SDRAM_2_SIZE |
280 | return gd->ram_size - PHYS_SDRAM_2_SIZE; | 280 | return gd->ram_size - PHYS_SDRAM_2_SIZE; |
281 | #else | 281 | #else |
282 | return gd->ram_size; | 282 | return gd->ram_size; |
283 | #endif | 283 | #endif |
284 | } | 284 | } |
285 | 285 | ||
286 | static u32 get_cpu_variant_type(u32 type) | 286 | static u32 get_cpu_variant_type(u32 type) |
287 | { | 287 | { |
288 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 288 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
289 | struct fuse_bank *bank = &ocotp->bank[1]; | 289 | struct fuse_bank *bank = &ocotp->bank[1]; |
290 | struct fuse_bank1_regs *fuse = | 290 | struct fuse_bank1_regs *fuse = |
291 | (struct fuse_bank1_regs *)bank->fuse_regs; | 291 | (struct fuse_bank1_regs *)bank->fuse_regs; |
292 | 292 | ||
293 | u32 value = readl(&fuse->tester4); | 293 | u32 value = readl(&fuse->tester4); |
294 | 294 | ||
295 | if (type == MXC_CPU_IMX8MQ) { | 295 | if (type == MXC_CPU_IMX8MQ) { |
296 | if ((value & 0x3) == 0x2) | 296 | if ((value & 0x3) == 0x2) |
297 | return MXC_CPU_IMX8MD; | 297 | return MXC_CPU_IMX8MD; |
298 | else if (value & 0x200000) | 298 | else if (value & 0x200000) |
299 | return MXC_CPU_IMX8MQL; | 299 | return MXC_CPU_IMX8MQL; |
300 | 300 | ||
301 | } else if (type == MXC_CPU_IMX8MM) { | 301 | } else if (type == MXC_CPU_IMX8MM) { |
302 | switch (value & 0x3) { | 302 | switch (value & 0x3) { |
303 | case 2: | 303 | case 2: |
304 | if (value & 0x1c0000) | 304 | if (value & 0x1c0000) |
305 | return MXC_CPU_IMX8MMDL; | 305 | return MXC_CPU_IMX8MMDL; |
306 | else | 306 | else |
307 | return MXC_CPU_IMX8MMD; | 307 | return MXC_CPU_IMX8MMD; |
308 | case 3: | 308 | case 3: |
309 | if (value & 0x1c0000) | 309 | if (value & 0x1c0000) |
310 | return MXC_CPU_IMX8MMSL; | 310 | return MXC_CPU_IMX8MMSL; |
311 | else | 311 | else |
312 | return MXC_CPU_IMX8MMS; | 312 | return MXC_CPU_IMX8MMS; |
313 | default: | 313 | default: |
314 | if (value & 0x1c0000) | 314 | if (value & 0x1c0000) |
315 | return MXC_CPU_IMX8MML; | 315 | return MXC_CPU_IMX8MML; |
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | } else if (type == MXC_CPU_IMX8MN) { | 318 | } else if (type == MXC_CPU_IMX8MN) { |
319 | switch (value & 0x3) { | 319 | switch (value & 0x3) { |
320 | case 2: | 320 | case 2: |
321 | if (value & 0x1000000) { | 321 | if (value & 0x1000000) { |
322 | if (value & 0x10000000) /* MIPI DSI */ | 322 | if (value & 0x10000000) /* MIPI DSI */ |
323 | return MXC_CPU_IMX8MNUD; | 323 | return MXC_CPU_IMX8MNUD; |
324 | else | 324 | else |
325 | return MXC_CPU_IMX8MNDL; | 325 | return MXC_CPU_IMX8MNDL; |
326 | } else { | 326 | } else { |
327 | return MXC_CPU_IMX8MND; | 327 | return MXC_CPU_IMX8MND; |
328 | } | 328 | } |
329 | case 3: | 329 | case 3: |
330 | if (value & 0x1000000) { | 330 | if (value & 0x1000000) { |
331 | if (value & 0x10000000) /* MIPI DSI */ | 331 | if (value & 0x10000000) /* MIPI DSI */ |
332 | return MXC_CPU_IMX8MNUS; | 332 | return MXC_CPU_IMX8MNUS; |
333 | else | 333 | else |
334 | return MXC_CPU_IMX8MNSL; | 334 | return MXC_CPU_IMX8MNSL; |
335 | } else { | 335 | } else { |
336 | return MXC_CPU_IMX8MNS; | 336 | return MXC_CPU_IMX8MNS; |
337 | } | 337 | } |
338 | default: | 338 | default: |
339 | if (value & 0x1000000) { | 339 | if (value & 0x1000000) { |
340 | if (value & 0x10000000) /* MIPI DSI */ | 340 | if (value & 0x10000000) /* MIPI DSI */ |
341 | return MXC_CPU_IMX8MNUQ; | 341 | return MXC_CPU_IMX8MNUQ; |
342 | else | 342 | else |
343 | return MXC_CPU_IMX8MNL; | 343 | return MXC_CPU_IMX8MNL; |
344 | } | 344 | } |
345 | break; | 345 | break; |
346 | } | 346 | } |
347 | } else if (type == MXC_CPU_IMX8MP) { | 347 | } else if (type == MXC_CPU_IMX8MP) { |
348 | u32 value0 = readl(&fuse->tester3); | 348 | u32 value0 = readl(&fuse->tester3); |
349 | u32 flag = 0; | 349 | u32 flag = 0; |
350 | 350 | ||
351 | if ((value0 & 0xc0000) == 0x80000) { | 351 | if ((value0 & 0xc0000) == 0x80000) { |
352 | return MXC_CPU_IMX8MPD; | 352 | return MXC_CPU_IMX8MPD; |
353 | } else { | 353 | } else { |
354 | /* vpu disabled */ | 354 | /* vpu disabled */ |
355 | if ((value0 & 0x43000000) == 0x43000000) | 355 | if ((value0 & 0x43000000) == 0x43000000) |
356 | flag = 1; | 356 | flag = 1; |
357 | 357 | ||
358 | /* npu disabled*/ | 358 | /* npu disabled*/ |
359 | if ((value & 0x8) == 0x8) | 359 | if ((value & 0x8) == 0x8) |
360 | flag |= (1 << 1); | 360 | flag |= (1 << 1); |
361 | 361 | ||
362 | /* isp disabled */ | 362 | /* isp disabled */ |
363 | if ((value & 0x3) == 0x3) | 363 | if ((value & 0x3) == 0x3) |
364 | flag |= (1 << 2); | 364 | flag |= (1 << 2); |
365 | 365 | ||
366 | switch (flag) { | 366 | switch (flag) { |
367 | case 7: | 367 | case 7: |
368 | return MXC_CPU_IMX8MPL; | 368 | return MXC_CPU_IMX8MPL; |
369 | case 2: | 369 | case 2: |
370 | return MXC_CPU_IMX8MP6; | 370 | return MXC_CPU_IMX8MP6; |
371 | default: | 371 | default: |
372 | break; | 372 | break; |
373 | } | 373 | } |
374 | } | 374 | } |
375 | } | 375 | } |
376 | 376 | ||
377 | return type; | 377 | return type; |
378 | } | 378 | } |
379 | 379 | ||
380 | u32 get_cpu_rev(void) | 380 | u32 get_cpu_rev(void) |
381 | { | 381 | { |
382 | struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; | 382 | struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; |
383 | u32 reg = readl(&ana_pll->digprog); | 383 | u32 reg = readl(&ana_pll->digprog); |
384 | u32 type = (reg >> 16) & 0xff; | 384 | u32 type = (reg >> 16) & 0xff; |
385 | u32 major_low = (reg >> 8) & 0xff; | 385 | u32 major_low = (reg >> 8) & 0xff; |
386 | u32 rom_version; | 386 | u32 rom_version; |
387 | 387 | ||
388 | reg &= 0xff; | 388 | reg &= 0xff; |
389 | 389 | ||
390 | /* iMX8MP */ | 390 | /* iMX8MP */ |
391 | if (major_low == 0x43) { | 391 | if (major_low == 0x43) { |
392 | type = get_cpu_variant_type(MXC_CPU_IMX8MP); | 392 | type = get_cpu_variant_type(MXC_CPU_IMX8MP); |
393 | } else if (major_low == 0x42) { | 393 | } else if (major_low == 0x42) { |
394 | /* iMX8MN */ | 394 | /* iMX8MN */ |
395 | type = get_cpu_variant_type(MXC_CPU_IMX8MN); | 395 | type = get_cpu_variant_type(MXC_CPU_IMX8MN); |
396 | } else if (major_low == 0x41) { | 396 | } else if (major_low == 0x41) { |
397 | type = get_cpu_variant_type(MXC_CPU_IMX8MM); | 397 | type = get_cpu_variant_type(MXC_CPU_IMX8MM); |
398 | } else { | 398 | } else { |
399 | if (reg == CHIP_REV_1_0) { | 399 | if (reg == CHIP_REV_1_0) { |
400 | /* | 400 | /* |
401 | * For B0 chip, the DIGPROG is not updated, | 401 | * For B0 chip, the DIGPROG is not updated, |
402 | * it is still TO1.0. we have to check ROM | 402 | * it is still TO1.0. we have to check ROM |
403 | * version or OCOTP_READ_FUSE_DATA. | 403 | * version or OCOTP_READ_FUSE_DATA. |
404 | * 0xff0055aa is magic number for B1. | 404 | * 0xff0055aa is magic number for B1. |
405 | */ | 405 | */ |
406 | if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) { | 406 | if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) { |
407 | reg = CHIP_REV_2_1; | 407 | /* |
408 | * B2 uses same DIGPROG and OCOTP_READ_FUSE_DATA value with B1, | ||
409 | * so have to check ROM to distinguish them | ||
410 | */ | ||
411 | rom_version = readl((void __iomem *)ROM_VERSION_B0); | ||
412 | rom_version &= 0xff; | ||
413 | if (rom_version == CHIP_REV_2_2) | ||
414 | reg = CHIP_REV_2_2; | ||
415 | else | ||
416 | reg = CHIP_REV_2_1; | ||
408 | } else { | 417 | } else { |
409 | rom_version = | 418 | rom_version = |
410 | readl((void __iomem *)ROM_VERSION_A0); | 419 | readl((void __iomem *)ROM_VERSION_A0); |
411 | if (rom_version != CHIP_REV_1_0) { | 420 | if (rom_version != CHIP_REV_1_0) { |
412 | rom_version = readl((void __iomem *)ROM_VERSION_B0); | 421 | rom_version = readl((void __iomem *)ROM_VERSION_B0); |
413 | rom_version &= 0xff; | 422 | rom_version &= 0xff; |
414 | if (rom_version == CHIP_REV_2_0) | 423 | if (rom_version == CHIP_REV_2_0) |
415 | reg = CHIP_REV_2_0; | 424 | reg = CHIP_REV_2_0; |
416 | } | 425 | } |
417 | } | 426 | } |
418 | } | 427 | } |
419 | 428 | ||
420 | type = get_cpu_variant_type(type); | 429 | type = get_cpu_variant_type(type); |
421 | } | 430 | } |
422 | 431 | ||
423 | return (type << 12) | reg; | 432 | return (type << 12) | reg; |
424 | } | 433 | } |
425 | 434 | ||
426 | static void imx_set_wdog_powerdown(bool enable) | 435 | static void imx_set_wdog_powerdown(bool enable) |
427 | { | 436 | { |
428 | struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; | 437 | struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; |
429 | struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; | 438 | struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; |
430 | struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; | 439 | struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; |
431 | 440 | ||
432 | /* Write to the PDE (Power Down Enable) bit */ | 441 | /* Write to the PDE (Power Down Enable) bit */ |
433 | writew(enable, &wdog1->wmcr); | 442 | writew(enable, &wdog1->wmcr); |
434 | writew(enable, &wdog2->wmcr); | 443 | writew(enable, &wdog2->wmcr); |
435 | writew(enable, &wdog3->wmcr); | 444 | writew(enable, &wdog3->wmcr); |
436 | } | 445 | } |
437 | 446 | ||
438 | int arch_cpu_init_dm(void) | 447 | int arch_cpu_init_dm(void) |
439 | { | 448 | { |
440 | struct udevice *dev; | 449 | struct udevice *dev; |
441 | int ret; | 450 | int ret; |
442 | 451 | ||
443 | if (CONFIG_IS_ENABLED(CLK)) { | 452 | if (CONFIG_IS_ENABLED(CLK)) { |
444 | ret = uclass_get_device_by_name(UCLASS_CLK, | 453 | ret = uclass_get_device_by_name(UCLASS_CLK, |
445 | "clock-controller@30380000", | 454 | "clock-controller@30380000", |
446 | &dev); | 455 | &dev); |
447 | if (ret < 0) { | 456 | if (ret < 0) { |
448 | printf("Failed to find clock node. Check device tree\n"); | 457 | printf("Failed to find clock node. Check device tree\n"); |
449 | return ret; | 458 | return ret; |
450 | } | 459 | } |
451 | } | 460 | } |
452 | 461 | ||
453 | return 0; | 462 | return 0; |
454 | } | 463 | } |
455 | 464 | ||
456 | #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ) | 465 | #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ) |
457 | static bool is_hdmi_fused(void) { | 466 | static bool is_hdmi_fused(void) { |
458 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 467 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
459 | struct fuse_bank *bank = &ocotp->bank[1]; | 468 | struct fuse_bank *bank = &ocotp->bank[1]; |
460 | struct fuse_bank1_regs *fuse = | 469 | struct fuse_bank1_regs *fuse = |
461 | (struct fuse_bank1_regs *)bank->fuse_regs; | 470 | (struct fuse_bank1_regs *)bank->fuse_regs; |
462 | 471 | ||
463 | u32 value = readl(&fuse->tester4); | 472 | u32 value = readl(&fuse->tester4); |
464 | 473 | ||
465 | if (is_imx8mq()) { | 474 | if (is_imx8mq()) { |
466 | if (value & 0x02000000) | 475 | if (value & 0x02000000) |
467 | return true; | 476 | return true; |
468 | } | 477 | } |
469 | 478 | ||
470 | return false; | 479 | return false; |
471 | } | 480 | } |
472 | 481 | ||
473 | bool is_uid_matched(u64 uid) { | 482 | bool is_uid_matched(u64 uid) { |
474 | struct tag_serialnr nr; | 483 | struct tag_serialnr nr; |
475 | get_board_serial(&nr); | 484 | get_board_serial(&nr); |
476 | 485 | ||
477 | if (lower_32_bits(uid) == nr.low && | 486 | if (lower_32_bits(uid) == nr.low && |
478 | upper_32_bits(uid) == nr.high) | 487 | upper_32_bits(uid) == nr.high) |
479 | return true; | 488 | return true; |
480 | 489 | ||
481 | return false; | 490 | return false; |
482 | } | 491 | } |
483 | 492 | ||
484 | static void secure_lockup(void) | 493 | static void secure_lockup(void) |
485 | { | 494 | { |
486 | if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) && | 495 | if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) && |
487 | imx_hab_is_enabled() && !is_hdmi_fused()) { | 496 | imx_hab_is_enabled() && !is_hdmi_fused()) { |
488 | #ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP | 497 | #ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP |
489 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 498 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
490 | 499 | ||
491 | clock_enable(CCGR_OCOTP, 1); | 500 | clock_enable(CCGR_OCOTP, 1); |
492 | setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */ | 501 | setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */ |
493 | writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */ | 502 | writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */ |
494 | #else | 503 | #else |
495 | /* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */ | 504 | /* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */ |
496 | if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID)) | 505 | if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID)) |
497 | hang(); | 506 | hang(); |
498 | #endif | 507 | #endif |
499 | } | 508 | } |
500 | } | 509 | } |
501 | #endif | 510 | #endif |
502 | 511 | ||
503 | int arch_cpu_init(void) | 512 | int arch_cpu_init(void) |
504 | { | 513 | { |
505 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 514 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
506 | /* | 515 | /* |
507 | * ROM might disable clock for SCTR, | 516 | * ROM might disable clock for SCTR, |
508 | * enable the clock before timer_init. | 517 | * enable the clock before timer_init. |
509 | */ | 518 | */ |
510 | if (IS_ENABLED(CONFIG_SPL_BUILD)) | 519 | if (IS_ENABLED(CONFIG_SPL_BUILD)) |
511 | clock_enable(CCGR_SCTR, 1); | 520 | clock_enable(CCGR_SCTR, 1); |
512 | /* | 521 | /* |
513 | * Init timer at very early state, because sscg pll setting | 522 | * Init timer at very early state, because sscg pll setting |
514 | * will use it | 523 | * will use it |
515 | */ | 524 | */ |
516 | timer_init(); | 525 | timer_init(); |
517 | 526 | ||
518 | if (IS_ENABLED(CONFIG_SPL_BUILD)) { | 527 | if (IS_ENABLED(CONFIG_SPL_BUILD)) { |
519 | clock_init(); | 528 | clock_init(); |
520 | imx_set_wdog_powerdown(false); | 529 | imx_set_wdog_powerdown(false); |
521 | 530 | ||
522 | #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ) | 531 | #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ) |
523 | secure_lockup(); | 532 | secure_lockup(); |
524 | #endif | 533 | #endif |
525 | if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() || | 534 | if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() || |
526 | is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl() || is_imx8mpd() || | 535 | is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl() || is_imx8mpd() || |
527 | is_imx8mnud() || is_imx8mnus()) { | 536 | is_imx8mnud() || is_imx8mnus()) { |
528 | /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */ | 537 | /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */ |
529 | struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840); | 538 | struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840); |
530 | struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880); | 539 | struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880); |
531 | struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0); | 540 | struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0); |
532 | struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR; | 541 | struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR; |
533 | 542 | ||
534 | writel(0x1, &pgc_core2->pgcr); | 543 | writel(0x1, &pgc_core2->pgcr); |
535 | writel(0x1, &pgc_core3->pgcr); | 544 | writel(0x1, &pgc_core3->pgcr); |
536 | if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) { | 545 | if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) { |
537 | writel(0x1, &pgc_core1->pgcr); | 546 | writel(0x1, &pgc_core1->pgcr); |
538 | writel(0xE, &gpc->cpu_pgc_dn_trg); | 547 | writel(0xE, &gpc->cpu_pgc_dn_trg); |
539 | } else { | 548 | } else { |
540 | writel(0xC, &gpc->cpu_pgc_dn_trg); | 549 | writel(0xC, &gpc->cpu_pgc_dn_trg); |
541 | } | 550 | } |
542 | } | 551 | } |
543 | } | 552 | } |
544 | 553 | ||
545 | #ifdef CONFIG_IMX_SEC_INIT | 554 | #ifdef CONFIG_IMX_SEC_INIT |
546 | /* Secure init function such RNG */ | 555 | /* Secure init function such RNG */ |
547 | imx_sec_init(); | 556 | imx_sec_init(); |
548 | #endif | 557 | #endif |
549 | #if defined(CONFIG_ANDROID_SUPPORT) | 558 | #if defined(CONFIG_ANDROID_SUPPORT) |
550 | /* Enable RTC */ | 559 | /* Enable RTC */ |
551 | writel(0x21, 0x30370038); | 560 | writel(0x21, 0x30370038); |
552 | #endif | 561 | #endif |
553 | 562 | ||
554 | if (is_imx8mq()) { | 563 | if (is_imx8mq()) { |
555 | clock_enable(CCGR_OCOTP, 1); | 564 | clock_enable(CCGR_OCOTP, 1); |
556 | if (readl(&ocotp->ctrl) & 0x200) | 565 | if (readl(&ocotp->ctrl) & 0x200) |
557 | writel(0x200, &ocotp->ctrl_clr); | 566 | writel(0x200, &ocotp->ctrl_clr); |
558 | } | 567 | } |
559 | 568 | ||
560 | return 0; | 569 | return 0; |
561 | } | 570 | } |
562 | 571 | ||
563 | #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) | 572 | #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) |
564 | struct rom_api *g_rom_api = (struct rom_api *)0x980; | 573 | struct rom_api *g_rom_api = (struct rom_api *)0x980; |
565 | 574 | ||
566 | enum boot_device get_boot_device(void) | 575 | enum boot_device get_boot_device(void) |
567 | { | 576 | { |
568 | volatile gd_t *pgd = gd; | 577 | volatile gd_t *pgd = gd; |
569 | int ret; | 578 | int ret; |
570 | u32 boot; | 579 | u32 boot; |
571 | u16 boot_type; | 580 | u16 boot_type; |
572 | u8 boot_instance; | 581 | u8 boot_instance; |
573 | enum boot_device boot_dev = SD1_BOOT; | 582 | enum boot_device boot_dev = SD1_BOOT; |
574 | 583 | ||
575 | ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot, | 584 | ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot, |
576 | ((uintptr_t)&boot) ^ QUERY_BT_DEV); | 585 | ((uintptr_t)&boot) ^ QUERY_BT_DEV); |
577 | gd = pgd; | 586 | gd = pgd; |
578 | 587 | ||
579 | if (ret != ROM_API_OKAY) { | 588 | if (ret != ROM_API_OKAY) { |
580 | puts("ROMAPI: failure at query_boot_info\n"); | 589 | puts("ROMAPI: failure at query_boot_info\n"); |
581 | return -1; | 590 | return -1; |
582 | } | 591 | } |
583 | 592 | ||
584 | boot_type = boot >> 16; | 593 | boot_type = boot >> 16; |
585 | boot_instance = (boot >> 8) & 0xff; | 594 | boot_instance = (boot >> 8) & 0xff; |
586 | 595 | ||
587 | switch (boot_type) { | 596 | switch (boot_type) { |
588 | case BT_DEV_TYPE_SD: | 597 | case BT_DEV_TYPE_SD: |
589 | boot_dev = boot_instance + SD1_BOOT; | 598 | boot_dev = boot_instance + SD1_BOOT; |
590 | break; | 599 | break; |
591 | case BT_DEV_TYPE_MMC: | 600 | case BT_DEV_TYPE_MMC: |
592 | boot_dev = boot_instance + MMC1_BOOT; | 601 | boot_dev = boot_instance + MMC1_BOOT; |
593 | break; | 602 | break; |
594 | case BT_DEV_TYPE_NAND: | 603 | case BT_DEV_TYPE_NAND: |
595 | boot_dev = NAND_BOOT; | 604 | boot_dev = NAND_BOOT; |
596 | break; | 605 | break; |
597 | case BT_DEV_TYPE_FLEXSPINOR: | 606 | case BT_DEV_TYPE_FLEXSPINOR: |
598 | boot_dev = QSPI_BOOT; | 607 | boot_dev = QSPI_BOOT; |
599 | break; | 608 | break; |
600 | case BT_DEV_TYPE_USB: | 609 | case BT_DEV_TYPE_USB: |
601 | boot_dev = USB_BOOT; | 610 | boot_dev = USB_BOOT; |
602 | break; | 611 | break; |
603 | default: | 612 | default: |
604 | break; | 613 | break; |
605 | } | 614 | } |
606 | 615 | ||
607 | return boot_dev; | 616 | return boot_dev; |
608 | } | 617 | } |
609 | #endif | 618 | #endif |
610 | 619 | ||
611 | bool is_usb_boot(void) | 620 | bool is_usb_boot(void) |
612 | { | 621 | { |
613 | return get_boot_device() == USB_BOOT; | 622 | return get_boot_device() == USB_BOOT; |
614 | } | 623 | } |
615 | #ifdef CONFIG_SERIAL_TAG | 624 | #ifdef CONFIG_SERIAL_TAG |
616 | void get_board_serial(struct tag_serialnr *serialnr) | 625 | void get_board_serial(struct tag_serialnr *serialnr) |
617 | { | 626 | { |
618 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 627 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
619 | struct fuse_bank *bank = &ocotp->bank[0]; | 628 | struct fuse_bank *bank = &ocotp->bank[0]; |
620 | struct fuse_bank0_regs *fuse = | 629 | struct fuse_bank0_regs *fuse = |
621 | (struct fuse_bank0_regs *)bank->fuse_regs; | 630 | (struct fuse_bank0_regs *)bank->fuse_regs; |
622 | 631 | ||
623 | serialnr->low = fuse->uid_low; | 632 | serialnr->low = fuse->uid_low; |
624 | serialnr->high = fuse->uid_high; | 633 | serialnr->high = fuse->uid_high; |
625 | } | 634 | } |
626 | #endif | 635 | #endif |
627 | 636 | ||
628 | #ifdef CONFIG_OF_SYSTEM_SETUP | 637 | #ifdef CONFIG_OF_SYSTEM_SETUP |
629 | bool check_fdt_new_path(void *blob) | 638 | bool check_fdt_new_path(void *blob) |
630 | { | 639 | { |
631 | const char *soc_path = "/soc@0"; | 640 | const char *soc_path = "/soc@0"; |
632 | int nodeoff; | 641 | int nodeoff; |
633 | 642 | ||
634 | nodeoff = fdt_path_offset(blob, soc_path); | 643 | nodeoff = fdt_path_offset(blob, soc_path); |
635 | if (nodeoff < 0) { | 644 | if (nodeoff < 0) { |
636 | return false; | 645 | return false; |
637 | } | 646 | } |
638 | 647 | ||
639 | return true; | 648 | return true; |
640 | } | 649 | } |
641 | 650 | ||
642 | static int disable_fdt_nodes(void *blob, const char *nodes_path[], int size_array) | 651 | static int disable_fdt_nodes(void *blob, const char *nodes_path[], int size_array) |
643 | { | 652 | { |
644 | int i = 0; | 653 | int i = 0; |
645 | int rc; | 654 | int rc; |
646 | int nodeoff; | 655 | int nodeoff; |
647 | const char *status = "disabled"; | 656 | const char *status = "disabled"; |
648 | 657 | ||
649 | for (i = 0; i < size_array; i++) { | 658 | for (i = 0; i < size_array; i++) { |
650 | nodeoff = fdt_path_offset(blob, nodes_path[i]); | 659 | nodeoff = fdt_path_offset(blob, nodes_path[i]); |
651 | if (nodeoff < 0) | 660 | if (nodeoff < 0) |
652 | continue; /* Not found, skip it */ | 661 | continue; /* Not found, skip it */ |
653 | 662 | ||
654 | printf("Found %s node\n", nodes_path[i]); | 663 | printf("Found %s node\n", nodes_path[i]); |
655 | 664 | ||
656 | add_status: | 665 | add_status: |
657 | rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1); | 666 | rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1); |
658 | if (rc) { | 667 | if (rc) { |
659 | if (rc == -FDT_ERR_NOSPACE) { | 668 | if (rc == -FDT_ERR_NOSPACE) { |
660 | rc = fdt_increase_size(blob, 512); | 669 | rc = fdt_increase_size(blob, 512); |
661 | if (!rc) | 670 | if (!rc) |
662 | goto add_status; | 671 | goto add_status; |
663 | } | 672 | } |
664 | printf("Unable to update property %s:%s, err=%s\n", | 673 | printf("Unable to update property %s:%s, err=%s\n", |
665 | nodes_path[i], "status", fdt_strerror(rc)); | 674 | nodes_path[i], "status", fdt_strerror(rc)); |
666 | } else { | 675 | } else { |
667 | printf("Modify %s:%s disabled\n", | 676 | printf("Modify %s:%s disabled\n", |
668 | nodes_path[i], "status"); | 677 | nodes_path[i], "status"); |
669 | } | 678 | } |
670 | } | 679 | } |
671 | 680 | ||
672 | return 0; | 681 | return 0; |
673 | } | 682 | } |
674 | 683 | ||
675 | #ifdef CONFIG_IMX8MQ | 684 | #ifdef CONFIG_IMX8MQ |
676 | bool check_dcss_fused(void) | 685 | bool check_dcss_fused(void) |
677 | { | 686 | { |
678 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 687 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
679 | struct fuse_bank *bank = &ocotp->bank[1]; | 688 | struct fuse_bank *bank = &ocotp->bank[1]; |
680 | struct fuse_bank1_regs *fuse = | 689 | struct fuse_bank1_regs *fuse = |
681 | (struct fuse_bank1_regs *)bank->fuse_regs; | 690 | (struct fuse_bank1_regs *)bank->fuse_regs; |
682 | 691 | ||
683 | u32 value = readl(&fuse->tester4); | 692 | u32 value = readl(&fuse->tester4); |
684 | if (value & 0x4000000) | 693 | if (value & 0x4000000) |
685 | return true; | 694 | return true; |
686 | 695 | ||
687 | return false; | 696 | return false; |
688 | } | 697 | } |
689 | 698 | ||
690 | static int disable_mipi_dsi_nodes(void *blob) | 699 | static int disable_mipi_dsi_nodes(void *blob) |
691 | { | 700 | { |
692 | const char *nodes_path[] = { | 701 | const char *nodes_path[] = { |
693 | "/mipi_dsi@30A00000", | 702 | "/mipi_dsi@30A00000", |
694 | "/mipi_dsi_bridge@30A00000", | 703 | "/mipi_dsi_bridge@30A00000", |
695 | "/dsi_phy@30A00300", | 704 | "/dsi_phy@30A00300", |
696 | "/soc@0/bus@30800000/mipi_dsi@30a00000", | 705 | "/soc@0/bus@30800000/mipi_dsi@30a00000", |
697 | "/soc@0/bus@30800000/dphy@30a00300" | 706 | "/soc@0/bus@30800000/dphy@30a00300" |
698 | "/soc@0/bus@30800000/mipi-dsi@30a00000", | 707 | "/soc@0/bus@30800000/mipi-dsi@30a00000", |
699 | }; | 708 | }; |
700 | 709 | ||
701 | return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); | 710 | return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); |
702 | } | 711 | } |
703 | 712 | ||
704 | static int disable_dcss_nodes(void *blob) | 713 | static int disable_dcss_nodes(void *blob) |
705 | { | 714 | { |
706 | const char *nodes_path[] = { | 715 | const char *nodes_path[] = { |
707 | "/dcss@0x32e00000", | 716 | "/dcss@0x32e00000", |
708 | "/dcss@32e00000", | 717 | "/dcss@32e00000", |
709 | "/hdmi@32c00000", | 718 | "/hdmi@32c00000", |
710 | "/hdmi_cec@32c33800", | 719 | "/hdmi_cec@32c33800", |
711 | "/hdmi_drm@32c00000", | 720 | "/hdmi_drm@32c00000", |
712 | "/display-subsystem", | 721 | "/display-subsystem", |
713 | "/sound-hdmi", | 722 | "/sound-hdmi", |
714 | "/sound-hdmi-arc", | 723 | "/sound-hdmi-arc", |
715 | "/soc@0/bus@32c00000/display-controller@32e00000", | 724 | "/soc@0/bus@32c00000/display-controller@32e00000", |
716 | "/soc@0/bus@32c00000/hdmi@32c00000", | 725 | "/soc@0/bus@32c00000/hdmi@32c00000", |
717 | }; | 726 | }; |
718 | 727 | ||
719 | return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); | 728 | return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); |
720 | } | 729 | } |
721 | 730 | ||
722 | static int check_mipi_dsi_nodes(void *blob) | 731 | static int check_mipi_dsi_nodes(void *blob) |
723 | { | 732 | { |
724 | const char *lcdif_path[] = { | 733 | const char *lcdif_path[] = { |
725 | "/lcdif@30320000", | 734 | "/lcdif@30320000", |
726 | "/soc@0/bus@30000000/lcdif@30320000", | 735 | "/soc@0/bus@30000000/lcdif@30320000", |
727 | "/soc@0/bus@30000000/lcd-controller@30320000" | 736 | "/soc@0/bus@30000000/lcd-controller@30320000" |
728 | }; | 737 | }; |
729 | const char *mipi_dsi_path[] = { | 738 | const char *mipi_dsi_path[] = { |
730 | "/mipi_dsi@30A00000", | 739 | "/mipi_dsi@30A00000", |
731 | "/soc@0/bus@30800000/mipi_dsi@30a00000" | 740 | "/soc@0/bus@30800000/mipi_dsi@30a00000" |
732 | }; | 741 | }; |
733 | const char *lcdif_ep_path[] = { | 742 | const char *lcdif_ep_path[] = { |
734 | "/lcdif@30320000/port@0/mipi-dsi-endpoint", | 743 | "/lcdif@30320000/port@0/mipi-dsi-endpoint", |
735 | "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint", | 744 | "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint", |
736 | "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint" | 745 | "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint" |
737 | }; | 746 | }; |
738 | const char *mipi_dsi_ep_path[] = { | 747 | const char *mipi_dsi_ep_path[] = { |
739 | "/mipi_dsi@30A00000/port@1/endpoint", | 748 | "/mipi_dsi@30A00000/port@1/endpoint", |
740 | "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint", | 749 | "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint", |
741 | "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0" | 750 | "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0" |
742 | }; | 751 | }; |
743 | 752 | ||
744 | int nodeoff; | 753 | int nodeoff; |
745 | bool new_path = check_fdt_new_path(blob); | 754 | bool new_path = check_fdt_new_path(blob); |
746 | int i = new_path? 1 : 0; | 755 | int i = new_path? 1 : 0; |
747 | 756 | ||
748 | nodeoff = fdt_path_offset(blob, lcdif_path[i]); | 757 | nodeoff = fdt_path_offset(blob, lcdif_path[i]); |
749 | if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) { | 758 | if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) { |
750 | /* If can't find lcdif node or lcdif node is disabled, then disable all mipi dsi, | 759 | /* If can't find lcdif node or lcdif node is disabled, then disable all mipi dsi, |
751 | since they only can input from DCSS */ | 760 | since they only can input from DCSS */ |
752 | return disable_mipi_dsi_nodes(blob); | 761 | return disable_mipi_dsi_nodes(blob); |
753 | } | 762 | } |
754 | 763 | ||
755 | nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]); | 764 | nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]); |
756 | if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) | 765 | if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) |
757 | return 0; | 766 | return 0; |
758 | 767 | ||
759 | nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]); | 768 | nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]); |
760 | if (nodeoff < 0) { | 769 | if (nodeoff < 0) { |
761 | /* If can't find lcdif endpoint, then disable all mipi dsi, | 770 | /* If can't find lcdif endpoint, then disable all mipi dsi, |
762 | since they only can input from DCSS */ | 771 | since they only can input from DCSS */ |
763 | return disable_mipi_dsi_nodes(blob); | 772 | return disable_mipi_dsi_nodes(blob); |
764 | } else { | 773 | } else { |
765 | int lookup_node; | 774 | int lookup_node; |
766 | lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint"); | 775 | lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint"); |
767 | nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]); | 776 | nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]); |
768 | 777 | ||
769 | if (nodeoff >0 && nodeoff == lookup_node) | 778 | if (nodeoff >0 && nodeoff == lookup_node) |
770 | return 0; | 779 | return 0; |
771 | 780 | ||
772 | return disable_mipi_dsi_nodes(blob); | 781 | return disable_mipi_dsi_nodes(blob); |
773 | } | 782 | } |
774 | 783 | ||
775 | } | 784 | } |
776 | #endif | 785 | #endif |
777 | 786 | ||
778 | void board_quiesce_devices(void) | 787 | void board_quiesce_devices(void) |
779 | { | 788 | { |
780 | #ifdef CONFIG_USB_DWC3 | 789 | #ifdef CONFIG_USB_DWC3 |
781 | if (is_usb_boot()) | 790 | if (is_usb_boot()) |
782 | disconnect_from_pc(); | 791 | disconnect_from_pc(); |
783 | #endif | 792 | #endif |
784 | } | 793 | } |
785 | 794 | ||
786 | int disable_vpu_nodes(void *blob) | 795 | int disable_vpu_nodes(void *blob) |
787 | { | 796 | { |
788 | const char *nodes_path_8mq[] = { | 797 | const char *nodes_path_8mq[] = { |
789 | "/vpu@38300000", | 798 | "/vpu@38300000", |
790 | "/soc@0/vpu@38300000" | 799 | "/soc@0/vpu@38300000" |
791 | }; | 800 | }; |
792 | 801 | ||
793 | const char *nodes_path_8mm[] = { | 802 | const char *nodes_path_8mm[] = { |
794 | "/vpu_g1@38300000", | 803 | "/vpu_g1@38300000", |
795 | "/vpu_g2@38310000", | 804 | "/vpu_g2@38310000", |
796 | "/vpu_h1@38320000" | 805 | "/vpu_h1@38320000" |
797 | }; | 806 | }; |
798 | 807 | ||
799 | const char *nodes_path_8mp[] = { | 808 | const char *nodes_path_8mp[] = { |
800 | "/vpu_g1@38300000", | 809 | "/vpu_g1@38300000", |
801 | "/vpu_g2@38310000", | 810 | "/vpu_g2@38310000", |
802 | "/vpu_vc8000e@38320000" | 811 | "/vpu_vc8000e@38320000" |
803 | }; | 812 | }; |
804 | 813 | ||
805 | if (is_imx8mq()) | 814 | if (is_imx8mq()) |
806 | return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq)); | 815 | return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq)); |
807 | else if (is_imx8mm()) | 816 | else if (is_imx8mm()) |
808 | return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm)); | 817 | return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm)); |
809 | else if (is_imx8mp()) | 818 | else if (is_imx8mp()) |
810 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); | 819 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); |
811 | else | 820 | else |
812 | return -EPERM; | 821 | return -EPERM; |
813 | 822 | ||
814 | } | 823 | } |
815 | 824 | ||
816 | #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE | 825 | #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE |
817 | static int low_drive_gpu_freq(void *blob) | 826 | static int low_drive_gpu_freq(void *blob) |
818 | { | 827 | { |
819 | const char *nodes_path_8mn[] = { | 828 | const char *nodes_path_8mn[] = { |
820 | "/gpu@38000000", | 829 | "/gpu@38000000", |
821 | "/soc@0/gpu@38000000" | 830 | "/soc@0/gpu@38000000" |
822 | }; | 831 | }; |
823 | 832 | ||
824 | int nodeoff, cnt, i, j; | 833 | int nodeoff, cnt, i, j; |
825 | u32 assignedclks[7]; | 834 | u32 assignedclks[7]; |
826 | 835 | ||
827 | for (i = 0; i < ARRAY_SIZE(nodes_path_8mn); i++) { | 836 | for (i = 0; i < ARRAY_SIZE(nodes_path_8mn); i++) { |
828 | nodeoff = fdt_path_offset(blob, nodes_path_8mn[i]); | 837 | nodeoff = fdt_path_offset(blob, nodes_path_8mn[i]); |
829 | if (nodeoff < 0) | 838 | if (nodeoff < 0) |
830 | continue; | 839 | continue; |
831 | 840 | ||
832 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7); | 841 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7); |
833 | if (cnt < 0) | 842 | if (cnt < 0) |
834 | return cnt; | 843 | return cnt; |
835 | 844 | ||
836 | if (cnt != 7) | 845 | if (cnt != 7) |
837 | printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[i], cnt); | 846 | printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[i], cnt); |
838 | 847 | ||
839 | assignedclks[cnt - 1] = 200000000; | 848 | assignedclks[cnt - 1] = 200000000; |
840 | assignedclks[cnt - 2] = 200000000; | 849 | assignedclks[cnt - 2] = 200000000; |
841 | 850 | ||
842 | for (j = 0; j < cnt; j++) { | 851 | for (j = 0; j < cnt; j++) { |
843 | debug("<%u>, ", assignedclks[j]); | 852 | debug("<%u>, ", assignedclks[j]); |
844 | assignedclks[j] = cpu_to_fdt32(assignedclks[j]); | 853 | assignedclks[j] = cpu_to_fdt32(assignedclks[j]); |
845 | } | 854 | } |
846 | debug("\n"); | 855 | debug("\n"); |
847 | 856 | ||
848 | return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks)); | 857 | return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks)); |
849 | } | 858 | } |
850 | 859 | ||
851 | return -ENOENT; | 860 | return -ENOENT; |
852 | } | 861 | } |
853 | #endif | 862 | #endif |
854 | 863 | ||
855 | int disable_gpu_nodes(void *blob) | 864 | int disable_gpu_nodes(void *blob) |
856 | { | 865 | { |
857 | const char *nodes_path_8mn[] = { | 866 | const char *nodes_path_8mn[] = { |
858 | "/gpu@38000000", | 867 | "/gpu@38000000", |
859 | "/soc@/gpu@38000000" | 868 | "/soc@/gpu@38000000" |
860 | }; | 869 | }; |
861 | 870 | ||
862 | return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn)); | 871 | return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn)); |
863 | } | 872 | } |
864 | 873 | ||
865 | int disable_npu_nodes(void *blob) | 874 | int disable_npu_nodes(void *blob) |
866 | { | 875 | { |
867 | const char *nodes_path_8mp[] = { | 876 | const char *nodes_path_8mp[] = { |
868 | "/vipsi@38500000" | 877 | "/vipsi@38500000" |
869 | }; | 878 | }; |
870 | 879 | ||
871 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); | 880 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); |
872 | } | 881 | } |
873 | 882 | ||
874 | int disable_isp_nodes(void *blob) | 883 | int disable_isp_nodes(void *blob) |
875 | { | 884 | { |
876 | const char *nodes_path_8mp[] = { | 885 | const char *nodes_path_8mp[] = { |
877 | "/soc@0/bus@32c00000/camera/isp@32e10000", | 886 | "/soc@0/bus@32c00000/camera/isp@32e10000", |
878 | "/soc@0/bus@32c00000/camera/isp@32e20000" | 887 | "/soc@0/bus@32c00000/camera/isp@32e20000" |
879 | }; | 888 | }; |
880 | 889 | ||
881 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); | 890 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); |
882 | } | 891 | } |
883 | 892 | ||
884 | int disable_dsp_nodes(void *blob) | 893 | int disable_dsp_nodes(void *blob) |
885 | { | 894 | { |
886 | const char *nodes_path_8mp[] = { | 895 | const char *nodes_path_8mp[] = { |
887 | "/dsp@3b6e8000" | 896 | "/dsp@3b6e8000" |
888 | }; | 897 | }; |
889 | 898 | ||
890 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); | 899 | return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); |
891 | } | 900 | } |
892 | 901 | ||
893 | static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores) | 902 | static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores) |
894 | { | 903 | { |
895 | const char *thermal_path[] = { | 904 | const char *thermal_path[] = { |
896 | "/thermal-zones/cpu-thermal/cooling-maps/map0" | 905 | "/thermal-zones/cpu-thermal/cooling-maps/map0" |
897 | }; | 906 | }; |
898 | 907 | ||
899 | int nodeoff, cnt, i, ret, j; | 908 | int nodeoff, cnt, i, ret, j; |
900 | u32 cooling_dev[12]; | 909 | u32 cooling_dev[12]; |
901 | 910 | ||
902 | for (i = 0; i < ARRAY_SIZE(thermal_path); i++) { | 911 | for (i = 0; i < ARRAY_SIZE(thermal_path); i++) { |
903 | nodeoff = fdt_path_offset(blob, thermal_path[i]); | 912 | nodeoff = fdt_path_offset(blob, thermal_path[i]); |
904 | if (nodeoff < 0) | 913 | if (nodeoff < 0) |
905 | continue; /* Not found, skip it */ | 914 | continue; /* Not found, skip it */ |
906 | 915 | ||
907 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12); | 916 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12); |
908 | if (cnt < 0) | 917 | if (cnt < 0) |
909 | continue; | 918 | continue; |
910 | 919 | ||
911 | if (cnt != 12) | 920 | if (cnt != 12) |
912 | printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt); | 921 | printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt); |
913 | 922 | ||
914 | for (j = 0; j < cnt; j++) { | 923 | for (j = 0; j < cnt; j++) { |
915 | cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]); | 924 | cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]); |
916 | } | 925 | } |
917 | 926 | ||
918 | ret= fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev, sizeof(u32) * (12 - disabled_cores * 3)); | 927 | ret= fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev, sizeof(u32) * (12 - disabled_cores * 3)); |
919 | if (ret < 0) { | 928 | if (ret < 0) { |
920 | printf("Warning: %s, cooling-device setprop failed %d\n", thermal_path[i], ret); | 929 | printf("Warning: %s, cooling-device setprop failed %d\n", thermal_path[i], ret); |
921 | continue; | 930 | continue; |
922 | } | 931 | } |
923 | 932 | ||
924 | printf("Update node %s, cooling-device prop\n", thermal_path[i]); | 933 | printf("Update node %s, cooling-device prop\n", thermal_path[i]); |
925 | } | 934 | } |
926 | } | 935 | } |
927 | 936 | ||
928 | static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores) | 937 | static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores) |
929 | { | 938 | { |
930 | const char *pmu_path[] = { | 939 | const char *pmu_path[] = { |
931 | "/pmu" | 940 | "/pmu" |
932 | }; | 941 | }; |
933 | 942 | ||
934 | int nodeoff, cnt, i, ret, j; | 943 | int nodeoff, cnt, i, ret, j; |
935 | u32 irq_affinity[4]; | 944 | u32 irq_affinity[4]; |
936 | 945 | ||
937 | for (i = 0; i < ARRAY_SIZE(pmu_path); i++) { | 946 | for (i = 0; i < ARRAY_SIZE(pmu_path); i++) { |
938 | nodeoff = fdt_path_offset(blob, pmu_path[i]); | 947 | nodeoff = fdt_path_offset(blob, pmu_path[i]); |
939 | if (nodeoff < 0) | 948 | if (nodeoff < 0) |
940 | continue; /* Not found, skip it */ | 949 | continue; /* Not found, skip it */ |
941 | 950 | ||
942 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity", irq_affinity, 4); | 951 | cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity", irq_affinity, 4); |
943 | if (cnt < 0) | 952 | if (cnt < 0) |
944 | continue; | 953 | continue; |
945 | 954 | ||
946 | if (cnt != 4) | 955 | if (cnt != 4) |
947 | printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt); | 956 | printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt); |
948 | 957 | ||
949 | for (j = 0; j < cnt; j++) { | 958 | for (j = 0; j < cnt; j++) { |
950 | irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]); | 959 | irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]); |
951 | } | 960 | } |
952 | 961 | ||
953 | ret= fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity, sizeof(u32) * (4 - disabled_cores)); | 962 | ret= fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity, sizeof(u32) * (4 - disabled_cores)); |
954 | if (ret < 0) { | 963 | if (ret < 0) { |
955 | printf("Warning: %s, interrupt-affinity setprop failed %d\n", pmu_path[i], ret); | 964 | printf("Warning: %s, interrupt-affinity setprop failed %d\n", pmu_path[i], ret); |
956 | continue; | 965 | continue; |
957 | } | 966 | } |
958 | 967 | ||
959 | printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]); | 968 | printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]); |
960 | } | 969 | } |
961 | } | 970 | } |
962 | 971 | ||
963 | static int disable_cpu_nodes(void *blob, u32 disabled_cores) | 972 | static int disable_cpu_nodes(void *blob, u32 disabled_cores) |
964 | { | 973 | { |
965 | const char *nodes_path[] = { | 974 | const char *nodes_path[] = { |
966 | "/cpus/cpu@1", | 975 | "/cpus/cpu@1", |
967 | "/cpus/cpu@2", | 976 | "/cpus/cpu@2", |
968 | "/cpus/cpu@3", | 977 | "/cpus/cpu@3", |
969 | }; | 978 | }; |
970 | 979 | ||
971 | u32 i = 0; | 980 | u32 i = 0; |
972 | int rc; | 981 | int rc; |
973 | int nodeoff; | 982 | int nodeoff; |
974 | 983 | ||
975 | if (disabled_cores > 3) | 984 | if (disabled_cores > 3) |
976 | return -EINVAL; | 985 | return -EINVAL; |
977 | 986 | ||
978 | i = 3 - disabled_cores; | 987 | i = 3 - disabled_cores; |
979 | 988 | ||
980 | for (; i < 3; i++) { | 989 | for (; i < 3; i++) { |
981 | nodeoff = fdt_path_offset(blob, nodes_path[i]); | 990 | nodeoff = fdt_path_offset(blob, nodes_path[i]); |
982 | if (nodeoff < 0) | 991 | if (nodeoff < 0) |
983 | continue; /* Not found, skip it */ | 992 | continue; /* Not found, skip it */ |
984 | 993 | ||
985 | printf("Found %s node\n", nodes_path[i]); | 994 | printf("Found %s node\n", nodes_path[i]); |
986 | 995 | ||
987 | rc = fdt_del_node(blob, nodeoff); | 996 | rc = fdt_del_node(blob, nodeoff); |
988 | if (rc < 0) { | 997 | if (rc < 0) { |
989 | printf("Unable to delete node %s, err=%s\n", | 998 | printf("Unable to delete node %s, err=%s\n", |
990 | nodes_path[i], fdt_strerror(rc)); | 999 | nodes_path[i], fdt_strerror(rc)); |
991 | } else { | 1000 | } else { |
992 | printf("Delete node %s\n", nodes_path[i]); | 1001 | printf("Delete node %s\n", nodes_path[i]); |
993 | } | 1002 | } |
994 | } | 1003 | } |
995 | 1004 | ||
996 | disable_thermal_cpu_nodes(blob, disabled_cores); | 1005 | disable_thermal_cpu_nodes(blob, disabled_cores); |
997 | disable_pmu_cpu_nodes(blob, disabled_cores); | 1006 | disable_pmu_cpu_nodes(blob, disabled_cores); |
998 | 1007 | ||
999 | return 0; | 1008 | return 0; |
1000 | } | 1009 | } |
1001 | 1010 | ||
1002 | int ft_system_setup(void *blob, bd_t *bd) | 1011 | int ft_system_setup(void *blob, bd_t *bd) |
1003 | { | 1012 | { |
1004 | #ifdef CONFIG_IMX8MQ | 1013 | #ifdef CONFIG_IMX8MQ |
1005 | int i = 0; | 1014 | int i = 0; |
1006 | int rc; | 1015 | int rc; |
1007 | int nodeoff; | 1016 | int nodeoff; |
1008 | 1017 | ||
1009 | if (get_boot_device() == USB_BOOT) { | 1018 | if (get_boot_device() == USB_BOOT) { |
1010 | 1019 | ||
1011 | disable_dcss_nodes(blob); | 1020 | disable_dcss_nodes(blob); |
1012 | 1021 | ||
1013 | bool new_path = check_fdt_new_path(blob); | 1022 | bool new_path = check_fdt_new_path(blob); |
1014 | int v = new_path? 1 : 0; | 1023 | int v = new_path? 1 : 0; |
1015 | const char *usb_dwc3_path[] = { | 1024 | const char *usb_dwc3_path[] = { |
1016 | "/usb@38100000/dwc3", | 1025 | "/usb@38100000/dwc3", |
1017 | "/soc@0/usb@38100000" | 1026 | "/soc@0/usb@38100000" |
1018 | }; | 1027 | }; |
1019 | 1028 | ||
1020 | nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]); | 1029 | nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]); |
1021 | if (nodeoff >= 0) { | 1030 | if (nodeoff >= 0) { |
1022 | const char *speed = "high-speed"; | 1031 | const char *speed = "high-speed"; |
1023 | printf("Found %s node\n", usb_dwc3_path[v]); | 1032 | printf("Found %s node\n", usb_dwc3_path[v]); |
1024 | 1033 | ||
1025 | usb_modify_speed: | 1034 | usb_modify_speed: |
1026 | 1035 | ||
1027 | rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1); | 1036 | rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1); |
1028 | if (rc) { | 1037 | if (rc) { |
1029 | if (rc == -FDT_ERR_NOSPACE) { | 1038 | if (rc == -FDT_ERR_NOSPACE) { |
1030 | rc = fdt_increase_size(blob, 512); | 1039 | rc = fdt_increase_size(blob, 512); |
1031 | if (!rc) | 1040 | if (!rc) |
1032 | goto usb_modify_speed; | 1041 | goto usb_modify_speed; |
1033 | } | 1042 | } |
1034 | printf("Unable to set property %s:%s, err=%s\n", | 1043 | printf("Unable to set property %s:%s, err=%s\n", |
1035 | usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc)); | 1044 | usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc)); |
1036 | } else { | 1045 | } else { |
1037 | printf("Modify %s:%s = %s\n", | 1046 | printf("Modify %s:%s = %s\n", |
1038 | usb_dwc3_path[v], "maximum-speed", speed); | 1047 | usb_dwc3_path[v], "maximum-speed", speed); |
1039 | } | 1048 | } |
1040 | }else { | 1049 | }else { |
1041 | printf("Can't found %s node\n", usb_dwc3_path[v]); | 1050 | printf("Can't found %s node\n", usb_dwc3_path[v]); |
1042 | } | 1051 | } |
1043 | } | 1052 | } |
1044 | 1053 | ||
1045 | /* Disable the CPU idle for A0 chip since the HW does not support it */ | 1054 | /* Disable the CPU idle for A0 chip since the HW does not support it */ |
1046 | if (is_soc_rev(CHIP_REV_1_0)) { | 1055 | if (is_soc_rev(CHIP_REV_1_0)) { |
1047 | static const char * const nodes_path[] = { | 1056 | static const char * const nodes_path[] = { |
1048 | "/cpus/cpu@0", | 1057 | "/cpus/cpu@0", |
1049 | "/cpus/cpu@1", | 1058 | "/cpus/cpu@1", |
1050 | "/cpus/cpu@2", | 1059 | "/cpus/cpu@2", |
1051 | "/cpus/cpu@3", | 1060 | "/cpus/cpu@3", |
1052 | }; | 1061 | }; |
1053 | 1062 | ||
1054 | for (i = 0; i < ARRAY_SIZE(nodes_path); i++) { | 1063 | for (i = 0; i < ARRAY_SIZE(nodes_path); i++) { |
1055 | nodeoff = fdt_path_offset(blob, nodes_path[i]); | 1064 | nodeoff = fdt_path_offset(blob, nodes_path[i]); |
1056 | if (nodeoff < 0) | 1065 | if (nodeoff < 0) |
1057 | continue; /* Not found, skip it */ | 1066 | continue; /* Not found, skip it */ |
1058 | 1067 | ||
1059 | printf("Found %s node\n", nodes_path[i]); | 1068 | printf("Found %s node\n", nodes_path[i]); |
1060 | 1069 | ||
1061 | rc = fdt_delprop(blob, nodeoff, "cpu-idle-states"); | 1070 | rc = fdt_delprop(blob, nodeoff, "cpu-idle-states"); |
1062 | if (rc) { | 1071 | if (rc) { |
1063 | printf("Unable to update property %s:%s, err=%s\n", | 1072 | printf("Unable to update property %s:%s, err=%s\n", |
1064 | nodes_path[i], "status", fdt_strerror(rc)); | 1073 | nodes_path[i], "status", fdt_strerror(rc)); |
1065 | return rc; | 1074 | return rc; |
1066 | } | 1075 | } |
1067 | 1076 | ||
1068 | printf("Remove %s:%s\n", nodes_path[i], | 1077 | printf("Remove %s:%s\n", nodes_path[i], |
1069 | "cpu-idle-states"); | 1078 | "cpu-idle-states"); |
1070 | } | 1079 | } |
1071 | } | 1080 | } |
1072 | 1081 | ||
1073 | if (is_imx8mql()) { | 1082 | if (is_imx8mql()) { |
1074 | disable_vpu_nodes(blob); | 1083 | disable_vpu_nodes(blob); |
1075 | if (check_dcss_fused()) { | 1084 | if (check_dcss_fused()) { |
1076 | printf("DCSS is fused\n"); | 1085 | printf("DCSS is fused\n"); |
1077 | disable_dcss_nodes(blob); | 1086 | disable_dcss_nodes(blob); |
1078 | check_mipi_dsi_nodes(blob); | 1087 | check_mipi_dsi_nodes(blob); |
1079 | } | 1088 | } |
1080 | } | 1089 | } |
1081 | 1090 | ||
1082 | if (is_imx8md()) | 1091 | if (is_imx8md()) |
1083 | disable_cpu_nodes(blob, 2); | 1092 | disable_cpu_nodes(blob, 2); |
1084 | 1093 | ||
1085 | #elif defined(CONFIG_IMX8MM) | 1094 | #elif defined(CONFIG_IMX8MM) |
1086 | if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl()) | 1095 | if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl()) |
1087 | disable_vpu_nodes(blob); | 1096 | disable_vpu_nodes(blob); |
1088 | 1097 | ||
1089 | if (is_imx8mmd() || is_imx8mmdl()) | 1098 | if (is_imx8mmd() || is_imx8mmdl()) |
1090 | disable_cpu_nodes(blob, 2); | 1099 | disable_cpu_nodes(blob, 2); |
1091 | else if (is_imx8mms() || is_imx8mmsl()) | 1100 | else if (is_imx8mms() || is_imx8mmsl()) |
1092 | disable_cpu_nodes(blob, 3); | 1101 | disable_cpu_nodes(blob, 3); |
1093 | 1102 | ||
1094 | #elif defined(CONFIG_IMX8MN) | 1103 | #elif defined(CONFIG_IMX8MN) |
1095 | if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl()) | 1104 | if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl()) |
1096 | disable_gpu_nodes(blob); | 1105 | disable_gpu_nodes(blob); |
1097 | #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE | 1106 | #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE |
1098 | else { | 1107 | else { |
1099 | int ldm_gpu = low_drive_gpu_freq(blob); | 1108 | int ldm_gpu = low_drive_gpu_freq(blob); |
1100 | if (ldm_gpu < 0) | 1109 | if (ldm_gpu < 0) |
1101 | printf("Update GPU node assigned-clock-rates failed\n"); | 1110 | printf("Update GPU node assigned-clock-rates failed\n"); |
1102 | else | 1111 | else |
1103 | printf("Update GPU node assigned-clock-rates ok\n"); | 1112 | printf("Update GPU node assigned-clock-rates ok\n"); |
1104 | } | 1113 | } |
1105 | #endif | 1114 | #endif |
1106 | 1115 | ||
1107 | if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud()) | 1116 | if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud()) |
1108 | disable_cpu_nodes(blob, 2); | 1117 | disable_cpu_nodes(blob, 2); |
1109 | else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) | 1118 | else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) |
1110 | disable_cpu_nodes(blob, 3); | 1119 | disable_cpu_nodes(blob, 3); |
1111 | 1120 | ||
1112 | #elif defined(CONFIG_IMX8MP) | 1121 | #elif defined(CONFIG_IMX8MP) |
1113 | if (is_imx8mpl()) | 1122 | if (is_imx8mpl()) |
1114 | disable_vpu_nodes(blob); | 1123 | disable_vpu_nodes(blob); |
1115 | 1124 | ||
1116 | if (is_imx8mpl() || is_imx8mp6()) | 1125 | if (is_imx8mpl() || is_imx8mp6()) |
1117 | disable_npu_nodes(blob); | 1126 | disable_npu_nodes(blob); |
1118 | 1127 | ||
1119 | if (is_imx8mpl()) | 1128 | if (is_imx8mpl()) |
1120 | disable_isp_nodes(blob); | 1129 | disable_isp_nodes(blob); |
1121 | 1130 | ||
1122 | if (is_imx8mpl() || is_imx8mp6()) | 1131 | if (is_imx8mpl() || is_imx8mp6()) |
1123 | disable_dsp_nodes(blob); | 1132 | disable_dsp_nodes(blob); |
1124 | 1133 | ||
1125 | if (is_imx8mpd()) | 1134 | if (is_imx8mpd()) |
1126 | disable_cpu_nodes(blob, 2); | 1135 | disable_cpu_nodes(blob, 2); |
1127 | #endif | 1136 | #endif |
1128 | 1137 | ||
1129 | return ft_add_optee_node(blob, bd); | 1138 | return ft_add_optee_node(blob, bd); |
1130 | } | 1139 | } |
1131 | #endif | 1140 | #endif |
1132 | 1141 | ||
1133 | #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYSRESET) | 1142 | #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYSRESET) |
1134 | void reset_cpu(ulong addr) | 1143 | void reset_cpu(ulong addr) |
1135 | { | 1144 | { |
1136 | struct watchdog_regs *wdog = (struct watchdog_regs *)addr; | 1145 | struct watchdog_regs *wdog = (struct watchdog_regs *)addr; |
1137 | 1146 | ||
1138 | if (!addr) | 1147 | if (!addr) |
1139 | wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; | 1148 | wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; |
1140 | 1149 | ||
1141 | /* Clear WDA to trigger WDOG_B immediately */ | 1150 | /* Clear WDA to trigger WDOG_B immediately */ |
1142 | writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr); | 1151 | writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr); |
1143 | 1152 | ||
1144 | while (1) { | 1153 | while (1) { |
1145 | /* | 1154 | /* |
1146 | * spin for 1 second before timeout reset | 1155 | * spin for 1 second before timeout reset |
1147 | */ | 1156 | */ |
1148 | } | 1157 | } |
1149 | } | 1158 | } |
1150 | #endif | 1159 | #endif |
1151 | 1160 | ||
1152 | #if defined(CONFIG_ARCH_MISC_INIT) | 1161 | #if defined(CONFIG_ARCH_MISC_INIT) |
1153 | #define FSL_SIP_BUILDINFO 0xC2000003 | 1162 | #define FSL_SIP_BUILDINFO 0xC2000003 |
1154 | #define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 | 1163 | #define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 |
1155 | static void acquire_buildinfo(void) | 1164 | static void acquire_buildinfo(void) |
1156 | { | 1165 | { |
1157 | uint64_t atf_commit = 0; | 1166 | uint64_t atf_commit = 0; |
1158 | 1167 | ||
1159 | /* Get ARM Trusted Firmware commit id */ | 1168 | /* Get ARM Trusted Firmware commit id */ |
1160 | atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, | 1169 | atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, |
1161 | FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); | 1170 | FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); |
1162 | if (atf_commit == 0xffffffff) { | 1171 | if (atf_commit == 0xffffffff) { |
1163 | debug("ATF does not support build info\n"); | 1172 | debug("ATF does not support build info\n"); |
1164 | atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ | 1173 | atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ |
1165 | } | 1174 | } |
1166 | 1175 | ||
1167 | printf("\n BuildInfo:\n - ATF %s\n - %s\n\n", (char *)&atf_commit, | 1176 | printf("\n BuildInfo:\n - ATF %s\n - %s\n\n", (char *)&atf_commit, |
1168 | U_BOOT_VERSION); | 1177 | U_BOOT_VERSION); |
1169 | } | 1178 | } |
1170 | 1179 | ||
1171 | int arch_misc_init(void) | 1180 | int arch_misc_init(void) |
1172 | { | 1181 | { |
1173 | acquire_buildinfo(); | 1182 | acquire_buildinfo(); |
1174 | 1183 | ||
1175 | return 0; | 1184 | return 0; |
1176 | } | 1185 | } |
1177 | #endif | 1186 | #endif |
1178 | 1187 | ||
1179 | #define FSL_SIP_GPC 0xC2000000 | 1188 | #define FSL_SIP_GPC 0xC2000000 |
1180 | #define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03 | 1189 | #define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03 |
1181 | 1190 | ||
1182 | #ifdef CONFIG_SPL_BUILD | 1191 | #ifdef CONFIG_SPL_BUILD |
1183 | static uint32_t gpc_pu_m_core_offset[11] = { | 1192 | static uint32_t gpc_pu_m_core_offset[11] = { |
1184 | 0xc00, 0xc40, 0xc80, 0xcc0, | 1193 | 0xc00, 0xc40, 0xc80, 0xcc0, |
1185 | 0xdc0, 0xe00, 0xe40, 0xe80, | 1194 | 0xdc0, 0xe00, 0xe40, 0xe80, |
1186 | 0xec0, 0xf00, 0xf40, | 1195 | 0xec0, 0xf00, 0xf40, |
1187 | }; | 1196 | }; |
1188 | 1197 | ||
1189 | #define PGC_PCR 0 | 1198 | #define PGC_PCR 0 |
1190 | 1199 | ||
1191 | void imx_gpc_set_m_core_pgc(unsigned int offset, bool pdn) | 1200 | void imx_gpc_set_m_core_pgc(unsigned int offset, bool pdn) |
1192 | { | 1201 | { |
1193 | uint32_t val; | 1202 | uint32_t val; |
1194 | uintptr_t reg = GPC_BASE_ADDR + offset; | 1203 | uintptr_t reg = GPC_BASE_ADDR + offset; |
1195 | 1204 | ||
1196 | val = readl(reg); | 1205 | val = readl(reg); |
1197 | val &= ~(0x1 << PGC_PCR); | 1206 | val &= ~(0x1 << PGC_PCR); |
1198 | 1207 | ||
1199 | if(pdn) | 1208 | if(pdn) |
1200 | val |= 0x1 << PGC_PCR; | 1209 | val |= 0x1 << PGC_PCR; |
1201 | writel(val, reg); | 1210 | writel(val, reg); |
1202 | } | 1211 | } |
1203 | 1212 | ||
1204 | void imx8m_usb_power_domain(uint32_t domain_id, bool on) | 1213 | void imx8m_usb_power_domain(uint32_t domain_id, bool on) |
1205 | { | 1214 | { |
1206 | uint32_t val; | 1215 | uint32_t val; |
1207 | uintptr_t reg; | 1216 | uintptr_t reg; |
1208 | 1217 | ||
1209 | imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], true); | 1218 | imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], true); |
1210 | 1219 | ||
1211 | reg = GPC_BASE_ADDR + (on ? 0xf8 : 0x104); | 1220 | reg = GPC_BASE_ADDR + (on ? 0xf8 : 0x104); |
1212 | val = 1 << (domain_id > 3 ? (domain_id + 3) : domain_id); | 1221 | val = 1 << (domain_id > 3 ? (domain_id + 3) : domain_id); |
1213 | writel(val, reg); | 1222 | writel(val, reg); |
1214 | while (readl(reg) & val) | 1223 | while (readl(reg) & val) |
1215 | ; | 1224 | ; |
1216 | imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], false); | 1225 | imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], false); |
1217 | } | 1226 | } |
1218 | #endif | 1227 | #endif |
1219 | 1228 | ||
1220 | int imx8m_usb_power(int usb_id, bool on) | 1229 | int imx8m_usb_power(int usb_id, bool on) |
1221 | { | 1230 | { |
1222 | if (usb_id > 1) | 1231 | if (usb_id > 1) |
1223 | return -EINVAL; | 1232 | return -EINVAL; |
1224 | 1233 | ||
1225 | #ifdef CONFIG_SPL_BUILD | 1234 | #ifdef CONFIG_SPL_BUILD |
1226 | imx8m_usb_power_domain(2 + usb_id, on); | 1235 | imx8m_usb_power_domain(2 + usb_id, on); |
1227 | #else | 1236 | #else |
1228 | unsigned long ret; | 1237 | unsigned long ret; |
1229 | ret = call_imx_sip(FSL_SIP_GPC, | 1238 | ret = call_imx_sip(FSL_SIP_GPC, |
1230 | FSL_SIP_CONFIG_GPC_PM_DOMAIN, 2 + usb_id, on, 0); | 1239 | FSL_SIP_CONFIG_GPC_PM_DOMAIN, 2 + usb_id, on, 0); |
1231 | if (ret) | 1240 | if (ret) |
1232 | return -EPERM; | 1241 | return -EPERM; |
1233 | #endif | 1242 | #endif |
1234 | 1243 | ||
1235 | return 0; | 1244 | return 0; |
1236 | } | 1245 | } |
1237 | 1246 | ||
1238 | void nxp_tmu_arch_init(void *reg_base) | 1247 | void nxp_tmu_arch_init(void *reg_base) |
1239 | { | 1248 | { |
1240 | if (is_imx8mm() || is_imx8mn()) { | 1249 | if (is_imx8mm() || is_imx8mn()) { |
1241 | /* Load TCALIV and TASR from fuses */ | 1250 | /* Load TCALIV and TASR from fuses */ |
1242 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 1251 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
1243 | struct fuse_bank *bank = &ocotp->bank[3]; | 1252 | struct fuse_bank *bank = &ocotp->bank[3]; |
1244 | struct fuse_bank3_regs *fuse = | 1253 | struct fuse_bank3_regs *fuse = |
1245 | (struct fuse_bank3_regs *)bank->fuse_regs; | 1254 | (struct fuse_bank3_regs *)bank->fuse_regs; |
1246 | 1255 | ||
1247 | u32 tca_rt, tca_hr, tca_en; | 1256 | u32 tca_rt, tca_hr, tca_en; |
1248 | u32 buf_vref, buf_slope; | 1257 | u32 buf_vref, buf_slope; |
1249 | 1258 | ||
1250 | tca_rt = fuse->ana0 & 0xFF; | 1259 | tca_rt = fuse->ana0 & 0xFF; |
1251 | tca_hr = (fuse->ana0 & 0xFF00) >> 8; | 1260 | tca_hr = (fuse->ana0 & 0xFF00) >> 8; |
1252 | tca_en = (fuse->ana0 & 0x2000000) >> 25; | 1261 | tca_en = (fuse->ana0 & 0x2000000) >> 25; |
1253 | 1262 | ||
1254 | buf_vref = (fuse->ana0 & 0x1F00000) >> 20; | 1263 | buf_vref = (fuse->ana0 & 0x1F00000) >> 20; |
1255 | buf_slope = (fuse->ana0 & 0xF0000) >> 16; | 1264 | buf_slope = (fuse->ana0 & 0xF0000) >> 16; |
1256 | 1265 | ||
1257 | writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); | 1266 | writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); |
1258 | writel((tca_en << 31) |(tca_hr <<16) | tca_rt, (ulong)reg_base + 0x30); | 1267 | writel((tca_en << 31) |(tca_hr <<16) | tca_rt, (ulong)reg_base + 0x30); |
1259 | } | 1268 | } |
1260 | #ifdef CONFIG_IMX8MP | 1269 | #ifdef CONFIG_IMX8MP |
1261 | /* Load TCALIV0/1/m40 and TRIM from fuses */ | 1270 | /* Load TCALIV0/1/m40 and TRIM from fuses */ |
1262 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | 1271 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; |
1263 | struct fuse_bank *bank = &ocotp->bank[38]; | 1272 | struct fuse_bank *bank = &ocotp->bank[38]; |
1264 | struct fuse_bank38_regs *fuse = | 1273 | struct fuse_bank38_regs *fuse = |
1265 | (struct fuse_bank38_regs *)bank->fuse_regs; | 1274 | (struct fuse_bank38_regs *)bank->fuse_regs; |
1266 | 1275 | ||
1267 | struct fuse_bank *bank2 = &ocotp->bank[39]; | 1276 | struct fuse_bank *bank2 = &ocotp->bank[39]; |
1268 | struct fuse_bank39_regs *fuse2 = | 1277 | struct fuse_bank39_regs *fuse2 = |
1269 | (struct fuse_bank39_regs *)bank2->fuse_regs; | 1278 | (struct fuse_bank39_regs *)bank2->fuse_regs; |
1270 | 1279 | ||
1271 | u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr; | 1280 | u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr; |
1272 | u32 reg; | 1281 | u32 reg; |
1273 | u32 tca40[2], tca25[2], tca105[2]; | 1282 | u32 tca40[2], tca25[2], tca105[2]; |
1274 | 1283 | ||
1275 | /* For blank sample */ | 1284 | /* For blank sample */ |
1276 | if (!fuse->ana_trim2 && !fuse->ana_trim3 && | 1285 | if (!fuse->ana_trim2 && !fuse->ana_trim3 && |
1277 | !fuse->ana_trim4 && !fuse2->ana_trim5) { | 1286 | !fuse->ana_trim4 && !fuse2->ana_trim5) { |
1278 | /* Use a default 25C binary codes */ | 1287 | /* Use a default 25C binary codes */ |
1279 | tca25[0] = 1596; | 1288 | tca25[0] = 1596; |
1280 | tca25[1] = 1596; | 1289 | tca25[1] = 1596; |
1281 | writel(tca25[0], (ulong)reg_base + 0x30); | 1290 | writel(tca25[0], (ulong)reg_base + 0x30); |
1282 | writel(tca25[1], (ulong)reg_base + 0x34); | 1291 | writel(tca25[1], (ulong)reg_base + 0x34); |
1283 | return; | 1292 | return; |
1284 | } | 1293 | } |
1285 | 1294 | ||
1286 | buf_vref = (fuse->ana_trim2 & 0xc0) >> 6; | 1295 | buf_vref = (fuse->ana_trim2 & 0xc0) >> 6; |
1287 | buf_slope = (fuse->ana_trim2 & 0xF00) >> 8; | 1296 | buf_slope = (fuse->ana_trim2 & 0xF00) >> 8; |
1288 | bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12; | 1297 | bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12; |
1289 | bgr = (fuse->ana_trim2 & 0xF0000) >> 16; | 1298 | bgr = (fuse->ana_trim2 & 0xF0000) >> 16; |
1290 | vlsb = (fuse->ana_trim2 & 0xF00000) >> 20; | 1299 | vlsb = (fuse->ana_trim2 & 0xF00000) >> 20; |
1291 | writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); | 1300 | writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); |
1292 | 1301 | ||
1293 | reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | ( 1 << 7); | 1302 | reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | ( 1 << 7); |
1294 | writel(reg, (ulong)reg_base + 0x3c); | 1303 | writel(reg, (ulong)reg_base + 0x3c); |
1295 | 1304 | ||
1296 | tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16; | 1305 | tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16; |
1297 | tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28; | 1306 | tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28; |
1298 | tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4); | 1307 | tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4); |
1299 | tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8; | 1308 | tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8; |
1300 | tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20; | 1309 | tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20; |
1301 | tca25[1] = fuse2->ana_trim5 & 0xFFF; | 1310 | tca25[1] = fuse2->ana_trim5 & 0xFFF; |
1302 | tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12; | 1311 | tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12; |
1303 | 1312 | ||
1304 | /* use 25c for 1p calibration */ | 1313 | /* use 25c for 1p calibration */ |
1305 | writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30); | 1314 | writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30); |
1306 | writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34); | 1315 | writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34); |
1307 | writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38); | 1316 | writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38); |
1308 | #endif | 1317 | #endif |
1309 | } | 1318 | } |
1310 | 1319 | ||
1311 | #if defined(CONFIG_SPL_BUILD) | 1320 | #if defined(CONFIG_SPL_BUILD) |
1312 | #if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) | 1321 | #if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) |
1313 | bool serror_need_skip = true; | 1322 | bool serror_need_skip = true; |
1314 | void do_error(struct pt_regs *pt_regs, unsigned int esr) | 1323 | void do_error(struct pt_regs *pt_regs, unsigned int esr) |
1315 | { | 1324 | { |
1316 | /* If stack is still in ROM reserved OCRAM not switch to SPL, it is the ROM SError */ | 1325 | /* If stack is still in ROM reserved OCRAM not switch to SPL, it is the ROM SError */ |
1317 | ulong sp; | 1326 | ulong sp; |
1318 | asm volatile("mov %0, sp" : "=r"(sp) : ); | 1327 | asm volatile("mov %0, sp" : "=r"(sp) : ); |
1319 | 1328 | ||
1320 | if (serror_need_skip && | 1329 | if (serror_need_skip && |
1321 | sp < 0x910000 && sp >= 0x900000) { | 1330 | sp < 0x910000 && sp >= 0x900000) { |
1322 | 1331 | ||
1323 | /* Check for ERR050342, imx8mq HDCP enabled parts */ | 1332 | /* Check for ERR050342, imx8mq HDCP enabled parts */ |
1324 | if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) { | 1333 | if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) { |
1325 | serror_need_skip = false; | 1334 | serror_need_skip = false; |
1326 | return; /* Do nothing skip the SError in ROM */ | 1335 | return; /* Do nothing skip the SError in ROM */ |
1327 | } | 1336 | } |
1328 | 1337 | ||
1329 | /* Check for ERR050350, field return mode for imx8mq, mm and mn */ | 1338 | /* Check for ERR050350, field return mode for imx8mq, mm and mn */ |
1330 | if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) { | 1339 | if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) { |
1331 | serror_need_skip = false; | 1340 | serror_need_skip = false; |
1332 | return; /* Do nothing skip the SError in ROM */ | 1341 | return; /* Do nothing skip the SError in ROM */ |
1333 | } | 1342 | } |
1334 | } | 1343 | } |
1335 | 1344 | ||
1336 | efi_restore_gd(); | 1345 | efi_restore_gd(); |
1337 | printf("\"Error\" handler, esr 0x%08x\n", esr); | 1346 | printf("\"Error\" handler, esr 0x%08x\n", esr); |
1338 | show_regs(pt_regs); | 1347 | show_regs(pt_regs); |
1339 | panic("Resetting CPU ...\n"); | 1348 | panic("Resetting CPU ...\n"); |
1340 | 1349 | ||
1341 | } | 1350 | } |
1342 | #endif | 1351 | #endif |
1343 | #endif | 1352 | #endif |
1344 | 1353 | ||
1345 | #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) | 1354 | #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) |
1346 | enum env_location env_get_location(enum env_operation op, int prio) | 1355 | enum env_location env_get_location(enum env_operation op, int prio) |
1347 | { | 1356 | { |
1348 | enum boot_device dev = get_boot_device(); | 1357 | enum boot_device dev = get_boot_device(); |
1349 | enum env_location env_loc = ENVL_UNKNOWN; | 1358 | enum env_location env_loc = ENVL_UNKNOWN; |
1350 | 1359 | ||
1351 | if (prio) | 1360 | if (prio) |
1352 | return env_loc; | 1361 | return env_loc; |
1353 | 1362 | ||
1354 | switch (dev) { | 1363 | switch (dev) { |
1355 | #ifdef CONFIG_ENV_IS_IN_SPI_FLASH | 1364 | #ifdef CONFIG_ENV_IS_IN_SPI_FLASH |
1356 | case QSPI_BOOT: | 1365 | case QSPI_BOOT: |
1357 | env_loc = ENVL_SPI_FLASH; | 1366 | env_loc = ENVL_SPI_FLASH; |
1358 | break; | 1367 | break; |
1359 | #endif | 1368 | #endif |
1360 | #ifdef CONFIG_ENV_IS_IN_NAND | 1369 | #ifdef CONFIG_ENV_IS_IN_NAND |
1361 | case NAND_BOOT: | 1370 | case NAND_BOOT: |
1362 | env_loc = ENVL_NAND; | 1371 | env_loc = ENVL_NAND; |
1363 | break; | 1372 | break; |
1364 | #endif | 1373 | #endif |
1365 | #ifdef CONFIG_ENV_IS_IN_MMC | 1374 | #ifdef CONFIG_ENV_IS_IN_MMC |
1366 | case SD1_BOOT: | 1375 | case SD1_BOOT: |
1367 | case SD2_BOOT: | 1376 | case SD2_BOOT: |
1368 | case SD3_BOOT: | 1377 | case SD3_BOOT: |
1369 | case MMC1_BOOT: | 1378 | case MMC1_BOOT: |
1370 | case MMC2_BOOT: | 1379 | case MMC2_BOOT: |
1371 | case MMC3_BOOT: | 1380 | case MMC3_BOOT: |
1372 | env_loc = ENVL_MMC; | 1381 | env_loc = ENVL_MMC; |
1373 | break; | 1382 | break; |
1374 | #endif | 1383 | #endif |
1375 | default: | 1384 | default: |
1376 | #if defined(CONFIG_ENV_IS_NOWHERE) | 1385 | #if defined(CONFIG_ENV_IS_NOWHERE) |
1377 | env_loc = ENVL_NOWHERE; | 1386 | env_loc = ENVL_NOWHERE; |
1378 | #endif | 1387 | #endif |
1379 | break; | 1388 | break; |
1380 | } | 1389 | } |
1381 | 1390 | ||
1382 | return env_loc; | 1391 | return env_loc; |
1383 | } | 1392 | } |
1384 | 1393 | ||
1385 | #ifndef ENV_IS_EMBEDDED | 1394 | #ifndef ENV_IS_EMBEDDED |
1386 | long long env_get_offset(long long defautl_offset) | 1395 | long long env_get_offset(long long defautl_offset) |
1387 | { | 1396 | { |
1388 | enum boot_device dev = get_boot_device(); | 1397 | enum boot_device dev = get_boot_device(); |
1389 | 1398 | ||
1390 | switch (dev) { | 1399 | switch (dev) { |
1391 | case NAND_BOOT: | 1400 | case NAND_BOOT: |
1392 | return (60 << 20); /* 60MB offset for NAND */ | 1401 | return (60 << 20); /* 60MB offset for NAND */ |
1393 | default: | 1402 | default: |
1394 | break; | 1403 | break; |
1395 | } | 1404 | } |
1396 | 1405 | ||
1397 | return defautl_offset; | 1406 | return defautl_offset; |
1398 | } | 1407 | } |
1399 | #endif | 1408 | #endif |
1400 | #endif | 1409 | #endif |
1401 | 1410 | ||
1402 | #ifdef CONFIG_IMX8MQ | 1411 | #ifdef CONFIG_IMX8MQ |
1403 | int imx8m_dcss_power_init(void) | 1412 | int imx8m_dcss_power_init(void) |
1404 | { | 1413 | { |
1405 | /* Enable the display CCGR before power on */ | 1414 | /* Enable the display CCGR before power on */ |
1406 | clock_enable(CCGR_DISPLAY, 1); | 1415 | clock_enable(CCGR_DISPLAY, 1); |
1407 | 1416 | ||
1408 | writel(0x0000ffff, 0x303A00EC); /*PGC_CPU_MAPPING */ | 1417 | writel(0x0000ffff, 0x303A00EC); /*PGC_CPU_MAPPING */ |
1409 | setbits_le32(0x303A00F8, 0x1 << 10); /*PU_PGC_SW_PUP_REQ : disp was 10 */ | 1418 | setbits_le32(0x303A00F8, 0x1 << 10); /*PU_PGC_SW_PUP_REQ : disp was 10 */ |
1410 | 1419 | ||
1411 | return 0; | 1420 | return 0; |
1412 | } | 1421 | } |
1413 | #endif | 1422 | #endif |
1414 | 1423 |