diff options
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 63 | ||||
-rw-r--r-- | drivers/crypto/caam/regs.h | 7 |
2 files changed, 52 insertions, 18 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 11c7f295857b..d5fe5f57108c 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -82,7 +82,7 @@ static int instantiate_rng(struct device *ctrldev) | |||
82 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | 82 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); |
83 | struct caam_full __iomem *topregs; | 83 | struct caam_full __iomem *topregs; |
84 | unsigned int timeout = 100000; | 84 | unsigned int timeout = 100000; |
85 | u32 *desc; | 85 | u32 *desc, deco_dbg_reg; |
86 | int i, ret = 0; | 86 | int i, ret = 0; |
87 | 87 | ||
88 | desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA); | 88 | desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA); |
@@ -112,9 +112,17 @@ static int instantiate_rng(struct device *ctrldev) | |||
112 | wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR); | 112 | wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR); |
113 | 113 | ||
114 | timeout = 10000000; | 114 | timeout = 10000000; |
115 | while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) && | 115 | do { |
116 | --timeout) | 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; | ||
117 | cpu_relax(); | 124 | cpu_relax(); |
125 | } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); | ||
118 | 126 | ||
119 | if (!timeout) { | 127 | if (!timeout) { |
120 | dev_err(ctrldev, "failed to instantiate RNG\n"); | 128 | dev_err(ctrldev, "failed to instantiate RNG\n"); |
@@ -128,10 +136,12 @@ out: | |||
128 | } | 136 | } |
129 | 137 | ||
130 | /* | 138 | /* |
131 | * By default, the TRNG runs for 200 clocks per sample; | 139 | * kick_trng - sets the various parameters for enabling the initialization |
132 | * 1600 clocks per sample generates better entropy. | 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. | ||
133 | */ | 143 | */ |
134 | static void kick_trng(struct platform_device *pdev) | 144 | static void kick_trng(struct platform_device *pdev, int ent_delay) |
135 | { | 145 | { |
136 | struct device *ctrldev = &pdev->dev; | 146 | struct device *ctrldev = &pdev->dev; |
137 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | 147 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); |
@@ -144,14 +154,31 @@ static void kick_trng(struct platform_device *pdev) | |||
144 | 154 | ||
145 | /* put RNG4 into program mode */ | 155 | /* put RNG4 into program mode */ |
146 | setbits32(&r4tst->rtmctl, RTMCTL_PRGM); | 156 | setbits32(&r4tst->rtmctl, RTMCTL_PRGM); |
147 | /* 1600 clocks per sample */ | 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 | |||
148 | val = rd_reg32(&r4tst->rtsdctl); | 174 | val = rd_reg32(&r4tst->rtsdctl); |
149 | val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT); | 175 | val = (val & ~RTSDCTL_ENT_DLY_MASK) | |
176 | (ent_delay << RTSDCTL_ENT_DLY_SHIFT); | ||
150 | wr_reg32(&r4tst->rtsdctl, val); | 177 | wr_reg32(&r4tst->rtsdctl, val); |
151 | /* min. freq. count */ | 178 | /* min. freq. count, equal to 1/4 of the entropy sample length */ |
152 | wr_reg32(&r4tst->rtfrqmin, 400); | 179 | wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2); |
153 | /* max. freq. count */ | 180 | /* max. freq. count, equal to 8 times the entropy sample length */ |
154 | wr_reg32(&r4tst->rtfrqmax, 6400); | 181 | wr_reg32(&r4tst->rtfrqmax, ent_delay << 3); |
155 | /* put RNG4 into run mode */ | 182 | /* put RNG4 into run mode */ |
156 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); | 183 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); |
157 | } | 184 | } |
@@ -192,7 +219,7 @@ EXPORT_SYMBOL(caam_get_era); | |||
192 | /* Probe routine for CAAM top (controller) level */ | 219 | /* Probe routine for CAAM top (controller) level */ |
193 | static int caam_probe(struct platform_device *pdev) | 220 | static int caam_probe(struct platform_device *pdev) |
194 | { | 221 | { |
195 | int ret, ring, rspec; | 222 | int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN; |
196 | u64 caam_id; | 223 | u64 caam_id; |
197 | struct device *dev; | 224 | struct device *dev; |
198 | struct device_node *nprop, *np; | 225 | struct device_node *nprop, *np; |
@@ -298,13 +325,17 @@ static int caam_probe(struct platform_device *pdev) | |||
298 | 325 | ||
299 | /* | 326 | /* |
300 | * If SEC has RNG version >= 4 and RNG state handle has not been | 327 | * If SEC has RNG version >= 4 and RNG state handle has not been |
301 | * already instantiated ,do RNG instantiation | 328 | * already instantiated, do RNG instantiation |
302 | */ | 329 | */ |
303 | if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 && | 330 | if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 && |
304 | !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) { | 331 | !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) { |
305 | kick_trng(pdev); | 332 | do { |
306 | ret = instantiate_rng(dev); | 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)); | ||
307 | if (ret) { | 337 | if (ret) { |
338 | dev_err(dev, "failed to instantiate RNG"); | ||
308 | caam_remove(pdev); | 339 | caam_remove(pdev); |
309 | return ret; | 340 | return ret; |
310 | } | 341 | } |
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index 4455396918de..9aa9f718a6fc 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h | |||
@@ -255,6 +255,8 @@ struct rng4tst { | |||
255 | }; | 255 | }; |
256 | #define RTSDCTL_ENT_DLY_SHIFT 16 | 256 | #define RTSDCTL_ENT_DLY_SHIFT 16 |
257 | #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT) | 257 | #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT) |
258 | #define RTSDCTL_ENT_DLY_MIN 1200 | ||
259 | #define RTSDCTL_ENT_DLY_MAX 12800 | ||
258 | u32 rtsdctl; /* seed control register */ | 260 | u32 rtsdctl; /* seed control register */ |
259 | union { | 261 | union { |
260 | u32 rtsblim; /* PRGM=1: sparse bit limit register */ | 262 | u32 rtsblim; /* PRGM=1: sparse bit limit register */ |
@@ -706,12 +708,13 @@ struct caam_deco { | |||
706 | u32 rsvd29[48]; | 708 | u32 rsvd29[48]; |
707 | u32 descbuf[64]; /* DxDESB - Descriptor buffer */ | 709 | u32 descbuf[64]; /* DxDESB - Descriptor buffer */ |
708 | u32 rscvd30[193]; | 710 | u32 rscvd30[193]; |
711 | #define DESC_DBG_DECO_STAT_HOST_ERR 0x00D00000 | ||
712 | #define DESC_DBG_DECO_STAT_VALID 0x80000000 | ||
713 | #define DESC_DBG_DECO_STAT_MASK 0x00F00000 | ||
709 | u32 desc_dbg; /* DxDDR - DECO Debug Register */ | 714 | u32 desc_dbg; /* DxDDR - DECO Debug Register */ |
710 | u32 rsvd31[126]; | 715 | u32 rsvd31[126]; |
711 | }; | 716 | }; |
712 | 717 | ||
713 | /* DECO DBG Register Valid Bit*/ | ||
714 | #define DECO_DBG_VALID 0x80000000 | ||
715 | #define DECO_JQCR_WHL 0x20000000 | 718 | #define DECO_JQCR_WHL 0x20000000 |
716 | #define DECO_JQCR_FOUR 0x10000000 | 719 | #define DECO_JQCR_FOUR 0x10000000 |
717 | 720 | ||