diff options
Diffstat (limited to 'drivers/crypto/caam/ctrl.c')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 129 |
1 files changed, 127 insertions, 2 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 9a2db9c30630..ac6abb375c8d 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -2,13 +2,15 @@ | |||
2 | * CAAM control-plane driver backend | 2 | * CAAM control-plane driver backend |
3 | * Controller-level driver, kernel property detection, initialization | 3 | * Controller-level driver, kernel property detection, initialization |
4 | * | 4 | * |
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | 5 | * Copyright 2008-2012 Freescale Semiconductor, Inc. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "compat.h" | 8 | #include "compat.h" |
9 | #include "regs.h" | 9 | #include "regs.h" |
10 | #include "intern.h" | 10 | #include "intern.h" |
11 | #include "jr.h" | 11 | #include "jr.h" |
12 | #include "desc_constr.h" | ||
13 | #include "error.h" | ||
12 | 14 | ||
13 | static int caam_remove(struct platform_device *pdev) | 15 | static int caam_remove(struct platform_device *pdev) |
14 | { | 16 | { |
@@ -43,10 +45,120 @@ static int caam_remove(struct platform_device *pdev) | |||
43 | return ret; | 45 | return ret; |
44 | } | 46 | } |
45 | 47 | ||
48 | /* | ||
49 | * Descriptor to instantiate RNG State Handle 0 in normal mode and | ||
50 | * load the JDKEK, TDKEK and TDSK registers | ||
51 | */ | ||
52 | static void build_instantiation_desc(u32 *desc) | ||
53 | { | ||
54 | u32 *jump_cmd; | ||
55 | |||
56 | init_job_desc(desc, 0); | ||
57 | |||
58 | /* INIT RNG in non-test mode */ | ||
59 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | ||
60 | OP_ALG_AS_INIT); | ||
61 | |||
62 | /* wait for done */ | ||
63 | jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1); | ||
64 | set_jump_tgt_here(desc, jump_cmd); | ||
65 | |||
66 | /* | ||
67 | * load 1 to clear written reg: | ||
68 | * resets the done interrrupt and returns the RNG to idle. | ||
69 | */ | ||
70 | append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); | ||
71 | |||
72 | /* generate secure keys (non-test) */ | ||
73 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | ||
74 | OP_ALG_RNG4_SK); | ||
75 | } | ||
76 | |||
77 | struct instantiate_result { | ||
78 | struct completion completion; | ||
79 | int err; | ||
80 | }; | ||
81 | |||
82 | static void rng4_init_done(struct device *dev, u32 *desc, u32 err, | ||
83 | void *context) | ||
84 | { | ||
85 | struct instantiate_result *instantiation = context; | ||
86 | |||
87 | if (err) { | ||
88 | char tmp[CAAM_ERROR_STR_MAX]; | ||
89 | |||
90 | dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); | ||
91 | } | ||
92 | |||
93 | instantiation->err = err; | ||
94 | complete(&instantiation->completion); | ||
95 | } | ||
96 | |||
97 | static int instantiate_rng(struct device *jrdev) | ||
98 | { | ||
99 | struct instantiate_result instantiation; | ||
100 | |||
101 | dma_addr_t desc_dma; | ||
102 | u32 *desc; | ||
103 | int ret; | ||
104 | |||
105 | desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA); | ||
106 | if (!desc) { | ||
107 | dev_err(jrdev, "cannot allocate RNG init descriptor memory\n"); | ||
108 | return -ENOMEM; | ||
109 | } | ||
110 | |||
111 | build_instantiation_desc(desc); | ||
112 | desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc), DMA_TO_DEVICE); | ||
113 | init_completion(&instantiation.completion); | ||
114 | ret = caam_jr_enqueue(jrdev, desc, rng4_init_done, &instantiation); | ||
115 | if (!ret) { | ||
116 | wait_for_completion_interruptible(&instantiation.completion); | ||
117 | ret = instantiation.err; | ||
118 | if (ret) | ||
119 | dev_err(jrdev, "unable to instantiate RNG\n"); | ||
120 | } | ||
121 | |||
122 | dma_unmap_single(jrdev, desc_dma, desc_bytes(desc), DMA_TO_DEVICE); | ||
123 | |||
124 | kfree(desc); | ||
125 | |||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * By default, the TRNG runs for 200 clocks per sample; | ||
131 | * 800 clocks per sample generates better entropy. | ||
132 | */ | ||
133 | static void kick_trng(struct platform_device *pdev) | ||
134 | { | ||
135 | struct device *ctrldev = &pdev->dev; | ||
136 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | ||
137 | struct caam_full __iomem *topregs; | ||
138 | struct rng4tst __iomem *r4tst; | ||
139 | u32 val; | ||
140 | |||
141 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | ||
142 | r4tst = &topregs->ctrl.r4tst[0]; | ||
143 | |||
144 | /* put RNG4 into program mode */ | ||
145 | setbits32(&r4tst->rtmctl, RTMCTL_PRGM); | ||
146 | /* 800 clocks per sample */ | ||
147 | val = rd_reg32(&r4tst->rtsdctl); | ||
148 | val = (val & ~RTSDCTL_ENT_DLY_MASK) | (800 << RTSDCTL_ENT_DLY_SHIFT); | ||
149 | wr_reg32(&r4tst->rtsdctl, val); | ||
150 | /* min. freq. count */ | ||
151 | wr_reg32(&r4tst->rtfrqmin, 400); | ||
152 | /* max. freq. count */ | ||
153 | wr_reg32(&r4tst->rtfrqmax, 6400); | ||
154 | /* put RNG4 into run mode */ | ||
155 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); | ||
156 | } | ||
157 | |||
46 | /* Probe routine for CAAM top (controller) level */ | 158 | /* Probe routine for CAAM top (controller) level */ |
47 | static int caam_probe(struct platform_device *pdev) | 159 | static int caam_probe(struct platform_device *pdev) |
48 | { | 160 | { |
49 | int ring, rspec; | 161 | int ret, ring, rspec; |
50 | struct device *dev; | 162 | struct device *dev; |
51 | struct device_node *nprop, *np; | 163 | struct device_node *nprop, *np; |
52 | struct caam_ctrl __iomem *ctrl; | 164 | struct caam_ctrl __iomem *ctrl; |
@@ -146,6 +258,19 @@ static int caam_probe(struct platform_device *pdev) | |||
146 | return -ENOMEM; | 258 | return -ENOMEM; |
147 | } | 259 | } |
148 | 260 | ||
261 | /* | ||
262 | * RNG4 based SECs (v5+) need special initialization prior | ||
263 | * to executing any descriptors | ||
264 | */ | ||
265 | if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) { | ||
266 | kick_trng(pdev); | ||
267 | ret = instantiate_rng(ctrlpriv->jrdev[0]); | ||
268 | if (ret) { | ||
269 | caam_remove(pdev); | ||
270 | return ret; | ||
271 | } | ||
272 | } | ||
273 | |||
149 | /* NOTE: RTIC detection ought to go here, around Si time */ | 274 | /* NOTE: RTIC detection ought to go here, around Si time */ |
150 | 275 | ||
151 | /* Initialize queue allocator lock */ | 276 | /* Initialize queue allocator lock */ |