}
ctrlpriv->caam_ipg = clk;
- clk = caam_drv_identify_clk(&pdev->dev, "mem");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM mem clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_mem = clk;
-
- clk = caam_drv_identify_clk(&pdev->dev, "aclk");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM aclk clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_aclk = clk;
-
- clk = caam_drv_identify_clk(&pdev->dev, "emi_slow");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(&pdev->dev,
- "can't identify CAAM emi_slow clk: %d\n", ret);
- return ret;
- }
- ctrlpriv->caam_emi_slow = clk;
-
ret = clk_prepare_enable(ctrlpriv->caam_ipg);
if (ret < 0) {
dev_err(&pdev->dev, "can't enable CAAM ipg clock: %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(ctrlpriv->caam_mem);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM secure mem clock: %d\n",
- ret);
- goto disable_caam_ipg;
- }
+ /* imx7d only has one caam clock */
+ if (!(of_find_compatible_node(NULL, NULL, "fsl,imx7d-caam"))) {
- ret = clk_prepare_enable(ctrlpriv->caam_aclk);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM aclk clock: %d\n", ret);
- goto disable_caam_mem;
- }
+ clk = caam_drv_identify_clk(&pdev->dev, "mem");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(&pdev->dev,
+ "can't identify CAAM mem clk: %d\n", ret);
+ goto disable_caam_ipg;
+ }
+ ctrlpriv->caam_mem = clk;
+
+ clk = caam_drv_identify_clk(&pdev->dev, "aclk");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(&pdev->dev,
+ "can't identify CAAM aclk clk: %d\n", ret);
+ goto disable_caam_ipg;
+ }
+ ctrlpriv->caam_aclk = clk;
+
+ clk = caam_drv_identify_clk(&pdev->dev, "emi_slow");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(&pdev->dev,
+ "can't identify CAAM emi_slow clk: %d\n", ret);
+ goto disable_caam_ipg;
+ }
+ ctrlpriv->caam_emi_slow = clk;
- ret = clk_prepare_enable(ctrlpriv->caam_emi_slow);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't enable CAAM emi slow clock: %d\n",
- ret);
- goto disable_caam_aclk;
+ ret = clk_prepare_enable(ctrlpriv->caam_mem);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't enable CAAM secure mem clock: %d\n",
+ ret);
+ goto disable_caam_ipg;
+ }
+
+ ret = clk_prepare_enable(ctrlpriv->caam_aclk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't enable CAAM aclk clock: %d\n", ret);
+ goto disable_caam_mem;
+ }
+
+ ret = clk_prepare_enable(ctrlpriv->caam_emi_slow);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "can't enable CAAM emi slow clock: %d\n",
+ ret);
+ goto disable_caam_aclk;
+ }
}
/* Get configuration properties from device tree */
/* Get CAAM-SM node and of_iomap() and save */
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
-
if (!np)
return -ENODEV;
#define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */
#define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */
+/* Secure Memory Configuration - if you have it */
+/* Secure Memory Register Offset from JR Base Reg*/
+#define SM_V1_OFFSET 0x0f4
+#define SM_V2_OFFSET 0xa00
+
+/* Minimum SM Version ID requiring v2 SM register mapping */
+#define SMVID_V2 0x20105
+
+struct caam_secure_mem_v1 {
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd1;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+};
+
+struct caam_secure_mem_v2 {
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+ u32 rsvd1[118];
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd2;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+};
+
/*
* caam_job_ring - direct job ring setup
* 1-4 possible per instantiation, base + 1000/2000/3000/4000
/* Command/control */
u32 rsvd11;
u32 jrcommand; /* JRCRx - JobR command */
-
- u32 rsvd12[33];
-
- /* Secure Memory Configuration - if you have it */
- u32 sm_cmd; /* SMCJRx - Secure memory command */
- u32 rsvd13;
- u32 sm_status; /* SMCSJRx - Secure memory status */
- u32 rsvd14;
- u32 sm_perm; /* SMAPJRx - Secure memory access perms */
- u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
- u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
-
- u32 rsvd15[891];
+ u32 rsvd12[931];
/* Performance Monitor f00-fff */
struct caam_perfmon perfmon;
struct platform_device *sm_pdev; /* Secure Memory platform device */
spinlock_t kslock ____cacheline_aligned;
+ /* SM Register offset from JR base address */
+ u32 sm_reg_offset;
+
/* Default parameters for geometry */
u32 max_pages; /* maximum pages this instance can support */
u32 top_partition; /* highest partition number in this instance */
#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
+static __always_inline int sm_set_cmd_reg(struct caam_drv_private_sm *smpriv,
+ struct caam_drv_private_jr *jrpriv,
+ u32 val)
+{
+
+ if (smpriv->sm_reg_offset == SM_V1_OFFSET) {
+ struct caam_secure_mem_v1 *sm_regs_v1;
+ sm_regs_v1 = (struct caam_secure_mem_v1 *)
+ ((void *)jrpriv->rregs + SM_V1_OFFSET);
+ wr_reg32(&sm_regs_v1->sm_cmd, val);
+
+ } else if (smpriv->sm_reg_offset == SM_V2_OFFSET) {
+ struct caam_secure_mem_v2 *sm_regs_v2;
+ sm_regs_v2 = (struct caam_secure_mem_v2 *)
+ ((void *)jrpriv->rregs + SM_V2_OFFSET);
+ wr_reg32(&sm_regs_v2->sm_cmd, val);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static __always_inline u32 sm_get_status_reg(struct caam_drv_private_sm *smpriv,
+ struct caam_drv_private_jr *jrpriv,
+ u32 *val)
+{
+ if (smpriv->sm_reg_offset == SM_V1_OFFSET) {
+ struct caam_secure_mem_v1 *sm_regs_v1;
+ sm_regs_v1 = (struct caam_secure_mem_v1 *)
+ ((void *)jrpriv->rregs + SM_V1_OFFSET);
+ *val = rd_reg32(&sm_regs_v1->sm_status);
+ } else if (smpriv->sm_reg_offset == SM_V2_OFFSET) {
+ struct caam_secure_mem_v2 *sm_regs_v2;
+ sm_regs_v2 = (struct caam_secure_mem_v2 *)
+ ((void *)jrpriv->rregs + SM_V2_OFFSET);
+ *val = rd_reg32(&sm_regs_v2->sm_status);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/*
* Construct a black key conversion job descriptor
*
struct caam_drv_private_jr *jrpriv; /* need this for reg page */
struct platform_device *sm_pdev;
struct sm_page_descriptor *lpagedesc;
- u32 page, pgstat, lpagect, detectedpage;
+ u32 page, pgstat, lpagect, detectedpage, smvid;
struct device_node *np;
ctrldev = &pdev->dev;
dev_set_drvdata(smdev, smpriv);
ctrlpriv->smdev = smdev;
+ /* Set the Secure Memory Register Map Version */
+ smvid = rd_reg32(&ctrlpriv->ctrl->perfmon.smvid);
+ if (smvid < SMVID_V2)
+ smpriv->sm_reg_offset = SM_V1_OFFSET;
+ else
+ smpriv->sm_reg_offset = SM_V2_OFFSET;
+
/*
* Collect configuration limit data for reference
* This batch comes from the partition data/vid registers in perfmon
& SMPART_MAX_NUMPG_MASK) >>
SMPART_MAX_NUMPG_SHIFT) + 1;
smpriv->top_partition = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
- & SMPART_MAX_PNUM_MASK) >>
+ & SMPART_MAX_PNUM_MASK) >>
SMPART_MAX_PNUM_SHIFT) + 1;
smpriv->top_page = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
& SMPART_MAX_PG_MASK) >> SMPART_MAX_PG_SHIFT) + 1;
smpriv->smringdev = &ctrlpriv->jrpdev[0]->dev;
jrpriv = dev_get_drvdata(smpriv->smringdev);
lpagect = 0;
+ pgstat = 0;
lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
* smpriv->max_pages, GFP_KERNEL);
if (lpagedesc == NULL) {
}
for (page = 0; page < smpriv->max_pages; page++) {
- wr_reg32(&jrpriv->rregs->sm_cmd,
- ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
- (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK));
- pgstat = rd_reg32(&jrpriv->rregs->sm_status);
+ if (sm_set_cmd_reg(smpriv, jrpriv,
+ ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
+ (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK)))
+ return -EINVAL;
+ if (sm_get_status_reg(smpriv, jrpriv, &pgstat))
+ return -EINVAL;
+
if (((pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT)
== SMCS_PGOWN_OWNED) { /* our page? */
lpagedesc[page].phys_pagenum =