blob: 1eaa68f8d5ff88e3bbd1eb9b23b73994772b5273 [file] [log] [blame]
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +02001// 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>
Peng Fan2e0644a2023-04-28 12:08:09 +080018#include <firmware/imx/sci/sci.h>
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +020019#include <asm/arch-imx8/imx8-pins.h>
20#include <asm/arch-imx8/snvs_security_sc.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060021#include <asm/global_data.h>
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +020022
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{
Peng Fan25b7eb42023-06-15 18:08:58 +0800289 int err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200290 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
Peng Fan25b7eb42023-06-15 18:08:58 +0800296 err = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, &d4, &d4, _cnt);
297 if (err) {
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200298 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:
Peng Fan25b7eb42023-06-15 18:08:58 +0800317 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200318}
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{
Peng Fan25b7eb42023-06-15 18:08:58 +0800325 int err = 0;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200326
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
Peng Fan25b7eb42023-06-15 18:08:58 +0800367 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)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200373 goto exit;
374
375 /* Configure AT */
Peng Fan25b7eb42023-06-15 18:08:58 +0800376 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)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200383 goto exit;
384
385 /* Configure AT routing */
Peng Fan25b7eb42023-06-15 18:08:58 +0800386 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)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200391 goto exit;
392
393 /* Configure AT frequency */
Peng Fan25b7eb42023-06-15 18:08:58 +0800394 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
395 &cnf->lp.act_tamper_clk_ctl);
396 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200397 goto exit;
398
399 /* Activate the ATs */
Peng Fan25b7eb42023-06-15 18:08:58 +0800400 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), &cnf->lp.act_tamper_ctl);
401 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200402 goto exit;
403
404 /* Activate the detectors */
Peng Fan25b7eb42023-06-15 18:08:58 +0800405 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)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200409 goto exit;
410
411 /* Configure LP secvio */
Peng Fan25b7eb42023-06-15 18:08:58 +0800412 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), &cnf->lp.secvio_ctl);
413 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200414 goto exit;
415
416 /* Configure HP secvio */
Peng Fan25b7eb42023-06-15 18:08:58 +0800417 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), &cnf->hp.secvio_ctl);
418 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200419 goto exit;
420
421 /* Lock access */
Peng Fan25b7eb42023-06-15 18:08:58 +0800422 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
423 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200424 goto exit;
425
Peng Fan25b7eb42023-06-15 18:08:58 +0800426 err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
427 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200428 goto exit;
429
430exit:
Peng Fan25b7eb42023-06-15 18:08:58 +0800431 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200432}
433
434static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
435{
Peng Fan25b7eb42023-06-15 18:08:58 +0800436 int err = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200437
Peng Fan25b7eb42023-06-15 18:08:58 +0800438 if (err) {
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200439 printf("Failed to set dgo configuration\n");
440 debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
441 }
442
Peng Fan25b7eb42023-06-15 18:08:58 +0800443 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200444}
445
446static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
447{
Peng Fan25b7eb42023-06-15 18:08:58 +0800448 int err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200449
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
Peng Fan25b7eb42023-06-15 18:08:58 +0800466 err = dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
467 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200468 goto exit;
469
Peng Fan25b7eb42023-06-15 18:08:58 +0800470 err = dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
471 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200472 goto exit;
473
Peng Fan25b7eb42023-06-15 18:08:58 +0800474 err = dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
475 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200476 goto exit;
477
Peng Fan25b7eb42023-06-15 18:08:58 +0800478 err = dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
479 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200480 goto exit;
481
Peng Fan25b7eb42023-06-15 18:08:58 +0800482 err = dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
483 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200484 goto exit;
485
486 /* Last as it could lock the writes */
Peng Fan25b7eb42023-06-15 18:08:58 +0800487 err = dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
488 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200489 goto exit;
490
491exit:
Peng Fan25b7eb42023-06-15 18:08:58 +0800492 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200493}
494
495static int pad_write(u32 _pad, u32 _value)
496{
Peng Fan25b7eb42023-06-15 18:08:58 +0800497 int err = sc_pad_set(-1, _pad, _value);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200498
Peng Fan25b7eb42023-06-15 18:08:58 +0800499 if (err) {
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200500 printf("Failed to set pad configuration\n");
501 debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
502 }
503
Peng Fan25b7eb42023-06-15 18:08:58 +0800504 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200505}
506
507static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
508{
Peng Fan25b7eb42023-06-15 18:08:58 +0800509 int err = 0;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200510 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);
Peng Fan25b7eb42023-06-15 18:08:58 +0800517 err = pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
518 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200519 goto exit;
520 }
521
522exit:
Peng Fan25b7eb42023-06-15 18:08:58 +0800523 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200524}
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
Simon Glassed38aef2020-05-10 11:40:03 -0600625static int do_snvs_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
626 char *const argv[])
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200627{
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
Simon Glass3ff49ec2021-07-24 09:03:29 -0600636 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);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200654
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
Simon Glassed38aef2020-05-10 11:40:03 -0600677static int do_snvs_dgo_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200678 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
Simon Glass3ff49ec2021-07-24 09:03:29 -0600688 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);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200694
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
Simon Glassed38aef2020-05-10 11:40:03 -0600713static int do_tamper_pin_cfg(struct cmd_tbl *cmdtp, int flag, int argc,
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200714 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
Simon Glassff9b9032021-07-24 09:03:30 -0600724 conf.pad = dectoul(argv[++idx], NULL);
Simon Glass3ff49ec2021-07-24 09:03:29 -0600725 conf.mux_conf = hextoul(argv[++idx], NULL);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200726
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
Simon Glassed38aef2020-05-10 11:40:03 -0600748static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
749 char *const argv[])
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200750{
Peng Fan25b7eb42023-06-15 18:08:58 +0800751 int err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200752 u32 idx = 0;
753
754 struct snvs_security_sc_conf conf = {0};
755
756 if (argc != (2 + 1))
757 return CMD_RET_USAGE;
758
Simon Glass3ff49ec2021-07-24 09:03:29 -0600759 conf.lp.status = hextoul(argv[++idx], NULL);
760 conf.lp.tamper_det_status = hextoul(argv[++idx], NULL);
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200761
Peng Fan25b7eb42023-06-15 18:08:58 +0800762 err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
763 &conf.lp.status, NULL, NULL, NULL, NULL, 1);
764 if (err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200765 goto exit;
766
Peng Fan25b7eb42023-06-15 18:08:58 +0800767 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)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200770 goto exit;
771
772exit:
Peng Fan25b7eb42023-06-15 18:08:58 +0800773 return err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200774}
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
Simon Glassed38aef2020-05-10 11:40:03 -0600786static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200787 char *const argv[])
788{
Peng Fan25b7eb42023-06-15 18:08:58 +0800789 int err;
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200790 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
Peng Fan25b7eb42023-06-15 18:08:58 +0800860 err = sc_pad_get(-1, pad_id, &data[0]);
861 if (!err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200862 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
Peng Fan25b7eb42023-06-15 18:08:58 +0800872 err = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
873 if (!err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200874 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
Peng Fan25b7eb42023-06-15 18:08:58 +0800884 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) {
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200888 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
Peng Fan25b7eb42023-06-15 18:08:58 +0800904 err = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
905 if (!err)
Franck LENORMANDd3b70ea2019-10-09 10:27:43 +0200906 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);