PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/exynos4/hal/libhwcomposer/SecHWCUtils.cpp

https://bitbucket.org/cyanogenmod/android_hardware_samsung
C++ | 1593 lines | 1272 code | 208 blank | 113 comment | 201 complexity | 8f63827f5bc3463780dc1e89e9742eb4 MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * Revision History:
  18. * - 2011/03/11 : Rama, Meka(v.meka@samsung.com)
  19. * Initial version
  20. *
  21. * - 2011/12/07 : Jeonghee, Kim(jhhhh.kim@samsung.com)
  22. * Add V4L2_PIX_FMT_YUV420M V4L2_PIX_FMT_NV12M
  23. *
  24. */
  25. #include "SecHWCUtils.h"
  26. #ifdef BOARD_USE_V4L2_ION
  27. #define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
  28. #define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
  29. #else
  30. #define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT
  31. #define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE
  32. #endif
  33. #define EXYNOS4_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
  34. //#define CHECK_FPS
  35. #ifdef CHECK_FPS
  36. #include <sys/time.h>
  37. #include <unistd.h>
  38. #define CHK_FRAME_CNT 30
  39. void check_fps()
  40. {
  41. static struct timeval tick, tick_old;
  42. static int total = 0;
  43. static int cnt = 0;
  44. int FPS;
  45. cnt++;
  46. gettimeofday(&tick, NULL);
  47. if (cnt > 10) {
  48. if (tick.tv_sec > tick_old.tv_sec)
  49. total += ((tick.tv_usec/1000) + (tick.tv_sec - tick_old.tv_sec)*1000 - (tick_old.tv_usec/1000));
  50. else
  51. total += ((tick.tv_usec - tick_old.tv_usec)/1000);
  52. memcpy(&tick_old, &tick, sizeof(timeval));
  53. if (cnt == (10 + CHK_FRAME_CNT)) {
  54. FPS = 1000*CHK_FRAME_CNT/total;
  55. LOGE("[FPS]:%d\n", FPS);
  56. total = 0;
  57. cnt = 10;
  58. }
  59. } else {
  60. memcpy(&tick_old, &tick, sizeof(timeval));
  61. total = 0;
  62. }
  63. }
  64. #endif
  65. struct yuv_fmt_list yuv_list[] = {
  66. { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 2 },
  67. { "V4L2_PIX_FMT_NV12T", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12T, 12, 2 },
  68. { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 2 },
  69. { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 },
  70. { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 },
  71. { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 },
  72. #ifdef BOARD_USE_V4L2_ION
  73. { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 },
  74. { "V4L2_PIX_FMT_NV12M", "YUV420/2P", V4L2_PIX_FMT_NV12M, 12, 2 },
  75. #endif
  76. { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 },
  77. { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 },
  78. { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 },
  79. { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 },
  80. { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 },
  81. { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 },
  82. { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 },
  83. { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 },
  84. { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 },
  85. };
  86. int window_open(struct hwc_win_info_t *win, int id)
  87. {
  88. int fd = 0;
  89. char name[64];
  90. int vsync = 1;
  91. int real_id = id;
  92. char const * const device_template = "/dev/graphics/fb%u";
  93. // window & FB maping
  94. // fb0 -> win-id : 2
  95. // fb1 -> win-id : 3
  96. // fb2 -> win-id : 4
  97. // fb3 -> win-id : 0
  98. // fb4 -> win_id : 1
  99. // it is pre assumed that ...win0 or win1 is used here..
  100. switch (id) {
  101. case 0:
  102. #ifdef BOARD_USE_V4L2_ION
  103. real_id = 2;
  104. #else
  105. real_id = 3;
  106. #endif
  107. break;
  108. case 1:
  109. #ifdef BOARD_USE_V4L2_ION
  110. real_id = 1;
  111. #else
  112. real_id = 4;
  113. #endif
  114. break;
  115. default:
  116. SEC_HWC_Log(HWC_LOG_ERROR, "%s::id(%d) is weird", __func__, id);
  117. goto error;
  118. }
  119. // 0/10
  120. // snprintf(name, 64, device_template, id + 3);
  121. // 5/10
  122. // snprintf(name, 64, device_template, id + 0);
  123. // 0/10
  124. // snprintf(name, 64, device_template, id + 1);
  125. snprintf(name, 64, device_template, real_id);
  126. win->fd = open(name, O_RDWR);
  127. if (win->fd <= 0) {
  128. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Failed to open window device (%s) : %s",
  129. __func__, strerror(errno), name);
  130. goto error;
  131. }
  132. #ifdef ENABLE_FIMD_VSYNC
  133. if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0) {
  134. SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__);
  135. goto error;
  136. }
  137. #endif
  138. return 0;
  139. error:
  140. if (0 < win->fd)
  141. close(win->fd);
  142. win->fd = 0;
  143. return -1;
  144. }
  145. int window_close(struct hwc_win_info_t *win)
  146. {
  147. int ret = 0;
  148. if (0 < win->fd) {
  149. #ifdef BOARD_USE_V4L2_ION
  150. ion_unmap((void *)win->addr[0], ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE));
  151. ion_free(win->ion_fd);
  152. #endif
  153. #ifdef ENABLE_FIMD_VSYNC
  154. int vsync = 0;
  155. if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0)
  156. SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__);
  157. #endif
  158. ret = close(win->fd);
  159. }
  160. win->fd = 0;
  161. return ret;
  162. }
  163. int window_set_pos(struct hwc_win_info_t *win)
  164. {
  165. struct s3cfb_user_window window;
  166. //before changing the screen configuration...powerdown the window
  167. if (window_hide(win) != 0)
  168. return -1;
  169. SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: x(%d), y(%d)",
  170. __func__, win->rect_info.x, win->rect_info.y);
  171. win->var_info.xres_virtual = (win->lcd_info.xres + 15) & ~ 15;
  172. win->var_info.yres_virtual = win->lcd_info.yres * NUM_OF_WIN_BUF;
  173. win->var_info.xres = win->rect_info.w;
  174. win->var_info.yres = win->rect_info.h;
  175. win->var_info.activate &= ~FB_ACTIVATE_MASK;
  176. win->var_info.activate |= FB_ACTIVATE_FORCE;
  177. if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) {
  178. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPUT_VSCREENINFO(%d, %d) fail",
  179. __func__, win->rect_info.w, win->rect_info.h);
  180. return -1;
  181. }
  182. window.x = win->rect_info.x;
  183. window.y = win->rect_info.y;
  184. if (ioctl(win->fd, S3CFB_WIN_POSITION, &window) < 0) {
  185. SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_WIN_POSITION(%d, %d) fail",
  186. __func__, window.x, window.y);
  187. return -1;
  188. }
  189. return 0;
  190. }
  191. int window_get_info(struct hwc_win_info_t *win, int win_num)
  192. {
  193. int temp_size = 0;
  194. if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
  195. SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_FSCREENINFO failed : %s",
  196. strerror(errno));
  197. goto error;
  198. }
  199. win->size = win->fix_info.line_length * win->var_info.yres;
  200. #ifdef BOARD_USE_V4L2_ION
  201. struct s3c_fb_user_ion_client ion_handle;
  202. void *ion_start_addr;
  203. if (ioctl(win->fd, S3CFB_GET_ION_USER_HANDLE, &ion_handle) < 0) {
  204. SEC_HWC_Log(HWC_LOG_ERROR, "Get fb ion client is failed\n");
  205. return -1;
  206. }
  207. win->ion_fd = ion_handle.fd;
  208. ion_start_addr = ion_map(win->ion_fd, ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE), 0);
  209. #endif
  210. for (int j = 0; j < NUM_OF_WIN_BUF; j++) {
  211. temp_size = win->size * j;
  212. #ifdef BOARD_USE_V4L2_ION
  213. win->addr[j] = (uint32_t)ion_start_addr + temp_size;
  214. #else
  215. win->addr[j] = win->fix_info.smem_start + temp_size;
  216. #endif
  217. SEC_HWC_Log(HWC_LOG_DEBUG, "%s::win-%d add[%d] %x ",
  218. __func__, win_num, j, win->addr[j]);
  219. }
  220. return 0;
  221. error:
  222. win->fix_info.smem_start = 0;
  223. return -1;
  224. }
  225. int window_pan_display(struct hwc_win_info_t *win)
  226. {
  227. struct fb_var_screeninfo *lcd_info = &(win->lcd_info);
  228. #ifdef ENABLE_FIMD_VSYNC
  229. #ifdef BOARD_USE_V4L2_ION
  230. int fimd_num = 0;
  231. if (ioctl(win->fd, FBIO_WAITFORVSYNC, &fimd_num) < 0)
  232. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIO_WAITFORVSYNC fail(%s)",
  233. __func__, strerror(errno));
  234. #else
  235. if (ioctl(win->fd, FBIO_WAITFORVSYNC, 0) < 0)
  236. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIO_WAITFORVSYNC fail(%s)",
  237. __func__, strerror(errno));
  238. #endif
  239. #endif
  240. lcd_info->yoffset = lcd_info->yres * win->buf_index;
  241. if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) {
  242. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)",
  243. __func__,
  244. lcd_info->yres,
  245. win->buf_index, lcd_info->yres_virtual,
  246. strerror(errno));
  247. return -1;
  248. }
  249. return 0;
  250. }
  251. int window_show(struct hwc_win_info_t *win)
  252. {
  253. if (win->power_state == 0) {
  254. if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
  255. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)",
  256. __func__, win->fd, strerror(errno));
  257. return -1;
  258. }
  259. win->power_state = 1;
  260. }
  261. return 0;
  262. }
  263. int window_hide(struct hwc_win_info_t *win)
  264. {
  265. if (win->power_state == 1) {
  266. if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
  267. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)",
  268. __func__, win->fd, strerror(errno));
  269. return -1;
  270. }
  271. win->power_state = 0;
  272. }
  273. return 0;
  274. }
  275. int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info)
  276. {
  277. if (ioctl(fd, FBIOGET_VSCREENINFO, lcd_info) < 0) {
  278. SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_VSCREENINFO failed : %s",
  279. strerror(errno));
  280. return -1;
  281. }
  282. SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: Default LCD x(%d),y(%d)",
  283. __func__, lcd_info->xres, lcd_info->yres);
  284. return 0;
  285. }
  286. int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
  287. {
  288. struct v4l2_format fmt;
  289. struct v4l2_cropcap cropcap;
  290. struct v4l2_crop crop;
  291. struct v4l2_requestbuffers req;
  292. #ifdef BOARD_USE_V4L2_ION
  293. /* You MUST initialize structure for v4l2 */
  294. memset(&fmt, 0, sizeof(fmt));
  295. memset(&cropcap, 0, sizeof(cropcap));
  296. memset(&crop, 0, sizeof(crop));
  297. memset(&req, 0, sizeof(req));
  298. /* To set size & format for source image (DMA-INPUT) */
  299. fmt.fmt.pix_mp.num_planes = src->planes;
  300. fmt.fmt.pix_mp.width = src->full_width;
  301. fmt.fmt.pix_mp.height = src->full_height;
  302. fmt.fmt.pix_mp.pixelformat = src->color_space;
  303. fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
  304. #else
  305. fmt.fmt.pix.width = src->full_width;
  306. fmt.fmt.pix.height = src->full_height;
  307. fmt.fmt.pix.pixelformat = src->color_space;
  308. fmt.fmt.pix.field = V4L2_FIELD_NONE;
  309. #endif
  310. fmt.type = V4L2_BUF_TYPE_OUTPUT;
  311. if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
  312. SEC_HWC_Log(HWC_LOG_ERROR, "%s::VIDIOC_S_FMT failed : errno=%d (%s)"
  313. " : fd=%d\n", __func__, errno, strerror(errno), fd);
  314. return -1;
  315. }
  316. /* crop input size */
  317. crop.type = V4L2_BUF_TYPE_OUTPUT;
  318. crop.c.width = src->width;
  319. crop.c.height = src->height;
  320. #ifdef BOARD_USE_V4L2_ION
  321. crop.c.left = src->start_x;
  322. crop.c.top = src->start_y;
  323. #else
  324. if (0x50 <= hw_ver) {
  325. crop.c.left = src->start_x;
  326. crop.c.top = src->start_y;
  327. } else {
  328. crop.c.left = 0;
  329. crop.c.top = 0;
  330. }
  331. #endif
  332. if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
  333. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP :"
  334. "crop.c.left : (%d), crop.c.top : (%d), crop.c.width : (%d), crop.c.height : (%d)",
  335. __func__, crop.c.left, crop.c.top, crop.c.width, crop.c.height);
  336. return -1;
  337. }
  338. /* input buffer type */
  339. req.count = 1;
  340. req.memory = V4L2_MEMORY_USERPTR;
  341. req.type = V4L2_BUF_TYPE_OUTPUT;
  342. if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {
  343. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS", __func__);
  344. return -1;
  345. }
  346. return 0;
  347. }
  348. int fimc_v4l2_set_dst(int fd, s5p_fimc_img_info *dst,
  349. int rotation, int hflip, int vflip, unsigned int addr)
  350. {
  351. struct v4l2_format sFormat;
  352. struct v4l2_control vc;
  353. struct v4l2_framebuffer fbuf;
  354. #ifdef BOARD_USE_V4L2_ION
  355. struct v4l2_crop crop;
  356. struct v4l2_requestbuffers req;
  357. #endif
  358. int ret;
  359. #ifdef BOARD_USE_V4L2_ION
  360. /* You MUST initialize structure for v4l2 */
  361. memset(&sFormat, 0, sizeof(sFormat));
  362. memset(&vc, 0, sizeof(vc));
  363. memset(&fbuf, 0, sizeof(fbuf));
  364. memset(&crop, 0, sizeof(crop));
  365. memset(&req, 0, sizeof(req));
  366. #endif
  367. /* set rotation configuration */
  368. #ifdef BOARD_USE_V4L2_ION
  369. vc.id = V4L2_CID_ROTATE;
  370. #else
  371. vc.id = V4L2_CID_ROTATION;
  372. #endif
  373. vc.value = rotation;
  374. ret = ioctl(fd, VIDIOC_S_CTRL, &vc);
  375. if (ret < 0) {
  376. SEC_HWC_Log(HWC_LOG_ERROR,
  377. "%s::Error in video VIDIOC_S_CTRL - rotation (%d)"
  378. "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value);
  379. return -1;
  380. }
  381. vc.id = V4L2_CID_HFLIP;
  382. vc.value = hflip;
  383. ret = ioctl(fd, VIDIOC_S_CTRL, &vc);
  384. if (ret < 0) {
  385. SEC_HWC_Log(HWC_LOG_ERROR,
  386. "%s::Error in video VIDIOC_S_CTRL - hflip (%d)"
  387. "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value);
  388. return -1;
  389. }
  390. vc.id = V4L2_CID_VFLIP;
  391. vc.value = vflip;
  392. ret = ioctl(fd, VIDIOC_S_CTRL, &vc);
  393. if (ret < 0) {
  394. SEC_HWC_Log(HWC_LOG_ERROR,
  395. "%s::Error in video VIDIOC_S_CTRL - vflip (%d)"
  396. "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value);
  397. return -1;
  398. }
  399. #ifdef BOARD_USE_V4L2_ION
  400. /* set destination */
  401. sFormat.type = V4L2_BUF_TYPE_CAPTURE;
  402. sFormat.fmt.pix_mp.width = dst->full_width;
  403. sFormat.fmt.pix_mp.height = dst->full_height;
  404. sFormat.fmt.pix_mp.pixelformat = dst->color_space;
  405. sFormat.fmt.pix_mp.num_planes = dst->planes;
  406. sFormat.fmt.pix.field = V4L2_FIELD_ANY;
  407. ret = ioctl(fd, VIDIOC_S_FMT, &sFormat);
  408. if (ret < 0) {
  409. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FMT (%d)", __func__, ret);
  410. return -1;
  411. }
  412. /* set destination window */
  413. crop.type = V4L2_BUF_TYPE_CAPTURE;
  414. crop.c.left = dst->start_x;
  415. crop.c.top = dst->start_y;
  416. crop.c.width = dst->width;
  417. crop.c.height = dst->height;
  418. ret = ioctl(fd, VIDIOC_S_CROP, &crop);
  419. if (ret < 0) {
  420. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP (%d)", __func__, ret);
  421. return -1;
  422. }
  423. /* input buffer type */
  424. req.count = 1;
  425. req.type = V4L2_BUF_TYPE_CAPTURE;
  426. req.memory = V4L2_MEMORY_USERPTR;
  427. ret = ioctl (fd, VIDIOC_REQBUFS, &req);
  428. if (ret < 0) {
  429. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS (%d)", __func__, ret);
  430. return -1;
  431. }
  432. #else
  433. /* set size, format & address for destination image (DMA-OUTPUT) */
  434. ret = ioctl(fd, VIDIOC_G_FBUF, &fbuf);
  435. if (ret < 0) {
  436. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_FBUF (%d)", __func__, ret);
  437. return -1;
  438. }
  439. fbuf.base = (void *)addr;
  440. fbuf.fmt.width = dst->full_width;
  441. fbuf.fmt.height = dst->full_height;
  442. fbuf.fmt.pixelformat = dst->color_space;
  443. ret = ioctl(fd, VIDIOC_S_FBUF, &fbuf);
  444. if (ret < 0) {
  445. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FBUF (%d)", __func__, ret);
  446. return -1;
  447. }
  448. /* set destination window */
  449. sFormat.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
  450. sFormat.fmt.win.w.left = dst->start_x;
  451. sFormat.fmt.win.w.top = dst->start_y;
  452. sFormat.fmt.win.w.width = dst->width;
  453. sFormat.fmt.win.w.height = dst->height;
  454. ret = ioctl(fd, VIDIOC_S_FMT, &sFormat);
  455. if (ret < 0) {
  456. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FMT (%d)", __func__, ret);
  457. return -1;
  458. }
  459. #endif
  460. return 0;
  461. }
  462. int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
  463. {
  464. if (-1 == ioctl(fd, VIDIOC_STREAMON, &type)) {
  465. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMON\n");
  466. return -1;
  467. }
  468. return 0;
  469. }
  470. int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type, int index)
  471. {
  472. #ifdef BOARD_USE_V4L2_ION
  473. struct v4l2_plane plane[3];
  474. int i;
  475. #endif
  476. struct v4l2_buffer buf;
  477. int ret;
  478. #ifdef BOARD_USE_V4L2_ION
  479. buf.length = fimc_buf->planes;
  480. #else
  481. buf.length = 0;
  482. buf.m.userptr = (unsigned long)fimc_buf;
  483. #endif
  484. buf.memory = V4L2_MEMORY_USERPTR;
  485. buf.index = index;
  486. buf.type = type;
  487. #ifdef BOARD_USE_V4L2_ION
  488. if (buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
  489. buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
  490. for (i = 0; i < buf.length; i++) {
  491. plane[i].m.userptr = fimc_buf->base[i];
  492. plane[i].length = fimc_buf->size[i];
  493. }
  494. }
  495. buf.m.planes = plane;
  496. #endif
  497. ret = ioctl(fd, VIDIOC_QBUF, &buf);
  498. if (0 > ret) {
  499. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_QBUF : (%d)", ret);
  500. return -1;
  501. }
  502. return 0;
  503. }
  504. int fimc_v4l2_dequeue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type)
  505. {
  506. struct v4l2_buffer buf;
  507. #ifdef BOARD_USE_V4L2_ION
  508. struct v4l2_plane plane[3];
  509. #endif
  510. #ifdef BOARD_USE_V4L2_ION
  511. buf.m.planes = plane;
  512. buf.length = fimc_buf->planes;
  513. #endif
  514. buf.memory = V4L2_MEMORY_USERPTR;
  515. buf.type = type;
  516. if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf)) {
  517. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_DQBUF\n");
  518. return -1;
  519. }
  520. return buf.index;
  521. }
  522. int fimc_v4l2_stream_off(int fd, enum v4l2_buf_type type)
  523. {
  524. if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) {
  525. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMOFF\n");
  526. return -1;
  527. }
  528. return 0;
  529. }
  530. int fimc_v4l2_clr_buf(int fd, enum v4l2_buf_type type)
  531. {
  532. struct v4l2_requestbuffers req;
  533. req.count = 0;
  534. req.memory = V4L2_MEMORY_USERPTR;
  535. req.type = type;
  536. if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
  537. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_REQBUFS");
  538. }
  539. return 0;
  540. }
  541. int fimc_v4l2_S_ctrl(int fd)
  542. {
  543. struct v4l2_control vc;
  544. vc.id = V4L2_CID_CACHEABLE;
  545. vc.value = 1;
  546. if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
  547. SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_S_CTRL");
  548. return -1;
  549. }
  550. return 0;
  551. }
  552. int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_src_buf, struct fimc_buf *fimc_dst_buf)
  553. {
  554. #ifdef CHECK_FPS
  555. check_fps();
  556. #endif
  557. #ifdef BOARD_USE_V4L2_ION
  558. if (fimc_v4l2_queue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT, 0) < 0) {
  559. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_queue()");
  560. return -1;
  561. }
  562. if (fimc_v4l2_queue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE, 0) < 0) {
  563. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_queue()");
  564. return -2;
  565. }
  566. if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_OUTPUT) < 0) {
  567. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_on()");
  568. return -3;
  569. }
  570. if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_CAPTURE) < 0) {
  571. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_on()");
  572. return -4;
  573. }
  574. #else
  575. if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_OUTPUT) < 0) {
  576. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_on()");
  577. return -5;
  578. }
  579. if (fimc_v4l2_queue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT, 0) < 0) {
  580. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_queue()");
  581. goto STREAM_OFF;
  582. }
  583. #endif
  584. if (fimc_v4l2_dequeue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT) < 0) {
  585. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_dequeue()");
  586. return -6;
  587. }
  588. #ifdef BOARD_USE_V4L2_ION
  589. if (fimc_v4l2_dequeue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE) < 0) {
  590. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_dequeue()");
  591. return -7;
  592. }
  593. #endif
  594. STREAM_OFF:
  595. if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_OUTPUT) < 0) {
  596. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_off()");
  597. return -8;
  598. }
  599. #ifdef BOARD_USE_V4L2_ION
  600. if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_CAPTURE) < 0) {
  601. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_off()");
  602. return -9;
  603. }
  604. #endif
  605. if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_OUTPUT) < 0) {
  606. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_clr_buf()");
  607. return -10;
  608. }
  609. #ifdef BOARD_USE_V4L2_ION
  610. if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_CAPTURE)< 0) {
  611. SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_clr_buf()");
  612. return -11;
  613. }
  614. #endif
  615. return 0;
  616. }
  617. static int memcpy_rect(void *dst, void *src, int fullW, int fullH, int realW, int realH, int format)
  618. {
  619. unsigned char *srcCb, *srcCr;
  620. unsigned char *dstCb, *dstCr;
  621. unsigned char *srcY, *dstY;
  622. int srcCbOffset, srcCrOffset;
  623. int dstCbOffset, dstFrameOffset, dstCrOffset;
  624. int cbFullW, cbRealW, cbFullH, cbRealH;
  625. int ySrcFW, ySrcFH, ySrcRW, ySrcRH;
  626. int planes;
  627. int i;
  628. SEC_HWC_Log(HWC_LOG_DEBUG,
  629. "++memcpy_rect()::"
  630. "dst(0x%x),src(0x%x),f.w(%d),f.h(%d),r.w(%d),r.h(%d),format(0x%x)",
  631. (unsigned int)dst, (unsigned int)src, fullW, fullH, realW, realH, format);
  632. // Set dst Y, Cb, Cr address for FIMC
  633. {
  634. cbFullW = fullW >> 1;
  635. cbRealW = realW >> 1;
  636. cbFullH = fullH >> 1;
  637. cbRealH = realH >> 1;
  638. dstFrameOffset = fullW * fullH;
  639. dstCrOffset = cbFullW * cbFullH;
  640. dstY = (unsigned char *)dst;
  641. dstCb = (unsigned char *)dst + dstFrameOffset;
  642. dstCr = (unsigned char *)dstCb + dstCrOffset;
  643. }
  644. // Get src Y, Cb, Cr address for source buffer.
  645. // Each address is aligned by 16's multiple for GPU both width and height.
  646. {
  647. ySrcFW = fullW;
  648. ySrcFH = fullH;
  649. ySrcRW = realW;
  650. ySrcRH = realH;
  651. srcCbOffset = EXYNOS4_ALIGN(ySrcRW,16)* EXYNOS4_ALIGN(ySrcRH,16);
  652. srcCrOffset = EXYNOS4_ALIGN(cbRealW,16)* EXYNOS4_ALIGN(cbRealH,16);
  653. srcY = (unsigned char *)src;
  654. srcCb = (unsigned char *)src + srcCbOffset;
  655. srcCr = (unsigned char *)srcCb + srcCrOffset;
  656. }
  657. SEC_HWC_Log(HWC_LOG_DEBUG,
  658. "--memcpy_rect()::\n"
  659. "dstY(0x%x),dstCb(0x%x),dstCr(0x%x) \n"
  660. "srcY(0x%x),srcCb(0x%x),srcCr(0x%x) \n"
  661. "cbRealW(%d),cbRealH(%d)",
  662. (unsigned int)dstY,(unsigned int)dstCb,(unsigned int)dstCr,
  663. (unsigned int)srcY,(unsigned int)srcCb,(unsigned int)srcCr,
  664. cbRealW, cbRealH);
  665. if (format == HAL_PIXEL_FORMAT_YV12) { //YV12(Y,Cr,Cv)
  666. planes = 3;
  667. //This is code for VE, deleted temporory by SSONG 2011.09.22
  668. // This will be enabled later.
  669. /*
  670. //as defined in hardware.h, cb & cr full_width should be aligned to 16. ALIGN(y_stride/2, 16).
  671. ////Alignment is hard coded to 16.
  672. ////for example...check frameworks/media/libvideoeditor/lvpp/VideoEditorTools.cpp file for UV stride cal
  673. cbSrcFW = (cbSrcFW + 15) & (~15);
  674. srcCbOffset = ySrcFW * fullH;
  675. srcCrOffset = srcCbOffset + ((cbSrcFW * fullH) >> 1);
  676. srcY = (unsigned char *)src;
  677. srcCb = (unsigned char *)src + srcCbOffset;
  678. srcCr = (unsigned char *)src + srcCrOffset;
  679. */
  680. } else if ((format == HAL_PIXEL_FORMAT_YCbCr_420_P)) {
  681. planes = 3;
  682. } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
  683. planes = 2;
  684. } else {
  685. SEC_HWC_Log(HWC_LOG_ERROR, "use default memcpy instead of memcpy_rect");
  686. return -1;
  687. }
  688. //#define CHECK_PERF
  689. #ifdef CHECK_PERF
  690. struct timeval start, end;
  691. gettimeofday(&start, NULL);
  692. #endif
  693. for (i = 0; i < realH; i++)
  694. memcpy(dstY + fullW * i, srcY + ySrcFW * i, ySrcRW);
  695. if (planes == 2) {
  696. for (i = 0; i < cbRealH; i++)
  697. memcpy(dstCb + ySrcFW * i, srcCb + ySrcFW * i, ySrcRW);
  698. } else if (planes == 3) {
  699. for (i = 0; i < cbRealH; i++)
  700. memcpy(dstCb + cbFullW * i, srcCb + cbFullW * i, cbRealW);
  701. for (i = 0; i < cbRealH; i++)
  702. memcpy(dstCr + cbFullW * i, srcCr + cbFullW * i, cbRealW);
  703. }
  704. #ifdef CHECK_PERF
  705. gettimeofday(&end, NULL);
  706. SEC_HWC_Log(HWC_LOG_ERROR, "[COPY]=%d,",(end.tv_sec - start.tv_sec)*1000+(end.tv_usec - start.tv_usec)/1000);
  707. #endif
  708. return 0;
  709. }
  710. /*****************************************************************************/
  711. static int get_src_phys_addr(struct hwc_context_t *ctx,
  712. sec_img *src_img, sec_rect *src_rect)
  713. {
  714. s5p_fimc_t *fimc = &ctx->fimc;
  715. struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[0];
  716. struct s3c_mem_dma_param s3c_mem_dma;
  717. #ifdef USE_HW_PMEM
  718. sec_pmem_alloc_t *pm_alloc = &ctx->sec_pmem.sec_pmem_alloc[0];
  719. #endif
  720. unsigned int src_virt_addr = 0;
  721. unsigned int src_phys_addr = 0;
  722. unsigned int src_frame_size = 0;
  723. struct pmem_region region;
  724. ADDRS * addr;
  725. // error check routine
  726. if (0 == src_img->base && !(src_img->usage & GRALLOC_USAGE_HW_FIMC1)) {
  727. SEC_HWC_Log(HWC_LOG_ERROR, "%s invalid src image base\n", __func__);
  728. return 0;
  729. }
  730. switch (src_img->mem_type) {
  731. case HWC_PHYS_MEM_TYPE:
  732. src_phys_addr = src_img->base + src_img->offset;
  733. break;
  734. case HWC_VIRT_MEM_TYPE:
  735. case HWC_UNKNOWN_MEM_TYPE:
  736. switch (src_img->format) {
  737. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
  738. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
  739. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
  740. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
  741. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
  742. addr = (ADDRS *)(src_img->base);
  743. fimc->params.src.buf_addr_phy_rgb_y = addr->addr_y;
  744. fimc->params.src.buf_addr_phy_cb = addr->addr_cbcr;
  745. src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y;
  746. if (0 == src_phys_addr) {
  747. SEC_HWC_Log(HWC_LOG_ERROR, "%s address error "
  748. "(format=CUSTOM_YCbCr/YCrCb_420_SP Y-addr=0x%x "
  749. "CbCr-Addr=0x%x)",
  750. __func__, fimc->params.src.buf_addr_phy_rgb_y,
  751. fimc->params.src.buf_addr_phy_cb);
  752. return 0;
  753. }
  754. break;
  755. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
  756. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
  757. case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
  758. case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
  759. addr = (ADDRS *)(src_img->base + src_img->offset);
  760. fimc->params.src.buf_addr_phy_rgb_y = addr->addr_y;
  761. src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y;
  762. if (0 == src_phys_addr) {
  763. SEC_HWC_Log(HWC_LOG_ERROR, "%s address error "
  764. "(format=CUSTOM_YCbCr/CbYCrY_422_I Y-addr=0x%x)",
  765. __func__, fimc->params.src.buf_addr_phy_rgb_y);
  766. return 0;
  767. }
  768. break;
  769. default:
  770. #ifdef BOARD_USE_V4L2_ION
  771. fimc->params.src.buf_addr_phy_rgb_y = src_img->base;
  772. fimc->params.src.buf_addr_phy_cb = src_img->base + src_img->uoffset;
  773. fimc->params.src.buf_addr_phy_cr = src_img->base + src_img->uoffset + src_img->voffset;
  774. src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y;
  775. break;
  776. #endif
  777. if (src_img->usage & GRALLOC_USAGE_HW_FIMC1) {
  778. fimc->params.src.buf_addr_phy_rgb_y = src_img->paddr;
  779. fimc->params.src.buf_addr_phy_cb = src_img->paddr + src_img->uoffset;
  780. fimc->params.src.buf_addr_phy_cr = src_img->paddr + src_img->uoffset + src_img->voffset;
  781. src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y;
  782. break;
  783. }
  784. // copy
  785. src_frame_size = FRAME_SIZE(src_img->format, src_img->w, src_img->h);
  786. if (src_frame_size == 0) {
  787. SEC_HWC_Log(HWC_LOG_ERROR, "%s::FRAME_SIZE fail", __func__);
  788. return 0;
  789. }
  790. #ifdef USE_HW_PMEM
  791. if (0 <= checkPmem(&ctx->sec_pmem, 0, src_frame_size)) {
  792. src_virt_addr = pm_alloc->virt_addr;
  793. src_phys_addr = pm_alloc->phys_addr;
  794. pm_alloc->size = src_frame_size;
  795. } else
  796. #endif
  797. if (0 <= checkMem(&ctx->s3c_mem, 0, src_frame_size)) {
  798. src_virt_addr = ptr_mem_alloc->vir_addr;
  799. src_phys_addr = ptr_mem_alloc->phy_addr;
  800. ptr_mem_alloc->size = src_frame_size;
  801. } else {
  802. SEC_HWC_Log(HWC_LOG_ERROR, "%s::check_mem fail", __func__);
  803. return 0;
  804. }
  805. if ((src_img->format == HAL_PIXEL_FORMAT_YCbCr_420_P) ||
  806. (src_img->format == HAL_PIXEL_FORMAT_YV12) ||
  807. (src_img->format == HAL_PIXEL_FORMAT_YCbCr_420_SP) ||
  808. (src_img->format == HAL_PIXEL_FORMAT_YCrCb_420_SP)) {
  809. if (memcpy_rect((void *)src_virt_addr, (void*)((unsigned int)src_img->base),
  810. src_img->f_w, src_img->f_h, src_rect->w, src_rect->h, src_img->format) != 0)
  811. return 0;
  812. } else {
  813. memcpy((void *)src_virt_addr, (void*)((unsigned int)src_img->base), src_frame_size);
  814. }
  815. #ifdef USE_HW_PMEM
  816. if (pm_alloc->size == src_frame_size) {
  817. region.offset = 0;
  818. region.len = src_frame_size;
  819. if (ioctl(ctx->sec_pmem.pmem_master_fd, PMEM_CACHE_FLUSH, &region) < 0)
  820. SEC_HWC_Log(HWC_LOG_ERROR, "%s::pmem cache flush fail ", __func__);
  821. }
  822. #endif
  823. break;
  824. }
  825. }
  826. return src_phys_addr;
  827. }
  828. static int get_dst_phys_addr(struct hwc_context_t *ctx, sec_img *dst_img,
  829. sec_rect *dst_rect, int *dst_memcpy_flag)
  830. {
  831. unsigned int dst_phys_addr = 0;
  832. if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
  833. dst_phys_addr = dst_img->base;
  834. else
  835. dst_phys_addr = dst_img->base;
  836. return dst_phys_addr;
  837. }
  838. static inline int rotateValueHAL2PP(unsigned char transform)
  839. {
  840. int rotate_flag = transform & 0x7;
  841. switch (rotate_flag) {
  842. case HAL_TRANSFORM_ROT_90: return 90;
  843. case HAL_TRANSFORM_ROT_180: return 180;
  844. case HAL_TRANSFORM_ROT_270: return 270;
  845. case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: return 90;
  846. case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: return 90;
  847. case HAL_TRANSFORM_FLIP_H: return 0;
  848. case HAL_TRANSFORM_FLIP_V: return 0;
  849. }
  850. return 0;
  851. }
  852. static inline int hflipValueHAL2PP(unsigned char transform)
  853. {
  854. int flip_flag = transform & 0x7;
  855. switch (flip_flag) {
  856. case HAL_TRANSFORM_FLIP_H:
  857. case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
  858. return 1;
  859. case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
  860. case HAL_TRANSFORM_ROT_90:
  861. case HAL_TRANSFORM_ROT_180:
  862. case HAL_TRANSFORM_ROT_270:
  863. case HAL_TRANSFORM_FLIP_V:
  864. break;
  865. }
  866. return 0;
  867. }
  868. static inline int vflipValueHAL2PP(unsigned char transform)
  869. {
  870. int flip_flag = transform & 0x7;
  871. switch (flip_flag) {
  872. case HAL_TRANSFORM_FLIP_V:
  873. case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
  874. return 1;
  875. case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
  876. case HAL_TRANSFORM_ROT_90:
  877. case HAL_TRANSFORM_ROT_180:
  878. case HAL_TRANSFORM_ROT_270:
  879. case HAL_TRANSFORM_FLIP_H:
  880. break;
  881. }
  882. return 0;
  883. }
  884. static inline int multipleOf2(int number)
  885. {
  886. if (number % 2 == 1)
  887. return (number - 1);
  888. else
  889. return number;
  890. }
  891. static inline int multipleOf4(int number)
  892. {
  893. int remain_number = number % 4;
  894. if (remain_number != 0)
  895. return (number - remain_number);
  896. else
  897. return number;
  898. }
  899. static inline int multipleOf8(int number)
  900. {
  901. int remain_number = number % 8;
  902. if (remain_number != 0)
  903. return (number - remain_number);
  904. else
  905. return number;
  906. }
  907. static inline int multipleOf16(int number)
  908. {
  909. int remain_number = number % 16;
  910. if (remain_number != 0)
  911. return (number - remain_number);
  912. else
  913. return number;
  914. }
  915. static inline int widthOfPP(unsigned int ver, int pp_color_format, int number)
  916. {
  917. #ifdef BOARD_USE_V4L2_ION
  918. if (1) {
  919. #else
  920. if (0x50 <= ver) {
  921. #endif
  922. switch (pp_color_format) {
  923. /* 422 1/2/3 plane */
  924. case V4L2_PIX_FMT_YUYV:
  925. case V4L2_PIX_FMT_UYVY:
  926. case V4L2_PIX_FMT_NV61:
  927. case V4L2_PIX_FMT_NV16:
  928. case V4L2_PIX_FMT_YUV422P:
  929. /* 420 2/3 plane */
  930. case V4L2_PIX_FMT_NV21:
  931. case V4L2_PIX_FMT_NV12:
  932. case V4L2_PIX_FMT_NV12T:
  933. case V4L2_PIX_FMT_YUV420:
  934. return multipleOf2(number);
  935. default :
  936. return number;
  937. }
  938. } else {
  939. switch (pp_color_format) {
  940. case V4L2_PIX_FMT_RGB565:
  941. return multipleOf8(number);
  942. case V4L2_PIX_FMT_RGB32:
  943. return multipleOf4(number);
  944. case V4L2_PIX_FMT_YUYV:
  945. case V4L2_PIX_FMT_UYVY:
  946. return multipleOf4(number);
  947. case V4L2_PIX_FMT_NV61:
  948. case V4L2_PIX_FMT_NV16:
  949. return multipleOf8(number);
  950. case V4L2_PIX_FMT_YUV422P:
  951. return multipleOf16(number);
  952. case V4L2_PIX_FMT_NV21:
  953. case V4L2_PIX_FMT_NV12:
  954. case V4L2_PIX_FMT_NV12T:
  955. return multipleOf8(number);
  956. case V4L2_PIX_FMT_YUV420:
  957. return multipleOf16(number);
  958. default :
  959. return number;
  960. }
  961. }
  962. return number;
  963. }
  964. static inline int heightOfPP(int pp_color_format, int number)
  965. {
  966. switch (pp_color_format) {
  967. case V4L2_PIX_FMT_NV21:
  968. case V4L2_PIX_FMT_NV12:
  969. case V4L2_PIX_FMT_NV12T:
  970. case V4L2_PIX_FMT_YUV420:
  971. return multipleOf2(number);
  972. default :
  973. return number;
  974. break;
  975. }
  976. return number;
  977. }
  978. static unsigned int get_yuv_bpp(unsigned int fmt)
  979. {
  980. int i, sel = -1;
  981. for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) {
  982. if (yuv_list[i].fmt == fmt) {
  983. sel = i;
  984. break;
  985. }
  986. }
  987. if (sel == -1)
  988. return sel;
  989. else
  990. return yuv_list[sel].bpp;
  991. }
  992. static unsigned int get_yuv_planes(unsigned int fmt)
  993. {
  994. int i, sel = -1;
  995. for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) {
  996. if (yuv_list[i].fmt == fmt) {
  997. sel = i;
  998. break;
  999. }
  1000. }
  1001. if (sel == -1)
  1002. return sel;
  1003. else
  1004. return yuv_list[sel].planes;
  1005. }
  1006. static int runcFimcCore(struct hwc_context_t *ctx,
  1007. unsigned int src_phys_addr, sec_img *src_img, sec_rect *src_rect,
  1008. uint32_t src_color_space,
  1009. unsigned int dst_phys_addr, sec_img *dst_img, sec_rect *dst_rect,
  1010. uint32_t dst_color_space, int transform)
  1011. {
  1012. s5p_fimc_t * fimc = &ctx->fimc;
  1013. s5p_fimc_params_t * params = &(fimc->params);
  1014. struct fimc_buf fimc_src_buf;
  1015. int src_bpp, src_planes;
  1016. #ifdef BOARD_USE_V4L2_ION
  1017. struct fimc_buf fimc_dst_buf;
  1018. int dst_bpp, dst_planes;
  1019. unsigned int src_frame_size = 0;
  1020. unsigned int dst_frame_size = 0;
  1021. #endif
  1022. unsigned int frame_size = 0;
  1023. bool src_cbcr_order = true;
  1024. int rotate_value = rotateValueHAL2PP(transform);
  1025. int hflip = hflipValueHAL2PP(transform);
  1026. int vflip = vflipValueHAL2PP(transform);
  1027. /* 1. param(fimc config)->src information
  1028. * - src_img,src_rect => s_fw,s_fh,s_w,s_h,s_x,s_y
  1029. */
  1030. params->src.full_width = src_img->f_w;
  1031. params->src.full_height = src_img->f_h;
  1032. params->src.width = src_rect->w;
  1033. params->src.height = src_rect->h;
  1034. params->src.start_x = src_rect->x;
  1035. params->src.start_y = src_rect->y;
  1036. params->src.color_space = src_color_space;
  1037. params->src.buf_addr_phy_rgb_y = src_phys_addr;
  1038. #ifdef BOARD_USE_V4L2_ION
  1039. params->dst.full_width = dst_img->f_w;
  1040. params->dst.full_height = dst_img->f_h;
  1041. params->dst.width = widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  1042. params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
  1043. params->dst.start_x = dst_rect->x;
  1044. params->dst.start_y = dst_rect->y;
  1045. params->dst.color_space = dst_color_space;
  1046. params->dst.buf_addr_phy_rgb_y = dst_phys_addr;
  1047. #endif
  1048. /* check src minimum */
  1049. if (src_rect->w < 16 || src_rect->h < 8) {
  1050. SEC_HWC_Log(HWC_LOG_ERROR,
  1051. "%s src size is not supported by fimc : f_w=%d f_h=%d "
  1052. "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
  1053. params->src.full_width, params->src.full_height,
  1054. params->src.start_x, params->src.start_y,
  1055. params->src.width, params->src.height,
  1056. src_rect->w, src_rect->h,
  1057. params->src.color_space);
  1058. return -1;
  1059. }
  1060. #ifdef BOARD_USE_V4L2_ION
  1061. #else
  1062. /* 2. param(fimc config)->dst information
  1063. * - dst_img,dst_rect,rot => d_fw,d_fh,d_w,d_h,d_x,d_y
  1064. */
  1065. switch (rotate_value) {
  1066. case 0:
  1067. params->dst.full_width = dst_img->f_w;
  1068. params->dst.full_height = dst_img->f_h;
  1069. params->dst.start_x = dst_rect->x;
  1070. params->dst.start_y = dst_rect->y;
  1071. params->dst.width =
  1072. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  1073. params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
  1074. break;
  1075. case 90:
  1076. params->dst.full_width = dst_img->f_h;
  1077. params->dst.full_height = dst_img->f_w;
  1078. params->dst.start_x = dst_rect->y;
  1079. params->dst.start_y = dst_img->f_w - (dst_rect->x + dst_rect->w);
  1080. params->dst.width =
  1081. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
  1082. params->dst.height =
  1083. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  1084. if (0x50 > fimc->hw_ver)
  1085. params->dst.start_y += (dst_rect->w - params->dst.height);
  1086. break;
  1087. case 180:
  1088. params->dst.full_width = dst_img->f_w;
  1089. params->dst.full_height = dst_img->f_h;
  1090. params->dst.start_x = dst_img->f_w - (dst_rect->x + dst_rect->w);
  1091. params->dst.start_y = dst_img->f_h - (dst_rect->y + dst_rect->h);
  1092. params->dst.width =
  1093. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  1094. params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
  1095. break;
  1096. case 270:
  1097. params->dst.full_width = dst_img->f_h;
  1098. params->dst.full_height = dst_img->f_w;
  1099. params->dst.start_x = dst_img->f_h - (dst_rect->y + dst_rect->h);
  1100. params->dst.start_y = dst_rect->x;
  1101. params->dst.width =
  1102. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
  1103. params->dst.height =
  1104. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  1105. if (0x50 > fimc->hw_ver)
  1106. params->dst.start_y += (dst_rect->w - params->dst.height);
  1107. break;
  1108. }
  1109. params->dst.color_space = dst_color_space;
  1110. #endif
  1111. SEC_HWC_Log(HWC_LOG_DEBUG,
  1112. "runcFimcCore()::"
  1113. "SRC f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)=>"
  1114. "DST f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)",
  1115. params->src.full_width, params->src.full_height,
  1116. params->src.start_x, params->src.start_y,
  1117. params->src.width, params->src.height,
  1118. params->dst.full_width, params->dst.full_height,
  1119. params->dst.start_x, params->dst.start_y,
  1120. params->dst.width, params->dst.height);
  1121. /* check dst minimum */
  1122. if (dst_rect->w < 8 || dst_rect->h < 4) {
  1123. SEC_HWC_Log(HWC_LOG_ERROR,
  1124. "%s dst size is not supported by fimc : f_w=%d f_h=%d "
  1125. "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
  1126. params->dst.full_width, params->dst.full_height,
  1127. params->dst.start_x, params->dst.start_y,
  1128. params->dst.width, params->dst.height,
  1129. dst_rect->w, dst_rect->h, params->dst.color_space);
  1130. return -1;
  1131. }
  1132. /* check scaling limit
  1133. * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
  1134. */
  1135. if (((src_rect->w > dst_rect->w) &&
  1136. ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
  1137. ((dst_rect->w > src_rect->w) &&
  1138. ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
  1139. SEC_HWC_Log(HWC_LOG_ERROR,
  1140. "%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
  1141. __func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
  1142. return -1;
  1143. }
  1144. /* 3. Set configuration related to destination (DMA-OUT)
  1145. * - set input format & size
  1146. * - crop input size
  1147. * - set input buffer
  1148. * - set buffer type (V4L2_MEMORY_USERPTR)
  1149. */
  1150. #ifdef BOARD_USE_V4L2_ION
  1151. switch (dst_img->format) {
  1152. case HAL_PIXEL_FORMAT_RGBA_8888:
  1153. case HAL_PIXEL_FORMAT_RGBX_8888:
  1154. case HAL_PIXEL_FORMAT_RGB_888:
  1155. case HAL_PIXEL_FORMAT_BGRA_8888:
  1156. dst_planes = 1;
  1157. dst_bpp = 32;
  1158. break;
  1159. case HAL_PIXEL_FORMAT_RGB_565:
  1160. case HAL_PIXEL_FORMAT_RGBA_5551:
  1161. case HAL_PIXEL_FORMAT_RGBA_4444:
  1162. dst_planes = 1;
  1163. dst_bpp = 16;
  1164. break;
  1165. }
  1166. dst_frame_size = params->dst.width * params->dst.height ;
  1167. params->dst.planes = dst_planes;
  1168. if (dst_planes == 1) {
  1169. fimc_dst_buf.base[0] = params->dst.buf_addr_phy_rgb_y;
  1170. if (dst_bpp == 32)
  1171. fimc_dst_buf.size[0] = dst_frame_size * 4;
  1172. else if (dst_bpp == 16)
  1173. fimc_dst_buf.size[0] = dst_frame_size * 2;
  1174. }
  1175. #endif
  1176. if (fimc_v4l2_set_dst(fimc->dev_fd, &params->dst, rotate_value, hflip, vflip, dst_phys_addr) < 0) {
  1177. SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_dst is failed\n");
  1178. return -1;
  1179. }
  1180. /* 4. Set configuration related to source (DMA-INPUT)
  1181. * - set input format & size
  1182. * - crop input size
  1183. * - set input buffer
  1184. * - set buffer type (V4L2_MEMORY_USERPTR)
  1185. */
  1186. #ifndef BOARD_USE_V4L2_ION
  1187. if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0) {
  1188. SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_src is failed\n");
  1189. return -1;
  1190. }
  1191. #endif
  1192. /* 5. Set input dma address (Y/RGB, Cb, Cr)
  1193. * - zero copy : mfc, camera
  1194. * - memcpy to pmem : SW dec(420P), video editor(YV12)
  1195. */
  1196. switch (src_img->format) {
  1197. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
  1198. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
  1199. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
  1200. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
  1201. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
  1202. /* for video contents zero copy case */
  1203. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  1204. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  1205. break;
  1206. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
  1207. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
  1208. case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
  1209. case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
  1210. case HAL_PIXEL_FORMAT_RGB_565:
  1211. case HAL_PIXEL_FORMAT_YV12:
  1212. default:
  1213. if (src_img->format == HAL_PIXEL_FORMAT_YV12)
  1214. src_cbcr_order = false;
  1215. #ifdef BOARD_USE_V4L2_ION
  1216. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  1217. if (src_cbcr_order == true) {
  1218. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  1219. fimc_src_buf.base[2] = params->src.buf_addr_phy_cr;
  1220. } else {
  1221. fimc_src_buf.base[1] = params->src.buf_addr_phy_cr;
  1222. fimc_src_buf.base[2] = params->src.buf_addr_phy_cb;
  1223. }
  1224. SEC_HWC_Log(HWC_LOG_DEBUG,
  1225. "runFimcCore - Y=0x%X, U=0x%X, V=0x%X\n",
  1226. fimc_src_buf.base[0], fimc_src_buf.base[1],fimc_src_buf.base[2]);
  1227. src_frame_size = params->src.full_width * params->src.full_height;
  1228. fimc_src_buf.size[0] = src_frame_size;
  1229. fimc_src_buf.size[1] = src_frame_size >> 2;
  1230. fimc_src_buf.size[2] = src_frame_size >> 2;
  1231. SEC_HWC_Log(HWC_LOG_DEBUG,
  1232. "runFimcCore - Y_length=%d, U_length=%d, V_length=%d\n",
  1233. fimc_src_buf.size[0], fimc_src_buf.size[1],fimc_src_buf.size[2]);
  1234. src_planes = get_yuv_planes(src_color_space);
  1235. break;
  1236. #endif
  1237. if (src_img->usage & GRALLOC_USAGE_HW_FIMC1) {
  1238. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  1239. if (src_cbcr_order == true) {
  1240. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  1241. fimc_src_buf.base[2] = params->src.buf_addr_phy_cr;
  1242. }
  1243. else {
  1244. fimc_src_buf.base[2] = params->src.buf_addr_phy_cb;
  1245. fimc_src_buf.base[1] = params->src.buf_addr_phy_cr;
  1246. }
  1247. SEC_HWC_Log(HWC_LOG_DEBUG,
  1248. "runFimcCore - Y=0x%X, U=0x%X, V=0x%X\n",
  1249. fimc_src_buf.base[0], fimc_src_buf.base[1],fimc_src_buf.base[2]);
  1250. break;
  1251. }
  1252. /* set source Y image */
  1253. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  1254. /* set source Cb,Cr images for 2 or 3 planes */
  1255. src_bpp = get_yuv_bpp(src_color_space);
  1256. src_planes = get_yuv_planes(src_color_space);
  1257. if (2 == src_planes) { /* 2 planes */
  1258. frame_size = params->src.full_width * params->src.full_height;
  1259. params->src.buf_addr_phy_cb =
  1260. params->src.buf_addr_phy_rgb_y + frame_size;
  1261. /* CbCr */
  1262. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  1263. } else if (3 == src_planes) { /* 3 planes */
  1264. frame_size = params->src.full_width * params->src.full_height;
  1265. params->src.buf_addr_phy_cb =
  1266. params->src.buf_addr_phy_rgb_y + frame_size;
  1267. if (12 == src_bpp)
  1268. params->src.buf_addr_phy_cr =
  1269. params->src.buf_addr_phy_cb + (frame_size >> 2);
  1270. else
  1271. params->src.buf_addr_phy_cr =
  1272. params->src.buf_addr_phy_cb + (frame_size >> 1);
  1273. /* Cb, Cr */
  1274. if (src_cbcr_order == true) {
  1275. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  1276. fimc_src_buf.base[2] = params->src.buf_addr_phy_cr;
  1277. }
  1278. else {
  1279. fimc_src_buf.base[2] = params->src.buf_addr_phy_cb;
  1280. fimc_src_buf.base[1] = params->src.buf_addr_phy_cr;
  1281. }
  1282. }
  1283. break;
  1284. }
  1285. /* 6. Run FIMC
  1286. * - stream on => queue => dequeue => stream off => clear buf
  1287. */
  1288. #ifdef BOARD_USE_V4L2_ION
  1289. int ret = 0;
  1290. params->src.planes = src_planes;
  1291. if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0) {
  1292. SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_src is failed\n");
  1293. return -1;
  1294. }
  1295. fimc_src_buf.planes = src_planes;
  1296. fimc_dst_buf.planes = dst_planes;
  1297. ret = fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf, &fimc_dst_buf);
  1298. if (ret < 0) {
  1299. SEC_HWC_Log(HWC_LOG_ERROR,"fimc_handle_oneshot = %d\n",ret);
  1300. if (ret == -2) {
  1301. fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT);
  1302. } else if (ret == -3) {
  1303. fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT);
  1304. fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_CAPTURE);
  1305. }
  1306. return ret;
  1307. }
  1308. #else
  1309. if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf, NULL) < 0) {
  1310. fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT);
  1311. return -1;
  1312. }
  1313. #endif
  1314. return 0;
  1315. }
  1316. #ifdef SUB_TITLES_HWC
  1317. int createG2d(sec_g2d_t *g2d)
  1318. {
  1319. g2d->dev_fd = open(SEC_G2D_DEV_NAME, O_RDWR);
  1320. if (g2d->dev_fd <= 0) {
  1321. SEC_HWC_Log(HWC_LOG_ERROR, "%s::G2d open error (%d)", __func__, errno);
  1322. goto err;
  1323. }
  1324. return 0;
  1325. err:
  1326. if (0 < g2d->dev_fd)
  1327. close(g2d->dev_fd);
  1328. g2d->dev_fd =0;
  1329. return -1;
  1330. }
  1331. int destroyG2d(sec_g2d_t *g2d)
  1332. {
  1333. // close
  1334. if (0 < g2d->dev_fd)
  1335. close(g2d->dev_fd);
  1336. g2d->dev_fd = 0;
  1337. return 0;
  1338. }
  1339. #endif
  1340. int createFimc(s5p_fimc_t *fimc)
  1341. {
  1342. struct v4l2_capability cap;
  1343. struct v4l2_format fmt;
  1344. struct v4l2_control vc;
  1345. // open device file
  1346. if (fimc->dev_fd <= 0)
  1347. fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
  1348. if (fimc->dev_fd <= 0) {
  1349. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Post processor open error (%d)",
  1350. __func__, errno);
  1351. goto err;
  1352. }
  1353. // check capability
  1354. if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
  1355. SEC_HWC_Log(HWC_LOG_ERROR, "VIDIOC_QUERYCAP failed");
  1356. goto err;
  1357. }
  1358. if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
  1359. SEC_HWC_Log(HWC_LOG_ERROR, "%d has no streaming support", fimc->dev_fd);
  1360. goto err;
  1361. }
  1362. if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
  1363. SEC_HWC_Log(HWC_LOG_ERROR, "%d is no video output", fimc->dev_fd);
  1364. goto err;
  1365. }
  1366. /*
  1367. * malloc fimc_outinfo structure
  1368. */
  1369. fmt.type = V4L2_BUF_TYPE_OUTPUT;
  1370. if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
  1371. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_FMT", __func__);
  1372. goto err;
  1373. }
  1374. #ifdef BOARD_USE_V4L2_ION
  1375. #else
  1376. vc.id = V4L2_CID_FIMC_VERSION;
  1377. vc.value = 0;
  1378. if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
  1379. SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_CTRL", __func__);
  1380. goto err;
  1381. }
  1382. fimc->hw_ver = vc.value;
  1383. #endif
  1384. return 0;
  1385. err: