1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) STMicroelectronics SA 2017
4 * Author: Fabien Dessenne <fabien.dessenne@st.com>
7 #include <linux/bitrev.h>
9 #include <linux/crc32.h>
10 #include <linux/crc32poly.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
18 #include <crypto/internal/hash.h>
20 #include <asm/unaligned.h>
22 #define DRIVER_NAME "stm32-crc32"
23 #define CHKSUM_DIGEST_SIZE 4
24 #define CHKSUM_BLOCK_SIZE 1
27 #define CRC_DR 0x00000000
28 #define CRC_CR 0x00000008
29 #define CRC_INIT 0x00000010
30 #define CRC_POL 0x00000014
32 /* Registers values */
33 #define CRC_CR_RESET BIT(0)
34 #define CRC_CR_REV_IN_WORD (BIT(6) | BIT(5))
35 #define CRC_CR_REV_IN_BYTE BIT(5)
36 #define CRC_CR_REV_OUT BIT(7)
37 #define CRC32C_INIT_DEFAULT 0xFFFFFFFF
39 #define CRC_AUTOSUSPEND_DELAY 50
41 static unsigned int burst_size
;
42 module_param(burst_size
, uint
, 0644);
43 MODULE_PARM_DESC(burst_size
, "Select burst byte size (0 unlimited)");
46 struct list_head list
;
53 struct stm32_crc_list
{
54 struct list_head dev_list
;
55 spinlock_t lock
; /* protect dev_list */
58 static struct stm32_crc_list crc_list
= {
59 .dev_list
= LIST_HEAD_INIT(crc_list
.dev_list
),
60 .lock
= __SPIN_LOCK_UNLOCKED(crc_list
.lock
),
63 struct stm32_crc_ctx
{
68 struct stm32_crc_desc_ctx
{
69 u32 partial
; /* crc32c: partial in first 4 bytes of that struct */
72 static int stm32_crc32_cra_init(struct crypto_tfm
*tfm
)
74 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
77 mctx
->poly
= CRC32_POLY_LE
;
81 static int stm32_crc32c_cra_init(struct crypto_tfm
*tfm
)
83 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
85 mctx
->key
= CRC32C_INIT_DEFAULT
;
86 mctx
->poly
= CRC32C_POLY_LE
;
90 static int stm32_crc_setkey(struct crypto_shash
*tfm
, const u8
*key
,
93 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(tfm
);
95 if (keylen
!= sizeof(u32
))
98 mctx
->key
= get_unaligned_le32(key
);
102 static struct stm32_crc
*stm32_crc_get_next_crc(void)
104 struct stm32_crc
*crc
;
106 spin_lock_bh(&crc_list
.lock
);
107 crc
= list_first_entry(&crc_list
.dev_list
, struct stm32_crc
, list
);
109 list_move_tail(&crc
->list
, &crc_list
.dev_list
);
110 spin_unlock_bh(&crc_list
.lock
);
115 static int stm32_crc_init(struct shash_desc
*desc
)
117 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
118 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
119 struct stm32_crc
*crc
;
122 crc
= stm32_crc_get_next_crc();
126 pm_runtime_get_sync(crc
->dev
);
128 spin_lock_irqsave(&crc
->lock
, flags
);
130 /* Reset, set key, poly and configure in bit reverse mode */
131 writel_relaxed(bitrev32(mctx
->key
), crc
->regs
+ CRC_INIT
);
132 writel_relaxed(bitrev32(mctx
->poly
), crc
->regs
+ CRC_POL
);
133 writel_relaxed(CRC_CR_RESET
| CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
136 /* Store partial result */
137 ctx
->partial
= readl_relaxed(crc
->regs
+ CRC_DR
);
139 spin_unlock_irqrestore(&crc
->lock
, flags
);
141 pm_runtime_mark_last_busy(crc
->dev
);
142 pm_runtime_put_autosuspend(crc
->dev
);
147 static int burst_update(struct shash_desc
*desc
, const u8
*d8
,
150 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
151 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
152 struct stm32_crc
*crc
;
154 crc
= stm32_crc_get_next_crc();
158 pm_runtime_get_sync(crc
->dev
);
160 if (!spin_trylock(&crc
->lock
)) {
161 /* Hardware is busy, calculate crc32 by software */
162 if (mctx
->poly
== CRC32_POLY_LE
)
163 ctx
->partial
= crc32_le(ctx
->partial
, d8
, length
);
165 ctx
->partial
= __crc32c_le(ctx
->partial
, d8
, length
);
171 * Restore previously calculated CRC for this context as init value
172 * Restore polynomial configuration
173 * Configure in register for word input data,
174 * Configure out register in reversed bit mode data.
176 writel_relaxed(bitrev32(ctx
->partial
), crc
->regs
+ CRC_INIT
);
177 writel_relaxed(bitrev32(mctx
->poly
), crc
->regs
+ CRC_POL
);
178 writel_relaxed(CRC_CR_RESET
| CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
181 if (d8
!= PTR_ALIGN(d8
, sizeof(u32
))) {
182 /* Configure for byte data */
183 writel_relaxed(CRC_CR_REV_IN_BYTE
| CRC_CR_REV_OUT
,
185 while (d8
!= PTR_ALIGN(d8
, sizeof(u32
)) && length
) {
186 writeb_relaxed(*d8
++, crc
->regs
+ CRC_DR
);
189 /* Configure for word data */
190 writel_relaxed(CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
194 for (; length
>= sizeof(u32
); d8
+= sizeof(u32
), length
-= sizeof(u32
))
195 writel_relaxed(*((u32
*)d8
), crc
->regs
+ CRC_DR
);
198 /* Configure for byte data */
199 writel_relaxed(CRC_CR_REV_IN_BYTE
| CRC_CR_REV_OUT
,
202 writeb_relaxed(*d8
++, crc
->regs
+ CRC_DR
);
205 /* Store partial result */
206 ctx
->partial
= readl_relaxed(crc
->regs
+ CRC_DR
);
208 spin_unlock(&crc
->lock
);
211 pm_runtime_mark_last_busy(crc
->dev
);
212 pm_runtime_put_autosuspend(crc
->dev
);
217 static int stm32_crc_update(struct shash_desc
*desc
, const u8
*d8
,
220 const unsigned int burst_sz
= burst_size
;
227 return burst_update(desc
, d8
, length
);
229 /* Digest first bytes not 32bit aligned at first pass in the loop */
230 size
= min_t(size_t, length
, burst_sz
+ (size_t)d8
-
231 ALIGN_DOWN((size_t)d8
, sizeof(u32
)));
232 for (rem_sz
= length
, cur
= d8
; rem_sz
;
233 rem_sz
-= size
, cur
+= size
, size
= min(rem_sz
, burst_sz
)) {
234 ret
= burst_update(desc
, cur
, size
);
242 static int stm32_crc_final(struct shash_desc
*desc
, u8
*out
)
244 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
245 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
247 /* Send computed CRC */
248 put_unaligned_le32(mctx
->poly
== CRC32C_POLY_LE
?
249 ~ctx
->partial
: ctx
->partial
, out
);
254 static int stm32_crc_finup(struct shash_desc
*desc
, const u8
*data
,
255 unsigned int length
, u8
*out
)
257 return stm32_crc_update(desc
, data
, length
) ?:
258 stm32_crc_final(desc
, out
);
261 static int stm32_crc_digest(struct shash_desc
*desc
, const u8
*data
,
262 unsigned int length
, u8
*out
)
264 return stm32_crc_init(desc
) ?: stm32_crc_finup(desc
, data
, length
, out
);
267 static unsigned int refcnt
;
268 static DEFINE_MUTEX(refcnt_lock
);
269 static struct shash_alg algs
[] = {
272 .setkey
= stm32_crc_setkey
,
273 .init
= stm32_crc_init
,
274 .update
= stm32_crc_update
,
275 .final
= stm32_crc_final
,
276 .finup
= stm32_crc_finup
,
277 .digest
= stm32_crc_digest
,
278 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
279 .digestsize
= CHKSUM_DIGEST_SIZE
,
282 .cra_driver_name
= DRIVER_NAME
,
284 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
285 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
287 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
288 .cra_module
= THIS_MODULE
,
289 .cra_init
= stm32_crc32_cra_init
,
292 /* CRC-32Castagnoli */
294 .setkey
= stm32_crc_setkey
,
295 .init
= stm32_crc_init
,
296 .update
= stm32_crc_update
,
297 .final
= stm32_crc_final
,
298 .finup
= stm32_crc_finup
,
299 .digest
= stm32_crc_digest
,
300 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
301 .digestsize
= CHKSUM_DIGEST_SIZE
,
303 .cra_name
= "crc32c",
304 .cra_driver_name
= DRIVER_NAME
,
306 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
307 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
309 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
310 .cra_module
= THIS_MODULE
,
311 .cra_init
= stm32_crc32c_cra_init
,
316 static int stm32_crc_probe(struct platform_device
*pdev
)
318 struct device
*dev
= &pdev
->dev
;
319 struct stm32_crc
*crc
;
322 crc
= devm_kzalloc(dev
, sizeof(*crc
), GFP_KERNEL
);
328 crc
->regs
= devm_platform_ioremap_resource(pdev
, 0);
329 if (IS_ERR(crc
->regs
)) {
330 dev_err(dev
, "Cannot map CRC IO\n");
331 return PTR_ERR(crc
->regs
);
334 crc
->clk
= devm_clk_get(dev
, NULL
);
335 if (IS_ERR(crc
->clk
)) {
336 dev_err(dev
, "Could not get clock\n");
337 return PTR_ERR(crc
->clk
);
340 ret
= clk_prepare_enable(crc
->clk
);
342 dev_err(crc
->dev
, "Failed to enable clock\n");
346 pm_runtime_set_autosuspend_delay(dev
, CRC_AUTOSUSPEND_DELAY
);
347 pm_runtime_use_autosuspend(dev
);
349 pm_runtime_get_noresume(dev
);
350 pm_runtime_set_active(dev
);
351 pm_runtime_irq_safe(dev
);
352 pm_runtime_enable(dev
);
354 spin_lock_init(&crc
->lock
);
356 platform_set_drvdata(pdev
, crc
);
358 spin_lock(&crc_list
.lock
);
359 list_add(&crc
->list
, &crc_list
.dev_list
);
360 spin_unlock(&crc_list
.lock
);
362 mutex_lock(&refcnt_lock
);
364 ret
= crypto_register_shashes(algs
, ARRAY_SIZE(algs
));
366 mutex_unlock(&refcnt_lock
);
367 dev_err(dev
, "Failed to register\n");
368 clk_disable_unprepare(crc
->clk
);
373 mutex_unlock(&refcnt_lock
);
375 dev_info(dev
, "Initialized\n");
377 pm_runtime_put_sync(dev
);
382 static int stm32_crc_remove(struct platform_device
*pdev
)
384 struct stm32_crc
*crc
= platform_get_drvdata(pdev
);
385 int ret
= pm_runtime_get_sync(crc
->dev
);
390 spin_lock(&crc_list
.lock
);
391 list_del(&crc
->list
);
392 spin_unlock(&crc_list
.lock
);
394 mutex_lock(&refcnt_lock
);
396 crypto_unregister_shashes(algs
, ARRAY_SIZE(algs
));
397 mutex_unlock(&refcnt_lock
);
399 pm_runtime_disable(crc
->dev
);
400 pm_runtime_put_noidle(crc
->dev
);
402 clk_disable_unprepare(crc
->clk
);
407 static int __maybe_unused
stm32_crc_suspend(struct device
*dev
)
409 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
412 ret
= pm_runtime_force_suspend(dev
);
416 clk_unprepare(crc
->clk
);
421 static int __maybe_unused
stm32_crc_resume(struct device
*dev
)
423 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
426 ret
= clk_prepare(crc
->clk
);
428 dev_err(crc
->dev
, "Failed to prepare clock\n");
432 return pm_runtime_force_resume(dev
);
435 static int __maybe_unused
stm32_crc_runtime_suspend(struct device
*dev
)
437 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
439 clk_disable(crc
->clk
);
444 static int __maybe_unused
stm32_crc_runtime_resume(struct device
*dev
)
446 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
449 ret
= clk_enable(crc
->clk
);
451 dev_err(crc
->dev
, "Failed to enable clock\n");
458 static const struct dev_pm_ops stm32_crc_pm_ops
= {
459 SET_SYSTEM_SLEEP_PM_OPS(stm32_crc_suspend
,
461 SET_RUNTIME_PM_OPS(stm32_crc_runtime_suspend
,
462 stm32_crc_runtime_resume
, NULL
)
465 static const struct of_device_id stm32_dt_ids
[] = {
466 { .compatible
= "st,stm32f7-crc", },
469 MODULE_DEVICE_TABLE(of
, stm32_dt_ids
);
471 static struct platform_driver stm32_crc_driver
= {
472 .probe
= stm32_crc_probe
,
473 .remove
= stm32_crc_remove
,
476 .pm
= &stm32_crc_pm_ops
,
477 .of_match_table
= stm32_dt_ids
,
481 module_platform_driver(stm32_crc_driver
);
483 MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
484 MODULE_DESCRIPTION("STMicrolectronics STM32 CRC32 hardware driver");
485 MODULE_LICENSE("GPL");