mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-09-03 10:33:11 +02:00
MLK-10897-1 ARM: imx7d: Add CAAM support for i.mx7d
CAAM only has a single clock in i.mx7d. Logic was added to initialize only the single clock. The Secure Memory registers moved in CAAM era included in i.mx7d. This required changes to support access to two different versions of the register map. The registers are access through a data structure that overlay the register region. Two new Secure Memory register structures were created to support the different versions. Logic was also added to determine which version is implemented based on the CAAM era, and access functions were added to support register access to the Secure Memory Command and Status registers. Signed-off-by: Dan Douglass <dan.douglass@freescale.com> (Vipul: Fixed merge conflicts) Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
This commit is contained in:
parent
35bbc34e99
commit
5316249198
|
@ -546,8 +546,7 @@ static int caam_probe(struct platform_device *pdev)
|
|||
}
|
||||
ctrlpriv->caam_ipg = clk;
|
||||
|
||||
if (!of_machine_is_compatible("fsl,imx7d") &&
|
||||
!of_machine_is_compatible("fsl,imx7s")) {
|
||||
if (!(of_find_compatible_node(NULL, NULL, "fsl,imx7d-caam"))) {
|
||||
clk = caam_drv_identify_clk(&pdev->dev, "mem");
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
|
@ -567,9 +566,8 @@ static int caam_probe(struct platform_device *pdev)
|
|||
}
|
||||
ctrlpriv->caam_aclk = clk;
|
||||
|
||||
if (!of_machine_is_compatible("fsl,imx6ul") &&
|
||||
!of_machine_is_compatible("fsl,imx7d") &&
|
||||
!of_machine_is_compatible("fsl,imx7s")) {
|
||||
if (!(of_find_compatible_node(NULL, NULL, "fsl,imx7d-caam")) &&
|
||||
!(of_find_compatible_node(NULL, NULL, "fsl,imx6ul-caam"))) {
|
||||
clk = caam_drv_identify_clk(&pdev->dev, "emi_slow");
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
|
|
|
@ -600,6 +600,34 @@ struct caam_ctrl {
|
|||
#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
|
||||
|
@ -641,19 +669,7 @@ struct caam_job_ring {
|
|||
/* 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;
|
||||
|
|
|
@ -96,6 +96,9 @@ struct caam_drv_private_sm {
|
|||
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 */
|
||||
|
|
|
@ -58,6 +58,54 @@ void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
|
|||
|
||||
#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
|
||||
*
|
||||
|
@ -949,7 +997,7 @@ int caam_sm_startup(struct platform_device *pdev)
|
|||
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;
|
||||
|
@ -986,6 +1034,13 @@ int caam_sm_startup(struct platform_device *pdev)
|
|||
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
|
||||
|
@ -994,7 +1049,7 @@ int caam_sm_startup(struct platform_device *pdev)
|
|||
& 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;
|
||||
|
@ -1024,6 +1079,7 @@ int caam_sm_startup(struct platform_device *pdev)
|
|||
smpriv->smringdev = caam_jr_alloc();
|
||||
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) {
|
||||
|
@ -1032,10 +1088,13 @@ int caam_sm_startup(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
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 =
|
||||
|
|
Loading…
Reference in New Issue
Block a user