vse_ioctl.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  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 "vse_driver.h"
  55. #else
  56. #include <linux/videodev2.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59. #endif
  60. #include "vse_ioctl.h"
  61. #include "vse_regs.h"
  62. #ifndef __KERNEL__
  63. #ifdef HAL_CMODEL
  64. #define VSE_REGISTER_OFFSET 0
  65. #else
  66. #define VSE_REGISTER_OFFSET 0x500000
  67. #endif
  68. #define VSE_REGISTER_CTL 0x308254
  69. pVseReadBar g_read_func;
  70. pVseWriteBar g_write_func;
  71. void vse_set_func(pVseReadBar read_func, pVseWriteBar write_func)
  72. {
  73. g_read_func = read_func;
  74. g_write_func = write_func;
  75. }
  76. void vse_write_reg(struct vse_ic_dev *dev, u32 offset, u32 val)
  77. {
  78. g_write_func(VSE_REGISTER_OFFSET + offset, val);
  79. }
  80. u32 vse_read_reg(struct vse_ic_dev *dev, u32 offset)
  81. {
  82. u32 data;
  83. g_read_func(VSE_REGISTER_OFFSET + offset, &data);
  84. return data;
  85. }
  86. long vse_copy_data(void *dst, void *src, int size)
  87. {
  88. if (dst != src)
  89. memcpy(dst, src, size);
  90. return 0;
  91. }
  92. #else
  93. void vse_write_reg(struct vse_ic_dev *dev, u32 offset, u32 val)
  94. {
  95. __raw_writel(val, dev->base + offset);
  96. }
  97. u32 vse_read_reg(struct vse_ic_dev *dev, u32 offset)
  98. {
  99. return __raw_readl(dev->base + offset);
  100. }
  101. #endif
  102. int vse_reset(struct vse_ic_dev *dev)
  103. {
  104. pr_info("enter %s\n", __func__);
  105. #ifdef VSE_REG_RESET
  106. __raw_writel(0, dev->reset);
  107. __raw_writel(1, dev->reset);
  108. #endif
  109. vse_write_reg(dev, VSE_REG_CTRL, 0x100);
  110. return 0;
  111. }
  112. void vse_triger_dma_read(struct vse_ic_dev *dev)
  113. {
  114. u32 reg = vse_read_reg(dev, VSE_REG_CTRL);
  115. REG_SET_BIT(reg, VSE_CONTROL_DMA_FRAME_START_BIT, 1);
  116. vse_write_reg(dev, VSE_REG_CTRL, reg);
  117. vse_write_reg(dev, VSE_REG_DMA_CTRL, 5);
  118. }
  119. void setMIBaseAddress(struct vse_ic_dev *dev, u32 width, u32 height, u32 format,
  120. u64 addr, int channel)
  121. {
  122. u32 stride = ALIGN_UP(width, 16);
  123. u32 crSize = 0;
  124. u32 yBaseAddr = addr;
  125. u32 regAddress = VSE_MI_BASE(channel);
  126. u32 crBaseAddr = 0;
  127. u32 ysize = stride * height;
  128. u32 cbSize = ysize;
  129. u32 cbBaseAddr = yBaseAddr + ysize;
  130. if (ysize == 0)
  131. return;
  132. switch (format) {
  133. case MEDIA_PIX_FMT_YUV420SP:
  134. cbSize /= 2;
  135. crSize = 0;
  136. break;
  137. case MEDIA_PIX_FMT_YUV422SP:
  138. break;
  139. case MEDIA_PIX_FMT_YUV444:
  140. case MEDIA_PIX_FMT_RGB888P:
  141. crSize = ysize;
  142. crBaseAddr = cbBaseAddr + cbSize;
  143. break;
  144. case MEDIA_PIX_FMT_RGB888: /* only supoort RGB interleave format. RGB RGB RGB .. */
  145. ysize *= 3;
  146. cbSize = 0;
  147. cbBaseAddr = 0;
  148. break;
  149. }
  150. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_BASE_ADDR_INIT, yBaseAddr);
  151. vse_write_reg(dev, regAddress + VSE_REG_MI_Y_SIZE_INIT, ysize);
  152. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_BASE_ADDR_INIT,
  153. cbBaseAddr);
  154. vse_write_reg(dev, regAddress + VSE_REG_MI_CB_SIZE_INIT, cbSize);
  155. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_BASE_ADDR_INIT,
  156. crBaseAddr);
  157. vse_write_reg(dev, regAddress + VSE_REG_MI_CR_SIZE_INIT, crSize);
  158. }
  159. int vse_start_dma_read(struct vse_ic_dev *dev, u64 addr)
  160. {
  161. u32 writeFormat = 0;
  162. u32 writeString = 0;
  163. u32 reg = 0;
  164. u32 address = VSE_REG_DMA_FORMAT;
  165. u32 width = dev->params.src_w;
  166. u32 height = dev->params.src_h;
  167. u32 format = dev->params.in_format;
  168. u32 ysize, cbSize;
  169. u32 yBaseAddr, cbBaseAddr, crBaseAddr;
  170. u32 stride;
  171. switch (format) {
  172. case MEDIA_PIX_FMT_YUV422SP:
  173. writeFormat = 1;
  174. writeString = 0;
  175. break;
  176. case MEDIA_PIX_FMT_YUV422I:
  177. writeFormat = 1;
  178. writeString = 1;
  179. break;
  180. case MEDIA_PIX_FMT_YUV420SP:
  181. writeFormat = 0;
  182. writeString = 0;
  183. break;
  184. }
  185. reg = vse_read_reg(dev, address);
  186. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, 0);
  187. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  188. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  189. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, 0);
  190. vse_write_reg(dev, address, reg);
  191. stride = ALIGN_UP(width, 16);
  192. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_WIDTH, width);
  193. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_HEIGHT, height);
  194. vse_write_reg(dev, VSE_REG_DMA_Y_PIC_STRIDE, stride);
  195. ysize = stride * height;
  196. cbSize = ysize;
  197. yBaseAddr = addr;
  198. cbBaseAddr = yBaseAddr + ysize;
  199. crBaseAddr = 0;
  200. if (format == MEDIA_PIX_FMT_YUV420SP) {
  201. cbSize /= 2;
  202. } else if (format == MEDIA_PIX_FMT_YUV422I) {
  203. cbSize /= 2;
  204. crBaseAddr = cbBaseAddr + cbSize;
  205. }
  206. vse_write_reg(dev, VSE_REG_Y_PIC_START_ADDR, yBaseAddr);
  207. vse_write_reg(dev, VSE_REG_CB_PIC_START_ADDR, cbBaseAddr);
  208. vse_write_reg(dev, VSE_REG_CR_PIC_START_ADDR, crBaseAddr);
  209. vse_triger_dma_read(dev);
  210. return 0;
  211. }
  212. void setFormatConvPack(struct vse_ic_dev *dev, u32 enable, int channel)
  213. {
  214. u32 reg;
  215. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  216. reg = vse_read_reg(dev, address);
  217. REG_SET_MASK(reg, VSE_FORMAT_CONV_ENABLE_PACK, enable);
  218. vse_write_reg(dev, address, reg);
  219. }
  220. void setFormatConvFull(struct vse_ic_dev *dev, u32 y_full, u32 cbcr_full,
  221. u32 noco422, int channel)
  222. {
  223. u32 reg;
  224. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  225. reg = vse_read_reg(dev, address);
  226. REG_SET_MASK(reg, VSE_FORMAT_CONV_Y_FULL, y_full);
  227. REG_SET_MASK(reg, VSE_FORMAT_CONV_CBCR_FULL, cbcr_full);
  228. REG_SET_MASK(reg, VSE_FORMAT_CONV_CONFIG_422NOCO, 0);
  229. vse_write_reg(dev, address, reg);
  230. }
  231. static u32 format_conv_map[] = { 2, 2, 1, 3, 6, 6 };
  232. void setFormatConvFormat(struct vse_ic_dev *dev, u32 inputFormat,
  233. u32 outputFormat, int channel)
  234. {
  235. u32 reg;
  236. u32 address = VSE_RSZBASE(channel) + VSE_REG_FORMAT_CONV_CTRL;
  237. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  238. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  239. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  240. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  241. inputFormat = MEDIA_PIX_FMT_YUV420SP;
  242. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  243. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  244. inputFormat = MEDIA_PIX_FMT_YUV422SP;
  245. }
  246. reg = vse_read_reg(dev, address);
  247. REG_SET_MASK(reg, VSE_FORMAT_CONV_OUTPUT_FORMAT,
  248. format_conv_map[outputFormat]);
  249. REG_SET_MASK(reg, VSE_FORMAT_CONV_INPUT_FORMAT,
  250. format_conv_map[inputFormat]);
  251. vse_write_reg(dev, address, reg);
  252. }
  253. void setInputSize(struct vse_ic_dev *dev, u32 width, u32 height)
  254. {
  255. u32 reg = ((height & 0x1FFF) << 16) | (width & 0x1FFF);
  256. vse_write_reg(dev, VSE_REG_IN_SIZE, reg);
  257. }
  258. void setCropSize(struct vse_ic_dev *dev, u32 left, u32 right, u32 top,
  259. u32 bottom, int channel)
  260. {
  261. u32 hreg = ((right & 0x1FFF) << 16) | (left & 0x1FFF);
  262. u32 vreg = ((bottom & 0x1FFF) << 16) | (top & 0x1FFF);
  263. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_XDIR, hreg);
  264. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_CROP_YDIR, vreg);
  265. }
  266. void updateResizeControl(struct vse_ic_dev *dev, u32 reg, int channel)
  267. {
  268. u32 address = VSE_RSZBASE(channel);
  269. vse_write_reg(dev, address, reg);
  270. }
  271. void resizeControlAutoUpdate(struct vse_ic_dev *dev, u32 autoUpdate,
  272. int channel)
  273. {
  274. u32 reg;
  275. u32 address = VSE_RSZBASE(channel);
  276. reg = vse_read_reg(dev, address);
  277. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  278. vse_write_reg(dev, address, reg);
  279. }
  280. void resizeControlConfigUpdate(struct vse_ic_dev *dev, u32 configUpdate,
  281. int channel)
  282. {
  283. u32 reg;
  284. u32 address = VSE_RSZBASE(channel);
  285. reg = vse_read_reg(dev, address);
  286. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  287. vse_write_reg(dev, address, reg);
  288. }
  289. void resizeControlEnableCrop(struct vse_ic_dev *dev, u32 enable, int channel)
  290. {
  291. u32 reg;
  292. u32 address = VSE_RSZBASE(channel);
  293. reg = vse_read_reg(dev, address);
  294. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_CROP_ENABLE_BIT, enable);
  295. vse_write_reg(dev, address, reg);
  296. }
  297. void updateVseControl(struct vse_ic_dev *dev, u32 inputChannel, u32 inputFormat,
  298. u32 enbalePath0, u32 enbalePath1, u32 enbalePath2,
  299. u32 autoUpdate, u32 configUpdate)
  300. {
  301. u32 reg = 0;
  302. REG_SET_BIT(reg, VSE_CONTROL_AUTO_UPDATE_BIT, autoUpdate);
  303. REG_SET_BIT(reg, VSE_CONTROL_CONFIG_UPDATE_BIT, configUpdate);
  304. REG_SET_BIT(reg, VSE_CONTROL_PATH0_ENABLE_BIT, enbalePath0);
  305. REG_SET_BIT(reg, VSE_CONTROL_PATH1_ENABLE_BIT, enbalePath1);
  306. REG_SET_BIT(reg, VSE_CONTROL_PATH2_ENABLE_BIT, enbalePath2);
  307. REG_SET_MASK(reg, VSE_CONTROL_INPUT_SELECT, inputChannel);
  308. REG_SET_MASK(reg, VSE_CONTROL_INPUT_FORMAT, inputFormat);
  309. vse_write_reg(dev, VSE_REG_CTRL, reg);
  310. /* BUS ID and BUS CONFIG, hardcode here, user need adjust it on their hardware. */
  311. vse_write_reg(dev, VSE_REG_MI0_BUS_ID, 0x01000108);
  312. vse_write_reg(dev, 0x000003e0, 0x001000fa);
  313. vse_write_reg(dev, 0x000003e8, 0x924c5214);
  314. vse_write_reg(dev, 0x000003f0, 0x100000fa);
  315. vse_write_reg(dev, 0x000003f4, 0x01000108);
  316. vse_write_reg(dev, 0x000003f8, 0x924c5214);
  317. }
  318. void enableMIControl(struct vse_ic_dev *dev, u32 enable, int channel)
  319. {
  320. u32 reg = vse_read_reg(dev, VSE_REG_MI_CTRL);
  321. REG_SET_BIT(reg, channel, enable);
  322. REG_SET_BIT(reg, VSE_MI_CONTROL_RDMA_ENABLE_BIT, 1);
  323. vse_write_reg(dev, VSE_REG_MI_CTRL, reg);
  324. }
  325. void setMIBufferInfo(struct vse_ic_dev *dev, u32 width, u32 height, u32 format,
  326. u32 is10Bit, u32 aligned, int channel)
  327. {
  328. u32 writeFormat = 0;
  329. u32 writeString = 0;
  330. u32 reg = 0;
  331. u32 address;
  332. u32 stride = ALIGN_UP(width, 16);
  333. u32 size = stride * height;
  334. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_LENGTH, stride);
  335. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_WIDTH,
  336. width);
  337. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_HEIGHT,
  338. height);
  339. vse_write_reg(dev, VSE_MI_BASE(channel) + VSE_REG_MI_Y_PIC_SIZE, size);
  340. switch (format) {
  341. case MEDIA_PIX_FMT_YUV422SP:
  342. writeFormat = 1;
  343. writeString = 0;
  344. break;
  345. case MEDIA_PIX_FMT_YUV422I:
  346. writeFormat = 1;
  347. writeString = 1;
  348. break;
  349. case MEDIA_PIX_FMT_YUV420SP:
  350. writeFormat = 0;
  351. writeString = 0;
  352. break;
  353. case MEDIA_PIX_FMT_YUV444:
  354. writeFormat = 2;
  355. writeString = 2;
  356. break;
  357. case MEDIA_PIX_FMT_RGB888:
  358. writeFormat = 2;
  359. writeString = 1;
  360. break;
  361. case MEDIA_PIX_FMT_RGB888P:
  362. writeFormat = 2;
  363. writeString = 2;
  364. break;
  365. }
  366. address = VSE_MI_BASE(channel) + VSE_REG_MI_FMT;
  367. reg = vse_read_reg(dev, address);
  368. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_FMT_ALIGNED, aligned);
  369. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_STR, writeString);
  370. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_FMT, writeFormat);
  371. REG_SET_MASK(reg, VSE_MI_FORMAT_WR_YUV_10BIT, is10Bit);
  372. vse_write_reg(dev, address, reg);
  373. }
  374. void setMIControlConfig(struct vse_ic_dev *dev, u32 enableOffset,
  375. u32 enableUpdateBaseAddress, u32 configUpdate, u32 skip,
  376. u32 autoUpdate, u32 enablePingpong, int channel)
  377. {
  378. u32 reg = 0;
  379. REG_SET_BIT(reg, VSE_MI_PATH_INIT_OFFSET_EN_BIT, enableOffset);
  380. REG_SET_BIT(reg, VSE_MI_PATH_INIT_BASE_EN_BIT, enableUpdateBaseAddress);
  381. REG_SET_BIT(reg, VSE_MI_PATH_CONFIG_UPDATE_BIT, configUpdate);
  382. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_SKIP_BIT, skip);
  383. REG_SET_BIT(reg, VSE_MI_PATH_AUTO_UPDATE_BIT, autoUpdate);
  384. REG_SET_BIT(reg, VSE_MI_PATH_ENABLE_PINGPONG_BIT, enablePingpong);
  385. vse_write_reg(dev, VSE_MI_BASE(channel), reg);
  386. }
  387. u32 vse_get_scale_factor(int src, int dst)
  388. {
  389. if (dst >= src) {
  390. return ((65536 * (src - 1)) / (dst - 1));
  391. } else if (dst < src) {
  392. return ((65536 * (dst - 1)) / (src - 1)) + 1;
  393. }
  394. return 0;
  395. }
  396. void setScaleFactor(struct vse_ic_dev *dev, u32 src_w, u32 src_h, u32 dst_w,
  397. u32 dst_h, u32 inputFormat, u32 outputFormat, int channel)
  398. {
  399. bool hyup, vyup, hcup, vcup;
  400. u32 scale_factor = vse_get_scale_factor(src_w, dst_w);
  401. u32 address = VSE_RSZBASE(channel);
  402. u32 reg = vse_read_reg(dev, address);
  403. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HY,
  404. scale_factor);
  405. scale_factor = vse_get_scale_factor(src_h, dst_h);
  406. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VY,
  407. scale_factor);
  408. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VY_ENABLE_BIT,
  409. ((src_h != dst_h) & 0x01));
  410. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HY_ENABLE_BIT,
  411. ((src_w != dst_w) & 0x01));
  412. hyup = src_w < dst_w;
  413. vyup = src_h < dst_h;
  414. /* Format conv module doesn't support convert other formats to YUV420SP.
  415. doesn't support convert 420SP to other formats too.
  416. so scale down/up cbcr here.
  417. */
  418. src_w /= 2;
  419. dst_w /= 2;
  420. if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  421. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  422. src_h /= 2;
  423. dst_h /= 2;
  424. } else if (inputFormat == MEDIA_PIX_FMT_YUV422SP
  425. && outputFormat == MEDIA_PIX_FMT_YUV420SP) {
  426. /* scale 422 to 420 */
  427. dst_h /= 2;
  428. } else if (inputFormat == MEDIA_PIX_FMT_YUV420SP
  429. && outputFormat != MEDIA_PIX_FMT_YUV420SP) {
  430. /* scale 420 to 422
  431. cbcr width*2, use input buffer as 422SP */
  432. src_h /= 2;
  433. }
  434. hcup = src_w < dst_w;
  435. vcup = src_h < dst_h;
  436. scale_factor = vse_get_scale_factor(src_w, dst_w);
  437. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCB,
  438. scale_factor);
  439. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_HCR,
  440. scale_factor);
  441. scale_factor = vse_get_scale_factor(src_h, dst_h);
  442. vse_write_reg(dev, VSE_RSZBASE(channel) + VSE_RSZ_SCALE_VC,
  443. scale_factor);
  444. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VCUP_BIT, vcup);
  445. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VYUP_BIT, vyup);
  446. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HCUP_BIT, hcup);
  447. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HYUP_BIT, hyup);
  448. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_VC_ENABLE_BIT,
  449. (src_h != dst_h));
  450. REG_SET_BIT(reg, VSE_RESIZE_CONTROL_SCALE_HC_ENABLE_BIT,
  451. (src_w != dst_w));
  452. vse_write_reg(dev, address, reg);
  453. }
  454. int vse_read_irq(struct vse_ic_dev *dev, u32 *ret)
  455. {
  456. pr_info("enter %s\n", __func__);
  457. *ret = vse_read_reg(dev, VSE_REG_MI_MSI);
  458. return 0;
  459. }
  460. int vse_clear_irq(struct vse_ic_dev *dev)
  461. {
  462. pr_info("enter %s\n", __func__);
  463. vse_write_reg(dev, VSE_REG_MI_MSI, 0);
  464. return 0;
  465. }
  466. int vse_mask_irq(struct vse_ic_dev *dev, u32 mask)
  467. {
  468. pr_info("enter %s 0x%08x\n", __func__, mask);
  469. vse_write_reg(dev, VSE_REG_MI_IMSC, mask);
  470. return 0;
  471. }
  472. int vse_ioc_qcap(struct vse_ic_dev *dev, void *args)
  473. {
  474. struct v4l2_capability *cap = (struct v4l2_capability *)args;
  475. strcpy((char *)cap->driver, "viv_vse");
  476. return 0;
  477. }
  478. int vse_update_buffers(struct vse_ic_dev *dev, u64 *addr)
  479. {
  480. struct vse_params *param = &dev->params;
  481. struct vse_mi_settings *mi = param->mi_settings;
  482. int i = 0;
  483. pr_info("enter %s\n", __func__);
  484. for (; i < 3; i++) {
  485. if (addr[i] != 0) {
  486. setMIBaseAddress(dev, mi[i].width, mi[i].height,
  487. mi[i].out_format, addr[i], i);
  488. }
  489. }
  490. return 0;
  491. }
  492. int vse_update_mi_info(struct vse_ic_dev *dev)
  493. {
  494. struct vse_params *param = &dev->params;
  495. struct vse_mi_settings *mi = param->mi_settings;
  496. int i = 0;
  497. pr_info("enter %s\n", __func__);
  498. for (; i < 3; i++) {
  499. if (!mi[i].enable)
  500. continue;
  501. setMIBufferInfo(dev, mi[i].width, mi[i].height,
  502. mi[i].out_format, false, false, i);
  503. enableMIControl(dev, mi[i].enable, i);
  504. setMIControlConfig(dev, true, true, true, false, true, false,
  505. i);
  506. }
  507. return 0;
  508. }
  509. int vse_s_params(struct vse_ic_dev *dev)
  510. {
  511. struct vse_params *param = &dev->params;
  512. int i = 0;
  513. int input_select = 0;
  514. int crop_w, crop_h, scale_w, scale_h;
  515. struct vse_crop_size *cropSize;
  516. struct vse_size *outputSize;
  517. pr_info("enter %s\n", __func__);
  518. setInputSize(dev, param->src_w, param->src_h);
  519. for (; i < 3; i++) {
  520. if (!param->resize_enable[i])
  521. continue;
  522. cropSize = &param->crop_size[i];
  523. outputSize = &param->out_size[i];
  524. crop_w = cropSize->right - cropSize->left + 1;
  525. crop_h = cropSize->bottom - cropSize->top + 1;
  526. scale_w = param->src_w;
  527. scale_h = param->src_h;
  528. if (crop_w > 1 && crop_h > 1) {
  529. resizeControlEnableCrop(dev, 1, i);
  530. setCropSize(dev, cropSize->left, cropSize->right,
  531. cropSize->top, cropSize->bottom, i);
  532. scale_w = crop_w;
  533. scale_h = crop_h;
  534. } else {
  535. resizeControlEnableCrop(dev, 0, i);
  536. }
  537. /* ONLY SUPPORT Semiplanar NOW, all enable pack */
  538. setFormatConvPack(dev, true, i);
  539. setFormatConvFull(dev, true, true, false, i);
  540. setFormatConvFormat(dev, param->in_format,
  541. param->format_conv[i].out_format, i);
  542. setScaleFactor(dev, scale_w, scale_h, outputSize->width,
  543. outputSize->height, param->in_format,
  544. param->format_conv[i].out_format, i);
  545. resizeControlAutoUpdate(dev, 1, i);
  546. resizeControlConfigUpdate(dev, 1, i);
  547. }
  548. #ifndef HAL_CMODEL
  549. input_select = param->input_select;
  550. #endif
  551. updateVseControl(dev, input_select, param->in_format,
  552. param->resize_enable[0],
  553. param->resize_enable[1],
  554. param->resize_enable[2], true, true);
  555. return 0;
  556. }
  557. long vse_priv_ioctl(struct vse_ic_dev *dev, unsigned int cmd, void *args)
  558. {
  559. int ret = -1;
  560. switch (cmd) {
  561. case VSEIOC_RESET:
  562. ret = vse_reset(dev);
  563. break;
  564. case VSEIOC_S_PARAMS:
  565. viv_check_retval(copy_from_user
  566. (&dev->params, args, sizeof(dev->params)));
  567. ret = vse_s_params(dev);
  568. break;
  569. case VSEIOC_CLEAR_IRQ:
  570. ret = vse_clear_irq(dev);
  571. break;
  572. case VSEIOC_READ_IRQ:{
  573. u32 irq = 0;
  574. ret = vse_read_irq(dev, &irq);
  575. viv_check_retval(copy_to_user(args, &irq, sizeof(irq)));
  576. break;
  577. }
  578. case VSEIOC_START_DMA_READ:{
  579. u64 addr;
  580. viv_check_retval(copy_from_user
  581. (&addr, args, sizeof(addr)));
  582. ret = vse_start_dma_read(dev, addr);
  583. break;
  584. }
  585. case VSEIOC_U_MI_INFO:
  586. ret = vse_update_mi_info(dev);
  587. break;
  588. case VSEIOC_U_BUFFER:{
  589. u64 addrs[3];
  590. viv_check_retval(copy_from_user
  591. (addrs, args, sizeof(addrs)));
  592. vse_update_buffers(dev, addrs);
  593. break;
  594. }
  595. case VSEIOC_MASK_IRQ:{
  596. u32 mask;
  597. viv_check_retval(copy_from_user
  598. (&mask, args, sizeof(mask)));
  599. vse_mask_irq(dev, mask);
  600. break;
  601. }
  602. case VIDIOC_QUERYCAP:
  603. ret = vse_ioc_qcap(dev, args);
  604. break;
  605. default:
  606. pr_err("unsupported vse command %d", cmd);
  607. break;
  608. }
  609. return ret;
  610. }
  611. int vvnative_vse_init(struct vse_ic_dev *dev)
  612. {
  613. return 0;
  614. }
  615. int vvnative_vse_deinit(struct vse_ic_dev *dev)
  616. {
  617. return 0;
  618. }