qcom_scm-smc.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
  3. */
  4. #include <linux/cleanup.h>
  5. #include <linux/io.h>
  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/firmware/qcom/qcom_scm.h>
  12. #include <linux/firmware/qcom/qcom_tzmem.h>
  13. #include <linux/arm-smccc.h>
  14. #include <linux/dma-mapping.h>
  15. #include "qcom_scm.h"
  16. /**
  17. * struct arm_smccc_args
  18. * @args: The array of values used in registers in smc instruction
  19. */
  20. struct arm_smccc_args {
  21. unsigned long args[8];
  22. };
  23. static DEFINE_MUTEX(qcom_scm_lock);
  24. #define QCOM_SCM_EBUSY_WAIT_MS 30
  25. #define QCOM_SCM_EBUSY_MAX_RETRY 20
  26. #define SCM_SMC_N_REG_ARGS 4
  27. #define SCM_SMC_FIRST_EXT_IDX (SCM_SMC_N_REG_ARGS - 1)
  28. #define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1)
  29. #define SCM_SMC_FIRST_REG_IDX 2
  30. #define SCM_SMC_LAST_REG_IDX (SCM_SMC_FIRST_REG_IDX + SCM_SMC_N_REG_ARGS - 1)
  31. static void __scm_smc_do_quirk(const struct arm_smccc_args *smc,
  32. struct arm_smccc_res *res)
  33. {
  34. unsigned long a0 = smc->args[0];
  35. struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 };
  36. quirk.state.a6 = 0;
  37. do {
  38. arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2],
  39. smc->args[3], smc->args[4], smc->args[5],
  40. quirk.state.a6, smc->args[7], res, &quirk);
  41. if (res->a0 == QCOM_SCM_INTERRUPTED)
  42. a0 = res->a0;
  43. } while (res->a0 == QCOM_SCM_INTERRUPTED);
  44. }
  45. static void fill_wq_resume_args(struct arm_smccc_args *resume, u32 smc_call_ctx)
  46. {
  47. memset(resume->args, 0, sizeof(resume->args[0]) * ARRAY_SIZE(resume->args));
  48. resume->args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
  49. ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP,
  50. SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_RESUME));
  51. resume->args[1] = QCOM_SCM_ARGS(1);
  52. resume->args[2] = smc_call_ctx;
  53. }
  54. int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending)
  55. {
  56. int ret;
  57. struct arm_smccc_res get_wq_res;
  58. struct arm_smccc_args get_wq_ctx = {0};
  59. get_wq_ctx.args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,
  60. ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP,
  61. SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_GET_WQ_CTX));
  62. /* Guaranteed to return only success or error, no WAITQ_* */
  63. __scm_smc_do_quirk(&get_wq_ctx, &get_wq_res);
  64. ret = get_wq_res.a0;
  65. if (ret)
  66. return ret;
  67. *wq_ctx = get_wq_res.a1;
  68. *flags = get_wq_res.a2;
  69. *more_pending = get_wq_res.a3;
  70. return 0;
  71. }
  72. static int __scm_smc_do_quirk_handle_waitq(struct device *dev, struct arm_smccc_args *waitq,
  73. struct arm_smccc_res *res)
  74. {
  75. int ret;
  76. u32 wq_ctx, smc_call_ctx;
  77. struct arm_smccc_args resume;
  78. struct arm_smccc_args *smc = waitq;
  79. do {
  80. __scm_smc_do_quirk(smc, res);
  81. if (res->a0 == QCOM_SCM_WAITQ_SLEEP) {
  82. wq_ctx = res->a1;
  83. smc_call_ctx = res->a2;
  84. ret = qcom_scm_wait_for_wq_completion(wq_ctx);
  85. if (ret)
  86. return ret;
  87. fill_wq_resume_args(&resume, smc_call_ctx);
  88. smc = &resume;
  89. }
  90. } while (res->a0 == QCOM_SCM_WAITQ_SLEEP);
  91. return 0;
  92. }
  93. static int __scm_smc_do(struct device *dev, struct arm_smccc_args *smc,
  94. struct arm_smccc_res *res, bool atomic)
  95. {
  96. int ret, retry_count = 0;
  97. if (atomic) {
  98. __scm_smc_do_quirk(smc, res);
  99. return 0;
  100. }
  101. do {
  102. mutex_lock(&qcom_scm_lock);
  103. ret = __scm_smc_do_quirk_handle_waitq(dev, smc, res);
  104. mutex_unlock(&qcom_scm_lock);
  105. if (ret)
  106. return ret;
  107. if (res->a0 == QCOM_SCM_V2_EBUSY) {
  108. if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
  109. break;
  110. msleep(QCOM_SCM_EBUSY_WAIT_MS);
  111. }
  112. } while (res->a0 == QCOM_SCM_V2_EBUSY);
  113. return 0;
  114. }
  115. int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
  116. enum qcom_scm_convention qcom_convention,
  117. struct qcom_scm_res *res, bool atomic)
  118. {
  119. struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
  120. int arglen = desc->arginfo & 0xf;
  121. int i, ret;
  122. void *args_virt __free(qcom_tzmem) = NULL;
  123. gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
  124. u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
  125. u32 qcom_smccc_convention = (qcom_convention == SMC_CONVENTION_ARM_32) ?
  126. ARM_SMCCC_SMC_32 : ARM_SMCCC_SMC_64;
  127. struct arm_smccc_res smc_res;
  128. struct arm_smccc_args smc = {0};
  129. smc.args[0] = ARM_SMCCC_CALL_VAL(
  130. smccc_call_type,
  131. qcom_smccc_convention,
  132. desc->owner,
  133. SCM_SMC_FNID(desc->svc, desc->cmd));
  134. smc.args[1] = desc->arginfo;
  135. for (i = 0; i < SCM_SMC_N_REG_ARGS; i++)
  136. smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
  137. if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
  138. if (!mempool)
  139. return -EINVAL;
  140. args_virt = qcom_tzmem_alloc(mempool,
  141. SCM_SMC_N_EXT_ARGS * sizeof(u64),
  142. flag);
  143. if (!args_virt)
  144. return -ENOMEM;
  145. if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
  146. __le32 *args = args_virt;
  147. for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
  148. args[i] = cpu_to_le32(desc->args[i +
  149. SCM_SMC_FIRST_EXT_IDX]);
  150. } else {
  151. __le64 *args = args_virt;
  152. for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
  153. args[i] = cpu_to_le64(desc->args[i +
  154. SCM_SMC_FIRST_EXT_IDX]);
  155. }
  156. smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt);
  157. }
  158. ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
  159. if (ret)
  160. return ret;
  161. if (res) {
  162. res->result[0] = smc_res.a1;
  163. res->result[1] = smc_res.a2;
  164. res->result[2] = smc_res.a3;
  165. }
  166. return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0;
  167. }