msm_vidc_state.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "msm_vidc_control.h"
  7. #include "msm_vidc_driver.h"
  8. #include "msm_vidc_state.h"
  9. #include "msm_vidc_debug.h"
  10. #include "msm_vidc_core.h"
  11. #include "msm_vidc_vb2.h"
  12. #include "msm_vidc.h"
  13. #include "msm_vidc_events.h"
  14. bool core_in_valid_state(struct msm_vidc_core *core)
  15. {
  16. return (core->state == MSM_VIDC_CORE_INIT ||
  17. core->state == MSM_VIDC_CORE_INIT_WAIT);
  18. }
  19. bool is_core_state(struct msm_vidc_core *core, enum msm_vidc_core_state state)
  20. {
  21. return core->state == state;
  22. }
  23. bool is_drc_pending(struct msm_vidc_inst *inst)
  24. {
  25. return is_sub_state(inst, MSM_VIDC_DRC) &&
  26. is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER);
  27. }
  28. bool is_drain_pending(struct msm_vidc_inst *inst)
  29. {
  30. return is_sub_state(inst, MSM_VIDC_DRAIN) &&
  31. is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER);
  32. }
  33. static const char * const core_state_name_arr[] =
  34. FOREACH_CORE_STATE(GENERATE_STRING);
  35. const char *core_state_name(enum msm_vidc_core_state state)
  36. {
  37. const char *name = "UNKNOWN STATE";
  38. if (state >= ARRAY_SIZE(core_state_name_arr))
  39. goto exit;
  40. name = core_state_name_arr[state];
  41. exit:
  42. return name;
  43. }
  44. static const char * const event_name_arr[] =
  45. FOREACH_EVENT(GENERATE_STRING);
  46. static const char *event_name(enum msm_vidc_event event)
  47. {
  48. const char *name = "UNKNOWN EVENT";
  49. if (event >= ARRAY_SIZE(event_name_arr))
  50. goto exit;
  51. name = event_name_arr[event];
  52. exit:
  53. return name;
  54. }
  55. static int __strict_check(struct msm_vidc_core *core, const char *function)
  56. {
  57. bool fatal = !mutex_is_locked(&core->lock);
  58. WARN_ON(fatal);
  59. if (fatal)
  60. d_vpr_e("%s: strict check failed\n", function);
  61. return fatal ? -EINVAL : 0;
  62. }
  63. static int __strict_inst_check(struct msm_vidc_inst *inst, const char *function)
  64. {
  65. bool fatal = !mutex_is_locked(&inst->lock);
  66. WARN_ON(fatal);
  67. if (fatal)
  68. d_vpr_e("%s: strict check failed\n", function);
  69. return fatal ? -EINVAL : 0;
  70. }
  71. static int msm_vidc_core_deinit_state(struct msm_vidc_core *core,
  72. enum msm_vidc_core_event_type type,
  73. struct msm_vidc_event_data *data)
  74. {
  75. if (!core || !data) {
  76. d_vpr_e("%s: invalid params\n", __func__);
  77. return -EINVAL;
  78. }
  79. d_vpr_e("%s: unexpected core event type %u\n", __func__, type);
  80. return -EINVAL;
  81. }
  82. static int msm_vidc_core_init_wait_state(struct msm_vidc_core *core,
  83. enum msm_vidc_core_event_type type,
  84. struct msm_vidc_event_data *data)
  85. {
  86. int rc = 0;
  87. if (!core || !data) {
  88. d_vpr_e("%s: invalid params\n", __func__);
  89. return -EINVAL;
  90. }
  91. switch (type) {
  92. case CORE_EVENT_UPDATE_SUB_STATE:
  93. {
  94. u32 req_sub_state;
  95. u32 allow_mask = -1;
  96. req_sub_state = data->edata.uval;
  97. /* none of the requested substate supported */
  98. if (!(req_sub_state & allow_mask)) {
  99. d_vpr_e("%s: invalid substate update request %#x\n",
  100. __func__, req_sub_state);
  101. return -EINVAL;
  102. }
  103. /* update core substate */
  104. core->sub_state |= req_sub_state & allow_mask;
  105. return rc;
  106. }
  107. default: {
  108. d_vpr_e("%s: unexpected core event type %u\n",
  109. __func__, type);
  110. return -EINVAL;
  111. }
  112. }
  113. return rc;
  114. }
  115. static int msm_vidc_core_init_state(struct msm_vidc_core *core,
  116. enum msm_vidc_core_event_type type,
  117. struct msm_vidc_event_data *data)
  118. {
  119. int rc = 0;
  120. if (!core || !data) {
  121. d_vpr_e("%s: invalid params\n", __func__);
  122. return -EINVAL;
  123. }
  124. switch (type) {
  125. case CORE_EVENT_UPDATE_SUB_STATE:
  126. {
  127. u32 req_sub_state;
  128. u32 allow_mask = -1;
  129. req_sub_state = data->edata.uval;
  130. /* none of the requested substate supported */
  131. if (!(req_sub_state & allow_mask)) {
  132. d_vpr_e("%s: invalid substate update request %#x\n",
  133. __func__, req_sub_state);
  134. return -EINVAL;
  135. }
  136. /* update core substate */
  137. core->sub_state |= req_sub_state & allow_mask;
  138. return rc;
  139. }
  140. default: {
  141. d_vpr_e("%s: unexpected core event type %u\n",
  142. __func__, type);
  143. return -EINVAL;
  144. }
  145. }
  146. return rc;
  147. }
  148. static int msm_vidc_core_error_state(struct msm_vidc_core *core,
  149. enum msm_vidc_core_event_type type,
  150. struct msm_vidc_event_data *data)
  151. {
  152. int rc = 0;
  153. if (!core || !data) {
  154. d_vpr_e("%s: invalid params\n", __func__);
  155. return -EINVAL;
  156. }
  157. switch (type) {
  158. case CORE_EVENT_UPDATE_SUB_STATE:
  159. {
  160. u32 req_sub_state;
  161. u32 allow_mask = -1;
  162. req_sub_state = data->edata.uval;
  163. /* none of the requested substate supported */
  164. if (!(req_sub_state & allow_mask)) {
  165. d_vpr_e("%s: invalid substate update request %#x\n",
  166. __func__, req_sub_state);
  167. return -EINVAL;
  168. }
  169. /* update core substate */
  170. core->sub_state |= req_sub_state & allow_mask;
  171. return rc;
  172. }
  173. default: {
  174. d_vpr_e("%s: unexpected core event type %u\n",
  175. __func__, type);
  176. return -EINVAL;
  177. }
  178. }
  179. return rc;
  180. }
  181. struct msm_vidc_core_state_handle {
  182. enum msm_vidc_core_state state;
  183. int (*handle)(struct msm_vidc_core *core,
  184. enum msm_vidc_core_event_type type,
  185. struct msm_vidc_event_data *data);
  186. };
  187. static struct msm_vidc_core_state_handle *msm_vidc_get_core_state_handle(
  188. enum msm_vidc_core_state req_state)
  189. {
  190. int cnt;
  191. struct msm_vidc_core_state_handle *core_state_handle = NULL;
  192. static struct msm_vidc_core_state_handle state_handle[] = {
  193. {MSM_VIDC_CORE_DEINIT, msm_vidc_core_deinit_state },
  194. {MSM_VIDC_CORE_INIT_WAIT, msm_vidc_core_init_wait_state },
  195. {MSM_VIDC_CORE_INIT, msm_vidc_core_init_state },
  196. {MSM_VIDC_CORE_ERROR, msm_vidc_core_error_state },
  197. };
  198. for (cnt = 0; cnt < ARRAY_SIZE(state_handle); cnt++) {
  199. if (state_handle[cnt].state == req_state) {
  200. core_state_handle = &state_handle[cnt];
  201. break;
  202. }
  203. }
  204. /* if req_state does not exist in the table */
  205. if (cnt == ARRAY_SIZE(state_handle)) {
  206. d_vpr_e("%s: invalid core state \"%s\" requested\n",
  207. __func__, core_state_name(req_state));
  208. return core_state_handle;
  209. }
  210. return core_state_handle;
  211. }
  212. int msm_vidc_update_core_state(struct msm_vidc_core *core,
  213. enum msm_vidc_core_state request_state, const char *func)
  214. {
  215. struct msm_vidc_core_state_handle *state_handle = NULL;
  216. int rc = 0;
  217. /* get core state handler for requested state */
  218. state_handle = msm_vidc_get_core_state_handle(request_state);
  219. if (!state_handle)
  220. return -EINVAL;
  221. d_vpr_h("%s: core state changed to %s from %s\n", func,
  222. core_state_name(state_handle->state), core_state_name(core->state));
  223. /* finally update core state and handler */
  224. core->state = state_handle->state;
  225. core->state_handle = state_handle->handle;
  226. return rc;
  227. }
  228. struct msm_vidc_core_state_allow {
  229. enum msm_vidc_core_state from;
  230. enum msm_vidc_core_state to;
  231. enum msm_vidc_allow allow;
  232. };
  233. enum msm_vidc_allow msm_vidc_allow_core_state_change(
  234. struct msm_vidc_core *core,
  235. enum msm_vidc_core_state req_state)
  236. {
  237. int cnt;
  238. enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
  239. static struct msm_vidc_core_state_allow state[] = {
  240. /* from, to, allow */
  241. {MSM_VIDC_CORE_DEINIT, MSM_VIDC_CORE_DEINIT, MSM_VIDC_IGNORE },
  242. {MSM_VIDC_CORE_DEINIT, MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_ALLOW },
  243. {MSM_VIDC_CORE_DEINIT, MSM_VIDC_CORE_INIT, MSM_VIDC_DISALLOW },
  244. {MSM_VIDC_CORE_DEINIT, MSM_VIDC_CORE_ERROR, MSM_VIDC_IGNORE },
  245. {MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_CORE_DEINIT, MSM_VIDC_DISALLOW },
  246. {MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_IGNORE },
  247. {MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_CORE_INIT, MSM_VIDC_ALLOW },
  248. {MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_CORE_ERROR, MSM_VIDC_ALLOW },
  249. {MSM_VIDC_CORE_INIT, MSM_VIDC_CORE_DEINIT, MSM_VIDC_ALLOW },
  250. {MSM_VIDC_CORE_INIT, MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_DISALLOW },
  251. {MSM_VIDC_CORE_INIT, MSM_VIDC_CORE_INIT, MSM_VIDC_IGNORE },
  252. {MSM_VIDC_CORE_INIT, MSM_VIDC_CORE_ERROR, MSM_VIDC_ALLOW },
  253. {MSM_VIDC_CORE_ERROR, MSM_VIDC_CORE_DEINIT, MSM_VIDC_ALLOW },
  254. {MSM_VIDC_CORE_ERROR, MSM_VIDC_CORE_INIT_WAIT, MSM_VIDC_IGNORE },
  255. {MSM_VIDC_CORE_ERROR, MSM_VIDC_CORE_INIT, MSM_VIDC_IGNORE },
  256. {MSM_VIDC_CORE_ERROR, MSM_VIDC_CORE_ERROR, MSM_VIDC_IGNORE },
  257. };
  258. for (cnt = 0; cnt < ARRAY_SIZE(state); cnt++) {
  259. if (state[cnt].from == core->state && state[cnt].to == req_state) {
  260. allow = state[cnt].allow;
  261. break;
  262. }
  263. }
  264. return allow;
  265. }
  266. int msm_vidc_change_core_state(struct msm_vidc_core *core,
  267. enum msm_vidc_core_state request_state, const char *func)
  268. {
  269. enum msm_vidc_allow allow;
  270. int rc = 0;
  271. if (!core) {
  272. d_vpr_e("%s: invalid params\n", __func__);
  273. return -EINVAL;
  274. }
  275. /* core must be locked */
  276. rc = __strict_check(core, func);
  277. if (rc) {
  278. d_vpr_e("%s(): core was not locked\n", func);
  279. return rc;
  280. }
  281. /* current and requested state is same */
  282. if (core->state == request_state)
  283. return 0;
  284. /* check if requested state movement is allowed */
  285. allow = msm_vidc_allow_core_state_change(core, request_state);
  286. if (allow == MSM_VIDC_IGNORE) {
  287. d_vpr_h("%s: %s core state change %s -> %s\n", func,
  288. allow_name(allow), core_state_name(core->state),
  289. core_state_name(request_state));
  290. return 0;
  291. } else if (allow == MSM_VIDC_DISALLOW) {
  292. d_vpr_e("%s: %s core state change %s -> %s\n", func,
  293. allow_name(allow), core_state_name(core->state),
  294. core_state_name(request_state));
  295. return -EINVAL;
  296. }
  297. /* go ahead and update core state */
  298. rc = msm_vidc_update_core_state(core, request_state, func);
  299. if (rc)
  300. return rc;
  301. return rc;
  302. }
  303. bool is_core_sub_state(struct msm_vidc_core *core,
  304. enum msm_vidc_core_sub_state sub_state)
  305. {
  306. return !!(core->sub_state & sub_state);
  307. }
  308. const char *core_sub_state_name(enum msm_vidc_core_sub_state sub_state)
  309. {
  310. switch (sub_state) {
  311. case CORE_SUBSTATE_NONE: return "NONE ";
  312. case CORE_SUBSTATE_GDSC_HANDOFF: return "GDSC_HANDOFF ";
  313. case CORE_SUBSTATE_PM_SUSPEND: return "PM_SUSPEND ";
  314. case CORE_SUBSTATE_FW_PWR_CTRL: return "FW_PWR_CTRL ";
  315. case CORE_SUBSTATE_POWER_ENABLE: return "POWER_ENABLE ";
  316. case CORE_SUBSTATE_PAGE_FAULT: return "PAGE_FAULT ";
  317. case CORE_SUBSTATE_CPU_WATCHDOG: return "CPU_WATCHDOG ";
  318. case CORE_SUBSTATE_VIDEO_UNRESPONSIVE: return "VIDEO_UNRESPONSIVE ";
  319. case CORE_SUBSTATE_MAX: return "MAX ";
  320. }
  321. return "UNKNOWN ";
  322. }
  323. static int prepare_core_sub_state_name(enum msm_vidc_core_sub_state sub_state,
  324. char *buf, u32 size)
  325. {
  326. int i = 0;
  327. if (!buf || !size)
  328. return -EINVAL;
  329. strscpy(buf, "\0", size);
  330. if (sub_state == CORE_SUBSTATE_NONE) {
  331. strscpy(buf, "CORE_SUBSTATE_NONE", size);
  332. return 0;
  333. }
  334. for (i = 0; BIT(i) < CORE_SUBSTATE_MAX; i++) {
  335. if (sub_state & BIT(i))
  336. strlcat(buf, core_sub_state_name(BIT(i)), size);
  337. }
  338. return 0;
  339. }
  340. static int msm_vidc_update_core_sub_state(struct msm_vidc_core *core,
  341. enum msm_vidc_core_sub_state sub_state, const char *func)
  342. {
  343. struct msm_vidc_event_data data;
  344. char sub_state_name[MAX_NAME_LENGTH];
  345. int ret = 0, rc = 0;
  346. if (!core) {
  347. d_vpr_e("%s: invalid params\n", __func__);
  348. return -EINVAL;
  349. }
  350. /* no substate update */
  351. if (!sub_state)
  352. return 0;
  353. /* invoke update core substate event */
  354. memset(&data, 0, sizeof(struct msm_vidc_event_data));
  355. data.edata.uval = sub_state;
  356. rc = core->state_handle(core, CORE_EVENT_UPDATE_SUB_STATE, &data);
  357. if (rc) {
  358. ret = prepare_core_sub_state_name(sub_state,
  359. sub_state_name, sizeof(sub_state_name) - 1);
  360. if (!ret)
  361. d_vpr_e("%s: state %s, requested invalid core substate %s\n",
  362. func, core_state_name(core->state), sub_state_name);
  363. return rc;
  364. }
  365. return rc;
  366. }
  367. int msm_vidc_change_core_sub_state(struct msm_vidc_core *core,
  368. enum msm_vidc_core_sub_state clear_sub_state,
  369. enum msm_vidc_core_sub_state set_sub_state, const char *func)
  370. {
  371. int rc = 0;
  372. enum msm_vidc_core_sub_state prev_sub_state;
  373. if (!core) {
  374. d_vpr_e("%s: invalid params\n", __func__);
  375. return -EINVAL;
  376. }
  377. /* core must be locked */
  378. rc = __strict_check(core, func);
  379. if (rc) {
  380. d_vpr_e("%s(): core was not locked\n", func);
  381. return rc;
  382. }
  383. /* sanitize core state handler */
  384. if (!core->state_handle) {
  385. d_vpr_e("%s: invalid core state handle\n", __func__);
  386. return -EINVAL;
  387. }
  388. /* final value will not change */
  389. if (clear_sub_state == set_sub_state)
  390. return 0;
  391. /* sanitize clear & set value */
  392. if (set_sub_state > CORE_SUBSTATE_MAX ||
  393. clear_sub_state > CORE_SUBSTATE_MAX) {
  394. d_vpr_e("%s: invalid sub states. clear %#x or set %#x\n",
  395. func, clear_sub_state, set_sub_state);
  396. return -EINVAL;
  397. }
  398. prev_sub_state = core->sub_state;
  399. /* set sub state */
  400. rc = msm_vidc_update_core_sub_state(core, set_sub_state, func);
  401. if (rc)
  402. return rc;
  403. /* check if all core substates updated */
  404. if ((core->sub_state & set_sub_state) != set_sub_state)
  405. d_vpr_e("%s: all substates not updated %#x, expected %#x\n",
  406. func, core->sub_state & set_sub_state, set_sub_state);
  407. /* clear sub state */
  408. core->sub_state &= ~clear_sub_state;
  409. /* print substates only when there is a change */
  410. if (core->sub_state != prev_sub_state) {
  411. rc = prepare_core_sub_state_name(core->sub_state, core->sub_state_name,
  412. sizeof(core->sub_state_name) - 1);
  413. if (!rc)
  414. d_vpr_h("%s: core sub state changed to %s\n", func, core->sub_state_name);
  415. }
  416. return 0;
  417. }
  418. /* do not modify the state names as it is used in test scripts */
  419. static const char * const state_name_arr[] =
  420. FOREACH_STATE(GENERATE_STRING);
  421. const char *state_name(enum msm_vidc_state state)
  422. {
  423. const char *name = "UNKNOWN STATE";
  424. if (state >= ARRAY_SIZE(state_name_arr))
  425. goto exit;
  426. name = state_name_arr[state];
  427. exit:
  428. return name;
  429. }
  430. bool is_state(struct msm_vidc_inst *inst, enum msm_vidc_state state)
  431. {
  432. return inst->state == state;
  433. }
  434. bool is_sub_state(struct msm_vidc_inst *inst, enum msm_vidc_sub_state sub_state)
  435. {
  436. return (inst->sub_state & sub_state);
  437. }
  438. const char *sub_state_name(enum msm_vidc_sub_state sub_state)
  439. {
  440. switch (sub_state) {
  441. case MSM_VIDC_DRAIN: return "DRAIN ";
  442. case MSM_VIDC_DRC: return "DRC ";
  443. case MSM_VIDC_DRAIN_LAST_BUFFER: return "DRAIN_LAST_BUFFER ";
  444. case MSM_VIDC_DRC_LAST_BUFFER: return "DRC_LAST_BUFFER ";
  445. case MSM_VIDC_INPUT_PAUSE: return "INPUT_PAUSE ";
  446. case MSM_VIDC_OUTPUT_PAUSE: return "OUTPUT_PAUSE ";
  447. }
  448. return "SUB_STATE_NONE";
  449. }
  450. static int prepare_sub_state_name(enum msm_vidc_sub_state sub_state,
  451. char *buf, u32 size)
  452. {
  453. int i = 0;
  454. if (!buf || !size)
  455. return -EINVAL;
  456. strscpy(buf, "\0", size);
  457. if (sub_state == MSM_VIDC_SUB_STATE_NONE) {
  458. strscpy(buf, "SUB_STATE_NONE", size);
  459. return 0;
  460. }
  461. for (i = 0; i < MSM_VIDC_MAX_SUB_STATES; i++) {
  462. if (sub_state & BIT(i))
  463. strlcat(buf, sub_state_name(BIT(i)), size);
  464. }
  465. return 0;
  466. }
  467. struct msm_vidc_state_allow {
  468. enum msm_vidc_state from;
  469. enum msm_vidc_state to;
  470. enum msm_vidc_allow allow;
  471. };
  472. static enum msm_vidc_allow msm_vidc_allow_state_change(
  473. struct msm_vidc_inst *inst,
  474. enum msm_vidc_state req_state)
  475. {
  476. int cnt;
  477. enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
  478. static struct msm_vidc_state_allow state[] = {
  479. /* from, to, allow */
  480. {MSM_VIDC_OPEN, MSM_VIDC_OPEN, MSM_VIDC_IGNORE },
  481. {MSM_VIDC_OPEN, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_ALLOW },
  482. {MSM_VIDC_OPEN, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_ALLOW },
  483. {MSM_VIDC_OPEN, MSM_VIDC_STREAMING, MSM_VIDC_DISALLOW },
  484. {MSM_VIDC_OPEN, MSM_VIDC_CLOSE, MSM_VIDC_ALLOW },
  485. {MSM_VIDC_OPEN, MSM_VIDC_ERROR, MSM_VIDC_ALLOW },
  486. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_OPEN, MSM_VIDC_ALLOW },
  487. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_IGNORE },
  488. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_DISALLOW },
  489. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_STREAMING, MSM_VIDC_ALLOW },
  490. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_CLOSE, MSM_VIDC_ALLOW },
  491. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_ERROR, MSM_VIDC_ALLOW },
  492. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_OPEN, MSM_VIDC_ALLOW },
  493. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_DISALLOW },
  494. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_IGNORE },
  495. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_STREAMING, MSM_VIDC_ALLOW },
  496. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_CLOSE, MSM_VIDC_ALLOW },
  497. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_ERROR, MSM_VIDC_ALLOW },
  498. {MSM_VIDC_STREAMING, MSM_VIDC_OPEN, MSM_VIDC_DISALLOW },
  499. {MSM_VIDC_STREAMING, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_ALLOW },
  500. {MSM_VIDC_STREAMING, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_ALLOW },
  501. {MSM_VIDC_STREAMING, MSM_VIDC_STREAMING, MSM_VIDC_IGNORE },
  502. {MSM_VIDC_STREAMING, MSM_VIDC_CLOSE, MSM_VIDC_ALLOW },
  503. {MSM_VIDC_STREAMING, MSM_VIDC_ERROR, MSM_VIDC_ALLOW },
  504. {MSM_VIDC_CLOSE, MSM_VIDC_OPEN, MSM_VIDC_DISALLOW },
  505. {MSM_VIDC_CLOSE, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_DISALLOW },
  506. {MSM_VIDC_CLOSE, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_DISALLOW },
  507. {MSM_VIDC_CLOSE, MSM_VIDC_STREAMING, MSM_VIDC_DISALLOW },
  508. {MSM_VIDC_CLOSE, MSM_VIDC_CLOSE, MSM_VIDC_IGNORE },
  509. {MSM_VIDC_CLOSE, MSM_VIDC_ERROR, MSM_VIDC_IGNORE },
  510. {MSM_VIDC_ERROR, MSM_VIDC_OPEN, MSM_VIDC_IGNORE },
  511. {MSM_VIDC_ERROR, MSM_VIDC_INPUT_STREAMING, MSM_VIDC_IGNORE },
  512. {MSM_VIDC_ERROR, MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_IGNORE },
  513. {MSM_VIDC_ERROR, MSM_VIDC_STREAMING, MSM_VIDC_IGNORE },
  514. {MSM_VIDC_ERROR, MSM_VIDC_CLOSE, MSM_VIDC_IGNORE },
  515. {MSM_VIDC_ERROR, MSM_VIDC_ERROR, MSM_VIDC_IGNORE },
  516. };
  517. for (cnt = 0; cnt < ARRAY_SIZE(state); cnt++) {
  518. if (state[cnt].from == inst->state && state[cnt].to == req_state) {
  519. allow = state[cnt].allow;
  520. break;
  521. }
  522. }
  523. return allow;
  524. }
  525. static int msm_vidc_open_state(struct msm_vidc_inst *inst,
  526. enum msm_vidc_event event, void *data)
  527. {
  528. int rc = 0;
  529. if (!inst) {
  530. d_vpr_e("%s: invalid params\n", __func__);
  531. return -EINVAL;
  532. }
  533. /* inst must be locked */
  534. rc = __strict_inst_check(inst, __func__);
  535. if (rc) {
  536. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  537. return -EINVAL;
  538. }
  539. switch (event) {
  540. case MSM_VIDC_S_FMT:
  541. {
  542. struct v4l2_format *f = (struct v4l2_format *)data;
  543. /* allow s_fmt request in open state */
  544. rc = msm_vidc_s_fmt(inst, f);
  545. if (rc)
  546. return rc;
  547. break;
  548. }
  549. case MSM_VIDC_S_CTRL:
  550. {
  551. struct v4l2_ctrl *ctrl = (struct v4l2_ctrl *)data;
  552. /* allow set_control request in open state */
  553. rc = msm_vidc_s_ctrl(inst, ctrl);
  554. if (rc)
  555. return rc;
  556. break;
  557. }
  558. case MSM_VIDC_REQBUFS:
  559. {
  560. struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
  561. /* allow reqbufs request in open state */
  562. rc = msm_vidc_reqbufs(inst, b);
  563. if (rc)
  564. return rc;
  565. break;
  566. }
  567. case MSM_VIDC_STREAMON:
  568. {
  569. struct vb2_queue *q = (struct vb2_queue *)data;
  570. /* allow streamon request in open state */
  571. rc = msm_vidc_start_streaming(inst, q);
  572. if (rc)
  573. return rc;
  574. break;
  575. }
  576. case MSM_VIDC_STREAMOFF:
  577. {
  578. struct vb2_queue *q = (struct vb2_queue *)data;
  579. /* ignore streamoff request in open state */
  580. i_vpr_h(inst, "%s: streamoff of (%s) ignored in state (%s)\n",
  581. __func__, v4l2_type_name(q->type), state_name(inst->state));
  582. break;
  583. }
  584. case MSM_VIDC_CMD_START:
  585. {
  586. /* disallow start cmd request in open state */
  587. i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
  588. __func__, event_name(event), inst->sub_state_name);
  589. return -EBUSY;
  590. }
  591. case MSM_VIDC_CMD_STOP:
  592. {
  593. /* ignore stop cmd request in open state */
  594. i_vpr_h(inst, "%s: (%s) ignored, sub_state (%s)\n",
  595. __func__, event_name(event), inst->sub_state_name);
  596. break;
  597. }
  598. case MSM_VIDC_BUF_QUEUE:
  599. {
  600. struct msm_vidc_buffer *buf = (struct msm_vidc_buffer *)data;
  601. /* defer qbuf request in open state */
  602. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  603. break;
  604. }
  605. default:
  606. {
  607. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  608. return -EINVAL;
  609. }
  610. }
  611. return rc;
  612. }
  613. static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
  614. enum msm_vidc_event event, void *data)
  615. {
  616. int rc = 0;
  617. if (!inst) {
  618. d_vpr_e("%s: invalid params\n", __func__);
  619. return -EINVAL;
  620. }
  621. /* inst must be locked */
  622. rc = __strict_inst_check(inst, __func__);
  623. if (rc) {
  624. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  625. return -EINVAL;
  626. }
  627. switch (event) {
  628. case MSM_VIDC_BUF_QUEUE:
  629. {
  630. struct msm_vidc_buffer *buf = (struct msm_vidc_buffer *)data;
  631. /* defer meta port */
  632. if (buf->type == MSM_VIDC_BUF_INPUT_META || buf->type == MSM_VIDC_BUF_OUTPUT_META) {
  633. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  634. return 0;
  635. }
  636. /* disallow */
  637. if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT) {
  638. i_vpr_e(inst, "%s: invalid buf type %u\n", __func__, buf->type);
  639. return -EINVAL;
  640. }
  641. /* defer output port */
  642. if (buf->type == MSM_VIDC_BUF_OUTPUT) {
  643. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  644. return 0;
  645. }
  646. rc = msm_vidc_buf_queue(inst, buf);
  647. if (rc)
  648. return rc;
  649. break;
  650. }
  651. case MSM_VIDC_S_FMT:
  652. {
  653. struct v4l2_format *f = (struct v4l2_format *)data;
  654. /* disallow */
  655. if (f->type == INPUT_MPLANE || f->type == INPUT_META_PLANE) {
  656. i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
  657. __func__, event_name(event), v4l2_type_name(f->type));
  658. return -EBUSY;
  659. }
  660. rc = msm_vidc_s_fmt(inst, f);
  661. if (rc)
  662. return rc;
  663. break;
  664. }
  665. case MSM_VIDC_S_CTRL:
  666. {
  667. struct v4l2_ctrl *ctrl = (struct v4l2_ctrl *)data;
  668. u32 cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
  669. if (cap_id == INST_CAP_NONE) {
  670. i_vpr_e(inst, "%s: invalid cap_id %u\n", __func__, cap_id);
  671. return -EINVAL;
  672. }
  673. /* disallow */
  674. if (is_decode_session(inst)) {
  675. /* check dynamic allowed if master port is streaming */
  676. if (!(inst->capabilities->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
  677. i_vpr_e(inst, "%s: cap_id %#x not allowed in state %s\n",
  678. __func__, cap_id, state_name(inst->state));
  679. return -EINVAL;
  680. }
  681. }
  682. rc = msm_vidc_s_ctrl(inst, ctrl);
  683. if (rc)
  684. return rc;
  685. break;
  686. }
  687. case MSM_VIDC_REQBUFS:
  688. {
  689. struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
  690. /* disallow */
  691. if (b->type == INPUT_MPLANE || b->type == INPUT_META_PLANE) {
  692. i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
  693. __func__, event_name(event), v4l2_type_name(b->type));
  694. return -EBUSY;
  695. }
  696. rc = msm_vidc_reqbufs(inst, b);
  697. if (rc)
  698. return rc;
  699. break;
  700. }
  701. case MSM_VIDC_STREAMON:
  702. {
  703. struct vb2_queue *q = (struct vb2_queue *)data;
  704. /* disallow */
  705. if (q->type == INPUT_MPLANE || q->type == INPUT_META_PLANE) {
  706. i_vpr_e(inst, "%s: (%s) not allowed for (%s) type\n",
  707. __func__, event_name(event), v4l2_type_name(q->type));
  708. return -EBUSY;
  709. }
  710. rc = msm_vidc_start_streaming(inst, q);
  711. if (rc)
  712. return rc;
  713. break;
  714. }
  715. case MSM_VIDC_STREAMOFF:
  716. {
  717. struct vb2_queue *q = (struct vb2_queue *)data;
  718. /* ignore */
  719. if (q->type == OUTPUT_MPLANE || q->type == OUTPUT_META_PLANE) {
  720. i_vpr_h(inst, "%s: streamoff of (%s) ignored in state (%s)\n",
  721. __func__, v4l2_type_name(q->type), state_name(inst->state));
  722. return 0;
  723. }
  724. /* disallow */
  725. if (q->type == INPUT_META_PLANE) {
  726. i_vpr_e(inst, "%s: streamoff of (%s) not allowed in state (%s)\n",
  727. __func__, v4l2_type_name(q->type), state_name(inst->state));
  728. return -EINVAL;
  729. }
  730. /* sanitize type field */
  731. if (q->type != INPUT_MPLANE) {
  732. i_vpr_e(inst, "%s: invalid type %d\n", __func__, q->type);
  733. return -EINVAL;
  734. }
  735. rc = msm_vidc_stop_streaming(inst, q);
  736. if (rc)
  737. return rc;
  738. break;
  739. }
  740. case MSM_VIDC_CMD_START:
  741. {
  742. /* disallow if START called for non DRC/drain cases */
  743. if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
  744. i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
  745. __func__, event_name(event), inst->sub_state_name);
  746. return -EBUSY;
  747. }
  748. /* client would call start(resume) to complete DRC/drain sequence */
  749. rc = msm_vidc_start_cmd(inst);
  750. if (rc)
  751. return rc;
  752. break;
  753. }
  754. case MSM_VIDC_CMD_STOP:
  755. {
  756. /* back to back drain not allowed */
  757. if (is_sub_state(inst, MSM_VIDC_DRAIN)) {
  758. i_vpr_e(inst, "%s: drain (%s) not allowed, sub_state (%s)\n\n",
  759. __func__, event_name(event), inst->sub_state_name);
  760. return -EBUSY;
  761. }
  762. rc = msm_vidc_stop_cmd(inst);
  763. if (rc)
  764. return rc;
  765. break;
  766. }
  767. default:
  768. {
  769. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  770. return -EINVAL;
  771. }
  772. }
  773. return rc;
  774. }
  775. static int msm_vidc_output_streaming_state(struct msm_vidc_inst *inst,
  776. enum msm_vidc_event event, void *data)
  777. {
  778. int rc = 0;
  779. if (!inst) {
  780. d_vpr_e("%s: invalid params\n", __func__);
  781. return -EINVAL;
  782. }
  783. /* inst must be locked */
  784. rc = __strict_inst_check(inst, __func__);
  785. if (rc) {
  786. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  787. return -EINVAL;
  788. }
  789. switch (event) {
  790. case MSM_VIDC_BUF_QUEUE:
  791. {
  792. struct msm_vidc_buffer *buf = (struct msm_vidc_buffer *)data;
  793. /* defer meta port */
  794. if (buf->type == MSM_VIDC_BUF_INPUT_META || buf->type == MSM_VIDC_BUF_OUTPUT_META) {
  795. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  796. return 0;
  797. }
  798. /* disallow */
  799. if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT) {
  800. i_vpr_e(inst, "%s: invalid buf type %u\n", __func__, buf->type);
  801. return -EINVAL;
  802. }
  803. /* defer input port */
  804. if (buf->type == MSM_VIDC_BUF_INPUT) {
  805. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  806. return 0;
  807. }
  808. rc = msm_vidc_buf_queue(inst, buf);
  809. if (rc)
  810. return rc;
  811. break;
  812. }
  813. case MSM_VIDC_S_FMT:
  814. {
  815. struct v4l2_format *f = (struct v4l2_format *)data;
  816. /* disallow */
  817. if (f->type == OUTPUT_MPLANE || f->type == OUTPUT_META_PLANE) {
  818. i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
  819. __func__, event_name(event), v4l2_type_name(f->type));
  820. return -EBUSY;
  821. }
  822. rc = msm_vidc_s_fmt(inst, f);
  823. if (rc)
  824. return rc;
  825. break;
  826. }
  827. case MSM_VIDC_S_CTRL:
  828. {
  829. struct v4l2_ctrl *ctrl = (struct v4l2_ctrl *)data;
  830. u32 cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
  831. if (cap_id == INST_CAP_NONE) {
  832. i_vpr_e(inst, "%s: invalid cap_id %u\n", __func__, cap_id);
  833. return -EINVAL;
  834. }
  835. /* disallow */
  836. if (is_encode_session(inst)) {
  837. /* check dynamic allowed if master port is streaming */
  838. if (!(inst->capabilities->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
  839. i_vpr_e(inst, "%s: cap_id %#x not allowed in state %s\n",
  840. __func__, cap_id, state_name(inst->state));
  841. return -EINVAL;
  842. }
  843. }
  844. rc = msm_vidc_s_ctrl(inst, ctrl);
  845. if (rc)
  846. return rc;
  847. break;
  848. }
  849. case MSM_VIDC_REQBUFS:
  850. {
  851. struct v4l2_requestbuffers *b = (struct v4l2_requestbuffers *)data;
  852. /* disallow */
  853. if (b->type == OUTPUT_MPLANE || b->type == OUTPUT_META_PLANE) {
  854. i_vpr_e(inst, "%s: (%s) not allowed for (%s) port\n",
  855. __func__, event_name(event), v4l2_type_name(b->type));
  856. return -EBUSY;
  857. }
  858. rc = msm_vidc_reqbufs(inst, b);
  859. if (rc)
  860. return rc;
  861. break;
  862. }
  863. case MSM_VIDC_STREAMON:
  864. {
  865. struct vb2_queue *q = (struct vb2_queue *)data;
  866. /* disallow */
  867. if (q->type == OUTPUT_MPLANE || q->type == OUTPUT_META_PLANE) {
  868. i_vpr_e(inst, "%s: (%s) not allowed for (%s) type\n",
  869. __func__, event_name(event), v4l2_type_name(q->type));
  870. return -EBUSY;
  871. }
  872. rc = msm_vidc_start_streaming(inst, q);
  873. if (rc)
  874. return rc;
  875. break;
  876. }
  877. case MSM_VIDC_STREAMOFF:
  878. {
  879. struct vb2_queue *q = (struct vb2_queue *)data;
  880. /* ignore */
  881. if (q->type == INPUT_MPLANE || q->type == INPUT_META_PLANE) {
  882. i_vpr_h(inst, "%s: streamoff of (%s) ignored in state (%s)\n",
  883. __func__, v4l2_type_name(q->type), state_name(inst->state));
  884. return 0;
  885. }
  886. /* disallow */
  887. if (q->type == OUTPUT_META_PLANE) {
  888. i_vpr_e(inst, "%s: streamoff of (%s) not allowed in state (%s)\n",
  889. __func__, v4l2_type_name(q->type), state_name(inst->state));
  890. return -EINVAL;
  891. }
  892. /* sanitize type field */
  893. if (q->type != OUTPUT_MPLANE) {
  894. i_vpr_e(inst, "%s: invalid type %d\n", __func__, q->type);
  895. return -EINVAL;
  896. }
  897. rc = msm_vidc_stop_streaming(inst, q);
  898. if (rc)
  899. return rc;
  900. break;
  901. }
  902. case MSM_VIDC_CMD_START:
  903. {
  904. /* disallow if START called for non DRC/drain cases */
  905. if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
  906. i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
  907. __func__, event_name(event), inst->sub_state_name);
  908. return -EBUSY;
  909. }
  910. /* client would call start(resume) to complete DRC/drain sequence */
  911. rc = msm_vidc_start_cmd(inst);
  912. if (rc)
  913. return rc;
  914. break;
  915. }
  916. case MSM_VIDC_CMD_STOP:
  917. {
  918. /* drain not allowed as input is not streaming */
  919. i_vpr_e(inst, "%s: drain (%s) not allowed, sub state %s\n",
  920. __func__, event_name(event), inst->sub_state_name);
  921. return -EBUSY;
  922. }
  923. default: {
  924. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  925. return -EINVAL;
  926. }
  927. }
  928. return rc;
  929. }
  930. static int msm_vidc_streaming_state(struct msm_vidc_inst *inst,
  931. enum msm_vidc_event event, void *data)
  932. {
  933. int rc = 0;
  934. if (!inst) {
  935. d_vpr_e("%s: invalid params\n", __func__);
  936. return -EINVAL;
  937. }
  938. /* inst must be locked */
  939. rc = __strict_inst_check(inst, __func__);
  940. if (rc) {
  941. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  942. return -EINVAL;
  943. }
  944. switch (event) {
  945. case MSM_VIDC_BUF_QUEUE:
  946. {
  947. struct msm_vidc_buffer *buf = (struct msm_vidc_buffer *)data;
  948. /* defer meta port */
  949. if (buf->type == MSM_VIDC_BUF_INPUT_META || buf->type == MSM_VIDC_BUF_OUTPUT_META) {
  950. print_vidc_buffer(VIDC_LOW, "low ", "qbuf deferred", inst, buf);
  951. return 0;
  952. }
  953. /* disallow */
  954. if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT) {
  955. i_vpr_e(inst, "%s: invalid buf type %u\n", __func__, buf->type);
  956. return -EINVAL;
  957. }
  958. rc = msm_vidc_buf_queue(inst, buf);
  959. if (rc)
  960. return rc;
  961. break;
  962. }
  963. case MSM_VIDC_S_CTRL:
  964. {
  965. struct v4l2_ctrl *ctrl = (struct v4l2_ctrl *)data;
  966. u32 cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
  967. if (cap_id == INST_CAP_NONE) {
  968. i_vpr_e(inst, "%s: invalid cap_id %u\n", __func__, cap_id);
  969. return -EINVAL;
  970. }
  971. /* disallow */
  972. if (!(inst->capabilities->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
  973. i_vpr_e(inst, "%s: cap_id %#x not allowed in state %s\n",
  974. __func__, cap_id, state_name(inst->state));
  975. return -EINVAL;
  976. }
  977. rc = msm_vidc_s_ctrl(inst, ctrl);
  978. if (rc)
  979. return rc;
  980. break;
  981. }
  982. case MSM_VIDC_STREAMOFF:
  983. {
  984. struct vb2_queue *q = (struct vb2_queue *)data;
  985. /* disallow */
  986. if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) {
  987. i_vpr_e(inst, "%s: streamoff of (%s) not allowed in state (%s)\n",
  988. __func__, v4l2_type_name(q->type), state_name(inst->state));
  989. return -EINVAL;
  990. }
  991. /* sanitize type field */
  992. if (q->type != INPUT_MPLANE && q->type != OUTPUT_MPLANE) {
  993. i_vpr_e(inst, "%s: invalid type %d\n", __func__, q->type);
  994. return -EINVAL;
  995. }
  996. rc = msm_vidc_stop_streaming(inst, q);
  997. if (rc)
  998. return rc;
  999. break;
  1000. }
  1001. case MSM_VIDC_CMD_START:
  1002. {
  1003. /* disallow if START called for non DRC/drain cases */
  1004. if (!is_drc_pending(inst) && !is_drain_pending(inst)) {
  1005. i_vpr_e(inst, "%s: (%s) not allowed, sub_state (%s)\n",
  1006. __func__, event_name(event), inst->sub_state_name);
  1007. return -EBUSY;
  1008. }
  1009. /* client would call start(resume) to complete DRC/drain sequence */
  1010. rc = msm_vidc_start_cmd(inst);
  1011. if (rc)
  1012. return rc;
  1013. break;
  1014. }
  1015. case MSM_VIDC_CMD_STOP:
  1016. {
  1017. /* back to back drain not allowed */
  1018. if (is_sub_state(inst, MSM_VIDC_DRAIN)) {
  1019. i_vpr_e(inst, "%s: drain (%s) not allowed, sub_state (%s)\n\n",
  1020. __func__, event_name(event), inst->sub_state_name);
  1021. return -EBUSY;
  1022. }
  1023. rc = msm_vidc_stop_cmd(inst);
  1024. if (rc)
  1025. return rc;
  1026. break;
  1027. }
  1028. default: {
  1029. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  1030. return -EINVAL;
  1031. }
  1032. }
  1033. return rc;
  1034. }
  1035. static int msm_vidc_close_state(struct msm_vidc_inst *inst,
  1036. enum msm_vidc_event event, void *data)
  1037. {
  1038. int rc = 0;
  1039. if (!inst) {
  1040. d_vpr_e("%s: invalid params\n", __func__);
  1041. return -EINVAL;
  1042. }
  1043. /* inst must be locked */
  1044. rc = __strict_inst_check(inst, __func__);
  1045. if (rc) {
  1046. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  1047. return -EINVAL;
  1048. }
  1049. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  1050. return -EINVAL;
  1051. }
  1052. static int msm_vidc_error_state(struct msm_vidc_inst *inst,
  1053. enum msm_vidc_event event, void *data)
  1054. {
  1055. int rc = 0;
  1056. if (!inst) {
  1057. d_vpr_e("%s: invalid params\n", __func__);
  1058. return -EINVAL;
  1059. }
  1060. /* inst must be locked */
  1061. rc = __strict_inst_check(inst, __func__);
  1062. if (rc) {
  1063. i_vpr_e(inst, "%s(): inst was not locked\n", __func__);
  1064. return -EINVAL;
  1065. }
  1066. switch (event) {
  1067. case MSM_VIDC_STREAMOFF:
  1068. {
  1069. struct vb2_queue *q = (struct vb2_queue *)data;
  1070. rc = msm_vidc_stop_streaming(inst, q);
  1071. if (rc)
  1072. return rc;
  1073. break;
  1074. }
  1075. default: {
  1076. i_vpr_e(inst, "%s: unexpected event %s\n", __func__, event_name(event));
  1077. return -EINVAL;
  1078. }
  1079. }
  1080. return rc;
  1081. }
  1082. struct msm_vidc_state_handle {
  1083. enum msm_vidc_state state;
  1084. int (*handle)(struct msm_vidc_inst *inst,
  1085. enum msm_vidc_event event, void *data);
  1086. };
  1087. static struct msm_vidc_state_handle *msm_vidc_get_state_handle(
  1088. struct msm_vidc_inst *inst,
  1089. enum msm_vidc_state req_state)
  1090. {
  1091. int cnt;
  1092. struct msm_vidc_state_handle *inst_state_handle = NULL;
  1093. static struct msm_vidc_state_handle state_handle[] = {
  1094. {MSM_VIDC_OPEN, msm_vidc_open_state },
  1095. {MSM_VIDC_INPUT_STREAMING, msm_vidc_input_streaming_state },
  1096. {MSM_VIDC_OUTPUT_STREAMING, msm_vidc_output_streaming_state },
  1097. {MSM_VIDC_STREAMING, msm_vidc_streaming_state },
  1098. {MSM_VIDC_CLOSE, msm_vidc_close_state },
  1099. {MSM_VIDC_ERROR, msm_vidc_error_state },
  1100. };
  1101. for (cnt = 0; cnt < ARRAY_SIZE(state_handle); cnt++) {
  1102. if (state_handle[cnt].state == req_state) {
  1103. inst_state_handle = &state_handle[cnt];
  1104. break;
  1105. }
  1106. }
  1107. /* check if req_state does not exist in the table */
  1108. if (cnt == ARRAY_SIZE(state_handle)) {
  1109. i_vpr_e(inst, "%s: invalid state %s\n", __func__, state_name(req_state));
  1110. return inst_state_handle;
  1111. }
  1112. return inst_state_handle;
  1113. }
  1114. int msm_vidc_update_state(struct msm_vidc_inst *inst,
  1115. enum msm_vidc_state request_state, const char *func)
  1116. {
  1117. struct msm_vidc_state_handle *state_handle = NULL;
  1118. int rc = 0;
  1119. /* get inst state handler for requested state */
  1120. state_handle = msm_vidc_get_state_handle(inst, request_state);
  1121. if (!state_handle)
  1122. return -EINVAL;
  1123. if (request_state == MSM_VIDC_ERROR)
  1124. i_vpr_e(inst, FMT_STRING_STATE_CHANGE,
  1125. func, state_name(request_state), state_name(inst->state));
  1126. else
  1127. i_vpr_h(inst, FMT_STRING_STATE_CHANGE,
  1128. func, state_name(request_state), state_name(inst->state));
  1129. trace_msm_vidc_common_state_change(inst, func, state_name(inst->state),
  1130. state_name(request_state));
  1131. /* finally update inst state and handler */
  1132. inst->state = state_handle->state;
  1133. inst->event_handle = state_handle->handle;
  1134. return rc;
  1135. }
  1136. int msm_vidc_change_state(struct msm_vidc_inst *inst,
  1137. enum msm_vidc_state request_state, const char *func)
  1138. {
  1139. enum msm_vidc_allow allow;
  1140. int rc;
  1141. if (!inst) {
  1142. d_vpr_e("%s: invalid params\n", __func__);
  1143. return -EINVAL;
  1144. }
  1145. if (is_session_error(inst)) {
  1146. i_vpr_h(inst,
  1147. "%s: inst is in bad state, can not change state to %s\n",
  1148. func, state_name(request_state));
  1149. return 0;
  1150. }
  1151. /* current and requested state is same */
  1152. if (inst->state == request_state)
  1153. return 0;
  1154. /* check if requested state movement is allowed */
  1155. allow = msm_vidc_allow_state_change(inst, request_state);
  1156. if (allow != MSM_VIDC_ALLOW) {
  1157. i_vpr_e(inst, "%s: %s state change %s -> %s\n", func,
  1158. allow_name(allow), state_name(inst->state),
  1159. state_name(request_state));
  1160. return (allow == MSM_VIDC_DISALLOW ? -EINVAL : 0);
  1161. }
  1162. /* go ahead and update inst state */
  1163. rc = msm_vidc_update_state(inst, request_state, func);
  1164. if (rc)
  1165. return rc;
  1166. return 0;
  1167. }
  1168. struct msm_vidc_sub_state_allow {
  1169. enum msm_vidc_state state;
  1170. enum msm_vidc_allow allow;
  1171. u32 sub_state_mask;
  1172. };
  1173. static int msm_vidc_set_sub_state(struct msm_vidc_inst *inst,
  1174. enum msm_vidc_sub_state sub_state, const char *func)
  1175. {
  1176. char sub_state_name[MAX_NAME_LENGTH];
  1177. int cnt, rc = 0;
  1178. static struct msm_vidc_sub_state_allow sub_state_allow[] = {
  1179. /* state, allow, sub_state */
  1180. {MSM_VIDC_OPEN, MSM_VIDC_DISALLOW, MSM_VIDC_DRC |
  1181. MSM_VIDC_DRAIN |
  1182. MSM_VIDC_DRC_LAST_BUFFER |
  1183. MSM_VIDC_DRAIN_LAST_BUFFER |
  1184. MSM_VIDC_INPUT_PAUSE |
  1185. MSM_VIDC_OUTPUT_PAUSE },
  1186. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_DISALLOW, MSM_VIDC_DRC_LAST_BUFFER |
  1187. MSM_VIDC_DRAIN_LAST_BUFFER |
  1188. MSM_VIDC_OUTPUT_PAUSE },
  1189. {MSM_VIDC_INPUT_STREAMING, MSM_VIDC_ALLOW, MSM_VIDC_DRC |
  1190. MSM_VIDC_DRAIN |
  1191. MSM_VIDC_INPUT_PAUSE },
  1192. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_DISALLOW, MSM_VIDC_DRC |
  1193. MSM_VIDC_DRAIN |
  1194. MSM_VIDC_INPUT_PAUSE },
  1195. {MSM_VIDC_OUTPUT_STREAMING, MSM_VIDC_ALLOW, MSM_VIDC_DRC_LAST_BUFFER |
  1196. MSM_VIDC_DRAIN_LAST_BUFFER |
  1197. MSM_VIDC_OUTPUT_PAUSE },
  1198. {MSM_VIDC_STREAMING, MSM_VIDC_ALLOW, MSM_VIDC_DRC |
  1199. MSM_VIDC_DRAIN |
  1200. MSM_VIDC_DRC_LAST_BUFFER |
  1201. MSM_VIDC_DRAIN_LAST_BUFFER |
  1202. MSM_VIDC_INPUT_PAUSE |
  1203. MSM_VIDC_OUTPUT_PAUSE },
  1204. {MSM_VIDC_CLOSE, MSM_VIDC_ALLOW, MSM_VIDC_DRC |
  1205. MSM_VIDC_DRAIN |
  1206. MSM_VIDC_DRC_LAST_BUFFER |
  1207. MSM_VIDC_DRAIN_LAST_BUFFER |
  1208. MSM_VIDC_INPUT_PAUSE |
  1209. MSM_VIDC_OUTPUT_PAUSE },
  1210. {MSM_VIDC_ERROR, MSM_VIDC_ALLOW, MSM_VIDC_DRC |
  1211. MSM_VIDC_DRAIN |
  1212. MSM_VIDC_DRC_LAST_BUFFER |
  1213. MSM_VIDC_DRAIN_LAST_BUFFER |
  1214. MSM_VIDC_INPUT_PAUSE |
  1215. MSM_VIDC_OUTPUT_PAUSE },
  1216. };
  1217. if (!inst) {
  1218. d_vpr_e("%s: invalid params\n", __func__);
  1219. return -EINVAL;
  1220. }
  1221. /* no substate to update */
  1222. if (!sub_state)
  1223. return 0;
  1224. /* check if any substate is disallowed */
  1225. for (cnt = 0; cnt < ARRAY_SIZE(sub_state_allow); cnt++) {
  1226. /* skip other states */
  1227. if (sub_state_allow[cnt].state != inst->state)
  1228. continue;
  1229. /* continue if not disallowed */
  1230. if (sub_state_allow[cnt].allow != MSM_VIDC_DISALLOW)
  1231. continue;
  1232. if (sub_state_allow[cnt].sub_state_mask & sub_state) {
  1233. prepare_sub_state_name(sub_state, sub_state_name, sizeof(sub_state_name));
  1234. i_vpr_e(inst, "%s: state (%s), disallow substate (%s)\n",
  1235. func, state_name(inst->state), sub_state_name);
  1236. return -EINVAL;
  1237. }
  1238. }
  1239. /* remove ignorable substates from a given substate */
  1240. for (cnt = 0; cnt < ARRAY_SIZE(sub_state_allow); cnt++) {
  1241. /* skip other states */
  1242. if (sub_state_allow[cnt].state != inst->state)
  1243. continue;
  1244. /* continue if not ignored */
  1245. if (sub_state_allow[cnt].allow != MSM_VIDC_IGNORE)
  1246. continue;
  1247. if (sub_state_allow[cnt].sub_state_mask & sub_state) {
  1248. prepare_sub_state_name(sub_state, sub_state_name, sizeof(sub_state_name));
  1249. i_vpr_h(inst, "%s: state (%s), ignore substate (%s)\n",
  1250. func, state_name(inst->state), sub_state_name);
  1251. /* remove ignorable substate bits from actual */
  1252. sub_state &= ~(sub_state_allow[cnt].sub_state_mask & sub_state);
  1253. break;
  1254. }
  1255. }
  1256. /* check if all substate bits are allowed */
  1257. for (cnt = 0; cnt < ARRAY_SIZE(sub_state_allow); cnt++) {
  1258. /* skip other states */
  1259. if (sub_state_allow[cnt].state != inst->state)
  1260. continue;
  1261. /* continue if not allowed */
  1262. if (sub_state_allow[cnt].allow != MSM_VIDC_ALLOW)
  1263. continue;
  1264. if ((sub_state_allow[cnt].sub_state_mask & sub_state) != sub_state) {
  1265. prepare_sub_state_name(sub_state, sub_state_name, sizeof(sub_state_name));
  1266. i_vpr_e(inst, "%s: state (%s), not all substates allowed (%s)\n",
  1267. func, state_name(inst->state), sub_state_name);
  1268. return -EINVAL;
  1269. }
  1270. }
  1271. /* update substate */
  1272. inst->sub_state |= sub_state;
  1273. return rc;
  1274. }
  1275. int msm_vidc_change_sub_state(struct msm_vidc_inst *inst,
  1276. enum msm_vidc_sub_state clear_sub_state,
  1277. enum msm_vidc_sub_state set_sub_state, const char *func)
  1278. {
  1279. enum msm_vidc_sub_state prev_sub_state;
  1280. int rc = 0;
  1281. if (!inst) {
  1282. d_vpr_e("%s: invalid params\n", __func__);
  1283. return -EINVAL;
  1284. }
  1285. if (is_session_error(inst)) {
  1286. i_vpr_h(inst,
  1287. "%s: inst is in bad state, can not change sub state\n", func);
  1288. return 0;
  1289. }
  1290. /* final value will not change */
  1291. if (!clear_sub_state && !set_sub_state)
  1292. return 0;
  1293. /* sanitize clear & set value */
  1294. if ((clear_sub_state & set_sub_state) ||
  1295. (set_sub_state > MSM_VIDC_MAX_SUB_STATE_VALUE) ||
  1296. (clear_sub_state > MSM_VIDC_MAX_SUB_STATE_VALUE)) {
  1297. i_vpr_e(inst, "%s: invalid sub states to clear %#x or set %#x\n",
  1298. func, clear_sub_state, set_sub_state);
  1299. return -EINVAL;
  1300. }
  1301. prev_sub_state = inst->sub_state;
  1302. /* set sub state */
  1303. rc = msm_vidc_set_sub_state(inst, set_sub_state, __func__);
  1304. if (rc)
  1305. return rc;
  1306. /* clear sub state */
  1307. inst->sub_state &= ~clear_sub_state;
  1308. /* print substates only when there is a change */
  1309. if (inst->sub_state != prev_sub_state) {
  1310. rc = prepare_sub_state_name(inst->sub_state, inst->sub_state_name,
  1311. sizeof(inst->sub_state_name));
  1312. if (!rc)
  1313. i_vpr_h(inst, "%s: state %s and sub state changed to %s\n",
  1314. func, state_name(inst->state), inst->sub_state_name);
  1315. }
  1316. return 0;
  1317. }