Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Support for Marvell's Cryptographic Engine and Security Accelerator (CESA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * that can be found on the following platform: Orion, Kirkwood, Armada. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * driver supports the TDMA engine on platforms on which it is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Author: Arnaud Ebalard <arno@natisbad.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * This work is based on an initial version written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/genalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/mbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "cesa.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* Limit of the crypto queue before reaching the backlog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define CESA_CRYPTO_DEFAULT_MAX_QLEN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) struct mv_cesa_dev *cesa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) struct crypto_async_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) mv_cesa_dequeue_req_locked(struct mv_cesa_engine *engine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			   struct crypto_async_request **backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct crypto_async_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	*backlog = crypto_get_backlog(&engine->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	req = crypto_dequeue_request(&engine->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static void mv_cesa_rearm_engine(struct mv_cesa_engine *engine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct crypto_async_request *req = NULL, *backlog = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct mv_cesa_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	spin_lock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (!engine->req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		req = mv_cesa_dequeue_req_locked(engine, &backlog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		engine->req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	spin_unlock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		backlog->complete(backlog, -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	ctx = crypto_tfm_ctx(req->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	ctx->ops->step(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int mv_cesa_std_process(struct mv_cesa_engine *engine, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct crypto_async_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct mv_cesa_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	req = engine->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	ctx = crypto_tfm_ctx(req->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	res = ctx->ops->process(req, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (res == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		ctx->ops->complete(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		mv_cesa_engine_enqueue_complete_request(engine, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	} else if (res == -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		ctx->ops->step(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static int mv_cesa_int_process(struct mv_cesa_engine *engine, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (engine->chain.first && engine->chain.last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		return mv_cesa_tdma_process(engine, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return mv_cesa_std_process(engine, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mv_cesa_complete_req(struct mv_cesa_ctx *ctx, struct crypto_async_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		     int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	ctx->ops->cleanup(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	req->complete(req, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static irqreturn_t mv_cesa_int(int irq, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct mv_cesa_engine *engine = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct crypto_async_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct mv_cesa_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	u32 status, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		mask = mv_cesa_get_int_mask(engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		status = readl(engine->regs + CESA_SA_INT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		if (!(status & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		 * TODO: avoid clearing the FPGA_INT_STATUS if this not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		 * relevant on some platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		writel(~status, engine->regs + CESA_SA_FPGA_INT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		writel(~status, engine->regs + CESA_SA_INT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		/* Process fetched requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		res = mv_cesa_int_process(engine, status & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		spin_lock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		req = engine->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		if (res != -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			engine->req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		spin_unlock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		ctx = crypto_tfm_ctx(req->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		if (res && res != -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			mv_cesa_complete_req(ctx, req, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		/* Launch the next pending request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		mv_cesa_rearm_engine(engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		/* Iterate over the complete queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			req = mv_cesa_engine_dequeue_complete_request(engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			ctx = crypto_tfm_ctx(req->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			mv_cesa_complete_req(ctx, req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int mv_cesa_queue_req(struct crypto_async_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		      struct mv_cesa_req *creq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct mv_cesa_engine *engine = creq->engine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	spin_lock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	ret = crypto_enqueue_request(&engine->queue, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if ((mv_cesa_req_get_type(creq) == CESA_DMA_REQ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	    (ret == -EINPROGRESS || ret == -EBUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		mv_cesa_tdma_chain(engine, creq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	spin_unlock_bh(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (ret != -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	mv_cesa_rearm_engine(engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int mv_cesa_add_algs(struct mv_cesa_dev *cesa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	for (i = 0; i < cesa->caps->ncipher_algs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		ret = crypto_register_skcipher(cesa->caps->cipher_algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			goto err_unregister_crypto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	for (i = 0; i < cesa->caps->nahash_algs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		ret = crypto_register_ahash(cesa->caps->ahash_algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			goto err_unregister_ahash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) err_unregister_ahash:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	for (j = 0; j < i; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		crypto_unregister_ahash(cesa->caps->ahash_algs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	i = cesa->caps->ncipher_algs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) err_unregister_crypto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	for (j = 0; j < i; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		crypto_unregister_skcipher(cesa->caps->cipher_algs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void mv_cesa_remove_algs(struct mv_cesa_dev *cesa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	for (i = 0; i < cesa->caps->nahash_algs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		crypto_unregister_ahash(cesa->caps->ahash_algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	for (i = 0; i < cesa->caps->ncipher_algs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		crypto_unregister_skcipher(cesa->caps->cipher_algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static struct skcipher_alg *orion_cipher_algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	&mv_cesa_ecb_des_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	&mv_cesa_cbc_des_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	&mv_cesa_ecb_des3_ede_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	&mv_cesa_cbc_des3_ede_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	&mv_cesa_ecb_aes_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	&mv_cesa_cbc_aes_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static struct ahash_alg *orion_ahash_algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	&mv_md5_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	&mv_sha1_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	&mv_ahmac_md5_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	&mv_ahmac_sha1_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static struct skcipher_alg *armada_370_cipher_algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	&mv_cesa_ecb_des_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	&mv_cesa_cbc_des_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	&mv_cesa_ecb_des3_ede_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	&mv_cesa_cbc_des3_ede_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	&mv_cesa_ecb_aes_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	&mv_cesa_cbc_aes_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static struct ahash_alg *armada_370_ahash_algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	&mv_md5_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	&mv_sha1_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	&mv_sha256_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	&mv_ahmac_md5_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	&mv_ahmac_sha1_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	&mv_ahmac_sha256_alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static const struct mv_cesa_caps orion_caps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	.nengines = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	.cipher_algs = orion_cipher_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	.ncipher_algs = ARRAY_SIZE(orion_cipher_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	.ahash_algs = orion_ahash_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	.nahash_algs = ARRAY_SIZE(orion_ahash_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	.has_tdma = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static const struct mv_cesa_caps kirkwood_caps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	.nengines = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	.cipher_algs = orion_cipher_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	.ncipher_algs = ARRAY_SIZE(orion_cipher_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	.ahash_algs = orion_ahash_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	.nahash_algs = ARRAY_SIZE(orion_ahash_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	.has_tdma = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static const struct mv_cesa_caps armada_370_caps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	.nengines = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	.cipher_algs = armada_370_cipher_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.ncipher_algs = ARRAY_SIZE(armada_370_cipher_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	.ahash_algs = armada_370_ahash_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	.nahash_algs = ARRAY_SIZE(armada_370_ahash_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	.has_tdma = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static const struct mv_cesa_caps armada_xp_caps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	.nengines = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	.cipher_algs = armada_370_cipher_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.ncipher_algs = ARRAY_SIZE(armada_370_cipher_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.ahash_algs = armada_370_ahash_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	.nahash_algs = ARRAY_SIZE(armada_370_ahash_algs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.has_tdma = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static const struct of_device_id mv_cesa_of_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	{ .compatible = "marvell,orion-crypto", .data = &orion_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	{ .compatible = "marvell,kirkwood-crypto", .data = &kirkwood_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	{ .compatible = "marvell,dove-crypto", .data = &kirkwood_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	{ .compatible = "marvell,armada-370-crypto", .data = &armada_370_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	{ .compatible = "marvell,armada-xp-crypto", .data = &armada_xp_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	{ .compatible = "marvell,armada-375-crypto", .data = &armada_xp_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	{ .compatible = "marvell,armada-38x-crypto", .data = &armada_xp_caps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) MODULE_DEVICE_TABLE(of, mv_cesa_of_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mv_cesa_conf_mbus_windows(struct mv_cesa_engine *engine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			  const struct mbus_dram_target_info *dram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	void __iomem *iobase = engine->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		writel(0, iobase + CESA_TDMA_WINDOW_CTRL(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		writel(0, iobase + CESA_TDMA_WINDOW_BASE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	for (i = 0; i < dram->num_cs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		const struct mbus_dram_window *cs = dram->cs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		writel(((cs->size - 1) & 0xffff0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		       (cs->mbus_attr << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		       (dram->mbus_dram_target_id << 4) | 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		       iobase + CESA_TDMA_WINDOW_CTRL(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		writel(cs->base, iobase + CESA_TDMA_WINDOW_BASE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	struct device *dev = cesa->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	struct mv_cesa_dev_dma *dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (!cesa->caps->has_tdma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (!dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	dma->tdma_desc_pool = dmam_pool_create("tdma_desc", dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 					sizeof(struct mv_cesa_tdma_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 					16, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (!dma->tdma_desc_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	dma->op_pool = dmam_pool_create("cesa_op", dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 					sizeof(struct mv_cesa_op_ctx), 16, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (!dma->op_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	dma->cache_pool = dmam_pool_create("cesa_cache", dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					   CESA_MAX_HASH_BLOCK_SIZE, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (!dma->cache_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (!dma->padding_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	cesa->dma = dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct mv_cesa_engine *engine = &cesa->engines[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	const char *res_name = "sram";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	engine->pool = of_gen_pool_get(cesa->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 				       "marvell,crypto-srams", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (engine->pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		engine->sram = gen_pool_dma_alloc(engine->pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 						  cesa->sram_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 						  &engine->sram_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		if (engine->sram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		engine->pool = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	if (cesa->caps->nengines > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (!idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			res_name = "sram0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			res_name = "sram1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 					   res_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (!res || resource_size(res) < cesa->sram_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	engine->sram = devm_ioremap_resource(cesa->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (IS_ERR(engine->sram))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		return PTR_ERR(engine->sram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	engine->sram_dma = dma_map_resource(cesa->dev, res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 					    cesa->sram_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 					    DMA_BIDIRECTIONAL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	if (dma_mapping_error(cesa->dev, engine->sram_dma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static void mv_cesa_put_sram(struct platform_device *pdev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct mv_cesa_engine *engine = &cesa->engines[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	if (engine->pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		gen_pool_free(engine->pool, (unsigned long)engine->sram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			      cesa->sram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		dma_unmap_resource(cesa->dev, engine->sram_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				   cesa->sram_size, DMA_BIDIRECTIONAL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int mv_cesa_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	const struct mv_cesa_caps *caps = &orion_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	const struct mbus_dram_target_info *dram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	struct mv_cesa_dev *cesa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct mv_cesa_engine *engines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	int irq, ret, i, cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	u32 sram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (cesa_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		dev_err(&pdev->dev, "Only one CESA device authorized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		match = of_match_node(mv_cesa_of_match_table, dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		if (!match || !match->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		caps = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	cesa = devm_kzalloc(dev, sizeof(*cesa), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	if (!cesa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	cesa->caps = caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	cesa->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	sram_size = CESA_SA_DEFAULT_SRAM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	of_property_read_u32(cesa->dev->of_node, "marvell,crypto-sram-size",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			     &sram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (sram_size < CESA_SA_MIN_SRAM_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		sram_size = CESA_SA_MIN_SRAM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	cesa->sram_size = sram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	cesa->engines = devm_kcalloc(dev, caps->nengines, sizeof(*engines),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (!cesa->engines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	spin_lock_init(&cesa->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	cesa->regs = devm_platform_ioremap_resource_byname(pdev, "regs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (IS_ERR(cesa->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		return PTR_ERR(cesa->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	ret = mv_cesa_dev_dma_init(cesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	dram = mv_mbus_dram_info_nooverlap();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	platform_set_drvdata(pdev, cesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	for (i = 0; i < caps->nengines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		struct mv_cesa_engine *engine = &cesa->engines[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		char res_name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		engine->id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		spin_lock_init(&engine->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		ret = mv_cesa_get_sram(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		irq = platform_get_irq(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			ret = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		engine->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		 * Not all platforms can gate the CESA clocks: do not complain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		 * if the clock does not exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		snprintf(res_name, sizeof(res_name), "cesa%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		engine->clk = devm_clk_get(dev, res_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		if (IS_ERR(engine->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 			engine->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			if (IS_ERR(engine->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 				engine->clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		snprintf(res_name, sizeof(res_name), "cesaz%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		engine->zclk = devm_clk_get(dev, res_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		if (IS_ERR(engine->zclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			engine->zclk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		ret = clk_prepare_enable(engine->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		ret = clk_prepare_enable(engine->zclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 			goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		engine->regs = cesa->regs + CESA_ENGINE_OFF(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		if (dram && cesa->caps->has_tdma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			mv_cesa_conf_mbus_windows(engine, dram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		writel(0, engine->regs + CESA_SA_INT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		writel(CESA_SA_CFG_STOP_DIG_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		       engine->regs + CESA_SA_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		writel(engine->sram_dma & CESA_SA_SRAM_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		       engine->regs + CESA_SA_DESC_P0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ret = devm_request_threaded_irq(dev, irq, NULL, mv_cesa_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 						IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 						dev_name(&pdev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 						engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		/* Set affinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		cpu = cpumask_local_spread(engine->id, NUMA_NO_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		irq_set_affinity_hint(irq, get_cpu_mask(cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		crypto_init_queue(&engine->queue, CESA_CRYPTO_DEFAULT_MAX_QLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		atomic_set(&engine->load, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		INIT_LIST_HEAD(&engine->complete_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	cesa_dev = cesa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	ret = mv_cesa_add_algs(cesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		cesa_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	dev_info(dev, "CESA device successfully registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) err_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	for (i = 0; i < caps->nengines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		clk_disable_unprepare(cesa->engines[i].zclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		clk_disable_unprepare(cesa->engines[i].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		mv_cesa_put_sram(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (cesa->engines[i].irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			irq_set_affinity_hint(cesa->engines[i].irq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int mv_cesa_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	mv_cesa_remove_algs(cesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	for (i = 0; i < cesa->caps->nengines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		clk_disable_unprepare(cesa->engines[i].zclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		clk_disable_unprepare(cesa->engines[i].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		mv_cesa_put_sram(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		irq_set_affinity_hint(cesa->engines[i].irq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static const struct platform_device_id mv_cesa_plat_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	{ .name = "mv_crypto" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	{ /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) MODULE_DEVICE_TABLE(platform, mv_cesa_plat_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static struct platform_driver marvell_cesa = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	.probe		= mv_cesa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	.remove		= mv_cesa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	.id_table	= mv_cesa_plat_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		.name	= "marvell-cesa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		.of_match_table = mv_cesa_of_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) module_platform_driver(marvell_cesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) MODULE_ALIAS("platform:mv_crypto");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) MODULE_AUTHOR("Arnaud Ebalard <arno@natisbad.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) MODULE_DESCRIPTION("Support for Marvell's cryptographic engine");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) MODULE_LICENSE("GPL v2");