mdp_ppp_v31.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. /* Copyright (c) 2008-2009, The Linux Foundation. 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. */
  13. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/sched.h>
  16. #include <linux/time.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/fb.h>
  20. #include "linux/proc_fs.h"
  21. #include <mach/hardware.h>
  22. #include <linux/io.h>
  23. #include <asm/system.h>
  24. #include <asm/mach-types.h>
  25. #include <linux/semaphore.h>
  26. #include <asm/div64.h>
  27. #include "mdp.h"
  28. #include "msm_fb.h"
  29. #define MDP_SCALE_COEFF_NUM 32
  30. #define MDP_SCALE_0P2_TO_0P4_INDEX 0
  31. #define MDP_SCALE_0P4_TO_0P6_INDEX 32
  32. #define MDP_SCALE_0P6_TO_0P8_INDEX 64
  33. #define MDP_SCALE_0P8_TO_8P0_INDEX 96
  34. #define MDP_SCALE_COEFF_MASK 0x3ff
  35. #define MDP_SCALE_PR 0
  36. #define MDP_SCALE_FIR 1
  37. static uint32 mdp_scale_0p8_to_8p0_mode;
  38. static uint32 mdp_scale_0p6_to_0p8_mode;
  39. static uint32 mdp_scale_0p4_to_0p6_mode;
  40. static uint32 mdp_scale_0p2_to_0p4_mode;
  41. /* -------- All scaling range, "pixel repeat" -------- */
  42. static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
  43. 0, 0, 0, 0, 0, 0, 0, 0,
  44. 0, 0, 0, 0, 0, 0, 0, 0,
  45. 0, 0, 0, 0, 0, 0, 0, 0,
  46. 0, 0, 0, 0, 0, 0, 0, 0
  47. };
  48. static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
  49. 511, 511, 511, 511, 511, 511, 511, 511,
  50. 511, 511, 511, 511, 511, 511, 511, 511,
  51. 511, 511, 511, 511, 511, 511, 511, 511,
  52. 511, 511, 511, 511, 511, 511, 511, 511
  53. };
  54. static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
  55. 0, 0, 0, 0, 0, 0, 0, 0,
  56. 0, 0, 0, 0, 0, 0, 0, 0,
  57. 0, 0, 0, 0, 0, 0, 0, 0,
  58. 0, 0, 0, 0, 0, 0, 0, 0
  59. };
  60. static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
  61. 0, 0, 0, 0, 0, 0, 0, 0,
  62. 0, 0, 0, 0, 0, 0, 0, 0,
  63. 0, 0, 0, 0, 0, 0, 0, 0,
  64. 0, 0, 0, 0, 0, 0, 0, 0
  65. };
  66. /* --------------------------- FIR ------------------------------------- */
  67. /* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */
  68. static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
  69. 0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
  70. -40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
  71. -31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
  72. -5, -2
  73. };
  74. static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
  75. 511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
  76. 405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
  77. 213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
  78. 28, 13
  79. };
  80. static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
  81. 0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
  82. 172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
  83. 370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
  84. 501, 507,
  85. };
  86. static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
  87. 0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
  88. -26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
  89. -41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
  90. -13, -7
  91. };
  92. /* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */
  93. static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
  94. 104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
  95. 38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
  96. 2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
  97. -8, -8
  98. };
  99. static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
  100. 303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
  101. 276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
  102. 206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
  103. 120, 112
  104. };
  105. static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
  106. 112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
  107. 197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
  108. 270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
  109. 303, 303
  110. };
  111. static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
  112. -8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
  113. 0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
  114. 33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
  115. 96, 104
  116. };
  117. /* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */
  118. static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
  119. 136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
  120. 95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
  121. 59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
  122. 32, 29
  123. };
  124. static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
  125. 206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
  126. 191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
  127. 170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
  128. 142, 140
  129. };
  130. static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
  131. 140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
  132. 168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
  133. 191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
  134. 205, 206
  135. };
  136. static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
  137. 29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
  138. 57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
  139. 91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
  140. 132, 136
  141. };
  142. /* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */
  143. static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
  144. 131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
  145. 124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
  146. 116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
  147. 108, 107
  148. };
  149. static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
  150. 141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
  151. 137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
  152. 135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
  153. 132, 132
  154. };
  155. static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
  156. 132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
  157. 135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
  158. 137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
  159. 140, 141
  160. };
  161. static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
  162. 107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
  163. 115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
  164. 123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
  165. 131, 131
  166. };
  167. static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
  168. int16 *c2, int16 *c3)
  169. {
  170. int i, val;
  171. for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
  172. val =
  173. ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
  174. (MDP_SCALE_COEFF_MASK & c0[i]);
  175. writel(val, MDP_PPP_SCALE_COEFF_LSBn(index));
  176. val =
  177. ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
  178. (MDP_SCALE_COEFF_MASK & c2[i]);
  179. writel(val, MDP_PPP_SCALE_COEFF_MSBn(index));
  180. index++;
  181. }
  182. }
  183. void mdp_init_scale_table(void)
  184. {
  185. mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
  186. mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
  187. mdp_scale_0p2_to_0p4_C0,
  188. mdp_scale_0p2_to_0p4_C1,
  189. mdp_scale_0p2_to_0p4_C2,
  190. mdp_scale_0p2_to_0p4_C3);
  191. mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
  192. mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
  193. mdp_scale_0p4_to_0p6_C0,
  194. mdp_scale_0p4_to_0p6_C1,
  195. mdp_scale_0p4_to_0p6_C2,
  196. mdp_scale_0p4_to_0p6_C3);
  197. mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
  198. mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
  199. mdp_scale_0p6_to_0p8_C0,
  200. mdp_scale_0p6_to_0p8_C1,
  201. mdp_scale_0p6_to_0p8_C2,
  202. mdp_scale_0p6_to_0p8_C3);
  203. mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
  204. mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
  205. mdp_scale_0p8_to_8p0_C0,
  206. mdp_scale_0p8_to_8p0_C1,
  207. mdp_scale_0p8_to_8p0_C2,
  208. mdp_scale_0p8_to_8p0_C3);
  209. }
  210. static long long mdp_do_div(long long num, long long den)
  211. {
  212. do_div(num, den);
  213. return num;
  214. }
  215. #define SCALER_PHASE_BITS 29
  216. #define HAL_MDP_PHASE_STEP_2P50 0x50000000
  217. #define HAL_MDP_PHASE_STEP_1P66 0x35555555
  218. #define HAL_MDP_PHASE_STEP_1P25 0x28000000
  219. struct phase_val {
  220. int phase_init_x;
  221. int phase_init_y;
  222. int phase_step_x;
  223. int phase_step_y;
  224. };
  225. static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
  226. uint32 in_h,
  227. uint32 out_w,
  228. uint32 out_h,
  229. boolean is_rotate,
  230. boolean is_pp_x,
  231. boolean is_pp_y, struct phase_val *pval)
  232. {
  233. uint64 dst_ROI_width;
  234. uint64 dst_ROI_height;
  235. uint64 src_ROI_width;
  236. uint64 src_ROI_height;
  237. /*
  238. * phase_step_x, phase_step_y, phase_init_x and phase_init_y
  239. * are represented in fixed-point, unsigned 3.29 format
  240. */
  241. uint32 phase_step_x = 0;
  242. uint32 phase_step_y = 0;
  243. uint32 phase_init_x = 0;
  244. uint32 phase_init_y = 0;
  245. uint32 yscale_filter_sel, xscale_filter_sel;
  246. uint32 scale_unit_sel_x, scale_unit_sel_y;
  247. uint64 numerator, denominator;
  248. uint64 temp_dim;
  249. src_ROI_width = in_w;
  250. src_ROI_height = in_h;
  251. dst_ROI_width = out_w;
  252. dst_ROI_height = out_h;
  253. /* if there is a 90 degree rotation */
  254. if (is_rotate) {
  255. /* decide whether to use FIR or M/N for scaling */
  256. /* if down-scaling by a factor smaller than 1/4 */
  257. if ((dst_ROI_height == 1 && src_ROI_width < 4) ||
  258. (src_ROI_width < 4 * dst_ROI_height - 3))
  259. scale_unit_sel_x = 0;/* use FIR scalar */
  260. else
  261. scale_unit_sel_x = 1;/* use M/N scalar */
  262. /* if down-scaling by a factor smaller than 1/4 */
  263. if ((dst_ROI_width == 1 && src_ROI_height < 4) ||
  264. (src_ROI_height < 4 * dst_ROI_width - 3))
  265. scale_unit_sel_y = 0;/* use FIR scalar */
  266. else
  267. scale_unit_sel_y = 1;/* use M/N scalar */
  268. } else {
  269. /* decide whether to use FIR or M/N for scaling */
  270. if ((dst_ROI_width == 1 && src_ROI_width < 4) ||
  271. (src_ROI_width < 4 * dst_ROI_width - 3))
  272. scale_unit_sel_x = 0;/* use FIR scalar */
  273. else
  274. scale_unit_sel_x = 1;/* use M/N scalar */
  275. if ((dst_ROI_height == 1 && src_ROI_height < 4) ||
  276. (src_ROI_height < 4 * dst_ROI_height - 3))
  277. scale_unit_sel_y = 0;/* use FIR scalar */
  278. else
  279. scale_unit_sel_y = 1;/* use M/N scalar */
  280. }
  281. /* if there is a 90 degree rotation */
  282. if (is_rotate) {
  283. /* swap the width and height of dst ROI */
  284. temp_dim = dst_ROI_width;
  285. dst_ROI_width = dst_ROI_height;
  286. dst_ROI_height = temp_dim;
  287. }
  288. /* calculate phase step for the x direction */
  289. /* if destination is only 1 pixel wide, the value of phase_step_x
  290. is unimportant. Assigning phase_step_x to src ROI width
  291. as an arbitrary value. */
  292. if (dst_ROI_width == 1)
  293. phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);
  294. /* if using FIR scalar */
  295. else if (scale_unit_sel_x == 0) {
  296. /* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
  297. with u3.29 precision. Quotient is rounded up to the larger
  298. 29th decimal point. */
  299. numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
  300. denominator = (dst_ROI_width - 1); /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
  301. phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* divide and round up to the larger 29th decimal point. */
  302. }
  303. /* if M/N scalar */
  304. else if (scale_unit_sel_x == 1) {
  305. /* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
  306. with u3.29 precision. Quotient is rounded down to the
  307. smaller 29th decimal point. */
  308. numerator = (src_ROI_width) << SCALER_PHASE_BITS;
  309. denominator = (dst_ROI_width);
  310. phase_step_x = (uint32) mdp_do_div(numerator, denominator);
  311. }
  312. /* calculate phase step for the y direction */
  313. /* if destination is only 1 pixel wide, the value of
  314. phase_step_x is unimportant. Assigning phase_step_x
  315. to src ROI width as an arbitrary value. */
  316. if (dst_ROI_height == 1)
  317. phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);
  318. /* if FIR scalar */
  319. else if (scale_unit_sel_y == 0) {
  320. /* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
  321. with u3.29 precision. Quotient is rounded up to the larger
  322. 29th decimal point. */
  323. numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
  324. denominator = (dst_ROI_height - 1); /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
  325. phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* Quotient is rounded up to the larger 29th decimal point. */
  326. }
  327. /* if M/N scalar */
  328. else if (scale_unit_sel_y == 1) {
  329. /* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
  330. with u3.29 precision. Quotient is rounded down to the smaller
  331. 29th decimal point. */
  332. numerator = (src_ROI_height) << SCALER_PHASE_BITS;
  333. denominator = (dst_ROI_height);
  334. phase_step_y = (uint32) mdp_do_div(numerator, denominator);
  335. }
  336. /* decide which set of FIR coefficients to use */
  337. if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
  338. xscale_filter_sel = 0;
  339. else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
  340. xscale_filter_sel = 1;
  341. else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
  342. xscale_filter_sel = 2;
  343. else
  344. xscale_filter_sel = 3;
  345. if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
  346. yscale_filter_sel = 0;
  347. else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
  348. yscale_filter_sel = 1;
  349. else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
  350. yscale_filter_sel = 2;
  351. else
  352. yscale_filter_sel = 3;
  353. /* calculate phase init for the x direction */
  354. /* if using FIR scalar */
  355. if (scale_unit_sel_x == 0) {
  356. if (dst_ROI_width == 1)
  357. phase_init_x =
  358. (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
  359. else
  360. phase_init_x = 0;
  361. }
  362. /* M over N scalar */
  363. else if (scale_unit_sel_x == 1)
  364. phase_init_x = 0;
  365. /* calculate phase init for the y direction
  366. if using FIR scalar */
  367. if (scale_unit_sel_y == 0) {
  368. if (dst_ROI_height == 1)
  369. phase_init_y =
  370. (uint32) ((src_ROI_height -
  371. 1) << SCALER_PHASE_BITS);
  372. else
  373. phase_init_y = 0;
  374. }
  375. /* M over N scalar */
  376. else if (scale_unit_sel_y == 1)
  377. phase_init_y = 0;
  378. /* write registers */
  379. pval->phase_step_x = (uint32) phase_step_x;
  380. pval->phase_step_y = (uint32) phase_step_y;
  381. pval->phase_init_x = (uint32) phase_init_x;
  382. pval->phase_init_y = (uint32) phase_init_y;
  383. return;
  384. }
  385. void mdp_set_scale(MDPIBUF *iBuf,
  386. uint32 dst_roi_width,
  387. uint32 dst_roi_height,
  388. boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
  389. {
  390. uint32 dst_roi_width_scale;
  391. uint32 dst_roi_height_scale;
  392. struct phase_val pval;
  393. boolean use_pr;
  394. uint32 ppp_scale_config = 0;
  395. if (!inputRGB)
  396. ppp_scale_config |= BIT(6);
  397. if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
  398. if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
  399. dst_roi_width_scale = dst_roi_height;
  400. dst_roi_height_scale = dst_roi_width;
  401. } else {
  402. dst_roi_width_scale = dst_roi_width;
  403. dst_roi_height_scale = dst_roi_height;
  404. }
  405. if ((dst_roi_width_scale != iBuf->roi.width) ||
  406. (dst_roi_height_scale != iBuf->roi.height) ||
  407. (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
  408. *pppop_reg_ptr |=
  409. (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
  410. mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
  411. iBuf->roi.height,
  412. dst_roi_width,
  413. dst_roi_height,
  414. iBuf->mdpImg.
  415. mdpOp & MDPOP_ROT90, 1, 1,
  416. &pval);
  417. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
  418. pval.phase_init_x);
  419. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
  420. pval.phase_init_y);
  421. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
  422. pval.phase_step_x);
  423. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
  424. pval.phase_step_y);
  425. /* disable the pixel repeat option for scaling */
  426. use_pr = false;
  427. /* x-direction */
  428. if ((dst_roi_width_scale == iBuf->roi.width) &&
  429. !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
  430. *pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
  431. } else
  432. if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
  433. 8) {
  434. if ((use_pr)
  435. && (mdp_scale_0p8_to_8p0_mode !=
  436. MDP_SCALE_PR)) {
  437. mdp_scale_0p8_to_8p0_mode =
  438. MDP_SCALE_PR;
  439. mdp_update_scale_table
  440. (MDP_SCALE_0P8_TO_8P0_INDEX,
  441. mdp_scale_pixel_repeat_C0,
  442. mdp_scale_pixel_repeat_C1,
  443. mdp_scale_pixel_repeat_C2,
  444. mdp_scale_pixel_repeat_C3);
  445. } else if ((!use_pr)
  446. && (mdp_scale_0p8_to_8p0_mode !=
  447. MDP_SCALE_FIR)) {
  448. mdp_scale_0p8_to_8p0_mode =
  449. MDP_SCALE_FIR;
  450. mdp_update_scale_table
  451. (MDP_SCALE_0P8_TO_8P0_INDEX,
  452. mdp_scale_0p8_to_8p0_C0,
  453. mdp_scale_0p8_to_8p0_C1,
  454. mdp_scale_0p8_to_8p0_C2,
  455. mdp_scale_0p8_to_8p0_C3);
  456. }
  457. ppp_scale_config |= (SCALE_U1_SET << 2);
  458. } else
  459. if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
  460. 6) {
  461. if ((use_pr)
  462. && (mdp_scale_0p6_to_0p8_mode !=
  463. MDP_SCALE_PR)) {
  464. mdp_scale_0p6_to_0p8_mode =
  465. MDP_SCALE_PR;
  466. mdp_update_scale_table
  467. (MDP_SCALE_0P6_TO_0P8_INDEX,
  468. mdp_scale_pixel_repeat_C0,
  469. mdp_scale_pixel_repeat_C1,
  470. mdp_scale_pixel_repeat_C2,
  471. mdp_scale_pixel_repeat_C3);
  472. } else if ((!use_pr)
  473. && (mdp_scale_0p6_to_0p8_mode !=
  474. MDP_SCALE_FIR)) {
  475. mdp_scale_0p6_to_0p8_mode =
  476. MDP_SCALE_FIR;
  477. mdp_update_scale_table
  478. (MDP_SCALE_0P6_TO_0P8_INDEX,
  479. mdp_scale_0p6_to_0p8_C0,
  480. mdp_scale_0p6_to_0p8_C1,
  481. mdp_scale_0p6_to_0p8_C2,
  482. mdp_scale_0p6_to_0p8_C3);
  483. }
  484. ppp_scale_config |= (SCALE_D2_SET << 2);
  485. } else
  486. if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
  487. 4) {
  488. if ((use_pr)
  489. && (mdp_scale_0p4_to_0p6_mode !=
  490. MDP_SCALE_PR)) {
  491. mdp_scale_0p4_to_0p6_mode =
  492. MDP_SCALE_PR;
  493. mdp_update_scale_table
  494. (MDP_SCALE_0P4_TO_0P6_INDEX,
  495. mdp_scale_pixel_repeat_C0,
  496. mdp_scale_pixel_repeat_C1,
  497. mdp_scale_pixel_repeat_C2,
  498. mdp_scale_pixel_repeat_C3);
  499. } else if ((!use_pr)
  500. && (mdp_scale_0p4_to_0p6_mode !=
  501. MDP_SCALE_FIR)) {
  502. mdp_scale_0p4_to_0p6_mode =
  503. MDP_SCALE_FIR;
  504. mdp_update_scale_table
  505. (MDP_SCALE_0P4_TO_0P6_INDEX,
  506. mdp_scale_0p4_to_0p6_C0,
  507. mdp_scale_0p4_to_0p6_C1,
  508. mdp_scale_0p4_to_0p6_C2,
  509. mdp_scale_0p4_to_0p6_C3);
  510. }
  511. ppp_scale_config |= (SCALE_D1_SET << 2);
  512. } else
  513. if ((dst_roi_width_scale == 1 && iBuf->roi.width < 4) ||
  514. (iBuf->roi.width < 4 * dst_roi_width_scale - 3)) {
  515. if ((use_pr)
  516. && (mdp_scale_0p2_to_0p4_mode !=
  517. MDP_SCALE_PR)) {
  518. mdp_scale_0p2_to_0p4_mode =
  519. MDP_SCALE_PR;
  520. mdp_update_scale_table
  521. (MDP_SCALE_0P2_TO_0P4_INDEX,
  522. mdp_scale_pixel_repeat_C0,
  523. mdp_scale_pixel_repeat_C1,
  524. mdp_scale_pixel_repeat_C2,
  525. mdp_scale_pixel_repeat_C3);
  526. } else if ((!use_pr)
  527. && (mdp_scale_0p2_to_0p4_mode !=
  528. MDP_SCALE_FIR)) {
  529. mdp_scale_0p2_to_0p4_mode =
  530. MDP_SCALE_FIR;
  531. mdp_update_scale_table
  532. (MDP_SCALE_0P2_TO_0P4_INDEX,
  533. mdp_scale_0p2_to_0p4_C0,
  534. mdp_scale_0p2_to_0p4_C1,
  535. mdp_scale_0p2_to_0p4_C2,
  536. mdp_scale_0p2_to_0p4_C3);
  537. }
  538. ppp_scale_config |= (SCALE_D0_SET << 2);
  539. } else
  540. ppp_scale_config |= BIT(0);
  541. /* y-direction */
  542. if ((dst_roi_height_scale == iBuf->roi.height) &&
  543. !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
  544. *pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
  545. } else if (((dst_roi_height_scale * 10) /
  546. iBuf->roi.height) > 8) {
  547. if ((use_pr)
  548. && (mdp_scale_0p8_to_8p0_mode !=
  549. MDP_SCALE_PR)) {
  550. mdp_scale_0p8_to_8p0_mode =
  551. MDP_SCALE_PR;
  552. mdp_update_scale_table
  553. (MDP_SCALE_0P8_TO_8P0_INDEX,
  554. mdp_scale_pixel_repeat_C0,
  555. mdp_scale_pixel_repeat_C1,
  556. mdp_scale_pixel_repeat_C2,
  557. mdp_scale_pixel_repeat_C3);
  558. } else if ((!use_pr)
  559. && (mdp_scale_0p8_to_8p0_mode !=
  560. MDP_SCALE_FIR)) {
  561. mdp_scale_0p8_to_8p0_mode =
  562. MDP_SCALE_FIR;
  563. mdp_update_scale_table
  564. (MDP_SCALE_0P8_TO_8P0_INDEX,
  565. mdp_scale_0p8_to_8p0_C0,
  566. mdp_scale_0p8_to_8p0_C1,
  567. mdp_scale_0p8_to_8p0_C2,
  568. mdp_scale_0p8_to_8p0_C3);
  569. }
  570. ppp_scale_config |= (SCALE_U1_SET << 4);
  571. } else
  572. if (((dst_roi_height_scale * 10) /
  573. iBuf->roi.height) > 6) {
  574. if ((use_pr)
  575. && (mdp_scale_0p6_to_0p8_mode !=
  576. MDP_SCALE_PR)) {
  577. mdp_scale_0p6_to_0p8_mode =
  578. MDP_SCALE_PR;
  579. mdp_update_scale_table
  580. (MDP_SCALE_0P6_TO_0P8_INDEX,
  581. mdp_scale_pixel_repeat_C0,
  582. mdp_scale_pixel_repeat_C1,
  583. mdp_scale_pixel_repeat_C2,
  584. mdp_scale_pixel_repeat_C3);
  585. } else if ((!use_pr)
  586. && (mdp_scale_0p6_to_0p8_mode !=
  587. MDP_SCALE_FIR)) {
  588. mdp_scale_0p6_to_0p8_mode =
  589. MDP_SCALE_FIR;
  590. mdp_update_scale_table
  591. (MDP_SCALE_0P6_TO_0P8_INDEX,
  592. mdp_scale_0p6_to_0p8_C0,
  593. mdp_scale_0p6_to_0p8_C1,
  594. mdp_scale_0p6_to_0p8_C2,
  595. mdp_scale_0p6_to_0p8_C3);
  596. }
  597. ppp_scale_config |= (SCALE_D2_SET << 4);
  598. } else
  599. if (((dst_roi_height_scale * 10) /
  600. iBuf->roi.height) > 4) {
  601. if ((use_pr)
  602. && (mdp_scale_0p4_to_0p6_mode !=
  603. MDP_SCALE_PR)) {
  604. mdp_scale_0p4_to_0p6_mode =
  605. MDP_SCALE_PR;
  606. mdp_update_scale_table
  607. (MDP_SCALE_0P4_TO_0P6_INDEX,
  608. mdp_scale_pixel_repeat_C0,
  609. mdp_scale_pixel_repeat_C1,
  610. mdp_scale_pixel_repeat_C2,
  611. mdp_scale_pixel_repeat_C3);
  612. } else if ((!use_pr)
  613. && (mdp_scale_0p4_to_0p6_mode !=
  614. MDP_SCALE_FIR)) {
  615. mdp_scale_0p4_to_0p6_mode =
  616. MDP_SCALE_FIR;
  617. mdp_update_scale_table
  618. (MDP_SCALE_0P4_TO_0P6_INDEX,
  619. mdp_scale_0p4_to_0p6_C0,
  620. mdp_scale_0p4_to_0p6_C1,
  621. mdp_scale_0p4_to_0p6_C2,
  622. mdp_scale_0p4_to_0p6_C3);
  623. }
  624. ppp_scale_config |= (SCALE_D1_SET << 4);
  625. } else if ((dst_roi_height_scale == 1 &&
  626. iBuf->roi.height < 4) ||
  627. (iBuf->roi.height < 4 * dst_roi_height_scale - 3)) {
  628. if ((use_pr)
  629. && (mdp_scale_0p2_to_0p4_mode !=
  630. MDP_SCALE_PR)) {
  631. mdp_scale_0p2_to_0p4_mode =
  632. MDP_SCALE_PR;
  633. mdp_update_scale_table
  634. (MDP_SCALE_0P2_TO_0P4_INDEX,
  635. mdp_scale_pixel_repeat_C0,
  636. mdp_scale_pixel_repeat_C1,
  637. mdp_scale_pixel_repeat_C2,
  638. mdp_scale_pixel_repeat_C3);
  639. } else if ((!use_pr)
  640. && (mdp_scale_0p2_to_0p4_mode !=
  641. MDP_SCALE_FIR)) {
  642. mdp_scale_0p2_to_0p4_mode =
  643. MDP_SCALE_FIR;
  644. mdp_update_scale_table
  645. (MDP_SCALE_0P2_TO_0P4_INDEX,
  646. mdp_scale_0p2_to_0p4_C0,
  647. mdp_scale_0p2_to_0p4_C1,
  648. mdp_scale_0p2_to_0p4_C2,
  649. mdp_scale_0p2_to_0p4_C3);
  650. }
  651. ppp_scale_config |= (SCALE_D0_SET << 4);
  652. } else
  653. ppp_scale_config |= BIT(1);
  654. if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
  655. ppp_scale_config |= BIT(7);
  656. MDP_OUTP(MDP_BASE + 0x50020,
  657. iBuf->mdpImg.sp_value);
  658. }
  659. MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
  660. } else {
  661. iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
  662. }
  663. }
  664. }
  665. void mdp_adjust_start_addr(uint8 **src0,
  666. uint8 **src1,
  667. int v_slice,
  668. int h_slice,
  669. int x,
  670. int y,
  671. uint32 width,
  672. uint32 height, int bpp, MDPIBUF *iBuf, int layer)
  673. {
  674. switch (layer) {
  675. case 0:
  676. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
  677. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
  678. (height << 16) | (width));
  679. break;
  680. case 1:
  681. /* MDP 3.1 HW bug workaround */
  682. if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
  683. *src0 += (x + y * width) * bpp;
  684. x = y = 0;
  685. width = iBuf->roi.dst_width;
  686. height = iBuf->roi.dst_height;
  687. }
  688. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
  689. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
  690. (height << 16) | (width));
  691. break;
  692. case 2:
  693. MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
  694. break;
  695. }
  696. }
  697. void mdp_set_blend_attr(MDPIBUF *iBuf,
  698. uint32 *alpha,
  699. uint32 *tpVal,
  700. uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
  701. {
  702. int bg_alpha;
  703. *alpha = iBuf->mdpImg.alpha;
  704. *tpVal = iBuf->mdpImg.tpVal;
  705. if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
  706. if (perPixelAlpha) {
  707. *pppop_reg_ptr |= PPP_OP_ROT_ON |
  708. PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
  709. }
  710. else {
  711. if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
  712. && (iBuf->mdpImg.alpha == 0xff)) {
  713. iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
  714. }
  715. if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
  716. || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
  717. *pppop_reg_ptr |=
  718. PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
  719. PPP_OP_BLEND_CONSTANT_ALPHA |
  720. PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
  721. }
  722. }
  723. bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
  724. PPP_BLEND_BG_ALPHA_REVERSE;
  725. if (perPixelAlpha)
  726. bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
  727. else {
  728. bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
  729. bg_alpha |= iBuf->mdpImg.alpha << 24;
  730. }
  731. outpdw(MDP_BASE + 0x70010, bg_alpha);
  732. if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
  733. *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
  734. } else if (perPixelAlpha) {
  735. *pppop_reg_ptr |= PPP_OP_ROT_ON |
  736. PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
  737. } else {
  738. if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
  739. && (iBuf->mdpImg.alpha == 0xff)) {
  740. iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
  741. }
  742. if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
  743. || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
  744. *pppop_reg_ptr |=
  745. PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
  746. PPP_OP_BLEND_CONSTANT_ALPHA |
  747. PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
  748. }
  749. if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
  750. *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
  751. }
  752. }