Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: starfive - Add crypto engine support

Adding device probe and DMA init for StarFive cryptographic module.

Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Jia Jie Ho and committed by
Herbert Xu
42ef0e94 4b66c6aa

+294
+7
MAINTAINERS
··· 20095 20095 F: drivers/clk/starfive/clk-starfive-jh71* 20096 20096 F: include/dt-bindings/clock/starfive?jh71*.h 20097 20097 20098 + STARFIVE CRYPTO DRIVER 20099 + M: Jia Jie Ho <jiajie.ho@starfivetech.com> 20100 + M: William Qiu <william.qiu@starfivetech.com> 20101 + S: Supported 20102 + F: Documentation/devicetree/bindings/crypto/starfive* 20103 + F: drivers/crypto/starfive/ 20104 + 20098 20105 STARFIVE JH71X0 PINCTRL DRIVERS 20099 20106 M: Emil Renner Berthing <kernel@esmil.dk> 20100 20107 M: Jianlong Huang <jianlong.huang@starfivetech.com>
+1
drivers/crypto/Kconfig
··· 807 807 acceleration for cryptographic algorithms on these devices. 808 808 809 809 source "drivers/crypto/aspeed/Kconfig" 810 + source "drivers/crypto/starfive/Kconfig" 810 811 811 812 endif # CRYPTO_HW
+1
drivers/crypto/Makefile
··· 50 50 obj-y += hisilicon/ 51 51 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ 52 52 obj-y += intel/ 53 + obj-y += starfive/
+17
drivers/crypto/starfive/Kconfig
··· 1 + # 2 + # StarFive crypto drivers configuration 3 + # 4 + 5 + config CRYPTO_DEV_JH7110 6 + tristate "StarFive JH7110 cryptographic engine driver" 7 + depends on SOC_STARFIVE || COMPILE_TEST 8 + select CRYPTO_ENGINE 9 + select ARM_AMBA 10 + select DMADEVICES 11 + select AMBA_PL08X 12 + help 13 + Support for StarFive JH7110 crypto hardware acceleration engine. 14 + This module provides acceleration for public key algo, 15 + skciphers, AEAD and hash functions. 16 + 17 + If you choose 'M' here, this module will be called jh7110-crypto.
+4
drivers/crypto/starfive/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o 4 + jh7110-crypto-objs := jh7110-cryp.o
+201
drivers/crypto/starfive/jh7110-cryp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Cryptographic API. 4 + * 5 + * Support for StarFive hardware cryptographic engine. 6 + * Copyright (c) 2022 StarFive Technology 7 + * 8 + */ 9 + 10 + #include <linux/clk.h> 11 + #include <linux/delay.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/iopoll.h> 14 + #include <linux/module.h> 15 + #include <linux/of_device.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/pm_runtime.h> 18 + #include <linux/reset.h> 19 + 20 + #include "jh7110-cryp.h" 21 + 22 + #define DRIVER_NAME "jh7110-crypto" 23 + 24 + struct starfive_dev_list { 25 + struct list_head dev_list; 26 + spinlock_t lock; /* protect dev_list */ 27 + }; 28 + 29 + static struct starfive_dev_list dev_list = { 30 + .dev_list = LIST_HEAD_INIT(dev_list.dev_list), 31 + .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock), 32 + }; 33 + 34 + struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx) 35 + { 36 + struct starfive_cryp_dev *cryp = NULL, *tmp; 37 + 38 + spin_lock_bh(&dev_list.lock); 39 + if (!ctx->cryp) { 40 + list_for_each_entry(tmp, &dev_list.dev_list, list) { 41 + cryp = tmp; 42 + break; 43 + } 44 + ctx->cryp = cryp; 45 + } else { 46 + cryp = ctx->cryp; 47 + } 48 + 49 + spin_unlock_bh(&dev_list.lock); 50 + 51 + return cryp; 52 + } 53 + 54 + static int starfive_dma_init(struct starfive_cryp_dev *cryp) 55 + { 56 + dma_cap_mask_t mask; 57 + 58 + dma_cap_zero(mask); 59 + dma_cap_set(DMA_SLAVE, mask); 60 + 61 + cryp->tx = dma_request_chan(cryp->dev, "tx"); 62 + if (IS_ERR(cryp->tx)) 63 + return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx), 64 + "Error requesting tx dma channel.\n"); 65 + 66 + cryp->rx = dma_request_chan(cryp->dev, "rx"); 67 + if (IS_ERR(cryp->rx)) { 68 + dma_release_channel(cryp->tx); 69 + return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx), 70 + "Error requesting rx dma channel.\n"); 71 + } 72 + 73 + return 0; 74 + } 75 + 76 + static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp) 77 + { 78 + dma_release_channel(cryp->tx); 79 + dma_release_channel(cryp->rx); 80 + } 81 + 82 + static int starfive_cryp_probe(struct platform_device *pdev) 83 + { 84 + struct starfive_cryp_dev *cryp; 85 + struct resource *res; 86 + int ret; 87 + 88 + cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL); 89 + if (!cryp) 90 + return -ENOMEM; 91 + 92 + platform_set_drvdata(pdev, cryp); 93 + cryp->dev = &pdev->dev; 94 + 95 + cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 96 + if (IS_ERR(cryp->base)) 97 + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base), 98 + "Error remapping memory for platform device\n"); 99 + 100 + cryp->phys_base = res->start; 101 + cryp->dma_maxburst = 32; 102 + 103 + cryp->hclk = devm_clk_get(&pdev->dev, "hclk"); 104 + if (IS_ERR(cryp->hclk)) 105 + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk), 106 + "Error getting hardware reference clock\n"); 107 + 108 + cryp->ahb = devm_clk_get(&pdev->dev, "ahb"); 109 + if (IS_ERR(cryp->ahb)) 110 + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb), 111 + "Error getting ahb reference clock\n"); 112 + 113 + cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL); 114 + if (IS_ERR(cryp->rst)) 115 + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst), 116 + "Error getting hardware reset line\n"); 117 + 118 + clk_prepare_enable(cryp->hclk); 119 + clk_prepare_enable(cryp->ahb); 120 + reset_control_deassert(cryp->rst); 121 + 122 + spin_lock(&dev_list.lock); 123 + list_add(&cryp->list, &dev_list.dev_list); 124 + spin_unlock(&dev_list.lock); 125 + 126 + ret = starfive_dma_init(cryp); 127 + if (ret) { 128 + if (ret == -EPROBE_DEFER) 129 + goto err_probe_defer; 130 + else 131 + goto err_dma_init; 132 + } 133 + 134 + /* Initialize crypto engine */ 135 + cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1); 136 + if (!cryp->engine) { 137 + ret = -ENOMEM; 138 + goto err_engine; 139 + } 140 + 141 + ret = crypto_engine_start(cryp->engine); 142 + if (ret) 143 + goto err_engine_start; 144 + 145 + return 0; 146 + 147 + err_engine_start: 148 + crypto_engine_exit(cryp->engine); 149 + err_engine: 150 + starfive_dma_cleanup(cryp); 151 + err_dma_init: 152 + spin_lock(&dev_list.lock); 153 + list_del(&cryp->list); 154 + spin_unlock(&dev_list.lock); 155 + 156 + clk_disable_unprepare(cryp->hclk); 157 + clk_disable_unprepare(cryp->ahb); 158 + reset_control_assert(cryp->rst); 159 + err_probe_defer: 160 + return ret; 161 + } 162 + 163 + static int starfive_cryp_remove(struct platform_device *pdev) 164 + { 165 + struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev); 166 + 167 + crypto_engine_stop(cryp->engine); 168 + crypto_engine_exit(cryp->engine); 169 + 170 + starfive_dma_cleanup(cryp); 171 + 172 + spin_lock(&dev_list.lock); 173 + list_del(&cryp->list); 174 + spin_unlock(&dev_list.lock); 175 + 176 + clk_disable_unprepare(cryp->hclk); 177 + clk_disable_unprepare(cryp->ahb); 178 + reset_control_assert(cryp->rst); 179 + 180 + return 0; 181 + } 182 + 183 + static const struct of_device_id starfive_dt_ids[] __maybe_unused = { 184 + { .compatible = "starfive,jh7110-crypto", .data = NULL}, 185 + {}, 186 + }; 187 + MODULE_DEVICE_TABLE(of, starfive_dt_ids); 188 + 189 + static struct platform_driver starfive_cryp_driver = { 190 + .probe = starfive_cryp_probe, 191 + .remove = starfive_cryp_remove, 192 + .driver = { 193 + .name = DRIVER_NAME, 194 + .of_match_table = starfive_dt_ids, 195 + }, 196 + }; 197 + 198 + module_platform_driver(starfive_cryp_driver); 199 + 200 + MODULE_LICENSE("GPL"); 201 + MODULE_DESCRIPTION("StarFive JH7110 Cryptographic Module");
+63
drivers/crypto/starfive/jh7110-cryp.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __STARFIVE_STR_H__ 3 + #define __STARFIVE_STR_H__ 4 + 5 + #include <linux/delay.h> 6 + #include <linux/dma-mapping.h> 7 + #include <linux/dmaengine.h> 8 + 9 + #include <crypto/engine.h> 10 + 11 + #define STARFIVE_ALG_CR_OFFSET 0x0 12 + #define STARFIVE_ALG_FIFO_OFFSET 0x4 13 + #define STARFIVE_IE_MASK_OFFSET 0x8 14 + #define STARFIVE_IE_FLAG_OFFSET 0xc 15 + #define STARFIVE_DMA_IN_LEN_OFFSET 0x10 16 + #define STARFIVE_DMA_OUT_LEN_OFFSET 0x14 17 + 18 + #define STARFIVE_MSG_BUFFER_SIZE SZ_16K 19 + 20 + union starfive_alg_cr { 21 + u32 v; 22 + struct { 23 + u32 start :1; 24 + u32 aes_dma_en :1; 25 + u32 rsvd_0 :1; 26 + u32 hash_dma_en :1; 27 + u32 alg_done :1; 28 + u32 rsvd_1 :3; 29 + u32 clear :1; 30 + u32 rsvd_2 :23; 31 + }; 32 + }; 33 + 34 + struct starfive_cryp_ctx { 35 + struct crypto_engine_ctx enginectx; 36 + struct starfive_cryp_dev *cryp; 37 + }; 38 + 39 + struct starfive_cryp_dev { 40 + struct list_head list; 41 + struct device *dev; 42 + 43 + struct clk *hclk; 44 + struct clk *ahb; 45 + struct reset_control *rst; 46 + 47 + void __iomem *base; 48 + phys_addr_t phys_base; 49 + 50 + u32 dma_maxburst; 51 + struct dma_chan *tx; 52 + struct dma_chan *rx; 53 + struct dma_slave_config cfg_in; 54 + struct dma_slave_config cfg_out; 55 + 56 + struct crypto_engine *engine; 57 + 58 + union starfive_alg_cr alg_cr; 59 + }; 60 + 61 + struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); 62 + 63 + #endif