]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/crypto/caam/ctrl.c
d5fe5f57108c6ffffea606630138bbe2e8e8fa21
[karo-tx-linux.git] / drivers / crypto / caam / ctrl.c
1 /*
2  * CAAM control-plane driver backend
3  * Controller-level driver, kernel property detection, initialization
4  *
5  * Copyright 2008-2012 Freescale Semiconductor, Inc.
6  */
7
8 #include "compat.h"
9 #include "regs.h"
10 #include "intern.h"
11 #include "jr.h"
12 #include "desc_constr.h"
13 #include "error.h"
14 #include "ctrl.h"
15
16 static int caam_remove(struct platform_device *pdev)
17 {
18         struct device *ctrldev;
19         struct caam_drv_private *ctrlpriv;
20         struct caam_drv_private_jr *jrpriv;
21         struct caam_full __iomem *topregs;
22         int ring, ret = 0;
23
24         ctrldev = &pdev->dev;
25         ctrlpriv = dev_get_drvdata(ctrldev);
26         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
27
28         /* shut down JobRs */
29         for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
30                 ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
31                 jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
32                 irq_dispose_mapping(jrpriv->irq);
33         }
34
35         /* Shut down debug views */
36 #ifdef CONFIG_DEBUG_FS
37         debugfs_remove_recursive(ctrlpriv->dfs_root);
38 #endif
39
40         /* Unmap controller region */
41         iounmap(&topregs->ctrl);
42
43         kfree(ctrlpriv->jrdev);
44         kfree(ctrlpriv);
45
46         return ret;
47 }
48
49 /*
50  * Descriptor to instantiate RNG State Handle 0 in normal mode and
51  * load the JDKEK, TDKEK and TDSK registers
52  */
53 static void build_instantiation_desc(u32 *desc)
54 {
55         u32 *jump_cmd;
56
57         init_job_desc(desc, 0);
58
59         /* INIT RNG in non-test mode */
60         append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
61                          OP_ALG_AS_INIT);
62
63         /* wait for done */
64         jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
65         set_jump_tgt_here(desc, jump_cmd);
66
67         /*
68          * load 1 to clear written reg:
69          * resets the done interrupt and returns the RNG to idle.
70          */
71         append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
72
73         /* generate secure keys (non-test) */
74         append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
75                          OP_ALG_RNG4_SK);
76
77         append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
78 }
79
80 static int instantiate_rng(struct device *ctrldev)
81 {
82         struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
83         struct caam_full __iomem *topregs;
84         unsigned int timeout = 100000;
85         u32 *desc, deco_dbg_reg;
86         int i, ret = 0;
87
88         desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA);
89         if (!desc) {
90                 dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
91                 return -ENOMEM;
92         }
93         build_instantiation_desc(desc);
94
95         /* Set the bit to request direct access to DECO0 */
96         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
97         setbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
98
99         while (!(rd_reg32(&topregs->ctrl.deco_rq) & DECORR_DEN0) &&
100                                                                  --timeout)
101                 cpu_relax();
102
103         if (!timeout) {
104                 dev_err(ctrldev, "failed to acquire DECO 0\n");
105                 ret = -EIO;
106                 goto out;
107         }
108
109         for (i = 0; i < desc_len(desc); i++)
110                 topregs->deco.descbuf[i] = *(desc + i);
111
112         wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
113
114         timeout = 10000000;
115         do {
116                 deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
117                 /*
118                  * If an error occured in the descriptor, then
119                  * the DECO status field will be set to 0x0D
120                  */
121                 if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
122                     DESC_DBG_DECO_STAT_HOST_ERR)
123                         break;
124                 cpu_relax();
125         } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
126
127         if (!timeout) {
128                 dev_err(ctrldev, "failed to instantiate RNG\n");
129                 ret = -EIO;
130         }
131
132         clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
133 out:
134         kfree(desc);
135         return ret;
136 }
137
138 /*
139  * kick_trng - sets the various parameters for enabling the initialization
140  *             of the RNG4 block in CAAM
141  * @pdev - pointer to the platform device
142  * @ent_delay - Defines the length (in system clocks) of each entropy sample.
143  */
144 static void kick_trng(struct platform_device *pdev, int ent_delay)
145 {
146         struct device *ctrldev = &pdev->dev;
147         struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
148         struct caam_full __iomem *topregs;
149         struct rng4tst __iomem *r4tst;
150         u32 val;
151
152         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
153         r4tst = &topregs->ctrl.r4tst[0];
154
155         /* put RNG4 into program mode */
156         setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
157
158         /*
159          * Performance-wise, it does not make sense to
160          * set the delay to a value that is lower
161          * than the last one that worked (i.e. the state handles
162          * were instantiated properly. Thus, instead of wasting
163          * time trying to set the values controlling the sample
164          * frequency, the function simply returns.
165          */
166         val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
167               >> RTSDCTL_ENT_DLY_SHIFT;
168         if (ent_delay <= val) {
169                 /* put RNG4 into run mode */
170                 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
171                 return;
172         }
173
174         val = rd_reg32(&r4tst->rtsdctl);
175         val = (val & ~RTSDCTL_ENT_DLY_MASK) |
176               (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
177         wr_reg32(&r4tst->rtsdctl, val);
178         /* min. freq. count, equal to 1/4 of the entropy sample length */
179         wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
180         /* max. freq. count, equal to 8 times the entropy sample length */
181         wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
182         /* put RNG4 into run mode */
183         clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
184 }
185
186 /**
187  * caam_get_era() - Return the ERA of the SEC on SoC, based
188  * on the SEC_VID register.
189  * Returns the ERA number (1..4) or -ENOTSUPP if the ERA is unknown.
190  * @caam_id - the value of the SEC_VID register
191  **/
192 int caam_get_era(u64 caam_id)
193 {
194         struct sec_vid *sec_vid = (struct sec_vid *)&caam_id;
195         static const struct {
196                 u16 ip_id;
197                 u8 maj_rev;
198                 u8 era;
199         } caam_eras[] = {
200                 {0x0A10, 1, 1},
201                 {0x0A10, 2, 2},
202                 {0x0A12, 1, 3},
203                 {0x0A14, 1, 3},
204                 {0x0A14, 2, 4},
205                 {0x0A16, 1, 4},
206                 {0x0A11, 1, 4}
207         };
208         int i;
209
210         for (i = 0; i < ARRAY_SIZE(caam_eras); i++)
211                 if (caam_eras[i].ip_id == sec_vid->ip_id &&
212                         caam_eras[i].maj_rev == sec_vid->maj_rev)
213                                 return caam_eras[i].era;
214
215         return -ENOTSUPP;
216 }
217 EXPORT_SYMBOL(caam_get_era);
218
219 /* Probe routine for CAAM top (controller) level */
220 static int caam_probe(struct platform_device *pdev)
221 {
222         int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN;
223         u64 caam_id;
224         struct device *dev;
225         struct device_node *nprop, *np;
226         struct caam_ctrl __iomem *ctrl;
227         struct caam_full __iomem *topregs;
228         struct caam_drv_private *ctrlpriv;
229 #ifdef CONFIG_DEBUG_FS
230         struct caam_perfmon *perfmon;
231 #endif
232         u64 cha_vid;
233
234         ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
235         if (!ctrlpriv)
236                 return -ENOMEM;
237
238         dev = &pdev->dev;
239         dev_set_drvdata(dev, ctrlpriv);
240         ctrlpriv->pdev = pdev;
241         nprop = pdev->dev.of_node;
242
243         /* Get configuration properties from device tree */
244         /* First, get register page */
245         ctrl = of_iomap(nprop, 0);
246         if (ctrl == NULL) {
247                 dev_err(dev, "caam: of_iomap() failed\n");
248                 return -ENOMEM;
249         }
250         ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl;
251
252         /* topregs used to derive pointers to CAAM sub-blocks only */
253         topregs = (struct caam_full __iomem *)ctrl;
254
255         /* Get the IRQ of the controller (for security violations only) */
256         ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
257
258         /*
259          * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
260          * long pointers in master configuration register
261          */
262         setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE |
263                   (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
264
265         if (sizeof(dma_addr_t) == sizeof(u64))
266                 if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
267                         dma_set_mask(dev, DMA_BIT_MASK(40));
268                 else
269                         dma_set_mask(dev, DMA_BIT_MASK(36));
270         else
271                 dma_set_mask(dev, DMA_BIT_MASK(32));
272
273         /*
274          * Detect and enable JobRs
275          * First, find out how many ring spec'ed, allocate references
276          * for all, then go probe each one.
277          */
278         rspec = 0;
279         for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring")
280                 rspec++;
281         if (!rspec) {
282                 /* for backward compatible with device trees */
283                 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring")
284                         rspec++;
285         }
286
287         ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
288         if (ctrlpriv->jrdev == NULL) {
289                 iounmap(&topregs->ctrl);
290                 return -ENOMEM;
291         }
292
293         ring = 0;
294         ctrlpriv->total_jobrs = 0;
295         for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
296                 caam_jr_probe(pdev, np, ring);
297                 ctrlpriv->total_jobrs++;
298                 ring++;
299         }
300         if (!ring) {
301                 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
302                         caam_jr_probe(pdev, np, ring);
303                         ctrlpriv->total_jobrs++;
304                         ring++;
305                 }
306         }
307
308         /* Check to see if QI present. If so, enable */
309         ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) &
310                                   CTPR_QI_MASK);
311         if (ctrlpriv->qi_present) {
312                 ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi;
313                 /* This is all that's required to physically enable QI */
314                 wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN);
315         }
316
317         /* If no QI and no rings specified, quit and go home */
318         if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
319                 dev_err(dev, "no queues configured, terminating\n");
320                 caam_remove(pdev);
321                 return -ENOMEM;
322         }
323
324         cha_vid = rd_reg64(&topregs->ctrl.perfmon.cha_id);
325
326         /*
327          * If SEC has RNG version >= 4 and RNG state handle has not been
328          * already instantiated, do RNG instantiation
329          */
330         if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
331             !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
332                 do {
333                         kick_trng(pdev, ent_delay);
334                         ret = instantiate_rng(dev);
335                         ent_delay += 400;
336                 } while ((ret == -EIO) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
337                 if (ret) {
338                         dev_err(dev, "failed to instantiate RNG");
339                         caam_remove(pdev);
340                         return ret;
341                 }
342
343                 /* Enable RDB bit so that RNG works faster */
344                 setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
345         }
346
347         /* NOTE: RTIC detection ought to go here, around Si time */
348
349         caam_id = rd_reg64(&topregs->ctrl.perfmon.caam_id);
350
351         /* Report "alive" for developer to see */
352         dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
353                  caam_get_era(caam_id));
354         dev_info(dev, "job rings = %d, qi = %d\n",
355                  ctrlpriv->total_jobrs, ctrlpriv->qi_present);
356
357 #ifdef CONFIG_DEBUG_FS
358         /*
359          * FIXME: needs better naming distinction, as some amalgamation of
360          * "caam" and nprop->full_name. The OF name isn't distinctive,
361          * but does separate instances
362          */
363         perfmon = (struct caam_perfmon __force *)&ctrl->perfmon;
364
365         ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL);
366         ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
367
368         /* Controller-level - performance monitor counters */
369         ctrlpriv->ctl_rq_dequeued =
370                 debugfs_create_u64("rq_dequeued",
371                                    S_IRUSR | S_IRGRP | S_IROTH,
372                                    ctrlpriv->ctl, &perfmon->req_dequeued);
373         ctrlpriv->ctl_ob_enc_req =
374                 debugfs_create_u64("ob_rq_encrypted",
375                                    S_IRUSR | S_IRGRP | S_IROTH,
376                                    ctrlpriv->ctl, &perfmon->ob_enc_req);
377         ctrlpriv->ctl_ib_dec_req =
378                 debugfs_create_u64("ib_rq_decrypted",
379                                    S_IRUSR | S_IRGRP | S_IROTH,
380                                    ctrlpriv->ctl, &perfmon->ib_dec_req);
381         ctrlpriv->ctl_ob_enc_bytes =
382                 debugfs_create_u64("ob_bytes_encrypted",
383                                    S_IRUSR | S_IRGRP | S_IROTH,
384                                    ctrlpriv->ctl, &perfmon->ob_enc_bytes);
385         ctrlpriv->ctl_ob_prot_bytes =
386                 debugfs_create_u64("ob_bytes_protected",
387                                    S_IRUSR | S_IRGRP | S_IROTH,
388                                    ctrlpriv->ctl, &perfmon->ob_prot_bytes);
389         ctrlpriv->ctl_ib_dec_bytes =
390                 debugfs_create_u64("ib_bytes_decrypted",
391                                    S_IRUSR | S_IRGRP | S_IROTH,
392                                    ctrlpriv->ctl, &perfmon->ib_dec_bytes);
393         ctrlpriv->ctl_ib_valid_bytes =
394                 debugfs_create_u64("ib_bytes_validated",
395                                    S_IRUSR | S_IRGRP | S_IROTH,
396                                    ctrlpriv->ctl, &perfmon->ib_valid_bytes);
397
398         /* Controller level - global status values */
399         ctrlpriv->ctl_faultaddr =
400                 debugfs_create_u64("fault_addr",
401                                    S_IRUSR | S_IRGRP | S_IROTH,
402                                    ctrlpriv->ctl, &perfmon->faultaddr);
403         ctrlpriv->ctl_faultdetail =
404                 debugfs_create_u32("fault_detail",
405                                    S_IRUSR | S_IRGRP | S_IROTH,
406                                    ctrlpriv->ctl, &perfmon->faultdetail);
407         ctrlpriv->ctl_faultstatus =
408                 debugfs_create_u32("fault_status",
409                                    S_IRUSR | S_IRGRP | S_IROTH,
410                                    ctrlpriv->ctl, &perfmon->status);
411
412         /* Internal covering keys (useful in non-secure mode only) */
413         ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0];
414         ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
415         ctrlpriv->ctl_kek = debugfs_create_blob("kek",
416                                                 S_IRUSR |
417                                                 S_IRGRP | S_IROTH,
418                                                 ctrlpriv->ctl,
419                                                 &ctrlpriv->ctl_kek_wrap);
420
421         ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0];
422         ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
423         ctrlpriv->ctl_tkek = debugfs_create_blob("tkek",
424                                                  S_IRUSR |
425                                                  S_IRGRP | S_IROTH,
426                                                  ctrlpriv->ctl,
427                                                  &ctrlpriv->ctl_tkek_wrap);
428
429         ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0];
430         ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32);
431         ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk",
432                                                  S_IRUSR |
433                                                  S_IRGRP | S_IROTH,
434                                                  ctrlpriv->ctl,
435                                                  &ctrlpriv->ctl_tdsk_wrap);
436 #endif
437         return 0;
438 }
439
440 static struct of_device_id caam_match[] = {
441         {
442                 .compatible = "fsl,sec-v4.0",
443         },
444         {
445                 .compatible = "fsl,sec4.0",
446         },
447         {},
448 };
449 MODULE_DEVICE_TABLE(of, caam_match);
450
451 static struct platform_driver caam_driver = {
452         .driver = {
453                 .name = "caam",
454                 .owner = THIS_MODULE,
455                 .of_match_table = caam_match,
456         },
457         .probe       = caam_probe,
458         .remove      = caam_remove,
459 };
460
461 module_platform_driver(caam_driver);
462
463 MODULE_LICENSE("GPL");
464 MODULE_DESCRIPTION("FSL CAAM request backend");
465 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");