hfi.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/io.h>
  6. #include <linux/delay.h>
  7. #include <linux/slab.h>
  8. #include <linux/random.h>
  9. #include <asm/errno.h>
  10. #include <linux/timer.h>
  11. #include <media/cam_icp.h>
  12. #include <linux/iopoll.h>
  13. #include "cam_presil_hw_access.h"
  14. #include "cam_io_util.h"
  15. #include "hfi_reg.h"
  16. #include "hfi_sys_defs.h"
  17. #include "hfi_session_defs.h"
  18. #include "hfi_intf.h"
  19. #include "cam_icp_hw_mgr_intf.h"
  20. #include "cam_debug_util.h"
  21. #include "cam_compat.h"
  22. #include "cam_soc_util.h"
  23. #define HFI_VERSION_INFO_MAJOR_VAL 1
  24. #define HFI_VERSION_INFO_MINOR_VAL 1
  25. #define HFI_VERSION_INFO_STEP_VAL 0
  26. #define HFI_VERSION_INFO_STEP_VAL 0
  27. #define HFI_VERSION_INFO_MAJOR_BMSK 0xFF000000
  28. #define HFI_VERSION_INFO_MAJOR_SHFT 24
  29. #define HFI_VERSION_INFO_MINOR_BMSK 0xFFFF00
  30. #define HFI_VERSION_INFO_MINOR_SHFT 8
  31. #define HFI_VERSION_INFO_STEP_BMSK 0xFF
  32. #define HFI_VERSION_INFO_STEP_SHFT 0
  33. /* TO DO Lower timeout value */
  34. #define HFI_POLL_DELAY_US 10
  35. #define HFI_POLL_TIMEOUT_US 1500000
  36. static struct hfi_info *g_hfi;
  37. unsigned int g_icp_mmu_hdl;
  38. static DEFINE_MUTEX(hfi_cmd_q_mutex);
  39. static DEFINE_MUTEX(hfi_msg_q_mutex);
  40. static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem);
  41. static int cam_hfi_presil_set_init_request(void);
  42. #ifndef CONFIG_CAM_PRESIL
  43. static void hfi_irq_raise(struct hfi_info *hfi)
  44. {
  45. if (hfi->ops.irq_raise)
  46. hfi->ops.irq_raise(hfi->priv);
  47. }
  48. #endif
  49. static void hfi_irq_enable(struct hfi_info *hfi)
  50. {
  51. if (hfi->ops.irq_enable)
  52. hfi->ops.irq_enable(hfi->priv);
  53. }
  54. static void __iomem *hfi_iface_addr(struct hfi_info *hfi)
  55. {
  56. void __iomem *ret = NULL;
  57. if (hfi->ops.iface_addr)
  58. ret = hfi->ops.iface_addr(hfi->priv);
  59. return IS_ERR_OR_NULL(ret) ? NULL : ret;
  60. }
  61. static void hfi_queue_dump(uint32_t *dwords, int count)
  62. {
  63. int i;
  64. int rows;
  65. int remaining;
  66. rows = count / 4;
  67. remaining = count % 4;
  68. for (i = 0; i < rows; i++, dwords += 4)
  69. CAM_DBG(CAM_HFI,
  70. "word[%04d]: 0x%08x 0x%08x 0x%08x 0x%08x",
  71. i * 4, dwords[0], dwords[1], dwords[2], dwords[3]);
  72. if (remaining == 1)
  73. CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x", rows * 4, dwords[0]);
  74. else if (remaining == 2)
  75. CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x 0x%08x",
  76. rows * 4, dwords[0], dwords[1]);
  77. else if (remaining == 3)
  78. CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x 0x%08x 0x%08x",
  79. rows * 4, dwords[0], dwords[1], dwords[2]);
  80. }
  81. void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst)
  82. {
  83. struct hfi_mem_info *hfi_mem = &g_hfi->map;
  84. struct hfi_qtbl *qtbl;
  85. struct hfi_q_hdr *q_hdr;
  86. uint32_t *dwords;
  87. int num_dwords;
  88. if (!hfi_mem) {
  89. CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues");
  90. return;
  91. }
  92. qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva;
  93. q_hdr = &qtbl->q_hdr[Q_CMD];
  94. dwords = (uint32_t *)hfi_mem->cmd_q.kva;
  95. num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  96. memcpy(dst->cmd_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES);
  97. q_hdr = &qtbl->q_hdr[Q_MSG];
  98. dwords = (uint32_t *)hfi_mem->msg_q.kva;
  99. memcpy(dst->msg_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES);
  100. dst->msg_q_state = g_hfi->msg_q_state;
  101. dst->cmd_q_state = g_hfi->cmd_q_state;
  102. }
  103. void cam_hfi_queue_dump(void)
  104. {
  105. struct hfi_mem_info *hfi_mem = &g_hfi->map;
  106. struct hfi_qtbl *qtbl;
  107. struct hfi_q_hdr *q_hdr;
  108. uint32_t *dwords;
  109. int num_dwords;
  110. if (!hfi_mem) {
  111. CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues");
  112. return;
  113. }
  114. qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva;
  115. CAM_DBG(CAM_HFI,
  116. "qtbl header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u",
  117. qtbl->q_tbl_hdr.qtbl_version,
  118. qtbl->q_tbl_hdr.qtbl_size,
  119. qtbl->q_tbl_hdr.qtbl_num_q,
  120. qtbl->q_tbl_hdr.qtbl_qhdr_size);
  121. q_hdr = &qtbl->q_hdr[Q_CMD];
  122. CAM_DBG(CAM_HFI,
  123. "cmd_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
  124. hfi_mem->cmd_q.iova,
  125. q_hdr->qhdr_q_size,
  126. q_hdr->qhdr_read_idx,
  127. q_hdr->qhdr_write_idx);
  128. dwords = (uint32_t *)hfi_mem->cmd_q.kva;
  129. num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  130. hfi_queue_dump(dwords, num_dwords);
  131. q_hdr = &qtbl->q_hdr[Q_MSG];
  132. CAM_DBG(CAM_HFI,
  133. "msg_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
  134. hfi_mem->msg_q.iova,
  135. q_hdr->qhdr_q_size,
  136. q_hdr->qhdr_read_idx,
  137. q_hdr->qhdr_write_idx);
  138. dwords = (uint32_t *)hfi_mem->msg_q.kva;
  139. num_dwords = ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  140. hfi_queue_dump(dwords, num_dwords);
  141. }
  142. #ifndef CONFIG_CAM_PRESIL
  143. int hfi_write_cmd(void *cmd_ptr)
  144. {
  145. uint32_t size_in_words, empty_space, new_write_idx, read_idx, temp;
  146. uint32_t *write_q, *write_ptr;
  147. struct hfi_qtbl *q_tbl;
  148. struct hfi_q_hdr *q;
  149. int rc = 0;
  150. if (!cmd_ptr) {
  151. CAM_ERR(CAM_HFI, "command is null");
  152. return -EINVAL;
  153. }
  154. mutex_lock(&hfi_cmd_q_mutex);
  155. if (!g_hfi) {
  156. CAM_ERR(CAM_HFI, "HFI interface not setup");
  157. rc = -ENODEV;
  158. goto err;
  159. }
  160. if (g_hfi->hfi_state != HFI_READY ||
  161. !g_hfi->cmd_q_state) {
  162. CAM_ERR(CAM_HFI, "HFI state: %u, cmd q state: %u",
  163. g_hfi->hfi_state, g_hfi->cmd_q_state);
  164. rc = -ENODEV;
  165. goto err;
  166. }
  167. q_tbl = (struct hfi_qtbl *)g_hfi->map.qtbl.kva;
  168. q = &q_tbl->q_hdr[Q_CMD];
  169. write_q = (uint32_t *)g_hfi->map.cmd_q.kva;
  170. size_in_words = (*(uint32_t *)cmd_ptr) >> BYTE_WORD_SHIFT;
  171. if (!size_in_words) {
  172. CAM_DBG(CAM_HFI, "failed");
  173. rc = -EINVAL;
  174. goto err;
  175. }
  176. read_idx = q->qhdr_read_idx;
  177. empty_space = (q->qhdr_write_idx >= read_idx) ?
  178. (q->qhdr_q_size - (q->qhdr_write_idx - read_idx)) :
  179. (read_idx - q->qhdr_write_idx);
  180. if (empty_space <= size_in_words) {
  181. CAM_ERR(CAM_HFI, "failed: empty space %u, size_in_words %u",
  182. empty_space, size_in_words);
  183. rc = -EIO;
  184. goto err;
  185. }
  186. new_write_idx = q->qhdr_write_idx + size_in_words;
  187. write_ptr = (uint32_t *)(write_q + q->qhdr_write_idx);
  188. if (new_write_idx < q->qhdr_q_size) {
  189. memcpy(write_ptr, (uint8_t *)cmd_ptr,
  190. size_in_words << BYTE_WORD_SHIFT);
  191. } else {
  192. new_write_idx -= q->qhdr_q_size;
  193. temp = (size_in_words - new_write_idx) << BYTE_WORD_SHIFT;
  194. memcpy(write_ptr, (uint8_t *)cmd_ptr, temp);
  195. memcpy(write_q, (uint8_t *)cmd_ptr + temp,
  196. new_write_idx << BYTE_WORD_SHIFT);
  197. }
  198. /*
  199. * To make sure command data in a command queue before
  200. * updating write index
  201. */
  202. wmb();
  203. q->qhdr_write_idx = new_write_idx;
  204. /*
  205. * Before raising interrupt make sure command data is ready for
  206. * firmware to process
  207. */
  208. wmb();
  209. hfi_irq_raise(g_hfi);
  210. /* Ensure HOST2ICP trigger is received by FW */
  211. wmb();
  212. err:
  213. mutex_unlock(&hfi_cmd_q_mutex);
  214. return rc;
  215. }
  216. int hfi_read_message(uint32_t *pmsg, uint8_t q_id,
  217. uint32_t *words_read)
  218. {
  219. struct hfi_qtbl *q_tbl_ptr;
  220. struct hfi_q_hdr *q;
  221. uint32_t new_read_idx, size_in_words, word_diff, temp;
  222. uint32_t *read_q, *read_ptr, *write_ptr;
  223. uint32_t size_upper_bound = 0;
  224. int rc = 0;
  225. if (!pmsg) {
  226. CAM_ERR(CAM_HFI, "Invalid msg");
  227. return -EINVAL;
  228. }
  229. if (q_id > Q_DBG) {
  230. CAM_ERR(CAM_HFI, "Invalid q :%u", q_id);
  231. return -EINVAL;
  232. }
  233. mutex_lock(&hfi_msg_q_mutex);
  234. if (!g_hfi) {
  235. CAM_ERR(CAM_HFI, "hfi not set up yet");
  236. rc = -ENODEV;
  237. goto err;
  238. }
  239. if ((g_hfi->hfi_state != HFI_READY) ||
  240. !g_hfi->msg_q_state) {
  241. CAM_ERR(CAM_HFI, "hfi state: %u, msg q state: %u",
  242. g_hfi->hfi_state, g_hfi->msg_q_state);
  243. rc = -ENODEV;
  244. goto err;
  245. }
  246. q_tbl_ptr = (struct hfi_qtbl *)g_hfi->map.qtbl.kva;
  247. q = &q_tbl_ptr->q_hdr[q_id];
  248. if (q->qhdr_read_idx == q->qhdr_write_idx) {
  249. CAM_DBG(CAM_HFI, "Q not ready, state:%u, r idx:%u, w idx:%u",
  250. g_hfi->hfi_state, q->qhdr_read_idx, q->qhdr_write_idx);
  251. rc = -EIO;
  252. goto err;
  253. }
  254. if (q_id == Q_MSG) {
  255. read_q = (uint32_t *)g_hfi->map.msg_q.kva;
  256. size_upper_bound = ICP_HFI_MAX_PKT_SIZE_MSGQ_IN_WORDS;
  257. } else {
  258. read_q = (uint32_t *)g_hfi->map.dbg_q.kva;
  259. size_upper_bound = ICP_HFI_MAX_PKT_SIZE_IN_WORDS;
  260. }
  261. read_ptr = (uint32_t *)(read_q + q->qhdr_read_idx);
  262. write_ptr = (uint32_t *)(read_q + q->qhdr_write_idx);
  263. if (write_ptr > read_ptr)
  264. size_in_words = write_ptr - read_ptr;
  265. else {
  266. word_diff = read_ptr - write_ptr;
  267. if (q_id == Q_MSG)
  268. size_in_words = (ICP_MSG_Q_SIZE_IN_BYTES >>
  269. BYTE_WORD_SHIFT) - word_diff;
  270. else
  271. size_in_words = (ICP_DBG_Q_SIZE_IN_BYTES >>
  272. BYTE_WORD_SHIFT) - word_diff;
  273. }
  274. if ((size_in_words == 0) ||
  275. (size_in_words > size_upper_bound)) {
  276. CAM_ERR(CAM_HFI, "invalid HFI message packet size - 0x%08x",
  277. size_in_words << BYTE_WORD_SHIFT);
  278. q->qhdr_read_idx = q->qhdr_write_idx;
  279. rc = -EIO;
  280. goto err;
  281. }
  282. new_read_idx = q->qhdr_read_idx + size_in_words;
  283. if (new_read_idx < q->qhdr_q_size) {
  284. memcpy(pmsg, read_ptr, size_in_words << BYTE_WORD_SHIFT);
  285. } else {
  286. new_read_idx -= q->qhdr_q_size;
  287. temp = (size_in_words - new_read_idx) << BYTE_WORD_SHIFT;
  288. memcpy(pmsg, read_ptr, temp);
  289. memcpy((uint8_t *)pmsg + temp, read_q,
  290. new_read_idx << BYTE_WORD_SHIFT);
  291. }
  292. q->qhdr_read_idx = new_read_idx;
  293. *words_read = size_in_words;
  294. /* Memory Barrier to make sure message
  295. * queue parameters are updated after read
  296. */
  297. wmb();
  298. err:
  299. mutex_unlock(&hfi_msg_q_mutex);
  300. return rc;
  301. }
  302. #endif /* #ifndef CONFIG_CAM_PRESIL */
  303. int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg)
  304. {
  305. uint8_t *prop;
  306. struct hfi_cmd_prop *dbg_prop;
  307. uint32_t size = 0;
  308. size = sizeof(struct hfi_cmd_prop) +
  309. sizeof(struct hfi_cmd_ubwc_cfg);
  310. CAM_DBG(CAM_HFI,
  311. "size of ubwc %u, ubwc_cfg [rd-0x%x,wr-0x%x]",
  312. size, ubwc_cfg[0], ubwc_cfg[1]);
  313. prop = kzalloc(size, GFP_KERNEL);
  314. if (!prop)
  315. return -ENOMEM;
  316. dbg_prop = (struct hfi_cmd_prop *)prop;
  317. dbg_prop->size = size;
  318. dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  319. dbg_prop->num_prop = 1;
  320. dbg_prop->prop_data[0] = HFI_PROP_SYS_UBWC_CFG;
  321. dbg_prop->prop_data[1] = ubwc_cfg[0];
  322. dbg_prop->prop_data[2] = ubwc_cfg[1];
  323. hfi_write_cmd(prop);
  324. kfree(prop);
  325. return 0;
  326. }
  327. int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg,
  328. uint32_t *ubwc_bps_cfg)
  329. {
  330. uint8_t *prop;
  331. struct hfi_cmd_prop *dbg_prop;
  332. uint32_t size = 0;
  333. size = sizeof(struct hfi_cmd_prop) +
  334. sizeof(struct hfi_cmd_ubwc_cfg_ext);
  335. CAM_DBG(CAM_HFI,
  336. "size of ubwc %u, ubwc_ipe_cfg[rd-0x%x,wr-0x%x] ubwc_bps_cfg[rd-0x%x,wr-0x%x]",
  337. size, ubwc_ipe_cfg[0], ubwc_ipe_cfg[1],
  338. ubwc_bps_cfg[0], ubwc_bps_cfg[1]);
  339. prop = kzalloc(size, GFP_KERNEL);
  340. if (!prop)
  341. return -ENOMEM;
  342. dbg_prop = (struct hfi_cmd_prop *)prop;
  343. dbg_prop->size = size;
  344. dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  345. dbg_prop->num_prop = 1;
  346. dbg_prop->prop_data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG_EX;
  347. dbg_prop->prop_data[1] = ubwc_bps_cfg[0];
  348. dbg_prop->prop_data[2] = ubwc_bps_cfg[1];
  349. dbg_prop->prop_data[3] = ubwc_ipe_cfg[0];
  350. dbg_prop->prop_data[4] = ubwc_ipe_cfg[1];
  351. hfi_write_cmd(prop);
  352. kfree(prop);
  353. return 0;
  354. }
  355. int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info)
  356. {
  357. uint8_t *prop;
  358. struct hfi_cmd_prop *dbg_prop;
  359. uint32_t size = 0;
  360. size = sizeof(struct hfi_cmd_prop) +
  361. sizeof(struct hfi_ipe_bps_pc);
  362. prop = kzalloc(size, GFP_KERNEL);
  363. if (!prop)
  364. return -ENOMEM;
  365. dbg_prop = (struct hfi_cmd_prop *)prop;
  366. dbg_prop->size = size;
  367. dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  368. dbg_prop->num_prop = 1;
  369. dbg_prop->prop_data[0] = HFI_PROP_SYS_IPEBPS_PC;
  370. dbg_prop->prop_data[1] = enable;
  371. dbg_prop->prop_data[2] = core_info;
  372. hfi_write_cmd(prop);
  373. kfree(prop);
  374. return 0;
  375. }
  376. int hfi_set_debug_level(u64 icp_dbg_type, uint32_t lvl)
  377. {
  378. uint8_t *prop;
  379. struct hfi_cmd_prop *dbg_prop;
  380. uint32_t size = 0, val;
  381. val = HFI_DEBUG_MSG_LOW |
  382. HFI_DEBUG_MSG_MEDIUM |
  383. HFI_DEBUG_MSG_HIGH |
  384. HFI_DEBUG_MSG_ERROR |
  385. HFI_DEBUG_MSG_FATAL |
  386. HFI_DEBUG_MSG_PERF |
  387. HFI_DEBUG_CFG_WFI |
  388. HFI_DEBUG_CFG_ARM9WD;
  389. if (lvl > val)
  390. return -EINVAL;
  391. if (g_hfi)
  392. g_hfi->dbg_lvl = lvl;
  393. size = sizeof(struct hfi_cmd_prop) +
  394. sizeof(struct hfi_debug);
  395. prop = kzalloc(size, GFP_KERNEL);
  396. if (!prop)
  397. return -ENOMEM;
  398. dbg_prop = (struct hfi_cmd_prop *)prop;
  399. dbg_prop->size = size;
  400. dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  401. dbg_prop->num_prop = 1;
  402. dbg_prop->prop_data[0] = HFI_PROP_SYS_DEBUG_CFG;
  403. dbg_prop->prop_data[1] = lvl;
  404. dbg_prop->prop_data[2] = icp_dbg_type;
  405. hfi_write_cmd(prop);
  406. kfree(prop);
  407. return 0;
  408. }
  409. int hfi_set_fw_dump_level(uint32_t lvl)
  410. {
  411. uint8_t *prop = NULL;
  412. struct hfi_cmd_prop *fw_dump_level_switch_prop = NULL;
  413. uint32_t size = 0;
  414. CAM_DBG(CAM_HFI, "fw dump ENTER");
  415. size = sizeof(struct hfi_cmd_prop) + sizeof(lvl);
  416. prop = kzalloc(size, GFP_KERNEL);
  417. if (!prop)
  418. return -ENOMEM;
  419. fw_dump_level_switch_prop = (struct hfi_cmd_prop *)prop;
  420. fw_dump_level_switch_prop->size = size;
  421. fw_dump_level_switch_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  422. fw_dump_level_switch_prop->num_prop = 1;
  423. fw_dump_level_switch_prop->prop_data[0] = HFI_PROP_SYS_FW_DUMP_CFG;
  424. fw_dump_level_switch_prop->prop_data[1] = lvl;
  425. CAM_DBG(CAM_HFI, "prop->size = %d\n"
  426. "prop->pkt_type = %d\n"
  427. "prop->num_prop = %d\n"
  428. "prop->prop_data[0] = %d\n"
  429. "prop->prop_data[1] = %d\n",
  430. fw_dump_level_switch_prop->size,
  431. fw_dump_level_switch_prop->pkt_type,
  432. fw_dump_level_switch_prop->num_prop,
  433. fw_dump_level_switch_prop->prop_data[0],
  434. fw_dump_level_switch_prop->prop_data[1]);
  435. hfi_write_cmd(prop);
  436. kfree(prop);
  437. return 0;
  438. }
  439. int hfi_send_freq_info(int32_t freq)
  440. {
  441. uint8_t *prop = NULL;
  442. struct hfi_cmd_prop *dbg_prop = NULL;
  443. uint32_t size = 0;
  444. if (!g_hfi) {
  445. CAM_ERR(CAM_HFI, "HFI interface not setup");
  446. return -ENODEV;
  447. }
  448. if (!(g_hfi->dbg_lvl & HFI_DEBUG_MSG_PERF))
  449. return -EINVAL;
  450. size = sizeof(struct hfi_cmd_prop) + sizeof(freq);
  451. prop = kzalloc(size, GFP_KERNEL);
  452. if (!prop)
  453. return -ENOMEM;
  454. dbg_prop = (struct hfi_cmd_prop *)prop;
  455. dbg_prop->size = size;
  456. dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
  457. dbg_prop->num_prop = 1;
  458. dbg_prop->prop_data[0] = HFI_PROPERTY_SYS_ICP_HW_FREQUENCY;
  459. dbg_prop->prop_data[1] = freq;
  460. CAM_DBG(CAM_HFI, "prop->size = %d\n"
  461. "prop->pkt_type = %d\n"
  462. "prop->num_prop = %d\n"
  463. "prop->prop_data[0] = %d\n"
  464. "prop->prop_data[1] = %d\n"
  465. "dbg_lvl = 0x%x\n",
  466. dbg_prop->size,
  467. dbg_prop->pkt_type,
  468. dbg_prop->num_prop,
  469. dbg_prop->prop_data[0],
  470. dbg_prop->prop_data[1],
  471. g_hfi->dbg_lvl);
  472. hfi_write_cmd(prop);
  473. kfree(prop);
  474. return 0;
  475. }
  476. void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size)
  477. {
  478. switch (type) {
  479. case HFI_CMD_SYS_INIT: {
  480. struct hfi_cmd_sys_init init;
  481. memset(&init, 0, sizeof(init));
  482. init.size = sizeof(struct hfi_cmd_sys_init);
  483. init.pkt_type = type;
  484. hfi_write_cmd(&init);
  485. }
  486. break;
  487. case HFI_CMD_SYS_PC_PREP: {
  488. struct hfi_cmd_pc_prep prep;
  489. prep.size = sizeof(struct hfi_cmd_pc_prep);
  490. prep.pkt_type = type;
  491. hfi_write_cmd(&prep);
  492. }
  493. break;
  494. case HFI_CMD_SYS_SET_PROPERTY: {
  495. struct hfi_cmd_prop prop;
  496. if ((uint32_t)data == (uint32_t)HFI_PROP_SYS_DEBUG_CFG) {
  497. prop.size = sizeof(struct hfi_cmd_prop);
  498. prop.pkt_type = type;
  499. prop.num_prop = 1;
  500. prop.prop_data[0] = HFI_PROP_SYS_DEBUG_CFG;
  501. hfi_write_cmd(&prop);
  502. }
  503. }
  504. break;
  505. case HFI_CMD_SYS_GET_PROPERTY:
  506. break;
  507. case HFI_CMD_SYS_PING: {
  508. struct hfi_cmd_ping_pkt ping;
  509. ping.size = sizeof(struct hfi_cmd_ping_pkt);
  510. ping.pkt_type = type;
  511. ping.user_data = (uint64_t)data;
  512. hfi_write_cmd(&ping);
  513. }
  514. break;
  515. case HFI_CMD_SYS_RESET: {
  516. struct hfi_cmd_sys_reset_pkt reset;
  517. reset.size = sizeof(struct hfi_cmd_sys_reset_pkt);
  518. reset.pkt_type = type;
  519. reset.user_data = (uint64_t)data;
  520. hfi_write_cmd(&reset);
  521. }
  522. break;
  523. case HFI_CMD_IPEBPS_CREATE_HANDLE: {
  524. struct hfi_cmd_create_handle handle;
  525. handle.size = sizeof(struct hfi_cmd_create_handle);
  526. handle.pkt_type = type;
  527. handle.handle_type = (uint32_t)data;
  528. handle.user_data1 = 0;
  529. hfi_write_cmd(&handle);
  530. }
  531. break;
  532. case HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT:
  533. break;
  534. default:
  535. CAM_ERR(CAM_HFI, "command not supported :%d", type);
  536. break;
  537. }
  538. }
  539. int hfi_get_hw_caps(void *query_buf)
  540. {
  541. int i = 0;
  542. struct cam_icp_query_cap_cmd *query_cmd = NULL;
  543. if (!query_buf) {
  544. CAM_ERR(CAM_HFI, "query buf is NULL");
  545. return -EINVAL;
  546. }
  547. query_cmd = (struct cam_icp_query_cap_cmd *)query_buf;
  548. query_cmd->fw_version.major = 0x12;
  549. query_cmd->fw_version.minor = 0x12;
  550. query_cmd->fw_version.revision = 0x12;
  551. query_cmd->api_version.major = 0x13;
  552. query_cmd->api_version.minor = 0x13;
  553. query_cmd->api_version.revision = 0x13;
  554. query_cmd->num_ipe = 2;
  555. query_cmd->num_bps = 1;
  556. for (i = 0; i < CAM_ICP_DEV_TYPE_MAX; i++) {
  557. query_cmd->dev_ver[i].dev_type = i;
  558. query_cmd->dev_ver[i].hw_ver.major = 0x34 + i;
  559. query_cmd->dev_ver[i].hw_ver.minor = 0x34 + i;
  560. query_cmd->dev_ver[i].hw_ver.incr = 0x34 + i;
  561. }
  562. return 0;
  563. }
  564. int cam_hfi_resume(struct hfi_mem_info *hfi_mem)
  565. {
  566. int rc = 0;
  567. uint32_t fw_version, status = 0;
  568. void __iomem *icp_base = hfi_iface_addr(g_hfi);
  569. if (!icp_base) {
  570. CAM_ERR(CAM_HFI, "invalid HFI interface address");
  571. return -EINVAL;
  572. }
  573. if (cam_common_read_poll_timeout(icp_base +
  574. HFI_REG_ICP_HOST_INIT_RESPONSE,
  575. HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US,
  576. (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) {
  577. CAM_ERR(CAM_HFI, "response poll timed out: status=0x%08x",
  578. status);
  579. return -ETIMEDOUT;
  580. }
  581. hfi_irq_enable(g_hfi);
  582. fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION);
  583. CAM_DBG(CAM_HFI, "fw version : [%x]", fw_version);
  584. cam_io_w_mb((uint32_t)hfi_mem->qtbl.iova, icp_base + HFI_REG_QTBL_PTR);
  585. cam_io_w_mb((uint32_t)hfi_mem->sfr_buf.iova,
  586. icp_base + HFI_REG_SFR_PTR);
  587. cam_io_w_mb((uint32_t)hfi_mem->shmem.iova,
  588. icp_base + HFI_REG_SHARED_MEM_PTR);
  589. cam_io_w_mb((uint32_t)hfi_mem->shmem.len,
  590. icp_base + HFI_REG_SHARED_MEM_SIZE);
  591. cam_io_w_mb((uint32_t)hfi_mem->sec_heap.iova,
  592. icp_base + HFI_REG_SECONDARY_HEAP_PTR);
  593. cam_io_w_mb((uint32_t)hfi_mem->sec_heap.len,
  594. icp_base + HFI_REG_SECONDARY_HEAP_SIZE);
  595. cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
  596. icp_base + HFI_REG_QDSS_IOVA);
  597. cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
  598. icp_base + HFI_REG_QDSS_IOVA_SIZE);
  599. cam_io_w_mb((uint32_t)hfi_mem->io_mem.iova,
  600. icp_base + HFI_REG_IO_REGION_IOVA);
  601. cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
  602. icp_base + HFI_REG_IO_REGION_SIZE);
  603. cam_io_w_mb((uint32_t)hfi_mem->io_mem2.iova,
  604. icp_base + HFI_REG_IO2_REGION_IOVA);
  605. cam_io_w_mb((uint32_t)hfi_mem->io_mem2.len,
  606. icp_base + HFI_REG_IO2_REGION_SIZE);
  607. cam_io_w_mb((uint32_t)hfi_mem->fw_uncached.iova,
  608. icp_base + HFI_REG_FWUNCACHED_REGION_IOVA);
  609. cam_io_w_mb((uint32_t)hfi_mem->fw_uncached.len,
  610. icp_base + HFI_REG_FWUNCACHED_REGION_SIZE);
  611. CAM_DBG(CAM_HFI, "IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]",
  612. hfi_mem->io_mem.iova, hfi_mem->io_mem.len,
  613. hfi_mem->io_mem2.iova, hfi_mem->io_mem2.len);
  614. CAM_DBG(CAM_HFI, "FwUncached : [0x%x 0x%x] Shared [0x%x 0x%x]",
  615. hfi_mem->fw_uncached.iova, hfi_mem->fw_uncached.len,
  616. hfi_mem->shmem.iova, hfi_mem->shmem.len);
  617. CAM_DBG(CAM_HFI, "SecHeap : [0x%x 0x%x] QDSS [0x%x 0x%x]",
  618. hfi_mem->sec_heap.iova, hfi_mem->sec_heap.len,
  619. hfi_mem->qdss.iova, hfi_mem->qdss.len);
  620. CAM_DBG(CAM_HFI, "QTbl : [0x%x 0x%x] Sfr [0x%x 0x%x]",
  621. hfi_mem->qtbl.iova, hfi_mem->qtbl.len,
  622. hfi_mem->sfr_buf.iova, hfi_mem->sfr_buf.len);
  623. return rc;
  624. }
  625. int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
  626. void *priv, uint8_t event_driven_mode)
  627. {
  628. int rc = 0;
  629. uint32_t status = 0;
  630. struct hfi_qtbl *qtbl;
  631. struct hfi_qtbl_hdr *qtbl_hdr;
  632. struct hfi_q_hdr *cmd_q_hdr, *msg_q_hdr, *dbg_q_hdr;
  633. struct sfr_buf *sfr_buffer;
  634. void __iomem *icp_base;
  635. if (!hfi_mem || !hfi_ops || !priv) {
  636. CAM_ERR(CAM_HFI,
  637. "invalid arg: hfi_mem=%pK hfi_ops=%pK priv=%pK",
  638. hfi_mem, hfi_ops, priv);
  639. return -EINVAL;
  640. }
  641. mutex_lock(&hfi_cmd_q_mutex);
  642. mutex_lock(&hfi_msg_q_mutex);
  643. if (!g_hfi) {
  644. g_hfi = kzalloc(sizeof(struct hfi_info), GFP_KERNEL);
  645. if (!g_hfi) {
  646. rc = -ENOMEM;
  647. goto alloc_fail;
  648. }
  649. }
  650. if (g_hfi->hfi_state != HFI_DEINIT) {
  651. CAM_ERR(CAM_HFI, "hfi_init: invalid state");
  652. rc = -EINVAL;
  653. goto regions_fail;
  654. }
  655. memcpy(&g_hfi->map, hfi_mem, sizeof(g_hfi->map));
  656. g_hfi->hfi_state = HFI_DEINIT;
  657. qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva;
  658. qtbl_hdr = &qtbl->q_tbl_hdr;
  659. qtbl_hdr->qtbl_version = 0xFFFFFFFF;
  660. qtbl_hdr->qtbl_size = sizeof(struct hfi_qtbl);
  661. qtbl_hdr->qtbl_qhdr0_offset = sizeof(struct hfi_qtbl_hdr);
  662. qtbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_q_hdr);
  663. qtbl_hdr->qtbl_num_q = ICP_HFI_NUMBER_OF_QS;
  664. qtbl_hdr->qtbl_num_active_q = ICP_HFI_NUMBER_OF_QS;
  665. /* setup host-to-firmware command queue */
  666. cmd_q_hdr = &qtbl->q_hdr[Q_CMD];
  667. cmd_q_hdr->qhdr_status = QHDR_ACTIVE;
  668. cmd_q_hdr->qhdr_start_addr = hfi_mem->cmd_q.iova;
  669. cmd_q_hdr->qhdr_q_size = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  670. cmd_q_hdr->qhdr_pkt_size = ICP_HFI_VAR_SIZE_PKT;
  671. cmd_q_hdr->qhdr_pkt_drop_cnt = RESET;
  672. cmd_q_hdr->qhdr_read_idx = RESET;
  673. cmd_q_hdr->qhdr_write_idx = RESET;
  674. /* setup firmware-to-Host message queue */
  675. msg_q_hdr = &qtbl->q_hdr[Q_MSG];
  676. msg_q_hdr->qhdr_status = QHDR_ACTIVE;
  677. msg_q_hdr->qhdr_start_addr = hfi_mem->msg_q.iova;
  678. msg_q_hdr->qhdr_q_size = ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  679. msg_q_hdr->qhdr_pkt_size = ICP_HFI_VAR_SIZE_PKT;
  680. msg_q_hdr->qhdr_pkt_drop_cnt = RESET;
  681. msg_q_hdr->qhdr_read_idx = RESET;
  682. msg_q_hdr->qhdr_write_idx = RESET;
  683. /* setup firmware-to-Host message queue */
  684. dbg_q_hdr = &qtbl->q_hdr[Q_DBG];
  685. dbg_q_hdr->qhdr_status = QHDR_ACTIVE;
  686. dbg_q_hdr->qhdr_start_addr = hfi_mem->dbg_q.iova;
  687. dbg_q_hdr->qhdr_q_size = ICP_DBG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
  688. dbg_q_hdr->qhdr_pkt_size = ICP_HFI_VAR_SIZE_PKT;
  689. dbg_q_hdr->qhdr_pkt_drop_cnt = RESET;
  690. dbg_q_hdr->qhdr_read_idx = RESET;
  691. dbg_q_hdr->qhdr_write_idx = RESET;
  692. sfr_buffer = (struct sfr_buf *)hfi_mem->sfr_buf.kva;
  693. sfr_buffer->size = ICP_MSG_SFR_SIZE_IN_BYTES;
  694. switch (event_driven_mode) {
  695. case INTR_MODE:
  696. cmd_q_hdr->qhdr_type = Q_CMD;
  697. cmd_q_hdr->qhdr_rx_wm = SET;
  698. cmd_q_hdr->qhdr_tx_wm = SET;
  699. cmd_q_hdr->qhdr_rx_req = SET;
  700. cmd_q_hdr->qhdr_tx_req = RESET;
  701. cmd_q_hdr->qhdr_rx_irq_status = RESET;
  702. cmd_q_hdr->qhdr_tx_irq_status = RESET;
  703. msg_q_hdr->qhdr_type = Q_MSG;
  704. msg_q_hdr->qhdr_rx_wm = SET;
  705. msg_q_hdr->qhdr_tx_wm = SET;
  706. msg_q_hdr->qhdr_rx_req = SET;
  707. msg_q_hdr->qhdr_tx_req = RESET;
  708. msg_q_hdr->qhdr_rx_irq_status = RESET;
  709. msg_q_hdr->qhdr_tx_irq_status = RESET;
  710. dbg_q_hdr->qhdr_type = Q_DBG;
  711. dbg_q_hdr->qhdr_rx_wm = SET;
  712. dbg_q_hdr->qhdr_tx_wm = SET_WM;
  713. dbg_q_hdr->qhdr_rx_req = RESET;
  714. dbg_q_hdr->qhdr_tx_req = RESET;
  715. dbg_q_hdr->qhdr_rx_irq_status = RESET;
  716. dbg_q_hdr->qhdr_tx_irq_status = RESET;
  717. break;
  718. case POLL_MODE:
  719. cmd_q_hdr->qhdr_type = Q_CMD | TX_EVENT_POLL_MODE_2 |
  720. RX_EVENT_POLL_MODE_2;
  721. msg_q_hdr->qhdr_type = Q_MSG | TX_EVENT_POLL_MODE_2 |
  722. RX_EVENT_POLL_MODE_2;
  723. dbg_q_hdr->qhdr_type = Q_DBG | TX_EVENT_POLL_MODE_2 |
  724. RX_EVENT_POLL_MODE_2;
  725. break;
  726. case WM_MODE:
  727. cmd_q_hdr->qhdr_type = Q_CMD | TX_EVENT_DRIVEN_MODE_2 |
  728. RX_EVENT_DRIVEN_MODE_2;
  729. cmd_q_hdr->qhdr_rx_wm = SET;
  730. cmd_q_hdr->qhdr_tx_wm = SET;
  731. cmd_q_hdr->qhdr_rx_req = RESET;
  732. cmd_q_hdr->qhdr_tx_req = SET;
  733. cmd_q_hdr->qhdr_rx_irq_status = RESET;
  734. cmd_q_hdr->qhdr_tx_irq_status = RESET;
  735. msg_q_hdr->qhdr_type = Q_MSG | TX_EVENT_DRIVEN_MODE_2 |
  736. RX_EVENT_DRIVEN_MODE_2;
  737. msg_q_hdr->qhdr_rx_wm = SET;
  738. msg_q_hdr->qhdr_tx_wm = SET;
  739. msg_q_hdr->qhdr_rx_req = SET;
  740. msg_q_hdr->qhdr_tx_req = RESET;
  741. msg_q_hdr->qhdr_rx_irq_status = RESET;
  742. msg_q_hdr->qhdr_tx_irq_status = RESET;
  743. dbg_q_hdr->qhdr_type = Q_DBG | TX_EVENT_DRIVEN_MODE_2 |
  744. RX_EVENT_DRIVEN_MODE_2;
  745. dbg_q_hdr->qhdr_rx_wm = SET;
  746. dbg_q_hdr->qhdr_tx_wm = SET_WM;
  747. dbg_q_hdr->qhdr_rx_req = RESET;
  748. dbg_q_hdr->qhdr_tx_req = RESET;
  749. dbg_q_hdr->qhdr_rx_irq_status = RESET;
  750. dbg_q_hdr->qhdr_tx_irq_status = RESET;
  751. break;
  752. default:
  753. CAM_ERR(CAM_HFI, "Invalid event driven mode :%u",
  754. event_driven_mode);
  755. break;
  756. }
  757. g_hfi->ops = *hfi_ops;
  758. g_hfi->priv = priv;
  759. icp_base = hfi_iface_addr(g_hfi);
  760. if (!icp_base) {
  761. CAM_ERR(CAM_HFI, "invalid HFI interface address");
  762. rc = -EINVAL;
  763. goto regions_fail;
  764. }
  765. cam_io_w_mb((uint32_t)hfi_mem->qtbl.iova,
  766. icp_base + HFI_REG_QTBL_PTR);
  767. cam_io_w_mb((uint32_t)hfi_mem->sfr_buf.iova,
  768. icp_base + HFI_REG_SFR_PTR);
  769. cam_io_w_mb((uint32_t)hfi_mem->shmem.iova,
  770. icp_base + HFI_REG_SHARED_MEM_PTR);
  771. cam_io_w_mb((uint32_t)hfi_mem->shmem.len,
  772. icp_base + HFI_REG_SHARED_MEM_SIZE);
  773. cam_io_w_mb((uint32_t)hfi_mem->sec_heap.iova,
  774. icp_base + HFI_REG_SECONDARY_HEAP_PTR);
  775. cam_io_w_mb((uint32_t)hfi_mem->sec_heap.len,
  776. icp_base + HFI_REG_SECONDARY_HEAP_SIZE);
  777. cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
  778. icp_base + HFI_REG_QDSS_IOVA);
  779. cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
  780. icp_base + HFI_REG_QDSS_IOVA_SIZE);
  781. cam_io_w_mb((uint32_t)hfi_mem->io_mem.iova,
  782. icp_base + HFI_REG_IO_REGION_IOVA);
  783. cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
  784. icp_base + HFI_REG_IO_REGION_SIZE);
  785. cam_io_w_mb((uint32_t)hfi_mem->io_mem2.iova,
  786. icp_base + HFI_REG_IO2_REGION_IOVA);
  787. cam_io_w_mb((uint32_t)hfi_mem->io_mem2.len,
  788. icp_base + HFI_REG_IO2_REGION_SIZE);
  789. cam_io_w_mb((uint32_t)hfi_mem->fw_uncached.iova,
  790. icp_base + HFI_REG_FWUNCACHED_REGION_IOVA);
  791. cam_io_w_mb((uint32_t)hfi_mem->fw_uncached.len,
  792. icp_base + HFI_REG_FWUNCACHED_REGION_SIZE);
  793. CAM_DBG(CAM_HFI, "IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]",
  794. hfi_mem->io_mem.iova, hfi_mem->io_mem.len,
  795. hfi_mem->io_mem2.iova, hfi_mem->io_mem2.len);
  796. CAM_DBG(CAM_HFI, "FwUncached : [0x%x 0x%x] Shared [0x%x 0x%x]",
  797. hfi_mem->fw_uncached.iova, hfi_mem->fw_uncached.len,
  798. hfi_mem->shmem.iova, hfi_mem->shmem.len);
  799. CAM_DBG(CAM_HFI, "SecHeap : [0x%x 0x%x] QDSS [0x%x 0x%x]",
  800. hfi_mem->sec_heap.iova, hfi_mem->sec_heap.len,
  801. hfi_mem->qdss.iova, hfi_mem->qdss.len);
  802. CAM_DBG(CAM_HFI, "QTbl : [0x%x 0x%x] Sfr [0x%x 0x%x]",
  803. hfi_mem->qtbl.iova, hfi_mem->qtbl.len,
  804. hfi_mem->sfr_buf.iova, hfi_mem->sfr_buf.len);
  805. if (cam_presil_mode_enabled())
  806. cam_hfi_presil_setup(hfi_mem);
  807. cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_SET,
  808. icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
  809. if (cam_presil_mode_enabled())
  810. cam_hfi_presil_set_init_request();
  811. if (cam_common_read_poll_timeout(icp_base +
  812. HFI_REG_ICP_HOST_INIT_RESPONSE,
  813. HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US,
  814. (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) {
  815. CAM_ERR(CAM_HFI, "response poll timed out: status=0x%08x",
  816. status);
  817. rc = -ETIMEDOUT;
  818. goto regions_fail;
  819. }
  820. CAM_DBG(CAM_HFI, "ICP fw version: 0x%x",
  821. cam_io_r(icp_base + HFI_REG_FW_VERSION));
  822. g_hfi->hfi_state = HFI_READY;
  823. g_hfi->cmd_q_state = true;
  824. g_hfi->msg_q_state = true;
  825. hfi_irq_enable(g_hfi);
  826. mutex_unlock(&hfi_cmd_q_mutex);
  827. mutex_unlock(&hfi_msg_q_mutex);
  828. return rc;
  829. regions_fail:
  830. kfree(g_hfi);
  831. g_hfi = NULL;
  832. alloc_fail:
  833. mutex_unlock(&hfi_cmd_q_mutex);
  834. mutex_unlock(&hfi_msg_q_mutex);
  835. return rc;
  836. }
  837. void cam_hfi_deinit(void)
  838. {
  839. if (cam_presil_mode_enabled()) {
  840. CAM_DBG(CAM_HFI, "SYS_RESET Needed in presil for back to back hfi_init success");
  841. hfi_send_system_cmd(HFI_CMD_SYS_RESET, 0, 0);
  842. }
  843. mutex_lock(&hfi_cmd_q_mutex);
  844. mutex_lock(&hfi_msg_q_mutex);
  845. if (!g_hfi) {
  846. CAM_ERR(CAM_HFI, "hfi path not established yet");
  847. goto err;
  848. }
  849. g_hfi->cmd_q_state = false;
  850. g_hfi->msg_q_state = false;
  851. cam_free_clear((void *)g_hfi);
  852. g_hfi = NULL;
  853. err:
  854. mutex_unlock(&hfi_cmd_q_mutex);
  855. mutex_unlock(&hfi_msg_q_mutex);
  856. }
  857. #ifdef CONFIG_CAM_PRESIL
  858. static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem)
  859. {
  860. /**
  861. * The pchost maintains its own set of queue structures and
  862. * needs additional info to accomplish this. Use the set of
  863. * dummy registers to pass along this info.
  864. */
  865. /**
  866. * IOVA region length for each queue is currently hardcoded in
  867. * pchost (except for SFR). No need to send for now.
  868. */
  869. cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_CMD_Q_IOVA, hfi_mem->cmd_q.iova);
  870. cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_MSG_Q_IOVA, hfi_mem->msg_q.iova);
  871. cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_DBG_Q_IOVA, hfi_mem->dbg_q.iova);
  872. cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_SFR_LEN, hfi_mem->sfr_buf.len);
  873. return 0;
  874. }
  875. static int cam_hfi_presil_set_init_request(void)
  876. {
  877. CAM_DBG(CAM_PRESIL, "notifying pchost to start HFI init...");
  878. cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_A5_HW_VERSION_TO_START_HFI_INIT, 0xFF);
  879. CAM_DBG(CAM_PRESIL, "got done with PCHOST HFI init...");
  880. return 0;
  881. }
  882. int hfi_write_cmd(void *cmd_ptr)
  883. {
  884. int presil_rc = CAM_PRESIL_BLOCKED;
  885. int rc = 0;
  886. if (!cmd_ptr) {
  887. CAM_ERR(CAM_HFI, "command is null");
  888. return -EINVAL;
  889. }
  890. mutex_lock(&hfi_cmd_q_mutex);
  891. presil_rc = cam_presil_hfi_write_cmd(cmd_ptr, (*(uint32_t *)cmd_ptr));
  892. if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) {
  893. CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc);
  894. rc = -EINVAL;
  895. } else {
  896. CAM_DBG(CAM_HFI, "presil rc %d", presil_rc);
  897. }
  898. mutex_unlock(&hfi_cmd_q_mutex);
  899. return rc;
  900. }
  901. int hfi_read_message(uint32_t *pmsg, uint8_t q_id,
  902. uint32_t *words_read)
  903. {
  904. int presil_rc = CAM_PRESIL_BLOCKED;
  905. int rc = 0;
  906. if (!pmsg) {
  907. CAM_ERR(CAM_HFI, "Invalid msg");
  908. return -EINVAL;
  909. }
  910. if (q_id > Q_DBG) {
  911. CAM_ERR(CAM_HFI, "Invalid q :%u", q_id);
  912. return -EINVAL;
  913. }
  914. mutex_lock(&hfi_msg_q_mutex);
  915. memset(pmsg, 0x0, sizeof(uint32_t) * 256 /* ICP_MSG_BUF_SIZE */);
  916. *words_read = 0;
  917. presil_rc = cam_presil_hfi_read_message(pmsg, q_id, words_read);
  918. if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) {
  919. CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc);
  920. rc = -EINVAL;
  921. } else {
  922. CAM_DBG(CAM_HFI, "presil rc %d", presil_rc);
  923. }
  924. mutex_unlock(&hfi_msg_q_mutex);
  925. return rc;
  926. }
  927. #else
  928. /* when presil mode not enabled */
  929. static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem)
  930. {
  931. return 0;
  932. }
  933. static int cam_hfi_presil_set_init_request(void)
  934. {
  935. return 0;
  936. }
  937. #endif /* #ifdef CONFIG_CAM_PRESIL */