Commit 297b9ceb authored by Horia Geantă's avatar Horia Geantă Committed by Herbert Xu

crypto: caam/jr - add support for DPAA2 parts

Add support for using the caam/jr backend on DPAA2-based SoCs.
These have some particularities we have to account for:
-HW S/G format is different
-Management Complex (MC) firmware initializes / manages (partially)
the CAAM block: MCFGR, QI enablement in QICTL, RNG
Signed-off-by: default avatarHoria Geantă <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent e28c190d
...@@ -791,8 +791,8 @@ static int ahash_update_ctx(struct ahash_request *req) ...@@ -791,8 +791,8 @@ static int ahash_update_ctx(struct ahash_request *req)
to_hash - *buflen, to_hash - *buflen,
*next_buflen, 0); *next_buflen, 0);
} else { } else {
(edesc->sec4_sg + sec4_sg_src_index - 1)->len |= sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index -
cpu_to_caam32(SEC4_SG_LEN_FIN); 1);
} }
desc = edesc->hw_desc; desc = edesc->hw_desc;
...@@ -882,8 +882,7 @@ static int ahash_final_ctx(struct ahash_request *req) ...@@ -882,8 +882,7 @@ static int ahash_final_ctx(struct ahash_request *req)
if (ret) if (ret)
goto unmap_ctx; goto unmap_ctx;
(edesc->sec4_sg + sec4_sg_src_index - 1)->len |= sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index - 1);
cpu_to_caam32(SEC4_SG_LEN_FIN);
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE); sec4_sg_bytes, DMA_TO_DEVICE);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
bool caam_little_end; bool caam_little_end;
EXPORT_SYMBOL(caam_little_end); EXPORT_SYMBOL(caam_little_end);
bool caam_dpaa2;
EXPORT_SYMBOL(caam_dpaa2);
#ifdef CONFIG_CAAM_QI #ifdef CONFIG_CAAM_QI
#include "qi.h" #include "qi.h"
...@@ -319,8 +321,11 @@ static int caam_remove(struct platform_device *pdev) ...@@ -319,8 +321,11 @@ static int caam_remove(struct platform_device *pdev)
caam_qi_shutdown(ctrlpriv->qidev); caam_qi_shutdown(ctrlpriv->qidev);
#endif #endif
/* De-initialize RNG state handles initialized by this driver. */ /*
if (ctrlpriv->rng4_sh_init) * De-initialize RNG state handles initialized by this driver.
* In case of DPAA 2.x, RNG is managed by MC firmware.
*/
if (!caam_dpaa2 && ctrlpriv->rng4_sh_init)
deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
/* Shut down debug views */ /* Shut down debug views */
...@@ -552,12 +557,17 @@ static int caam_probe(struct platform_device *pdev) ...@@ -552,12 +557,17 @@ static int caam_probe(struct platform_device *pdev)
/* /*
* Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
* long pointers in master configuration register * long pointers in master configuration register.
* In case of DPAA 2.x, Management Complex firmware performs
* the configuration.
*/ */
caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
if (!caam_dpaa2)
clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
MCFGR_WDENABLE | MCFGR_LARGE_BURST | MCFGR_WDENABLE | MCFGR_LARGE_BURST |
(sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); (sizeof(dma_addr_t) == sizeof(u64) ?
MCFGR_LONG_PTR : 0));
/* /*
* Read the Compile Time paramters and SCFGR to determine * Read the Compile Time paramters and SCFGR to determine
...@@ -586,7 +596,9 @@ static int caam_probe(struct platform_device *pdev) ...@@ -586,7 +596,9 @@ static int caam_probe(struct platform_device *pdev)
JRSTART_JR3_START); JRSTART_JR3_START);
if (sizeof(dma_addr_t) == sizeof(u64)) { if (sizeof(dma_addr_t) == sizeof(u64)) {
if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) if (caam_dpaa2)
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49));
else if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
else else
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36)); ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
...@@ -629,11 +641,9 @@ static int caam_probe(struct platform_device *pdev) ...@@ -629,11 +641,9 @@ static int caam_probe(struct platform_device *pdev)
ring++; ring++;
} }
/* Check to see if QI present. If so, enable */ /* Check to see if (DPAA 1.x) QI present. If so, enable */
ctrlpriv->qi_present = ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
!!(rd_reg32(&ctrl->perfmon.comp_parms_ms) & if (ctrlpriv->qi_present && !caam_dpaa2) {
CTPR_MS_QI_MASK);
if (ctrlpriv->qi_present) {
ctrlpriv->qi = (struct caam_queue_if __iomem __force *) ctrlpriv->qi = (struct caam_queue_if __iomem __force *)
((__force uint8_t *)ctrl + ((__force uint8_t *)ctrl +
BLOCK_OFFSET * QI_BLOCK_NUMBER BLOCK_OFFSET * QI_BLOCK_NUMBER
...@@ -661,8 +671,10 @@ static int caam_probe(struct platform_device *pdev) ...@@ -661,8 +671,10 @@ static int caam_probe(struct platform_device *pdev)
/* /*
* If SEC has RNG version >= 4 and RNG state handle has not been * If SEC has RNG version >= 4 and RNG state handle has not been
* already instantiated, do RNG instantiation * already instantiated, do RNG instantiation
* In case of DPAA 2.x, RNG is managed by MC firmware.
*/ */
if ((cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) { if (!caam_dpaa2 &&
(cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
ctrlpriv->rng4_sh_init = ctrlpriv->rng4_sh_init =
rd_reg32(&ctrl->r4tst[0].rdsta); rd_reg32(&ctrl->r4tst[0].rdsta);
/* /*
...@@ -730,8 +742,9 @@ static int caam_probe(struct platform_device *pdev) ...@@ -730,8 +742,9 @@ static int caam_probe(struct platform_device *pdev)
/* Report "alive" for developer to see */ /* Report "alive" for developer to see */
dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id, dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
caam_get_era()); caam_get_era());
dev_info(dev, "job rings = %d, qi = %d\n", dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
ctrlpriv->total_jobrs, ctrlpriv->qi_present); ctrlpriv->total_jobrs, ctrlpriv->qi_present,
caam_dpaa2 ? "yes" : "no");
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -10,4 +10,6 @@ ...@@ -10,4 +10,6 @@
/* Prototypes for backend-level services exposed to APIs */ /* Prototypes for backend-level services exposed to APIs */
int caam_get_era(void); int caam_get_era(void);
extern bool caam_dpaa2;
#endif /* CTRL_H */ #endif /* CTRL_H */
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include "compat.h" #include "compat.h"
#include "ctrl.h"
#include "regs.h" #include "regs.h"
#include "jr.h" #include "jr.h"
#include "desc.h" #include "desc.h"
...@@ -499,7 +500,11 @@ static int caam_jr_probe(struct platform_device *pdev) ...@@ -499,7 +500,11 @@ static int caam_jr_probe(struct platform_device *pdev)
jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl; jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl;
if (sizeof(dma_addr_t) == sizeof(u64)) { if (sizeof(dma_addr_t) == sizeof(u64)) {
if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring")) if (caam_dpaa2)
error = dma_set_mask_and_coherent(jrdev,
DMA_BIT_MASK(49));
else if (of_device_is_compatible(nprop,
"fsl,sec-v5.0-job-ring"))
error = dma_set_mask_and_coherent(jrdev, error = dma_set_mask_and_coherent(jrdev,
DMA_BIT_MASK(40)); DMA_BIT_MASK(40));
else else
......
...@@ -293,6 +293,7 @@ struct caam_perfmon { ...@@ -293,6 +293,7 @@ struct caam_perfmon {
u32 cha_rev_ls; /* CRNR - CHA Rev No. Least significant half*/ u32 cha_rev_ls; /* CRNR - CHA Rev No. Least significant half*/
#define CTPR_MS_QI_SHIFT 25 #define CTPR_MS_QI_SHIFT 25
#define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT) #define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT)
#define CTPR_MS_DPAA2 BIT(13)
#define CTPR_MS_VIRT_EN_INCL 0x00000001 #define CTPR_MS_VIRT_EN_INCL 0x00000001
#define CTPR_MS_VIRT_EN_POR 0x00000002 #define CTPR_MS_VIRT_EN_POR 0x00000002
#define CTPR_MS_PG_SZ_MASK 0x10 #define CTPR_MS_PG_SZ_MASK 0x10
......
/*
* Copyright 2015-2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SG_SW_QM2_H_
#define _SG_SW_QM2_H_
#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
static inline void dma_to_qm_sg_one(struct dpaa2_sg_entry *qm_sg_ptr,
dma_addr_t dma, u32 len, u16 offset)
{
dpaa2_sg_set_addr(qm_sg_ptr, dma);
dpaa2_sg_set_format(qm_sg_ptr, dpaa2_sg_single);
dpaa2_sg_set_final(qm_sg_ptr, false);
dpaa2_sg_set_len(qm_sg_ptr, len);
dpaa2_sg_set_bpid(qm_sg_ptr, 0);
dpaa2_sg_set_offset(qm_sg_ptr, offset);
}
/*
* convert scatterlist to h/w link table format
* but does not have final bit; instead, returns last entry
*/
static inline struct dpaa2_sg_entry *
sg_to_qm_sg(struct scatterlist *sg, int sg_count,
struct dpaa2_sg_entry *qm_sg_ptr, u16 offset)
{
while (sg_count && sg) {
dma_to_qm_sg_one(qm_sg_ptr, sg_dma_address(sg),
sg_dma_len(sg), offset);
qm_sg_ptr++;
sg = sg_next(sg);
sg_count--;
}
return qm_sg_ptr - 1;
}
/*
* convert scatterlist to h/w link table format
* scatterlist must have been previously dma mapped
*/
static inline void sg_to_qm_sg_last(struct scatterlist *sg, int sg_count,
struct dpaa2_sg_entry *qm_sg_ptr,
u16 offset)
{
qm_sg_ptr = sg_to_qm_sg(sg, sg_count, qm_sg_ptr, offset);
dpaa2_sg_set_final(qm_sg_ptr, true);
}
#endif /* _SG_SW_QM2_H_ */
...@@ -5,7 +5,13 @@ ...@@ -5,7 +5,13 @@
* *
*/ */
#ifndef _SG_SW_SEC4_H_
#define _SG_SW_SEC4_H_
#include "ctrl.h"
#include "regs.h" #include "regs.h"
#include "sg_sw_qm2.h"
#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
struct sec4_sg_entry { struct sec4_sg_entry {
u64 ptr; u64 ptr;
...@@ -19,9 +25,15 @@ struct sec4_sg_entry { ...@@ -19,9 +25,15 @@ struct sec4_sg_entry {
static inline void dma_to_sec4_sg_one(struct sec4_sg_entry *sec4_sg_ptr, static inline void dma_to_sec4_sg_one(struct sec4_sg_entry *sec4_sg_ptr,
dma_addr_t dma, u32 len, u16 offset) dma_addr_t dma, u32 len, u16 offset)
{ {
if (caam_dpaa2) {
dma_to_qm_sg_one((struct dpaa2_sg_entry *)sec4_sg_ptr, dma, len,
offset);
} else {
sec4_sg_ptr->ptr = cpu_to_caam_dma64(dma); sec4_sg_ptr->ptr = cpu_to_caam_dma64(dma);
sec4_sg_ptr->len = cpu_to_caam32(len); sec4_sg_ptr->len = cpu_to_caam32(len);
sec4_sg_ptr->bpid_offset = cpu_to_caam32(offset & SEC4_SG_OFFSET_MASK); sec4_sg_ptr->bpid_offset = cpu_to_caam32(offset &
SEC4_SG_OFFSET_MASK);
}
#ifdef DEBUG #ifdef DEBUG
print_hex_dump(KERN_ERR, "sec4_sg_ptr@: ", print_hex_dump(KERN_ERR, "sec4_sg_ptr@: ",
DUMP_PREFIX_ADDRESS, 16, 4, sec4_sg_ptr, DUMP_PREFIX_ADDRESS, 16, 4, sec4_sg_ptr,
...@@ -47,6 +59,14 @@ sg_to_sec4_sg(struct scatterlist *sg, int sg_count, ...@@ -47,6 +59,14 @@ sg_to_sec4_sg(struct scatterlist *sg, int sg_count,
return sec4_sg_ptr - 1; return sec4_sg_ptr - 1;
} }
static inline void sg_to_sec4_set_last(struct sec4_sg_entry *sec4_sg_ptr)
{
if (caam_dpaa2)
dpaa2_sg_set_final((struct dpaa2_sg_entry *)sec4_sg_ptr, true);
else
sec4_sg_ptr->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
}
/* /*
* convert scatterlist to h/w link table format * convert scatterlist to h/w link table format
* scatterlist must have been previously dma mapped * scatterlist must have been previously dma mapped
...@@ -56,5 +76,7 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count, ...@@ -56,5 +76,7 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count,
u16 offset) u16 offset)
{ {
sec4_sg_ptr = sg_to_sec4_sg(sg, sg_count, sec4_sg_ptr, offset); sec4_sg_ptr = sg_to_sec4_sg(sg, sg_count, sec4_sg_ptr, offset);
sec4_sg_ptr->len |= cpu_to_caam32(SEC4_SG_LEN_FIN); sg_to_sec4_set_last(sec4_sg_ptr);
} }
#endif /* _SG_SW_SEC4_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment