ddp_ovl.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502
  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, fmt=%s, addr=%lx,\n",
  470. idx, layer, (source == 0) ? "memory" : "dim", src_x, src_y, dst_x, dst_y,
  471. dst_w, dst_h, src_pitch, ovl_intput_format_name(fmt, input_swap));
  472. DDPMSG("keyEn=%d, key=%d, aen=%d, alpha=%d, sur_aen=%d,sur_alpha=0x%x, constant_color=0x%x, yuv_range=%d,\n",
  473. addr, key_en, key, aen, alpha, sur_aen, dst_alpha << 2 | src_alpha, constant_color, yuv_range);
  474. DDPMSG("sec=%d,ovlsec=%d\n", sec, is_engine_sec);
  475. #endif
  476. if (source == OVL_LAYER_SOURCE_RESERVED) { /* ==1, means constant color */
  477. if (aen == 0)
  478. DDPERR("dim layer ahpha enable should be 1!\n");
  479. if (fmt != OVL_INPUT_FORMAT_RGB565 && fmt != OVL_INPUT_FORMAT_RGB888) {
  480. /* DDPERR("dim layer format should be RGB565"); */
  481. fmt = OVL_INPUT_FORMAT_RGB888;
  482. input_fmt = ovl_input_fmt_reg_value(fmt);
  483. }
  484. }
  485. /* DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1); */
  486. value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) |
  487. REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) |
  488. REG_FLD_VAL((L_CON_FLD_AEN), (aen)) |
  489. REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) |
  490. REG_FLD_VAL((L_CON_FLD_SKEN), (key_en)) |
  491. REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap)));
  492. if (space == OVL_COLOR_SPACE_YUV)
  493. value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix));
  494. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  495. if (!is_memory)
  496. value |= 0x600;
  497. #endif
  498. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CON + layer_offset, value);
  499. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CLR + idx_offset + layer * 4, constant_color);
  500. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_SRC_SIZE + layer_offset, dst_h << 16 | dst_w);
  501. #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW
  502. if (!is_memory) {
  503. bg_h = DISP_REG_GET(idx_offset + DISP_REG_OVL_ROI_SIZE);
  504. bg_w = bg_h & 0xFFFF;
  505. bg_h = bg_h >> 16;
  506. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET + layer_offset,
  507. ((bg_h - dst_h - dst_y) << 16) | (bg_w - dst_w - dst_x));
  508. } else {
  509. DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET + layer_offset,
  510. 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. }
  638. ovl_clock_cnt[idx]++;
  639. #endif
  640. return 0;
  641. }
  642. int ovl_clock_off(DISP_MODULE_ENUM module, void *handle)
  643. {
  644. int idx = ovl_index(module);
  645. DDPMSG("ovl%d_clock_off\n", idx);
  646. #ifdef ENABLE_CLK_MGR
  647. if (ovl_clock_cnt[idx] == 0) {
  648. DDPERR("ovl_deinit, clock off OVL%d, but it's already off!\n", idx);
  649. return 0;
  650. }
  651. if (idx == 0) {
  652. #ifdef CONFIG_MTK_CLKMGR
  653. disable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0");
  654. #else
  655. ddp_clk_disable(DISP0_DISP_OVL0);
  656. #endif
  657. }
  658. ovl_clock_cnt[idx]--;
  659. #endif
  660. return 0;
  661. }
  662. int ovl_resume(DISP_MODULE_ENUM module, void *handle)
  663. {
  664. int idx = ovl_index(module);
  665. DDPMSG("ovl%d_resume\n", idx);
  666. #ifdef ENABLE_CLK_MGR
  667. if (idx == 0) {
  668. #ifdef CONFIG_MTK_CLKMGR
  669. enable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0");
  670. #else
  671. ddp_clk_enable(DISP0_DISP_OVL0);
  672. #endif
  673. }
  674. #endif
  675. ovl_restore_regs(module, handle);
  676. return 0;
  677. }
  678. int ovl_suspend(DISP_MODULE_ENUM module, void *handle)
  679. {
  680. int idx = ovl_index(module);
  681. DDPMSG("ovl%d_suspend\n", idx);
  682. ovl_store_regs(module);
  683. #ifdef ENABLE_CLK_MGR
  684. if (idx == 0) {
  685. #ifdef CONFIG_MTK_CLKMGR
  686. disable_clock(MT_CG_DISP0_DISP_OVL0 + idx, "OVL0");
  687. #else
  688. ddp_clk_disable(DISP0_DISP_OVL0 + idx);
  689. #endif
  690. } else {
  691. #ifdef CONFIG_MTK_CLKMGR
  692. disable_clock(MT_CG_DISP0_DISP_OVL0 + idx, "OVL1");
  693. #else
  694. ddp_clk_disable(DISP0_DISP_OVL0 + idx);
  695. #endif
  696. }
  697. #endif
  698. return 0;
  699. }
  700. int ovl_init(DISP_MODULE_ENUM module, void *handle)
  701. {
  702. ovl_clock_on(module, handle);
  703. return 0;
  704. }
  705. int ovl_deinit(DISP_MODULE_ENUM module, void *handle)
  706. {
  707. ovl_clock_off(module, handle);
  708. return 0;
  709. }
  710. unsigned int ddp_ovl_get_cur_addr(bool rdma_mode, int layerid)
  711. {
  712. if (rdma_mode)
  713. return DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR);
  714. #ifdef OVL_CASCADE_SUPPORT
  715. /* OVL 1 */
  716. if (layerid < 4 && (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY ||
  717. ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_RELEASING ||
  718. ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING)) {
  719. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + DISP_OVL_INDEX_OFFSET + layerid * 0x20) & 0x1)
  720. return DISP_REG_GET(DISP_REG_OVL_L0_ADDR + DISP_OVL_INDEX_OFFSET + layerid * 0x20);
  721. else
  722. return 0;
  723. } else { /* OVL 0 */
  724. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + (layerid % 4) * 0x20) & 0x1)
  725. return DISP_REG_GET(DISP_REG_OVL_L0_ADDR + (layerid % 4) * 0x20);
  726. else
  727. return 0;
  728. }
  729. #else
  730. if (DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + layerid * 0x20) & 0x1)
  731. return DISP_REG_GET(DISP_REG_OVL_L0_ADDR + layerid * 0x20);
  732. else
  733. return 0;
  734. #endif
  735. }
  736. void ovl_get_address(DISP_MODULE_ENUM module, unsigned long *add)
  737. {
  738. int i = 0;
  739. int idx = ovl_index(module);
  740. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  741. unsigned int layer_off = 0;
  742. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  743. for (i = 0; i < 4; i++) {
  744. layer_off = i * OVL_LAYER_OFFSET + idx_offset;
  745. if (src_on & (0x1 << i))
  746. add[i] = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  747. else
  748. add[i] = 0;
  749. }
  750. }
  751. void ovl_get_info(int idx, void *data)
  752. {
  753. int i = 0;
  754. OVL_BASIC_STRUCT *pdata = (OVL_BASIC_STRUCT *) data;
  755. unsigned int idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  756. unsigned int layer_off = 0;
  757. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  758. OVL_BASIC_STRUCT *p = NULL;
  759. memset(pdata, 0, sizeof(OVL_BASIC_STRUCT) * OVL_LAYER_NUM);
  760. if (ovl_get_status() == DDP_OVL1_STATUS_SUB || ovl_get_status() == DDP_OVL1_STATUS_IDLE) { /* 4+4 mode */
  761. /* idx=0; */
  762. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  763. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  764. for (i = 0; i < OVL_LAYER_NUM_PER_OVL; i++) {
  765. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  766. p = &pdata[i];
  767. p->layer = i;
  768. p->layer_en = src_on & (0x1 << i);
  769. if (p->layer_en) {
  770. p->fmt =
  771. (unsigned int)
  772. ovl_input_fmt(DISP_REG_GET_FIELD
  773. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  774. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  775. layer_off +
  776. DISP_REG_OVL_L0_CON));
  777. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  778. p->src_w =
  779. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  780. p->src_h =
  781. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  782. 0xfff;
  783. p->src_pitch =
  784. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  785. p->bpp =
  786. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  787. (L_CON_FLD_CFMT,
  788. layer_off + DISP_REG_OVL_L0_CON));
  789. }
  790. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  791. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  792. }
  793. } else {
  794. idx = 0;
  795. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  796. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  797. for (i = OVL_LAYER_NUM_PER_OVL; i < OVL_LAYER_NUM; i++) {
  798. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  799. p = &pdata[i];
  800. p->layer = i;
  801. p->layer_en = src_on & (0x1 << (i % 4));
  802. if (p->layer_en) {
  803. p->fmt =
  804. (unsigned int)
  805. ovl_input_fmt(DISP_REG_GET_FIELD
  806. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  807. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  808. layer_off +
  809. DISP_REG_OVL_L0_CON));
  810. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  811. p->src_w =
  812. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  813. p->src_h =
  814. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  815. 0xfff;
  816. p->src_pitch =
  817. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  818. p->bpp =
  819. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  820. (L_CON_FLD_CFMT,
  821. layer_off + DISP_REG_OVL_L0_CON));
  822. }
  823. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  824. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  825. }
  826. idx = 1;
  827. idx_offset = idx * DISP_OVL_INDEX_OFFSET;
  828. src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset);
  829. for (i = 0; i < OVL_LAYER_NUM_PER_OVL; i++) {
  830. layer_off = (i % 4) * OVL_LAYER_OFFSET + idx_offset;
  831. p = &pdata[i];
  832. p->layer = i;
  833. p->layer_en = src_on & (0x1 << (i % 4));
  834. if (p->layer_en) {
  835. p->fmt =
  836. (unsigned int)
  837. ovl_input_fmt(DISP_REG_GET_FIELD
  838. (L_CON_FLD_CFMT, layer_off + DISP_REG_OVL_L0_CON),
  839. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  840. layer_off +
  841. DISP_REG_OVL_L0_CON));
  842. p->addr = DISP_REG_GET(layer_off + DISP_REG_OVL_L0_ADDR);
  843. p->src_w =
  844. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff;
  845. p->src_h =
  846. (DISP_REG_GET(layer_off + DISP_REG_OVL_L0_SRC_SIZE) >> 16) &
  847. 0xfff;
  848. p->src_pitch =
  849. DISP_REG_GET(layer_off + DISP_REG_OVL_L0_PITCH) & 0xffff;
  850. p->bpp =
  851. ovl_input_fmt_bpp(DISP_REG_GET_FIELD
  852. (L_CON_FLD_CFMT,
  853. layer_off + DISP_REG_OVL_L0_CON));
  854. }
  855. DDPMSG("ovl_get_info:layer%d,en %d,w %d,h %d,bpp %d,addr %lu\n",
  856. i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr);
  857. }
  858. }
  859. }
  860. static int ovl_check_input_param(OVL_CONFIG_STRUCT *config)
  861. {
  862. if ((config->addr == 0 && config->source == 0) || config->dst_w == 0 || config->dst_h == 0) {
  863. DDPERR("ovl parameter invalidate, addr=%lx, w=%d, h=%d\n",
  864. config->addr, config->dst_w, config->dst_h);
  865. ASSERT(0);
  866. return -1;
  867. }
  868. return 0;
  869. }
  870. void ovl_reset_by_cmdq(void *handle, DISP_MODULE_ENUM module)
  871. {
  872. /* warm reset ovl every time we use it */
  873. if (handle) {
  874. if ((primary_display_is_decouple_mode() == 1) ||
  875. (primary_display_is_video_mode() == 0)) {
  876. unsigned int offset;
  877. offset = ovl_index(module) * DISP_OVL_INDEX_OFFSET;
  878. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x1);
  879. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x0);
  880. cmdqRecPoll(handle, disp_addr_convert(DISP_REG_OVL_STA + offset), 0, 0x1);
  881. }
  882. }
  883. }
  884. static int ovl_is_sec[2];
  885. static int ovl_config_l(DISP_MODULE_ENUM module, disp_ddp_path_config *pConfig, void *handle)
  886. {
  887. int i = 0;
  888. unsigned int layer_min = 0;
  889. unsigned int layer_max = 0;
  890. int has_sec_layer = 0;
  891. int ovl_idx = ovl_index(module);
  892. CMDQ_ENG_ENUM cmdq_engine;
  893. int layer_enable = 0;
  894. #ifdef OVL_CASCADE_SUPPORT
  895. /* OVL0 always on top */
  896. if (module == DISP_MODULE_OVL0 && (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY ||
  897. ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING)) {
  898. layer_min = 4;
  899. layer_max = 8;
  900. } else {
  901. layer_min = 0;
  902. layer_max = 4;
  903. }
  904. #else
  905. layer_min = 0;
  906. layer_max = 4;
  907. #endif
  908. /* warm reset ovl every time we use it */
  909. if (handle) {
  910. if ((primary_display_is_decouple_mode() == 1) ||
  911. (primary_display_is_video_mode() == 0)) {
  912. unsigned int offset;
  913. offset = ovl_index(module) * DISP_OVL_INDEX_OFFSET;
  914. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x1);
  915. DISP_REG_SET(handle, DISP_REG_OVL_RST + offset, 0x0);
  916. cmdqRecPoll(handle, disp_addr_convert(DISP_REG_OVL_STA + offset), 0, 0x1);
  917. }
  918. }
  919. if (pConfig->dst_dirty || pConfig->roi_dirty)
  920. ovl_roi(module, pConfig->dst_w, pConfig->dst_h, gOVLBackground, handle);
  921. if (!pConfig->ovl_dirty)
  922. return 0;
  923. /* check if we has sec layer */
  924. for (i = layer_min; i < layer_max; i++) {
  925. if (pConfig->ovl_config[i].layer_en &&
  926. (pConfig->ovl_config[i].security == DISP_SECURE_BUFFER))
  927. has_sec_layer = 1;
  928. }
  929. if (!ovl_idx)
  930. cmdq_engine = CMDQ_ENG_DISP_OVL0;
  931. else
  932. cmdq_engine = CMDQ_ENG_DISP_OVL1;
  933. if (has_sec_layer) {
  934. cmdqRecSetSecure(handle, 1);
  935. /* set engine as sec */
  936. cmdqRecSecureEnablePortSecurity(handle, (1LL << cmdq_engine));
  937. /* cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine)); */
  938. if (ovl_is_sec[ovl_idx] == 0)
  939. DDPMSG("[SVP] switch ovl%d to sec\n", ovl_idx);
  940. ovl_is_sec[ovl_idx] = 1;
  941. } else {
  942. if (ovl_is_sec[ovl_idx] == 1) {
  943. /* ovl is in sec stat, we need to switch it to nonsec */
  944. static cmdqRecHandle nonsec_switch_handle;
  945. int ret;
  946. /* BAD WROKAROUND for SVP path. */
  947. /* Need to wait for last secure frame done before OVL switch to non-secure. */
  948. /* Add 16msec delay to gurantee the trigger loop is already get the TE event and */
  949. /* start to send last secure frame to LCM. */
  950. /* msleep(16); */
  951. usleep_range(16000, 17000);
  952. /* */
  953. ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_PRIMARY_DISABLE_SECURE_PATH,
  954. &(nonsec_switch_handle));
  955. if (ret)
  956. DDPAEE("[SVP]fail to create disable handle %s ret=%d\n",
  957. __func__, ret);
  958. cmdqRecReset(nonsec_switch_handle);
  959. _cmdq_insert_wait_frame_done_token_mira(nonsec_switch_handle);
  960. cmdqRecSetSecure(nonsec_switch_handle, 1);
  961. /* we should disable ovl before new (nonsec) setting take effect
  962. * or translation fault may happen,
  963. * if we switch ovl to nonsec BUT its setting is still sec */
  964. DISP_REG_SET(nonsec_switch_handle,
  965. DISP_REG_OVL_SRC_CON + (module -
  966. DISP_MODULE_OVL0) *
  967. DISP_OVL_INDEX_OFFSET, 0);
  968. for (i = 0; i < 4; i++)
  969. ovl_layer_switch(module, i, 0, nonsec_switch_handle);
  970. /*in fact, dapc/port_sec will be disabled by cmdq */
  971. cmdqRecSecureEnablePortSecurity(nonsec_switch_handle, (1LL << cmdq_engine));
  972. /* cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine)); */
  973. cmdqRecFlush(nonsec_switch_handle);
  974. cmdqRecDestroy(nonsec_switch_handle);
  975. DDPMSG("[SVP] switch ovl%d to nonsec\n", ovl_idx);
  976. }
  977. ovl_is_sec[ovl_idx] = 0;
  978. }
  979. for (i = layer_min; i < layer_max; i++) {
  980. if (pConfig->ovl_config[i].layer_en != 0) {
  981. if (ovl_check_input_param(&pConfig->ovl_config[i]))
  982. continue;
  983. /* if AEE=1, assert layer addr must equal to asert_pa or
  984. * reg value is not equal to assert_pa(maybe 0 after suspend)
  985. */
  986. if (module == DISP_MODULE_OVL0 &&
  987. i == (layer_max - 1) &&
  988. isAEEEnabled && pConfig->ovl_config[i].addr != get_Assert_Layer_PA()) {
  989. DDPMLOG
  990. ("O - assert layer skip. O%d/L%d/LMax%d/mva0x%lx,reg_addr=0x%x\n",
  991. module, i, layer_max, pConfig->ovl_config[i].addr,
  992. DISP_REG_GET(DISP_REG_OVL_L3_ADDR));
  993. ovl_layer_switch(module, i % 4, pConfig->ovl_config[i].layer_en,
  994. handle);
  995. layer_enable |= (1 << (i % 4));
  996. continue;
  997. }
  998. if (module == DISP_MODULE_OVL0 && DISP_REG_GET(DISP_REG_OVL_EN) == 0) {
  999. /* DDPERR("OVL0 EN=0 while config, force set to 1!\n"); */
  1000. DISP_REG_SET(handle, DISP_REG_OVL_EN, 1);
  1001. }
  1002. if (module == DISP_MODULE_OVL1
  1003. && DISP_REG_GET(DISP_REG_OVL_EN + DISP_OVL_INDEX_OFFSET) == 0) {
  1004. /* DDPERR("OVL1 EN=0 while config, force set to 1!\n"); */
  1005. DISP_REG_SET(handle, DISP_REG_OVL_EN + DISP_OVL_INDEX_OFFSET, 1);
  1006. }
  1007. ovl_layer_config(module, i % 4, pConfig->ovl_config[i].source,
  1008. pConfig->ovl_config[i].fmt, pConfig->ovl_config[i].addr,
  1009. pConfig->ovl_config[i].src_x, pConfig->ovl_config[i].src_y,
  1010. pConfig->ovl_config[i].src_pitch, pConfig->ovl_config[i].dst_x,
  1011. pConfig->ovl_config[i].dst_y, pConfig->ovl_config[i].dst_w,
  1012. pConfig->ovl_config[i].dst_h, pConfig->ovl_config[i].keyEn,
  1013. pConfig->ovl_config[i].key, pConfig->ovl_config[i].aen,
  1014. pConfig->ovl_config[i].alpha, pConfig->ovl_config[i].sur_aen,
  1015. pConfig->ovl_config[i].src_alpha, pConfig->ovl_config[i].dst_alpha,
  1016. 0xff000000, /* constant_color */
  1017. pConfig->ovl_config[i].yuv_range,
  1018. pConfig->ovl_config[i].security, has_sec_layer, handle, pConfig->is_memory);
  1019. DDPMLOG("O%d/L%d/S%d/%s/0x%lx/(%d,%d)/P%d/(%d,%d,%d,%d).\n",
  1020. module - DISP_MODULE_OVL0,
  1021. i,
  1022. pConfig->ovl_config[i].source,
  1023. ovl_intput_format_name(ovl_input_fmt_convert
  1024. (pConfig->ovl_config[i].fmt),
  1025. ovl_input_fmt_byte_swap(ovl_input_fmt_convert
  1026. (pConfig->
  1027. ovl_config[i].
  1028. fmt))),
  1029. pConfig->ovl_config[i].addr, pConfig->ovl_config[i].src_x,
  1030. pConfig->ovl_config[i].src_y, pConfig->ovl_config[i].src_pitch,
  1031. pConfig->ovl_config[i].dst_x, pConfig->ovl_config[i].dst_y,
  1032. pConfig->ovl_config[i].dst_w, pConfig->ovl_config[i].dst_h);
  1033. MMProfileLogEx(ddp_mmp_get_events()->ovl_enable, MMProfileFlagPulse,
  1034. ((module - DISP_MODULE_OVL0) << 4) + (i % 4),
  1035. pConfig->ovl_config[i].addr);
  1036. } else {
  1037. /* from enable to disable */
  1038. if (DISP_REG_GET
  1039. (DISP_REG_OVL_SRC_CON +
  1040. (module - DISP_MODULE_OVL0) * DISP_OVL_INDEX_OFFSET) & (0x1 << i)) {
  1041. /* DDPMLOG("disable L%d.\n",i%4); */
  1042. MMProfileLogEx(ddp_mmp_get_events()->ovl_disable,
  1043. MMProfileFlagPulse,
  1044. ((module - DISP_MODULE_OVL0) << 4) + (i % 4), 0);
  1045. }
  1046. }
  1047. ovl_layer_switch(module, i % 4, pConfig->ovl_config[i].layer_en, handle);
  1048. if (pConfig->ovl_config[i].layer_en == 1)
  1049. layer_enable |= (1 << (i % 4));
  1050. }
  1051. /* config layer once without write with mask */
  1052. DISP_REG_SET(handle,
  1053. DISP_REG_OVL_SRC_CON + (module - DISP_MODULE_OVL0) * DISP_OVL_INDEX_OFFSET,
  1054. layer_enable);
  1055. return 0;
  1056. }
  1057. int ovl_build_cmdq(DISP_MODULE_ENUM module, void *cmdq_trigger_handle, CMDQ_STATE state)
  1058. {
  1059. int ret = 0;
  1060. if (cmdq_trigger_handle == NULL) {
  1061. DDPERR("cmdq_trigger_handle is NULL\n");
  1062. return -1;
  1063. }
  1064. if (primary_display_is_video_mode() == 1 && primary_display_is_decouple_mode() == 0) {
  1065. if (state == CMDQ_CHECK_IDLE_AFTER_STREAM_EOF) {
  1066. if (module == DISP_MODULE_OVL0) {
  1067. ret =
  1068. cmdqRecPoll(cmdq_trigger_handle, DISP_REG_OVL0_STATE_PA, 2,
  1069. 0x3ff);
  1070. } else if (module == DISP_MODULE_OVL1) {
  1071. ret =
  1072. cmdqRecPoll(cmdq_trigger_handle, DISP_REG_OVL1_STATE_PA, 2,
  1073. 0x3ff);
  1074. } else {
  1075. DDPERR("wrong module: %s\n", ddp_get_module_name(module));
  1076. return -1;
  1077. }
  1078. }
  1079. }
  1080. return 0;
  1081. }
  1082. /***************** ovl debug info ************/
  1083. void ovl_dump_reg(DISP_MODULE_ENUM module)
  1084. {
  1085. int idx = ovl_index(module);
  1086. unsigned int offset = idx * DISP_OVL_INDEX_OFFSET;
  1087. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset);
  1088. DDPDUMP("== DISP OVL%d REGS ==\n", idx);
  1089. DDPDUMP("OVL:0x000=0x%08x,0x004=0x%08x,0x008=0x%08x,0x00c=0x%08x\n",
  1090. DISP_REG_GET(DISP_REG_OVL_STA + offset),
  1091. DISP_REG_GET(DISP_REG_OVL_INTEN + offset),
  1092. DISP_REG_GET(DISP_REG_OVL_INTSTA + offset), DISP_REG_GET(DISP_REG_OVL_EN + offset));
  1093. DDPDUMP("OVL:0x010=0x%08x,0x014=0x%08x,0x020=0x%08x,0x024=0x%08x\n",
  1094. DISP_REG_GET(DISP_REG_OVL_TRIG + offset),
  1095. DISP_REG_GET(DISP_REG_OVL_RST + offset),
  1096. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset),
  1097. DISP_REG_GET(DISP_REG_OVL_DATAPATH_CON + offset));
  1098. DDPDUMP("OVL:0x028=0x%08x,0x02c=0x%08x\n",
  1099. DISP_REG_GET(DISP_REG_OVL_ROI_BGCLR + offset),
  1100. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset));
  1101. if (src_on & 0x1) {
  1102. DDPDUMP("OVL:0x030=0x%08x,0x034=0x%08x,0x038=0x%08x,0x03c=0x%08x\n",
  1103. DISP_REG_GET(DISP_REG_OVL_L0_CON + offset),
  1104. DISP_REG_GET(DISP_REG_OVL_L0_SRCKEY + offset),
  1105. DISP_REG_GET(DISP_REG_OVL_L0_SRC_SIZE + offset),
  1106. DISP_REG_GET(DISP_REG_OVL_L0_OFFSET + offset));
  1107. DDPDUMP("OVL:0xf40=0x%08x,0x044=0x%08x,0x0c0=0x%08x,0x0c8=0x%08x,0x0d0=0x%08x\n",
  1108. DISP_REG_GET(DISP_REG_OVL_L0_ADDR + offset),
  1109. DISP_REG_GET(DISP_REG_OVL_L0_PITCH + offset),
  1110. DISP_REG_GET(DISP_REG_OVL_RDMA0_CTRL + offset),
  1111. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING + offset),
  1112. DISP_REG_GET(DISP_REG_OVL_RDMA0_FIFO_CTRL + offset));
  1113. DDPDUMP("OVL:0x1e0=0x%08x,0x24c=0x%08x\n",
  1114. DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_S2 + offset),
  1115. DISP_REG_GET(DISP_REG_OVL_RDMA0_DBG + offset));
  1116. }
  1117. if (src_on & 0x2) {
  1118. DDPDUMP("OVL:0x050=0x%08x,0x054=0x%08x,0x058=0x%08x,0x05c=0x%08x\n",
  1119. DISP_REG_GET(DISP_REG_OVL_L1_CON + offset),
  1120. DISP_REG_GET(DISP_REG_OVL_L1_SRCKEY + offset),
  1121. DISP_REG_GET(DISP_REG_OVL_L1_SRC_SIZE + offset),
  1122. DISP_REG_GET(DISP_REG_OVL_L1_OFFSET + offset));
  1123. DDPDUMP("OVL:0xf60=0x%08x,0x064=0x%08x,0x0e0=0x%08x,0x0e8=0x%08x,0x0f0=0x%08x\n",
  1124. DISP_REG_GET(DISP_REG_OVL_L1_ADDR + offset),
  1125. DISP_REG_GET(DISP_REG_OVL_L1_PITCH + offset),
  1126. DISP_REG_GET(DISP_REG_OVL_RDMA1_CTRL + offset),
  1127. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_SETTING + offset),
  1128. DISP_REG_GET(DISP_REG_OVL_RDMA1_FIFO_CTRL + offset));
  1129. DDPDUMP("OVL:0x1e4=0x%08x,0x250=0x%08x\n",
  1130. DISP_REG_GET(DISP_REG_OVL_RDMA1_MEM_GMC_S2 + offset),
  1131. DISP_REG_GET(DISP_REG_OVL_RDMA1_DBG + offset));
  1132. }
  1133. if (src_on & 0x4) {
  1134. DDPDUMP("OVL:0x070=0x%08x,0x074=0x%08x,0x078=0x%08x,0x07c=0x%08x\n",
  1135. DISP_REG_GET(DISP_REG_OVL_L2_CON + offset),
  1136. DISP_REG_GET(DISP_REG_OVL_L2_SRCKEY + offset),
  1137. DISP_REG_GET(DISP_REG_OVL_L2_SRC_SIZE + offset),
  1138. DISP_REG_GET(DISP_REG_OVL_L2_OFFSET + offset));
  1139. DDPDUMP("OVL:0xf80=0x%08x,0x084=0x%08x,0x100=0x%08x,0x110=0x%08x\n",
  1140. DISP_REG_GET(DISP_REG_OVL_L2_ADDR + offset),
  1141. DISP_REG_GET(DISP_REG_OVL_L2_PITCH + offset),
  1142. DISP_REG_GET(DISP_REG_OVL_RDMA2_CTRL + offset),
  1143. DISP_REG_GET(DISP_REG_OVL_RDMA2_FIFO_CTRL + offset));
  1144. DDPDUMP("OVL:0x1e8=0x%08x,0x254=0x%08x\n",
  1145. DISP_REG_GET(DISP_REG_OVL_RDMA2_MEM_GMC_S2 + offset),
  1146. DISP_REG_GET(DISP_REG_OVL_RDMA2_DBG + offset));
  1147. }
  1148. if (src_on & 0x8) {
  1149. DDPDUMP("OVL:0x090=0x%08x,0x094=0x%08x,0x098=0x%08x,0x09c=0x%08x\n",
  1150. DISP_REG_GET(DISP_REG_OVL_L3_CON + offset),
  1151. DISP_REG_GET(DISP_REG_OVL_L3_SRCKEY + offset),
  1152. DISP_REG_GET(DISP_REG_OVL_L3_SRC_SIZE + offset),
  1153. DISP_REG_GET(DISP_REG_OVL_L3_OFFSET + offset));
  1154. DDPDUMP("OVL:0xfa0=0x%08x,0x0a4=0x%08x,0x120=0x%08x,0x130=0x%08x\n",
  1155. DISP_REG_GET(DISP_REG_OVL_L3_ADDR + offset),
  1156. DISP_REG_GET(DISP_REG_OVL_L3_PITCH + offset),
  1157. DISP_REG_GET(DISP_REG_OVL_RDMA3_CTRL + offset),
  1158. DISP_REG_GET(DISP_REG_OVL_RDMA3_FIFO_CTRL + offset));
  1159. DDPDUMP("OVL:0x1ec=0x%08x,0x258=0x%08x\n",
  1160. DISP_REG_GET(DISP_REG_OVL_RDMA3_MEM_GMC_S2 + offset),
  1161. DISP_REG_GET(DISP_REG_OVL_RDMA3_DBG + offset));
  1162. }
  1163. DDPDUMP("OVL:0x1d4=0x%08x,0x200=0x%08x,0x240=0x%08x,0x244=0x%08x\n",
  1164. DISP_REG_GET(DISP_REG_OVL_DEBUG_MON_SEL + offset),
  1165. DISP_REG_GET(DISP_REG_OVL_DUMMY_REG + offset),
  1166. DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset),
  1167. DISP_REG_GET(DISP_REG_OVL_ADDCON_DBG + offset));
  1168. DDPDUMP("OVL:0x25c=0x%08x,0x260=0x%08x,0x264=0x%08x,0x268=0x%08x\n",
  1169. DISP_REG_GET(DISP_REG_OVL_L0_CLR + offset),
  1170. DISP_REG_GET(DISP_REG_OVL_L1_CLR + offset),
  1171. DISP_REG_GET(DISP_REG_OVL_L2_CLR + offset),
  1172. DISP_REG_GET(DISP_REG_OVL_L3_CLR + offset));
  1173. }
  1174. static char *ovl_get_state_name(unsigned int status)
  1175. {
  1176. switch (status & 0x3ff) {
  1177. case 0x1:
  1178. return "idle";
  1179. case 0x2:
  1180. return "wait_SOF";
  1181. case 0x4:
  1182. return "prepare";
  1183. case 0x8:
  1184. return "reg_update";
  1185. case 0x10:
  1186. return "eng_clr(internal reset)";
  1187. case 0x20:
  1188. return "eng_act(processing)";
  1189. case 0x40:
  1190. return "h_wait_w_rst";
  1191. case 0x80:
  1192. return "s_wait_w_rst";
  1193. case 0x100:
  1194. return "h_w_rst";
  1195. case 0x200:
  1196. return "s_w_rst";
  1197. default:
  1198. return "ovl_fsm_unknown";
  1199. }
  1200. }
  1201. static void ovl_printf_status(int idx, unsigned int status)
  1202. {
  1203. #if 0
  1204. DDPDUMP("=OVL%d_FLOW_CONTROL_DEBUG=:\n", idx);
  1205. DDPDUMP("addcon_idle:%d,blend_idle:%d,out_valid:%d,out_ready:%d,out_idle:%d\n",
  1206. (status >> 10) & (0x1),
  1207. (status >> 11) & (0x1),
  1208. (status >> 12) & (0x1), (status >> 13) & (0x1), (status >> 15) & (0x1)
  1209. );
  1210. DDPDUMP("rdma3_idle:%d,rdma2_idle:%d,rdma1_idle:%d, rdma0_idle:%d,rst:%d\n",
  1211. (status >> 16) & (0x1),
  1212. (status >> 17) & (0x1),
  1213. (status >> 18) & (0x1), (status >> 19) & (0x1), (status >> 20) & (0x1)
  1214. );
  1215. DDPDUMP("trig:%d,frame_hwrst_done:%d,frame_swrst_done:%d,frame_underrun:%d,frame_done:%d\n",
  1216. (status >> 21) & (0x1),
  1217. (status >> 23) & (0x1),
  1218. (status >> 24) & (0x1), (status >> 25) & (0x1), (status >> 26) & (0x1)
  1219. );
  1220. DDPDUMP("ovl_running:%d,ovl_start:%d,ovl_clr:%d,reg_update:%d,ovl_upd_reg:%d\n",
  1221. (status >> 27) & (0x1),
  1222. (status >> 28) & (0x1),
  1223. (status >> 29) & (0x1), (status >> 30) & (0x1), (status >> 31) & (0x1)
  1224. );
  1225. #endif
  1226. DDPDUMP("ovl%d, state=0x%x, fms_state:%s\n", idx, status, ovl_get_state_name(status));
  1227. }
  1228. void ovl_dump_analysis(DISP_MODULE_ENUM module)
  1229. {
  1230. int i = 0;
  1231. unsigned int layer_offset = 0;
  1232. unsigned int rdma_offset = 0;
  1233. int index = ovl_index(module);
  1234. unsigned int offset = index * DISP_OVL_INDEX_OFFSET;
  1235. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset);
  1236. DDPDUMP("==DISP OVL%d ANALYSIS==\n", index);
  1237. DDPDUMP("ovl_en=%d,layer_enable(%d,%d,%d,%d),bg(w=%d, h=%d),\n",
  1238. DISP_REG_GET(DISP_REG_OVL_EN + offset),
  1239. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) & 0x1,
  1240. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 1) & 0x1,
  1241. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 2) & 0x1,
  1242. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 3) & 0x1,
  1243. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) & 0xfff,
  1244. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) >> 16) & 0xfff);
  1245. DDPDUMP("cur_pos(x=%d,y=%d),layer_hit(%d,%d,%d,%d), ovl_complete_cnt=(%d, %d)\n",
  1246. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_X, DISP_REG_OVL_ADDCON_DBG + offset),
  1247. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_Y, DISP_REG_OVL_ADDCON_DBG + offset),
  1248. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L0_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1249. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L1_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1250. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L2_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1251. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L3_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1252. ovl_complete_irq_cnt[0], ovl_complete_irq_cnt[1]);
  1253. for (i = 0; i < 4; i++) {
  1254. layer_offset = i * OVL_LAYER_OFFSET + offset;
  1255. rdma_offset = i * OVL_RDMA_DEBUG_OFFSET + offset;
  1256. if (src_on & (0x1 << i)) {
  1257. DDPDUMP
  1258. ("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",
  1259. i, DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff,
  1260. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) >> 16) & 0xfff,
  1261. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) & 0xfff,
  1262. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) >> 16) & 0xfff,
  1263. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_PITCH) & 0xffff,
  1264. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_ADDR),
  1265. ovl_intput_format_name(DISP_REG_GET_FIELD
  1266. (L_CON_FLD_CFMT,
  1267. DISP_REG_OVL_L0_CON + layer_offset),
  1268. DISP_REG_GET_FIELD(L_CON_FLD_BTSW,
  1269. DISP_REG_OVL_L0_CON +
  1270. layer_offset)),
  1271. (DISP_REG_GET_FIELD(L_CON_FLD_LARC, DISP_REG_OVL_L0_CON + layer_offset)
  1272. == 0) ? "memory" : "constant_color", DISP_REG_GET_FIELD(L_CON_FLD_AEN,
  1273. DISP_REG_OVL_L0_CON
  1274. +
  1275. layer_offset),
  1276. DISP_REG_GET_FIELD(L_CON_FLD_APHA, DISP_REG_OVL_L0_CON + layer_offset));
  1277. DDPDUMP("ovl rdma%d status:(en %d)\n", i,
  1278. DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_CTRL));
  1279. }
  1280. }
  1281. ovl_printf_status(index, DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset));
  1282. }
  1283. int ovl_dump(DISP_MODULE_ENUM module, int level)
  1284. {
  1285. ovl_dump_analysis(module);
  1286. ovl_dump_reg(module);
  1287. return 0;
  1288. }
  1289. static int ovl_io(DISP_MODULE_ENUM module, int msg, unsigned long arg, void *cmdq)
  1290. {
  1291. int ret = 0;
  1292. if (module != DISP_MODULE_OVL0 && module != DISP_MODULE_OVL1) {
  1293. DDPDUMP("error, ovl_io unknown module=%d\n", module);
  1294. ret = -1;
  1295. return ret;
  1296. }
  1297. switch (msg) {
  1298. case DISP_IOCTL_OVL_ENABLE_CASCADE:
  1299. {
  1300. DDPDUMP("enable cascade ovl1\n");
  1301. DISP_REG_SET_FIELD(cmdq, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  1302. DISP_REG_OVL_DATAPATH_CON, 1);
  1303. /* when add ovl1 to path, dst_dirty may be not 1, so we have to call ovl_roi */
  1304. ovl_roi(DISP_MODULE_OVL1,
  1305. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE) & 0xfff,
  1306. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE) >> 16) & 0xfff,
  1307. gOVLBackground, cmdq);
  1308. /* ovl1_status = DDP_OVL1_STATUS_PRIMARY; */
  1309. break;
  1310. }
  1311. case DISP_IOCTL_OVL_DISABLE_CASCADE:
  1312. {
  1313. DDPDUMP("disable cascade ovl1\n");
  1314. DISP_REG_SET_FIELD(cmdq, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  1315. DISP_REG_OVL_DATAPATH_CON, 0);
  1316. /* ovl1_status = DDP_OVL1_STATUS_IDLE; */
  1317. break;
  1318. }
  1319. default:
  1320. DDPDUMP("error: unknown cmd=%d\n", msg);
  1321. }
  1322. return ret;
  1323. }
  1324. /***************** driver************/
  1325. DDP_MODULE_DRIVER ddp_driver_ovl = {
  1326. .init = ovl_init,
  1327. .deinit = ovl_deinit,
  1328. .config = ovl_config_l,
  1329. .start = ovl_start,
  1330. .trigger = NULL,
  1331. .stop = ovl_stop,
  1332. .reset = ovl_reset,
  1333. .power_on = ovl_clock_on,
  1334. .power_off = ovl_clock_off,
  1335. .suspend = ovl_suspend,
  1336. .resume = ovl_resume,
  1337. .is_idle = NULL,
  1338. .is_busy = NULL,
  1339. .dump_info = ovl_dump,
  1340. .bypass = NULL,
  1341. .build_cmdq = NULL,
  1342. .set_lcm_utils = NULL,
  1343. .cmd = ovl_io,
  1344. };