msm_cvp_synx.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. #include "cvp_comm_def.h"
  11. #ifdef CVP_SYNX_ENABLED
  12. static int cvp_sess_init_synx_v2(struct msm_cvp_inst *inst)
  13. {
  14. struct synx_initialization_params params = { 0 };
  15. params.name = "cvp-kernel-client";
  16. params.id = SYNX_CLIENT_EVA_CTX0;
  17. inst->synx_session_id = synx_initialize(&params);
  18. if (IS_ERR_OR_NULL(&inst->synx_session_id)) {
  19. dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__);
  20. return -EFAULT;
  21. }
  22. return 0;
  23. }
  24. static int cvp_sess_deinit_synx_v2(struct msm_cvp_inst *inst)
  25. {
  26. if (!inst) {
  27. dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n");
  28. return -EINVAL;
  29. }
  30. synx_uninitialize(inst->synx_session_id);
  31. return 0;
  32. }
  33. static void cvp_dump_fence_queue_v2(struct msm_cvp_inst *inst)
  34. {
  35. struct cvp_fence_queue *q;
  36. struct cvp_fence_command *f;
  37. struct synx_session *ssid;
  38. int i;
  39. q = &inst->fence_cmd_queue;
  40. ssid = inst->synx_session_id;
  41. mutex_lock(&q->lock);
  42. dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %pK\n",
  43. hash32_ptr(inst->session), q->mode, ssid);
  44. dprintk(CVP_WARN, "fence cmdq wait list:\n");
  45. list_for_each_entry(f, &q->wait_list, list) {
  46. dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
  47. for (i = 0; i < f->output_index; i++)
  48. dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
  49. i, f->synx[i],
  50. synx_get_status(ssid, f->synx[i]));
  51. }
  52. dprintk(CVP_WARN, "fence cmdq schedule list:\n");
  53. list_for_each_entry(f, &q->sched_list, list) {
  54. dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
  55. for (i = 0; i < f->output_index; i++)
  56. dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
  57. i, f->synx[i],
  58. synx_get_status(ssid, f->synx[i]));
  59. }
  60. mutex_unlock(&q->lock);
  61. }
  62. static int cvp_import_synx_v2(struct msm_cvp_inst *inst,
  63. struct cvp_fence_command *fc,
  64. u32 *fence)
  65. {
  66. int rc = 0, rr = 0;
  67. int i;
  68. struct eva_kmd_fence *fs;
  69. struct synx_import_params params = {0};
  70. u32 h_synx;
  71. struct synx_session *ssid;
  72. fs = (struct eva_kmd_fence *)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.type = SYNX_IMPORT_INDV_PARAMS;
  78. params.indv.fence = &h_synx;
  79. params.indv.flags = SYNX_IMPORT_SYNX_FENCE
  80. | SYNX_IMPORT_LOCAL_FENCE;
  81. params.indv.new_h_synx = &fc->synx[i];
  82. rc = synx_import(ssid, &params);
  83. if (rc) {
  84. dprintk(CVP_ERR,
  85. "%s: %u synx_import failed\n",
  86. __func__, h_synx);
  87. rr = rc;
  88. }
  89. }
  90. }
  91. return rr;
  92. }
  93. static int cvp_release_synx_v2(struct msm_cvp_inst *inst,
  94. struct cvp_fence_command *fc)
  95. {
  96. int rc = 0;
  97. int i;
  98. u32 h_synx;
  99. struct synx_session *ssid;
  100. ssid = inst->synx_session_id;
  101. for (i = 0; i < fc->num_fences; ++i) {
  102. h_synx = fc->synx[i];
  103. if (h_synx) {
  104. rc = synx_release(ssid, h_synx);
  105. if (rc)
  106. dprintk(CVP_ERR,
  107. "%s: synx_release %d, %d failed\n",
  108. __func__, h_synx, i);
  109. }
  110. }
  111. return rc;
  112. }
  113. static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst,
  114. enum cvp_synx_type type,
  115. struct cvp_fence_command *fc,
  116. int synx_state)
  117. {
  118. int rc = 0;
  119. int i;
  120. u32 h_synx;
  121. struct synx_session *ssid;
  122. int start = 0, end = 0;
  123. ssid = inst->synx_session_id;
  124. if (type == CVP_INPUT_SYNX) {
  125. start = 0;
  126. end = fc->output_index;
  127. } else if (type == CVP_OUTPUT_SYNX) {
  128. start = fc->output_index;
  129. end = fc->num_fences;
  130. } else {
  131. dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__);
  132. return -EINVAL;
  133. }
  134. for (i = start; i < end; ++i) {
  135. h_synx = fc->synx[i];
  136. if (h_synx) {
  137. rc = synx_signal(ssid, h_synx, synx_state);
  138. dprintk(CVP_SYNX, "Cancel synx %d session %llx\n",
  139. h_synx, inst);
  140. if (rc)
  141. dprintk(CVP_ERR,
  142. "%s: synx_signal %d %d %d failed\n",
  143. __func__, h_synx, i, synx_state);
  144. }
  145. }
  146. return rc;
  147. }
  148. static int cvp_cancel_synx_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  149. struct cvp_fence_command *fc, int synx_state)
  150. {
  151. return cvp_cancel_synx_impl(inst, type, fc, synx_state);
  152. }
  153. static int cvp_wait_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
  154. u32 *synx_state)
  155. {
  156. int i = 0, rc = 0;
  157. unsigned long timeout_ms = 2000;
  158. u32 h_synx;
  159. while (i < num_synx) {
  160. h_synx = synx[i];
  161. if (h_synx) {
  162. rc = synx_wait(ssid, h_synx, timeout_ms);
  163. if (rc) {
  164. *synx_state = synx_get_status(ssid, h_synx);
  165. if(*synx_state == SYNX_STATE_SIGNALED_SUCCESS)
  166. {
  167. dprintk(CVP_SYNX, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__);
  168. rc=0;
  169. i++;
  170. continue;
  171. }
  172. else if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) {
  173. dprintk(CVP_SYNX,
  174. "%s: synx_wait %d cancel %d state %d\n",
  175. current->comm, i, rc, *synx_state);
  176. } else {
  177. dprintk(CVP_ERR,
  178. "%s: synx_wait %d failed %d state %d\n",
  179. current->comm, i, rc, *synx_state);
  180. *synx_state = SYNX_STATE_SIGNALED_CANCEL;
  181. }
  182. return rc;
  183. } else {
  184. rc = 0; /* SYNX_STATE_SIGNALED_SUCCESS = 2 */
  185. }
  186. dprintk(CVP_SYNX, "Wait synx %u returned succes\n",
  187. h_synx);
  188. }
  189. ++i;
  190. }
  191. return rc;
  192. }
  193. static int cvp_signal_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
  194. u32 synx_state)
  195. {
  196. int i = 0, rc = 0;
  197. u32 h_synx;
  198. while (i < num_synx) {
  199. h_synx = synx[i];
  200. if (h_synx) {
  201. rc = synx_signal(ssid, h_synx, synx_state);
  202. if (rc) {
  203. dprintk(CVP_ERR,
  204. "%s: synx_signal %u %d failed\n",
  205. current->comm, h_synx, i);
  206. synx_state = SYNX_STATE_SIGNALED_CANCEL;
  207. }
  208. dprintk(CVP_SYNX, "Signaled synx %u state %d\n",
  209. h_synx, synx_state);
  210. }
  211. ++i;
  212. }
  213. return rc;
  214. }
  215. static int cvp_synx_ops_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  216. struct cvp_fence_command *fc, u32 *synx_state)
  217. {
  218. struct synx_session *ssid;
  219. if (fc->signature == 0xB0BABABE)
  220. return 0;
  221. ssid = inst->synx_session_id;
  222. if (type == CVP_INPUT_SYNX) {
  223. return cvp_wait_synx(ssid, fc->synx, fc->output_index,
  224. synx_state);
  225. } else if (type == CVP_OUTPUT_SYNX) {
  226. return cvp_signal_synx(ssid, &fc->synx[fc->output_index],
  227. (fc->num_fences - fc->output_index),
  228. *synx_state);
  229. } else {
  230. dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__);
  231. return -EINVAL;
  232. }
  233. }
  234. static struct msm_cvp_synx_ops cvp_synx = {
  235. .cvp_sess_init_synx = cvp_sess_init_synx_v2,
  236. .cvp_sess_deinit_synx = cvp_sess_deinit_synx_v2,
  237. .cvp_release_synx = cvp_release_synx_v2,
  238. .cvp_import_synx = cvp_import_synx_v2,
  239. .cvp_synx_ops = cvp_synx_ops_v2,
  240. .cvp_cancel_synx = cvp_cancel_synx_v2,
  241. .cvp_dump_fence_queue = cvp_dump_fence_queue_v2,
  242. };
  243. #else
  244. static int cvp_sess_init_synx_stub(struct msm_cvp_inst *inst)
  245. {
  246. return 0;
  247. }
  248. static int cvp_sess_deinit_synx_stub(struct msm_cvp_inst *inst)
  249. {
  250. return 0;
  251. }
  252. static int cvp_release_synx_stub(struct msm_cvp_inst *inst,
  253. struct cvp_fence_command *fc)
  254. {
  255. return 0;
  256. }
  257. static int cvp_import_synx_stub(struct msm_cvp_inst *inst,
  258. struct cvp_fence_command *fc,
  259. u32 *fence)
  260. {
  261. return 0;
  262. }
  263. static int cvp_synx_ops_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  264. struct cvp_fence_command *fc, u32 *synx_state)
  265. {
  266. return 0;
  267. }
  268. static int cvp_cancel_synx_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
  269. struct cvp_fence_command *fc, int synx_state)
  270. {
  271. return 0;
  272. }
  273. static void cvp_dump_fence_queue_stub(struct msm_cvp_inst *inst)
  274. {
  275. }
  276. static struct msm_cvp_synx_ops cvp_synx = {
  277. .cvp_sess_init_synx = cvp_sess_init_synx_stub,
  278. .cvp_sess_deinit_synx = cvp_sess_deinit_synx_stub,
  279. .cvp_release_synx = cvp_release_synx_stub,
  280. .cvp_import_synx = cvp_import_synx_stub,
  281. .cvp_synx_ops = cvp_synx_ops_stub,
  282. .cvp_cancel_synx = cvp_cancel_synx_stub,
  283. .cvp_dump_fence_queue = cvp_dump_fence_queue_stub,
  284. };
  285. #endif /* End of CVP_SYNX_ENABLED */
  286. void cvp_synx_ftbl_init(struct msm_cvp_core *core)
  287. {
  288. if (!core)
  289. return;
  290. /* Synx API version check below if needed */
  291. core->synx_ftbl = &cvp_synx;
  292. }