cam_cdm_util.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/types.h>
  6. #include <linux/kernel.h>
  7. #include <linux/errno.h>
  8. #include <linux/bug.h>
  9. #include "cam_cdm_intf_api.h"
  10. #include "cam_cdm_util.h"
  11. #include "cam_cdm.h"
  12. #include "cam_io_util.h"
  13. #define CAM_CDM_DWORD 4
  14. #define CAM_CDM_SW_CMD_COUNT 2
  15. #define CAM_CMD_LENGTH_MASK 0xFFFF
  16. #define CAM_CDM_COMMAND_OFFSET 24
  17. #define CAM_CDM_REG_OFFSET_MASK 0x00FFFFFF
  18. #define CAM_CDM_DMI_DATA_HI_OFFSET 8
  19. #define CAM_CDM_DMI_DATA_OFFSET 8
  20. #define CAM_CDM_DMI_DATA_LO_OFFSET 12
  21. static unsigned int CDMCmdHeaderSizes[
  22. CAM_CDM_CMD_PRIVATE_BASE + CAM_CDM_SW_CMD_COUNT] = {
  23. 0, /* UNUSED*/
  24. 3, /* DMI*/
  25. 0, /* UNUSED*/
  26. 2, /* RegContinuous*/
  27. 1, /* RegRandom*/
  28. 2, /* BUFFER_INDIREC*/
  29. 2, /* GenerateIRQ*/
  30. 3, /* WaitForEvent*/
  31. 1, /* ChangeBase*/
  32. 1, /* PERF_CONTROL*/
  33. 3, /* DMI32*/
  34. 3, /* DMI64*/
  35. };
  36. /**
  37. * struct cdm_regrandom_cmd - Definition for CDM random register command.
  38. * @count: Number of register writes
  39. * @reserved: reserved bits
  40. * @cmd: Command ID (CDMCmd)
  41. */
  42. struct cdm_regrandom_cmd {
  43. unsigned int count : 16;
  44. unsigned int reserved : 8;
  45. unsigned int cmd : 8;
  46. } __attribute__((__packed__));
  47. /**
  48. * struct cdm_regcontinuous_cmd - Definition for a CDM register range command.
  49. * @count: Number of register writes
  50. * @reserved0: reserved bits
  51. * @cmd: Command ID (CDMCmd)
  52. * @offset: Start address of the range of registers
  53. * @reserved1: reserved bits
  54. */
  55. struct cdm_regcontinuous_cmd {
  56. unsigned int count : 16;
  57. unsigned int reserved0 : 8;
  58. unsigned int cmd : 8;
  59. unsigned int offset : 24;
  60. unsigned int reserved1 : 8;
  61. } __attribute__((__packed__));
  62. /**
  63. * struct cdm_dmi_cmd - Definition for a CDM DMI command.
  64. * @length: Number of bytes in LUT - 1
  65. * @reserved: reserved bits
  66. * @cmd: Command ID (CDMCmd)
  67. * @addr: Address of the LUT in memory
  68. * @DMIAddr: Address of the target DMI config register
  69. * @DMISel: DMI identifier
  70. */
  71. struct cdm_dmi_cmd {
  72. unsigned int length : 16;
  73. unsigned int reserved : 8;
  74. unsigned int cmd : 8;
  75. unsigned int addr;
  76. unsigned int DMIAddr : 24;
  77. unsigned int DMISel : 8;
  78. } __attribute__((__packed__));
  79. /**
  80. * struct cdm_indirect_cmd - Definition for a CDM indirect buffer command.
  81. * @length: Number of bytes in buffer - 1
  82. * @reserved: reserved bits
  83. * @cmd: Command ID (CDMCmd)
  84. * @addr: Device address of the indirect buffer
  85. */
  86. struct cdm_indirect_cmd {
  87. unsigned int length : 16;
  88. unsigned int reserved : 8;
  89. unsigned int cmd : 8;
  90. unsigned int addr;
  91. } __attribute__((__packed__));
  92. /**
  93. * struct cdm_changebase_cmd - Definition for CDM base address change command.
  94. * @base: Base address to be changed to
  95. * @cmd:Command ID (CDMCmd)
  96. */
  97. struct cdm_changebase_cmd {
  98. unsigned int base : 24;
  99. unsigned int cmd : 8;
  100. } __attribute__((__packed__));
  101. /**
  102. * struct cdm_wait_event_cmd - Definition for a CDM Gen IRQ command.
  103. * @mask: Mask for the events
  104. * @id: ID to read back for debug
  105. * @iw_reserved: reserved bits
  106. * @iw: iw AHB write bit
  107. * @cmd:Command ID (CDMCmd)
  108. * @offset: Offset to where data is written
  109. * @offset_reserved: reserved bits
  110. * @data: data returned in IRQ_USR_DATA
  111. */
  112. struct cdm_wait_event_cmd {
  113. unsigned int mask : 8;
  114. unsigned int id : 8;
  115. unsigned int iw_reserved : 7;
  116. unsigned int iw : 1;
  117. unsigned int cmd : 8;
  118. unsigned int offset : 24;
  119. unsigned int offset_reserved : 8;
  120. unsigned int data;
  121. } __attribute__((__packed__));
  122. /**
  123. * struct cdm_genirq_cmd - Definition for a CDM Wait event command.
  124. * @reserved: reserved bits
  125. * @cmd:Command ID (CDMCmd)
  126. * @userdata: userdata returned in IRQ_USR_DATA
  127. */
  128. struct cdm_genirq_cmd {
  129. unsigned int reserved : 24;
  130. unsigned int cmd : 8;
  131. unsigned int userdata;
  132. } __attribute__((__packed__));
  133. /**
  134. * struct cdm_perf_ctrl_cmd_t - Definition for CDM perf control command.
  135. * @perf: perf command
  136. * @reserved: reserved bits
  137. * @cmd:Command ID (CDMCmd)
  138. */
  139. struct cdm_perf_ctrl_cmd {
  140. unsigned int perf : 2;
  141. unsigned int reserved : 22;
  142. unsigned int cmd : 8;
  143. } __attribute__((__packed__));
  144. uint32_t cdm_get_cmd_header_size(unsigned int command)
  145. {
  146. return CDMCmdHeaderSizes[command];
  147. }
  148. uint32_t cdm_required_size_reg_continuous(uint32_t numVals)
  149. {
  150. return cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT) + numVals;
  151. }
  152. uint32_t cdm_required_size_reg_random(uint32_t numRegVals)
  153. {
  154. return cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM) +
  155. (2 * numRegVals);
  156. }
  157. uint32_t cdm_required_size_dmi(void)
  158. {
  159. return cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
  160. }
  161. uint32_t cdm_required_size_genirq(void)
  162. {
  163. return cdm_get_cmd_header_size(CAM_CDM_CMD_GEN_IRQ);
  164. }
  165. uint32_t cdm_required_size_indirect(void)
  166. {
  167. return cdm_get_cmd_header_size(CAM_CDM_CMD_BUFF_INDIRECT);
  168. }
  169. uint32_t cdm_required_size_changebase(void)
  170. {
  171. return cdm_get_cmd_header_size(CAM_CDM_CMD_CHANGE_BASE);
  172. }
  173. uint32_t cdm_offsetof_dmi_addr(void)
  174. {
  175. return offsetof(struct cdm_dmi_cmd, addr);
  176. }
  177. uint32_t cdm_offsetof_indirect_addr(void)
  178. {
  179. return offsetof(struct cdm_indirect_cmd, addr);
  180. }
  181. uint32_t *cdm_write_regcontinuous(uint32_t *pCmdBuffer, uint32_t reg,
  182. uint32_t numVals, uint32_t *pVals)
  183. {
  184. uint32_t i;
  185. struct cdm_regcontinuous_cmd *pHeader =
  186. (struct cdm_regcontinuous_cmd *)pCmdBuffer;
  187. pHeader->count = numVals;
  188. pHeader->cmd = CAM_CDM_CMD_REG_CONT;
  189. pHeader->reserved0 = 0;
  190. pHeader->reserved1 = 0;
  191. pHeader->offset = reg;
  192. pCmdBuffer += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  193. for (i = 0; i < numVals; i++)
  194. (((uint32_t *)pCmdBuffer)[i]) = (((uint32_t *)pVals)[i]);
  195. pCmdBuffer += numVals;
  196. return pCmdBuffer;
  197. }
  198. uint32_t *cdm_write_regrandom(uint32_t *pCmdBuffer, uint32_t numRegVals,
  199. uint32_t *pRegVals)
  200. {
  201. uint32_t i;
  202. uint32_t *dst, *src;
  203. struct cdm_regrandom_cmd *pHeader =
  204. (struct cdm_regrandom_cmd *)pCmdBuffer;
  205. pHeader->count = numRegVals;
  206. pHeader->cmd = CAM_CDM_CMD_REG_RANDOM;
  207. pHeader->reserved = 0;
  208. pCmdBuffer += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  209. dst = pCmdBuffer;
  210. src = pRegVals;
  211. for (i = 0; i < numRegVals; i++) {
  212. *dst++ = *src++;
  213. *dst++ = *src++;
  214. }
  215. return dst;
  216. }
  217. uint32_t *cdm_write_dmi(uint32_t *pCmdBuffer, uint8_t dmiCmd,
  218. uint32_t DMIAddr, uint8_t DMISel, uint32_t dmiBufferAddr,
  219. uint32_t length)
  220. {
  221. struct cdm_dmi_cmd *pHeader = (struct cdm_dmi_cmd *)pCmdBuffer;
  222. pHeader->cmd = dmiCmd;
  223. pHeader->addr = dmiBufferAddr;
  224. pHeader->length = length - 1;
  225. pHeader->DMIAddr = DMIAddr;
  226. pHeader->DMISel = DMISel;
  227. pCmdBuffer += cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
  228. return pCmdBuffer;
  229. }
  230. uint32_t *cdm_write_indirect(uint32_t *pCmdBuffer, uint32_t indirectBufAddr,
  231. uint32_t length)
  232. {
  233. struct cdm_indirect_cmd *pHeader =
  234. (struct cdm_indirect_cmd *)pCmdBuffer;
  235. pHeader->cmd = CAM_CDM_CMD_BUFF_INDIRECT;
  236. pHeader->addr = indirectBufAddr;
  237. pHeader->length = length - 1;
  238. pCmdBuffer += cdm_get_cmd_header_size(CAM_CDM_CMD_BUFF_INDIRECT);
  239. return pCmdBuffer;
  240. }
  241. uint32_t *cdm_write_changebase(uint32_t *pCmdBuffer, uint32_t base)
  242. {
  243. struct cdm_changebase_cmd *pHeader =
  244. (struct cdm_changebase_cmd *)pCmdBuffer;
  245. pHeader->cmd = CAM_CDM_CMD_CHANGE_BASE;
  246. pHeader->base = base;
  247. pCmdBuffer += cdm_get_cmd_header_size(CAM_CDM_CMD_CHANGE_BASE);
  248. return pCmdBuffer;
  249. }
  250. void cdm_write_genirq(uint32_t *pCmdBuffer, uint32_t userdata)
  251. {
  252. struct cdm_genirq_cmd *pHeader = (struct cdm_genirq_cmd *)pCmdBuffer;
  253. pHeader->cmd = CAM_CDM_CMD_GEN_IRQ;
  254. pHeader->userdata = userdata;
  255. }
  256. struct cam_cdm_utils_ops CDM170_ops = {
  257. cdm_get_cmd_header_size,
  258. cdm_required_size_reg_continuous,
  259. cdm_required_size_reg_random,
  260. cdm_required_size_dmi,
  261. cdm_required_size_genirq,
  262. cdm_required_size_indirect,
  263. cdm_required_size_changebase,
  264. cdm_offsetof_dmi_addr,
  265. cdm_offsetof_indirect_addr,
  266. cdm_write_regcontinuous,
  267. cdm_write_regrandom,
  268. cdm_write_dmi,
  269. cdm_write_indirect,
  270. cdm_write_changebase,
  271. cdm_write_genirq,
  272. };
  273. int cam_cdm_get_ioremap_from_base(uint32_t hw_base,
  274. uint32_t base_array_size,
  275. struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
  276. void __iomem **device_base)
  277. {
  278. int ret = -EINVAL, i;
  279. for (i = 0; i < base_array_size; i++) {
  280. if (base_table[i])
  281. CAM_DBG(CAM_CDM, "In loop %d ioremap for %x addr=%x",
  282. i, (base_table[i])->mem_cam_base, hw_base);
  283. if ((base_table[i]) &&
  284. ((base_table[i])->mem_cam_base == hw_base)) {
  285. *device_base = (base_table[i])->mem_base;
  286. ret = 0;
  287. break;
  288. }
  289. }
  290. return ret;
  291. }
  292. static int cam_cdm_util_reg_cont_write(void __iomem *base_addr,
  293. uint32_t *cmd_buf, uint32_t cmd_buf_size, uint32_t *used_bytes)
  294. {
  295. int ret = 0;
  296. uint32_t *data;
  297. struct cdm_regcontinuous_cmd *reg_cont;
  298. if ((cmd_buf_size < cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) ||
  299. (!base_addr)) {
  300. CAM_ERR(CAM_CDM, "invalid base addr and data length %d %pK",
  301. cmd_buf_size, base_addr);
  302. return -EINVAL;
  303. }
  304. reg_cont = (struct cdm_regcontinuous_cmd *)cmd_buf;
  305. if ((!reg_cont->count) || (reg_cont->count > 0x10000) ||
  306. (((reg_cont->count * sizeof(uint32_t)) +
  307. cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) >
  308. cmd_buf_size)) {
  309. CAM_ERR(CAM_CDM, "buffer size %d is not sufficient for count%d",
  310. cmd_buf_size, reg_cont->count);
  311. return -EINVAL;
  312. }
  313. data = cmd_buf + cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  314. cam_io_memcpy(base_addr + reg_cont->offset, data,
  315. reg_cont->count * sizeof(uint32_t));
  316. *used_bytes = (reg_cont->count * sizeof(uint32_t)) +
  317. (4 * cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT));
  318. return ret;
  319. }
  320. static int cam_cdm_util_reg_random_write(void __iomem *base_addr,
  321. uint32_t *cmd_buf, uint32_t cmd_buf_size, uint32_t *used_bytes)
  322. {
  323. uint32_t i;
  324. struct cdm_regrandom_cmd *reg_random;
  325. uint32_t *data;
  326. if (!base_addr) {
  327. CAM_ERR(CAM_CDM, "invalid base address");
  328. return -EINVAL;
  329. }
  330. reg_random = (struct cdm_regrandom_cmd *) cmd_buf;
  331. if ((!reg_random->count) || (reg_random->count > 0x10000) ||
  332. (((reg_random->count * (sizeof(uint32_t) * 2)) +
  333. cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)) >
  334. cmd_buf_size)) {
  335. CAM_ERR(CAM_CDM, "invalid reg_count %d cmd_buf_size %d",
  336. reg_random->count, cmd_buf_size);
  337. return -EINVAL;
  338. }
  339. data = cmd_buf + cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  340. for (i = 0; i < reg_random->count; i++) {
  341. CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x",
  342. ((void __iomem *)(base_addr + data[0])),
  343. data[1]);
  344. cam_io_w(data[1], base_addr + data[0]);
  345. data += 2;
  346. }
  347. *used_bytes = ((reg_random->count * (sizeof(uint32_t) * 2)) +
  348. (4 * cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)));
  349. return 0;
  350. }
  351. static int cam_cdm_util_swd_dmi_write(uint32_t cdm_cmd_type,
  352. void __iomem *base_addr, uint32_t *cmd_buf, uint32_t cmd_buf_size,
  353. uint32_t *used_bytes)
  354. {
  355. uint32_t i;
  356. struct cdm_dmi_cmd *swd_dmi;
  357. uint32_t *data;
  358. swd_dmi = (struct cdm_dmi_cmd *)cmd_buf;
  359. if (cmd_buf_size < (cdm_required_size_dmi() + swd_dmi->length + 1)) {
  360. CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
  361. swd_dmi->length + 1);
  362. return -EINVAL;
  363. }
  364. data = cmd_buf + cdm_required_size_dmi();
  365. if (cdm_cmd_type == CAM_CDM_CMD_SWD_DMI_64) {
  366. for (i = 0; i < (swd_dmi->length + 1)/8; i++) {
  367. cam_io_w_mb(data[0], base_addr +
  368. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
  369. cam_io_w_mb(data[1], base_addr +
  370. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET);
  371. data += 2;
  372. }
  373. } else if (cdm_cmd_type == CAM_CDM_CMD_DMI) {
  374. for (i = 0; i < (swd_dmi->length + 1)/4; i++) {
  375. cam_io_w_mb(data[0], base_addr +
  376. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
  377. data += 1;
  378. }
  379. } else {
  380. for (i = 0; i < (swd_dmi->length + 1)/4; i++) {
  381. cam_io_w_mb(data[0], base_addr +
  382. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
  383. data += 1;
  384. }
  385. }
  386. *used_bytes = (4 * cdm_required_size_dmi()) + swd_dmi->length + 1;
  387. return 0;
  388. }
  389. int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base,
  390. uint32_t *cmd_buf, uint32_t cmd_buf_size,
  391. struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
  392. uint32_t base_array_size, uint8_t bl_tag)
  393. {
  394. int ret = 0;
  395. uint32_t cdm_cmd_type = 0, total_cmd_buf_size = 0;
  396. uint32_t used_bytes = 0;
  397. total_cmd_buf_size = cmd_buf_size;
  398. while (cmd_buf_size > 0) {
  399. CAM_DBG(CAM_CDM, "cmd data=%x", *cmd_buf);
  400. cdm_cmd_type = (*cmd_buf >> CAM_CDM_COMMAND_OFFSET);
  401. switch (cdm_cmd_type) {
  402. case CAM_CDM_CMD_REG_CONT: {
  403. ret = cam_cdm_util_reg_cont_write(*current_device_base,
  404. cmd_buf, cmd_buf_size, &used_bytes);
  405. if (ret)
  406. break;
  407. if (used_bytes > 0) {
  408. cmd_buf_size -= used_bytes;
  409. cmd_buf += used_bytes/4;
  410. }
  411. }
  412. break;
  413. case CAM_CDM_CMD_REG_RANDOM: {
  414. ret = cam_cdm_util_reg_random_write(
  415. *current_device_base, cmd_buf, cmd_buf_size,
  416. &used_bytes);
  417. if (ret)
  418. break;
  419. if (used_bytes > 0) {
  420. cmd_buf_size -= used_bytes;
  421. cmd_buf += used_bytes / 4;
  422. }
  423. }
  424. break;
  425. case CAM_CDM_CMD_DMI:
  426. case CAM_CDM_CMD_SWD_DMI_32:
  427. case CAM_CDM_CMD_SWD_DMI_64: {
  428. if (*current_device_base == 0) {
  429. CAM_ERR(CAM_CDM,
  430. "Got SWI DMI cmd =%d for invalid hw",
  431. cdm_cmd_type);
  432. ret = -EINVAL;
  433. break;
  434. }
  435. ret = cam_cdm_util_swd_dmi_write(cdm_cmd_type,
  436. *current_device_base, cmd_buf, cmd_buf_size,
  437. &used_bytes);
  438. if (ret)
  439. break;
  440. if (used_bytes > 0) {
  441. cmd_buf_size -= used_bytes;
  442. cmd_buf += used_bytes / 4;
  443. }
  444. }
  445. break;
  446. case CAM_CDM_CMD_CHANGE_BASE: {
  447. struct cdm_changebase_cmd *change_base_cmd =
  448. (struct cdm_changebase_cmd *)cmd_buf;
  449. ret = cam_cdm_get_ioremap_from_base(
  450. change_base_cmd->base, base_array_size,
  451. base_table, current_device_base);
  452. if (ret != 0) {
  453. CAM_ERR(CAM_CDM,
  454. "Get ioremap change base failed %x",
  455. change_base_cmd->base);
  456. break;
  457. }
  458. CAM_DBG(CAM_CDM, "Got ioremap for %x addr=%pK",
  459. change_base_cmd->base,
  460. current_device_base);
  461. cmd_buf_size -= (4 *
  462. cdm_required_size_changebase());
  463. cmd_buf += cdm_required_size_changebase();
  464. }
  465. break;
  466. default:
  467. CAM_ERR(CAM_CDM, "unsupported cdm_cmd_type type 0%x",
  468. cdm_cmd_type);
  469. ret = -EINVAL;
  470. break;
  471. }
  472. if (ret < 0)
  473. break;
  474. }
  475. return ret;
  476. }
  477. static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr)
  478. {
  479. long ret = 0;
  480. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
  481. CAM_INFO(CAM_CDM, "DMI");
  482. return ret;
  483. }
  484. static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr)
  485. {
  486. long ret = 0;
  487. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
  488. CAM_INFO(CAM_CDM, "Buff Indirect");
  489. return ret;
  490. }
  491. static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
  492. {
  493. long ret = 0;
  494. struct cdm_regcontinuous_cmd *p_regcont_cmd;
  495. uint32_t *temp_ptr = cmd_buf_addr;
  496. int i = 0;
  497. p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
  498. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
  499. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
  500. CAM_INFO(CAM_CDM, "REG_CONT: COUNT: %u OFFSET: 0x%X",
  501. p_regcont_cmd->count, p_regcont_cmd->offset);
  502. for (i = 0; i < p_regcont_cmd->count; i++) {
  503. CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i,
  504. *temp_ptr);
  505. temp_ptr++;
  506. ret++;
  507. }
  508. return ret;
  509. }
  510. static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr)
  511. {
  512. struct cdm_regrandom_cmd *p_regrand_cmd;
  513. uint32_t *temp_ptr = cmd_buf_addr;
  514. long ret = 0;
  515. int i = 0;
  516. p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
  517. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
  518. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
  519. CAM_INFO(CAM_CDM, "REG_RAND: COUNT: %u",
  520. p_regrand_cmd->count);
  521. for (i = 0; i < p_regrand_cmd->count; i++) {
  522. CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X",
  523. i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i,
  524. *(temp_ptr + 1));
  525. temp_ptr += 2;
  526. ret += 2;
  527. }
  528. return ret;
  529. }
  530. static long cam_cdm_util_dump_gen_irq_cmd(uint32_t *cmd_buf_addr)
  531. {
  532. long ret = 0;
  533. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ];
  534. CAM_INFO(CAM_CDM, "GEN_IRQ");
  535. return ret;
  536. }
  537. static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr)
  538. {
  539. long ret = 0;
  540. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT];
  541. CAM_INFO(CAM_CDM, "WAIT_EVENT");
  542. return ret;
  543. }
  544. static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr)
  545. {
  546. long ret = 0;
  547. struct cdm_changebase_cmd *p_cbase_cmd;
  548. uint32_t *temp_ptr = cmd_buf_addr;
  549. p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr;
  550. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
  551. CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X",
  552. p_cbase_cmd->base);
  553. return ret;
  554. }
  555. static long cam_cdm_util_dump_perf_ctrl_cmd(uint32_t *cmd_buf_addr)
  556. {
  557. long ret = 0;
  558. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL];
  559. CAM_INFO(CAM_CDM, "PERF_CTRL");
  560. return ret;
  561. }
  562. void cam_cdm_util_dump_cmd_buf(
  563. uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
  564. {
  565. uint32_t *buf_now = cmd_buf_start;
  566. uint32_t cmd = 0;
  567. if (!cmd_buf_start || !cmd_buf_end) {
  568. CAM_INFO(CAM_CDM, "Invalid args");
  569. return;
  570. }
  571. do {
  572. cmd = *buf_now;
  573. cmd = cmd >> CAM_CDM_COMMAND_OFFSET;
  574. switch (cmd) {
  575. case CAM_CDM_CMD_DMI:
  576. case CAM_CDM_CMD_DMI_32:
  577. case CAM_CDM_CMD_DMI_64:
  578. buf_now += cam_cdm_util_dump_dmi_cmd(buf_now);
  579. break;
  580. case CAM_CDM_CMD_REG_CONT:
  581. buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now);
  582. break;
  583. case CAM_CDM_CMD_REG_RANDOM:
  584. buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now);
  585. break;
  586. case CAM_CDM_CMD_BUFF_INDIRECT:
  587. buf_now += cam_cdm_util_dump_buff_indirect(buf_now);
  588. break;
  589. case CAM_CDM_CMD_GEN_IRQ:
  590. buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now);
  591. break;
  592. case CAM_CDM_CMD_WAIT_EVENT:
  593. buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now);
  594. break;
  595. case CAM_CDM_CMD_CHANGE_BASE:
  596. buf_now += cam_cdm_util_dump_change_base_cmd(buf_now);
  597. break;
  598. case CAM_CDM_CMD_PERF_CTRL:
  599. buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now);
  600. break;
  601. default:
  602. CAM_INFO(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x",
  603. cmd, *buf_now);
  604. buf_now++;
  605. break;
  606. }
  607. } while (buf_now <= cmd_buf_end);
  608. }