|
@@ -1,5 +1,4 @@
|
|
|
-/*
|
|
|
- * CAAM control-plane driver backend
|
|
|
+/* * CAAM control-plane driver backend
|
|
|
* Controller-level driver, kernel property detection, initialization
|
|
|
*
|
|
|
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
|
@@ -81,38 +80,37 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
|
|
|
u32 *status)
|
|
|
{
|
|
|
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;
|
|
|
u32 deco_dbg_reg, flags;
|
|
|
int i;
|
|
|
|
|
|
- /* Set the bit to request direct access to DECO0 */
|
|
|
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
|
|
|
|
|
|
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)
|
|
|
cpu_relax();
|
|
|
|
|
|
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)
|
|
|
cpu_relax();
|
|
|
|
|
|
if (!timeout) {
|
|
|
dev_err(ctrldev, "failed to acquire DECO 0\n");
|
|
|
- clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
|
|
|
+ clrbits32(&ctrl->deco_rq, DECORR_RQD0ENABLE);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
/*
|
|
@@ -123,11 +121,11 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
|
|
|
flags |= DECO_JQCR_FOUR;
|
|
|
|
|
|
/* Instruct the DECO to execute it */
|
|
|
- wr_reg32(&topregs->deco.jr_ctl_hi, flags);
|
|
|
+ wr_reg32(&deco->jr_ctl_hi, flags);
|
|
|
|
|
|
timeout = 10000000;
|
|
|
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
|
|
|
* 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();
|
|
|
} 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;
|
|
|
|
|
|
if (ctrlpriv->virt_en == 1)
|
|
|
- clrbits32(&topregs->ctrl.deco_rsr, DECORSR_JR0);
|
|
|
+ clrbits32(&ctrl->deco_rsr, DECORSR_JR0);
|
|
|
|
|
|
/* Mark the DECO as free */
|
|
|
- clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
|
|
|
+ clrbits32(&ctrl->deco_rq, DECORR_RQD0ENABLE);
|
|
|
|
|
|
if (!timeout)
|
|
|
return -EAGAIN;
|
|
@@ -176,13 +174,13 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
|
|
|
int gen_sk)
|
|
|
{
|
|
|
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
|
|
|
- struct caam_full __iomem *topregs;
|
|
|
+ struct caam_ctrl __iomem *ctrl;
|
|
|
struct rng4tst __iomem *r4tst;
|
|
|
u32 *desc, status, rdsta_val;
|
|
|
int ret = 0, sh_idx;
|
|
|
|
|
|
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
|
|
|
- r4tst = &topregs->ctrl.r4tst[0];
|
|
|
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
|
|
|
+ r4tst = &ctrl->r4tst[0];
|
|
|
|
|
|
desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
|
|
|
if (!desc)
|
|
@@ -212,12 +210,11 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
|
|
|
* CAAM eras), then try again.
|
|
|
*/
|
|
|
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)))
|
|
|
ret = -EAGAIN;
|
|
|
if (ret)
|
|
|
break;
|
|
|
-
|
|
|
dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
|
|
|
/* Clear the contents before recreating the descriptor */
|
|
|
memset(desc, 0x00, CAAM_CMD_SZ * 7);
|
|
@@ -285,12 +282,12 @@ static int caam_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
struct device *ctrldev;
|
|
|
struct caam_drv_private *ctrlpriv;
|
|
|
- struct caam_full __iomem *topregs;
|
|
|
+ struct caam_ctrl __iomem *ctrl;
|
|
|
int ring, ret = 0;
|
|
|
|
|
|
ctrldev = &pdev->dev;
|
|
|
ctrlpriv = dev_get_drvdata(ctrldev);
|
|
|
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
|
|
|
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
|
|
|
|
|
|
/* Remove platform devices for JobRs */
|
|
|
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
|
|
@@ -308,7 +305,7 @@ static int caam_remove(struct platform_device *pdev)
|
|
|
#endif
|
|
|
|
|
|
/* Unmap controller region */
|
|
|
- iounmap(&topregs->ctrl);
|
|
|
+ iounmap(&ctrl);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -323,12 +320,12 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
|
|
|
{
|
|
|
struct device *ctrldev = &pdev->dev;
|
|
|
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
|
|
|
- struct caam_full __iomem *topregs;
|
|
|
+ struct caam_ctrl __iomem *ctrl;
|
|
|
struct rng4tst __iomem *r4tst;
|
|
|
u32 val;
|
|
|
|
|
|
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
|
|
|
- r4tst = &topregs->ctrl.r4tst[0];
|
|
|
+ ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
|
|
|
+ r4tst = &ctrl->r4tst[0];
|
|
|
|
|
|
/* put RNG4 into program mode */
|
|
|
setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
|
|
@@ -396,13 +393,14 @@ static int caam_probe(struct platform_device *pdev)
|
|
|
struct device *dev;
|
|
|
struct device_node *nprop, *np;
|
|
|
struct caam_ctrl __iomem *ctrl;
|
|
|
- struct caam_full __iomem *topregs;
|
|
|
struct caam_drv_private *ctrlpriv;
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
|
struct caam_perfmon *perfmon;
|
|
|
#endif
|
|
|
u32 scfgr, comp_params;
|
|
|
u32 cha_vid_ls;
|
|
|
+ int pg_size;
|
|
|
+ int BLOCK_OFFSET = 0;
|
|
|
|
|
|
ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(struct caam_drv_private),
|
|
|
GFP_KERNEL);
|
|
@@ -421,10 +419,27 @@ static int caam_probe(struct platform_device *pdev)
|
|
|
dev_err(dev, "caam: of_iomap() failed\n");
|
|
|
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 */
|
|
|
- topregs = (struct caam_full __iomem *)ctrl;
|
|
|
+ /* Allocating the BLOCK_OFFSET based on the supported page size on
|
|
|
+ * 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) */
|
|
|
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,
|
|
|
* 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));
|
|
|
|
|
|
/*
|
|
|
* Read the Compile Time paramters and SCFGR to determine
|
|
|
* if Virtualization is enabled for this platform
|
|
|
*/
|
|
|
- comp_params = rd_reg32(&topregs->ctrl.perfmon.comp_parms_ms);
|
|
|
- scfgr = rd_reg32(&topregs->ctrl.scfgr);
|
|
|
+ scfgr = rd_reg32(&ctrl->scfgr);
|
|
|
|
|
|
ctrlpriv->virt_en = 0;
|
|
|
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)
|
|
|
- setbits32(&topregs->ctrl.jrstart, JRSTART_JR0_START |
|
|
|
+ setbits32(&ctrl->jrstart, JRSTART_JR0_START |
|
|
|
JRSTART_JR1_START | JRSTART_JR2_START |
|
|
|
JRSTART_JR3_START);
|
|
|
|
|
@@ -486,7 +500,7 @@ static int caam_probe(struct platform_device *pdev)
|
|
|
sizeof(struct platform_device *) * rspec,
|
|
|
GFP_KERNEL);
|
|
|
if (ctrlpriv->jrpdev == NULL) {
|
|
|
- iounmap(&topregs->ctrl);
|
|
|
+ iounmap(&ctrl);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
@@ -502,18 +516,26 @@ static int caam_probe(struct platform_device *pdev)
|
|
|
ring);
|
|
|
continue;
|
|
|
}
|
|
|
+ ctrlpriv->jr[ring] = (struct caam_job_ring __force *)
|
|
|
+ ((uint8_t *)ctrl +
|
|
|
+ (ring + JR_BLOCK_NUMBER) *
|
|
|
+ BLOCK_OFFSET
|
|
|
+ );
|
|
|
ctrlpriv->total_jobrs++;
|
|
|
ring++;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
/* Check to see if QI present. If so, enable */
|
|
|
ctrlpriv->qi_present =
|
|
|
- !!(rd_reg32(&topregs->ctrl.perfmon.comp_parms_ms) &
|
|
|
+ !!(rd_reg32(&ctrl->perfmon.comp_parms_ms) &
|
|
|
CTPR_MS_QI_MASK);
|
|
|
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 */
|
|
|
- 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 */
|
|
@@ -523,7 +545,7 @@ static int caam_probe(struct platform_device *pdev)
|
|
|
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
|
|
@@ -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) {
|
|
|
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
|
|
|
* 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;
|
|
|
do {
|
|
|
int inst_handles =
|
|
|
- rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
|
|
|
+ rd_reg32(&ctrl->r4tst[0].rdsta) &
|
|
|
RDSTA_IFMASK;
|
|
|
/*
|
|
|
* 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;
|
|
|
|
|
|
/* 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 */
|
|
|
|
|
|
- caam_id = (u64)rd_reg32(&topregs->ctrl.perfmon.caam_id_ms) << 32 |
|
|
|
- (u64)rd_reg32(&topregs->ctrl.perfmon.caam_id_ls);
|
|
|
+ caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 |
|
|
|
+ (u64)rd_reg32(&ctrl->perfmon.caam_id_ls);
|
|
|
|
|
|
/* Report "alive" for developer to see */
|
|
|
dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
|