1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019-2020 NXP.
4  */
5 
6 /*
7  * Configuration of the Tamper pins in different mode:
8  *  - default (no tamper pins): _default_
9  *  - passive mode expecting VCC on the line: "_passive_vcc_"
10  *  - passive mode expecting VCC on the line: "_passive_gnd_"
11  *  - active mode: "_active_"
12  */
13 
14 #include <command.h>
15 #include <log.h>
16 #include <stddef.h>
17 #include <common.h>
18 #include <asm/arch/sci/sci.h>
19 #include <asm/arch-imx8/imx8-pins.h>
20 #include <asm/arch-imx8/snvs_security_sc.h>
21 #include <asm/global_data.h>
22 
23 /* Access to gd */
24 DECLARE_GLOBAL_DATA_PTR;
25 
26 #define SC_WRITE_CONF 1
27 
28 #define PGD_HEX_VALUE 0x41736166
29 #define SRTC_EN 0x1
30 #define DP_EN BIT(5)
31 
32 struct snvs_security_sc_conf {
33 	struct snvs_hp_conf {
34 		u32 lock;		/* HPLR - HP Lock */
35 		u32 __cmd;		/* HPCOMR - HP Command */
36 		u32 __ctl;		/* HPCR - HP Control */
37 		u32 secvio_intcfg;	/* HPSICR - Security Violation Int
38 					 * Config
39 					 */
40 		u32 secvio_ctl;		/* HPSVCR - Security Violation Control*/
41 		u32 status;		/* HPSR - HP Status */
42 		u32 secvio_status;	/* HPSVSR - Security Violation Status */
43 		u32 __ha_counteriv;	/* High Assurance Counter IV */
44 		u32 __ha_counter;		/* High Assurance Counter */
45 		u32 __rtc_msb;		/* Real Time Clock/Counter MSB */
46 		u32 __rtc_lsb;		/* Real Time Counter LSB */
47 		u32 __time_alarm_msb;	/* Time Alarm MSB */
48 		u32 __time_alarm_lsb;	/* Time Alarm LSB */
49 	} hp;
50 	struct snvs_lp_conf {
51 		u32 lock;
52 		u32 __ctl;
53 		u32 __mstr_key_ctl;	/* Master Key Control */
54 		u32 secvio_ctl;		/* Security Violation Control */
55 		u32 tamper_filt_cfg;	/* Tamper Glitch Filters Configuration*/
56 		u32 tamper_det_cfg;	/* Tamper Detectors Configuration */
57 		u32 status;
58 		u32 __srtc_msb;		/* Secure Real Time Clock/Counter MSB */
59 		u32 __srtc_lsb;		/* Secure Real Time Clock/Counter LSB */
60 		u32 __time_alarm;		/* Time Alarm */
61 		u32 __smc_msb;		/* Secure Monotonic Counter MSB */
62 		u32 __smc_lsb;		/* Secure Monotonic Counter LSB */
63 		u32 __pwr_glitch_det;	/* Power Glitch Detector */
64 		u32 __gen_purpose;
65 		u8 __zmk[32];		/* Zeroizable Master Key */
66 		u32 __rsvd0;
67 		u32 __gen_purposes[4];	/* gp0_30 to gp0_33 */
68 		u32 tamper_det_cfg2;	/* Tamper Detectors Configuration2 */
69 		u32 tamper_det_status;	/* Tamper Detectors status */
70 		u32 tamper_filt1_cfg;	/* Tamper Glitch Filter1 Configuration*/
71 		u32 tamper_filt2_cfg;	/* Tamper Glitch Filter2 Configuration*/
72 		u32 __rsvd1[4];
73 		u32 act_tamper1_cfg;	/* Active Tamper1 Configuration */
74 		u32 act_tamper2_cfg;	/* Active Tamper2 Configuration */
75 		u32 act_tamper3_cfg;	/* Active Tamper3 Configuration */
76 		u32 act_tamper4_cfg;	/* Active Tamper4 Configuration */
77 		u32 act_tamper5_cfg;	/* Active Tamper5 Configuration */
78 		u32 __rsvd2[3];
79 		u32 act_tamper_ctl;	/* Active Tamper Control */
80 		u32 act_tamper_clk_ctl;	/* Active Tamper Clock Control */
81 		u32 act_tamper_routing_ctl1;/* Active Tamper Routing Control1 */
82 		u32 act_tamper_routing_ctl2;/* Active Tamper Routing Control2 */
83 	} lp;
84 };
85 
86 static struct snvs_security_sc_conf snvs_default_config = {
87 	.hp = {
88 		.lock = 0x1f0703ff,
89 		.secvio_ctl = 0x3000007f,
90 	},
91 	.lp = {
92 		.lock = 0x1f0003ff,
93 		.secvio_ctl = 0x36,
94 		.tamper_filt_cfg = 0,
95 		.tamper_det_cfg = 0x76, /* analogic tampers
96 					 * + rollover tampers
97 					 */
98 		.tamper_det_cfg2 = 0,
99 		.tamper_filt1_cfg = 0,
100 		.tamper_filt2_cfg = 0,
101 		.act_tamper1_cfg = 0,
102 		.act_tamper2_cfg = 0,
103 		.act_tamper3_cfg = 0,
104 		.act_tamper4_cfg = 0,
105 		.act_tamper5_cfg = 0,
106 		.act_tamper_ctl = 0,
107 		.act_tamper_clk_ctl = 0,
108 		.act_tamper_routing_ctl1 = 0,
109 		.act_tamper_routing_ctl2 = 0,
110 	}
111 };
112 
113 static struct snvs_security_sc_conf snvs_passive_vcc_config = {
114 	.hp = {
115 		.lock = 0x1f0703ff,
116 		.secvio_ctl = 0x3000007f,
117 	},
118 	.lp = {
119 		.lock = 0x1f0003ff,
120 		.secvio_ctl = 0x36,
121 		.tamper_filt_cfg = 0,
122 		.tamper_det_cfg = 0x276, /* ET1 will trig on line at GND
123 					  *  + analogic tampers
124 					  *  + rollover tampers
125 					  */
126 		.tamper_det_cfg2 = 0,
127 		.tamper_filt1_cfg = 0,
128 		.tamper_filt2_cfg = 0,
129 		.act_tamper1_cfg = 0,
130 		.act_tamper2_cfg = 0,
131 		.act_tamper3_cfg = 0,
132 		.act_tamper4_cfg = 0,
133 		.act_tamper5_cfg = 0,
134 		.act_tamper_ctl = 0,
135 		.act_tamper_clk_ctl = 0,
136 		.act_tamper_routing_ctl1 = 0,
137 		.act_tamper_routing_ctl2 = 0,
138 	}
139 };
140 
141 static struct snvs_security_sc_conf snvs_passive_gnd_config = {
142 	.hp = {
143 		.lock = 0x1f0703ff,
144 		.secvio_ctl = 0x3000007f,
145 	},
146 	.lp = {
147 		.lock = 0x1f0003ff,
148 		.secvio_ctl = 0x36,
149 		.tamper_filt_cfg = 0,
150 		.tamper_det_cfg = 0xa76, /* ET1 will trig on line at VCC
151 					  *  + analogic tampers
152 					  *  + rollover tampers
153 					  */
154 		.tamper_det_cfg2 = 0,
155 		.tamper_filt1_cfg = 0,
156 		.tamper_filt2_cfg = 0,
157 		.act_tamper1_cfg = 0,
158 		.act_tamper2_cfg = 0,
159 		.act_tamper3_cfg = 0,
160 		.act_tamper4_cfg = 0,
161 		.act_tamper5_cfg = 0,
162 		.act_tamper_ctl = 0,
163 		.act_tamper_clk_ctl = 0,
164 		.act_tamper_routing_ctl1 = 0,
165 		.act_tamper_routing_ctl2 = 0,
166 	}
167 };
168 
169 static struct snvs_security_sc_conf snvs_active_config = {
170 	.hp = {
171 		.lock = 0x1f0703ff,
172 		.secvio_ctl = 0x3000007f,
173 	},
174 	.lp = {
175 		.lock = 0x1f0003ff,
176 		.secvio_ctl = 0x36,
177 		.tamper_filt_cfg = 0x00800000, /* Enable filtering */
178 		.tamper_det_cfg = 0x276, /* ET1 enabled + analogic tampers
179 					  *  + rollover tampers
180 					  */
181 		.tamper_det_cfg2 = 0,
182 		.tamper_filt1_cfg = 0,
183 		.tamper_filt2_cfg = 0,
184 		.act_tamper1_cfg = 0x84001111,
185 		.act_tamper2_cfg = 0,
186 		.act_tamper3_cfg = 0,
187 		.act_tamper4_cfg = 0,
188 		.act_tamper5_cfg = 0,
189 		.act_tamper_ctl = 0x00010001,
190 		.act_tamper_clk_ctl = 0,
191 		.act_tamper_routing_ctl1 = 0x1,
192 		.act_tamper_routing_ctl2 = 0,
193 	}
194 };
195 
get_snvs_config(void)196 static struct snvs_security_sc_conf *get_snvs_config(void)
197 {
198 	return &snvs_default_config;
199 }
200 
201 struct snvs_dgo_conf {
202 	u32 tamper_offset_ctl;
203 	u32 tamper_pull_ctl;
204 	u32 tamper_ana_test_ctl;
205 	u32 tamper_sensor_trim_ctl;
206 	u32 tamper_misc_ctl;
207 	u32 tamper_core_volt_mon_ctl;
208 };
209 
210 static struct snvs_dgo_conf snvs_dgo_default_config = {
211 	.tamper_misc_ctl = 0x80000000, /* Lock the DGO */
212 };
213 
214 static struct snvs_dgo_conf snvs_dgo_passive_vcc_config = {
215 	.tamper_misc_ctl = 0x80000000, /* Lock the DGO */
216 	.tamper_pull_ctl = 0x00000001, /* Pull down ET1 */
217 	.tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
218 };
219 
220 static struct snvs_dgo_conf snvs_dgo_passive_gnd_config = {
221 	.tamper_misc_ctl = 0x80000000, /* Lock the DGO */
222 	.tamper_pull_ctl = 0x00000401, /* Pull up ET1 */
223 	.tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
224 };
225 
226 static struct snvs_dgo_conf snvs_dgo_active_config = {
227 	.tamper_misc_ctl = 0x80000000, /* Lock the DGO */
228 	.tamper_ana_test_ctl = 0x20000000, /* Enable tamper */
229 };
230 
get_snvs_dgo_config(void)231 static struct snvs_dgo_conf *get_snvs_dgo_config(void)
232 {
233 	return &snvs_dgo_default_config;
234 }
235 
236 struct tamper_pin_cfg {
237 	u32 pad;
238 	u32 mux_conf;
239 };
240 
241 static struct tamper_pin_cfg tamper_pin_list_default_config[] = {
242 	{SC_P_CSI_D00, 0}, /* Tamp_Out0 */
243 	{SC_P_CSI_D01, 0}, /* Tamp_Out1 */
244 	{SC_P_CSI_D02, 0}, /* Tamp_Out2 */
245 	{SC_P_CSI_D03, 0}, /* Tamp_Out3 */
246 	{SC_P_CSI_D04, 0}, /* Tamp_Out4 */
247 	{SC_P_CSI_D05, 0}, /* Tamp_In0 */
248 	{SC_P_CSI_D06, 0}, /* Tamp_In1 */
249 	{SC_P_CSI_D07, 0}, /* Tamp_In2 */
250 	{SC_P_CSI_HSYNC, 0}, /* Tamp_In3 */
251 	{SC_P_CSI_VSYNC, 0}, /* Tamp_In4 */
252 };
253 
254 static struct tamper_pin_cfg tamper_pin_list_passive_vcc_config[] = {
255 	{SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
256 };
257 
258 static struct tamper_pin_cfg tamper_pin_list_passive_gnd_config[] = {
259 	{SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
260 };
261 
262 static struct tamper_pin_cfg tamper_pin_list_active_config[] = {
263 	{SC_P_CSI_D00, 0x1a000060}, /* Tamp_Out0 */ /* Sel tamper + OD */
264 	{SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
265 };
266 
267 #define TAMPER_PIN_LIST_CHOSEN tamper_pin_list_default_config
268 
get_tamper_pin_cfg_list(u32 * size)269 static struct tamper_pin_cfg *get_tamper_pin_cfg_list(u32 *size)
270 {
271 	*size = sizeof(TAMPER_PIN_LIST_CHOSEN) /
272 		sizeof(TAMPER_PIN_LIST_CHOSEN[0]);
273 
274 	return TAMPER_PIN_LIST_CHOSEN;
275 }
276 
277 #define SC_CONF_OFFSET_OF(_field) \
278 	(offsetof(struct snvs_security_sc_conf, _field))
279 
ptr_value(u32 * _p)280 static u32 ptr_value(u32 *_p)
281 {
282 	return (_p) ? *_p : 0xdeadbeef;
283 }
284 
check_write_secvio_config(u32 id,u32 * _p1,u32 * _p2,u32 * _p3,u32 * _p4,u32 * _p5,u32 _cnt)285 static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2,
286 				     u32 *_p3, u32 *_p4, u32 *_p5,
287 				     u32 _cnt)
288 {
289 	int scierr = 0;
290 	u32 d1 = ptr_value(_p1);
291 	u32 d2 = ptr_value(_p2);
292 	u32 d3 = ptr_value(_p3);
293 	u32 d4 = ptr_value(_p4);
294 	u32 d5 = ptr_value(_p5);
295 
296 	scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3,
297 				       &d4, &d4, _cnt);
298 	if (scierr != SC_ERR_NONE) {
299 		printf("Failed to set secvio configuration\n");
300 		debug("Failed to set conf id 0x%x with values ", id);
301 		debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n",
302 		      d1, d2, d3, d4, d5, _cnt);
303 		goto exit;
304 	}
305 
306 	if (_p1)
307 		*(u32 *)_p1 = d1;
308 	if (_p2)
309 		*(u32 *)_p2 = d2;
310 	if (_p3)
311 		*(u32 *)_p3 = d3;
312 	if (_p4)
313 		*(u32 *)_p4 = d4;
314 	if (_p5)
315 		*(u32 *)_p5 = d5;
316 
317 exit:
318 	return scierr;
319 }
320 
321 #define SC_CHECK_WRITE1(id, _p1) \
322 	check_write_secvio_config(id, _p1, NULL, NULL, NULL, NULL, 1)
323 
apply_snvs_config(struct snvs_security_sc_conf * cnf)324 static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
325 {
326 	int scierr = 0;
327 
328 	debug("%s\n", __func__);
329 
330 	debug("Applying config:\n"
331 		  "\thp.lock = 0x%.8x\n"
332 		  "\thp.secvio_ctl = 0x%.8x\n"
333 		  "\tlp.lock = 0x%.8x\n"
334 		  "\tlp.secvio_ctl = 0x%.8x\n"
335 		  "\tlp.tamper_filt_cfg = 0x%.8x\n"
336 		  "\tlp.tamper_det_cfg = 0x%.8x\n"
337 		  "\tlp.tamper_det_cfg2 = 0x%.8x\n"
338 		  "\tlp.tamper_filt1_cfg = 0x%.8x\n"
339 		  "\tlp.tamper_filt2_cfg = 0x%.8x\n"
340 		  "\tlp.act_tamper1_cfg = 0x%.8x\n"
341 		  "\tlp.act_tamper2_cfg = 0x%.8x\n"
342 		  "\tlp.act_tamper3_cfg = 0x%.8x\n"
343 		  "\tlp.act_tamper4_cfg = 0x%.8x\n"
344 		  "\tlp.act_tamper5_cfg = 0x%.8x\n"
345 		  "\tlp.act_tamper_ctl = 0x%.8x\n"
346 		  "\tlp.act_tamper_clk_ctl = 0x%.8x\n"
347 		  "\tlp.act_tamper_routing_ctl1 = 0x%.8x\n"
348 		  "\tlp.act_tamper_routing_ctl2 = 0x%.8x\n",
349 			cnf->hp.lock,
350 			cnf->hp.secvio_ctl,
351 			cnf->lp.lock,
352 			cnf->lp.secvio_ctl,
353 			cnf->lp.tamper_filt_cfg,
354 			cnf->lp.tamper_det_cfg,
355 			cnf->lp.tamper_det_cfg2,
356 			cnf->lp.tamper_filt1_cfg,
357 			cnf->lp.tamper_filt2_cfg,
358 			cnf->lp.act_tamper1_cfg,
359 			cnf->lp.act_tamper2_cfg,
360 			cnf->lp.act_tamper3_cfg,
361 			cnf->lp.act_tamper4_cfg,
362 			cnf->lp.act_tamper5_cfg,
363 			cnf->lp.act_tamper_ctl,
364 			cnf->lp.act_tamper_clk_ctl,
365 			cnf->lp.act_tamper_routing_ctl1,
366 			cnf->lp.act_tamper_routing_ctl2);
367 
368 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
369 					   &cnf->lp.tamper_filt_cfg,
370 					   &cnf->lp.tamper_filt1_cfg,
371 					   &cnf->lp.tamper_filt2_cfg, NULL,
372 					   NULL, 3);
373 	if (scierr != SC_ERR_NONE)
374 		goto exit;
375 
376 	/* Configure AT */
377 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
378 					   &cnf->lp.act_tamper1_cfg,
379 					   &cnf->lp.act_tamper2_cfg,
380 					   &cnf->lp.act_tamper2_cfg,
381 					   &cnf->lp.act_tamper2_cfg,
382 					   &cnf->lp.act_tamper2_cfg, 5);
383 	if (scierr != SC_ERR_NONE)
384 		goto exit;
385 
386 	/* Configure AT routing */
387 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
388 					   &cnf->lp.act_tamper_routing_ctl1,
389 					   &cnf->lp.act_tamper_routing_ctl2,
390 					   NULL, NULL, NULL, 2);
391 	if (scierr != SC_ERR_NONE)
392 		goto exit;
393 
394 	/* Configure AT frequency */
395 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
396 				 &cnf->lp.act_tamper_clk_ctl);
397 	if (scierr != SC_ERR_NONE)
398 		goto exit;
399 
400 	/* Activate the ATs */
401 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl),
402 				 &cnf->lp.act_tamper_ctl);
403 	if (scierr != SC_ERR_NONE)
404 		goto exit;
405 
406 	/* Activate the detectors */
407 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
408 					   &cnf->lp.tamper_det_cfg,
409 					   &cnf->lp.tamper_det_cfg2, NULL, NULL,
410 					   NULL, 2);
411 	if (scierr != SC_ERR_NONE)
412 		goto exit;
413 
414 	/* Configure LP secvio */
415 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl),
416 				 &cnf->lp.secvio_ctl);
417 	if (scierr != SC_ERR_NONE)
418 		goto exit;
419 
420 	/* Configure HP secvio */
421 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl),
422 				 &cnf->hp.secvio_ctl);
423 	if (scierr != SC_ERR_NONE)
424 		goto exit;
425 
426 	/* Lock access */
427 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
428 	if (scierr != SC_ERR_NONE)
429 		goto exit;
430 
431 	scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
432 	if (scierr != SC_ERR_NONE)
433 		goto exit;
434 
435 exit:
436 	return (scierr == SC_ERR_NONE) ? 0 : -EIO;
437 }
438 
dgo_write(u32 _id,u8 _access,u32 * _pdata)439 static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
440 {
441 	int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
442 
443 	if (scierr != SC_ERR_NONE) {
444 		printf("Failed to set dgo configuration\n");
445 		debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
446 	}
447 
448 	return scierr;
449 }
450 
apply_snvs_dgo_config(struct snvs_dgo_conf * cnf)451 static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
452 {
453 	int scierr = 0;
454 
455 	debug("%s\n", __func__);
456 
457 	debug("Applying config:\n"
458 		"\ttamper_offset_ctl = 0x%.8x\n"
459 		"\ttamper_pull_ctl = 0x%.8x\n"
460 		"\ttamper_ana_test_ctl = 0x%.8x\n"
461 		"\ttamper_sensor_trim_ctl = 0x%.8x\n"
462 		"\ttamper_misc_ctl = 0x%.8x\n"
463 		"\ttamper_core_volt_mon_ctl = 0x%.8x\n",
464 			cnf->tamper_offset_ctl,
465 			cnf->tamper_pull_ctl,
466 			cnf->tamper_ana_test_ctl,
467 			cnf->tamper_sensor_trim_ctl,
468 			cnf->tamper_misc_ctl,
469 			cnf->tamper_core_volt_mon_ctl);
470 
471 	dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
472 	if (scierr != SC_ERR_NONE)
473 		goto exit;
474 
475 	dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
476 	if (scierr != SC_ERR_NONE)
477 		goto exit;
478 
479 	dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
480 	if (scierr != SC_ERR_NONE)
481 		goto exit;
482 
483 	dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
484 	if (scierr != SC_ERR_NONE)
485 		goto exit;
486 
487 	dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
488 	if (scierr != SC_ERR_NONE)
489 		goto exit;
490 
491 	/* Last as it could lock the writes */
492 	dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
493 	if (scierr != SC_ERR_NONE)
494 		goto exit;
495 
496 exit:
497 	return (scierr == SC_ERR_NONE) ? 0 : -EIO;
498 }
499 
pad_write(u32 _pad,u32 _value)500 static int pad_write(u32 _pad, u32 _value)
501 {
502 	int scierr = sc_pad_set(-1, _pad, _value);
503 
504 	if (scierr != SC_ERR_NONE) {
505 		printf("Failed to set pad configuration\n");
506 		debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
507 	}
508 
509 	return scierr;
510 }
511 
apply_tamper_pin_list_config(struct tamper_pin_cfg * confs,u32 size)512 static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
513 {
514 	int scierr = 0;
515 	u32 idx;
516 
517 	debug("%s\n", __func__);
518 
519 	for (idx = 0; idx < size; idx++) {
520 		debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad,
521 		      confs[idx].mux_conf);
522 		pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
523 		if (scierr != SC_ERR_NONE)
524 			goto exit;
525 	}
526 
527 exit:
528 	return (scierr == SC_ERR_NONE) ? 0 : -EIO;
529 }
530 
examples(void)531 int examples(void)
532 {
533 	u32 size;
534 	struct snvs_security_sc_conf *snvs_conf;
535 	struct snvs_dgo_conf *snvs_dgo_conf;
536 	struct tamper_pin_cfg *tamper_pin_conf;
537 
538 	/* Caller */
539 	snvs_conf = get_snvs_config();
540 	snvs_dgo_conf = get_snvs_dgo_config();
541 	tamper_pin_conf = get_tamper_pin_cfg_list(&size);
542 
543 	/* Default */
544 	snvs_conf = &snvs_default_config;
545 	snvs_dgo_conf = &snvs_dgo_default_config;
546 	tamper_pin_conf = tamper_pin_list_default_config;
547 
548 	/* Passive tamper expecting VCC on the line */
549 	snvs_conf = &snvs_passive_vcc_config;
550 	snvs_dgo_conf = &snvs_dgo_passive_vcc_config;
551 	tamper_pin_conf = tamper_pin_list_passive_vcc_config;
552 
553 	/* Passive tamper expecting GND on the line */
554 	snvs_conf = &snvs_passive_gnd_config;
555 	snvs_dgo_conf = &snvs_dgo_passive_gnd_config;
556 	tamper_pin_conf = tamper_pin_list_passive_gnd_config;
557 
558 	/* Active tamper */
559 	snvs_conf = &snvs_active_config;
560 	snvs_dgo_conf = &snvs_dgo_active_config;
561 	tamper_pin_conf = tamper_pin_list_active_config;
562 
563 	return !snvs_conf + !snvs_dgo_conf + !tamper_pin_conf;
564 }
565 
566 #ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO
snvs_security_sc_init(void)567 int snvs_security_sc_init(void)
568 {
569 	int err = 0;
570 
571 	struct snvs_security_sc_conf *snvs_conf;
572 	struct snvs_dgo_conf *snvs_dgo_conf;
573 	struct tamper_pin_cfg *tamper_pin_conf;
574 	u32 size;
575 
576 	debug("%s\n", __func__);
577 
578 	snvs_conf = get_snvs_config();
579 	snvs_dgo_conf = get_snvs_dgo_config();
580 
581 	tamper_pin_conf = get_tamper_pin_cfg_list(&size);
582 
583 	err = apply_tamper_pin_list_config(tamper_pin_conf, size);
584 	if (err) {
585 		debug("Failed to set pins\n");
586 		goto exit;
587 	}
588 
589 	err = apply_snvs_dgo_config(snvs_dgo_conf);
590 	if (err) {
591 		debug("Failed to set dgo\n");
592 		goto exit;
593 	}
594 
595 	err = apply_snvs_config(snvs_conf);
596 	if (err) {
597 		debug("Failed to set snvs\n");
598 		goto exit;
599 	}
600 
601 exit:
602 	return err;
603 }
604 #endif /* CONFIG_IMX_SNVS_SEC_SC_AUTO */
605 
606 static char snvs_cfg_help_text[] =
607 	"snvs_cfg\n"
608 	"\thp.lock\n"
609 	"\thp.secvio_ctl\n"
610 	"\tlp.lock\n"
611 	"\tlp.secvio_ctl\n"
612 	"\tlp.tamper_filt_cfg\n"
613 	"\tlp.tamper_det_cfg\n"
614 	"\tlp.tamper_det_cfg2\n"
615 	"\tlp.tamper_filt1_cfg\n"
616 	"\tlp.tamper_filt2_cfg\n"
617 	"\tlp.act_tamper1_cfg\n"
618 	"\tlp.act_tamper2_cfg\n"
619 	"\tlp.act_tamper3_cfg\n"
620 	"\tlp.act_tamper4_cfg\n"
621 	"\tlp.act_tamper5_cfg\n"
622 	"\tlp.act_tamper_ctl\n"
623 	"\tlp.act_tamper_clk_ctl\n"
624 	"\tlp.act_tamper_routing_ctl1\n"
625 	"\tlp.act_tamper_routing_ctl2\n"
626 	"\n"
627 	"ALL values should be in hexadecimal format";
628 
629 #define NB_REGISTERS 18
do_snvs_cfg(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])630 static int do_snvs_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
631 		       char *const argv[])
632 {
633 	int err = 0;
634 	u32 idx = 0;
635 
636 	struct snvs_security_sc_conf conf = {0};
637 
638 	if (argc != (NB_REGISTERS + 1))
639 		return CMD_RET_USAGE;
640 
641 	conf.hp.lock = simple_strtoul(argv[++idx], NULL, 16);
642 	conf.hp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16);
643 	conf.lp.lock = simple_strtoul(argv[++idx], NULL, 16);
644 	conf.lp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16);
645 	conf.lp.tamper_filt_cfg = simple_strtoul(argv[++idx], NULL, 16);
646 	conf.lp.tamper_det_cfg = simple_strtoul(argv[++idx], NULL, 16);
647 	conf.lp.tamper_det_cfg2 = simple_strtoul(argv[++idx], NULL, 16);
648 	conf.lp.tamper_filt1_cfg = simple_strtoul(argv[++idx], NULL, 16);
649 	conf.lp.tamper_filt2_cfg = simple_strtoul(argv[++idx], NULL, 16);
650 	conf.lp.act_tamper1_cfg = simple_strtoul(argv[++idx], NULL, 16);
651 	conf.lp.act_tamper2_cfg = simple_strtoul(argv[++idx], NULL, 16);
652 	conf.lp.act_tamper3_cfg = simple_strtoul(argv[++idx], NULL, 16);
653 	conf.lp.act_tamper4_cfg = simple_strtoul(argv[++idx], NULL, 16);
654 	conf.lp.act_tamper5_cfg = simple_strtoul(argv[++idx], NULL, 16);
655 	conf.lp.act_tamper_ctl = simple_strtoul(argv[++idx], NULL, 16);
656 	conf.lp.act_tamper_clk_ctl = simple_strtoul(argv[++idx], NULL, 16);
657 	conf.lp.act_tamper_routing_ctl1 = simple_strtoul(argv[++idx], NULL, 16);
658 	conf.lp.act_tamper_routing_ctl2 = simple_strtoul(argv[++idx], NULL, 16);
659 
660 	err = apply_snvs_config(&conf);
661 
662 	return err;
663 }
664 
665 U_BOOT_CMD(snvs_cfg,
666 	   NB_REGISTERS + 1, 1, do_snvs_cfg,
667 	   "Security violation configuration",
668 	   snvs_cfg_help_text
669 );
670 
671 static char snvs_dgo_cfg_help_text[] =
672 	"snvs_dgo_cfg\n"
673 	"\ttamper_offset_ctl\n"
674 	"\ttamper_pull_ctl\n"
675 	"\ttamper_ana_test_ctl\n"
676 	"\ttamper_sensor_trim_ctl\n"
677 	"\ttamper_misc_ctl\n"
678 	"\ttamper_core_volt_mon_ctl\n"
679 	"\n"
680 	"ALL values should be in hexadecimal format";
681 
do_snvs_dgo_cfg(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])682 static int do_snvs_dgo_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
683 			   char *const argv[])
684 {
685 	int err = 0;
686 	u32 idx = 0;
687 
688 	struct snvs_dgo_conf conf = {0};
689 
690 	if (argc != (6 + 1))
691 		return CMD_RET_USAGE;
692 
693 	conf.tamper_offset_ctl = simple_strtoul(argv[++idx], NULL, 16);
694 	conf.tamper_pull_ctl = simple_strtoul(argv[++idx], NULL, 16);
695 	conf.tamper_ana_test_ctl = simple_strtoul(argv[++idx], NULL, 16);
696 	conf.tamper_sensor_trim_ctl = simple_strtoul(argv[++idx], NULL, 16);
697 	conf.tamper_misc_ctl = simple_strtoul(argv[++idx], NULL, 16);
698 	conf.tamper_core_volt_mon_ctl = simple_strtoul(argv[++idx], NULL, 16);
699 
700 	err = apply_snvs_dgo_config(&conf);
701 
702 	return err;
703 }
704 
705 U_BOOT_CMD(snvs_dgo_cfg,
706 	   7, 1, do_snvs_dgo_cfg,
707 	   "SNVS DGO configuration",
708 	   snvs_dgo_cfg_help_text
709 );
710 
711 static char tamper_pin_cfg_help_text[] =
712 	"snvs_dgo_cfg\n"
713 	"\tpad\n"
714 	"\tvalue\n"
715 	"\n"
716 	"ALL values should be in hexadecimal format";
717 
do_tamper_pin_cfg(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])718 static int do_tamper_pin_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
719 			     char *const argv[])
720 {
721 	int err = 0;
722 	u32 idx = 0;
723 
724 	struct tamper_pin_cfg conf = {0};
725 
726 	if (argc != (2 + 1))
727 		return CMD_RET_USAGE;
728 
729 	conf.pad = simple_strtoul(argv[++idx], NULL, 10);
730 	conf.mux_conf = simple_strtoul(argv[++idx], NULL, 16);
731 
732 	err = apply_tamper_pin_list_config(&conf, 1);
733 
734 	return err;
735 }
736 
737 U_BOOT_CMD(tamper_pin_cfg,
738 	   3, 1, do_tamper_pin_cfg,
739 	   "tamper pin configuration",
740 	   tamper_pin_cfg_help_text
741 );
742 
743 static char snvs_clear_status_help_text[] =
744 	"snvs_clear_status\n"
745 	"\tHPSR\n"
746 	"\tHPSVSR\n"
747 	"\tLPSR\n"
748 	"\tLPTDSR\n"
749 	"\n"
750 	"Write the status registers with the value provided,"
751 	" clearing the status";
752 
do_snvs_clear_status(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])753 static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
754 				char *const argv[])
755 {
756 	int scierr = 0;
757 	u32 idx = 0;
758 
759 	struct snvs_security_sc_conf conf = {0};
760 
761 	if (argc != (2 + 1))
762 		return CMD_RET_USAGE;
763 
764 	conf.lp.status = simple_strtoul(argv[++idx], NULL, 16);
765 	conf.lp.tamper_det_status = simple_strtoul(argv[++idx], NULL, 16);
766 
767 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
768 					   &conf.lp.status, NULL, NULL, NULL,
769 					   NULL, 1);
770 	if (scierr != SC_ERR_NONE)
771 		goto exit;
772 
773 	scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
774 					   &conf.lp.tamper_det_status, NULL,
775 					   NULL, NULL, NULL, 1);
776 	if (scierr != SC_ERR_NONE)
777 		goto exit;
778 
779 exit:
780 	return (scierr == SC_ERR_NONE) ? 0 : 1;
781 }
782 
783 U_BOOT_CMD(snvs_clear_status,
784 	   3, 1, do_snvs_clear_status,
785 	   "snvs clear status",
786 	   snvs_clear_status_help_text
787 );
788 
789 static char snvs_sec_status_help_text[] =
790 	"snvs_sec_status\n"
791 	"Display information about the security related to tamper and secvio";
792 
do_snvs_sec_status(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])793 static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
794 			      char *const argv[])
795 {
796 	int scierr;
797 	u32 idx;
798 
799 	u32 data[5];
800 
801 	u32 pads[] = {
802 		SC_P_CSI_D00,
803 		SC_P_CSI_D01,
804 		SC_P_CSI_D02,
805 		SC_P_CSI_D03,
806 		SC_P_CSI_D04,
807 		SC_P_CSI_D05,
808 		SC_P_CSI_D06,
809 		SC_P_CSI_D07,
810 		SC_P_CSI_HSYNC,
811 		SC_P_CSI_VSYNC,
812 	};
813 
814 	u32 fuses[] = {
815 		14,
816 		30,
817 		31,
818 		260,
819 		261,
820 		262,
821 		263,
822 		768,
823 	};
824 
825 	struct snvs_reg {
826 		u32 id;
827 		u32 nb;
828 	} snvs[] = {
829 		/* Locks */
830 		{0x0,  1},
831 		{0x34, 1},
832 		/* Security violation */
833 		{0xc,  1},
834 		{0x10, 1},
835 		{0x18, 1},
836 		{0x40, 1},
837 		/* Temper detectors */
838 		{0x48, 2},
839 		{0x4c, 1},
840 		{0xa4, 1},
841 		/* */
842 		{0x44, 3},
843 		{0xe0, 1},
844 		{0xe4, 1},
845 		{0xe8, 2},
846 		/* Misc */
847 		{0x3c, 1},
848 		{0x5c, 2},
849 		{0x64, 1},
850 		{0xf8, 2},
851 	};
852 
853 	u32 dgo[] = {
854 		0x0,
855 		0x10,
856 		0x20,
857 		0x30,
858 		0x40,
859 		0x50,
860 	};
861 
862 	/* Pins */
863 	printf("Pins:\n");
864 	for (idx = 0; idx < ARRAY_SIZE(pads); idx++) {
865 		u8 pad_id = pads[idx];
866 
867 		scierr = sc_pad_get(-1, pad_id, &data[0]);
868 		if (scierr == 0)
869 			printf("\t- Pin %d: %.8x\n", pad_id, data[0]);
870 		else
871 			printf("Failed to read Pin %d\n", pad_id);
872 	}
873 
874 	/* Fuses */
875 	printf("Fuses:\n");
876 	for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) {
877 		u32 fuse_id = fuses[idx];
878 
879 		scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
880 		if (scierr == 0)
881 			printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]);
882 		else
883 			printf("Failed to read Fuse %d\n", fuse_id);
884 	}
885 
886 	/* SNVS */
887 	printf("SNVS:\n");
888 	for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) {
889 		struct snvs_reg *reg = &snvs[idx];
890 
891 		scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
892 					       &data[1], &data[2], &data[3],
893 					       &data[4], reg->nb);
894 		if (scierr == 0) {
895 			int subidx;
896 
897 			printf("\t- SNVS %.2x(%d):", reg->id, reg->nb);
898 			for (subidx = 0; subidx < reg->nb; subidx++)
899 				printf(" %.8x", data[subidx]);
900 			printf("\n");
901 		} else {
902 			printf("Failed to read SNVS %d\n", reg->id);
903 		}
904 	}
905 
906 	/* DGO */
907 	printf("DGO:\n");
908 	for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) {
909 		u8 dgo_id = dgo[idx];
910 
911 		scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
912 		if (scierr == 0)
913 			printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]);
914 		else
915 			printf("Failed to read DGO %d\n", dgo_id);
916 	}
917 
918 	return 0;
919 }
920 
921 U_BOOT_CMD(snvs_sec_status,
922 	   1, 1, do_snvs_sec_status,
923 	   "tamper pin configuration",
924 	   snvs_sec_status_help_text
925 );
926