diff options
author | Nitesh Narayan Lal <b44382@freescale.com> | 2014-09-02 10:24:14 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:36:01 (GMT) |
commit | a2814c6b29c8455e0cece39207025aa1cd270d8c (patch) | |
tree | 51693bf3459b29166341016cffa896196439a1d3 /drivers | |
parent | 9bfa675ce5f66793d07b1a39e69fa0ee642915ef (diff) | |
download | linux-fsl-qoriq-a2814c6b29c8455e0cece39207025aa1cd270d8c.tar.xz |
crypto: caam - Dynamic allocation of addresses for various memory blocks in CAAM.
CAAM's memory is broken into following address blocks:
Block Included Registers
0 General Registers
1-4 Job ring registers
6 RTIC registers
7 QI registers
8 DECO and CCB
Size of the above stated blocks varies in various platforms. The block size can be 4K or 64K.
The block size can be dynamically determined by reading CTPR register in CAAM.
This patch initializes the block addresses dynamically based on the value read from this register.
Signed-off-by: Ruchika Gupta <r66431@freescale.com>
Signed-off-by: Nitesh Narayan Lal <b44382@freescale.com>
Change-Id: I0ff5e5fe947134c56014544f335843dcc1595259
Reviewed-on: http://git.am.freescale.net:8181/17748
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Ruchika Gupta <ruchika.gupta@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 137 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 9 | ||||
-rw-r--r-- | drivers/crypto/caam/regs.h | 41 |
3 files changed, 94 insertions, 93 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 570fdaa..102869b 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -81,38 +81,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 +122,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 +137,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 +175,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 +211,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 +283,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++) { @@ -312,7 +310,7 @@ static int caam_remove(struct platform_device *pdev) #endif /* Unmap controller region */ - iounmap(&topregs->ctrl); + iounmap(&ctrl); kfree(ctrlpriv->jrpdev); kfree(ctrlpriv); @@ -329,12 +327,12 @@ static int caam_remove(struct platform_device *pdev) static void kick_trng(struct device *dev, int ent_delay) { struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); - 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); @@ -390,18 +388,18 @@ static int caam_rng_init(struct device *dev) int gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); u64 cha_vid_ls; - struct caam_full __iomem *topregs; + struct caam_ctrl __iomem *ctrl; int ret = 0; - topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; - cha_vid_ls = rd_reg32(&topregs->ctrl.perfmon.cha_id_ls); + ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl; + cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls); /* * If SEC has RNG version >= 4 and RNG state handle has not been * already instantiated, do RNG instantiation */ 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 @@ -412,7 +410,7 @@ static int caam_rng_init(struct device *dev) 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 @@ -447,7 +445,7 @@ static int caam_rng_init(struct device *dev) 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); } return 0; } @@ -460,12 +458,13 @@ 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; + int pg_size; + int BLOCK_OFFSET = 0; ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL); if (!ctrlpriv) @@ -483,10 +482,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 = of_irq_to_resource(nprop, 0, NULL); @@ -495,15 +511,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) { @@ -521,7 +536,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); @@ -550,7 +565,7 @@ static int caam_probe(struct platform_device *pdev) ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec, GFP_KERNEL); if (ctrlpriv->jrpdev == NULL) { - iounmap(&topregs->ctrl); + iounmap(&ctrl); return -ENOMEM; } @@ -563,6 +578,11 @@ static int caam_probe(struct platform_device *pdev) pr_warn("JR%d Platform device creation error\n", ring); continue; } + ctrlpriv->jr[ring] = (struct caam_job_ring __force *) + ((uint8_t *)ctrl + + (ring + JR_BLOCK_NUMBER) * + BLOCK_OFFSET + ); ctrlpriv->total_jobrs++; ring++; } @@ -582,12 +602,15 @@ static int caam_probe(struct platform_device *pdev) /* 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 QMAN driver is present, init CAAM-QI backend */ #ifdef CONFIG_FSL_QMAN @@ -612,8 +635,8 @@ static int caam_probe(struct platform_device *pdev) /* NOTE: RTIC detection ought to go here, around Si time */ ctrlpriv->era = caam_get_era(); - 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, @@ -705,11 +728,11 @@ static int caam_probe(struct platform_device *pdev) } #ifdef CONFIG_PM -static int caam_stop_qi(struct caam_full __iomem *topregs) +static int caam_stop_qi(struct caam_qi __iomem *qi) { int qi_stopped, loop = 0; - setbits32(&topregs->qi.qi_control_lo, QICTL_STOP); + setbits32(&qi->qi_control_lo, QICTL_STOP); /* * Wait till QI Job's in Holding tank/deco are completed. @@ -717,10 +740,10 @@ static int caam_stop_qi(struct caam_full __iomem *topregs) * reenabled. */ while (loop <= 100000) { - qi_stopped = rd_reg32(&topregs->qi.qi_status) & + qi_stopped = rd_reg32(&qi->qi_status) & QISTA_STOPD; if (qi_stopped) { - wr_reg32(&topregs->qi.qi_control_lo, + wr_reg32(&qi->qi_control_lo, QICTL_STOP); return 0; } @@ -728,7 +751,7 @@ static int caam_stop_qi(struct caam_full __iomem *topregs) } /* Failed to stop QI interface. Reenable QI Interface */ - wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN); + wr_reg32(&qi->qi_control_lo, QICTL_DQEN); return -EBUSY; } @@ -736,22 +759,22 @@ static int caam_stop_qi(struct caam_full __iomem *topregs) static int caam_suspend(struct device *dev) { struct caam_drv_private *caam_priv; - struct caam_full __iomem *topregs; struct caam_ctrl __iomem *ctrl; + struct caam_qi __iomem *qi; int ret = 0; caam_priv = dev_get_drvdata(dev); ctrl = caam_priv->ctrl; - topregs = (struct caam_full __iomem *)ctrl; + qi = caam_priv->qi; /* QI Interface graceful stoppping during suspend */ if (caam_priv->qi_present) { int qi_dqen; - qi_dqen = rd_reg32(&topregs->qi.qi_control_lo) & + qi_dqen = rd_reg32(&qi->qi_control_lo) & QICTL_DQEN; if (qi_dqen) - ret = caam_stop_qi(topregs); + ret = caam_stop_qi(qi); } return ret; @@ -761,23 +784,21 @@ static int caam_suspend(struct device *dev) static int caam_resume(struct device *dev) { struct caam_drv_private *caam_priv; - struct caam_full __iomem *topregs; struct caam_ctrl __iomem *ctrl; int ret; caam_priv = dev_get_drvdata(dev); ctrl = caam_priv->ctrl; - topregs = (struct caam_full __iomem *)ctrl; /* * 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)); /* Enable QI interface of SEC */ if (caam_priv->qi_present) - wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN); + wr_reg32(&qi->qi_control_lo, QICTL_DQEN); ret = caam_rng_init(dev); diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index 9b2afc8..423886a 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -78,10 +78,11 @@ struct caam_drv_private { struct platform_device *pdev; /* Physical-presence section */ - struct caam_ctrl *ctrl; /* controller region */ - struct caam_deco **deco; /* DECO/CCB views */ - struct caam_assurance *ac; - struct caam_queue_if *qi; /* QI control region */ + struct caam_ctrl __iomem *ctrl; /* controller region */ + struct caam_deco __iomem *deco; /* DECO/CCB views */ + struct caam_assurance __iomem *assure; + struct caam_queue_if __iomem *qi; /* QI control region */ + struct caam_job_ring __iomem *jr[4]; /* JobR's register space */ /* * Detected geometry block. Filled in from device tree if powerpc, diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index 2982d85..79d2bf3 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -200,6 +200,8 @@ struct caam_perfmon { #define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT) #define CTPR_MS_VIRT_EN_INCL 0x00000001 #define CTPR_MS_VIRT_EN_POR 0x00000002 +#define CTPR_MS_PG_SZ_MASK 0x10 +#define CTPR_MS_PG_SZ_SHIFT 4 u32 comp_parms_ms; /* CTPR - Compile Parameters Register */ u32 comp_parms_ls; /* CTPR - Compile Parameters Register */ u64 rsvd1[2]; @@ -764,34 +766,11 @@ struct caam_deco { #define DECO_JQCR_WHL 0x20000000 #define DECO_JQCR_FOUR 0x10000000 -/* - * Current top-level view of memory map is: - * - * 0x0000 - 0x0fff - CAAM Top-Level Control - * 0x1000 - 0x1fff - Job Ring 0 - * 0x2000 - 0x2fff - Job Ring 1 - * 0x3000 - 0x3fff - Job Ring 2 - * 0x4000 - 0x4fff - Job Ring 3 - * 0x5000 - 0x5fff - (unused) - * 0x6000 - 0x6fff - Assurance Controller - * 0x7000 - 0x7fff - Queue Interface - * 0x8000 - 0x8fff - DECO-CCB 0 - * 0x9000 - 0x9fff - DECO-CCB 1 - * 0xa000 - 0xafff - DECO-CCB 2 - * 0xb000 - 0xbfff - DECO-CCB 3 - * 0xc000 - 0xcfff - DECO-CCB 4 - * - * caam_full describes the full register view of CAAM if useful, - * although many configurations may choose to implement parts of - * the register map separately, in differing privilege regions - */ -struct caam_full { - struct caam_ctrl __iomem ctrl; - struct caam_job_ring jr[4]; - u64 rsvd[512]; - struct caam_assurance assure; - struct caam_queue_if qi; - struct caam_deco deco; -}; - -#endif /* REGS_H */ +#define JR_BLOCK_NUMBER 1 +#define ASSURE_BLOCK_NUMBER 6 +#define QI_BLOCK_NUMBER 7 +#define DECO_BLOCK_NUMBER 8 +#define PG_SIZE_4K 0x1000 +#define PG_SIZE_64K 0x10000 +#endif +/* REGS_H */ |