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

Commit eff149ef authored by Sonal Gupta's avatar Sonal Gupta Committed by Gerrit - the friendly Code Review server
Browse files

msm: crypto: Parse smmu context bank details



Parse smmu context bank information in the Crypto
driver. This information will be used to map and
unmap buffers in the Crypto driver.

CRs-Fixed: 1072414
Change-Id: I3bde52e349d52658474881e937fc8082e6885c07
Signed-off-by: default avatarSonal Gupta <sonalg@codeaurora.org>
parent 2e92080e
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
* QCEDEV (QTI Crypto Engine Device)

[Root level node]
Crypto Engine
============
Required properties:
  - compatible : should be "qcom,qcedev"
  - reg : should contain crypto, BAM register map.
@@ -23,6 +26,19 @@ Optional properties:
  - qcom,smmu-s1-enable : Boolean flag to enable SMMU stage 1 translation.
  - iommus : A list of phandle and IOMMU specifier pairs that describe the IOMMU master interfaces of the device.


[Second level nodes]
Context banks
=============
Required properties:
  - compatible : should be "qcom,qcedev,context-bank"
  - iommus : A phandle parsed by smmu driver. Number of entries will vary across targets.

Optional properties:
  - label - string describing iommu domain usage.
  - virtual-addr : start of virtual address pool.
  - virtual-size : size of virtual address pool.

Example:

	qcom,qcedev@fd440000 {
@@ -42,4 +58,15 @@ Example:
				<56 512 0 0>,
				<56 512 3936000 393600>,
		qcom,ce-opp-freq = <100000000>;

		qcom_cedev_ns_cb {
			compatible = "qcom,qcedev,context-bank";
			label = "ns_context";
			iommus = <&anoc2_smmu 0x1878>,
				<&anoc2_smmu 0x1879>,
				<&anoc2_smmu 0x187c>,
				<&anoc2_smmu 0x187f>;
			virtual-addr = <0x60000000>;
			virtual-size = <0x00200000>;
		};
	};
+1 −0
Original line number Diff line number Diff line
obj-$(CONFIG_CRYPTO_DEV_QCOM_MSM_QCE) += qce50.o
obj-$(CONFIG_CRYPTO_DEV_QCEDEV) += qcedev.o
obj-$(CONFIG_CRYPTO_DEV_QCEDEV) += qcedev_smmu.o
obj-$(CONFIG_CRYPTO_DEV_QCRYPTO) += qcrypto.o
obj-$(CONFIG_CRYPTO_DEV_OTA_CRYPTO) += ota_crypto.o
obj-$(CONFIG_CRYPTO_DEV_QCOM_ICE) += ice.o
+40 −10
Original line number Diff line number Diff line
/*
 * QTI CE device driver.
 *
 * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
#include <crypto/hash.h>
#include "qcedevi.h"
#include "qce.h"
#include "qcedev_smmu.h"

#include <linux/compat.h>
#include "compat_qcedev.h"
@@ -59,6 +60,14 @@ static DEFINE_MUTEX(send_cmd_lock);
static DEFINE_MUTEX(qcedev_sent_bw_req);
static DEFINE_MUTEX(hash_access_lock);

MODULE_DEVICE_TABLE(of, qcedev_match);

static const struct of_device_id qcedev_match[] = {
	{	.compatible = "qcom,qcedev"},
	{	.compatible = "qcom,qcedev,context-bank"},
	{}
};

static int qcedev_control_clocks(struct qcedev_control *podev, bool enable)
{
	unsigned int control_flag;
@@ -1864,7 +1873,7 @@ static inline long qcedev_ioctl(struct file *file,
	return err;
}

static int qcedev_probe(struct platform_device *pdev)
static int qcedev_probe_device(struct platform_device *pdev)
{
	void *handle = NULL;
	int rc = 0;
@@ -1877,6 +1886,8 @@ static int qcedev_probe(struct platform_device *pdev)
	INIT_LIST_HEAD(&podev->ready_commands);
	podev->active_command = NULL;

	INIT_LIST_HEAD(&podev->context_banks);

	spin_lock_init(&podev->lock);

	tasklet_init(&podev->done_tasklet, req_done, (unsigned long)podev);
@@ -1934,9 +1945,22 @@ static int qcedev_probe(struct platform_device *pdev)
	}

	rc = misc_register(&podev->miscdevice);
	if (rc >= 0)
	if (rc) {
		pr_err("%s: err: register failed for misc: %d\n", __func__, rc);
		goto exit_qce_close;
	}

	rc = of_platform_populate(pdev->dev.of_node, qcedev_match,
			NULL, &pdev->dev);
	if (rc) {
		pr_err("%s: err: of_platform_populate failed: %d\n",
			__func__, rc);
		goto err;
	}

	return 0;

err:
	misc_deregister(&podev->miscdevice);

exit_qce_close:
@@ -1947,11 +1971,23 @@ static int qcedev_probe(struct platform_device *pdev)
exit_unregister_bus_scale:
	if (podev->platform_support.bus_scale_table != NULL)
		msm_bus_scale_unregister_client(podev->bus_scale_handle);
	podev->bus_scale_handle = 0;
	platform_set_drvdata(pdev, NULL);
	podev->pdev = NULL;
	podev->qce = NULL;

	return rc;
}

static int qcedev_probe(struct platform_device *pdev)
{
	if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcedev"))
		return qcedev_probe_device(pdev);
	else if (of_device_is_compatible(pdev->dev.of_node,
		"qcom,qcedev,context-bank"))
		return qcedev_parse_context_bank(pdev);

	return -EINVAL;
};

static int qcedev_remove(struct platform_device *pdev)
@@ -2017,12 +2053,6 @@ static int qcedev_resume(struct platform_device *pdev)
	return 0;
}

static const struct of_device_id qcedev_match[] = {
	{	.compatible = "qcom,qcedev",
	},
	{}
};

static struct platform_driver qcedev_plat_driver = {
	.probe = qcedev_probe,
	.remove = qcedev_remove,
+141 −0
Original line number Diff line number Diff line
/* Qti (or) Qualcomm Technologies Inc CE device driver.
 *
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include <asm/dma-iommu.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/qcedev.h>
#include "qcedevi.h"
#include "qcedev_smmu.h"
#include "soc/qcom/secure_buffer.h"

static int qcedev_setup_context_bank(struct context_bank_info *cb,
				struct device *dev)
{
	int rc = 0;
	int secure_vmid = VMID_INVAL;
	struct bus_type *bus;

	if (!dev || !cb) {
		pr_err("%s err: invalid input params\n", __func__);
		return -EINVAL;
	}
	cb->dev = dev;

	bus = cb->dev->bus;
	if (IS_ERR_OR_NULL(bus)) {
		pr_err("%s err: failed to get bus type\n", __func__);
		rc = PTR_ERR(bus) ?: -ENODEV;
		goto remove_cb;
	}

	cb->mapping = arm_iommu_create_mapping(bus, cb->start_addr, cb->size);
	if (IS_ERR_OR_NULL(cb->mapping)) {
		pr_err("%s err: failed to create mapping\n", __func__);
		rc = PTR_ERR(cb->mapping) ?: -ENODEV;
		goto remove_cb;
	}

	if (cb->is_secure) {
		/* Hardcoded since we only have this vmid.*/
		secure_vmid = VMID_CP_BITSTREAM;
		rc = iommu_domain_set_attr(cb->mapping->domain,
			DOMAIN_ATTR_SECURE_VMID, &secure_vmid);
		if (rc) {
			pr_err("%s err: programming secure vmid failed %s %d\n",
				__func__, dev_name(dev), rc);
			goto release_mapping;
		}
	}

	rc = arm_iommu_attach_device(cb->dev, cb->mapping);
	if (rc) {
		pr_err("%s err: Failed to attach %s - %d\n",
			__func__, dev_name(dev), rc);
		goto release_mapping;
	}

	pr_info("%s Attached %s and create mapping\n", __func__, dev_name(dev));
	pr_info("%s Context Bank name:%s, is_secure:%d, start_addr:%#x\n",
			__func__, cb->name, cb->is_secure, cb->start_addr);
	pr_info("%s size:%#x, dev:%pK, mapping:%pK\n", __func__, cb->size,
			cb->dev, cb->mapping);
	return rc;

