ddp_ovl.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534
  1. #define LOG_TAG "OVL"
  2. #include "ddp_log.h"
  3. #ifdef CONFIG_MTK_CLKMGR
  4. #include <mach/mt_clkmgr.h>
  5. #endif
  6. #include "m4u.h"
  7. #include <linux/delay.h>
  8. #include "disp_drv_platform.h"
  9. #include "ddp_info.h"
  10. #include "ddp_hal.h"
  11. #include "ddp_reg.h"
  12. #include "ddp_ovl.h"
  13. #include "ddp_drv.h"
  14. #include "primary_display.h"
  15. #include "ddp_debug.h"
  16. #include "disp_assert_layer.h"
  17. #include "ddp_irq.h"
  18. #define OVL_NUM (2)
  19. #define OVL_REG_BACK_MAX (40)
  20. #define OVL_LAYER_OFFSET (0x20)
  21. #define OVL_RDMA_DEBUG_OFFSET (0x4)
  22. enum OVL_COLOR_SPACE {
  23. OVL_COLOR_SPACE_RGB = 0,
  24. OVL_COLOR_SPACE_YUV,
  25. };
  26. enum OVL_INPUT_FORMAT {
  27. OVL_INPUT_FORMAT_BGR565 = 0,
  28. OVL_INPUT_FORMAT_RGB888 = 1,
  29. OVL_INPUT_FORMAT_RGBA8888 = 2,
  30. OVL_INPUT_FORMAT_ARGB8888 = 3,
  31. OVL_INPUT_FORMAT_VYUY = 4,
  32. OVL_INPUT_FORMAT_YVYU = 5,
  33. OVL_INPUT_FORMAT_RGB565 = 6,
  34. OVL_INPUT_FORMAT_BGR888 = 7,
  35. OVL_INPUT_FORMAT_BGRA8888 = 8,
  36. OVL_INPUT_FORMAT_ABGR8888 = 9,
  37. OVL_INPUT_FORMAT_UYVY = 10,
  38. OVL_INPUT_FORMAT_YUYV = 11,
  39. OVL_INPUT_FORMAT_UNKNOWN = 32,
  40. };
  41. struct OVL_REG {
  42. unsigned long address;
  43. unsigned int value;
  44. };
  45. DISP_OVL1_STATUS ovl1_status = DDP_OVL1_STATUS_IDLE;
  46. static int reg_back_cnt[OVL_NUM];
  47. static struct OVL_REG reg_back[OVL_NUM][OVL_REG_BACK_MAX];
  48. static char *ovl_get_status_name(DISP_OVL1_STATUS status)
  49. {
  50. switch (status) {
  51. case DDP_OVL1_STATUS_IDLE:
  52. return "idle";
  53. case DDP_OVL1_STATUS_PRIMARY:
  54. return "primary";
  55. case DDP_OVL1_STATUS_SUB:
  56. return "sub";
  57. case DDP_OVL1_STATUS_SUB_REQUESTING:
  58. return "sub_requesting";
  59. case DDP_OVL1_STATUS_PRIMARY_RELEASED:
  60. return "primary_released";
  61. case DDP_OVL1_STATUS_PRIMARY_RELEASING:
  62. return "primary_releasing";
  63. case DDP_OVL1_STATUS_PRIMARY_DISABLE:
  64. return "primary_disabled";
  65. default:
  66. return "unknown";
  67. }
  68. }
  69. /* get ovl1 status */
  70. DISP_OVL1_STATUS ovl_get_status(void)
  71. {
  72. return ovl1_status;
  73. }
  74. /* set ovl1 status */
  75. void ovl_set_status(DISP_OVL1_STATUS status)
  76. {
  77. DDPMSG("cascade, set_ovl1 from %s to %s!\n", ovl_get_status_name(ovl1_status),
  78. ovl_get_status_name(status));
  79. MMProfileLogEx(ddp_mmp_get_events()->ovl1_status, MMProfileFlagPulse, ovl1_status, status);
  80. ovl1_status = status; /* atomic operation */
  81. }
  82. static enum OVL_INPUT_FORMAT ovl_input_fmt_convert(DpColorFormat fmt)
  83. {
  84. enum OVL_INPUT_FORMAT ovl_fmt = OVL_INPUT_FORMAT_UNKNOWN;
  85. switch (fmt) {
  86. case eBGR565:
  87. ovl_fmt = OVL_INPUT_FORMAT_BGR565;
  88. break;
  89. case eRGB565:
  90. ovl_fmt = OVL_INPUT_FORMAT_RGB565;
  91. break;
  92. case eRGB888:
  93. ovl_fmt = OVL_INPUT_FORMAT_RGB888;
  94. break;
  95. case eBGR888:
  96. ovl_fmt = OVL_INPUT_FORMAT_BGR888;
  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. default:
  144. DDPERR("ovl_input_fmt fmt=%d, swap=%d\n", fmt, swap);
  145. break;
  146. }
  147. return eRGB888;
  148. }
  149. static unsigned int ovl_input_fmt_byte_swap(enum OVL_INPUT_FORMAT fmt)
  150. {
  151. int input_swap = 0;
  152. switch (fmt) {
  153. case OVL_INPUT_FORMAT_BGR565:
  154. case OVL_INPUT_FORMAT_RGB888:
  155. case OVL_INPUT_FORMAT_RGBA8888:
  156. case OVL_INPUT_FORMAT_ARGB8888:
  157. case OVL_INPUT_FORMAT_VYUY:
  158. case OVL_INPUT_FORMAT_YVYU:
  159. input_swap = 1;
  160. break;
  161. case OVL_INPUT_FORMAT_RGB565:
  162. case OVL_INPUT_FORMAT_BGR888:
  163. case OVL_INPUT_FORMAT_BGRA8888:
  164. case OVL_INPUT_FORMAT_ABGR8888:
  165. case OVL_INPUT_FORMAT_UYVY:
  166. case OVL_INPUT_FORMAT_YUYV:
  167. input_swap = 0;
  168. break;
  169. default:
  170. DDPERR("unknown input ovl format is %d\n", fmt);
  171. ASSERT(0);
  172. }
  173. return input_swap;
  174. }
  175. static unsigned int ovl_input_fmt_bpp(enum OVL_INPUT_FORMAT fmt)
  176. {
  177. int bpp = 0;
  178. switch (fmt) {
  179. case OVL_INPUT_FORMAT_BGR565:
  180. case OVL_INPUT_FORMAT_RGB565:
  181. case OVL_INPUT_FORMAT_VYUY:
  182. case OVL_INPUT_FORMAT_UYVY:
  183. case OVL_INPUT_FORMAT_YVYU:
  184. case OVL_INPUT_FORMAT_YUYV:
  185. bpp = 2;
  186. break;
  187. case OVL_INPUT_FORMAT_RGB888:
  188. case OVL_INPUT_FORMAT_BGR888:
  189. bpp = 3;
  190. break;
  191. case OVL_INPUT_FORMAT_RGBA8888:
  192. case OVL_INPUT_FORMAT_BGRA8888:
  193. case OVL_INPUT_FORMAT_ARGB8888:
  194. case OVL_INPUT_FORMAT_ABGR8888:
  195. bpp = 4;
  196. break;
  197. default:
  198. DDPERR("unknown ovl input format = %d\n", fmt);
  199. ASSERT(0);
  200. }
  201. return bpp;
  202. }
  203. static enum OVL_COLOR_SPACE ovl_input_fmt_color_space(enum OVL_INPUT_FORMAT fmt)
  204. {
  205. enum OVL_COLOR_SPACE space = OVL_COLOR_SPACE_RGB;
  206. switch (fmt) {
  207. case OVL_INPUT_FORMAT_BGR565:
  208. case OVL_INPUT_FORMAT_RGB565:
  209. case OVL_INPUT_FORMAT_RGB888:
  210. case OVL_INPUT_FORMAT_BGR888:
  211. case OVL_INPUT_FORMAT_RGBA8888:
  212. case OVL_INPUT_FORMAT_BGRA8888:
  213. case OVL_INPUT_FORMAT_ARGB8888:
  214. case OVL_INPUT_FORMAT_ABGR8888:
  215. space = OVL_COLOR_SPACE_RGB;
  216. break;
  217. case OVL_INPUT_FORMAT_VYUY:
  218. case OVL_INPUT_FORMAT_UYVY:
  219. case OVL_INPUT_FORMAT_YVYU:
  220. case OVL_INPUT_FORMAT_YUYV:
  221. space = OVL_COLOR_SPACE_YUV;
  222. break;
  223. default:
  224. DDPERR("unknown ovl input format = %d\n", fmt);
  225. ASSERT(0);
  226. }
  227. return space;
  228. }
  229. static unsigned int ovl_input_fmt_reg_value(enum OVL_INPUT_FORMAT fmt)
  230. {
  231. int reg_value = 0;
  232. switch (fmt) {
  233. case OVL_INPUT_FORMAT_BGR565:
  234. case OVL_INPUT_FORMAT_RGB565:
  235. reg_value = 0x0;
  236. break;
  237. case OVL_INPUT_FORMAT_RGB888:
  238. case OVL_INPUT_FORMAT_BGR888:
  239. reg_value = 0x1;
  240. break;
  241. case OVL_INPUT_FORMAT_RGBA8888:
  242. case OVL_INPUT_FORMAT_BGRA8888:
  243. reg_value = 0x2;
  244. break;
  245. case OVL_INPUT_FORMAT_ARGB8888:
  246. case OVL_INPUT_FORMAT_ABGR8888:
  247. reg_value = 0x3;
  248. break;
  249. case OVL_INPUT_FORMAT_VYUY:
  250. case OVL_INPUT_FORMAT_UYVY:
  251. reg_value = 0x4;
  252. break;
  253. case OVL_INPUT_FORMAT_YVYU:
  254. case OVL_INPUT_FORMAT_YUYV:
  255. reg_value = 0x5;
  256. break;
  257. default:
  258. DDPERR("unknown ovl input format is %d\n", fmt);
  259. ASSERT(0);
  260. }
  261. return reg_value;
  262. }
  263. static char *ovl_intput_format_name(enum OVL_INPUT_FORMAT fmt, int swap)
  264. {
  265. switch (fmt) {
  266. case OVL_INPUT_FORMAT_BGR565:
  267. return swap ? "eBGR565" : "eRGB565";
  268. case OVL_INPUT_FORMAT_RGB565:
  269. return "eRGB565";
  270. case OVL_INPUT_FORMAT_RGB888:
  271. return swap ? "eRGB888" : "eBGR888";
  272. case OVL_INPUT_FORMAT_BGR888:
  273. return "eBGR888";
  274. case OVL_INPUT_FORMAT_RGBA8888:
  275. return swap ? "eRGBA8888" : "eBGRA8888";
  276. case OVL_INPUT_FORMAT_BGRA8888:
  277. return "eBGRA8888";
  278. case OVL_INPUT_FORMAT_ARGB8888:
  279. return swap ? "eARGB8888" : "eABGR8888";
  280. case OVL_INPUT_FORMAT_ABGR8888:
  281. return "eABGR8888";
  282. case OVL_INPUT_FORMAT_VYUY:
  283. return swap ? "eVYUY" : "eUYVY";
  284. case OVL_INPUT_FORMAT_UYVY:
  285. return "eUYVY";
  286. case OVL_INPUT_FORMAT_YVYU:
  287. return swap ? "eYVYU" : "eYUY2";
  288. case OVL_INPUT_FORMAT_YUYV:
  289. return "eYUY2";
  290. default:
  291. DDPERR("ovl_intput_fmt unknown fmt=%d, swap=%d\n", fmt, swap);
  292. break;
  293. }
  294. return "unknown";
  295. }
  296. static unsigned int ovl_index(DISP_MODULE_ENUM module)
  297. {
  298. int idx = 0;
  299. switch (module) {
  300. case DISP_MODULE_OVL0:
  301. idx = 0;
  302. break;
  303. case DISP_MODULE_OVL1:
  304. idx = 1;
  305. break;
  306. default:
  307. DDPERR("invalid module=%d\n", module);
  308. ASSERT(0);
  309. }
  310. return idx;
  311. }
  312. int ovl_start(DISP_MODULE_ENUM module, void *handle)
  313. {
  314. int idx = ovl_index(module);
  315. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  316. int enable_ovl_irq = 1;
  317. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_EN, 0x01);
  318. #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT)
  319. enable_ovl_irq = 1;
  320. #else
  321. if (gEnableIRQ == 1)
  322. enable_ovl_irq = 1;
  323. else
  324. enable_ovl_irq = 0;
  325. #endif
  326. if (enable_ovl_irq)
  327. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_INTEN, 0x1e2);
  328. else
  329. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_INTEN, 0x1e0);
  330. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_LAYER_SMI_ID_EN,
  331. idx_offset + DISP_REG_OVL_DATAPATH_CON, 0x1);
  332. return 0;
  333. }
  334. int ovl_stop(DISP_MODULE_ENUM module, void *handle)
  335. {
  336. int idx = ovl_index(module);
  337. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  338. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_INTEN, 0x00);
  339. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_EN, 0x00);
  340. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_INTSTA, 0x00);
  341. return 0;
  342. }
  343. int ovl_is_idle(DISP_MODULE_ENUM module)
  344. {
  345. int idx = ovl_index(module);
  346. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  347. if (((DISP_REG_GET(idx_offset + DISP_REG_OVL_FLOW_CTRL_DBG) & 0x3ff) != 0x1) &&
  348. ((DISP_REG_GET(idx_offset + DISP_REG_OVL_FLOW_CTRL_DBG) & 0x3ff) != 0x2))
  349. return 0;
  350. else
  351. return 1;
  352. }
  353. int ovl_reset(DISP_MODULE_ENUM module, void *handle)
  354. {
  355. #define OVL_IDLE (0x3)
  356. int ret = 0;
  357. unsigned int delay_cnt = 0;
  358. int idx = ovl_index(module);
  359. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  360. DISP_CPU_REG_SET(idx_offset + DISP_REG_OVL_RST, 0x1);
  361. DISP_CPU_REG_SET(idx_offset + DISP_REG_OVL_RST, 0x0);
  362. /*only wait if not cmdq */
  363. if (handle == NULL) {
  364. while (!(DISP_REG_GET(idx_offset + DISP_REG_OVL_FLOW_CTRL_DBG) & OVL_IDLE)) {
  365. delay_cnt++;
  366. udelay(10);
  367. if (delay_cnt > 2000) {
  368. DDPERR("ovl%d_reset timeout!\n", idx);
  369. ret = -1;
  370. break;
  371. }
  372. }
  373. }
  374. return ret;
  375. }
  376. int ovl_roi(DISP_MODULE_ENUM module,
  377. unsigned int bg_w, unsigned int bg_h, unsigned int bg_color, void *handle)
  378. {
  379. int idx = ovl_index(module);
  380. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  381. if ((bg_w > OVL_MAX_WIDTH) || (bg_h > OVL_MAX_HEIGHT)) {
  382. DDPERR("ovl_roi,exceed OVL max size, w=%d, h=%d\n", bg_w, bg_h);
  383. ASSERT(0);
  384. }
  385. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_ROI_SIZE, bg_h << 16 | bg_w);
  386. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_ROI_BGCLR, bg_color);
  387. return 0;
  388. }
  389. int ovl_layer_switch(DISP_MODULE_ENUM module, unsigned layer, unsigned int en, void *handle)
  390. {
  391. int idx = ovl_index(module);
  392. int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  393. ASSERT(layer <= 3);
  394. /* DDPDBG("ovl%d,layer %d,enable %d\n", idx, layer, en); */
  395. switch (layer) {
  396. case 0:
  397. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_RDMA0_CTRL, en);
  398. break;
  399. case 1:
  400. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_RDMA1_CTRL, en);
  401. break;
  402. case 2:
  403. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_RDMA2_CTRL, en);
  404. break;
  405. case 3:
  406. DISP_REG_SET(handle, idx_offset + DISP_REG_OVL_RDMA3_CTRL, en);
  407. break;
  408. default:
  409. DDPERR("invalid layer=%d\n", layer);
  410. ASSERT(0);
  411. }
  412. return 0;
  413. }
  414. static int ovl_layer_config(DISP_MODULE_ENUM module, unsigned int layer,
  415. unsigned int source, DpColorFormat format,
  416. unsigned long addr, unsigned int src_x, /* ROI x offset */
  417. unsigned int src_y, /* ROI y offset */
  418. unsigned int src_pitch, unsigned int dst_x, /* ROI x offset */
  419. unsigned int dst_y, /* ROI y offset */
  420. unsigned int dst_w, /* ROT width */
  421. unsigned int dst_h, /* ROI height */
  422. unsigned int key_en, unsigned int key, /*color key */
  423. unsigned int aen, /* alpha enable */
  424. unsigned char alpha,
  425. unsigned int sur_aen,
  426. unsigned int src_alpha,
  427. unsigned int dst_alpha,
  428. unsigned int constant_color,
  429. unsigned int yuv_range,
  430. DISP_BUFFER_TYPE sec, unsigned int is_engine_sec, void *handle,
  431. bool is_memory)
  432. {
  433. int idx = ovl_index(module);
  434. unsigned int value = 0;
  435. enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format);
  436. unsigned int bpp = ovl_input_fmt_bpp(fmt);
  437. unsigned int input_swap = ovl_input_fmt_byte_swap(fmt);
  438. unsigned int input_fmt = ovl_input_fmt_reg_value(fmt);
  439. enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt);
  440. unsigned int offset = 0;
  441. /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB) */
  442. int color_matrix = 0x4;
  443. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  444. unsigned int layer_offset = idx_offset + layer * OVL_LAYER_OFFSET;
  445. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  446. unsigned int bg_h, bg_w;
  447. #endif
  448. switch (yuv_range) {
  449. case 0:
  450. color_matrix = 4;
  451. break; /* BT601_full */
  452. case 1:
  453. color_matrix = 6;
  454. break; /* BT601 */
  455. case 2:
  456. color_matrix = 7;
  457. break; /* BT709 */
  458. default:
  459. DDPERR("un-recognized yuv_range=%d!\n", yuv_range);
  460. color_matrix = 4;
  461. }
  462. /* DDPMSG("color matrix=%d.\n", color_matrix); */
  463. ASSERT((dst_w <= OVL_MAX_WIDTH) && (dst_h <= OVL_MAX_HEIGHT) && (layer <= 3));
  464. if (addr == 0) {
  465. DDPERR("source from memory, but addr is 0!\n");
  466. ASSERT(0);
  467. }
  468. #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT)
  469. DDPMSG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d,\n",
  470. idx, layer, (source == 0) ? "memory" : "dim", src_x, src_y, dst_x, dst_y,
  471. dst_w, dst_h, src_pitch);
  472. DDPMSG("fmt=%s, addr=%lx, keyEn=%d, key=%d, aen=%d, alpha=%d,\n",
  473. ovl_intput_format_name(fmt, input_swap), addr, key_en, key, aen, alpha);
  474. DDPMSG("sur_aen=%d,sur_alpha=0x%x, constant_color=0x%x, yuv_range=%d, sec=%d,ovlsec=%d\n",
  475. sur_aen, dst_alpha << 2 | src_alpha, constant_color, yuv_range, sec, is_engine_sec);
  476. #endif
  477. if (source == OVL_LAYER_SOURCE_RESERVED) {/* ==1, means constant color */
  478. if (aen == 0)
  479. DDPERR("dim layer ahpha enable should be 1!\n");
  480. if (fmt != OVL_INPUT_FORMAT_RGB565 && fmt != OVL_INPUT_FORMAT_RGB888) {
  481. /* DDPERR("dim layer format should be RGB565"); */
  482. fmt = OVL_INPUT_FORMAT_RGB888;
  483. input_fmt = ovl_input_fmt_reg_value(fmt);
  484. }
  485. }
  486. /* DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1); */
  487. value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) |
  488. REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) |
  489. REG_FLD_VAL((L_CON_FLD_AEN), (aen)) |
  490. REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) |
  491. REG_FLD_VAL((L_CON_FLD_SKEN), (key_en)) |
  492. REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap)));
  493. if (space == OVL_COLOR_SPACE_YUV)
  494. value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix));
  495. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  496. if (!is_memory)
  497. value |= 0x600;
  498. #endif
  499. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CON + layer_offset, value);
  500. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CLR + idx_offset + layer * 4, constant_color);
  501. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_SRC_SIZE + layer_offset, dst_h << 16 | dst_w);
  502. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  503. if (!is_memory) {
  504. bg_h = DISP_REG_GET(idx_offset + DISP_REG_OVL_ROI_SIZE);
  505. bg_w = bg_h & 0xFFFF;
  506. bg_h = bg_h >> 16;
  507. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET + layer_offset,
  508. ((bg_h - dst_h - dst_y) << 16) | (bg_w - dst_w - dst_x));
  509. } else {
  510. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET + layer_offset, dst_y << 16 | dst_x);
  511. }
  512. #else
  513. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET + layer_offset, dst_y << 16 | dst_x);
  514. #endif
  515. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  516. if (!is_memory)
  517. offset = src_pitch * (dst_h + src_y - 1) + (src_x + dst_w) * bpp - 1;
  518. else
  519. offset = src_x * bpp + src_y * src_pitch;
  520. #else
  521. offset = src_x * bpp + src_y * src_pitch;
  522. #endif
  523. if (!is_engine_sec) {
  524. DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR + layer_offset, addr + offset);
  525. } else {
  526. unsigned int size;
  527. int m4u_port;
  528. size = (dst_h - 1) * src_pitch + dst_w * bpp;
  529. #if defined(MTK_FB_OVL1_SUPPORT)
  530. m4u_port = idx == 0 ? M4U_PORT_DISP_OVL0 : M4U_PORT_DISP_OVL1;
  531. #else
  532. m4u_port = M4U_PORT_DISP_OVL0;
  533. #endif
  534. if (sec != DISP_SECURE_BUFFER) {
  535. /* ovl is sec but this layer is non-sec */
  536. /* we need to tell cmdq to help map non-sec mva to sec mva */
  537. cmdqRecWriteSecure(handle,
  538. disp_addr_convert(DISP_REG_OVL_L0_ADDR + layer_offset),
  539. CMDQ_SAM_NMVA_2_MVA, addr + offset, 0, size, m4u_port);
  540. } else {
  541. /* for sec layer, addr variable stores sec handle */
  542. /* we need to pass this handle and offset to cmdq driver */
  543. /* cmdq sec driver will help to convert handle to correct address */
  544. offset = src_x * bpp + src_y * src_pitch;
  545. cmdqRecWriteSecure(handle,
  546. disp_addr_convert(DISP_REG_OVL_L0_ADDR + layer_offset),
  547. CMDQ_SAM_H_2_MVA, addr, offset, size, m4u_port);
  548. }
  549. }
  550. if (key_en == 1)
  551. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_SRCKEY + layer_offset, key);
  552. value = (((sur_aen & 0x1) << 15) |
  553. ((dst_alpha & 0x3) << 6) | ((dst_alpha & 0x3) << 4) |
  554. ((src_alpha & 0x3) << 2) | (src_alpha & 0x3));
  555. value = (REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) |
  556. REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch)));
  557. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_PITCH + layer_offset, value);
  558. if (idx == 0) {
  559. if (primary_display_is_decouple_mode() == 0) {
  560. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset) !=
  561. 0x6070)
  562. DISP_REG_SET(handle,
  563. DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset,
  564. 0x6070);
  565. } else {
  566. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset) !=
  567. 0x50FF)
  568. DISP_REG_SET(handle,
  569. DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset,
  570. 0x50FF);
  571. }
  572. }
  573. if (idx == 1) {
  574. if (primary_display_is_decouple_mode() == 0
  575. && ovl_get_status() != DDP_OVL1_STATUS_SUB) {
  576. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset) !=
  577. 0x6070)
  578. DISP_REG_SET(handle,
  579. DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset,
  580. 0x6070);
  581. } else {
  582. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset) !=
  583. 0x50FF)
  584. DISP_REG_SET(handle,
  585. DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + layer_offset,
  586. 0x50FF);
  587. }
  588. }
  589. return 0;
  590. }
  591. static void ovl_store_regs(DISP_MODULE_ENUM module)
  592. {
  593. int i = 0;
  594. int idx = ovl_index(module);
  595. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  596. #if 0
  597. static const unsigned long regs[] = {
  598. DISP_REG_OVL_ROI_SIZE, DISP_REG_OVL_ROI_BGCLR,
  599. };
  600. #else
  601. static unsigned long regs[3];
  602. regs[0] = DISP_REG_OVL_ROI_SIZE + idx_offset;
  603. regs[1] = DISP_REG_OVL_ROI_BGCLR + idx_offset;
  604. regs[2] = DISP_REG_OVL_DATAPATH_CON + idx_offset;
  605. #endif
  606. reg_back_cnt[idx] = sizeof(regs) / sizeof(unsigned long);
  607. ASSERT(reg_back_cnt[idx] <= OVL_REG_BACK_MAX);
  608. for (i = 0; i < reg_back_cnt[idx]; i++) {
  609. reg_back[idx][i].address = regs[i];
  610. reg_back[idx][i].value = DISP_REG_GET(regs[i]);
  611. }
  612. DDPMSG("store %d cnt registers on ovl %d\n", reg_back_cnt[idx], idx);
  613. }
  614. static void ovl_restore_regs(DISP_MODULE_ENUM module, void *handle)
  615. {
  616. int idx = ovl_index(module);
  617. int i = reg_back_cnt[idx];
  618. while (i > 0) {
  619. i--;
  620. DISP_REG_SET(handle, reg_back[idx][i].address, reg_back[idx][i].value);
  621. }
  622. DDPMSG("restore %d cnt registers on ovl %d\n", reg_back_cnt[idx], idx);
  623. reg_back_cnt[idx] = 0;
  624. }
  625. static unsigned int ovl_clock_cnt[2] = { 0, 0 };
  626. int ovl_clock_on(DISP_MODULE_ENUM module, void *handle)
  627. {
  628. int idx = ovl_index(module);
  629. DDPMSG("ovl%d_clock_on\n", idx);
  630. #ifdef ENABLE_CLK_MGR
  631. if (idx == 0) {
  632. #ifdef CONFIG_MTK_CLKMGR
  633. enable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0");
  634. #else
  635. ddp_clk_enable(DISP0_DISP_OVL0);
  636. #endif
  637. } else {
  638. #ifdef CONFIG_MTK_CLKMGR
  639. enable_clock(MT_CG_DISP0_DISP_OVL1, "OVL1");
  640. #else
  641. ddp_clk_enable(DISP0_DISP_OVL1);
  642. #endif
  643. }
  644. ovl_clock_cnt[idx]++;
  645. #endif
  646. return 0;
  647. }
  648. int ovl_clock_off(DISP_MODULE_ENUM module, void *handle)
  649. {
  650. int idx = ovl_index(module);
  651. DDPMSG("ovl%d_clock_off\n", idx);
  652. #ifdef ENABLE_CLK_MGR
  653. if (ovl_clock_cnt[idx] == 0) {
  654. DDPERR("ovl_deinit, clock off OVL%d, but it's already off!\n", idx);
  655. return 0;
  656. }
  657. if (idx == 0) {
  658. #ifdef CONFIG_MTK_CLKMGR
  659. disable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0");
  660. #else
  661. ddp_clk_disable(DISP0_DISP_OVL0);
  662. #endif
  663. } else {
  664. #ifdef CONFIG_MTK_CLKMGR
  665. disable_clock(MT_CG_DISP0_DISP_OVL1, "OVL1");
  666. #else
  667. ddp_clk_disable(DISP0_DISP_OVL1);
  668. #endif
  669. }
  670. ovl_clock_cnt[idx]--;
  671. #endif
  672. return 0;
  673. }
  674. int ovl_resume(DISP_MODULE_ENUM module, void *handle)
  675. {
  676. int idx = ovl_index(module);
  677. DDPMSG("ovl%d_resume\n", idx);
  678. #ifdef ENABLE_CLK_MGR
  679. if (idx == 0) {
  680. #ifdef CONFIG_MTK_CLKMGR
  681. enable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0");
  682. #else
  683. ddp_clk_enable(DISP0_DISP_OVL0);
  684. #endif
  685. } else {
  686. #ifdef CONFIG_MTK_CLKMGR
  687. enable_clock(MT_CG_DISP0_DISP_OVL1, "OVL1");
  688. #else
  689. ddp_clk_enable(DISP0_DISP_OVL1);
  690. #endif
  691. }
  692. #endif
  693. ovl_restore_regs(module, handle);
  694. return 0;
  695. }
  696. int ovl_suspend(DISP_MODULE_ENUM module, void *handle)
  697. {
  698. int idx = ovl_index(module);
  699. DDPMSG("ovl%d_suspend\n", idx);
  700. ovl_store_regs(module);
  701. #ifdef ENABLE_CLK_MGR
  702. if (idx == 0) {
  703. #ifdef CONFIG_MTK_CLKMGR
  704. disable_clock(MT_CG_DISP0_DISP_OVL0 + idx, "OVL0");
  705. #else
  706. ddp_clk_disable(DISP0_DISP_OVL0 + idx);
  707. #endif
  708. } else {
  709. #ifdef CONFIG_MTK_CLKMGR
  710. disable_clock(MT_CG_DISP0_DISP_OVL0 + idx, "OVL1");
  711. #else
  712. ddp_clk_disable(DISP0_DISP_OVL0 + idx);
  713. #endif
  714. }
  715. #endif
  716. return 0;
  717. }
  718. int ovl_init(DISP_MODULE_ENUM module, void *handle)
  719. {
  720. ovl_clock_on(module, handle);
  721. return 0;
  722. }
  723. int ovl_deinit(DISP_MODULE_ENUM module, void *handle)
  724. {
  725. ovl_clock_off(module, handle);
  726. return 0;
  727. }
  728. unsigned int ddp_ovl_get_cur_addr(bool rdma_mode, int layerid)
  729. {
  730. if (rdma_mode)
  731. return DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR);
  732. #ifdef OVL_CASCADE_SUPPORT
  733. if (layerid < 4
  734. && (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY
  735. || ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_RELEASING
  736. || ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING)
  737. ) { /* OVL 1 */
  738. if (DISP_REG_GET
  739. (DISP_REG_OVL_RDMA0_CTRL + DISP_OVL_INDEX_OFFSET +
  740. layerid * 0x20) & 0x1)
  741. return (DISP_REG_GET
  742. (DISP_REG_OVL_L0_ADDR + DISP_OVL_INDEX_OFFSET +
  743. layerid * 0x20));
  744. else
  745. return 0;
  746. } else { /* OVL 0 */
  747. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + (layerid % 4) * 0x20) & 0x1)
  748. return DISP_REG_GET(DISP_REG_OVL_L0_ADDR + (layerid % 4) * 0x20);
  749. else
  750. return 0;
  751. }
  752. #else
  753. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + layerid * 0x20) & 0x1)
  754. return DISP_REG_GET(DISP_REG_OVL_L0_ADDR + layerid * 0x20);
  755. else
  756. return 0;
  757. #endif
  758. }
  759. void ovl_get_address(DISP_MODULE_ENUM module, unsigned long *add)
  760. {
  761. int i = 0;
  762. int idx = ovl_index(module);
  763. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  764. unsigned int layer_off = 0;
  765. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  766. for (i = 0; i < 4; i++) {
  767. layer_off = i * OVL_LAYER_OFFSET + idx_offset;
  768. if (src_on & (0x1 << i))
  769. add[i] = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  770. else
  771. add[i] = 0;
  772. }
  773. }
  774. void ovl_get_info(int idx, void *data)
  775. {
  776. int i = 0;
  777. OVL_BASIC_STRUCT *pdata = (OVL_BASIC_STRUCT *) data;
  778. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  779. unsigned int layer_off = 0;
  780. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  781. OVL_BASIC_STRUCT *p = NULL;
  782. memset(pdata, 0, sizeof(OVL_BASIC_STRUCT) * OVL_LAYER_NUM);
  783. if (ovl_get_status() == DDP_OVL1_STATUS_SUB || ovl_get_status() == DDP_OVL1_STATUS_IDLE) {
  784. /* 4+4 mode */
  785. /* idx=0; */
  786. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  787. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  788. for (i = 0; i < OVL_LAYER_NUM_PER_OVL; i++) {
  789. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  790. p = &pdata[i];
  791. p->layer = i;
  792. p->layer_en = src_on & (0x1 << i);
  793. if (p->layer_en) {
  794. p->fmt =
  795. (unsigned int)
  796. ovl_input_fmt(DISP_REG_GET_FIELD
  797. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  798. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  799. layer_off +
  800. DISP_REG_OVL_L0_CON));
  801. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  802. p->src_w =
  803. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  804. p->src_h =
  805. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  806. 0xfff;
  807. p->src_pitch =
  808. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  809. p->bpp =
  810. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  811. (L_CON_FLD_CFMT,
  812. layer_off + DISP_REG_OVL_L0_CON));
  813. }
  814. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  815. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  816. }
  817. } else {
  818. idx = 0;
  819. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  820. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  821. for (i = OVL_LAYER_NUM_PER_OVL; i < OVL_LAYER_NUM; i++) {
  822. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  823. p = &pdata[i];
  824. p->layer = i;
  825. p->layer_en = src_on & (0x1 << (i % 4));
  826. if (p->layer_en) {
  827. p->fmt =
  828. (unsigned int)
  829. ovl_input_fmt(DISP_REG_GET_FIELD
  830. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  831. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  832. layer_off +
  833. DISP_REG_OVL_L0_CON));
  834. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  835. p->src_w =
  836. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  837. p->src_h =
  838. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  839. 0xfff;
  840. p->src_pitch =
  841. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  842. p->bpp =
  843. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  844. (L_CON_FLD_CFMT,
  845. layer_off + DISP_REG_OVL_L0_CON));
  846. }
  847. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  848. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  849. }
  850. idx = 1;
  851. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  852. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  853. for (i = 0; i < OVL_LAYER_NUM_PER_OVL; i++) {
  854. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  855. p = &pdata[i];
  856. p->layer = i;
  857. p->layer_en = src_on & (0x1 << (i % 4));
  858. if (p->layer_en) {
  859. p->fmt =
  860. (unsigned int)
  861. ovl_input_fmt(DISP_REG_GET_FIELD
  862. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  863. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  864. layer_off +
  865. DISP_REG_OVL_L0_CON));
  866. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  867. p->src_w =
  868. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  869. p->src_h =
  870. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  871. 0xfff;
  872. p->src_pitch =
  873. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  874. p->bpp =
  875. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  876. (L_CON_FLD_CFMT,
  877. layer_off + DISP_REG_OVL_L0_CON));
  878. }
  879. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  880. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  881. }
  882. }
  883. }
  884. static int ovl_check_input_param(OVL_CONFIG_STRUCT *config)
  885. {
  886. if ((config->addr == 0 && config->source == 0) || config->dst_w == 0 || config->dst_h == 0) {
  887. DDPERR("ovl parameter invalidate, addr=%lx, w=%d, h=%d\n",
  888. config->addr, config->dst_w, config->dst_h);
  889. ASSERT(0);
  890. return -1;
  891. }
  892. return 0;
  893. }
  894. void ovl_reset_by_cmdq(void *handle, DISP_MODULE_ENUM module)
  895. {
  896. /* warm reset ovl every time we use it */
  897. if (handle) {
  898. if ((primary_display_is_decouple_mode() == 1) ||
  899. (primary_display_is_video_mode() == 0)) {
  900. unsigned int offset;
  901. offset = ovl_index(module) * DISP_OVL_INDEX_OFFSET;
  902. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x1);
  903. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x0);
  904. cmdqRecPoll(handle, disp_addr_convert(DISP_REG_OVL_STA + offset), 0, 0x1);
  905. }
  906. }
  907. }
  908. static int ovl_is_sec[2];
  909. static int ovl_config_l(DISP_MODULE_ENUM module, disp_ddp_path_config *pConfig, void *handle)
  910. {
  911. int i = 0;
  912. unsigned int layer_min = 0;
  913. unsigned int layer_max = 0;
  914. int has_sec_layer = 0;
  915. int ovl_idx = ovl_index(module);
  916. CMDQ_ENG_ENUM cmdq_engine;
  917. int layer_enable = 0;
  918. #ifdef OVL_CASCADE_SUPPORT
  919. if (module == DISP_MODULE_OVL1) {
  920. layer_min = 0;
  921. layer_max = 2;
  922. } else if (module == DISP_MODULE_OVL0 && (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY ||
  923. ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING)) {
  924. /* OVL0 always on top */
  925. layer_min = 2;
  926. layer_max = 6;
  927. } else {
  928. layer_min = 0;
  929. layer_max = 4;
  930. }
  931. #else
  932. layer_min = 0;
  933. layer_max = 4;
  934. #endif
  935. /* warm reset ovl every time we use it */
  936. if (handle) {
  937. if ((primary_display_is_decouple_mode() == 1) ||
  938. (primary_display_is_video_mode() == 0)) {
  939. unsigned int offset;
  940. offset = ovl_index(module) * DISP_OVL_INDEX_OFFSET;
  941. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x1);
  942. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x0);
  943. cmdqRecPoll(handle, disp_addr_convert(DISP_REG_OVL_STA + offset), 0, 0x1);
  944. }
  945. }
  946. if (pConfig->dst_dirty || pConfig->roi_dirty)
  947. ovl_roi(module, pConfig->dst_w, pConfig->dst_h, gOVLBackground, handle);
  948. if (!pConfig->ovl_dirty)
  949. return 0;
  950. /* check if we has sec layer */
  951. for (i = layer_min; i < layer_max; i++) {
  952. if (pConfig->ovl_config[i].layer_en &&
  953. (pConfig->ovl_config[i].security == DISP_SECURE_BUFFER))
  954. has_sec_layer = 1;
  955. }
  956. if (!ovl_idx)
  957. cmdq_engine = CMDQ_ENG_DISP_OVL0;
  958. else
  959. cmdq_engine = CMDQ_ENG_DISP_OVL1;
  960. if (has_sec_layer) {
  961. cmdqRecSetSecure(handle, 1);
  962. /* set engine as sec */
  963. cmdqRecSecureEnablePortSecurity(handle, (1LL << cmdq_engine));
  964. /* cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine)); */
  965. if (ovl_is_sec[ovl_idx] == 0)
  966. DDPMSG("[SVP] switch ovl%d to sec\n", ovl_idx);
  967. ovl_is_sec[ovl_idx] = 1;
  968. } else {
  969. if (ovl_is_sec[ovl_idx] == 1 && !primary_display_is_ovl1to2_handle(handle)) {
  970. /* ovl is in sec stat, we need to switch it to nonsec */
  971. static cmdqRecHandle nonsec_switch_handle;
  972. int ret;
  973. /* BAD WROKAROUND for SVP path. */
  974. /* Need to wait for last secure frame done before OVL switch to non-secure. */
  975. /* Add 16msec delay to gurantee the trigger loop is already get the TE event and */
  976. /* start to send last secure frame to LCM. */
  977. /* msleep(16); */
  978. usleep_range(16000, 17000);
  979. /* */
  980. ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_PRIMARY_DISABLE_SECURE_PATH,
  981. &(nonsec_switch_handle));
  982. if (ret)
  983. DDPAEE("[SVP]fail to create disable handle %s ret=%d\n",
  984. __func__, ret);
  985. cmdqRecReset(nonsec_switch_handle);
  986. _cmdq_insert_wait_frame_done_token_mira(nonsec_switch_handle);
  987. cmdqRecSetSecure(nonsec_switch_handle, 1);
  988. /* we should disable ovl before new (nonsec) setting take effect
  989. * or translation fault may happen,
  990. * if we switch ovl to nonsec BUT its setting is still sec */
  991. DISP_REG_SET(nonsec_switch_handle,
  992. DISP_REG_OVL_SRC_CON + (module -
  993. DISP_MODULE_OVL0) *
  994. DISP_OVL_INDEX_OFFSET, 0);
  995. for (i = 0; i < 4; i++)
  996. ovl_layer_switch(module, i, 0, nonsec_switch_handle);
  997. /*in fact, dapc/port_sec will be disabled by cmdq */
  998. cmdqRecSecureEnablePortSecurity(nonsec_switch_handle, (1LL << cmdq_engine));
  999. /* cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine)); */
  1000. cmdqRecFlush(nonsec_switch_handle);
  1001. cmdqRecDestroy(nonsec_switch_handle);
  1002. DDPMSG("[SVP] switch ovl%d to nonsec\n", ovl_idx);
  1003. }
  1004. ovl_is_sec[ovl_idx] = 0;
  1005. }
  1006. for (i = layer_min; i < layer_max; i++) {
  1007. if (pConfig->ovl_config[i].layer_en != 0) {
  1008. if (ovl_check_input_param(&pConfig->ovl_config[i]))
  1009. continue;
  1010. /* if AEE=1, assert layer addr must equal to asert_pa or
  1011. * reg value is not equal to assert_pa(maybe 0 after suspend)
  1012. */
  1013. if (module == DISP_MODULE_OVL0 &&
  1014. i == (layer_max - 1) &&
  1015. isAEEEnabled && pConfig->ovl_config[i].addr == 0) {
  1016. DDPMLOG
  1017. ("O - assert layer skip. O%d/L%d/LMax%d/mva0x%lx,reg_addr=0x%x\n",
  1018. module, i, layer_max, pConfig->ovl_config[i].addr,
  1019. DISP_REG_GET(DISP_REG_OVL_L3_ADDR));
  1020. ovl_layer_switch(module, (i + layer_min) % 4,
  1021. pConfig->ovl_config[i].layer_en, handle);
  1022. layer_enable |= (1 << ((i + layer_min) % 4));
  1023. continue;
  1024. }
  1025. if (module == DISP_MODULE_OVL0 && DISP_REG_GET(DISP_REG_OVL_EN) == 0) {
  1026. /* DDPERR("OVL0 EN=0 while config, force set to 1!\n"); */
  1027. DISP_REG_SET(handle, DISP_REG_OVL_EN, 1);
  1028. }
  1029. if (module == DISP_MODULE_OVL1
  1030. && DISP_REG_GET(DISP_REG_OVL_EN + DISP_OVL_INDEX_OFFSET) == 0) {
  1031. /* DDPERR("OVL1 EN=0 while config, force set to 1!\n"); */
  1032. DISP_REG_SET(handle, DISP_REG_OVL_EN + DISP_OVL_INDEX_OFFSET, 1);
  1033. }
  1034. ovl_layer_config(module, (i + layer_min) % 4, pConfig->ovl_config[i].source,
  1035. pConfig->ovl_config[i].fmt, pConfig->ovl_config[i].addr,
  1036. pConfig->ovl_config[i].src_x, pConfig->ovl_config[i].src_y,
  1037. pConfig->ovl_config[i].src_pitch, pConfig->ovl_config[i].dst_x,
  1038. pConfig->ovl_config[i].dst_y, pConfig->ovl_config[i].dst_w,
  1039. pConfig->ovl_config[i].dst_h, pConfig->ovl_config[i].keyEn,
  1040. pConfig->ovl_config[i].key, pConfig->ovl_config[i].aen,
  1041. pConfig->ovl_config[i].alpha, pConfig->ovl_config[i].sur_aen,
  1042. pConfig->ovl_config[i].src_alpha, pConfig->ovl_config[i].dst_alpha,
  1043. 0xff000000, /* constant_color */
  1044. pConfig->ovl_config[i].yuv_range,
  1045. pConfig->ovl_config[i].security, has_sec_layer, handle, pConfig->is_memory);
  1046. DDPMLOG("O%d/L%d/S%d/%s/0x%lx/(%d,%d)/P%d/(%d,%d,%d,%d).\n",
  1047. module - DISP_MODULE_OVL0,
  1048. i,
  1049. pConfig->ovl_config[i].source,
  1050. ovl_intput_format_name(ovl_input_fmt_convert
  1051. (pConfig->ovl_config[i].fmt),
  1052. ovl_input_fmt_byte_swap(ovl_input_fmt_convert
  1053. (pConfig->
  1054. ovl_config[i].
  1055. fmt))),
  1056. pConfig->ovl_config[i].addr, pConfig->ovl_config[i].src_x,
  1057. pConfig->ovl_config[i].src_y, pConfig->ovl_config[i].src_pitch,
  1058. pConfig->ovl_config[i].dst_x, pConfig->ovl_config[i].dst_y,
  1059. pConfig->ovl_config[i].dst_w, pConfig->ovl_config[i].dst_h);
  1060. MMProfileLogEx(ddp_mmp_get_events()->ovl_enable, MMProfileFlagPulse,
  1061. ((module - DISP_MODULE_OVL0) << 4) + ((i + layer_min) % 4),
  1062. pConfig->ovl_config[i].addr);
  1063. } else {
  1064. /* from enable to disable */
  1065. if (DISP_REG_GET
  1066. (DISP_REG_OVL_SRC_CON +
  1067. (module -
  1068. DISP_MODULE_OVL0) * DISP_OVL_INDEX_OFFSET) & (0x1 << ((i +
  1069. layer_min) %
  1070. 4))) {
  1071. /* DDPMLOG("disable L%d.\n",i%4); */
  1072. MMProfileLogEx(ddp_mmp_get_events()->ovl_disable,
  1073. MMProfileFlagPulse,
  1074. ((module - DISP_MODULE_OVL0) << 4) +
  1075. ((i + layer_min) % 4), 0);
  1076. }
  1077. }
  1078. ovl_layer_switch(module, (i + layer_min) % 4,
  1079. pConfig->ovl_config[i].layer_en, handle);
  1080. if (pConfig->ovl_config[i].layer_en == 1)
  1081. layer_enable |= (1 << ((i + layer_min) % 4));
  1082. }
  1083. /* config layer once without write with mask */
  1084. DISP_REG_SET(handle,
  1085. DISP_REG_OVL_SRC_CON + (module - DISP_MODULE_OVL0) * DISP_OVL_INDEX_OFFSET,
  1086. layer_enable);
  1087. return 0;
  1088. }
  1089. int ovl_build_cmdq(DISP_MODULE_ENUM module, void *cmdq_trigger_handle, CMDQ_STATE state)
  1090. {
  1091. int ret = 0;
  1092. if (cmdq_trigger_handle == NULL) {
  1093. DDPERR("cmdq_trigger_handle is NULL\n");
  1094. return -1;
  1095. }
  1096. if (primary_display_is_video_mode() == 1 && primary_display_is_decouple_mode() == 0) {
  1097. if (state == CMDQ_CHECK_IDLE_AFTER_STREAM_EOF) {
  1098. if (module == DISP_MODULE_OVL0) {
  1099. ret =
  1100. cmdqRecPoll(cmdq_trigger_handle, DISP_REG_OVL0_STATE_PA, 2,
  1101. 0x3ff);
  1102. } else if (module == DISP_MODULE_OVL1) {
  1103. ret =
  1104. cmdqRecPoll(cmdq_trigger_handle, DISP_REG_OVL1_STATE_PA, 2,
  1105. 0x3ff);
  1106. } else {
  1107. DDPERR("wrong module: %s\n", ddp_get_module_name(module));
  1108. return -1;
  1109. }
  1110. }
  1111. }
  1112. return 0;
  1113. }
  1114. /***************** ovl debug info ************/
  1115. void ovl_dump_reg(DISP_MODULE_ENUM module)
  1116. {
  1117. int idx = ovl_index(module);
  1118. unsigned int offset = idx * DISP_OVL_INDEX_OFFSET;
  1119. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset);
  1120. DDPDUMP("== DISP OVL%d REGS ==\n", idx);
  1121. DDPDUMP("OVL:0x000=0x%08x,0x004=0x%08x,0x008=0x%08x,0x00c=0x%08x\n",
  1122. DISP_REG_GET(DISP_REG_OVL_STA + offset),
  1123. DISP_REG_GET(DISP_REG_OVL_INTEN + offset),
  1124. DISP_REG_GET(DISP_REG_OVL_INTSTA + offset), DISP_REG_GET(DISP_REG_OVL_EN + offset));
  1125. DDPDUMP("OVL:0x010=0x%08x,0x014=0x%08x,0x020=0x%08x,0x024=0x%08x\n",
  1126. DISP_REG_GET(DISP_REG_OVL_TRIG + offset),
  1127. DISP_REG_GET(DISP_REG_OVL_RST + offset),
  1128. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset),
  1129. DISP_REG_GET(DISP_REG_OVL_DATAPATH_CON + offset));
  1130. DDPDUMP("OVL:0x028=0x%08x,0x02c=0x%08x\n",
  1131. DISP_REG_GET(DISP_REG_OVL_ROI_BGCLR + offset),
  1132. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset));
  1133. if (src_on & 0x1) {
  1134. DDPDUMP("OVL:0x030=0x%08x,0x034=0x%08x,0x038=0x%08x,0x03c=0x%08x\n",
  1135. DISP_REG_GET(DISP_REG_OVL_L0_CON + offset),
  1136. DISP_REG_GET(DISP_REG_OVL_L0_SRCKEY + offset),
  1137. DISP_REG_GET(DISP_REG_OVL_L0_SRC_SIZE + offset),
  1138. DISP_REG_GET(DISP_REG_OVL_L0_OFFSET + offset));
  1139. DDPDUMP("OVL:0xf40=0x%08x,0x044=0x%08x,0x0c0=0x%08x,0x0c8=0x%08x,0x0d0=0x%08x\n",
  1140. DISP_REG_GET(DISP_REG_OVL_L0_ADDR + offset),
  1141. DISP_REG_GET(DISP_REG_OVL_L0_PITCH + offset),
  1142. DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + offset),
  1143. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + offset),
  1144. DISP_REG_GET(DISP_REG_OVL_RDMA0_FIFO_CTRL + offset));
  1145. DDPDUMP("OVL:0x1e0=0x%08x,0x24c=0x%08x\n",
  1146. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_S2 + offset),
  1147. DISP_REG_GET(DISP_REG_OVL_RDMA0_DBG + offset));
  1148. }
  1149. if (src_on & 0x2) {
  1150. DDPDUMP("OVL:0x050=0x%08x,0x054=0x%08x,0x058=0x%08x,0x05c=0x%08x\n",
  1151. DISP_REG_GET(DISP_REG_OVL_L1_CON + offset),
  1152. DISP_REG_GET(DISP_REG_OVL_L1_SRCKEY + offset),
  1153. DISP_REG_GET(DISP_REG_OVL_L1_SRC_SIZE + offset),
  1154. DISP_REG_GET(DISP_REG_OVL_L1_OFFSET + offset));
  1155. DDPDUMP("OVL:0xf60=0x%08x,0x064=0x%08x,0x0e0=0x%08x,0x0e8=0x%08x,0x0f0=0x%08x\n",
  1156. DISP_REG_GET(DISP_REG_OVL_L1_ADDR + offset),
  1157. DISP_REG_GET(DISP_REG_OVL_L1_PITCH + offset),
  1158. DISP_REG_GET(DISP_REG_OVL_RDMA1_CTRL + offset),
  1159. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_SETTING + offset),
  1160. DISP_REG_GET(DISP_REG_OVL_RDMA1_FIFO_CTRL + offset));
  1161. DDPDUMP("OVL:0x1e4=0x%08x,0x250=0x%08x\n",
  1162. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_S2 + offset),
  1163. DISP_REG_GET(DISP_REG_OVL_RDMA1_DBG + offset));
  1164. }
  1165. if (src_on & 0x4) {
  1166. DDPDUMP("OVL:0x070=0x%08x,0x074=0x%08x,0x078=0x%08x,0x07c=0x%08x\n",
  1167. DISP_REG_GET(DISP_REG_OVL_L2_CON + offset),
  1168. DISP_REG_GET(DISP_REG_OVL_L2_SRCKEY + offset),
  1169. DISP_REG_GET(DISP_REG_OVL_L2_SRC_SIZE + offset),
  1170. DISP_REG_GET(DISP_REG_OVL_L2_OFFSET + offset));
  1171. DDPDUMP("OVL:0xf80=0x%08x,0x084=0x%08x,0x100=0x%08x,0x110=0x%08x\n",
  1172. DISP_REG_GET(DISP_REG_OVL_L2_ADDR + offset),
  1173. DISP_REG_GET(DISP_REG_OVL_L2_PITCH + offset),
  1174. DISP_REG_GET(DISP_REG_OVL_RDMA2_CTRL + offset),
  1175. DISP_REG_GET(DISP_REG_OVL_RDMA2_FIFO_CTRL + offset));
  1176. DDPDUMP("OVL:0x1e8=0x%08x,0x254=0x%08x\n",
  1177. DISP_REG_GET(DISP_REG_OVL_RDMA2_MEM_GMC_S2 + offset),
  1178. DISP_REG_GET(DISP_REG_OVL_RDMA2_DBG + offset));
  1179. }
  1180. if (src_on & 0x8) {
  1181. DDPDUMP("OVL:0x090=0x%08x,0x094=0x%08x,0x098=0x%08x,0x09c=0x%08x\n",
  1182. DISP_REG_GET(DISP_REG_OVL_L3_CON + offset),
  1183. DISP_REG_GET(DISP_REG_OVL_L3_SRCKEY + offset),
  1184. DISP_REG_GET(DISP_REG_OVL_L3_SRC_SIZE + offset),
  1185. DISP_REG_GET(DISP_REG_OVL_L3_OFFSET + offset));
  1186. DDPDUMP("OVL:0xfa0=0x%08x,0x0a4=0x%08x,0x120=0x%08x,0x130=0x%08x\n",
  1187. DISP_REG_GET(DISP_REG_OVL_L3_ADDR + offset),
  1188. DISP_REG_GET(DISP_REG_OVL_L3_PITCH + offset),
  1189. DISP_REG_GET(DISP_REG_OVL_RDMA3_CTRL + offset),
  1190. DISP_REG_GET(DISP_REG_OVL_RDMA3_FIFO_CTRL + offset));
  1191. DDPDUMP("OVL:0x1ec=0x%08x,0x258=0x%08x\n",
  1192. DISP_REG_GET(DISP_REG_OVL_RDMA3_MEM_GMC_S2 + offset),
  1193. DISP_REG_GET(DISP_REG_OVL_RDMA3_DBG + offset));
  1194. }
  1195. DDPDUMP("OVL:0x1d4=0x%08x,0x200=0x%08x,0x240=0x%08x,0x244=0x%08x\n",
  1196. DISP_REG_GET(DISP_REG_OVL_DEBUG_MON_SEL + offset),
  1197. DISP_REG_GET(DISP_REG_OVL_DUMMY_REG + offset),
  1198. DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset),
  1199. DISP_REG_GET(DISP_REG_OVL_ADDCON_DBG + offset));
  1200. DDPDUMP("OVL:0x25c=0x%08x,0x260=0x%08x,0x264=0x%08x,0x268=0x%08x\n",
  1201. DISP_REG_GET(DISP_REG_OVL_L0_CLR + offset),
  1202. DISP_REG_GET(DISP_REG_OVL_L1_CLR + offset),
  1203. DISP_REG_GET(DISP_REG_OVL_L2_CLR + offset),
  1204. DISP_REG_GET(DISP_REG_OVL_L3_CLR + offset));
  1205. }
  1206. static char *ovl_get_state_name(unsigned int status)
  1207. {
  1208. switch (status & 0x3ff) {
  1209. case 0x1:
  1210. return "idle";
  1211. case 0x2:
  1212. return "wait_SOF";
  1213. case 0x4:
  1214. return "prepare";
  1215. case 0x8:
  1216. return "reg_update";
  1217. case 0x10:
  1218. return "eng_clr(internal reset)";
  1219. case 0x20:
  1220. return "eng_act(processing)";
  1221. case 0x40:
  1222. return "h_wait_w_rst";
  1223. case 0x80:
  1224. return "s_wait_w_rst";
  1225. case 0x100:
  1226. return "h_w_rst";
  1227. case 0x200:
  1228. return "s_w_rst";
  1229. default:
  1230. return "ovl_fsm_unknown";
  1231. }
  1232. }
  1233. static void ovl_printf_status(int idx, unsigned int status)
  1234. {
  1235. #if 0
  1236. DDPDUMP("=OVL%d_FLOW_CONTROL_DEBUG=:\n", idx);
  1237. DDPDUMP("addcon_idle:%d,blend_idle:%d,out_valid:%d,out_ready:%d,out_idle:%d\n",
  1238. (status >> 10) & (0x1),
  1239. (status >> 11) & (0x1),
  1240. (status >> 12) & (0x1), (status >> 13) & (0x1), (status >> 15) & (0x1)
  1241. );
  1242. DDPDUMP("rdma3_idle:%d,rdma2_idle:%d,rdma1_idle:%d, rdma0_idle:%d,rst:%d\n",
  1243. (status >> 16) & (0x1),
  1244. (status >> 17) & (0x1),
  1245. (status >> 18) & (0x1), (status >> 19) & (0x1), (status >> 20) & (0x1)
  1246. );
  1247. DDPDUMP("trig:%d,frame_hwrst_done:%d,frame_swrst_done:%d,frame_underrun:%d,frame_done:%d\n",
  1248. (status >> 21) & (0x1),
  1249. (status >> 23) & (0x1),
  1250. (status >> 24) & (0x1), (status >> 25) & (0x1), (status >> 26) & (0x1)
  1251. );
  1252. DDPDUMP("ovl_running:%d,ovl_start:%d,ovl_clr:%d,reg_update:%d,ovl_upd_reg:%d\n",
  1253. (status >> 27) & (0x1),
  1254. (status >> 28) & (0x1),
  1255. (status >> 29) & (0x1), (status >> 30) & (0x1), (status >> 31) & (0x1)
  1256. );
  1257. #endif
  1258. DDPDUMP("ovl%d, state=0x%x, fms_state:%s\n", idx, status, ovl_get_state_name(status));
  1259. }
  1260. void ovl_dump_analysis(DISP_MODULE_ENUM module)
  1261. {
  1262. int i = 0;
  1263. unsigned int layer_offset = 0;
  1264. unsigned int rdma_offset = 0;
  1265. int index = ovl_index(module);
  1266. unsigned int offset = index * DISP_OVL_INDEX_OFFSET;
  1267. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset);
  1268. DDPDUMP("==DISP OVL%d ANALYSIS==\n", index);
  1269. DDPDUMP("ovl_en=%d,layer_enable(%d,%d,%d,%d),bg(w=%d, h=%d),\n",
  1270. DISP_REG_GET(DISP_REG_OVL_EN + offset),
  1271. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) & 0x1,
  1272. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 1) & 0x1,
  1273. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 2) & 0x1,
  1274. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 3) & 0x1,
  1275. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) & 0xfff,
  1276. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) >> 16) & 0xfff);
  1277. DDPDUMP("cur_pos(x=%d,y=%d),layer_hit(%d,%d,%d,%d), ovl_complete_cnt=(%d, %d)\n",
  1278. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_X, DISP_REG_OVL_ADDCON_DBG + offset),
  1279. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_Y, DISP_REG_OVL_ADDCON_DBG + offset),
  1280. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L0_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1281. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L1_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1282. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L2_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1283. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L3_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1284. ovl_complete_irq_cnt[0], ovl_complete_irq_cnt[1]);
  1285. for (i = 0; i < 4; i++) {
  1286. layer_offset = i * OVL_LAYER_OFFSET + offset;
  1287. rdma_offset = i * OVL_RDMA_DEBUG_OFFSET + offset;
  1288. if (src_on & (0x1 << i)) {
  1289. DDPDUMP
  1290. ("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",
  1291. i, DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff,
  1292. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) >> 16) & 0xfff,
  1293. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) & 0xfff,
  1294. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) >> 16) & 0xfff,
  1295. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_PITCH) & 0xffff,
  1296. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_ADDR),
  1297. ovl_intput_format_name(DISP_REG_GET_FIELD
  1298. (L_CON_FLD_CFMT,
  1299. DISP_REG_OVL_L0_CON + layer_offset),
  1300. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  1301. DISP_REG_OVL_L0_CON +
  1302. layer_offset)),
  1303. (DISP_REG_GET_FIELD(L_CON_FLD_LARC, DISP_REG_OVL_L0_CON + layer_offset)
  1304. == 0) ? "memory" : "constant_color", DISP_REG_GET_FIELD(L_CON_FLD_AEN,
  1305. DISP_REG_OVL_L0_CON
  1306. +
  1307. layer_offset),
  1308. DISP_REG_GET_FIELD(L_CON_FLD_APHA, DISP_REG_OVL_L0_CON + layer_offset)
  1309. );
  1310. DDPDUMP("ovl rdma%d status:(en %d)\n", i,
  1311. DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_CTRL));
  1312. }
  1313. }
  1314. ovl_printf_status(index, DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset));
  1315. }
  1316. int ovl_dump(DISP_MODULE_ENUM module, int level)
  1317. {
  1318. ovl_dump_analysis(module);
  1319. ovl_dump_reg(module);
  1320. return 0;
  1321. }
  1322. static int ovl_io(DISP_MODULE_ENUM module, int msg, unsigned long arg, void *cmdq)
  1323. {
  1324. int ret = 0;
  1325. if (module != DISP_MODULE_OVL0 && module != DISP_MODULE_OVL1) {
  1326. DDPDUMP("error, ovl_io unknown module=%d\n", module);
  1327. ret = -1;
  1328. return ret;
  1329. }
  1330. switch (msg) {
  1331. case DISP_IOCTL_OVL_ENABLE_CASCADE:
  1332. {
  1333. DDPDUMP("enable cascade ovl1\n");
  1334. DISP_REG_SET_FIELD(cmdq, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  1335. DISP_REG_OVL_DATAPATH_CON, 1);
  1336. /* when add ovl1 to path, dst_dirty may be not 1, so we have to call ovl_roi */
  1337. ovl_roi(DISP_MODULE_OVL1,
  1338. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE) & 0xfff,
  1339. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE) >> 16) & 0xfff,
  1340. gOVLBackground, cmdq);
  1341. /* ovl1_status = DDP_OVL1_STATUS_PRIMARY; */
  1342. break;
  1343. }
  1344. case DISP_IOCTL_OVL_DISABLE_CASCADE:
  1345. {
  1346. DDPDUMP("disable cascade ovl1\n");
  1347. DISP_REG_SET_FIELD(cmdq, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  1348. DISP_REG_OVL_DATAPATH_CON, 0);
  1349. /* ovl1_status = DDP_OVL1_STATUS_IDLE; */
  1350. break;
  1351. }
  1352. default:
  1353. DDPDUMP("error: unknown cmd=%d\n", msg);
  1354. }
  1355. return ret;
  1356. }
  1357. /***************** driver************/
  1358. DDP_MODULE_DRIVER ddp_driver_ovl = {
  1359. .init = ovl_init,
  1360. .deinit = ovl_deinit,
  1361. .config = ovl_config_l,
  1362. .start = ovl_start,
  1363. .trigger = NULL,
  1364. .stop = ovl_stop,
  1365. .reset = ovl_reset,
  1366. .power_on = ovl_clock_on,
  1367. .power_off = ovl_clock_off,
  1368. .suspend = ovl_suspend,
  1369. .resume = ovl_resume,
  1370. .is_idle = NULL,
  1371. .is_busy = NULL,
  1372. .dump_info = ovl_dump,
  1373. .bypass = NULL,
  1374. .build_cmdq = NULL,
  1375. .set_lcm_utils = NULL,
  1376. .cmd = ovl_io,
  1377. };