dw200_ioctl.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. *
  25. *****************************************************************************
  26. *
  27. * The GPL License (GPL)
  28. *
  29. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  30. *
  31. * This program is free software; you can redistribute it and/or
  32. * modify it under the terms of the GNU General Public License
  33. * as published by the Free Software Foundation; either version 2
  34. * of the License, or (at your option) any later version.
  35. *
  36. * This program is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with this program;
  43. *
  44. *****************************************************************************
  45. *
  46. * Note: This software is released under dual MIT and GPL licenses. A
  47. * recipient may use this file under the terms of either the MIT license or
  48. * GPL License. If you wish to use only one license not the other, you can
  49. * indicate your decision by deleting one of the above license notices in your
  50. * version of this file.
  51. *
  52. *****************************************************************************/
  53. #ifdef __KERNEL__
  54. //#include "dw200_driver.h"
  55. #else
  56. #include <linux/videodev2.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59. #endif
  60. #include "dw200_ioctl.h"
  61. #include "dwe_regs.h"
  62. #include "vse_regs.h"
  63. #undef ALIGN_UP
  64. #define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align)-1))
  65. #ifdef __KERNEL__
  66. #define dw_info(...)
  67. #else
  68. #define dw_info(...)
  69. #endif
  70. #ifndef __KERNEL__
  71. #ifdef HAL_CMODEL
  72. #define DEWARP_REGISTER_OFFSET 0xc00
  73. #else
  74. #define DEWARP_REGISTER_OFFSET 0x380000
  75. #endif
  76. #define DEWARP_REGISTER_CTL 0x308250
  77. pReadBar g_dw200_read_func;
  78. pWriteBar g_dw200_write_func;
  79. void dwe_set_func(pReadBar read_func, pWriteBar write_func)
  80. {
  81. g_dw200_read_func = read_func;
  82. g_dw200_write_func = write_func;
  83. }
  84. void dwe_write_reg(struct dw200_subdev *dev, u32 offset, u32 val)
  85. {
  86. g_dw200_write_func(DEWARP_REGISTER_OFFSET + offset, val);
  87. }
  88. u32 dwe_read_reg(struct dw200_subdev *dev, u32 offset)
  89. {
  90. u32 data;
  91. g_dw200_read_func(DEWARP_REGISTER_OFFSET + offset, &data);
  92. return data;
  93. }
  94. long dw200_copy_data(void *dst, void *src, int size)
  95. {
  96. if (dst != src)
  97. memcpy(dst, src, size);
  98. return 0;
  99. }
  100. void vse_set_func(pVseReadBar read_func, pVseWriteBar write_func)
  101. {
  102. g_dw200_read_func = read_func;
  103. g_dw200_write_func = write_func;
  104. }
  105. void vse_write_reg(struct dw200_subdev *dev, u32 offset, u32 val)
  106. {
  107. g_dw200_write_func(offset, val);
  108. }
  109. u32 vse_read_reg(struct dw200_subdev *dev, u32 offset)
  110. {
  111. u32 data;
  112. g_dw200_read_func(offset, &data);
  113. return data;
  114. }
  115. #else
  116. void dwe_write_reg(struct dw200_subdev *dev, u32 offset, u32 val)
  117. {
  118. //dw_info("dwe write addr 0x%08x val 0x%08x\n",offset,val);
  119. __raw_writel(val, dev->dwe_base + offset);
  120. }
  121. u32 dwe_read_reg(struct dw200_subdev *dev, u32 offset)
  122. {
  123. u32 val;
  124. val=__raw_readl(dev->dwe_base + offset);
  125. dw_info("dwe read addr 0x%08x val 0x%08x\n",offset,val);
  126. return val;
  127. }
  128. void vse_write_reg(struct dw200_subdev *dev, u32 offset, u32 val)
  129. {
  130. //dw_info("vse write addr 0x%08x val 0x%08x\n",offset,val);
  131. __raw_writel(val, dev->vse_base + offset);
  132. }
  133. u32 vse_read_reg(struct dw200_subdev *dev, u32 offset)
  134. {
  135. u32 val;
  136. return __raw_readl(dev->vse_base + offset);
  137. dw_info("vse read addr 0x%08x val 0x%08x\n",offset,val);
  138. return val;
  139. }
  140. #endif
  141. int dwe_reset(struct dw200_subdev *dev)
  142. {
  143. dw_info("enter %s\n", __func__);
  144. #ifdef DWE_REG_RESET
  145. __raw_writel(0, dev->dwe_reset);
  146. __raw_writel(1, dev->dwe_reset);
  147. #endif
  148. dwe_write_reg(dev, DEWARP_CTRL, 0x0c);
  149. return 0;
  150. }
  151. int dwe_s_params(struct dw200_subdev *dev)
  152. {
  153. struct dwe_hw_info *info = &dev->dwe_info;
  154. u32 reg = 0;
  155. u32 reg_y_rbuff_size = ALIGN_UP(info->dst_stride * info->dst_h, 16);
  156. u32 vUp = (info->split_v1 & ~0x0F) | 0x0C;
  157. u32 vDown = (info->split_v2 & ~0x0F) | 0x0C;
  158. u32 hLine = (info->split_h & ~0x0F) | 0x0C;
  159. u32 dst_img_width_bn;
  160. if(info->out_yuvbit)
  161. dst_img_width_bn = info->dst_w * 2;
  162. else{
  163. if(info->out_format == MEDIA_PIX_FMT_YUV422I)
  164. dst_img_width_bn = info->dst_w * 2;
  165. else
  166. dst_img_width_bn = info->dst_w;
  167. }
  168. dw_info("enter %s\n", __func__);
  169. dwe_write_reg(dev, MAP_LUT_SIZE,
  170. ((info->map_w & 0x7ff) | ((info->map_h & 0x7ff) << 16)));
  171. dwe_write_reg(dev, SRC_IMG_SIZE,
  172. ((info->src_w & 0x1fff) |
  173. ((info->src_h & 0x1fff) << 16)));
  174. dwe_write_reg(dev, SRC_IMG_STRIDE, info->src_stride);
  175. dwe_write_reg(dev, DST_IMG_SIZE,
  176. ((info->dst_w & 0x1FFF) |
  177. ((info->dst_h & 0x1FFF) << 16)));
  178. dwe_write_reg(dev, DST_IMG_WIDTH_BN,
  179. ((dst_img_width_bn & 0x7FFF) |
  180. ((dst_img_width_bn & 0x7FFF) << 16)));
  181. dwe_write_reg(dev, DST_IMG_STRIDE, info->dst_stride);
  182. dwe_write_reg(dev, DST_IMG_Y_SIZE1, reg_y_rbuff_size >> 4);
  183. dwe_write_reg(dev, DST_IMG_UV_SIZE1, info->dst_size_uv >> 4);
  184. dwe_write_reg(dev, VERTICAL_SPLIT_LINE,
  185. (vUp & 0x1fff) | ((vDown & 0x1fff) << 16));
  186. dwe_write_reg(dev, HORIZON_SPLIT_LINE, (hLine & 0x1fff));
  187. reg = 0x4c808009;
  188. reg |= ((info->split_line & 0x1) << 11);
  189. reg |= ((info->in_format & 0x3) << 4);
  190. reg |= ((info->out_format & 0x3) << 6);
  191. reg |= ((info->in_yuvbit & 0x1) << 12);
  192. reg |= ((info->out_yuvbit & 0x1) << 13);
  193. reg |=
  194. ((info->src_auto_shadow & 0x1) << 8) |
  195. ((info->dst_auto_shadow & 0x1) << 10);
  196. reg |= ((info->hand_shake & 0x1) << 9);
  197. dwe_write_reg(dev, DEWARP_CTRL, reg);
  198. dwe_write_reg(dev, BOUNDRY_PIXEL,
  199. (((info->boundary_y & 0xff) << 16) |
  200. ((info->boundary_u & 0xff)
  201. << 8) | (info->boundary_v & 0xff)));
  202. dwe_write_reg(dev, SCALE_FACTOR, info->scale_factor);
  203. dwe_write_reg(dev, ROI_START,
  204. ((info->roi_x & 0x1fff) |
  205. ((info->roi_y & 0x1fff) << 16)));
  206. return 0;
  207. }
  208. int dwe_enable_bus(struct dw200_subdev *dev, bool enable)
  209. {
  210. u32 reg = dwe_read_reg(dev, BUS_CTRL);
  211. dw_info("enter %s\n", __func__);
  212. if (enable) {
  213. reg |= DEWRAP_BUS_CTRL_ENABLE_MASK;
  214. reg |= DEWRAP_BUS_CTRL_WR_ID_ENABLE_MASK;
  215. reg |= DEWRAP_BUS_CTRL_RD_ID_ENABLE_MASK;
  216. reg &= ~(0xff << DEWRAP_BUS_CTRL_RD_ID_SHIFT);
  217. reg &= ~(0xff << DEWRAP_BUS_CTRL_WR_ID_SHIFT);
  218. reg |= (0x0 << DEWRAP_BUS_CTRL_RD_ID_SHIFT); //set read id as 1
  219. reg |= (0x0 << DEWRAP_BUS_CTRL_WR_ID_SHIFT); //set write id as 2
  220. dwe_write_reg(dev, BUS_CTRL, reg);
  221. } else {
  222. reg &= ~DEWRAP_BUS_CTRL_ENABLE_MASK;
  223. reg &= ~DEWRAP_BUS_CTRL_WR_ID_ENABLE_MASK;
  224. reg &= ~DEWRAP_BUS_CTRL_RD_ID_ENABLE_MASK;
  225. reg &= ~(0xff << DEWRAP_BUS_CTRL_RD_ID_SHIFT);
  226. reg &= ~(0xff << DEWRAP_BUS_CTRL_WR_ID_SHIFT);
  227. dwe_write_reg(dev, BUS_CTRL, reg);
  228. }
  229. return 0;
  230. }
  231. int dwe_disable_irq(struct dw200_subdev *dev)
  232. {
  233. dw_info("enter %s\n", __func__);
  234. dwe_write_reg(dev, INTERRUPT_STATUS, INT_RESET_MASK|INT_CLR_MASK);
  235. return 0;
  236. }
  237. int dwe_clear_irq(struct dw200_subdev *dev, u32 mis)
  238. {
  239. u32 interrupt_status;
  240. dw_info("enter %s\n", __func__);
  241. interrupt_status = dwe_read_reg(dev, INTERRUPT_STATUS);
  242. dwe_write_reg(dev, INTERRUPT_STATUS, mis|interrupt_status);// INT_CLR_MASK);
  243. // dwe_write_reg(dev, DEWARP_CTRL, reg_dewarp_ctrl | 2);
  244. // dwe_write_reg(dev, DEWARP_CTRL, reg_dewarp_ctrl);
  245. return 0;
  246. }
  247. int dwe_clear_irq_1(struct dw200_subdev *dev)
  248. {
  249. u32 reg_dewarp_ctrl;
  250. dw_info("enter %s\n", __func__);
  251. reg_dewarp_ctrl = dwe_read_reg(dev, DEWARP_CTRL);
  252. dwe_write_reg(dev, INTERRUPT_STATUS, INT_CLR_MASK);
  253. dwe_write_reg(dev, DEWARP_CTRL, reg_dewarp_ctrl | 2);
  254. dwe_write_reg(dev, DEWARP_CTRL, reg_dewarp_ctrl);
  255. return 0;
  256. }
  257. int dwe_read_irq(struct dw200_subdev *dev, u32 * ret)
  258. {
  259. u32 irq = 0;
  260. irq = dwe_read_reg(dev, INTERRUPT_STATUS);
  261. *ret = irq;
  262. return 0;
  263. }
  264. int dwe_dequeue_irq(struct dw200_subdev *dev, u32 * ret)
  265. {
  266. vivdw200_mis_t data;
  267. if (dev == NULL || ret == NULL) {
  268. dw_info("wrong input parameter.\n");
  269. return -1;
  270. }
  271. if(0 ==vivdw200_read_circle_queue(&data, &dev->dwe_circle_list)){
  272. *ret = data.val;
  273. } else {
  274. //pr_err("failed to dequeue dwe mis.\n");
  275. *ret = 0;
  276. }
  277. return 0;
  278. }
  279. int dwe_start_dma_read(struct dw200_subdev *dev, dw_src_addr_t src_addr)
  280. {
  281. struct dwe_hw_info *info = &dev->dwe_info;
  282. #ifdef DWE_REG_RESET
  283. u32 regStart = 1 << 4;
  284. u32 reg;
  285. #endif
  286. if (src_addr.uv_addr == 0) {
  287. u32 reg_y_rbuff_size = ALIGN_UP(info->src_stride * info->src_h, 16);
  288. src_addr.uv_addr = (u32) src_addr.y_addr + reg_y_rbuff_size;
  289. }
  290. dw_info("enter %s\n", __func__);
  291. dwe_write_reg(dev, SRC_IMG_Y_BASE, (src_addr.y_addr) >> 4);
  292. dwe_write_reg(dev, SRC_IMG_UV_BASE, (src_addr.uv_addr) >> 4);
  293. #ifdef DWE_REG_RESET
  294. reg = __raw_readl(dev->dwe_reset);
  295. __raw_writel(reg | regStart, dev->dwe_reset);
  296. __raw_writel(reg & ~regStart, dev->dwe_reset);
  297. #endif
  298. return 0;
  299. }
  300. int dwe_start(struct dw200_subdev *dev)
  301. {
  302. dw_info("enter %s\n", __func__);
  303. u32 reg_dewarp_ctrl;
  304. reg_dewarp_ctrl = dwe_read_reg(dev, DEWARP_CTRL);
  305. dwe_write_reg(dev, DEWARP_CTRL, reg_dewarp_ctrl | 2);
  306. return 0;
  307. }
  308. int dwe_set_buffer(struct dw200_subdev *dev, u64 addr)
  309. {
  310. struct dwe_hw_info *info = &dev->dwe_info;
  311. u32 reg_dst_y_base = (u32) addr;
  312. u32 reg_y_rbuff_size = ALIGN_UP(info->dst_stride * info->dst_h, 16);
  313. u32 reg_dst_uv_base = reg_dst_y_base + reg_y_rbuff_size;
  314. dw_info("enter %s\n", __func__);
  315. dwe_write_reg(dev, DST_IMG_Y_BASE, (reg_dst_y_base) >> 4);
  316. dwe_write_reg(dev, DST_IMG_UV_BASE, (reg_dst_uv_base) >> 4);
  317. return 0;
  318. }
  319. int dwe_set_lut(struct dw200_subdev *dev, u64 addr)
  320. {
  321. dwe_write_reg(dev, MAP_LUT_ADDR, ((u32) addr) >> 4);
  322. return 0;
  323. }
  324. int dwe_ioc_qcap(struct dw200_subdev *dev, void *args)
  325. {
  326. struct v4l2_capability *cap = (struct v4l2_capability *)args;
  327. strcpy((char *)cap->driver, "viv_dw200");
  328. return 0;
  329. }
  330. extern void __iomem *visys_sw_rst;
  331. void visys_reset(void)
  332. {
  333. u32 val = __raw_readl(visys_sw_rst);
  334. __raw_writel( val & ~BIT(31), visys_sw_rst);
  335. udelay(1);
  336. __raw_writel(val, visys_sw_rst);
  337. udelay(1);
  338. }
  339. int vse_reset(struct dw200_subdev *dev)
  340. {
  341. dw_info("enter %s\n", __func__);
  342. #ifdef VSE_REG_RESET
  343. __raw_writel(0, dev->vse_reset);
  344. __raw_writel(1, dev->vse_reset);
  345. #endif
  346. vse_write_reg(dev, VSE_REG_CTRL, 0x100);
  347. return 0;
  348. }
  349. void vse_triger_dma_read(struct dw200_subdev *dev)
  350. {
  351. u32 reg = vse_read_reg(dev, VSE_REG_CTRL);
  352. REG_SET_BIT(reg, VSE_CONTROL_DMA_FRAME_START_BIT, 1);
  353. vse_write_reg(dev, VSE_REG_CTRL, reg);
  354. vse_write_reg(dev, VSE_REG_DMA_CTRL, 5);
  355. }
  356. #define swap(a, b) \
  357. { \
  358. (a) ^= (b); \
  359. (b) ^= (a); \
  360. (a) ^= (b); \
  361. }
  362. void setMIBaseAddress(struct dw200_subdev *dev, u32 width, u32 height,
  363. u32 format,u32 yuvbit, u64 addr, int channel)
  364. {
  365. u32 stride = ALIGN_UP(width*(yuvbit+1), 16);
  366. u32 crSize = 0;
  367. u32 yBaseAddr = addr;
  368. u32 regAddress = VSE_MI_BASE(channel);
  369. u32 crBaseAddr = 0;
  370. u32 ysize = stride * height;
  371. u32 cbSize = ysize;
  372. u32 cbBaseAddr = yBaseAddr + ysize;
  373. if (ysize == 0)
  374. return;
  375. switch (format) {
  376. case MEDIA_PIX_FMT_YUV420SP:
  377. cbSize /= 2;
  378. crSize = 0;
  379. break;
  380. case MEDIA_PIX_FMT_YUV422SP:
  381. break;
  382. case MEDIA_PIX_FMT_YUV422I:
  383. ysize = ysize * 2;
  384. break;
  385. case MEDIA_PIX_FMT_YUV444P:
  386. case MEDIA_PIX_FMT_RGB888P:
  387. crSize = ysize;
  388. crBaseAddr = cbBaseAddr + cbSize;
  389. break;
  390. case MEDIA_PIX_FMT_RGB888: /* only supoort RGB interleave format. RGB RGB RGB .. */
  391. case MEDIA_PIX_FMT_YUV444I:
  392. ysize *= 3;
  393. cbSize = 0;
  394. cbBaseAddr = 0;
  395. break;
  396. case MEDIA_PIX_FMT_BGR888P:
  397. crSize = ysize;
  398. crBaseAddr = cbBaseAddr + cbSize;
  399. swap(yBaseAddr, crBaseAddr);
  400. break;
  401. }
  402. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_BASE_ADDR_INIT, yBaseAddr);
  403. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_SIZE_INIT, ysize);
  404. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_BASE_ADDR_INIT,
  405. cbBaseAddr);
  406. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_SIZE_INIT, cbSize);
  407. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_BASE_ADDR_INIT,
  408. crBaseAddr);
  409. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_SIZE_INIT, crSize);
  410. }
  411. int vse_start_dma_read(struct dw200_subdev *dev, u64 addr)
  412. {
  413. u32 writeFormat = 0;
  414. u32 writeString = 0;
  415. u32 reg = 0;
  416. u32 address = VSE_REG_DMA_FORMAT;
  417. u32 width = dev->vse_info.src_w;
  418. u32 height = dev->vse_info.src_h;
  419. u32 format = dev->vse_info.in_format;
  420. u32 yuvbit = dev->vse_info.in_yuvbit;
  421. u32 ysize, cbSize;
  422. u32 yBaseAddr, cbBaseAddr, crBaseAddr;
  423. u32 stride;
  424. u32 img_width_bn;
  425. if(yuvbit)
  426. img_width_bn = width * 2;
  427. else{
  428. if(format == MEDIA_PIX_FMT_YUV422I){
  429. img_width_bn = width * 2;
  430. stride = stride * 2;
  431. }else
  432. img_width_bn = width;
  433. }
  434. switch (format) {
  435. case MEDIA_PIX_FMT_YUV422SP:
  436. writeFormat = 1;
  437. writeString = 0;
  438. break;
  439. case MEDIA_PIX_FMT_YUV422I:
  440. writeFormat = 1;
  441. writeString = 1;
  442. break;
  443. case MEDIA_PIX_FMT_YUV420SP:
  444. writeFormat = 0;
  445. writeString = 0;
  446. break;
  447. }
  448. reg = vse_read_reg(dev, address);
  449. dw_info("img_width_bn 0x%08x\n", img_width_bn );
  450. REG_SET_MASK(reg, VSE_RD_IMG_HSIZE_BN, (img_width_bn & 0x3FFF));
  451. REG_SET_MASK(reg, VSE_MI_FORMAT_WORD_ALIGNED, yuvbit);
  452. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, yuvbit);
  453. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  454. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  455. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, yuvbit);
  456. dw_info("VSE_REG_DMA_FORMAT reg 0x%08x\n", reg);
  457. vse_write_reg(dev, address, reg);
  458. stride = ALIGN_UP(width*(yuvbit+1), 16);
  459. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_WIDTH, width);
  460. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_HEIGHT, height);
  461. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_STRIDE, stride);
  462. ysize = stride * height;
  463. cbSize = ysize;
  464. yBaseAddr = addr;
  465. cbBaseAddr = yBaseAddr + ysize;
  466. crBaseAddr = 0;
  467. if (format == MEDIA_PIX_FMT_YUV420SP) {
  468. cbSize /= 2;
  469. } else if (format == MEDIA_PIX_FMT_YUV422I) {
  470. cbSize /= 2;
  471. crBaseAddr = cbBaseAddr + cbSize;
  472. }
  473. vse_write_reg(dev, VSE_REG_Y_PIC_START_ADDR, yBaseAddr);
  474. vse_write_reg(dev, VSE_REG_CB_PIC_START_ADDR, cbBaseAddr);
  475. vse_write_reg(dev, VSE_REG_CR_PIC_START_ADDR, crBaseAddr);
  476. vse_triger_dma_read(dev);
  477. return 0;
  478. }
  479. void setFormatConvPack(struct dw200_subdev *dev, u32 enable, int channel)
  480. {
  481. u32 reg;
  482. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  483. reg = vse_read_reg(dev, address);
  484. REG_SET_MASK(reg, VSE_FORMAT_CONV_ENABLE_PACK, enable);
  485. vse_write_reg(dev, address, reg);
  486. }
  487. void setFormatConvFull(struct dw200_subdev *dev, u32 y_full, u32 cbcr_full,
  488. u32 noco422, int channel)
  489. {
  490. u32 reg;
  491. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  492. reg = vse_read_reg(dev, address);
  493. REG_SET_MASK(reg, VSE_FORMAT_CONV_Y_FULL, y_full);
  494. REG_SET_MASK(reg, VSE_FORMAT_CONV_CBCR_FULL, cbcr_full);
  495. REG_SET_MASK(reg, VSE_FORMAT_CONV_CONFIG_422NOCO, 0);
  496. vse_write_reg(dev, address, reg);
  497. }
  498. static u32 format_conv_map[] = { 2, 2, 1, 3, 3, 6, 6, 6 };
  499. void setFormatConvFormat(struct dw200_subdev *dev, u32 inputFormat,
  500. u32 outputFormat,u32 yuvbit, int channel)
  501. {
  502. u32 reg;
  503. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  504. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  505. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  506. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  507. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  508. inputFormat = MEDIA_PIX_FMT_YUV420SP;
  509. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  510. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  511. inputFormat = MEDIA_PIX_FMT_YUV422SP;
  512. }
  513. reg = vse_read_reg(dev, address);
  514. REG_SET_MASK(reg, VSE_FORMAT_CONV_OUTPUT_FORMAT,
  515. format_conv_map[outputFormat]);
  516. REG_SET_MASK(reg, VSE_FORMAT_CONV_INPUT_FORMAT,
  517. format_conv_map[inputFormat]);
  518. REG_SET_MASK(reg, VSE_FORMAT_CONV_EXPAND_8TO10_ENABLE,
  519. yuvbit);
  520. vse_write_reg(dev, address, reg);
  521. }
  522. void setInputSize(struct dw200_subdev *dev, u32 width, u32 height)
  523. {
  524. u32 reg = ((height & 0x1FFF) << 16) | (width & 0x1FFF);
  525. vse_write_reg(dev, VSE_REG_IN_SIZE, reg);
  526. }
  527. void setCropSize(struct dw200_subdev *dev, u32 left, u32 right, u32 top,
  528. u32 bottom, int channel)
  529. {
  530. u32 hreg = ((right & 0x1FFF) << 16) | (left & 0x1FFF);
  531. u32 vreg = ((bottom & 0x1FFF) << 16) | (top & 0x1FFF);
  532. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_XDIR, hreg);
  533. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_YDIR, vreg);
  534. }
  535. void updateResizeControl(struct dw200_subdev *dev, u32 reg, int channel)
  536. {
  537. u32 address = VSE_RSZBASE(channel);
  538. vse_write_reg(dev, address, reg);
  539. }
  540. void resizeControlAutoUpdate(struct dw200_subdev *dev, u32 autoUpdate,
  541. int channel)
  542. {
  543. u32 reg;
  544. u32 address = VSE_RSZBASE(channel);
  545. reg = vse_read_reg(dev, address);
  546. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  547. vse_write_reg(dev, address, reg);
  548. }
  549. void resizeControlConfigUpdate(struct dw200_subdev *dev, u32 configUpdate,
  550. int channel)
  551. {
  552. u32 reg;
  553. u32 address = VSE_RSZBASE(channel);
  554. reg = vse_read_reg(dev, address);
  555. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  556. vse_write_reg(dev, address, reg);
  557. }
  558. void resizeControlEnableCrop(struct dw200_subdev *dev, u32 enable, int channel)
  559. {
  560. u32 reg;
  561. u32 address = VSE_RSZBASE(channel);
  562. reg = vse_read_reg(dev, address);
  563. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CROP_ENABLE_BIT, enable);
  564. vse_write_reg(dev, address, reg);
  565. }
  566. void updateVseControl(struct dw200_subdev *dev, u32 inputChannel,
  567. u32 inputFormat, u32 enbalePath0, u32 enbalePath1,
  568. u32 enbalePath2, u32 autoUpdate, u32 configUpdate)
  569. {
  570. u32 reg = 0;
  571. REG_SET_BIT(reg, VSE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  572. REG_SET_BIT(reg, VSE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  573. REG_SET_BIT(reg, VSE_CONTROL_PATH0_ENABLE_BIT, enbalePath0);
  574. REG_SET_BIT(reg, VSE_CONTROL_PATH1_ENABLE_BIT, enbalePath1);
  575. REG_SET_BIT(reg, VSE_CONTROL_PATH2_ENABLE_BIT, enbalePath2);
  576. REG_SET_MASK(reg, VSE_CONTROL_INPUT_SELECT, inputChannel);
  577. REG_SET_MASK(reg, VSE_CONTROL_INPUT_FORMAT, inputFormat);
  578. vse_write_reg(dev, VSE_REG_CTRL, reg);
  579. int i;
  580. for(i=0 ;i <3; i++){
  581. reg = vse_read_reg(dev,VSE_RSZBASE(i));
  582. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CONFIG_UPDATE_BIT, 1);
  583. vse_write_reg(dev, VSE_RSZBASE(i), reg);
  584. }
  585. /* BUS ID and BUS CONFIG, hardcode here, user need adjust it on their hardware. */
  586. vse_write_reg(dev, 0xa24, 0x01000100);
  587. vse_write_reg(dev, 0xa20, 0x001000fa);
  588. vse_write_reg(dev, 0xa28, 0x924c5214);
  589. vse_write_reg(dev, 0xa30, 0x100000fa);
  590. vse_write_reg(dev, 0xa34, 0x01000100);
  591. vse_write_reg(dev, 0xa38, 0x924c5214);
  592. }
  593. void enableMIControl(struct dw200_subdev *dev, u32 enable, int channel)
  594. {
  595. u32 reg = vse_read_reg(dev, VSE_REG_MI_CTRL);
  596. REG_SET_BIT(reg, channel, enable);
  597. REG_SET_BIT(reg, VSE_MI_CONTROL_RDMA_ENABLE_BIT, 1);
  598. vse_write_reg(dev, VSE_REG_MI_CTRL, reg);
  599. }
  600. void setMIBufferInfo(struct dw200_subdev *dev, u32 width, u32 height,
  601. u32 format, u32 is10Bit, u32 aligned, int channel)
  602. {
  603. u32 writeFormat = 0;
  604. u32 writeString = 0;
  605. u32 reg = 0;
  606. u32 address;
  607. u32 stride = ALIGN_UP(width*(is10Bit+1), 16);
  608. u32 size = stride * height;
  609. switch (format) {
  610. case MEDIA_PIX_FMT_YUV422SP:
  611. writeFormat = 1;
  612. writeString = 0;
  613. break;
  614. case MEDIA_PIX_FMT_YUV422I:
  615. size = size * 2;
  616. writeFormat = 1;
  617. writeString = 1;
  618. break;
  619. case MEDIA_PIX_FMT_YUV420SP:
  620. writeFormat = 0;
  621. writeString = 0;
  622. break;
  623. case MEDIA_PIX_FMT_YUV444P:
  624. writeFormat = 2;
  625. writeString = 2;
  626. break;
  627. case MEDIA_PIX_FMT_YUV444I:
  628. writeFormat = 2;
  629. writeString = 1;
  630. break;
  631. case MEDIA_PIX_FMT_RGB888:
  632. writeFormat = 2;
  633. writeString = 1;
  634. break;
  635. case MEDIA_PIX_FMT_RGB888P:
  636. case MEDIA_PIX_FMT_BGR888P:
  637. writeFormat = 2;
  638. writeString = 2;
  639. break;
  640. }
  641. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_LENGTH, stride);
  642. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_WIDTH,
  643. width);
  644. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_HEIGHT,
  645. height);
  646. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_SIZE, size);
  647. address = VSE_MI_BASE(channel) + VSE_REG_MI_FMT;
  648. reg = vse_read_reg(dev, address);
  649. REG_SET_MASK(reg, VSE_MI_FORMAT_WORD_ALIGNED, is10Bit);
  650. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, is10Bit);
  651. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  652. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  653. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, is10Bit);
  654. vse_write_reg(dev, address, reg);
  655. }
  656. void setMIControlConfig(struct dw200_subdev *dev, u32 enableOffset,
  657. u32 enableUpdateBaseAddress, u32 configUpdate, u32 skip,
  658. u32 autoUpdate, u32 enablePingpong, int channel)
  659. {
  660. u32 reg = 0;
  661. REG_SET_BIT(reg, VSE_MI_PATH_INIT_OFFSET_EN_BIT, enableOffset);
  662. REG_SET_BIT(reg, VSE_MI_PATH_INIT_BASE_EN_BIT, enableUpdateBaseAddress);
  663. REG_SET_BIT(reg, VSE_MI_PATH_CONFIG_UPDATE_BIT, configUpdate);
  664. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_SKIP_BIT, skip);
  665. REG_SET_BIT(reg, VSE_MI_PATH_AUTO_UPDATE_BIT, autoUpdate);
  666. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_PINGPONG_BIT, enablePingpong);
  667. vse_write_reg(dev, VSE_MI_BASE(channel), reg);
  668. }
  669. u32 vse_get_scale_factor(int src, int dst)
  670. {
  671. if (dst >= src) {
  672. return ((65536 * (src - 1)) / (dst - 1));
  673. } else if (dst < src) {
  674. return ((65536 * (dst - 1)) / (src - 1)) + 1;
  675. }
  676. return 0;
  677. }
  678. void setScaleFactor(struct dw200_subdev *dev, u32 src_w, u32 src_h, u32 dst_w,
  679. u32 dst_h, u32 inputFormat, u32 outputFormat, int channel)
  680. {
  681. bool hyup, vyup, hcup, vcup;
  682. u32 scale_factor = vse_get_scale_factor(src_w, dst_w);
  683. u32 address = VSE_RSZBASE(channel);
  684. u32 reg = vse_read_reg(dev, address);
  685. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HY,
  686. scale_factor);
  687. scale_factor = vse_get_scale_factor(src_h, dst_h);
  688. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VY,
  689. scale_factor);
  690. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VY_ENABLE_BIT,
  691. ((src_h != dst_h) & 0x01));
  692. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HY_ENABLE_BIT,
  693. ((src_w != dst_w) & 0x01));
  694. hyup = src_w < dst_w;
  695. vyup = src_h < dst_h;
  696. /* Format conv module doesn't support convert other formats to YUV420SP.
  697. doesn't support convert 420SP to other formats too.
  698. so scale down/up cbcr here.
  699. */
  700. src_w /= 2;
  701. dst_w /= 2;
  702. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  703. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  704. src_h /= 2;
  705. dst_h /= 2;
  706. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  707. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  708. /* scale 422 to 420 */
  709. dst_h /= 2;
  710. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  711. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  712. /* scale 420 to 422
  713. cbcr width*2, use input buffer as 422SP */
  714. src_h /= 2;
  715. }
  716. hcup = src_w < dst_w;
  717. vcup = src_h < dst_h;
  718. scale_factor = vse_get_scale_factor(src_w, dst_w);
  719. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCB,
  720. scale_factor);
  721. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCR,
  722. scale_factor);
  723. scale_factor = vse_get_scale_factor(src_h, dst_h);
  724. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VC,
  725. scale_factor);
  726. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VCUP_BIT, vcup);
  727. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VYUP_BIT, vyup);
  728. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HCUP_BIT, hcup);
  729. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HYUP_BIT, hyup);
  730. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VC_ENABLE_BIT,
  731. (src_h != dst_h));
  732. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HC_ENABLE_BIT,
  733. (src_w != dst_w));
  734. vse_write_reg(dev, address, reg);
  735. }
  736. int vse_read_irq(struct dw200_subdev *dev, u32 * ret)
  737. {
  738. // dw_info("enter %s\n", __func__);
  739. *ret = vse_read_reg(dev, VSE_REG_MI_MSI);
  740. return 0;
  741. }
  742. int vse_dequeue_irq(struct dw200_subdev *dev, u32 * ret)
  743. {
  744. vivdw200_mis_t data;
  745. if (dev == NULL || ret == NULL) {
  746. dw_info("wrong input parameter.\n");
  747. return -1;
  748. }
  749. if(0 == vivdw200_read_circle_queue(&data, &dev->vse_circle_list)) {
  750. *ret = data.val;
  751. } else {
  752. //pr_err("failed to dequeue vse mis.\n");
  753. *ret = 0;
  754. }
  755. return 0;
  756. }
  757. int vse_clear_irq(struct dw200_subdev *dev, u32 mis)
  758. {
  759. dw_info("enter %s\n", __func__);
  760. vse_write_reg(dev, VSE_REG_MI_ICR, mis);
  761. return 0;
  762. }
  763. int vse_mask_irq(struct dw200_subdev *dev, u32 mask)
  764. {
  765. dw_info("enter %s 0x%08x\n", __func__, mask);
  766. vse_write_reg(dev, VSE_REG_MI_IMSC, mask);
  767. return 0;
  768. }
  769. int vse_ioc_qcap(struct dw200_subdev *dev, void *args)
  770. {
  771. struct v4l2_capability *cap = (struct v4l2_capability *)args;
  772. strcpy((char *)cap->driver, "viv_vse");
  773. return 0;
  774. }
  775. int vse_update_buffers(struct dw200_subdev *dev, u64 * addr)
  776. {
  777. struct vse_params *param = &dev->vse_info;
  778. struct vse_mi_settings *mi = param->mi_settings;
  779. int i = 0;
  780. dw_info("enter %s\n", __func__);
  781. for (; i < 3; i++) {
  782. if (addr[i] != 0) {
  783. setMIBaseAddress(dev, mi[i].width, mi[i].height,
  784. mi[i].out_format,mi[i].yuvbit, addr[i], i);
  785. }
  786. }
  787. return 0;
  788. }
  789. int vse_update_mi_info(struct dw200_subdev *dev)
  790. {
  791. struct vse_params *param = &dev->vse_info;
  792. struct vse_mi_settings *mi = param->mi_settings;
  793. int i = 0;
  794. dw_info("enter %s\n", __func__);
  795. for (; i < 3; i++) {
  796. if (!mi[i].enable)
  797. continue;
  798. setMIBufferInfo(dev, mi[i].width, mi[i].height,
  799. mi[i].out_format, mi[i].yuvbit, true, i);
  800. enableMIControl(dev, mi[i].enable, i);
  801. setMIControlConfig(dev, true, true, true, false, true, false,
  802. i);
  803. }
  804. return 0;
  805. }
  806. int vse_s_params(struct dw200_subdev *dev)
  807. {
  808. struct vse_params *param = &dev->vse_info;
  809. int i = 0;
  810. int input_select = 0;
  811. int crop_w, crop_h, scale_w, scale_h;
  812. struct vse_crop_size *cropSize;
  813. struct vse_size *outputSize;
  814. dw_info("enter %s\n", __func__);
  815. setInputSize(dev, param->src_w, param->src_h);
  816. for (; i < 3; i++) {
  817. if (!param->resize_enable[i])
  818. continue;
  819. cropSize = &param->crop_size[i];
  820. outputSize = &param->out_size[i];
  821. crop_w = cropSize->right - cropSize->left + 1;
  822. crop_h = cropSize->bottom - cropSize->top + 1;
  823. scale_w = param->src_w;
  824. scale_h = param->src_h;
  825. if (crop_w > 1 && crop_h > 1) {
  826. resizeControlEnableCrop(dev, 1, i);
  827. setCropSize(dev, cropSize->left, cropSize->right,
  828. cropSize->top, cropSize->bottom, i);
  829. scale_w = crop_w;
  830. scale_h = crop_h;
  831. } else {
  832. resizeControlEnableCrop(dev, 0, i);
  833. }
  834. /* ONLY SUPPORT Semiplanar NOW, all enable pack */
  835. setFormatConvPack(dev, true, i);
  836. setFormatConvFull(dev, true, true, false, i);
  837. setFormatConvFormat(dev, param->in_format,
  838. param->format_conv[i].out_format,param->mi_settings[i].yuvbit, i);
  839. setScaleFactor(dev, scale_w, scale_h, outputSize->width,
  840. outputSize->height, param->in_format,
  841. param->format_conv[i].out_format, i);
  842. resizeControlAutoUpdate(dev, 1, i);
  843. resizeControlConfigUpdate(dev, 1, i);
  844. }
  845. #ifndef HAL_CMODEL
  846. input_select = param->input_select;
  847. #endif
  848. updateVseControl(dev, input_select, param->in_format,
  849. param->resize_enable[0],
  850. param->resize_enable[1],
  851. param->resize_enable[2], true, true);
  852. return 0;
  853. }
  854. long dw200_priv_ioctl(struct dw200_subdev *dev, unsigned int cmd, void *args)
  855. {
  856. int ret = -1;
  857. u64 addr;
  858. switch (cmd) {
  859. case DWEIOC_RESET:
  860. dw_info("DWEIOC_RESET\n");
  861. ret = dwe_reset(dev);
  862. break;
  863. case DWEIOC_S_PARAMS:
  864. dw_info("DWEIOC_S_PARAMS\n");
  865. viv_check_retval(copy_from_user
  866. (&dev->dwe_info, args, sizeof(dev->dwe_info)));
  867. ret = dwe_s_params(dev);
  868. break;
  869. case DWEIOC_ENABLE_BUS:
  870. dw_info("DWEIOC_ENABLE_BUS\n");
  871. ret = dwe_enable_bus(dev, 1);
  872. break;
  873. case DWEIOC_DISABLE_BUS:
  874. dw_info("DWEIOC_DISABLE_BUS\n");
  875. ret = dwe_enable_bus(dev, 0);
  876. break;
  877. case DWEIOC_DISABLE_IRQ:
  878. dw_info("DWEIOC_DISABLE_IRQ\n");
  879. ret = dwe_disable_irq(dev);
  880. break;
  881. case DWEIOC_CLEAR_IRQ:
  882. dw_info("DWEIOC_CLEAR_IRQ\n");
  883. ret = dwe_clear_irq_1(dev);
  884. break;
  885. case DWEIOC_READ_IRQ:{
  886. dw_info("DWEIOC_READ_IRQ\n");
  887. u32 irq = 0;
  888. #ifdef HAL_CMODEL
  889. dwe_read_irq((struct dw200_subdev *)dev, &irq);
  890. #else
  891. ret = dwe_dequeue_irq(dev, &irq);
  892. #endif
  893. viv_check_retval(copy_to_user(args, &irq, sizeof(irq)));
  894. break;
  895. }
  896. case DWEIOC_START_DMA_READ:
  897. dw_info("DWEIOC_START_DMA_READ\n");
  898. ;dw_src_addr_t src_addr;
  899. viv_check_retval(copy_from_user(&src_addr, args, sizeof(src_addr)));
  900. ret = dwe_start_dma_read(dev, src_addr);
  901. break;
  902. case DWEIOC_SET_BUFFER:
  903. dw_info("DWEIOC_SET_BUFFER\n");
  904. viv_check_retval(copy_from_user(&addr, args, sizeof(addr)));
  905. ret = dwe_set_buffer(dev, addr);
  906. break;
  907. case DWEIOC_SET_LUT:
  908. dw_info("DWEIOC_SET_LUT\n");
  909. viv_check_retval(copy_from_user(&addr, args, sizeof(addr)));
  910. ret = dwe_set_lut(dev, addr);
  911. break;
  912. case DWEIOC_START:
  913. dw_info("DWEIOC_START\n");
  914. ret = dwe_start(dev);
  915. break;
  916. #ifdef __KERNEL__
  917. case VIDIOC_QUERYCAP:
  918. ret = dwe_ioc_qcap(dev, args);
  919. break;
  920. #endif
  921. case VSEIOC_RESET:
  922. dw_info("VSEIOC_RESET\n");
  923. ret = vse_reset(dev);
  924. break;
  925. case VSEIOC_S_PARAMS:
  926. dw_info("VSEIOC_S_PARAMS\n");
  927. viv_check_retval(copy_from_user
  928. (&dev->vse_info, args, sizeof(dev->vse_info)));
  929. ret = vse_s_params(dev);
  930. break;
  931. case VSEIOC_CLEAR_IRQ:
  932. dw_info("VSEIOC_CLEAR_IRQ\n");
  933. //ret = vse_clear_irq(dev);
  934. vse_write_reg(dev, VSE_REG_MI_MSI, 0);
  935. break;
  936. case VSEIOC_READ_IRQ:{
  937. dw_info("VSEIOC_READ_IRQ\n");
  938. u32 irq = 0;
  939. #ifdef HAL_CMODEL
  940. vse_read_irq((struct dw200_subdev *)dev, &irq);
  941. #else
  942. ret = vse_dequeue_irq(dev, &irq);
  943. #endif
  944. viv_check_retval(copy_to_user(args, &irq, sizeof(irq)));
  945. break;
  946. }
  947. case VSEIOC_START_DMA_READ:{
  948. dw_info("VSEIOC_START_DMA_READ\n");
  949. u64 addr;
  950. viv_check_retval(copy_from_user
  951. (&addr, args, sizeof(addr)));
  952. ret = vse_start_dma_read(dev, addr);
  953. break;
  954. }
  955. case VSEIOC_U_MI_INFO:
  956. dw_info("VSEIOC_U_MI_INFO\n");
  957. ret = vse_update_mi_info(dev);
  958. break;
  959. case VSEIOC_U_BUFFER:{
  960. dw_info("VSEIOC_U_BUFFER\n");
  961. u64 addrs[3];
  962. viv_check_retval(copy_from_user
  963. (addrs, args, sizeof(addrs)));
  964. vse_update_buffers(dev, addrs);
  965. break;
  966. }
  967. case VSEIOC_MASK_IRQ:{
  968. dw_info("VSEIOC_MASK_IRQ\n");
  969. u32 mask;
  970. viv_check_retval(copy_from_user
  971. (&mask, args, sizeof(mask)));
  972. vse_mask_irq(dev, mask);
  973. break;
  974. }
  975. case DW200IOC_VISYS_RESET:
  976. dw_info("DW200IOC_VISYS_RESET\n");
  977. visys_reset();
  978. break;
  979. default:
  980. //pr_err("unsupported dwe command %d", cmd);
  981. break;
  982. }
  983. return ret;
  984. }