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/crc32poly.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/platform_device.h>
13 #include <linux/pm_runtime.h>
15 #include <crypto/internal/hash.h>
17 #include <asm/unaligned.h>
19 #define DRIVER_NAME "stm32-crc32"
20 #define CHKSUM_DIGEST_SIZE 4
21 #define CHKSUM_BLOCK_SIZE 1
24 #define CRC_DR 0x00000000
25 #define CRC_CR 0x00000008
26 #define CRC_INIT 0x00000010
27 #define CRC_POL 0x00000014
29 /* Registers values */
30 #define CRC_CR_RESET BIT(0)
31 #define CRC_CR_REV_IN_WORD (BIT(6) | BIT(5))
32 #define CRC_CR_REV_IN_BYTE BIT(5)
33 #define CRC_CR_REV_OUT BIT(7)
34 #define CRC32C_INIT_DEFAULT 0xFFFFFFFF
36 #define CRC_AUTOSUSPEND_DELAY 50
39 struct list_head list
;
45 struct stm32_crc_list
{
46 struct list_head dev_list
;
47 spinlock_t lock
; /* protect dev_list */
50 static struct stm32_crc_list crc_list
= {
51 .dev_list
= LIST_HEAD_INIT(crc_list
.dev_list
),
52 .lock
= __SPIN_LOCK_UNLOCKED(crc_list
.lock
),
55 struct stm32_crc_ctx
{
60 struct stm32_crc_desc_ctx
{
61 u32 partial
; /* crc32c: partial in first 4 bytes of that struct */
64 static int stm32_crc32_cra_init(struct crypto_tfm
*tfm
)
66 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
69 mctx
->poly
= CRC32_POLY_LE
;
73 static int stm32_crc32c_cra_init(struct crypto_tfm
*tfm
)
75 struct stm32_crc_ctx
*mctx
= crypto_tfm_ctx(tfm
);
77 mctx
->key
= CRC32C_INIT_DEFAULT
;
78 mctx
->poly
= CRC32C_POLY_LE
;
82 static int stm32_crc_setkey(struct crypto_shash
*tfm
, const u8
*key
,
85 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(tfm
);
87 if (keylen
!= sizeof(u32
))
90 mctx
->key
= get_unaligned_le32(key
);
94 static struct stm32_crc
*stm32_crc_get_next_crc(void)
96 struct stm32_crc
*crc
;
98 spin_lock_bh(&crc_list
.lock
);
99 crc
= list_first_entry(&crc_list
.dev_list
, struct stm32_crc
, list
);
101 list_move_tail(&crc
->list
, &crc_list
.dev_list
);
102 spin_unlock_bh(&crc_list
.lock
);
107 static int stm32_crc_init(struct shash_desc
*desc
)
109 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
110 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
111 struct stm32_crc
*crc
;
113 crc
= stm32_crc_get_next_crc();
117 pm_runtime_get_sync(crc
->dev
);
119 /* Reset, set key, poly and configure in bit reverse mode */
120 writel_relaxed(bitrev32(mctx
->key
), crc
->regs
+ CRC_INIT
);
121 writel_relaxed(bitrev32(mctx
->poly
), crc
->regs
+ CRC_POL
);
122 writel_relaxed(CRC_CR_RESET
| CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
125 /* Store partial result */
126 ctx
->partial
= readl_relaxed(crc
->regs
+ CRC_DR
);
128 pm_runtime_mark_last_busy(crc
->dev
);
129 pm_runtime_put_autosuspend(crc
->dev
);
134 static int stm32_crc_update(struct shash_desc
*desc
, const u8
*d8
,
137 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
138 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
139 struct stm32_crc
*crc
;
141 crc
= stm32_crc_get_next_crc();
145 pm_runtime_get_sync(crc
->dev
);
148 * Restore previously calculated CRC for this context as init value
149 * Restore polynomial configuration
150 * Configure in register for word input data,
151 * Configure out register in reversed bit mode data.
153 writel_relaxed(bitrev32(ctx
->partial
), crc
->regs
+ CRC_INIT
);
154 writel_relaxed(bitrev32(mctx
->poly
), crc
->regs
+ CRC_POL
);
155 writel_relaxed(CRC_CR_RESET
| CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
158 if (d8
!= PTR_ALIGN(d8
, sizeof(u32
))) {
159 /* Configure for byte data */
160 writel_relaxed(CRC_CR_REV_IN_BYTE
| CRC_CR_REV_OUT
,
162 while (d8
!= PTR_ALIGN(d8
, sizeof(u32
)) && length
) {
163 writeb_relaxed(*d8
++, crc
->regs
+ CRC_DR
);
166 /* Configure for word data */
167 writel_relaxed(CRC_CR_REV_IN_WORD
| CRC_CR_REV_OUT
,
171 for (; length
>= sizeof(u32
); d8
+= sizeof(u32
), length
-= sizeof(u32
))
172 writel_relaxed(*((u32
*)d8
), crc
->regs
+ CRC_DR
);
175 /* Configure for byte data */
176 writel_relaxed(CRC_CR_REV_IN_BYTE
| CRC_CR_REV_OUT
,
179 writeb_relaxed(*d8
++, crc
->regs
+ CRC_DR
);
182 /* Store partial result */
183 ctx
->partial
= readl_relaxed(crc
->regs
+ CRC_DR
);
185 pm_runtime_mark_last_busy(crc
->dev
);
186 pm_runtime_put_autosuspend(crc
->dev
);
191 static int stm32_crc_final(struct shash_desc
*desc
, u8
*out
)
193 struct stm32_crc_desc_ctx
*ctx
= shash_desc_ctx(desc
);
194 struct stm32_crc_ctx
*mctx
= crypto_shash_ctx(desc
->tfm
);
196 /* Send computed CRC */
197 put_unaligned_le32(mctx
->poly
== CRC32C_POLY_LE
?
198 ~ctx
->partial
: ctx
->partial
, out
);
203 static int stm32_crc_finup(struct shash_desc
*desc
, const u8
*data
,
204 unsigned int length
, u8
*out
)
206 return stm32_crc_update(desc
, data
, length
) ?:
207 stm32_crc_final(desc
, out
);
210 static int stm32_crc_digest(struct shash_desc
*desc
, const u8
*data
,
211 unsigned int length
, u8
*out
)
213 return stm32_crc_init(desc
) ?: stm32_crc_finup(desc
, data
, length
, out
);
216 static unsigned int refcnt
;
217 static DEFINE_MUTEX(refcnt_lock
);
218 static struct shash_alg algs
[] = {
221 .setkey
= stm32_crc_setkey
,
222 .init
= stm32_crc_init
,
223 .update
= stm32_crc_update
,
224 .final
= stm32_crc_final
,
225 .finup
= stm32_crc_finup
,
226 .digest
= stm32_crc_digest
,
227 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
228 .digestsize
= CHKSUM_DIGEST_SIZE
,
231 .cra_driver_name
= DRIVER_NAME
,
233 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
234 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
236 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
237 .cra_module
= THIS_MODULE
,
238 .cra_init
= stm32_crc32_cra_init
,
241 /* CRC-32Castagnoli */
243 .setkey
= stm32_crc_setkey
,
244 .init
= stm32_crc_init
,
245 .update
= stm32_crc_update
,
246 .final
= stm32_crc_final
,
247 .finup
= stm32_crc_finup
,
248 .digest
= stm32_crc_digest
,
249 .descsize
= sizeof(struct stm32_crc_desc_ctx
),
250 .digestsize
= CHKSUM_DIGEST_SIZE
,
252 .cra_name
= "crc32c",
253 .cra_driver_name
= DRIVER_NAME
,
255 .cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
256 .cra_blocksize
= CHKSUM_BLOCK_SIZE
,
258 .cra_ctxsize
= sizeof(struct stm32_crc_ctx
),
259 .cra_module
= THIS_MODULE
,
260 .cra_init
= stm32_crc32c_cra_init
,
265 static int stm32_crc_probe(struct platform_device
*pdev
)
267 struct device
*dev
= &pdev
->dev
;
268 struct stm32_crc
*crc
;
271 crc
= devm_kzalloc(dev
, sizeof(*crc
), GFP_KERNEL
);
277 crc
->regs
= devm_platform_ioremap_resource(pdev
, 0);
278 if (IS_ERR(crc
->regs
)) {
279 dev_err(dev
, "Cannot map CRC IO\n");
280 return PTR_ERR(crc
->regs
);
283 crc
->clk
= devm_clk_get(dev
, NULL
);
284 if (IS_ERR(crc
->clk
)) {
285 dev_err(dev
, "Could not get clock\n");
286 return PTR_ERR(crc
->clk
);
289 ret
= clk_prepare_enable(crc
->clk
);
291 dev_err(crc
->dev
, "Failed to enable clock\n");
295 pm_runtime_set_autosuspend_delay(dev
, CRC_AUTOSUSPEND_DELAY
);
296 pm_runtime_use_autosuspend(dev
);
298 pm_runtime_get_noresume(dev
);
299 pm_runtime_set_active(dev
);
300 pm_runtime_enable(dev
);
302 platform_set_drvdata(pdev
, crc
);
304 spin_lock(&crc_list
.lock
);
305 list_add(&crc
->list
, &crc_list
.dev_list
);
306 spin_unlock(&crc_list
.lock
);
308 mutex_lock(&refcnt_lock
);
310 ret
= crypto_register_shashes(algs
, ARRAY_SIZE(algs
));
312 mutex_unlock(&refcnt_lock
);
313 dev_err(dev
, "Failed to register\n");
314 clk_disable_unprepare(crc
->clk
);
319 mutex_unlock(&refcnt_lock
);
321 dev_info(dev
, "Initialized\n");
323 pm_runtime_put_sync(dev
);
328 static int stm32_crc_remove(struct platform_device
*pdev
)
330 struct stm32_crc
*crc
= platform_get_drvdata(pdev
);
331 int ret
= pm_runtime_get_sync(crc
->dev
);
336 spin_lock(&crc_list
.lock
);
337 list_del(&crc
->list
);
338 spin_unlock(&crc_list
.lock
);
340 mutex_lock(&refcnt_lock
);
342 crypto_unregister_shashes(algs
, ARRAY_SIZE(algs
));
343 mutex_unlock(&refcnt_lock
);
345 pm_runtime_disable(crc
->dev
);
346 pm_runtime_put_noidle(crc
->dev
);
348 clk_disable_unprepare(crc
->clk
);
354 static int stm32_crc_runtime_suspend(struct device
*dev
)
356 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
358 clk_disable_unprepare(crc
->clk
);
363 static int stm32_crc_runtime_resume(struct device
*dev
)
365 struct stm32_crc
*crc
= dev_get_drvdata(dev
);
368 ret
= clk_prepare_enable(crc
->clk
);
370 dev_err(crc
->dev
, "Failed to prepare_enable clock\n");
378 static const struct dev_pm_ops stm32_crc_pm_ops
= {
379 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
380 pm_runtime_force_resume
)
381 SET_RUNTIME_PM_OPS(stm32_crc_runtime_suspend
,
382 stm32_crc_runtime_resume
, NULL
)
385 static const struct of_device_id stm32_dt_ids
[] = {
386 { .compatible
= "st,stm32f7-crc", },
389 MODULE_DEVICE_TABLE(of
, stm32_dt_ids
);
391 static struct platform_driver stm32_crc_driver
= {
392 .probe
= stm32_crc_probe
,
393 .remove
= stm32_crc_remove
,
396 .pm
= &stm32_crc_pm_ops
,
397 .of_match_table
= stm32_dt_ids
,
401 module_platform_driver(stm32_crc_driver
);
403 MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
404 MODULE_DESCRIPTION("STMicrolectronics STM32 CRC32 hardware driver");
405 MODULE_LICENSE("GPL");