bdisp-debug.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /*
  2. * Copyright (C) STMicroelectronics SA 2014
  3. * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
  4. * License terms: GNU General Public License (GPL), version 2
  5. */
  6. #include <linux/debugfs.h>
  7. #include <linux/pm_runtime.h>
  8. #include "bdisp.h"
  9. #include "bdisp-filter.h"
  10. #include "bdisp-reg.h"
  11. void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp)
  12. {
  13. bdisp->dbg.hw_start = ktime_get();
  14. }
  15. void bdisp_dbg_perf_end(struct bdisp_dev *bdisp)
  16. {
  17. s64 time_us;
  18. time_us = ktime_us_delta(ktime_get(), bdisp->dbg.hw_start);
  19. if (!bdisp->dbg.min_duration)
  20. bdisp->dbg.min_duration = time_us;
  21. else
  22. bdisp->dbg.min_duration = min(time_us, bdisp->dbg.min_duration);
  23. bdisp->dbg.last_duration = time_us;
  24. bdisp->dbg.max_duration = max(time_us, bdisp->dbg.max_duration);
  25. bdisp->dbg.tot_duration += time_us;
  26. }
  27. static void bdisp_dbg_dump_ins(struct seq_file *s, u32 val)
  28. {
  29. seq_printf(s, "INS\t0x%08X\t", val);
  30. switch (val & BLT_INS_S1_MASK) {
  31. case BLT_INS_S1_OFF:
  32. break;
  33. case BLT_INS_S1_MEM:
  34. seq_puts(s, "SRC1=mem - ");
  35. break;
  36. case BLT_INS_S1_CF:
  37. seq_puts(s, "SRC1=ColorFill - ");
  38. break;
  39. case BLT_INS_S1_COPY:
  40. seq_puts(s, "SRC1=copy - ");
  41. break;
  42. case BLT_INS_S1_FILL:
  43. seq_puts(s, "SRC1=fil - ");
  44. break;
  45. default:
  46. seq_puts(s, "SRC1=??? - ");
  47. break;
  48. }
  49. switch (val & BLT_INS_S2_MASK) {
  50. case BLT_INS_S2_OFF:
  51. break;
  52. case BLT_INS_S2_MEM:
  53. seq_puts(s, "SRC2=mem - ");
  54. break;
  55. case BLT_INS_S2_CF:
  56. seq_puts(s, "SRC2=ColorFill - ");
  57. break;
  58. default:
  59. seq_puts(s, "SRC2=??? - ");
  60. break;
  61. }
  62. if ((val & BLT_INS_S3_MASK) == BLT_INS_S3_MEM)
  63. seq_puts(s, "SRC3=mem - ");
  64. if (val & BLT_INS_IVMX)
  65. seq_puts(s, "IVMX - ");
  66. if (val & BLT_INS_CLUT)
  67. seq_puts(s, "CLUT - ");
  68. if (val & BLT_INS_SCALE)
  69. seq_puts(s, "Scale - ");
  70. if (val & BLT_INS_FLICK)
  71. seq_puts(s, "Flicker - ");
  72. if (val & BLT_INS_CLIP)
  73. seq_puts(s, "Clip - ");
  74. if (val & BLT_INS_CKEY)
  75. seq_puts(s, "ColorKey - ");
  76. if (val & BLT_INS_OVMX)
  77. seq_puts(s, "OVMX - ");
  78. if (val & BLT_INS_DEI)
  79. seq_puts(s, "Deint - ");
  80. if (val & BLT_INS_PMASK)
  81. seq_puts(s, "PlaneMask - ");
  82. if (val & BLT_INS_VC1R)
  83. seq_puts(s, "VC1R - ");
  84. if (val & BLT_INS_ROTATE)
  85. seq_puts(s, "Rotate - ");
  86. if (val & BLT_INS_GRAD)
  87. seq_puts(s, "GradFill - ");
  88. if (val & BLT_INS_AQLOCK)
  89. seq_puts(s, "AQLock - ");
  90. if (val & BLT_INS_PACE)
  91. seq_puts(s, "Pace - ");
  92. if (val & BLT_INS_IRQ)
  93. seq_puts(s, "IRQ - ");
  94. seq_puts(s, "\n");
  95. }
  96. static void bdisp_dbg_dump_tty(struct seq_file *s, u32 val)
  97. {
  98. seq_printf(s, "TTY\t0x%08X\t", val);
  99. seq_printf(s, "Pitch=%d - ", val & 0xFFFF);
  100. switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) {
  101. case BDISP_RGB565:
  102. seq_puts(s, "RGB565 - ");
  103. break;
  104. case BDISP_RGB888:
  105. seq_puts(s, "RGB888 - ");
  106. break;
  107. case BDISP_XRGB8888:
  108. seq_puts(s, "xRGB888 - ");
  109. break;
  110. case BDISP_ARGB8888:
  111. seq_puts(s, "ARGB8888 - ");
  112. break;
  113. case BDISP_NV12:
  114. seq_puts(s, "NV12 - ");
  115. break;
  116. case BDISP_YUV_3B:
  117. seq_puts(s, "YUV420P - ");
  118. break;
  119. default:
  120. seq_puts(s, "ColorFormat ??? - ");
  121. break;
  122. }
  123. if (val & BLT_TTY_ALPHA_R)
  124. seq_puts(s, "AlphaRange - ");
  125. if (val & BLT_TTY_CR_NOT_CB)
  126. seq_puts(s, "CrNotCb - ");
  127. if (val & BLT_TTY_MB)
  128. seq_puts(s, "MB - ");
  129. if (val & BLT_TTY_HSO)
  130. seq_puts(s, "HSO inverse - ");
  131. if (val & BLT_TTY_VSO)
  132. seq_puts(s, "VSO inverse - ");
  133. if (val & BLT_TTY_DITHER)
  134. seq_puts(s, "Dither - ");
  135. if (val & BLT_TTY_CHROMA)
  136. seq_puts(s, "Write CHROMA - ");
  137. if (val & BLT_TTY_BIG_END)
  138. seq_puts(s, "BigEndian - ");
  139. seq_puts(s, "\n");
  140. }
  141. static void bdisp_dbg_dump_xy(struct seq_file *s, u32 val, char *name)
  142. {
  143. seq_printf(s, "%s\t0x%08X\t", name, val);
  144. seq_printf(s, "(%d,%d)\n", val & 0xFFFF, (val >> 16));
  145. }
  146. static void bdisp_dbg_dump_sz(struct seq_file *s, u32 val, char *name)
  147. {
  148. seq_printf(s, "%s\t0x%08X\t", name, val);
  149. seq_printf(s, "%dx%d\n", val & 0x1FFF, (val >> 16) & 0x1FFF);
  150. }
  151. static void bdisp_dbg_dump_sty(struct seq_file *s,
  152. u32 val, u32 addr, char *name)
  153. {
  154. bool s1, s2, s3;
  155. seq_printf(s, "%s\t0x%08X\t", name, val);
  156. if (!addr || !name || (strlen(name) < 2))
  157. goto done;
  158. s1 = name[strlen(name) - 1] == '1';
  159. s2 = name[strlen(name) - 1] == '2';
  160. s3 = name[strlen(name) - 1] == '3';
  161. seq_printf(s, "Pitch=%d - ", val & 0xFFFF);
  162. switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) {
  163. case BDISP_RGB565:
  164. seq_puts(s, "RGB565 - ");
  165. break;
  166. case BDISP_RGB888:
  167. seq_puts(s, "RGB888 - ");
  168. break;
  169. case BDISP_XRGB8888:
  170. seq_puts(s, "xRGB888 - ");
  171. break;
  172. case BDISP_ARGB8888:
  173. seq_puts(s, "ARGB888 - ");
  174. break;
  175. case BDISP_NV12:
  176. seq_puts(s, "NV12 - ");
  177. break;
  178. case BDISP_YUV_3B:
  179. seq_puts(s, "YUV420P - ");
  180. break;
  181. default:
  182. seq_puts(s, "ColorFormat ??? - ");
  183. break;
  184. }
  185. if ((val & BLT_TTY_ALPHA_R) && !s3)
  186. seq_puts(s, "AlphaRange - ");
  187. if ((val & BLT_S1TY_A1_SUBSET) && !s3)
  188. seq_puts(s, "A1SubSet - ");
  189. if ((val & BLT_TTY_MB) && !s1)
  190. seq_puts(s, "MB - ");
  191. if (val & BLT_TTY_HSO)
  192. seq_puts(s, "HSO inverse - ");
  193. if (val & BLT_TTY_VSO)
  194. seq_puts(s, "VSO inverse - ");
  195. if ((val & BLT_S1TY_CHROMA_EXT) && (s1 || s2))
  196. seq_puts(s, "ChromaExt - ");
  197. if ((val & BLT_S3TY_BLANK_ACC) && s3)
  198. seq_puts(s, "Blank Acc - ");
  199. if ((val & BTL_S1TY_SUBBYTE) && !s3)
  200. seq_puts(s, "SubByte - ");
  201. if ((val & BLT_S1TY_RGB_EXP) && !s3)
  202. seq_puts(s, "RGBExpand - ");
  203. if ((val & BLT_TTY_BIG_END) && !s3)
  204. seq_puts(s, "BigEndian - ");
  205. done:
  206. seq_puts(s, "\n");
  207. }
  208. static void bdisp_dbg_dump_fctl(struct seq_file *s, u32 val)
  209. {
  210. seq_printf(s, "FCTL\t0x%08X\t", val);
  211. if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SCALE)
  212. seq_puts(s, "Resize Luma - ");
  213. else if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SAMPLE)
  214. seq_puts(s, "Sample Luma - ");
  215. if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SCALE)
  216. seq_puts(s, "Resize Chroma");
  217. else if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SAMPLE)
  218. seq_puts(s, "Sample Chroma");
  219. seq_puts(s, "\n");
  220. }
  221. static void bdisp_dbg_dump_rsf(struct seq_file *s, u32 val, char *name)
  222. {
  223. u32 inc;
  224. seq_printf(s, "%s\t0x%08X\t", name, val);
  225. if (!val)
  226. goto done;
  227. inc = val & 0xFFFF;
  228. seq_printf(s, "H: %d(6.10) / scale~%dx0.1 - ", inc, 1024 * 10 / inc);
  229. inc = val >> 16;
  230. seq_printf(s, "V: %d(6.10) / scale~%dx0.1", inc, 1024 * 10 / inc);
  231. done:
  232. seq_puts(s, "\n");
  233. }
  234. static void bdisp_dbg_dump_rzi(struct seq_file *s, u32 val, char *name)
  235. {
  236. seq_printf(s, "%s\t0x%08X\t", name, val);
  237. if (!val)
  238. goto done;
  239. seq_printf(s, "H: init=%d repeat=%d - ", val & 0x3FF, (val >> 12) & 7);
  240. val >>= 16;
  241. seq_printf(s, "V: init=%d repeat=%d", val & 0x3FF, (val >> 12) & 7);
  242. done:
  243. seq_puts(s, "\n");
  244. }
  245. static void bdisp_dbg_dump_ivmx(struct seq_file *s,
  246. u32 c0, u32 c1, u32 c2, u32 c3)
  247. {
  248. seq_printf(s, "IVMX0\t0x%08X\n", c0);
  249. seq_printf(s, "IVMX1\t0x%08X\n", c1);
  250. seq_printf(s, "IVMX2\t0x%08X\n", c2);
  251. seq_printf(s, "IVMX3\t0x%08X\t", c3);
  252. if (!c0 && !c1 && !c2 && !c3) {
  253. seq_puts(s, "\n");
  254. return;
  255. }
  256. if ((c0 == bdisp_rgb_to_yuv[0]) &&
  257. (c1 == bdisp_rgb_to_yuv[1]) &&
  258. (c2 == bdisp_rgb_to_yuv[2]) &&
  259. (c3 == bdisp_rgb_to_yuv[3])) {
  260. seq_puts(s, "RGB to YUV\n");
  261. return;
  262. }
  263. if ((c0 == bdisp_yuv_to_rgb[0]) &&
  264. (c1 == bdisp_yuv_to_rgb[1]) &&
  265. (c2 == bdisp_yuv_to_rgb[2]) &&
  266. (c3 == bdisp_yuv_to_rgb[3])) {
  267. seq_puts(s, "YUV to RGB\n");
  268. return;
  269. }
  270. seq_puts(s, "Unknown conversion\n");
  271. }
  272. static int bdisp_dbg_last_nodes(struct seq_file *s, void *data)
  273. {
  274. /* Not dumping all fields, focusing on significant ones */
  275. struct bdisp_dev *bdisp = s->private;
  276. struct bdisp_node *node;
  277. int i = 0;
  278. if (!bdisp->dbg.copy_node[0]) {
  279. seq_puts(s, "No node built yet\n");
  280. return 0;
  281. }
  282. do {
  283. node = bdisp->dbg.copy_node[i];
  284. if (!node)
  285. break;
  286. seq_printf(s, "--------\nNode %d:\n", i);
  287. seq_puts(s, "-- General --\n");
  288. seq_printf(s, "NIP\t0x%08X\n", node->nip);
  289. seq_printf(s, "CIC\t0x%08X\n", node->cic);
  290. bdisp_dbg_dump_ins(s, node->ins);
  291. seq_printf(s, "ACK\t0x%08X\n", node->ack);
  292. seq_puts(s, "-- Target --\n");
  293. seq_printf(s, "TBA\t0x%08X\n", node->tba);
  294. bdisp_dbg_dump_tty(s, node->tty);
  295. bdisp_dbg_dump_xy(s, node->txy, "TXY");
  296. bdisp_dbg_dump_sz(s, node->tsz, "TSZ");
  297. /* Color Fill not dumped */
  298. seq_puts(s, "-- Source 1 --\n");
  299. seq_printf(s, "S1BA\t0x%08X\n", node->s1ba);
  300. bdisp_dbg_dump_sty(s, node->s1ty, node->s1ba, "S1TY");
  301. bdisp_dbg_dump_xy(s, node->s1xy, "S1XY");
  302. seq_puts(s, "-- Source 2 --\n");
  303. seq_printf(s, "S2BA\t0x%08X\n", node->s2ba);
  304. bdisp_dbg_dump_sty(s, node->s2ty, node->s2ba, "S2TY");
  305. bdisp_dbg_dump_xy(s, node->s2xy, "S2XY");
  306. bdisp_dbg_dump_sz(s, node->s2sz, "S2SZ");
  307. seq_puts(s, "-- Source 3 --\n");
  308. seq_printf(s, "S3BA\t0x%08X\n", node->s3ba);
  309. bdisp_dbg_dump_sty(s, node->s3ty, node->s3ba, "S3TY");
  310. bdisp_dbg_dump_xy(s, node->s3xy, "S3XY");
  311. bdisp_dbg_dump_sz(s, node->s3sz, "S3SZ");
  312. /* Clipping not dumped */
  313. /* CLUT not dumped */
  314. seq_puts(s, "-- Filter & Mask --\n");
  315. bdisp_dbg_dump_fctl(s, node->fctl);
  316. /* PMK not dumped */
  317. seq_puts(s, "-- Chroma Filter --\n");
  318. bdisp_dbg_dump_rsf(s, node->rsf, "RSF");
  319. bdisp_dbg_dump_rzi(s, node->rzi, "RZI");
  320. seq_printf(s, "HFP\t0x%08X\n", node->hfp);
  321. seq_printf(s, "VFP\t0x%08X\n", node->vfp);
  322. seq_puts(s, "-- Luma Filter --\n");
  323. bdisp_dbg_dump_rsf(s, node->y_rsf, "Y_RSF");
  324. bdisp_dbg_dump_rzi(s, node->y_rzi, "Y_RZI");
  325. seq_printf(s, "Y_HFP\t0x%08X\n", node->y_hfp);
  326. seq_printf(s, "Y_VFP\t0x%08X\n", node->y_vfp);
  327. /* Flicker not dumped */
  328. /* Color key not dumped */
  329. /* Reserved not dumped */
  330. /* Static Address & User not dumped */
  331. seq_puts(s, "-- Input Versatile Matrix --\n");
  332. bdisp_dbg_dump_ivmx(s, node->ivmx0, node->ivmx1,
  333. node->ivmx2, node->ivmx3);
  334. /* Output Versatile Matrix not dumped */
  335. /* Pace not dumped */
  336. /* VC1R & DEI not dumped */
  337. /* Gradient Fill not dumped */
  338. } while ((++i < MAX_NB_NODE) && node->nip);
  339. return 0;
  340. }
  341. static int bdisp_dbg_last_nodes_raw(struct seq_file *s, void *data)
  342. {
  343. struct bdisp_dev *bdisp = s->private;
  344. struct bdisp_node *node;
  345. u32 *val;
  346. int j, i = 0;
  347. if (!bdisp->dbg.copy_node[0]) {
  348. seq_puts(s, "No node built yet\n");
  349. return 0;
  350. }
  351. do {
  352. node = bdisp->dbg.copy_node[i];
  353. if (!node)
  354. break;
  355. seq_printf(s, "--------\nNode %d:\n", i);
  356. val = (u32 *)node;
  357. for (j = 0; j < sizeof(struct bdisp_node) / sizeof(u32); j++)
  358. seq_printf(s, "0x%08X\n", *val++);
  359. } while ((++i < MAX_NB_NODE) && node->nip);
  360. return 0;
  361. }
  362. static const char *bdisp_fmt_to_str(struct bdisp_frame frame)
  363. {
  364. switch (frame.fmt->pixelformat) {
  365. case V4L2_PIX_FMT_YUV420:
  366. return "YUV420P";
  367. case V4L2_PIX_FMT_NV12:
  368. if (frame.field == V4L2_FIELD_INTERLACED)
  369. return "NV12 interlaced";
  370. else
  371. return "NV12";
  372. case V4L2_PIX_FMT_RGB565:
  373. return "RGB16";
  374. case V4L2_PIX_FMT_RGB24:
  375. return "RGB24";
  376. case V4L2_PIX_FMT_XBGR32:
  377. return "XRGB";
  378. case V4L2_PIX_FMT_ABGR32:
  379. return "ARGB";
  380. default:
  381. return "????";
  382. }
  383. }
  384. static int bdisp_dbg_last_request(struct seq_file *s, void *data)
  385. {
  386. struct bdisp_dev *bdisp = s->private;
  387. struct bdisp_request *request = &bdisp->dbg.copy_request;
  388. struct bdisp_frame src, dst;
  389. if (!request->nb_req) {
  390. seq_puts(s, "No request\n");
  391. return 0;
  392. }
  393. src = request->src;
  394. dst = request->dst;
  395. seq_printf(s, "\nRequest #%d\n", request->nb_req);
  396. seq_printf(s, "Format: %s\t\t\t%s\n",
  397. bdisp_fmt_to_str(src), bdisp_fmt_to_str(dst));
  398. seq_printf(s, "Crop area: %dx%d @ %d,%d ==>\t%dx%d @ %d,%d\n",
  399. src.crop.width, src.crop.height,
  400. src.crop.left, src.crop.top,
  401. dst.crop.width, dst.crop.height,
  402. dst.crop.left, dst.crop.top);
  403. seq_printf(s, "Buff size: %dx%d\t\t%dx%d\n\n",
  404. src.width, src.height, dst.width, dst.height);
  405. if (request->hflip)
  406. seq_puts(s, "Horizontal flip\n\n");
  407. if (request->vflip)
  408. seq_puts(s, "Vertical flip\n\n");
  409. return 0;
  410. }
  411. #define DUMP(reg) seq_printf(s, #reg " \t0x%08X\n", readl(bdisp->regs + reg))
  412. static int bdisp_dbg_regs(struct seq_file *s, void *data)
  413. {
  414. struct bdisp_dev *bdisp = s->private;
  415. int ret;
  416. unsigned int i;
  417. ret = pm_runtime_get_sync(bdisp->dev);
  418. if (ret < 0) {
  419. seq_puts(s, "Cannot wake up IP\n");
  420. return 0;
  421. }
  422. seq_printf(s, "Reg @ = 0x%p\n", bdisp->regs);
  423. seq_puts(s, "\nStatic:\n");
  424. DUMP(BLT_CTL);
  425. DUMP(BLT_ITS);
  426. DUMP(BLT_STA1);
  427. DUMP(BLT_AQ1_CTL);
  428. DUMP(BLT_AQ1_IP);
  429. DUMP(BLT_AQ1_LNA);
  430. DUMP(BLT_AQ1_STA);
  431. DUMP(BLT_ITM0);
  432. seq_puts(s, "\nPlugs:\n");
  433. DUMP(BLT_PLUGS1_OP2);
  434. DUMP(BLT_PLUGS1_CHZ);
  435. DUMP(BLT_PLUGS1_MSZ);
  436. DUMP(BLT_PLUGS1_PGZ);
  437. DUMP(BLT_PLUGS2_OP2);
  438. DUMP(BLT_PLUGS2_CHZ);
  439. DUMP(BLT_PLUGS2_MSZ);
  440. DUMP(BLT_PLUGS2_PGZ);
  441. DUMP(BLT_PLUGS3_OP2);
  442. DUMP(BLT_PLUGS3_CHZ);
  443. DUMP(BLT_PLUGS3_MSZ);
  444. DUMP(BLT_PLUGS3_PGZ);
  445. DUMP(BLT_PLUGT_OP2);
  446. DUMP(BLT_PLUGT_CHZ);
  447. DUMP(BLT_PLUGT_MSZ);
  448. DUMP(BLT_PLUGT_PGZ);
  449. seq_puts(s, "\nNode:\n");
  450. DUMP(BLT_NIP);
  451. DUMP(BLT_CIC);
  452. DUMP(BLT_INS);
  453. DUMP(BLT_ACK);
  454. DUMP(BLT_TBA);
  455. DUMP(BLT_TTY);
  456. DUMP(BLT_TXY);
  457. DUMP(BLT_TSZ);
  458. DUMP(BLT_S1BA);
  459. DUMP(BLT_S1TY);
  460. DUMP(BLT_S1XY);
  461. DUMP(BLT_S2BA);
  462. DUMP(BLT_S2TY);
  463. DUMP(BLT_S2XY);
  464. DUMP(BLT_S2SZ);
  465. DUMP(BLT_S3BA);
  466. DUMP(BLT_S3TY);
  467. DUMP(BLT_S3XY);
  468. DUMP(BLT_S3SZ);
  469. DUMP(BLT_FCTL);
  470. DUMP(BLT_RSF);
  471. DUMP(BLT_RZI);
  472. DUMP(BLT_HFP);
  473. DUMP(BLT_VFP);
  474. DUMP(BLT_Y_RSF);
  475. DUMP(BLT_Y_RZI);
  476. DUMP(BLT_Y_HFP);
  477. DUMP(BLT_Y_VFP);
  478. DUMP(BLT_IVMX0);
  479. DUMP(BLT_IVMX1);
  480. DUMP(BLT_IVMX2);
  481. DUMP(BLT_IVMX3);
  482. DUMP(BLT_OVMX0);
  483. DUMP(BLT_OVMX1);
  484. DUMP(BLT_OVMX2);
  485. DUMP(BLT_OVMX3);
  486. DUMP(BLT_DEI);
  487. seq_puts(s, "\nFilter:\n");
  488. for (i = 0; i < BLT_NB_H_COEF; i++) {
  489. seq_printf(s, "BLT_HFC%d \t0x%08X\n", i,
  490. readl(bdisp->regs + BLT_HFC_N + i * 4));
  491. }
  492. for (i = 0; i < BLT_NB_V_COEF; i++) {
  493. seq_printf(s, "BLT_VFC%d \t0x%08X\n", i,
  494. readl(bdisp->regs + BLT_VFC_N + i * 4));
  495. }
  496. seq_puts(s, "\nLuma filter:\n");
  497. for (i = 0; i < BLT_NB_H_COEF; i++) {
  498. seq_printf(s, "BLT_Y_HFC%d \t0x%08X\n", i,
  499. readl(bdisp->regs + BLT_Y_HFC_N + i * 4));
  500. }
  501. for (i = 0; i < BLT_NB_V_COEF; i++) {
  502. seq_printf(s, "BLT_Y_VFC%d \t0x%08X\n", i,
  503. readl(bdisp->regs + BLT_Y_VFC_N + i * 4));
  504. }
  505. pm_runtime_put(bdisp->dev);
  506. return 0;
  507. }
  508. #define SECOND 1000000
  509. static int bdisp_dbg_perf(struct seq_file *s, void *data)
  510. {
  511. struct bdisp_dev *bdisp = s->private;
  512. struct bdisp_request *request = &bdisp->dbg.copy_request;
  513. s64 avg_time_us;
  514. int avg_fps, min_fps, max_fps, last_fps;
  515. if (!request->nb_req) {
  516. seq_puts(s, "No request\n");
  517. return 0;
  518. }
  519. avg_time_us = div64_s64(bdisp->dbg.tot_duration, request->nb_req);
  520. if (avg_time_us > SECOND)
  521. avg_fps = 0;
  522. else
  523. avg_fps = SECOND / (s32)avg_time_us;
  524. if (bdisp->dbg.min_duration > SECOND)
  525. min_fps = 0;
  526. else
  527. min_fps = SECOND / (s32)bdisp->dbg.min_duration;
  528. if (bdisp->dbg.max_duration > SECOND)
  529. max_fps = 0;
  530. else
  531. max_fps = SECOND / (s32)bdisp->dbg.max_duration;
  532. if (bdisp->dbg.last_duration > SECOND)
  533. last_fps = 0;
  534. else
  535. last_fps = SECOND / (s32)bdisp->dbg.last_duration;
  536. seq_printf(s, "HW processing (%d requests):\n", request->nb_req);
  537. seq_printf(s, " Average: %5lld us (%3d fps)\n",
  538. avg_time_us, avg_fps);
  539. seq_printf(s, " Min-Max: %5lld us (%3d fps) - %5lld us (%3d fps)\n",
  540. bdisp->dbg.min_duration, min_fps,
  541. bdisp->dbg.max_duration, max_fps);
  542. seq_printf(s, " Last: %5lld us (%3d fps)\n",
  543. bdisp->dbg.last_duration, last_fps);
  544. return 0;
  545. }
  546. #define bdisp_dbg_declare(name) \
  547. static int bdisp_dbg_##name##_open(struct inode *i, struct file *f) \
  548. { \
  549. return single_open(f, bdisp_dbg_##name, i->i_private); \
  550. } \
  551. static const struct file_operations bdisp_dbg_##name##_fops = { \
  552. .open = bdisp_dbg_##name##_open, \
  553. .read = seq_read, \
  554. .llseek = seq_lseek, \
  555. .release = single_release, \
  556. }
  557. #define bdisp_dbg_create_entry(name) \
  558. debugfs_create_file(#name, S_IRUGO, bdisp->dbg.debugfs_entry, bdisp, \
  559. &bdisp_dbg_##name##_fops)
  560. bdisp_dbg_declare(regs);
  561. bdisp_dbg_declare(last_nodes);
  562. bdisp_dbg_declare(last_nodes_raw);
  563. bdisp_dbg_declare(last_request);
  564. bdisp_dbg_declare(perf);
  565. int bdisp_debugfs_create(struct bdisp_dev *bdisp)
  566. {
  567. char dirname[16];
  568. snprintf(dirname, sizeof(dirname), "%s%d", BDISP_NAME, bdisp->id);
  569. bdisp->dbg.debugfs_entry = debugfs_create_dir(dirname, NULL);
  570. if (!bdisp->dbg.debugfs_entry)
  571. goto err;
  572. if (!bdisp_dbg_create_entry(regs))
  573. goto err;
  574. if (!bdisp_dbg_create_entry(last_nodes))
  575. goto err;
  576. if (!bdisp_dbg_create_entry(last_nodes_raw))
  577. goto err;
  578. if (!bdisp_dbg_create_entry(last_request))
  579. goto err;
  580. if (!bdisp_dbg_create_entry(perf))
  581. goto err;
  582. return 0;
  583. err:
  584. bdisp_debugfs_remove(bdisp);
  585. return 0;
  586. }
  587. void bdisp_debugfs_remove(struct bdisp_dev *bdisp)
  588. {
  589. debugfs_remove_recursive(bdisp->dbg.debugfs_entry);
  590. bdisp->dbg.debugfs_entry = NULL;
  591. }