Revert "crypto: tegra: Use separate buffer for each host1x command"

This reverts commit f6c3d49e92.

Reason for revert: Optimize implementation and align with upstream.

Bug 4883011

Change-Id: I32fe35daa30ddb5a272dbeee0c3316134e9ca55b
Signed-off-by: Brad Griffis <bgriffis@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3321697
(cherry picked from commit efeb1061bb)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3322625
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
This commit is contained in:
Brad Griffis
2025-03-18 09:28:16 -07:00
committed by Amulya Yarlagadda
parent 087418781c
commit 36a712b801
5 changed files with 39 additions and 78 deletions

View File

@@ -42,7 +42,6 @@ struct tegra_aes_reqctx {
u32 crypto_config; u32 crypto_config;
u32 len; u32 len;
u32 *iv; u32 *iv;
u32 *cmdbuf;
}; };
struct tegra_aead_ctx { struct tegra_aead_ctx {
@@ -70,7 +69,6 @@ struct tegra_aead_reqctx {
u32 key_id; u32 key_id;
u32 iv[4]; u32 iv[4];
u8 authdata[16]; u8 authdata[16];
u32 *cmdbuf;
}; };
struct tegra_cmac_ctx { struct tegra_cmac_ctx {
@@ -95,7 +93,6 @@ struct tegra_cmac_reqctx {
u32 key_id; u32 key_id;
u32 *iv; u32 *iv;
u32 result[CMAC_RESULT_REG_COUNT]; u32 result[CMAC_RESULT_REG_COUNT];
u32 *cmdbuf;
}; };
/* increment counter (128-bit int) */ /* increment counter (128-bit int) */
@@ -216,7 +213,7 @@ static int tegra234_aes_cfg(u32 alg, bool encrypt)
static unsigned int tegra_aes_prep_cmd(struct tegra_se *se, struct tegra_aes_reqctx *rctx) static unsigned int tegra_aes_prep_cmd(struct tegra_se *se, struct tegra_aes_reqctx *rctx)
{ {
unsigned int data_count, res_bits, i = 0, j; unsigned int data_count, res_bits, i = 0, j;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
dma_addr_t addr = rctx->datbuf.addr; dma_addr_t addr = rctx->datbuf.addr;
data_count = rctx->len / AES_BLOCK_SIZE; data_count = rctx->len / AES_BLOCK_SIZE;
@@ -295,17 +292,16 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
/* Prepare the command and submit for execution */ /* Prepare the command and submit for execution */
cmdlen = tegra_aes_prep_cmd(se, rctx); cmdlen = tegra_aes_prep_cmd(se, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
/* Copy the result */ /* Copy the result */
tegra_aes_update_iv(req, ctx); tegra_aes_update_iv(req, ctx);
scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1); scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
/* Free the buffer */ /* Free the buffer */
dma_free_coherent(se->dev, rctx->datbuf.size, dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
rctx->datbuf.buf, rctx->datbuf.addr); rctx->datbuf.buf, rctx->datbuf.addr);
kfree(rctx->cmdbuf);
crypto_finalize_skcipher_request(se->engine, req, ret); crypto_finalize_skcipher_request(se->engine, req, ret);
return 0; return 0;
@@ -463,13 +459,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
if (!req->cryptlen) if (!req->cryptlen)
return 0; return 0;
if (ctx->alg == SE_ALG_ECB)
req->iv = NULL;
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
if (!rctx->cmdbuf)
return -ENOMEM;
rctx->encrypt = encrypt; rctx->encrypt = encrypt;
rctx->config = tegra234_aes_cfg(ctx->alg, encrypt); rctx->config = tegra234_aes_cfg(ctx->alg, encrypt);
rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt); rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt);
@@ -608,7 +597,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
{ {
unsigned int data_count, res_bits, i = 0; unsigned int data_count, res_bits, i = 0;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
data_count = (rctx->assoclen / AES_BLOCK_SIZE); data_count = (rctx->assoclen / AES_BLOCK_SIZE);
res_bits = (rctx->assoclen % AES_BLOCK_SIZE) * 8; res_bits = (rctx->assoclen % AES_BLOCK_SIZE) * 8;
@@ -646,7 +635,7 @@ static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_r
static unsigned int tegra_gcm_crypt_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) static unsigned int tegra_gcm_crypt_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
{ {
unsigned int data_count, res_bits, i = 0, j; unsigned int data_count, res_bits, i = 0, j;
u32 *cpuvaddr = rctx->cmdbuf, op; u32 *cpuvaddr = se->cmdbuf->addr, op;
data_count = (rctx->cryptlen / AES_BLOCK_SIZE); data_count = (rctx->cryptlen / AES_BLOCK_SIZE);
res_bits = (rctx->cryptlen % AES_BLOCK_SIZE) * 8; res_bits = (rctx->cryptlen % AES_BLOCK_SIZE) * 8;
@@ -766,7 +755,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
cmdlen = tegra_gmac_prep_cmd(se, rctx); cmdlen = tegra_gmac_prep_cmd(se, rctx);
return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); return tegra_se_host1x_submit(se, cmdlen);
} }
static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx) static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
@@ -783,7 +772,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
/* Prepare command and submit */ /* Prepare command and submit */
cmdlen = tegra_gcm_crypt_prep_cmd(se, rctx); cmdlen = tegra_gcm_crypt_prep_cmd(se, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
if (ret) if (ret)
return ret; return ret;
@@ -797,7 +786,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx) static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
{ {
struct tegra_se *se = ctx->se; struct tegra_se *se = ctx->se;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
int cmdlen, ret, offset; int cmdlen, ret, offset;
rctx->config = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt); rctx->config = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt);
@@ -806,7 +795,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
/* Prepare command and submit */ /* Prepare command and submit */
cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx); cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
if (ret) if (ret)
return ret; return ret;
@@ -851,7 +840,7 @@ static inline int tegra_ccm_check_iv(const u8 *iv)
static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
{ {
unsigned int data_count, i = 0; unsigned int data_count, i = 0;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
data_count = (rctx->inbuf.size / AES_BLOCK_SIZE) - 1; data_count = (rctx->inbuf.size / AES_BLOCK_SIZE) - 1;
@@ -884,7 +873,7 @@ static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead
static unsigned int tegra_ctr_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) static unsigned int tegra_ctr_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx)
{ {
unsigned int i = 0, j; unsigned int i = 0, j;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
cpuvaddr[i++] = host1x_opcode_setpayload(SE_CRYPTO_CTR_REG_COUNT); cpuvaddr[i++] = host1x_opcode_setpayload(SE_CRYPTO_CTR_REG_COUNT);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->linear_ctr); cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->linear_ctr);
@@ -934,7 +923,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
/* Prepare command and submit */ /* Prepare command and submit */
cmdlen = tegra_cbcmac_prep_cmd(se, rctx); cmdlen = tegra_cbcmac_prep_cmd(se, rctx);
return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); return tegra_se_host1x_submit(se, cmdlen);
} }
static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize) static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize)
@@ -1141,7 +1130,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
/* Prepare command and submit */ /* Prepare command and submit */
cmdlen = tegra_ctr_prep_cmd(se, rctx); cmdlen = tegra_ctr_prep_cmd(se, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
if (ret) if (ret)
return ret; return ret;
@@ -1242,7 +1231,6 @@ outbuf_err:
dma_free_coherent(ctx->se->dev, rctx->inbuf.size, dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
rctx->inbuf.buf, rctx->inbuf.addr); rctx->inbuf.buf, rctx->inbuf.addr);
kfree(rctx->cmdbuf);
crypto_finalize_aead_request(ctx->se->engine, req, ret); crypto_finalize_aead_request(ctx->se->engine, req, ret);
return 0; return 0;
@@ -1316,7 +1304,6 @@ outbuf_err:
rctx->inbuf.buf, rctx->inbuf.addr); rctx->inbuf.buf, rctx->inbuf.addr);
/* Finalize the request if there are no errors */ /* Finalize the request if there are no errors */
kfree(rctx->cmdbuf);
crypto_finalize_aead_request(ctx->se->engine, req, ret); crypto_finalize_aead_request(ctx->se->engine, req, ret);
return 0; return 0;
@@ -1447,10 +1434,6 @@ static int tegra_aead_crypt(struct aead_request *req, bool encrypt)
struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm); struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm);
struct tegra_aead_reqctx *rctx = aead_request_ctx(req); struct tegra_aead_reqctx *rctx = aead_request_ctx(req);
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
if (!rctx->cmdbuf)
return -ENOMEM;
rctx->encrypt = encrypt; rctx->encrypt = encrypt;
return crypto_transfer_aead_request_to_engine(ctx->se->engine, req); return crypto_transfer_aead_request_to_engine(ctx->se->engine, req);
@@ -1482,7 +1465,7 @@ static int tegra_aead_setkey(struct crypto_aead *tfm,
static unsigned int tegra_cmac_prep_cmd(struct tegra_se *se, struct tegra_cmac_reqctx *rctx) static unsigned int tegra_cmac_prep_cmd(struct tegra_se *se, struct tegra_cmac_reqctx *rctx)
{ {
unsigned int data_count, res_bits = 0, i = 0, j; unsigned int data_count, res_bits = 0, i = 0, j;
u32 *cpuvaddr = rctx->cmdbuf, op; u32 *cpuvaddr = se->cmdbuf->addr, op;
data_count = (rctx->datbuf.size / AES_BLOCK_SIZE); data_count = (rctx->datbuf.size / AES_BLOCK_SIZE);
@@ -1617,7 +1600,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
cmdlen = tegra_cmac_prep_cmd(se, rctx); cmdlen = tegra_cmac_prep_cmd(se, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
/* /*
* If this is not the final update, copy the intermediate results * If this is not the final update, copy the intermediate results
* from the registers so that it can be used in the next 'update' * from the registers so that it can be used in the next 'update'
@@ -1662,7 +1645,7 @@ static int tegra_cmac_do_final(struct ahash_request *req)
/* Prepare command and submit */ /* Prepare command and submit */
cmdlen = tegra_cmac_prep_cmd(se, rctx); cmdlen = tegra_cmac_prep_cmd(se, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); ret = tegra_se_host1x_submit(se, cmdlen);
if (ret) if (ret)
goto out; goto out;
@@ -1680,8 +1663,6 @@ out:
out_free: out_free:
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2, dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2,
rctx->residue.buf, rctx->residue.addr); rctx->residue.buf, rctx->residue.addr);
kfree(rctx->cmdbuf);
return ret; return ret;
} }
@@ -1792,14 +1773,10 @@ static int tegra_cmac_init(struct ahash_request *req)
rctx->task = SHA_FIRST; rctx->task = SHA_FIRST;
rctx->blk_size = crypto_ahash_blocksize(tfm); rctx->blk_size = crypto_ahash_blocksize(tfm);
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
if (!rctx->cmdbuf)
return -ENOMEM;
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2, rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
&rctx->residue.addr, GFP_KERNEL); &rctx->residue.addr, GFP_KERNEL);
if (!rctx->residue.buf) if (!rctx->residue.buf)
goto cmdbuf_free; return -ENOMEM;
rctx->residue.size = 0; rctx->residue.size = 0;
rctx->datbuf.size = 0; rctx->datbuf.size = 0;
@@ -1809,11 +1786,6 @@ static int tegra_cmac_init(struct ahash_request *req)
writel(0, se->base + se->hw->regs->result + (i * 4)); writel(0, se->base + se->hw->regs->result + (i * 4));
return 0; return 0;
cmdbuf_free:
kfree(rctx->cmdbuf);
return -ENOMEM;
} }
static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,

