cam_cdm_util.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/types.h>
  7. #include <linux/kernel.h>
  8. #include <linux/errno.h>
  9. #include <linux/bug.h>
  10. #include "cam_cdm_intf_api.h"
  11. #include "cam_cdm_util.h"
  12. #include "cam_cdm.h"
  13. #include "cam_io_util.h"
  14. #define CAM_CDM_DWORD 4
  15. #define CAM_CDM_SW_CMD_COUNT 2
  16. #define CAM_CMD_LENGTH_MASK 0xFFFF
  17. #define CAM_CDM_COMMAND_OFFSET 24
  18. #define CAM_CDM_REG_OFFSET_MASK 0x00FFFFFF
  19. #define CAM_CDM_DMI_DATA_HI_OFFSET 8
  20. #define CAM_CDM_DMI_DATA_OFFSET 8
  21. #define CAM_CDM_DMI_DATA_LO_OFFSET 12
  22. static unsigned int CDMCmdHeaderSizes[
  23. CAM_CDM_CMD_PRIVATE_BASE + CAM_CDM_SW_CMD_COUNT] = {
  24. 0, /* UNUSED*/
  25. 3, /* DMI*/
  26. 0, /* UNUSED*/
  27. 2, /* RegContinuous*/
  28. 1, /* RegRandom*/
  29. 2, /* BUFFER_INDIREC*/
  30. 2, /* GenerateIRQ*/
  31. 3, /* WaitForEvent*/
  32. 1, /* ChangeBase*/
  33. 1, /* PERF_CONTROL*/
  34. 3, /* DMI32*/
  35. 3, /* DMI64*/
  36. 3, /* WaitCompEvent*/
  37. 3, /* ClearCompEvent*/
  38. 3, /* WaitPrefetchDisable*/
  39. };
  40. /**
  41. * struct cdm_regrandom_cmd - Definition for CDM random register command.
  42. * @count: Number of register writes
  43. * @reserved: reserved bits
  44. * @cmd: Command ID (CDMCmd)
  45. */
  46. struct cdm_regrandom_cmd {
  47. unsigned int count : 16;
  48. unsigned int reserved : 8;
  49. unsigned int cmd : 8;
  50. } __attribute__((__packed__));
  51. /**
  52. * struct cdm_regcontinuous_cmd - Definition for a CDM register range command.
  53. * @count: Number of register writes
  54. * @reserved0: reserved bits
  55. * @cmd: Command ID (CDMCmd)
  56. * @offset: Start address of the range of registers
  57. * @reserved1: reserved bits
  58. */
  59. struct cdm_regcontinuous_cmd {
  60. unsigned int count : 16;
  61. unsigned int reserved0 : 8;
  62. unsigned int cmd : 8;
  63. unsigned int offset : 24;
  64. unsigned int reserved1 : 8;
  65. } __attribute__((__packed__));
  66. /**
  67. * struct cdm_dmi_cmd - Definition for a CDM DMI command.
  68. * @length: Number of bytes in LUT - 1
  69. * @reserved: reserved bits
  70. * @cmd: Command ID (CDMCmd)
  71. * @addr: Address of the LUT in memory
  72. * @DMIAddr: Address of the target DMI config register
  73. * @DMISel: DMI identifier
  74. */
  75. struct cdm_dmi_cmd {
  76. unsigned int length : 16;
  77. unsigned int reserved : 8;
  78. unsigned int cmd : 8;
  79. unsigned int addr;
  80. unsigned int DMIAddr : 24;
  81. unsigned int DMISel : 8;
  82. } __attribute__((__packed__));
  83. /**
  84. * struct cdm_indirect_cmd - Definition for a CDM indirect buffer command.
  85. * @length: Number of bytes in buffer - 1
  86. * @reserved: reserved bits
  87. * @cmd: Command ID (CDMCmd)
  88. * @addr: Device address of the indirect buffer
  89. */
  90. struct cdm_indirect_cmd {
  91. unsigned int length : 16;
  92. unsigned int reserved : 8;
  93. unsigned int cmd : 8;
  94. unsigned int addr;
  95. } __attribute__((__packed__));
  96. /**
  97. * struct cdm_changebase_cmd - Definition for CDM base address change command.
  98. * @base: Base address to be changed to
  99. * @cmd:Command ID (CDMCmd)
  100. */
  101. struct cdm_changebase_cmd {
  102. unsigned int base : 24;
  103. unsigned int cmd : 8;
  104. } __attribute__((__packed__));
  105. /**
  106. * struct cdm_wait_event_cmd - Definition for a CDM Gen IRQ command.
  107. * @mask: Mask for the events
  108. * @id: ID to read back for debug
  109. * @iw_reserved: reserved bits
  110. * @iw: iw AHB write bit
  111. * @cmd:Command ID (CDMCmd)
  112. * @offset: Offset to where data is written
  113. * @offset_reserved: reserved bits
  114. * @data: data returned in IRQ_USR_DATA
  115. */
  116. struct cdm_wait_event_cmd {
  117. unsigned int mask : 8;
  118. unsigned int id : 8;
  119. unsigned int iw_reserved : 7;
  120. unsigned int iw : 1;
  121. unsigned int cmd : 8;
  122. unsigned int offset : 24;
  123. unsigned int offset_reserved : 8;
  124. unsigned int data;
  125. } __attribute__((__packed__));
  126. /**
  127. * struct cdm_genirq_cmd - Definition for a CDM Wait event command.
  128. * @reserved: reserved bits
  129. * @cmd:Command ID (CDMCmd)
  130. * @userdata: userdata returned in IRQ_USR_DATA
  131. */
  132. struct cdm_genirq_cmd {
  133. unsigned int reserved : 24;
  134. unsigned int cmd : 8;
  135. unsigned int userdata;
  136. } __attribute__((__packed__));
  137. /**
  138. * struct cdm_perf_ctrl_cmd_t - Definition for CDM perf control command.
  139. * @perf: perf command
  140. * @reserved: reserved bits
  141. * @cmd:Command ID (CDMCmd)
  142. */
  143. struct cdm_perf_ctrl_cmd {
  144. unsigned int perf : 2;
  145. unsigned int reserved : 22;
  146. unsigned int cmd : 8;
  147. } __attribute__((__packed__));
  148. struct cdm_wait_comp_event_cmd {
  149. unsigned int reserved : 8;
  150. unsigned int id : 8;
  151. unsigned int id_reserved: 8;
  152. unsigned int cmd : 8;
  153. unsigned int mask1;
  154. unsigned int mask2;
  155. } __attribute__((__packed__));
  156. struct cdm_clear_comp_event_cmd {
  157. unsigned int reserved : 8;
  158. unsigned int id : 8;
  159. unsigned int id_reserved: 8;
  160. unsigned int cmd : 8;
  161. unsigned int mask1;
  162. unsigned int mask2;
  163. } __attribute__((__packed__));
  164. struct cdm_prefetch_disable_event_cmd {
  165. unsigned int reserved : 8;
  166. unsigned int id : 8;
  167. unsigned int id_reserved: 8;
  168. unsigned int cmd : 8;
  169. unsigned int mask1;
  170. unsigned int mask2;
  171. } __attribute__((__packed__));
  172. uint32_t cam_cdm_get_cmd_header_size(unsigned int command)
  173. {
  174. return CDMCmdHeaderSizes[command];
  175. }
  176. uint32_t cam_cdm_required_size_dmi(void)
  177. {
  178. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
  179. }
  180. uint32_t cam_cdm_required_size_reg_continuous(uint32_t numVals)
  181. {
  182. if (!numVals) {
  183. CAM_WARN(CAM_CDM, "numVals cant be 0");
  184. return 0;
  185. }
  186. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT) + numVals;
  187. }
  188. uint32_t cam_cdm_required_size_reg_random(uint32_t numRegVals)
  189. {
  190. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM) +
  191. (2 * numRegVals);
  192. }
  193. uint32_t cam_cdm_required_size_indirect(void)
  194. {
  195. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_BUFF_INDIRECT);
  196. }
  197. uint32_t cam_cdm_required_size_genirq(void)
  198. {
  199. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_GEN_IRQ);
  200. }
  201. uint32_t cam_cdm_required_size_wait_event(void)
  202. {
  203. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_WAIT_EVENT);
  204. }
  205. uint32_t cam_cdm_required_size_changebase(void)
  206. {
  207. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_CHANGE_BASE);
  208. }
  209. uint32_t cam_cdm_required_size_comp_wait(void)
  210. {
  211. return cam_cdm_get_cmd_header_size(CAM_CDM_CMD_COMP_WAIT);
  212. }
  213. uint32_t cam_cdm_required_size_clear_comp_event(void)
  214. {
  215. return cam_cdm_get_cmd_header_size(CAM_CDM_CLEAR_COMP_WAIT);
  216. }
  217. uint32_t cam_cdm_required_size_prefetch_disable(void)
  218. {
  219. return cam_cdm_get_cmd_header_size(CAM_CDM_WAIT_PREFETCH_DISABLE);
  220. }
  221. uint32_t cam_cdm_offsetof_dmi_addr(void)
  222. {
  223. return offsetof(struct cdm_dmi_cmd, addr);
  224. }
  225. uint32_t cam_cdm_offsetof_indirect_addr(void)
  226. {
  227. return offsetof(struct cdm_indirect_cmd, addr);
  228. }
  229. uint32_t *cam_cdm_write_dmi(uint32_t *pCmdBuffer, uint8_t dmiCmd,
  230. uint32_t DMIAddr, uint8_t DMISel, uint32_t dmiBufferAddr,
  231. uint32_t length)
  232. {
  233. struct cdm_dmi_cmd *pHeader = (struct cdm_dmi_cmd *)pCmdBuffer;
  234. pHeader->cmd = CAM_CDM_CMD_DMI;
  235. pHeader->addr = dmiBufferAddr;
  236. pHeader->length = length;
  237. pHeader->DMIAddr = DMIAddr;
  238. pHeader->DMISel = DMISel;
  239. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
  240. return pCmdBuffer;
  241. }
  242. uint32_t *cam_cdm_write_regcontinuous(uint32_t *pCmdBuffer, uint32_t reg,
  243. uint32_t numVals, uint32_t *pVals)
  244. {
  245. uint32_t i;
  246. struct cdm_regcontinuous_cmd *pHeader =
  247. (struct cdm_regcontinuous_cmd *)pCmdBuffer;
  248. pHeader->count = numVals;
  249. pHeader->cmd = CAM_CDM_CMD_REG_CONT;
  250. pHeader->reserved0 = 0;
  251. pHeader->reserved1 = 0;
  252. pHeader->offset = reg;
  253. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  254. for (i = 0; i < numVals; i++)
  255. (((uint32_t *)pCmdBuffer)[i]) = (((uint32_t *)pVals)[i]);
  256. pCmdBuffer += numVals;
  257. return pCmdBuffer;
  258. }
  259. uint32_t *cam_cdm_write_regrandom(uint32_t *pCmdBuffer, uint32_t numRegVals,
  260. uint32_t *pRegVals)
  261. {
  262. uint32_t i;
  263. uint32_t *dst, *src;
  264. struct cdm_regrandom_cmd *pHeader =
  265. (struct cdm_regrandom_cmd *)pCmdBuffer;
  266. if (!numRegVals) {
  267. CAM_ERR(CAM_CDM, "Number of reg-val pairs can not be 0");
  268. return pCmdBuffer;
  269. }
  270. pHeader->count = numRegVals;
  271. pHeader->cmd = CAM_CDM_CMD_REG_RANDOM;
  272. pHeader->reserved = 0;
  273. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  274. dst = pCmdBuffer;
  275. src = pRegVals;
  276. for (i = 0; i < numRegVals; i++) {
  277. *dst++ = *src++;
  278. *dst++ = *src++;
  279. }
  280. return dst;
  281. }
  282. uint32_t *cam_cdm_write_indirect(uint32_t *pCmdBuffer, uint32_t indirectBufAddr,
  283. uint32_t length)
  284. {
  285. struct cdm_indirect_cmd *pHeader =
  286. (struct cdm_indirect_cmd *)pCmdBuffer;
  287. pHeader->cmd = CAM_CDM_CMD_BUFF_INDIRECT;
  288. pHeader->addr = indirectBufAddr;
  289. pHeader->length = length - 1;
  290. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_BUFF_INDIRECT);
  291. return pCmdBuffer;
  292. }
  293. void cam_cdm_write_genirq(uint32_t *pCmdBuffer, uint32_t userdata,
  294. bool bit_wr_enable, uint32_t fifo_idx)
  295. {
  296. struct cdm_genirq_cmd *pHeader = (struct cdm_genirq_cmd *)pCmdBuffer;
  297. CAM_DBG(CAM_CDM, "userdata 0x%x, fifo_idx %d",
  298. userdata, fifo_idx);
  299. if (bit_wr_enable)
  300. pHeader->reserved = (unsigned int)((fifo_idx << 1)
  301. | (unsigned int)(bit_wr_enable));
  302. pHeader->cmd = CAM_CDM_CMD_GEN_IRQ;
  303. pHeader->userdata = (userdata << (8 * fifo_idx));
  304. }
  305. uint32_t *cam_cdm_write_wait_event(uint32_t *pcmdbuffer, uint32_t iw,
  306. uint32_t id, uint32_t mask,
  307. uint32_t offset, uint32_t data)
  308. {
  309. struct cdm_wait_event_cmd *pheader =
  310. (struct cdm_wait_event_cmd *)pcmdbuffer;
  311. pheader->cmd = CAM_CDM_CMD_WAIT_EVENT;
  312. pheader->mask = mask;
  313. pheader->data = data;
  314. pheader->id = id;
  315. pheader->iw = iw;
  316. pheader->offset = offset;
  317. pheader->iw_reserved = 0;
  318. pheader->offset_reserved = 0;
  319. pcmdbuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_WAIT_EVENT);
  320. return pcmdbuffer;
  321. }
  322. uint32_t *cam_cdm_write_changebase(uint32_t *pCmdBuffer, uint32_t base)
  323. {
  324. struct cdm_changebase_cmd *pHeader =
  325. (struct cdm_changebase_cmd *)pCmdBuffer;
  326. CAM_DBG(CAM_CDM, "Change to base 0x%x", base);
  327. pHeader->cmd = CAM_CDM_CMD_CHANGE_BASE;
  328. pHeader->base = base;
  329. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_CHANGE_BASE);
  330. return pCmdBuffer;
  331. }
  332. uint32_t *cam_cdm_write_wait_comp_event(
  333. uint32_t *pCmdBuffer, uint32_t mask1, uint32_t mask2)
  334. {
  335. struct cdm_wait_comp_event_cmd *pHeader =
  336. (struct cdm_wait_comp_event_cmd *)pCmdBuffer;
  337. pHeader->cmd = CAM_CDM_CMD_COMP_WAIT;
  338. pHeader->mask1 = mask1;
  339. pHeader->mask2 = mask2;
  340. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_COMP_WAIT);
  341. return pCmdBuffer;
  342. }
  343. uint32_t *cam_cdm_write_clear_comp_event(
  344. uint32_t *pCmdBuffer, uint32_t mask1, uint32_t mask2)
  345. {
  346. struct cdm_clear_comp_event_cmd *pHeader =
  347. (struct cdm_clear_comp_event_cmd *)pCmdBuffer;
  348. pHeader->cmd = CAM_CDM_CLEAR_COMP_WAIT;
  349. pHeader->mask1 = mask1;
  350. pHeader->mask2 = mask2;
  351. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_CLEAR_COMP_WAIT);
  352. return pCmdBuffer;
  353. }
  354. uint32_t *cam_cdm_write_wait_prefetch_disable(
  355. uint32_t *pCmdBuffer,
  356. uint32_t id,
  357. uint32_t mask1,
  358. uint32_t mask2)
  359. {
  360. struct cdm_prefetch_disable_event_cmd *pHeader =
  361. (struct cdm_prefetch_disable_event_cmd *)pCmdBuffer;
  362. pHeader->cmd = CAM_CDM_WAIT_PREFETCH_DISABLE;
  363. pHeader->id = id;
  364. pHeader->mask1 = mask1;
  365. pHeader->mask2 = mask2;
  366. pCmdBuffer += cam_cdm_get_cmd_header_size(CAM_CDM_WAIT_PREFETCH_DISABLE);
  367. return pCmdBuffer;
  368. }
  369. struct cam_cdm_utils_ops CDM170_ops = {
  370. .cdm_get_cmd_header_size = cam_cdm_get_cmd_header_size,
  371. .cdm_required_size_dmi = cam_cdm_required_size_dmi,
  372. .cdm_required_size_reg_continuous = cam_cdm_required_size_reg_continuous,
  373. .cdm_required_size_reg_random = cam_cdm_required_size_reg_random,
  374. .cdm_required_size_indirect = cam_cdm_required_size_indirect,
  375. .cdm_required_size_genirq = cam_cdm_required_size_genirq,
  376. .cdm_required_size_wait_event = cam_cdm_required_size_wait_event,
  377. .cdm_required_size_changebase = cam_cdm_required_size_changebase,
  378. .cdm_required_size_comp_wait = cam_cdm_required_size_comp_wait,
  379. .cdm_required_size_clear_comp_event = cam_cdm_required_size_clear_comp_event,
  380. .cdm_required_size_prefetch_disable = cam_cdm_required_size_prefetch_disable,
  381. .cdm_offsetof_dmi_addr = cam_cdm_offsetof_dmi_addr,
  382. .cdm_offsetof_indirect_addr = cam_cdm_offsetof_indirect_addr,
  383. .cdm_write_dmi = cam_cdm_write_dmi,
  384. .cdm_write_regcontinuous = cam_cdm_write_regcontinuous,
  385. .cdm_write_regrandom = cam_cdm_write_regrandom,
  386. .cdm_write_indirect = cam_cdm_write_indirect,
  387. .cdm_write_genirq = cam_cdm_write_genirq,
  388. .cdm_write_wait_event = cam_cdm_write_wait_event,
  389. .cdm_write_changebase = cam_cdm_write_changebase,
  390. .cdm_write_wait_comp_event = cam_cdm_write_wait_comp_event,
  391. .cdm_write_clear_comp_event = cam_cdm_write_clear_comp_event,
  392. .cdm_write_wait_prefetch_disable = cam_cdm_write_wait_prefetch_disable,
  393. };
  394. int cam_cdm_get_ioremap_from_base(uint32_t hw_base,
  395. uint32_t base_array_size,
  396. struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
  397. void __iomem **device_base)
  398. {
  399. int ret = -EINVAL, i;
  400. for (i = 0; i < base_array_size; i++) {
  401. if (base_table[i])
  402. CAM_DBG(CAM_CDM, "In loop %d ioremap for %x addr=%x",
  403. i, (base_table[i])->mem_cam_base, hw_base);
  404. if ((base_table[i]) &&
  405. ((base_table[i])->mem_cam_base == hw_base)) {
  406. *device_base = (base_table[i])->mem_base;
  407. ret = 0;
  408. break;
  409. }
  410. }
  411. return ret;
  412. }
  413. static int cam_cdm_util_reg_cont_write(void __iomem *base_addr,
  414. uint32_t *cmd_buf, uint32_t cmd_buf_size, uint32_t *used_bytes)
  415. {
  416. int ret = 0;
  417. uint32_t *data;
  418. struct cdm_regcontinuous_cmd *reg_cont;
  419. if ((cmd_buf_size < cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) ||
  420. (!base_addr)) {
  421. CAM_ERR(CAM_CDM, "invalid base addr and data length %d %pK",
  422. cmd_buf_size, base_addr);
  423. return -EINVAL;
  424. }
  425. reg_cont = (struct cdm_regcontinuous_cmd *)cmd_buf;
  426. if ((!reg_cont->count) || (reg_cont->count > 0x10000) ||
  427. (((reg_cont->count * sizeof(uint32_t)) +
  428. cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT)) >
  429. cmd_buf_size)) {
  430. CAM_ERR(CAM_CDM, "buffer size %d is not sufficient for count%d",
  431. cmd_buf_size, reg_cont->count);
  432. return -EINVAL;
  433. }
  434. data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  435. cam_io_memcpy(base_addr + reg_cont->offset, data,
  436. reg_cont->count * sizeof(uint32_t));
  437. *used_bytes = (reg_cont->count * sizeof(uint32_t)) +
  438. (4 * cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT));
  439. return ret;
  440. }
  441. static int cam_cdm_util_reg_random_write(void __iomem *base_addr,
  442. uint32_t *cmd_buf, uint32_t cmd_buf_size, uint32_t *used_bytes)
  443. {
  444. uint32_t i;
  445. struct cdm_regrandom_cmd *reg_random;
  446. uint32_t *data;
  447. if (!base_addr) {
  448. CAM_ERR(CAM_CDM, "invalid base address");
  449. return -EINVAL;
  450. }
  451. reg_random = (struct cdm_regrandom_cmd *) cmd_buf;
  452. if ((!reg_random->count) || (reg_random->count > 0x10000) ||
  453. (((reg_random->count * (sizeof(uint32_t) * 2)) +
  454. cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)) >
  455. cmd_buf_size)) {
  456. CAM_ERR(CAM_CDM, "invalid reg_count %d cmd_buf_size %d",
  457. reg_random->count, cmd_buf_size);
  458. return -EINVAL;
  459. }
  460. data = cmd_buf + cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  461. for (i = 0; i < reg_random->count; i++) {
  462. CAM_DBG(CAM_CDM, "reg random: offset %pK, value 0x%x",
  463. ((void __iomem *)(base_addr + data[0])),
  464. data[1]);
  465. cam_io_w(data[1], base_addr + data[0]);
  466. data += 2;
  467. }
  468. *used_bytes = ((reg_random->count * (sizeof(uint32_t) * 2)) +
  469. (4 * cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM)));
  470. return 0;
  471. }
  472. static int cam_cdm_util_swd_dmi_write(uint32_t cdm_cmd_type,
  473. void __iomem *base_addr, uint32_t *cmd_buf, uint32_t cmd_buf_size,
  474. uint32_t *used_bytes)
  475. {
  476. uint32_t i;
  477. struct cdm_dmi_cmd *swd_dmi;
  478. uint32_t *data;
  479. swd_dmi = (struct cdm_dmi_cmd *)cmd_buf;
  480. if (cmd_buf_size < (cam_cdm_required_size_dmi() + swd_dmi->length + 1)) {
  481. CAM_ERR(CAM_CDM, "invalid CDM_SWD_DMI length %d",
  482. swd_dmi->length + 1);
  483. return -EINVAL;
  484. }
  485. data = cmd_buf + cam_cdm_required_size_dmi();
  486. if (cdm_cmd_type == CAM_CDM_CMD_SWD_DMI_64) {
  487. for (i = 0; i < (swd_dmi->length + 1)/8; i++) {
  488. cam_io_w_mb(data[0], base_addr +
  489. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
  490. cam_io_w_mb(data[1], base_addr +
  491. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_HI_OFFSET);
  492. data += 2;
  493. }
  494. } else if (cdm_cmd_type == CAM_CDM_CMD_DMI) {
  495. for (i = 0; i < (swd_dmi->length + 1)/4; i++) {
  496. cam_io_w_mb(data[0], base_addr +
  497. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_OFFSET);
  498. data += 1;
  499. }
  500. } else {
  501. for (i = 0; i < (swd_dmi->length + 1)/4; i++) {
  502. cam_io_w_mb(data[0], base_addr +
  503. swd_dmi->DMIAddr + CAM_CDM_DMI_DATA_LO_OFFSET);
  504. data += 1;
  505. }
  506. }
  507. *used_bytes = (4 * cam_cdm_required_size_dmi()) + swd_dmi->length + 1;
  508. return 0;
  509. }
  510. int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base,
  511. uint32_t *cmd_buf, uint32_t cmd_buf_size,
  512. struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
  513. uint32_t base_array_size, uint8_t bl_tag)
  514. {
  515. int ret = 0;
  516. uint32_t cdm_cmd_type = 0, total_cmd_buf_size = 0;
  517. uint32_t used_bytes = 0;
  518. total_cmd_buf_size = cmd_buf_size;
  519. while (cmd_buf_size > 0) {
  520. CAM_DBG(CAM_CDM, "cmd data=%x", *cmd_buf);
  521. cdm_cmd_type = (*cmd_buf >> CAM_CDM_COMMAND_OFFSET);
  522. switch (cdm_cmd_type) {
  523. case CAM_CDM_CMD_REG_CONT: {
  524. ret = cam_cdm_util_reg_cont_write(*current_device_base,
  525. cmd_buf, cmd_buf_size, &used_bytes);
  526. if (ret)
  527. break;
  528. if (used_bytes > 0) {
  529. cmd_buf_size -= used_bytes;
  530. cmd_buf += used_bytes/4;
  531. }
  532. }
  533. break;
  534. case CAM_CDM_CMD_REG_RANDOM: {
  535. ret = cam_cdm_util_reg_random_write(
  536. *current_device_base, cmd_buf, cmd_buf_size,
  537. &used_bytes);
  538. if (ret)
  539. break;
  540. if (used_bytes > 0) {
  541. cmd_buf_size -= used_bytes;
  542. cmd_buf += used_bytes / 4;
  543. }
  544. }
  545. break;
  546. case CAM_CDM_CMD_DMI:
  547. case CAM_CDM_CMD_SWD_DMI_32:
  548. case CAM_CDM_CMD_SWD_DMI_64: {
  549. if (*current_device_base == 0) {
  550. CAM_ERR(CAM_CDM,
  551. "Got SWI DMI cmd =%d for invalid hw",
  552. cdm_cmd_type);
  553. ret = -EINVAL;
  554. break;
  555. }
  556. ret = cam_cdm_util_swd_dmi_write(cdm_cmd_type,
  557. *current_device_base, cmd_buf, cmd_buf_size,
  558. &used_bytes);
  559. if (ret)
  560. break;
  561. if (used_bytes > 0) {
  562. cmd_buf_size -= used_bytes;
  563. cmd_buf += used_bytes / 4;
  564. }
  565. }
  566. break;
  567. case CAM_CDM_CMD_CHANGE_BASE: {
  568. struct cdm_changebase_cmd *change_base_cmd =
  569. (struct cdm_changebase_cmd *)cmd_buf;
  570. ret = cam_cdm_get_ioremap_from_base(
  571. change_base_cmd->base, base_array_size,
  572. base_table, current_device_base);
  573. if (ret != 0) {
  574. CAM_ERR(CAM_CDM,
  575. "Get ioremap change base failed %x",
  576. change_base_cmd->base);
  577. break;
  578. }
  579. CAM_DBG(CAM_CDM, "Got ioremap for %x addr=%pK",
  580. change_base_cmd->base,
  581. current_device_base);
  582. cmd_buf_size -= (4 *
  583. cam_cdm_required_size_changebase());
  584. cmd_buf += cam_cdm_required_size_changebase();
  585. }
  586. break;
  587. default:
  588. CAM_ERR(CAM_CDM, "unsupported cdm_cmd_type type 0%x",
  589. cdm_cmd_type);
  590. ret = -EINVAL;
  591. break;
  592. }
  593. if (ret < 0)
  594. break;
  595. }
  596. return ret;
  597. }
  598. static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr,
  599. uint32_t *cmd_buf_addr_end)
  600. {
  601. long ret = 0;
  602. struct cdm_dmi_cmd *p_dmi_cmd;
  603. uint32_t *temp_ptr = cmd_buf_addr;
  604. p_dmi_cmd = (struct cdm_dmi_cmd *)cmd_buf_addr;
  605. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
  606. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
  607. if (temp_ptr > cmd_buf_addr_end)
  608. CAM_ERR(CAM_CDM,
  609. "Invalid cmd start addr:%pK end addr:%pK",
  610. temp_ptr, cmd_buf_addr_end);
  611. CAM_INFO(CAM_CDM,
  612. "DMI: LEN: %u DMIAddr: 0x%X DMISel: 0x%X LUT_addr: 0x%X",
  613. p_dmi_cmd->length, p_dmi_cmd->DMIAddr,
  614. p_dmi_cmd->DMISel, p_dmi_cmd->addr);
  615. return ret;
  616. }
  617. static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr,
  618. uint32_t *cmd_buf_addr_end)
  619. {
  620. long ret = 0;
  621. struct cdm_indirect_cmd *p_indirect_cmd;
  622. uint32_t *temp_ptr = cmd_buf_addr;
  623. p_indirect_cmd = (struct cdm_indirect_cmd *)cmd_buf_addr;
  624. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
  625. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
  626. if (temp_ptr > cmd_buf_addr_end)
  627. CAM_ERR(CAM_CDM,
  628. "Invalid cmd start addr:%pK end addr:%pK",
  629. temp_ptr, cmd_buf_addr_end);
  630. CAM_INFO(CAM_CDM,
  631. "Buff Indirect: LEN: %u addr: 0x%X",
  632. p_indirect_cmd->length, p_indirect_cmd->addr);
  633. return ret;
  634. }
  635. static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr,
  636. uint32_t *cmd_buf_addr_end)
  637. {
  638. long ret = 0;
  639. struct cdm_regcontinuous_cmd *p_regcont_cmd;
  640. uint32_t *temp_ptr = cmd_buf_addr;
  641. int i = 0;
  642. p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
  643. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
  644. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
  645. CAM_INFO(CAM_CDM, "REG_CONT: COUNT: %u OFFSET: 0x%X",
  646. p_regcont_cmd->count, p_regcont_cmd->offset);
  647. for (i = 0; i < p_regcont_cmd->count; i++) {
  648. if (temp_ptr > cmd_buf_addr_end) {
  649. CAM_ERR(CAM_CDM,
  650. "Invalid cmd(%d) start addr:%pK end addr:%pK",
  651. i, temp_ptr, cmd_buf_addr_end);
  652. break;
  653. }
  654. CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i,
  655. *temp_ptr);
  656. temp_ptr++;
  657. ret++;
  658. }
  659. return ret;
  660. }
  661. static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr,
  662. uint32_t *cmd_buf_addr_end)
  663. {
  664. struct cdm_regrandom_cmd *p_regrand_cmd;
  665. uint32_t *temp_ptr = cmd_buf_addr;
  666. long ret = 0;
  667. int i = 0;
  668. p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
  669. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
  670. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
  671. CAM_INFO(CAM_CDM, "REG_RAND: COUNT: %u",
  672. p_regrand_cmd->count);
  673. for (i = 0; i < p_regrand_cmd->count; i++) {
  674. if (temp_ptr > cmd_buf_addr_end) {
  675. CAM_ERR(CAM_CDM,
  676. "Invalid cmd(%d) start addr:%pK end addr:%pK",
  677. i, temp_ptr, cmd_buf_addr_end);
  678. break;
  679. }
  680. CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X",
  681. i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i,
  682. *(temp_ptr + 1));
  683. temp_ptr += 2;
  684. ret += 2;
  685. }
  686. return ret;
  687. }
  688. static long cam_cdm_util_dump_gen_irq_cmd(uint32_t *cmd_buf_addr)
  689. {
  690. long ret = 0;
  691. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ];
  692. CAM_INFO(CAM_CDM, "GEN_IRQ");
  693. return ret;
  694. }
  695. static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr)
  696. {
  697. long ret = 0;
  698. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT];
  699. CAM_INFO(CAM_CDM, "WAIT_EVENT");
  700. return ret;
  701. }
  702. static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr,
  703. uint32_t *cmd_buf_addr_end)
  704. {
  705. long ret = 0;
  706. struct cdm_changebase_cmd *p_cbase_cmd;
  707. uint32_t *temp_ptr = cmd_buf_addr;
  708. if (temp_ptr > cmd_buf_addr_end) {
  709. CAM_ERR(CAM_CDM,
  710. "Invalid cmd start addr:%pK end addr:%pK",
  711. temp_ptr, cmd_buf_addr_end);
  712. return 0;
  713. }
  714. p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr;
  715. temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
  716. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
  717. CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X",
  718. p_cbase_cmd->base);
  719. return ret;
  720. }
  721. static long cam_cdm_util_dump_comp_wait_event_cmd(uint32_t *cmd_buf_addr)
  722. {
  723. long ret = 0;
  724. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_COMP_WAIT];
  725. CAM_INFO(CAM_CDM, "WAIT_EVENT");
  726. return ret;
  727. }
  728. static long cam_cdm_util_dump_perf_ctrl_cmd(uint32_t *cmd_buf_addr)
  729. {
  730. long ret = 0;
  731. ret += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL];
  732. CAM_INFO(CAM_CDM, "PERF_CTRL");
  733. return ret;
  734. }
  735. void cam_cdm_util_dump_cmd_buf(
  736. uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
  737. {
  738. uint32_t *buf_now = cmd_buf_start;
  739. uint32_t *buf_end = cmd_buf_end;
  740. uint32_t cmd = 0;
  741. if (!cmd_buf_start || !cmd_buf_end) {
  742. CAM_ERR(CAM_CDM, "Invalid args");
  743. return;
  744. }
  745. do {
  746. cmd = *buf_now;
  747. cmd = cmd >> CAM_CDM_COMMAND_OFFSET;
  748. switch (cmd) {
  749. case CAM_CDM_CMD_DMI:
  750. case CAM_CDM_CMD_DMI_32:
  751. case CAM_CDM_CMD_DMI_64:
  752. buf_now += cam_cdm_util_dump_dmi_cmd(buf_now,
  753. buf_end);
  754. break;
  755. case CAM_CDM_CMD_REG_CONT:
  756. buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now,
  757. buf_end);
  758. break;
  759. case CAM_CDM_CMD_REG_RANDOM:
  760. buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now,
  761. buf_end);
  762. break;
  763. case CAM_CDM_CMD_BUFF_INDIRECT:
  764. buf_now += cam_cdm_util_dump_buff_indirect(buf_now,
  765. buf_end);
  766. break;
  767. case CAM_CDM_CMD_GEN_IRQ:
  768. buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now);
  769. break;
  770. case CAM_CDM_CMD_WAIT_EVENT:
  771. buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now);
  772. break;
  773. case CAM_CDM_CMD_CHANGE_BASE:
  774. buf_now += cam_cdm_util_dump_change_base_cmd(buf_now,
  775. buf_end);
  776. break;
  777. case CAM_CDM_CMD_PERF_CTRL:
  778. buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now);
  779. break;
  780. case CAM_CDM_CMD_COMP_WAIT:
  781. buf_now +=
  782. cam_cdm_util_dump_comp_wait_event_cmd(buf_now);
  783. break;
  784. default:
  785. CAM_ERR(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x",
  786. cmd, *buf_now);
  787. buf_now++;
  788. break;
  789. }
  790. } while (buf_now <= cmd_buf_end);
  791. }
  792. static uint32_t cam_cdm_util_dump_reg_cont_cmd_v2(
  793. uint32_t *cmd_buf_addr,
  794. struct cam_cdm_cmd_buf_dump_info *dump_info)
  795. {
  796. int i;
  797. long ret;
  798. uint8_t *dst;
  799. size_t remain_len;
  800. uint32_t *temp_ptr = cmd_buf_addr;
  801. uint32_t *addr, *start;
  802. uint32_t min_len;
  803. struct cdm_regcontinuous_cmd *p_regcont_cmd;
  804. struct cam_cdm_cmd_dump_header *hdr;
  805. p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
  806. temp_ptr += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  807. ret = cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
  808. min_len = (sizeof(uint32_t) * p_regcont_cmd->count) +
  809. sizeof(struct cam_cdm_cmd_dump_header) +
  810. (2 * sizeof(uint32_t));
  811. remain_len = dump_info->dst_max_size - dump_info->dst_offset;
  812. if (remain_len < min_len) {
  813. CAM_WARN_RATE_LIMIT(CAM_CDM,
  814. "Dump buffer exhaust remain %zu min %u",
  815. remain_len, min_len);
  816. return ret;
  817. }
  818. dst = (char *)dump_info->dst_start + dump_info->dst_offset;
  819. hdr = (struct cam_cdm_cmd_dump_header *)dst;
  820. scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_CONT:");
  821. hdr->word_size = sizeof(uint32_t);
  822. addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
  823. start = addr;
  824. *addr++ = p_regcont_cmd->offset;
  825. *addr++ = p_regcont_cmd->count;
  826. for (i = 0; i < p_regcont_cmd->count; i++) {
  827. *addr = *temp_ptr;
  828. temp_ptr++;
  829. addr++;
  830. ret++;
  831. }
  832. hdr->size = hdr->word_size * (addr - start);
  833. dump_info->dst_offset += hdr->size +
  834. sizeof(struct cam_cdm_cmd_dump_header);
  835. return ret;
  836. }
  837. static uint32_t cam_cdm_util_dump_reg_random_cmd_v2(
  838. uint32_t *cmd_buf_addr,
  839. struct cam_cdm_cmd_buf_dump_info *dump_info)
  840. {
  841. int i;
  842. long ret;
  843. uint8_t *dst;
  844. uint32_t *temp_ptr = cmd_buf_addr;
  845. uint32_t *addr, *start;
  846. size_t remain_len;
  847. uint32_t min_len;
  848. struct cdm_regrandom_cmd *p_regrand_cmd;
  849. struct cam_cdm_cmd_dump_header *hdr;
  850. p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
  851. temp_ptr += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  852. ret = cam_cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
  853. min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) +
  854. sizeof(struct cam_cdm_cmd_dump_header) + sizeof(uint32_t);
  855. remain_len = dump_info->dst_max_size - dump_info->dst_offset;
  856. if (remain_len < min_len) {
  857. CAM_WARN_RATE_LIMIT(CAM_CDM,
  858. "Dump buffer exhaust remain %zu min %u",
  859. remain_len, min_len);
  860. return ret;
  861. }
  862. dst = (char *)dump_info->dst_start + dump_info->dst_offset;
  863. hdr = (struct cam_cdm_cmd_dump_header *)dst;
  864. scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_RANDOM:");
  865. hdr->word_size = sizeof(uint32_t);
  866. addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
  867. start = addr;
  868. *addr++ = p_regrand_cmd->count;
  869. for (i = 0; i < p_regrand_cmd->count; i++) {
  870. addr[0] = temp_ptr[0] & CAM_CDM_REG_OFFSET_MASK;
  871. addr[1] = temp_ptr[1];
  872. temp_ptr += 2;
  873. addr += 2;
  874. ret += 2;
  875. }
  876. hdr->size = hdr->word_size * (addr - start);
  877. dump_info->dst_offset += hdr->size +
  878. sizeof(struct cam_cdm_cmd_dump_header);
  879. return ret;
  880. }
  881. int cam_cdm_util_dump_cmd_bufs_v2(
  882. struct cam_cdm_cmd_buf_dump_info *dump_info)
  883. {
  884. uint32_t cmd;
  885. uint32_t *buf_now;
  886. int rc = 0;
  887. if (!dump_info || !dump_info->src_start || !dump_info->src_end ||
  888. !dump_info->dst_start) {
  889. CAM_INFO(CAM_CDM, "Invalid args");
  890. return -EINVAL;
  891. }
  892. buf_now = dump_info->src_start;
  893. do {
  894. if (dump_info->dst_offset >= dump_info->dst_max_size) {
  895. CAM_WARN(CAM_CDM,
  896. "Dump overshoot offset %zu size %zu",
  897. dump_info->dst_offset,
  898. dump_info->dst_max_size);
  899. return -ENOSPC;
  900. }
  901. cmd = *buf_now;
  902. cmd = cmd >> CAM_CDM_COMMAND_OFFSET;
  903. switch (cmd) {
  904. case CAM_CDM_CMD_DMI:
  905. case CAM_CDM_CMD_DMI_32:
  906. case CAM_CDM_CMD_DMI_64:
  907. buf_now += cam_cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
  908. break;
  909. case CAM_CDM_CMD_REG_CONT:
  910. buf_now += cam_cdm_util_dump_reg_cont_cmd_v2(buf_now,
  911. dump_info);
  912. break;
  913. case CAM_CDM_CMD_REG_RANDOM:
  914. buf_now += cam_cdm_util_dump_reg_random_cmd_v2(buf_now,
  915. dump_info);
  916. break;
  917. case CAM_CDM_CMD_BUFF_INDIRECT:
  918. buf_now += cam_cdm_get_cmd_header_size(
  919. CAM_CDM_CMD_BUFF_INDIRECT);
  920. break;
  921. case CAM_CDM_CMD_GEN_IRQ:
  922. buf_now += cam_cdm_get_cmd_header_size(
  923. CAM_CDM_CMD_GEN_IRQ);
  924. break;
  925. case CAM_CDM_CMD_WAIT_EVENT:
  926. buf_now += cam_cdm_get_cmd_header_size(
  927. CAM_CDM_CMD_WAIT_EVENT);
  928. break;
  929. case CAM_CDM_CMD_CHANGE_BASE:
  930. buf_now += cam_cdm_get_cmd_header_size(
  931. CAM_CDM_CMD_CHANGE_BASE);
  932. break;
  933. case CAM_CDM_CMD_PERF_CTRL:
  934. buf_now += cam_cdm_get_cmd_header_size(
  935. CAM_CDM_CMD_PERF_CTRL);
  936. break;
  937. case CAM_CDM_CMD_COMP_WAIT:
  938. buf_now += cam_cdm_get_cmd_header_size(
  939. CAM_CDM_CMD_COMP_WAIT);
  940. break;
  941. default:
  942. CAM_ERR(CAM_CDM, "Invalid CMD: 0x%x", cmd);
  943. buf_now++;
  944. break;
  945. }
  946. } while (buf_now <= dump_info->src_end);
  947. return rc;
  948. }