@ -1,5 +1,4 @@
/*
/* * CAAM control-plane driver backend
* CAAM control - plane driver backend
* Controller - level driver , kernel property detection , initialization
* Controller - level driver , kernel property detection , initialization
*
*
* Copyright 2008 - 2012 Freescale Semiconductor , Inc .
* Copyright 2008 - 2012 Freescale Semiconductor , Inc .
@ -81,38 +80,37 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
u32 * status )
u32 * status )
{
{
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_full __iomem * topregs ;
struct caam_ctrl __iomem * ctrl = ctrlpriv - > ctrl ;
struct caam_deco __iomem * deco = ctrlpriv - > deco ;
unsigned int timeout = 100000 ;
unsigned int timeout = 100000 ;
u32 deco_dbg_reg , flags ;
u32 deco_dbg_reg , flags ;
int i ;
int i ;
/* Set the bit to request direct access to DECO0 */
topregs = ( struct caam_full __iomem * ) ctrlpriv - > ctrl ;
if ( ctrlpriv - > virt_en = = 1 ) {
if ( ctrlpriv - > virt_en = = 1 ) {
setbits32 ( & topregs - > ctrl . deco_rsr , DECORSR_JR0 ) ;
setbits32 ( & ctrl - > deco_rsr , DECORSR_JR0 ) ;
while ( ! ( rd_reg32 ( & topregs - > ctrl . deco_rsr ) & DECORSR_VALID ) & &
while ( ! ( rd_reg32 ( & ctrl - > deco_rsr ) & DECORSR_VALID ) & &
- - timeout )
- - timeout )
cpu_relax ( ) ;
cpu_relax ( ) ;
timeout = 100000 ;
timeout = 100000 ;
}
}
setbits32 ( & topregs - > ctrl . deco_rq , DECORR_RQD0ENABLE ) ;
setbits32 ( & ctrl - > deco_rq , DECORR_RQD0ENABLE ) ;
while ( ! ( rd_reg32 ( & topregs - > ctrl . deco_rq ) & DECORR_DEN0 ) & &
while ( ! ( rd_reg32 ( & ctrl - > deco_rq ) & DECORR_DEN0 ) & &
- - timeout )
- - timeout )
cpu_relax ( ) ;
cpu_relax ( ) ;
if ( ! timeout ) {
if ( ! timeout ) {
dev_err ( ctrldev , " failed to acquire DECO 0 \n " ) ;
dev_err ( ctrldev , " failed to acquire DECO 0 \n " ) ;
clrbits32 ( & topregs - > ctrl . deco_rq , DECORR_RQD0ENABLE ) ;
clrbits32 ( & ctrl - > deco_rq , DECORR_RQD0ENABLE ) ;
return - ENODEV ;
return - ENODEV ;
}
}
for ( i = 0 ; i < desc_len ( desc ) ; i + + )
for ( i = 0 ; i < desc_len ( desc ) ; i + + )
wr_reg32 ( & topregs - > deco . descbuf [ i ] , * ( desc + i ) ) ;
wr_reg32 ( & deco - > descbuf [ i ] , * ( desc + i ) ) ;
flags = DECO_JQCR_WHL ;
flags = DECO_JQCR_WHL ;
/*
/*
@ -123,11 +121,11 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
flags | = DECO_JQCR_FOUR ;
flags | = DECO_JQCR_FOUR ;
/* Instruct the DECO to execute it */
/* Instruct the DECO to execute it */
wr_reg32 ( & topregs - > deco . jr_ctl_hi , flags ) ;
wr_reg32 ( & deco - > jr_ctl_hi , flags ) ;
timeout = 10000000 ;
timeout = 10000000 ;
do {
do {
deco_dbg_reg = rd_reg32 ( & topregs - > deco . desc_dbg ) ;
deco_dbg_reg = rd_reg32 ( & deco - > desc_dbg ) ;
/*
/*
* If an error occured in the descriptor , then
* If an error occured in the descriptor , then
* the DECO status field will be set to 0x0D
* the DECO status field will be set to 0x0D
@ -138,14 +136,14 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
cpu_relax ( ) ;
cpu_relax ( ) ;
} while ( ( deco_dbg_reg & DESC_DBG_DECO_STAT_VALID ) & & - - timeout ) ;
} while ( ( deco_dbg_reg & DESC_DBG_DECO_STAT_VALID ) & & - - timeout ) ;
* status = rd_reg32 ( & topregs - > deco . op_status_hi ) &
* status = rd_reg32 ( & deco - > op_status_hi ) &
DECO_OP_STATUS_HI_ERR_MASK ;
DECO_OP_STATUS_HI_ERR_MASK ;
if ( ctrlpriv - > virt_en = = 1 )
if ( ctrlpriv - > virt_en = = 1 )
clrbits32 ( & topregs - > ctrl . deco_rsr , DECORSR_JR0 ) ;
clrbits32 ( & ctrl - > deco_rsr , DECORSR_JR0 ) ;
/* Mark the DECO as free */
/* Mark the DECO as free */
clrbits32 ( & topregs - > ctrl . deco_rq , DECORR_RQD0ENABLE ) ;
clrbits32 ( & ctrl - > deco_rq , DECORR_RQD0ENABLE ) ;
if ( ! timeout )
if ( ! timeout )
return - EAGAIN ;
return - EAGAIN ;
@ -176,13 +174,13 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
int gen_sk )
int gen_sk )
{
{
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_full __iomem * topregs ;
struct caam_ctrl __iomem * ctrl ;
struct rng4tst __iomem * r4tst ;
struct rng4tst __iomem * r4tst ;
u32 * desc , status , rdsta_val ;
u32 * desc , status , rdsta_val ;
int ret = 0 , sh_idx ;
int ret = 0 , sh_idx ;
topregs = ( struct caam_ful l __iomem * ) ctrlpriv - > ctrl ;
ctrl = ( struct caam_ctr l __iomem * ) ctrlpriv - > ctrl ;
r4tst = & topregs - > ctrl . r4tst [ 0 ] ;
r4tst = & ctrl - > r4tst [ 0 ] ;
desc = kmalloc ( CAAM_CMD_SZ * 7 , GFP_KERNEL ) ;
desc = kmalloc ( CAAM_CMD_SZ * 7 , GFP_KERNEL ) ;
if ( ! desc )
if ( ! desc )
@ -212,12 +210,11 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
* CAAM eras ) , then try again .
* CAAM eras ) , then try again .
*/
*/
rdsta_val =
rdsta_val =
rd_reg32 ( & topregs - > ctrl . r4tst [ 0 ] . rdsta ) & RDSTA_IFMASK ;
rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) & RDSTA_IFMASK ;
if ( status | | ! ( rdsta_val & ( 1 < < sh_idx ) ) )
if ( status | | ! ( rdsta_val & ( 1 < < sh_idx ) ) )
ret = - EAGAIN ;
ret = - EAGAIN ;
if ( ret )
if ( ret )
break ;
break ;
dev_info ( ctrldev , " Instantiated RNG4 SH%d \n " , sh_idx ) ;
dev_info ( ctrldev , " Instantiated RNG4 SH%d \n " , sh_idx ) ;
/* Clear the contents before recreating the descriptor */
/* Clear the contents before recreating the descriptor */
memset ( desc , 0x00 , CAAM_CMD_SZ * 7 ) ;
memset ( desc , 0x00 , CAAM_CMD_SZ * 7 ) ;
@ -285,12 +282,12 @@ static int caam_remove(struct platform_device *pdev)
{
{
struct device * ctrldev ;
struct device * ctrldev ;
struct caam_drv_private * ctrlpriv ;
struct caam_drv_private * ctrlpriv ;
struct caam_full __iomem * topregs ;
struct caam_ctrl __iomem * ctrl ;
int ring , ret = 0 ;
int ring , ret = 0 ;
ctrldev = & pdev - > dev ;
ctrldev = & pdev - > dev ;
ctrlpriv = dev_get_drvdata ( ctrldev ) ;
ctrlpriv = dev_get_drvdata ( ctrldev ) ;
topregs = ( struct caam_ful l __iomem * ) ctrlpriv - > ctrl ;
ctrl = ( struct caam_ctr l __iomem * ) ctrlpriv - > ctrl ;
/* Remove platform devices for JobRs */
/* Remove platform devices for JobRs */
for ( ring = 0 ; ring < ctrlpriv - > total_jobrs ; ring + + ) {
for ( ring = 0 ; ring < ctrlpriv - > total_jobrs ; ring + + ) {
@ -308,7 +305,7 @@ static int caam_remove(struct platform_device *pdev)
# endif
# endif
/* Unmap controller region */
/* Unmap controller region */
iounmap ( & topregs - > ctrl ) ;
iounmap ( & ctrl ) ;
return ret ;
return ret ;
}
}
@ -323,12 +320,12 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
{
{
struct device * ctrldev = & pdev - > dev ;
struct device * ctrldev = & pdev - > dev ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_drv_private * ctrlpriv = dev_get_drvdata ( ctrldev ) ;
struct caam_full __iomem * topregs ;
struct caam_ctrl __iomem * ctrl ;
struct rng4tst __iomem * r4tst ;
struct rng4tst __iomem * r4tst ;
u32 val ;
u32 val ;
topregs = ( struct caam_ful l __iomem * ) ctrlpriv - > ctrl ;
ctrl = ( struct caam_ctr l __iomem * ) ctrlpriv - > ctrl ;
r4tst = & topregs - > ctrl . r4tst [ 0 ] ;
r4tst = & ctrl - > r4tst [ 0 ] ;
/* put RNG4 into program mode */
/* put RNG4 into program mode */
setbits32 ( & r4tst - > rtmctl , RTMCTL_PRGM ) ;
setbits32 ( & r4tst - > rtmctl , RTMCTL_PRGM ) ;
@ -396,13 +393,14 @@ static int caam_probe(struct platform_device *pdev)
struct device * dev ;
struct device * dev ;
struct device_node * nprop , * np ;
struct device_node * nprop , * np ;
struct caam_ctrl __iomem * ctrl ;
struct caam_ctrl __iomem * ctrl ;
struct caam_full __iomem * topregs ;
struct caam_drv_private * ctrlpriv ;
struct caam_drv_private * ctrlpriv ;
# ifdef CONFIG_DEBUG_FS
# ifdef CONFIG_DEBUG_FS
struct caam_perfmon * perfmon ;
struct caam_perfmon * perfmon ;
# endif
# endif
u32 scfgr , comp_params ;
u32 scfgr , comp_params ;
u32 cha_vid_ls ;
u32 cha_vid_ls ;
int pg_size ;
int BLOCK_OFFSET = 0 ;
ctrlpriv = devm_kzalloc ( & pdev - > dev , sizeof ( struct caam_drv_private ) ,
ctrlpriv = devm_kzalloc ( & pdev - > dev , sizeof ( struct caam_drv_private ) ,
GFP_KERNEL ) ;
GFP_KERNEL ) ;
@ -421,10 +419,27 @@ static int caam_probe(struct platform_device *pdev)
dev_err ( dev , " caam: of_iomap() failed \n " ) ;
dev_err ( dev , " caam: of_iomap() failed \n " ) ;
return - ENOMEM ;
return - ENOMEM ;
}
}
ctrlpriv - > ctrl = ( struct caam_ctrl __force * ) ctrl ;
/* Finding the page size for using the CTPR_MS register */
comp_params = rd_reg32 ( & ctrl - > perfmon . comp_parms_ms ) ;
pg_size = ( comp_params & CTPR_MS_PG_SZ_MASK ) > > CTPR_MS_PG_SZ_SHIFT ;
/* topregs used to derive pointers to CAAM sub-blocks only */
/* Allocating the BLOCK_OFFSET based on the supported page size on
topregs = ( struct caam_full __iomem * ) ctrl ;
* the platform
*/
if ( pg_size = = 0 )
BLOCK_OFFSET = PG_SIZE_4K ;
else
BLOCK_OFFSET = PG_SIZE_64K ;
ctrlpriv - > ctrl = ( struct caam_ctrl __force * ) ctrl ;
ctrlpriv - > assure = ( struct caam_assurance __force * )
( ( uint8_t * ) ctrl +
BLOCK_OFFSET * ASSURE_BLOCK_NUMBER
) ;
ctrlpriv - > deco = ( struct caam_deco __force * )
( ( uint8_t * ) ctrl +
BLOCK_OFFSET * DECO_BLOCK_NUMBER
) ;
/* Get the IRQ of the controller (for security violations only) */
/* Get the IRQ of the controller (for security violations only) */
ctrlpriv - > secvio_irq = irq_of_parse_and_map ( nprop , 0 ) ;
ctrlpriv - > secvio_irq = irq_of_parse_and_map ( nprop , 0 ) ;
@ -433,15 +448,14 @@ 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
*/
*/
setbits32 ( & topregs - > ctrl . mcr , MCFGR_WDENABLE |
setbits32 ( & ctrl - > mcr , MCFGR_WDENABLE |
( 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
* if Virtualization is enabled for this platform
* if Virtualization is enabled for this platform
*/
*/
comp_params = rd_reg32 ( & topregs - > ctrl . perfmon . comp_parms_ms ) ;
scfgr = rd_reg32 ( & ctrl - > scfgr ) ;
scfgr = rd_reg32 ( & topregs - > ctrl . scfgr ) ;
ctrlpriv - > virt_en = 0 ;
ctrlpriv - > virt_en = 0 ;
if ( comp_params & CTPR_MS_VIRT_EN_INCL ) {
if ( comp_params & CTPR_MS_VIRT_EN_INCL ) {
@ -459,7 +473,7 @@ static int caam_probe(struct platform_device *pdev)
}
}
if ( ctrlpriv - > virt_en = = 1 )
if ( ctrlpriv - > virt_en = = 1 )
setbits32 ( & topregs - > ctrl . jrstart , JRSTART_JR0_START |
setbits32 ( & ctrl - > jrstart , JRSTART_JR0_START |
JRSTART_JR1_START | JRSTART_JR2_START |
JRSTART_JR1_START | JRSTART_JR2_START |
JRSTART_JR3_START ) ;
JRSTART_JR3_START ) ;
@ -486,7 +500,7 @@ static int caam_probe(struct platform_device *pdev)
sizeof ( struct platform_device * ) * rspec ,
sizeof ( struct platform_device * ) * rspec ,
GFP_KERNEL ) ;
GFP_KERNEL ) ;
if ( ctrlpriv - > jrpdev = = NULL ) {
if ( ctrlpriv - > jrpdev = = NULL ) {
iounmap ( & topregs - > ctrl ) ;
iounmap ( & ctrl ) ;
return - ENOMEM ;
return - ENOMEM ;
}
}
@ -502,18 +516,26 @@ static int caam_probe(struct platform_device *pdev)
ring ) ;
ring ) ;
continue ;
continue ;
}
}
ctrlpriv - > jr [ ring ] = ( struct caam_job_ring __force * )
( ( uint8_t * ) ctrl +
( ring + JR_BLOCK_NUMBER ) *
BLOCK_OFFSET
) ;
ctrlpriv - > total_jobrs + + ;
ctrlpriv - > total_jobrs + + ;
ring + + ;
ring + + ;
}
}
/* Check to see if QI present. If so, enable */
/* Check to see if QI present. If so, enable */
ctrlpriv - > qi_present =
ctrlpriv - > qi_present =
! ! ( rd_reg32 ( & topregs - > ctrl . perfmon . comp_parms_ms ) &
! ! ( rd_reg32 ( & ctrl - > perfmon . comp_parms_ms ) &
CTPR_MS_QI_MASK ) ;
CTPR_MS_QI_MASK ) ;
if ( ctrlpriv - > qi_present ) {
if ( ctrlpriv - > qi_present ) {
ctrlpriv - > qi = ( struct caam_queue_if __force * ) & topregs - > qi ;
ctrlpriv - > qi = ( struct caam_queue_if __force * )
( ( uint8_t * ) ctrl +
BLOCK_OFFSET * QI_BLOCK_NUMBER
) ;
/* This is all that's required to physically enable QI */
/* This is all that's required to physically enable QI */
wr_reg32 ( & topregs - > qi . qi_control_lo , QICTL_DQEN ) ;
wr_reg32 ( & ctrlpriv - > qi - > qi_control_lo , QICTL_DQEN ) ;
}
}
/* If no QI and no rings specified, quit and go home */
/* If no QI and no rings specified, quit and go home */
@ -523,7 +545,7 @@ static int caam_probe(struct platform_device *pdev)
return - ENOMEM ;
return - ENOMEM ;
}
}
cha_vid_ls = rd_reg32 ( & topregs - > ctrl . perfmon . cha_id_ls ) ;
cha_vid_ls = rd_reg32 ( & ctrl - > perfmon . cha_id_ls ) ;
/*
/*
* 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
@ -531,7 +553,7 @@ static int caam_probe(struct platform_device *pdev)
*/
*/
if ( ( cha_vid_ls & CHA_ID_LS_RNG_MASK ) > > CHA_ID_LS_RNG_SHIFT > = 4 ) {
if ( ( cha_vid_ls & CHA_ID_LS_RNG_MASK ) > > CHA_ID_LS_RNG_SHIFT > = 4 ) {
ctrlpriv - > rng4_sh_init =
ctrlpriv - > rng4_sh_init =
rd_reg32 ( & topregs - > ctrl . r4tst [ 0 ] . rdsta ) ;
rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) ;
/*
/*
* If the secure keys ( TDKEK , JDKEK , TDSK ) , were already
* If the secure keys ( TDKEK , JDKEK , TDSK ) , were already
* generated , signal this to the function that is instantiating
* generated , signal this to the function that is instantiating
@ -542,7 +564,7 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv - > rng4_sh_init & = RDSTA_IFMASK ;
ctrlpriv - > rng4_sh_init & = RDSTA_IFMASK ;
do {
do {
int inst_handles =
int inst_handles =
rd_reg32 ( & topregs - > ctrl . r4tst [ 0 ] . rdsta ) &
rd_reg32 ( & ctrl - > r4tst [ 0 ] . rdsta ) &
RDSTA_IFMASK ;
RDSTA_IFMASK ;
/*
/*
* If either SH were instantiated by somebody else
* If either SH were instantiated by somebody else
@ -587,13 +609,13 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv - > rng4_sh_init = ~ ctrlpriv - > rng4_sh_init & RDSTA_IFMASK ;
ctrlpriv - > rng4_sh_init = ~ ctrlpriv - > rng4_sh_init & RDSTA_IFMASK ;
/* Enable RDB bit so that RNG works faster */
/* Enable RDB bit so that RNG works faster */
setbits32 ( & topregs - > ctrl . scfgr , SCFGR_RDBENABLE ) ;
setbits32 ( & ctrl - > scfgr , SCFGR_RDBENABLE ) ;
}
}
/* NOTE: RTIC detection ought to go here, around Si time */
/* NOTE: RTIC detection ought to go here, around Si time */
caam_id = ( u64 ) rd_reg32 ( & topregs - > ctrl . perfmon . caam_id_ms ) < < 32 |
caam_id = ( u64 ) rd_reg32 ( & ctrl - > perfmon . caam_id_ms ) < < 32 |
( u64 ) rd_reg32 ( & topregs - > ctrl . perfmon . caam_id_ls ) ;
( u64 ) rd_reg32 ( & ctrl - > perfmon . caam_id_ls ) ;
/* 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 ,