1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
3 * Rockchip ISP1 Driver - Base driver
5 * Copyright (C) 2019 Collabora, Ltd.
7 * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
8 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
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>
19 #include "rkisp1-common.h"
20 #include "rkisp1-regs.h"
22 struct rkisp1_debug_register {
25 const char * const name;
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 \
33 /* Keep this up-to-date when adding new registers. */
34 #define RKISP1_MAX_REG_LENGTH 21
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)
40 const int width = RKISP1_MAX_REG_LENGTH;
44 ret = pm_runtime_get_if_in_use(rkisp1->dev);
46 return ret ? : -ENODATA;
48 for (; regs->name; ++regs) {
49 val = rkisp1_read(rkisp1, offset + regs->reg);
52 shd = rkisp1_read(rkisp1, offset + regs->shd);
53 seq_printf(m, "%*s: 0x%08x/0x%08x\n", width, regs->name,
56 seq_printf(m, "%*s: 0x%08x\n", width, regs->name, val);
60 pm_runtime_put(rkisp1->dev);
65 static int rkisp1_debug_dump_core_regs_show(struct seq_file *m, void *p)
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),
81 struct rkisp1_device *rkisp1 = m->private;
83 return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
85 DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_core_regs);
87 static int rkisp1_debug_dump_isp_regs_show(struct seq_file *m, void *p)
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),
97 struct rkisp1_device *rkisp1 = m->private;
99 return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
101 DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_isp_regs);
103 static int rkisp1_debug_dump_rsz_regs_show(struct seq_file *m, void *p)
105 static const struct rkisp1_debug_register registers[] = {
106 RKISP1_DEBUG_SHD_REG(RSZ_CTRL),
107 RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HY),
108 RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HCB),
109 RKISP1_DEBUG_SHD_REG(RSZ_SCALE_HCR),
110 RKISP1_DEBUG_SHD_REG(RSZ_SCALE_VY),
111 RKISP1_DEBUG_SHD_REG(RSZ_SCALE_VC),
112 RKISP1_DEBUG_SHD_REG(RSZ_PHASE_HY),
113 RKISP1_DEBUG_SHD_REG(RSZ_PHASE_HC),
114 RKISP1_DEBUG_SHD_REG(RSZ_PHASE_VY),
115 RKISP1_DEBUG_SHD_REG(RSZ_PHASE_VC),
118 struct rkisp1_resizer *rsz = m->private;
120 return rkisp1_debug_dump_regs(rsz->rkisp1, m, rsz->regs_base, registers);
122 DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_rsz_regs);
124 static int rkisp1_debug_dump_mi_mp_show(struct seq_file *m, void *p)
126 static const struct rkisp1_debug_register registers[] = {
127 RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_INIT),
128 RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_INIT2),
129 RKISP1_DEBUG_REG(MI_MP_Y_BASE_AD_SHD),
130 RKISP1_DEBUG_REG(MI_MP_Y_SIZE_INIT),
131 RKISP1_DEBUG_REG(MI_MP_Y_SIZE_INIT),
132 RKISP1_DEBUG_REG(MI_MP_Y_SIZE_SHD),
133 RKISP1_DEBUG_REG(MI_MP_Y_OFFS_CNT_SHD),
136 struct rkisp1_device *rkisp1 = m->private;
138 return rkisp1_debug_dump_regs(rkisp1, m, 0, registers);
140 DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_dump_mi_mp);
142 #define RKISP1_DEBUG_DATA_COUNT_BINS 32
143 #define RKISP1_DEBUG_DATA_COUNT_STEP (4096 / RKISP1_DEBUG_DATA_COUNT_BINS)
145 static int rkisp1_debug_input_status_show(struct seq_file *m, void *p)
147 struct rkisp1_device *rkisp1 = m->private;
148 u16 data_count[RKISP1_DEBUG_DATA_COUNT_BINS] = { };
149 unsigned int hsync_count = 0;
150 unsigned int vsync_count = 0;
156 ret = pm_runtime_get_if_in_use(rkisp1->dev);
158 return ret ? : -ENODATA;
160 /* Sample the ISP input port status 10000 times with a 1µs interval. */
161 for (i = 0; i < 10000; ++i) {
162 val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_FLAGS_SHD);
164 data = (val & RKISP1_CIF_ISP_FLAGS_SHD_S_DATA_MASK)
165 >> RKISP1_CIF_ISP_FLAGS_SHD_S_DATA_SHIFT;
166 data_count[data / RKISP1_DEBUG_DATA_COUNT_STEP]++;
168 if (val & RKISP1_CIF_ISP_FLAGS_SHD_S_HSYNC)
170 if (val & RKISP1_CIF_ISP_FLAGS_SHD_S_VSYNC)
176 pm_runtime_put(rkisp1->dev);
178 seq_printf(m, "vsync: %u, hsync: %u\n", vsync_count, hsync_count);
179 seq_puts(m, "data:\n");
180 for (i = 0; i < ARRAY_SIZE(data_count); ++i)
181 seq_printf(m, "- [%04u:%04u]: %u\n",
182 i * RKISP1_DEBUG_DATA_COUNT_STEP,
183 (i + 1) * RKISP1_DEBUG_DATA_COUNT_STEP - 1,
188 DEFINE_SHOW_ATTRIBUTE(rkisp1_debug_input_status);
190 void rkisp1_debug_init(struct rkisp1_device *rkisp1)
192 struct rkisp1_debug *debug = &rkisp1->debug;
193 struct dentry *regs_dir;
195 debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL);
197 debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
199 debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir,
200 &debug->outform_size_error);
201 debugfs_create_ulong("img_stabilization_size_error", 0444,
203 &debug->img_stabilization_size_error);
204 debugfs_create_ulong("inform_size_error", 0444, debug->debugfs_dir,
205 &debug->inform_size_error);
206 debugfs_create_ulong("irq_delay", 0444, debug->debugfs_dir,
208 debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
210 debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
211 &debug->stats_error);
212 debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
213 &debug->stop_timeout[RKISP1_MAINPATH]);
214 debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
215 &debug->stop_timeout[RKISP1_SELFPATH]);
216 debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
217 &debug->frame_drop[RKISP1_MAINPATH]);
218 debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
219 &debug->frame_drop[RKISP1_SELFPATH]);
220 debugfs_create_file("input_status", 0444, debug->debugfs_dir, rkisp1,
221 &rkisp1_debug_input_status_fops);
223 regs_dir = debugfs_create_dir("regs", debug->debugfs_dir);
225 debugfs_create_file("core", 0444, regs_dir, rkisp1,
226 &rkisp1_debug_dump_core_regs_fops);
227 debugfs_create_file("isp", 0444, regs_dir, rkisp1,
228 &rkisp1_debug_dump_isp_regs_fops);
229 debugfs_create_file("mrsz", 0444, regs_dir,
230 &rkisp1->resizer_devs[RKISP1_MAINPATH],
231 &rkisp1_debug_dump_rsz_regs_fops);
232 debugfs_create_file("srsz", 0444, regs_dir,
233 &rkisp1->resizer_devs[RKISP1_SELFPATH],
234 &rkisp1_debug_dump_rsz_regs_fops);
236 debugfs_create_file("mi_mp", 0444, regs_dir, rkisp1,
237 &rkisp1_debug_dump_mi_mp_fops);
240 void rkisp1_debug_cleanup(struct rkisp1_device *rkisp1)
242 debugfs_remove_recursive(rkisp1->debug.debugfs_dir);