1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #include <asm/cacheflush.h>
7 #include <linux/clk.h>
8 #include <linux/completion.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/initramfs.h>
11 #include <linux/interrupt.h>
12 #include <linux/iopoll.h>
13 #include <linux/kernel.h>
14 #include <linux/kthread.h>
15 #include <linux/mm.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_address.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/soc/rockchip/rockchip_decompress.h>
22
23 #define SHA256_PROBE_TIMEOUT 1000
24 #define SHA256_COMPARE_TIMEOUT 2000
25 #define SHA256_HASH_SIZE 32
26 #define _SBF(s, v) ((v) << (s))
27 #define CRYPTO_WRITE_MASK_SHIFT (16)
28 #define CRYPTO_WRITE_MASK_ALL ((0xffffu << CRYPTO_WRITE_MASK_SHIFT))
29
30 /* Crypto DMA control registers*/
31 #define CRYPTO_DMA_INT_EN 0x0008
32 #define CRYPTO_ZERO_ERR_INT_EN BIT(6)
33 #define CRYPTO_LIST_ERR_INT_EN BIT(5)
34 #define CRYPTO_SRC_ERR_INT_EN BIT(4)
35 #define CRYPTO_DST_ERR_INT_EN BIT(3)
36 #define CRYPTO_SRC_ITEM_INT_EN BIT(2)
37 #define CRYPTO_DST_ITEM_DONE_INT_EN BIT(1)
38 #define CRYPTO_LIST_DONE_INT_EN BIT(0)
39
40 #define CRYPTO_DMA_INT_ST 0x000C
41 #define CRYPTO_ZERO_LEN_INT_ST BIT(6)
42 #define CRYPTO_LIST_ERR_INT_ST BIT(5)
43 #define CRYPTO_SRC_ERR_INT_ST BIT(4)
44 #define CRYPTO_DST_ERR_INT_ST BIT(3)
45 #define CRYPTO_SRC_ITEM_DONE_INT_ST BIT(2)
46 #define CRYPTO_DST_ITEM_DONE_INT_ST BIT(1)
47 #define CRYPTO_LIST_DONE_INT_ST BIT(0)
48
49 #define CRYPTO_DMA_CTL 0x0010
50 #define CRYPTO_DMA_RESTART BIT(1)
51 #define CRYPTO_DMA_START BIT(0)
52
53 /* DMA LIST Start Address Register */
54 #define CRYPTO_DMA_LLI_ADDR 0x0014
55
56 #define CRYPTO_FIFO_CTL 0x0040
57 #define CRYPTO_DOUT_BYTESWAP BIT(1)
58 #define CRYPTO_DOIN_BYTESWAP BIT(0)
59
60 /* Hash Control Register */
61 #define CRYPTO_HASH_CTL 0x0048
62 #define CRYPTO_SHA1 _SBF(4, 0x00)
63 #define CRYPTO_MD5 _SBF(4, 0x01)
64 #define CRYPTO_SHA256 _SBF(4, 0x02)
65 #define CRYPTO_SHA224 _SBF(4, 0x03)
66 #define CRYPTO_SM3 _SBF(4, 0x06)
67 #define CRYPTO_SHA512 _SBF(4, 0x08)
68 #define CRYPTO_SHA384 _SBF(4, 0x09)
69 #define CRYPTO_SHA512_224 _SBF(4, 0x0A)
70 #define CRYPTO_SHA512_256 _SBF(4, 0x0B)
71 #define CRYPTO_HMAC_ENABLE BIT(3)
72 #define CRYPTO_HW_PAD_ENABLE BIT(2)
73 #define CRYPTO_HASH_SRC_SEL BIT(1)
74 #define CRYPTO_HASH_ENABLE BIT(0)
75
76 #define CRYPTO_HASH_DOUT_0 0x03a0
77 #define CRYPTO_HASH_DOUT_1 0x03a4
78 #define CRYPTO_HASH_DOUT_2 0x03a8
79 #define CRYPTO_HASH_DOUT_3 0x03ac
80 #define CRYPTO_HASH_DOUT_4 0x03b0
81 #define CRYPTO_HASH_DOUT_5 0x03b4
82 #define CRYPTO_HASH_DOUT_6 0x03b8
83 #define CRYPTO_HASH_DOUT_7 0x03bc
84 #define CRYPTO_HASH_DOUT_8 0x03c0
85 #define CRYPTO_HASH_DOUT_9 0x03c4
86 #define CRYPTO_HASH_DOUT_10 0x03c8
87 #define CRYPTO_HASH_DOUT_11 0x03cc
88 #define CRYPTO_HASH_DOUT_12 0x03d0
89 #define CRYPTO_HASH_DOUT_13 0x03d4
90 #define CRYPTO_HASH_DOUT_14 0x03d8
91 #define CRYPTO_HASH_DOUT_15 0x03dc
92
93 #define CRYPTO_HASH_VALID 0x03e4
94 #define CRYPTO_HASH_IS_VALID BIT(0)
95
96 #define LLI_DMA_CTRL_LAST BIT(0)
97 #define LLI_DMA_CTRL_PAUSE BIT(1)
98 #define LLI_DMA_CTRL_LIST_DONE BIT(8)
99 #define LLI_DMA_CTRL_DST_DONE BIT(9)
100 #define LLI_DMA_CTRL_SRC_DONE BIT(10)
101
102 #define LLI_USER_CPIHER_START BIT(0)
103 #define LLI_USER_STRING_START BIT(1)
104 #define LLI_USER_STRING_LAST BIT(2)
105 #define LLI_USER_STRING_ADA BIT(3)
106 #define LLI_USER_PRIVACY_KEY BIT(7)
107 #define LLI_USER_ROOT_KEY BIT(8)
108
109 #define CRYPTO_READ(dev, offset) \
110 readl_relaxed(((dev)->reg + (offset)))
111 #define CRYPTO_WRITE(dev, offset, val) \
112 writel_relaxed((val), ((dev)->reg + (offset)))
113
114 #ifdef DEBUG
115 #define CRYPTO_TRACE(format, ...) pr_err("[%s, %05d]-trace: " format "\n", \
116 __func__, __LINE__, ##__VA_ARGS__)
117 #define CRYPTO_MSG(format, ...) pr_err("[%s, %05d]-msg:" format "\n", \
118 __func__, __LINE__, ##__VA_ARGS__)
119 #define CRYPTO_DUMPHEX(var_name, data, len) \
120 print_hex_dump(KERN_CONT, (var_name), \
121 DUMP_PREFIX_OFFSET, \
122 16, 1, (data), (len), false)
123 #else
124 #define CRYPTO_TRACE(format, ...)
125 #define CRYPTO_MSG(format, ...)
126 #define CRYPTO_DUMPHEX(var_name, data, len)
127 #endif
128
129 struct crypto_lli_desc {
130 u32 src_addr;
131 u32 src_len;
132 u32 dst_addr;
133 u32 dst_len;
134 u32 user_define;
135 u32 reserve;
136 u32 dma_ctrl;
137 u32 next_addr;
138 };
139
140 struct crypto_data {
141 struct device *dev;
142 void __iomem *reg;
143 int irq;
144 int clks_num;
145 struct clk_bulk_data *clk_bulks;
146 struct crypto_lli_desc *desc;
147 dma_addr_t desc_dma;
148 int calc_ret;
149 void (*done_cb)(void *user_data,
150 int hash_ret,
151 u8 *hash_val);
152 void *cb_data;
153 u8 *hash;
154 };
155
156 enum endian_mode {
157 BIG_ENDIAN = 0,
158 LITTLE_ENDIAN
159 };
160
161 static struct crypto_data *g_crypto_info;
162 static DECLARE_COMPLETION(sha256_probe_complete);
163
164 static DECLARE_WAIT_QUEUE_HEAD(crypto_sha256_compare_done);
165 static bool compare_done;
166
rk_tb_crypto_sha256_wait_compare_done(void)167 int __init rk_tb_crypto_sha256_wait_compare_done(void)
168 {
169 if (wait_event_timeout(crypto_sha256_compare_done, compare_done,
170 SHA256_COMPARE_TIMEOUT))
171 return 0;
172
173 return -ETIMEDOUT;
174 }
175
word2byte(u32 word,u8 * ch,u32 endian)176 static void word2byte(u32 word, u8 *ch, u32 endian)
177 {
178 /* 0: Big-Endian 1: Little-Endian */
179 if (endian == BIG_ENDIAN) {
180 ch[0] = (word >> 24) & 0xff;
181 ch[1] = (word >> 16) & 0xff;
182 ch[2] = (word >> 8) & 0xff;
183 ch[3] = (word >> 0) & 0xff;
184 } else if (endian == LITTLE_ENDIAN) {
185 ch[0] = (word >> 0) & 0xff;
186 ch[1] = (word >> 8) & 0xff;
187 ch[2] = (word >> 16) & 0xff;
188 ch[3] = (word >> 24) & 0xff;
189 } else {
190 ch[0] = 0;
191 ch[1] = 0;
192 ch[2] = 0;
193 ch[3] = 0;
194 }
195 }
196
sha256_done_cb(void * user_data,int hash_ret,u8 * hash_val)197 static void sha256_done_cb(void *user_data, int hash_ret, u8 *hash_val)
198 {
199 CRYPTO_TRACE();
200 if (!memcmp(user_data, hash_val, 32)) {
201 compare_done = true;
202 wake_up(&crypto_sha256_compare_done);
203 }
204 }
205
clear_hash_out_reg(struct crypto_data * dev)206 static inline void clear_hash_out_reg(struct crypto_data *dev)
207 {
208 int i;
209
210 /*clear out register*/
211 for (i = 0; i < 16; i++)
212 CRYPTO_WRITE(dev, CRYPTO_HASH_DOUT_0 + 4 * i, 0);
213 }
214
get_hash_value(struct crypto_data * dev,u8 * data,u32 data_len)215 static int get_hash_value(struct crypto_data *dev, u8 *data, u32 data_len)
216 {
217 int ret = 0;
218 u32 i, offset;
219
220 offset = CRYPTO_HASH_DOUT_0;
221 for (i = 0; i < data_len / 4; i++, offset += 4)
222 word2byte(CRYPTO_READ(dev, offset), data + i * 4, BIG_ENDIAN);
223
224 if (data_len % 4) {
225 uint8_t tmp_buf[4];
226
227 word2byte(CRYPTO_READ(dev, offset), tmp_buf, BIG_ENDIAN);
228 memcpy(data + i * 4, tmp_buf, data_len % 4);
229 }
230
231 CRYPTO_WRITE(dev, CRYPTO_HASH_VALID, CRYPTO_HASH_IS_VALID);
232
233 return ret;
234 }
235
rk_tb_crypto_disable_clk(struct crypto_data * dev)236 static void rk_tb_crypto_disable_clk(struct crypto_data *dev)
237 {
238 dev_dbg(dev->dev, "clk_bulk_disable_unprepare.\n");
239
240 clk_bulk_disable_unprepare(dev->clks_num, dev->clk_bulks);
241 }
242
rk_tb_crypto_irq_handle(int irq,void * dev_id)243 static irqreturn_t rk_tb_crypto_irq_handle(int irq, void *dev_id)
244 {
245 struct crypto_data *crypto_info = platform_get_drvdata(dev_id);
246
247 CRYPTO_TRACE("xxxxxxxxxx irq xxxxxxxxxx");
248
249 if (crypto_info) {
250 u32 interrupt_status;
251
252 get_hash_value(crypto_info, crypto_info->hash, SHA256_HASH_SIZE);
253 CRYPTO_WRITE(crypto_info, CRYPTO_HASH_CTL, CRYPTO_WRITE_MASK_ALL | 0);
254 interrupt_status = CRYPTO_READ(crypto_info, CRYPTO_DMA_INT_ST);
255 CRYPTO_WRITE(crypto_info, CRYPTO_DMA_INT_ST, interrupt_status);
256 if (interrupt_status == CRYPTO_LIST_DONE_INT_ST)
257 crypto_info->calc_ret = 0;
258
259 CRYPTO_TRACE("interrupt_status = %08x", interrupt_status);
260 if (crypto_info->done_cb)
261 crypto_info->done_cb(crypto_info->cb_data,
262 crypto_info->calc_ret,
263 crypto_info->hash);
264
265 rk_tb_crypto_disable_clk(crypto_info);
266 }
267
268 return IRQ_HANDLED;
269 }
270
rk_tb_sha256(dma_addr_t data,size_t data_len,void * user_data)271 int rk_tb_sha256(dma_addr_t data, size_t data_len, void *user_data)
272 {
273 u32 reg_ctrl = 0;
274 struct crypto_data *crypto_info;
275
276 wait_for_completion_interruptible_timeout(&sha256_probe_complete,
277 SHA256_PROBE_TIMEOUT);
278 crypto_info = g_crypto_info;
279 if (!crypto_info)
280 return -ENODEV;
281
282 if (data % 4)
283 return -EINVAL;
284
285 clear_hash_out_reg(crypto_info);
286
287 reg_ctrl = CRYPTO_SHA256 | CRYPTO_HW_PAD_ENABLE;
288 CRYPTO_WRITE(crypto_info, CRYPTO_HASH_CTL,
289 reg_ctrl | CRYPTO_WRITE_MASK_ALL);
290
291 reg_ctrl = CRYPTO_ZERO_ERR_INT_EN |
292 CRYPTO_LIST_ERR_INT_EN |
293 CRYPTO_SRC_ERR_INT_EN |
294 CRYPTO_DST_ERR_INT_EN |
295 CRYPTO_LIST_DONE_INT_EN;
296
297 CRYPTO_WRITE(crypto_info, CRYPTO_FIFO_CTL, 0x00030003);
298 CRYPTO_WRITE(crypto_info, CRYPTO_DMA_INT_EN, reg_ctrl);
299
300 memset(crypto_info->desc, 0x00, sizeof(*crypto_info->desc));
301
302 crypto_info->desc->src_addr = (u32)data;
303 crypto_info->desc->src_len = data_len;
304 crypto_info->desc->next_addr = 0;
305 crypto_info->desc->dma_ctrl = LLI_DMA_CTRL_LIST_DONE |
306 LLI_DMA_CTRL_LAST;
307 crypto_info->desc->user_define = LLI_USER_CPIHER_START |
308 LLI_USER_STRING_START |
309 LLI_USER_STRING_LAST;
310 #ifdef CONFIG_ARM64
311 __flush_dcache_area((void *)crypto_info->desc,
312 sizeof(struct crypto_data));
313 #else
314 __cpuc_flush_dcache_area((void *)crypto_info->desc,
315 sizeof(struct crypto_data));
316 #endif
317 CRYPTO_WRITE(crypto_info, CRYPTO_DMA_LLI_ADDR, crypto_info->desc_dma);
318 CRYPTO_WRITE(crypto_info, CRYPTO_HASH_CTL,
319 (CRYPTO_HASH_ENABLE <<
320 CRYPTO_WRITE_MASK_SHIFT) |
321 CRYPTO_HASH_ENABLE);
322
323 CRYPTO_WRITE(crypto_info, CRYPTO_DMA_CTL, 0x00010001); /* start */
324
325 crypto_info->calc_ret = -1;
326
327 crypto_info->done_cb = sha256_done_cb;
328 crypto_info->cb_data = user_data;
329 crypto_info->hash = devm_kzalloc(crypto_info->dev, 32, GFP_KERNEL);
330 if (!crypto_info->hash)
331 return -ENOMEM;
332
333 return 0;
334 }
335 EXPORT_SYMBOL_GPL(rk_tb_sha256);
336
rk_tb_crypto_probe(struct platform_device * pdev)337 static int __init rk_tb_crypto_probe(struct platform_device *pdev)
338 {
339 struct crypto_data *crypto_info;
340 struct resource *res;
341 int ret = 0;
342
343 CRYPTO_TRACE();
344
345 crypto_info = devm_kzalloc(&pdev->dev, sizeof(*crypto_info),
346 GFP_KERNEL);
347 if (!crypto_info)
348 return -ENOMEM;
349
350 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
351 crypto_info->reg = devm_ioremap_resource(&pdev->dev, res);
352 if (IS_ERR(crypto_info->reg)) {
353 dev_err(crypto_info->dev,
354 "devm_ioremap_resource crypto reg error.\n");
355 ret = PTR_ERR(crypto_info->reg);
356 goto exit;
357 }
358
359 crypto_info->dev = &pdev->dev;
360 crypto_info->clks_num =
361 devm_clk_bulk_get_all(&pdev->dev, &crypto_info->clk_bulks);
362 if (crypto_info->clks_num < 0) {
363 dev_err(&pdev->dev, "failed to get clks property\n");
364 ret = -ENODEV;
365 goto exit;
366 }
367
368 ret = clk_bulk_prepare_enable(crypto_info->clks_num, crypto_info->clk_bulks);
369 if (ret) {
370 dev_err(&pdev->dev, "failed to enable clks\n");
371 goto exit;
372 }
373
374 crypto_info->irq = platform_get_irq(pdev, 0);
375 if (crypto_info->irq < 0) {
376 dev_err(crypto_info->dev,
377 "control Interrupt is not available.\n");
378 ret = crypto_info->irq;
379 goto exit;
380 }
381
382 ret = devm_request_irq(&pdev->dev, crypto_info->irq,
383 rk_tb_crypto_irq_handle, IRQF_SHARED,
384 "rk-tb-crypto", pdev);
385
386 if (ret) {
387 dev_err(crypto_info->dev, "irq request failed.\n");
388 goto exit;
389 }
390
391 crypto_info->desc = devm_kzalloc(&pdev->dev, sizeof(struct crypto_data),
392 GFP_KERNEL | GFP_DMA);
393 crypto_info->desc_dma = (dma_addr_t)virt_to_phys(crypto_info->desc);
394 if (!crypto_info->desc) {
395 dev_err(crypto_info->dev, "desc alloc failed.\n");
396 ret = -ENOMEM;
397 goto exit;
398 }
399
400 g_crypto_info = crypto_info;
401 platform_set_drvdata(pdev, crypto_info);
402 complete(&sha256_probe_complete);
403 exit:
404 return ret;
405 }
406
407 #ifdef CONFIG_OF
408 static const struct of_device_id rk_tb_crypto_dt_match[] = {
409 { .compatible = "rockchip,rv1126-crypto" },
410 {},
411 };
412 #endif
413
414 static struct platform_driver rk_tb_crypto_driver = {
415 .driver = {
416 .name = "rockchip_thunder_boot_crypto",
417 .of_match_table = rk_tb_crypto_dt_match,
418 },
419 };
420
rk_tb_crypto_init(void)421 static int __init rk_tb_crypto_init(void)
422 {
423 struct device_node *node;
424
425 CRYPTO_TRACE();
426
427 node = of_find_matching_node(NULL, rk_tb_crypto_dt_match);
428 if (node) {
429 of_platform_device_create(node, NULL, NULL);
430 of_node_put(node);
431 return platform_driver_probe(&rk_tb_crypto_driver,
432 rk_tb_crypto_probe);
433 }
434
435 CRYPTO_TRACE();
436
437 return 0;
438 }
439
440 pure_initcall(rk_tb_crypto_init);
441