View File

@@ -44,7 +44,6 @@ struct tegra_sha_reqctx {
unsigned int blk_size; unsigned int blk_size;
unsigned int task; unsigned int task;
u32 key_id; u32 key_id;
u32 *cmdbuf;
u32 result[HASH_RESULT_REG_COUNT]; u32 result[HASH_RESULT_REG_COUNT];
struct ahash_request fallback_req; struct ahash_request fallback_req;
}; };
@@ -306,7 +305,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req); struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
unsigned int nblks, nresidue, size, ret; unsigned int nblks, nresidue, size, ret;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = ctx->se->cmdbuf->addr;
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size; nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size; nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size;
@@ -367,7 +366,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx); size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
ret = tegra_se_host1x_submit(ctx->se, rctx->cmdbuf, size); ret = tegra_se_host1x_submit(ctx->se, size);
/* /*
* If this is not the final update, copy the intermediate results * If this is not the final update, copy the intermediate results
@@ -389,7 +388,7 @@ static int tegra_sha_do_final(struct ahash_request *req)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm); struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
struct tegra_se *se = ctx->se; struct tegra_se *se = ctx->se;
u32 *cpuvaddr = rctx->cmdbuf; u32 *cpuvaddr = se->cmdbuf->addr;
int size, ret = 0; int size, ret = 0;
rctx->datbuf.size = rctx->residue.size; rctx->datbuf.size = rctx->residue.size;
@@ -410,7 +409,7 @@ static int tegra_sha_do_final(struct ahash_request *req)
} }
size = tegra_sha_prep_cmd(se, cpuvaddr, rctx); size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
ret = tegra_se_host1x_submit(se, rctx->cmdbuf, size); ret = tegra_se_host1x_submit(se, size);
if (ret) if (ret)
goto out; goto out;
@@ -426,8 +425,6 @@ out_free:
rctx->residue.buf, rctx->residue.addr); rctx->residue.buf, rctx->residue.addr);
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
rctx->digest.addr); rctx->digest.addr);
kfree(rctx->cmdbuf);
return ret; return ret;
} }
@@ -552,10 +549,6 @@ static int tegra_sha_init(struct ahash_request *req)
rctx->blk_size = crypto_ahash_blocksize(tfm); rctx->blk_size = crypto_ahash_blocksize(tfm);
rctx->digest.size = crypto_ahash_digestsize(tfm); rctx->digest.size = crypto_ahash_digestsize(tfm);
rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL);
if (!rctx->cmdbuf)
return -ENOMEM;
rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size, rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
&rctx->digest.addr, GFP_KERNEL); &rctx->digest.addr, GFP_KERNEL);
if (!rctx->digest.buf) if (!rctx->digest.buf)
@@ -572,8 +565,6 @@ resbuf_fail:
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
rctx->digest.addr); rctx->digest.addr);
digbuf_fail: digbuf_fail:
kfree(rctx->cmdbuf);
return -ENOMEM; return -ENOMEM;
} }

View File

@@ -115,11 +115,11 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
u32 keylen, u16 slot, u32 alg) u32 keylen, u16 slot, u32 alg)
{ {
const u32 *keyval = (u32 *)key; const u32 *keyval = (u32 *)key;
u32 addr[100], size; u32 *addr = se->cmdbuf->addr, size;
size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg); size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg);
return tegra_se_host1x_submit(se, addr, size); return tegra_se_host1x_submit(se, size);
} }
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg) void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)

View File

@@ -141,10 +141,9 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
return cmdbuf; return cmdbuf;
} }
int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size) int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
{ {
struct host1x_job *job; struct host1x_job *job;
struct tegra_se_cmdbuf *cmdbuf;
int ret; int ret;
job = host1x_job_alloc(se->channel, 1, 0, true); job = host1x_job_alloc(se->channel, 1, 0, true);
@@ -153,12 +152,6 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size)
return -ENOMEM; return -ENOMEM;
} }
cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
if (!cmdbuf)
goto job_put;
memcpy(cmdbuf->addr, cpuvaddr, size * 4);
job->syncpt = host1x_syncpt_get(se->syncpt); job->syncpt = host1x_syncpt_get(se->syncpt);
job->syncpt_incrs = 1; job->syncpt_incrs = 1;
job->client = &se->client; job->client = &se->client;
@@ -167,14 +160,14 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size)
job->engine_fallback_streamid = se->stream_id; job->engine_fallback_streamid = se->stream_id;
job->engine_streamid_offset = SE_STREAM_ID; job->engine_streamid_offset = SE_STREAM_ID;
cmdbuf->words = size; se->cmdbuf->words = size;
host1x_job_add_gather(job, &cmdbuf->bo, size, 0); host1x_job_add_gather(job, &se->cmdbuf->bo, size, 0);
ret = host1x_job_pin(job, se->dev); ret = host1x_job_pin(job, se->dev);
if (ret) { if (ret) {
dev_err(se->dev, "failed to pin host1x job\n"); dev_err(se->dev, "failed to pin host1x job\n");
goto cmdbuf_put; goto job_put;
} }
ret = host1x_job_submit(job); ret = host1x_job_submit(job);
@@ -191,14 +184,10 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size)
} }
host1x_job_put(job); host1x_job_put(job);
tegra_se_cmdbuf_put(&cmdbuf->bo);
return 0; return 0;
job_unpin: job_unpin:
host1x_job_unpin(job); host1x_job_unpin(job);
cmdbuf_put:
tegra_se_cmdbuf_put(&cmdbuf->bo);
job_put: job_put:
host1x_job_put(job); host1x_job_put(job);
@@ -225,14 +214,22 @@ static int tegra_se_client_init(struct host1x_client *client)
se->syncpt_id = host1x_syncpt_id(se->syncpt); se->syncpt_id = host1x_syncpt_id(se->syncpt);
se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
if (!se->cmdbuf) {
ret = -ENOMEM;
goto syncpt_put;
}
ret = se->hw->init_alg(se); ret = se->hw->init_alg(se);
if (ret) { if (ret) {
dev_err(se->dev, "failed to register algorithms\n"); dev_err(se->dev, "failed to register algorithms\n");
goto syncpt_put; goto cmdbuf_put;
} }
return 0; return 0;
cmdbuf_put:
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
syncpt_put: syncpt_put:
host1x_syncpt_put(se->syncpt); host1x_syncpt_put(se->syncpt);
channel_put: channel_put:
@@ -246,6 +243,7 @@ static int tegra_se_client_deinit(struct host1x_client *client)
struct tegra_se *se = container_of(client, struct tegra_se, client); struct tegra_se *se = container_of(client, struct tegra_se, client);
se->hw->deinit_alg(se); se->hw->deinit_alg(se);
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
host1x_syncpt_put(se->syncpt); host1x_syncpt_put(se->syncpt);
host1x_channel_put(se->channel); host1x_channel_put(se->channel);

View File

@@ -23,7 +23,6 @@
#define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x) #define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x)
#define TEGRA_GPSE_ID 3 #define TEGRA_GPSE_ID 3
#define SE_MAX_CMDLEN (100 * 4) /* max 100 commands of 4 bytes each */
#define SE_STREAM_ID 0x90 #define SE_STREAM_ID 0x90
#define SE_SHA_CFG 0x4004 #define SE_SHA_CFG 0x4004
@@ -442,6 +441,7 @@ struct tegra_se {
const struct tegra_se_hw *hw; const struct tegra_se_hw *hw;
struct host1x_client client; struct host1x_client client;
struct host1x_channel *channel; struct host1x_channel *channel;
struct tegra_se_cmdbuf *cmdbuf;
struct crypto_engine *engine; struct crypto_engine *engine;
struct host1x_syncpt *syncpt; struct host1x_syncpt *syncpt;
struct device *dev; struct device *dev;
@@ -524,7 +524,7 @@ void tegra_deinit_hash(struct tegra_se *se);
int tegra_key_submit(struct tegra_se *se, const u8 *key, int tegra_key_submit(struct tegra_se *se, const u8 *key,
u32 keylen, u32 alg, u32 *keyid); u32 keylen, u32 alg, u32 *keyid);
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg); void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size); int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
/* HOST1x OPCODES */ /* HOST1x OPCODES */
static inline u32 host1x_opcode_setpayload(unsigned int payload) static inline u32 host1x_opcode_setpayload(unsigned int payload)