ddp_ovl.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #define LOG_TAG "OVL"
  32. #include "platform/ddp_reg.h"
  33. #include "platform/ddp_matrix_para.h"
  34. #include "platform/ddp_info.h"
  35. #include "platform/ddp_log.h"
  36. #include "platform/ddp_ovl.h"
  37. #include "platform/disp_drv_platform.h"
  38. #include "platform/mt_gpt.h"
  39. #define OVL_REG_BACK_MAX (40)
  40. #define OVL_LAYER_OFFSET (0x20)
  41. #define OVL_RDMA_DEBUG_OFFSET (0x4)
  42. enum OVL_COLOR_SPACE {
  43. OVL_COLOR_SPACE_RGB = 0,
  44. OVL_COLOR_SPACE_YUV,
  45. };
  46. enum OVL_INPUT_FORMAT {
  47. OVL_INPUT_FORMAT_BGR565 = 0,
  48. OVL_INPUT_FORMAT_RGB888 = 1,
  49. OVL_INPUT_FORMAT_RGBA8888 = 2,
  50. OVL_INPUT_FORMAT_ARGB8888 = 3,
  51. OVL_INPUT_FORMAT_VYUY = 4,
  52. OVL_INPUT_FORMAT_YVYU = 5,
  53. OVL_INPUT_FORMAT_RGB565 = 6,
  54. OVL_INPUT_FORMAT_BGR888 = 7,
  55. OVL_INPUT_FORMAT_BGRA8888 = 8,
  56. OVL_INPUT_FORMAT_ABGR8888 = 9,
  57. OVL_INPUT_FORMAT_UYVY = 10,
  58. OVL_INPUT_FORMAT_YUYV = 11,
  59. OVL_INPUT_FORMAT_RGBA4444 = 12,
  60. OVL_INPUT_FORMAT_BGRA4444 = 13,
  61. OVL_INPUT_FORMAT_UNKNOWN = 32,
  62. };
  63. typedef struct {
  64. unsigned int address;
  65. unsigned int value;
  66. } OVL_REG;
  67. static int reg_back_cnt[OVL_NUM];
  68. static OVL_REG reg_back[OVL_NUM][OVL_REG_BACK_MAX];
  69. static enum OVL_INPUT_FORMAT ovl_input_fmt_convert(DpColorFormat fmt);
  70. static unsigned int ovl_input_fmt_byte_swap(enum OVL_INPUT_FORMAT inputFormat);
  71. static unsigned int ovl_input_fmt_bpp(enum OVL_INPUT_FORMAT inputFormat);
  72. static enum OVL_COLOR_SPACE ovl_input_fmt_color_space(enum OVL_INPUT_FORMAT inputFormat);
  73. static unsigned int ovl_input_fmt_reg_value(enum OVL_INPUT_FORMAT inputFormat);
  74. static void ovl_store_regs(int idx);
  75. static void ovl_restore_regs(int idx,void * handle);
  76. static enum OVL_INPUT_FORMAT ovl_input_fmt_convert(DpColorFormat fmt)
  77. {
  78. enum OVL_INPUT_FORMAT ovl_fmt = OVL_INPUT_FORMAT_UNKNOWN;
  79. switch (fmt) {
  80. case eBGR565:
  81. ovl_fmt = OVL_INPUT_FORMAT_BGR565;
  82. break;
  83. case eRGB565:
  84. ovl_fmt = OVL_INPUT_FORMAT_RGB565;
  85. break;
  86. case eRGB888:
  87. ovl_fmt = OVL_INPUT_FORMAT_RGB888;
  88. break;
  89. case eBGR888:
  90. ovl_fmt = OVL_INPUT_FORMAT_BGR888;
  91. break;
  92. case eRGBA4444:
  93. ovl_fmt = OVL_INPUT_FORMAT_RGBA4444;
  94. break;
  95. case eBGRA4444:
  96. ovl_fmt = OVL_INPUT_FORMAT_BGRA4444;
  97. break;
  98. case eRGBA8888:
  99. ovl_fmt = OVL_INPUT_FORMAT_RGBA8888;
  100. break;
  101. case eBGRA8888:
  102. ovl_fmt = OVL_INPUT_FORMAT_BGRA8888;
  103. break;
  104. case eARGB8888:
  105. ovl_fmt = OVL_INPUT_FORMAT_ARGB8888;
  106. break;
  107. case eABGR8888:
  108. ovl_fmt = OVL_INPUT_FORMAT_ABGR8888;
  109. break;
  110. case eVYUY:
  111. ovl_fmt = OVL_INPUT_FORMAT_VYUY;
  112. break;
  113. case eYVYU:
  114. ovl_fmt = OVL_INPUT_FORMAT_YVYU;
  115. break;
  116. case eUYVY:
  117. ovl_fmt = OVL_INPUT_FORMAT_UYVY;
  118. break;
  119. case eYUY2:
  120. ovl_fmt = OVL_INPUT_FORMAT_YUYV;
  121. break;
  122. default:
  123. DDPERR("ovl_fmt_convert fmt=%d, ovl_fmt=%d\n", fmt, ovl_fmt);
  124. break;
  125. }
  126. return ovl_fmt;
  127. }
  128. static DpColorFormat ovl_input_fmt(enum OVL_INPUT_FORMAT fmt, int swap)
  129. {
  130. switch (fmt) {
  131. case OVL_INPUT_FORMAT_BGR565:
  132. return swap ? eBGR565 : eRGB565;
  133. case OVL_INPUT_FORMAT_RGB888:
  134. return swap ? eRGB888 : eBGR888;
  135. case OVL_INPUT_FORMAT_RGBA8888:
  136. return swap ? eRGBA8888 : eBGRA8888;
  137. case OVL_INPUT_FORMAT_ARGB8888:
  138. return swap ? eARGB8888 : eABGR8888;
  139. case OVL_INPUT_FORMAT_VYUY:
  140. return swap ? eVYUY : eUYVY;
  141. case OVL_INPUT_FORMAT_YVYU:
  142. return swap ? eYVYU : eYUY2;
  143. case OVL_INPUT_FORMAT_RGBA4444:
  144. return swap ? eRGBA4444 : eBGRA4444;
  145. default:
  146. DDPERR("ovl_input_fmt fmt=%d, swap=%d\n", fmt, swap);
  147. break;
  148. }
  149. return eRGB888;
  150. }
  151. static char *ovl_intput_format_name(enum OVL_INPUT_FORMAT fmt, int swap)
  152. {
  153. switch (fmt) {
  154. case OVL_INPUT_FORMAT_BGR565:
  155. return swap ? "eBGR565" : "eRGB565";
  156. case OVL_INPUT_FORMAT_RGB565:
  157. return "eRGB565";
  158. case OVL_INPUT_FORMAT_RGB888:
  159. return swap ? "eRGB888" : "eBGR888";
  160. case OVL_INPUT_FORMAT_BGR888:
  161. return "eBGR888";
  162. case OVL_INPUT_FORMAT_RGBA8888:
  163. return swap ? "eRGBA8888" : "eBGRA8888";
  164. case OVL_INPUT_FORMAT_BGRA8888:
  165. return "eBGRA8888";
  166. case OVL_INPUT_FORMAT_ARGB8888:
  167. return swap ? "eARGB8888" : "eABGR8888";
  168. case OVL_INPUT_FORMAT_ABGR8888:
  169. return "eABGR8888";
  170. case OVL_INPUT_FORMAT_VYUY:
  171. return swap ? "eVYUY" : "eUYVY";
  172. case OVL_INPUT_FORMAT_UYVY:
  173. return "eUYVY";
  174. case OVL_INPUT_FORMAT_YVYU:
  175. return swap ? "eYVYU" : "eYUY2";
  176. case OVL_INPUT_FORMAT_YUYV:
  177. return "eYUY2";
  178. case OVL_INPUT_FORMAT_RGBA4444:
  179. return swap ? "eRGBA4444" : "eBGRA4444";
  180. default:
  181. DDPERR("ovl_intput_fmt unknow fmt=%d, swap=%d\n", fmt, swap);
  182. break;
  183. }
  184. return "unknow";
  185. }
  186. static unsigned int ovl_index(DISP_MODULE_ENUM module)
  187. {
  188. int idx = 0;
  189. switch (module) {
  190. case DISP_MODULE_OVL0:
  191. idx = 0;
  192. break;
  193. case DISP_MODULE_OVL0_2L:
  194. idx = 1;
  195. break;
  196. case DISP_MODULE_OVL1_2L:
  197. idx = 2;
  198. break;
  199. default:
  200. DDPERR("invalid module=%d \n", module);// invalid module
  201. ASSERT(0);
  202. }
  203. return idx;
  204. }
  205. int OVLStart(DISP_MODULE_ENUM module, void *handle)
  206. {
  207. int idx = ovl_index(module);
  208. DISP_REG_SET_FIELD(handle, EN_FLD_OVL_EN, idx*DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x1);
  209. DISP_REG_SET(handle, idx*DISP_INDEX_OFFSET + DISP_REG_OVL_INTEN,
  210. 0x1E | REG_FLD_VAL(INTEN_FLD_ABNORMAL_SOF, 1));
  211. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_LAYER_SMI_ID_EN,
  212. idx*DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 0x1);
  213. dprintf(CRITICAL, "ovl start done idx = %d, addr = 0x%x\n", idx, idx*DISP_INDEX_OFFSET + DISP_REG_OVL_EN);
  214. dprintf(CRITICAL, "ovl start done addr0 = 0x%x\n", DISP_INDEX_OFFSET);
  215. dprintf(CRITICAL, "ovl start done addr1 = 0x%x\n", idx*DISP_INDEX_OFFSET);
  216. dprintf(CRITICAL, "ovl start done addr2 = 0x%x\n", DISP_REG_OVL_EN);
  217. dprintf(CRITICAL, "ovl start done addr3 = 0x%x\n", (idx*DISP_INDEX_OFFSET) + DISP_REG_OVL_EN);
  218. dprintf(CRITICAL, "ovl start done addr4 = 0x%x\n", idx*DISP_INDEX_OFFSET+DISP_REG_OVL_EN);
  219. return 0;
  220. }
  221. int OVLStop(DISP_MODULE_ENUM module, void *handle)
  222. {
  223. int idx = ovl_index(module);
  224. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTEN, 0x00);
  225. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_EN, 0x00);
  226. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTSTA, 0x00);
  227. return 0;
  228. }
  229. int OVLReset(DISP_MODULE_ENUM module, void *handle)
  230. {
  231. #define OVL_IDLE (0x3)
  232. unsigned int delay_cnt = 0;
  233. int idx = ovl_index(module);
  234. /*always use cpu do reset*/
  235. DISP_CPU_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_RST, 0x1); // soft reset
  236. DISP_CPU_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_RST, 0x0);
  237. while (!(DISP_REG_GET(idx*DISP_INDEX_OFFSET+DISP_REG_OVL_FLOW_CTRL_DBG) & OVL_IDLE)) {
  238. delay_cnt++;
  239. udelay(10);
  240. if (delay_cnt>2000) {
  241. DDPERR("OVL%dReset() timeout! \n",idx);
  242. break;
  243. }
  244. }
  245. return 0;
  246. }
  247. int OVLROI(DISP_MODULE_ENUM module,
  248. unsigned int bgW,
  249. unsigned int bgH,
  250. unsigned int bgColor,
  251. void * handle)
  252. {
  253. int idx = ovl_index(module);
  254. if ((bgW > OVL_MAX_WIDTH) || (bgH > OVL_MAX_HEIGHT)) {
  255. DDPERR("OVLROI(), exceed OVL max size, w=%d, h=%d \n", bgW, bgH);
  256. ASSERT(0);
  257. }
  258. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_ROI_SIZE, bgH<<16 | bgW);
  259. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_ROI_BGCLR, bgColor);
  260. return 0;
  261. }
  262. int OVLLayerSwitch(DISP_MODULE_ENUM module,
  263. unsigned layer,
  264. unsigned int en,
  265. void * handle)
  266. {
  267. int idx = ovl_index(module);
  268. ASSERT(layer<=3);
  269. switch (layer) {
  270. case 0:
  271. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L0_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  272. break;
  273. case 1:
  274. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L1_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  275. break;
  276. case 2:
  277. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L2_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  278. break;
  279. case 3:
  280. DISP_REG_SET_FIELD(handle,SRC_CON_FLD_L3_EN, idx*DISP_INDEX_OFFSET+DISP_REG_OVL_SRC_CON, en);
  281. break;
  282. default:
  283. DDPERR("invalid layer=%d\n", layer); // invalid layer
  284. ASSERT(0);
  285. }
  286. return 0;
  287. }
  288. int OVL3DConfig(DISP_MODULE_ENUM module,
  289. unsigned int layer_id,
  290. unsigned int en_3d,
  291. unsigned int landscape,
  292. unsigned int r_first,
  293. void *handle)
  294. {
  295. return 0;
  296. }
  297. int OVLLayerConfig(DISP_MODULE_ENUM module,
  298. unsigned int layer,
  299. unsigned int source,
  300. DpColorFormat format,
  301. unsigned int addr,
  302. unsigned int src_x, // ROI x offset
  303. unsigned int src_y, // ROI y offset
  304. unsigned int src_pitch,
  305. unsigned int dst_x, // ROI x offset
  306. unsigned int dst_y, // ROI y offset
  307. unsigned int dst_w, // ROT width
  308. unsigned int dst_h, // ROI height
  309. unsigned int keyEn,
  310. unsigned int key, // color key
  311. unsigned int aen, // alpha enable
  312. unsigned char alpha,
  313. void * handle)
  314. {
  315. int idx = ovl_index(module);
  316. unsigned int value = 0;
  317. enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format);
  318. unsigned int bpp = ovl_input_fmt_bpp(fmt);
  319. unsigned int input_swap = ovl_input_fmt_byte_swap(fmt);
  320. unsigned int input_fmt = ovl_input_fmt_reg_value(fmt);
  321. enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt);
  322. unsigned int offset = 0;
  323. /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB)*/
  324. int color_matrix = 0x4;
  325. unsigned int idx_offset = idx*DISP_INDEX_OFFSET;
  326. unsigned int layer_offset = idx_offset + layer * 0x20;
  327. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  328. unsigned int bg_h, bg_w;
  329. #endif
  330. ASSERT((dst_w <= OVL_MAX_WIDTH) &&
  331. (dst_h <= OVL_MAX_HEIGHT) &&
  332. (layer <= 3));
  333. if (addr == 0) {
  334. DDPERR("source from memory, but addr is 0!\n");
  335. ASSERT(0);
  336. }
  337. DDPDBG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d,"
  338. "fmt=%s, addr=%x, keyEn=%d, key=%d, aen=%d, alpha=%d \n",
  339. idx,
  340. layer,
  341. (source==0)?"memory":"constant_color",
  342. src_x,
  343. src_y,
  344. dst_x,
  345. dst_y,
  346. dst_w,
  347. dst_h,
  348. src_pitch,
  349. ovl_intput_format_name(fmt, input_swap),
  350. addr,
  351. keyEn,
  352. key,
  353. aen,
  354. alpha);
  355. if (source==OVL_LAYER_SOURCE_RESERVED) { //==1, means constant color
  356. if (aen==0) {
  357. DDPERR("dim layer ahpha enable should be 1!\n");
  358. }
  359. if (fmt!=OVL_INPUT_FORMAT_RGB565) {
  360. DDPERR("dim layer format should be RGB565");
  361. fmt = OVL_INPUT_FORMAT_RGB565;
  362. }
  363. }
  364. DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1);
  365. value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) |
  366. REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) |
  367. REG_FLD_VAL((L_CON_FLD_AEN), (aen)) |
  368. REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) |
  369. REG_FLD_VAL((L_CON_FLD_SKEN), (keyEn)) |
  370. REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap)));
  371. if (fmt == OVL_INPUT_FORMAT_RGBA4444)
  372. value |= REG_FLD_VAL((L_CON_FLD_CLRFMT_MAN), (1));
  373. if (space == OVL_COLOR_SPACE_YUV)
  374. value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix));
  375. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  376. value |= (REG_FLD_VAL((L_CON_FLD_VIRTICAL_FLIP), 1) |
  377. REG_FLD_VAL((L_CON_FLD_HORI_FLIP), 1));
  378. #endif
  379. DISP_REG_SET(handle, DISP_REG_OVL_L0_CON+layer_offset, value);
  380. #ifdef MTK_LCM_PHYSICAL_ROTATION_HW
  381. bg_h = DISP_REG_GET(idx_offset + DISP_REG_OVL_ROI_SIZE);
  382. bg_w = bg_h & 0xFFFF;
  383. bg_h = bg_h >> 16;
  384. DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset,
  385. (bg_h-dst_h-dst_y)<<16 | (bg_w-dst_w-dst_x));
  386. offset = (src_x+dst_w+1)*bpp + (src_y+dst_h-1)*src_pitch - 1;
  387. #else
  388. DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset,
  389. dst_y<<16 | dst_x);
  390. offset = src_x*bpp+src_y*src_pitch;
  391. #endif
  392. DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR+layer_offset,
  393. addr+offset);
  394. DISP_REG_SET(handle, DISP_REG_OVL_L0_SRC_SIZE+layer_offset,
  395. dst_h<<16 | dst_w);
  396. DISP_REG_SET(handle, DISP_REG_OVL_L0_SRCKEY+layer_offset,
  397. key);
  398. value = REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch));
  399. if (fmt == OVL_INPUT_FORMAT_RGBA4444) {
  400. value |= REG_FLD_VAL(L_PITCH_FLD_SRGB_SEL, (1)) |
  401. REG_FLD_VAL(L_PITCH_FLD_DRGB_SEL, (2)) |
  402. REG_FLD_VAL(L_PITCH_FLD_SURFL_EN, (1));
  403. }
  404. DISP_REG_SET(handle, DISP_REG_OVL_L0_PITCH+layer_offset, value);
  405. //DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070);
  406. return 0;
  407. }
  408. static unsigned int ovl_input_fmt_byte_swap(enum OVL_INPUT_FORMAT inputFormat)
  409. {
  410. int input_swap = 0;
  411. switch (inputFormat) {
  412. case OVL_INPUT_FORMAT_BGR565:
  413. case OVL_INPUT_FORMAT_RGB888:
  414. case OVL_INPUT_FORMAT_RGBA8888:
  415. case OVL_INPUT_FORMAT_ARGB8888:
  416. case OVL_INPUT_FORMAT_BGRA4444:
  417. case OVL_INPUT_FORMAT_VYUY:
  418. case OVL_INPUT_FORMAT_YVYU:
  419. input_swap = 1;
  420. break;
  421. case OVL_INPUT_FORMAT_RGB565:
  422. case OVL_INPUT_FORMAT_BGR888:
  423. case OVL_INPUT_FORMAT_BGRA8888:
  424. case OVL_INPUT_FORMAT_ABGR8888:
  425. case OVL_INPUT_FORMAT_RGBA4444:
  426. case OVL_INPUT_FORMAT_UYVY:
  427. case OVL_INPUT_FORMAT_YUYV:
  428. input_swap = 0;
  429. break;
  430. default:
  431. DDPERR("unknow input ovl format is %d\n", inputFormat);
  432. ASSERT(0);
  433. }
  434. return input_swap;
  435. }
  436. static unsigned int ovl_input_fmt_bpp(enum OVL_INPUT_FORMAT inputFormat)
  437. {
  438. int bpp = 0;
  439. switch (inputFormat) {
  440. case OVL_INPUT_FORMAT_BGR565:
  441. case OVL_INPUT_FORMAT_RGB565:
  442. case OVL_INPUT_FORMAT_VYUY:
  443. case OVL_INPUT_FORMAT_UYVY:
  444. case OVL_INPUT_FORMAT_YVYU:
  445. case OVL_INPUT_FORMAT_YUYV:
  446. case OVL_INPUT_FORMAT_RGBA4444:
  447. case OVL_INPUT_FORMAT_BGRA4444:
  448. bpp = 2;
  449. break;
  450. case OVL_INPUT_FORMAT_RGB888:
  451. case OVL_INPUT_FORMAT_BGR888:
  452. bpp = 3;
  453. break;
  454. case OVL_INPUT_FORMAT_RGBA8888:
  455. case OVL_INPUT_FORMAT_BGRA8888:
  456. case OVL_INPUT_FORMAT_ARGB8888:
  457. case OVL_INPUT_FORMAT_ABGR8888:
  458. bpp = 4;
  459. break;
  460. default:
  461. DDPERR("unknown ovl input format = %d\n", inputFormat);
  462. ASSERT(0);
  463. }
  464. return bpp;
  465. }
  466. static enum OVL_COLOR_SPACE ovl_input_fmt_color_space(enum OVL_INPUT_FORMAT inputFormat)
  467. {
  468. enum OVL_COLOR_SPACE space = OVL_COLOR_SPACE_RGB;
  469. switch (inputFormat) {
  470. case OVL_INPUT_FORMAT_BGR565:
  471. case OVL_INPUT_FORMAT_RGB565:
  472. case OVL_INPUT_FORMAT_RGB888:
  473. case OVL_INPUT_FORMAT_BGR888:
  474. case OVL_INPUT_FORMAT_BGRA4444:
  475. case OVL_INPUT_FORMAT_RGBA4444:
  476. case OVL_INPUT_FORMAT_RGBA8888:
  477. case OVL_INPUT_FORMAT_BGRA8888:
  478. case OVL_INPUT_FORMAT_ARGB8888:
  479. case OVL_INPUT_FORMAT_ABGR8888:
  480. space = OVL_COLOR_SPACE_RGB;
  481. break;
  482. case OVL_INPUT_FORMAT_VYUY:
  483. case OVL_INPUT_FORMAT_UYVY:
  484. case OVL_INPUT_FORMAT_YVYU:
  485. case OVL_INPUT_FORMAT_YUYV:
  486. space = OVL_COLOR_SPACE_YUV;
  487. break;
  488. default:
  489. DDPERR("unknown ovl input format = %d\n", inputFormat);
  490. ASSERT(0);
  491. }
  492. return space;
  493. }
  494. static unsigned int ovl_input_fmt_reg_value(enum OVL_INPUT_FORMAT inputFormat)
  495. {
  496. int reg_value = 0;
  497. switch (inputFormat) {
  498. case OVL_INPUT_FORMAT_BGR565:
  499. case OVL_INPUT_FORMAT_RGB565:
  500. reg_value = 0x0;
  501. break;
  502. case OVL_INPUT_FORMAT_RGB888:
  503. case OVL_INPUT_FORMAT_BGR888:
  504. reg_value = 0x1;
  505. break;
  506. case OVL_INPUT_FORMAT_RGBA8888:
  507. case OVL_INPUT_FORMAT_BGRA8888:
  508. reg_value = 0x2;
  509. break;
  510. case OVL_INPUT_FORMAT_ARGB8888:
  511. case OVL_INPUT_FORMAT_ABGR8888:
  512. reg_value = 0x3;
  513. break;
  514. case OVL_INPUT_FORMAT_VYUY:
  515. case OVL_INPUT_FORMAT_UYVY:
  516. case OVL_INPUT_FORMAT_RGBA4444:
  517. case OVL_INPUT_FORMAT_BGRA4444:
  518. reg_value = 0x4;
  519. break;
  520. case OVL_INPUT_FORMAT_YVYU:
  521. case OVL_INPUT_FORMAT_YUYV:
  522. reg_value = 0x5;
  523. break;
  524. default:
  525. DDPERR("unknow ovl input format is %d\n", inputFormat);
  526. ASSERT(0);
  527. }
  528. return reg_value;
  529. }
  530. void OVLRegStore(DISP_MODULE_ENUM module)
  531. {
  532. int i =0;
  533. int idx = ovl_index(module);
  534. const unsigned int regs[] = {
  535. //start
  536. DISP_REG_OVL_INTEN , DISP_REG_OVL_EN ,DISP_REG_OVL_DATAPATH_CON,
  537. // roi
  538. DISP_REG_OVL_ROI_SIZE , DISP_REG_OVL_ROI_BGCLR ,
  539. //layers enable
  540. DISP_REG_OVL_SRC_CON,
  541. //layer0
  542. DISP_REG_OVL_RDMA0_CTRL , DISP_REG_OVL_L0_CON ,DISP_REG_OVL_L0_SRC_SIZE,
  543. DISP_REG_OVL_L0_OFFSET , DISP_REG_OVL_L0_ADDR ,DISP_REG_OVL_L0_PITCH,
  544. DISP_REG_OVL_L0_SRCKEY ,
  545. //layer1
  546. DISP_REG_OVL_RDMA1_CTRL , DISP_REG_OVL_L1_CON ,DISP_REG_OVL_L1_SRC_SIZE,
  547. DISP_REG_OVL_L1_OFFSET , DISP_REG_OVL_L1_ADDR ,DISP_REG_OVL_L1_PITCH,
  548. DISP_REG_OVL_L1_SRCKEY ,
  549. //layer2
  550. DISP_REG_OVL_RDMA2_CTRL , DISP_REG_OVL_L2_CON ,DISP_REG_OVL_L2_SRC_SIZE,
  551. DISP_REG_OVL_L2_OFFSET , DISP_REG_OVL_L2_ADDR ,DISP_REG_OVL_L2_PITCH,
  552. DISP_REG_OVL_L2_SRCKEY ,
  553. //layer3
  554. DISP_REG_OVL_RDMA3_CTRL , DISP_REG_OVL_L3_CON ,DISP_REG_OVL_L3_SRC_SIZE,
  555. DISP_REG_OVL_L3_OFFSET , DISP_REG_OVL_L3_ADDR ,DISP_REG_OVL_L3_PITCH,
  556. DISP_REG_OVL_L3_SRCKEY ,
  557. };
  558. reg_back_cnt[idx] = sizeof(regs)/sizeof(unsigned int);
  559. ASSERT(reg_back_cnt[idx] <= OVL_REG_BACK_MAX);
  560. for (i =0; i< reg_back_cnt[idx]; i++) {
  561. reg_back[idx][i].address = regs[i];
  562. reg_back[idx][i].value = DISP_REG_GET(regs[i]);
  563. }
  564. DDPDBG("store %c cnt registers on ovl %d",reg_back_cnt[idx],idx);
  565. }
  566. void OVLRegRestore(DISP_MODULE_ENUM module,void * handle)
  567. {
  568. int idx = ovl_index(module);
  569. int i = reg_back_cnt[idx];
  570. while (i > 0) {
  571. i--;
  572. DISP_REG_SET(handle,reg_back[idx][i].address, reg_back[idx][i].value);
  573. }
  574. DDPDBG("restore %d cnt registers on ovl %d",reg_back_cnt[idx],idx);
  575. reg_back_cnt[idx] = 0;
  576. }
  577. int OVLClockOn(DISP_MODULE_ENUM module,void * handle)
  578. {
  579. int idx = ovl_index(module);
  580. ddp_enable_module_clock(module);
  581. DDPMSG("OVL%dClockOn CG 0x%x \n",idx, DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0));
  582. return 0;
  583. }
  584. int OVLClockOff(DISP_MODULE_ENUM module,void * handle)
  585. {
  586. int idx = ovl_index(module);
  587. DDPMSG("OVL%dClockOff\n",idx);
  588. //store registers
  589. // OVLRegRestore(module,handle);
  590. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_EN, 0x00);
  591. OVLReset(module,handle);
  592. DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+DISP_REG_OVL_INTEN, 0x00);
  593. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_INTSTA, 0x00);
  594. ddp_disable_module_clock(module);
  595. return 0;
  596. }
  597. int OVLInit(DISP_MODULE_ENUM module,void * handle)
  598. {
  599. //power on, no need to care clock
  600. ddp_enable_module_clock(module);
  601. return 0;
  602. }
  603. int OVLDeInit(DISP_MODULE_ENUM module,void * handle)
  604. {
  605. int idx = ovl_index(module);
  606. DDPMSG("OVL%dDeInit close CG \n",idx);
  607. ddp_disable_module_clock(module);
  608. return 0;
  609. }
  610. static inline int is_module_ovl(DISP_MODULE_ENUM module)
  611. {
  612. if (module == DISP_MODULE_OVL0 ||
  613. module == DISP_MODULE_OVL0_2L ||
  614. module == DISP_MODULE_OVL1_2L)
  615. return 1;
  616. else
  617. return 0;
  618. }
  619. int OVLConnect(DISP_MODULE_ENUM module, DISP_MODULE_ENUM prev,
  620. DISP_MODULE_ENUM next, int connect, void *handle)
  621. {
  622. int idx = ovl_index(module);
  623. if (connect && is_module_ovl(prev))
  624. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  625. idx * DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 1);
  626. else
  627. DISP_REG_SET_FIELD(handle, DATAPATH_CON_FLD_BGCLR_IN_SEL,
  628. idx * DISP_INDEX_OFFSET + DISP_REG_OVL_DATAPATH_CON, 0);
  629. return 0;
  630. }
  631. void OVLDump(DISP_MODULE_ENUM module)
  632. {
  633. int idx = ovl_index(module);
  634. unsigned long module_base = 0;
  635. const char *module_name = ddp_get_module_name(module);
  636. module_base = idx * DISP_INDEX_OFFSET + DISP_OVL0_OVL_STA;
  637. DDPDUMP("== START: DISP %s registers ==\n", module_name);
  638. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  639. module_name,
  640. 0x0, INREG32(module_base + 0x0),
  641. 0x4, INREG32(module_base + 0x4),
  642. 0x8, INREG32(module_base + 0x8),
  643. 0xC, INREG32(module_base + 0xC));
  644. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  645. module_name,
  646. 0x10, INREG32(module_base + 0x10),
  647. 0x14, INREG32(module_base + 0x14),
  648. 0x20, INREG32(module_base + 0x20),
  649. 0x24, INREG32(module_base + 0x24));
  650. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  651. module_name,
  652. 0x28, INREG32(module_base + 0x28),
  653. 0x2C, INREG32(module_base + 0x2C),
  654. 0x30, INREG32(module_base + 0x30),
  655. 0x34, INREG32(module_base + 0x34));
  656. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  657. module_name,
  658. 0x38, INREG32(module_base + 0x38),
  659. 0x3C, INREG32(module_base + 0x3C),
  660. 0xF40, INREG32(module_base + 0xF40),
  661. 0x44, INREG32(module_base + 0x44));
  662. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  663. module_name,
  664. 0x48, INREG32(module_base + 0x48),
  665. 0x4C, INREG32(module_base + 0x4C),
  666. 0x50, INREG32(module_base + 0x50),
  667. 0x54, INREG32(module_base + 0x54));
  668. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  669. module_name,
  670. 0x58, INREG32(module_base + 0x58),
  671. 0x5C, INREG32(module_base + 0x5C),
  672. 0xF60, INREG32(module_base + 0xF60),
  673. 0x64, INREG32(module_base + 0x64));
  674. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  675. module_name,
  676. 0x68, INREG32(module_base + 0x68),
  677. 0x6C, INREG32(module_base + 0x6C),
  678. 0x70, INREG32(module_base + 0x70),
  679. 0x74, INREG32(module_base + 0x74));
  680. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  681. module_name,
  682. 0x78, INREG32(module_base + 0x78),
  683. 0x7C, INREG32(module_base + 0x7C),
  684. 0xF80, INREG32(module_base + 0xF80),
  685. 0x84, INREG32(module_base + 0x84));
  686. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  687. module_name,
  688. 0x88, INREG32(module_base + 0x88),
  689. 0x8C, INREG32(module_base + 0x8C),
  690. 0x90, INREG32(module_base + 0x90),
  691. 0x94, INREG32(module_base + 0x94));
  692. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  693. module_name,
  694. 0x98, INREG32(module_base + 0x98),
  695. 0x9C, INREG32(module_base + 0x9C),
  696. 0xFa0, INREG32(module_base + 0xFa0),
  697. 0xa4, INREG32(module_base + 0xa4));
  698. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  699. module_name,
  700. 0xa8, INREG32(module_base + 0xa8),
  701. 0xAC, INREG32(module_base + 0xAC),
  702. 0xc0, INREG32(module_base + 0xc0),
  703. 0xc8, INREG32(module_base + 0xc8));
  704. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  705. module_name,
  706. 0xcc, INREG32(module_base + 0xcc),
  707. 0xd0, INREG32(module_base + 0xd0),
  708. 0xe0, INREG32(module_base + 0xe0),
  709. 0xe8, INREG32(module_base + 0xe8));
  710. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  711. module_name,
  712. 0xec, INREG32(module_base + 0xec),
  713. 0xf0, INREG32(module_base + 0xf0),
  714. 0x100, INREG32(module_base + 0x100),
  715. 0x108, INREG32(module_base + 0x108));
  716. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  717. module_name,
  718. 0x10c, INREG32(module_base + 0x10c),
  719. 0x110, INREG32(module_base + 0x110),
  720. 0x120, INREG32(module_base + 0x120),
  721. 0x128, INREG32(module_base + 0x128));
  722. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  723. module_name,
  724. 0x12c, INREG32(module_base + 0x12c),
  725. 0x130, INREG32(module_base + 0x130),
  726. 0x134, INREG32(module_base + 0x134),
  727. 0x138, INREG32(module_base + 0x138));
  728. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  729. module_name,
  730. 0x13c, INREG32(module_base + 0x13c),
  731. 0x140, INREG32(module_base + 0x140),
  732. 0x144, INREG32(module_base + 0x144),
  733. 0x148, INREG32(module_base + 0x148));
  734. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  735. module_name,
  736. 0x14c, INREG32(module_base + 0x14c),
  737. 0x150, INREG32(module_base + 0x150),
  738. 0x154, INREG32(module_base + 0x154),
  739. 0x158, INREG32(module_base + 0x158));
  740. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  741. module_name,
  742. 0x15c, INREG32(module_base + 0x15c),
  743. 0x160, INREG32(module_base + 0x160),
  744. 0x164, INREG32(module_base + 0x164),
  745. 0x168, INREG32(module_base + 0x168));
  746. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  747. module_name,
  748. 0x16c, INREG32(module_base + 0x16c),
  749. 0x170, INREG32(module_base + 0x170),
  750. 0x174, INREG32(module_base + 0x174),
  751. 0x178, INREG32(module_base + 0x178));
  752. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  753. module_name,
  754. 0x17c, INREG32(module_base + 0x17c),
  755. 0x180, INREG32(module_base + 0x180),
  756. 0x184, INREG32(module_base + 0x184),
  757. 0x188, INREG32(module_base + 0x188));
  758. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  759. module_name,
  760. 0x18c, INREG32(module_base + 0x18c),
  761. 0x190, INREG32(module_base + 0x190),
  762. 0x194, INREG32(module_base + 0x194),
  763. 0x198, INREG32(module_base + 0x198));
  764. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  765. module_name,
  766. 0x19c, INREG32(module_base + 0x19c),
  767. 0x1a0, INREG32(module_base + 0x1a0),
  768. 0x1a4, INREG32(module_base + 0x1a4),
  769. 0x1a8, INREG32(module_base + 0x1a8));
  770. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  771. module_name,
  772. 0x1ac, INREG32(module_base + 0x1ac),
  773. 0x1b0, INREG32(module_base + 0x1b0),
  774. 0x1b4, INREG32(module_base + 0x1b4),
  775. 0x1b8, INREG32(module_base + 0x1b8));
  776. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  777. module_name,
  778. 0x1bc, INREG32(module_base + 0x1bc),
  779. 0x1c0, INREG32(module_base + 0x1c0),
  780. 0x1c4, INREG32(module_base + 0x1c4),
  781. 0x1c8, INREG32(module_base + 0x1c8));
  782. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  783. module_name,
  784. 0x1cc, INREG32(module_base + 0x1cc),
  785. 0x1d0, INREG32(module_base + 0x1d0),
  786. 0x1d4, INREG32(module_base + 0x1d4),
  787. 0x1dc, INREG32(module_base + 0x1dc));
  788. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  789. module_name,
  790. 0x1e0, INREG32(module_base + 0x1e0),
  791. 0x1e4, INREG32(module_base + 0x1e4),
  792. 0x1e8, INREG32(module_base + 0x1e8),
  793. 0x1ec, INREG32(module_base + 0x1ec));
  794. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  795. module_name,
  796. 0x1F0, INREG32(module_base + 0x1F0),
  797. 0x1F4, INREG32(module_base + 0x1F4),
  798. 0x1F8, INREG32(module_base + 0x1F8),
  799. 0x1FC, INREG32(module_base + 0x1FC));
  800. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  801. module_name,
  802. 0x200, INREG32(module_base + 0x200),
  803. 0x208, INREG32(module_base + 0x208),
  804. 0x20C, INREG32(module_base + 0x20C),
  805. 0x210, INREG32(module_base + 0x210));
  806. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  807. module_name,
  808. 0x214, INREG32(module_base + 0x214),
  809. 0x218, INREG32(module_base + 0x218),
  810. 0x21C, INREG32(module_base + 0x21C),
  811. 0x220, INREG32(module_base + 0x220));
  812. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  813. module_name,
  814. 0x224, INREG32(module_base + 0x224),
  815. 0x228, INREG32(module_base + 0x228),
  816. 0x22C, INREG32(module_base + 0x22C),
  817. 0x230, INREG32(module_base + 0x230));
  818. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  819. module_name,
  820. 0x234, INREG32(module_base + 0x234),
  821. 0x238, INREG32(module_base + 0x238),
  822. 0x240, INREG32(module_base + 0x240),
  823. 0x244, INREG32(module_base + 0x244));
  824. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  825. module_name,
  826. 0x24c, INREG32(module_base + 0x24c),
  827. 0x250, INREG32(module_base + 0x250),
  828. 0x254, INREG32(module_base + 0x254),
  829. 0x258, INREG32(module_base + 0x258));
  830. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  831. module_name,
  832. 0x25c, INREG32(module_base + 0x25c),
  833. 0x260, INREG32(module_base + 0x260),
  834. 0x264, INREG32(module_base + 0x264),
  835. 0x268, INREG32(module_base + 0x268));
  836. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  837. module_name,
  838. 0x26C, INREG32(module_base + 0x26C),
  839. 0x270, INREG32(module_base + 0x270),
  840. 0x280, INREG32(module_base + 0x280),
  841. 0x284, INREG32(module_base + 0x284));
  842. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  843. module_name,
  844. 0x288, INREG32(module_base + 0x288),
  845. 0x28C, INREG32(module_base + 0x28C),
  846. 0x290, INREG32(module_base + 0x290),
  847. 0x29C, INREG32(module_base + 0x29C));
  848. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  849. module_name,
  850. 0x2A0, INREG32(module_base + 0x2A0),
  851. 0x2A4, INREG32(module_base + 0x2A4),
  852. 0x2B0, INREG32(module_base + 0x2B0),
  853. 0x2B4, INREG32(module_base + 0x2B4));
  854. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  855. module_name,
  856. 0x2B8, INREG32(module_base + 0x2B8),
  857. 0x2BC, INREG32(module_base + 0x2BC),
  858. 0x2C0, INREG32(module_base + 0x2C0),
  859. 0x2C4, INREG32(module_base + 0x2C4));
  860. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  861. module_name,
  862. 0x2C8, INREG32(module_base + 0x2C8),
  863. 0x324, INREG32(module_base + 0x324),
  864. 0x330, INREG32(module_base + 0x330),
  865. 0x334, INREG32(module_base + 0x334));
  866. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  867. module_name,
  868. 0x338, INREG32(module_base + 0x338),
  869. 0x33C, INREG32(module_base + 0x33C),
  870. 0xFB0, INREG32(module_base + 0xFB0),
  871. 0x344, INREG32(module_base + 0x344));
  872. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  873. module_name,
  874. 0x348, INREG32(module_base + 0x348),
  875. 0x34C, INREG32(module_base + 0x34C),
  876. 0x350, INREG32(module_base + 0x350),
  877. 0x354, INREG32(module_base + 0x354));
  878. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  879. module_name,
  880. 0x358, INREG32(module_base + 0x358),
  881. 0x35C, INREG32(module_base + 0x35C),
  882. 0xFB4, INREG32(module_base + 0xFB4),
  883. 0x364, INREG32(module_base + 0x364));
  884. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  885. module_name,
  886. 0x368, INREG32(module_base + 0x368),
  887. 0x36C, INREG32(module_base + 0x36C),
  888. 0x370, INREG32(module_base + 0x370),
  889. 0x374, INREG32(module_base + 0x374));
  890. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  891. module_name,
  892. 0x378, INREG32(module_base + 0x378),
  893. 0x37C, INREG32(module_base + 0x37C),
  894. 0xFB8, INREG32(module_base + 0xFB8),
  895. 0x384, INREG32(module_base + 0x384));
  896. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  897. module_name,
  898. 0x388, INREG32(module_base + 0x388),
  899. 0x38C, INREG32(module_base + 0x38C),
  900. 0x390, INREG32(module_base + 0x390),
  901. 0x394, INREG32(module_base + 0x394));
  902. DDPDUMP("%s 0x%04x=0x%08x, 0x%04x=0x%08x\n",
  903. module_name,
  904. 0x398, INREG32(module_base + 0x398),
  905. 0xFC0, INREG32(module_base + 0xFC0));
  906. DDPDUMP("-- END: DISP %s registers --\n", module_name);
  907. }
  908. static void ovl_printf_status(unsigned int status)
  909. {
  910. DDPDUMP("=OVL_FLOW_CONTROL_DEBUG=:\n");
  911. DDPDUMP("addcon_idle:%d,blend_idle:%d,out_valid:%d,out_ready:%d,out_idle:%d\n",
  912. (status >> 10) & (0x1),
  913. (status >> 11) & (0x1),
  914. (status >> 12) & (0x1), (status >> 13) & (0x1), (status >> 15) & (0x1)
  915. );
  916. DDPDUMP("rdma3_idle:%d,rdma2_idle:%d,rdma1_idle:%d, rdma0_idle:%d,rst:%d\n",
  917. (status >> 16) & (0x1),
  918. (status >> 17) & (0x1),
  919. (status >> 18) & (0x1), (status >> 19) & (0x1), (status >> 20) & (0x1)
  920. );
  921. DDPDUMP("trig:%d,frame_hwrst_done:%d,frame_swrst_done:%d,frame_underrun:%d,frame_done:%d\n",
  922. (status >> 21) & (0x1),
  923. (status >> 23) & (0x1),
  924. (status >> 24) & (0x1), (status >> 25) & (0x1), (status >> 26) & (0x1)
  925. );
  926. DDPDUMP("ovl_running:%d,ovl_start:%d,ovl_clr:%d,reg_update:%d,ovl_upd_reg:%d\n",
  927. (status >> 27) & (0x1),
  928. (status >> 28) & (0x1),
  929. (status >> 29) & (0x1), (status >> 30) & (0x1), (status >> 31) & (0x1)
  930. );
  931. DDPDUMP("ovl_fms_state:\n");
  932. switch (status & 0x3ff) {
  933. case 0x1:
  934. DDPDUMP("idle\n");
  935. break;
  936. case 0x2:
  937. DDPDUMP("wait_SOF\n");
  938. break;
  939. case 0x4:
  940. DDPDUMP("prepare\n");
  941. break;
  942. case 0x8:
  943. DDPDUMP("reg_update\n");
  944. break;
  945. case 0x10:
  946. DDPDUMP("eng_clr(internal reset)\n");
  947. break;
  948. case 0x20:
  949. DDPDUMP("eng_act(processing)\n");
  950. break;
  951. case 0x40:
  952. DDPDUMP("h_wait_w_rst\n");
  953. break;
  954. case 0x80:
  955. DDPDUMP("s_wait_w_rst\n");
  956. break;
  957. case 0x100:
  958. DDPDUMP("h_w_rst\n");
  959. break;
  960. case 0x200:
  961. DDPDUMP("s_w_rst\n");
  962. break;
  963. default:
  964. DDPDUMP("ovl_fsm_unknown\n");
  965. break;
  966. }
  967. }
  968. static void ovl_print_ovl_rdma_status(unsigned int status)
  969. {
  970. DDPDUMP("wram_rst_cs:0x%x,layer_greq:0x%x,out_data:0x%x,",
  971. status & 0x7, (status >> 3) & 0x1, (status >> 4) & 0xffffff);
  972. DDPDUMP("out_ready:0x%x,out_valid:0x%x,smi_busy:0x%x,smi_greq:0x%x\n",
  973. (status >> 28) & 0x1, (status >> 29) & 0x1, (status >> 30) & 0x1,
  974. (status >> 31) & 0x1);
  975. }
  976. static void ovl_dump_layer_info(int layer, unsigned long layer_offset)
  977. {
  978. DDPDUMP("layer%d: w=%d,h=%d,off(x=%d,y=%d),pitch=%d,addr=0x%x,fmt=%s,source=%s,aen=%d,alpha=%d\n",
  979. layer, DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) & 0xfff,
  980. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_SRC_SIZE) >> 16) & 0xfff,
  981. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) & 0xfff,
  982. (DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_OFFSET) >> 16) & 0xfff,
  983. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_PITCH) & 0xffff,
  984. DISP_REG_GET(layer_offset + DISP_REG_OVL_L0_ADDR),
  985. ovl_intput_format_name(
  986. DISP_REG_GET_FIELD(L_CON_FLD_CFMT, DISP_REG_OVL_L0_CON+layer_offset),
  987. DISP_REG_GET_FIELD(L_CON_FLD_BTSW, DISP_REG_OVL_L0_CON+layer_offset)),
  988. (DISP_REG_GET_FIELD(L_CON_FLD_LARC, DISP_REG_OVL_L0_CON + layer_offset) ==
  989. 0) ? "memory" : "constant_color", DISP_REG_GET_FIELD(L_CON_FLD_AEN,
  990. DISP_REG_OVL_L0_CON +
  991. layer_offset),
  992. DISP_REG_GET_FIELD(L_CON_FLD_APHA, DISP_REG_OVL_L0_CON + layer_offset)
  993. );
  994. }
  995. void ovl_dump_analysis(DISP_MODULE_ENUM module)
  996. {
  997. int i = 0;
  998. unsigned int layer_offset = 0;
  999. unsigned int rdma_offset = 0;
  1000. int idx = ovl_index(module);
  1001. unsigned int offset = idx * DISP_INDEX_OFFSET;
  1002. unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON+offset);
  1003. unsigned int rdma_ctrl;
  1004. DDPDUMP("==DISP %s ANALYSIS==\n", ddp_get_module_name(module));
  1005. DDPDUMP("ovl_en=%d,layer_enable(%d,%d,%d,%d),bg(w=%d, h=%d),",
  1006. DISP_REG_GET(DISP_REG_OVL_EN + offset),
  1007. DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) & 0x1,
  1008. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 1) & 0x1,
  1009. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 2) & 0x1,
  1010. (DISP_REG_GET(DISP_REG_OVL_SRC_CON + offset) >> 3) & 0x1,
  1011. DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) & 0xfff,
  1012. (DISP_REG_GET(DISP_REG_OVL_ROI_SIZE + offset) >> 16) & 0xfff);
  1013. DDPDUMP("cur_pos(x=%d,y=%d),layer_hit(%d,%d,%d,%d),bg_mode=%s,sta=0x%x\n",
  1014. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_X, DISP_REG_OVL_ADDCON_DBG + offset),
  1015. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_ROI_Y, DISP_REG_OVL_ADDCON_DBG + offset),
  1016. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L0_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1017. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L1_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1018. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L2_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1019. DISP_REG_GET_FIELD(ADDCON_DBG_FLD_L3_WIN_HIT, DISP_REG_OVL_ADDCON_DBG + offset),
  1020. DISP_REG_GET_FIELD(DATAPATH_CON_FLD_BGCLR_IN_SEL,
  1021. DISP_REG_OVL_DATAPATH_CON + offset) ? "directlink" : "const",
  1022. DISP_REG_GET(DISP_REG_OVL_STA + offset)
  1023. );
  1024. for (i = 0; i < 4; i++) {
  1025. layer_offset = i * OVL_LAYER_OFFSET + offset;
  1026. rdma_offset = i * OVL_RDMA_DEBUG_OFFSET + offset;
  1027. if (src_on & (0x1 << i))
  1028. ovl_dump_layer_info(i, layer_offset);
  1029. else
  1030. DDPDUMP("layer%d: disabled\n", i);
  1031. rdma_ctrl = DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_CTRL);
  1032. DDPDUMP("ovl rdma%d status:(en=%d, fifo_used %d, GMC=0x%x)\n", i,
  1033. REG_FLD_VAL_GET(RDMA0_CTRL_FLD_RDMA_EN, rdma_ctrl),
  1034. REG_FLD_VAL_GET(RDMA0_CTRL_FLD_RMDA_FIFO_USED_SZ, rdma_ctrl),
  1035. DISP_REG_GET(layer_offset + DISP_REG_OVL_RDMA0_MEM_GMC_SETTING));
  1036. ovl_print_ovl_rdma_status(DISP_REG_GET(DISP_REG_OVL_RDMA0_DBG + rdma_offset));
  1037. }
  1038. ovl_printf_status(DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG + offset));
  1039. }
  1040. static inline unsigned long ovl_layer_num(DISP_MODULE_ENUM module)
  1041. {
  1042. switch (module) {
  1043. case DISP_MODULE_OVL0:
  1044. return 4;
  1045. case DISP_MODULE_OVL0_2L:
  1046. return 2;
  1047. case DISP_MODULE_OVL1_2L:
  1048. return 2;
  1049. default:
  1050. DDPERR("invalid ovl module=%d\n", module);
  1051. ASSERT(0);
  1052. }
  1053. return 0;
  1054. }
  1055. static int OVLConfig_l(DISP_MODULE_ENUM module, disp_ddp_path_config* pConfig, void* handle)
  1056. {
  1057. int enabled_layers = 0;
  1058. unsigned int local_layer = 0, global_layer = 0;
  1059. int idx = ovl_index(module);
  1060. if (pConfig->dst_dirty) {
  1061. OVLROI(module,
  1062. pConfig->dst_w, // width
  1063. pConfig->dst_h, // height
  1064. 0xFF000000, // background color
  1065. handle);
  1066. }
  1067. if (!pConfig->ovl_dirty) {
  1068. return 0;
  1069. }
  1070. for (global_layer = 0; global_layer < TOTAL_OVL_LAYER_NUM; global_layer++) {
  1071. if (!(pConfig->ovl_layer_scanned & (1 << global_layer)))
  1072. break;
  1073. }
  1074. if (global_layer > TOTAL_OVL_LAYER_NUM - ovl_layer_num(module)) {
  1075. DDPERR("%s: %s scan error, layer_scanned=%u\n", __func__,
  1076. ddp_get_module_name(module), pConfig->ovl_layer_scanned);
  1077. ASSERT(0);
  1078. }
  1079. for (local_layer = 0; local_layer < ovl_layer_num(module); local_layer++, global_layer++) {
  1080. OVL_CONFIG_STRUCT *ovl_cfg = &pConfig->ovl_config[global_layer];
  1081. pConfig->ovl_layer_scanned |= (1 << global_layer);
  1082. if (ovl_cfg->layer_en == 0)
  1083. continue;
  1084. if (ovl_cfg->addr==0 || ovl_cfg->dst_w==0 || ovl_cfg->dst_h==0) {
  1085. DDPERR("ovl parameter invalidate, addr=0x%x, w=%d, h=%d \n",
  1086. ovl_cfg->addr,
  1087. ovl_cfg->dst_w,
  1088. ovl_cfg->dst_h);
  1089. return -1;
  1090. }
  1091. DDPDBG("module %d, layer=%d, en=%d, src=%d, fmt=%d, addr=0x%x, x=%d, y=%d, pitch=%d, dst(%d, %d, %d, %d),keyEn=%d, key=%d, aen=%d, alpha=%d\n",
  1092. module,
  1093. local_layer,
  1094. ovl_cfg->layer_en,
  1095. ovl_cfg->source, // data source (0=memory)
  1096. ovl_cfg->fmt,
  1097. ovl_cfg->addr, // addr
  1098. ovl_cfg->src_x, // x
  1099. ovl_cfg->src_y, // y
  1100. ovl_cfg->src_pitch, //pitch, pixel number
  1101. ovl_cfg->dst_x, // x
  1102. ovl_cfg->dst_y, // y
  1103. ovl_cfg->dst_w, // width
  1104. ovl_cfg->dst_h, // height
  1105. ovl_cfg->keyEn, //color key
  1106. ovl_cfg->key, //color key
  1107. ovl_cfg->aen, // alpha enable
  1108. ovl_cfg->alpha);
  1109. OVLLayerConfig(module,
  1110. local_layer,
  1111. ovl_cfg->source,
  1112. ovl_cfg->fmt,
  1113. ovl_cfg->addr,
  1114. ovl_cfg->src_x,
  1115. ovl_cfg->src_y,
  1116. ovl_cfg->src_pitch,
  1117. ovl_cfg->dst_x,
  1118. ovl_cfg->dst_y,
  1119. ovl_cfg->dst_w,
  1120. ovl_cfg->dst_h,
  1121. ovl_cfg->keyEn,
  1122. ovl_cfg->key,
  1123. ovl_cfg->aen,
  1124. ovl_cfg->alpha,
  1125. handle);
  1126. // print_layer_config_args(module, local_layer, ovl_cfg);
  1127. // ovl_layer_config(module, local_layer, has_sec_layer, ovl_cfg, handle);
  1128. enabled_layers |= 1 << local_layer;
  1129. }
  1130. DISP_REG_SET(handle, idx * DISP_INDEX_OFFSET + DISP_REG_OVL_SRC_CON, enabled_layers);
  1131. return 0;
  1132. }
  1133. DDP_MODULE_DRIVER ddp_driver_ovl = {
  1134. .module = DISP_MODULE_OVL0,
  1135. .init = OVLInit,
  1136. .deinit = OVLDeInit,
  1137. .config = OVLConfig_l,
  1138. .start = OVLStart,
  1139. .trigger = NULL,
  1140. .stop = OVLStop,
  1141. .reset = NULL,
  1142. .power_on = OVLClockOn,
  1143. .power_off = OVLClockOff,
  1144. .is_idle = NULL,
  1145. .is_busy = NULL,
  1146. .dump_info = NULL,
  1147. .bypass = NULL,
  1148. .build_cmdq = NULL,
  1149. .set_lcm_utils = NULL,
  1150. .connect = OVLConnect,
  1151. };