Loading drivers/firmware/qcom_scm-64.c +120 −74 Original line number Diff line number Diff line Loading @@ -46,8 +46,11 @@ enum qcom_scm_arg_types { * @res: The values returned by the secure syscall */ struct qcom_scm_desc { u32 svc; u32 cmd; u32 arginfo; u64 args[MAX_QCOM_SCM_ARGS]; u32 owner; }; static u64 qcom_smccc_convention = -1; Loading @@ -62,14 +65,16 @@ static DEFINE_MUTEX(qcom_scm_lock); #define SMCCC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SMCCC_N_REG_ARGS + 1) static void __qcom_scm_call_do_quirk(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, u32 type) struct arm_smccc_res *res, u64 x5, u32 type) { u64 cmd; struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention, ARM_SMCCC_OWNER_SIP, fn_id); cmd = ARM_SMCCC_CALL_VAL( type, qcom_smccc_convention, desc->owner, SMCCC_FUNCNUM(desc->svc, desc->cmd)); quirk.state.a6 = 0; Loading @@ -85,22 +90,19 @@ static void __qcom_scm_call_do_quirk(const struct qcom_scm_desc *desc, } static void qcom_scm_call_do_smccc(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, bool atomic) struct arm_smccc_res *res, u64 x5, bool atomic) { int retry_count = 0; if (atomic) { __qcom_scm_call_do_quirk(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL); __qcom_scm_call_do_quirk(desc, res, x5, ARM_SMCCC_FAST_CALL); return; } do { mutex_lock(&qcom_scm_lock); __qcom_scm_call_do_quirk(desc, res, fn_id, x5, ARM_SMCCC_STD_CALL); __qcom_scm_call_do_quirk(desc, res, x5, ARM_SMCCC_STD_CALL); mutex_unlock(&qcom_scm_lock); Loading @@ -112,13 +114,12 @@ static void qcom_scm_call_do_smccc(const struct qcom_scm_desc *desc, } while (res->a0 == QCOM_SCM_V2_EBUSY); } static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, static int ___qcom_scm_call_smccc(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; u32 fn_id = SMCCC_FUNCNUM(svc_id, cmd_id); u64 x5 = desc->args[SMCCC_FIRST_EXT_IDX]; dma_addr_t args_phys = 0; void *args_virt = NULL; Loading Loading @@ -157,7 +158,7 @@ static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, x5 = args_phys; } qcom_scm_call_do_smccc(desc, res, fn_id, x5, atomic); qcom_scm_call_do_smccc(desc, res, x5, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); Loading @@ -180,12 +181,11 @@ static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This should *only* be called in pre-emptible context. */ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, const struct qcom_scm_desc *desc, static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { might_sleep(); return ___qcom_scm_call_smccc(dev, svc_id, cmd_id, desc, res, false); return ___qcom_scm_call_smccc(dev, desc, res, false); } /** Loading @@ -199,11 +199,11 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This can be called in atomic context. */ static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id, static int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { return ___qcom_scm_call_smccc(dev, svc_id, cmd_id, desc, res, true); return ___qcom_scm_call_smccc(dev, desc, res, true); } /** Loading Loading @@ -248,7 +248,11 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -256,39 +260,41 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) desc.args[1] = id; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, &desc, &res); return qcom_scm_call(dev, &desc, &res); } bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_IS_SUPPORTED, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? false : !!res.a1; } Loading @@ -297,15 +303,18 @@ 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 qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_INIT_IMAGE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -314,7 +323,11 @@ 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 qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = peripheral; Loading @@ -322,8 +335,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, desc.args[2] = size; desc.arginfo = QCOM_SCM_ARGS(3); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MEM_SETUP, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -331,15 +343,17 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_AUTH_AND_RESET, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -347,21 +361,28 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_SHUTDOWN, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -369,8 +390,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) desc.args[1] = 0; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -378,15 +398,18 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_IO, .cmd = QCOM_SCM_IO_READ, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); if (ret >= 0) *val = res.a1; Loading @@ -395,36 +418,46 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_IO, .cmd = QCOM_SCM_IO_WRITE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = addr; desc.args[1] = val; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, &desc, &res); return qcom_scm_call(dev, &desc, &res); } int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_INFO, .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.arginfo = QCOM_SCM_ARGS(1); desc.args[0] = SMCCC_FUNCNUM(svc_id, cmd_id) | (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -432,8 +465,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) desc.args[1] = spare; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -441,15 +473,18 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; desc.args[0] = spare; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); if (size) *size = res.a1; Loading @@ -460,7 +495,11 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -470,8 +509,7 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); /* the pg table has been initialized already, ignore the error */ if (ret == -EPERM) Loading @@ -485,7 +523,11 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, phys_addr_t dest, size_t dest_sz) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_ASSIGN, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = mem_region; Loading @@ -500,9 +542,7 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_ASSIGN, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -511,7 +551,11 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_HDCP, .cmd = QCOM_SCM_HDCP_INVOKE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) Loading @@ -529,8 +573,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, desc.args[9] = req[4].val; desc.arginfo = QCOM_SCM_ARGS(10); ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); *resp = res.a1; return ret; Loading @@ -538,15 +581,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_SMMU_PROGRAM, .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; desc.args[1] = en; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM, QCOM_SCM_SMMU_CONFIG_ERRATA1, &desc, &res); return qcom_scm_call_atomic(dev, &desc, &res); } void __qcom_scm_init(void) Loading Loading
drivers/firmware/qcom_scm-64.c +120 −74 Original line number Diff line number Diff line Loading @@ -46,8 +46,11 @@ enum qcom_scm_arg_types { * @res: The values returned by the secure syscall */ struct qcom_scm_desc { u32 svc; u32 cmd; u32 arginfo; u64 args[MAX_QCOM_SCM_ARGS]; u32 owner; }; static u64 qcom_smccc_convention = -1; Loading @@ -62,14 +65,16 @@ static DEFINE_MUTEX(qcom_scm_lock); #define SMCCC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SMCCC_N_REG_ARGS + 1) static void __qcom_scm_call_do_quirk(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, u32 type) struct arm_smccc_res *res, u64 x5, u32 type) { u64 cmd; struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention, ARM_SMCCC_OWNER_SIP, fn_id); cmd = ARM_SMCCC_CALL_VAL( type, qcom_smccc_convention, desc->owner, SMCCC_FUNCNUM(desc->svc, desc->cmd)); quirk.state.a6 = 0; Loading @@ -85,22 +90,19 @@ static void __qcom_scm_call_do_quirk(const struct qcom_scm_desc *desc, } static void qcom_scm_call_do_smccc(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, bool atomic) struct arm_smccc_res *res, u64 x5, bool atomic) { int retry_count = 0; if (atomic) { __qcom_scm_call_do_quirk(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL); __qcom_scm_call_do_quirk(desc, res, x5, ARM_SMCCC_FAST_CALL); return; } do { mutex_lock(&qcom_scm_lock); __qcom_scm_call_do_quirk(desc, res, fn_id, x5, ARM_SMCCC_STD_CALL); __qcom_scm_call_do_quirk(desc, res, x5, ARM_SMCCC_STD_CALL); mutex_unlock(&qcom_scm_lock); Loading @@ -112,13 +114,12 @@ static void qcom_scm_call_do_smccc(const struct qcom_scm_desc *desc, } while (res->a0 == QCOM_SCM_V2_EBUSY); } static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, static int ___qcom_scm_call_smccc(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; u32 fn_id = SMCCC_FUNCNUM(svc_id, cmd_id); u64 x5 = desc->args[SMCCC_FIRST_EXT_IDX]; dma_addr_t args_phys = 0; void *args_virt = NULL; Loading Loading @@ -157,7 +158,7 @@ static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, x5 = args_phys; } qcom_scm_call_do_smccc(desc, res, fn_id, x5, atomic); qcom_scm_call_do_smccc(desc, res, x5, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); Loading @@ -180,12 +181,11 @@ static int ___qcom_scm_call_smccc(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This should *only* be called in pre-emptible context. */ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, const struct qcom_scm_desc *desc, static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { might_sleep(); return ___qcom_scm_call_smccc(dev, svc_id, cmd_id, desc, res, false); return ___qcom_scm_call_smccc(dev, desc, res, false); } /** Loading @@ -199,11 +199,11 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This can be called in atomic context. */ static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id, static int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { return ___qcom_scm_call_smccc(dev, svc_id, cmd_id, desc, res, true); return ___qcom_scm_call_smccc(dev, desc, res, true); } /** Loading Loading @@ -248,7 +248,11 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -256,39 +260,41 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) desc.args[1] = id; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, &desc, &res); return qcom_scm_call(dev, &desc, &res); } bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_IS_SUPPORTED, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? false : !!res.a1; } Loading @@ -297,15 +303,18 @@ 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 qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_INIT_IMAGE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -314,7 +323,11 @@ 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 qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = peripheral; Loading @@ -322,8 +335,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, desc.args[2] = size; desc.arginfo = QCOM_SCM_ARGS(3); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MEM_SETUP, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -331,15 +343,17 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_AUTH_AND_RESET, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -347,21 +361,28 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, .owner = ARM_SMCCC_OWNER_SIP, }; 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_PIL_PAS_SHUTDOWN, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_PIL, .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -369,8 +390,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) desc.args[1] = 0; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -378,15 +398,18 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_IO, .cmd = QCOM_SCM_IO_READ, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); if (ret >= 0) *val = res.a1; Loading @@ -395,36 +418,46 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_IO, .cmd = QCOM_SCM_IO_WRITE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = addr; desc.args[1] = val; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, &desc, &res); return qcom_scm_call(dev, &desc, &res); } int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_INFO, .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.arginfo = QCOM_SCM_ARGS(1); desc.args[0] = SMCCC_FUNCNUM(svc_id, cmd_id) | (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -432,8 +465,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) desc.args[1] = spare; desc.arginfo = QCOM_SCM_ARGS(2); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -441,15 +473,18 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; desc.args[0] = spare; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); if (size) *size = res.a1; Loading @@ -460,7 +495,11 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; int ret; Loading @@ -470,8 +509,7 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); /* the pg table has been initialized already, ignore the error */ if (ret == -EPERM) Loading @@ -485,7 +523,11 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, phys_addr_t dest, size_t dest_sz) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = QCOM_SCM_MP_ASSIGN, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = mem_region; Loading @@ -500,9 +542,7 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_ASSIGN, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } Loading @@ -511,7 +551,11 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { int ret; struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_HDCP, .cmd = QCOM_SCM_HDCP_INVOKE, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) Loading @@ -529,8 +573,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, desc.args[9] = req[4].val; desc.arginfo = QCOM_SCM_ARGS(10); ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, &desc, &res); ret = qcom_scm_call(dev, &desc, &res); *resp = res.a1; return ret; Loading @@ -538,15 +581,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) { struct qcom_scm_desc desc = {0}; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_SMMU_PROGRAM, .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, .owner = ARM_SMCCC_OWNER_SIP, }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; desc.args[1] = en; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM, QCOM_SCM_SMMU_CONFIG_ERRATA1, &desc, &res); return qcom_scm_call_atomic(dev, &desc, &res); } void __qcom_scm_init(void) Loading