summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/qcom_scm-64.c
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@sonymobile.com>2015-09-23 12:56:12 -0700
committerAndy Gross <andy.gross@linaro.org>2016-06-24 22:53:50 -0500
commitf01e90fe34f563a5e189d4070de4a23948105642 (patch)
treefaf82fa8a27f2f04de8e3b4465cc3ecf36f1de3b /drivers/firmware/qcom_scm-64.c
parent3680a4a97435496ad22cd0fc9f2ba51751cc4e36 (diff)
downloadlinux-f01e90fe34f563a5e189d4070de4a23948105642.tar.bz2
firmware: qcom: scm: Peripheral Authentication Service
This adds the Peripheral Authentication Service (PAS) interface to the Qualcomm SCM interface. The API is used to authenticate and boot a range of external processors in various Qualcomm platforms. Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com> Signed-off-by: Andy Gross <andy.gross@linaro.org>
Diffstat (limited to 'drivers/firmware/qcom_scm-64.c')
-rw-r--r--drivers/firmware/qcom_scm-64.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 01949f1828f4..3ac249037dbf 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -27,6 +27,13 @@
#define MAX_QCOM_SCM_ARGS 10
#define MAX_QCOM_SCM_RETS 3
+enum qcom_scm_arg_types {
+ QCOM_SCM_VAL,
+ QCOM_SCM_RO,
+ QCOM_SCM_RW,
+ QCOM_SCM_BUFVAL,
+};
+
#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
(((a) & 0x3) << 4) | \
(((b) & 0x3) << 6) | \
@@ -253,3 +260,85 @@ void __qcom_scm_init(void)
else
qcom_smccc_convention = ARM_SMCCC_SMC_32;
}
+
+bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
+{
+ int ret;
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+
+ desc.args[0] = peripheral;
+ desc.arginfo = QCOM_SCM_ARGS(1);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
+ QCOM_SCM_PAS_IS_SUPPORTED_CMD,
+ &desc, &res);
+
+ return ret ? false : !!res.a1;
+}
+
+int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral,
+ dma_addr_t metadata_phys)
+{
+ int ret;
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+
+ desc.args[0] = peripheral;
+ desc.args[1] = metadata_phys;
+ desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
+ &desc, &res);
+
+ return ret ? : res.a1;
+}
+
+int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral,
+ phys_addr_t addr, phys_addr_t size)
+{
+ int ret;
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+
+ desc.args[0] = peripheral;
+ desc.args[1] = addr;
+ desc.args[2] = size;
+ desc.arginfo = QCOM_SCM_ARGS(3);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD,
+ &desc, &res);
+
+ return ret ? : res.a1;
+}
+
+int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral)
+{
+ int ret;
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+
+ desc.args[0] = peripheral;
+ desc.arginfo = QCOM_SCM_ARGS(1);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
+ QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
+ &desc, &res);
+
+ return ret ? : res.a1;
+}
+
+int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral)
+{
+ int ret;
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+
+ desc.args[0] = peripheral;
+ desc.arginfo = QCOM_SCM_ARGS(1);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD,
+ &desc, &res);
+
+ return ret ? : res.a1;
+}