Merge tag 'xilinx-for-v2021.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u...
[platform/kernel/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 #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
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
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
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
280 static u32 ptr_value(u32 *_p)
281 {
282         return (_p) ? *_p : 0xdeadbeef;
283 }
284
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
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
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
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
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
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
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
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
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
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
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
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
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 );