1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2015, 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 QCOM_SCM_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
19 #define MAX_QCOM_SCM_ARGS 10
20 #define MAX_QCOM_SCM_RETS 3
22 enum qcom_scm_arg_types
{
29 #define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
30 (((a) & 0x3) << 4) | \
31 (((b) & 0x3) << 6) | \
32 (((c) & 0x3) << 8) | \
33 (((d) & 0x3) << 10) | \
34 (((e) & 0x3) << 12) | \
35 (((f) & 0x3) << 14) | \
36 (((g) & 0x3) << 16) | \
37 (((h) & 0x3) << 18) | \
38 (((i) & 0x3) << 20) | \
39 (((j) & 0x3) << 22) | \
42 #define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
45 * struct qcom_scm_desc
46 * @arginfo: Metadata describing the arguments in args[]
47 * @args: The array of arguments for the secure syscall
48 * @res: The values returned by the secure syscall
50 struct qcom_scm_desc
{
52 u64 args
[MAX_QCOM_SCM_ARGS
];
55 static u64 qcom_smccc_convention
= -1;
56 static DEFINE_MUTEX(qcom_scm_lock
);
58 #define QCOM_SCM_EBUSY_WAIT_MS 30
59 #define QCOM_SCM_EBUSY_MAX_RETRY 20
61 #define N_EXT_QCOM_SCM_ARGS 7
62 #define FIRST_EXT_ARG_IDX 3
63 #define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
66 * qcom_scm_call() - Invoke a syscall in the secure world
68 * @svc_id: service identifier
69 * @cmd_id: command identifier
70 * @desc: Descriptor structure containing arguments and return values
72 * Sends a command to the SCM and waits for the command to finish processing.
73 * This should *only* be called in pre-emptible context.
75 static int qcom_scm_call(struct device
*dev
, u32 svc_id
, u32 cmd_id
,
76 const struct qcom_scm_desc
*desc
,
77 struct arm_smccc_res
*res
)
79 int arglen
= desc
->arginfo
& 0xf;
80 int retry_count
= 0, i
;
81 u32 fn_id
= QCOM_SCM_FNID(svc_id
, cmd_id
);
82 u64 cmd
, x5
= desc
->args
[FIRST_EXT_ARG_IDX
];
83 dma_addr_t args_phys
= 0;
84 void *args_virt
= NULL
;
86 struct arm_smccc_quirk quirk
= {.id
= ARM_SMCCC_QUIRK_QCOM_A6
};
88 if (unlikely(arglen
> N_REGISTER_ARGS
)) {
89 alloc_len
= N_EXT_QCOM_SCM_ARGS
* sizeof(u64
);
90 args_virt
= kzalloc(PAGE_ALIGN(alloc_len
), GFP_KERNEL
);
95 if (qcom_smccc_convention
== ARM_SMCCC_SMC_32
) {
96 __le32
*args
= args_virt
;
98 for (i
= 0; i
< N_EXT_QCOM_SCM_ARGS
; i
++)
99 args
[i
] = cpu_to_le32(desc
->args
[i
+
102 __le64
*args
= args_virt
;
104 for (i
= 0; i
< N_EXT_QCOM_SCM_ARGS
; i
++)
105 args
[i
] = cpu_to_le64(desc
->args
[i
+
109 args_phys
= dma_map_single(dev
, args_virt
, alloc_len
,
112 if (dma_mapping_error(dev
, args_phys
)) {
121 mutex_lock(&qcom_scm_lock
);
123 cmd
= ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL
,
124 qcom_smccc_convention
,
125 ARM_SMCCC_OWNER_SIP
, fn_id
);
130 arm_smccc_smc_quirk(cmd
, desc
->arginfo
, desc
->args
[0],
131 desc
->args
[1], desc
->args
[2], x5
,
132 quirk
.state
.a6
, 0, res
, &quirk
);
134 if (res
->a0
== QCOM_SCM_INTERRUPTED
)
137 } while (res
->a0
== QCOM_SCM_INTERRUPTED
);
139 mutex_unlock(&qcom_scm_lock
);
141 if (res
->a0
== QCOM_SCM_V2_EBUSY
) {
142 if (retry_count
++ > QCOM_SCM_EBUSY_MAX_RETRY
)
144 msleep(QCOM_SCM_EBUSY_WAIT_MS
);
146 } while (res
->a0
== QCOM_SCM_V2_EBUSY
);
149 dma_unmap_single(dev
, args_phys
, alloc_len
, DMA_TO_DEVICE
);
154 return qcom_scm_remap_error(res
->a0
);
160 * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
161 * @entry: Entry point function for the cpus
162 * @cpus: The cpumask of cpus that will use the entry point
164 * Set the cold boot address of the cpus. Any cpu outside the supported
165 * range would be removed from the cpu present mask.
167 int __qcom_scm_set_cold_boot_addr(void *entry
, const cpumask_t
*cpus
)
173 * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
174 * @dev: Device pointer
175 * @entry: Entry point function for the cpus
176 * @cpus: The cpumask of cpus that will use the entry point
178 * Set the Linux entry point for the SCM to transfer control to when coming
179 * out of a power down. CPU power down may be executed on cpuidle or hotplug.
181 int __qcom_scm_set_warm_boot_addr(struct device
*dev
, void *entry
,
182 const cpumask_t
*cpus
)
188 * qcom_scm_cpu_power_down() - Power down the cpu
189 * @flags - Flags to flush cache
191 * This is an end point to power down cpu. If there was a pending interrupt,
192 * the control would return from this function, otherwise, the cpu jumps to the
193 * warm boot entry point set for this cpu upon reset.
195 void __qcom_scm_cpu_power_down(u32 flags
)
199 int __qcom_scm_is_call_available(struct device
*dev
, u32 svc_id
, u32 cmd_id
)
202 struct qcom_scm_desc desc
= {0};
203 struct arm_smccc_res res
;
205 desc
.arginfo
= QCOM_SCM_ARGS(1);
206 desc
.args
[0] = QCOM_SCM_FNID(svc_id
, cmd_id
) |
207 (ARM_SMCCC_OWNER_SIP
<< ARM_SMCCC_OWNER_SHIFT
);
209 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_INFO
, QCOM_IS_CALL_AVAIL_CMD
,
212 return ret
? : res
.a1
;
215 int __qcom_scm_hdcp_req(struct device
*dev
, struct qcom_scm_hdcp_req
*req
,
216 u32 req_cnt
, u32
*resp
)
219 struct qcom_scm_desc desc
= {0};
220 struct arm_smccc_res res
;
222 if (req_cnt
> QCOM_SCM_HDCP_MAX_REQ_CNT
)
225 desc
.args
[0] = req
[0].addr
;
226 desc
.args
[1] = req
[0].val
;
227 desc
.args
[2] = req
[1].addr
;
228 desc
.args
[3] = req
[1].val
;
229 desc
.args
[4] = req
[2].addr
;
230 desc
.args
[5] = req
[2].val
;
231 desc
.args
[6] = req
[3].addr
;
232 desc
.args
[7] = req
[3].val
;
233 desc
.args
[8] = req
[4].addr
;
234 desc
.args
[9] = req
[4].val
;
235 desc
.arginfo
= QCOM_SCM_ARGS(10);
237 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_HDCP
, QCOM_SCM_CMD_HDCP
, &desc
,
244 void __qcom_scm_init(void)
247 struct arm_smccc_res res
;
248 u32 function
= QCOM_SCM_FNID(QCOM_SCM_SVC_INFO
, QCOM_IS_CALL_AVAIL_CMD
);
250 /* First try a SMC64 call */
251 cmd
= ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL
, ARM_SMCCC_SMC_64
,
252 ARM_SMCCC_OWNER_SIP
, function
);
254 arm_smccc_smc(cmd
, QCOM_SCM_ARGS(1), cmd
& (~BIT(ARM_SMCCC_TYPE_SHIFT
)),
255 0, 0, 0, 0, 0, &res
);
257 if (!res
.a0
&& res
.a1
)
258 qcom_smccc_convention
= ARM_SMCCC_SMC_64
;
260 qcom_smccc_convention
= ARM_SMCCC_SMC_32
;
263 bool __qcom_scm_pas_supported(struct device
*dev
, u32 peripheral
)
266 struct qcom_scm_desc desc
= {0};
267 struct arm_smccc_res res
;
269 desc
.args
[0] = peripheral
;
270 desc
.arginfo
= QCOM_SCM_ARGS(1);
272 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
,
273 QCOM_SCM_PAS_IS_SUPPORTED_CMD
,
276 return ret
? false : !!res
.a1
;
279 int __qcom_scm_pas_init_image(struct device
*dev
, u32 peripheral
,
280 dma_addr_t metadata_phys
)
283 struct qcom_scm_desc desc
= {0};
284 struct arm_smccc_res res
;
286 desc
.args
[0] = peripheral
;
287 desc
.args
[1] = metadata_phys
;
288 desc
.arginfo
= QCOM_SCM_ARGS(2, QCOM_SCM_VAL
, QCOM_SCM_RW
);
290 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
, QCOM_SCM_PAS_INIT_IMAGE_CMD
,
293 return ret
? : res
.a1
;
296 int __qcom_scm_pas_mem_setup(struct device
*dev
, u32 peripheral
,
297 phys_addr_t addr
, phys_addr_t size
)
300 struct qcom_scm_desc desc
= {0};
301 struct arm_smccc_res res
;
303 desc
.args
[0] = peripheral
;
306 desc
.arginfo
= QCOM_SCM_ARGS(3);
308 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
, QCOM_SCM_PAS_MEM_SETUP_CMD
,
311 return ret
? : res
.a1
;
314 int __qcom_scm_pas_auth_and_reset(struct device
*dev
, u32 peripheral
)
317 struct qcom_scm_desc desc
= {0};
318 struct arm_smccc_res res
;
320 desc
.args
[0] = peripheral
;
321 desc
.arginfo
= QCOM_SCM_ARGS(1);
323 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
,
324 QCOM_SCM_PAS_AUTH_AND_RESET_CMD
,
327 return ret
? : res
.a1
;
330 int __qcom_scm_pas_shutdown(struct device
*dev
, u32 peripheral
)
333 struct qcom_scm_desc desc
= {0};
334 struct arm_smccc_res res
;
336 desc
.args
[0] = peripheral
;
337 desc
.arginfo
= QCOM_SCM_ARGS(1);
339 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
, QCOM_SCM_PAS_SHUTDOWN_CMD
,
342 return ret
? : res
.a1
;
345 int __qcom_scm_pas_mss_reset(struct device
*dev
, bool reset
)
347 struct qcom_scm_desc desc
= {0};
348 struct arm_smccc_res res
;
351 desc
.args
[0] = reset
;
353 desc
.arginfo
= QCOM_SCM_ARGS(2);
355 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_PIL
, QCOM_SCM_PAS_MSS_RESET
, &desc
,
358 return ret
? : res
.a1
;
361 int __qcom_scm_set_remote_state(struct device
*dev
, u32 state
, u32 id
)
363 struct qcom_scm_desc desc
= {0};
364 struct arm_smccc_res res
;
367 desc
.args
[0] = state
;
369 desc
.arginfo
= QCOM_SCM_ARGS(2);
371 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_BOOT
, QCOM_SCM_SET_REMOTE_STATE
,
374 return ret
? : res
.a1
;
377 int __qcom_scm_assign_mem(struct device
*dev
, phys_addr_t mem_region
,
378 size_t mem_sz
, phys_addr_t src
, size_t src_sz
,
379 phys_addr_t dest
, size_t dest_sz
)
382 struct qcom_scm_desc desc
= {0};
383 struct arm_smccc_res res
;
385 desc
.args
[0] = mem_region
;
386 desc
.args
[1] = mem_sz
;
388 desc
.args
[3] = src_sz
;
390 desc
.args
[5] = dest_sz
;
393 desc
.arginfo
= QCOM_SCM_ARGS(7, QCOM_SCM_RO
, QCOM_SCM_VAL
,
394 QCOM_SCM_RO
, QCOM_SCM_VAL
, QCOM_SCM_RO
,
395 QCOM_SCM_VAL
, QCOM_SCM_VAL
);
397 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_MP
,
398 QCOM_MEM_PROT_ASSIGN_ID
,
401 return ret
? : res
.a1
;
404 int __qcom_scm_restore_sec_cfg(struct device
*dev
, u32 device_id
, u32 spare
)
406 struct qcom_scm_desc desc
= {0};
407 struct arm_smccc_res res
;
410 desc
.args
[0] = device_id
;
411 desc
.args
[1] = spare
;
412 desc
.arginfo
= QCOM_SCM_ARGS(2);
414 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_MP
, QCOM_SCM_RESTORE_SEC_CFG
,
417 return ret
? : res
.a1
;
420 int __qcom_scm_iommu_secure_ptbl_size(struct device
*dev
, u32 spare
,
423 struct qcom_scm_desc desc
= {0};
424 struct arm_smccc_res res
;
427 desc
.args
[0] = spare
;
428 desc
.arginfo
= QCOM_SCM_ARGS(1);
430 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_MP
,
431 QCOM_SCM_IOMMU_SECURE_PTBL_SIZE
, &desc
, &res
);
436 return ret
? : res
.a2
;
439 int __qcom_scm_iommu_secure_ptbl_init(struct device
*dev
, u64 addr
, u32 size
,
442 struct qcom_scm_desc desc
= {0};
443 struct arm_smccc_res res
;
448 desc
.args
[2] = spare
;
449 desc
.arginfo
= QCOM_SCM_ARGS(3, QCOM_SCM_RW
, QCOM_SCM_VAL
,
452 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_MP
,
453 QCOM_SCM_IOMMU_SECURE_PTBL_INIT
, &desc
, &res
);
455 /* the pg table has been initialized already, ignore the error */
462 int __qcom_scm_set_dload_mode(struct device
*dev
, bool enable
)
464 struct qcom_scm_desc desc
= {0};
465 struct arm_smccc_res res
;
467 desc
.args
[0] = QCOM_SCM_SET_DLOAD_MODE
;
468 desc
.args
[1] = enable
? QCOM_SCM_SET_DLOAD_MODE
: 0;
469 desc
.arginfo
= QCOM_SCM_ARGS(2);
471 return qcom_scm_call(dev
, QCOM_SCM_SVC_BOOT
, QCOM_SCM_SET_DLOAD_MODE
,
475 int __qcom_scm_io_readl(struct device
*dev
, phys_addr_t addr
,
478 struct qcom_scm_desc desc
= {0};
479 struct arm_smccc_res res
;
483 desc
.arginfo
= QCOM_SCM_ARGS(1);
485 ret
= qcom_scm_call(dev
, QCOM_SCM_SVC_IO
, QCOM_SCM_IO_READ
,
490 return ret
< 0 ? ret
: 0;
493 int __qcom_scm_io_writel(struct device
*dev
, phys_addr_t addr
, unsigned int val
)
495 struct qcom_scm_desc desc
= {0};
496 struct arm_smccc_res res
;
500 desc
.arginfo
= QCOM_SCM_ARGS(2);
502 return qcom_scm_call(dev
, QCOM_SCM_SVC_IO
, QCOM_SCM_IO_WRITE
,