1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/cleanup.h>
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/dma-mapping.h>
10 #include <linux/interconnect.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/types.h>
17 #include <crypto/algapi.h>
18 #include <crypto/internal/hash.h>
19
20 #include "core.h"
21 #include "cipher.h"
22 #include "sha.h"
23 #include "aead.h"
24
25 #define QCE_QUEUE_LENGTH 1
26
27 #define QCE_DEFAULT_MEM_BANDWIDTH 393600
28
29 static const struct qce_algo_ops *qce_ops[] = {
30 #ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
31 &skcipher_ops,
32 #endif
33 #ifdef CONFIG_CRYPTO_DEV_QCE_SHA
34 &ahash_ops,
35 #endif
36 #ifdef CONFIG_CRYPTO_DEV_QCE_AEAD
37 &aead_ops,
38 #endif
39 };
40
qce_unregister_algs(void * data)41 static void qce_unregister_algs(void *data)
42 {
43 const struct qce_algo_ops *ops;
44 struct qce_device *qce = data;
45 int i;
46
47 for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
48 ops = qce_ops[i];
49 ops->unregister_algs(qce);
50 }
51 }
52
devm_qce_register_algs(struct qce_device * qce)53 static int devm_qce_register_algs(struct qce_device *qce)
54 {
55 const struct qce_algo_ops *ops;
56 int i, ret;
57
58 for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
59 ops = qce_ops[i];
60 ret = ops->register_algs(qce);
61 if (ret) {
62 while (i--)
63 qce_ops[i]->unregister_algs(qce);
64 return ret;
65 }
66 }
67
68 return devm_add_action_or_reset(qce->dev, qce_unregister_algs, qce);
69 }
70
qce_handle_request(struct crypto_async_request * async_req)71 static int qce_handle_request(struct crypto_async_request *async_req)
72 {
73 int i;
74 const struct qce_algo_ops *ops;
75 u32 type = crypto_tfm_alg_type(async_req->tfm);
76
77 for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
78 ops = qce_ops[i];
79 if (type == ops->type)
80 return ops->async_req_handle(async_req);
81 }
82
83 return -EINVAL;
84 }
85
qce_handle_queue(struct qce_device * qce,struct crypto_async_request * req)86 static int qce_handle_queue(struct qce_device *qce,
87 struct crypto_async_request *req)
88 {
89 struct crypto_async_request *async_req, *backlog;
90 int ret, err;
91
92 PM_RUNTIME_ACQUIRE_AUTOSUSPEND(qce->dev, pm);
93 ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
94 if (ret)
95 return ret;
96
97 scoped_guard(mutex, &qce->lock) {
98 if (req)
99 ret = crypto_enqueue_request(&qce->queue, req);
100
101 /* busy, do not dequeue request */
102 if (qce->req)
103 return ret;
104
105 backlog = crypto_get_backlog(&qce->queue);
106 async_req = crypto_dequeue_request(&qce->queue);
107 if (async_req)
108 qce->req = async_req;
109 }
110
111 if (!async_req)
112 return ret;
113
114 if (backlog) {
115 scoped_guard(mutex, &qce->lock)
116 crypto_request_complete(backlog, -EINPROGRESS);
117 }
118
119 err = qce_handle_request(async_req);
120 if (err) {
121 qce->result = err;
122 schedule_work(&qce->done_work);
123 }
124
125 return ret;
126 }
127
qce_req_done_work(struct work_struct * work)128 static void qce_req_done_work(struct work_struct *work)
129 {
130 struct qce_device *qce = container_of(work, struct qce_device,
131 done_work);
132 struct crypto_async_request *req;
133
134 scoped_guard(mutex, &qce->lock) {
135 req = qce->req;
136 qce->req = NULL;
137 }
138
139 if (req)
140 crypto_request_complete(req, qce->result);
141
142 qce_handle_queue(qce, NULL);
143 }
144
qce_async_request_enqueue(struct qce_device * qce,struct crypto_async_request * req)145 static int qce_async_request_enqueue(struct qce_device *qce,
146 struct crypto_async_request *req)
147 {
148 return qce_handle_queue(qce, req);
149 }
150
qce_async_request_done(struct qce_device * qce,int ret)151 static void qce_async_request_done(struct qce_device *qce, int ret)
152 {
153 qce->result = ret;
154 schedule_work(&qce->done_work);
155 }
156
qce_check_version(struct qce_device * qce)157 static int qce_check_version(struct qce_device *qce)
158 {
159 u32 major, minor, step;
160
161 qce_get_version(qce, &major, &minor, &step);
162
163 /*
164 * the driver does not support v5 with minor 0 because it has special
165 * alignment requirements.
166 */
167 if (major == 5 && minor == 0)
168 return -ENODEV;
169
170 qce->burst_size = QCE_BAM_BURST_SIZE;
171
172 /*
173 * Rx and tx pipes are treated as a pair inside CE.
174 * Pipe pair number depends on the actual BAM dma pipe
175 * that is used for transfers. The BAM dma pipes are passed
176 * from the device tree and used to derive the pipe pair
177 * id in the CE driver as follows.
178 * BAM dma pipes(rx, tx) CE pipe pair id
179 * 0,1 0
180 * 2,3 1
181 * 4,5 2
182 * 6,7 3
183 * ...
184 */
185 qce->pipe_pair_id = qce->dma.rxchan->chan_id >> 1;
186
187 dev_dbg(qce->dev, "Crypto device found, version %d.%d.%d\n",
188 major, minor, step);
189
190 return 0;
191 }
192
qce_crypto_probe(struct platform_device * pdev)193 static int qce_crypto_probe(struct platform_device *pdev)
194 {
195 struct device *dev = &pdev->dev;
196 struct qce_device *qce;
197 int ret;
198
199 qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL);
200 if (!qce)
201 return -ENOMEM;
202
203 qce->dev = dev;
204 platform_set_drvdata(pdev, qce);
205
206 qce->base = devm_platform_ioremap_resource(pdev, 0);
207 if (IS_ERR(qce->base))
208 return PTR_ERR(qce->base);
209
210 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
211 if (ret < 0)
212 return ret;
213
214 qce->core = devm_clk_get_optional(qce->dev, "core");
215 if (IS_ERR(qce->core))
216 return PTR_ERR(qce->core);
217
218 qce->iface = devm_clk_get_optional(qce->dev, "iface");
219 if (IS_ERR(qce->iface))
220 return PTR_ERR(qce->iface);
221
222 qce->bus = devm_clk_get_optional(qce->dev, "bus");
223 if (IS_ERR(qce->bus))
224 return PTR_ERR(qce->bus);
225
226 qce->mem_path = devm_of_icc_get(dev, "memory");
227 if (IS_ERR(qce->mem_path))
228 return PTR_ERR(qce->mem_path);
229
230 /*
231 * Enable runtime PM after clocks and ICC path are acquired so that
232 * the resume callback can enable clocks and apply the ICC bandwidth
233 * vote before any hardware access takes place.
234 */
235 ret = devm_pm_runtime_enable(dev);
236 if (ret)
237 return ret;
238
239 PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
240 ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
241 if (ret)
242 return ret;
243
244 ret = devm_qce_dma_request(qce->dev, &qce->dma);
245 if (ret)
246 return ret;
247
248 ret = qce_check_version(qce);
249 if (ret)
250 return ret;
251
252 ret = devm_mutex_init(qce->dev, &qce->lock);
253 if (ret)
254 return ret;
255
256 INIT_WORK(&qce->done_work, qce_req_done_work);
257 crypto_init_queue(&qce->queue, QCE_QUEUE_LENGTH);
258
259 qce->async_req_enqueue = qce_async_request_enqueue;
260 qce->async_req_done = qce_async_request_done;
261
262 ret = devm_qce_register_algs(qce);
263 if (ret)
264 return ret;
265
266 /* Configure autosuspend after successful init */
267 pm_runtime_set_autosuspend_delay(dev, 100);
268 pm_runtime_use_autosuspend(dev);
269 pm_runtime_mark_last_busy(dev);
270
271 return 0;
272 }
273
qce_runtime_suspend(struct device * dev)274 static int qce_runtime_suspend(struct device *dev)
275 {
276 struct qce_device *qce = dev_get_drvdata(dev);
277 int ret;
278
279 clk_disable_unprepare(qce->core);
280 clk_disable_unprepare(qce->iface);
281 clk_disable_unprepare(qce->bus);
282
283 ret = icc_set_bw(qce->mem_path, 0, 0);
284 if (ret) {
285 clk_prepare_enable(qce->bus);
286 clk_prepare_enable(qce->iface);
287 clk_prepare_enable(qce->core);
288 return ret;
289 }
290
291 return 0;
292 }
293
qce_runtime_resume(struct device * dev)294 static int qce_runtime_resume(struct device *dev)
295 {
296 struct qce_device *qce = dev_get_drvdata(dev);
297 int ret;
298
299 ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH,
300 QCE_DEFAULT_MEM_BANDWIDTH);
301 if (ret)
302 return ret;
303
304 ret = clk_prepare_enable(qce->core);
305 if (ret)
306 goto err_core;
307
308 ret = clk_prepare_enable(qce->iface);
309 if (ret)
310 goto err_iface;
311
312 ret = clk_prepare_enable(qce->bus);
313 if (ret)
314 goto err_bus;
315
316 return 0;
317
318 err_bus:
319 clk_disable_unprepare(qce->iface);
320 err_iface:
321 clk_disable_unprepare(qce->core);
322 err_core:
323 icc_set_bw(qce->mem_path, 0, 0);
324 return ret;
325 }
326
327 static const struct dev_pm_ops qce_crypto_pm_ops = {
328 RUNTIME_PM_OPS(qce_runtime_suspend, qce_runtime_resume, NULL)
329 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
330 };
331
332 static const struct of_device_id qce_crypto_of_match[] = {
333 { .compatible = "qcom,crypto-v5.1", },
334 { .compatible = "qcom,crypto-v5.4", },
335 { .compatible = "qcom,qce", },
336 {}
337 };
338 MODULE_DEVICE_TABLE(of, qce_crypto_of_match);
339
340 static struct platform_driver qce_crypto_driver = {
341 .probe = qce_crypto_probe,
342 .driver = {
343 .name = KBUILD_MODNAME,
344 .of_match_table = qce_crypto_of_match,
345 .pm = pm_ptr(&qce_crypto_pm_ops),
346 },
347 };
348 module_platform_driver(qce_crypto_driver);
349
350 MODULE_LICENSE("GPL v2");
351 MODULE_DESCRIPTION("Qualcomm crypto engine driver");
352 MODULE_ALIAS("platform:" KBUILD_MODNAME);
353 MODULE_AUTHOR("The Linux Foundation");
354