]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/ccree/ssi_sram_mgr.c
Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[karo-tx-linux.git] / drivers / staging / ccree / ssi_sram_mgr.c
1 /*
2  * Copyright (C) 2012-2017 ARM Limited or its affiliates.
3  * 
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  * 
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include "ssi_driver.h"
18 #include "ssi_sram_mgr.h"
19
20
21 /**
22  * struct ssi_sram_mgr_ctx -Internal RAM context manager
23  * @sram_free_offset:   the offset to the non-allocated area
24  */
25 struct ssi_sram_mgr_ctx {
26         ssi_sram_addr_t sram_free_offset;
27 };
28
29
30 /**
31  * ssi_sram_mgr_fini() - Cleanup SRAM pool.
32  * 
33  * @drvdata: Associated device driver context
34  */
35 void ssi_sram_mgr_fini(struct ssi_drvdata *drvdata)
36 {
37         struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle;
38
39         /* Free "this" context */
40         if (smgr_ctx != NULL) {
41                 memset(smgr_ctx, 0, sizeof(struct ssi_sram_mgr_ctx));
42                 kfree(smgr_ctx);
43         }
44 }
45
46 /**
47  * ssi_sram_mgr_init() - Initializes SRAM pool. 
48  *      The pool starts right at the beginning of SRAM.
49  *      Returns zero for success, negative value otherwise.
50  * 
51  * @drvdata: Associated device driver context
52  */
53 int ssi_sram_mgr_init(struct ssi_drvdata *drvdata)
54 {
55         struct ssi_sram_mgr_ctx *smgr_ctx;
56         int rc;
57
58         /* Allocate "this" context */
59         drvdata->sram_mgr_handle = kzalloc(
60                         sizeof(struct ssi_sram_mgr_ctx), GFP_KERNEL);
61         if (!drvdata->sram_mgr_handle) {
62                 SSI_LOG_ERR("Not enough memory to allocate SRAM_MGR ctx (%zu)\n",
63                         sizeof(struct ssi_sram_mgr_ctx));
64                 rc = -ENOMEM;
65                 goto out;
66         }
67         smgr_ctx = drvdata->sram_mgr_handle;
68
69         /* Pool starts at start of SRAM */
70         smgr_ctx->sram_free_offset = 0;
71
72         return 0;
73
74 out:
75         ssi_sram_mgr_fini(drvdata);
76         return rc;
77 }
78
79 /*!
80  * Allocated buffer from SRAM pool. 
81  * Note: Caller is responsible to free the LAST allocated buffer. 
82  * This function does not taking care of any fragmentation may occur 
83  * by the order of calls to alloc/free. 
84  * 
85  * \param drvdata 
86  * \param size The requested bytes to allocate
87  */
88 ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, uint32_t size)
89 {
90         struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle;
91         ssi_sram_addr_t p;
92
93         if (unlikely((size & 0x3) != 0)) {
94                 SSI_LOG_ERR("Requested buffer size (%u) is not multiple of 4",
95                         size);
96                 return NULL_SRAM_ADDR;
97         }
98         if (unlikely(size > (SSI_CC_SRAM_SIZE - smgr_ctx->sram_free_offset))) {
99                 SSI_LOG_ERR("Not enough space to allocate %u B (at offset %llu)\n",
100                         size, smgr_ctx->sram_free_offset);
101                 return NULL_SRAM_ADDR;
102         }
103         
104         p = smgr_ctx->sram_free_offset;
105         smgr_ctx->sram_free_offset += size;
106         SSI_LOG_DEBUG("Allocated %u B @ %u\n", size, (unsigned int)p);
107         return p;
108 }
109
110 /**
111  * ssi_sram_mgr_const2sram_desc() - Create const descriptors sequence to
112  *      set values in given array into SRAM. 
113  * Note: each const value can't exceed word size.
114  * 
115  * @src:          A pointer to array of words to set as consts.
116  * @dst:          The target SRAM buffer to set into
117  * @nelements:    The number of words in "src" array
118  * @seq:          A pointer to the given IN/OUT descriptor sequence
119  * @seq_len:      A pointer to the given IN/OUT sequence length
120  */
121 void ssi_sram_mgr_const2sram_desc(
122         const uint32_t *src, ssi_sram_addr_t dst,
123         unsigned int nelement,
124         HwDesc_s *seq, unsigned int *seq_len)
125 {
126         uint32_t i;
127         unsigned int idx = *seq_len;
128
129         for (i = 0; i < nelement; i++, idx++) {
130                 HW_DESC_INIT(&seq[idx]);
131                 HW_DESC_SET_DIN_CONST(&seq[idx], src[i], sizeof(uint32_t));
132                 HW_DESC_SET_DOUT_SRAM(&seq[idx], dst + (i * sizeof(uint32_t)), sizeof(uint32_t));
133                 HW_DESC_SET_FLOW_MODE(&seq[idx], BYPASS);
134         }
135
136         *seq_len = idx;
137 }
138