From 8a0bf079f870379a1e392819ac1116d74500ec01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
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ă <horia.geanta@nxp.com>
---
 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) */
