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