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

Commit 050d2dca authored by Siddharth Gupta's avatar Siddharth Gupta Committed by Elliot Berman
Browse files

iommu/arm-smmu: Migrate SCM IO calls in arm-smmu



Migrate SCM IO read calls in the smmu driver to use new SCM driver.
Add support for io-pgtable-msm-secure map and unmap in SCM driver.

Change-Id: If1ce054b9cfcfdcdab3aecc6752fcd4765197a05
Signed-off-by: default avatarSiddharth Gupta <sidgup@codeaurora.org>
Signed-off-by: default avatarElliot Berman <eberman@codeaurora.org>
parent e061e5f0
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -952,6 +952,58 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size,
	return ret;
}

int __qcom_scm_iommu_secure_map(struct device *dev, phys_addr_t sg_list_addr,
			size_t num_sg, size_t sg_block_size, u64 sec_id,
			int cbndx, unsigned long iova, size_t total_len)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_MP,
		.cmd = QCOM_SCM_MP_IOMMU_SECURE_MAP2_FLAT,
		.owner = ARM_SMCCC_OWNER_SIP
	};

	desc.args[0] = sg_list_addr;
	desc.args[1] = num_sg;
	desc.args[2] = sg_block_size;
	desc.args[3] = sec_id;
	desc.args[4] = cbndx;
	desc.args[5] = iova;
	desc.args[6] = total_len;
	desc.args[7] = 0;


	desc.arginfo = QCOM_SCM_ARGS(8, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL,
			QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL,
			QCOM_SCM_VAL);

	ret = qcom_scm_call(dev, &desc);

	return ret ? : desc.res[0];
}

int __qcom_scm_iommu_secure_unmap(struct device *dev, u64 sec_id, int cbndx,
			unsigned long iova, size_t total_len)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_MP,
		.cmd = QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT,
		.owner = ARM_SMCCC_OWNER_SIP
	};

	desc.args[0] = sec_id;
	desc.args[1] = cbndx;
	desc.args[2] = iova;
	desc.args[3] = total_len;
	desc.args[4] = QCOM_SCM_IOMMU_TLBINVAL_FLAG;
	desc.arginfo = QCOM_SCM_ARGS(5);

	ret = qcom_scm_call(dev, &desc);

	return ret ? : desc.res[0];
}

int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
			  size_t mem_sz, phys_addr_t src, size_t src_sz,
			  phys_addr_t dest, size_t dest_sz)
+17 −0
Original line number Diff line number Diff line
@@ -358,6 +358,23 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);

int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg,
				size_t sg_block_size, u64 sec_id, int cbndx,
				unsigned long iova, size_t total_len)
{
	return __qcom_scm_iommu_secure_map(__scm->dev, sg_list_addr, num_sg,
				sg_block_size, sec_id, cbndx, iova, total_len);
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_map);

int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx, unsigned long iova,
				size_t total_len)
{
	return __qcom_scm_iommu_secure_unmap(__scm->dev, sec_id, cbndx, iova,
						total_len);
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_unmap);

/**
 * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership
 * @mem_addr: mem region whose ownership need to be reassigned
+11 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ extern void __qcom_scm_mmu_sync(struct device *dev, bool sync);
#define QCOM_SCM_MP_RESTORE_SEC_CFG		0x02
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE	0x03
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT	0x04
#define QCOM_SCM_MP_IOMMU_SECURE_MAP2_FLAT	0x12
#define QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT	0x13
#define QCOM_SCM_MP_ASSIGN			0x16
extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
				      u32 spare);
@@ -62,10 +64,19 @@ extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
					     size_t *size);
extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr,
					     u32 size, u32 spare);
extern int __qcom_scm_iommu_secure_map(struct device *dev,
				phys_addr_t sg_list_addr, size_t num_sg,
				size_t sg_block_size, u64 sec_id, int cbndx,
				unsigned long iova, size_t total_len);
extern int __qcom_scm_iommu_secure_unmap(struct device *dev, u64 sec_id,
				int cbndx, unsigned long iova,
				size_t total_len);
extern int  __qcom_scm_assign_mem(struct device *dev,
				  phys_addr_t mem_region, size_t mem_sz,
				  phys_addr_t src, size_t src_sz,
				  phys_addr_t dest, size_t dest_sz);
#define QCOM_SCM_IOMMU_TLBINVAL_FLAG    0x00000001


#define QCOM_SCM_SVC_HDCP			0x11
#define QCOM_SCM_HDCP_INVOKE			0x01
+7 −6
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@
#include <linux/amba/bus.h>
#include <linux/fsl/mc.h>

#include <soc/qcom/scm.h>
#include <linux/qcom_scm.h>
#include "arm-smmu.h"

#define CREATE_TRACE_POINTS
@@ -868,7 +868,7 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
				int sync, int status)
{
	unsigned int spin_cnt, delay;
	u32 sync_inv_ack, tbu_pwr_status, sync_inv_progress;
	u32 sync_inv_ack, tbu_pwr_status = -EINVAL, sync_inv_progress = -EINVAL;
	u32 reg;

	arm_smmu_writel(smmu, page, sync, QCOM_DUMMY_VAL);
@@ -885,10 +885,11 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
	sync_inv_ack = arm_smmu_readl(smmu,
				      ARM_SMMU_IMPL_DEF0,
				      ARM_SMMU_STATS_SYNC_INV_TBU_ACK);
	tbu_pwr_status = scm_io_read((unsigned long)(smmu->phys_addr +
				     ARM_SMMU_TBU_PWR_STATUS));
	sync_inv_progress = scm_io_read((unsigned long)(smmu->phys_addr +
					ARM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR));
	qcom_scm_io_readl((unsigned long)(smmu->phys_addr +
			ARM_SMMU_TBU_PWR_STATUS), &tbu_pwr_status);
	qcom_scm_io_readl((unsigned long)(smmu->phys_addr +
			      ARM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR),
			      &sync_inv_progress);
	trace_tlbsync_timeout(smmu->dev, 0);
	dev_err_ratelimited(smmu->dev,
			    "TLB sync timed out -- SMMU may be deadlocked ack 0x%x pwr 0x%x sync and invalidation progress 0x%x\n",
+10 −0
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@ extern void qcom_scm_mmu_sync(bool sync);
extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
extern int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg,
				size_t sg_block_size, u64 sec_id, int cbndx,
				unsigned long iova, size_t total_len);
extern int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx,
				unsigned long iova, size_t total_len);
extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
			       unsigned int *src,
			       const struct qcom_scm_vmperm *newvm,
@@ -95,6 +100,11 @@ static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
		{ return -ENODEV; }
static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
		{ return -ENODEV; }
static inline int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr,
		size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx,
		unsigned long iova, size_t total_len) { return -ENODEV; }
static inline int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx,
		unsigned long iova, size_t total_len) { return -ENODEV; }
static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
				      unsigned int *src,
				      const struct qcom_scm_vmperm *newvm,