cam_sync_synx.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include "cam_sync_synx.h"
  6. #include "cam_sync_util.h"
  7. extern unsigned long cam_sync_monitor_mask;
  8. /**
  9. * struct cam_synx_obj_row - Synx obj row
  10. */
  11. struct cam_synx_obj_row {
  12. char name[CAM_SYNX_OBJ_NAME_LEN];
  13. uint32_t synx_obj;
  14. enum cam_synx_obj_state state;
  15. cam_sync_callback_for_synx_obj sync_cb;
  16. bool cb_registered_for_sync;
  17. bool sync_signal_synx;
  18. int32_t sync_obj;
  19. };
  20. /**
  21. * struct cam_synx_obj_device - Synx obj device
  22. */
  23. struct cam_synx_obj_device {
  24. struct cam_synx_obj_row rows[CAM_SYNX_MAX_OBJS];
  25. spinlock_t row_spinlocks[CAM_SYNX_MAX_OBJS];
  26. struct synx_session *session_handle;
  27. struct mutex dev_lock;
  28. DECLARE_BITMAP(bitmap, CAM_SYNX_MAX_OBJS);
  29. struct cam_generic_fence_monitor_data **monitor_data;
  30. };
  31. static struct cam_synx_obj_device *g_cam_synx_obj_dev;
  32. static char cam_synx_session_name[64] = "Camera_Generic_Synx_Session";
  33. static inline struct cam_generic_fence_monitor_entry *
  34. __cam_synx_obj_get_monitor_entries(int idx)
  35. {
  36. struct cam_generic_fence_monitor_data *monitor_data;
  37. monitor_data = CAM_GENERIC_MONITOR_GET_DATA(
  38. g_cam_synx_obj_dev->monitor_data, idx);
  39. if (monitor_data->swap_monitor_entries)
  40. return monitor_data->prev_monitor_entries;
  41. else
  42. return monitor_data->monitor_entries;
  43. }
  44. static inline struct cam_generic_fence_monitor_entry *
  45. __cam_synx_obj_get_prev_monitor_entries(int idx)
  46. {
  47. struct cam_generic_fence_monitor_data *monitor_data;
  48. monitor_data = CAM_GENERIC_MONITOR_GET_DATA(
  49. g_cam_synx_obj_dev->monitor_data, idx);
  50. if (monitor_data->swap_monitor_entries)
  51. return monitor_data->monitor_entries;
  52. else
  53. return monitor_data->prev_monitor_entries;
  54. }
  55. static int __cam_synx_obj_map_sync_status_util(uint32_t sync_status,
  56. uint32_t *out_synx_status)
  57. {
  58. if (!out_synx_status)
  59. return -EINVAL;
  60. switch (sync_status) {
  61. case CAM_SYNC_STATE_SIGNALED_SUCCESS:
  62. *out_synx_status = SYNX_STATE_SIGNALED_SUCCESS;
  63. break;
  64. case CAM_SYNC_STATE_SIGNALED_CANCEL:
  65. default:
  66. *out_synx_status = SYNX_STATE_SIGNALED_CANCEL;
  67. break;
  68. }
  69. return 0;
  70. }
  71. static void __cam_synx_obj_save_previous_monitor_data(int32_t row_idx)
  72. {
  73. struct cam_generic_fence_monitor_data *row_mon_data;
  74. struct cam_synx_obj_row *row;
  75. if (!g_cam_synx_obj_dev->monitor_data)
  76. return;
  77. row = &g_cam_synx_obj_dev->rows[row_idx];
  78. row_mon_data = CAM_GENERIC_MONITOR_GET_DATA(
  79. g_cam_synx_obj_dev->monitor_data, row_idx);
  80. /* save current usage details into prev variables */
  81. strscpy(row_mon_data->prev_name, row->name, CAM_SYNX_OBJ_NAME_LEN);
  82. row_mon_data->prev_obj_id = row->synx_obj;
  83. row_mon_data->prev_sync_id = row->sync_obj;
  84. row_mon_data->prev_state = row->state;
  85. row_mon_data->prev_monitor_head = atomic64_read(&row_mon_data->monitor_head);
  86. row_mon_data->swap_monitor_entries = !row_mon_data->swap_monitor_entries;
  87. }
  88. static void __cam_synx_obj_dump_monitor_array(int32_t row_idx)
  89. {
  90. struct cam_generic_fence_monitor_obj_info obj_info;
  91. struct cam_synx_obj_row *row;
  92. if (!g_cam_synx_obj_dev->monitor_data ||
  93. !test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  94. return;
  95. if (!CAM_GENERIC_MONITOR_GET_DATA(g_cam_synx_obj_dev->monitor_data,
  96. row_idx)->prev_obj_id)
  97. return;
  98. row = &g_cam_synx_obj_dev->rows[row_idx];
  99. obj_info.name = row->name;
  100. obj_info.obj_id = row->synx_obj;
  101. obj_info.state = row->state;
  102. obj_info.monitor_data = CAM_GENERIC_MONITOR_GET_DATA(
  103. g_cam_synx_obj_dev->monitor_data, row_idx);
  104. obj_info.fence_type = CAM_GENERIC_FENCE_TYPE_SYNX_OBJ;
  105. obj_info.sync_id = row->sync_obj;
  106. obj_info.monitor_entries =
  107. __cam_synx_obj_get_monitor_entries(row_idx);
  108. obj_info.prev_monitor_entries =
  109. __cam_synx_obj_get_prev_monitor_entries(row_idx);
  110. cam_generic_fence_dump_monitor_array(&obj_info);
  111. }
  112. static int __cam_synx_obj_release(int32_t row_idx)
  113. {
  114. struct cam_synx_obj_row *row = NULL;
  115. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  116. row = &g_cam_synx_obj_dev->rows[row_idx];
  117. if (row->state == CAM_SYNX_OBJ_STATE_ACTIVE) {
  118. CAM_WARN(CAM_SYNX,
  119. "Unsignaled synx obj being released name: %s synx_obj:%d",
  120. row->name, row->synx_obj);
  121. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  122. &cam_sync_monitor_mask))
  123. cam_generic_fence_update_monitor_array(row_idx,
  124. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  125. CAM_FENCE_OP_SIGNAL);
  126. synx_signal(g_cam_synx_obj_dev->session_handle, row->synx_obj,
  127. SYNX_STATE_SIGNALED_CANCEL);
  128. }
  129. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask)) {
  130. /* Update monitor entries & save data before row memset to 0 */
  131. cam_generic_fence_update_monitor_array(row_idx,
  132. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  133. CAM_FENCE_OP_DESTROY);
  134. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ_DUMP, &cam_sync_monitor_mask))
  135. __cam_synx_obj_dump_monitor_array(row_idx);
  136. __cam_synx_obj_save_previous_monitor_data(row_idx);
  137. }
  138. CAM_DBG(CAM_SYNX,
  139. "Releasing synx_obj: %d[%s] row_idx: %u",
  140. row->synx_obj, row->name, row_idx);
  141. synx_release(g_cam_synx_obj_dev->session_handle, row->synx_obj);
  142. /* deinit row */
  143. memset(row, 0, sizeof(struct cam_synx_obj_row));
  144. clear_bit(row_idx, g_cam_synx_obj_dev->bitmap);
  145. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  146. return 0;
  147. }
  148. static int __cam_synx_obj_find_free_idx(uint32_t *idx)
  149. {
  150. int rc = -ENOMEM;
  151. /* Hold lock to obtain free index */
  152. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  153. *idx = find_first_zero_bit(g_cam_synx_obj_dev->bitmap, CAM_SYNX_MAX_OBJS);
  154. if (*idx < CAM_SYNX_MAX_OBJS) {
  155. set_bit(*idx, g_cam_synx_obj_dev->bitmap);
  156. rc = 0;
  157. }
  158. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  159. if (rc)
  160. CAM_ERR(CAM_SYNX, "No free synx idx");
  161. return rc;
  162. }
  163. static void __cam_synx_obj_init_row(uint32_t idx, const char *name,
  164. uint32_t synx_obj)
  165. {
  166. struct cam_synx_obj_row *row;
  167. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  168. row = &g_cam_synx_obj_dev->rows[idx];
  169. row->synx_obj = synx_obj;
  170. row->state = CAM_SYNX_OBJ_STATE_ACTIVE;
  171. strscpy(row->name, name, CAM_SYNX_OBJ_NAME_LEN);
  172. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask)) {
  173. cam_generic_fence_update_monitor_array(idx,
  174. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  175. CAM_FENCE_OP_CREATE);
  176. }
  177. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  178. }
  179. static int __cam_synx_obj_release_row(int32_t row_idx)
  180. {
  181. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  182. CAM_ERR(CAM_SYNX, "synx row idx: %d is invalid",
  183. row_idx);
  184. return -EINVAL;
  185. }
  186. return __cam_synx_obj_release(row_idx);
  187. }
  188. static void __cam_synx_obj_signal_cb(u32 h_synx, int status, void *data)
  189. {
  190. struct cam_synx_obj_signal_sync_obj signal_sync_obj;
  191. struct cam_synx_obj_row *synx_obj_row = NULL;
  192. int32_t idx;
  193. if (!data) {
  194. CAM_ERR(CAM_SYNX,
  195. "Invalid data passed to synx obj : %d callback function.",
  196. synx_obj_row->synx_obj);
  197. return;
  198. }
  199. synx_obj_row = (struct cam_synx_obj_row *)data;
  200. /* If this synx obj is signaled by sync obj, skip cb */
  201. if (synx_obj_row->sync_signal_synx)
  202. return;
  203. if (synx_obj_row->synx_obj != h_synx) {
  204. CAM_ERR(CAM_SYNX,
  205. "Synx obj: %d callback does not match synx obj: %d in sync table.",
  206. h_synx, synx_obj_row->synx_obj);
  207. return;
  208. }
  209. if (synx_obj_row->state == CAM_SYNX_OBJ_STATE_INVALID) {
  210. CAM_ERR(CAM_SYNX,
  211. "Synx obj :%d is in invalid state: %d",
  212. synx_obj_row->synx_obj, synx_obj_row->state);
  213. return;
  214. }
  215. CAM_DBG(CAM_SYNX, "Synx obj: %d signaled, signal sync obj: %d",
  216. synx_obj_row->synx_obj, synx_obj_row->sync_obj);
  217. if ((synx_obj_row->cb_registered_for_sync) && (synx_obj_row->sync_cb)) {
  218. signal_sync_obj.synx_obj = synx_obj_row->synx_obj;
  219. switch (status) {
  220. case SYNX_STATE_SIGNALED_SUCCESS:
  221. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_SUCCESS;
  222. break;
  223. case SYNX_STATE_SIGNALED_CANCEL:
  224. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_CANCEL;
  225. break;
  226. default:
  227. CAM_WARN(CAM_SYNX,
  228. "Synx signal status %d is neither SUCCESS nor CANCEL, custom code?",
  229. status);
  230. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_ERROR;
  231. break;
  232. }
  233. synx_obj_row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  234. synx_obj_row->sync_cb(synx_obj_row->sync_obj, &signal_sync_obj);
  235. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  236. &cam_sync_monitor_mask)) {
  237. cam_synx_obj_find_obj_in_table(synx_obj_row->synx_obj, &idx);
  238. cam_generic_fence_update_monitor_array(idx,
  239. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  240. CAM_FENCE_OP_UNREGISTER_ON_SIGNAL);
  241. }
  242. }
  243. }
  244. int cam_synx_obj_find_obj_in_table(uint32_t synx_obj, int32_t *idx)
  245. {
  246. int i, rc = -EINVAL;
  247. struct cam_synx_obj_row *row = NULL;
  248. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++) {
  249. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  250. row = &g_cam_synx_obj_dev->rows[i];
  251. if ((row->state != CAM_SYNX_OBJ_STATE_INVALID) &&
  252. (row->synx_obj == synx_obj)) {
  253. *idx = i;
  254. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  255. rc = 0;
  256. break;
  257. }
  258. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  259. }
  260. return rc;
  261. }
  262. static int __cam_synx_obj_release_obj(uint32_t synx_obj, int32_t *idx)
  263. {
  264. if (cam_synx_obj_find_obj_in_table(synx_obj, idx)) {
  265. CAM_ERR(CAM_SYNX, "Failed to find synx obj: %d", synx_obj);
  266. return -EINVAL;
  267. }
  268. return __cam_synx_obj_release(*idx);
  269. }
  270. static int __cam_synx_obj_import(const char *name,
  271. struct synx_import_params *params, int32_t *row_idx)
  272. {
  273. int rc = -1;
  274. uint32_t idx;
  275. if (__cam_synx_obj_find_free_idx(&idx))
  276. goto end;
  277. rc = synx_import(g_cam_synx_obj_dev->session_handle, params);
  278. if (rc) {
  279. CAM_ERR(CAM_SYNX, "Synx import failed for fence : %p",
  280. params->indv.fence);
  281. goto free_idx;
  282. }
  283. *row_idx = idx;
  284. __cam_synx_obj_init_row(idx, name, *params->indv.new_h_synx);
  285. CAM_DBG(CAM_SYNX, "Imported synx obj handle: %d[%s] row_idx: %u",
  286. *params->indv.new_h_synx, name, idx);
  287. return rc;
  288. free_idx:
  289. clear_bit(idx, g_cam_synx_obj_dev->bitmap);
  290. end:
  291. return rc;
  292. }
  293. static int __cam_synx_map_generic_flags_to_create(uint32_t generic_flags,
  294. struct synx_create_params *params)
  295. {
  296. if (!params) {
  297. CAM_ERR(CAM_SYNX, "Create parameters missing");
  298. return -EINVAL;
  299. }
  300. /*
  301. * Create Global Always - remove after userspace optimizes and
  302. * determines when global Vs local is needed
  303. */
  304. params->flags |= SYNX_CREATE_GLOBAL_FENCE;
  305. return 0;
  306. }
  307. static int __cam_synx_map_generic_flags_to_import(uint32_t generic_flags,
  308. struct synx_import_indv_params *params)
  309. {
  310. if (!params) {
  311. CAM_ERR(CAM_SYNX, "Import parameters missing");
  312. return -EINVAL;
  313. }
  314. /*
  315. * Create Global Always - remove after userspace optimizes and
  316. * determines when global Vs local is needed
  317. */
  318. params->flags |= SYNX_IMPORT_GLOBAL_FENCE;
  319. return 0;
  320. }
  321. int cam_synx_obj_create(const char *name, uint32_t flags, uint32_t *synx_obj,
  322. int32_t *row_idx)
  323. {
  324. int rc = -1;
  325. uint32_t idx;
  326. struct synx_create_params params;
  327. if (__cam_synx_obj_find_free_idx(&idx))
  328. goto end;
  329. params.fence = NULL;
  330. params.name = name;
  331. params.flags = 0;
  332. params.h_synx = synx_obj;
  333. rc = __cam_synx_map_generic_flags_to_create(flags, &params);
  334. if (rc) {
  335. CAM_ERR(CAM_SYNX, "Failed to generate create flags");
  336. goto free_idx;
  337. }
  338. rc = synx_create(g_cam_synx_obj_dev->session_handle, &params);
  339. if (rc) {
  340. CAM_ERR(CAM_SYNX, "Failed to create synx obj");
  341. goto free_idx;
  342. }
  343. *row_idx = idx;
  344. __cam_synx_obj_init_row(idx, name, *synx_obj);
  345. CAM_DBG(CAM_SYNX, "Created synx obj handle: %d[%s] row_idx: %u",
  346. *synx_obj, name, idx);
  347. return rc;
  348. free_idx:
  349. clear_bit(idx, g_cam_synx_obj_dev->bitmap);
  350. end:
  351. return rc;
  352. }
  353. int cam_synx_obj_import_dma_fence(const char *name, uint32_t flags, void *fence,
  354. uint32_t *synx_obj, int32_t *row_idx)
  355. {
  356. struct synx_import_params params;
  357. if (!fence) {
  358. CAM_ERR(CAM_SYNX,
  359. "Importing DMA fence failed - fence pointer is NULL");
  360. return -EINVAL;
  361. }
  362. params.indv.flags = 0;
  363. params.indv.fence = fence;
  364. params.indv.new_h_synx = synx_obj;
  365. params.type = SYNX_IMPORT_INDV_PARAMS;
  366. params.indv.flags |= SYNX_IMPORT_DMA_FENCE;
  367. if (__cam_synx_map_generic_flags_to_import(flags, &params.indv)) {
  368. CAM_ERR(CAM_SYNX,
  369. "Importing DMA fence failed - invalid synx import flags");
  370. return -EINVAL;
  371. }
  372. return __cam_synx_obj_import(name, &params, row_idx);
  373. }
  374. int cam_synx_obj_internal_signal(int32_t row_idx,
  375. struct cam_synx_obj_signal *signal_synx_obj)
  376. {
  377. int rc;
  378. uint32_t signal_status, synx_obj = 0;
  379. struct cam_synx_obj_row *row = NULL;
  380. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  381. CAM_ERR(CAM_SYNX, "synx obj row idx: %d is invalid",
  382. row_idx);
  383. return -EINVAL;
  384. }
  385. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  386. row = &g_cam_synx_obj_dev->rows[row_idx];
  387. /* Ensures sync obj cb is not invoked */
  388. row->sync_signal_synx = true;
  389. synx_obj = row->synx_obj;
  390. if (row->state == CAM_SYNX_OBJ_STATE_SIGNALED) {
  391. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  392. CAM_WARN(CAM_SYNX, "synx obj fd: %d already in signaled state",
  393. signal_synx_obj->synx_obj);
  394. return 0;
  395. }
  396. rc = __cam_synx_obj_map_sync_status_util(signal_synx_obj->status,
  397. &signal_status);
  398. if (rc) {
  399. CAM_WARN(CAM_SYNX,
  400. "Signaling undefined status: %d for synx obj: %d",
  401. signal_synx_obj->status,
  402. signal_synx_obj->synx_obj);
  403. }
  404. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  405. cam_generic_fence_update_monitor_array(row_idx,
  406. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  407. CAM_FENCE_OP_SIGNAL);
  408. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  409. signal_synx_obj->synx_obj, signal_status);
  410. if (rc) {
  411. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  412. synx_obj, rc);
  413. goto end;
  414. }
  415. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  416. signal_synx_obj->synx_obj, signal_status, rc);
  417. end:
  418. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  419. return rc;
  420. }
  421. int cam_synx_obj_release(struct cam_synx_obj_release_params *release_params)
  422. {
  423. int rc;
  424. int32_t idx = -1;
  425. if (release_params->use_row_idx) {
  426. rc = __cam_synx_obj_release_row(release_params->u.synx_row_idx);
  427. if (rc < 0)
  428. __cam_synx_obj_dump_monitor_array(release_params->u.synx_row_idx);
  429. } else {
  430. rc = __cam_synx_obj_release_obj(release_params->u.synx_obj, &idx);
  431. if ((rc < 0) && (idx >= 0))
  432. __cam_synx_obj_dump_monitor_array(idx);
  433. }
  434. return rc;
  435. }
  436. int cam_synx_obj_signal_obj(struct cam_synx_obj_signal *signal_synx_obj)
  437. {
  438. int rc;
  439. uint32_t idx, signal_status = 0, synx_obj = 0;
  440. struct cam_synx_obj_row *row = NULL;
  441. rc = cam_synx_obj_find_obj_in_table(
  442. signal_synx_obj->synx_obj, &idx);
  443. if (rc) {
  444. CAM_ERR(CAM_SYNX, "Failed to find synx obj: %d",
  445. signal_synx_obj->synx_obj);
  446. return -EINVAL;
  447. }
  448. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  449. row = &g_cam_synx_obj_dev->rows[idx];
  450. synx_obj = row->synx_obj;
  451. if (row->state == CAM_SYNX_OBJ_STATE_SIGNALED) {
  452. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  453. CAM_WARN(CAM_SYNX, "synx obj: %d already in signaled state",
  454. signal_synx_obj->synx_obj);
  455. return 0;
  456. }
  457. rc = __cam_synx_obj_map_sync_status_util(signal_synx_obj->status,
  458. &signal_status);
  459. if (rc) {
  460. CAM_WARN(CAM_SYNX,
  461. "Signaling undefined sync status: %d for synx obj: %d",
  462. signal_synx_obj->status,
  463. signal_synx_obj->synx_obj);
  464. }
  465. row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  466. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  467. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  468. cam_generic_fence_update_monitor_array(idx,
  469. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  470. CAM_FENCE_OP_SIGNAL);
  471. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  472. signal_synx_obj->synx_obj, signal_status);
  473. if (rc) {
  474. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  475. synx_obj, rc);
  476. goto end;
  477. }
  478. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  479. signal_synx_obj->synx_obj, signal_status, rc);
  480. end:
  481. return rc;
  482. }
  483. int cam_synx_obj_register_cb(int32_t *sync_obj, int32_t row_idx,
  484. cam_sync_callback_for_synx_obj sync_cb)
  485. {
  486. int rc = 0;
  487. uint32_t synx_obj = 0;
  488. struct cam_synx_obj_row *row = NULL;
  489. struct synx_callback_params cb_params;
  490. if (!sync_obj || !sync_cb) {
  491. CAM_ERR(CAM_SYNX, "Invalid args sync_obj: %p sync_cb: %p",
  492. sync_obj, sync_cb);
  493. return -EINVAL;
  494. }
  495. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  496. CAM_ERR(CAM_SYNX, "synx obj idx: %d is invalid",
  497. row_idx);
  498. return -EINVAL;
  499. }
  500. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  501. row = &g_cam_synx_obj_dev->rows[row_idx];
  502. synx_obj = row->synx_obj;
  503. if (row->state != CAM_SYNX_OBJ_STATE_ACTIVE) {
  504. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  505. &cam_sync_monitor_mask))
  506. cam_generic_fence_update_monitor_array(row_idx,
  507. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  508. CAM_FENCE_OP_SKIP_REGISTER_CB);
  509. CAM_ERR(CAM_SYNX,
  510. "synx obj at idx: %d handle: %d is not active, current state: %d",
  511. row_idx, row->synx_obj, row->state);
  512. rc = -EINVAL;
  513. goto monitor_dump;
  514. }
  515. /**
  516. * If the cb is already registered, return
  517. */
  518. if (row->cb_registered_for_sync) {
  519. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  520. &cam_sync_monitor_mask))
  521. cam_generic_fence_update_monitor_array(row_idx,
  522. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  523. CAM_FENCE_OP_ALREADY_REGISTERED_CB);
  524. CAM_WARN(CAM_SYNX,
  525. "synx obj at idx: %d handle: %d has already registered a cb for sync: %d",
  526. row_idx, row->synx_obj, row->sync_obj);
  527. goto end;
  528. }
  529. row->sync_cb = sync_cb;
  530. row->sync_obj = *sync_obj;
  531. row->cb_registered_for_sync = true;
  532. cb_params.userdata = row;
  533. cb_params.cancel_cb_func = NULL;
  534. cb_params.h_synx = synx_obj;
  535. cb_params.cb_func = __cam_synx_obj_signal_cb;
  536. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  537. cam_generic_fence_update_monitor_array(row_idx,
  538. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  539. CAM_FENCE_OP_REGISTER_CB);
  540. rc = synx_async_wait(g_cam_synx_obj_dev->session_handle, &cb_params);
  541. if (rc) {
  542. CAM_ERR(CAM_SYNX,
  543. "Failed to register cb for synx obj: %d rc: %d",
  544. synx_obj, rc);
  545. goto monitor_dump;
  546. }
  547. CAM_DBG(CAM_SYNX,
  548. "CB successfully registered for synx obj: %d for sync_obj: %d",
  549. synx_obj, *sync_obj);
  550. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  551. return rc;
  552. monitor_dump:
  553. __cam_synx_obj_dump_monitor_array(row_idx);
  554. end:
  555. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  556. return rc;
  557. }
  558. int __cam_synx_init_session(void)
  559. {
  560. struct synx_queue_desc queue_desc;
  561. struct synx_initialization_params params;
  562. params.name = cam_synx_session_name;
  563. params.ptr = &queue_desc;
  564. params.flags = SYNX_INIT_MAX;
  565. params.id = SYNX_CLIENT_NATIVE;
  566. g_cam_synx_obj_dev->session_handle = synx_initialize(&params);
  567. if (!g_cam_synx_obj_dev->session_handle) {
  568. CAM_ERR(CAM_SYNX, "Synx session initialization failed");
  569. return -EINVAL;
  570. }
  571. CAM_DBG(CAM_SYNX, "Synx session initialized: %p",
  572. g_cam_synx_obj_dev->session_handle);
  573. return 0;
  574. }
  575. void cam_synx_obj_open(void)
  576. {
  577. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  578. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask)) {
  579. g_cam_synx_obj_dev->monitor_data = kzalloc(
  580. sizeof(struct cam_generic_fence_monitor_data *) *
  581. CAM_SYNX_TABLE_SZ, GFP_KERNEL);
  582. if (!g_cam_synx_obj_dev->monitor_data) {
  583. CAM_WARN(CAM_DMA_FENCE, "Failed to allocate memory %d",
  584. sizeof(struct cam_generic_fence_monitor_data *) *
  585. CAM_SYNX_TABLE_SZ);
  586. }
  587. }
  588. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  589. }
  590. void cam_synx_obj_close(void)
  591. {
  592. int i, rc;
  593. struct cam_synx_obj_row *row = NULL;
  594. struct synx_callback_params cb_params;
  595. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  596. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++) {
  597. row = &g_cam_synx_obj_dev->rows[i];
  598. if (row->state == CAM_SYNX_OBJ_STATE_INVALID)
  599. continue;
  600. CAM_DBG(CAM_SYNX, "Releasing synx_obj: %d[%s]",
  601. row->synx_obj, row->name);
  602. /* If registered for cb, remove cb */
  603. if (row->cb_registered_for_sync) {
  604. cb_params.userdata = row;
  605. cb_params.cancel_cb_func = NULL;
  606. cb_params.h_synx = row->synx_obj;
  607. cb_params.cb_func = __cam_synx_obj_signal_cb;
  608. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  609. &cam_sync_monitor_mask))
  610. cam_generic_fence_update_monitor_array(i,
  611. &g_cam_synx_obj_dev->dev_lock,
  612. g_cam_synx_obj_dev->monitor_data,
  613. CAM_FENCE_OP_UNREGISTER_CB);
  614. rc = synx_cancel_async_wait(
  615. g_cam_synx_obj_dev->session_handle,
  616. &cb_params);
  617. if (rc) {
  618. CAM_WARN(CAM_SYNX,
  619. "Registered callback could not be canceled for synx obj : %d",
  620. cb_params.h_synx);
  621. }
  622. }
  623. /* Signal and release the synx obj */
  624. if (row->state != CAM_SYNX_OBJ_STATE_SIGNALED) {
  625. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  626. &cam_sync_monitor_mask))
  627. cam_generic_fence_update_monitor_array(i,
  628. &g_cam_synx_obj_dev->dev_lock,
  629. g_cam_synx_obj_dev->monitor_data,
  630. CAM_FENCE_OP_SIGNAL);
  631. synx_signal(g_cam_synx_obj_dev->session_handle,
  632. row->synx_obj, SYNX_STATE_SIGNALED_CANCEL);
  633. }
  634. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  635. &cam_sync_monitor_mask))
  636. cam_generic_fence_update_monitor_array(i,
  637. &g_cam_synx_obj_dev->dev_lock,
  638. g_cam_synx_obj_dev->monitor_data,
  639. CAM_FENCE_OP_DESTROY);
  640. synx_release(g_cam_synx_obj_dev->session_handle,
  641. row->synx_obj);
  642. memset(row, 0, sizeof(struct cam_synx_obj_row));
  643. clear_bit(i, g_cam_synx_obj_dev->bitmap);
  644. }
  645. if (g_cam_synx_obj_dev->monitor_data) {
  646. for (i = 0; i < CAM_SYNX_TABLE_SZ; i++)
  647. kfree(g_cam_synx_obj_dev->monitor_data[i]);
  648. }
  649. kfree(g_cam_synx_obj_dev->monitor_data);
  650. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  651. CAM_DBG(CAM_SYNX, "Close on Camera SYNX driver");
  652. }
  653. int cam_synx_obj_driver_init(void)
  654. {
  655. int i;
  656. g_cam_synx_obj_dev = kzalloc(sizeof(struct cam_synx_obj_device), GFP_KERNEL);
  657. if (!g_cam_synx_obj_dev)
  658. return -ENOMEM;
  659. if (__cam_synx_init_session())
  660. goto deinit_driver;
  661. mutex_init(&g_cam_synx_obj_dev->dev_lock);
  662. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++)
  663. spin_lock_init(&g_cam_synx_obj_dev->row_spinlocks[i]);
  664. memset(&g_cam_synx_obj_dev->rows, 0, sizeof(g_cam_synx_obj_dev->rows));
  665. memset(&g_cam_synx_obj_dev->bitmap, 0, sizeof(g_cam_synx_obj_dev->bitmap));
  666. bitmap_zero(g_cam_synx_obj_dev->bitmap, CAM_SYNX_MAX_OBJS);
  667. CAM_DBG(CAM_SYNX, "Camera synx obj driver initialized");
  668. return 0;
  669. deinit_driver:
  670. CAM_ERR(CAM_SYNX, "Camera synx obj driver initialization failed");
  671. kfree(g_cam_synx_obj_dev);
  672. g_cam_synx_obj_dev = NULL;
  673. return -EINVAL;
  674. }
  675. void cam_synx_obj_driver_deinit(void)
  676. {
  677. int rc;
  678. if (g_cam_synx_obj_dev->session_handle) {
  679. rc = synx_uninitialize(g_cam_synx_obj_dev->session_handle);
  680. if (rc) {
  681. CAM_ERR(CAM_SYNX,
  682. "Synx failed to uninitialize session: %p, rc: %d",
  683. g_cam_synx_obj_dev->session_handle, rc);
  684. }
  685. }
  686. kfree(g_cam_synx_obj_dev);
  687. g_cam_synx_obj_dev = NULL;
  688. CAM_DBG(CAM_SYNX, "Camera synx obj driver deinitialized");
  689. }