From 8a0bf079f870379a1e392819ac1116d74500ec01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horia=20Geant=C4=83?= Date: Fri, 4 Oct 2019 15:07:41 +0300 Subject: [PATCH] MLKU-114-3 crypto: caam - OP-TEE firmware support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit caam driver needs to be aware of OP-TEE f/w presence, since some things are done differently: 1. there is no access to controller's register page (note however that some registers are aliased in job rings' register pages) It's worth mentioning that due to this, MCFGR[PS] cannot be read and driver assumes MCFGR[PS] = b'0 - engine using 32-bit address pointers. This is in sync with the fact that: -all i.MX SoCs currently use MCFGR[PS] = b'0 -only i.MX OP-TEE use cases don't allow access to controller register page Note: When DN OP-TEE will start enforcing the same policy, this solution will stop working and information about caam configuration will have to deduced in some other way. 2. as a consequence of "1.", part of the initialization is moved in other f/w (TF-A etc.), e.g. RNG initialization Signed-off-by: Horia Geantă --- drivers/crypto/caam/ctrl.c | 22 ++++++++++++++++++---- drivers/crypto/caam/intern.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -583,6 +583,7 @@ static int caam_probe(struct platform_de u8 rng_vid; int pg_size; int BLOCK_OFFSET = 0; + bool reg_access = true; ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL); if (!ctrlpriv) @@ -600,6 +601,8 @@ static int caam_probe(struct platform_de ctrlpriv->scu_en = !!np; of_node_put(np); + reg_access = !ctrlpriv->scu_en; + /* * CAAM clocks cannot be controlled from kernel. * They are automatically turned on by SCU f/w. @@ -607,6 +610,17 @@ static int caam_probe(struct platform_de if (ctrlpriv->scu_en) goto iomap_ctrl; + /* + * Until Layerscape and i.MX OP-TEE get in sync, + * only i.MX OP-TEE use cases disallow access to + * caam page 0 (controller) registers. + */ + np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); + ctrlpriv->optee_en = !!np; + of_node_put(np); + + reg_access = reg_access && !ctrlpriv->optee_en; + if (!imx_soc_match->data) { dev_err(dev, "No clock data provided for i.MX SoC"); return -EINVAL; @@ -657,7 +671,7 @@ iomap_ctrl: caam_little_end = !(bool)(rd_reg32(&perfmon->status) & (CSTA_PLEND | CSTA_ALT_PLEND)); comp_params = rd_reg32(&perfmon->comp_parms_ms); - if (!ctrlpriv->scu_en && comp_params & CTPR_MS_PS && + if (reg_access && comp_params & CTPR_MS_PS && rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) caam_ptr_sz = sizeof(u64); else @@ -708,7 +722,7 @@ iomap_ctrl: /* Get the IRQ of the controller (for security violations only) */ ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); - if (ctrlpriv->scu_en) + if (!reg_access) goto set_dma_mask; /* @@ -801,7 +815,7 @@ set_dma_mask: return -ENOMEM; } - if (ctrlpriv->scu_en) + if (!reg_access) goto report_live; if (ctrlpriv->era < 10) { @@ -928,7 +942,7 @@ report_live: ctrlpriv->ctl, &perfmon->status, &caam_fops_u32_ro); - if (ctrlpriv->scu_en) + if (!reg_access) goto probe_jrs; /* Internal covering keys (useful in non-secure mode only) */ --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -83,6 +83,7 @@ struct caam_drv_private { u8 qi_present; /* Nonzero if QI present in device */ u8 mc_en; /* Nonzero if MC f/w is active */ u8 scu_en; /* Nonzero if SCU f/w is active */ ++ u8 optee_en; /* Nonzero if OP-TEE f/w is active */ int secvio_irq; /* Security violation interrupt number */ int virt_en; /* Virtualization enabled in CAAM */ int era; /* CAAM Era (internal HW revision) */