/drivers/staging/msm/mdp4_overlay.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 1259 lines · 998 code · 209 blank · 52 comment · 196 complexity · 6262d4f49cc3773d965efcbeab87eba8 MD5 · raw file

  1. /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. * 02110-1301, USA.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/kernel.h>
  19. #include <linux/sched.h>
  20. #include <linux/time.h>
  21. #include <linux/init.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/spinlock.h>
  24. #include <linux/hrtimer.h>
  25. #include <linux/clk.h>
  26. #include <mach/hardware.h>
  27. #include <linux/io.h>
  28. #include <linux/debugfs.h>
  29. #include <linux/fb.h>
  30. #include <msm_mdp.h>
  31. #include <linux/file.h>
  32. #include "android_pmem.h"
  33. #include <linux/major.h>
  34. #include <asm/system.h>
  35. #include <asm/mach-types.h>
  36. #include <linux/semaphore.h>
  37. #include <linux/uaccess.h>
  38. #include <linux/mutex.h>
  39. #include "mdp.h"
  40. #include "msm_fb.h"
  41. #include "mdp4.h"
  42. struct mdp4_overlay_ctrl {
  43. struct mdp4_overlay_pipe plist[MDP4_MAX_OVERLAY_PIPE];
  44. struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE];
  45. } mdp4_overlay_db;
  46. static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
  47. void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
  48. {
  49. uint32 dma2_cfg_reg;
  50. dma2_cfg_reg = DMA_DITHER_EN;
  51. if (mfd->fb_imgType == MDP_BGR_565)
  52. dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
  53. else
  54. dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
  55. if (mfd->panel_info.bpp == 18) {
  56. dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
  57. DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
  58. } else if (mfd->panel_info.bpp == 16) {
  59. dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
  60. DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
  61. } else {
  62. dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
  63. DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
  64. }
  65. if (lcdc)
  66. dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
  67. /* dma2 config register */
  68. MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
  69. }
  70. void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
  71. {
  72. /* dma_p source */
  73. MDP_OUTP(MDP_BASE + 0x90004,
  74. (pipe->src_height << 16 | pipe->src_width));
  75. MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
  76. MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
  77. /* dma_p dest */
  78. MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
  79. }
  80. #define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
  81. #define MDP4_VG_PHASE_STEP_SHIFT 29
  82. static int mdp4_leading_0(uint32 num)
  83. {
  84. uint32 bit = 0x80000000;
  85. int i;
  86. for (i = 0; i < 32; i++) {
  87. if (bit & num)
  88. return i;
  89. bit >>= 1;
  90. }
  91. return i;
  92. }
  93. static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
  94. {
  95. uint32 val;
  96. int n;
  97. n = mdp4_leading_0(src);
  98. if (n > f_num)
  99. n = f_num;
  100. val = src << n; /* maximum to reduce lose of resolution */
  101. val /= dst;
  102. if (n < f_num) {
  103. n = f_num - n;
  104. val <<= n;
  105. }
  106. return val;
  107. }
  108. static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
  109. {
  110. pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
  111. pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
  112. if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
  113. if (pipe->dst_h >= pipe->src_h * 8) /* too much */
  114. return;
  115. pipe->op_mode |= MDP4_OP_SCALEY_EN;
  116. if (pipe->pipe_type == OVERLAY_TYPE_VG) {
  117. if (pipe->dst_h <= (pipe->src_h / 4))
  118. pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
  119. else
  120. pipe->op_mode |= MDP4_OP_SCALEY_FIR;
  121. }
  122. pipe->phasey_step = mdp4_scale_phase_step(29,
  123. pipe->src_h, pipe->dst_h);
  124. }
  125. if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
  126. if (pipe->dst_w >= pipe->src_w * 8) /* too much */
  127. return;
  128. pipe->op_mode |= MDP4_OP_SCALEX_EN;
  129. if (pipe->pipe_type == OVERLAY_TYPE_VG) {
  130. if (pipe->dst_w <= (pipe->src_w / 4))
  131. pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
  132. else
  133. pipe->op_mode |= MDP4_OP_SCALEY_FIR;
  134. }
  135. pipe->phasex_step = mdp4_scale_phase_step(29,
  136. pipe->src_w, pipe->dst_w);
  137. }
  138. }
  139. void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
  140. {
  141. char *rgb_base;
  142. uint32 src_size, src_xy, dst_size, dst_xy;
  143. uint32 format, pattern;
  144. rgb_base = MDP_BASE + MDP4_RGB_BASE;
  145. rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
  146. src_size = ((pipe->src_h << 16) | pipe->src_w);
  147. src_xy = ((pipe->src_y << 16) | pipe->src_x);
  148. dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
  149. dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
  150. format = mdp4_overlay_format(pipe);
  151. pattern = mdp4_overlay_unpack_pattern(pipe);
  152. pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
  153. mdp4_scale_setup(pipe);
  154. outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
  155. outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
  156. outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
  157. outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
  158. outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
  159. outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
  160. outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
  161. outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
  162. outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
  163. outpdw(rgb_base + 0x005c, pipe->phasex_step);
  164. outpdw(rgb_base + 0x0060, pipe->phasey_step);
  165. /* 16 bytes-burst x 3 req <= 48 bytes */
  166. outpdw(rgb_base + 0x1004, 0xc2); /* MDP_RGB_FETCH_CFG */
  167. }
  168. void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
  169. {
  170. char *vg_base;
  171. uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
  172. uint32 format, pattern;
  173. vg_base = MDP_BASE + MDP4_VIDEO_BASE;
  174. vg_base += (MDP4_VIDEO_OFF * pipe->pipe_num);
  175. frame_size = ((pipe->src_height << 16) | pipe->src_width);
  176. src_size = ((pipe->src_h << 16) | pipe->src_w);
  177. src_xy = ((pipe->src_y << 16) | pipe->src_x);
  178. dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
  179. dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
  180. format = mdp4_overlay_format(pipe);
  181. pattern = mdp4_overlay_unpack_pattern(pipe);
  182. pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
  183. MDP4_OP_IGC_LUT_EN);
  184. mdp4_scale_setup(pipe);
  185. outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
  186. outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
  187. outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
  188. outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
  189. outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
  190. /* luma component plane */
  191. outpdw(vg_base + 0x0010, pipe->srcp0_addr);
  192. /* chroma component plane */
  193. outpdw(vg_base + 0x0014, pipe->srcp1_addr);
  194. outpdw(vg_base + 0x0040,
  195. pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
  196. outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
  197. outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
  198. outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
  199. outpdw(vg_base + 0x005c, pipe->phasex_step);
  200. outpdw(vg_base + 0x0060, pipe->phasey_step);
  201. if (pipe->op_mode & MDP4_OP_DITHER_EN) {
  202. outpdw(vg_base + 0x0068,
  203. pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
  204. }
  205. /* 16 bytes-burst x 3 req <= 48 bytes */
  206. outpdw(vg_base + 0x1004, 0xc2); /* MDP_VG_FETCH_CFG */
  207. }
  208. int mdp4_overlay_format2type(uint32 format)
  209. {
  210. switch (format) {
  211. case MDP_RGB_565:
  212. case MDP_RGB_888:
  213. case MDP_BGR_565:
  214. case MDP_ARGB_8888:
  215. case MDP_RGBA_8888:
  216. case MDP_BGRA_8888:
  217. return OVERLAY_TYPE_RGB;
  218. case MDP_YCRYCB_H2V1:
  219. case MDP_Y_CRCB_H2V1:
  220. case MDP_Y_CBCR_H2V1:
  221. case MDP_Y_CRCB_H2V2:
  222. case MDP_Y_CBCR_H2V2:
  223. case MDP_Y_CBCR_H2V2_TILE:
  224. case MDP_Y_CRCB_H2V2_TILE:
  225. return OVERLAY_TYPE_VG;
  226. default:
  227. return -ERANGE;
  228. }
  229. }
  230. #define C3_ALPHA 3 /* alpha */
  231. #define C2_R_Cr 2 /* R/Cr */
  232. #define C1_B_Cb 1 /* B/Cb */
  233. #define C0_G_Y 0 /* G/luma */
  234. int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
  235. {
  236. switch (pipe->src_format) {
  237. case MDP_RGB_565:
  238. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  239. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  240. pipe->a_bit = 0;
  241. pipe->r_bit = 1; /* R, 5 bits */
  242. pipe->b_bit = 1; /* B, 5 bits */
  243. pipe->g_bit = 2; /* G, 6 bits */
  244. pipe->alpha_enable = 0;
  245. pipe->unpack_tight = 1;
  246. pipe->unpack_align_msb = 0;
  247. pipe->unpack_count = 2;
  248. pipe->element2 = C2_R_Cr; /* R */
  249. pipe->element1 = C0_G_Y; /* G */
  250. pipe->element0 = C1_B_Cb; /* B */
  251. pipe->bpp = 2; /* 2 bpp */
  252. break;
  253. case MDP_RGB_888:
  254. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  255. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  256. pipe->a_bit = 0;
  257. pipe->r_bit = 3; /* R, 8 bits */
  258. pipe->b_bit = 3; /* B, 8 bits */
  259. pipe->g_bit = 3; /* G, 8 bits */
  260. pipe->alpha_enable = 0;
  261. pipe->unpack_tight = 1;
  262. pipe->unpack_align_msb = 0;
  263. pipe->unpack_count = 2;
  264. pipe->element2 = C2_R_Cr; /* R */
  265. pipe->element1 = C0_G_Y; /* G */
  266. pipe->element0 = C1_B_Cb; /* B */
  267. pipe->bpp = 3; /* 3 bpp */
  268. break;
  269. case MDP_BGR_565:
  270. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  271. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  272. pipe->a_bit = 0;
  273. pipe->r_bit = 1; /* R, 5 bits */
  274. pipe->b_bit = 1; /* B, 5 bits */
  275. pipe->g_bit = 2; /* G, 6 bits */
  276. pipe->alpha_enable = 0;
  277. pipe->unpack_tight = 1;
  278. pipe->unpack_align_msb = 0;
  279. pipe->unpack_count = 2;
  280. pipe->element2 = C1_B_Cb; /* B */
  281. pipe->element1 = C0_G_Y; /* G */
  282. pipe->element0 = C2_R_Cr; /* R */
  283. pipe->bpp = 2; /* 2 bpp */
  284. break;
  285. case MDP_ARGB_8888:
  286. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  287. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  288. pipe->a_bit = 3; /* alpha, 4 bits */
  289. pipe->r_bit = 3; /* R, 8 bits */
  290. pipe->b_bit = 3; /* B, 8 bits */
  291. pipe->g_bit = 3; /* G, 8 bits */
  292. pipe->alpha_enable = 1;
  293. pipe->unpack_tight = 1;
  294. pipe->unpack_align_msb = 0;
  295. pipe->unpack_count = 3;
  296. pipe->element3 = C3_ALPHA; /* alpha */
  297. pipe->element2 = C2_R_Cr; /* R */
  298. pipe->element1 = C0_G_Y; /* G */
  299. pipe->element0 = C1_B_Cb; /* B */
  300. pipe->bpp = 4; /* 4 bpp */
  301. break;
  302. case MDP_RGBA_8888:
  303. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  304. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  305. pipe->a_bit = 3; /* alpha, 4 bits */
  306. pipe->r_bit = 3; /* R, 8 bits */
  307. pipe->b_bit = 3; /* B, 8 bits */
  308. pipe->g_bit = 3; /* G, 8 bits */
  309. pipe->alpha_enable = 1;
  310. pipe->unpack_tight = 1;
  311. pipe->unpack_align_msb = 0;
  312. pipe->unpack_count = 3;
  313. pipe->element3 = C2_R_Cr; /* R */
  314. pipe->element2 = C0_G_Y; /* G */
  315. pipe->element1 = C1_B_Cb; /* B */
  316. pipe->element0 = C3_ALPHA; /* alpha */
  317. pipe->bpp = 4; /* 4 bpp */
  318. break;
  319. case MDP_BGRA_8888:
  320. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  321. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  322. pipe->a_bit = 3; /* alpha, 4 bits */
  323. pipe->r_bit = 3; /* R, 8 bits */
  324. pipe->b_bit = 3; /* B, 8 bits */
  325. pipe->g_bit = 3; /* G, 8 bits */
  326. pipe->alpha_enable = 1;
  327. pipe->unpack_tight = 1;
  328. pipe->unpack_align_msb = 0;
  329. pipe->unpack_count = 3;
  330. pipe->element3 = C1_B_Cb; /* B */
  331. pipe->element2 = C0_G_Y; /* G */
  332. pipe->element1 = C2_R_Cr; /* R */
  333. pipe->element0 = C3_ALPHA; /* alpha */
  334. pipe->bpp = 4; /* 4 bpp */
  335. break;
  336. case MDP_YCRYCB_H2V1:
  337. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  338. pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
  339. pipe->a_bit = 0; /* alpha, 4 bits */
  340. pipe->r_bit = 3; /* R, 8 bits */
  341. pipe->b_bit = 3; /* B, 8 bits */
  342. pipe->g_bit = 3; /* G, 8 bits */
  343. pipe->alpha_enable = 0;
  344. pipe->unpack_tight = 1;
  345. pipe->unpack_align_msb = 0;
  346. pipe->unpack_count = 3;
  347. pipe->element3 = C0_G_Y; /* G */
  348. pipe->element2 = C2_R_Cr; /* R */
  349. pipe->element1 = C0_G_Y; /* G */
  350. pipe->element0 = C1_B_Cb; /* B */
  351. pipe->bpp = 2; /* 2 bpp */
  352. pipe->chroma_sample = MDP4_CHROMA_H2V1;
  353. break;
  354. case MDP_Y_CRCB_H2V1:
  355. case MDP_Y_CBCR_H2V1:
  356. case MDP_Y_CRCB_H2V2:
  357. case MDP_Y_CBCR_H2V2:
  358. pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
  359. pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
  360. pipe->a_bit = 0;
  361. pipe->r_bit = 3; /* R, 8 bits */
  362. pipe->b_bit = 3; /* B, 8 bits */
  363. pipe->g_bit = 3; /* G, 8 bits */
  364. pipe->alpha_enable = 0;
  365. pipe->unpack_tight = 1;
  366. pipe->unpack_align_msb = 0;
  367. pipe->unpack_count = 1; /* 2 */
  368. pipe->element3 = C0_G_Y; /* not used */
  369. pipe->element2 = C0_G_Y; /* not used */
  370. if (pipe->src_format == MDP_Y_CRCB_H2V1) {
  371. pipe->element1 = C2_R_Cr; /* R */
  372. pipe->element0 = C1_B_Cb; /* B */
  373. pipe->chroma_sample = MDP4_CHROMA_H2V1;
  374. } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
  375. pipe->element1 = C1_B_Cb; /* B */
  376. pipe->element0 = C2_R_Cr; /* R */
  377. pipe->chroma_sample = MDP4_CHROMA_H2V1;
  378. } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
  379. pipe->element1 = C2_R_Cr; /* R */
  380. pipe->element0 = C1_B_Cb; /* B */
  381. pipe->chroma_sample = MDP4_CHROMA_420;
  382. } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
  383. pipe->element1 = C1_B_Cb; /* B */
  384. pipe->element0 = C2_R_Cr; /* R */
  385. pipe->chroma_sample = MDP4_CHROMA_420;
  386. }
  387. pipe->bpp = 2; /* 2 bpp */
  388. break;
  389. case MDP_Y_CBCR_H2V2_TILE:
  390. case MDP_Y_CRCB_H2V2_TILE:
  391. pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
  392. pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
  393. pipe->a_bit = 0;
  394. pipe->r_bit = 3; /* R, 8 bits */
  395. pipe->b_bit = 3; /* B, 8 bits */
  396. pipe->g_bit = 3; /* G, 8 bits */
  397. pipe->alpha_enable = 0;
  398. pipe->unpack_tight = 1;
  399. pipe->unpack_align_msb = 0;
  400. pipe->unpack_count = 1; /* 2 */
  401. pipe->element3 = C0_G_Y; /* not used */
  402. pipe->element2 = C0_G_Y; /* not used */
  403. if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
  404. pipe->element1 = C2_R_Cr; /* R */
  405. pipe->element0 = C1_B_Cb; /* B */
  406. pipe->chroma_sample = MDP4_CHROMA_420;
  407. } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
  408. pipe->element1 = C1_B_Cb; /* B */
  409. pipe->element0 = C2_R_Cr; /* R */
  410. pipe->chroma_sample = MDP4_CHROMA_420;
  411. }
  412. pipe->bpp = 2; /* 2 bpp */
  413. break;
  414. default:
  415. /* not likely */
  416. return -ERANGE;
  417. }
  418. return 0;
  419. }
  420. /*
  421. * color_key_convert: output with 12 bits color key
  422. */
  423. static uint32 color_key_convert(int start, int num, uint32 color)
  424. {
  425. uint32 data;
  426. data = (color >> start) & ((1 << num) - 1);
  427. if (num == 5)
  428. data = (data << 7) + (data << 2) + (data >> 3);
  429. else if (num == 6)
  430. data = (data << 6) + data;
  431. else /* 8 bits */
  432. data = (data << 4) + (data >> 4);
  433. return data;
  434. }
  435. void transp_color_key(int format, uint32 transp,
  436. uint32 *c0, uint32 *c1, uint32 *c2)
  437. {
  438. int b_start, g_start, r_start;
  439. int b_num, g_num, r_num;
  440. switch (format) {
  441. case MDP_RGB_565:
  442. b_start = 0;
  443. g_start = 5;
  444. r_start = 11;
  445. r_num = 5;
  446. g_num = 6;
  447. b_num = 5;
  448. break;
  449. case MDP_RGB_888:
  450. case MDP_XRGB_8888:
  451. case MDP_ARGB_8888:
  452. b_start = 0;
  453. g_start = 8;
  454. r_start = 16;
  455. r_num = 8;
  456. g_num = 8;
  457. b_num = 8;
  458. break;
  459. case MDP_BGR_565:
  460. b_start = 11;
  461. g_start = 5;
  462. r_start = 0;
  463. r_num = 5;
  464. g_num = 6;
  465. b_num = 5;
  466. break;
  467. case MDP_Y_CBCR_H2V2:
  468. case MDP_Y_CBCR_H2V1:
  469. b_start = 8;
  470. g_start = 16;
  471. r_start = 0;
  472. r_num = 8;
  473. g_num = 8;
  474. b_num = 8;
  475. break;
  476. case MDP_Y_CRCB_H2V2:
  477. case MDP_Y_CRCB_H2V1:
  478. b_start = 0;
  479. g_start = 16;
  480. r_start = 8;
  481. r_num = 8;
  482. g_num = 8;
  483. b_num = 8;
  484. break;
  485. default:
  486. b_start = 0;
  487. g_start = 8;
  488. r_start = 16;
  489. r_num = 8;
  490. g_num = 8;
  491. b_num = 8;
  492. break;
  493. }
  494. *c0 = color_key_convert(g_start, g_num, transp);
  495. *c1 = color_key_convert(b_start, b_num, transp);
  496. *c2 = color_key_convert(r_start, r_num, transp);
  497. }
  498. uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
  499. {
  500. uint32 format;
  501. format = 0;
  502. if (pipe->solid_fill)
  503. format |= MDP4_FORMAT_SOLID_FILL;
  504. if (pipe->unpack_align_msb)
  505. format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
  506. if (pipe->unpack_tight)
  507. format |= MDP4_FORMAT_UNPACK_TIGHT;
  508. if (pipe->alpha_enable)
  509. format |= MDP4_FORMAT_ALPHA_ENABLE;
  510. format |= (pipe->unpack_count << 13);
  511. format |= ((pipe->bpp - 1) << 9);
  512. format |= (pipe->a_bit << 6);
  513. format |= (pipe->r_bit << 4);
  514. format |= (pipe->b_bit << 2);
  515. format |= pipe->g_bit;
  516. format |= (pipe->frame_format << 29);
  517. if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
  518. /* video/graphic */
  519. format |= (pipe->fetch_plane << 19);
  520. format |= (pipe->chroma_site << 28);
  521. format |= (pipe->chroma_sample << 26);
  522. }
  523. return format;
  524. }
  525. uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
  526. {
  527. return (pipe->element3 << 24) | (pipe->element2 << 16) |
  528. (pipe->element1 << 8) | pipe->element0;
  529. }
  530. void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
  531. {
  532. uint32 data;
  533. char *overlay_base;
  534. if (pipe->mixer_num == MDP4_MIXER1)
  535. overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
  536. else
  537. overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
  538. /* MDP_OVERLAYPROC_CFG */
  539. outpdw(overlay_base + 0x0004, 0x01); /* directout */
  540. data = pipe->src_height;
  541. data <<= 16;
  542. data |= pipe->src_width;
  543. outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
  544. outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
  545. outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
  546. outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
  547. }
  548. int mdp4_overlay_active(int mixer)
  549. {
  550. uint32 data, mask, i;
  551. int p1, p2;
  552. data = inpdw(MDP_BASE + 0x10100);
  553. p1 = 0;
  554. p2 = 0;
  555. for (i = 0; i < 8; i++) {
  556. mask = data & 0x0f;
  557. if (mask) {
  558. if (mask <= 4)
  559. p1++;
  560. else
  561. p2++;
  562. }
  563. data >>= 4;
  564. }
  565. if (mixer)
  566. return p2;
  567. else
  568. return p1;
  569. }
  570. void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
  571. {
  572. uint32 data, mask, snum, stage, mixer;
  573. stage = pipe->mixer_stage;
  574. mixer = pipe->mixer_num;
  575. /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
  576. data = inpdw(MDP_BASE + 0x10100);
  577. if (mixer == MDP4_MIXER1)
  578. stage += 8;
  579. if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
  580. snum = 0;
  581. snum += (4 * pipe->pipe_num);
  582. } else {
  583. snum = 8;
  584. snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
  585. }
  586. mask = 0x0f;
  587. mask <<= snum;
  588. stage <<= snum;
  589. data &= ~mask; /* clear old bits */
  590. data |= stage;
  591. outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
  592. data = inpdw(MDP_BASE + 0x10100);
  593. ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
  594. }
  595. void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
  596. {
  597. uint32 data, mask, snum, stage, mixer;
  598. stage = pipe->mixer_stage;
  599. mixer = pipe->mixer_num;
  600. if (pipe != ctrl->stage[mixer][stage]) /* not running */
  601. return;
  602. /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
  603. data = inpdw(MDP_BASE + 0x10100);
  604. if (mixer == MDP4_MIXER1)
  605. stage += 8;
  606. if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
  607. snum = 0;
  608. snum += (4 * pipe->pipe_num);
  609. } else {
  610. snum = 8;
  611. snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
  612. }
  613. mask = 0x0f;
  614. mask <<= snum;
  615. data &= ~mask; /* clear old bits */
  616. outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
  617. data = inpdw(MDP_BASE + 0x10100);
  618. ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
  619. }
  620. void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
  621. {
  622. unsigned char *overlay_base;
  623. uint32 c0, c1, c2, blend_op;
  624. int off;
  625. if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
  626. overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
  627. else
  628. overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
  629. /* stage 0 to stage 2 */
  630. off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
  631. blend_op = 0;
  632. if (pipe->alpha_enable) /* ARGB */
  633. blend_op = MDP4_BLEND_FG_ALPHA_FG_PIXEL |
  634. MDP4_BLEND_BG_ALPHA_FG_PIXEL;
  635. else
  636. blend_op = (MDP4_BLEND_BG_ALPHA_BG_CONST |
  637. MDP4_BLEND_FG_ALPHA_FG_CONST);
  638. if (pipe->alpha_enable == 0) { /* not ARGB */
  639. if (pipe->is_fg) {
  640. outpdw(overlay_base + off + 0x108, pipe->alpha);
  641. outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
  642. } else {
  643. outpdw(overlay_base + off + 0x108, 0xff - pipe->alpha);
  644. outpdw(overlay_base + off + 0x10c, pipe->alpha);
  645. }
  646. }
  647. if (pipe->transp != MDP_TRANSP_NOP) {
  648. transp_color_key(pipe->src_format, pipe->transp, &c0, &c1, &c2);
  649. if (pipe->is_fg) {
  650. blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */
  651. /* lower limit */
  652. if (c0 > 0x10)
  653. c0 -= 0x10;
  654. if (c1 > 0x10)
  655. c1 -= 0x10;
  656. if (c2 > 0x10)
  657. c2 -= 0x10;
  658. outpdw(overlay_base + off + 0x110,
  659. (c1 << 16 | c0));/* low */
  660. outpdw(overlay_base + off + 0x114, c2);/* low */
  661. /* upper limit */
  662. if ((c0 + 0x20) < 0x0fff)
  663. c0 += 0x20;
  664. else
  665. c0 = 0x0fff;
  666. if ((c1 + 0x20) < 0x0fff)
  667. c1 += 0x20;
  668. else
  669. c1 = 0x0fff;
  670. if ((c2 + 0x20) < 0x0fff)
  671. c2 += 0x20;
  672. else
  673. c2 = 0x0fff;
  674. outpdw(overlay_base + off + 0x118,
  675. (c1 << 16 | c0));/* high */
  676. outpdw(overlay_base + off + 0x11c, c2);/* high */
  677. } else {
  678. blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */
  679. /* lower limit */
  680. if (c0 > 0x10)
  681. c0 -= 0x10;
  682. if (c1 > 0x10)
  683. c1 -= 0x10;
  684. if (c2 > 0x10)
  685. c2 -= 0x10;
  686. outpdw(overlay_base + 0x180,
  687. (c1 << 16 | c0));/* low */
  688. outpdw(overlay_base + 0x184, c2);/* low */
  689. /* upper limit */
  690. if ((c0 + 0x20) < 0x0fff)
  691. c0 += 0x20;
  692. else
  693. c0 = 0x0fff;
  694. if ((c1 + 0x20) < 0x0fff)
  695. c1 += 0x20;
  696. else
  697. c1 = 0x0fff;
  698. if ((c2 + 0x20) < 0x0fff)
  699. c2 += 0x20;
  700. else
  701. c2 = 0x0fff;
  702. outpdw(overlay_base + 0x188,
  703. (c1 << 16 | c0));/* high */
  704. outpdw(overlay_base + 0x18c, c2);/* high */
  705. }
  706. }
  707. outpdw(overlay_base + off + 0x104, blend_op);
  708. }
  709. void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
  710. {
  711. uint32 bits = 0;
  712. if (pipe->mixer_num == MDP4_MIXER1)
  713. bits |= 0x02;
  714. else
  715. bits |= 0x01;
  716. if (all) {
  717. if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
  718. if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
  719. bits |= 0x20;
  720. else
  721. bits |= 0x10;
  722. } else {
  723. if (pipe->pipe_num == OVERLAY_PIPE_VG2)
  724. bits |= 0x08;
  725. else
  726. bits |= 0x04;
  727. }
  728. }
  729. outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
  730. while (inpdw(MDP_BASE + 0x18000) & bits) /* self clear when complete */
  731. ;
  732. }
  733. struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
  734. {
  735. struct mdp4_overlay_pipe *pipe;
  736. if (ndx == 0 || ndx >= MDP4_MAX_OVERLAY_PIPE)
  737. return NULL;
  738. pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
  739. if (pipe->pipe_ndx == 0)
  740. return NULL;
  741. return pipe;
  742. }
  743. struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
  744. {
  745. int i;
  746. struct mdp4_overlay_pipe *pipe;
  747. pipe = &ctrl->plist[0];
  748. for (i = 0; i < MDP4_MAX_OVERLAY_PIPE; i++) {
  749. if (pipe->pipe_ndx == 0) {
  750. pipe->pipe_ndx = i + 1; /* start from 1 */
  751. init_completion(&pipe->comp);
  752. printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%p ndx=%d\n",
  753. pipe, pipe->pipe_ndx);
  754. return pipe;
  755. }
  756. pipe++;
  757. }
  758. return NULL;
  759. }
  760. void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
  761. {
  762. printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%p ndx=%d\n",
  763. pipe, pipe->pipe_ndx);
  764. memset(pipe, 0, sizeof(*pipe));
  765. }
  766. static int get_pipe_num(int ptype, int stage)
  767. {
  768. if (ptype == OVERLAY_TYPE_RGB) {
  769. if (stage == MDP4_MIXER_STAGE_BASE)
  770. return OVERLAY_PIPE_RGB1;
  771. else
  772. return OVERLAY_PIPE_RGB2;
  773. } else {
  774. if (stage == MDP4_MIXER_STAGE0)
  775. return OVERLAY_PIPE_VG1;
  776. else
  777. return OVERLAY_PIPE_VG2;
  778. }
  779. }
  780. int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
  781. {
  782. struct mdp4_overlay_pipe *pipe;
  783. pipe = ctrl->stage[mixer][z_order];
  784. if (pipe == NULL)
  785. return 0;
  786. if (pipe->pipe_ndx == id) /* same req, recycle */
  787. return 0;
  788. return -EPERM;
  789. }
  790. static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
  791. struct mdp4_overlay_pipe **ppipe)
  792. {
  793. struct mdp4_overlay_pipe *pipe;
  794. int ret, ptype;
  795. if (mixer >= MDP4_MAX_MIXER) {
  796. printk(KERN_ERR "mpd_overlay_req2pipe: mixer out of range!\n");
  797. return -ERANGE;
  798. }
  799. if (req->z_order < 0 || req->z_order > 2) {
  800. printk(KERN_ERR "mpd_overlay_req2pipe: z_order=%d out of range!\n",
  801. req->z_order);
  802. return -ERANGE;
  803. }
  804. if (req->src_rect.h == 0 || req->src_rect.w == 0) {
  805. printk(KERN_ERR "mpd_overlay_req2pipe: src img of zero size!\n");
  806. return -EINVAL;
  807. }
  808. ret = mdp4_overlay_req_check(req->id, req->z_order, mixer);
  809. if (ret < 0)
  810. return ret;
  811. ptype = mdp4_overlay_format2type(req->src.format);
  812. if (ptype < 0)
  813. return ptype;
  814. if (req->id == MSMFB_NEW_REQUEST) /* new request */
  815. pipe = mdp4_overlay_pipe_alloc();
  816. else
  817. pipe = mdp4_overlay_ndx2pipe(req->id);
  818. if (pipe == NULL)
  819. return -ENOMEM;
  820. pipe->src_format = req->src.format;
  821. ret = mdp4_overlay_format2pipe(pipe);
  822. if (ret < 0)
  823. return ret;
  824. /*
  825. * base layer == 1, reserved for frame buffer
  826. * zorder 0 == stage 0 == 2
  827. * zorder 1 == stage 1 == 3
  828. * zorder 2 == stage 2 == 4
  829. */
  830. if (req->id == MSMFB_NEW_REQUEST) { /* new request */
  831. pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
  832. pipe->pipe_type = ptype;
  833. pipe->pipe_num = get_pipe_num(ptype, pipe->mixer_stage);
  834. printk(KERN_INFO "mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n",
  835. req->z_order, pipe->pipe_num);
  836. }
  837. pipe->src_width = req->src.width & 0x07ff; /* source img width */
  838. pipe->src_height = req->src.height & 0x07ff; /* source img height */
  839. pipe->src_h = req->src_rect.h & 0x07ff;
  840. pipe->src_w = req->src_rect.w & 0x07ff;
  841. pipe->src_y = req->src_rect.y & 0x07ff;
  842. pipe->src_x = req->src_rect.x & 0x07ff;
  843. pipe->dst_h = req->dst_rect.h & 0x07ff;
  844. pipe->dst_w = req->dst_rect.w & 0x07ff;
  845. pipe->dst_y = req->dst_rect.y & 0x07ff;
  846. pipe->dst_x = req->dst_rect.x & 0x07ff;
  847. if (req->flags & MDP_FLIP_LR)
  848. pipe->op_mode |= MDP4_OP_FLIP_LR;
  849. if (req->flags & MDP_FLIP_UD)
  850. pipe->op_mode |= MDP4_OP_FLIP_UD;
  851. if (req->flags & MDP_DITHER)
  852. pipe->op_mode |= MDP4_OP_DITHER_EN;
  853. if (req->flags & MDP_DEINTERLACE)
  854. pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
  855. pipe->is_fg = req->is_fg;/* control alpha and color key */
  856. pipe->alpha = req->alpha & 0x0ff;
  857. pipe->transp = req->transp_mask;
  858. *ppipe = pipe;
  859. return 0;
  860. }
  861. int get_img(struct msmfb_data *img, struct fb_info *info,
  862. unsigned long *start, unsigned long *len, struct file **pp_file)
  863. {
  864. int put_needed, ret = 0;
  865. struct file *file;
  866. #ifdef CONFIG_ANDROID_PMEM
  867. unsigned long vstart;
  868. #endif
  869. #ifdef CONFIG_ANDROID_PMEM
  870. if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
  871. return 0;
  872. #endif
  873. file = fget_light(img->memory_id, &put_needed);
  874. if (file == NULL)
  875. return -1;
  876. if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
  877. *start = info->fix.smem_start;
  878. *len = info->fix.smem_len;
  879. *pp_file = file;
  880. } else {
  881. ret = -1;
  882. fput_light(file, put_needed);
  883. }
  884. return ret;
  885. }
  886. int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
  887. {
  888. struct mdp4_overlay_pipe *pipe;
  889. pipe = mdp4_overlay_ndx2pipe(req->id);
  890. if (pipe == NULL)
  891. return -ENODEV;
  892. *req = pipe->req_data;
  893. return 0;
  894. }
  895. int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
  896. {
  897. struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
  898. int ret, mixer;
  899. struct mdp4_overlay_pipe *pipe;
  900. int lcdc;
  901. if (mfd == NULL)
  902. return -ENODEV;
  903. if (req->src.format == MDP_FB_FORMAT)
  904. req->src.format = mfd->fb_imgType;
  905. if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
  906. return -EINTR;
  907. mixer = info->node; /* minor number of char device */
  908. ret = mdp4_overlay_req2pipe(req, mixer, &pipe);
  909. if (ret < 0) {
  910. mutex_unlock(&mfd->dma->ov_mutex);
  911. return ret;
  912. }
  913. lcdc = inpdw(MDP_BASE + 0xc0000);
  914. if (lcdc == 0) { /* mddi */
  915. /* MDP cmd block enable */
  916. mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
  917. }
  918. /* return id back to user */
  919. req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
  920. pipe->req_data = *req; /* keep original req */
  921. mutex_unlock(&mfd->dma->ov_mutex);
  922. return 0;
  923. }
  924. int mdp4_overlay_unset(struct fb_info *info, int ndx)
  925. {
  926. struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
  927. struct mdp4_overlay_pipe *pipe;
  928. int lcdc;
  929. if (mfd == NULL)
  930. return -ENODEV;
  931. if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
  932. return -EINTR;
  933. pipe = mdp4_overlay_ndx2pipe(ndx);
  934. if (pipe == NULL) {
  935. mutex_unlock(&mfd->dma->ov_mutex);
  936. return -ENODEV;
  937. }
  938. lcdc = inpdw(MDP_BASE + 0xc0000);
  939. mdp4_mixer_stage_down(pipe);
  940. if (lcdc == 0) { /* mddi */
  941. /* MDP cmd block disable */
  942. mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
  943. }
  944. if (lcdc) /* LCDC mode */
  945. mdp4_overlay_reg_flush(pipe, 0);
  946. mdp4_overlay_pipe_free(pipe);
  947. if (lcdc == 0) { /* mddi */
  948. mdp4_mddi_overlay_restore();
  949. }
  950. mutex_unlock(&mfd->dma->ov_mutex);
  951. return 0;
  952. }
  953. struct tile_desc {
  954. uint32 width; /* tile's width */
  955. uint32 height; /* tile's height */
  956. uint32 row_tile_w; /* tiles per row's width */
  957. uint32 row_tile_h; /* tiles per row's height */
  958. };
  959. void tile_samsung(struct tile_desc *tp)
  960. {
  961. /*
  962. * each row of samsung tile consists of two tiles in height
  963. * and two tiles in width which means width should align to
  964. * 64 x 2 bytes and height should align to 32 x 2 bytes.
  965. * video decoder generate two tiles in width and one tile
  966. * in height which ends up height align to 32 X 1 bytes.
  967. */
  968. tp->width = 64; /* 64 bytes */
  969. tp->row_tile_w = 2; /* 2 tiles per row's width */
  970. tp->height = 32; /* 32 bytes */
  971. tp->row_tile_h = 1; /* 1 tiles per row's height */
  972. }
  973. uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
  974. {
  975. uint32 tile_w, tile_h;
  976. uint32 row_num_w, row_num_h;
  977. tile_w = tp->width * tp->row_tile_w;
  978. tile_h = tp->height * tp->row_tile_h;
  979. row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
  980. row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
  981. return row_num_w * row_num_h * tile_w * tile_h;
  982. }
  983. int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
  984. struct file **pp_src_file)
  985. {
  986. struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
  987. struct msmfb_data *img;
  988. struct mdp4_overlay_pipe *pipe;
  989. ulong start, addr;
  990. ulong len = 0;
  991. struct file *p_src_file = 0;
  992. int lcdc;
  993. if (mfd == NULL)
  994. return -ENODEV;
  995. pipe = mdp4_overlay_ndx2pipe(req->id);
  996. if (pipe == NULL)
  997. return -ENODEV;
  998. if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
  999. return -EINTR;
  1000. img = &req->data;
  1001. get_img(img, info, &start, &len, &p_src_file);
  1002. if (len == 0) {
  1003. mutex_unlock(&mfd->dma->ov_mutex);
  1004. printk(KERN_ERR "mdp_overlay_play: could not retrieve"
  1005. " image from memory\n");
  1006. return -1;
  1007. }
  1008. *pp_src_file = p_src_file;
  1009. addr = start + img->offset;
  1010. pipe->srcp0_addr = addr;
  1011. pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
  1012. if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
  1013. if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
  1014. struct tile_desc tile;
  1015. tile_samsung(&tile);
  1016. pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
  1017. } else
  1018. pipe->srcp1_addr = addr +
  1019. pipe->src_width * pipe->src_height;
  1020. pipe->srcp0_ystride = pipe->src_width;
  1021. pipe->srcp1_ystride = pipe->src_width;
  1022. }
  1023. lcdc = inpdw(MDP_BASE + 0xc0000);
  1024. lcdc &= 0x01; /* LCDC mode */
  1025. if (pipe->pipe_type == OVERLAY_TYPE_VG)
  1026. mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
  1027. else
  1028. mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
  1029. mdp4_mixer_blend_setup(pipe);
  1030. mdp4_mixer_stage_up(pipe);
  1031. if (lcdc) { /* LCDC mode */
  1032. mdp4_overlay_reg_flush(pipe, 1);
  1033. }
  1034. if (lcdc) { /* LCDC mode */
  1035. if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */
  1036. mutex_unlock(&mfd->dma->ov_mutex);
  1037. return 0;
  1038. }
  1039. }
  1040. if (lcdc == 0) { /* MDDI mode */
  1041. #ifdef MDP4_NONBLOCKING
  1042. if (mfd->panel_power_on)
  1043. #else
  1044. if (!mfd->dma->busy && mfd->panel_power_on)
  1045. #endif
  1046. mdp4_mddi_overlay_kickoff(mfd, pipe);
  1047. }
  1048. mutex_unlock(&mfd->dma->ov_mutex);
  1049. return 0;
  1050. }