cam_sync_synx.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  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. row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  405. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  406. cam_generic_fence_update_monitor_array(row_idx,
  407. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  408. CAM_FENCE_OP_SIGNAL);
  409. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  410. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  411. signal_synx_obj->synx_obj, signal_status);
  412. if (rc) {
  413. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  414. synx_obj, rc);
  415. goto end;
  416. }
  417. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  418. signal_synx_obj->synx_obj, signal_status, rc);
  419. end:
  420. return rc;
  421. }
  422. int cam_synx_obj_release(struct cam_synx_obj_release_params *release_params)
  423. {
  424. int rc;
  425. int32_t idx = -1;
  426. if (release_params->use_row_idx) {
  427. rc = __cam_synx_obj_release_row(release_params->u.synx_row_idx);
  428. if (rc < 0)
  429. __cam_synx_obj_dump_monitor_array(release_params->u.synx_row_idx);
  430. } else {
  431. rc = __cam_synx_obj_release_obj(release_params->u.synx_obj, &idx);
  432. if ((rc < 0) && (idx >= 0))
  433. __cam_synx_obj_dump_monitor_array(idx);
  434. }
  435. return rc;
  436. }
  437. int cam_synx_obj_signal_obj(struct cam_synx_obj_signal *signal_synx_obj)
  438. {
  439. int rc;
  440. uint32_t idx, signal_status = 0, synx_obj = 0;
  441. struct cam_synx_obj_row *row = NULL;
  442. rc = cam_synx_obj_find_obj_in_table(
  443. signal_synx_obj->synx_obj, &idx);
  444. if (rc) {
  445. CAM_ERR(CAM_SYNX, "Failed to find synx obj: %d",
  446. signal_synx_obj->synx_obj);
  447. return -EINVAL;
  448. }
  449. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  450. row = &g_cam_synx_obj_dev->rows[idx];
  451. synx_obj = row->synx_obj;
  452. if (row->state == CAM_SYNX_OBJ_STATE_SIGNALED) {
  453. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  454. CAM_WARN(CAM_SYNX, "synx obj: %d already in signaled state",
  455. signal_synx_obj->synx_obj);
  456. return 0;
  457. }
  458. rc = __cam_synx_obj_map_sync_status_util(signal_synx_obj->status,
  459. &signal_status);
  460. if (rc) {
  461. CAM_WARN(CAM_SYNX,
  462. "Signaling undefined sync status: %d for synx obj: %d",
  463. signal_synx_obj->status,
  464. signal_synx_obj->synx_obj);
  465. }
  466. row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  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. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  472. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  473. signal_synx_obj->synx_obj, signal_status);
  474. if (rc) {
  475. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  476. synx_obj, rc);
  477. goto end;
  478. }
  479. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  480. signal_synx_obj->synx_obj, signal_status, rc);
  481. end:
  482. return rc;
  483. }
  484. int cam_synx_obj_register_cb(int32_t *sync_obj, int32_t row_idx,
  485. cam_sync_callback_for_synx_obj sync_cb)
  486. {
  487. int rc = 0;
  488. uint32_t synx_obj = 0;
  489. struct cam_synx_obj_row *row = NULL;
  490. struct synx_callback_params cb_params;
  491. if (!sync_obj || !sync_cb) {
  492. CAM_ERR(CAM_SYNX, "Invalid args sync_obj: %p sync_cb: %p",
  493. sync_obj, sync_cb);
  494. return -EINVAL;
  495. }
  496. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  497. CAM_ERR(CAM_SYNX, "synx obj idx: %d is invalid",
  498. row_idx);
  499. return -EINVAL;
  500. }
  501. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  502. row = &g_cam_synx_obj_dev->rows[row_idx];
  503. synx_obj = row->synx_obj;
  504. if (row->state != CAM_SYNX_OBJ_STATE_ACTIVE) {
  505. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  506. &cam_sync_monitor_mask))
  507. cam_generic_fence_update_monitor_array(row_idx,
  508. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  509. CAM_FENCE_OP_SKIP_REGISTER_CB);
  510. CAM_ERR(CAM_SYNX,
  511. "synx obj at idx: %d handle: %d is not active, current state: %d",
  512. row_idx, row->synx_obj, row->state);
  513. rc = -EINVAL;
  514. goto monitor_dump;
  515. }
  516. /**
  517. * If the cb is already registered, return
  518. */
  519. if (row->cb_registered_for_sync) {
  520. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  521. &cam_sync_monitor_mask))
  522. cam_generic_fence_update_monitor_array(row_idx,
  523. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  524. CAM_FENCE_OP_ALREADY_REGISTERED_CB);
  525. CAM_WARN(CAM_SYNX,
  526. "synx obj at idx: %d handle: %d has already registered a cb for sync: %d",
  527. row_idx, row->synx_obj, row->sync_obj);
  528. goto end;
  529. }
  530. row->sync_cb = sync_cb;
  531. row->sync_obj = *sync_obj;
  532. row->cb_registered_for_sync = true;
  533. cb_params.userdata = row;
  534. cb_params.cancel_cb_func = NULL;
  535. cb_params.h_synx = synx_obj;
  536. cb_params.cb_func = __cam_synx_obj_signal_cb;
  537. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask))
  538. cam_generic_fence_update_monitor_array(row_idx,
  539. &g_cam_synx_obj_dev->dev_lock, g_cam_synx_obj_dev->monitor_data,
  540. CAM_FENCE_OP_REGISTER_CB);
  541. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  542. rc = synx_async_wait(g_cam_synx_obj_dev->session_handle, &cb_params);
  543. if (rc) {
  544. CAM_ERR(CAM_SYNX,
  545. "Failed to register cb for synx obj: %d rc: %d",
  546. synx_obj, rc);
  547. return rc;
  548. }
  549. CAM_DBG(CAM_SYNX,
  550. "CB successfully registered for synx obj: %d for sync_obj: %d",
  551. synx_obj, *sync_obj);
  552. return rc;
  553. monitor_dump:
  554. __cam_synx_obj_dump_monitor_array(row_idx);
  555. end:
  556. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  557. return rc;
  558. }
  559. int __cam_synx_init_session(void)
  560. {
  561. struct synx_queue_desc queue_desc;
  562. struct synx_initialization_params params;
  563. params.name = cam_synx_session_name;
  564. params.ptr = &queue_desc;
  565. params.flags = SYNX_INIT_MAX;
  566. params.id = SYNX_CLIENT_NATIVE;
  567. g_cam_synx_obj_dev->session_handle = synx_initialize(&params);
  568. if (!g_cam_synx_obj_dev->session_handle) {
  569. CAM_ERR(CAM_SYNX, "Synx session initialization failed");
  570. return -EINVAL;
  571. }
  572. CAM_DBG(CAM_SYNX, "Synx session initialized: %p",
  573. g_cam_synx_obj_dev->session_handle);
  574. return 0;
  575. }
  576. void cam_synx_obj_open(void)
  577. {
  578. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  579. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ, &cam_sync_monitor_mask)) {
  580. g_cam_synx_obj_dev->monitor_data = kzalloc(
  581. sizeof(struct cam_generic_fence_monitor_data *) *
  582. CAM_SYNX_TABLE_SZ, GFP_KERNEL);
  583. if (!g_cam_synx_obj_dev->monitor_data) {
  584. CAM_WARN(CAM_DMA_FENCE, "Failed to allocate memory %d",
  585. sizeof(struct cam_generic_fence_monitor_data *) *
  586. CAM_SYNX_TABLE_SZ);
  587. }
  588. }
  589. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  590. }
  591. void cam_synx_obj_close(void)
  592. {
  593. int i, rc;
  594. struct cam_synx_obj_row *row = NULL;
  595. struct synx_callback_params cb_params;
  596. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  597. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++) {
  598. row = &g_cam_synx_obj_dev->rows[i];
  599. if (row->state == CAM_SYNX_OBJ_STATE_INVALID)
  600. continue;
  601. CAM_DBG(CAM_SYNX, "Releasing synx_obj: %d[%s]",
  602. row->synx_obj, row->name);
  603. /* If registered for cb, remove cb */
  604. if (row->cb_registered_for_sync) {
  605. cb_params.userdata = row;
  606. cb_params.cancel_cb_func = NULL;
  607. cb_params.h_synx = row->synx_obj;
  608. cb_params.cb_func = __cam_synx_obj_signal_cb;
  609. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  610. &cam_sync_monitor_mask))
  611. cam_generic_fence_update_monitor_array(i,
  612. &g_cam_synx_obj_dev->dev_lock,
  613. g_cam_synx_obj_dev->monitor_data,
  614. CAM_FENCE_OP_UNREGISTER_CB);
  615. rc = synx_cancel_async_wait(
  616. g_cam_synx_obj_dev->session_handle,
  617. &cb_params);
  618. if (rc) {
  619. CAM_WARN(CAM_SYNX,
  620. "Registered callback could not be canceled for synx obj : %d",
  621. cb_params.h_synx);
  622. }
  623. }
  624. /* Signal and release the synx obj */
  625. if (row->state != CAM_SYNX_OBJ_STATE_SIGNALED) {
  626. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  627. &cam_sync_monitor_mask))
  628. cam_generic_fence_update_monitor_array(i,
  629. &g_cam_synx_obj_dev->dev_lock,
  630. g_cam_synx_obj_dev->monitor_data,
  631. CAM_FENCE_OP_SIGNAL);
  632. synx_signal(g_cam_synx_obj_dev->session_handle,
  633. row->synx_obj, SYNX_STATE_SIGNALED_CANCEL);
  634. }
  635. if (test_bit(CAM_GENERIC_FENCE_TYPE_SYNX_OBJ,
  636. &cam_sync_monitor_mask))
  637. cam_generic_fence_update_monitor_array(i,
  638. &g_cam_synx_obj_dev->dev_lock,
  639. g_cam_synx_obj_dev->monitor_data,
  640. CAM_FENCE_OP_DESTROY);
  641. synx_release(g_cam_synx_obj_dev->session_handle,
  642. row->synx_obj);
  643. memset(row, 0, sizeof(struct cam_synx_obj_row));
  644. clear_bit(i, g_cam_synx_obj_dev->bitmap);
  645. }
  646. if (g_cam_synx_obj_dev->monitor_data) {
  647. for (i = 0; i < CAM_SYNX_TABLE_SZ; i++)
  648. kfree(g_cam_synx_obj_dev->monitor_data[i]);
  649. }
  650. kfree(g_cam_synx_obj_dev->monitor_data);
  651. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  652. CAM_DBG(CAM_SYNX, "Close on Camera SYNX driver");
  653. }
  654. int cam_synx_obj_driver_init(void)
  655. {
  656. int i;
  657. g_cam_synx_obj_dev = kzalloc(sizeof(struct cam_synx_obj_device), GFP_KERNEL);
  658. if (!g_cam_synx_obj_dev)
  659. return -ENOMEM;
  660. if (__cam_synx_init_session())
  661. goto deinit_driver;
  662. mutex_init(&g_cam_synx_obj_dev->dev_lock);
  663. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++)
  664. spin_lock_init(&g_cam_synx_obj_dev->row_spinlocks[i]);
  665. memset(&g_cam_synx_obj_dev->rows, 0, sizeof(g_cam_synx_obj_dev->rows));
  666. memset(&g_cam_synx_obj_dev->bitmap, 0, sizeof(g_cam_synx_obj_dev->bitmap));
  667. bitmap_zero(g_cam_synx_obj_dev->bitmap, CAM_SYNX_MAX_OBJS);
  668. CAM_DBG(CAM_SYNX, "Camera synx obj driver initialized");
  669. return 0;
  670. deinit_driver:
  671. CAM_ERR(CAM_SYNX, "Camera synx obj driver initialization failed");
  672. kfree(g_cam_synx_obj_dev);
  673. g_cam_synx_obj_dev = NULL;
  674. return -EINVAL;
  675. }
  676. void cam_synx_obj_driver_deinit(void)
  677. {
  678. int rc;
  679. if (g_cam_synx_obj_dev->session_handle) {
  680. rc = synx_uninitialize(g_cam_synx_obj_dev->session_handle);
  681. if (rc) {
  682. CAM_ERR(CAM_SYNX,
  683. "Synx failed to uninitialize session: %p, rc: %d",
  684. g_cam_synx_obj_dev->session_handle, rc);
  685. }
  686. }
  687. kfree(g_cam_synx_obj_dev);
  688. g_cam_synx_obj_dev = NULL;
  689. CAM_DBG(CAM_SYNX, "Camera synx obj driver deinitialized");
  690. }