xref: /OK3568_Linux_fs/kernel/drivers/crypto/ccree/cc_sram_mgr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright (C) 2012-2019 ARM Limited (or its affiliates). */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include "cc_driver.h"
5*4882a593Smuzhiyun #include "cc_sram_mgr.h"
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun /**
8*4882a593Smuzhiyun  * cc_sram_mgr_init() - Initializes SRAM pool.
9*4882a593Smuzhiyun  *      The pool starts right at the beginning of SRAM.
10*4882a593Smuzhiyun  *      Returns zero for success, negative value otherwise.
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * @drvdata: Associated device driver context
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * Return:
15*4882a593Smuzhiyun  * 0 for success, negative error code for failure.
16*4882a593Smuzhiyun  */
cc_sram_mgr_init(struct cc_drvdata * drvdata)17*4882a593Smuzhiyun int cc_sram_mgr_init(struct cc_drvdata *drvdata)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun 	u32 start = 0;
20*4882a593Smuzhiyun 	struct device *dev = drvdata_to_dev(drvdata);
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	if (drvdata->hw_rev < CC_HW_REV_712) {
23*4882a593Smuzhiyun 		/* Pool starts after ROM bytes */
24*4882a593Smuzhiyun 		start = cc_ioread(drvdata, CC_REG(HOST_SEP_SRAM_THRESHOLD));
25*4882a593Smuzhiyun 		if ((start & 0x3) != 0) {
26*4882a593Smuzhiyun 			dev_err(dev, "Invalid SRAM offset 0x%x\n", start);
27*4882a593Smuzhiyun 			return -EINVAL;
28*4882a593Smuzhiyun 		}
29*4882a593Smuzhiyun 	}
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	drvdata->sram_free_offset = start;
32*4882a593Smuzhiyun 	return 0;
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /**
36*4882a593Smuzhiyun  * cc_sram_alloc() - Allocate buffer from SRAM pool.
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * @drvdata: Associated device driver context
39*4882a593Smuzhiyun  * @size: The requested numer of bytes to allocate
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  * Return:
42*4882a593Smuzhiyun  * Address offset in SRAM or NULL_SRAM_ADDR for failure.
43*4882a593Smuzhiyun  */
cc_sram_alloc(struct cc_drvdata * drvdata,u32 size)44*4882a593Smuzhiyun u32 cc_sram_alloc(struct cc_drvdata *drvdata, u32 size)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	struct device *dev = drvdata_to_dev(drvdata);
47*4882a593Smuzhiyun 	u32 p;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if ((size & 0x3)) {
50*4882a593Smuzhiyun 		dev_err(dev, "Requested buffer size (%u) is not multiple of 4",
51*4882a593Smuzhiyun 			size);
52*4882a593Smuzhiyun 		return NULL_SRAM_ADDR;
53*4882a593Smuzhiyun 	}
54*4882a593Smuzhiyun 	if (size > (CC_CC_SRAM_SIZE - drvdata->sram_free_offset)) {
55*4882a593Smuzhiyun 		dev_err(dev, "Not enough space to allocate %u B (at offset %u)\n",
56*4882a593Smuzhiyun 			size, drvdata->sram_free_offset);
57*4882a593Smuzhiyun 		return NULL_SRAM_ADDR;
58*4882a593Smuzhiyun 	}
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	p = drvdata->sram_free_offset;
61*4882a593Smuzhiyun 	drvdata->sram_free_offset += size;
62*4882a593Smuzhiyun 	dev_dbg(dev, "Allocated %u B @ %u\n", size, p);
63*4882a593Smuzhiyun 	return p;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /**
67*4882a593Smuzhiyun  * cc_set_sram_desc() - Create const descriptors sequence to
68*4882a593Smuzhiyun  *	set values in given array into SRAM.
69*4882a593Smuzhiyun  * Note: each const value can't exceed word size.
70*4882a593Smuzhiyun  *
71*4882a593Smuzhiyun  * @src:	  A pointer to array of words to set as consts.
72*4882a593Smuzhiyun  * @dst:	  The target SRAM buffer to set into
73*4882a593Smuzhiyun  * @nelement:	  The number of words in "src" array
74*4882a593Smuzhiyun  * @seq:	  A pointer to the given IN/OUT descriptor sequence
75*4882a593Smuzhiyun  * @seq_len:	  A pointer to the given IN/OUT sequence length
76*4882a593Smuzhiyun  */
cc_set_sram_desc(const u32 * src,u32 dst,unsigned int nelement,struct cc_hw_desc * seq,unsigned int * seq_len)77*4882a593Smuzhiyun void cc_set_sram_desc(const u32 *src, u32 dst, unsigned int nelement,
78*4882a593Smuzhiyun 		      struct cc_hw_desc *seq, unsigned int *seq_len)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	u32 i;
81*4882a593Smuzhiyun 	unsigned int idx = *seq_len;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	for (i = 0; i < nelement; i++, idx++) {
84*4882a593Smuzhiyun 		hw_desc_init(&seq[idx]);
85*4882a593Smuzhiyun 		set_din_const(&seq[idx], src[i], sizeof(u32));
86*4882a593Smuzhiyun 		set_dout_sram(&seq[idx], dst + (i * sizeof(u32)), sizeof(u32));
87*4882a593Smuzhiyun 		set_flow_mode(&seq[idx], BYPASS);
88*4882a593Smuzhiyun 	}
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	*seq_len = idx;
91*4882a593Smuzhiyun }
92