xref: /rk3399_ARM-atf/drivers/st/bsec/bsec3.c (revision ae6542f6c7ac9224843448424d3a539733bd651b)
1*ae6542f6SNicolas Le Bayon /*
2*ae6542f6SNicolas Le Bayon  * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
3*ae6542f6SNicolas Le Bayon  *
4*ae6542f6SNicolas Le Bayon  * SPDX-License-Identifier: BSD-3-Clause
5*ae6542f6SNicolas Le Bayon  */
6*ae6542f6SNicolas Le Bayon 
7*ae6542f6SNicolas Le Bayon #include <assert.h>
8*ae6542f6SNicolas Le Bayon #include <limits.h>
9*ae6542f6SNicolas Le Bayon 
10*ae6542f6SNicolas Le Bayon #include <arch_helpers.h>
11*ae6542f6SNicolas Le Bayon #include <common/debug.h>
12*ae6542f6SNicolas Le Bayon #include <drivers/st/bsec.h>
13*ae6542f6SNicolas Le Bayon #include <drivers/st/bsec3_reg.h>
14*ae6542f6SNicolas Le Bayon #include <drivers/st/stm32mp_reset.h>
15*ae6542f6SNicolas Le Bayon #include <lib/mmio.h>
16*ae6542f6SNicolas Le Bayon #include <lib/spinlock.h>
17*ae6542f6SNicolas Le Bayon #include <libfdt.h>
18*ae6542f6SNicolas Le Bayon 
19*ae6542f6SNicolas Le Bayon #include <platform_def.h>
20*ae6542f6SNicolas Le Bayon 
21*ae6542f6SNicolas Le Bayon #define BSEC_IP_VERSION_1_0	U(0x10)
22*ae6542f6SNicolas Le Bayon #define BSEC_IP_ID_3		U(0x100033)
23*ae6542f6SNicolas Le Bayon 
24*ae6542f6SNicolas Le Bayon #define MAX_NB_TRIES		U(3)
25*ae6542f6SNicolas Le Bayon 
26*ae6542f6SNicolas Le Bayon /*
27*ae6542f6SNicolas Le Bayon  * IP configuration
28*ae6542f6SNicolas Le Bayon  */
29*ae6542f6SNicolas Le Bayon #define BSEC_OTP_MASK			GENMASK_32(4, 0)
30*ae6542f6SNicolas Le Bayon #define BSEC_OTP_BANK_SHIFT		U(5)
31*ae6542f6SNicolas Le Bayon #define BSEC_TIMEOUT_VALUE		U(0x800000) /* ~7sec @1.2GHz */
32*ae6542f6SNicolas Le Bayon 
33*ae6542f6SNicolas Le Bayon /* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
34*ae6542f6SNicolas Le Bayon #define BSEC_MAGIC			U(0x42534543)
35*ae6542f6SNicolas Le Bayon 
36*ae6542f6SNicolas Le Bayon #define OTP_MAX_SIZE			(STM32MP2_OTP_MAX_ID + U(1))
37*ae6542f6SNicolas Le Bayon 
38*ae6542f6SNicolas Le Bayon struct bsec_shadow {
39*ae6542f6SNicolas Le Bayon 	uint32_t magic;
40*ae6542f6SNicolas Le Bayon 	uint32_t state;
41*ae6542f6SNicolas Le Bayon 	uint32_t value[OTP_MAX_SIZE];
42*ae6542f6SNicolas Le Bayon 	uint32_t status[OTP_MAX_SIZE];
43*ae6542f6SNicolas Le Bayon };
44*ae6542f6SNicolas Le Bayon 
45*ae6542f6SNicolas Le Bayon static uint32_t otp_bank(uint32_t otp)
46*ae6542f6SNicolas Le Bayon {
47*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
48*ae6542f6SNicolas Le Bayon 		panic();
49*ae6542f6SNicolas Le Bayon 	}
50*ae6542f6SNicolas Le Bayon 
51*ae6542f6SNicolas Le Bayon 	return (otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT;
52*ae6542f6SNicolas Le Bayon }
53*ae6542f6SNicolas Le Bayon 
54*ae6542f6SNicolas Le Bayon static uint32_t otp_bit_mask(uint32_t otp)
55*ae6542f6SNicolas Le Bayon {
56*ae6542f6SNicolas Le Bayon 	return BIT(otp & BSEC_OTP_MASK);
57*ae6542f6SNicolas Le Bayon }
58*ae6542f6SNicolas Le Bayon 
59*ae6542f6SNicolas Le Bayon /*
60*ae6542f6SNicolas Le Bayon  * bsec_get_status: return status register value.
61*ae6542f6SNicolas Le Bayon  */
62*ae6542f6SNicolas Le Bayon static uint32_t bsec_get_status(void)
63*ae6542f6SNicolas Le Bayon {
64*ae6542f6SNicolas Le Bayon 	return mmio_read_32(BSEC_BASE + BSEC_OTPSR);
65*ae6542f6SNicolas Le Bayon }
66*ae6542f6SNicolas Le Bayon 
67*ae6542f6SNicolas Le Bayon /*
68*ae6542f6SNicolas Le Bayon  * bsec_get_version: return BSEC version.
69*ae6542f6SNicolas Le Bayon  */
70*ae6542f6SNicolas Le Bayon static uint32_t bsec_get_version(void)
71*ae6542f6SNicolas Le Bayon {
72*ae6542f6SNicolas Le Bayon 	return mmio_read_32(BSEC_BASE + BSEC_VERR) & BSEC_VERR_MASK;
73*ae6542f6SNicolas Le Bayon }
74*ae6542f6SNicolas Le Bayon 
75*ae6542f6SNicolas Le Bayon /*
76*ae6542f6SNicolas Le Bayon  * bsec_get_id: return BSEC ID.
77*ae6542f6SNicolas Le Bayon  */
78*ae6542f6SNicolas Le Bayon static uint32_t bsec_get_id(void)
79*ae6542f6SNicolas Le Bayon {
80*ae6542f6SNicolas Le Bayon 	return mmio_read_32(BSEC_BASE + BSEC_IPIDR);
81*ae6542f6SNicolas Le Bayon }
82*ae6542f6SNicolas Le Bayon 
83*ae6542f6SNicolas Le Bayon static bool is_fuse_shadowed(uint32_t otp)
84*ae6542f6SNicolas Le Bayon {
85*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
86*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
87*ae6542f6SNicolas Le Bayon 	uint32_t bank_value;
88*ae6542f6SNicolas Le Bayon 
89*ae6542f6SNicolas Le Bayon 	bank_value = mmio_read_32(BSEC_BASE + BSEC_SFSR(bank));
90*ae6542f6SNicolas Le Bayon 
91*ae6542f6SNicolas Le Bayon 	if ((bank_value & otp_mask) != 0U) {
92*ae6542f6SNicolas Le Bayon 		return true;
93*ae6542f6SNicolas Le Bayon 	}
94*ae6542f6SNicolas Le Bayon 
95*ae6542f6SNicolas Le Bayon 	return false;
96*ae6542f6SNicolas Le Bayon }
97*ae6542f6SNicolas Le Bayon 
98*ae6542f6SNicolas Le Bayon static void poll_otp_status_busy(void)
99*ae6542f6SNicolas Le Bayon {
100*ae6542f6SNicolas Le Bayon 	uint32_t timeout = BSEC_TIMEOUT_VALUE;
101*ae6542f6SNicolas Le Bayon 
102*ae6542f6SNicolas Le Bayon 	while (((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) && (timeout != 0U)) {
103*ae6542f6SNicolas Le Bayon 		timeout--;
104*ae6542f6SNicolas Le Bayon 	}
105*ae6542f6SNicolas Le Bayon 
106*ae6542f6SNicolas Le Bayon 	if ((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) {
107*ae6542f6SNicolas Le Bayon 		ERROR("BSEC timeout\n");
108*ae6542f6SNicolas Le Bayon 		panic();
109*ae6542f6SNicolas Le Bayon 	}
110*ae6542f6SNicolas Le Bayon }
111*ae6542f6SNicolas Le Bayon 
112*ae6542f6SNicolas Le Bayon static uint32_t check_read_error(uint32_t otp)
113*ae6542f6SNicolas Le Bayon {
114*ae6542f6SNicolas Le Bayon 	uint32_t status = bsec_get_status();
115*ae6542f6SNicolas Le Bayon 
116*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_SECF) != 0U) {
117*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC read %u single error correction detected\n", otp);
118*ae6542f6SNicolas Le Bayon 	}
119*ae6542f6SNicolas Le Bayon 
120*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_PPLF) != 0U) {
121*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC read %u permanent programming lock detected.\n", otp);
122*ae6542f6SNicolas Le Bayon 	}
123*ae6542f6SNicolas Le Bayon 
124*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_PPLMF) != 0U) {
125*ae6542f6SNicolas Le Bayon 		ERROR("BSEC read %u error 0x%x\n", otp, status);
126*ae6542f6SNicolas Le Bayon 		return BSEC_ERROR;
127*ae6542f6SNicolas Le Bayon 	}
128*ae6542f6SNicolas Le Bayon 
129*ae6542f6SNicolas Le Bayon 	if ((status & (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)) != 0U) {
130*ae6542f6SNicolas Le Bayon 		ERROR("BSEC read %u error 0x%x with invalid FVR\n", otp, status);
131*ae6542f6SNicolas Le Bayon 		return BSEC_RETRY;
132*ae6542f6SNicolas Le Bayon 	}
133*ae6542f6SNicolas Le Bayon 
134*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
135*ae6542f6SNicolas Le Bayon }
136*ae6542f6SNicolas Le Bayon 
137*ae6542f6SNicolas Le Bayon static uint32_t check_program_error(uint32_t otp)
138*ae6542f6SNicolas Le Bayon {
139*ae6542f6SNicolas Le Bayon 	uint32_t status = bsec_get_status();
140*ae6542f6SNicolas Le Bayon 
141*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_PROGFAIL) != 0U) {
142*ae6542f6SNicolas Le Bayon 		ERROR("BSEC program %u error 0x%x\n", otp, status);
143*ae6542f6SNicolas Le Bayon 		return BSEC_RETRY;
144*ae6542f6SNicolas Le Bayon 	}
145*ae6542f6SNicolas Le Bayon 
146*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
147*ae6542f6SNicolas Le Bayon }
148*ae6542f6SNicolas Le Bayon 
149*ae6542f6SNicolas Le Bayon static void check_reset_error(void)
150*ae6542f6SNicolas Le Bayon {
151*ae6542f6SNicolas Le Bayon 	uint32_t status = bsec_get_status();
152*ae6542f6SNicolas Le Bayon 
153*ae6542f6SNicolas Le Bayon 	/* check initial status reporting */
154*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_BUSY) != 0U) {
155*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC reset and busy when OTPSR read\n");
156*ae6542f6SNicolas Le Bayon 	}
157*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_HIDEUP) != 0U) {
158*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC upper fuse are not accessible (HIDEUP)\n");
159*ae6542f6SNicolas Le Bayon 	}
160*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_OTPSEC) != 0U) {
161*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC reset single error correction detected\n");
162*ae6542f6SNicolas Le Bayon 	}
163*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_OTPNVIR) == 0U) {
164*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC reset first fuse word 0 is detected zero\n");
165*ae6542f6SNicolas Le Bayon 	}
166*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_OTPERR) != 0U) {
167*ae6542f6SNicolas Le Bayon 		ERROR("BSEC reset critical error 0x%x\n", status);
168*ae6542f6SNicolas Le Bayon 		panic();
169*ae6542f6SNicolas Le Bayon 	}
170*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
171*ae6542f6SNicolas Le Bayon 		ERROR("BSEC reset critical error 0x%x\n", status);
172*ae6542f6SNicolas Le Bayon 		panic();
173*ae6542f6SNicolas Le Bayon 	}
174*ae6542f6SNicolas Le Bayon }
175*ae6542f6SNicolas Le Bayon 
176*ae6542f6SNicolas Le Bayon static bool is_bsec_write_locked(void)
177*ae6542f6SNicolas Le Bayon {
178*ae6542f6SNicolas Le Bayon 	return (mmio_read_32(BSEC_BASE + BSEC_LOCKR) & BSEC_LOCKR_GWLOCK_MASK) != 0U;
179*ae6542f6SNicolas Le Bayon }
180*ae6542f6SNicolas Le Bayon 
181*ae6542f6SNicolas Le Bayon /*
182*ae6542f6SNicolas Le Bayon  * bsec_probe: initialize BSEC driver.
183*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
184*ae6542f6SNicolas Le Bayon  */
185*ae6542f6SNicolas Le Bayon uint32_t bsec_probe(void)
186*ae6542f6SNicolas Le Bayon {
187*ae6542f6SNicolas Le Bayon 	uint32_t version = bsec_get_version();
188*ae6542f6SNicolas Le Bayon 	uint32_t id = bsec_get_id();
189*ae6542f6SNicolas Le Bayon 
190*ae6542f6SNicolas Le Bayon 	if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
191*ae6542f6SNicolas Le Bayon 		ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
192*ae6542f6SNicolas Le Bayon 		panic();
193*ae6542f6SNicolas Le Bayon 	}
194*ae6542f6SNicolas Le Bayon 
195*ae6542f6SNicolas Le Bayon 	check_reset_error();
196*ae6542f6SNicolas Le Bayon 
197*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
198*ae6542f6SNicolas Le Bayon }
199*ae6542f6SNicolas Le Bayon 
200*ae6542f6SNicolas Le Bayon /*
201*ae6542f6SNicolas Le Bayon  * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
202*ae6542f6SNicolas Le Bayon  * otp: OTP number.
203*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
204*ae6542f6SNicolas Le Bayon  */
205*ae6542f6SNicolas Le Bayon static uint32_t bsec_shadow_register(uint32_t otp)
206*ae6542f6SNicolas Le Bayon {
207*ae6542f6SNicolas Le Bayon 	uint32_t result;
208*ae6542f6SNicolas Le Bayon 	uint32_t i;
209*ae6542f6SNicolas Le Bayon 	bool value;
210*ae6542f6SNicolas Le Bayon 
211*ae6542f6SNicolas Le Bayon 	result = bsec_read_sr_lock(otp, &value);
212*ae6542f6SNicolas Le Bayon 	if (result != BSEC_OK) {
213*ae6542f6SNicolas Le Bayon 		WARN("BSEC: %u Sticky-read bit read Error %u\n", otp, result);
214*ae6542f6SNicolas Le Bayon 	} else if (value) {
215*ae6542f6SNicolas Le Bayon 		VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", otp);
216*ae6542f6SNicolas Le Bayon 	}
217*ae6542f6SNicolas Le Bayon 
218*ae6542f6SNicolas Le Bayon 	for (i = 0U; i < MAX_NB_TRIES; i++) {
219*ae6542f6SNicolas Le Bayon 		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp);
220*ae6542f6SNicolas Le Bayon 
221*ae6542f6SNicolas Le Bayon 		poll_otp_status_busy();
222*ae6542f6SNicolas Le Bayon 
223*ae6542f6SNicolas Le Bayon 		result = check_read_error(otp);
224*ae6542f6SNicolas Le Bayon 		if (result != BSEC_RETRY) {
225*ae6542f6SNicolas Le Bayon 			break;
226*ae6542f6SNicolas Le Bayon 		}
227*ae6542f6SNicolas Le Bayon 	}
228*ae6542f6SNicolas Le Bayon 
229*ae6542f6SNicolas Le Bayon 	return result;
230*ae6542f6SNicolas Le Bayon }
231*ae6542f6SNicolas Le Bayon 
232*ae6542f6SNicolas Le Bayon /*
233*ae6542f6SNicolas Le Bayon  * bsec_write_otp: write a value in shadow OTP.
234*ae6542f6SNicolas Le Bayon  * val: value to program.
235*ae6542f6SNicolas Le Bayon  * otp: OTP number.
236*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
237*ae6542f6SNicolas Le Bayon  */
238*ae6542f6SNicolas Le Bayon uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
239*ae6542f6SNicolas Le Bayon {
240*ae6542f6SNicolas Le Bayon 	bool state;
241*ae6542f6SNicolas Le Bayon 	uint32_t result;
242*ae6542f6SNicolas Le Bayon 
243*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
244*ae6542f6SNicolas Le Bayon 		panic();
245*ae6542f6SNicolas Le Bayon 	}
246*ae6542f6SNicolas Le Bayon 
247*ae6542f6SNicolas Le Bayon 	if (!is_fuse_shadowed(otp)) {
248*ae6542f6SNicolas Le Bayon 		return BSEC_ERROR;
249*ae6542f6SNicolas Le Bayon 	}
250*ae6542f6SNicolas Le Bayon 
251*ae6542f6SNicolas Le Bayon 	if (is_bsec_write_locked()) {
252*ae6542f6SNicolas Le Bayon 		return BSEC_WRITE_LOCKED;
253*ae6542f6SNicolas Le Bayon 	}
254*ae6542f6SNicolas Le Bayon 
255*ae6542f6SNicolas Le Bayon 	result = bsec_read_sw_lock(otp, &state);
256*ae6542f6SNicolas Le Bayon 	if (result != BSEC_OK) {
257*ae6542f6SNicolas Le Bayon 		WARN("Shadow register is SW locked\n");
258*ae6542f6SNicolas Le Bayon 		return result;
259*ae6542f6SNicolas Le Bayon 	}
260*ae6542f6SNicolas Le Bayon 
261*ae6542f6SNicolas Le Bayon 	mmio_write_32(BSEC_BASE + BSEC_FVR(otp), val);
262*ae6542f6SNicolas Le Bayon 
263*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
264*ae6542f6SNicolas Le Bayon }
265*ae6542f6SNicolas Le Bayon 
266*ae6542f6SNicolas Le Bayon /*
267*ae6542f6SNicolas Le Bayon  * bsec_program_otp: program a bit in SAFMEM after the prog.
268*ae6542f6SNicolas Le Bayon  *	The OTP data is not refreshed.
269*ae6542f6SNicolas Le Bayon  * val: value to program.
270*ae6542f6SNicolas Le Bayon  * otp: OTP number.
271*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
272*ae6542f6SNicolas Le Bayon  */
273*ae6542f6SNicolas Le Bayon uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
274*ae6542f6SNicolas Le Bayon {
275*ae6542f6SNicolas Le Bayon 	uint32_t result;
276*ae6542f6SNicolas Le Bayon 	uint32_t i;
277*ae6542f6SNicolas Le Bayon 	bool value;
278*ae6542f6SNicolas Le Bayon 
279*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
280*ae6542f6SNicolas Le Bayon 		panic();
281*ae6542f6SNicolas Le Bayon 	}
282*ae6542f6SNicolas Le Bayon 
283*ae6542f6SNicolas Le Bayon 	if (is_bsec_write_locked() == true) {
284*ae6542f6SNicolas Le Bayon 		return BSEC_WRITE_LOCKED;
285*ae6542f6SNicolas Le Bayon 	}
286*ae6542f6SNicolas Le Bayon 
287*ae6542f6SNicolas Le Bayon 	result = bsec_read_sp_lock(otp, &value);
288*ae6542f6SNicolas Le Bayon 	if (result != BSEC_OK) {
289*ae6542f6SNicolas Le Bayon 		WARN("BSEC: %u Sticky-prog bit read Error %u\n", otp, result);
290*ae6542f6SNicolas Le Bayon 	} else if (value) {
291*ae6542f6SNicolas Le Bayon 		WARN("BSEC: OTP locked, prog will be ignored\n");
292*ae6542f6SNicolas Le Bayon 		return BSEC_WRITE_LOCKED;
293*ae6542f6SNicolas Le Bayon 	}
294*ae6542f6SNicolas Le Bayon 
295*ae6542f6SNicolas Le Bayon 	mmio_write_32(BSEC_BASE + BSEC_WDR, val);
296*ae6542f6SNicolas Le Bayon 
297*ae6542f6SNicolas Le Bayon 	for (i = 0U; i < MAX_NB_TRIES; i++) {
298*ae6542f6SNicolas Le Bayon 		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp | BSEC_OTPCR_PROG);
299*ae6542f6SNicolas Le Bayon 
300*ae6542f6SNicolas Le Bayon 		poll_otp_status_busy();
301*ae6542f6SNicolas Le Bayon 
302*ae6542f6SNicolas Le Bayon 		result = check_program_error(otp);
303*ae6542f6SNicolas Le Bayon 		if (result != BSEC_RETRY) {
304*ae6542f6SNicolas Le Bayon 			break;
305*ae6542f6SNicolas Le Bayon 		}
306*ae6542f6SNicolas Le Bayon 	}
307*ae6542f6SNicolas Le Bayon 
308*ae6542f6SNicolas Le Bayon 	return result;
309*ae6542f6SNicolas Le Bayon }
310*ae6542f6SNicolas Le Bayon 
311*ae6542f6SNicolas Le Bayon /*
312*ae6542f6SNicolas Le Bayon  * bsec_read_debug_conf: read debug configuration.
313*ae6542f6SNicolas Le Bayon  */
314*ae6542f6SNicolas Le Bayon uint32_t bsec_read_debug_conf(void)
315*ae6542f6SNicolas Le Bayon {
316*ae6542f6SNicolas Le Bayon 	return mmio_read_32(BSEC_BASE + BSEC_DENR);
317*ae6542f6SNicolas Le Bayon }
318*ae6542f6SNicolas Le Bayon 
319*ae6542f6SNicolas Le Bayon static uint32_t bsec_lock_register_set(uint32_t offset, uint32_t mask)
320*ae6542f6SNicolas Le Bayon {
321*ae6542f6SNicolas Le Bayon 	uint32_t value = mmio_read_32(BSEC_BASE + offset);
322*ae6542f6SNicolas Le Bayon 
323*ae6542f6SNicolas Le Bayon 	/* The lock is already set */
324*ae6542f6SNicolas Le Bayon 	if ((value & mask) != 0U) {
325*ae6542f6SNicolas Le Bayon 		return BSEC_OK;
326*ae6542f6SNicolas Le Bayon 	}
327*ae6542f6SNicolas Le Bayon 
328*ae6542f6SNicolas Le Bayon 	if (is_bsec_write_locked()) {
329*ae6542f6SNicolas Le Bayon 		return BSEC_WRITE_LOCKED;
330*ae6542f6SNicolas Le Bayon 	}
331*ae6542f6SNicolas Le Bayon 
332*ae6542f6SNicolas Le Bayon 	value |= mask;
333*ae6542f6SNicolas Le Bayon 
334*ae6542f6SNicolas Le Bayon 	mmio_write_32(BSEC_BASE + offset, value);
335*ae6542f6SNicolas Le Bayon 
336*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
337*ae6542f6SNicolas Le Bayon }
338*ae6542f6SNicolas Le Bayon 
339*ae6542f6SNicolas Le Bayon static bool bsec_lock_register_get(uint32_t offset, uint32_t mask)
340*ae6542f6SNicolas Le Bayon {
341*ae6542f6SNicolas Le Bayon 	uint32_t value = mmio_read_32(BSEC_BASE + offset);
342*ae6542f6SNicolas Le Bayon 
343*ae6542f6SNicolas Le Bayon 	return (value & mask) != 0U;
344*ae6542f6SNicolas Le Bayon }
345*ae6542f6SNicolas Le Bayon 
346*ae6542f6SNicolas Le Bayon /*
347*ae6542f6SNicolas Le Bayon  * bsec_set_sr_lock: set shadow-read lock.
348*ae6542f6SNicolas Le Bayon  * otp: OTP number.
349*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
350*ae6542f6SNicolas Le Bayon  */
351*ae6542f6SNicolas Le Bayon uint32_t bsec_set_sr_lock(uint32_t otp)
352*ae6542f6SNicolas Le Bayon {
353*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
354*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
355*ae6542f6SNicolas Le Bayon 
356*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
357*ae6542f6SNicolas Le Bayon 		panic();
358*ae6542f6SNicolas Le Bayon 	}
359*ae6542f6SNicolas Le Bayon 
360*ae6542f6SNicolas Le Bayon 	return bsec_lock_register_set(BSEC_SRLOCK(bank), otp_mask);
361*ae6542f6SNicolas Le Bayon }
362*ae6542f6SNicolas Le Bayon 
363*ae6542f6SNicolas Le Bayon /*
364*ae6542f6SNicolas Le Bayon  * bsec_read_sr_lock: read shadow-read lock.
365*ae6542f6SNicolas Le Bayon  * otp: OTP number.
366*ae6542f6SNicolas Le Bayon  * value: read value (true or false).
367*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
368*ae6542f6SNicolas Le Bayon  */
369*ae6542f6SNicolas Le Bayon uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
370*ae6542f6SNicolas Le Bayon {
371*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
372*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
373*ae6542f6SNicolas Le Bayon 
374*ae6542f6SNicolas Le Bayon 	assert(value != NULL);
375*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
376*ae6542f6SNicolas Le Bayon 		panic();
377*ae6542f6SNicolas Le Bayon 	}
378*ae6542f6SNicolas Le Bayon 
379*ae6542f6SNicolas Le Bayon 	*value = bsec_lock_register_get(BSEC_SRLOCK(bank), otp_mask);
380*ae6542f6SNicolas Le Bayon 
381*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
382*ae6542f6SNicolas Le Bayon }
383*ae6542f6SNicolas Le Bayon 
384*ae6542f6SNicolas Le Bayon /*
385*ae6542f6SNicolas Le Bayon  * bsec_set_sw_lock: set shadow-write lock.
386*ae6542f6SNicolas Le Bayon  * otp: OTP number.
387*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
388*ae6542f6SNicolas Le Bayon  */
389*ae6542f6SNicolas Le Bayon uint32_t bsec_set_sw_lock(uint32_t otp)
390*ae6542f6SNicolas Le Bayon {
391*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
392*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
393*ae6542f6SNicolas Le Bayon 
394*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
395*ae6542f6SNicolas Le Bayon 		panic();
396*ae6542f6SNicolas Le Bayon 	}
397*ae6542f6SNicolas Le Bayon 
398*ae6542f6SNicolas Le Bayon 	return bsec_lock_register_set(BSEC_SWLOCK(bank), otp_mask);
399*ae6542f6SNicolas Le Bayon }
400*ae6542f6SNicolas Le Bayon 
401*ae6542f6SNicolas Le Bayon /*
402*ae6542f6SNicolas Le Bayon  * bsec_read_sw_lock: read shadow-write lock.
403*ae6542f6SNicolas Le Bayon  * otp: OTP number.
404*ae6542f6SNicolas Le Bayon  * value: read value (true or false).
405*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
406*ae6542f6SNicolas Le Bayon  */
407*ae6542f6SNicolas Le Bayon uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
408*ae6542f6SNicolas Le Bayon {
409*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
410*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
411*ae6542f6SNicolas Le Bayon 
412*ae6542f6SNicolas Le Bayon 	assert(value != NULL);
413*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
414*ae6542f6SNicolas Le Bayon 		panic();
415*ae6542f6SNicolas Le Bayon 	}
416*ae6542f6SNicolas Le Bayon 
417*ae6542f6SNicolas Le Bayon 	*value = bsec_lock_register_get(BSEC_SWLOCK(bank), otp_mask);
418*ae6542f6SNicolas Le Bayon 
419*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
420*ae6542f6SNicolas Le Bayon }
421*ae6542f6SNicolas Le Bayon 
422*ae6542f6SNicolas Le Bayon /*
423*ae6542f6SNicolas Le Bayon  * bsec_set_sp_lock: set shadow-program lock.
424*ae6542f6SNicolas Le Bayon  * otp: OTP number.
425*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
426*ae6542f6SNicolas Le Bayon  */
427*ae6542f6SNicolas Le Bayon uint32_t bsec_set_sp_lock(uint32_t otp)
428*ae6542f6SNicolas Le Bayon {
429*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
430*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
431*ae6542f6SNicolas Le Bayon 
432*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
433*ae6542f6SNicolas Le Bayon 		panic();
434*ae6542f6SNicolas Le Bayon 	}
435*ae6542f6SNicolas Le Bayon 
436*ae6542f6SNicolas Le Bayon 	return bsec_lock_register_set(BSEC_SPLOCK(bank), otp_mask);
437*ae6542f6SNicolas Le Bayon }
438*ae6542f6SNicolas Le Bayon 
439*ae6542f6SNicolas Le Bayon /*
440*ae6542f6SNicolas Le Bayon  * bsec_read_sp_lock: read shadow-program lock.
441*ae6542f6SNicolas Le Bayon  * otp: OTP number.
442*ae6542f6SNicolas Le Bayon  * value: read value (true or false).
443*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
444*ae6542f6SNicolas Le Bayon  */
445*ae6542f6SNicolas Le Bayon uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
446*ae6542f6SNicolas Le Bayon {
447*ae6542f6SNicolas Le Bayon 	uint32_t bank = otp_bank(otp);
448*ae6542f6SNicolas Le Bayon 	uint32_t otp_mask = otp_bit_mask(otp);
449*ae6542f6SNicolas Le Bayon 
450*ae6542f6SNicolas Le Bayon 	assert(value != NULL);
451*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
452*ae6542f6SNicolas Le Bayon 		panic();
453*ae6542f6SNicolas Le Bayon 	}
454*ae6542f6SNicolas Le Bayon 
455*ae6542f6SNicolas Le Bayon 	*value = bsec_lock_register_get(BSEC_SPLOCK(bank), otp_mask);
456*ae6542f6SNicolas Le Bayon 
457*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
458*ae6542f6SNicolas Le Bayon }
459*ae6542f6SNicolas Le Bayon 
460*ae6542f6SNicolas Le Bayon /*
461*ae6542f6SNicolas Le Bayon  * bsec_get_secure_state: read state in BSEC status register.
462*ae6542f6SNicolas Le Bayon  * return: secure state
463*ae6542f6SNicolas Le Bayon  */
464*ae6542f6SNicolas Le Bayon uint32_t bsec_get_secure_state(void)
465*ae6542f6SNicolas Le Bayon {
466*ae6542f6SNicolas Le Bayon 	uint32_t state = BSEC_STATE_INVALID;
467*ae6542f6SNicolas Le Bayon 	uint32_t status = bsec_get_status();
468*ae6542f6SNicolas Le Bayon 	uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
469*ae6542f6SNicolas Le Bayon 
470*ae6542f6SNicolas Le Bayon 	if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
471*ae6542f6SNicolas Le Bayon 		/* NVSTATE is only valid if FUSEOK */
472*ae6542f6SNicolas Le Bayon 		uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
473*ae6542f6SNicolas Le Bayon 
474*ae6542f6SNicolas Le Bayon 		if (nvstates == BSEC_SR_NVSTATE_OPEN) {
475*ae6542f6SNicolas Le Bayon 			state = BSEC_STATE_SEC_OPEN;
476*ae6542f6SNicolas Le Bayon 		} else if (nvstates == BSEC_SR_NVSTATE_CLOSED) {
477*ae6542f6SNicolas Le Bayon 			state = BSEC_STATE_SEC_CLOSED;
478*ae6542f6SNicolas Le Bayon 		} else {
479*ae6542f6SNicolas Le Bayon 			VERBOSE("%s nvstates = %u\n", __func__, nvstates);
480*ae6542f6SNicolas Le Bayon 		}
481*ae6542f6SNicolas Le Bayon 	}
482*ae6542f6SNicolas Le Bayon 
483*ae6542f6SNicolas Le Bayon 	return state;
484*ae6542f6SNicolas Le Bayon }
485*ae6542f6SNicolas Le Bayon 
486*ae6542f6SNicolas Le Bayon /*
487*ae6542f6SNicolas Le Bayon  * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
488*ae6542f6SNicolas Le Bayon  * val: read value.
489*ae6542f6SNicolas Le Bayon  * otp: OTP number.
490*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
491*ae6542f6SNicolas Le Bayon  */
492*ae6542f6SNicolas Le Bayon uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
493*ae6542f6SNicolas Le Bayon {
494*ae6542f6SNicolas Le Bayon 	assert(val != NULL);
495*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
496*ae6542f6SNicolas Le Bayon 		panic();
497*ae6542f6SNicolas Le Bayon 	}
498*ae6542f6SNicolas Le Bayon 
499*ae6542f6SNicolas Le Bayon 	*val = 0U;
500*ae6542f6SNicolas Le Bayon 
501*ae6542f6SNicolas Le Bayon 	if (is_bsec_write_locked()) {
502*ae6542f6SNicolas Le Bayon 		return BSEC_WRITE_LOCKED;
503*ae6542f6SNicolas Le Bayon 	}
504*ae6542f6SNicolas Le Bayon 
505*ae6542f6SNicolas Le Bayon 	if (!is_fuse_shadowed(otp)) {
506*ae6542f6SNicolas Le Bayon 		uint32_t result = bsec_shadow_register(otp);
507*ae6542f6SNicolas Le Bayon 
508*ae6542f6SNicolas Le Bayon 		if (result != BSEC_OK) {
509*ae6542f6SNicolas Le Bayon 			ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
510*ae6542f6SNicolas Le Bayon 			return result;
511*ae6542f6SNicolas Le Bayon 		}
512*ae6542f6SNicolas Le Bayon 	}
513*ae6542f6SNicolas Le Bayon 
514*ae6542f6SNicolas Le Bayon 	*val = mmio_read_32(BSEC_BASE + BSEC_FVR(otp));
515*ae6542f6SNicolas Le Bayon 
516*ae6542f6SNicolas Le Bayon 	return BSEC_OK;
517*ae6542f6SNicolas Le Bayon }
518*ae6542f6SNicolas Le Bayon 
519*ae6542f6SNicolas Le Bayon /*
520*ae6542f6SNicolas Le Bayon  * bsec_read_otp: read an OTP data value.
521*ae6542f6SNicolas Le Bayon  * val: read value.
522*ae6542f6SNicolas Le Bayon  * otp: OTP number.
523*ae6542f6SNicolas Le Bayon  * return value: BSEC_OK if no error.
524*ae6542f6SNicolas Le Bayon  */
525*ae6542f6SNicolas Le Bayon uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
526*ae6542f6SNicolas Le Bayon {
527*ae6542f6SNicolas Le Bayon 	assert(val != NULL);
528*ae6542f6SNicolas Le Bayon 	if (otp > STM32MP2_OTP_MAX_ID) {
529*ae6542f6SNicolas Le Bayon 		panic();
530*ae6542f6SNicolas Le Bayon 	}
531*ae6542f6SNicolas Le Bayon 
532*ae6542f6SNicolas Le Bayon 	return bsec_shadow_read_otp(val, otp);
533*ae6542f6SNicolas Le Bayon }
534