Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Horia Geantă and committed by
Herbert Xu
297b9ceb e28c190d

+148 -25
+3 -4
drivers/crypto/caam/caamhash.c
··· 791 791 to_hash - *buflen, 792 792 *next_buflen, 0); 793 793 } else { 794 - (edesc->sec4_sg + sec4_sg_src_index - 1)->len |= 795 - cpu_to_caam32(SEC4_SG_LEN_FIN); 794 + sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index - 795 + 1); 796 796 } 797 797 798 798 desc = edesc->hw_desc; ··· 882 882 if (ret) 883 883 goto unmap_ctx; 884 884 885 - (edesc->sec4_sg + sec4_sg_src_index - 1)->len |= 886 - cpu_to_caam32(SEC4_SG_LEN_FIN); 885 + sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index - 1); 887 886 888 887 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, 889 888 sec4_sg_bytes, DMA_TO_DEVICE);
+29 -16
drivers/crypto/caam/ctrl.c
··· 17 17 18 18 bool caam_little_end; 19 19 EXPORT_SYMBOL(caam_little_end); 20 + bool caam_dpaa2; 21 + EXPORT_SYMBOL(caam_dpaa2); 20 22 21 23 #ifdef CONFIG_CAAM_QI 22 24 #include "qi.h" ··· 321 319 caam_qi_shutdown(ctrlpriv->qidev); 322 320 #endif 323 321 324 - /* De-initialize RNG state handles initialized by this driver. */ 325 - if (ctrlpriv->rng4_sh_init) 322 + /* 323 + * De-initialize RNG state handles initialized by this driver. 324 + * In case of DPAA 2.x, RNG is managed by MC firmware. 325 + */ 326 + if (!caam_dpaa2 && ctrlpriv->rng4_sh_init) 326 327 deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); 327 328 328 329 /* Shut down debug views */ ··· 557 552 558 553 /* 559 554 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, 560 - * long pointers in master configuration register 555 + * long pointers in master configuration register. 556 + * In case of DPAA 2.x, Management Complex firmware performs 557 + * the configuration. 561 558 */ 562 - clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, 563 - MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | 564 - MCFGR_WDENABLE | MCFGR_LARGE_BURST | 565 - (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); 559 + caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2); 560 + if (!caam_dpaa2) 561 + clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, 562 + MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | 563 + MCFGR_WDENABLE | MCFGR_LARGE_BURST | 564 + (sizeof(dma_addr_t) == sizeof(u64) ? 565 + MCFGR_LONG_PTR : 0)); 566 566 567 567 /* 568 568 * Read the Compile Time paramters and SCFGR to determine ··· 596 586 JRSTART_JR3_START); 597 587 598 588 if (sizeof(dma_addr_t) == sizeof(u64)) { 599 - if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) 589 + if (caam_dpaa2) 590 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49)); 591 + else if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) 600 592 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); 601 593 else 602 594 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36)); ··· 641 629 ring++; 642 630 } 643 631 644 - /* Check to see if QI present. If so, enable */ 645 - ctrlpriv->qi_present = 646 - !!(rd_reg32(&ctrl->perfmon.comp_parms_ms) & 647 - CTPR_MS_QI_MASK); 648 - if (ctrlpriv->qi_present) { 632 + /* Check to see if (DPAA 1.x) QI present. If so, enable */ 633 + ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK); 634 + if (ctrlpriv->qi_present && !caam_dpaa2) { 649 635 ctrlpriv->qi = (struct caam_queue_if __iomem __force *) 650 636 ((__force uint8_t *)ctrl + 651 637 BLOCK_OFFSET * QI_BLOCK_NUMBER ··· 671 661 /* 672 662 * If SEC has RNG version >= 4 and RNG state handle has not been 673 663 * already instantiated, do RNG instantiation 664 + * In case of DPAA 2.x, RNG is managed by MC firmware. 674 665 */ 675 - if ((cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) { 666 + if (!caam_dpaa2 && 667 + (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) { 676 668 ctrlpriv->rng4_sh_init = 677 669 rd_reg32(&ctrl->r4tst[0].rdsta); 678 670 /* ··· 742 730 /* Report "alive" for developer to see */ 743 731 dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id, 744 732 caam_get_era()); 745 - dev_info(dev, "job rings = %d, qi = %d\n", 746 - ctrlpriv->total_jobrs, ctrlpriv->qi_present); 733 + dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n", 734 + ctrlpriv->total_jobrs, ctrlpriv->qi_present, 735 + caam_dpaa2 ? "yes" : "no"); 747 736 748 737 #ifdef CONFIG_DEBUG_FS 749 738
+2
drivers/crypto/caam/ctrl.h
··· 10 10 /* Prototypes for backend-level services exposed to APIs */ 11 11 int caam_get_era(void); 12 12 13 + extern bool caam_dpaa2; 14 + 13 15 #endif /* CTRL_H */
+6 -1
drivers/crypto/caam/jr.c
··· 9 9 #include <linux/of_address.h> 10 10 11 11 #include "compat.h" 12 + #include "ctrl.h" 12 13 #include "regs.h" 13 14 #include "jr.h" 14 15 #include "desc.h" ··· 500 499 jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl; 501 500 502 501 if (sizeof(dma_addr_t) == sizeof(u64)) { 503 - if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring")) 502 + if (caam_dpaa2) 503 + error = dma_set_mask_and_coherent(jrdev, 504 + DMA_BIT_MASK(49)); 505 + else if (of_device_is_compatible(nprop, 506 + "fsl,sec-v5.0-job-ring")) 504 507 error = dma_set_mask_and_coherent(jrdev, 505 508 DMA_BIT_MASK(40)); 506 509 else
+1
drivers/crypto/caam/regs.h
··· 293 293 u32 cha_rev_ls; /* CRNR - CHA Rev No. Least significant half*/ 294 294 #define CTPR_MS_QI_SHIFT 25 295 295 #define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT) 296 + #define CTPR_MS_DPAA2 BIT(13) 296 297 #define CTPR_MS_VIRT_EN_INCL 0x00000001 297 298 #define CTPR_MS_VIRT_EN_POR 0x00000002 298 299 #define CTPR_MS_PG_SZ_MASK 0x10
+81
drivers/crypto/caam/sg_sw_qm2.h
··· 1 + /* 2 + * Copyright 2015-2016 Freescale Semiconductor, Inc. 3 + * Copyright 2017 NXP 4 + * 5 + * Redistribution and use in source and binary forms, with or without 6 + * modification, are permitted provided that the following conditions are met: 7 + * * Redistributions of source code must retain the above copyright 8 + * notice, this list of conditions and the following disclaimer. 9 + * * Redistributions in binary form must reproduce the above copyright 10 + * notice, this list of conditions and the following disclaimer in the 11 + * documentation and/or other materials provided with the distribution. 12 + * * Neither the names of the above-listed copyright holders nor the 13 + * names of any contributors may be used to endorse or promote products 14 + * derived from this software without specific prior written permission. 15 + * 16 + * 17 + * ALTERNATIVELY, this software may be distributed under the terms of the 18 + * GNU General Public License ("GPL") as published by the Free Software 19 + * Foundation, either version 2 of that License or (at your option) any 20 + * later version. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 26 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 + * POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #ifndef _SG_SW_QM2_H_ 36 + #define _SG_SW_QM2_H_ 37 + 38 + #include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h" 39 + 40 + static inline void dma_to_qm_sg_one(struct dpaa2_sg_entry *qm_sg_ptr, 41 + dma_addr_t dma, u32 len, u16 offset) 42 + { 43 + dpaa2_sg_set_addr(qm_sg_ptr, dma); 44 + dpaa2_sg_set_format(qm_sg_ptr, dpaa2_sg_single); 45 + dpaa2_sg_set_final(qm_sg_ptr, false); 46 + dpaa2_sg_set_len(qm_sg_ptr, len); 47 + dpaa2_sg_set_bpid(qm_sg_ptr, 0); 48 + dpaa2_sg_set_offset(qm_sg_ptr, offset); 49 + } 50 + 51 + /* 52 + * convert scatterlist to h/w link table format 53 + * but does not have final bit; instead, returns last entry 54 + */ 55 + static inline struct dpaa2_sg_entry * 56 + sg_to_qm_sg(struct scatterlist *sg, int sg_count, 57 + struct dpaa2_sg_entry *qm_sg_ptr, u16 offset) 58 + { 59 + while (sg_count && sg) { 60 + dma_to_qm_sg_one(qm_sg_ptr, sg_dma_address(sg), 61 + sg_dma_len(sg), offset); 62 + qm_sg_ptr++; 63 + sg = sg_next(sg); 64 + sg_count--; 65 + } 66 + return qm_sg_ptr - 1; 67 + } 68 + 69 + /* 70 + * convert scatterlist to h/w link table format 71 + * scatterlist must have been previously dma mapped 72 + */ 73 + static inline void sg_to_qm_sg_last(struct scatterlist *sg, int sg_count, 74 + struct dpaa2_sg_entry *qm_sg_ptr, 75 + u16 offset) 76 + { 77 + qm_sg_ptr = sg_to_qm_sg(sg, sg_count, qm_sg_ptr, offset); 78 + dpaa2_sg_set_final(qm_sg_ptr, true); 79 + } 80 + 81 + #endif /* _SG_SW_QM2_H_ */
+26 -4
drivers/crypto/caam/sg_sw_sec4.h
··· 5 5 * 6 6 */ 7 7 8 + #ifndef _SG_SW_SEC4_H_ 9 + #define _SG_SW_SEC4_H_ 10 + 11 + #include "ctrl.h" 8 12 #include "regs.h" 13 + #include "sg_sw_qm2.h" 14 + #include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h" 9 15 10 16 struct sec4_sg_entry { 11 17 u64 ptr; ··· 25 19 static inline void dma_to_sec4_sg_one(struct sec4_sg_entry *sec4_sg_ptr, 26 20 dma_addr_t dma, u32 len, u16 offset) 27 21 { 28 - sec4_sg_ptr->ptr = cpu_to_caam_dma64(dma); 29 - sec4_sg_ptr->len = cpu_to_caam32(len); 30 - sec4_sg_ptr->bpid_offset = cpu_to_caam32(offset & SEC4_SG_OFFSET_MASK); 22 + if (caam_dpaa2) { 23 + dma_to_qm_sg_one((struct dpaa2_sg_entry *)sec4_sg_ptr, dma, len, 24 + offset); 25 + } else { 26 + sec4_sg_ptr->ptr = cpu_to_caam_dma64(dma); 27 + sec4_sg_ptr->len = cpu_to_caam32(len); 28 + sec4_sg_ptr->bpid_offset = cpu_to_caam32(offset & 29 + SEC4_SG_OFFSET_MASK); 30 + } 31 31 #ifdef DEBUG 32 32 print_hex_dump(KERN_ERR, "sec4_sg_ptr@: ", 33 33 DUMP_PREFIX_ADDRESS, 16, 4, sec4_sg_ptr, ··· 59 47 return sec4_sg_ptr - 1; 60 48 } 61 49 50 + static inline void sg_to_sec4_set_last(struct sec4_sg_entry *sec4_sg_ptr) 51 + { 52 + if (caam_dpaa2) 53 + dpaa2_sg_set_final((struct dpaa2_sg_entry *)sec4_sg_ptr, true); 54 + else 55 + sec4_sg_ptr->len |= cpu_to_caam32(SEC4_SG_LEN_FIN); 56 + } 57 + 62 58 /* 63 59 * convert scatterlist to h/w link table format 64 60 * scatterlist must have been previously dma mapped ··· 76 56 u16 offset) 77 57 { 78 58 sec4_sg_ptr = sg_to_sec4_sg(sg, sg_count, sec4_sg_ptr, offset); 79 - sec4_sg_ptr->len |= cpu_to_caam32(SEC4_SG_LEN_FIN); 59 + sg_to_sec4_set_last(sec4_sg_ptr); 80 60 } 61 + 62 + #endif /* _SG_SW_SEC4_H_ */