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 <firmware/imx/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 */
24DECLARE_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
32struct 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
86static 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
113static 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
141static 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
169static 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
196static struct snvs_security_sc_conf *get_snvs_config(void)
197{
198	return &snvs_default_config;
199}
200
201struct 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
210static struct snvs_dgo_conf snvs_dgo_default_config = {
211	.tamper_misc_ctl = 0x80000000, /* Lock the DGO */
212};
213
214static 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
220static 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
226static 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
231static struct snvs_dgo_conf *get_snvs_dgo_config(void)
232{
233	return &snvs_dgo_default_config;
234}
235
236struct tamper_pin_cfg {
237	u32 pad;
238	u32 mux_conf;
239};
240
241static 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
254static struct tamper_pin_cfg tamper_pin_list_passive_vcc_config[] = {
255	{SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
256};
257
258static struct tamper_pin_cfg tamper_pin_list_passive_gnd_config[] = {
259	{SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */
260};
261
262static 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
269static 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
280static u32 ptr_value(u32 *_p)
281{
282	return (_p) ? *_p : 0xdeadbeef;
283}
284
285static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2,
286				     u32 *_p3, u32 *_p4, u32 *_p5,
287				     u32 _cnt)
288{
289	int err;
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	err = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, &d4, &d4, _cnt);
297	if (err) {
298		printf("Failed to set secvio configuration\n");
299		debug("Failed to set conf id 0x%x with values ", id);
300		debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n",
301		      d1, d2, d3, d4, d5, _cnt);
302		goto exit;
303	}
304
305	if (_p1)
306		*(u32 *)_p1 = d1;
307	if (_p2)
308		*(u32 *)_p2 = d2;
309	if (_p3)
310		*(u32 *)_p3 = d3;
311	if (_p4)
312		*(u32 *)_p4 = d4;
313	if (_p5)
314		*(u32 *)_p5 = d5;
315
316exit:
317	return err;
318}
319
320#define SC_CHECK_WRITE1(id, _p1) \
321	check_write_secvio_config(id, _p1, NULL, NULL, NULL, NULL, 1)
322
323static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
324{
325	int err = 0;
326
327	debug("%s\n", __func__);
328
329	debug("Applying config:\n"
330		  "\thp.lock = 0x%.8x\n"
331		  "\thp.secvio_ctl = 0x%.8x\n"
332		  "\tlp.lock = 0x%.8x\n"
333		  "\tlp.secvio_ctl = 0x%.8x\n"
334		  "\tlp.tamper_filt_cfg = 0x%.8x\n"
335		  "\tlp.tamper_det_cfg = 0x%.8x\n"
336		  "\tlp.tamper_det_cfg2 = 0x%.8x\n"
337		  "\tlp.tamper_filt1_cfg = 0x%.8x\n"
338		  "\tlp.tamper_filt2_cfg = 0x%.8x\n"
339		  "\tlp.act_tamper1_cfg = 0x%.8x\n"
340		  "\tlp.act_tamper2_cfg = 0x%.8x\n"
341		  "\tlp.act_tamper3_cfg = 0x%.8x\n"
342		  "\tlp.act_tamper4_cfg = 0x%.8x\n"
343		  "\tlp.act_tamper5_cfg = 0x%.8x\n"
344		  "\tlp.act_tamper_ctl = 0x%.8x\n"
345		  "\tlp.act_tamper_clk_ctl = 0x%.8x\n"
346		  "\tlp.act_tamper_routing_ctl1 = 0x%.8x\n"
347		  "\tlp.act_tamper_routing_ctl2 = 0x%.8x\n",
348			cnf->hp.lock,
349			cnf->hp.secvio_ctl,
350			cnf->lp.lock,
351			cnf->lp.secvio_ctl,
352			cnf->lp.tamper_filt_cfg,
353			cnf->lp.tamper_det_cfg,
354			cnf->lp.tamper_det_cfg2,
355			cnf->lp.tamper_filt1_cfg,
356			cnf->lp.tamper_filt2_cfg,
357			cnf->lp.act_tamper1_cfg,
358			cnf->lp.act_tamper2_cfg,
359			cnf->lp.act_tamper3_cfg,
360			cnf->lp.act_tamper4_cfg,
361			cnf->lp.act_tamper5_cfg,
362			cnf->lp.act_tamper_ctl,
363			cnf->lp.act_tamper_clk_ctl,
364			cnf->lp.act_tamper_routing_ctl1,
365			cnf->lp.act_tamper_routing_ctl2);
366
367	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
368					&cnf->lp.tamper_filt_cfg,
369					&cnf->lp.tamper_filt1_cfg,
370					&cnf->lp.tamper_filt2_cfg,
371					NULL, NULL, 3);
372	if (err)
373		goto exit;
374
375	/* Configure AT */
376	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
377					&cnf->lp.act_tamper1_cfg,
378					&cnf->lp.act_tamper2_cfg,
379					&cnf->lp.act_tamper2_cfg,
380					&cnf->lp.act_tamper2_cfg,
381					&cnf->lp.act_tamper2_cfg, 5);
382	if (err)
383		goto exit;
384
385	/* Configure AT routing */
386	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
387					&cnf->lp.act_tamper_routing_ctl1,
388					&cnf->lp.act_tamper_routing_ctl2,
389					NULL, NULL, NULL, 2);
390	if (err)
391		goto exit;
392
393	/* Configure AT frequency */
394	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
395			      &cnf->lp.act_tamper_clk_ctl);
396	if (err)
397		goto exit;
398
399	/* Activate the ATs */
400	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), &cnf->lp.act_tamper_ctl);
401	if (err)
402		goto exit;
403
404	/* Activate the detectors */
405	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
406					&cnf->lp.tamper_det_cfg,
407					&cnf->lp.tamper_det_cfg2, NULL, NULL, NULL, 2);
408	if (err)
409		goto exit;
410
411	/* Configure LP secvio */
412	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), &cnf->lp.secvio_ctl);
413	if (err)
414		goto exit;
415
416	/* Configure HP secvio */
417	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), &cnf->hp.secvio_ctl);
418	if (err)
419		goto exit;
420
421	/* Lock access */
422	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
423	if (err)
424		goto exit;
425
426	err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
427	if (err)
428		goto exit;
429
430exit:
431	return err;
432}
433
434static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
435{
436	int err = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
437
438	if (err) {
439		printf("Failed to set dgo configuration\n");
440		debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
441	}
442
443	return err;
444}
445
446static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
447{
448	int err;
449
450	debug("%s\n", __func__);
451
452	debug("Applying config:\n"
453		"\ttamper_offset_ctl = 0x%.8x\n"
454		"\ttamper_pull_ctl = 0x%.8x\n"
455		"\ttamper_ana_test_ctl = 0x%.8x\n"
456		"\ttamper_sensor_trim_ctl = 0x%.8x\n"
457		"\ttamper_misc_ctl = 0x%.8x\n"
458		"\ttamper_core_volt_mon_ctl = 0x%.8x\n",
459			cnf->tamper_offset_ctl,
460			cnf->tamper_pull_ctl,
461			cnf->tamper_ana_test_ctl,
462			cnf->tamper_sensor_trim_ctl,
463			cnf->tamper_misc_ctl,
464			cnf->tamper_core_volt_mon_ctl);
465
466	err = dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
467	if (err)
468		goto exit;
469
470	err = dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
471	if (err)
472		goto exit;
473
474	err = dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
475	if (err)
476		goto exit;
477
478	err = dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
479	if (err)
480		goto exit;
481
482	err = dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
483	if (err)
484		goto exit;
485
486	/* Last as it could lock the writes */
487	err = dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
488	if (err)
489		goto exit;
490
491exit:
492	return err;
493}
494
495static int pad_write(u32 _pad, u32 _value)
496{
497	int err = sc_pad_set(-1, _pad, _value);
498
499	if (err) {
500		printf("Failed to set pad configuration\n");
501		debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
502	}
503
504	return err;
505}
506
507static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
508{
509	int err = 0;
510	u32 idx;
511
512	debug("%s\n", __func__);
513
514	for (idx = 0; idx < size; idx++) {
515		debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad,
516		      confs[idx].mux_conf);
517		err = pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
518		if (err)
519			goto exit;
520	}
521
522exit:
523	return err;
524}
525
526int examples(void)
527{
528	u32 size;
529	struct snvs_security_sc_conf *snvs_conf;
530	struct snvs_dgo_conf *snvs_dgo_conf;
531	struct tamper_pin_cfg *tamper_pin_conf;
532
533	/* Caller */
534	snvs_conf = get_snvs_config();
535	snvs_dgo_conf = get_snvs_dgo_config();
536	tamper_pin_conf = get_tamper_pin_cfg_list(&size);
537
538	/* Default */
539	snvs_conf = &snvs_default_config;
540	snvs_dgo_conf = &snvs_dgo_default_config;
541	tamper_pin_conf = tamper_pin_list_default_config;
542
543	/* Passive tamper expecting VCC on the line */
544	snvs_conf = &snvs_passive_vcc_config;
545	snvs_dgo_conf = &snvs_dgo_passive_vcc_config;
546	tamper_pin_conf = tamper_pin_list_passive_vcc_config;
547
548	/* Passive tamper expecting GND on the line */
549	snvs_conf = &snvs_passive_gnd_config;
550	snvs_dgo_conf = &snvs_dgo_passive_gnd_config;
551	tamper_pin_conf = tamper_pin_list_passive_gnd_config;
552
553	/* Active tamper */
554	snvs_conf = &snvs_active_config;
555	snvs_dgo_conf = &snvs_dgo_active_config;
556	tamper_pin_conf = tamper_pin_list_active_config;
557
558	return !snvs_conf + !snvs_dgo_conf + !tamper_pin_conf;
559}
560
561#ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO
562int snvs_security_sc_init(void)
563{
564	int err = 0;
565
566	struct snvs_security_sc_conf *snvs_conf;
567	struct snvs_dgo_conf *snvs_dgo_conf;
568	struct tamper_pin_cfg *tamper_pin_conf;
569	u32 size;
570
571	debug("%s\n", __func__);
572
573	snvs_conf = get_snvs_config();
574	snvs_dgo_conf = get_snvs_dgo_config();
575
576	tamper_pin_conf = get_tamper_pin_cfg_list(&size);
577
578	err = apply_tamper_pin_list_config(tamper_pin_conf, size);
579	if (err) {
580		debug("Failed to set pins\n");
581		goto exit;
582	}
583
584	err = apply_snvs_dgo_config(snvs_dgo_conf);
585	if (err) {
586		debug("Failed to set dgo\n");
587		goto exit;
588	}
589
590	err = apply_snvs_config(snvs_conf);
591	if (err) {
592		debug("Failed to set snvs\n");
593		goto exit;
594	}
595
596exit:
597	return err;
598}
599#endif /* CONFIG_IMX_SNVS_SEC_SC_AUTO */
600
601static char snvs_cfg_help_text[] =
602	"snvs_cfg\n"
603	"\thp.lock\n"
604	"\thp.secvio_ctl\n"
605	"\tlp.lock\n"
606	"\tlp.secvio_ctl\n"
607	"\tlp.tamper_filt_cfg\n"
608	"\tlp.tamper_det_cfg\n"
609	"\tlp.tamper_det_cfg2\n"
610	"\tlp.tamper_filt1_cfg\n"
611	"\tlp.tamper_filt2_cfg\n"
612	"\tlp.act_tamper1_cfg\n"
613	"\tlp.act_tamper2_cfg\n"
614	"\tlp.act_tamper3_cfg\n"
615	"\tlp.act_tamper4_cfg\n"
616	"\tlp.act_tamper5_cfg\n"
617	"\tlp.act_tamper_ctl\n"
618	"\tlp.act_tamper_clk_ctl\n"
619	"\tlp.act_tamper_routing_ctl1\n"
620	"\tlp.act_tamper_routing_ctl2\n"
621	"\n"
622	"ALL values should be in hexadecimal format";
623
624#define NB_REGISTERS 18
625static int do_snvs_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
626		       char *const argv[])
627{
628	int err = 0;
629	u32 idx = 0;
630
631	struct snvs_security_sc_conf conf = {0};
632
633	if (argc != (NB_REGISTERS + 1))
634		return CMD_RET_USAGE;
635
636	conf.hp.lock = hextoul(argv[++idx], NULL);
637	conf.hp.secvio_ctl = hextoul(argv[++idx], NULL);
638	conf.lp.lock = hextoul(argv[++idx], NULL);
639	conf.lp.secvio_ctl = hextoul(argv[++idx], NULL);
640	conf.lp.tamper_filt_cfg = hextoul(argv[++idx], NULL);
641	conf.lp.tamper_det_cfg = hextoul(argv[++idx], NULL);
642	conf.lp.tamper_det_cfg2 = hextoul(argv[++idx], NULL);
643	conf.lp.tamper_filt1_cfg = hextoul(argv[++idx], NULL);
644	conf.lp.tamper_filt2_cfg = hextoul(argv[++idx], NULL);
645	conf.lp.act_tamper1_cfg = hextoul(argv[++idx], NULL);
646	conf.lp.act_tamper2_cfg = hextoul(argv[++idx], NULL);
647	conf.lp.act_tamper3_cfg = hextoul(argv[++idx], NULL);
648	conf.lp.act_tamper4_cfg = hextoul(argv[++idx], NULL);
649	conf.lp.act_tamper5_cfg = hextoul(argv[++idx], NULL);
650	conf.lp.act_tamper_ctl = hextoul(argv[++idx], NULL);
651	conf.lp.act_tamper_clk_ctl = hextoul(argv[++idx], NULL);
652	conf.lp.act_tamper_routing_ctl1 = hextoul(argv[++idx], NULL);
653	conf.lp.act_tamper_routing_ctl2 = hextoul(argv[++idx], NULL);
654
655	err = apply_snvs_config(&conf);
656
657	return err;
658}
659
660U_BOOT_CMD(snvs_cfg,
661	   NB_REGISTERS + 1, 1, do_snvs_cfg,
662	   "Security violation configuration",
663	   snvs_cfg_help_text
664);
665
666static char snvs_dgo_cfg_help_text[] =
667	"snvs_dgo_cfg\n"
668	"\ttamper_offset_ctl\n"
669	"\ttamper_pull_ctl\n"
670	"\ttamper_ana_test_ctl\n"
671	"\ttamper_sensor_trim_ctl\n"
672	"\ttamper_misc_ctl\n"
673	"\ttamper_core_volt_mon_ctl\n"
674	"\n"
675	"ALL values should be in hexadecimal format";
676
677static int do_snvs_dgo_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
678			   char *const argv[])
679{
680	int err = 0;
681	u32 idx = 0;
682
683	struct snvs_dgo_conf conf = {0};
684
685	if (argc != (6 + 1))
686		return CMD_RET_USAGE;
687
688	conf.tamper_offset_ctl = hextoul(argv[++idx], NULL);
689	conf.tamper_pull_ctl = hextoul(argv[++idx], NULL);
690	conf.tamper_ana_test_ctl = hextoul(argv[++idx], NULL);
691	conf.tamper_sensor_trim_ctl = hextoul(argv[++idx], NULL);
692	conf.tamper_misc_ctl = hextoul(argv[++idx], NULL);
693	conf.tamper_core_volt_mon_ctl = hextoul(argv[++idx], NULL);
694
695	err = apply_snvs_dgo_config(&conf);
696
697	return err;
698}
699
700U_BOOT_CMD(snvs_dgo_cfg,
701	   7, 1, do_snvs_dgo_cfg,
702	   "SNVS DGO configuration",
703	   snvs_dgo_cfg_help_text
704);
705
706static char tamper_pin_cfg_help_text[] =
707	"snvs_dgo_cfg\n"
708	"\tpad\n"
709	"\tvalue\n"
710	"\n"
711	"ALL values should be in hexadecimal format";
712
713static int do_tamper_pin_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
714			     char *const argv[])
715{
716	int err = 0;
717	u32 idx = 0;
718
719	struct tamper_pin_cfg conf = {0};
720
721	if (argc != (2 + 1))
722		return CMD_RET_USAGE;
723
724	conf.pad = dectoul(argv[++idx], NULL);
725	conf.mux_conf = hextoul(argv[++idx], NULL);
726
727	err = apply_tamper_pin_list_config(&conf, 1);
728
729	return err;
730}
731
732U_BOOT_CMD(tamper_pin_cfg,
733	   3, 1, do_tamper_pin_cfg,
734	   "tamper pin configuration",
735	   tamper_pin_cfg_help_text
736);
737
738static char snvs_clear_status_help_text[] =
739	"snvs_clear_status\n"
740	"\tHPSR\n"
741	"\tHPSVSR\n"
742	"\tLPSR\n"
743	"\tLPTDSR\n"
744	"\n"
745	"Write the status registers with the value provided,"
746	" clearing the status";
747
748static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
749				char *const argv[])
750{
751	int err;
752	u32 idx = 0;
753
754	struct snvs_security_sc_conf conf = {0};
755
756	if (argc != (2 + 1))
757		return CMD_RET_USAGE;
758
759	conf.lp.status = hextoul(argv[++idx], NULL);
760	conf.lp.tamper_det_status = hextoul(argv[++idx], NULL);
761
762	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
763					&conf.lp.status, NULL, NULL, NULL, NULL, 1);
764	if (err)
765		goto exit;
766
767	err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
768					&conf.lp.tamper_det_status, NULL, NULL, NULL, NULL, 1);
769	if (err)
770		goto exit;
771
772exit:
773	return err;
774}
775
776U_BOOT_CMD(snvs_clear_status,
777	   3, 1, do_snvs_clear_status,
778	   "snvs clear status",
779	   snvs_clear_status_help_text
780);
781
782static char snvs_sec_status_help_text[] =
783	"snvs_sec_status\n"
784	"Display information about the security related to tamper and secvio";
785
786static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
787			      char *const argv[])
788{
789	int err;
790	u32 idx;
791
792	u32 data[5];
793
794	u32 pads[] = {
795		SC_P_CSI_D00,
796		SC_P_CSI_D01,
797		SC_P_CSI_D02,
798		SC_P_CSI_D03,
799		SC_P_CSI_D04,
800		SC_P_CSI_D05,
801		SC_P_CSI_D06,
802		SC_P_CSI_D07,
803		SC_P_CSI_HSYNC,
804		SC_P_CSI_VSYNC,
805	};
806
807	u32 fuses[] = {
808		14,
809		30,
810		31,
811		260,
812		261,
813		262,
814		263,
815		768,
816	};
817
818	struct snvs_reg {
819		u32 id;
820		u32 nb;
821	} snvs[] = {
822		/* Locks */
823		{0x0,  1},
824		{0x34, 1},
825		/* Security violation */
826		{0xc,  1},
827		{0x10, 1},
828		{0x18, 1},
829		{0x40, 1},
830		/* Temper detectors */
831		{0x48, 2},
832		{0x4c, 1},
833		{0xa4, 1},
834		/* */
835		{0x44, 3},
836		{0xe0, 1},
837		{0xe4, 1},
838		{0xe8, 2},
839		/* Misc */
840		{0x3c, 1},
841		{0x5c, 2},
842		{0x64, 1},
843		{0xf8, 2},
844	};
845
846	u32 dgo[] = {
847		0x0,
848		0x10,
849		0x20,
850		0x30,
851		0x40,
852		0x50,
853	};
854
855	/* Pins */
856	printf("Pins:\n");
857	for (idx = 0; idx < ARRAY_SIZE(pads); idx++) {
858		u8 pad_id = pads[idx];
859
860		err = sc_pad_get(-1, pad_id, &data[0]);
861		if (!err)
862			printf("\t- Pin %d: %.8x\n", pad_id, data[0]);
863		else
864			printf("Failed to read Pin %d\n", pad_id);
865	}
866
867	/* Fuses */
868	printf("Fuses:\n");
869	for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) {
870		u32 fuse_id = fuses[idx];
871
872		err = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
873		if (!err)
874			printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]);
875		else
876			printf("Failed to read Fuse %d\n", fuse_id);
877	}
878
879	/* SNVS */
880	printf("SNVS:\n");
881	for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) {
882		struct snvs_reg *reg = &snvs[idx];
883
884		err = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
885					    &data[1], &data[2], &data[3],
886					    &data[4], reg->nb);
887		if (!err) {
888			int subidx;
889
890			printf("\t- SNVS %.2x(%d):", reg->id, reg->nb);
891			for (subidx = 0; subidx < reg->nb; subidx++)
892				printf(" %.8x", data[subidx]);
893			printf("\n");
894		} else {
895			printf("Failed to read SNVS %d\n", reg->id);
896		}
897	}
898
899	/* DGO */
900	printf("DGO:\n");
901	for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) {
902		u8 dgo_id = dgo[idx];
903
904		err = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
905		if (!err)
906			printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]);
907		else
908			printf("Failed to read DGO %d\n", dgo_id);
909	}
910
911	return 0;
912}
913
914U_BOOT_CMD(snvs_sec_status,
915	   1, 1, do_snvs_sec_status,
916	   "tamper pin configuration",
917	   snvs_sec_status_help_text
918);
919