msm_cvp_synx.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include "msm_cvp_common.h"
  6. #include "cvp_hfi_api.h"
  7. #include "msm_cvp_debug.h"
  8. #include "msm_cvp_core.h"
  9. #include "msm_cvp_dsp.h"
  10. #ifdef CVP_SYNX_ENABLED
  11. int cvp_sess_init_synx(struct msm_cvp_inst *inst)
  12. {
  13. struct synx_initialization_params params;
  14. params.name = "cvp-kernel-client";
  15. if (synx_initialize(&inst->synx_session_id, &params)) {
  16. dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__);
  17. return -EFAULT;
  18. }
  19. return 0;
  20. }
  21. int cvp_sess_deinit_synx(struct msm_cvp_inst *inst)
  22. {
  23. if (!inst) {
  24. dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n");
  25. return -EINVAL;
  26. }
  27. synx_uninitialize(inst->synx_session_id);
  28. return 0;
  29. }
  30. void cvp_dump_fence_queue(struct msm_cvp_inst *inst)
  31. {
  32. struct cvp_fence_queue *q;
  33. struct cvp_fence_command *f;
  34. struct synx_session ssid;
  35. int i;
  36. q = &inst->fence_cmd_queue;
  37. ssid = inst->synx_session_id;
  38. mutex_lock(&q->lock);
  39. dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n",
  40. hash32_ptr(inst->session), q->mode, ssid.client_id);
  41. dprintk(CVP_WARN, "fence cmdq wait list:\n");
  42. list_for_each_entry(f, &q->wait_list, list) {
  43. dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
  44. for (i = 0; i < f->output_index; i++)
  45. dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
  46. i, f->synx[i],
  47. synx_get_status(ssid, f->synx[i]));
  48. }
  49. dprintk(CVP_WARN, "fence cmdq schedule list:\n");
  50. list_for_each_entry(f, &q->sched_list, list) {
  51. dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
  52. for (i = 0; i < f->output_index; i++)
  53. dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
  54. i, f->synx[i],
  55. synx_get_status(ssid, f->synx[i]));
  56. }
  57. mutex_unlock(&q->lock);
  58. }
  59. int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc,
  60. u32 *fence)
  61. {
  62. int rc = 0;
  63. int i;
  64. struct cvp_fence_type *fs;
  65. struct synx_import_params params;
  66. s32 h_synx;
  67. struct synx_session ssid;
  68. if (fc->signature != 0xFEEDFACE) {
  69. dprintk(CVP_ERR, "%s Deprecated synx path\n", __func__);
  70. return -EINVAL;
  71. }
  72. fs = (struct cvp_fence_type *)fence;
  73. ssid = inst->synx_session_id;
  74. for (i = 0; i < fc->num_fences; ++i) {
  75. h_synx = fs[i].h_synx;
  76. if (h_synx) {
  77. params.h_synx = h_synx;
  78. params.secure_key = fs[i].secure_key;
  79. params.new_h_synx = &fc->synx[i];
  80. rc = synx_import(ssid, &params);
  81. if (rc) {
  82. dprintk(CVP_ERR,
  83. "%s: %d synx_import failed\n",
  84. __func__, h_synx);
  85. return rc;
  86. }
  87. }
  88. }
  89. return 0;
  90. }
  91. int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc)
  92. {
  93. int rc = 0;
  94. int i;
  95. s32 h_synx;
  96. struct synx_session ssid;
  97. if (fc->signature != 0xFEEDFACE) {
  98. dprintk(CVP_ERR, "%s deprecated synx_path\n", __func__);
  99. return -EINVAL;
  100. }
  101. ssid = inst->synx_session_id;
  102. for (i = 0; i < fc->num_fences; ++i) {
  103. h_synx = fc->synx[i];
  104. if (h_synx) {
  105. rc = synx_release(ssid, h_synx);
  106. if (rc)
  107. dprintk(CVP_ERR,
  108. "%s: synx_release %d, %d failed\n",
  109. __func__, h_synx, i);
  110. }
  111. }
  112. return rc;
  113. }
  114. static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst,
  115. enum cvp_synx_type type,
  116. struct cvp_fence_command *fc,
  117. int synx_state)
  118. {
  119. int rc = 0;
  120. int i;
  121. int h_synx;
  122. struct synx_session ssid;
  123. int start = 0, end = 0;
  124. ssid = inst->synx_session_id;
  125. if (type == CVP_INPUT_SYNX) {
  126. start = 0;
  127. end = fc->output_index;
  128. } else if (type == CVP_OUTPUT_SYNX) {
  129. start = fc->output_index;
  130. end = fc->num_fences;
  131. } else {
  132. dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__);
  133. return -EINVAL;
  134. }
  135. for (i = start; i < end; ++i) {
  136. h_synx = fc->synx[i];
  137. if (h_synx) {
  138. rc = synx_signal(ssid, h_synx, synx_state);
  139. dprintk(CVP_SYNX, "Cancel synx %d session %llx\n",
  140. h_synx, inst);
  141. if (rc)
  142. dprintk(CVP_ERR,
  143. "%s: synx_signal %d %d %d failed\n",
  144. __func__, h_synx, i, synx_state);
  145. }
  146. }
  147. return rc;
  148. }
  149. int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  150. struct cvp_fence_command *fc, int synx_state)
  151. {
  152. if (fc->signature != 0xFEEDFACE) {
  153. dprintk(CVP_ERR, "%s deprecated synx path\n", __func__);
  154. return -EINVAL;
  155. }
  156. return cvp_cancel_synx_impl(inst, type, fc, synx_state);
  157. }
  158. static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx,
  159. u32 *synx_state)
  160. {
  161. int i = 0, rc = 0;
  162. unsigned long timeout_ms = 2000;
  163. int h_synx;
  164. while (i < num_synx) {
  165. h_synx = synx[i];
  166. if (h_synx) {
  167. rc = synx_wait(ssid, h_synx, timeout_ms);
  168. if (rc) {
  169. *synx_state = synx_get_status(ssid, h_synx);
  170. if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) {
  171. dprintk(CVP_SYNX,
  172. "%s: synx_wait %d cancel %d state %d\n",
  173. current->comm, i, rc, *synx_state);
  174. } else {
  175. dprintk(CVP_ERR,
  176. "%s: synx_wait %d failed %d state %d\n",
  177. current->comm, i, rc, *synx_state);
  178. *synx_state = SYNX_STATE_SIGNALED_ERROR;
  179. }
  180. return rc;
  181. }
  182. dprintk(CVP_SYNX, "Wait synx %d returned succes\n",
  183. h_synx);
  184. }
  185. ++i;
  186. }
  187. return rc;
  188. }
  189. static int cvp_signal_synx(struct synx_session ssid, u32 *synx, u32 num_synx,
  190. u32 synx_state)
  191. {
  192. int i = 0, rc = 0;
  193. int h_synx;
  194. while (i < num_synx) {
  195. h_synx = synx[i];
  196. if (h_synx) {
  197. rc = synx_signal(ssid, h_synx, synx_state);
  198. if (rc) {
  199. dprintk(CVP_ERR,
  200. "%s: synx_signal %d %d failed\n",
  201. current->comm, h_synx, i);
  202. synx_state = SYNX_STATE_SIGNALED_ERROR;
  203. }
  204. dprintk(CVP_SYNX, "Signaled synx %d\n", h_synx);
  205. }
  206. ++i;
  207. }
  208. return rc;
  209. }
  210. int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  211. struct cvp_fence_command *fc, u32 *synx_state)
  212. {
  213. struct synx_session ssid;
  214. ssid = inst->synx_session_id;
  215. if (fc->signature != 0xFEEDFACE) {
  216. dprintk(CVP_ERR, "%s deprecated synx, type %d\n", __func__);
  217. return -EINVAL;
  218. }
  219. if (type == CVP_INPUT_SYNX) {
  220. return cvp_wait_synx(ssid, fc->synx, fc->output_index,
  221. synx_state);
  222. } else if (type == CVP_OUTPUT_SYNX) {
  223. return cvp_signal_synx(ssid, &fc->synx[fc->output_index],
  224. (fc->num_fences - fc->output_index),
  225. *synx_state);
  226. } else {
  227. dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__);
  228. return -EINVAL;
  229. }
  230. }
  231. #endif