diff options
Diffstat (limited to 'drivers/firmware/qcom/qcom_scm.h')
-rw-r--r-- | drivers/firmware/qcom/qcom_scm.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h new file mode 100644 index 000000000000..4532907e8489 --- /dev/null +++ b/drivers/firmware/qcom/qcom_scm.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2010-2015,2019 The Linux Foundation. All rights reserved. + */ +#ifndef __QCOM_SCM_INT_H +#define __QCOM_SCM_INT_H + +struct device; + +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 + +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) | \ + (((c) & 0x3) << 8) | \ + (((d) & 0x3) << 10) | \ + (((e) & 0x3) << 12) | \ + (((f) & 0x3) << 14) | \ + (((g) & 0x3) << 16) | \ + (((h) & 0x3) << 18) | \ + (((i) & 0x3) << 20) | \ + (((j) & 0x3) << 22) | \ + ((num) & 0xf)) + +#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + + +/** + * struct qcom_scm_desc + * @arginfo: Metadata describing the arguments in args[] + * @args: The array of arguments for the secure syscall + */ +struct qcom_scm_desc { + u32 svc; + u32 cmd; + u32 arginfo; + u64 args[MAX_QCOM_SCM_ARGS]; + u32 owner; +}; + +/** + * struct qcom_scm_res + * @result: The values returned by the secure syscall + */ +struct qcom_scm_res { + u64 result[MAX_QCOM_SCM_RETS]; +}; + +int qcom_scm_wait_for_wq_completion(u32 wq_ctx); +int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending); + +#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) +int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, + enum qcom_scm_convention qcom_convention, + struct qcom_scm_res *res, bool atomic); +#define scm_smc_call(dev, desc, res, atomic) \ + __scm_smc_call((dev), (desc), qcom_scm_convention, (res), (atomic)) + +#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) +int scm_legacy_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res); +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 +#define QCOM_SCM_BOOT_TERMINATE_PC 0x02 +#define QCOM_SCM_BOOT_SDI_CONFIG 0x09 +#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 +#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11 +#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a +#define QCOM_SCM_FLUSH_FLAG_MASK 0x3 +#define QCOM_SCM_BOOT_MAX_CPUS 4 +#define QCOM_SCM_BOOT_MC_FLAG_AARCH64 BIT(0) +#define QCOM_SCM_BOOT_MC_FLAG_COLDBOOT BIT(1) +#define QCOM_SCM_BOOT_MC_FLAG_WARMBOOT BIT(2) + +#define QCOM_SCM_SVC_PIL 0x02 +#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x01 +#define QCOM_SCM_PIL_PAS_MEM_SETUP 0x02 +#define QCOM_SCM_PIL_PAS_AUTH_AND_RESET 0x05 +#define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06 +#define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07 +#define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a + +#define QCOM_SCM_SVC_IO 0x05 +#define QCOM_SCM_IO_READ 0x01 +#define QCOM_SCM_IO_WRITE 0x02 + +#define QCOM_SCM_SVC_INFO 0x06 +#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01 + +#define QCOM_SCM_SVC_MP 0x0c +#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 +#define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05 +#define QCOM_SCM_MP_VIDEO_VAR 0x08 +#define QCOM_SCM_MP_ASSIGN 0x16 + +#define QCOM_SCM_SVC_OCMEM 0x0f +#define QCOM_SCM_OCMEM_LOCK_CMD 0x01 +#define QCOM_SCM_OCMEM_UNLOCK_CMD 0x02 + +#define QCOM_SCM_SVC_ES 0x10 /* Enterprise Security */ +#define QCOM_SCM_ES_INVALIDATE_ICE_KEY 0x03 +#define QCOM_SCM_ES_CONFIG_SET_ICE_KEY 0x04 + +#define QCOM_SCM_SVC_HDCP 0x11 +#define QCOM_SCM_HDCP_INVOKE 0x01 + +#define QCOM_SCM_SVC_LMH 0x13 +#define QCOM_SCM_LMH_LIMIT_PROFILE_CHANGE 0x01 +#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10 + +#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 +#define QCOM_SCM_SMMU_PT_FORMAT 0x01 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 + +#define QCOM_SCM_SVC_WAITQ 0x24 +#define QCOM_SCM_WAITQ_RESUME 0x02 +#define QCOM_SCM_WAITQ_GET_WQ_CTX 0x03 + +/* common error codes */ +#define QCOM_SCM_V2_EBUSY -12 +#define QCOM_SCM_ENOMEM -5 +#define QCOM_SCM_EOPNOTSUPP -4 +#define QCOM_SCM_EINVAL_ADDR -3 +#define QCOM_SCM_EINVAL_ARG -2 +#define QCOM_SCM_ERROR -1 +#define QCOM_SCM_INTERRUPTED 1 +#define QCOM_SCM_WAITQ_SLEEP 2 + +static inline int qcom_scm_remap_error(int err) +{ + switch (err) { + case QCOM_SCM_ERROR: + return -EIO; + case QCOM_SCM_EINVAL_ADDR: + case QCOM_SCM_EINVAL_ARG: + return -EINVAL; + case QCOM_SCM_EOPNOTSUPP: + return -EOPNOTSUPP; + case QCOM_SCM_ENOMEM: + return -ENOMEM; + case QCOM_SCM_V2_EBUSY: + return -EBUSY; + } + return -EINVAL; +} + +#endif |