msm_cvp_synx.c 5.5 KB

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