diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/crypto/caam/ctrl.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/crypto/caam/ctrl.c')
| -rw-r--r-- | drivers/crypto/caam/ctrl.c | 112 | 
1 files changed, 78 insertions, 34 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 6278afb951c3..bedcc2ab3a00 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -3,7 +3,7 @@   * Controller-level driver, kernel property detection, initialization   *   * Copyright 2008-2012 Freescale Semiconductor, Inc. - * Copyright 2018-2019 NXP + * Copyright 2018-2019, 2023 NXP   */  #include <linux/device.h> @@ -284,6 +284,10 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,  		const u32 rdsta_if = RDSTA_IF0 << sh_idx;  		const u32 rdsta_pr = RDSTA_PR0 << sh_idx;  		const u32 rdsta_mask = rdsta_if | rdsta_pr; + +		/* Clear the contents before using the descriptor */ +		memset(desc, 0x00, CAAM_CMD_SZ * 7); +  		/*  		 * If the corresponding bit is set, this state handle  		 * was initialized by somebody else, so it's left alone. @@ -327,8 +331,6 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,  		}  		dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx); -		/* Clear the contents before recreating the descriptor */ -		memset(desc, 0x00, CAAM_CMD_SZ * 7);  	}  	kfree(desc); @@ -395,7 +397,7 @@ start_rng:  		      RTMCTL_SAMP_MODE_RAW_ES_SC);  } -static int caam_get_era_from_hw(struct caam_ctrl __iomem *ctrl) +static int caam_get_era_from_hw(struct caam_perfmon __iomem *perfmon)  {  	static const struct {  		u16 ip_id; @@ -421,12 +423,12 @@ static int caam_get_era_from_hw(struct caam_ctrl __iomem *ctrl)  	u16 ip_id;  	int i; -	ccbvid = rd_reg32(&ctrl->perfmon.ccb_id); +	ccbvid = rd_reg32(&perfmon->ccb_id);  	era = (ccbvid & CCBVID_ERA_MASK) >> CCBVID_ERA_SHIFT;  	if (era)	/* This is '0' prior to CAAM ERA-6 */  		return era; -	id_ms = rd_reg32(&ctrl->perfmon.caam_id_ms); +	id_ms = rd_reg32(&perfmon->caam_id_ms);  	ip_id = (id_ms & SECVID_MS_IPID_MASK) >> SECVID_MS_IPID_SHIFT;  	maj_rev = (id_ms & SECVID_MS_MAJ_REV_MASK) >> SECVID_MS_MAJ_REV_SHIFT; @@ -444,9 +446,9 @@ static int caam_get_era_from_hw(struct caam_ctrl __iomem *ctrl)   * In case this property is not passed an attempt to retrieve the CAAM   * era via register reads will be made.   * - * @ctrl:	controller region + * @perfmon:	Performance Monitor Registers   */ -static int caam_get_era(struct caam_ctrl __iomem *ctrl) +static int caam_get_era(struct caam_perfmon __iomem *perfmon)  {  	struct device_node *caam_node;  	int ret; @@ -459,7 +461,7 @@ static int caam_get_era(struct caam_ctrl __iomem *ctrl)  	if (!ret)  		return prop;  	else -		return caam_get_era_from_hw(ctrl); +		return caam_get_era_from_hw(perfmon);  }  /* @@ -626,12 +628,14 @@ static int caam_probe(struct platform_device *pdev)  	struct device_node *nprop, *np;  	struct caam_ctrl __iomem *ctrl;  	struct caam_drv_private *ctrlpriv; +	struct caam_perfmon __iomem *perfmon;  	struct dentry *dfs_root;  	u32 scfgr, comp_params;  	u8 rng_vid;  	int pg_size;  	int BLOCK_OFFSET = 0;  	bool pr_support = false; +	bool reg_access = true;  	ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);  	if (!ctrlpriv) @@ -645,6 +649,17 @@ static int caam_probe(struct platform_device *pdev)  	caam_imx = (bool)imx_soc_match;  	if (imx_soc_match) { +		/* +		 * 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 = !ctrlpriv->optee_en; +  		if (!imx_soc_match->data) {  			dev_err(dev, "No clock data provided for i.MX SoC");  			return -EINVAL; @@ -665,10 +680,38 @@ static int caam_probe(struct platform_device *pdev)  		return ret;  	} -	caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) & +	ring = 0; +	for_each_available_child_of_node(nprop, np) +		if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || +		    of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { +			u32 reg; + +			if (of_property_read_u32_index(np, "reg", 0, ®)) { +				dev_err(dev, "%s read reg property error\n", +					np->full_name); +				continue; +			} + +			ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) +					     ((__force uint8_t *)ctrl + reg); + +			ctrlpriv->total_jobrs++; +			ring++; +		} + +	/* +	 * Wherever possible, instead of accessing registers from the global page, +	 * use the alias registers in the first (cf. DT nodes order) +	 * job ring's page. +	 */ +	perfmon = ring ? (struct caam_perfmon __iomem *)&ctrlpriv->jr[0]->perfmon : +			 (struct caam_perfmon __iomem *)&ctrl->perfmon; + +	caam_little_end = !(bool)(rd_reg32(&perfmon->status) &  				  (CSTA_PLEND | CSTA_ALT_PLEND)); -	comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms); -	if (comp_params & CTPR_MS_PS && rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) +	comp_params = rd_reg32(&perfmon->comp_parms_ms); +	if (reg_access && comp_params & CTPR_MS_PS && +	    rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR)  		caam_ptr_sz = sizeof(u64);  	else  		caam_ptr_sz = sizeof(u32); @@ -733,6 +776,9 @@ static int caam_probe(struct platform_device *pdev)  	}  #endif +	if (!reg_access) +		goto set_dma_mask; +  	/*  	 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,  	 * long pointers in master configuration register. @@ -772,13 +818,14 @@ static int caam_probe(struct platform_device *pdev)  			      JRSTART_JR1_START | JRSTART_JR2_START |  			      JRSTART_JR3_START); +set_dma_mask:  	ret = dma_set_mask_and_coherent(dev, caam_get_dma_mask(dev));  	if (ret) {  		dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);  		return ret;  	} -	ctrlpriv->era = caam_get_era(ctrl); +	ctrlpriv->era = caam_get_era(perfmon);  	ctrlpriv->domain = iommu_get_domain_for_dev(dev);  	dfs_root = debugfs_create_dir(dev_name(dev), NULL); @@ -789,7 +836,7 @@ static int caam_probe(struct platform_device *pdev)  			return ret;  	} -	caam_debugfs_init(ctrlpriv, dfs_root); +	caam_debugfs_init(ctrlpriv, perfmon, dfs_root);  	/* Check to see if (DPAA 1.x) QI present. If so, enable */  	if (ctrlpriv->qi_present && !caam_dpaa2) { @@ -808,26 +855,16 @@ static int caam_probe(struct platform_device *pdev)  #endif  	} -	ring = 0; -	for_each_available_child_of_node(nprop, np) -		if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || -		    of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { -			ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) -					     ((__force uint8_t *)ctrl + -					     (ring + JR_BLOCK_NUMBER) * -					      BLOCK_OFFSET -					     ); -			ctrlpriv->total_jobrs++; -			ring++; -		} -  	/* If no QI and no rings specified, quit and go home */  	if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {  		dev_err(dev, "no queues configured, terminating\n");  		return -ENOMEM;  	} -	comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ls); +	if (!reg_access) +		goto report_live; + +	comp_params = rd_reg32(&perfmon->comp_parms_ls);  	ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB);  	/* @@ -836,15 +873,21 @@ static int caam_probe(struct platform_device *pdev)  	 * check both here.  	 */  	if (ctrlpriv->era < 10) { -		rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) & +		rng_vid = (rd_reg32(&perfmon->cha_id_ls) &  			   CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;  		ctrlpriv->blob_present = ctrlpriv->blob_present && -			(rd_reg32(&ctrl->perfmon.cha_num_ls) & CHA_ID_LS_AES_MASK); +			(rd_reg32(&perfmon->cha_num_ls) & CHA_ID_LS_AES_MASK);  	} else { -		rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >> +		struct version_regs __iomem *vreg; + +		vreg =  ctrlpriv->total_jobrs ? +			(struct version_regs __iomem *)&ctrlpriv->jr[0]->vreg : +			(struct version_regs __iomem *)&ctrl->vreg; + +		rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>  			   CHA_VER_VID_SHIFT;  		ctrlpriv->blob_present = ctrlpriv->blob_present && -			(rd_reg32(&ctrl->vreg.aesa) & CHA_VER_MISC_AES_NUM_MASK); +			(rd_reg32(&vreg->aesa) & CHA_VER_MISC_AES_NUM_MASK);  	}  	/* @@ -923,10 +966,11 @@ static int caam_probe(struct platform_device *pdev)  		clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);  	} +report_live:  	/* NOTE: RTIC detection ought to go here, around Si time */ -	caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 | -		  (u64)rd_reg32(&ctrl->perfmon.caam_id_ls); +	caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 | +		  (u64)rd_reg32(&perfmon->caam_id_ls);  	/* Report "alive" for developer to see */  	dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,  |