hfi.c 37 KB

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