summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/qcom_scm.h
diff options
context:
space:
mode:
authorElliot Berman <eberman@codeaurora.org>2020-01-07 22:04:26 +0100
committerBjorn Andersson <bjorn.andersson@linaro.org>2020-01-08 07:14:43 +0100
commit9a434cee773ae15309ac225f27551b5492618e4a (patch)
tree26d7deff138efa039629a0611ada779626d552e5 /drivers/firmware/qcom_scm.h
parentfirmware: qcom_scm: Remove thin wrappers (diff)
downloadlinux-9a434cee773ae15309ac225f27551b5492618e4a.tar.xz
linux-9a434cee773ae15309ac225f27551b5492618e4a.zip
firmware: qcom_scm: Dynamically support SMCCC and legacy conventions
Dynamically support SMCCCC and legacy conventions by detecting which convention to use at runtime. qcom_scm_call_atomic and qcom_scm_call can then be moved in qcom_scm.c and use underlying convention backend as appropriate. Thus, rename qcom_scm-64,-32 to reflect that they are backends for -smc and -legacy, respectively. Also add support for making SCM calls earlier than when SCM driver probes to support use cases such as qcom_scm_set_cold_boot_addr. Support is added by lazily initializing the convention and guarding the query with a spin lock. The limitation of these early SCM calls is that they cannot use DMA, as in the case of >4 arguments for SMC convention and any non-atomic call for legacy convention. Tested-by: Brian Masney <masneyb@onstation.org> # arm32 Tested-by: Stephan Gerhold <stephan@gerhold.net> Signed-off-by: Elliot Berman <eberman@codeaurora.org> Link: https://lore.kernel.org/r/1578431066-19600-18-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/firmware/qcom_scm.h')
-rw-r--r--drivers/firmware/qcom_scm.h27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 9b7b3577821c..d9ed670da222 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -3,6 +3,16 @@
*/
#ifndef __QCOM_SCM_INT_H
#define __QCOM_SCM_INT_H
+
+enum qcom_scm_convention {
+ SMC_CONVENTION_UNKNOWN,
+ SMC_CONVENTION_LEGACY,
+ SMC_CONVENTION_ARM_32,
+ SMC_CONVENTION_ARM_64,
+};
+
+extern enum qcom_scm_convention qcom_scm_convention;
+
#define MAX_QCOM_SCM_ARGS 10
#define MAX_QCOM_SCM_RETS 3
@@ -50,11 +60,16 @@ struct qcom_scm_res {
u64 result[MAX_QCOM_SCM_RETS];
};
-extern int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,
- struct qcom_scm_res *res);
-extern int qcom_scm_call_atomic(struct device *dev,
- const struct qcom_scm_desc *desc,
- struct qcom_scm_res *res);
+#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
+extern int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
+ struct qcom_scm_res *res, bool atomic);
+
+#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff))
+extern int scm_legacy_call_atomic(struct device *dev,
+ const struct qcom_scm_desc *desc,
+ struct qcom_scm_res *res);
+extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
+ struct qcom_scm_res *res);
#define QCOM_SCM_SVC_BOOT 0x01
#define QCOM_SCM_BOOT_SET_ADDR 0x01
@@ -77,8 +92,6 @@ extern int qcom_scm_call_atomic(struct device *dev,
#define QCOM_SCM_SVC_INFO 0x06
#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01
-extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
- u32 cmd_id);
#define QCOM_SCM_SVC_MP 0x0c
#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02