0065-crypto-starfive-Add-crypto-engine-support.patch 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. From 8b1069fcc1dbb524556d851f3dedf0629a71f17b Mon Sep 17 00:00:00 2001
  2. From: Jia Jie Ho <[email protected]>
  3. Date: Mon, 15 May 2023 20:53:53 +0800
  4. Subject: [PATCH 065/122] crypto: starfive - Add crypto engine support
  5. Adding device probe and DMA init for StarFive cryptographic module.
  6. Co-developed-by: Huan Feng <[email protected]>
  7. Signed-off-by: Huan Feng <[email protected]>
  8. Signed-off-by: Jia Jie Ho <[email protected]>
  9. Signed-off-by: Herbert Xu <[email protected]>
  10. ---
  11. drivers/crypto/Kconfig | 1 +
  12. drivers/crypto/Makefile | 1 +
  13. drivers/crypto/starfive/Kconfig | 17 +++
  14. drivers/crypto/starfive/Makefile | 4 +
  15. drivers/crypto/starfive/jh7110-cryp.c | 201 ++++++++++++++++++++++++++
  16. drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++
  17. 6 files changed, 287 insertions(+)
  18. create mode 100644 drivers/crypto/starfive/Kconfig
  19. create mode 100644 drivers/crypto/starfive/Makefile
  20. create mode 100644 drivers/crypto/starfive/jh7110-cryp.c
  21. create mode 100644 drivers/crypto/starfive/jh7110-cryp.h
  22. --- a/drivers/crypto/Kconfig
  23. +++ b/drivers/crypto/Kconfig
  24. @@ -823,5 +823,6 @@ config CRYPTO_DEV_SA2UL
  25. source "drivers/crypto/keembay/Kconfig"
  26. source "drivers/crypto/aspeed/Kconfig"
  27. +source "drivers/crypto/starfive/Kconfig"
  28. endif # CRYPTO_HW
  29. --- a/drivers/crypto/Makefile
  30. +++ b/drivers/crypto/Makefile
  31. @@ -53,3 +53,4 @@ obj-y += xilinx/
  32. obj-y += hisilicon/
  33. obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
  34. obj-y += keembay/
  35. +obj-y += starfive/
  36. --- /dev/null
  37. +++ b/drivers/crypto/starfive/Kconfig
  38. @@ -0,0 +1,17 @@
  39. +#
  40. +# StarFive crypto drivers configuration
  41. +#
  42. +
  43. +config CRYPTO_DEV_JH7110
  44. + tristate "StarFive JH7110 cryptographic engine driver"
  45. + depends on SOC_STARFIVE || COMPILE_TEST
  46. + select CRYPTO_ENGINE
  47. + select ARM_AMBA
  48. + select DMADEVICES
  49. + select AMBA_PL08X
  50. + help
  51. + Support for StarFive JH7110 crypto hardware acceleration engine.
  52. + This module provides acceleration for public key algo,
  53. + skciphers, AEAD and hash functions.
  54. +
  55. + If you choose 'M' here, this module will be called jh7110-crypto.
  56. --- /dev/null
  57. +++ b/drivers/crypto/starfive/Makefile
  58. @@ -0,0 +1,4 @@
  59. +# SPDX-License-Identifier: GPL-2.0
  60. +
  61. +obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
  62. +jh7110-crypto-objs := jh7110-cryp.o
  63. --- /dev/null
  64. +++ b/drivers/crypto/starfive/jh7110-cryp.c
  65. @@ -0,0 +1,201 @@
  66. +// SPDX-License-Identifier: GPL-2.0
  67. +/*
  68. + * Cryptographic API.
  69. + *
  70. + * Support for StarFive hardware cryptographic engine.
  71. + * Copyright (c) 2022 StarFive Technology
  72. + *
  73. + */
  74. +
  75. +#include <linux/clk.h>
  76. +#include <linux/delay.h>
  77. +#include <linux/interrupt.h>
  78. +#include <linux/iopoll.h>
  79. +#include <linux/module.h>
  80. +#include <linux/of_device.h>
  81. +#include <linux/platform_device.h>
  82. +#include <linux/pm_runtime.h>
  83. +#include <linux/reset.h>
  84. +
  85. +#include "jh7110-cryp.h"
  86. +
  87. +#define DRIVER_NAME "jh7110-crypto"
  88. +
  89. +struct starfive_dev_list {
  90. + struct list_head dev_list;
  91. + spinlock_t lock; /* protect dev_list */
  92. +};
  93. +
  94. +static struct starfive_dev_list dev_list = {
  95. + .dev_list = LIST_HEAD_INIT(dev_list.dev_list),
  96. + .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock),
  97. +};
  98. +
  99. +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx)
  100. +{
  101. + struct starfive_cryp_dev *cryp = NULL, *tmp;
  102. +
  103. + spin_lock_bh(&dev_list.lock);
  104. + if (!ctx->cryp) {
  105. + list_for_each_entry(tmp, &dev_list.dev_list, list) {
  106. + cryp = tmp;
  107. + break;
  108. + }
  109. + ctx->cryp = cryp;
  110. + } else {
  111. + cryp = ctx->cryp;
  112. + }
  113. +
  114. + spin_unlock_bh(&dev_list.lock);
  115. +
  116. + return cryp;
  117. +}
  118. +
  119. +static int starfive_dma_init(struct starfive_cryp_dev *cryp)
  120. +{
  121. + dma_cap_mask_t mask;
  122. +
  123. + dma_cap_zero(mask);
  124. + dma_cap_set(DMA_SLAVE, mask);
  125. +
  126. + cryp->tx = dma_request_chan(cryp->dev, "tx");
  127. + if (IS_ERR(cryp->tx))
  128. + return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx),
  129. + "Error requesting tx dma channel.\n");
  130. +
  131. + cryp->rx = dma_request_chan(cryp->dev, "rx");
  132. + if (IS_ERR(cryp->rx)) {
  133. + dma_release_channel(cryp->tx);
  134. + return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx),
  135. + "Error requesting rx dma channel.\n");
  136. + }
  137. +
  138. + return 0;
  139. +}
  140. +
  141. +static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
  142. +{
  143. + dma_release_channel(cryp->tx);
  144. + dma_release_channel(cryp->rx);
  145. +}
  146. +
  147. +static int starfive_cryp_probe(struct platform_device *pdev)
  148. +{
  149. + struct starfive_cryp_dev *cryp;
  150. + struct resource *res;
  151. + int ret;
  152. +
  153. + cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL);
  154. + if (!cryp)
  155. + return -ENOMEM;
  156. +
  157. + platform_set_drvdata(pdev, cryp);
  158. + cryp->dev = &pdev->dev;
  159. +
  160. + cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
  161. + if (IS_ERR(cryp->base))
  162. + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base),
  163. + "Error remapping memory for platform device\n");
  164. +
  165. + cryp->phys_base = res->start;
  166. + cryp->dma_maxburst = 32;
  167. +
  168. + cryp->hclk = devm_clk_get(&pdev->dev, "hclk");
  169. + if (IS_ERR(cryp->hclk))
  170. + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk),
  171. + "Error getting hardware reference clock\n");
  172. +
  173. + cryp->ahb = devm_clk_get(&pdev->dev, "ahb");
  174. + if (IS_ERR(cryp->ahb))
  175. + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb),
  176. + "Error getting ahb reference clock\n");
  177. +
  178. + cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL);
  179. + if (IS_ERR(cryp->rst))
  180. + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
  181. + "Error getting hardware reset line\n");
  182. +
  183. + clk_prepare_enable(cryp->hclk);
  184. + clk_prepare_enable(cryp->ahb);
  185. + reset_control_deassert(cryp->rst);
  186. +
  187. + spin_lock(&dev_list.lock);
  188. + list_add(&cryp->list, &dev_list.dev_list);
  189. + spin_unlock(&dev_list.lock);
  190. +
  191. + ret = starfive_dma_init(cryp);
  192. + if (ret) {
  193. + if (ret == -EPROBE_DEFER)
  194. + goto err_probe_defer;
  195. + else
  196. + goto err_dma_init;
  197. + }
  198. +
  199. + /* Initialize crypto engine */
  200. + cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1);
  201. + if (!cryp->engine) {
  202. + ret = -ENOMEM;
  203. + goto err_engine;
  204. + }
  205. +
  206. + ret = crypto_engine_start(cryp->engine);
  207. + if (ret)
  208. + goto err_engine_start;
  209. +
  210. + return 0;
  211. +
  212. +err_engine_start:
  213. + crypto_engine_exit(cryp->engine);
  214. +err_engine:
  215. + starfive_dma_cleanup(cryp);
  216. +err_dma_init:
  217. + spin_lock(&dev_list.lock);
  218. + list_del(&cryp->list);
  219. + spin_unlock(&dev_list.lock);
  220. +
  221. + clk_disable_unprepare(cryp->hclk);
  222. + clk_disable_unprepare(cryp->ahb);
  223. + reset_control_assert(cryp->rst);
  224. +err_probe_defer:
  225. + return ret;
  226. +}
  227. +
  228. +static int starfive_cryp_remove(struct platform_device *pdev)
  229. +{
  230. + struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
  231. +
  232. + crypto_engine_stop(cryp->engine);
  233. + crypto_engine_exit(cryp->engine);
  234. +
  235. + starfive_dma_cleanup(cryp);
  236. +
  237. + spin_lock(&dev_list.lock);
  238. + list_del(&cryp->list);
  239. + spin_unlock(&dev_list.lock);
  240. +
  241. + clk_disable_unprepare(cryp->hclk);
  242. + clk_disable_unprepare(cryp->ahb);
  243. + reset_control_assert(cryp->rst);
  244. +
  245. + return 0;
  246. +}
  247. +
  248. +static const struct of_device_id starfive_dt_ids[] __maybe_unused = {
  249. + { .compatible = "starfive,jh7110-crypto", .data = NULL},
  250. + {},
  251. +};
  252. +MODULE_DEVICE_TABLE(of, starfive_dt_ids);
  253. +
  254. +static struct platform_driver starfive_cryp_driver = {
  255. + .probe = starfive_cryp_probe,
  256. + .remove = starfive_cryp_remove,
  257. + .driver = {
  258. + .name = DRIVER_NAME,
  259. + .of_match_table = starfive_dt_ids,
  260. + },
  261. +};
  262. +
  263. +module_platform_driver(starfive_cryp_driver);
  264. +
  265. +MODULE_LICENSE("GPL");
  266. +MODULE_DESCRIPTION("StarFive JH7110 Cryptographic Module");
  267. --- /dev/null
  268. +++ b/drivers/crypto/starfive/jh7110-cryp.h
  269. @@ -0,0 +1,63 @@
  270. +/* SPDX-License-Identifier: GPL-2.0 */
  271. +#ifndef __STARFIVE_STR_H__
  272. +#define __STARFIVE_STR_H__
  273. +
  274. +#include <linux/delay.h>
  275. +#include <linux/dma-mapping.h>
  276. +#include <linux/dmaengine.h>
  277. +
  278. +#include <crypto/engine.h>
  279. +
  280. +#define STARFIVE_ALG_CR_OFFSET 0x0
  281. +#define STARFIVE_ALG_FIFO_OFFSET 0x4
  282. +#define STARFIVE_IE_MASK_OFFSET 0x8
  283. +#define STARFIVE_IE_FLAG_OFFSET 0xc
  284. +#define STARFIVE_DMA_IN_LEN_OFFSET 0x10
  285. +#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
  286. +
  287. +#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
  288. +
  289. +union starfive_alg_cr {
  290. + u32 v;
  291. + struct {
  292. + u32 start :1;
  293. + u32 aes_dma_en :1;
  294. + u32 rsvd_0 :1;
  295. + u32 hash_dma_en :1;
  296. + u32 alg_done :1;
  297. + u32 rsvd_1 :3;
  298. + u32 clear :1;
  299. + u32 rsvd_2 :23;
  300. + };
  301. +};
  302. +
  303. +struct starfive_cryp_ctx {
  304. + struct crypto_engine_ctx enginectx;
  305. + struct starfive_cryp_dev *cryp;
  306. +};
  307. +
  308. +struct starfive_cryp_dev {
  309. + struct list_head list;
  310. + struct device *dev;
  311. +
  312. + struct clk *hclk;
  313. + struct clk *ahb;
  314. + struct reset_control *rst;
  315. +
  316. + void __iomem *base;
  317. + phys_addr_t phys_base;
  318. +
  319. + u32 dma_maxburst;
  320. + struct dma_chan *tx;
  321. + struct dma_chan *rx;
  322. + struct dma_slave_config cfg_in;
  323. + struct dma_slave_config cfg_out;
  324. +
  325. + struct crypto_engine *engine;
  326. +
  327. + union starfive_alg_cr alg_cr;
  328. +};
  329. +
  330. +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
  331. +
  332. +#endif