ddp_ovl.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #define LOG_TAG "OVL"
  32. #include "platform/ddp_reg.h"
  33. #include "platform/ddp_matrix_para.h"
  34. #include "platform/ddp_info.h"
  35. #include "platform/ddp_log.h"
  36. #include "platform/ddp_ovl.h"
  37. #include "platform/disp_drv_platform.h"
  38. #define OVL_NUM (2)
  39. #define OVL_REG_BACK_MAX (40)
  40. #define OVL_LAYER_OFFSET (0x20)
  41. #define OVL_RDMA_DEBUG_OFFSET (0x4)
  42. enum OVL_COLOR_SPACE {
  43. OVL_COLOR_SPACE_RGB = 0,
  44. OVL_COLOR_SPACE_YUV,
  45. };
  46. enum OVL_INPUT_FORMAT {
  47. OVL_INPUT_FORMAT_BGR565 = 0,
  48. OVL_INPUT_FORMAT_RGB888 = 1,
  49. OVL_INPUT_FORMAT_RGBA8888 = 2,
  50. OVL_INPUT_FORMAT_ARGB8888 = 3,
  51. OVL_INPUT_FORMAT_VYUY = 4,
  52. OVL_INPUT_FORMAT_YVYU = 5,
  53. OVL_INPUT_FORMAT_RGB565 = 6,
  54. OVL_INPUT_FORMAT_BGR888 = 7,
  55. OVL_INPUT_FORMAT_BGRA8888 = 8,
  56. OVL_INPUT_FORMAT_ABGR8888 = 9,
  57. OVL_INPUT_FORMAT_UYVY = 10,
  58. OVL_INPUT_FORMAT_YUYV = 11,
  59. OVL_INPUT_FORMAT_RGBA4444 = 12,
  60. OVL_INPUT_FORMAT_BGRA4444 = 13,
  61. OVL_INPUT_FORMAT_UNKNOWN = 32,
  62. };
  63. typedef struct {
  64. unsigned int address;
  65. unsigned int value;
  66. } OVL_REG;
  67. static int reg_back_cnt[OVL_NUM];
  68. static OVL_REG reg_back[OVL_NUM][OVL_REG_BACK_MAX];
  69. static enum OVL_INPUT_FORMAT ovl_input_fmt_convert(DpColorFormat fmt);
  70. static unsigned int ovl_input_fmt_byte_swap(enum OVL_INPUT_FORMAT inputFormat);
  71. static unsigned int ovl_input_fmt_bpp(enum OVL_INPUT_FORMAT inputFormat);
  72. static enum OVL_COLOR_SPACE ovl_input_fmt_color_space(enum OVL_INPUT_FORMAT inputFormat);
  73. static unsigned int ovl_input_fmt_reg_value(enum OVL_INPUT_FORMAT inputFormat);
  74. static void ovl_store_regs(int idx);
  75. static void ovl_restore_regs(int idx,void * handle);
  76. static enum OVL_INPUT_FORMAT ovl_input_fmt_convert(DpColorFormat fmt)
  77. {
  78. enum OVL_INPUT_FORMAT ovl_fmt = OVL_INPUT_FORMAT_UNKNOWN;
  79. switch (fmt) {
  80. case eBGR565:
  81. ovl_fmt = OVL_INPUT_FORMAT_BGR565;
  82. break;
  83. case eRGB565:
  84. ovl_fmt = OVL_INPUT_FORMAT_RGB565;
  85. break;
  86. case eRGB888:
  87. ovl_fmt = OVL_INPUT_FORMAT_RGB888;
  88. break;
  89. case eBGR888:
  90. ovl_fmt = OVL_INPUT_FORMAT_BGR888;
  91. break;
  92. case eRGBA4444:
  93. ovl_fmt = OVL_INPUT_FORMAT_RGBA4444;
  94. break;
  95. case eBGRA4444:
  96. ovl_fmt = OVL_INPUT_FORMAT_BGRA4444;
  97. break;
  98. case eRGBA8888:
  99. ovl_fmt = OVL_INPUT_FORMAT_RGBA8888;
  100. break;
  101. case eBGRA8888:
  102. ovl_fmt = OVL_INPUT_FORMAT_BGRA8888;
  103. break;
  104. case eARGB8888:
  105. ovl_fmt = OVL_INPUT_FORMAT_ARGB8888;
  106. break;
  107. case eABGR8888:
  108. ovl_fmt = OVL_INPUT_FORMAT_ABGR8888;
  109. break;
  110. case eVYUY:
  111. ovl_fmt = OVL_INPUT_FORMAT_VYUY;
  112. break;
  113. case eYVYU:
  114. ovl_fmt = OVL_INPUT_FORMAT_YVYU;
  115. break;
  116. case eUYVY:
  117. ovl_fmt = OVL_INPUT_FORMAT_UYVY;
  118. break;
  119. case eYUY2:
  120. ovl_fmt = OVL_INPUT_FORMAT_YUYV;
  121. break;
  122. default:
  123. DDPERR("ovl_fmt_convert fmt=%d, ovl_fmt=%d\n", fmt, ovl_fmt);
  124. break;
  125. }
  126. return ovl_fmt;
  127. }
  128. static DpColorFormat ovl_input_fmt(enum OVL_INPUT_FORMAT fmt, int swap)
  129. {
  130. switch (fmt) {
  131. case OVL_INPUT_FORMAT_BGR565:
  132. return swap ? eBGR565 : eRGB565;
  133. case OVL_INPUT_FORMAT_RGB888:
  134. return swap ? eRGB888 : eBGR888;
  135. case OVL_INPUT_FORMAT_RGBA8888:
  136. return swap ? eRGBA8888 : eBGRA8888;
  137. case OVL_INPUT_FORMAT_ARGB8888:
  138. return swap ? eARGB8888 : eABGR8888;
  139. case OVL_INPUT_FORMAT_VYUY:
  140. return swap ? eVYUY : eUYVY;
  141. case OVL_INPUT_FORMAT_YVYU:
  142. return swap ? eYVYU : eYUY2;
  143. case OVL_INPUT_FORMAT_RGBA4444:
  144. return swap ? eRGBA4444 : eBGRA4444;
  145. default:
  146. DDPERR("ovl_input_fmt fmt=%d, swap=%d\n", fmt, swap);
  147. break;
  148. }
  149. return eRGB888;
  150. }
  151. static char *ovl_intput_format_name(enum OVL_INPUT_FORMAT fmt, int swap)
  152. {
  153. switch (fmt) {
  154. case OVL_INPUT_FORMAT_BGR565:
  155. return swap ? "eBGR565" : "eRGB565";
  156. case OVL_INPUT_FORMAT_RGB565:
  157. return "eRGB565";
  158. case OVL_INPUT_FORMAT_RGB888:
  159. return swap ? "eRGB888" : "eBGR888";
  160. case OVL_INPUT_FORMAT_BGR888:
  161. return "eBGR888";
  162. case OVL_INPUT_FORMAT_RGBA8888:
  163. return swap ? "eRGBA8888" : "eBGRA8888";
  164. case OVL_INPUT_FORMAT_BGRA8888:
  165. return "eBGRA8888";
  166. case OVL_INPUT_FORMAT_ARGB8888:
  167. return swap ? "eARGB8888" : "eABGR8888";
  168. case OVL_INPUT_FORMAT_ABGR8888:
  169. return "eABGR8888";
  170. case OVL_INPUT_FORMAT_VYUY:
  171. return swap ? "eVYUY" : "eUYVY";
  172. case OVL_INPUT_FORMAT_UYVY:
  173. return "eUYVY";
  174. case OVL_INPUT_FORMAT_YVYU:
  175. return swap ? "eYVYU" : "eYUY2";
  176. case OVL_INPUT_FORMAT_YUYV:
  177. return "eYUY2";
  178. case OVL_INPUT_FORMAT_RGBA4444:
  179. return swap ? "eRGBA4444" : "eBGRA4444";
  180. default:
  181. DDPERR("ovl_intput_fmt unknow fmt=%d, swap=%d\n", fmt, swap);
  182. break;
  183. }
  184. return "unknow";
  185. }
  186. static unsigned int ovl_index(DISP_MODULE_ENUM module)
  187. {
  188. int idx = 0;
  189. switch (module) {
  190. case DISP_MODULE_OVL0:
  191. idx = 0;
  192. break;
  193. case DISP_MODULE_OVL0_2L:
  194. idx = 1;
  195. break;
  196. default:
  197. DDPERR("invalid module=%d \n", module);// invalid module
  198. ASSERT(0);
  199. }
  200. return idx;
  201. }
  202. int OVLStart(DISP_MODULE_ENUM module, void *handle)
  203. {
  204. int idx = ovl_index(module);
  205. /* bypass shadow */
  206. #ifdef LK_BYPASS_SHADOW_REG
  207. DISP_REG_SET_FIELD(handle, EN_FLD_BYPASS_SHADOW,
  208. idx*DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x1);
  209. DISP_REG_SET_FIELD(handle, EN_FLD_RD_WRK_REG,
  210. idx*DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x1);
  211. #endif
  212. DISP_REG_SET_FIELD(handle, EN_FLD_OVL_EN,
  213. idx*DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x1);
  214. DISP_REG_SET(handle, idx*DISP_INDEX_OFFSET + DISP_REG_OVL_INTEN,
  215. 0x1E | REG_FLD_VAL(INTEN_FLD_ABNORMAL_SOF, 1));
  216. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_LAYER_SMI_ID_EN,
  217. idx*DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 0x1);
  218. return 0;
  219. }
  220. int OVLStop(DISP_MODULE_ENUM module, void *handle)
  221. {
  222. int idx = ovl_index(module);
  223. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTEN, 0x00);
  224. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_EN, 0x00);
  225. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTSTA, 0x00);
  226. return 0;
  227. }
  228. int OVLReset(DISP_MODULE_ENUM module, void *handle)
  229. {
  230. #define OVL_IDLE (0x3)
  231. unsigned int delay_cnt = 0;
  232. int idx = ovl_index(module);
  233. /*always use cpu do reset*/
  234. DISP_CPU_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_RST, 0x1); // soft reset
  235. DISP_CPU_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_RST, 0x0);
  236. while (!(DISP_REG_GET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_FLOW_CTRL_DBG) & OVL_IDLE)) {
  237. delay_cnt++;
  238. udelay(10);
  239. if (delay_cnt>2000) {
  240. DDPERR("OVL%dReset() timeout! \n",idx);
  241. break;
  242. }
  243. }
  244. return 0;
  245. }
  246. int OVLROI(DISP_MODULE_ENUM module,
  247. unsigned int bgW,
  248. unsigned int bgH,
  249. unsigned int bgColor,
  250. void * handle)
  251. {
  252. int idx = ovl_index(module);
  253. if ((bgW > OVL_MAX_WIDTH) || (bgH > OVL_MAX_HEIGHT)) {
  254. DDPERR("OVLROI(), exceed OVL max size, w=%d, h=%d \n", bgW, bgH);
  255. ASSERT(0);
  256. }
  257. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_ROI_SIZE, bgH<<16 | bgW);
  258. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_ROI_BGCLR, bgColor);
  259. return 0;
  260. }
  261. int OVLLayerSwitch(DISP_MODULE_ENUM module,
  262. unsigned layer,
  263. unsigned int en,
  264. void * handle)
  265. {
  266. int idx = ovl_index(module);
  267. ASSERT(layer<=3);
  268. switch (layer) {
  269. case 0:
  270. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L0_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  271. break;
  272. case 1:
  273. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L1_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  274. break;
  275. case 2:
  276. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L2_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  277. break;
  278. case 3:
  279. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L3_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  280. break;
  281. default:
  282. DDPERR("invalid layer=%d\n", layer); // invalid layer
  283. ASSERT(0);
  284. }
  285. return 0;
  286. }
  287. int OVL3DConfig(DISP_MODULE_ENUM module,
  288. unsigned int layer_id,
  289. unsigned int en_3d,
  290. unsigned int landscape,
  291. unsigned int r_first,
  292. void *handle)
  293. {
  294. return 0;
  295. }
  296. void OVLLayerConfig(DISP_MODULE_ENUM module,
  297. unsigned int layer,
  298. unsigned int source,
  299. DpColorFormat format,
  300. unsigned int addr,
  301. unsigned int src_x, // ROI x offset
  302. unsigned int src_y, // ROI y offset
  303. unsigned int src_pitch,
  304. unsigned int dst_x, // ROI x offset
  305. unsigned int dst_y, // ROI y offset
  306. unsigned int dst_w, // ROT width
  307. unsigned int dst_h, // ROI height
  308. unsigned int keyEn,
  309. unsigned int key, // color key
  310. unsigned int aen, // alpha enable
  311. unsigned char alpha,
  312. void * handle)
  313. {
  314. int idx = ovl_index(module);
  315. unsigned int value = 0;
  316. enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format);
  317. unsigned int bpp = ovl_input_fmt_bpp(fmt);
  318. unsigned int input_swap = ovl_input_fmt_byte_swap(fmt);
  319. unsigned int input_fmt = ovl_input_fmt_reg_value(fmt);
  320. enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt);
  321. unsigned int offset = 0;
  322. /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB)*/
  323. int color_matrix = 0x4;
  324. unsigned int idx_offset = idx*DISP_INDEX_OFFSET;
  325. unsigned int layer_offset = idx_offset + layer * 0x20;
  326. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  327. unsigned int bg_h, bg_w;
  328. #endif
  329. ASSERT((dst_w <= OVL_MAX_WIDTH) &&
  330. (dst_h <= OVL_MAX_HEIGHT) &&
  331. (layer <= 3));
  332. if (addr == 0) {
  333. DDPERR("source from memory, but addr is 0!\n");
  334. ASSERT(0);
  335. }
  336. DDPDBG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d,"
  337. "fmt=%s, addr=%x, keyEn=%d, key=%d, aen=%d, alpha=%d \n",
  338. idx,
  339. layer,
  340. (source==0)?"memory":"constant_color",
  341. src_x,
  342. src_y,
  343. dst_x,
  344. dst_y,
  345. dst_w,
  346. dst_h,
  347. src_pitch,
  348. ovl_intput_format_name(fmt, input_swap),
  349. addr,
  350. keyEn,
  351. key,
  352. aen,
  353. alpha);
  354. if (source==OVL_LAYER_SOURCE_RESERVED) { //==1, means constant color
  355. if (aen==0) {
  356. DDPERR("dim layer ahpha enable should be 1!\n");
  357. }
  358. if (fmt!=OVL_INPUT_FORMAT_RGB565) {
  359. DDPERR("dim layer format should be RGB565");
  360. fmt = OVL_INPUT_FORMAT_RGB565;
  361. }
  362. }
  363. DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1);
  364. value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) |
  365. REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) |
  366. REG_FLD_VAL((L_CON_FLD_AEN), (aen)) |
  367. REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) |
  368. REG_FLD_VAL((L_CON_FLD_SKEN), (keyEn)) |
  369. REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap)));
  370. if (fmt == OVL_INPUT_FORMAT_RGBA4444)
  371. value |= REG_FLD_VAL((L_CON_FLD_CLRFMT_MAN), (1));
  372. if (space == OVL_COLOR_SPACE_YUV)
  373. value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix));
  374. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  375. value |= (REG_FLD_VAL((L_CON_FLD_VIRTICAL_FLIP), 1) |
  376. REG_FLD_VAL((L_CON_FLD_HORI_FLIP), 1));
  377. #endif
  378. DISP_REG_SET(handle, DISP_REG_OVL_L0_CON+layer_offset, value);
  379. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  380. bg_h = DISP_REG_GET(idx_offset + DISP_REG_OVL_ROI_SIZE);
  381. bg_w = bg_h & 0xFFFF;
  382. bg_h = bg_h >> 16;
  383. DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset,
  384. (bg_h-dst_h-dst_y)<<16 | (bg_w-dst_w-dst_x));
  385. offset = (src_x+dst_w+1)*bpp + (src_y+dst_h-1)*src_pitch - 1;
  386. #else
  387. DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset,
  388. dst_y<<16 | dst_x);
  389. offset = src_x*bpp+src_y*src_pitch;
  390. #endif
  391. DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR+layer_offset,
  392. addr+offset);
  393. DISP_REG_SET(handle, DISP_REG_OVL_L0_SRC_SIZE+layer_offset,
  394. dst_h<<16 | dst_w);
  395. DISP_REG_SET(handle, DISP_REG_OVL_L0_SRCKEY+layer_offset,
  396. key);
  397. value = (REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) |
  398. REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch)));
  399. if (fmt == OVL_INPUT_FORMAT_RGBA4444) {
  400. value |= REG_FLD_VAL(L_PITCH_FLD_SRGB_SEL, (1)) |
  401. REG_FLD_VAL(L_PITCH_FLD_DRGB_SEL, (2)) |
  402. REG_FLD_VAL(L_PITCH_FLD_SURFL_EN, (1)) |
  403. REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) |
  404. REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch));
  405. }
  406. DISP_REG_SET(handle, DISP_REG_OVL_L0_PITCH+layer_offset, value);
  407. //DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070);
  408. }
  409. static unsigned int ovl_input_fmt_byte_swap(enum OVL_INPUT_FORMAT inputFormat)
  410. {
  411. int input_swap = 0;
  412. switch (inputFormat) {
  413. case OVL_INPUT_FORMAT_BGR565:
  414. case OVL_INPUT_FORMAT_RGB888:
  415. case OVL_INPUT_FORMAT_RGBA8888:
  416. case OVL_INPUT_FORMAT_ARGB8888:
  417. case OVL_INPUT_FORMAT_BGRA4444:
  418. case OVL_INPUT_FORMAT_VYUY:
  419. case OVL_INPUT_FORMAT_YVYU:
  420. input_swap = 1;
  421. break;
  422. case OVL_INPUT_FORMAT_RGB565:
  423. case OVL_INPUT_FORMAT_BGR888:
  424. case OVL_INPUT_FORMAT_BGRA8888:
  425. case OVL_INPUT_FORMAT_ABGR8888:
  426. case OVL_INPUT_FORMAT_RGBA4444:
  427. case OVL_INPUT_FORMAT_UYVY:
  428. case OVL_INPUT_FORMAT_YUYV:
  429. input_swap = 0;
  430. break;
  431. default:
  432. DDPERR("unknow input ovl format is %d\n", inputFormat);
  433. ASSERT(0);
  434. }
  435. return input_swap;
  436. }
  437. static unsigned int ovl_input_fmt_bpp(enum OVL_INPUT_FORMAT inputFormat)
  438. {
  439. int bpp = 0;
  440. switch (inputFormat) {
  441. case OVL_INPUT_FORMAT_BGR565:
  442. case OVL_INPUT_FORMAT_RGB565:
  443. case OVL_INPUT_FORMAT_VYUY:
  444. case OVL_INPUT_FORMAT_UYVY:
  445. case OVL_INPUT_FORMAT_YVYU:
  446. case OVL_INPUT_FORMAT_YUYV:
  447. case OVL_INPUT_FORMAT_RGBA4444:
  448. case OVL_INPUT_FORMAT_BGRA4444:
  449. bpp = 2;
  450. break;
  451. case OVL_INPUT_FORMAT_RGB888:
  452. case OVL_INPUT_FORMAT_BGR888:
  453. bpp = 3;
  454. break;
  455. case OVL_INPUT_FORMAT_RGBA8888:
  456. case OVL_INPUT_FORMAT_BGRA8888:
  457. case OVL_INPUT_FORMAT_ARGB8888:
  458. case OVL_INPUT_FORMAT_ABGR8888:
  459. bpp = 4;
  460. break;
  461. default:
  462. DDPERR("unknown ovl input format = %d\n", inputFormat);
  463. ASSERT(0);
  464. }
  465. return bpp;
  466. }
  467. static enum OVL_COLOR_SPACE ovl_input_fmt_color_space(enum OVL_INPUT_FORMAT inputFormat)
  468. {
  469. enum OVL_COLOR_SPACE space = OVL_COLOR_SPACE_RGB;
  470. switch (inputFormat) {
  471. case OVL_INPUT_FORMAT_BGR565:
  472. case OVL_INPUT_FORMAT_RGB565:
  473. case OVL_INPUT_FORMAT_RGB888:
  474. case OVL_INPUT_FORMAT_BGR888:
  475. case OVL_INPUT_FORMAT_BGRA4444:
  476. case OVL_INPUT_FORMAT_RGBA4444:
  477. case OVL_INPUT_FORMAT_RGBA8888:
  478. case OVL_INPUT_FORMAT_BGRA8888:
  479. case OVL_INPUT_FORMAT_ARGB8888:
  480. case OVL_INPUT_FORMAT_ABGR8888:
  481. space = OVL_COLOR_SPACE_RGB;
  482. break;
  483. case OVL_INPUT_FORMAT_VYUY:
  484. case OVL_INPUT_FORMAT_UYVY:
  485. case OVL_INPUT_FORMAT_YVYU:
  486. case OVL_INPUT_FORMAT_YUYV:
  487. space = OVL_COLOR_SPACE_YUV;
  488. break;
  489. default:
  490. DDPERR("unknown ovl input format = %d\n", inputFormat);
  491. ASSERT(0);
  492. }
  493. return space;
  494. }
  495. static unsigned int ovl_input_fmt_reg_value(enum OVL_INPUT_FORMAT inputFormat)
  496. {
  497. int reg_value = 0;
  498. switch (inputFormat) {
  499. case OVL_INPUT_FORMAT_BGR565:
  500. case OVL_INPUT_FORMAT_RGB565:
  501. reg_value = 0x0;
  502. break;
  503. case OVL_INPUT_FORMAT_RGB888:
  504. case OVL_INPUT_FORMAT_BGR888:
  505. reg_value = 0x1;
  506. break;
  507. case OVL_INPUT_FORMAT_RGBA8888:
  508. case OVL_INPUT_FORMAT_BGRA8888:
  509. reg_value = 0x2;
  510. break;
  511. case OVL_INPUT_FORMAT_ARGB8888:
  512. case OVL_INPUT_FORMAT_ABGR8888:
  513. reg_value = 0x3;
  514. break;
  515. case OVL_INPUT_FORMAT_VYUY:
  516. case OVL_INPUT_FORMAT_UYVY:
  517. case OVL_INPUT_FORMAT_RGBA4444:
  518. case OVL_INPUT_FORMAT_BGRA4444:
  519. reg_value = 0x4;
  520. break;
  521. case OVL_INPUT_FORMAT_YVYU:
  522. case OVL_INPUT_FORMAT_YUYV:
  523. reg_value = 0x5;
  524. break;
  525. default:
  526. DDPERR("unknow ovl input format is %d\n", inputFormat);
  527. ASSERT(0);
  528. }
  529. return reg_value;
  530. }
  531. void OVLRegStore(DISP_MODULE_ENUM module)
  532. {
  533. int i =0;
  534. int idx = ovl_index(module);
  535. static const unsigned int regs[] = {
  536. //start
  537. DISP_REG_OVL_INTEN , DISP_REG_OVL_EN ,DISP_REG_OVL_DATAPATH_CON,
  538. // roi
  539. DISP_REG_OVL_ROI_SIZE , DISP_REG_OVL_ROI_BGCLR ,
  540. //layers enable
  541. DISP_REG_OVL_SRC_CON,
  542. //layer0
  543. DISP_REG_OVL_RDMA0_CTRL , DISP_REG_OVL_L0_CON ,DISP_REG_OVL_L0_SRC_SIZE,
  544. DISP_REG_OVL_L0_OFFSET , DISP_REG_OVL_L0_ADDR ,DISP_REG_OVL_L0_PITCH,
  545. DISP_REG_OVL_L0_SRCKEY ,
  546. //layer1
  547. DISP_REG_OVL_RDMA1_CTRL , DISP_REG_OVL_L1_CON ,DISP_REG_OVL_L1_SRC_SIZE,
  548. DISP_REG_OVL_L1_OFFSET , DISP_REG_OVL_L1_ADDR ,DISP_REG_OVL_L1_PITCH,
  549. DISP_REG_OVL_L1_SRCKEY ,
  550. //layer2
  551. DISP_REG_OVL_RDMA2_CTRL , DISP_REG_OVL_L2_CON ,DISP_REG_OVL_L2_SRC_SIZE,
  552. DISP_REG_OVL_L2_OFFSET , DISP_REG_OVL_L2_ADDR ,DISP_REG_OVL_L2_PITCH,
  553. DISP_REG_OVL_L2_SRCKEY ,
  554. //layer3
  555. DISP_REG_OVL_RDMA3_CTRL , DISP_REG_OVL_L3_CON ,DISP_REG_OVL_L3_SRC_SIZE,
  556. DISP_REG_OVL_L3_OFFSET , DISP_REG_OVL_L3_ADDR ,DISP_REG_OVL_L3_PITCH,
  557. DISP_REG_OVL_L3_SRCKEY ,
  558. };
  559. reg_back_cnt[idx] = sizeof(regs)/sizeof(unsigned int);
  560. ASSERT(reg_back_cnt[idx] <= OVL_REG_BACK_MAX);
  561. for (i =0; i< reg_back_cnt[idx]; i++) {
  562. reg_back[idx][i].address = regs[i];
  563. reg_back[idx][i].value = DISP_REG_GET(regs[i]);
  564. }
  565. DDPDBG("store %d cnt registers on ovl %d",reg_back_cnt[idx],idx);
  566. }
  567. void OVLRegRestore(DISP_MODULE_ENUM module,void * handle)
  568. {
  569. unsigned int idx = ovl_index(module);
  570. int i = reg_back_cnt[idx];
  571. while (i > 0) {
  572. i--;
  573. DISP_REG_SET(handle,reg_back[idx][i].address, reg_back[idx][i].value);
  574. }
  575. DDPDBG("restore %d cnt registers on ovl %d",reg_back_cnt[idx],idx);
  576. reg_back_cnt[idx] = 0;
  577. }
  578. void OVLClockOn(DISP_MODULE_ENUM module,void * handle)
  579. {
  580. int idx = ovl_index(module);
  581. ddp_enable_module_clock(module);
  582. DDPMSG("OVL%dClockOn CG 0x%x \n",idx, DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0));
  583. return;
  584. }
  585. void OVLClockOff(DISP_MODULE_ENUM module,void * handle)
  586. {
  587. int idx = ovl_index(module);
  588. DDPMSG("OVL%dClockOff\n",idx);
  589. //store registers
  590. // OVLRegRestore(module,handle);
  591. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x00);
  592. OVLReset(module,handle);
  593. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTEN, 0x00);
  594. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_INTSTA, 0x00);
  595. ddp_disable_module_clock(module);
  596. return;
  597. }
  598. void OVLInit(DISP_MODULE_ENUM module,void * handle)
  599. {
  600. //power on, no need to care clock
  601. ddp_enable_module_clock(module);
  602. return;
  603. }
  604. void OVLDeInit(DISP_MODULE_ENUM module,void * handle)
  605. {
  606. int idx = ovl_index(module);
  607. DDPMSG("OVL%dDeInit close CG \n",idx);
  608. ddp_disable_module_clock(module);
  609. return;
  610. }
  611. static inline int is_module_ovl(DISP_MODULE_ENUM module)
  612. {
  613. if (module == DISP_MODULE_OVL0 ||
  614. module == DISP_MODULE_OVL1 ||
  615. module == DISP_MODULE_OVL0_2L ||
  616. module == DISP_MODULE_OVL1_2L)
  617. return 1;
  618. else
  619. return 0;
  620. }
  621. int OVLConnect(DISP_MODULE_ENUM module, DISP_MODULE_ENUM prev,
  622. DISP_MODULE_ENUM next, int connect, void *handle)
  623. {
  624. int idx = ovl_index(module);
  625. if (connect && is_module_ovl(prev))
  626. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  627. idx * DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 1);
  628. else
  629. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  630. idx * DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 0);
  631. return 0;
  632. }
  633. void OVLDump(DISP_MODULE_ENUM module)
  634. {
  635. int idx = ovl_index(module);
  636. unsigned long offset = DISP_INDEX_OFFSET*idx;
  637. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset);
  638. DDPDUMP("== DISP %s REGS ==\n", ddp_get_module_name(module));
  639. DDPDUMP("OVL:0x000=0x%08x,0x004=0x%08x,0x008=0x%08x,0x00c=0x%08x\n",
  640. DISP_REG_GET(DISP_REG_OVL_STA + offset),
  641. DISP_REG_GET(DISP_REG_OVL_INTEN + offset),
  642. DISP_REG_GET(DISP_REG_OVL_INTSTA + offset), DISP_REG_GET(DISP_REG_OVL_EN + offset));
  643. DDPDUMP("OVL:0x010=0x%08x,0x014=0x%08x,0x020=0x%08x,0x024=0x%08x\n",
  644. DISP_REG_GET(DISP_REG_OVL_TRIG + offset),
  645. DISP_REG_GET(DISP_REG_OVL_RST + offset),
  646. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset),
  647. DISP_REG_GET(DISP_REG_OVL_DATAPATH_CON + offset));
  648. DDPDUMP("OVL:0x028=0x%08x,0x02c=0x%08x\n",
  649. DISP_REG_GET(DISP_REG_OVL_ROI_BGCLR + offset),
  650. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset));
  651. if (src_on & 0x1) {
  652. DDPDUMP("OVL:0x030=0x%08x,0x034=0x%08x,0x038=0x%08x,0x03c=0x%08x\n",
  653. DISP_REG_GET(DISP_REG_OVL_L0_CON + offset),
  654. DISP_REG_GET(DISP_REG_OVL_L0_SRCKEY + offset),
  655. DISP_REG_GET(DISP_REG_OVL_L0_SRC_SIZE + offset),
  656. DISP_REG_GET(DISP_REG_OVL_L0_OFFSET + offset));
  657. DDPDUMP("OVL:0xf40=0x%08x,0x044=0x%08x,0x0c0=0x%08x,0x0c8=0x%08x\n",
  658. DISP_REG_GET(DISP_REG_OVL_L0_ADDR + offset),
  659. DISP_REG_GET(DISP_REG_OVL_L0_PITCH + offset),
  660. DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + offset),
  661. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + offset));
  662. DDPDUMP("OVL:0x0d0=0x%08x,0x1e0=0x%08x,0x24c=0x%08x\n",
  663. DISP_REG_GET(DISP_REG_OVL_RDMA0_FIFO_CTRL + offset),
  664. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_S2 + offset),
  665. DISP_REG_GET(DISP_REG_OVL_RDMA0_DBG + offset));
  666. }
  667. if (src_on & 0x2) {
  668. DDPDUMP("OVL:0x050=0x%08x,0x054=0x%08x,0x058=0x%08x,0x05c=0x%08x\n",
  669. DISP_REG_GET(DISP_REG_OVL_L1_CON + offset),
  670. DISP_REG_GET(DISP_REG_OVL_L1_SRCKEY + offset),
  671. DISP_REG_GET(DISP_REG_OVL_L1_SRC_SIZE + offset),
  672. DISP_REG_GET(DISP_REG_OVL_L1_OFFSET + offset));
  673. DDPDUMP("OVL:0xf60=0x%08x,0x064=0x%08x,0x0e0=0x%08x,0x0e8=0x%08x,0x0f0=0x%08x\n",
  674. DISP_REG_GET(DISP_REG_OVL_L1_ADDR + offset),
  675. DISP_REG_GET(DISP_REG_OVL_L1_PITCH + offset),
  676. DISP_REG_GET(DISP_REG_OVL_RDMA1_CTRL + offset),
  677. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_SETTING + offset),
  678. DISP_REG_GET(DISP_REG_OVL_RDMA1_FIFO_CTRL + offset));
  679. DDPDUMP("OVL:0x1e4=0x%08x,0x250=0x%08x\n",
  680. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_S2 + offset),
  681. DISP_REG_GET(DISP_REG_OVL_RDMA1_DBG + offset));
  682. }
  683. if (src_on & 0x4) {
  684. DDPDUMP("OVL:0x070=0x%08x,0x074=0x%08x,0x078=0x%08x,0x07c=0x%08x\n",
  685. DISP_REG_GET(DISP_REG_OVL_L2_CON + offset),
  686. DISP_REG_GET(DISP_REG_OVL_L2_SRCKEY + offset),
  687. DISP_REG_GET(DISP_REG_OVL_L2_SRC_SIZE + offset),
  688. DISP_REG_GET(DISP_REG_OVL_L2_OFFSET + offset));
  689. DDPDUMP("OVL:0xf80=0x%08x,0x084=0x%08x,0x100=0x%08x,0x110=0x%08x\n",
  690. DISP_REG_GET(DISP_REG_OVL_L2_ADDR + offset),
  691. DISP_REG_GET(DISP_REG_OVL_L2_PITCH + offset),
  692. DISP_REG_GET(DISP_REG_OVL_RDMA2_CTRL + offset),
  693. DISP_REG_GET(DISP_REG_OVL_RDMA2_FIFO_CTRL + offset));
  694. DDPDUMP("OVL:0x1e8=0x%08x,0x254=0x%08x\n",
  695. DISP_REG_GET(DISP_REG_OVL_RDMA2_MEM_GMC_S2 + offset),
  696. DISP_REG_GET(DISP_REG_OVL_RDMA2_DBG + offset));
  697. }
  698. if (src_on & 0x8) {
  699. DDPDUMP("OVL:0x090=0x%08x,0x094=0x%08x,0x098=0x%08x,0x09c=0x%08x\n",
  700. DISP_REG_GET(DISP_REG_OVL_L3_CON + offset),
  701. DISP_REG_GET(DISP_REG_OVL_L3_SRCKEY + offset),
  702. DISP_REG_GET(DISP_REG_OVL_L3_SRC_SIZE + offset),
  703. DISP_REG_GET(DISP_REG_OVL_L3_OFFSET + offset));
  704. DDPDUMP("OVL:0xfa0=0x%08x,0x0a4=0x%08x,0x120=0x%08x,0x130=0x%08x\n",
  705. DISP_REG_GET(DISP_REG_OVL_L3_ADDR + offset),
  706. DISP_REG_GET(DISP_REG_OVL_L3_PITCH + offset),
  707. DISP_REG_GET(DISP_REG_OVL_RDMA3_CTRL + offset),
  708. DISP_REG_GET(DISP_REG_OVL_RDMA3_FIFO_CTRL + offset));
  709. DDPDUMP("OVL:0x1ec=0x%08x,0x258=0x%08x\n",
  710. DISP_REG_GET(DISP_REG_OVL_RDMA3_MEM_GMC_S2 + offset),
  711. DISP_REG_GET(DISP_REG_OVL_RDMA3_DBG + offset));
  712. }
  713. DDPDUMP("OVL:0x1d4=0x%08x,0x1f8=0x%08x,0x1fc=0x%08x,0x200=0x%08x,0x20c=0x%08x\n"
  714. "0x210=0x%08x,0x214=0x%08x,0x218=0x%08x,0x21c=0x%08x\n"
  715. "0x230=0x%08x,0x234=0x%08x,0x240=0x%08x,0x244=0x%08x,0x2A0=0x%08x,0x2A4=0x%08x\n",
  716. DISP_REG_GET(DISP_REG_OVL_DEBUG_MON_SEL + offset),
  717. DISP_REG_GET(DISP_REG_OVL_RDMA_GREQ_NUM + offset),
  718. DISP_REG_GET(DISP_REG_OVL_RDMA_GREQ_URG_NUM + offset),
  719. DISP_REG_GET(DISP_REG_OVL_DUMMY_REG + offset),
  720. DISP_REG_GET(DISP_REG_OVL_RDMA_ULTRA_SRC + offset),
  721. DISP_REG_GET(DISP_REG_OVL_RDMAn_BUF_LOW(0) + offset),
  722. DISP_REG_GET(DISP_REG_OVL_RDMAn_BUF_LOW(1) + offset),
  723. DISP_REG_GET(DISP_REG_OVL_RDMAn_BUF_LOW(2) + offset),
  724. DISP_REG_GET(DISP_REG_OVL_RDMAn_BUF_LOW(3) + offset),
  725. DISP_REG_GET(DISP_REG_OVL_SMI_DBG + offset),
  726. DISP_REG_GET(DISP_REG_OVL_GREQ_LAYER_CNT + offset),
  727. DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset),
  728. DISP_REG_GET(DISP_REG_OVL_ADDCON_DBG + offset),
  729. DISP_REG_GET(DISP_REG_OVL_FUNC_DCM0 + offset),
  730. DISP_REG_GET(DISP_REG_OVL_FUNC_DCM1 + offset));
  731. }
  732. static void ovl_printf_status(unsigned int status)
  733. {
  734. DDPDUMP("=OVL_FLOW_CONTROL_DEBUG=:\n");
  735. DDPDUMP("addcon_idle:%d,blend_idle:%d,out_valid:%d,out_ready:%d,out_idle:%d\n",
  736. (status >> 10) & (0x1),
  737. (status >> 11) & (0x1),
  738. (status >> 12) & (0x1), (status >> 13) & (0x1), (status >> 15) & (0x1)
  739. );
  740. DDPDUMP("rdma3_idle:%d,rdma2_idle:%d,rdma1_idle:%d, rdma0_idle:%d,rst:%d\n",
  741. (status >> 16) & (0x1),
  742. (status >> 17) & (0x1),
  743. (status >> 18) & (0x1), (status >> 19) & (0x1), (status >> 20) & (0x1)
  744. );
  745. DDPDUMP("trig:%d,frame_hwrst_done:%d,frame_swrst_done:%d,frame_underrun:%d,frame_done:%d\n",
  746. (status >> 21) & (0x1),
  747. (status >> 23) & (0x1),
  748. (status >> 24) & (0x1), (status >> 25) & (0x1), (status >> 26) & (0x1)
  749. );
  750. DDPDUMP("ovl_running:%d,ovl_start:%d,ovl_clr:%d,reg_update:%d,ovl_upd_reg:%d\n",
  751. (status >> 27) & (0x1),
  752. (status >> 28) & (0x1),
  753. (status >> 29) & (0x1), (status >> 30) & (0x1), (status >> 31) & (0x1)
  754. );
  755. DDPDUMP("ovl_fms_state:\n");
  756. switch (status & 0x3ff) {
  757. case 0x1:
  758. DDPDUMP("idle\n");
  759. break;
  760. case 0x2:
  761. DDPDUMP("wait_SOF\n");
  762. break;
  763. case 0x4:
  764. DDPDUMP("prepare\n");
  765. break;
  766. case 0x8:
  767. DDPDUMP("reg_update\n");
  768. break;
  769. case 0x10:
  770. DDPDUMP("eng_clr(internal reset)\n");
  771. break;
  772. case 0x20:
  773. DDPDUMP("eng_act(processing)\n");
  774. break;
  775. case 0x40:
  776. DDPDUMP("h_wait_w_rst\n");
  777. break;
  778. case 0x80:
  779. DDPDUMP("s_wait_w_rst\n");
  780. break;
  781. case 0x100:
  782. DDPDUMP("h_w_rst\n");
  783. break;
  784. case 0x200:
  785. DDPDUMP("s_w_rst\n");
  786. break;
  787. default:
  788. DDPDUMP("ovl_fsm_unknown\n");
  789. break;
  790. }
  791. }
  792. static void ovl_print_ovl_rdma_status(unsigned int status)
  793. {
  794. DDPDUMP("wram_rst_cs:0x%x,layer_greq:0x%x,out_data:0x%x,",
  795. status & 0x7, (status >> 3) & 0x1, (status >> 4) & 0xffffff);
  796. DDPDUMP("out_ready:0x%x,out_valid:0x%x,smi_busy:0x%x,smi_greq:0x%x\n",
  797. (status >> 28) & 0x1, (status >> 29) & 0x1, (status >> 30) & 0x1,
  798. (status >> 31) & 0x1);
  799. }
  800. static void ovl_dump_layer_info(int layer, unsigned long layer_offset)
  801. {
  802. DDPDUMP("layer%d: w=%d,h=%d,off(x=%d,y=%d),pitch=%d,addr=0x%x,fmt=%s,source=%s,aen=%d,alpha=%d\n",
  803. layer, DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff,
  804. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) >> 16) & 0xfff,
  805. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) & 0xfff,
  806. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) >> 16) & 0xfff,
  807. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_PITCH) & 0xffff,
  808. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_ADDR),
  809. ovl_intput_format_name(
  810. DISP_REG_GET_FIELD(L_CON_FLD_CFMT, DISP_REG_OVL_L0_CON+layer_offset),
  811. DISP_REG_GET_FIELD(L_CON_FLD_BTSW, DISP_REG_OVL_L0_CON+layer_offset)),
  812. (DISP_REG_GET_FIELD(L_CON_FLD_LARC, DISP_REG_OVL_L0_CON + layer_offset) ==
  813. 0) ? "memory" : "constant_color", DISP_REG_GET_FIELD(L_CON_FLD_AEN,
  814. DISP_REG_OVL_L0_CON +
  815. layer_offset),
  816. DISP_REG_GET_FIELD(L_CON_FLD_APHA, DISP_REG_OVL_L0_CON + layer_offset)
  817. );
  818. }
  819. void ovl_dump_analysis(DISP_MODULE_ENUM module)
  820. {
  821. int i = 0;
  822. unsigned int layer_offset = 0;
  823. unsigned int rdma_offset = 0;
  824. int idx = ovl_index(module);
  825. unsigned int offset = idx * DISP_INDEX_OFFSET;
  826. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON+offset);
  827. unsigned int rdma_ctrl;
  828. DDPDUMP("==DISP %s ANALYSIS==\n", ddp_get_module_name(module));
  829. DDPDUMP("ovl_en=%d,layer_enable(%d,%d,%d,%d),bg(w=%d, h=%d),",
  830. DISP_REG_GET(DISP_REG_OVL_EN + offset),
  831. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) & 0x1,
  832. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 1) & 0x1,
  833. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 2) & 0x1,
  834. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 3) & 0x1,
  835. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) & 0xfff,
  836. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) >> 16) & 0xfff);
  837. DDPDUMP("cur_pos(x=%d,y=%d),layer_hit(%d,%d,%d,%d),bg_mode=%s,sta=0x%x\n",
  838. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_X, DISP_REG_OVL_ADDCON_DBG + offset),
  839. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_Y, DISP_REG_OVL_ADDCON_DBG + offset),
  840. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L0_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  841. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L1_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  842. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L2_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  843. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L3_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  844. DISP_REG_GET_FIELD(DATAPATH_CON_FLD_BGCLR_IN_SEL,
  845. DISP_REG_OVL_DATAPATH_CON + offset) ? "directlink" : "const",
  846. DISP_REG_GET(DISP_REG_OVL_STA + offset)
  847. );
  848. for (i = 0; i < 4; i++) {
  849. layer_offset = i * OVL_LAYER_OFFSET + offset;
  850. rdma_offset = i * OVL_RDMA_DEBUG_OFFSET + offset;
  851. if (src_on & (0x1 << i))
  852. ovl_dump_layer_info(i, layer_offset);
  853. else
  854. DDPDUMP("layer%d: disabled\n", i);
  855. rdma_ctrl = DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_CTRL);
  856. DDPDUMP("ovl rdma%d status:(en=%d, fifo_used %d, GMC=0x%x)\n", i,
  857. REG_FLD_VAL_GET(RDMA0_CTRL_FLD_RDMA_EN, rdma_ctrl),
  858. REG_FLD_VAL_GET(RDMA0_CTRL_FLD_RMDA_FIFO_USED_SZ, rdma_ctrl),
  859. DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_MEM_GMC_SETTING));
  860. ovl_print_ovl_rdma_status(DISP_REG_GET(DISP_REG_OVL_RDMA0_DBG + rdma_offset));
  861. }
  862. ovl_printf_status(DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset));
  863. }
  864. static inline unsigned long ovl_layer_num(DISP_MODULE_ENUM module)
  865. {
  866. switch (module) {
  867. case DISP_MODULE_OVL0:
  868. return 4;
  869. case DISP_MODULE_OVL1:
  870. return 0;
  871. case DISP_MODULE_OVL0_2L:
  872. return 2;
  873. case DISP_MODULE_OVL1_2L:
  874. return 2;
  875. default:
  876. DDPERR("invalid ovl module=%d\n", module);
  877. ASSERT(0);
  878. }
  879. return 0;
  880. }
  881. static int OVLConfig_l(DISP_MODULE_ENUM module, disp_ddp_path_config* pConfig, void* handle)
  882. {
  883. int enabled_layers = 0;
  884. int local_layer = 0, global_layer = 0;
  885. int idx = ovl_index(module);
  886. if (pConfig->dst_dirty) {
  887. OVLROI(module,
  888. pConfig->dst_w, // width
  889. pConfig->dst_h, // height
  890. 0xFF000000, // background color
  891. handle);
  892. }
  893. if (!pConfig->ovl_dirty) {
  894. return 0;
  895. }
  896. for (global_layer = 0; global_layer < TOTAL_OVL_LAYER_NUM; global_layer++) {
  897. if (!(pConfig->ovl_layer_scanned & (1 << global_layer)))
  898. break;
  899. }
  900. if (global_layer > TOTAL_OVL_LAYER_NUM - ovl_layer_num(module)) {
  901. DDPERR("%s: %s scan error, layer_scanned=%u\n", __func__,
  902. ddp_get_module_name(module), pConfig->ovl_layer_scanned);
  903. ASSERT(0);
  904. }
  905. for (local_layer = 0; local_layer < ovl_layer_num(module); local_layer++, global_layer++) {
  906. OVL_CONFIG_STRUCT *ovl_cfg = &pConfig->ovl_config[global_layer];
  907. pConfig->ovl_layer_scanned |= (1 << global_layer);
  908. if (ovl_cfg->layer_en == 0)
  909. continue;
  910. if (ovl_cfg->addr==0 || ovl_cfg->dst_w==0 || ovl_cfg->dst_h==0) {
  911. DDPERR("ovl parameter invalidate, addr=0x%x, w=%d, h=%d \n",
  912. ovl_cfg->addr,
  913. ovl_cfg->dst_w,
  914. ovl_cfg->dst_h);
  915. return -1;
  916. }
  917. DDPDBG("module %d, layer=%d, en=%d, src=%d, fmt=%d, addr=0x%x, x=%d, y=%d, pitch=%d, dst(%d, %d, %d, %d),keyEn=%d, key=%d, aen=%d, alpha=%d\n",
  918. module,
  919. local_layer,
  920. ovl_cfg->layer_en,
  921. ovl_cfg->source, // data source (0=memory)
  922. ovl_cfg->fmt,
  923. ovl_cfg->addr, // addr
  924. ovl_cfg->src_x, // x
  925. ovl_cfg->src_y, // y
  926. ovl_cfg->src_pitch, //pitch, pixel number
  927. ovl_cfg->dst_x, // x
  928. ovl_cfg->dst_y, // y
  929. ovl_cfg->dst_w, // width
  930. ovl_cfg->dst_h, // height
  931. ovl_cfg->keyEn, //color key
  932. ovl_cfg->key, //color key
  933. ovl_cfg->aen, // alpha enable
  934. ovl_cfg->alpha);
  935. OVLLayerConfig(module,
  936. local_layer,
  937. ovl_cfg->source,
  938. ovl_cfg->fmt,
  939. ovl_cfg->addr,
  940. ovl_cfg->src_x,
  941. ovl_cfg->src_y,
  942. ovl_cfg->src_pitch,
  943. ovl_cfg->dst_x,
  944. ovl_cfg->dst_y,
  945. ovl_cfg->dst_w,
  946. ovl_cfg->dst_h,
  947. ovl_cfg->keyEn,
  948. ovl_cfg->key,
  949. ovl_cfg->aen,
  950. ovl_cfg->alpha,
  951. handle);
  952. // print_layer_config_args(module, local_layer, ovl_cfg);
  953. // ovl_layer_config(module, local_layer, has_sec_layer, ovl_cfg, handle);
  954. enabled_layers |= 1 << local_layer;
  955. }
  956. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_SRC_CON, enabled_layers);
  957. return 0;
  958. }
  959. DDP_MODULE_DRIVER ddp_driver_ovl = {
  960. .module = DISP_MODULE_OVL0,
  961. .init = OVLInit,
  962. .deinit = OVLDeInit,
  963. .config = OVLConfig_l,
  964. .start = OVLStart,
  965. .trigger = NULL,
  966. .stop = OVLStop,
  967. .reset = NULL,
  968. .power_on = OVLClockOn,
  969. .power_off = OVLClockOff,
  970. .is_idle = NULL,
  971. .is_busy = NULL,
  972. .dump_info = NULL,
  973. .bypass = NULL,
  974. .build_cmdq = NULL,
  975. .set_lcm_utils = NULL,
  976. .connect = OVLConnect,
  977. };