2018-10-10 14:26:48 +03:00
// SPDX-License-Identifier: GPL-2.0+
2014-09-01 13:30:44 +04:00
/* * CAAM control-plane driver backend
2011-03-13 11:54:26 +03:00
* Controller - level driver , kernel property detection , initialization
*
2012-06-23 04:48:52 +04:00
* Copyright 2008 - 2012 Freescale Semiconductor , Inc .
2019-05-03 17:17:39 +03:00
* Copyright 2018 - 2019 NXP
2011-03-13 11:54:26 +03:00
*/
crypto: caam - Introduce the use of the managed version of kzalloc
This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. Also, linux/device.h is added to make sure the devm_*()
routine declarations are unambiguously available. Earlier, in the probe
function ctrlpriv was leaked on the failure of ctrl = of_iomap(nprop, 0);
as well as on the failure of ctrlpriv->jrpdev = kzalloc(...); . These
two bugs have been fixed by the patch.
The following Coccinelle semantic patch was used for making the change:
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};
@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
<+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
...
?-kfree(e);
...+>
}
@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
<...
- kfree(e);
...>
}
Signed-off-by: Himangi Saraogi <himangi774@gmail.com>
Acked-by: Julia Lawall <julia.lawall@lip6.fr>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-05-27 22:25:48 +04:00
# include <linux/device.h>
2013-09-17 23:28:33 +04:00
# include <linux/of_address.h>
# include <linux/of_irq.h>
2017-09-01 17:12:59 +03:00
# include <linux/sys_soc.h>
2020-03-19 19:12:32 +03:00
# include <linux/fsl/mc.h>
2013-09-17 23:28:33 +04:00
2011-03-13 11:54:26 +03:00
# include "compat.h"
2020-08-06 21:09:49 +03:00
# include "debugfs.h"
2011-03-13 11:54:26 +03:00
# include "regs.h"
# include "intern.h"
# include "jr.h"
2012-06-23 04:48:52 +04:00
# include "desc_constr.h"
2016-08-26 12:56:24 +03:00
# include "ctrl.h"
2011-03-13 11:54:26 +03:00
2017-07-18 18:30:47 +03:00
bool caam_dpaa2 ;
EXPORT_SYMBOL ( caam_dpaa2 ) ;
2016-05-19 18:11:26 +03:00
2017-03-17 13:06:01 +03:00
# ifdef CONFIG_CAAM_QI
# include "qi.h"
# endif
2012-06-23 04:48:52 +04:00
/*
* Descriptor to instantiate RNG State Handle 0 in normal mode and
* load the JDKEK , TDKEK and TDSK registers
*/
2013-09-09 19:56:34 +04:00
static void build_instantiation_desc ( u32 * desc , int handle , int do_sk )
2012-06-23 04:48:52 +04:00
{
2013-09-09 19:56:34 +04:00
u32 * jump_cmd , op_flags ;
2012-06-23 04:48:52 +04:00
init_job_desc ( desc , 0 ) ;
2013-09-09 19:56:34 +04:00
op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
2020-03-19 19:12:32 +03:00
( handle < < OP_ALG_AAI_SHIFT ) | OP_ALG_AS_INIT |
OP_ALG_PR_ON ;
2013-09-09 19:56:34 +04:00
2012-06-23 04:48:52 +04:00
/* INIT RNG in non-test mode */
2013-09-09 19:56:34 +04:00
append_operation ( desc , op_flags ) ;
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:34 +04:00
if ( ! handle & & do_sk ) {
/*
* For SH0 , Secure Keys must be generated as well
*/
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:34 +04:00
/* wait for done */
jump_cmd = append_jump ( desc , JUMP_CLASS_CLASS1 ) ;
set_jump_tgt_here ( desc , jump_cmd ) ;
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:34 +04:00
/*
* load 1 to clear written reg :
2020-06-04 13:39:47 +03:00
* resets the done interrupt and returns the RNG to idle .
2013-09-09 19:56:34 +04:00
*/
append_load_imm_u32 ( desc , 1 , LDST_SRCDST_WORD_CLRW ) ;
/* Initialize State Handle */
append_operation ( desc , OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
OP_ALG_AAI_RNG4_SK ) ;
}
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:28 +04:00
append_jump ( desc , JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT ) ;
2012-06-23 04:48:52 +04:00
}
2013-09-09 19:56:32 +04:00
/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
2013-09-09 19:56:34 +04:00
static void build_deinstantiation_desc ( u32 * desc , int handle )
2013-09-09 19:56:32 +04:00
{
init_job_desc ( desc , 0 ) ;
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:32 +04:00
/* Uninstantiate State Handle 0 */
2012-06-23 04:48:52 +04:00
append_operation ( desc , OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
2013-09-09 19:56:34 +04:00
( handle < < OP_ALG_AAI_SHIFT ) | OP_ALG_AS_INITFINAL ) ;
2013-09-09 19:56:32 +04:00
append_jump ( desc , JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT ) ;
2012-06-23 04:48:52 +04:00
}
2013-09-09 19:56:31 +04:00
/*
* run_descriptor_deco0 - runs a descriptor on DECO0 , under direct control of
* the software ( no JR / QI used ) .
* @ ctrldev - pointer to device
2013-09-09 19:56:34 +04:00
* @ status - descriptor status , after being run
*
2013-09-09 19:56:31 +04:00
* Return : - 0 if no error occurred
* - - ENODEV if the DECO couldn ' t be acquired
* - - EAGAIN if an error occurred while executing the descriptor
*/
2013-09-09 19:56:34 +04:00
static inline int run_descriptor_deco0 ( struct device * ctrldev , u32 * desc ,
u32 * status )
2012-06-23 04:48:52 +04:00
{
2013-07-04 09:56:03 +04:00
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
2014-09-01 13:30:44 +04:00
struct caam_ctrl __iomem * ctrl = ctrlpriv - > ctrl ;
struct caam_deco __iomem * deco = ctrlpriv - > deco ;
2013-07-04 09:56:03 +04:00
unsigned int timeout = 100000 ;
2018-11-08 16:36:27 +03:00
u32 deco_dbg_reg , deco_state , flags ;
2013-09-09 19:56:32 +04:00
int i ;
2013-07-04 09:56:03 +04:00
2014-06-23 16:12:33 +04:00
2019-08-20 23:24:00 +03:00
if ( ctrlpriv - > virt_en = = 1 | |
/*
2020-01-17 17:35:13 +03:00
* Apparently on i . MX8M { Q , M , N , P } it doesn ' t matter if virt_en = = 1
2019-08-20 23:24:00 +03:00
* and the following steps should be performed regardless
*/
2019-12-18 16:06:14 +03:00
of_machine_is_compatible ( " fsl,imx8mq " ) | |
2020-01-06 23:01:53 +03:00
of_machine_is_compatible ( " fsl,imx8mm " ) | |
2020-01-17 17:35:13 +03:00
of_machine_is_compatible ( " fsl,imx8mn " ) | |
of_machine_is_compatible ( " fsl,imx8mp " ) ) {
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > deco_rsr , 0 , DECORSR_JR0 ) ;
2014-06-23 16:12:33 +04:00
2014-09-01 13:30:44 +04:00
while ( ! ( rd_reg32 ( & ctrl - > deco_rsr ) & DECORSR_VALID ) & &
2014-07-21 17:03:21 +04:00
- - timeout )
cpu_relax ( ) ;
timeout = 100000 ;
}
2014-06-23 16:12:33 +04:00
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > deco_rq , 0 , DECORR_RQD0ENABLE ) ;
2013-07-04 09:56:03 +04:00
2014-09-01 13:30:44 +04:00
while ( ! ( rd_reg32 ( & ctrl - > deco_rq ) & DECORR_DEN0 ) & &
2013-07-04 09:56:03 +04:00
- - timeout )
cpu_relax ( ) ;
if ( ! timeout ) {
dev_err ( ctrldev , " failed to acquire DECO 0 \n " ) ;
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > deco_rq , DECORR_RQD0ENABLE , 0 ) ;
2013-09-09 19:56:31 +04:00
return - ENODEV ;
2012-06-23 04:48:52 +04:00
}
2013-07-04 09:56:03 +04:00
for ( i = 0 ; i < desc_len ( desc ) ; i + + )
2016-05-19 18:11:26 +03:00
wr_reg32 ( & deco - > descbuf [ i ] , caam32_to_cpu ( * ( desc + i ) ) ) ;
2012-06-23 04:48:52 +04:00
2013-09-09 19:56:31 +04:00
flags = DECO_JQCR_WHL ;
/*
* If the descriptor length is longer than 4 words , then the
* FOUR bit in JRCTRL register must be set .
*/
if ( desc_len ( desc ) > = 4 )
flags | = DECO_JQCR_FOUR ;
/* Instruct the DECO to execute it */
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & deco - > jr_ctl_hi , 0 , flags ) ;
2013-07-04 09:56:03 +04:00
timeout = 10000000 ;
2013-09-09 19:56:30 +04:00
do {
2014-09-01 13:30:44 +04:00
deco_dbg_reg = rd_reg32 ( & deco - > desc_dbg ) ;
2018-11-08 16:36:27 +03:00
if ( ctrlpriv - > era < 10 )
deco_state = ( deco_dbg_reg & DESC_DBG_DECO_STAT_MASK ) > >
DESC_DBG_DECO_STAT_SHIFT ;
else
deco_state = ( rd_reg32 ( & deco - > dbg_exec ) &
DESC_DER_DECO_STAT_MASK ) > >
DESC_DER_DECO_STAT_SHIFT ;
2013-09-09 19:56:30 +04:00
/*
2020-06-04 13:39:47 +03:00
* If an error occurred in the descriptor , then
2013-09-09 19:56:30 +04:00
* the DECO status field will be set to 0x0D
*/
2018-11-08 16:36:27 +03:00
if ( deco_state = = DECO_STAT_HOST_ERR )
2013-09-09 19:56:30 +04:00
break ;
2018-11-08 16:36:27 +03:00
2013-07-04 09:56:03 +04:00
cpu_relax ( ) ;
2013-09-09 19:56:30 +04:00
} while ( ( deco_dbg_reg & DESC_DBG_DECO_STAT_VALID ) & & - - timeout ) ;
2012-06-23 04:48:52 +04:00
2014-09-01 13:30:44 +04:00
* status = rd_reg32 ( & deco - > op_status_hi ) &
2013-09-09 19:56:34 +04:00
DECO_OP_STATUS_HI_ERR_MASK ;
2013-07-04 09:56:03 +04:00
2014-06-23 16:12:33 +04:00
if ( ctrlpriv - > virt_en = = 1 )
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > deco_rsr , DECORSR_JR0 , 0 ) ;
2014-06-23 16:12:33 +04:00
2013-09-09 19:56:31 +04:00
/* Mark the DECO as free */
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > deco_rq , DECORR_RQD0ENABLE , 0 ) ;
2013-09-09 19:56:31 +04:00
if ( ! timeout )
return - EAGAIN ;
return 0 ;
}
2019-10-22 18:30:10 +03:00
/*
* deinstantiate_rng - builds and executes a descriptor on DECO0 ,
* which deinitializes the RNG block .
* @ ctrldev - pointer to device
* @ state_handle_mask - bitmask containing the instantiation status
* for the RNG4 state handles which exist in
* the RNG4 block : 1 if it ' s been instantiated
*
* Return : - 0 if no error occurred
* - - ENOMEM if there isn ' t enough memory to allocate the descriptor
* - - ENODEV if DECO0 couldn ' t be acquired
* - - EAGAIN if an error occurred when executing the descriptor
*/
static int deinstantiate_rng ( struct device * ctrldev , int state_handle_mask )
{
u32 * desc , status ;
int sh_idx , ret = 0 ;
2020-03-19 19:12:25 +03:00
desc = kmalloc ( CAAM_CMD_SZ * 3 , GFP_KERNEL | GFP_DMA ) ;
2019-10-22 18:30:10 +03:00
if ( ! desc )
return - ENOMEM ;
for ( sh_idx = 0 ; sh_idx < RNG4_MAX_HANDLES ; sh_idx + + ) {
/*
* If the corresponding bit is set , then it means the state
* handle was initialized by us , and thus it needs to be
* deinitialized as well
*/
if ( ( 1 < < sh_idx ) & state_handle_mask ) {
/*
* Create the descriptor for deinstantating this state
* handle
*/
build_deinstantiation_desc ( desc , sh_idx ) ;
/* Try to run it through DECO0 */
ret = run_descriptor_deco0 ( ctrldev , desc , & status ) ;
if ( ret | |
( status & & status ! = JRSTA_SSRC_JUMP_HALT_CC ) ) {
dev_err ( ctrldev ,
" Failed to deinstantiate RNG4 SH%d \n " ,
sh_idx ) ;
break ;
}
dev_info ( ctrldev , " Deinstantiated RNG4 SH%d \n " , sh_idx ) ;
}
}
kfree ( desc ) ;
return ret ;
}
static void devm_deinstantiate_rng ( void * data )
{
struct device * ctrldev = data ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
/*
* De - initialize RNG state handles initialized by this driver .
* In case of SoCs with Management Complex , RNG is managed by MC f / w .
*/
if ( ctrlpriv - > rng4_sh_init )
deinstantiate_rng ( ctrldev , ctrlpriv - > rng4_sh_init ) ;
}
2013-09-09 19:56:31 +04:00
/*
* instantiate_rng - builds and executes a descriptor on DECO0 ,
* which initializes the RNG block .
* @ ctrldev - pointer to device
2013-09-09 19:56:34 +04:00
* @ state_handle_mask - bitmask containing the instantiation status
* for the RNG4 state handles which exist in
* the RNG4 block : 1 if it ' s been instantiated
* by an external entry , 0 otherwise .
* @ gen_sk - generate data to be loaded into the JDKEK , TDKEK and TDSK ;
* Caution : this can be done only once ; if the keys need to be
* regenerated , a POR is required
*
2013-09-09 19:56:31 +04:00
* Return : - 0 if no error occurred
* - - ENOMEM if there isn ' t enough memory to allocate the descriptor
* - - ENODEV if DECO0 couldn ' t be acquired
* - - EAGAIN if an error occurred when executing the descriptor
* f . i . there was a RNG hardware error due to not " good enough "
2020-06-04 13:39:47 +03:00
* entropy being acquired .
2013-09-09 19:56:31 +04:00
*/
2013-09-09 19:56:34 +04:00
static int instantiate_rng ( struct device * ctrldev , int state_handle_mask ,
int gen_sk )
2013-09-09 19:56:31 +04:00
{
2013-09-09 19:56:34 +04:00
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
2014-09-01 13:30:44 +04:00
struct caam_ctrl __iomem * ctrl ;
2015-07-17 16:54:53 +03:00
u32 * desc , status = 0 , rdsta_val ;
2013-09-09 19:56:34 +04:00
int ret = 0 , sh_idx ;
2014-09-01 13:30:44 +04:00
ctrl = ( struct caam_ctrl __iomem * ) ctrlpriv - > ctrl ;
2020-03-19 19:12:25 +03:00
desc = kmalloc ( CAAM_CMD_SZ * 7 , GFP_KERNEL | GFP_DMA ) ;
2013-09-09 19:56:31 +04:00
if ( ! desc )
return - ENOMEM ;
2013-09-09 19:56:34 +04:00
for ( sh_idx = 0 ; sh_idx < RNG4_MAX_HANDLES ; sh_idx + + ) {
2020-03-19 19:12:32 +03:00
const u32 rdsta_if = RDSTA_IF0 < < sh_idx ;
const u32 rdsta_pr = RDSTA_PR0 < < sh_idx ;
const u32 rdsta_mask = rdsta_if | rdsta_pr ;
2013-09-09 19:56:34 +04:00
/*
* If the corresponding bit is set , this state handle
* was initialized by somebody else , so it ' s left alone .
*/
2020-03-19 19:12:32 +03:00
if ( rdsta_if & state_handle_mask ) {
if ( rdsta_pr & state_handle_mask )
continue ;
dev_info ( ctrldev ,
" RNG4 SH%d was previously instantiated without prediction resistance. Tearing it down \n " ,
sh_idx ) ;
ret = deinstantiate_rng ( ctrldev , rdsta_if ) ;
if ( ret )
break ;
}
2013-09-09 19:56:34 +04:00
/* Create the descriptor for instantiating RNG State Handle */
build_instantiation_desc ( desc , sh_idx , gen_sk ) ;
/* Try to run it through DECO0 */
ret = run_descriptor_deco0 ( ctrldev , desc , & status ) ;
/*
* If ret is not 0 , or descriptor status is not 0 , then
* something went wrong . No need to try the next state
* handle ( if available ) , bail out here .
* Also , if for some reason , the State Handle didn ' t get
* instantiated although the descriptor has finished
* without any error ( HW optimizations for later
* CAAM eras ) , then try again .
*/
2018-02-05 12:15:52 +03:00
if ( ret )
break ;
2020-03-19 19:12:32 +03:00
rdsta_val = rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) & RDSTA_MASK ;
2015-07-17 16:54:53 +03:00
if ( ( status & & status ! = JRSTA_SSRC_JUMP_HALT_CC ) | |
2020-03-19 19:12:32 +03:00
( rdsta_val & rdsta_mask ) ! = rdsta_mask ) {
2013-09-09 19:56:34 +04:00
ret = - EAGAIN ;
break ;
2018-02-05 12:15:52 +03:00
}
2013-09-09 19:56:34 +04:00
dev_info ( ctrldev , " Instantiated RNG4 SH%d \n " , sh_idx ) ;
/* Clear the contents before recreating the descriptor */
memset ( desc , 0x00 , CAAM_CMD_SZ * 7 ) ;
}
2013-09-09 19:56:31 +04:00
2013-07-04 09:56:03 +04:00
kfree ( desc ) ;
2013-09-09 19:56:31 +04:00
2020-08-31 10:58:32 +03:00
if ( ret )
return ret ;
2013-09-09 19:56:32 +04:00
2020-08-31 10:58:32 +03:00
return devm_add_action_or_reset ( ctrldev , devm_deinstantiate_rng , ctrldev ) ;
2013-09-09 19:56:32 +04:00
}
2012-06-23 04:48:52 +04:00
/*
2013-09-09 19:56:30 +04:00
* kick_trng - sets the various parameters for enabling the initialization
* of the RNG4 block in CAAM
* @ pdev - pointer to the platform device
* @ ent_delay - Defines the length ( in system clocks ) of each entropy sample .
2012-06-23 04:48:52 +04:00
*/
2013-09-09 19:56:30 +04:00
static void kick_trng ( struct platform_device * pdev , int ent_delay )
2012-06-23 04:48:52 +04:00
{
struct device * ctrldev = & pdev - > dev ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
2014-09-01 13:30:44 +04:00
struct caam_ctrl __iomem * ctrl ;
2012-06-23 04:48:52 +04:00
struct rng4tst __iomem * r4tst ;
u32 val ;
2014-09-01 13:30:44 +04:00
ctrl = ( struct caam_ctrl __iomem * ) ctrlpriv - > ctrl ;
r4tst = & ctrl - > r4tst [ 0 ] ;
2012-06-23 04:48:52 +04:00
2020-03-19 19:12:30 +03:00
/*
* Setting both RTMCTL : PRGM and RTMCTL : TRNG_ACC causes TRNG to
* properly invalidate the entropy in the entropy register and
* force re - generation .
*/
clrsetbits_32 ( & r4tst - > rtmctl , 0 , RTMCTL_PRGM | RTMCTL_ACC ) ;
2013-09-09 19:56:30 +04:00
/*
* Performance - wise , it does not make sense to
* set the delay to a value that is lower
* than the last one that worked ( i . e . the state handles
* were instantiated properly . Thus , instead of wasting
* time trying to set the values controlling the sample
* frequency , the function simply returns .
*/
val = ( rd_reg32 ( & r4tst - > rtsdctl ) & RTSDCTL_ENT_DLY_MASK )
> > RTSDCTL_ENT_DLY_SHIFT ;
2016-11-09 11:46:14 +03:00
if ( ent_delay < = val )
goto start_rng ;
2013-09-09 19:56:30 +04:00
2012-06-23 04:48:52 +04:00
val = rd_reg32 ( & r4tst - > rtsdctl ) ;
2013-09-09 19:56:30 +04:00
val = ( val & ~ RTSDCTL_ENT_DLY_MASK ) |
( ent_delay < < RTSDCTL_ENT_DLY_SHIFT ) ;
2012-06-23 04:48:52 +04:00
wr_reg32 ( & r4tst - > rtsdctl , val ) ;
2013-09-09 19:56:30 +04:00
/* min. freq. count, equal to 1/4 of the entropy sample length */
wr_reg32 ( & r4tst - > rtfrqmin , ent_delay > > 2 ) ;
2014-08-11 12:40:15 +04:00
/* disable maximum frequency count */
wr_reg32 ( & r4tst - > rtfrqmax , RTFRQMAX_DISABLE ) ;
2014-08-11 12:40:17 +04:00
/* read the control register */
val = rd_reg32 ( & r4tst - > rtmctl ) ;
2016-11-09 11:46:14 +03:00
start_rng :
2014-08-11 12:40:17 +04:00
/*
* select raw sampling in both entropy shifter
2016-11-09 11:46:14 +03:00
* and statistical checker ; ; put RNG4 into run mode
2014-08-11 12:40:17 +04:00
*/
2020-03-19 19:12:30 +03:00
clrsetbits_32 ( & r4tst - > rtmctl , RTMCTL_PRGM | RTMCTL_ACC ,
RTMCTL_SAMP_MODE_RAW_ES_SC ) ;
2012-06-23 04:48:52 +04:00
}
2018-04-11 15:45:20 +03:00
static int caam_get_era_from_hw ( struct caam_ctrl __iomem * ctrl )
{
static const struct {
u16 ip_id ;
u8 maj_rev ;
u8 era ;
} id [ ] = {
{ 0x0A10 , 1 , 1 } ,
{ 0x0A10 , 2 , 2 } ,
{ 0x0A12 , 1 , 3 } ,
{ 0x0A14 , 1 , 3 } ,
{ 0x0A14 , 2 , 4 } ,
{ 0x0A16 , 1 , 4 } ,
{ 0x0A10 , 3 , 4 } ,
{ 0x0A11 , 1 , 4 } ,
{ 0x0A18 , 1 , 4 } ,
{ 0x0A11 , 2 , 5 } ,
{ 0x0A12 , 2 , 5 } ,
{ 0x0A13 , 1 , 5 } ,
{ 0x0A1C , 1 , 5 }
} ;
u32 ccbvid , id_ms ;
u8 maj_rev , era ;
u16 ip_id ;
int i ;
ccbvid = rd_reg32 ( & ctrl - > perfmon . ccb_id ) ;
era = ( ccbvid & CCBVID_ERA_MASK ) > > CCBVID_ERA_SHIFT ;
if ( era ) /* This is '0' prior to CAAM ERA-6 */
return era ;
id_ms = rd_reg32 ( & ctrl - > perfmon . caam_id_ms ) ;
ip_id = ( id_ms & SECVID_MS_IPID_MASK ) > > SECVID_MS_IPID_SHIFT ;
maj_rev = ( id_ms & SECVID_MS_MAJ_REV_MASK ) > > SECVID_MS_MAJ_REV_SHIFT ;
for ( i = 0 ; i < ARRAY_SIZE ( id ) ; i + + )
if ( id [ i ] . ip_id = = ip_id & & id [ i ] . maj_rev = = maj_rev )
return id [ i ] . era ;
return - ENOTSUPP ;
}
2012-07-11 07:06:11 +04:00
/**
* caam_get_era ( ) - Return the ERA of the SEC on SoC , based
2018-04-11 15:45:20 +03:00
* on " sec-era " optional property in the DTS . This property is updated
* by u - boot .
* In case this property is not passed an attempt to retrieve the CAAM
* era via register reads will be made .
2020-09-10 22:29:16 +03:00
*
* @ ctrl : controller region
*/
2018-04-11 15:45:20 +03:00
static int caam_get_era ( struct caam_ctrl __iomem * ctrl )
2012-07-11 07:06:11 +04:00
{
2014-02-06 12:27:19 +04:00
struct device_node * caam_node ;
2015-07-17 16:54:51 +03:00
int ret ;
u32 prop ;
caam_node = of_find_compatible_node ( NULL , NULL , " fsl,sec-v4.0 " ) ;
ret = of_property_read_u32 ( caam_node , " fsl,sec-era " , & prop ) ;
of_node_put ( caam_node ) ;
2012-07-11 07:06:11 +04:00
2018-04-11 15:45:20 +03:00
if ( ! ret )
return prop ;
else
return caam_get_era_from_hw ( ctrl ) ;
2012-07-11 07:06:11 +04:00
}
2019-03-22 16:39:28 +03:00
/*
2019-05-14 20:13:09 +03:00
* ERRATA : imx6 devices ( imx6D , imx6Q , imx6DL , imx6S , imx6DP and imx6QP )
2019-03-22 16:39:28 +03:00
* have an issue wherein AXI bus transactions may not occur in the correct
* order . This isn ' t a problem running single descriptors , but can be if
* running multiple concurrent descriptors . Reworking the driver to throttle
* to single requests is impractical , thus the workaround is to limit the AXI
* pipeline to a depth of 1 ( from it ' s default of 4 ) to preclude this situation
* from occurring .
*/
2020-06-12 09:00:23 +03:00
static void handle_imx6_err005766 ( u32 __iomem * mcr )
2019-03-22 16:39:28 +03:00
{
if ( of_machine_is_compatible ( " fsl,imx6q " ) | |
of_machine_is_compatible ( " fsl,imx6dl " ) | |
of_machine_is_compatible ( " fsl,imx6qp " ) )
clrsetbits_32 ( mcr , MCFGR_AXIPIPE_MASK ,
1 < < MCFGR_AXIPIPE_SHIFT ) ;
}
crypto: caam - fix JR platform device subsequent (re)creations
The way Job Ring platform devices are created and released does not
allow for multiple create-release cycles.
JR0 Platform device creation error
JR0 Platform device creation error
caam 2100000.caam: no queues configured, terminating
caam: probe of 2100000.caam failed with error -12
The reason is that platform devices are created for each job ring:
for_each_available_child_of_node(nprop, np)
if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
ctrlpriv->jrpdev[ring] =
of_platform_device_create(np, NULL, dev);
which sets OF_POPULATED on the device node, but then it cleans these up:
/* Remove platform devices for JobRs */
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
if (ctrlpriv->jrpdev[ring])
of_device_unregister(ctrlpriv->jrpdev[ring]);
}
which leaves OF_POPULATED set.
Use of_platform_populate / of_platform_depopulate instead.
This allows for a bit of driver clean-up, jrpdev is no longer needed.
Logic changes a bit too:
-exit in case of_platform_populate fails, since currently even QI backend
depends on JR; true, we no longer support the case when "some" of the JR
DT nodes are incorrect
-when cleaning up, caam_remove() would also depopulate RTIC in case
it would have been populated somewhere else - not the case for now
Cc: <stable@vger.kernel.org>
Fixes: 313ea293e9c4d ("crypto: caam - Add Platform driver for Job Ring")
Reported-by: Russell King <rmk+kernel@armlinux.org.uk>
Suggested-by: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-03 18:12:04 +03:00
static const struct of_device_id caam_match [ ] = {
{
. compatible = " fsl,sec-v4.0 " ,
} ,
{
. compatible = " fsl,sec4.0 " ,
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , caam_match ) ;
2019-08-20 23:23:48 +03:00
struct caam_imx_data {
const struct clk_bulk_data * clks ;
int num_clks ;
} ;
static const struct clk_bulk_data caam_imx6_clks [ ] = {
{ . id = " ipg " } ,
{ . id = " mem " } ,
{ . id = " aclk " } ,
{ . id = " emi_slow " } ,
} ;
static const struct caam_imx_data caam_imx6_data = {
. clks = caam_imx6_clks ,
. num_clks = ARRAY_SIZE ( caam_imx6_clks ) ,
} ;
static const struct clk_bulk_data caam_imx7_clks [ ] = {
{ . id = " ipg " } ,
{ . id = " aclk " } ,
} ;
static const struct caam_imx_data caam_imx7_data = {
. clks = caam_imx7_clks ,
. num_clks = ARRAY_SIZE ( caam_imx7_clks ) ,
} ;
static const struct clk_bulk_data caam_imx6ul_clks [ ] = {
{ . id = " ipg " } ,
{ . id = " mem " } ,
{ . id = " aclk " } ,
} ;
static const struct caam_imx_data caam_imx6ul_data = {
. clks = caam_imx6ul_clks ,
. num_clks = ARRAY_SIZE ( caam_imx6ul_clks ) ,
} ;
2020-06-02 02:07:26 +03:00
static const struct clk_bulk_data caam_vf610_clks [ ] = {
{ . id = " ipg " } ,
} ;
static const struct caam_imx_data caam_vf610_data = {
. clks = caam_vf610_clks ,
. num_clks = ARRAY_SIZE ( caam_vf610_clks ) ,
} ;
2019-08-20 23:23:48 +03:00
static const struct soc_device_attribute caam_imx_soc_table [ ] = {
{ . soc_id = " i.MX6UL " , . data = & caam_imx6ul_data } ,
{ . soc_id = " i.MX6* " , . data = & caam_imx6_data } ,
{ . soc_id = " i.MX7* " , . data = & caam_imx7_data } ,
2020-01-06 23:01:53 +03:00
{ . soc_id = " i.MX8M* " , . data = & caam_imx7_data } ,
2020-06-02 02:07:26 +03:00
{ . soc_id = " VF* " , . data = & caam_vf610_data } ,
2019-08-20 23:23:48 +03:00
{ . family = " Freescale i.MX " } ,
{ /* sentinel */ }
} ;
static void disable_clocks ( void * data )
{
struct caam_drv_private * ctrlpriv = data ;
clk_bulk_disable_unprepare ( ctrlpriv - > num_clks , ctrlpriv - > clks ) ;
}
static int init_clocks ( struct device * dev , const struct caam_imx_data * data )
{
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( dev ) ;
int ret ;
ctrlpriv - > num_clks = data - > num_clks ;
ctrlpriv - > clks = devm_kmemdup ( dev , data - > clks ,
data - > num_clks * sizeof ( data - > clks [ 0 ] ) ,
GFP_KERNEL ) ;
if ( ! ctrlpriv - > clks )
return - ENOMEM ;
ret = devm_clk_bulk_get ( dev , ctrlpriv - > num_clks , ctrlpriv - > clks ) ;
if ( ret ) {
dev_err ( dev ,
" Failed to request all necessary clocks \n " ) ;
return ret ;
}
ret = clk_bulk_prepare_enable ( ctrlpriv - > num_clks , ctrlpriv - > clks ) ;
if ( ret ) {
dev_err ( dev ,
" Failed to prepare/enable all necessary clocks \n " ) ;
return ret ;
}
return devm_add_action_or_reset ( dev , disable_clocks , ctrlpriv ) ;
}
2019-10-22 18:30:09 +03:00
static void caam_remove_debugfs ( void * root )
{
debugfs_remove_recursive ( root ) ;
}
2020-03-19 19:12:32 +03:00
# ifdef CONFIG_FSL_MC_BUS
static bool check_version ( struct fsl_mc_version * mc_version , u32 major ,
u32 minor , u32 revision )
{
if ( mc_version - > major > major )
return true ;
if ( mc_version - > major = = major ) {
if ( mc_version - > minor > minor )
return true ;
if ( mc_version - > minor = = minor & &
mc_version - > revision > revision )
return true ;
}
return false ;
}
# endif
2022-04-20 15:06:01 +03:00
static bool needs_entropy_delay_adjustment ( void )
{
if ( of_machine_is_compatible ( " fsl,imx6sx " ) )
return true ;
return false ;
}
2011-03-13 11:54:26 +03:00
/* Probe routine for CAAM top (controller) level */
2011-05-15 07:07:55 +04:00
static int caam_probe ( struct platform_device * pdev )
2011-03-13 11:54:26 +03:00
{
crypto: caam - fix JR platform device subsequent (re)creations
The way Job Ring platform devices are created and released does not
allow for multiple create-release cycles.
JR0 Platform device creation error
JR0 Platform device creation error
caam 2100000.caam: no queues configured, terminating
caam: probe of 2100000.caam failed with error -12
The reason is that platform devices are created for each job ring:
for_each_available_child_of_node(nprop, np)
if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
ctrlpriv->jrpdev[ring] =
of_platform_device_create(np, NULL, dev);
which sets OF_POPULATED on the device node, but then it cleans these up:
/* Remove platform devices for JobRs */
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
if (ctrlpriv->jrpdev[ring])
of_device_unregister(ctrlpriv->jrpdev[ring]);
}
which leaves OF_POPULATED set.
Use of_platform_populate / of_platform_depopulate instead.
This allows for a bit of driver clean-up, jrpdev is no longer needed.
Logic changes a bit too:
-exit in case of_platform_populate fails, since currently even QI backend
depends on JR; true, we no longer support the case when "some" of the JR
DT nodes are incorrect
-when cleaning up, caam_remove() would also depopulate RTIC in case
it would have been populated somewhere else - not the case for now
Cc: <stable@vger.kernel.org>
Fixes: 313ea293e9c4d ("crypto: caam - Add Platform driver for Job Ring")
Reported-by: Russell King <rmk+kernel@armlinux.org.uk>
Suggested-by: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-03 18:12:04 +03:00
int ret , ring , gen_sk , ent_delay = RTSDCTL_ENT_DLY_MIN ;
2012-07-11 07:06:11 +04:00
u64 caam_id ;
2019-08-20 23:23:48 +03:00
const struct soc_device_attribute * imx_soc_match ;
2011-03-13 11:54:26 +03:00
struct device * dev ;
struct device_node * nprop , * np ;
struct caam_ctrl __iomem * ctrl ;
struct caam_drv_private * ctrlpriv ;
2019-10-22 18:30:09 +03:00
struct dentry * dfs_root ;
2014-06-23 16:12:33 +04:00
u32 scfgr , comp_params ;
2018-11-08 16:36:27 +03:00
u8 rng_vid ;
2014-09-01 13:30:44 +04:00
int pg_size ;
int BLOCK_OFFSET = 0 ;
2020-03-19 19:12:32 +03:00
bool pr_support = false ;
2011-03-13 11:54:26 +03:00
2015-08-21 19:52:00 +03:00
ctrlpriv = devm_kzalloc ( & pdev - > dev , sizeof ( * ctrlpriv ) , GFP_KERNEL ) ;
2011-03-13 11:54:26 +03:00
if ( ! ctrlpriv )
return - ENOMEM ;
dev = & pdev - > dev ;
dev_set_drvdata ( dev , ctrlpriv ) ;
nprop = pdev - > dev . of_node ;
2019-09-04 05:35:04 +03:00
imx_soc_match = soc_device_match ( caam_imx_soc_table ) ;
caam_imx = ( bool ) imx_soc_match ;
if ( imx_soc_match ) {
if ( ! imx_soc_match - > data ) {
dev_err ( dev , " No clock data provided for i.MX SoC " ) ;
return - EINVAL ;
}
ret = init_clocks ( dev , imx_soc_match - > data ) ;
if ( ret )
return ret ;
}
2019-07-28 22:26:38 +03:00
/* Get configuration properties from device tree */
/* First, get register page */
2019-10-22 18:30:08 +03:00
ctrl = devm_of_iomap ( dev , nprop , 0 , NULL ) ;
ret = PTR_ERR_OR_ZERO ( ctrl ) ;
if ( ret ) {
2019-07-28 22:26:38 +03:00
dev_err ( dev , " caam: of_iomap() failed \n " ) ;
2019-10-22 18:30:08 +03:00
return ret ;
2019-07-28 22:26:38 +03:00
}
caam_little_end = ! ( bool ) ( rd_reg32 ( & ctrl - > perfmon . status ) &
( CSTA_PLEND | CSTA_ALT_PLEND ) ) ;
comp_params = rd_reg32 ( & ctrl - > perfmon . comp_parms_ms ) ;
2019-08-20 23:23:59 +03:00
if ( comp_params & CTPR_MS_PS & & rd_reg32 ( & ctrl - > mcr ) & MCFGR_LONG_PTR )
caam_ptr_sz = sizeof ( u64 ) ;
else
caam_ptr_sz = sizeof ( u32 ) ;
2019-07-28 22:26:38 +03:00
caam_dpaa2 = ! ! ( comp_params & CTPR_MS_DPAA2 ) ;
ctrlpriv - > qi_present = ! ! ( comp_params & CTPR_MS_QI_MASK ) ;
# ifdef CONFIG_CAAM_QI
/* If (DPAA 1.x) QI present, check whether dependencies are available */
if ( ctrlpriv - > qi_present & & ! caam_dpaa2 ) {
ret = qman_is_probed ( ) ;
if ( ! ret ) {
2019-10-22 18:30:08 +03:00
return - EPROBE_DEFER ;
2019-07-28 22:26:38 +03:00
} else if ( ret < 0 ) {
dev_err ( dev , " failing probe due to qman probe error \n " ) ;
2019-10-22 18:30:08 +03:00
return - ENODEV ;
2019-07-28 22:26:38 +03:00
}
ret = qman_portals_probed ( ) ;
if ( ! ret ) {
2019-10-22 18:30:08 +03:00
return - EPROBE_DEFER ;
2019-07-28 22:26:38 +03:00
} else if ( ret < 0 ) {
dev_err ( dev , " failing probe due to qman portals probe error \n " ) ;
2019-10-22 18:30:08 +03:00
return - ENODEV ;
2019-07-28 22:26:38 +03:00
}
}
# endif
2014-09-01 13:30:44 +04:00
/* Allocating the BLOCK_OFFSET based on the supported page size on
* the platform
*/
2019-07-28 22:26:38 +03:00
pg_size = ( comp_params & CTPR_MS_PG_SZ_MASK ) > > CTPR_MS_PG_SZ_SHIFT ;
2014-09-01 13:30:44 +04:00
if ( pg_size = = 0 )
BLOCK_OFFSET = PG_SIZE_4K ;
else
BLOCK_OFFSET = PG_SIZE_64K ;
2016-11-09 11:46:14 +03:00
ctrlpriv - > ctrl = ( struct caam_ctrl __iomem __force * ) ctrl ;
ctrlpriv - > assure = ( struct caam_assurance __iomem __force * )
( ( __force uint8_t * ) ctrl +
2014-09-01 13:30:44 +04:00
BLOCK_OFFSET * ASSURE_BLOCK_NUMBER
) ;
2016-11-09 11:46:14 +03:00
ctrlpriv - > deco = ( struct caam_deco __iomem __force * )
( ( __force uint8_t * ) ctrl +
2014-09-01 13:30:44 +04:00
BLOCK_OFFSET * DECO_BLOCK_NUMBER
) ;
2011-03-13 11:54:26 +03:00
/* Get the IRQ of the controller (for security violations only) */
2013-09-18 17:24:44 +04:00
ctrlpriv - > secvio_irq = irq_of_parse_and_map ( nprop , 0 ) ;
2020-03-19 19:12:32 +03:00
np = of_find_compatible_node ( NULL , NULL , " fsl,qoriq-mc " ) ;
ctrlpriv - > mc_en = ! ! np ;
of_node_put ( np ) ;
# ifdef CONFIG_FSL_MC_BUS
if ( ctrlpriv - > mc_en ) {
struct fsl_mc_version * mc_version ;
mc_version = fsl_mc_get_version ( ) ;
if ( mc_version )
pr_support = check_version ( mc_version , 10 , 20 , 0 ) ;
else
return - EPROBE_DEFER ;
}
# endif
2011-03-13 11:54:26 +03:00
/*
* Enable DECO watchdogs and , if this is a PHYS_ADDR_T_64BIT kernel ,
2017-07-18 18:30:47 +03:00
* long pointers in master configuration register .
2018-05-23 14:32:40 +03:00
* In case of SoCs with Management Complex , MC f / w performs
2017-07-18 18:30:47 +03:00
* the configuration .
2011-03-13 11:54:26 +03:00
*/
2018-05-23 14:32:40 +03:00
if ( ! ctrlpriv - > mc_en )
2019-11-27 01:54:26 +03:00
clrsetbits_32 ( & ctrl - > mcr , MCFGR_AWCACHE_MASK ,
2017-07-18 18:30:47 +03:00
MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
2019-11-27 01:54:26 +03:00
MCFGR_WDENABLE | MCFGR_LARGE_BURST ) ;
2011-03-13 11:54:26 +03:00
2019-03-22 16:39:28 +03:00
handle_imx6_err005766 ( & ctrl - > mcr ) ;
2014-06-23 16:12:33 +04:00
/*
2020-06-04 13:39:47 +03:00
* Read the Compile Time parameters and SCFGR to determine
* if virtualization is enabled for this platform
2014-06-23 16:12:33 +04:00
*/
2014-09-01 13:30:44 +04:00
scfgr = rd_reg32 ( & ctrl - > scfgr ) ;
2014-06-23 16:12:33 +04:00
ctrlpriv - > virt_en = 0 ;
if ( comp_params & CTPR_MS_VIRT_EN_INCL ) {
/* VIRT_EN_INCL = 1 & VIRT_EN_POR = 1 or
* VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SCFGR_VIRT_EN = 1
*/
if ( ( comp_params & CTPR_MS_VIRT_EN_POR ) | |
( ! ( comp_params & CTPR_MS_VIRT_EN_POR ) & &
( scfgr & SCFGR_VIRT_EN ) ) )
ctrlpriv - > virt_en = 1 ;
} else {
/* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
if ( comp_params & CTPR_MS_VIRT_EN_POR )
ctrlpriv - > virt_en = 1 ;
}
if ( ctrlpriv - > virt_en = = 1 )
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > jrstart , 0 , JRSTART_JR0_START |
JRSTART_JR1_START | JRSTART_JR2_START |
JRSTART_JR3_START ) ;
2014-06-23 16:12:33 +04:00
2019-08-20 23:23:47 +03:00
ret = dma_set_mask_and_coherent ( dev , caam_get_dma_mask ( dev ) ) ;
2017-02-10 15:07:15 +03:00
if ( ret ) {
dev_err ( dev , " dma_set_mask_and_coherent failed (%d) \n " , ret ) ;
2019-10-22 18:30:08 +03:00
return ret ;
2017-02-10 15:07:15 +03:00
}
2011-03-13 11:54:26 +03:00
2018-04-11 15:45:20 +03:00
ctrlpriv - > era = caam_get_era ( ctrl ) ;
2019-05-03 17:17:41 +03:00
ctrlpriv - > domain = iommu_get_domain_for_dev ( dev ) ;
2017-12-19 13:16:06 +03:00
2019-10-22 18:30:09 +03:00
dfs_root = debugfs_create_dir ( dev_name ( dev ) , NULL ) ;
2020-08-06 21:09:49 +03:00
if ( IS_ENABLED ( CONFIG_DEBUG_FS ) ) {
ret = devm_add_action_or_reset ( dev , caam_remove_debugfs ,
dfs_root ) ;
if ( ret )
return ret ;
}
2019-10-22 18:30:09 +03:00
2020-08-06 21:09:49 +03:00
caam_debugfs_init ( ctrlpriv , dfs_root ) ;
2017-04-05 16:57:07 +03:00
2017-07-18 18:30:47 +03:00
/* Check to see if (DPAA 1.x) QI present. If so, enable */
if ( ctrlpriv - > qi_present & & ! caam_dpaa2 ) {
2016-11-09 11:46:14 +03:00
ctrlpriv - > qi = ( struct caam_queue_if __iomem __force * )
( ( __force uint8_t * ) ctrl +
2014-09-01 13:30:44 +04:00
BLOCK_OFFSET * QI_BLOCK_NUMBER
) ;
2011-03-13 11:54:26 +03:00
/* This is all that's required to physically enable QI */
2014-09-01 13:30:44 +04:00
wr_reg32 ( & ctrlpriv - > qi - > qi_control_lo , QICTL_DQEN ) ;
2017-03-17 13:06:01 +03:00
/* If QMAN driver is present, init CAAM-QI backend */
# ifdef CONFIG_CAAM_QI
ret = caam_qi_init ( pdev ) ;
if ( ret )
dev_err ( dev , " caam qi i/f init failed: %d \n " , ret ) ;
# endif
2011-03-13 11:54:26 +03:00
}
2019-05-03 17:17:39 +03:00
ring = 0 ;
for_each_available_child_of_node ( nprop , np )
if ( of_device_is_compatible ( np , " fsl,sec-v4.0-job-ring " ) | |
of_device_is_compatible ( np , " fsl,sec4.0-job-ring " ) ) {
ctrlpriv - > jr [ ring ] = ( struct caam_job_ring __iomem __force * )
( ( __force uint8_t * ) ctrl +
( ring + JR_BLOCK_NUMBER ) *
BLOCK_OFFSET
) ;
ctrlpriv - > total_jobrs + + ;
ring + + ;
}
2011-03-13 11:54:26 +03:00
/* If no QI and no rings specified, quit and go home */
if ( ( ! ctrlpriv - > qi_present ) & & ( ! ctrlpriv - > total_jobrs ) ) {
dev_err ( dev , " no queues configured, terminating \n " ) ;
2019-10-22 18:30:12 +03:00
return - ENOMEM ;
2011-03-13 11:54:26 +03:00
}
2022-05-13 17:57:01 +03:00
comp_params = rd_reg32 ( & ctrl - > perfmon . comp_parms_ls ) ;
ctrlpriv - > blob_present = ! ! ( comp_params & CTPR_LS_BLOB ) ;
/*
* Some SoCs like the LS1028A ( non - E ) indicate CTPR_LS_BLOB support ,
* but fail when actually using it due to missing AES support , so
* check both here .
*/
if ( ctrlpriv - > era < 10 ) {
2018-11-08 16:36:27 +03:00
rng_vid = ( rd_reg32 ( & ctrl - > perfmon . cha_id_ls ) &
CHA_ID_LS_RNG_MASK ) > > CHA_ID_LS_RNG_SHIFT ;
2022-05-13 17:57:01 +03:00
ctrlpriv - > blob_present = ctrlpriv - > blob_present & &
( rd_reg32 ( & ctrl - > perfmon . cha_num_ls ) & CHA_ID_LS_AES_MASK ) ;
} else {
2018-11-08 16:36:27 +03:00
rng_vid = ( rd_reg32 ( & ctrl - > vreg . rng ) & CHA_VER_VID_MASK ) > >
CHA_VER_VID_SHIFT ;
2022-05-13 17:57:01 +03:00
ctrlpriv - > blob_present = ctrlpriv - > blob_present & &
( rd_reg32 ( & ctrl - > vreg . aesa ) & CHA_VER_MISC_AES_NUM_MASK ) ;
}
2013-04-26 14:14:54 +04:00
2012-06-23 04:48:52 +04:00
/*
2013-04-26 14:14:54 +04:00
* If SEC has RNG version > = 4 and RNG state handle has not been
2013-09-09 19:56:30 +04:00
* already instantiated , do RNG instantiation
2018-05-23 14:32:40 +03:00
* In case of SoCs with Management Complex , RNG is managed by MC f / w .
2012-06-23 04:48:52 +04:00
*/
2020-03-19 19:12:32 +03:00
if ( ! ( ctrlpriv - > mc_en & & pr_support ) & & rng_vid > = 4 ) {
2013-09-09 19:56:34 +04:00
ctrlpriv - > rng4_sh_init =
2014-09-01 13:30:44 +04:00
rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) ;
2013-09-09 19:56:34 +04:00
/*
* If the secure keys ( TDKEK , JDKEK , TDSK ) , were already
* generated , signal this to the function that is instantiating
* the state handles . An error would occur if RNG4 attempts
* to regenerate these keys before the next POR .
*/
gen_sk = ctrlpriv - > rng4_sh_init & RDSTA_SKVN ? 0 : 1 ;
2020-03-19 19:12:32 +03:00
ctrlpriv - > rng4_sh_init & = RDSTA_MASK ;
2013-09-09 19:56:30 +04:00
do {
2013-09-09 19:56:34 +04:00
int inst_handles =
2014-09-01 13:30:44 +04:00
rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) &
2020-03-19 19:12:32 +03:00
RDSTA_MASK ;
2013-09-09 19:56:34 +04:00
/*
* If either SH were instantiated by somebody else
* ( e . g . u - boot ) then it is assumed that the entropy
* parameters are properly set and thus the function
* setting these ( kick_trng ( . . . ) ) is skipped .
* Also , if a handle was instantiated , do not change
* the TRNG parameters .
*/
2022-04-20 15:06:01 +03:00
if ( needs_entropy_delay_adjustment ( ) )
ent_delay = 12000 ;
2013-09-09 19:56:34 +04:00
if ( ! ( ctrlpriv - > rng4_sh_init | | inst_handles ) ) {
2014-08-11 12:40:16 +04:00
dev_info ( dev ,
" Entropy delay = %u \n " ,
ent_delay ) ;
2013-09-09 19:56:34 +04:00
kick_trng ( pdev , ent_delay ) ;
ent_delay + = 400 ;
}
/*
* if instantiate_rng ( . . . ) fails , the loop will rerun
2020-06-04 13:39:47 +03:00
* and the kick_trng ( . . . ) function will modify the
2013-09-09 19:56:34 +04:00
* upper and lower limits of the entropy sampling
2020-06-04 13:39:47 +03:00
* interval , leading to a successful initialization of
2013-09-09 19:56:34 +04:00
* the RNG .
*/
ret = instantiate_rng ( dev , inst_handles ,
gen_sk ) ;
2022-04-20 15:06:01 +03:00
/*
* Entropy delay is determined via TRNG characterization .
* TRNG characterization is run across different voltages
* and temperatures .
* If worst case value for ent_dly is identified ,
* the loop can be skipped for that platform .
*/
if ( needs_entropy_delay_adjustment ( ) )
break ;
2014-08-11 12:40:16 +04:00
if ( ret = = - EAGAIN )
/*
* if here , the loop will rerun ,
* so don ' t hog the CPU
*/
cpu_relax ( ) ;
2013-09-09 19:56:31 +04:00
} while ( ( ret = = - EAGAIN ) & & ( ent_delay < RTSDCTL_ENT_DLY_MAX ) ) ;
2012-06-23 04:48:52 +04:00
if ( ret ) {
2013-09-09 19:56:30 +04:00
dev_err ( dev , " failed to instantiate RNG " ) ;
2019-10-22 18:30:12 +03:00
return ret ;
2012-06-23 04:48:52 +04:00
}
2013-09-09 19:56:34 +04:00
/*
2020-06-04 13:39:47 +03:00
* Set handles initialized by this module as the complement of
* the already initialized ones
2013-09-09 19:56:34 +04:00
*/
2020-03-19 19:12:32 +03:00
ctrlpriv - > rng4_sh_init = ~ ctrlpriv - > rng4_sh_init & RDSTA_MASK ;
2013-03-12 12:25:21 +04:00
/* Enable RDB bit so that RNG works faster */
2016-05-19 18:11:26 +03:00
clrsetbits_32 ( & ctrl - > scfgr , 0 , SCFGR_RDBENABLE ) ;
2012-06-23 04:48:52 +04:00
}
2011-03-13 11:54:26 +03:00
/* NOTE: RTIC detection ought to go here, around Si time */
2014-09-01 13:30:44 +04:00
caam_id = ( u64 ) rd_reg32 ( & ctrl - > perfmon . caam_id_ms ) < < 32 |
( u64 ) rd_reg32 ( & ctrl - > perfmon . caam_id_ls ) ;
2012-07-11 07:06:11 +04:00
2011-03-13 11:54:26 +03:00
/* Report "alive" for developer to see */
2012-07-11 07:06:11 +04:00
dev_info ( dev , " device ID = 0x%016llx (Era %d) \n " , caam_id ,
2017-12-19 13:16:06 +03:00
ctrlpriv - > era ) ;
2018-05-23 14:32:40 +03:00
dev_info ( dev , " job rings = %d, qi = %d \n " ,
ctrlpriv - > total_jobrs , ctrlpriv - > qi_present ) ;
2011-03-13 11:54:26 +03:00
2019-10-22 18:30:13 +03:00
ret = devm_of_platform_populate ( dev ) ;
if ( ret )
dev_err ( dev , " JR platform devices creation error \n " ) ;
return ret ;
2011-03-13 11:54:26 +03:00
}
2011-05-15 07:07:55 +04:00
static struct platform_driver caam_driver = {
2011-03-13 11:54:26 +03:00
. driver = {
. name = " caam " ,
. of_match_table = caam_match ,
} ,
. probe = caam_probe ,
} ;
2011-11-26 17:26:19 +04:00
module_platform_driver ( caam_driver ) ;
2011-03-13 11:54:26 +03:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " FSL CAAM request backend " ) ;
MODULE_AUTHOR ( " Freescale Semiconductor - NMG/STC " ) ;