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