1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
6 #include <linux/errno.h>
7 #include <linux/delay.h>
8 #include <linux/mutex.h>
9 #include <linux/slab.h>
10 #include <linux/types.h>
11 #include <linux/qcom_scm.h>
12 #include <linux/arm-smccc.h>
13 #include <linux/dma-mapping.h>
17 #define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
20 * struct arm_smccc_args
21 * @args: The array of values used in registers in smc instruction
23 struct arm_smccc_args {
24 unsigned long args[8];
27 static u64 qcom_smccc_convention = -1;
28 static DEFINE_MUTEX(qcom_scm_lock);
30 #define QCOM_SCM_EBUSY_WAIT_MS 30
31 #define QCOM_SCM_EBUSY_MAX_RETRY 20
33 #define SCM_SMC_N_REG_ARGS 4
34 #define SCM_SMC_FIRST_EXT_IDX (SCM_SMC_N_REG_ARGS - 1)
35 #define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1)
36 #define SCM_SMC_FIRST_REG_IDX 2
37 #define SCM_SMC_LAST_REG_IDX (SCM_SMC_FIRST_REG_IDX + SCM_SMC_N_REG_ARGS - 1)
39 static void __scm_smc_do_quirk(const struct arm_smccc_args *smc,
40 struct arm_smccc_res *res)
42 unsigned long a0 = smc->args[0];
43 struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 };
48 arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2],
49 smc->args[3], smc->args[4], smc->args[5],
50 quirk.state.a6, smc->args[7], res, &quirk);
52 if (res->a0 == QCOM_SCM_INTERRUPTED)
55 } while (res->a0 == QCOM_SCM_INTERRUPTED);
58 static void __scm_smc_do(const struct arm_smccc_args *smc,
59 struct arm_smccc_res *res, bool atomic)
64 __scm_smc_do_quirk(smc, res);
69 mutex_lock(&qcom_scm_lock);
71 __scm_smc_do_quirk(smc, res);
73 mutex_unlock(&qcom_scm_lock);
75 if (res->a0 == QCOM_SCM_V2_EBUSY) {
76 if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
78 msleep(QCOM_SCM_EBUSY_WAIT_MS);
80 } while (res->a0 == QCOM_SCM_V2_EBUSY);
83 static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
84 struct qcom_scm_res *res, bool atomic)
86 int arglen = desc->arginfo & 0xf;
88 dma_addr_t args_phys = 0;
89 void *args_virt = NULL;
91 gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
92 u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
93 struct arm_smccc_res smc_res;
94 struct arm_smccc_args smc = {0};
96 smc.args[0] = ARM_SMCCC_CALL_VAL(
98 qcom_smccc_convention,
100 SCM_SMC_FNID(desc->svc, desc->cmd));
101 smc.args[1] = desc->arginfo;
102 for (i = 0; i < SCM_SMC_N_REG_ARGS; i++)
103 smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
105 if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
106 alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
107 args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
112 if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
113 __le32 *args = args_virt;
115 for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
116 args[i] = cpu_to_le32(desc->args[i +
117 SCM_SMC_FIRST_EXT_IDX]);
119 __le64 *args = args_virt;
121 for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
122 args[i] = cpu_to_le64(desc->args[i +
123 SCM_SMC_FIRST_EXT_IDX]);
126 args_phys = dma_map_single(dev, args_virt, alloc_len,
129 if (dma_mapping_error(dev, args_phys)) {
134 smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
137 __scm_smc_do(&smc, &smc_res, atomic);
140 dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
145 res->result[0] = smc_res.a1;
146 res->result[1] = smc_res.a2;
147 res->result[2] = smc_res.a3;
150 return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0;
154 * qcom_scm_call() - Invoke a syscall in the secure world
156 * @svc_id: service identifier
157 * @cmd_id: command identifier
158 * @desc: Descriptor structure containing arguments and return values
160 * Sends a command to the SCM and waits for the command to finish processing.
161 * This should *only* be called in pre-emptible context.
163 int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,
164 struct qcom_scm_res *res)
167 return __scm_smc_call(dev, desc, res, false);
171 * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
173 * @svc_id: service identifier
174 * @cmd_id: command identifier
175 * @desc: Descriptor structure containing arguments and return values
176 * @res: Structure containing results from SMC/HVC call
178 * Sends a command to the SCM and waits for the command to finish processing.
179 * This can be called in atomic context.
181 int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc,
182 struct qcom_scm_res *res)
184 return __scm_smc_call(dev, desc, res, true);
187 int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
190 struct qcom_scm_desc desc = {
191 .svc = QCOM_SCM_SVC_INFO,
192 .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,
193 .owner = ARM_SMCCC_OWNER_SIP,
195 struct qcom_scm_res res;
197 desc.arginfo = QCOM_SCM_ARGS(1);
198 desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) |
199 (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
201 ret = qcom_scm_call(dev, &desc, &res);
203 return ret ? : res.result[0];
206 void __qcom_scm_init(void)
208 struct qcom_scm_desc desc = {
209 .svc = QCOM_SCM_SVC_INFO,
210 .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,
211 .args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO,
212 QCOM_SCM_INFO_IS_CALL_AVAIL) |
213 (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT),
214 .arginfo = QCOM_SCM_ARGS(1),
215 .owner = ARM_SMCCC_OWNER_SIP,
217 struct qcom_scm_res res;
220 qcom_smccc_convention = ARM_SMCCC_SMC_64;
221 // Device isn't required as there is only one argument - no device
222 // needed to dma_map_single to secure world
223 ret = qcom_scm_call_atomic(NULL, &desc, &res);
224 if (!ret && res.result[0] == 1)
227 qcom_smccc_convention = ARM_SMCCC_SMC_32;
228 ret = qcom_scm_call_atomic(NULL, &desc, &res);
229 if (!ret && res.result[0] == 1)
232 qcom_smccc_convention = -1;
235 pr_info("QCOM SCM SMC Convention: %lld\n", qcom_smccc_convention);