release_mapping:
	arm_iommu_release_mapping(cb->mapping);
remove_cb:
	return rc;
}

int qcedev_parse_context_bank(struct platform_device *pdev)
{
	struct qcedev_control *podev;
	struct context_bank_info *cb = NULL;
	struct device_node *np = NULL;
	int rc = 0;

	if (!pdev) {
		pr_err("%s err: invalid platform devices\n", __func__);
		return -EINVAL;
	}
	if (!pdev->dev.parent) {
		pr_err("%s err: failed to find a parent for %s\n",
			__func__, dev_name(&pdev->dev));
		return -EINVAL;
	}

	podev = dev_get_drvdata(pdev->dev.parent);
	np = pdev->dev.of_node;
	cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL);
	if (!cb) {
		pr_err("%s ERROR = Failed to allocate cb\n", __func__);
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&cb->list);
	list_add_tail(&cb->list, &podev->context_banks);

	rc = of_property_read_string(np, "label", &cb->name);
	if (rc)
		pr_debug("%s ERROR = Unable to read label\n", __func__);

	rc = of_property_read_u32(np, "virtual-addr", &cb->start_addr);
	if (rc) {
		pr_err("%s err: cannot read virtual region addr %d\n",
			__func__, rc);
		goto err_setup_cb;
	}

	rc = of_property_read_u32(np, "virtual-size", &cb->size);
	if (rc) {
		pr_err("%s err: cannot read virtual region size %d\n",
			__func__, rc);
		goto err_setup_cb;
	}

	cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank");

	rc = qcedev_setup_context_bank(cb, &pdev->dev);
	if (rc) {
		pr_err("%s err: cannot setup context bank %d\n", __func__, rc);
		goto err_setup_cb;
	}

	return 0;

err_setup_cb:
	devm_kfree(&pdev->dev, cb);
	list_del(&cb->list);
	return rc;
}
+35 −0
Original line number Diff line number Diff line
/* Qti (or) Qualcomm Technologies Inc CE device driver.
 *
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _DRIVERS_CRYPTO_PARSE_H_
#define _DRIVERS_CRYPTO_PARSE_H_

#include <linux/of.h>
#include <linux/of_platform.h>

struct context_bank_info {
	struct list_head list;
	const char *name;
	u32 buffer_type;
	u32 start_addr;
	u32 size;
	bool is_secure;
	struct device *dev;
	struct dma_iommu_mapping *mapping;
};

int qcedev_parse_context_bank(struct platform_device *pdev);

#endif
Loading