debug.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. #include <linux/string.h>
  2. #include <linux/time.h>
  3. #include <linux/uaccess.h>
  4. #include <linux/fb.h>
  5. #include <linux/vmalloc.h>
  6. #include <linux/sched.h>
  7. #include <linux/debugfs.h>
  8. #include <linux/wait.h>
  9. #include <linux/time.h>
  10. #include <linux/delay.h>
  11. #include <linux/types.h>
  12. #include "m4u.h"
  13. #include "disp_drv_log.h"
  14. #include "mtkfb.h"
  15. #include "debug.h"
  16. #include "lcm_drv.h"
  17. #include "ddp_ovl.h"
  18. #include "ddp_path.h"
  19. #include "ddp_reg.h"
  20. #include "primary_display.h"
  21. #include "display_recorder.h"
  22. #ifdef CONFIG_MTK_LEGACY
  23. #include <mt-plat/mt_gpio.h>
  24. /* #include <cust_gpio_usage.h> */
  25. #endif
  26. #include <mach/mt_clkmgr.h>
  27. #include "mtkfb_fence.h"
  28. #include "ddp_manager.h"
  29. #include "ddp_dsi.h"
  30. #include "disp_assert_layer.h"
  31. struct MTKFB_MMP_Events_t MTKFB_MMP_Events;
  32. #ifdef ROME_TODO
  33. /* extern LCM_DRIVER *lcm_drv; */
  34. #endif
  35. /* extern unsigned int EnableVSyncLog; */
  36. /* extern unsigned int gTriggerDispMode; */ /* 0: normal, 1: lcd only, 2: none of lcd and lcm */
  37. #define MTKFB_DEBUG_FS_CAPTURE_LAYER_CONTENT_SUPPORT
  38. /* --------------------------------------------------------------------------- */
  39. /* External variable declarations */
  40. /* --------------------------------------------------------------------------- */
  41. /* extern long tpd_last_down_time; */
  42. /* extern int tpd_start_profiling; */
  43. #ifdef ROME_TODO
  44. /* extern void disp_log_enable(int enable); */
  45. /* extern void mtkfb_capture_fb_only(bool enable);*/
  46. /* extern void esd_recovery_pause(BOOL en); */
  47. /* extern void mtkfb_pan_disp_test(void); */
  48. /* extern void mtkfb_show_sem_cnt(void); */
  49. /* extern void mtkfb_hang_test(bool en); */
  50. /* extern void mtkfb_switch_normal_to_factory(void); */
  51. /* extern void mtkfb_switch_factory_to_normal(void); */
  52. /* extern unsigned int gCaptureOvlThreadEnable; */
  53. /* extern unsigned int gCaptureOvlDownX; */
  54. /* extern unsigned int gCaptureOvlDownY; */
  55. /* extern struct task_struct *captureovl_task; */
  56. /* extern unsigned int gCaptureFBEnable; */
  57. /* extern unsigned int gCaptureFBDownX; */
  58. /* extern unsigned int gCaptureFBDownY; */
  59. /* extern unsigned int gCaptureFBPeriod; */
  60. /* extern struct task_struct *capturefb_task; */
  61. /* extern wait_queue_head_t gCaptureFBWQ; */
  62. /* extern OVL_CONFIG_STRUCT cached_layer_config[DDP_OVL_LAYER_MUN]; */
  63. /* extern void hdmi_force_init(void); */
  64. #endif
  65. /* extern void mtkfb_vsync_log_enable(int enable); */
  66. /* extern unsigned int gCaptureLayerEnable; */
  67. /* extern unsigned int gCaptureLayerDownX; */
  68. /* extern unsigned int gCaptureLayerDownY; */
  69. extern unsigned int dvfs_test;
  70. extern int primary_display_switch_mmsys_clk(int mmsys_clk_old, int mmsys_clk_new);
  71. #ifdef MTKFB_DEBUG_FS_CAPTURE_LAYER_CONTENT_SUPPORT
  72. struct dentry *mtkfb_layer_dbgfs[DDP_OVL_LAYER_MUN];
  73. typedef struct {
  74. uint32_t layer_index;
  75. unsigned long working_buf;
  76. uint32_t working_size;
  77. } MTKFB_LAYER_DBG_OPTIONS;
  78. MTKFB_LAYER_DBG_OPTIONS mtkfb_layer_dbg_opt[DDP_OVL_LAYER_MUN];
  79. #endif
  80. #ifdef ROME_TODO
  81. /* extern LCM_DRIVER *lcm_drv; */
  82. #endif
  83. /* --------------------------------------------------------------------------- */
  84. /* Debug Options */
  85. /* --------------------------------------------------------------------------- */
  86. static const long int DEFAULT_LOG_FPS_WND_SIZE = 30;
  87. typedef struct {
  88. unsigned int en_fps_log;
  89. unsigned int en_touch_latency_log;
  90. unsigned int log_fps_wnd_size;
  91. unsigned int force_dis_layers;
  92. } DBG_OPTIONS;
  93. static DBG_OPTIONS dbg_opt = { 0 };
  94. static bool enable_ovl1_to_mem = true;
  95. unsigned int g_mobilelog;
  96. /* --------------------------------------------------------------------------- */
  97. /* Information Dump Routines */
  98. /* --------------------------------------------------------------------------- */
  99. void init_mtkfb_mmp_events(void)
  100. {
  101. if (MTKFB_MMP_Events.MTKFB == 0) {
  102. MTKFB_MMP_Events.MTKFB = MMProfileRegisterEvent(MMP_RootEvent, "MTKFB");
  103. MTKFB_MMP_Events.PanDisplay =
  104. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "PanDisplay");
  105. MTKFB_MMP_Events.CreateSyncTimeline =
  106. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "CreateSyncTimeline");
  107. MTKFB_MMP_Events.SetOverlayLayer =
  108. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "SetOverlayLayer");
  109. MTKFB_MMP_Events.SetOverlayLayers =
  110. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "SetOverlayLayers");
  111. MTKFB_MMP_Events.SetMultipleLayers =
  112. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "SetMultipleLayers");
  113. MTKFB_MMP_Events.CreateSyncFence =
  114. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "CreateSyncFence");
  115. MTKFB_MMP_Events.IncSyncTimeline =
  116. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "IncSyncTimeline");
  117. MTKFB_MMP_Events.SignalSyncFence =
  118. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "SignalSyncFence");
  119. MTKFB_MMP_Events.TrigOverlayOut =
  120. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "TrigOverlayOut");
  121. MTKFB_MMP_Events.UpdateScreenImpl =
  122. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "UpdateScreenImpl");
  123. MTKFB_MMP_Events.VSync = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "VSync");
  124. MTKFB_MMP_Events.UpdateConfig =
  125. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "UpdateConfig");
  126. MTKFB_MMP_Events.EsdCheck =
  127. MMProfileRegisterEvent(MTKFB_MMP_Events.UpdateConfig, "EsdCheck");
  128. MTKFB_MMP_Events.ConfigOVL =
  129. MMProfileRegisterEvent(MTKFB_MMP_Events.UpdateConfig, "ConfigOVL");
  130. MTKFB_MMP_Events.ConfigAAL =
  131. MMProfileRegisterEvent(MTKFB_MMP_Events.UpdateConfig, "ConfigAAL");
  132. MTKFB_MMP_Events.ConfigMemOut =
  133. MMProfileRegisterEvent(MTKFB_MMP_Events.UpdateConfig, "ConfigMemOut");
  134. MTKFB_MMP_Events.ScreenUpdate =
  135. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "ScreenUpdate");
  136. MTKFB_MMP_Events.CaptureFramebuffer =
  137. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "CaptureFB");
  138. MTKFB_MMP_Events.RegUpdate =
  139. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "RegUpdate");
  140. MTKFB_MMP_Events.EarlySuspend =
  141. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "EarlySuspend");
  142. MTKFB_MMP_Events.DispDone =
  143. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "DispDone");
  144. MTKFB_MMP_Events.DSICmd = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "DSICmd");
  145. MTKFB_MMP_Events.DSIIRQ = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "DSIIrq");
  146. MTKFB_MMP_Events.WaitVSync =
  147. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "WaitVSync");
  148. MTKFB_MMP_Events.LayerDump =
  149. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "LayerDump");
  150. MTKFB_MMP_Events.Layer[0] =
  151. MMProfileRegisterEvent(MTKFB_MMP_Events.LayerDump, "Layer0");
  152. MTKFB_MMP_Events.Layer[1] =
  153. MMProfileRegisterEvent(MTKFB_MMP_Events.LayerDump, "Layer1");
  154. MTKFB_MMP_Events.Layer[2] =
  155. MMProfileRegisterEvent(MTKFB_MMP_Events.LayerDump, "Layer2");
  156. MTKFB_MMP_Events.Layer[3] =
  157. MMProfileRegisterEvent(MTKFB_MMP_Events.LayerDump, "Layer3");
  158. MTKFB_MMP_Events.OvlDump =
  159. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "OvlDump");
  160. MTKFB_MMP_Events.FBDump = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "FBDump");
  161. MTKFB_MMP_Events.DSIRead =
  162. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "DSIRead");
  163. MTKFB_MMP_Events.GetLayerInfo =
  164. MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "GetLayerInfo");
  165. MTKFB_MMP_Events.LayerInfo[0] =
  166. MMProfileRegisterEvent(MTKFB_MMP_Events.GetLayerInfo, "LayerInfo0");
  167. MTKFB_MMP_Events.LayerInfo[1] =
  168. MMProfileRegisterEvent(MTKFB_MMP_Events.GetLayerInfo, "LayerInfo1");
  169. MTKFB_MMP_Events.LayerInfo[2] =
  170. MMProfileRegisterEvent(MTKFB_MMP_Events.GetLayerInfo, "LayerInfo2");
  171. MTKFB_MMP_Events.LayerInfo[3] =
  172. MMProfileRegisterEvent(MTKFB_MMP_Events.GetLayerInfo, "LayerInfo3");
  173. MTKFB_MMP_Events.IOCtrl = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "IOCtrl");
  174. MTKFB_MMP_Events.Debug = MMProfileRegisterEvent(MTKFB_MMP_Events.MTKFB, "Debug");
  175. MMProfileEnableEventRecursive(MTKFB_MMP_Events.MTKFB, 1);
  176. }
  177. }
  178. static inline int is_layer_enable(unsigned int roi_ctl, unsigned int layer)
  179. {
  180. return (roi_ctl >> (31 - layer)) & 0x1;
  181. }
  182. /* --------------------------------------------------------------------------- */
  183. /* FPS Log */
  184. /* --------------------------------------------------------------------------- */
  185. typedef struct {
  186. long int current_lcd_time_us;
  187. long int current_te_delay_time_us;
  188. long int total_lcd_time_us;
  189. long int total_te_delay_time_us;
  190. long int start_time_us;
  191. long int trigger_lcd_time_us;
  192. unsigned int trigger_lcd_count;
  193. long int current_hdmi_time_us;
  194. long int total_hdmi_time_us;
  195. long int hdmi_start_time_us;
  196. long int trigger_hdmi_time_us;
  197. unsigned int trigger_hdmi_count;
  198. } FPS_LOGGER;
  199. static FPS_LOGGER fps = { 0 };
  200. static FPS_LOGGER hdmi_fps = { 0 };
  201. static long int get_current_time_us(void)
  202. {
  203. struct timeval t;
  204. do_gettimeofday(&t);
  205. return (t.tv_sec & 0xFFF) * 1000000 + t.tv_usec;
  206. }
  207. static inline void reset_fps_logger(void)
  208. {
  209. memset(&fps, 0, sizeof(fps));
  210. }
  211. static inline void reset_hdmi_fps_logger(void)
  212. {
  213. memset(&hdmi_fps, 0, sizeof(hdmi_fps));
  214. }
  215. void DBG_OnTriggerLcd(void)
  216. {
  217. if (!dbg_opt.en_fps_log && !dbg_opt.en_touch_latency_log)
  218. return;
  219. fps.trigger_lcd_time_us = get_current_time_us();
  220. if (fps.trigger_lcd_count == 0)
  221. fps.start_time_us = fps.trigger_lcd_time_us;
  222. }
  223. void DBG_OnTriggerHDMI(void)
  224. {
  225. if (!dbg_opt.en_fps_log && !dbg_opt.en_touch_latency_log)
  226. return;
  227. hdmi_fps.trigger_hdmi_time_us = get_current_time_us();
  228. if (hdmi_fps.trigger_hdmi_count == 0)
  229. hdmi_fps.hdmi_start_time_us = hdmi_fps.trigger_hdmi_time_us;
  230. }
  231. void DBG_OnTeDelayDone(void)
  232. {
  233. long int time;
  234. if (!dbg_opt.en_fps_log && !dbg_opt.en_touch_latency_log)
  235. return;
  236. time = get_current_time_us();
  237. fps.current_te_delay_time_us = (time - fps.trigger_lcd_time_us);
  238. fps.total_te_delay_time_us += fps.current_te_delay_time_us;
  239. }
  240. void DBG_OnLcdDone(void)
  241. {
  242. long int time;
  243. if (!dbg_opt.en_fps_log && !dbg_opt.en_touch_latency_log)
  244. return;
  245. /* deal with touch latency log */
  246. time = get_current_time_us();
  247. fps.current_lcd_time_us = (time - fps.trigger_lcd_time_us);
  248. #if 0 /* FIXME */
  249. if (dbg_opt.en_touch_latency_log && tpd_start_profiling) {
  250. pr_debug("DISP/DBG " "Touch Latency: %ld ms\n", (time - tpd_last_down_time) / 1000);
  251. pr_debug("DISP/DBG " "LCD update time %ld ms (TE delay %ld ms + LCD %ld ms)\n",
  252. fps.current_lcd_time_us / 1000,
  253. fps.current_te_delay_time_us / 1000,
  254. (fps.current_lcd_time_us - fps.current_te_delay_time_us) / 1000);
  255. tpd_start_profiling = 0;
  256. }
  257. #endif
  258. if (!dbg_opt.en_fps_log)
  259. return;
  260. /* deal with fps log */
  261. fps.total_lcd_time_us += fps.current_lcd_time_us;
  262. ++fps.trigger_lcd_count;
  263. if (fps.trigger_lcd_count >= dbg_opt.log_fps_wnd_size) {
  264. long int f = fps.trigger_lcd_count * 100 * 1000 * 1000 / (time - fps.start_time_us);
  265. long int update = fps.total_lcd_time_us * 100 / (1000 * fps.trigger_lcd_count);
  266. long int te = fps.total_te_delay_time_us * 100 / (1000 * fps.trigger_lcd_count);
  267. long int lcd = (fps.total_lcd_time_us - fps.total_te_delay_time_us) * 100
  268. / (1000 * fps.trigger_lcd_count);
  269. pr_debug("DISP/DBG " "MTKFB FPS: %ld.%02ld, Avg. update time: %ld.%02ld ms,\n",
  270. f / 100, f % 100, update / 100, update % 100);
  271. pr_debug("(TE delay %ld.%02ld ms, LCD %ld.%02ld ms)\n", te / 100, te % 100, lcd / 100, lcd % 100);
  272. reset_fps_logger();
  273. }
  274. }
  275. void DBG_OnHDMIDone(void)
  276. {
  277. long int time;
  278. if (!dbg_opt.en_fps_log && !dbg_opt.en_touch_latency_log)
  279. return;
  280. /* deal with touch latency log */
  281. time = get_current_time_us();
  282. hdmi_fps.current_hdmi_time_us = (time - hdmi_fps.trigger_hdmi_time_us);
  283. if (!dbg_opt.en_fps_log)
  284. return;
  285. /* deal with fps log */
  286. hdmi_fps.total_hdmi_time_us += hdmi_fps.current_hdmi_time_us;
  287. ++hdmi_fps.trigger_hdmi_count;
  288. if (hdmi_fps.trigger_hdmi_count >= dbg_opt.log_fps_wnd_size) {
  289. long int f = hdmi_fps.trigger_hdmi_count * 100 * 1000 * 1000
  290. / (time - hdmi_fps.hdmi_start_time_us);
  291. long int update = hdmi_fps.total_hdmi_time_us * 100
  292. / (1000 * hdmi_fps.trigger_hdmi_count);
  293. pr_debug("DISP/DBG " "[HDMI] FPS: %ld.%02ld, Avg. update time: %ld.%02ld ms\n",
  294. f / 100, f % 100, update / 100, update % 100);
  295. reset_hdmi_fps_logger();
  296. }
  297. }
  298. /* --------------------------------------------------------------------------- */
  299. /* Command Processor */
  300. /* --------------------------------------------------------------------------- */
  301. /* extern int DSI_BIST_Pattern_Test(DISP_MODULE_ENUM module, cmdqRecHandle cmdq, bool enable,
  302. unsigned int color); */
  303. bool get_ovl1_to_mem_on(void)
  304. {
  305. return enable_ovl1_to_mem;
  306. }
  307. void switch_ovl1_to_mem(bool on)
  308. {
  309. enable_ovl1_to_mem = on;
  310. pr_debug("DISP/DBG " "switch_ovl1_to_mem %d\n", enable_ovl1_to_mem);
  311. }
  312. static int _draw_line(unsigned long addr, int l, int t, int r, int b, int linepitch,
  313. unsigned int color)
  314. {
  315. int i = 0;
  316. if (l > r || b < t)
  317. return -1;
  318. if (l == r) { /* vertical line */
  319. for (i = 0; i < (b - t); i++)
  320. *(unsigned long *)(addr + (t + i) * linepitch + l * 4) = color;
  321. } else if (t == b) { /* horizontal line */
  322. for (i = 0; i < (r - l); i++)
  323. *(unsigned long *)(addr + t * linepitch + (l + i) * 4) = color;
  324. } else { /* tile line, not support now */
  325. return -1;
  326. }
  327. return 0;
  328. }
  329. static int _draw_rect(unsigned long addr, int l, int t, int r, int b, unsigned int linepitch,
  330. unsigned int color)
  331. {
  332. int ret = 0;
  333. ret += _draw_line(addr, l, t, r, t, linepitch, color);
  334. ret += _draw_line(addr, l, t, l, b, linepitch, color);
  335. ret += _draw_line(addr, r, t, r, b, linepitch, color);
  336. ret += _draw_line(addr, l, b, r, b, linepitch, color);
  337. return ret;
  338. }
  339. static void _draw_block(unsigned long addr, unsigned int x, unsigned int y, unsigned int w,
  340. unsigned int h, unsigned int linepitch, unsigned int color)
  341. {
  342. int i = 0;
  343. int j = 0;
  344. unsigned long start_addr = addr + linepitch * y + x * 4;
  345. DISPMSG("addr=0x%lx, start_addr=0x%lx, x=%d,y=%d,w=%d,h=%d,linepitch=%d, color=0x%08x\n",
  346. addr, start_addr, x, y, w, h, linepitch, color);
  347. for (j = 0; j < h; j++) {
  348. for (i = 0; i < w; i++)
  349. *(unsigned long *)(start_addr + i * 4 + j * linepitch) = color;
  350. }
  351. }
  352. /* extern void smp_inner_dcache_flush_all(void); */
  353. static int g_display_debug_pattern_index;
  354. void _debug_pattern(unsigned long mva, unsigned long va, unsigned int w, unsigned int h,
  355. unsigned int linepitch, unsigned int color, unsigned int layerid,
  356. unsigned int bufidx)
  357. {
  358. unsigned long addr = 0;
  359. unsigned int layer_size = 0;
  360. unsigned int mapped_size = 0;
  361. unsigned int bcolor = 0xff808080;
  362. if (g_display_debug_pattern_index == 0)
  363. return;
  364. if (layerid == 0)
  365. bcolor = 0x0000ffff;
  366. else if (layerid == 1)
  367. bcolor = 0x00ff00ff;
  368. else if (layerid == 2)
  369. bcolor = 0xff0000ff;
  370. else if (layerid == 3)
  371. bcolor = 0xffff00ff;
  372. if (va) {
  373. addr = va;
  374. } else {
  375. layer_size = linepitch * h;
  376. m4u_mva_map_kernel(mva, layer_size, &addr, &mapped_size);
  377. if (mapped_size == 0) {
  378. DISPERR("m4u_mva_map_kernel failed\n");
  379. return;
  380. }
  381. }
  382. switch (g_display_debug_pattern_index) {
  383. case 1:
  384. {
  385. unsigned int resize_factor = layerid + 1;
  386. _draw_rect(addr, w / 10 * resize_factor + 0, h / 10 * resize_factor + 0,
  387. w / 10 * (10 - resize_factor) - 0,
  388. h / 10 * (10 - resize_factor) - 0, linepitch, bcolor);
  389. _draw_rect(addr, w / 10 * resize_factor + 1, h / 10 * resize_factor + 1,
  390. w / 10 * (10 - resize_factor) - 1,
  391. h / 10 * (10 - resize_factor) - 1, linepitch, bcolor);
  392. _draw_rect(addr, w / 10 * resize_factor + 2, h / 10 * resize_factor + 2,
  393. w / 10 * (10 - resize_factor) - 2,
  394. h / 10 * (10 - resize_factor) - 2, linepitch, bcolor);
  395. _draw_rect(addr, w / 10 * resize_factor + 3, h / 10 * resize_factor + 3,
  396. w / 10 * (10 - resize_factor) - 3,
  397. h / 10 * (10 - resize_factor) - 3, linepitch, bcolor);
  398. break;
  399. }
  400. case 2:
  401. {
  402. int bw = 20;
  403. int bh = 20;
  404. _draw_block(addr, bufidx % (w / bw) * bw,
  405. bufidx % (w * h / bh / bh) / (w / bh) * bh, bw, bh, linepitch,
  406. bcolor);
  407. break;
  408. }
  409. case 3:
  410. {
  411. int bw = 20;
  412. int bh = 20;
  413. _draw_block(addr, bufidx % (w / bw) * bw,
  414. bufidx % (w * h / bh / bh) / (w / bh) * bh, bw, bh, linepitch,
  415. bcolor);
  416. break;
  417. }
  418. }
  419. /* smp_inner_dcache_flush_all(); */
  420. /* outer_flush_all(); */
  421. if (mapped_size)
  422. m4u_mva_unmap_kernel(addr, layer_size, addr);
  423. }
  424. #define DEBUG_FPS_METER_SHOW_COUNT 60
  425. static int _fps_meter_array[DEBUG_FPS_METER_SHOW_COUNT] = { 0 };
  426. static unsigned long long _last_ts;
  427. void _debug_fps_meter(unsigned long mva, unsigned long va, unsigned int w, unsigned int h,
  428. unsigned int linepitch, unsigned int color, unsigned int layerid,
  429. unsigned int bufidx)
  430. {
  431. int i = 0;
  432. unsigned long addr = 0;
  433. unsigned int layer_size = 0;
  434. unsigned int mapped_size = 0;
  435. unsigned long long current_ts = sched_clock();
  436. unsigned long long t = current_ts;
  437. unsigned long mod = 0;
  438. unsigned long current_idx = 0;
  439. unsigned long long l = _last_ts;
  440. if (g_display_debug_pattern_index != 3)
  441. return;
  442. DISPMSG("layerid=%d\n", layerid);
  443. _last_ts = current_ts;
  444. if (va) {
  445. addr = va;
  446. } else {
  447. layer_size = linepitch * h;
  448. m4u_mva_map_kernel(mva, layer_size, &addr, &mapped_size);
  449. if (mapped_size == 0) {
  450. DISPERR("m4u_mva_map_kernel failed\n");
  451. return;
  452. }
  453. }
  454. mod = do_div(t, 1000 * 1000 * 1000);
  455. do_div(l, 1000 * 1000 * 1000);
  456. if (t != l) {
  457. memset((void *)_fps_meter_array, 0, sizeof(_fps_meter_array));
  458. _draw_block(addr, 0, 10, w, 36, linepitch, 0x00000000);
  459. }
  460. current_idx = mod / 1000 / 16666;
  461. DISPMSG("mod=%ld, current_idx=%ld\n", mod, current_idx);
  462. _fps_meter_array[current_idx]++;
  463. for (i = 0; i < DEBUG_FPS_METER_SHOW_COUNT; i++) {
  464. if (_fps_meter_array[i])
  465. _draw_block(addr, i * 18, 10, 18, 18 * _fps_meter_array[i], linepitch,
  466. 0xff0000ff);
  467. else
  468. ; /* _draw_block(addr, i*18, 10, 18, 18, linepitch, 0x00000000); */
  469. }
  470. /* smp_inner_dcache_flush_all(); */
  471. /* outer_flush_all(); */
  472. if (mapped_size)
  473. m4u_mva_unmap_kernel(addr, layer_size, addr);
  474. }
  475. static void process_dbg_opt(const char *opt)
  476. {
  477. int ret = 0;
  478. if (0 == strncmp(opt, "dsipattern", 10)) {
  479. char *p = (char *)opt + 11;
  480. unsigned long int pattern = 0;
  481. ret = kstrtoul(p, 16, &pattern);
  482. if (ret)
  483. pr_err("DISP/%s: errno %d\n", __func__, ret);
  484. if (pattern) {
  485. DSI_BIST_Pattern_Test(DISP_MODULE_DSI0, NULL, true, pattern);
  486. DISPMSG("enable dsi pattern: 0x%08lx\n", pattern);
  487. } else {
  488. primary_display_manual_lock();
  489. DSI_BIST_Pattern_Test(DISP_MODULE_DSI0, NULL, false, 0);
  490. primary_display_manual_unlock();
  491. return;
  492. }
  493. } else if (0 == strncmp(opt, "dvfs_test:", 10)) {
  494. char *p = (char *)opt + 10;
  495. unsigned int val = (unsigned int)simple_strtoul(p, &p, 16);
  496. switch (val) {
  497. case 0:
  498. case 1:
  499. case 2:
  500. /* normal test */
  501. primary_display_switch_mmsys_clk(dvfs_test, val);
  502. break;
  503. default:
  504. /* finish */
  505. break;
  506. }
  507. pr_err("DISP/ERROR " "DVFS mode:%d->%d\n", dvfs_test, val);
  508. dvfs_test = val;
  509. } else if (0 == strncmp(opt, "mobile:", 7)) {
  510. if (0 == strncmp(opt + 7, "on", 2))
  511. g_mobilelog = 1;
  512. else if (0 == strncmp(opt + 7, "off", 3))
  513. g_mobilelog = 0;
  514. } else if (0 == strncmp(opt, "trigger", 7)) {
  515. int i = 0;
  516. for (i = 0; i < 1200; i++)
  517. dpmgr_module_notify(DISP_MODULE_AAL, DISP_PATH_EVENT_TRIGGER);
  518. } else if (0 == strncmp(opt, "diagnose", 8)) {
  519. primary_display_diagnose();
  520. return;
  521. } else if (0 == strncmp(opt, "_efuse_test", 11)) {
  522. primary_display_check_test();
  523. } else if (0 == strncmp(opt, "trigger", 7)) {
  524. display_primary_path_context *ctx = primary_display_path_lock("debug");
  525. if (ctx)
  526. dpmgr_signal_event(ctx->dpmgr_handle, DISP_PATH_EVENT_TRIGGER);
  527. primary_display_path_unlock("debug");
  528. return;
  529. } else if (0 == strncmp(opt, "dprec_reset", 11)) {
  530. dprec_logger_reset_all();
  531. return;
  532. } else if (0 == strncmp(opt, "suspend", 4)) {
  533. primary_display_suspend();
  534. return;
  535. } else if (0 == strncmp(opt, "ata", 3)) {
  536. mtkfb_fm_auto_test();
  537. return;
  538. } else if (0 == strncmp(opt, "resume", 4)) {
  539. primary_display_resume();
  540. } else if (0 == strncmp(opt, "dalprintf", 9)) {
  541. DAL_Printf("display aee layer test\n");
  542. } else if (0 == strncmp(opt, "dalclean", 8)) {
  543. DAL_Clean();
  544. } else if (0 == strncmp(opt, "DP", 2)) {
  545. char *p = (char *)opt + 3;
  546. unsigned long int pattern = 0;
  547. ret = kstrtoul(p, 16, &pattern);
  548. if (ret)
  549. pr_err("DISP/%s: errno %d\n", __func__, ret);
  550. g_display_debug_pattern_index = (int)pattern;
  551. return;
  552. } else if (0 == strncmp(opt, "dsi0_clk:", 9)) {
  553. char *p = (char *)opt + 9;
  554. unsigned long int clk = 0;
  555. ret = kstrtoul(p, 10, &clk);
  556. if (ret)
  557. pr_err("DISP/%s: errno %d\n", __func__, ret);
  558. DSI_ChangeClk(DISP_MODULE_DSI0, (uint32_t)clk);
  559. } else if (0 == strncmp(opt, "diagnose", 8)) {
  560. primary_display_diagnose();
  561. return;
  562. } else if (0 == strncmp(opt, "switch:", 7)) {
  563. char *p = (char *)opt + 7;
  564. unsigned long int mode = 0;
  565. ret = kstrtoul(p, 10, &mode);
  566. if (ret)
  567. pr_err("DISP/%s: errno %d\n", __func__, ret);
  568. primary_display_switch_dst_mode((uint32_t)mode % 2);
  569. return;
  570. } else if (0 == strncmp(opt, "disp_mode:", 10)) {
  571. char *p = (char *)opt + 10;
  572. unsigned long int disp_mode = 0;
  573. ret = kstrtoul(p, 10, &disp_mode);
  574. gTriggerDispMode = (int)disp_mode;
  575. if (ret)
  576. pr_err("DISP/%s: errno %d\n", __func__, ret);
  577. DISPMSG("DDP: gTriggerDispMode=%d\n", gTriggerDispMode);
  578. } else if (0 == strncmp(opt, "regw:", 5)) {
  579. char *p = (char *)opt + 5;
  580. unsigned long addr = 0;
  581. unsigned long val = 0;
  582. ret = kstrtoul(p, 16, &addr);
  583. if (ret)
  584. pr_err("DISP/%s: errno %d\n", __func__, ret);
  585. ret = kstrtoul(p + 1, 16, &val);
  586. if (ret)
  587. pr_err("DISP/%s: errno %d\n", __func__, ret);
  588. if (addr)
  589. OUTREG32(addr, val);
  590. else
  591. return;
  592. } else if (0 == strncmp(opt, "regr:", 5)) {
  593. char *p = (char *)opt + 5;
  594. unsigned long addr = 0;
  595. ret = kstrtoul(p, 16, (unsigned long int *)&addr);
  596. if (ret)
  597. pr_err("DISP/%s: errno %d\n", __func__, ret);
  598. if (addr)
  599. pr_debug("Read register 0x%lx: 0x%08x\n", addr, INREG32(addr));
  600. else
  601. return;
  602. } else if (0 == strncmp(opt, "cmmva_dprec", 11)) {
  603. dprec_handle_option(0x7);
  604. } else if (0 == strncmp(opt, "cmmpa_dprec", 11)) {
  605. dprec_handle_option(0x3);
  606. } else if (0 == strncmp(opt, "dprec", 5)) {
  607. char *p = (char *)opt + 6;
  608. unsigned long int option = 0;
  609. ret = kstrtoul(p, 16, (unsigned long int *)&option);
  610. if (ret)
  611. pr_err("DISP/%s: errno %d\n", __func__, ret);
  612. dprec_handle_option((int)option);
  613. } else if (0 == strncmp(opt, "cmdq", 4)) {
  614. char *p = (char *)opt + 5;
  615. unsigned long int option = 0;
  616. ret = kstrtoul(p, 16, &option);
  617. if (ret)
  618. pr_err("DISP/%s: errno %d\n", __func__, ret);
  619. if (option)
  620. primary_display_switch_cmdq_cpu(CMDQ_ENABLE);
  621. else
  622. primary_display_switch_cmdq_cpu(CMDQ_DISABLE);
  623. } else if (0 == strncmp(opt, "maxlayer", 8)) {
  624. char *p = (char *)opt + 9;
  625. unsigned long int maxlayer = 0;
  626. ret = kstrtoul(p, 10, &maxlayer);
  627. if (ret)
  628. pr_err("DISP/%s: errno %d\n", __func__, ret);
  629. if (maxlayer)
  630. primary_display_set_max_layer((int)maxlayer);
  631. else
  632. DISPERR("can't set max layer to 0\n");
  633. } else if (0 == strncmp(opt, "primary_reset", 13)) {
  634. primary_display_reset();
  635. } else if (0 == strncmp(opt, "esd_check", 9)) {
  636. char *p = (char *)opt + 10;
  637. unsigned long int enable = 0;
  638. ret = kstrtoul(p, 10, &enable);
  639. if (ret)
  640. pr_err("DISP/%s: errno %d\n", __func__, ret);
  641. primary_display_esd_check_enable((int)enable);
  642. } else if (0 == strncmp(opt, "cmd:", 4)) {
  643. char *p = (char *)opt + 4;
  644. unsigned long int value = 0;
  645. int lcm_cmd[5];
  646. unsigned int cmd_num = 1;
  647. ret = kstrtoul(p, 5, &value);
  648. if (ret)
  649. pr_err("DISP/%s: errno %d\n", __func__, ret);
  650. lcm_cmd[0] = (int)value;
  651. primary_display_set_cmd(lcm_cmd, cmd_num);
  652. } else if (0 == strncmp(opt, "esd_recovery", 12)) {
  653. primary_display_esd_recovery();
  654. } else if (0 == strncmp(opt, "lcm0_reset", 10)) {
  655. #if 1
  656. DISP_CPU_REG_SET(DDP_REG_BASE_MMSYS_CONFIG + 0x150, 1);
  657. /* msleep(10); */
  658. usleep_range(10000, 11000);
  659. DISP_CPU_REG_SET(DDP_REG_BASE_MMSYS_CONFIG + 0x150, 0);
  660. /* msleep(10); */
  661. usleep_range(10000, 11000);
  662. DISP_CPU_REG_SET(DDP_REG_BASE_MMSYS_CONFIG + 0x150, 1);
  663. #else
  664. #if 0
  665. mt_set_gpio_mode(GPIO106 | 0x80000000, GPIO_MODE_00);
  666. mt_set_gpio_dir(GPIO106 | 0x80000000, GPIO_DIR_OUT);
  667. mt_set_gpio_out(GPIO106 | 0x80000000, GPIO_OUT_ONE);
  668. /* msleep(10); */
  669. usleep_range(10000, 11000);
  670. mt_set_gpio_out(GPIO106 | 0x80000000, GPIO_OUT_ZERO);
  671. /* msleep(10); */
  672. usleep_range(10000, 11000);
  673. mt_set_gpio_out(GPIO106 | 0x80000000, GPIO_OUT_ONE);
  674. #endif
  675. #endif
  676. } else if (0 == strncmp(opt, "lcm0_reset0", 11)) {
  677. DISP_CPU_REG_SET(DDP_REG_BASE_MMSYS_CONFIG + 0x150, 0);
  678. } else if (0 == strncmp(opt, "lcm0_reset1", 11)) {
  679. DISP_CPU_REG_SET(DDP_REG_BASE_MMSYS_CONFIG + 0x150, 1);
  680. } else if (0 == strncmp(opt, "cg", 2)) {
  681. char *p = (char *)opt + 2;
  682. unsigned long int enable = 0;
  683. ret = kstrtoul(p, 10, &enable);
  684. if (ret)
  685. pr_err("DISP/%s: errno %d\n", __func__, ret);
  686. primary_display_enable_path_cg((int)enable);
  687. } else if (0 == strncmp(opt, "ovl2mem:", 8)) {
  688. if (0 == strncmp(opt + 8, "on", 2))
  689. switch_ovl1_to_mem(true);
  690. else
  691. switch_ovl1_to_mem(false);
  692. } else if (0 == strncmp(opt, "dump_layer:", 11)) {
  693. if (0 == strncmp(opt + 11, "on", 2)) {
  694. char *p = (char *)opt + 14;
  695. unsigned long int temp;
  696. ret = kstrtoul(p, 10, &temp);
  697. gCapturePriLayerDownX = (int)temp;
  698. if (ret)
  699. pr_err("DISP/%s: errno %d\n", __func__, ret);
  700. ret = kstrtoul(p + 1, 10, (unsigned long int *)&temp);
  701. gCapturePriLayerDownY = (int)temp;
  702. if (ret)
  703. pr_err("DISP/%s: errno %d\n", __func__, ret);
  704. ret = kstrtoul(p + 1, 10, (unsigned long int *)&temp);
  705. gCapturePriLayerNum = (int)temp;
  706. if (ret)
  707. pr_err("DISP/%s: errno %d\n", __func__, ret);
  708. gCapturePriLayerEnable = 1;
  709. if (gCapturePriLayerDownX == 0)
  710. gCapturePriLayerDownX = 20;
  711. if (gCapturePriLayerDownY == 0)
  712. gCapturePriLayerDownY = 20;
  713. pr_debug("dump_layer En %d DownX %d DownY %d,Num %d",
  714. gCapturePriLayerEnable, gCapturePriLayerDownX,
  715. gCapturePriLayerDownY, gCapturePriLayerNum);
  716. } else if (0 == strncmp(opt + 11, "off", 3)) {
  717. gCapturePriLayerEnable = 0;
  718. gCapturePriLayerNum = OVL_LAYER_NUM;
  719. pr_debug("dump_layer En %d\n", gCapturePriLayerEnable);
  720. }
  721. } else if (0 == strncmp(opt, "dump_decouple:", 14)) {
  722. if (0 == strncmp(opt + 14, "on", 2)) {
  723. char *p = (char *)opt + 17;
  724. unsigned long int temp;
  725. ret = kstrtoul(p, 10, &temp);
  726. gCapturePriLayerDownX = (int)temp;
  727. if (ret)
  728. pr_err("DISP/%s: errno %d\n", __func__, ret);
  729. ret = kstrtoul(p + 1, 10, &temp);
  730. gCapturePriLayerDownY = (int)temp;
  731. if (ret)
  732. pr_err("DISP/%s: errno %d\n", __func__, ret);
  733. ret = kstrtoul(p + 1, 10, &temp);
  734. gCapturePriLayerNum = (int)temp;
  735. if (ret)
  736. pr_err("DISP/%s: errno %d\n", __func__, ret);
  737. gCaptureWdmaLayerEnable = 1;
  738. if (gCapturePriLayerDownX == 0)
  739. gCapturePriLayerDownX = 20;
  740. if (gCapturePriLayerDownY == 0)
  741. gCapturePriLayerDownY = 20;
  742. pr_debug("dump_decouple En %d DownX %d DownY %d,Num %d",
  743. gCaptureWdmaLayerEnable, gCapturePriLayerDownX,
  744. gCapturePriLayerDownY, gCapturePriLayerNum);
  745. } else if (0 == strncmp(opt + 14, "off", 3)) {
  746. gCaptureWdmaLayerEnable = 0;
  747. pr_debug("dump_decouple En %d\n", gCaptureWdmaLayerEnable);
  748. }
  749. } else if (0 == strncmp(opt, "bkl:", 4)) {
  750. char *p = (char *)opt + 4;
  751. unsigned long int level = 0;
  752. ret = kstrtoul(p, 10, &level);
  753. if (ret)
  754. pr_err("DISP/%s: errno %d\n", __func__, ret);
  755. pr_debug("process_dbg_opt(), set backlight level = %ld\n", level);
  756. primary_display_setbacklight(level);
  757. }
  758. }
  759. static void process_dbg_cmd(char *cmd)
  760. {
  761. char *tok;
  762. pr_debug("DISP/DBG " "[mtkfb_dbg] %s\n", cmd);
  763. while ((tok = strsep(&cmd, " ")) != NULL)
  764. process_dbg_opt(tok);
  765. }
  766. /* --------------------------------------------------------------------------- */
  767. /* Debug FileSystem Routines */
  768. /* --------------------------------------------------------------------------- */
  769. struct dentry *mtkfb_dbgfs = NULL;
  770. static int debug_open(struct inode *inode, struct file *file)
  771. {
  772. file->private_data = inode->i_private;
  773. return 0;
  774. }
  775. #if defined(CONFIG_MT_ENG_BUILD) || !defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
  776. static char debug_buffer[4096 + 30 * 16 * 1024];
  777. #else
  778. static char debug_buffer[10240];
  779. #endif
  780. void debug_info_dump_to_printk(char *buf, int buf_len)
  781. {
  782. int i = 0;
  783. int n = buf_len;
  784. for (i = 0; i < n; i += 256)
  785. DISPMSG("%s", buf + i);
  786. }
  787. static ssize_t debug_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos)
  788. {
  789. const int debug_bufmax = sizeof(debug_buffer) - 1;
  790. static int n;
  791. /* Debugfs read only fetch 4096 byte each time, thus whole ringbuffer need massive
  792. * iteration. We only copy ringbuffer content to debugfs buffer at first time (*ppos = 0)
  793. */
  794. if (*ppos != 0)
  795. goto out;
  796. DISPFUNC();
  797. n = mtkfb_get_debug_state(debug_buffer + n, debug_bufmax - n);
  798. n += primary_display_get_debug_state(debug_buffer + n, debug_bufmax - n);
  799. n += disp_sync_get_debug_info(debug_buffer + n, debug_bufmax - n);
  800. n += dprec_logger_get_result_string_all(debug_buffer + n, debug_bufmax - n);
  801. n += primary_display_check_path(debug_buffer + n, debug_bufmax - n);
  802. n += dprec_logger_get_buf(DPREC_LOGGER_ERROR, debug_buffer + n, debug_bufmax - n);
  803. n += dprec_logger_get_buf(DPREC_LOGGER_FENCE, debug_buffer + n, debug_bufmax - n);
  804. n += dprec_logger_get_buf(DPREC_LOGGER_DUMP, debug_buffer + n, debug_bufmax - n);
  805. n += dprec_logger_get_buf(DPREC_LOGGER_DEBUG, debug_buffer + n, debug_bufmax - n);
  806. out:
  807. return simple_read_from_buffer(ubuf, count, ppos, debug_buffer, n);
  808. }
  809. static ssize_t debug_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
  810. {
  811. const int debug_bufmax = sizeof(debug_buffer) - 1;
  812. size_t ret;
  813. ret = count;
  814. if (count > debug_bufmax)
  815. count = debug_bufmax;
  816. if (copy_from_user(&debug_buffer, ubuf, count))
  817. return -EFAULT;
  818. debug_buffer[count] = 0;
  819. process_dbg_cmd(debug_buffer);
  820. return ret;
  821. }
  822. static const struct file_operations debug_fops = {
  823. .read = debug_read,
  824. .write = debug_write,
  825. .open = debug_open,
  826. };
  827. #ifdef MTKFB_DEBUG_FS_CAPTURE_LAYER_CONTENT_SUPPORT
  828. static int layer_debug_open(struct inode *inode, struct file *file)
  829. {
  830. MTKFB_LAYER_DBG_OPTIONS *dbgopt;
  831. /* /record the private data */
  832. file->private_data = inode->i_private;
  833. dbgopt = (MTKFB_LAYER_DBG_OPTIONS *) file->private_data;
  834. dbgopt->working_size = DISP_GetScreenWidth() * DISP_GetScreenHeight() * 2 + 32;
  835. dbgopt->working_buf = (unsigned long)vmalloc(dbgopt->working_size);
  836. if (dbgopt->working_buf == 0)
  837. pr_debug("DISP/DBG Vmalloc to get temp buffer failed\n");
  838. return 0;
  839. }
  840. static ssize_t layer_debug_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos)
  841. {
  842. return 0;
  843. }
  844. static ssize_t layer_debug_write(struct file *file,
  845. const char __user *ubuf, size_t count, loff_t *ppos)
  846. {
  847. MTKFB_LAYER_DBG_OPTIONS *dbgopt = (MTKFB_LAYER_DBG_OPTIONS *) file->private_data;
  848. pr_debug("DISP/DBG " "mtkfb_layer%d write is not implemented yet\n", dbgopt->layer_index);
  849. return count;
  850. }
  851. static int layer_debug_release(struct inode *inode, struct file *file)
  852. {
  853. MTKFB_LAYER_DBG_OPTIONS *dbgopt;
  854. dbgopt = (MTKFB_LAYER_DBG_OPTIONS *) file->private_data;
  855. if (dbgopt->working_buf != 0)
  856. vfree((void *)dbgopt->working_buf);
  857. dbgopt->working_buf = 0;
  858. return 0;
  859. }
  860. static const struct file_operations layer_debug_fops = {
  861. .read = layer_debug_read,
  862. .write = layer_debug_write,
  863. .open = layer_debug_open,
  864. .release = layer_debug_release,
  865. };
  866. #endif
  867. void DBG_Init(void)
  868. {
  869. mtkfb_dbgfs = debugfs_create_file("mtkfb", S_IFREG | S_IRUGO, NULL, (void *)0, &debug_fops);
  870. memset(&dbg_opt, 0, sizeof(dbg_opt));
  871. memset(&fps, 0, sizeof(fps));
  872. dbg_opt.log_fps_wnd_size = DEFAULT_LOG_FPS_WND_SIZE;
  873. /* xuecheng, enable fps log by default */
  874. dbg_opt.en_fps_log = 1;
  875. #ifdef MTKFB_DEBUG_FS_CAPTURE_LAYER_CONTENT_SUPPORT
  876. {
  877. unsigned int i;
  878. unsigned char a[13];
  879. a[0] = 'm';
  880. a[1] = 't';
  881. a[2] = 'k';
  882. a[3] = 'f';
  883. a[4] = 'b';
  884. a[5] = '_';
  885. a[6] = 'l';
  886. a[7] = 'a';
  887. a[8] = 'y';
  888. a[9] = 'e';
  889. a[10] = 'r';
  890. a[11] = '0';
  891. a[12] = '\0';
  892. for (i = 0; i < DDP_OVL_LAYER_MUN; i++) {
  893. a[11] = '0' + i;
  894. mtkfb_layer_dbg_opt[i].layer_index = i;
  895. mtkfb_layer_dbgfs[i] = debugfs_create_file(a,
  896. S_IFREG | S_IRUGO, NULL,
  897. (void *)&mtkfb_layer_dbg_opt[i],
  898. &layer_debug_fops);
  899. }
  900. }
  901. #endif
  902. }
  903. void DBG_Deinit(void)
  904. {
  905. debugfs_remove(mtkfb_dbgfs);
  906. #ifdef MTKFB_DEBUG_FS_CAPTURE_LAYER_CONTENT_SUPPORT
  907. {
  908. unsigned int i;
  909. for (i = 0; i < DDP_OVL_LAYER_MUN; i++)
  910. debugfs_remove(mtkfb_layer_dbgfs[i]);
  911. }
  912. #endif
  913. }