Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42e15f71 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "crypto: msm: Add multi-core crypto support"

parents 42a0cee6 249c3327
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ struct ce_hw_support {
	bool use_sw_aes_ccm_algo;
	bool clk_mgmt_sus_res;
	unsigned int ce_device;
	unsigned int ce_hw_instance;
};

/* Sha operation parameters */
+13 −18
Original line number Diff line number Diff line
@@ -5198,6 +5198,12 @@ static int __qce_get_device_tree_data(struct platform_device *pdev,
		pr_err("Fail to get CE device information.\n");
		return -EINVAL;
	}
	if (of_property_read_u32((&pdev->dev)->of_node,
				"qcom,ce-hw-instance",
				&pce_dev->ce_sps.ce_hw_instance)) {
		pr_err("Fail to get CE hw instance information.\n");
		return -EINVAL;
	}
	pce_dev->ce_sps.dest_pipe_index	= 2 * pce_dev->ce_sps.pipe_pair_index;
	pce_dev->ce_sps.src_pipe_index	= pce_dev->ce_sps.dest_pipe_index + 1;

@@ -5249,7 +5255,6 @@ err_getting_bam_info:
static int __qce_init_clk(struct qce_device *pce_dev)
{
	int rc = 0;
	struct clk *ce_core_clk;
	struct clk *ce_clk;
	struct clk *ce_core_src_clk;
	struct clk *ce_bus_clk;
@@ -5259,8 +5264,8 @@ static int __qce_init_clk(struct qce_device *pce_dev)
	if (!IS_ERR(ce_core_src_clk)) {
		pce_dev->ce_core_src_clk = ce_core_src_clk;

		/* Set the core src clk @100Mhz */
		rc = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
		/* Set the core src clk @171.43Mhz */
		rc = clk_set_rate(pce_dev->ce_core_src_clk, 171430000);
		if (rc) {
			clk_put(pce_dev->ce_core_src_clk);
			pce_dev->ce_core_src_clk = NULL;
@@ -5272,17 +5277,6 @@ static int __qce_init_clk(struct qce_device *pce_dev)
		pce_dev->ce_core_src_clk = NULL;
	}

	/* Get CE core clk */
	ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
	if (IS_ERR(ce_core_clk)) {
		rc = PTR_ERR(ce_core_clk);
		pr_err("Unable to get CE core clk\n");
		if (pce_dev->ce_core_src_clk != NULL)
			clk_put(pce_dev->ce_core_src_clk);
		goto err_clk;
	}
	pce_dev->ce_core_clk = ce_core_clk;

	/* Get CE Interface clk */
	ce_clk = clk_get(pce_dev->pdev, "iface_clk");
	if (IS_ERR(ce_clk)) {
@@ -5340,8 +5334,8 @@ int qce_enable_clk(void *handle)
	int rc = 0;

	/* Enable CE core clk */
	if (pce_dev->ce_core_clk != NULL) {
		rc = clk_prepare_enable(pce_dev->ce_core_clk);
	if (pce_dev->ce_core_src_clk != NULL) {
		rc = clk_prepare_enable(pce_dev->ce_core_src_clk);
		if (rc) {
			pr_err("Unable to enable/prepare CE core clk\n");
			return rc;
@@ -5378,8 +5372,8 @@ int qce_disable_clk(void *handle)

	if (pce_dev->ce_clk != NULL)
		clk_disable_unprepare(pce_dev->ce_clk);
	if (pce_dev->ce_core_clk != NULL)
		clk_disable_unprepare(pce_dev->ce_core_clk);
	if (pce_dev->ce_core_src_clk != NULL)
		clk_disable_unprepare(pce_dev->ce_core_src_clk);
	if (pce_dev->ce_bus_clk != NULL)
		clk_disable_unprepare(pce_dev->ce_bus_clk);

@@ -5532,6 +5526,7 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
	ce_support->use_sw_aes_ccm_algo =
				pce_dev->use_sw_aes_ccm_algo;
	ce_support->ce_device = pce_dev->ce_sps.ce_device;
	ce_support->ce_hw_instance = pce_dev->ce_sps.ce_hw_instance;
	return 0;
}
EXPORT_SYMBOL(qce_hw_support);
+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ struct ce_sps_data {
	struct scatterlist		*src;
	struct scatterlist		*dst;
	uint32_t			ce_device;
	uint32_t			ce_hw_instance;
	unsigned int			pipe_pair_index;
	unsigned int			src_pipe_index;
	unsigned int			dest_pipe_index;
+75 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ struct crypto_engine {
	u64 err_req;
	u32 unit;
	u32 ce_device;
	u32 ce_hw_instance;
	unsigned int signature;

	enum qcrypto_bus_state bw_state;
@@ -230,6 +231,63 @@ static struct crypto_engine *_qrypto_find_pengine_device(struct crypto_priv *cp,
	return entry;
}

static struct crypto_engine *_qrypto_find_pengine_device_hw
			(struct crypto_priv *cp,
			u32 device,
			u32 hw_instance)
{
	struct crypto_engine *entry = NULL;
	unsigned long flags;

	spin_lock_irqsave(&cp->lock, flags);
	list_for_each_entry(entry, &cp->engine_list, elist) {
		if ((entry->ce_device == device) &&
			(entry->ce_hw_instance == hw_instance))
			break;
	}
	spin_unlock_irqrestore(&cp->lock, flags);

	if (((entry != NULL) &&
		((entry->ce_device != device)
		|| (entry->ce_hw_instance != hw_instance)))
		|| (entry == NULL)) {
		pr_err("Device node for CE device %d NOT FOUND!!\n",
						 device);
		return NULL;
	}
	return entry;
}

int qcrypto_get_num_engines()
{
	struct crypto_priv *cp = &qcrypto_dev;
	struct crypto_engine *entry = NULL;
	int count = 0;

	list_for_each_entry(entry, &cp->engine_list, elist) {
		count++;
	}
	return count;
}
EXPORT_SYMBOL(qcrypto_get_num_engines);

void qcrypto_get_engine_list(size_t num_engines,
				struct crypto_engine_entry *arr)
{
	struct crypto_priv *cp = &qcrypto_dev;
	struct crypto_engine *entry = NULL;
	size_t arr_index = 0;

	list_for_each_entry(entry, &cp->engine_list, elist) {
			arr[arr_index].ce_device = entry->ce_device;
			arr[arr_index].hw_instance = entry->ce_hw_instance;
			arr_index++;
			if (arr_index >= num_engines)
				break;
	}
}
EXPORT_SYMBOL(qcrypto_get_engine_list);

static void qcrypto_unlock_ce(struct work_struct *work)
{
	int response = 0;
@@ -3826,6 +3884,22 @@ int qcrypto_cipher_set_device(struct ablkcipher_request *req, unsigned int dev)
};
EXPORT_SYMBOL(qcrypto_cipher_set_device);

int qcrypto_cipher_set_device_hw(struct ablkcipher_request *req, u32 dev,
			u32 hw_inst)
{
	struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
	struct crypto_priv *cp = ctx->cp;
	struct crypto_engine *pengine = NULL;

	pengine = _qrypto_find_pengine_device_hw(cp, dev, hw_inst);
	if (pengine == NULL)
		return -ENODEV;
	ctx->pengine = pengine;

	return 0;
}
EXPORT_SYMBOL(qcrypto_cipher_set_device_hw);

int qcrypto_aead_set_device(struct aead_request *req, unsigned int dev)
{
	struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
@@ -4524,6 +4598,7 @@ static int _qcrypto_probe(struct platform_device *pdev)
	spin_unlock_irqrestore(&cp->lock, flags);

	qce_hw_support(pengine->qce, &cp->ce_support);
	pengine->ce_hw_instance = cp->ce_support.ce_hw_instance;
	if (cp->ce_support.bam)	 {
		cp->platform_support.ce_shared = cp->ce_support.is_shared;
		cp->platform_support.shared_ce_resource = 0;
+14 −0
Original line number Diff line number Diff line
@@ -38,4 +38,18 @@ int qcrypto_cipher_clear_flag(struct ablkcipher_request *req,
int qcrypto_ahash_clear_flag(struct ahash_request *req, unsigned int flags);
int qcrypto_aead_clear_flag(struct aead_request *req, unsigned int flags);

struct crypto_engine_entry {
	u32 hw_instance;
	u32 ce_device;
	int shared;
};

int qcrypto_get_num_engines(void);
void qcrypto_get_engine_list(size_t num_engines,
				struct crypto_engine_entry *arr);
int qcrypto_cipher_set_device_hw(struct ablkcipher_request *req,
				unsigned int fde_pfe,
				unsigned int hw_inst);


#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTO_H */