xref: /OK3568_Linux_fs/kernel/drivers/media/platform/rockchip/cif/procfs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Rockchip Electronics Co., Ltd. */
3 #include <linux/clk.h>
4 #include <linux/math64.h>
5 #include <linux/proc_fs.h>
6 #include <linux/sem.h>
7 #include <linux/seq_file.h>
8 #include <linux/spinlock.h>
9 #include <linux/v4l2-mediabus.h>
10 
11 #include "dev.h"
12 #include "procfs.h"
13 
14 #ifdef CONFIG_PROC_FS
15 
16 static const struct {
17 	const char *name;
18 	u32 mbus_code;
19 } mbus_formats[] = {
20 	/* media bus code */
21 	{ "RGB444_1X12", MEDIA_BUS_FMT_RGB444_1X12 },
22 	{ "RGB444_2X8_PADHI_BE", MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE },
23 	{ "RGB444_2X8_PADHI_LE", MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE },
24 	{ "RGB555_2X8_PADHI_BE", MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE },
25 	{ "RGB555_2X8_PADHI_LE", MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE },
26 	{ "RGB565_1X16", MEDIA_BUS_FMT_RGB565_1X16 },
27 	{ "BGR565_2X8_BE", MEDIA_BUS_FMT_BGR565_2X8_BE },
28 	{ "BGR565_2X8_LE", MEDIA_BUS_FMT_BGR565_2X8_LE },
29 	{ "RGB565_2X8_BE", MEDIA_BUS_FMT_RGB565_2X8_BE },
30 	{ "RGB565_2X8_LE", MEDIA_BUS_FMT_RGB565_2X8_LE },
31 	{ "RGB666_1X18", MEDIA_BUS_FMT_RGB666_1X18 },
32 	{ "RBG888_1X24", MEDIA_BUS_FMT_RBG888_1X24 },
33 	{ "RGB666_1X24_CPADHI", MEDIA_BUS_FMT_RGB666_1X24_CPADHI },
34 	{ "RGB666_1X7X3_SPWG", MEDIA_BUS_FMT_RGB666_1X7X3_SPWG },
35 	{ "BGR888_1X24", MEDIA_BUS_FMT_BGR888_1X24 },
36 	{ "GBR888_1X24", MEDIA_BUS_FMT_GBR888_1X24 },
37 	{ "RGB888_1X24", MEDIA_BUS_FMT_RGB888_1X24 },
38 	{ "RGB888_2X12_BE", MEDIA_BUS_FMT_RGB888_2X12_BE },
39 	{ "RGB888_2X12_LE", MEDIA_BUS_FMT_RGB888_2X12_LE },
40 	{ "RGB888_1X7X4_SPWG", MEDIA_BUS_FMT_RGB888_1X7X4_SPWG },
41 	{ "RGB888_1X7X4_JEIDA", MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA },
42 	{ "ARGB8888_1X32", MEDIA_BUS_FMT_ARGB8888_1X32 },
43 	{ "RGB888_1X32_PADHI", MEDIA_BUS_FMT_RGB888_1X32_PADHI },
44 	{ "RGB101010_1X30", MEDIA_BUS_FMT_RGB101010_1X30 },
45 	{ "RGB121212_1X36", MEDIA_BUS_FMT_RGB121212_1X36 },
46 	{ "RGB161616_1X48", MEDIA_BUS_FMT_RGB161616_1X48 },
47 	{ "Y8_1X8", MEDIA_BUS_FMT_Y8_1X8 },
48 	{ "UV8_1X8", MEDIA_BUS_FMT_UV8_1X8 },
49 	{ "UYVY8_1_5X8", MEDIA_BUS_FMT_UYVY8_1_5X8 },
50 	{ "VYUY8_1_5X8", MEDIA_BUS_FMT_VYUY8_1_5X8 },
51 	{ "YUYV8_1_5X8", MEDIA_BUS_FMT_YUYV8_1_5X8 },
52 	{ "YVYU8_1_5X8", MEDIA_BUS_FMT_YVYU8_1_5X8 },
53 	{ "UYVY8_2X8", MEDIA_BUS_FMT_UYVY8_2X8 },
54 	{ "VYUY8_2X8", MEDIA_BUS_FMT_VYUY8_2X8 },
55 	{ "YUYV8_2X8", MEDIA_BUS_FMT_YUYV8_2X8 },
56 	{ "YVYU8_2X8", MEDIA_BUS_FMT_YVYU8_2X8 },
57 	{ "Y10_1X10", MEDIA_BUS_FMT_Y10_1X10 },
58 	{ "Y10_2X8_PADHI_LE", MEDIA_BUS_FMT_Y10_2X8_PADHI_LE },
59 	{ "UYVY10_2X10", MEDIA_BUS_FMT_UYVY10_2X10 },
60 	{ "VYUY10_2X10", MEDIA_BUS_FMT_VYUY10_2X10 },
61 	{ "YUYV10_2X10", MEDIA_BUS_FMT_YUYV10_2X10 },
62 	{ "YVYU10_2X10", MEDIA_BUS_FMT_YVYU10_2X10 },
63 	{ "Y12_1X12", MEDIA_BUS_FMT_Y12_1X12 },
64 	{ "UYVY12_2X12", MEDIA_BUS_FMT_UYVY12_2X12 },
65 	{ "VYUY12_2X12", MEDIA_BUS_FMT_VYUY12_2X12 },
66 	{ "YUYV12_2X12", MEDIA_BUS_FMT_YUYV12_2X12 },
67 	{ "YVYU12_2X12", MEDIA_BUS_FMT_YVYU12_2X12 },
68 	{ "UYVY8_1X16", MEDIA_BUS_FMT_UYVY8_1X16 },
69 	{ "VYUY8_1X16", MEDIA_BUS_FMT_VYUY8_1X16 },
70 	{ "YUYV8_1X16", MEDIA_BUS_FMT_YUYV8_1X16 },
71 	{ "YVYU8_1X16", MEDIA_BUS_FMT_YVYU8_1X16 },
72 	{ "YDYUYDYV8_1X16", MEDIA_BUS_FMT_YDYUYDYV8_1X16 },
73 	{ "UYVY10_1X20", MEDIA_BUS_FMT_UYVY10_1X20 },
74 	{ "VYUY10_1X20", MEDIA_BUS_FMT_VYUY10_1X20 },
75 	{ "YUYV10_1X20", MEDIA_BUS_FMT_YUYV10_1X20 },
76 	{ "YVYU10_1X20", MEDIA_BUS_FMT_YVYU10_1X20 },
77 	{ "VUY8_1X24", MEDIA_BUS_FMT_VUY8_1X24 },
78 	{ "YUV8_1X24", MEDIA_BUS_FMT_YUV8_1X24 },
79 	{ "UYYVYY8_0_5X24", MEDIA_BUS_FMT_UYYVYY8_0_5X24 },
80 	{ "UYVY12_1X24", MEDIA_BUS_FMT_UYVY12_1X24 },
81 	{ "VYUY12_1X24", MEDIA_BUS_FMT_VYUY12_1X24 },
82 	{ "YUYV12_1X24", MEDIA_BUS_FMT_YUYV12_1X24 },
83 	{ "YVYU12_1X24", MEDIA_BUS_FMT_YVYU12_1X24 },
84 	{ "YUV10_1X30", MEDIA_BUS_FMT_YUV10_1X30 },
85 	{ "UYYVYY10_0_5X30", MEDIA_BUS_FMT_UYYVYY10_0_5X30 },
86 	{ "AYUV8_1X32", MEDIA_BUS_FMT_AYUV8_1X32 },
87 	{ "UYYVYY12_0_5X36", MEDIA_BUS_FMT_UYYVYY12_0_5X36 },
88 	{ "YUV12_1X36", MEDIA_BUS_FMT_YUV12_1X36 },
89 	{ "YUV16_1X48", MEDIA_BUS_FMT_YUV16_1X48 },
90 	{ "UYYVYY16_0_5X48", MEDIA_BUS_FMT_UYYVYY16_0_5X48 },
91 	{ "SBGGR8_1X8", MEDIA_BUS_FMT_SBGGR8_1X8 },
92 	{ "SGBRG8_1X8", MEDIA_BUS_FMT_SGBRG8_1X8 },
93 	{ "SGRBG8_1X8", MEDIA_BUS_FMT_SGRBG8_1X8 },
94 	{ "SRGGB8_1X8", MEDIA_BUS_FMT_SRGGB8_1X8 },
95 	{ "SBGGR10_ALAW8_1X8", MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 },
96 	{ "SGBRG10_ALAW8_1X8", MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 },
97 	{ "SGRBG10_ALAW8_1X8", MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 },
98 	{ "SRGGB10_ALAW8_1X8", MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 },
99 	{ "SBGGR10_DPCM8_1X8", MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 },
100 	{ "SGBRG10_DPCM8_1X8", MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 },
101 	{ "SGRBG10_DPCM8_1X8", MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 },
102 	{ "SRGGB10_DPCM8_1X8", MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 },
103 	{ "SBGGR10_2X8_PADHI_BE", MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE },
104 	{ "SBGGR10_2X8_PADHI_LE", MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE },
105 	{ "SBGGR10_2X8_PADLO_BE", MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE },
106 	{ "SBGGR10_2X8_PADLO_LE", MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE },
107 	{ "SBGGR10_1X10", MEDIA_BUS_FMT_SBGGR10_1X10 },
108 	{ "SGBRG10_1X10", MEDIA_BUS_FMT_SGBRG10_1X10 },
109 	{ "SGRBG10_1X10", MEDIA_BUS_FMT_SGRBG10_1X10 },
110 	{ "SRGGB10_1X10", MEDIA_BUS_FMT_SRGGB10_1X10 },
111 	{ "SBGGR12_1X12", MEDIA_BUS_FMT_SBGGR12_1X12 },
112 	{ "SGBRG12_1X12", MEDIA_BUS_FMT_SGBRG12_1X12 },
113 	{ "SGRBG12_1X12", MEDIA_BUS_FMT_SGRBG12_1X12 },
114 	{ "SRGGB12_1X12", MEDIA_BUS_FMT_SRGGB12_1X12 },
115 	{ "SBGGR14_1X14", MEDIA_BUS_FMT_SBGGR14_1X14 },
116 	{ "SGBRG14_1X14", MEDIA_BUS_FMT_SGBRG14_1X14 },
117 	{ "SGRBG14_1X14", MEDIA_BUS_FMT_SGRBG14_1X14 },
118 	{ "SRGGB14_1X14", MEDIA_BUS_FMT_SRGGB14_1X14 },
119 	{ "SBGGR16_1X16", MEDIA_BUS_FMT_SBGGR16_1X16 },
120 	{ "SGBRG16_1X16", MEDIA_BUS_FMT_SGBRG16_1X16 },
121 	{ "SGRBG16_1X16", MEDIA_BUS_FMT_SGRBG16_1X16 },
122 	{ "SRGGB16_1X16", MEDIA_BUS_FMT_SRGGB16_1X16 },
123 	{ "JPEG_1X8", MEDIA_BUS_FMT_JPEG_1X8 },
124 	{ "S5C_UYVY_JPEG_1X8", MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 },
125 	{ "AHSV8888_1X32", MEDIA_BUS_FMT_AHSV8888_1X32 },
126 	{ "FIXED", MEDIA_BUS_FMT_FIXED },
127 	{ "Y8", MEDIA_BUS_FMT_Y8_1X8 },
128 	{ "Y10", MEDIA_BUS_FMT_Y10_1X10 },
129 	{ "Y12", MEDIA_BUS_FMT_Y12_1X12 },
130 	{ "YUYV", MEDIA_BUS_FMT_YUYV8_1X16 },
131 	{ "YUYV1_5X8", MEDIA_BUS_FMT_YUYV8_1_5X8 },
132 	{ "YUYV2X8", MEDIA_BUS_FMT_YUYV8_2X8 },
133 	{ "UYVY", MEDIA_BUS_FMT_UYVY8_1X16 },
134 	{ "UYVY1_5X8", MEDIA_BUS_FMT_UYVY8_1_5X8 },
135 	{ "UYVY2X8", MEDIA_BUS_FMT_UYVY8_2X8 },
136 	{ "VUY24", MEDIA_BUS_FMT_VUY8_1X24 },
137 	{ "SBGGR8", MEDIA_BUS_FMT_SBGGR8_1X8 },
138 	{ "SGBRG8", MEDIA_BUS_FMT_SGBRG8_1X8 },
139 	{ "SGRBG8", MEDIA_BUS_FMT_SGRBG8_1X8 },
140 	{ "SRGGB8", MEDIA_BUS_FMT_SRGGB8_1X8 },
141 	{ "SBGGR10", MEDIA_BUS_FMT_SBGGR10_1X10 },
142 	{ "SGBRG10", MEDIA_BUS_FMT_SGBRG10_1X10 },
143 	{ "SGRBG10", MEDIA_BUS_FMT_SGRBG10_1X10 },
144 	{ "SRGGB10", MEDIA_BUS_FMT_SRGGB10_1X10 },
145 	{ "SBGGR10_DPCM8", MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 },
146 	{ "SGBRG10_DPCM8", MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 },
147 	{ "SGRBG10_DPCM8", MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 },
148 	{ "SRGGB10_DPCM8", MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 },
149 	{ "SBGGR12", MEDIA_BUS_FMT_SBGGR12_1X12 },
150 	{ "SGBRG12", MEDIA_BUS_FMT_SGBRG12_1X12 },
151 	{ "SGRBG12", MEDIA_BUS_FMT_SGRBG12_1X12 },
152 	{ "SRGGB12", MEDIA_BUS_FMT_SRGGB12_1X12 },
153 	{ "AYUV32", MEDIA_BUS_FMT_AYUV8_1X32 },
154 	{ "RBG24", MEDIA_BUS_FMT_RBG888_1X24 },
155 	{ "RGB32", MEDIA_BUS_FMT_RGB888_1X32_PADHI },
156 	{ "ARGB32", MEDIA_BUS_FMT_ARGB8888_1X32 },
157 
158 	/* v4l2 fourcc code */
159 	{ "NV16", V4L2_PIX_FMT_NV16},
160 	{ "NV61", V4L2_PIX_FMT_NV61},
161 	{ "NV12", V4L2_PIX_FMT_NV12},
162 	{ "NV21", V4L2_PIX_FMT_NV21},
163 	{ "YUYV", V4L2_PIX_FMT_YUYV},
164 	{ "YVYU", V4L2_PIX_FMT_YVYU},
165 	{ "UYVY", V4L2_PIX_FMT_UYVY},
166 	{ "VYUY", V4L2_PIX_FMT_VYUY},
167 	{ "RGB3", V4L2_PIX_FMT_RGB24},
168 	{ "RGBP", V4L2_PIX_FMT_RGB565},
169 	{ "BGRH", V4L2_PIX_FMT_BGR666},
170 	{ "RGGB", V4L2_PIX_FMT_SRGGB8},
171 	{ "GRBG", V4L2_PIX_FMT_SGRBG8},
172 	{ "GBRG", V4L2_PIX_FMT_SGBRG8},
173 	{ "BA81", V4L2_PIX_FMT_SBGGR8},
174 	{ "RG10", V4L2_PIX_FMT_SRGGB10},
175 	{ "BA10", V4L2_PIX_FMT_SGRBG10},
176 	{ "GB10", V4L2_PIX_FMT_SGBRG10},
177 	{ "BG10", V4L2_PIX_FMT_SBGGR10},
178 	{ "RG12", V4L2_PIX_FMT_SRGGB12},
179 	{ "BA12", V4L2_PIX_FMT_SGRBG12},
180 	{ "GB12", V4L2_PIX_FMT_SGBRG12},
181 	{ "BG12", V4L2_PIX_FMT_SBGGR12},
182 	{ "BYR2", V4L2_PIX_FMT_SBGGR16},
183 	{ "Y16 ", V4L2_PIX_FMT_Y16},
184 };
185 
rkcif_pixelcode_to_string(u32 mbus_code)186 static const char *rkcif_pixelcode_to_string(u32 mbus_code)
187 {
188 	unsigned int i;
189 
190 	for (i = 0; i < ARRAY_SIZE(mbus_formats); ++i) {
191 		if (mbus_formats[i].mbus_code == mbus_code)
192 			return mbus_formats[i].name;
193 	}
194 
195 	return "unknown";
196 }
197 
rkcif_get_monitor_mode(enum rkcif_monitor_mode monitor_mode)198 static const char *rkcif_get_monitor_mode(enum rkcif_monitor_mode monitor_mode)
199 {
200 	switch (monitor_mode) {
201 	case RKCIF_MONITOR_MODE_IDLE:
202 		return "idle";
203 	case RKCIF_MONITOR_MODE_CONTINUE:
204 		return "continue";
205 	case RKCIF_MONITOR_MODE_TRIGGER:
206 		return "trigger";
207 	case RKCIF_MONITOR_MODE_HOTPLUG:
208 		return "hotplug";
209 	default:
210 		return "unknown";
211 	}
212 }
213 
rkcif_show_mixed_info(struct rkcif_device * dev,struct seq_file * f)214 static void rkcif_show_mixed_info(struct rkcif_device *dev, struct seq_file *f)
215 {
216 	enum rkcif_monitor_mode monitor_mode;
217 
218 	seq_printf(f, "Driver Version:v%02x.%02x.%02x\n",
219 		   RKCIF_DRIVER_VERSION >> 16,
220 		   (RKCIF_DRIVER_VERSION & 0xff00) >> 8,
221 		    RKCIF_DRIVER_VERSION & 0x00ff);
222 	seq_printf(f, "Work Mode:%s\n",
223 		   dev->workmode == RKCIF_WORKMODE_ONEFRAME ? "one frame" :
224 		   dev->workmode == RKCIF_WORKMODE_PINGPONG ? "ping pong" : "line loop");
225 
226 	monitor_mode = dev->reset_watchdog_timer.monitor_mode;
227 	seq_printf(f, "Monitor Mode:%s\n",
228 		   rkcif_get_monitor_mode(monitor_mode));
229 }
230 
rkcif_show_clks(struct rkcif_device * dev,struct seq_file * f)231 static void rkcif_show_clks(struct rkcif_device *dev, struct seq_file *f)
232 {
233 	int i;
234 	struct rkcif_hw *hw = dev->hw_dev;
235 
236 	for (i = 0; i < hw->clk_size; i++) {
237 		seq_printf(f, "%s:%ld\n",
238 			   hw->match_data->clks[i],
239 			   clk_get_rate(hw->clks[i]));
240 	}
241 }
242 
rkcif_show_format(struct rkcif_device * dev,struct seq_file * f)243 static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f)
244 {
245 	struct rkcif_stream *stream = &dev->stream[0];
246 	struct rkcif_pipeline *pipe = &dev->pipe;
247 	struct rkcif_sensor_info *sensor = &dev->terminal_sensor;
248 	struct v4l2_rect *rect = &sensor->raw_rect;
249 	struct v4l2_subdev_frame_interval *interval = &sensor->fi;
250 	struct v4l2_subdev_selection *sel = &sensor->selection;
251 	u32 i, mbus_flags;
252 	u64 fps, timestamp0, timestamp1;
253 	unsigned long flags;
254 	u32 time_val = 0;
255 
256 	if (atomic_read(&pipe->stream_cnt) < 1)
257 		return;
258 
259 	if (sensor) {
260 		seq_puts(f, "Input Info:\n");
261 
262 		seq_printf(f, "\tsrc subdev:%s\n", sensor->sd->name);
263 		mbus_flags = sensor->mbus.flags;
264 		if (sensor->mbus.type == V4L2_MBUS_PARALLEL ||
265 		    sensor->mbus.type == V4L2_MBUS_BT656) {
266 			seq_printf(f, "\tinterface:%s\n",
267 				   sensor->mbus.type == V4L2_MBUS_PARALLEL ? "BT601" : "BT656/BT1120");
268 			seq_printf(f, "\thref_pol:%s\n",
269 				   mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH ? "high active" : "low active");
270 			seq_printf(f, "\tvsync_pol:%s\n",
271 				   mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH ? "high active" : "low active");
272 		} else {
273 			seq_printf(f, "\tinterface:%s\n",
274 				   sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ? "mipi csi2 dphy" :
275 				   sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ? "mipi csi2 cphy" :
276 				   sensor->mbus.type == V4L2_MBUS_CCP2 ? "lvds" : "unknown");
277 			seq_printf(f, "\tlanes:%d\n", sensor->lanes);
278 			seq_puts(f, "\tvc channel:");
279 			if (mbus_flags & V4L2_MBUS_CSI2_CHANNELS) {
280 				for (i = 0; i < 4; i++) {
281 					if ((mbus_flags >> (4 + i)) & 0x1)
282 						seq_printf(f, " %d", i);
283 				}
284 				seq_puts(f, "\n");
285 			} else {
286 				seq_puts(f, "unknown\n");
287 			}
288 		}
289 
290 		seq_printf(f, "\thdr mode: %s\n",
291 			   dev->hdr.hdr_mode == NO_HDR ? "normal" :
292 			   dev->hdr.hdr_mode == HDR_COMPR ? "hdr_compr" :
293 			   dev->hdr.hdr_mode == HDR_X2 ? "hdr_x2" : "hdr_x3");
294 
295 		seq_printf(f, "\tformat:%s/%ux%u@%d\n",
296 			   rkcif_pixelcode_to_string(stream->cif_fmt_in->mbus_code),
297 			   rect->width, rect->height,
298 			   interval->interval.denominator / interval->interval.numerator);
299 
300 		seq_printf(f, "\tcrop.bounds:(%u, %u)/%ux%u\n",
301 			   sel->r.left, sel->r.top,
302 			   sel->r.width, sel->r.height);
303 
304 		spin_lock_irqsave(&stream->fps_lock, flags);
305 		timestamp0 = stream->fps_stats.frm0_timestamp;
306 		timestamp1 = stream->fps_stats.frm1_timestamp;
307 		spin_unlock_irqrestore(&stream->fps_lock, flags);
308 		fps = timestamp0 > timestamp1 ?
309 		      timestamp0 - timestamp1 : timestamp1 - timestamp0;
310 		fps = div_u64(fps, 1000000);
311 
312 		seq_puts(f, "Output Info:\n");
313 		seq_printf(f, "\tformat:%s/%ux%u(%u,%u)\n",
314 			   rkcif_pixelcode_to_string(stream->cif_fmt_out->fourcc),
315 			   dev->channels[0].width, dev->channels[0].height,
316 			   dev->channels[0].crop_st_x, dev->channels[0].crop_st_y);
317 		seq_printf(f, "\tcompact:%s\n", stream->is_compact ? "enable" : "disabled");
318 		seq_printf(f, "\tframe amount:%d\n", stream->frame_idx - 1);
319 		if (dev->inf_id == RKCIF_MIPI_LVDS) {
320 			time_val = div_u64(stream->readout.early_time, 1000000);
321 			seq_printf(f, "\tearly:%u ms\n", time_val);
322 			if (dev->hdr.hdr_mode == NO_HDR ||
323 			    dev->hdr.hdr_mode == HDR_COMPR) {
324 				time_val = div_u64(stream->readout.readout_time, 1000000);
325 				seq_printf(f, "\treadout:%u ms\n", time_val);
326 			} else {
327 				time_val = div_u64(stream->readout.readout_time, 1000000);
328 				seq_printf(f, "\tsingle readout:%u ms\n", time_val);
329 				time_val = div_u64(stream->readout.total_time, 1000000);
330 				seq_printf(f, "\ttotal readout:%u ms\n", time_val);
331 
332 			}
333 		}
334 		seq_printf(f, "\trate:%llu ms\n", fps);
335 		fps = div_u64(1000, fps);
336 		seq_printf(f, "\tfps:%llu\n", fps);
337 		seq_puts(f, "\tirq statistics:\n");
338 		seq_printf(f, "\t\t\ttotal:%llu\n",
339 			   dev->irq_stats.frm_end_cnt[0] +
340 			   dev->irq_stats.frm_end_cnt[1] +
341 			   dev->irq_stats.frm_end_cnt[2] +
342 			   dev->irq_stats.frm_end_cnt[3] +
343 			   dev->irq_stats.all_err_cnt);
344 		if (sensor->mbus.type == V4L2_MBUS_PARALLEL ||
345 		    sensor->mbus.type == V4L2_MBUS_BT656) {
346 			seq_printf(f, "\t\t\tdvp bus err:%llu\n", dev->irq_stats.dvp_bus_err_cnt);
347 			seq_printf(f, "\t\t\tdvp pix err:%llu\n", dev->irq_stats.dvp_pix_err_cnt);
348 			seq_printf(f, "\t\t\tdvp line err:%llu\n", dev->irq_stats.dvp_line_err_cnt);
349 			seq_printf(f, "\t\t\tdvp over flow:%llu\n", dev->irq_stats.dvp_overflow_cnt);
350 			seq_printf(f, "\t\t\tdvp bandwidth lack:%llu\n",
351 				   dev->irq_stats.dvp_bwidth_lack_cnt);
352 			seq_printf(f, "\t\t\tdvp size err:%llu\n", dev->irq_stats.dvp_size_err_cnt);
353 		} else {
354 			seq_printf(f, "\t\t\tcsi over flow:%llu\n", dev->irq_stats.csi_overflow_cnt);
355 			seq_printf(f, "\t\t\tcsi bandwidth lack:%llu\n",
356 				   dev->irq_stats.csi_bwidth_lack_cnt);
357 			seq_printf(f, "\t\t\tcsi size err:%llu\n", dev->irq_stats.csi_size_err_cnt);
358 		}
359 		seq_printf(f, "\t\t\tnot active buf cnt:%llu %llu %llu %llu\n",
360 			   dev->irq_stats.not_active_buf_cnt[0],
361 			   dev->irq_stats.not_active_buf_cnt[1],
362 			   dev->irq_stats.not_active_buf_cnt[2],
363 			   dev->irq_stats.not_active_buf_cnt[3]);
364 		seq_printf(f, "\t\t\tall err count:%llu\n", dev->irq_stats.all_err_cnt);
365 		seq_printf(f, "\t\t\tframe dma end:%llu %llu %llu %llu\n",
366 			   dev->irq_stats.frm_end_cnt[0],
367 			   dev->irq_stats.frm_end_cnt[1],
368 			   dev->irq_stats.frm_end_cnt[2],
369 			   dev->irq_stats.frm_end_cnt[3]);
370 		seq_printf(f, "irq time: %llu ns\n", dev->hw_dev->irq_time);
371 		seq_printf(f, "dma enable: 0x%x 0x%x 0x%x 0x%x\n",
372 			   dev->stream[0].dma_en, dev->stream[1].dma_en,
373 			   dev->stream[2].dma_en, dev->stream[3].dma_en);
374 		seq_printf(f, "buf_cnt in drv: %d %d %d %d\n",
375 			   atomic_read(&dev->stream[0].buf_cnt),
376 			   atomic_read(&dev->stream[1].buf_cnt),
377 			   atomic_read(&dev->stream[2].buf_cnt),
378 			   atomic_read(&dev->stream[3].buf_cnt));
379 		seq_printf(f, "total buf_cnt: %d %d %d %d\n",
380 			   dev->stream[0].total_buf_num,
381 			   dev->stream[1].total_buf_num,
382 			   dev->stream[2].total_buf_num,
383 			   dev->stream[3].total_buf_num);
384 	}
385 }
386 
rkcif_proc_show(struct seq_file * f,void * v)387 static int rkcif_proc_show(struct seq_file *f, void *v)
388 {
389 	struct rkcif_device *dev = f->private;
390 
391 	if (dev) {
392 		rkcif_show_mixed_info(dev, f);
393 		rkcif_show_clks(dev, f);
394 		rkcif_show_format(dev, f);
395 	} else {
396 		seq_puts(f, "dev null\n");
397 	}
398 
399 	return 0;
400 }
401 
rkcif_proc_open(struct inode * inode,struct file * file)402 static int rkcif_proc_open(struct inode *inode, struct file *file)
403 {
404 	struct rkcif_device *data = PDE_DATA(inode);
405 
406 	return single_open(file, rkcif_proc_show, data);
407 }
408 
409 static const struct proc_ops rkcif_proc_fops = {
410 	.proc_open = rkcif_proc_open,
411 	.proc_release = single_release,
412 	.proc_read = seq_read,
413 	.proc_lseek = seq_lseek,
414 };
415 
rkcif_proc_init(struct rkcif_device * dev)416 int rkcif_proc_init(struct rkcif_device *dev)
417 {
418 
419 	dev->proc_dir = proc_create_data(dev_name(dev->dev), 0444,
420 					 NULL, &rkcif_proc_fops,
421 					 dev);
422 	if (!dev->proc_dir) {
423 		dev_err(dev->dev, "create proc/%s failed!\n",
424 			dev_name(dev->dev));
425 		return -ENODEV;
426 	}
427 
428 	return 0;
429 }
430 
rkcif_proc_cleanup(struct rkcif_device * dev)431 void rkcif_proc_cleanup(struct rkcif_device *dev)
432 {
433 	remove_proc_entry(dev_name(dev->dev), NULL);
434 }
435 
436 #endif
437