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

Commit 5362320e authored by Vivek Gautam's avatar Vivek Gautam Committed by Alistair Delva
Browse files

UPSTREAM: firmware/qcom_scm: Add scm call to handle smmu errata



Qcom's smmu-500 needs to toggle wait-for-safe sequence to
handle TLB invalidation sync's.
Few firmwares allow doing that through SCM interface.
Add API to toggle wait for safe from firmware through a
SCM call.

Signed-off-by: default avatarVivek Gautam <vivek.gautam@codeaurora.org>
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
Acked-by: default avatarAndy Gross <agross@kernel.org>
Signed-off-by: default avatarSai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
(cherry picked from commit 5eb0e0e4f90addc6b79ebf1cb4b06b56b09f09de)
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Bug: 146449535
Change-Id: I1e6ef0d2391be1ea9508eb44329a7a70de1b1481
parent b869aae8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -614,3 +614,8 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
	return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
				     addr, val);
}

int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable)
{
	return -ENODEV;
}
+13 −0
Original line number Diff line number Diff line
@@ -552,3 +552,16 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
	return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
			     &desc, &res);
}

int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en)
{
	struct qcom_scm_desc desc = {0};
	struct arm_smccc_res res;

	desc.args[0] = QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL;
	desc.args[1] = en;
	desc.arginfo = QCOM_SCM_ARGS(2);

	return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM,
				    QCOM_SCM_CONFIG_ERRATA1, &desc, &res);
}
+6 −0
Original line number Diff line number Diff line
@@ -345,6 +345,12 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);

int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
{
	return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en);
}
EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle);

int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
{
	return __qcom_scm_io_readl(__scm->dev, addr, val);
+5 −0
Original line number Diff line number Diff line
@@ -91,10 +91,15 @@ extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
				      u32 spare);
#define QCOM_SCM_IOMMU_SECURE_PTBL_SIZE	3
#define QCOM_SCM_IOMMU_SECURE_PTBL_INIT	4
#define QCOM_SCM_SVC_SMMU_PROGRAM	0x15
#define QCOM_SCM_CONFIG_ERRATA1		0x3
#define QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL	0x2
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_qsmmu500_wait_safe_toggle(struct device *dev,
						bool enable);
#define QCOM_MEM_PROT_ASSIGN_ID	0x16
extern int  __qcom_scm_assign_mem(struct device *dev,
				  phys_addr_t mem_region, size_t mem_sz,
+2 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ extern int qcom_scm_set_remote_state(u32 state, u32 id);
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_qsmmu500_wait_safe_toggle(bool en);
extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
#else
@@ -97,6 +98,7 @@ qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; }
static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; }
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_qsmmu500_wait_safe_toggle(bool en) { return -ENODEV; }
static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { return -ENODEV; }
static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { return -ENODEV; }
#endif