xref: /optee_os/core/arch/arm/plat-imx/imx-common.c (revision 7194a0c620729ffcc2ecc1374ef8d3028d146b2e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2016 Freescale Semiconductor, Inc.
4  * Copyright 2017-2019, 2021 NXP
5  *
6  * Peng Fan <peng.fan@nxp.com>
7  */
8 
9 #include <config.h>
10 #include <console.h>
11 #include <io.h>
12 #include <imx.h>
13 #include <mm/core_mmu.h>
14 #include <mm/core_memprot.h>
15 #include <platform_config.h>
16 
17 #define SOC_TYPE(reg)	       (((reg) & (0x00FF0000)) >> 16)
18 #define SOC_REV_MAJOR(reg)     (((reg) & (0x0000FF00)) >> 8)
19 #define SOC_REV_MINOR(reg)     ((reg) & (0x0000000F))
20 #define SOC_REV_MINOR_MX7(reg) ((reg) & (0x000000FF))
21 
22 static uint32_t imx_digprog;
23 
24 #ifdef ANATOP_BASE
imx_get_digprog(void)25 uint32_t imx_get_digprog(void)
26 {
27 	vaddr_t addr = 0;
28 
29 	if (imx_digprog)
30 		return imx_digprog;
31 
32 	addr = core_mmu_get_va(ANATOP_BASE, MEM_AREA_IO_SEC, 0x1000);
33 	if (!addr)
34 		return 0;
35 
36 	imx_digprog = io_read32(addr + DIGPROG_OFFSET);
37 
38 #ifdef CFG_MX8MQ
39 	/*
40 	 * On the i.MX8MQ, the minor revision number must be updated to make
41 	 * the difference between B0 chip and the newer chips.
42 	 */
43 	addr = core_mmu_get_va(OCOTP_BASE, MEM_AREA_IO_SEC, OCOTP_SIZE);
44 	if (!addr)
45 		return 0;
46 
47 	if (io_read32(addr + OCOTP_SW_INFO_B1) == OCOTP_SW_MAGIC_B1)
48 		imx_digprog |= BIT32(0);
49 #endif /* CFG_MX8MQ */
50 
51 	return imx_digprog;
52 }
53 #else  /* ANATOP_BASE */
imx_get_digprog(void)54 uint32_t imx_get_digprog(void)
55 {
56 	if (imx_digprog)
57 		return imx_digprog;
58 
59 	if (IS_ENABLED(CFG_MX7ULP))
60 		imx_digprog = SOC_MX7ULP << 16;
61 	else if (IS_ENABLED(CFG_MX8QX))
62 		imx_digprog = SOC_MX8QX << 16;
63 	else if (IS_ENABLED(CFG_MX8QM))
64 		imx_digprog = SOC_MX8QM << 16;
65 	else if (IS_ENABLED(CFG_MX8DXL))
66 		imx_digprog = SOC_MX8DXL << 16;
67 	else if (IS_ENABLED(CFG_MX8ULP))
68 		imx_digprog = SOC_MX8ULP << 16;
69 	else if (IS_ENABLED(CFG_MX93))
70 		imx_digprog = SOC_MX93 << 16;
71 	else if (IS_ENABLED(CFG_MX91))
72 		imx_digprog = SOC_MX91 << 16;
73 	else if (IS_ENABLED(CFG_MX95))
74 		imx_digprog = SOC_MX95 << 16;
75 	else if (IS_ENABLED(CFG_MX943))
76 		imx_digprog = SOC_MX943 << 16;
77 
78 	return imx_digprog;
79 }
80 #endif /* ANATOP_BASE */
81 
imx_soc_rev_major(void)82 uint32_t imx_soc_rev_major(void)
83 {
84 	if (imx_digprog == 0)
85 		imx_get_digprog();
86 
87 	return SOC_REV_MAJOR(imx_digprog);
88 }
89 
imx_soc_rev_minor(void)90 uint32_t imx_soc_rev_minor(void)
91 {
92 	if (imx_digprog == 0)
93 		imx_get_digprog();
94 
95 	if (IS_ENABLED(CFG_MX7))
96 		return SOC_REV_MINOR_MX7(imx_digprog);
97 	else
98 		return SOC_REV_MINOR(imx_digprog);
99 }
100 
imx_soc_type(void)101 uint32_t imx_soc_type(void)
102 {
103 	if (imx_digprog == 0)
104 		imx_get_digprog();
105 
106 	return SOC_TYPE(imx_digprog);
107 }
108 
soc_is_imx6sl(void)109 bool soc_is_imx6sl(void)
110 {
111 	return imx_soc_type() == SOC_MX6SL;
112 }
113 
soc_is_imx6sll(void)114 bool soc_is_imx6sll(void)
115 {
116 	return imx_soc_type() == SOC_MX6SLL;
117 }
118 
soc_is_imx6sx(void)119 bool soc_is_imx6sx(void)
120 {
121 	return imx_soc_type() == SOC_MX6SX;
122 }
123 
soc_is_imx6ul(void)124 bool soc_is_imx6ul(void)
125 {
126 	return imx_soc_type() == SOC_MX6UL;
127 }
128 
soc_is_imx6ull(void)129 bool soc_is_imx6ull(void)
130 {
131 	return imx_soc_type() == SOC_MX6ULL;
132 }
133 
soc_is_imx6sdl(void)134 bool soc_is_imx6sdl(void)
135 {
136 	return imx_soc_type() == SOC_MX6DL;
137 }
138 
soc_is_imx6dq(void)139 bool soc_is_imx6dq(void)
140 {
141 	return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 0);
142 }
143 
soc_is_imx6dqp(void)144 bool soc_is_imx6dqp(void)
145 {
146 	return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 1);
147 }
148 
soc_is_imx6(void)149 bool soc_is_imx6(void)
150 {
151 	uint32_t soc = imx_soc_type();
152 
153 	return (soc == SOC_MX6SLL) || (soc == SOC_MX6SL) ||
154 	       (soc == SOC_MX6D) || (soc == SOC_MX6SX) ||
155 	       (soc == SOC_MX6UL) || (soc == SOC_MX6ULL) ||
156 	       (soc == SOC_MX6DL) || (soc == SOC_MX6Q);
157 }
158 
soc_is_imx7ds(void)159 bool soc_is_imx7ds(void)
160 {
161 	return imx_soc_type() == SOC_MX7D;
162 }
163 
soc_is_imx7ulp(void)164 bool soc_is_imx7ulp(void)
165 {
166 	return imx_soc_type() == SOC_MX7ULP;
167 }
168 
soc_is_imx8mq(void)169 bool soc_is_imx8mq(void)
170 {
171 	return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x40;
172 }
173 
soc_is_imx8mm(void)174 bool soc_is_imx8mm(void)
175 {
176 	return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x41;
177 }
178 
soc_is_imx8mn(void)179 bool soc_is_imx8mn(void)
180 {
181 	return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x42;
182 }
183 
soc_is_imx8mp(void)184 bool soc_is_imx8mp(void)
185 {
186 	return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x43;
187 }
188 
soc_is_imx8m(void)189 bool soc_is_imx8m(void)
190 {
191 	return soc_is_imx8mq() || soc_is_imx8mm() || soc_is_imx8mn() ||
192 	       soc_is_imx8mp();
193 }
194 
soc_is_imx8mq_b0_layer(void)195 bool soc_is_imx8mq_b0_layer(void)
196 {
197 	if (soc_is_imx8mq() && imx_soc_rev_minor() == 0x0)
198 		return true;
199 	else
200 		return false;
201 }
202