dw200_ioctl.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  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. __raw_writel(val, visys_sw_rst);
  336. }
  337. int vse_reset(struct dw200_subdev *dev)
  338. {
  339. dw_info("enter %s\n", __func__);
  340. #ifdef VSE_REG_RESET
  341. __raw_writel(0, dev->vse_reset);
  342. __raw_writel(1, dev->vse_reset);
  343. #endif
  344. vse_write_reg(dev, VSE_REG_CTRL, 0x100);
  345. return 0;
  346. }
  347. void vse_triger_dma_read(struct dw200_subdev *dev)
  348. {
  349. u32 reg = vse_read_reg(dev, VSE_REG_CTRL);
  350. REG_SET_BIT(reg, VSE_CONTROL_DMA_FRAME_START_BIT, 1);
  351. vse_write_reg(dev, VSE_REG_CTRL, reg);
  352. vse_write_reg(dev, VSE_REG_DMA_CTRL, 5);
  353. }
  354. #define swap(a, b) \
  355. { \
  356. (a) ^= (b); \
  357. (b) ^= (a); \
  358. (a) ^= (b); \
  359. }
  360. void setMIBaseAddress(struct dw200_subdev *dev, u32 width, u32 height,
  361. u32 format,u32 yuvbit, u64 addr, int channel)
  362. {
  363. u32 stride = ALIGN_UP(width*(yuvbit+1), 16);
  364. u32 crSize = 0;
  365. u32 yBaseAddr = addr;
  366. u32 regAddress = VSE_MI_BASE(channel);
  367. u32 crBaseAddr = 0;
  368. u32 ysize = stride * height;
  369. u32 cbSize = ysize;
  370. u32 cbBaseAddr = yBaseAddr + ysize;
  371. if (ysize == 0)
  372. return;
  373. switch (format) {
  374. case MEDIA_PIX_FMT_YUV420SP:
  375. cbSize /= 2;
  376. crSize = 0;
  377. break;
  378. case MEDIA_PIX_FMT_YUV422SP:
  379. break;
  380. case MEDIA_PIX_FMT_YUV422I:
  381. ysize = ysize * 2;
  382. break;
  383. case MEDIA_PIX_FMT_YUV444P:
  384. case MEDIA_PIX_FMT_RGB888P:
  385. crSize = ysize;
  386. crBaseAddr = cbBaseAddr + cbSize;
  387. break;
  388. case MEDIA_PIX_FMT_RGB888: /* only supoort RGB interleave format. RGB RGB RGB .. */
  389. case MEDIA_PIX_FMT_YUV444I:
  390. ysize *= 3;
  391. cbSize = 0;
  392. cbBaseAddr = 0;
  393. break;
  394. case MEDIA_PIX_FMT_BGR888P:
  395. crSize = ysize;
  396. crBaseAddr = cbBaseAddr + cbSize;
  397. swap(yBaseAddr, crBaseAddr);
  398. break;
  399. }
  400. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_BASE_ADDR_INIT, yBaseAddr);
  401. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_SIZE_INIT, ysize);
  402. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_BASE_ADDR_INIT,
  403. cbBaseAddr);
  404. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_SIZE_INIT, cbSize);
  405. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_BASE_ADDR_INIT,
  406. crBaseAddr);
  407. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_SIZE_INIT, crSize);
  408. }
  409. int vse_start_dma_read(struct dw200_subdev *dev, u64 addr)
  410. {
  411. u32 writeFormat = 0;
  412. u32 writeString = 0;
  413. u32 reg = 0;
  414. u32 address = VSE_REG_DMA_FORMAT;
  415. u32 width = dev->vse_info.src_w;
  416. u32 height = dev->vse_info.src_h;
  417. u32 format = dev->vse_info.in_format;
  418. u32 yuvbit = dev->vse_info.in_yuvbit;
  419. u32 ysize, cbSize;
  420. u32 yBaseAddr, cbBaseAddr, crBaseAddr;
  421. u32 stride;
  422. u32 img_width_bn;
  423. if(yuvbit)
  424. img_width_bn = width * 2;
  425. else{
  426. if(format == MEDIA_PIX_FMT_YUV422I){
  427. img_width_bn = width * 2;
  428. stride = stride * 2;
  429. }else
  430. img_width_bn = width;
  431. }
  432. switch (format) {
  433. case MEDIA_PIX_FMT_YUV422SP:
  434. writeFormat = 1;
  435. writeString = 0;
  436. break;
  437. case MEDIA_PIX_FMT_YUV422I:
  438. writeFormat = 1;
  439. writeString = 1;
  440. break;
  441. case MEDIA_PIX_FMT_YUV420SP:
  442. writeFormat = 0;
  443. writeString = 0;
  444. break;
  445. }
  446. reg = vse_read_reg(dev, address);
  447. dw_info("img_width_bn 0x%08x\n", img_width_bn );
  448. REG_SET_MASK(reg, VSE_RD_IMG_HSIZE_BN, (img_width_bn & 0x3FFF));
  449. REG_SET_MASK(reg, VSE_MI_FORMAT_WORD_ALIGNED, yuvbit);
  450. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, yuvbit);
  451. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  452. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  453. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, yuvbit);
  454. dw_info("VSE_REG_DMA_FORMAT reg 0x%08x\n", reg);
  455. vse_write_reg(dev, address, reg);
  456. stride = ALIGN_UP(width*(yuvbit+1), 16);
  457. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_WIDTH, width);
  458. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_HEIGHT, height);
  459. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_STRIDE, stride);
  460. ysize = stride * height;
  461. cbSize = ysize;
  462. yBaseAddr = addr;
  463. cbBaseAddr = yBaseAddr + ysize;
  464. crBaseAddr = 0;
  465. if (format == MEDIA_PIX_FMT_YUV420SP) {
  466. cbSize /= 2;
  467. } else if (format == MEDIA_PIX_FMT_YUV422I) {
  468. cbSize /= 2;
  469. crBaseAddr = cbBaseAddr + cbSize;
  470. }
  471. vse_write_reg(dev, VSE_REG_Y_PIC_START_ADDR, yBaseAddr);
  472. vse_write_reg(dev, VSE_REG_CB_PIC_START_ADDR, cbBaseAddr);
  473. vse_write_reg(dev, VSE_REG_CR_PIC_START_ADDR, crBaseAddr);
  474. vse_triger_dma_read(dev);
  475. return 0;
  476. }
  477. void setFormatConvPack(struct dw200_subdev *dev, u32 enable, int channel)
  478. {
  479. u32 reg;
  480. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  481. reg = vse_read_reg(dev, address);
  482. REG_SET_MASK(reg, VSE_FORMAT_CONV_ENABLE_PACK, enable);
  483. vse_write_reg(dev, address, reg);
  484. }
  485. void setFormatConvFull(struct dw200_subdev *dev, u32 y_full, u32 cbcr_full,
  486. u32 noco422, int channel)
  487. {
  488. u32 reg;
  489. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  490. reg = vse_read_reg(dev, address);
  491. REG_SET_MASK(reg, VSE_FORMAT_CONV_Y_FULL, y_full);
  492. REG_SET_MASK(reg, VSE_FORMAT_CONV_CBCR_FULL, cbcr_full);
  493. REG_SET_MASK(reg, VSE_FORMAT_CONV_CONFIG_422NOCO, 0);
  494. vse_write_reg(dev, address, reg);
  495. }
  496. static u32 format_conv_map[] = { 2, 2, 1, 3, 3, 6, 6, 6 };
  497. void setFormatConvFormat(struct dw200_subdev *dev, u32 inputFormat,
  498. u32 outputFormat,u32 yuvbit, int channel)
  499. {
  500. u32 reg;
  501. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  502. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  503. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  504. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  505. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  506. inputFormat = MEDIA_PIX_FMT_YUV420SP;
  507. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  508. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  509. inputFormat = MEDIA_PIX_FMT_YUV422SP;
  510. }
  511. reg = vse_read_reg(dev, address);
  512. REG_SET_MASK(reg, VSE_FORMAT_CONV_OUTPUT_FORMAT,
  513. format_conv_map[outputFormat]);
  514. REG_SET_MASK(reg, VSE_FORMAT_CONV_INPUT_FORMAT,
  515. format_conv_map[inputFormat]);
  516. REG_SET_MASK(reg, VSE_FORMAT_CONV_EXPAND_8TO10_ENABLE,
  517. yuvbit);
  518. vse_write_reg(dev, address, reg);
  519. }
  520. void setInputSize(struct dw200_subdev *dev, u32 width, u32 height)
  521. {
  522. u32 reg = ((height & 0x1FFF) << 16) | (width & 0x1FFF);
  523. vse_write_reg(dev, VSE_REG_IN_SIZE, reg);
  524. }
  525. void setCropSize(struct dw200_subdev *dev, u32 left, u32 right, u32 top,
  526. u32 bottom, int channel)
  527. {
  528. u32 hreg = ((right & 0x1FFF) << 16) | (left & 0x1FFF);
  529. u32 vreg = ((bottom & 0x1FFF) << 16) | (top & 0x1FFF);
  530. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_XDIR, hreg);
  531. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_YDIR, vreg);
  532. }
  533. void updateResizeControl(struct dw200_subdev *dev, u32 reg, int channel)
  534. {
  535. u32 address = VSE_RSZBASE(channel);
  536. vse_write_reg(dev, address, reg);
  537. }
  538. void resizeControlAutoUpdate(struct dw200_subdev *dev, u32 autoUpdate,
  539. int channel)
  540. {
  541. u32 reg;
  542. u32 address = VSE_RSZBASE(channel);
  543. reg = vse_read_reg(dev, address);
  544. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  545. vse_write_reg(dev, address, reg);
  546. }
  547. void resizeControlConfigUpdate(struct dw200_subdev *dev, u32 configUpdate,
  548. int channel)
  549. {
  550. u32 reg;
  551. u32 address = VSE_RSZBASE(channel);
  552. reg = vse_read_reg(dev, address);
  553. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  554. vse_write_reg(dev, address, reg);
  555. }
  556. void resizeControlEnableCrop(struct dw200_subdev *dev, u32 enable, int channel)
  557. {
  558. u32 reg;
  559. u32 address = VSE_RSZBASE(channel);
  560. reg = vse_read_reg(dev, address);
  561. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CROP_ENABLE_BIT, enable);
  562. vse_write_reg(dev, address, reg);
  563. }
  564. void updateVseControl(struct dw200_subdev *dev, u32 inputChannel,
  565. u32 inputFormat, u32 enbalePath0, u32 enbalePath1,
  566. u32 enbalePath2, u32 autoUpdate, u32 configUpdate)
  567. {
  568. u32 reg = 0;
  569. REG_SET_BIT(reg, VSE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  570. REG_SET_BIT(reg, VSE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  571. REG_SET_BIT(reg, VSE_CONTROL_PATH0_ENABLE_BIT, enbalePath0);
  572. REG_SET_BIT(reg, VSE_CONTROL_PATH1_ENABLE_BIT, enbalePath1);
  573. REG_SET_BIT(reg, VSE_CONTROL_PATH2_ENABLE_BIT, enbalePath2);
  574. REG_SET_MASK(reg, VSE_CONTROL_INPUT_SELECT, inputChannel);
  575. REG_SET_MASK(reg, VSE_CONTROL_INPUT_FORMAT, inputFormat);
  576. vse_write_reg(dev, VSE_REG_CTRL, reg);
  577. int i;
  578. for(i=0 ;i <3; i++){
  579. reg = vse_read_reg(dev,VSE_RSZBASE(i));
  580. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CONFIG_UPDATE_BIT, 1);
  581. vse_write_reg(dev, VSE_RSZBASE(i), reg);
  582. }
  583. /* BUS ID and BUS CONFIG, hardcode here, user need adjust it on their hardware. */
  584. vse_write_reg(dev, 0xa24, 0x01000100);
  585. vse_write_reg(dev, 0xa20, 0x001000fa);
  586. vse_write_reg(dev, 0xa28, 0x924c5214);
  587. vse_write_reg(dev, 0xa30, 0x100000fa);
  588. vse_write_reg(dev, 0xa34, 0x01000100);
  589. vse_write_reg(dev, 0xa38, 0x924c5214);
  590. }
  591. void enableMIControl(struct dw200_subdev *dev, u32 enable, int channel)
  592. {
  593. u32 reg = vse_read_reg(dev, VSE_REG_MI_CTRL);
  594. REG_SET_BIT(reg, channel, enable);
  595. REG_SET_BIT(reg, VSE_MI_CONTROL_RDMA_ENABLE_BIT, 1);
  596. vse_write_reg(dev, VSE_REG_MI_CTRL, reg);
  597. }
  598. void setMIBufferInfo(struct dw200_subdev *dev, u32 width, u32 height,
  599. u32 format, u32 is10Bit, u32 aligned, int channel)
  600. {
  601. u32 writeFormat = 0;
  602. u32 writeString = 0;
  603. u32 reg = 0;
  604. u32 address;
  605. u32 stride = ALIGN_UP(width*(is10Bit+1), 16);
  606. u32 size = stride * height;
  607. switch (format) {
  608. case MEDIA_PIX_FMT_YUV422SP:
  609. writeFormat = 1;
  610. writeString = 0;
  611. break;
  612. case MEDIA_PIX_FMT_YUV422I:
  613. size = size * 2;
  614. writeFormat = 1;
  615. writeString = 1;
  616. break;
  617. case MEDIA_PIX_FMT_YUV420SP:
  618. writeFormat = 0;
  619. writeString = 0;
  620. break;
  621. case MEDIA_PIX_FMT_YUV444P:
  622. writeFormat = 2;
  623. writeString = 2;
  624. break;
  625. case MEDIA_PIX_FMT_YUV444I:
  626. writeFormat = 2;
  627. writeString = 1;
  628. break;
  629. case MEDIA_PIX_FMT_RGB888:
  630. writeFormat = 2;
  631. writeString = 1;
  632. break;
  633. case MEDIA_PIX_FMT_RGB888P:
  634. case MEDIA_PIX_FMT_BGR888P:
  635. writeFormat = 2;
  636. writeString = 2;
  637. break;
  638. }
  639. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_LENGTH, stride);
  640. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_WIDTH,
  641. width);
  642. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_HEIGHT,
  643. height);
  644. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_SIZE, size);
  645. address = VSE_MI_BASE(channel) + VSE_REG_MI_FMT;
  646. reg = vse_read_reg(dev, address);
  647. REG_SET_MASK(reg, VSE_MI_FORMAT_WORD_ALIGNED, is10Bit);
  648. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, is10Bit);
  649. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  650. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  651. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, is10Bit);
  652. vse_write_reg(dev, address, reg);
  653. }
  654. void setMIControlConfig(struct dw200_subdev *dev, u32 enableOffset,
  655. u32 enableUpdateBaseAddress, u32 configUpdate, u32 skip,
  656. u32 autoUpdate, u32 enablePingpong, int channel)
  657. {
  658. u32 reg = 0;
  659. REG_SET_BIT(reg, VSE_MI_PATH_INIT_OFFSET_EN_BIT, enableOffset);
  660. REG_SET_BIT(reg, VSE_MI_PATH_INIT_BASE_EN_BIT, enableUpdateBaseAddress);
  661. REG_SET_BIT(reg, VSE_MI_PATH_CONFIG_UPDATE_BIT, configUpdate);
  662. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_SKIP_BIT, skip);
  663. REG_SET_BIT(reg, VSE_MI_PATH_AUTO_UPDATE_BIT, autoUpdate);
  664. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_PINGPONG_BIT, enablePingpong);
  665. vse_write_reg(dev, VSE_MI_BASE(channel), reg);
  666. }
  667. u32 vse_get_scale_factor(int src, int dst)
  668. {
  669. if (dst >= src) {
  670. return ((65536 * (src - 1)) / (dst - 1));
  671. } else if (dst < src) {
  672. return ((65536 * (dst - 1)) / (src - 1)) + 1;
  673. }
  674. return 0;
  675. }
  676. void setScaleFactor(struct dw200_subdev *dev, u32 src_w, u32 src_h, u32 dst_w,
  677. u32 dst_h, u32 inputFormat, u32 outputFormat, int channel)
  678. {
  679. bool hyup, vyup, hcup, vcup;
  680. u32 scale_factor = vse_get_scale_factor(src_w, dst_w);
  681. u32 address = VSE_RSZBASE(channel);
  682. u32 reg = vse_read_reg(dev, address);
  683. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HY,
  684. scale_factor);
  685. scale_factor = vse_get_scale_factor(src_h, dst_h);
  686. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VY,
  687. scale_factor);
  688. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VY_ENABLE_BIT,
  689. ((src_h != dst_h) & 0x01));
  690. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HY_ENABLE_BIT,
  691. ((src_w != dst_w) & 0x01));
  692. hyup = src_w < dst_w;
  693. vyup = src_h < dst_h;
  694. /* Format conv module doesn't support convert other formats to YUV420SP.
  695. doesn't support convert 420SP to other formats too.
  696. so scale down/up cbcr here.
  697. */
  698. src_w /= 2;
  699. dst_w /= 2;
  700. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  701. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  702. src_h /= 2;
  703. dst_h /= 2;
  704. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  705. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  706. /* scale 422 to 420 */
  707. dst_h /= 2;
  708. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  709. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  710. /* scale 420 to 422
  711. cbcr width*2, use input buffer as 422SP */
  712. src_h /= 2;
  713. }
  714. hcup = src_w < dst_w;
  715. vcup = src_h < dst_h;
  716. scale_factor = vse_get_scale_factor(src_w, dst_w);
  717. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCB,
  718. scale_factor);
  719. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCR,
  720. scale_factor);
  721. scale_factor = vse_get_scale_factor(src_h, dst_h);
  722. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VC,
  723. scale_factor);
  724. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VCUP_BIT, vcup);
  725. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VYUP_BIT, vyup);
  726. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HCUP_BIT, hcup);
  727. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HYUP_BIT, hyup);
  728. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VC_ENABLE_BIT,
  729. (src_h != dst_h));
  730. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HC_ENABLE_BIT,
  731. (src_w != dst_w));
  732. vse_write_reg(dev, address, reg);
  733. }
  734. int vse_read_irq(struct dw200_subdev *dev, u32 * ret)
  735. {
  736. // dw_info("enter %s\n", __func__);
  737. *ret = vse_read_reg(dev, VSE_REG_MI_MSI);
  738. return 0;
  739. }
  740. int vse_dequeue_irq(struct dw200_subdev *dev, u32 * ret)
  741. {
  742. vivdw200_mis_t data;
  743. if (dev == NULL || ret == NULL) {
  744. dw_info("wrong input parameter.\n");
  745. return -1;
  746. }
  747. if(0 == vivdw200_read_circle_queue(&data, &dev->vse_circle_list)) {
  748. *ret = data.val;
  749. } else {
  750. //pr_err("failed to dequeue vse mis.\n");
  751. *ret = 0;
  752. }
  753. return 0;
  754. }
  755. int vse_clear_irq(struct dw200_subdev *dev, u32 mis)
  756. {
  757. dw_info("enter %s\n", __func__);
  758. vse_write_reg(dev, VSE_REG_MI_ICR, mis);
  759. return 0;
  760. }
  761. int vse_mask_irq(struct dw200_subdev *dev, u32 mask)
  762. {
  763. dw_info("enter %s 0x%08x\n", __func__, mask);
  764. vse_write_reg(dev, VSE_REG_MI_IMSC, mask);
  765. return 0;
  766. }
  767. int vse_ioc_qcap(struct dw200_subdev *dev, void *args)
  768. {
  769. struct v4l2_capability *cap = (struct v4l2_capability *)args;
  770. strcpy((char *)cap->driver, "viv_vse");
  771. return 0;
  772. }
  773. int vse_update_buffers(struct dw200_subdev *dev, u64 * addr)
  774. {
  775. struct vse_params *param = &dev->vse_info;
  776. struct vse_mi_settings *mi = param->mi_settings;
  777. int i = 0;
  778. dw_info("enter %s\n", __func__);
  779. for (; i < 3; i++) {
  780. if (addr[i] != 0) {
  781. setMIBaseAddress(dev, mi[i].width, mi[i].height,
  782. mi[i].out_format,mi[i].yuvbit, addr[i], i);
  783. }
  784. }
  785. return 0;
  786. }
  787. int vse_update_mi_info(struct dw200_subdev *dev)
  788. {
  789. struct vse_params *param = &dev->vse_info;
  790. struct vse_mi_settings *mi = param->mi_settings;
  791. int i = 0;
  792. dw_info("enter %s\n", __func__);
  793. for (; i < 3; i++) {
  794. if (!mi[i].enable)
  795. continue;
  796. setMIBufferInfo(dev, mi[i].width, mi[i].height,
  797. mi[i].out_format, mi[i].yuvbit, true, i);
  798. enableMIControl(dev, mi[i].enable, i);
  799. setMIControlConfig(dev, true, true, true, false, true, false,
  800. i);
  801. }
  802. return 0;
  803. }
  804. int vse_s_params(struct dw200_subdev *dev)
  805. {
  806. struct vse_params *param = &dev->vse_info;
  807. int i = 0;
  808. int input_select = 0;
  809. int crop_w, crop_h, scale_w, scale_h;
  810. struct vse_crop_size *cropSize;
  811. struct vse_size *outputSize;
  812. dw_info("enter %s\n", __func__);
  813. setInputSize(dev, param->src_w, param->src_h);
  814. for (; i < 3; i++) {
  815. if (!param->resize_enable[i])
  816. continue;
  817. cropSize = &param->crop_size[i];
  818. outputSize = &param->out_size[i];
  819. crop_w = cropSize->right - cropSize->left + 1;
  820. crop_h = cropSize->bottom - cropSize->top + 1;
  821. scale_w = param->src_w;
  822. scale_h = param->src_h;
  823. if (crop_w > 1 && crop_h > 1) {
  824. resizeControlEnableCrop(dev, 1, i);
  825. setCropSize(dev, cropSize->left, cropSize->right,
  826. cropSize->top, cropSize->bottom, i);
  827. scale_w = crop_w;
  828. scale_h = crop_h;
  829. } else {
  830. resizeControlEnableCrop(dev, 0, i);
  831. }
  832. /* ONLY SUPPORT Semiplanar NOW, all enable pack */
  833. setFormatConvPack(dev, true, i);
  834. setFormatConvFull(dev, true, true, false, i);
  835. setFormatConvFormat(dev, param->in_format,
  836. param->format_conv[i].out_format,param->mi_settings[i].yuvbit, i);
  837. setScaleFactor(dev, scale_w, scale_h, outputSize->width,
  838. outputSize->height, param->in_format,
  839. param->format_conv[i].out_format, i);
  840. resizeControlAutoUpdate(dev, 1, i);
  841. resizeControlConfigUpdate(dev, 1, i);
  842. }
  843. #ifndef HAL_CMODEL
  844. input_select = param->input_select;
  845. #endif
  846. updateVseControl(dev, input_select, param->in_format,
  847. param->resize_enable[0],
  848. param->resize_enable[1],
  849. param->resize_enable[2], true, true);
  850. return 0;
  851. }
  852. void dw200_mutex_lock(struct dw200_subdev *dev)
  853. {
  854. mutex_lock(dev->vvmutex);
  855. }
  856. void dw200_mutex_unlock(struct dw200_subdev *dev)
  857. {
  858. mutex_unlock(dev->vvmutex);
  859. }
  860. long dw200_priv_ioctl(struct dw200_subdev *dev, unsigned int cmd, void *args)
  861. {
  862. int ret = -1;
  863. u64 addr;
  864. switch (cmd) {
  865. case DWEIOC_RESET:
  866. dw_info("DWEIOC_RESET\n");
  867. ret = dwe_reset(dev);
  868. break;
  869. case DWEIOC_S_PARAMS:
  870. dw_info("DWEIOC_S_PARAMS\n");
  871. viv_check_retval(copy_from_user
  872. (&dev->dwe_info, args, sizeof(dev->dwe_info)));
  873. ret = dwe_s_params(dev);
  874. break;
  875. case DWEIOC_ENABLE_BUS:
  876. dw_info("DWEIOC_ENABLE_BUS\n");
  877. ret = dwe_enable_bus(dev, 1);
  878. break;
  879. case DWEIOC_DISABLE_BUS:
  880. dw_info("DWEIOC_DISABLE_BUS\n");
  881. ret = dwe_enable_bus(dev, 0);
  882. break;
  883. case DWEIOC_DISABLE_IRQ:
  884. dw_info("DWEIOC_DISABLE_IRQ\n");
  885. ret = dwe_disable_irq(dev);
  886. break;
  887. case DWEIOC_CLEAR_IRQ:
  888. dw_info("DWEIOC_CLEAR_IRQ\n");
  889. ret = dwe_clear_irq_1(dev);
  890. break;
  891. case DWEIOC_READ_IRQ:{
  892. dw_info("DWEIOC_READ_IRQ\n");
  893. u32 irq = 0;
  894. #ifdef HAL_CMODEL
  895. dwe_read_irq((struct dw200_subdev *)dev, &irq);
  896. #else
  897. ret = dwe_dequeue_irq(dev, &irq);
  898. #endif
  899. viv_check_retval(copy_to_user(args, &irq, sizeof(irq)));
  900. break;
  901. }
  902. case DWEIOC_START_DMA_READ:
  903. dw_info("DWEIOC_START_DMA_READ\n");
  904. ;dw_src_addr_t src_addr;
  905. viv_check_retval(copy_from_user(&src_addr, args, sizeof(src_addr)));
  906. ret = dwe_start_dma_read(dev, src_addr);
  907. break;
  908. case DWEIOC_SET_BUFFER:
  909. dw_info("DWEIOC_SET_BUFFER\n");
  910. viv_check_retval(copy_from_user(&addr, args, sizeof(addr)));
  911. ret = dwe_set_buffer(dev, addr);
  912. break;
  913. case DWEIOC_SET_LUT:
  914. dw_info("DWEIOC_SET_LUT\n");
  915. viv_check_retval(copy_from_user(&addr, args, sizeof(addr)));
  916. ret = dwe_set_lut(dev, addr);
  917. break;
  918. case DWEIOC_START:
  919. dw_info("DWEIOC_START\n");
  920. ret = dwe_start(dev);
  921. break;
  922. #ifdef __KERNEL__
  923. case VIDIOC_QUERYCAP:
  924. ret = dwe_ioc_qcap(dev, args);
  925. break;
  926. #endif
  927. case VSEIOC_RESET:
  928. dw_info("VSEIOC_RESET\n");
  929. ret = vse_reset(dev);
  930. break;
  931. case VSEIOC_S_PARAMS:
  932. dw_info("VSEIOC_S_PARAMS\n");
  933. viv_check_retval(copy_from_user
  934. (&dev->vse_info, args, sizeof(dev->vse_info)));
  935. ret = vse_s_params(dev);
  936. break;
  937. case VSEIOC_CLEAR_IRQ:
  938. dw_info("VSEIOC_CLEAR_IRQ\n");
  939. //ret = vse_clear_irq(dev);
  940. vse_write_reg(dev, VSE_REG_MI_MSI, 0);
  941. break;
  942. case VSEIOC_READ_IRQ:{
  943. dw_info("VSEIOC_READ_IRQ\n");
  944. u32 irq = 0;
  945. #ifdef HAL_CMODEL
  946. vse_read_irq((struct dw200_subdev *)dev, &irq);
  947. #else
  948. ret = vse_dequeue_irq(dev, &irq);
  949. #endif
  950. viv_check_retval(copy_to_user(args, &irq, sizeof(irq)));
  951. break;
  952. }
  953. case VSEIOC_START_DMA_READ:{
  954. dw_info("VSEIOC_START_DMA_READ\n");
  955. u64 addr;
  956. viv_check_retval(copy_from_user
  957. (&addr, args, sizeof(addr)));
  958. ret = vse_start_dma_read(dev, addr);
  959. break;
  960. }
  961. case VSEIOC_U_MI_INFO:
  962. dw_info("VSEIOC_U_MI_INFO\n");
  963. ret = vse_update_mi_info(dev);
  964. break;
  965. case VSEIOC_U_BUFFER:{
  966. dw_info("VSEIOC_U_BUFFER\n");
  967. u64 addrs[3];
  968. viv_check_retval(copy_from_user
  969. (addrs, args, sizeof(addrs)));
  970. vse_update_buffers(dev, addrs);
  971. break;
  972. }
  973. case VSEIOC_MASK_IRQ:{
  974. dw_info("VSEIOC_MASK_IRQ\n");
  975. u32 mask;
  976. viv_check_retval(copy_from_user
  977. (&mask, args, sizeof(mask)));
  978. vse_mask_irq(dev, mask);
  979. break;
  980. }
  981. case DW200IOC_LOCK:
  982. dw_info("DW200IOC_LOCK\n");
  983. dw200_mutex_lock(dev);
  984. break;
  985. case DW200IOC_UNLOCK:
  986. dw_info("DW200IOC_UNLOCK\n");
  987. dw200_mutex_unlock(dev);
  988. break;
  989. case DW200IOC_VISYS_RESET:
  990. dw_info("DW200IOC_VISYS_RESET\n");
  991. visys_reset();
  992. break;
  993. default:
  994. //pr_err("unsupported dwe command %d", cmd);
  995. break;
  996. }
  997. return ret;
  998. }