rkisp1-debug.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  2. /*
  3. * Rockchip ISP1 Driver - Base driver
  4. *
  5. * Copyright (C) 2019 Collabora, Ltd.
  6. *
  7. * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
  8. * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
  9. */
  10. #include <linux/debugfs.h>
  11. #include <linux/delay.h>
  12. #include <linux/device.h>
  13. #include <linux/minmax.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/seq_file.h>
  16. #include <linux/string.h>
  17. #include "rkisp1-common.h"
  18. #include "rkisp1-regs.h"
  19. struct rkisp1_debug_register {
  20. u32 reg;
  21. u32 shd;
  22. const char * const name;
  23. };
  24. #define RKISP1_DEBUG_REG(name) { RKISP1_CIF_##name, 0, #name }
  25. #define RKISP1_DEBUG_SHD_REG(name) { \
  26. RKISP1_CIF_##name, RKISP1_CIF_##name##_SHD, #name \
  27. }
  28. /* Keep this up-to-date when adding new registers. */
  29. #define RKISP1_MAX_REG_LENGTH 21
  30. static int rkisp1_debug_dump_regs(struct rkisp1_device *rkisp1,
  31. struct seq_file *m, unsigned int offset,
  32. const struct rkisp1_debug_register *regs)
  33. {
  34. const int width = RKISP1_MAX_REG_LENGTH;
  35. u32 val, shd;
  36. int ret;
  37. ret = pm_runtime_get_if_in_use(rkisp1->dev);
  38. if (ret <= 0)
  39. return ret ? : -ENODATA;
  40. for (; regs->name; ++regs) {
  41. val = rkisp1_read(rkisp1, offset + regs->reg);
  42. if (regs->shd) {
  43. shd = rkisp1_read(rkisp1, offset + regs->shd);
  44. seq_printf(m, "%*s: 0x%08x/0x%08x\n", width, regs->name,
  45. val, shd);
  46. } else {
  47. seq_printf(m, "%*s: 0x%08x\n", width, regs->name, val);
  48. }
  49. }
  50. pm_runtime_put(rkisp1->dev);
  51. return 0;
  52. }
  53. static int rkisp1_debug_dump_core_regs_show(struct seq_file *m, void *p)
  54. {
  55. static const struct rkisp1_debug_register registers[] = {
  56. RKISP1_DEBUG_REG(VI_CCL),
  57. RKISP1_DEBUG_REG(VI_ICCL),
  58. RKISP1_DEBUG_REG(VI_IRCL),
  59. RKISP1_DEBUG_REG(VI_DPCL),
  60. RKISP1_DEBUG_REG(MI_CTRL),
  61. RKISP1_DEBUG_REG(MI_BYTE_CNT),
  62. RKISP1_DEBUG_REG(MI_CTRL_SHD),
  63. RKISP1_DEBUG_REG(MI_RIS),
  64. RKISP1_DEBUG_REG(MI_STATUS),
  65. RKISP1_DEBUG_REG(MI_DMA_CTRL),
  66. RKISP1_DEBUG_REG(MI_DMA_STATUS),
  67. { /* Sentinel */ },
  68. };
  69. struct rkisp1_device *rkisp1 = m->private;
  70. return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
  71. }
  72. DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_core_regs);
  73. static int rkisp1_debug_dump_isp_regs_show(struct seq_file *m, void *p)
  74. {
  75. static const struct rkisp1_debug_register registers[] = {
  76. RKISP1_DEBUG_REG(ISP_CTRL),
  77. RKISP1_DEBUG_REG(ISP_ACQ_PROP),
  78. RKISP1_DEBUG_REG(ISP_FLAGS_SHD),
  79. RKISP1_DEBUG_REG(ISP_RIS),
  80. RKISP1_DEBUG_REG(ISP_ERR),
  81. RKISP1_DEBUG_SHD_REG(ISP_IS_H_OFFS),
  82. RKISP1_DEBUG_SHD_REG(ISP_IS_V_OFFS),
  83. RKISP1_DEBUG_SHD_REG(ISP_IS_H_SIZE),
  84. RKISP1_DEBUG_SHD_REG(ISP_IS_V_SIZE),
  85. { /* Sentinel */ },
  86. };
  87. struct rkisp1_device *rkisp1 = m->private;
  88. return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
  89. }
  90. DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_isp_regs);
  91. static int rkisp1_debug_dump_rsz_regs_show(struct seq_file *m, void *p)
  92. {
  93. static const struct rkisp1_debug_register registers[] = {
  94. RKISP1_DEBUG_SHD_REG(RSZ_CTRL),
  95. RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HY),
  96. RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HCB),
  97. RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HCR),
  98. RKISP1_DEBUG_SHD_REG(RSZ_SCALE_VY),
  99. RKISP1_DEBUG_SHD_REG(RSZ_SCALE_VC),
  100. RKISP1_DEBUG_SHD_REG(RSZ_PHASE_HY),
  101. RKISP1_DEBUG_SHD_REG(RSZ_PHASE_HC),
  102. RKISP1_DEBUG_SHD_REG(RSZ_PHASE_VY),
  103. RKISP1_DEBUG_SHD_REG(RSZ_PHASE_VC),
  104. { /* Sentinel */ },
  105. };
  106. struct rkisp1_resizer *rsz = m->private;
  107. return rkisp1_debug_dump_regs(rsz->rkisp1, m, rsz->regs_base, registers);
  108. }
  109. DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_rsz_regs);
  110. static int rkisp1_debug_dump_mi_mp_show(struct seq_file *m, void *p)
  111. {
  112. static const struct rkisp1_debug_register registers[] = {
  113. RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_INIT),
  114. RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_INIT2),
  115. RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_SHD),
  116. RKISP1_DEBUG_REG(MI_MP_Y_SIZE_INIT),
  117. RKISP1_DEBUG_REG(MI_MP_Y_SIZE_INIT),
  118. RKISP1_DEBUG_REG(MI_MP_Y_SIZE_SHD),
  119. RKISP1_DEBUG_REG(MI_MP_Y_OFFS_CNT_SHD),
  120. { /* Sentinel */ },
  121. };
  122. struct rkisp1_device *rkisp1 = m->private;
  123. return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
  124. }
  125. DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_mi_mp);
  126. #define RKISP1_DEBUG_DATA_COUNT_BINS 32
  127. #define RKISP1_DEBUG_DATA_COUNT_STEP (4096 / RKISP1_DEBUG_DATA_COUNT_BINS)
  128. static int rkisp1_debug_input_status_show(struct seq_file *m, void *p)
  129. {
  130. struct rkisp1_device *rkisp1 = m->private;
  131. u16 data_count[RKISP1_DEBUG_DATA_COUNT_BINS] = { };
  132. unsigned int hsync_count = 0;
  133. unsigned int vsync_count = 0;
  134. unsigned int i;
  135. u32 data;
  136. u32 val;
  137. int ret;
  138. ret = pm_runtime_get_if_in_use(rkisp1->dev);
  139. if (ret <= 0)
  140. return ret ? : -ENODATA;
  141. /* Sample the ISP input port status 10000 times with a 1µs interval. */
  142. for (i = 0; i < 10000; ++i) {
  143. val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_FLAGS_SHD);
  144. data = (val & RKISP1_CIF_ISP_FLAGS_SHD_S_DATA_MASK)
  145. >> RKISP1_CIF_ISP_FLAGS_SHD_S_DATA_SHIFT;
  146. data_count[data / RKISP1_DEBUG_DATA_COUNT_STEP]++;
  147. if (val & RKISP1_CIF_ISP_FLAGS_SHD_S_HSYNC)
  148. hsync_count++;
  149. if (val & RKISP1_CIF_ISP_FLAGS_SHD_S_VSYNC)
  150. vsync_count++;
  151. udelay(1);
  152. }
  153. pm_runtime_put(rkisp1->dev);
  154. seq_printf(m, "vsync: %u, hsync: %u\n", vsync_count, hsync_count);
  155. seq_puts(m, "data:\n");
  156. for (i = 0; i < ARRAY_SIZE(data_count); ++i)
  157. seq_printf(m, "- [%04u:%04u]: %u\n",
  158. i * RKISP1_DEBUG_DATA_COUNT_STEP,
  159. (i + 1) * RKISP1_DEBUG_DATA_COUNT_STEP - 1,
  160. data_count[i]);
  161. return 0;
  162. }
  163. DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_input_status);
  164. void rkisp1_debug_init(struct rkisp1_device *rkisp1)
  165. {
  166. struct rkisp1_debug *debug = &rkisp1->debug;
  167. struct dentry *regs_dir;
  168. debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL);
  169. debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
  170. &debug->data_loss);
  171. debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir,
  172. &debug->outform_size_error);
  173. debugfs_create_ulong("img_stabilization_size_error", 0444,
  174. debug->debugfs_dir,
  175. &debug->img_stabilization_size_error);
  176. debugfs_create_ulong("inform_size_error", 0444, debug->debugfs_dir,
  177. &debug->inform_size_error);
  178. debugfs_create_ulong("irq_delay", 0444, debug->debugfs_dir,
  179. &debug->irq_delay);
  180. debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
  181. &debug->mipi_error);
  182. debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
  183. &debug->stats_error);
  184. debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
  185. &debug->stop_timeout[RKISP1_MAINPATH]);
  186. debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
  187. &debug->stop_timeout[RKISP1_SELFPATH]);
  188. debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
  189. &debug->frame_drop[RKISP1_MAINPATH]);
  190. debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
  191. &debug->frame_drop[RKISP1_SELFPATH]);
  192. debugfs_create_ulong("complete_frames", 0444, debug->debugfs_dir,
  193. &debug->complete_frames);
  194. debugfs_create_file("input_status", 0444, debug->debugfs_dir, rkisp1,
  195. &rkisp1_debug_input_status_fops);
  196. regs_dir = debugfs_create_dir("regs", debug->debugfs_dir);
  197. debugfs_create_file("core", 0444, regs_dir, rkisp1,
  198. &rkisp1_debug_dump_core_regs_fops);
  199. debugfs_create_file("isp", 0444, regs_dir, rkisp1,
  200. &rkisp1_debug_dump_isp_regs_fops);
  201. debugfs_create_file("mrsz", 0444, regs_dir,
  202. &rkisp1->resizer_devs[RKISP1_MAINPATH],
  203. &rkisp1_debug_dump_rsz_regs_fops);
  204. debugfs_create_file("srsz", 0444, regs_dir,
  205. &rkisp1->resizer_devs[RKISP1_SELFPATH],
  206. &rkisp1_debug_dump_rsz_regs_fops);
  207. debugfs_create_file("mi_mp", 0444, regs_dir, rkisp1,
  208. &rkisp1_debug_dump_mi_mp_fops);
  209. }
  210. void rkisp1_debug_cleanup(struct rkisp1_device *rkisp1)
  211. {
  212. debugfs_remove_recursive(rkisp1->debug.debugfs_dir);
  213. }