diff options
Diffstat (limited to 'drivers/crypto/caam/ctrl.c')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 138 |
1 files changed, 89 insertions, 49 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 3cade79ea41e..31000c8c4a90 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -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); @@ -355,10 +352,19 @@ static void kick_trng(struct platform_device *pdev, int ent_delay) wr_reg32(&r4tst->rtsdctl, val); /* min. freq. count, equal to 1/4 of the entropy sample length */ wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2); - /* max. freq. count, equal to 8 times the entropy sample length */ - wr_reg32(&r4tst->rtfrqmax, ent_delay << 3); + /* disable maximum frequency count */ + wr_reg32(&r4tst->rtfrqmax, RTFRQMAX_DISABLE); + /* read the control register */ + val = rd_reg32(&r4tst->rtmctl); + /* + * select raw sampling in both entropy shifter + * and statistical checker + */ + setbits32(&val, RTMCTL_SAMP_MODE_RAW_ES_SC); /* put RNG4 into run mode */ - clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); + clrbits32(&val, RTMCTL_PRGM); + /* write back the control register */ + wr_reg32(&r4tst->rtmctl, val); } /** @@ -387,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); @@ -412,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); @@ -424,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) { @@ -450,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); @@ -477,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; } @@ -493,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 */ @@ -514,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 @@ -522,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 @@ -533,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 @@ -544,6 +575,9 @@ static int caam_probe(struct platform_device *pdev) * the TRNG parameters. */ if (!(ctrlpriv->rng4_sh_init || inst_handles)) { + dev_info(dev, + "Entropy delay = %u\n", + ent_delay); kick_trng(pdev, ent_delay); ent_delay += 400; } @@ -556,6 +590,12 @@ static int caam_probe(struct platform_device *pdev) */ ret = instantiate_rng(dev, inst_handles, gen_sk); + if (ret == -EAGAIN) + /* + * if here, the loop will rerun, + * so don't hog the CPU + */ + cpu_relax(); } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); if (ret) { dev_err(dev, "failed to instantiate RNG"); @@ -569,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, |