mdp_ppp.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713
  1. /* drivers/video/msm/src/drv/mdp/mdp_ppp.c
  2. *
  3. * Copyright (C) 2007 Google Incorporated
  4. * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  5. *
  6. * This software is licensed under the terms of the GNU General Public
  7. * License version 2, as published by the Free Software Foundation, and
  8. * may be copied, distributed, and modified under those terms.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/sched.h>
  18. #include <linux/time.h>
  19. #include <linux/init.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/fb.h>
  22. #include <linux/msm_mdp.h>
  23. #include <linux/file.h>
  24. #include <linux/major.h>
  25. #include "linux/proc_fs.h"
  26. #include <mach/hardware.h>
  27. #include <linux/io.h>
  28. #include <asm/system.h>
  29. #include <asm/mach-types.h>
  30. #include <linux/semaphore.h>
  31. #include <linux/msm_kgsl.h>
  32. #include "mdp.h"
  33. #include "msm_fb.h"
  34. #define MDP_IS_IMGTYPE_BAD(x) (((x) >= MDP_IMGTYPE_LIMIT) && \
  35. (((x) < MDP_IMGTYPE2_START) || \
  36. ((x) >= MDP_IMGTYPE_LIMIT2)))
  37. static uint32_t bytes_per_pixel[] = {
  38. [MDP_RGB_565] = 2,
  39. [MDP_RGB_888] = 3,
  40. [MDP_XRGB_8888] = 4,
  41. [MDP_ARGB_8888] = 4,
  42. [MDP_RGBA_8888] = 4,
  43. [MDP_BGRA_8888] = 4,
  44. [MDP_RGBX_8888] = 4,
  45. [MDP_Y_CBCR_H2V1] = 1,
  46. [MDP_Y_CBCR_H2V2] = 1,
  47. [MDP_Y_CBCR_H2V2_ADRENO] = 1,
  48. [MDP_Y_CRCB_H2V1] = 1,
  49. [MDP_Y_CRCB_H2V2] = 1,
  50. [MDP_YCRYCB_H2V1] = 2,
  51. [MDP_BGR_565] = 2
  52. };
  53. extern uint32 mdp_plv[];
  54. extern struct semaphore mdp_ppp_mutex;
  55. static struct ion_client *ppp_display_iclient;
  56. int mdp_get_bytes_per_pixel(uint32_t format,
  57. struct msm_fb_data_type *mfd)
  58. {
  59. int bpp = -EINVAL;
  60. if (format == MDP_FB_FORMAT)
  61. format = mfd->fb_imgType;
  62. if (format < ARRAY_SIZE(bytes_per_pixel))
  63. bpp = bytes_per_pixel[format];
  64. if (bpp <= 0)
  65. printk(KERN_ERR "%s incorrect format %d\n", __func__, format);
  66. return bpp;
  67. }
  68. static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel,
  69. uint16 *matrix_and_bias_vector,
  70. uint32 *clamp_vector,
  71. uint32 *look_up_table)
  72. {
  73. uint8 input_C2, input_C0, input_C1;
  74. uint32 output;
  75. int32 comp_C2, comp_C1, comp_C0, temp;
  76. int32 temp1, temp2, temp3;
  77. int32 matrix[9];
  78. int32 bias_vector[3];
  79. int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
  80. int32 i;
  81. uint32 _is_lookup_table_enabled;
  82. input_C2 = (input_pixel >> 16) & 0xFF;
  83. input_C1 = (input_pixel >> 8) & 0xFF;
  84. input_C0 = (input_pixel >> 0) & 0xFF;
  85. comp_C0 = input_C0;
  86. comp_C1 = input_C1;
  87. comp_C2 = input_C2;
  88. for (i = 0; i < 9; i++)
  89. matrix[i] =
  90. ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
  91. bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
  92. bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
  93. bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
  94. Y_low_limit = (int32) clamp_vector[0];
  95. Y_high_limit = (int32) clamp_vector[1];
  96. C_low_limit = (int32) clamp_vector[2];
  97. C_high_limit = (int32) clamp_vector[3];
  98. if (look_up_table == 0) /* check for NULL point */
  99. _is_lookup_table_enabled = 0;
  100. else
  101. _is_lookup_table_enabled = 1;
  102. if (_is_lookup_table_enabled == 1) {
  103. comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
  104. comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
  105. comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
  106. }
  107. /*
  108. * Color Conversion
  109. * reorder input colors
  110. */
  111. temp = comp_C2;
  112. comp_C2 = comp_C1;
  113. comp_C1 = comp_C0;
  114. comp_C0 = temp;
  115. /* matrix multiplication */
  116. temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
  117. temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
  118. temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
  119. comp_C0 = temp1 + 0x100;
  120. comp_C1 = temp2 + 0x100;
  121. comp_C2 = temp3 + 0x100;
  122. /* take interger part */
  123. comp_C0 >>= 9;
  124. comp_C1 >>= 9;
  125. comp_C2 >>= 9;
  126. /* post bias (+) */
  127. comp_C0 += bias_vector[0];
  128. comp_C1 += bias_vector[1];
  129. comp_C2 += bias_vector[2];
  130. /* limit pixel to 8-bit */
  131. if (comp_C0 < 0)
  132. comp_C0 = 0;
  133. if (comp_C0 > 255)
  134. comp_C0 = 255;
  135. if (comp_C1 < 0)
  136. comp_C1 = 0;
  137. if (comp_C1 > 255)
  138. comp_C1 = 255;
  139. if (comp_C2 < 0)
  140. comp_C2 = 0;
  141. if (comp_C2 > 255)
  142. comp_C2 = 255;
  143. /* clamp */
  144. if (comp_C0 < Y_low_limit)
  145. comp_C0 = Y_low_limit;
  146. if (comp_C0 > Y_high_limit)
  147. comp_C0 = Y_high_limit;
  148. if (comp_C1 < C_low_limit)
  149. comp_C1 = C_low_limit;
  150. if (comp_C1 > C_high_limit)
  151. comp_C1 = C_high_limit;
  152. if (comp_C2 < C_low_limit)
  153. comp_C2 = C_low_limit;
  154. if (comp_C2 > C_high_limit)
  155. comp_C2 = C_high_limit;
  156. output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
  157. return output;
  158. }
  159. uint32 mdp_conv_matx_yuv2rgb(uint32 input_pixel,
  160. uint16 *matrix_and_bias_vector,
  161. uint32 *clamp_vector, uint32 *look_up_table)
  162. {
  163. uint8 input_C2, input_C0, input_C1;
  164. uint32 output;
  165. int32 comp_C2, comp_C1, comp_C0, temp;
  166. int32 temp1, temp2, temp3;
  167. int32 matrix[9];
  168. int32 bias_vector[3];
  169. int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
  170. int32 i;
  171. uint32 _is_lookup_table_enabled;
  172. input_C2 = (input_pixel >> 16) & 0xFF;
  173. input_C1 = (input_pixel >> 8) & 0xFF;
  174. input_C0 = (input_pixel >> 0) & 0xFF;
  175. comp_C0 = input_C0;
  176. comp_C1 = input_C1;
  177. comp_C2 = input_C2;
  178. for (i = 0; i < 9; i++)
  179. matrix[i] =
  180. ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
  181. bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
  182. bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
  183. bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
  184. Y_low_limit = (int32) clamp_vector[0];
  185. Y_high_limit = (int32) clamp_vector[1];
  186. C_low_limit = (int32) clamp_vector[2];
  187. C_high_limit = (int32) clamp_vector[3];
  188. if (look_up_table == 0) /* check for NULL point */
  189. _is_lookup_table_enabled = 0;
  190. else
  191. _is_lookup_table_enabled = 1;
  192. /* clamp */
  193. if (comp_C0 < Y_low_limit)
  194. comp_C0 = Y_low_limit;
  195. if (comp_C0 > Y_high_limit)
  196. comp_C0 = Y_high_limit;
  197. if (comp_C1 < C_low_limit)
  198. comp_C1 = C_low_limit;
  199. if (comp_C1 > C_high_limit)
  200. comp_C1 = C_high_limit;
  201. if (comp_C2 < C_low_limit)
  202. comp_C2 = C_low_limit;
  203. if (comp_C2 > C_high_limit)
  204. comp_C2 = C_high_limit;
  205. /*
  206. * Color Conversion
  207. * pre bias (-)
  208. */
  209. comp_C0 -= bias_vector[0];
  210. comp_C1 -= bias_vector[1];
  211. comp_C2 -= bias_vector[2];
  212. /* matrix multiplication */
  213. temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
  214. temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
  215. temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
  216. comp_C0 = temp1 + 0x100;
  217. comp_C1 = temp2 + 0x100;
  218. comp_C2 = temp3 + 0x100;
  219. /* take interger part */
  220. comp_C0 >>= 9;
  221. comp_C1 >>= 9;
  222. comp_C2 >>= 9;
  223. /* reorder output colors */
  224. temp = comp_C0;
  225. comp_C0 = comp_C1;
  226. comp_C1 = comp_C2;
  227. comp_C2 = temp;
  228. /* limit pixel to 8-bit */
  229. if (comp_C0 < 0)
  230. comp_C0 = 0;
  231. if (comp_C0 > 255)
  232. comp_C0 = 255;
  233. if (comp_C1 < 0)
  234. comp_C1 = 0;
  235. if (comp_C1 > 255)
  236. comp_C1 = 255;
  237. if (comp_C2 < 0)
  238. comp_C2 = 0;
  239. if (comp_C2 > 255)
  240. comp_C2 = 255;
  241. /* Look-up table */
  242. if (_is_lookup_table_enabled == 1) {
  243. comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
  244. comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
  245. comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
  246. }
  247. output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
  248. return output;
  249. }
  250. static uint32 mdp_calc_tpval(MDPIMG *mdpImg)
  251. {
  252. uint32 tpVal;
  253. uint8 plane_tp;
  254. tpVal = 0;
  255. if ((mdpImg->imgType == MDP_RGB_565)
  256. || (mdpImg->imgType == MDP_BGR_565)) {
  257. /*
  258. * transparent color conversion into 24 bpp
  259. *
  260. * C2R_8BIT
  261. * left shift the entire bit and or it with the upper most bits
  262. */
  263. plane_tp = (uint8) ((mdpImg->tpVal & 0xF800) >> 11);
  264. tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 16;
  265. /* C1B_8BIT */
  266. plane_tp = (uint8) (mdpImg->tpVal & 0x1F);
  267. tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 8;
  268. /* C0G_8BIT */
  269. plane_tp = (uint8) ((mdpImg->tpVal & 0x7E0) >> 5);
  270. tpVal |= ((plane_tp << 2) | ((plane_tp & 0x30) >> 4));
  271. } else {
  272. /* 24bit RGB to RBG conversion */
  273. tpVal = (mdpImg->tpVal & 0xFF00) >> 8;
  274. tpVal |= (mdpImg->tpVal & 0xFF) << 8;
  275. tpVal |= (mdpImg->tpVal & 0xFF0000);
  276. }
  277. return tpVal;
  278. }
  279. static uint8 *mdp_get_chroma_addr(MDPIBUF *iBuf)
  280. {
  281. uint8 *dest1;
  282. dest1 = NULL;
  283. switch (iBuf->ibuf_type) {
  284. case MDP_Y_CBCR_H2V2:
  285. case MDP_Y_CRCB_H2V2:
  286. case MDP_Y_CBCR_H2V1:
  287. case MDP_Y_CRCB_H2V1:
  288. dest1 = (uint8 *) iBuf->buf;
  289. dest1 += iBuf->ibuf_width * iBuf->ibuf_height * iBuf->bpp;
  290. break;
  291. default:
  292. break;
  293. }
  294. return dest1;
  295. }
  296. static void mdp_ppp_setbg(MDPIBUF *iBuf)
  297. {
  298. uint8 *bg0_addr;
  299. uint8 *bg1_addr;
  300. uint32 bg0_ystride, bg1_ystride;
  301. uint32 ppp_src_cfg_reg, unpack_pattern;
  302. int v_slice, h_slice;
  303. v_slice = h_slice = 1;
  304. bg0_addr = (uint8 *) iBuf->buf;
  305. bg1_addr = mdp_get_chroma_addr(iBuf);
  306. bg0_ystride = iBuf->ibuf_width * iBuf->bpp;
  307. bg1_ystride = iBuf->ibuf_width * iBuf->bpp;
  308. switch (iBuf->ibuf_type) {
  309. case MDP_BGR_565:
  310. case MDP_RGB_565:
  311. /* 888 = 3bytes
  312. * RGB = 3Components
  313. * RGB interleaved
  314. */
  315. ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
  316. PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
  317. PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  318. PPP_SRC_UNPACK_ALIGN_LSB |
  319. PPP_SRC_FETCH_PLANES_INTERLVD;
  320. if (iBuf->ibuf_type == MDP_RGB_565)
  321. unpack_pattern =
  322. MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  323. else
  324. unpack_pattern =
  325. MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
  326. break;
  327. case MDP_RGB_888:
  328. /*
  329. * 888 = 3bytes
  330. * RGB = 3Components
  331. * RGB interleaved
  332. */
  333. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
  334. PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
  335. PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  336. PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_INTERLVD;
  337. unpack_pattern =
  338. MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  339. break;
  340. case MDP_BGRA_8888:
  341. case MDP_RGBA_8888:
  342. case MDP_ARGB_8888:
  343. case MDP_XRGB_8888:
  344. case MDP_RGBX_8888:
  345. /*
  346. * 8888 = 4bytes
  347. * ARGB = 4Components
  348. * ARGB interleaved
  349. */
  350. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
  351. PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS | PPP_SRC_C3_ALPHA_EN |
  352. PPP_SRC_BPP_INTERLVD_4BYTES | PPP_SRC_INTERLVD_4COMPONENTS |
  353. PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB |
  354. PPP_SRC_FETCH_PLANES_INTERLVD;
  355. if (iBuf->ibuf_type == MDP_BGRA_8888)
  356. unpack_pattern =
  357. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  358. 8);
  359. else if (iBuf->ibuf_type == MDP_RGBA_8888 ||
  360. iBuf->ibuf_type == MDP_RGBX_8888)
  361. unpack_pattern =
  362. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
  363. 8);
  364. else if (iBuf->ibuf_type == MDP_XRGB_8888)
  365. unpack_pattern =
  366. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  367. 8);
  368. else
  369. unpack_pattern =
  370. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  371. 8);
  372. break;
  373. case MDP_Y_CBCR_H2V2:
  374. case MDP_Y_CRCB_H2V2:
  375. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
  376. PPP_SRC_C0G_8BITS |
  377. PPP_SRC_C1B_8BITS |
  378. PPP_SRC_C3A_8BITS |
  379. PPP_SRC_BPP_INTERLVD_2BYTES |
  380. PPP_SRC_INTERLVD_2COMPONENTS |
  381. PPP_SRC_UNPACK_TIGHT |
  382. PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
  383. if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
  384. unpack_pattern =
  385. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  386. else
  387. unpack_pattern =
  388. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  389. v_slice = h_slice = 2;
  390. break;
  391. case MDP_YCRYCB_H2V1:
  392. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
  393. PPP_SRC_C0G_8BITS |
  394. PPP_SRC_C1B_8BITS |
  395. PPP_SRC_C3A_8BITS |
  396. PPP_SRC_BPP_INTERLVD_2BYTES |
  397. PPP_SRC_INTERLVD_4COMPONENTS |
  398. PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
  399. unpack_pattern =
  400. MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
  401. h_slice = 2;
  402. break;
  403. case MDP_Y_CBCR_H2V1:
  404. case MDP_Y_CRCB_H2V1:
  405. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
  406. PPP_SRC_C0G_8BITS |
  407. PPP_SRC_C1B_8BITS |
  408. PPP_SRC_C3A_8BITS |
  409. PPP_SRC_BPP_INTERLVD_2BYTES |
  410. PPP_SRC_INTERLVD_2COMPONENTS |
  411. PPP_SRC_UNPACK_TIGHT |
  412. PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
  413. if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
  414. unpack_pattern =
  415. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  416. else
  417. unpack_pattern =
  418. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  419. h_slice = 2;
  420. break;
  421. default:
  422. return;
  423. }
  424. /* starting input address adjustment */
  425. mdp_adjust_start_addr(&bg0_addr, &bg1_addr, v_slice, h_slice,
  426. iBuf->roi.lcd_x, iBuf->roi.lcd_y,
  427. iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
  428. iBuf, 1);
  429. /*
  430. * 0x01c0: background plane 0 addr
  431. * 0x01c4: background plane 1 addr
  432. * 0x01c8: background plane 2 addr
  433. * 0x01cc: bg y stride for plane 0 and 1
  434. * 0x01d0: bg y stride for plane 2
  435. * 0x01d4: bg src PPP config
  436. * 0x01d8: unpack pattern
  437. */
  438. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c0, bg0_addr);
  439. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c4, bg1_addr);
  440. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01cc,
  441. (bg1_ystride << 16) | bg0_ystride);
  442. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d4, ppp_src_cfg_reg);
  443. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d8, unpack_pattern);
  444. }
  445. #define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
  446. (img == MDP_Y_CBCR_H2V2) | \
  447. (img == MDP_Y_CBCR_H2V2_ADRENO) | \
  448. (img == MDP_Y_CRCB_H2V1) | \
  449. (img == MDP_Y_CBCR_H2V1))
  450. #define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
  451. #define Y_TO_CRCB_RATIO(format) \
  452. ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CBCR_H2V2_ADRENO || \
  453. format == MDP_Y_CRCB_H2V2) ? 2 : (format == MDP_Y_CBCR_H2V1 || \
  454. format == MDP_Y_CRCB_H2V1) ? 1 : 1)
  455. static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
  456. struct file *p_src_file, struct file *p_dst_file) { }
  457. static void mdp_start_ppp(struct msm_fb_data_type *mfd, MDPIBUF *iBuf,
  458. struct mdp_blit_req *req, struct file *p_src_file, struct file *p_dst_file)
  459. {
  460. uint8 *src0, *src1;
  461. uint8 *dest0, *dest1;
  462. uint16 inpBpp;
  463. uint32 dest0_ystride;
  464. uint32 src_width;
  465. uint32 src_height;
  466. uint32 src0_ystride;
  467. uint32 src0_y1stride;
  468. uint32 dst_roi_width;
  469. uint32 dst_roi_height;
  470. uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg;
  471. uint32 alpha, tpVal;
  472. uint32 packPattern;
  473. uint32 dst_packPattern;
  474. boolean inputRGB, outputRGB, pseudoplanr_output;
  475. int sv_slice, sh_slice;
  476. int dv_slice, dh_slice;
  477. boolean perPixelAlpha = FALSE;
  478. boolean ppp_lookUp_enable = FALSE;
  479. sv_slice = sh_slice = dv_slice = dh_slice = 1;
  480. alpha = tpVal = 0;
  481. src_width = iBuf->mdpImg.width;
  482. src_height = iBuf->roi.y + iBuf->roi.height;
  483. src1 = NULL;
  484. dest1 = NULL;
  485. inputRGB = outputRGB = TRUE;
  486. pseudoplanr_output = FALSE;
  487. ppp_operation_reg = 0;
  488. ppp_dst_cfg_reg = 0;
  489. ppp_src_cfg_reg = 0;
  490. /* Wait for the pipe to clear */
  491. do { } while (mdp_ppp_pipe_wait() <= 0);
  492. /*
  493. * destination config
  494. */
  495. switch (iBuf->ibuf_type) {
  496. case MDP_RGB_888:
  497. dst_packPattern =
  498. MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  499. ppp_dst_cfg_reg =
  500. PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT | PPP_DST_C2R_8BIT |
  501. PPP_DST_PACKET_CNT_INTERLVD_3ELEM | PPP_DST_PACK_TIGHT |
  502. PPP_DST_PACK_ALIGN_LSB | PPP_DST_OUT_SEL_AXI |
  503. PPP_DST_BPP_3BYTES | PPP_DST_PLANE_INTERLVD;
  504. break;
  505. case MDP_BGRA_8888:
  506. case MDP_XRGB_8888:
  507. case MDP_ARGB_8888:
  508. case MDP_RGBA_8888:
  509. case MDP_RGBX_8888:
  510. if (iBuf->ibuf_type == MDP_BGRA_8888)
  511. dst_packPattern =
  512. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  513. 8);
  514. else if (iBuf->ibuf_type == MDP_RGBA_8888 ||
  515. iBuf->ibuf_type == MDP_RGBX_8888)
  516. dst_packPattern =
  517. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
  518. 8);
  519. else if (iBuf->ibuf_type == MDP_XRGB_8888)
  520. dst_packPattern =
  521. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  522. 8);
  523. else
  524. dst_packPattern =
  525. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  526. 8);
  527. ppp_dst_cfg_reg = PPP_DST_C0G_8BIT |
  528. PPP_DST_C1B_8BIT |
  529. PPP_DST_C2R_8BIT |
  530. PPP_DST_C3A_8BIT |
  531. PPP_DST_C3ALPHA_EN |
  532. PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
  533. PPP_DST_PACK_TIGHT |
  534. PPP_DST_PACK_ALIGN_LSB |
  535. PPP_DST_OUT_SEL_AXI |
  536. PPP_DST_BPP_4BYTES | PPP_DST_PLANE_INTERLVD;
  537. break;
  538. case MDP_Y_CBCR_H2V2:
  539. case MDP_Y_CRCB_H2V2:
  540. if (iBuf->ibuf_type == MDP_Y_CBCR_H2V2)
  541. dst_packPattern =
  542. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  543. else
  544. dst_packPattern =
  545. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  546. ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
  547. PPP_DST_C0G_8BIT |
  548. PPP_DST_C1B_8BIT |
  549. PPP_DST_C3A_8BIT |
  550. PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
  551. PPP_DST_PACK_TIGHT |
  552. PPP_DST_PACK_ALIGN_LSB |
  553. PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
  554. ppp_operation_reg |= PPP_OP_DST_CHROMA_420;
  555. outputRGB = FALSE;
  556. pseudoplanr_output = TRUE;
  557. /*
  558. * vertically (y direction) and horizontally (x direction)
  559. * sample reduction by 2
  560. */
  561. /*
  562. * H2V2(YUV420) Cosite
  563. *
  564. * Y Y Y Y
  565. * CbCr CbCr
  566. * Y Y Y Y
  567. * Y Y Y Y
  568. * CbCr CbCr
  569. * Y Y Y Y
  570. */
  571. dv_slice = dh_slice = 2;
  572. /* (x,y) and (width,height) must be even numbern */
  573. iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
  574. iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
  575. iBuf->roi.x = (iBuf->roi.x / 2) * 2;
  576. iBuf->roi.width = (iBuf->roi.width / 2) * 2;
  577. iBuf->roi.lcd_y = (iBuf->roi.lcd_y / 2) * 2;
  578. iBuf->roi.dst_height = (iBuf->roi.dst_height / 2) * 2;
  579. iBuf->roi.y = (iBuf->roi.y / 2) * 2;
  580. iBuf->roi.height = (iBuf->roi.height / 2) * 2;
  581. break;
  582. case MDP_YCRYCB_H2V1:
  583. dst_packPattern =
  584. MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
  585. ppp_dst_cfg_reg =
  586. PPP_DST_C2R_8BIT | PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT |
  587. PPP_DST_C3A_8BIT | PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
  588. PPP_DST_PACK_TIGHT | PPP_DST_PACK_ALIGN_LSB |
  589. PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES |
  590. PPP_DST_PLANE_INTERLVD;
  591. ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
  592. outputRGB = FALSE;
  593. /*
  594. * horizontally (x direction) sample reduction by 2
  595. *
  596. * H2V1(YUV422) Cosite
  597. *
  598. * YCbCr Y YCbCr Y
  599. * YCbCr Y YCbCr Y
  600. * YCbCr Y YCbCr Y
  601. * YCbCr Y YCbCr Y
  602. */
  603. dh_slice = 2;
  604. /*
  605. * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
  606. * preloaded gamma setting of 2.2 when the content is
  607. * non-linear ppp_lookUp_enable = TRUE;
  608. */
  609. /* x and width must be even number */
  610. iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
  611. iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
  612. iBuf->roi.x = (iBuf->roi.x / 2) * 2;
  613. iBuf->roi.width = (iBuf->roi.width / 2) * 2;
  614. break;
  615. case MDP_Y_CBCR_H2V1:
  616. case MDP_Y_CRCB_H2V1:
  617. if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
  618. dst_packPattern =
  619. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  620. else
  621. dst_packPattern =
  622. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  623. ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
  624. PPP_DST_C0G_8BIT |
  625. PPP_DST_C1B_8BIT |
  626. PPP_DST_C3A_8BIT |
  627. PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
  628. PPP_DST_PACK_TIGHT |
  629. PPP_DST_PACK_ALIGN_LSB |
  630. PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
  631. ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
  632. outputRGB = FALSE;
  633. pseudoplanr_output = TRUE;
  634. /* horizontally (x direction) sample reduction by 2 */
  635. dh_slice = 2;
  636. /* x and width must be even number */
  637. iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
  638. iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
  639. iBuf->roi.x = (iBuf->roi.x / 2) * 2;
  640. iBuf->roi.width = (iBuf->roi.width / 2) * 2;
  641. break;
  642. case MDP_BGR_565:
  643. case MDP_RGB_565:
  644. default:
  645. if (iBuf->ibuf_type == MDP_RGB_565)
  646. dst_packPattern =
  647. MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  648. else
  649. dst_packPattern =
  650. MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
  651. ppp_dst_cfg_reg = PPP_DST_C0G_6BIT |
  652. PPP_DST_C1B_5BIT |
  653. PPP_DST_C2R_5BIT |
  654. PPP_DST_PACKET_CNT_INTERLVD_3ELEM |
  655. PPP_DST_PACK_TIGHT |
  656. PPP_DST_PACK_ALIGN_LSB |
  657. PPP_DST_OUT_SEL_AXI |
  658. PPP_DST_BPP_2BYTES | PPP_DST_PLANE_INTERLVD;
  659. break;
  660. }
  661. /* source config */
  662. switch (iBuf->mdpImg.imgType) {
  663. case MDP_RGB_888:
  664. inpBpp = 3;
  665. /*
  666. * 565 = 2bytes
  667. * RGB = 3Components
  668. * RGB interleaved
  669. */
  670. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
  671. PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
  672. PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  673. PPP_SRC_UNPACK_ALIGN_LSB |
  674. PPP_SRC_FETCH_PLANES_INTERLVD;
  675. packPattern = MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  676. ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
  677. PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
  678. break;
  679. case MDP_BGRA_8888:
  680. case MDP_RGBA_8888:
  681. case MDP_ARGB_8888:
  682. perPixelAlpha = TRUE;
  683. case MDP_XRGB_8888:
  684. case MDP_RGBX_8888:
  685. inpBpp = 4;
  686. /*
  687. * 8888 = 4bytes
  688. * ARGB = 4Components
  689. * ARGB interleaved
  690. */
  691. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
  692. PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS |
  693. PPP_SRC_C3_ALPHA_EN | PPP_SRC_BPP_INTERLVD_4BYTES |
  694. PPP_SRC_INTERLVD_4COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  695. PPP_SRC_UNPACK_ALIGN_LSB |
  696. PPP_SRC_FETCH_PLANES_INTERLVD;
  697. if (iBuf->mdpImg.imgType == MDP_BGRA_8888)
  698. packPattern =
  699. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  700. 8);
  701. else if (iBuf->mdpImg.imgType == MDP_RGBA_8888 ||
  702. iBuf->mdpImg.imgType == MDP_RGBX_8888)
  703. packPattern =
  704. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
  705. 8);
  706. else if (iBuf->ibuf_type == MDP_XRGB_8888)
  707. packPattern =
  708. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  709. 8);
  710. else
  711. packPattern =
  712. MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
  713. 8);
  714. ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
  715. PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
  716. break;
  717. case MDP_Y_CBCR_H2V2:
  718. case MDP_Y_CBCR_H2V2_ADRENO:
  719. case MDP_Y_CRCB_H2V2:
  720. inpBpp = 1;
  721. src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
  722. /*
  723. * CbCr = 2bytes
  724. * CbCr = 2Components
  725. * Y+CbCr
  726. */
  727. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
  728. PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
  729. PPP_SRC_INTERLVD_2COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  730. PPP_SRC_UNPACK_ALIGN_LSB |
  731. PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
  732. if (iBuf->mdpImg.imgType == MDP_Y_CRCB_H2V2)
  733. packPattern =
  734. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  735. else
  736. packPattern =
  737. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  738. ppp_operation_reg |= PPP_OP_COLOR_SPACE_YCBCR |
  739. PPP_OP_SRC_CHROMA_420 |
  740. PPP_OP_SRC_CHROMA_COSITE |
  741. PPP_OP_DST_CHROMA_RGB | PPP_OP_DST_CHROMA_COSITE;
  742. inputRGB = FALSE;
  743. sh_slice = sv_slice = 2;
  744. break;
  745. case MDP_YCRYCB_H2V1:
  746. inpBpp = 2;
  747. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
  748. PPP_SRC_C0G_8BITS |
  749. PPP_SRC_C1B_8BITS |
  750. PPP_SRC_C3A_8BITS |
  751. PPP_SRC_BPP_INTERLVD_2BYTES |
  752. PPP_SRC_INTERLVD_4COMPONENTS |
  753. PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
  754. packPattern =
  755. MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
  756. ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
  757. PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
  758. /*
  759. * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
  760. * preloaded inverse gamma setting of 2.2 since they're
  761. * symetric when the content is non-linear
  762. * ppp_lookUp_enable = TRUE;
  763. */
  764. /* x and width must be even number */
  765. iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
  766. iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
  767. iBuf->roi.x = (iBuf->roi.x / 2) * 2;
  768. iBuf->roi.width = (iBuf->roi.width / 2) * 2;
  769. inputRGB = FALSE;
  770. sh_slice = 2;
  771. break;
  772. case MDP_Y_CBCR_H2V1:
  773. case MDP_Y_CRCB_H2V1:
  774. inpBpp = 1;
  775. src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
  776. ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
  777. PPP_SRC_C0G_8BITS |
  778. PPP_SRC_C1B_8BITS |
  779. PPP_SRC_C3A_8BITS |
  780. PPP_SRC_BPP_INTERLVD_2BYTES |
  781. PPP_SRC_INTERLVD_2COMPONENTS |
  782. PPP_SRC_UNPACK_TIGHT |
  783. PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
  784. if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V1)
  785. packPattern =
  786. MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
  787. else
  788. packPattern =
  789. MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
  790. ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
  791. PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
  792. inputRGB = FALSE;
  793. sh_slice = 2;
  794. break;
  795. case MDP_BGR_565:
  796. case MDP_RGB_565:
  797. default:
  798. inpBpp = 2;
  799. /*
  800. * 565 = 2bytes
  801. * RGB = 3Components
  802. * RGB interleaved
  803. */
  804. ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
  805. PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
  806. PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
  807. PPP_SRC_UNPACK_ALIGN_LSB |
  808. PPP_SRC_FETCH_PLANES_INTERLVD;
  809. if (iBuf->mdpImg.imgType == MDP_RGB_565)
  810. packPattern =
  811. MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
  812. else
  813. packPattern =
  814. MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
  815. ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
  816. PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
  817. break;
  818. }
  819. if (pseudoplanr_output)
  820. ppp_dst_cfg_reg |= PPP_DST_PLANE_PSEUDOPLN;
  821. /* YCbCr to RGB color conversion flag */
  822. if ((!inputRGB) && (outputRGB)) {
  823. ppp_operation_reg |= PPP_OP_CONVERT_YCBCR2RGB |
  824. PPP_OP_CONVERT_ON;
  825. /*
  826. * primary/secondary is sort of misleading term...but
  827. * in mdp2.2/3.0 we only use primary matrix (forward/rev)
  828. * in mdp3.1 we use set1(prim) and set2(secd)
  829. */
  830. #ifdef CONFIG_FB_MSM_MDP31
  831. ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_SECONDARY |
  832. PPP_OP_DST_RGB;
  833. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0);
  834. #endif
  835. if (ppp_lookUp_enable) {
  836. ppp_operation_reg |= PPP_OP_LUT_C0_ON |
  837. PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
  838. }
  839. }
  840. /* RGB to YCbCr color conversion flag */
  841. if ((inputRGB) && (!outputRGB)) {
  842. ppp_operation_reg |= PPP_OP_CONVERT_RGB2YCBCR |
  843. PPP_OP_CONVERT_ON;
  844. #ifdef CONFIG_FB_MSM_MDP31
  845. ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_PRIMARY |
  846. PPP_OP_DST_YCBCR;
  847. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0x1e);
  848. #endif
  849. if (ppp_lookUp_enable) {
  850. ppp_operation_reg |= PPP_OP_LUT_C0_ON |
  851. PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
  852. }
  853. }
  854. /* YCbCr to YCbCr color conversion flag */
  855. if ((!inputRGB) && (!outputRGB)) {
  856. if ((ppp_lookUp_enable) &&
  857. (iBuf->mdpImg.imgType != iBuf->ibuf_type)) {
  858. ppp_operation_reg |= PPP_OP_LUT_C0_ON;
  859. }
  860. }
  861. ppp_src_cfg_reg |= (iBuf->roi.x % 2) ? PPP_SRC_BPP_ROI_ODD_X : 0;
  862. ppp_src_cfg_reg |= (iBuf->roi.y % 2) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
  863. if (req->flags & MDP_DEINTERLACE)
  864. ppp_operation_reg |= PPP_OP_DEINT_EN;
  865. /* Dither at DMA side only since iBuf format is RGB888 */
  866. if (iBuf->mdpImg.mdpOp & MDPOP_DITHER)
  867. ppp_operation_reg |= PPP_OP_DITHER_EN;
  868. if (iBuf->mdpImg.mdpOp & MDPOP_ROTATION) {
  869. ppp_operation_reg |= PPP_OP_ROT_ON;
  870. if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
  871. ppp_operation_reg |= PPP_OP_ROT_90;
  872. }
  873. if (iBuf->mdpImg.mdpOp & MDPOP_LR) {
  874. ppp_operation_reg |= PPP_OP_FLIP_LR;
  875. }
  876. if (iBuf->mdpImg.mdpOp & MDPOP_UD) {
  877. ppp_operation_reg |= PPP_OP_FLIP_UD;
  878. }
  879. }
  880. if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
  881. src0_ystride = ALIGN(src_width, 32) * inpBpp;
  882. else
  883. src0_ystride = src_width * inpBpp;
  884. if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
  885. src0_y1stride = 2 * ALIGN(src_width/2, 32);
  886. else
  887. src0_y1stride = src0_ystride;
  888. dest0_ystride = iBuf->ibuf_width * iBuf->bpp;
  889. /* no need to care about rotation since it's the real-XY. */
  890. dst_roi_width = iBuf->roi.dst_width;
  891. dst_roi_height = iBuf->roi.dst_height;
  892. src0 = (uint8 *) iBuf->mdpImg.bmy_addr;
  893. dest0 = (uint8 *) iBuf->buf;
  894. /* Jumping from Y-Plane to Chroma Plane */
  895. dest1 = mdp_get_chroma_addr(iBuf);
  896. /* first pixel addr calculation */
  897. mdp_adjust_start_addr(&src0, &src1, sv_slice, sh_slice, iBuf->roi.x,
  898. iBuf->roi.y, src_width, src_height, inpBpp, iBuf,
  899. 0);
  900. mdp_adjust_start_addr(&dest0, &dest1, dv_slice, dh_slice,
  901. iBuf->roi.lcd_x, iBuf->roi.lcd_y,
  902. iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
  903. iBuf, 2);
  904. /* set scale operation */
  905. mdp_set_scale(iBuf, dst_roi_width, dst_roi_height,
  906. inputRGB, outputRGB, &ppp_operation_reg);
  907. /*
  908. * setting background source for blending
  909. */
  910. mdp_set_blend_attr(iBuf, &alpha, &tpVal, perPixelAlpha,
  911. &ppp_operation_reg);
  912. if (ppp_operation_reg & PPP_OP_BLEND_ON) {
  913. mdp_ppp_setbg(iBuf);
  914. if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
  915. ppp_operation_reg |= PPP_OP_BG_CHROMA_H2V1;
  916. if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
  917. tpVal = mdp_conv_matx_rgb2yuv(tpVal,
  918. (uint16 *) &
  919. mdp_ccs_rgb2yuv,
  920. &mdp_plv[0], NULL);
  921. }
  922. }
  923. }
  924. /*
  925. * 0x0004: enable dbg bus
  926. * 0x0100: "don't care" Edge Condit until scaling is on
  927. * 0x0104: xrc tile x&y size u7.6 format = 7bit.6bit
  928. * 0x0108: src pixel size
  929. * 0x010c: component plane 0 starting address
  930. * 0x011c: component plane 0 ystride
  931. * 0x0124: PPP source config register
  932. * 0x0128: unpacked pattern from lsb to msb (eg. RGB->BGR)
  933. */
  934. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0108, (iBuf->roi.height << 16 |
  935. iBuf->roi.width));
  936. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x010c, src0); /* comp.plane 0 */
  937. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0110, src1); /* comp.plane 1 */
  938. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x011c,
  939. (src0_y1stride << 16 | src0_ystride));
  940. /* setup for rgb 565 */
  941. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0124, ppp_src_cfg_reg);
  942. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0128, packPattern);
  943. /*
  944. * 0x0138: PPP destination operation register
  945. * 0x014c: constant_alpha|transparent_color
  946. * 0x0150: PPP destination config register
  947. * 0x0154: PPP packing pattern
  948. */
  949. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0138, ppp_operation_reg);
  950. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x014c, alpha << 24 | (tpVal &
  951. 0xffffff));
  952. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0150, ppp_dst_cfg_reg);
  953. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0154, dst_packPattern);
  954. /*
  955. * 0x0164: ROI height and width
  956. * 0x0168: Component Plane 0 starting addr
  957. * 0x016c: Component Plane 1 starting addr
  958. * 0x0178: Component Plane 1/0 y stride
  959. */
  960. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0164,
  961. (dst_roi_height << 16 | dst_roi_width));
  962. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0168, dest0);
  963. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x016c, dest1);
  964. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0178,
  965. (dest0_ystride << 16 | dest0_ystride));
  966. flush_imgs(req, inpBpp, iBuf->bpp, p_src_file, p_dst_file);
  967. #ifdef CONFIG_FB_MSM_MDP31
  968. MDP_OUTP(MDP_BASE + 0x00100, 0xFF00);
  969. #endif
  970. mdp_pipe_kickoff(MDP_PPP_TERM, mfd);
  971. }
  972. static int mdp_ppp_verify_req(struct mdp_blit_req *req)
  973. {
  974. u32 src_width, src_height, dst_width, dst_height;
  975. if (req == NULL) {
  976. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  977. __LINE__);
  978. return -1;
  979. }
  980. if (MDP_IS_IMGTYPE_BAD(req->src.format) ||
  981. MDP_IS_IMGTYPE_BAD(req->dst.format)) {
  982. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  983. __LINE__);
  984. return -1;
  985. }
  986. if ((req->src.width == 0) || (req->src.height == 0) ||
  987. (req->src_rect.w == 0) || (req->src_rect.h == 0) ||
  988. (req->dst.width == 0) || (req->dst.height == 0) ||
  989. (req->dst_rect.w == 0) || (req->dst_rect.h == 0)) {
  990. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  991. __LINE__);
  992. return -1;
  993. }
  994. if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
  995. ((req->src_rect.y + req->src_rect.h) > req->src.height)) {
  996. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  997. __LINE__);
  998. return -1;
  999. }
  1000. if (((req->dst_rect.x + req->dst_rect.w) > req->dst.width) ||
  1001. ((req->dst_rect.y + req->dst_rect.h) > req->dst.height)) {
  1002. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  1003. __LINE__);
  1004. return -1;
  1005. }
  1006. /*
  1007. * scaling range check
  1008. */
  1009. src_width = req->src_rect.w;
  1010. src_height = req->src_rect.h;
  1011. if (req->flags & MDP_ROT_90) {
  1012. dst_width = req->dst_rect.h;
  1013. dst_height = req->dst_rect.w;
  1014. } else {
  1015. dst_width = req->dst_rect.w;
  1016. dst_height = req->dst_rect.h;
  1017. }
  1018. switch (req->dst.format) {
  1019. case MDP_Y_CRCB_H2V2:
  1020. case MDP_Y_CBCR_H2V2:
  1021. src_width = (src_width / 2) * 2;
  1022. src_height = (src_height / 2) * 2;
  1023. dst_width = (src_width / 2) * 2;
  1024. dst_height = (src_height / 2) * 2;
  1025. break;
  1026. case MDP_Y_CRCB_H2V1:
  1027. case MDP_Y_CBCR_H2V1:
  1028. case MDP_YCRYCB_H2V1:
  1029. src_width = (src_width / 2) * 2;
  1030. dst_width = (src_width / 2) * 2;
  1031. break;
  1032. default:
  1033. break;
  1034. }
  1035. if (((MDP_SCALE_Q_FACTOR * dst_width) / src_width >
  1036. MDP_MAX_X_SCALE_FACTOR)
  1037. || ((MDP_SCALE_Q_FACTOR * dst_width) / src_width <
  1038. MDP_MIN_X_SCALE_FACTOR)) {
  1039. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  1040. __LINE__);
  1041. return -1;
  1042. }
  1043. if (((MDP_SCALE_Q_FACTOR * dst_height) / src_height >
  1044. MDP_MAX_Y_SCALE_FACTOR)
  1045. || ((MDP_SCALE_Q_FACTOR * dst_height) / src_height <
  1046. MDP_MIN_Y_SCALE_FACTOR)) {
  1047. printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
  1048. __LINE__);
  1049. return -1;
  1050. }
  1051. return 0;
  1052. }
  1053. int get_gem_img(struct mdp_img *img, unsigned long *start, unsigned long *len)
  1054. {
  1055. /* Set len to zero to appropriately error out if
  1056. kgsl_gem_obj_addr fails */
  1057. *len = 0;
  1058. return kgsl_gem_obj_addr(img->memory_id, (int) img->priv, start, len);
  1059. }
  1060. int get_img(struct mdp_img *img, struct mdp_blit_req *req,
  1061. struct fb_info *info, unsigned long *start, unsigned long *len,
  1062. struct file **srcp_file, struct ion_handle **srcp_ihdl)
  1063. {
  1064. int put_needed, fb_num, ret = 0;
  1065. struct file *file;
  1066. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  1067. struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
  1068. #endif
  1069. if (req->flags & MDP_MEMORY_ID_TYPE_FB) {
  1070. file = fget_light(img->memory_id, &put_needed);
  1071. if (file == NULL)
  1072. return -EINVAL;
  1073. if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
  1074. fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
  1075. if (get_fb_phys_info(start, len, fb_num,
  1076. DISPLAY_SUBSYSTEM_ID)) {
  1077. pr_err("get_fb_phys_info() failed\n");
  1078. fput_light(file, put_needed);
  1079. } else {
  1080. *srcp_file = file;
  1081. }
  1082. return ret;
  1083. } else {
  1084. fput_light(file, put_needed);
  1085. }
  1086. }
  1087. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  1088. *srcp_ihdl = ion_import_dma_buf(mfd->iclient, img->memory_id);
  1089. if (IS_ERR_OR_NULL(*srcp_ihdl))
  1090. return PTR_ERR(*srcp_ihdl);
  1091. if (!ion_phys(mfd->iclient, *srcp_ihdl, start, (size_t *) len))
  1092. return ret;
  1093. else
  1094. return -EINVAL;
  1095. #endif
  1096. }
  1097. void put_img(struct file *p_src_file, struct ion_handle *p_ihdl)
  1098. {
  1099. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  1100. if (!IS_ERR_OR_NULL(p_ihdl))
  1101. ion_free(ppp_display_iclient, p_ihdl);
  1102. #endif
  1103. }
  1104. static int mdp_ppp_blit_addr(struct fb_info *info, struct mdp_blit_req *req,
  1105. unsigned long srcp0_start, unsigned long srcp0_len,
  1106. unsigned long srcp1_start, unsigned long srcp1_len,
  1107. unsigned long dst_start, unsigned long dst_len,
  1108. struct file *p_src_file, struct file *p_dst_file,
  1109. struct ion_handle **src_ihdl, struct ion_handle **dst_ihdl)
  1110. {
  1111. MDPIBUF iBuf;
  1112. u32 dst_width, dst_height;
  1113. struct msm_fb_data_type *mfd = info->par;
  1114. if (req->dst.format == MDP_FB_FORMAT)
  1115. req->dst.format = mfd->fb_imgType;
  1116. if (req->src.format == MDP_FB_FORMAT)
  1117. req->src.format = mfd->fb_imgType;
  1118. if (mdp_ppp_verify_req(req)) {
  1119. pr_err("mdp_ppp: invalid image!\n");
  1120. put_img(p_src_file, *src_ihdl);
  1121. put_img(p_dst_file, *dst_ihdl);
  1122. return -1;
  1123. }
  1124. iBuf.ibuf_width = req->dst.width;
  1125. iBuf.ibuf_height = req->dst.height;
  1126. iBuf.bpp = bytes_per_pixel[req->dst.format];
  1127. iBuf.ibuf_type = req->dst.format;
  1128. iBuf.buf = (uint8 *) dst_start;
  1129. iBuf.buf += req->dst.offset;
  1130. iBuf.roi.lcd_x = req->dst_rect.x;
  1131. iBuf.roi.lcd_y = req->dst_rect.y;
  1132. iBuf.roi.dst_width = req->dst_rect.w;
  1133. iBuf.roi.dst_height = req->dst_rect.h;
  1134. iBuf.roi.x = req->src_rect.x;
  1135. iBuf.roi.width = req->src_rect.w;
  1136. iBuf.roi.y = req->src_rect.y;
  1137. iBuf.roi.height = req->src_rect.h;
  1138. iBuf.mdpImg.width = req->src.width;
  1139. iBuf.mdpImg.imgType = req->src.format;
  1140. iBuf.mdpImg.bmy_addr = (uint32 *) (srcp0_start + req->src.offset);
  1141. if (iBuf.mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
  1142. iBuf.mdpImg.cbcr_addr =
  1143. (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
  1144. ALIGN((ALIGN(req->src.width, 32) *
  1145. ALIGN(req->src.height, 32)), 4096));
  1146. else
  1147. iBuf.mdpImg.cbcr_addr = srcp1_start ? (uint32 *)srcp1_start :
  1148. (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
  1149. req->src.width * req->src.height);
  1150. iBuf.mdpImg.mdpOp = MDPOP_NOP;
  1151. if (req->flags & MDP_IS_FG)
  1152. iBuf.mdpImg.mdpOp |= MDPOP_LAYER_IS_FG;
  1153. /* blending check */
  1154. if (req->transp_mask != MDP_TRANSP_NOP) {
  1155. iBuf.mdpImg.mdpOp |= MDPOP_TRANSP;
  1156. iBuf.mdpImg.tpVal = req->transp_mask;
  1157. iBuf.mdpImg.tpVal = mdp_calc_tpval(&iBuf.mdpImg);
  1158. } else {
  1159. iBuf.mdpImg.tpVal = 0;
  1160. }
  1161. req->alpha &= 0xff;
  1162. if (req->alpha < MDP_ALPHA_NOP) {
  1163. iBuf.mdpImg.mdpOp |= MDPOP_ALPHAB;
  1164. iBuf.mdpImg.alpha = req->alpha;
  1165. } else {
  1166. iBuf.mdpImg.alpha = 0xff;
  1167. }
  1168. /* rotation check */
  1169. if (req->flags & MDP_FLIP_LR)
  1170. iBuf.mdpImg.mdpOp |= MDPOP_LR;
  1171. if (req->flags & MDP_FLIP_UD)
  1172. iBuf.mdpImg.mdpOp |= MDPOP_UD;
  1173. if (req->flags & MDP_ROT_90)
  1174. iBuf.mdpImg.mdpOp |= MDPOP_ROT90;
  1175. if (req->flags & MDP_DITHER)
  1176. iBuf.mdpImg.mdpOp |= MDPOP_DITHER;
  1177. if (req->flags & MDP_BLEND_FG_PREMULT) {
  1178. #if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP303)
  1179. iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA;
  1180. #else
  1181. put_img(p_src_file, *src_ihdl);
  1182. put_img(p_dst_file, *dst_ihdl);
  1183. return -EINVAL;
  1184. #endif
  1185. }
  1186. if (req->flags & MDP_DEINTERLACE) {
  1187. #ifdef CONFIG_FB_MSM_MDP31
  1188. if ((req->src.format != MDP_Y_CBCR_H2V2) &&
  1189. (req->src.format != MDP_Y_CRCB_H2V2)) {
  1190. #endif
  1191. put_img(p_src_file, *src_ihdl);
  1192. put_img(p_dst_file, *dst_ihdl);
  1193. return -EINVAL;
  1194. #ifdef CONFIG_FB_MSM_MDP31
  1195. }
  1196. #endif
  1197. }
  1198. /* scale check */
  1199. if (req->flags & MDP_ROT_90) {
  1200. dst_width = req->dst_rect.h;
  1201. dst_height = req->dst_rect.w;
  1202. } else {
  1203. dst_width = req->dst_rect.w;
  1204. dst_height = req->dst_rect.h;
  1205. }
  1206. if ((iBuf.roi.width != dst_width) || (iBuf.roi.height != dst_height))
  1207. iBuf.mdpImg.mdpOp |= MDPOP_ASCALE;
  1208. if (req->flags & MDP_BLUR) {
  1209. #ifdef CONFIG_FB_MSM_MDP31
  1210. if (req->flags & MDP_SHARPENING)
  1211. printk(KERN_WARNING
  1212. "mdp: MDP_SHARPENING is set with MDP_BLUR!\n");
  1213. req->flags |= MDP_SHARPENING;
  1214. req->sharpening_strength = -127;
  1215. #else
  1216. iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_BLUR;
  1217. #endif
  1218. }
  1219. if (req->flags & MDP_SHARPENING) {
  1220. #ifdef CONFIG_FB_MSM_MDP31
  1221. if ((req->sharpening_strength > 127) ||
  1222. (req->sharpening_strength < -127)) {
  1223. printk(KERN_ERR
  1224. "%s: sharpening strength out of range\n",
  1225. __func__);
  1226. put_img(p_src_file, *src_ihdl);
  1227. put_img(p_dst_file, *dst_ihdl);
  1228. return -EINVAL;
  1229. }
  1230. iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING;
  1231. iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff;
  1232. #else
  1233. put_img(p_src_file, *src_ihdl);
  1234. put_img(p_dst_file, *dst_ihdl);
  1235. return -EINVAL;
  1236. #endif
  1237. }
  1238. down(&mdp_ppp_mutex);
  1239. /* MDP cmd block enable */
  1240. mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
  1241. #ifndef CONFIG_FB_MSM_MDP22
  1242. mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
  1243. #else
  1244. /* bg tile fetching HW workaround */
  1245. if (((iBuf.mdpImg.mdpOp & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
  1246. (req->src.format == MDP_ARGB_8888) ||
  1247. (req->src.format == MDP_BGRA_8888) ||
  1248. (req->src.format == MDP_RGBA_8888)) &&
  1249. (iBuf.mdpImg.mdpOp & MDPOP_ROT90) && (req->dst_rect.w <= 16)) {
  1250. int dst_h, src_w, i;
  1251. uint32 mdpOp = iBuf.mdpImg.mdpOp;
  1252. src_w = req->src_rect.w;
  1253. dst_h = iBuf.roi.dst_height;
  1254. for (i = 0; i < (req->dst_rect.h / 16); i++) {
  1255. /* this tile size */
  1256. iBuf.roi.dst_height = 16;
  1257. iBuf.roi.width =
  1258. (16 * req->src_rect.w) / req->dst_rect.h;
  1259. /* if it's out of scale range... */
  1260. if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1261. iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR)
  1262. iBuf.roi.width =
  1263. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1264. MDP_MAX_X_SCALE_FACTOR;
  1265. else if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1266. iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR)
  1267. iBuf.roi.width =
  1268. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1269. MDP_MIN_X_SCALE_FACTOR;
  1270. mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
  1271. /* next tile location */
  1272. iBuf.roi.lcd_y += 16;
  1273. iBuf.roi.x += iBuf.roi.width;
  1274. /* this is for a remainder update */
  1275. dst_h -= 16;
  1276. src_w -= iBuf.roi.width;
  1277. /* restore mdpOp since MDPOP_ASCALE have been cleared */
  1278. iBuf.mdpImg.mdpOp = mdpOp;
  1279. }
  1280. if ((dst_h < 0) || (src_w < 0))
  1281. printk
  1282. ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n",
  1283. __LINE__);
  1284. /* remainder update */
  1285. if ((dst_h > 0) && (src_w > 0)) {
  1286. u32 tmp_v;
  1287. iBuf.roi.dst_height = dst_h;
  1288. iBuf.roi.width = src_w;
  1289. if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1290. iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) {
  1291. tmp_v =
  1292. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1293. MDP_MAX_X_SCALE_FACTOR +
  1294. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
  1295. MDP_MAX_X_SCALE_FACTOR ? 1 : 0;
  1296. /* move x location as roi width gets bigger */
  1297. iBuf.roi.x -= tmp_v - iBuf.roi.width;
  1298. iBuf.roi.width = tmp_v;
  1299. } else
  1300. if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1301. iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) {
  1302. tmp_v =
  1303. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
  1304. MDP_MIN_X_SCALE_FACTOR +
  1305. (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
  1306. MDP_MIN_X_SCALE_FACTOR ? 1 : 0;
  1307. /*
  1308. * we don't move x location for continuity of
  1309. * source image
  1310. */
  1311. iBuf.roi.width = tmp_v;
  1312. }
  1313. mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
  1314. }
  1315. } else {
  1316. mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
  1317. }
  1318. #endif
  1319. /* MDP cmd block disable */
  1320. mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
  1321. up(&mdp_ppp_mutex);
  1322. put_img(p_src_file, *src_ihdl);
  1323. put_img(p_dst_file, *dst_ihdl);
  1324. return 0;
  1325. }
  1326. int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
  1327. {
  1328. unsigned long src_start, dst_start;
  1329. unsigned long src_len = 0;
  1330. unsigned long dst_len = 0;
  1331. struct file *p_src_file = 0 , *p_dst_file = 0;
  1332. struct ion_handle *src_ihdl = NULL;
  1333. struct ion_handle *dst_ihdl = NULL;
  1334. struct msm_fb_data_type *mfd = info->par;
  1335. ppp_display_iclient = mfd->iclient;
  1336. if (req->flags & MDP_BLIT_SRC_GEM)
  1337. get_gem_img(&req->src, &src_start, &src_len);
  1338. else
  1339. get_img(&req->src, req, info, &src_start, &src_len, &p_src_file,
  1340. &src_ihdl);
  1341. if (src_len == 0) {
  1342. pr_err("mdp_ppp: could not retrieve source image from "
  1343. "memory\n");
  1344. return -EINVAL;
  1345. }
  1346. if (req->flags & MDP_BLIT_DST_GEM)
  1347. get_gem_img(&req->dst, &dst_start, &dst_len);
  1348. else
  1349. get_img(&req->dst, req, info, &dst_start, &dst_len, &p_dst_file,
  1350. &dst_ihdl);
  1351. if (dst_len == 0) {
  1352. put_img(p_src_file, src_ihdl);
  1353. pr_err("mdp_ppp: could not retrieve destination image from "
  1354. "memory\n");
  1355. return -EINVAL;
  1356. }
  1357. return mdp_ppp_blit_addr(info, req, src_start, src_len, 0, 0, dst_start,
  1358. dst_len, p_src_file, p_dst_file, &src_ihdl, &dst_ihdl);
  1359. }
  1360. static struct mdp_blit_req overlay_req;
  1361. static bool mdp_overlay_req_set;
  1362. int mdp_ppp_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req)
  1363. {
  1364. memset(&overlay_req, 0, sizeof(struct mdp_blit_req));
  1365. overlay_req.src.width = req->src.width;
  1366. overlay_req.src.height = req->src.height;
  1367. overlay_req.src.format = req->src.format;
  1368. overlay_req.dst.width = req->dst_rect.w;
  1369. overlay_req.dst.height = req->dst_rect.h;
  1370. overlay_req.dst.format = MDP_FB_FORMAT;
  1371. overlay_req.transp_mask = req->transp_mask;
  1372. overlay_req.flags = req->flags;
  1373. overlay_req.alpha = req->alpha;
  1374. overlay_req.src_rect.x = req->src_rect.x;
  1375. overlay_req.src_rect.y = req->src_rect.y;
  1376. overlay_req.src_rect.w = req->src_rect.w;
  1377. overlay_req.src_rect.h = req->src_rect.h;
  1378. overlay_req.dst_rect.x = req->dst_rect.x;
  1379. overlay_req.dst_rect.y = req->dst_rect.y;
  1380. overlay_req.dst_rect.w = req->dst_rect.w;
  1381. overlay_req.dst_rect.h = req->dst_rect.h;
  1382. mdp_overlay_req_set = true;
  1383. pr_debug("%s: Overlay parameters:", __func__);
  1384. pr_debug("Src_Image (%u %u)\n", overlay_req.src.width,
  1385. overlay_req.src.height);
  1386. if (overlay_req.src.format == MDP_Y_CRCB_H2V2)
  1387. pr_debug("Overlay format MDP_Y_CRCB_H2V2\n");
  1388. else if (overlay_req.src.format == MDP_RGB_565)
  1389. pr_debug("Overlay format MDP_RGB_565\n");
  1390. else
  1391. pr_debug("Overlay format(%u) unknown\n",
  1392. overlay_req.src.format);
  1393. pr_debug("Dst_Image (%u %u)\n", overlay_req.dst.width,
  1394. overlay_req.dst.height);
  1395. pr_debug("Src rect: (%u,%u,%u,%u), Dst rect: (%u,%u,%u,%u)\n",
  1396. overlay_req.src_rect.x, overlay_req.src_rect.y,
  1397. overlay_req.src_rect.w, overlay_req.src_rect.h,
  1398. overlay_req.dst_rect.x, overlay_req.dst_rect.y,
  1399. overlay_req.dst_rect.w, overlay_req.dst_rect.h);
  1400. return 0;
  1401. }
  1402. int mdp_ppp_v4l2_overlay_clear(void)
  1403. {
  1404. memset(&overlay_req, 0, sizeof(struct mdp_overlay));
  1405. mdp_overlay_req_set = false;
  1406. return 0;
  1407. }
  1408. int mdp_ppp_v4l2_overlay_play(struct fb_info *info, bool bUserPtr,
  1409. unsigned long srcp0_addr, unsigned long srcp0_size,
  1410. unsigned long srcp1_addr, unsigned long srcp1_size)
  1411. {
  1412. int ret;
  1413. unsigned long srcp0_start = 0, srcp1_start = 0;
  1414. unsigned long srcp0_len = 0, srcp1_len = 0;
  1415. struct ion_handle *srcp0_ihdl = NULL;
  1416. struct ion_handle *srcp1_ihdl = NULL;
  1417. struct msm_fb_data_type *mfd = info->par;
  1418. ppp_display_iclient = mfd->iclient;
  1419. if (!mdp_overlay_req_set) {
  1420. pr_err("mdp_ppp:v4l2:No overlay set, ignore play req\n");
  1421. return -EINVAL;
  1422. }
  1423. overlay_req.dst.width = info->var.xres;
  1424. overlay_req.dst.height = info->var.yres;
  1425. if (bUserPtr) {
  1426. overlay_req.src.memory_id = srcp0_addr;
  1427. get_img(&overlay_req.src, &overlay_req, info, &srcp0_start,
  1428. &srcp0_len, NULL, &srcp0_ihdl);
  1429. if (srcp0_len == 0) {
  1430. pr_err("%s: could not retrieve source image0"
  1431. , __func__);
  1432. return -EINVAL;
  1433. }
  1434. srcp0_addr = srcp0_start + srcp0_size;
  1435. srcp0_size = srcp0_len;
  1436. if (srcp1_addr) {
  1437. overlay_req.src.memory_id = srcp1_addr;
  1438. get_img(&overlay_req.src, &overlay_req, info,
  1439. &srcp1_start, &srcp1_len, NULL, &srcp1_ihdl);
  1440. if (srcp1_len == 0) {
  1441. pr_err("%s: could not retrieve source image1"
  1442. , __func__);
  1443. return -EINVAL;
  1444. }
  1445. srcp1_addr = srcp1_start + srcp1_size;
  1446. srcp1_size = srcp1_len;
  1447. }
  1448. }
  1449. ret = mdp_ppp_blit_addr(info, &overlay_req,
  1450. srcp0_addr, srcp0_size, srcp1_addr, srcp1_size,
  1451. info->fix.smem_start, info->fix.smem_len, NULL, NULL,
  1452. NULL, NULL);
  1453. if (ret)
  1454. pr_err("%s:Blitting overlay failed(%d)\n", __func__, ret);
  1455. return ret;
  1456. }