Commit ae1dd17d authored by Horia GeantA's avatar Horia GeantA Committed by Herbert Xu
Browse files

crypto: caam - reduce page 0 regs access to minimum



Use job ring register map, in place of controller register map
to access page 0 registers, as access to the controller register
map is not permitted.

Signed-off-by: default avatarHoria GeantA <horia.geanta@nxp.com>
Signed-off-by: default avatarGaurav Jain <gaurav.jain@nxp.com>
Signed-off-by: default avatarMeenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Reviewed-by: default avatarVarun Sethi <v.sethi@nxp.com>
Reviewed-by: default avatarGaurav Jain <gaurav.jain@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 6699e143
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * caam - Freescale FSL CAAM support for crypto API
 *
 * Copyright 2008-2011 Freescale Semiconductor, Inc.
 * Copyright 2016-2019 NXP
 * Copyright 2016-2019, 2023 NXP
 *
 * Based on talitos crypto API driver.
 *
@@ -3542,13 +3542,14 @@ int caam_algapi_init(struct device *ctrldev)
	 * First, detect presence and attributes of DES, AES, and MD blocks.
	 */
	if (priv->era < 10) {
		struct caam_perfmon __iomem *perfmon = &priv->jr[0]->perfmon;
		u32 cha_vid, cha_inst, aes_rn;

		cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
		cha_vid = rd_reg32(&perfmon->cha_id_ls);
		aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
		md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;

		cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
		cha_inst = rd_reg32(&perfmon->cha_num_ls);
		des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
			   CHA_ID_LS_DES_SHIFT;
		aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
@@ -3556,23 +3557,23 @@ int caam_algapi_init(struct device *ctrldev)
		ccha_inst = 0;
		ptha_inst = 0;

		aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) &
			 CHA_ID_LS_AES_MASK;
		aes_rn = rd_reg32(&perfmon->cha_rev_ls) & CHA_ID_LS_AES_MASK;
		gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8);
	} else {
		struct version_regs __iomem *vreg = &priv->jr[0]->vreg;
		u32 aesa, mdha;

		aesa = rd_reg32(&priv->ctrl->vreg.aesa);
		mdha = rd_reg32(&priv->ctrl->vreg.mdha);
		aesa = rd_reg32(&vreg->aesa);
		mdha = rd_reg32(&vreg->mdha);

		aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;

		des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
		des_inst = rd_reg32(&vreg->desa) & CHA_VER_NUM_MASK;
		aes_inst = aesa & CHA_VER_NUM_MASK;
		md_inst = mdha & CHA_VER_NUM_MASK;
		ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
		ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
		ccha_inst = rd_reg32(&vreg->ccha) & CHA_VER_NUM_MASK;
		ptha_inst = rd_reg32(&vreg->ptha) & CHA_VER_NUM_MASK;

		gcm_support = aesa & CHA_VER_MISC_AES_GCM;
	}
+6 −4
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * caam - Freescale FSL CAAM support for ahash functions of crypto API
 *
 * Copyright 2011 Freescale Semiconductor, Inc.
 * Copyright 2018-2019 NXP
 * Copyright 2018-2019, 2023 NXP
 *
 * Based on caamalg.c crypto API driver.
 *
@@ -1956,12 +1956,14 @@ int caam_algapi_hash_init(struct device *ctrldev)
	 * presence and attributes of MD block.
	 */
	if (priv->era < 10) {
		md_vid = (rd_reg32(&priv->ctrl->perfmon.cha_id_ls) &
		struct caam_perfmon __iomem *perfmon = &priv->jr[0]->perfmon;

		md_vid = (rd_reg32(&perfmon->cha_id_ls) &
			  CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
		md_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
		md_inst = (rd_reg32(&perfmon->cha_num_ls) &
			   CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
	} else {
		u32 mdha = rd_reg32(&priv->ctrl->vreg.mdha);
		u32 mdha = rd_reg32(&priv->jr[0]->vreg.mdha);

		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
		md_inst = mdha & CHA_VER_NUM_MASK;
+3 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * caam - Freescale FSL CAAM support for Public Key Cryptography
 *
 * Copyright 2016 Freescale Semiconductor, Inc.
 * Copyright 2018-2019 NXP
 * Copyright 2018-2019, 2023 NXP
 *
 * There is no Shared Descriptor for PKC so that the Job Descriptor must carry
 * all the desired key parameters, input and output pointers.
@@ -1168,10 +1168,10 @@ int caam_pkc_init(struct device *ctrldev)

	/* Determine public key hardware accelerator presence. */
	if (priv->era < 10) {
		pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
		pk_inst = (rd_reg32(&priv->jr[0]->perfmon.cha_num_ls) &
			   CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
	} else {
		pkha = rd_reg32(&priv->ctrl->vreg.pkha);
		pkha = rd_reg32(&priv->jr[0]->vreg.pkha);
		pk_inst = pkha & CHA_VER_NUM_MASK;

		/*
+3 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * caam - Freescale FSL CAAM support for hw_random
 *
 * Copyright 2011 Freescale Semiconductor, Inc.
 * Copyright 2018-2019 NXP
 * Copyright 2018-2019, 2023 NXP
 *
 * Based on caamalg.c crypto API driver.
 *
@@ -227,10 +227,10 @@ int caam_rng_init(struct device *ctrldev)

	/* Check for an instantiated RNG before registration */
	if (priv->era < 10)
		rng_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
		rng_inst = (rd_reg32(&priv->jr[0]->perfmon.cha_num_ls) &
			    CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
	else
		rng_inst = rd_reg32(&priv->ctrl->vreg.rng) & CHA_VER_NUM_MASK;
		rng_inst = rd_reg32(&priv->jr[0]->vreg.rng) & CHA_VER_NUM_MASK;

	if (!rng_inst)
		return 0;
+52 −31
Original line number Diff line number Diff line
@@ -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>
@@ -397,7 +397,7 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
		      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;
@@ -423,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;

@@ -446,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;
@@ -461,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);
}

/*
@@ -628,6 +628,7 @@ 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;
@@ -667,9 +668,36 @@ 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, &reg)) {
				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);
	comp_params = rd_reg32(&perfmon->comp_parms_ms);
	if (comp_params & CTPR_MS_PS && rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR)
		caam_ptr_sz = sizeof(u64);
	else
@@ -780,7 +808,7 @@ static int caam_probe(struct platform_device *pdev)
		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);
@@ -791,7 +819,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) {
@@ -810,26 +838,13 @@ 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);
	comp_params = rd_reg32(&perfmon->comp_parms_ls);
	ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB);

	/*
@@ -838,15 +853,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);
	}

	/*
@@ -927,8 +948,8 @@ static int caam_probe(struct platform_device *pdev)

	/* 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,
Loading