ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 804-crypto-0019-MLKU-38-3-crypto-caam-add-SNVS-SECVIO-support.patch
1 From 03ec635be0eb1c1b63b1f631938d41b379dad637 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
3 Date: Mon, 30 Sep 2019 00:22:09 +0300
4 Subject: [PATCH] MLKU-38-3 crypto: caam - add SNVS / SECVIO support
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 This is a squash of the following i.MX BSP commits
10 (rel_imx_4.19.35_1.1.0_rc2)
11
12 1. 8f6a17b41917 ("ENGR00289885 [iMX6Q] Add Secure Memory and SECVIO support.")
13 2. 8433c811e97a ("MLK-9710-18 snvs - make SECVIO module device tree correct")
14 3. 35bbc34e996b ("MLK-9769-23 Replace SECVIO of_irq_to_resource() with irq_of_parse_and_map()")
15 4. 3ac6edcd92d4 ("MLK-11360-01 crypto: caam_snvs: add snvs clock management")
16 5. 9d9ca7a03e3b ("MLK-11922 i.mx6: Linux 3.14.28 CAAM & SNVS enabled by default. JTAG, DS-5 attachment causes exceptions")
17 6. fcdaabf1bba2 ("MLK-17412-01: Fix secvio driver to have same driver name as DTS")
18
19 Signed-off-by: Dan Douglass <dan.douglass@nxp.com>
20 Signed-off-by: Victoria Milhoan <vicki.milhoan@freescale.com>
21 Signed-off-by: Steve Cornelius <steve.cornelius@nxp.com>
22 Signed-off-by: Fugang Duan <andy.duan@nxp.com>
23 Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
24
25 that have been reworked:
26
27 1.
28 -make SM depend on JR
29 -enable SM, SECVIO only on i.MX SoCs
30 -fix resource leak - add off_node_put() where needed
31
32 Split commit in three:
33 - SNVS/SECVIO driver
34 - Secure Memory driver
35 - DT changes
36
37 3.
38 JR changes dropped - no longer needed, already upstream in
39 commit 549077d7d86a1 ("crypto: caam - check irq_of_parse_and_map for errors")
40
41 4.
42 Split the patch in two:
43 -DT bindings changes
44 -driver changes
45
46 5.
47 Fixed conflicts in imx7d.dtsi - added caam_sm and irq_sec_vio nodes.
48
49 Split commit in 3:
50 -SECVIO/SNVS driver changes
51 -SECVIO/SNVS DT changes
52 -Secure Memory DT changes
53
54 Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
55 ---
56  drivers/crypto/caam/Kconfig    |   7 +
57  drivers/crypto/caam/Makefile   |   1 +
58  drivers/crypto/caam/ctrl.c     |   3 -
59  drivers/crypto/caam/intern.h   |   4 +-
60  drivers/crypto/caam/secvio.c   | 342 +++++++++++++++++++++++++++++++++++++++++
61  drivers/crypto/caam/secvio.h   |  69 +++++++++
62  drivers/crypto/caam/snvsregs.h | 239 ++++++++++++++++++++++++++++
63  7 files changed, 660 insertions(+), 5 deletions(-)
64  create mode 100644 drivers/crypto/caam/secvio.c
65  create mode 100644 drivers/crypto/caam/secvio.h
66  create mode 100644 drivers/crypto/caam/snvsregs.h
67
68 --- a/drivers/crypto/caam/Kconfig
69 +++ b/drivers/crypto/caam/Kconfig
70 @@ -155,6 +155,13 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST
71           caam RNG. This test is several minutes long and executes
72           just before the RNG is registered with the hw_random API.
73  
74 +config CRYPTO_DEV_FSL_CAAM_SECVIO
75 +       tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)"
76 +       help
77 +         Enables installation of an interrupt handler with registrable
78 +          handler functions which can be specified to act on the consequences
79 +          of a security violation.
80 +
81  endif # CRYPTO_DEV_FSL_CAAM_JR
82  
83  endif # CRYPTO_DEV_FSL_CAAM
84 --- a/drivers/crypto/caam/Makefile
85 +++ b/drivers/crypto/caam/Makefile
86 @@ -21,6 +21,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRY
87  caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
88  caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
89  caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
90 +caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
91  
92  caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
93  ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
94 --- a/drivers/crypto/caam/ctrl.c
95 +++ b/drivers/crypto/caam/ctrl.c
96 @@ -719,9 +719,6 @@ iomap_ctrl:
97                          BLOCK_OFFSET * DECO_BLOCK_NUMBER
98                          );
99  
100 -       /* Get the IRQ of the controller (for security violations only) */
101 -       ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
102 -
103         if (!reg_access)
104                 goto set_dma_mask;
105  
106 --- a/drivers/crypto/caam/intern.h
107 +++ b/drivers/crypto/caam/intern.h
108 @@ -66,6 +66,7 @@ struct caam_drv_private_jr {
109   * Driver-private storage for a single CAAM block instance
110   */
111  struct caam_drv_private {
112 +
113         /* Physical-presence section */
114         struct caam_ctrl __iomem *ctrl; /* controller region */
115         struct caam_deco __iomem *deco; /* DECO/CCB views */
116 @@ -83,8 +84,7 @@ struct caam_drv_private {
117         u8 qi_present;          /* Nonzero if QI present in device */
118         u8 mc_en;               /* Nonzero if MC f/w is active */
119         u8 scu_en;              /* Nonzero if SCU f/w is active */
120 -+      u8 optee_en;            /* Nonzero if OP-TEE f/w is active */
121 -       int secvio_irq;         /* Security violation interrupt number */
122 +       u8 optee_en;            /* Nonzero if OP-TEE f/w is active */
123         int virt_en;            /* Virtualization enabled in CAAM */
124         int era;                /* CAAM Era (internal HW revision) */
125  
126 --- /dev/null
127 +++ b/drivers/crypto/caam/secvio.c
128 @@ -0,0 +1,342 @@
129 +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
130 +/*
131 + * SNVS Security Violation Handler
132 + *
133 + * Copyright 2012-2016 Freescale Semiconductor, Inc.
134 + * Copyright 2017-2019 NXP
135 + */
136 +
137 +#include "compat.h"
138 +#include "secvio.h"
139 +#include "regs.h"
140 +#include "intern.h"
141 +#include <linux/of.h>
142 +#include <linux/of_irq.h>
143 +#include <linux/of_address.h>
144 +
145 +/* The driver is matched with node caam_snvs to get regmap
146 + * It will then retrieve interruption and tamper alarm configuration from
147 + * node caam-secvio searching for the compat string "fsl,imx6q-caam-secvio"
148 + */
149 +#define DRIVER_NAME "caam-snvs"
150 +
151 +/*
152 + * These names are associated with each violation handler.
153 + * The source names were taken from MX6, and are based on recommendations
154 + * for most common SoCs.
155 + */
156 +static const u8 *violation_src_name[] = {
157 +       "CAAM Internal Security Violation",
158 +       "JTAG Alarm",
159 +       "Watchdog",
160 +       "(reserved)",
161 +       "External Boot",
162 +       "External Tamper Detect",
163 +};
164 +
165 +/* These names help describe security monitor state for the console */
166 +static const u8 *snvs_ssm_state_name[] = {
167 +       "init",
168 +       "hard fail",
169 +       "(undef:2)",
170 +       "soft fail",
171 +       "(undef:4)",
172 +       "(undef:5)",
173 +       "(undef:6)",
174 +       "(undef:7)",
175 +       "transition",
176 +       "check",
177 +       "(undef:10)",
178 +       "non-secure",
179 +       "(undef:12)",
180 +       "trusted",
181 +       "(undef:14)",
182 +       "secure",
183 +};
184 +
185 +/* Top-level security violation interrupt */
186 +static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev)
187 +{
188 +       struct device *dev = snvsdev;
189 +       struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
190 +
191 +       clk_enable(svpriv->clk);
192 +       /* Check the HP secvio status register */
193 +       svpriv->irqcause = rd_reg32(&svpriv->svregs->hp.secvio_status) &
194 +                                   HP_SECVIOST_SECVIOMASK;
195 +
196 +       if (!svpriv->irqcause) {
197 +               clk_disable(svpriv->clk);
198 +               return IRQ_NONE;
199 +       }
200 +
201 +       /* Now ACK cause */
202 +       clrsetbits_32(&svpriv->svregs->hp.secvio_status, 0, svpriv->irqcause);
203 +
204 +       /* And run deferred service */
205 +       preempt_disable();
206 +       tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
207 +       preempt_enable();
208 +
209 +       clk_disable(svpriv->clk);
210 +
211 +       return IRQ_HANDLED;
212 +}
213 +
214 +/* Deferred service handler. Tasklet arg is simply the SNVS dev */
215 +static void snvs_secvio_dispatch(unsigned long indev)
216 +{
217 +       struct device *dev = (struct device *)indev;
218 +       struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
219 +       unsigned long flags;
220 +       int i;
221 +
222 +
223 +       /* Look through stored causes, call each handler if exists */
224 +       for (i = 0; i < MAX_SECVIO_SOURCES; i++)
225 +               if (svpriv->irqcause & (1 << i)) {
226 +                       spin_lock_irqsave(&svpriv->svlock, flags);
227 +                       svpriv->intsrc[i].handler(dev, i,
228 +                                                 svpriv->intsrc[i].ext);
229 +                       spin_unlock_irqrestore(&svpriv->svlock, flags);
230 +               };
231 +
232 +       /* Re-enable now-serviced interrupts */
233 +       clrsetbits_32(&svpriv->svregs->hp.secvio_intcfg, 0, svpriv->irqcause);
234 +}
235 +
236 +/*
237 + * Default cause handler, used in lieu of an application-defined handler.
238 + * All it does at this time is print a console message. It could force a halt.
239 + */
240 +static void snvs_secvio_default(struct device *dev, u32 cause, void *ext)
241 +{
242 +       struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
243 +
244 +       dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
245 +               cause, svpriv->intsrc[cause].intname);
246 +}
247 +
248 +/*
249 + * Install an application-defined handler for a specified cause
250 + * Arguments:
251 + * - dev        points to SNVS-owning device
252 + * - cause      interrupt source cause
253 + * - handler    application-defined handler, gets called with dev
254 + *              source cause, and locally-defined handler argument
255 + * - cause_description   points to a string to override the default cause
256 + *                       name, this can be used as an alternate for error
257 + *                       messages and such. If left NULL, the default
258 + *                       description string is used.
259 + * - ext        pointer to any extra data needed by the handler.
260 + */
261 +int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
262 +                               void (*handler)(struct device *dev, u32 cause,
263 +                                               void *ext),
264 +                               u8 *cause_description, void *ext)
265 +{
266 +       unsigned long flags;
267 +       struct snvs_secvio_drv_private *svpriv;
268 +
269 +       svpriv = dev_get_drvdata(dev);
270 +
271 +       if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
272 +               return -EINVAL;
273 +
274 +       spin_lock_irqsave(&svpriv->svlock, flags);
275 +       svpriv->intsrc[cause].handler = handler;
276 +       if (cause_description != NULL)
277 +               svpriv->intsrc[cause].intname = cause_description;
278 +       if (ext != NULL)
279 +               svpriv->intsrc[cause].ext = ext;
280 +       spin_unlock_irqrestore(&svpriv->svlock, flags);
281 +
282 +       return 0;
283 +}
284 +EXPORT_SYMBOL(snvs_secvio_install_handler);
285 +
286 +/*
287 + * Remove an application-defined handler for a specified cause (and, by
288 + * implication, restore the "default".
289 + * Arguments:
290 + * - dev       points to SNVS-owning device
291 + * - cause     interrupt source cause
292 + */
293 +int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
294 +{
295 +       unsigned long flags;
296 +       struct snvs_secvio_drv_private *svpriv;
297 +
298 +       svpriv = dev_get_drvdata(dev);
299 +
300 +       if (cause > SECVIO_CAUSE_SOURCE_5)
301 +               return -EINVAL;
302 +
303 +       spin_lock_irqsave(&svpriv->svlock, flags);
304 +       svpriv->intsrc[cause].intname = violation_src_name[cause];
305 +       svpriv->intsrc[cause].handler = snvs_secvio_default;
306 +       svpriv->intsrc[cause].ext = NULL;
307 +       spin_unlock_irqrestore(&svpriv->svlock, flags);
308 +       return 0;
309 +}
310 +EXPORT_SYMBOL(snvs_secvio_remove_handler);
311 +
312 +static int snvs_secvio_remove(struct platform_device *pdev)
313 +{
314 +       struct device *svdev;
315 +       struct snvs_secvio_drv_private *svpriv;
316 +       int i;
317 +
318 +       svdev = &pdev->dev;
319 +       svpriv = dev_get_drvdata(svdev);
320 +
321 +       clk_enable(svpriv->clk);
322 +       /* Set all sources to nonfatal */
323 +       wr_reg32(&svpriv->svregs->hp.secvio_intcfg, 0);
324 +
325 +       /* Remove tasklets and release interrupt */
326 +       for_each_possible_cpu(i)
327 +               tasklet_kill(&svpriv->irqtask[i]);
328 +
329 +       clk_disable_unprepare(svpriv->clk);
330 +       free_irq(svpriv->irq, svdev);
331 +       iounmap(svpriv->svregs);
332 +       kfree(svpriv);
333 +
334 +       return 0;
335 +}
336 +
337 +static int snvs_secvio_probe(struct platform_device *pdev)
338 +{
339 +       struct device *svdev;
340 +       struct snvs_secvio_drv_private *svpriv;
341 +       struct device_node *np, *npirq;
342 +       struct snvs_full __iomem *snvsregs;
343 +       int i, error;
344 +       u32 hpstate;
345 +       const void *jtd, *wtd, *itd, *etd;
346 +       u32 td_en;
347 +
348 +       svpriv = kzalloc(sizeof(struct snvs_secvio_drv_private), GFP_KERNEL);
349 +       if (!svpriv)
350 +               return -ENOMEM;
351 +
352 +       svdev = &pdev->dev;
353 +       dev_set_drvdata(svdev, svpriv);
354 +       svpriv->pdev = pdev;
355 +       np = pdev->dev.of_node;
356 +
357 +       npirq = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
358 +       if (!npirq) {
359 +               dev_err(svdev, "can't find secvio node\n");
360 +               kfree(svpriv);
361 +               return -EINVAL;
362 +       }
363 +       svpriv->irq = irq_of_parse_and_map(npirq, 0);
364 +       if (svpriv->irq <= 0) {
365 +               dev_err(svdev, "can't identify secvio interrupt\n");
366 +               kfree(svpriv);
367 +               return -EINVAL;
368 +       }
369 +
370 +       jtd = of_get_property(npirq, "jtag-tamper", NULL);
371 +       wtd = of_get_property(npirq, "watchdog-tamper", NULL);
372 +       itd = of_get_property(npirq, "internal-boot-tamper", NULL);
373 +       etd = of_get_property(npirq, "external-pin-tamper", NULL);
374 +       if (!jtd | !wtd | !itd | !etd ) {
375 +               dev_err(svdev, "can't identify all tamper alarm configuration\n");
376 +               kfree(svpriv);
377 +               return -EINVAL;
378 +       }
379 +
380 +       /*
381 +        * Configure all sources  according to device tree property.
382 +        * If the property is enabled then the source is ser as
383 +        * fatal violations except LP section,
384 +        * source #5 (typically used as an external tamper detect), and
385 +        * source #3 (typically unused). Whenever the transition to
386 +        * secure mode has occurred, these will now be "fatal" violations
387 +        */
388 +       td_en = HP_SECVIO_INTEN_SRC0;
389 +       if (!strcmp(jtd, "enabled"))
390 +               td_en |= HP_SECVIO_INTEN_SRC1;
391 +       if (!strcmp(wtd, "enabled"))
392 +               td_en |= HP_SECVIO_INTEN_SRC2;
393 +       if (!strcmp(itd, "enabled"))
394 +               td_en |= HP_SECVIO_INTEN_SRC4;
395 +       if (!strcmp(etd, "enabled"))
396 +               td_en |= HP_SECVIO_INTEN_SRC5;
397 +
398 +       snvsregs = of_iomap(np, 0);
399 +       if (!snvsregs) {
400 +               dev_err(svdev, "register mapping failed\n");
401 +               return -ENOMEM;
402 +       }
403 +       svpriv->svregs = (struct snvs_full __force *)snvsregs;
404 +
405 +       svpriv->clk = devm_clk_get(&pdev->dev, NULL);
406 +       if (IS_ERR(svpriv->clk)) {
407 +               dev_err(&pdev->dev, "can't get snvs clock\n");
408 +               svpriv->clk = NULL;
409 +       }
410 +
411 +       /* Write the Secvio Enable Config the SVCR */
412 +       wr_reg32(&svpriv->svregs->hp.secvio_ctl, td_en);
413 +       wr_reg32(&svpriv->svregs->hp.secvio_intcfg, td_en);
414 +
415 +        /* Device data set up. Now init interrupt source descriptions */
416 +       for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
417 +               svpriv->intsrc[i].intname = violation_src_name[i];
418 +               svpriv->intsrc[i].handler = snvs_secvio_default;
419 +       }
420 +       /* Connect main handler */
421 +       for_each_possible_cpu(i)
422 +               tasklet_init(&svpriv->irqtask[i], snvs_secvio_dispatch,
423 +                            (unsigned long)svdev);
424 +
425 +       error = request_irq(svpriv->irq, snvs_secvio_interrupt,
426 +                           IRQF_SHARED, DRIVER_NAME, svdev);
427 +       if (error) {
428 +               dev_err(svdev, "can't connect secvio interrupt\n");
429 +               irq_dispose_mapping(svpriv->irq);
430 +               svpriv->irq = 0;
431 +               iounmap(svpriv->svregs);
432 +               kfree(svpriv);
433 +               return -EINVAL;
434 +       }
435 +
436 +       clk_prepare_enable(svpriv->clk);
437 +
438 +       hpstate = (rd_reg32(&svpriv->svregs->hp.status) &
439 +                           HP_STATUS_SSM_ST_MASK) >> HP_STATUS_SSM_ST_SHIFT;
440 +       dev_info(svdev, "violation handlers armed - %s state\n",
441 +                snvs_ssm_state_name[hpstate]);
442 +
443 +       clk_disable(svpriv->clk);
444 +
445 +       return 0;
446 +}
447 +
448 +static struct of_device_id snvs_secvio_match[] = {
449 +       {
450 +               .compatible = "fsl,imx6q-caam-snvs",
451 +       },
452 +       {},
453 +};
454 +MODULE_DEVICE_TABLE(of, snvs_secvio_match);
455 +
456 +static struct platform_driver snvs_secvio_driver = {
457 +       .driver = {
458 +               .name = DRIVER_NAME,
459 +               .owner = THIS_MODULE,
460 +               .of_match_table = snvs_secvio_match,
461 +       },
462 +       .probe       = snvs_secvio_probe,
463 +       .remove      = snvs_secvio_remove,
464 +};
465 +
466 +module_platform_driver(snvs_secvio_driver);
467 +
468 +MODULE_LICENSE("Dual BSD/GPL");
469 +MODULE_DESCRIPTION("FSL SNVS Security Violation Handler");
470 +MODULE_AUTHOR("Freescale Semiconductor - MCU");
471 --- /dev/null
472 +++ b/drivers/crypto/caam/secvio.h
473 @@ -0,0 +1,69 @@
474 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
475 +/*
476 + * CAAM Security Violation Handler
477 + *
478 + * Copyright 2012-2015 Freescale Semiconductor, Inc.
479 + * Copyright 2016-2019 NXP
480 + */
481 +
482 +#ifndef SECVIO_H
483 +#define SECVIO_H
484 +
485 +#include "snvsregs.h"
486 +
487 +
488 +/*
489 + * Defines the published interfaces to install/remove application-specified
490 + * handlers for catching violations
491 + */
492 +
493 +#define MAX_SECVIO_SOURCES 6
494 +
495 +/* these are the untranslated causes */
496 +enum secvio_cause {
497 +       SECVIO_CAUSE_SOURCE_0,
498 +       SECVIO_CAUSE_SOURCE_1,
499 +       SECVIO_CAUSE_SOURCE_2,
500 +       SECVIO_CAUSE_SOURCE_3,
501 +       SECVIO_CAUSE_SOURCE_4,
502 +       SECVIO_CAUSE_SOURCE_5
503 +};
504 +
505 +/* These are common "recommended" cause definitions for most devices */
506 +#define SECVIO_CAUSE_CAAM_VIOLATION    SECVIO_CAUSE_SOURCE_0
507 +#define SECVIO_CAUSE_JTAG_ALARM                SECVIO_CAUSE_SOURCE_1
508 +#define SECVIO_CAUSE_WATCHDOG          SECVIO_CAUSE_SOURCE_2
509 +#define SECVIO_CAUSE_EXTERNAL_BOOT     SECVIO_CAUSE_SOURCE_4
510 +#define SECVIO_CAUSE_TAMPER_DETECT     SECVIO_CAUSE_SOURCE_5
511 +
512 +int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause,
513 +                               void (*handler)(struct device *dev, u32 cause,
514 +                                               void *ext),
515 +                               u8 *cause_description, void *ext);
516 +int snvs_secvio_remove_handler(struct device *dev, enum  secvio_cause cause);
517 +
518 +/*
519 + * Private data definitions for the secvio "driver"
520 + */
521 +
522 +struct secvio_int_src {
523 +       const u8 *intname;      /* Points to a descriptive name for source */
524 +       void *ext;              /* Extended data to pass to the handler */
525 +       void (*handler)(struct device *dev, u32 cause, void *ext);
526 +};
527 +
528 +struct snvs_secvio_drv_private {
529 +       struct platform_device *pdev;
530 +       spinlock_t svlock ____cacheline_aligned;
531 +       struct tasklet_struct irqtask[NR_CPUS];
532 +       struct snvs_full __iomem *svregs;       /* both HP and LP domains */
533 +       struct clk *clk;
534 +       int irq;
535 +       u32 irqcause; /* stashed cause of violation interrupt */
536 +
537 +       /* Registered handlers for each violation */
538 +       struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
539 +
540 +};
541 +
542 +#endif /* SECVIO_H */
543 --- /dev/null
544 +++ b/drivers/crypto/caam/snvsregs.h
545 @@ -0,0 +1,239 @@
546 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
547 +/*
548 + * SNVS hardware register-level view
549 + *
550 + * Copyright 2012-2015 Freescale Semiconductor, Inc.
551 + * Copyright 2016-2019 NXP
552 + */
553 +
554 +#ifndef SNVSREGS_H
555 +#define SNVSREGS_H
556 +
557 +#include <linux/types.h>
558 +#include <linux/io.h>
559 +
560 +/*
561 + * SNVS High Power Domain
562 + * Includes security violations, HA counter, RTC, alarm
563 + */
564 +struct snvs_hp {
565 +       u32 lock;               /* HPLR - HP Lock */
566 +       u32 cmd;                /* HPCOMR - HP Command */
567 +       u32 ctl;                /* HPCR - HP Control */
568 +       u32 secvio_intcfg;      /* HPSICR - Security Violation Int Config */
569 +       u32 secvio_ctl;         /* HPSVCR - Security Violation Control */
570 +       u32 status;             /* HPSR - HP Status */
571 +       u32 secvio_status;      /* HPSVSR - Security Violation Status */
572 +       u32 ha_counteriv;       /* High Assurance Counter IV */
573 +       u32 ha_counter;         /* High Assurance Counter */
574 +       u32 rtc_msb;            /* Real Time Clock/Counter MSB */
575 +       u32 rtc_lsb;            /* Real Time Counter LSB */
576 +       u32 time_alarm_msb;     /* Time Alarm MSB */
577 +       u32 time_alarm_lsb;     /* Time Alarm LSB */
578 +};
579 +
580 +#define HP_LOCK_HAC_LCK                0x00040000
581 +#define HP_LOCK_HPSICR_LCK     0x00020000
582 +#define HP_LOCK_HPSVCR_LCK     0x00010000
583 +#define HP_LOCK_MKEYSEL_LCK    0x00000200
584 +#define HP_LOCK_TAMPCFG_LCK    0x00000100
585 +#define HP_LOCK_TAMPFLT_LCK    0x00000080
586 +#define HP_LOCK_SECVIO_LCK     0x00000040
587 +#define HP_LOCK_GENP_LCK       0x00000020
588 +#define HP_LOCK_MONOCTR_LCK    0x00000010
589 +#define HP_LOCK_CALIB_LCK      0x00000008
590 +#define HP_LOCK_SRTC_LCK       0x00000004
591 +#define HP_LOCK_ZMK_RD_LCK     0x00000002
592 +#define HP_LOCK_ZMK_WT_LCK     0x00000001
593 +
594 +#define HP_CMD_NONPRIV_AXS     0x80000000
595 +#define HP_CMD_HAC_STOP                0x00080000
596 +#define HP_CMD_HAC_CLEAR       0x00040000
597 +#define HP_CMD_HAC_LOAD                0x00020000
598 +#define HP_CMD_HAC_CFG_EN      0x00010000
599 +#define HP_CMD_SNVS_MSTR_KEY   0x00002000
600 +#define HP_CMD_PROG_ZMK                0x00001000
601 +#define HP_CMD_SW_LPSV         0x00000400
602 +#define HP_CMD_SW_FSV          0x00000200
603 +#define HP_CMD_SW_SV           0x00000100
604 +#define HP_CMD_LP_SWR_DIS      0x00000020
605 +#define HP_CMD_LP_SWR          0x00000010
606 +#define HP_CMD_SSM_SFNS_DIS    0x00000004
607 +#define HP_CMD_SSM_ST_DIS      0x00000002
608 +#define HP_CMD_SMM_ST          0x00000001
609 +
610 +#define HP_CTL_TIME_SYNC       0x00010000
611 +#define HP_CTL_CAL_VAL_SHIFT   10
612 +#define HP_CTL_CAL_VAL_MASK    (0x1f << HP_CTL_CALIB_SHIFT)
613 +#define HP_CTL_CALIB_EN                0x00000100
614 +#define HP_CTL_PI_FREQ_SHIFT   4
615 +#define HP_CTL_PI_FREQ_MASK    (0xf << HP_CTL_PI_FREQ_SHIFT)
616 +#define HP_CTL_PI_EN           0x00000008
617 +#define HP_CTL_TIMEALARM_EN    0x00000002
618 +#define HP_CTL_RTC_EN          0x00000001
619 +
620 +#define HP_SECVIO_INTEN_EN     0x10000000
621 +#define HP_SECVIO_INTEN_SRC5   0x00000020
622 +#define HP_SECVIO_INTEN_SRC4   0x00000010
623 +#define HP_SECVIO_INTEN_SRC3   0x00000008
624 +#define HP_SECVIO_INTEN_SRC2   0x00000004
625 +#define HP_SECVIO_INTEN_SRC1   0x00000002
626 +#define HP_SECVIO_INTEN_SRC0   0x00000001
627 +#define HP_SECVIO_INTEN_ALL    0x8000003f
628 +
629 +#define HP_SECVIO_ICTL_CFG_SHIFT       30
630 +#define HP_SECVIO_ICTL_CFG_MASK                (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
631 +#define HP_SECVIO_ICTL_CFG5_SHIFT      5
632 +#define HP_SECVIO_ICTL_CFG5_MASK       (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
633 +#define HP_SECVIO_ICTL_CFG_DISABLE     0
634 +#define HP_SECVIO_ICTL_CFG_NONFATAL    1
635 +#define HP_SECVIO_ICTL_CFG_FATAL       2
636 +#define HP_SECVIO_ICTL_CFG4_FATAL      0x00000010
637 +#define HP_SECVIO_ICTL_CFG3_FATAL      0x00000008
638 +#define HP_SECVIO_ICTL_CFG2_FATAL      0x00000004
639 +#define HP_SECVIO_ICTL_CFG1_FATAL      0x00000002
640 +#define HP_SECVIO_ICTL_CFG0_FATAL      0x00000001
641 +
642 +#define HP_STATUS_ZMK_ZERO             0x80000000
643 +#define HP_STATUS_OTPMK_ZERO           0x08000000
644 +#define HP_STATUS_OTPMK_SYN_SHIFT      16
645 +#define HP_STATUS_OTPMK_SYN_MASK       (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
646 +#define HP_STATUS_SSM_ST_SHIFT         8
647 +#define HP_STATUS_SSM_ST_MASK          (0xf << HP_STATUS_SSM_ST_SHIFT)
648 +#define HP_STATUS_SSM_ST_INIT          0
649 +#define HP_STATUS_SSM_ST_HARDFAIL      1
650 +#define HP_STATUS_SSM_ST_SOFTFAIL      3
651 +#define HP_STATUS_SSM_ST_INITINT       8
652 +#define HP_STATUS_SSM_ST_CHECK         9
653 +#define HP_STATUS_SSM_ST_NONSECURE     11
654 +#define HP_STATUS_SSM_ST_TRUSTED       13
655 +#define HP_STATUS_SSM_ST_SECURE                15
656 +
657 +#define HP_SECVIOST_ZMK_ECC_FAIL       0x08000000      /* write to clear */
658 +#define HP_SECVIOST_ZMK_SYN_SHIFT      16
659 +#define HP_SECVIOST_ZMK_SYN_MASK       (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
660 +#define HP_SECVIOST_SECVIO5            0x00000020
661 +#define HP_SECVIOST_SECVIO4            0x00000010
662 +#define HP_SECVIOST_SECVIO3            0x00000008
663 +#define HP_SECVIOST_SECVIO2            0x00000004
664 +#define HP_SECVIOST_SECVIO1            0x00000002
665 +#define HP_SECVIOST_SECVIO0            0x00000001
666 +#define HP_SECVIOST_SECVIOMASK         0x0000003f
667 +
668 +/*
669 + * SNVS Low Power Domain
670 + * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
671 + */
672 +struct snvs_lp {
673 +       u32 lock;
674 +       u32 ctl;
675 +       u32 mstr_key_ctl;       /* Master Key Control */
676 +       u32 secvio_ctl;         /* Security Violation Control */
677 +       u32 tamper_filt_cfg;    /* Tamper Glitch Filters Configuration */
678 +       u32 tamper_det_cfg;     /* Tamper Detectors Configuration */
679 +       u32 status;
680 +       u32 srtc_msb;           /* Secure Real Time Clock/Counter MSB */
681 +       u32 srtc_lsb;           /* Secure Real Time Clock/Counter LSB */
682 +       u32 time_alarm;         /* Time Alarm */
683 +       u32 smc_msb;            /* Secure Monotonic Counter MSB */
684 +       u32 smc_lsb;            /* Secure Monotonic Counter LSB */
685 +       u32 pwr_glitch_det;     /* Power Glitch Detector */
686 +       u32 gen_purpose;
687 +       u32 zmk[8];             /* Zeroizable Master Key */
688 +};
689 +
690 +#define LP_LOCK_MKEYSEL_LCK    0x00000200
691 +#define LP_LOCK_TAMPDET_LCK    0x00000100
692 +#define LP_LOCK_TAMPFLT_LCK    0x00000080
693 +#define LP_LOCK_SECVIO_LCK     0x00000040
694 +#define LP_LOCK_GENP_LCK       0x00000020
695 +#define LP_LOCK_MONOCTR_LCK    0x00000010
696 +#define LP_LOCK_CALIB_LCK      0x00000008
697 +#define LP_LOCK_SRTC_LCK       0x00000004
698 +#define LP_LOCK_ZMK_RD_LCK     0x00000002
699 +#define LP_LOCK_ZMK_WT_LCK     0x00000001
700 +
701 +#define LP_CTL_CAL_VAL_SHIFT   10
702 +#define LP_CTL_CAL_VAL_MASK    (0x1f << LP_CTL_CAL_VAL_SHIFT)
703 +#define LP_CTL_CALIB_EN                0x00000100
704 +#define LP_CTL_SRTC_INVAL_EN   0x00000010
705 +#define LP_CTL_WAKE_INT_EN     0x00000008
706 +#define LP_CTL_MONOCTR_EN      0x00000004
707 +#define LP_CTL_TIMEALARM_EN    0x00000002
708 +#define LP_CTL_SRTC_EN         0x00000001
709 +
710 +#define LP_MKEYCTL_ZMKECC_SHIFT        8
711 +#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
712 +#define LP_MKEYCTL_ZMKECC_EN   0x00000010
713 +#define LP_MKEYCTL_ZMKECC_VAL  0x00000008
714 +#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
715 +#define LP_MKEYCTL_MKSEL_SHIFT 0
716 +#define LP_MKEYCTL_MKSEL_MASK  (3 << LP_MKEYCTL_MKSEL_SHIFT)
717 +#define LP_MKEYCTL_MK_OTP      0
718 +#define LP_MKEYCTL_MK_ZMK      2
719 +#define LP_MKEYCTL_MK_COMB     3
720 +
721 +#define LP_SECVIO_CTL_SRC5     0x20
722 +#define LP_SECVIO_CTL_SRC4     0x10
723 +#define LP_SECVIO_CTL_SRC3     0x08
724 +#define LP_SECVIO_CTL_SRC2     0x04
725 +#define LP_SECVIO_CTL_SRC1     0x02
726 +#define LP_SECVIO_CTL_SRC0     0x01
727 +
728 +#define LP_TAMPFILT_EXT2_EN    0x80000000
729 +#define LP_TAMPFILT_EXT2_SHIFT 24
730 +#define LP_TAMPFILT_EXT2_MASK  (0x1f << LP_TAMPFILT_EXT2_SHIFT)
731 +#define LP_TAMPFILT_EXT1_EN    0x00800000
732 +#define LP_TAMPFILT_EXT1_SHIFT 16
733 +#define LP_TAMPFILT_EXT1_MASK  (0x1f << LP_TAMPFILT_EXT1_SHIFT)
734 +#define LP_TAMPFILT_WM_EN      0x00000080
735 +#define LP_TAMPFILT_WM_SHIFT   0
736 +#define LP_TAMPFILT_WM_MASK    (0x1f << LP_TAMPFILT_WM_SHIFT)
737 +
738 +#define LP_TAMPDET_OSC_BPS     0x10000000
739 +#define LP_TAMPDET_VRC_SHIFT   24
740 +#define LP_TAMPDET_VRC_MASK    (3 << LP_TAMPFILT_VRC_SHIFT)
741 +#define LP_TAMPDET_HTDC_SHIFT  20
742 +#define LP_TAMPDET_HTDC_MASK   (3 << LP_TAMPFILT_HTDC_SHIFT)
743 +#define LP_TAMPDET_LTDC_SHIFT  16
744 +#define LP_TAMPDET_LTDC_MASK   (3 << LP_TAMPFILT_LTDC_SHIFT)
745 +#define LP_TAMPDET_POR_OBS     0x00008000
746 +#define LP_TAMPDET_PFD_OBS     0x00004000
747 +#define LP_TAMPDET_ET2_EN      0x00000400
748 +#define LP_TAMPDET_ET1_EN      0x00000200
749 +#define LP_TAMPDET_WMT2_EN     0x00000100
750 +#define LP_TAMPDET_WMT1_EN     0x00000080
751 +#define LP_TAMPDET_VT_EN       0x00000040
752 +#define LP_TAMPDET_TT_EN       0x00000020
753 +#define LP_TAMPDET_CT_EN       0x00000010
754 +#define LP_TAMPDET_MCR_EN      0x00000004
755 +#define LP_TAMPDET_SRTCR_EN    0x00000002
756 +
757 +#define LP_STATUS_SECURE
758 +#define LP_STATUS_NONSECURE
759 +#define LP_STATUS_SCANEXIT     0x00100000      /* all write 1 clear here on */
760 +#define LP_STATUS_EXT_SECVIO   0x00010000
761 +#define LP_STATUS_ET2          0x00000400
762 +#define LP_STATUS_ET1          0x00000200
763 +#define LP_STATUS_WMT2         0x00000100
764 +#define LP_STATUS_WMT1         0x00000080
765 +#define LP_STATUS_VTD          0x00000040
766 +#define LP_STATUS_TTD          0x00000020
767 +#define LP_STATUS_CTD          0x00000010
768 +#define LP_STATUS_PGD          0x00000008
769 +#define LP_STATUS_MCR          0x00000004
770 +#define LP_STATUS_SRTCR                0x00000002
771 +#define LP_STATUS_LPTA         0x00000001
772 +
773 +/* Full SNVS register page, including version/options */
774 +struct snvs_full {
775 +       struct snvs_hp hp;
776 +       struct snvs_lp lp;
777 +       u32 rsvd[731];          /* deadspace 0x08c-0xbf7 */
778 +
779 +       /* Version / Revision / Option ID space - end of register page */
780 +       u32 vid;                /* 0xbf8 HP Version ID (VID 1) */
781 +       u32 opt_rev;            /* 0xbfc HP Options / Revision (VID 2) */
782 +};
783 +
784 +#endif /* SNVSREGS_H */