1*e7b8153eSMauro Carvalho Chehab // SPDX-License-Identifier: GPL-2.0
2*e7b8153eSMauro Carvalho Chehab /*
3*e7b8153eSMauro Carvalho Chehab  * Copyright (C) STMicroelectronics SA 2015
4*e7b8153eSMauro Carvalho Chehab  * Authors: Yannick Fertre <yannick.fertre@st.com>
5*e7b8153eSMauro Carvalho Chehab  *          Hugues Fruchet <hugues.fruchet@st.com>
6*e7b8153eSMauro Carvalho Chehab  */
7*e7b8153eSMauro Carvalho Chehab 
8*e7b8153eSMauro Carvalho Chehab #include <linux/debugfs.h>
9*e7b8153eSMauro Carvalho Chehab 
10*e7b8153eSMauro Carvalho Chehab #include "hva.h"
11*e7b8153eSMauro Carvalho Chehab #include "hva-hw.h"
12*e7b8153eSMauro Carvalho Chehab 
format_ctx(struct seq_file * s,struct hva_ctx * ctx)13*e7b8153eSMauro Carvalho Chehab static void format_ctx(struct seq_file *s, struct hva_ctx *ctx)
14*e7b8153eSMauro Carvalho Chehab {
15*e7b8153eSMauro Carvalho Chehab 	struct hva_streaminfo *stream = &ctx->streaminfo;
16*e7b8153eSMauro Carvalho Chehab 	struct hva_frameinfo *frame = &ctx->frameinfo;
17*e7b8153eSMauro Carvalho Chehab 	struct hva_controls *ctrls = &ctx->ctrls;
18*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx_dbg *dbg = &ctx->dbg;
19*e7b8153eSMauro Carvalho Chehab 	u32 bitrate_mode, aspect, entropy, vui_sar, sei_fp;
20*e7b8153eSMauro Carvalho Chehab 
21*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "|-%s\n  |\n", ctx->name);
22*e7b8153eSMauro Carvalho Chehab 
23*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  |-[%sframe info]\n",
24*e7b8153eSMauro Carvalho Chehab 		   ctx->flags & HVA_FLAG_FRAMEINFO ? "" : "default ");
25*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  | |- pixel format=%4.4s\n"
26*e7b8153eSMauro Carvalho Chehab 		      "  | |- wxh=%dx%d\n"
27*e7b8153eSMauro Carvalho Chehab 		      "  | |- wxh (w/ encoder alignment constraint)=%dx%d\n"
28*e7b8153eSMauro Carvalho Chehab 		      "  |\n",
29*e7b8153eSMauro Carvalho Chehab 		      (char *)&frame->pixelformat,
30*e7b8153eSMauro Carvalho Chehab 		      frame->width, frame->height,
31*e7b8153eSMauro Carvalho Chehab 		      frame->aligned_width, frame->aligned_height);
32*e7b8153eSMauro Carvalho Chehab 
33*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  |-[%sstream info]\n",
34*e7b8153eSMauro Carvalho Chehab 		   ctx->flags & HVA_FLAG_STREAMINFO ? "" : "default ");
35*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  | |- stream format=%4.4s\n"
36*e7b8153eSMauro Carvalho Chehab 		      "  | |- wxh=%dx%d\n"
37*e7b8153eSMauro Carvalho Chehab 		      "  | |- %s\n"
38*e7b8153eSMauro Carvalho Chehab 		      "  | |- %s\n"
39*e7b8153eSMauro Carvalho Chehab 		      "  |\n",
40*e7b8153eSMauro Carvalho Chehab 		      (char *)&stream->streamformat,
41*e7b8153eSMauro Carvalho Chehab 		      stream->width, stream->height,
42*e7b8153eSMauro Carvalho Chehab 		      stream->profile, stream->level);
43*e7b8153eSMauro Carvalho Chehab 
44*e7b8153eSMauro Carvalho Chehab 	bitrate_mode = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
45*e7b8153eSMauro Carvalho Chehab 	aspect = V4L2_CID_MPEG_VIDEO_ASPECT;
46*e7b8153eSMauro Carvalho Chehab 	seq_puts(s, "  |-[parameters]\n");
47*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  | |- %s\n"
48*e7b8153eSMauro Carvalho Chehab 		      "  | |- bitrate=%d bps\n"
49*e7b8153eSMauro Carvalho Chehab 		      "  | |- GOP size=%d\n"
50*e7b8153eSMauro Carvalho Chehab 		      "  | |- video aspect=%s\n"
51*e7b8153eSMauro Carvalho Chehab 		      "  | |- framerate=%d/%d\n",
52*e7b8153eSMauro Carvalho Chehab 		      v4l2_ctrl_get_menu(bitrate_mode)[ctrls->bitrate_mode],
53*e7b8153eSMauro Carvalho Chehab 		      ctrls->bitrate,
54*e7b8153eSMauro Carvalho Chehab 		      ctrls->gop_size,
55*e7b8153eSMauro Carvalho Chehab 		      v4l2_ctrl_get_menu(aspect)[ctrls->aspect],
56*e7b8153eSMauro Carvalho Chehab 		      ctrls->time_per_frame.denominator,
57*e7b8153eSMauro Carvalho Chehab 		      ctrls->time_per_frame.numerator);
58*e7b8153eSMauro Carvalho Chehab 
59*e7b8153eSMauro Carvalho Chehab 	entropy = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
60*e7b8153eSMauro Carvalho Chehab 	vui_sar = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
61*e7b8153eSMauro Carvalho Chehab 	sei_fp =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
62*e7b8153eSMauro Carvalho Chehab 	if (stream->streamformat == V4L2_PIX_FMT_H264) {
63*e7b8153eSMauro Carvalho Chehab 		seq_printf(s, "  | |- %s entropy mode\n"
64*e7b8153eSMauro Carvalho Chehab 			      "  | |- CPB size=%d kB\n"
65*e7b8153eSMauro Carvalho Chehab 			      "  | |- DCT8x8 enable=%s\n"
66*e7b8153eSMauro Carvalho Chehab 			      "  | |- qpmin=%d\n"
67*e7b8153eSMauro Carvalho Chehab 			      "  | |- qpmax=%d\n"
68*e7b8153eSMauro Carvalho Chehab 			      "  | |- PAR enable=%s\n"
69*e7b8153eSMauro Carvalho Chehab 			      "  | |- PAR id=%s\n"
70*e7b8153eSMauro Carvalho Chehab 			      "  | |- SEI frame packing enable=%s\n"
71*e7b8153eSMauro Carvalho Chehab 			      "  | |- SEI frame packing type=%s\n",
72*e7b8153eSMauro Carvalho Chehab 			      v4l2_ctrl_get_menu(entropy)[ctrls->entropy_mode],
73*e7b8153eSMauro Carvalho Chehab 			      ctrls->cpb_size,
74*e7b8153eSMauro Carvalho Chehab 			      ctrls->dct8x8 ? "true" : "false",
75*e7b8153eSMauro Carvalho Chehab 			      ctrls->qpmin,
76*e7b8153eSMauro Carvalho Chehab 			      ctrls->qpmax,
77*e7b8153eSMauro Carvalho Chehab 			      ctrls->vui_sar ? "true" : "false",
78*e7b8153eSMauro Carvalho Chehab 			      v4l2_ctrl_get_menu(vui_sar)[ctrls->vui_sar_idc],
79*e7b8153eSMauro Carvalho Chehab 			      ctrls->sei_fp ? "true" : "false",
80*e7b8153eSMauro Carvalho Chehab 			      v4l2_ctrl_get_menu(sei_fp)[ctrls->sei_fp_type]);
81*e7b8153eSMauro Carvalho Chehab 	}
82*e7b8153eSMauro Carvalho Chehab 
83*e7b8153eSMauro Carvalho Chehab 	if (ctx->sys_errors || ctx->encode_errors || ctx->frame_errors) {
84*e7b8153eSMauro Carvalho Chehab 		seq_puts(s, "  |\n  |-[errors]\n");
85*e7b8153eSMauro Carvalho Chehab 		seq_printf(s, "  | |- system=%d\n"
86*e7b8153eSMauro Carvalho Chehab 			      "  | |- encoding=%d\n"
87*e7b8153eSMauro Carvalho Chehab 			      "  | |- frame=%d\n",
88*e7b8153eSMauro Carvalho Chehab 			      ctx->sys_errors,
89*e7b8153eSMauro Carvalho Chehab 			      ctx->encode_errors,
90*e7b8153eSMauro Carvalho Chehab 			      ctx->frame_errors);
91*e7b8153eSMauro Carvalho Chehab 	}
92*e7b8153eSMauro Carvalho Chehab 
93*e7b8153eSMauro Carvalho Chehab 	seq_puts(s, "  |\n  |-[performances]\n");
94*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "  | |- frames encoded=%d\n"
95*e7b8153eSMauro Carvalho Chehab 		      "  | |- avg HW processing duration (0.1ms)=%d [min=%d, max=%d]\n"
96*e7b8153eSMauro Carvalho Chehab 		      "  | |- avg encoding period (0.1ms)=%d [min=%d, max=%d]\n"
97*e7b8153eSMauro Carvalho Chehab 		      "  | |- avg fps (0.1Hz)=%d\n"
98*e7b8153eSMauro Carvalho Chehab 		      "  | |- max reachable fps (0.1Hz)=%d\n"
99*e7b8153eSMauro Carvalho Chehab 		      "  | |- avg bitrate (kbps)=%d [min=%d, max=%d]\n"
100*e7b8153eSMauro Carvalho Chehab 		      "  | |- last bitrate (kbps)=%d\n",
101*e7b8153eSMauro Carvalho Chehab 		      dbg->cnt_duration,
102*e7b8153eSMauro Carvalho Chehab 		      dbg->avg_duration,
103*e7b8153eSMauro Carvalho Chehab 		      dbg->min_duration,
104*e7b8153eSMauro Carvalho Chehab 		      dbg->max_duration,
105*e7b8153eSMauro Carvalho Chehab 		      dbg->avg_period,
106*e7b8153eSMauro Carvalho Chehab 		      dbg->min_period,
107*e7b8153eSMauro Carvalho Chehab 		      dbg->max_period,
108*e7b8153eSMauro Carvalho Chehab 		      dbg->avg_fps,
109*e7b8153eSMauro Carvalho Chehab 		      dbg->max_fps,
110*e7b8153eSMauro Carvalho Chehab 		      dbg->avg_bitrate,
111*e7b8153eSMauro Carvalho Chehab 		      dbg->min_bitrate,
112*e7b8153eSMauro Carvalho Chehab 		      dbg->max_bitrate,
113*e7b8153eSMauro Carvalho Chehab 		      dbg->last_bitrate);
114*e7b8153eSMauro Carvalho Chehab }
115*e7b8153eSMauro Carvalho Chehab 
116*e7b8153eSMauro Carvalho Chehab /*
117*e7b8153eSMauro Carvalho Chehab  * performance debug info
118*e7b8153eSMauro Carvalho Chehab  */
hva_dbg_perf_begin(struct hva_ctx * ctx)119*e7b8153eSMauro Carvalho Chehab void hva_dbg_perf_begin(struct hva_ctx *ctx)
120*e7b8153eSMauro Carvalho Chehab {
121*e7b8153eSMauro Carvalho Chehab 	u64 div;
122*e7b8153eSMauro Carvalho Chehab 	u32 period;
123*e7b8153eSMauro Carvalho Chehab 	u32 bitrate;
124*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx_dbg *dbg = &ctx->dbg;
125*e7b8153eSMauro Carvalho Chehab 	ktime_t prev = dbg->begin;
126*e7b8153eSMauro Carvalho Chehab 
127*e7b8153eSMauro Carvalho Chehab 	dbg->begin = ktime_get();
128*e7b8153eSMauro Carvalho Chehab 
129*e7b8153eSMauro Carvalho Chehab 	if (dbg->is_valid_period) {
130*e7b8153eSMauro Carvalho Chehab 		/* encoding period */
131*e7b8153eSMauro Carvalho Chehab 		div = (u64)ktime_us_delta(dbg->begin, prev);
132*e7b8153eSMauro Carvalho Chehab 		do_div(div, 100);
133*e7b8153eSMauro Carvalho Chehab 		period = (u32)div;
134*e7b8153eSMauro Carvalho Chehab 		dbg->min_period = min(period, dbg->min_period);
135*e7b8153eSMauro Carvalho Chehab 		dbg->max_period = max(period, dbg->max_period);
136*e7b8153eSMauro Carvalho Chehab 		dbg->total_period += period;
137*e7b8153eSMauro Carvalho Chehab 		dbg->cnt_period++;
138*e7b8153eSMauro Carvalho Chehab 
139*e7b8153eSMauro Carvalho Chehab 		/*
140*e7b8153eSMauro Carvalho Chehab 		 * minimum and maximum bitrates are based on the
141*e7b8153eSMauro Carvalho Chehab 		 * encoding period values upon a window of 32 samples
142*e7b8153eSMauro Carvalho Chehab 		 */
143*e7b8153eSMauro Carvalho Chehab 		dbg->window_duration += period;
144*e7b8153eSMauro Carvalho Chehab 		dbg->cnt_window++;
145*e7b8153eSMauro Carvalho Chehab 		if (dbg->cnt_window >= 32) {
146*e7b8153eSMauro Carvalho Chehab 			/*
147*e7b8153eSMauro Carvalho Chehab 			 * bitrate in kbps = (size * 8 / 1000) /
148*e7b8153eSMauro Carvalho Chehab 			 *                   (duration / 10000)
149*e7b8153eSMauro Carvalho Chehab 			 *                 = size * 80 / duration
150*e7b8153eSMauro Carvalho Chehab 			 */
151*e7b8153eSMauro Carvalho Chehab 			if (dbg->window_duration > 0) {
152*e7b8153eSMauro Carvalho Chehab 				div = (u64)dbg->window_stream_size * 80;
153*e7b8153eSMauro Carvalho Chehab 				do_div(div, dbg->window_duration);
154*e7b8153eSMauro Carvalho Chehab 				bitrate = (u32)div;
155*e7b8153eSMauro Carvalho Chehab 				dbg->last_bitrate = bitrate;
156*e7b8153eSMauro Carvalho Chehab 				dbg->min_bitrate = min(bitrate,
157*e7b8153eSMauro Carvalho Chehab 						       dbg->min_bitrate);
158*e7b8153eSMauro Carvalho Chehab 				dbg->max_bitrate = max(bitrate,
159*e7b8153eSMauro Carvalho Chehab 						       dbg->max_bitrate);
160*e7b8153eSMauro Carvalho Chehab 			}
161*e7b8153eSMauro Carvalho Chehab 			dbg->window_stream_size = 0;
162*e7b8153eSMauro Carvalho Chehab 			dbg->window_duration = 0;
163*e7b8153eSMauro Carvalho Chehab 			dbg->cnt_window = 0;
164*e7b8153eSMauro Carvalho Chehab 		}
165*e7b8153eSMauro Carvalho Chehab 	}
166*e7b8153eSMauro Carvalho Chehab 
167*e7b8153eSMauro Carvalho Chehab 	/*
168*e7b8153eSMauro Carvalho Chehab 	 * filter sequences valid for performance:
169*e7b8153eSMauro Carvalho Chehab 	 * - begin/begin (no stream available) is an invalid sequence
170*e7b8153eSMauro Carvalho Chehab 	 * - begin/end is a valid sequence
171*e7b8153eSMauro Carvalho Chehab 	 */
172*e7b8153eSMauro Carvalho Chehab 	dbg->is_valid_period = false;
173*e7b8153eSMauro Carvalho Chehab }
174*e7b8153eSMauro Carvalho Chehab 
hva_dbg_perf_end(struct hva_ctx * ctx,struct hva_stream * stream)175*e7b8153eSMauro Carvalho Chehab void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream)
176*e7b8153eSMauro Carvalho Chehab {
177*e7b8153eSMauro Carvalho Chehab 	struct device *dev = ctx_to_dev(ctx);
178*e7b8153eSMauro Carvalho Chehab 	u64 div;
179*e7b8153eSMauro Carvalho Chehab 	u32 duration;
180*e7b8153eSMauro Carvalho Chehab 	u32 bytesused;
181*e7b8153eSMauro Carvalho Chehab 	u32 timestamp;
182*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx_dbg *dbg = &ctx->dbg;
183*e7b8153eSMauro Carvalho Chehab 	ktime_t end = ktime_get();
184*e7b8153eSMauro Carvalho Chehab 
185*e7b8153eSMauro Carvalho Chehab 	/* stream bytesused and timestamp in us */
186*e7b8153eSMauro Carvalho Chehab 	bytesused = vb2_get_plane_payload(&stream->vbuf.vb2_buf, 0);
187*e7b8153eSMauro Carvalho Chehab 	div = stream->vbuf.vb2_buf.timestamp;
188*e7b8153eSMauro Carvalho Chehab 	do_div(div, 1000);
189*e7b8153eSMauro Carvalho Chehab 	timestamp = (u32)div;
190*e7b8153eSMauro Carvalho Chehab 
191*e7b8153eSMauro Carvalho Chehab 	/* encoding duration */
192*e7b8153eSMauro Carvalho Chehab 	div = (u64)ktime_us_delta(end, dbg->begin);
193*e7b8153eSMauro Carvalho Chehab 
194*e7b8153eSMauro Carvalho Chehab 	dev_dbg(dev,
195*e7b8153eSMauro Carvalho Chehab 		"%s perf stream[%d] dts=%d encoded using %d bytes in %d us",
196*e7b8153eSMauro Carvalho Chehab 		ctx->name,
197*e7b8153eSMauro Carvalho Chehab 		stream->vbuf.sequence,
198*e7b8153eSMauro Carvalho Chehab 		timestamp,
199*e7b8153eSMauro Carvalho Chehab 		bytesused, (u32)div);
200*e7b8153eSMauro Carvalho Chehab 
201*e7b8153eSMauro Carvalho Chehab 	do_div(div, 100);
202*e7b8153eSMauro Carvalho Chehab 	duration = (u32)div;
203*e7b8153eSMauro Carvalho Chehab 
204*e7b8153eSMauro Carvalho Chehab 	dbg->min_duration = min(duration, dbg->min_duration);
205*e7b8153eSMauro Carvalho Chehab 	dbg->max_duration = max(duration, dbg->max_duration);
206*e7b8153eSMauro Carvalho Chehab 	dbg->total_duration += duration;
207*e7b8153eSMauro Carvalho Chehab 	dbg->cnt_duration++;
208*e7b8153eSMauro Carvalho Chehab 
209*e7b8153eSMauro Carvalho Chehab 	/*
210*e7b8153eSMauro Carvalho Chehab 	 * the average bitrate is based on the total stream size
211*e7b8153eSMauro Carvalho Chehab 	 * and the total encoding periods
212*e7b8153eSMauro Carvalho Chehab 	 */
213*e7b8153eSMauro Carvalho Chehab 	dbg->total_stream_size += bytesused;
214*e7b8153eSMauro Carvalho Chehab 	dbg->window_stream_size += bytesused;
215*e7b8153eSMauro Carvalho Chehab 
216*e7b8153eSMauro Carvalho Chehab 	dbg->is_valid_period = true;
217*e7b8153eSMauro Carvalho Chehab }
218*e7b8153eSMauro Carvalho Chehab 
hva_dbg_perf_compute(struct hva_ctx * ctx)219*e7b8153eSMauro Carvalho Chehab static void hva_dbg_perf_compute(struct hva_ctx *ctx)
220*e7b8153eSMauro Carvalho Chehab {
221*e7b8153eSMauro Carvalho Chehab 	u64 div;
222*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx_dbg *dbg = &ctx->dbg;
223*e7b8153eSMauro Carvalho Chehab 
224*e7b8153eSMauro Carvalho Chehab 	if (dbg->cnt_duration > 0) {
225*e7b8153eSMauro Carvalho Chehab 		div = (u64)dbg->total_duration;
226*e7b8153eSMauro Carvalho Chehab 		do_div(div, dbg->cnt_duration);
227*e7b8153eSMauro Carvalho Chehab 		dbg->avg_duration = (u32)div;
228*e7b8153eSMauro Carvalho Chehab 	} else {
229*e7b8153eSMauro Carvalho Chehab 		dbg->avg_duration = 0;
230*e7b8153eSMauro Carvalho Chehab 	}
231*e7b8153eSMauro Carvalho Chehab 
232*e7b8153eSMauro Carvalho Chehab 	if (dbg->total_duration > 0) {
233*e7b8153eSMauro Carvalho Chehab 		div = (u64)dbg->cnt_duration * 100000;
234*e7b8153eSMauro Carvalho Chehab 		do_div(div, dbg->total_duration);
235*e7b8153eSMauro Carvalho Chehab 		dbg->max_fps = (u32)div;
236*e7b8153eSMauro Carvalho Chehab 	} else {
237*e7b8153eSMauro Carvalho Chehab 		dbg->max_fps = 0;
238*e7b8153eSMauro Carvalho Chehab 	}
239*e7b8153eSMauro Carvalho Chehab 
240*e7b8153eSMauro Carvalho Chehab 	if (dbg->cnt_period > 0) {
241*e7b8153eSMauro Carvalho Chehab 		div = (u64)dbg->total_period;
242*e7b8153eSMauro Carvalho Chehab 		do_div(div, dbg->cnt_period);
243*e7b8153eSMauro Carvalho Chehab 		dbg->avg_period = (u32)div;
244*e7b8153eSMauro Carvalho Chehab 	} else {
245*e7b8153eSMauro Carvalho Chehab 		dbg->avg_period = 0;
246*e7b8153eSMauro Carvalho Chehab 	}
247*e7b8153eSMauro Carvalho Chehab 
248*e7b8153eSMauro Carvalho Chehab 	if (dbg->total_period > 0) {
249*e7b8153eSMauro Carvalho Chehab 		div = (u64)dbg->cnt_period * 100000;
250*e7b8153eSMauro Carvalho Chehab 		do_div(div, dbg->total_period);
251*e7b8153eSMauro Carvalho Chehab 		dbg->avg_fps = (u32)div;
252*e7b8153eSMauro Carvalho Chehab 	} else {
253*e7b8153eSMauro Carvalho Chehab 		dbg->avg_fps = 0;
254*e7b8153eSMauro Carvalho Chehab 	}
255*e7b8153eSMauro Carvalho Chehab 
256*e7b8153eSMauro Carvalho Chehab 	if (dbg->total_period > 0) {
257*e7b8153eSMauro Carvalho Chehab 		/*
258*e7b8153eSMauro Carvalho Chehab 		 * bitrate in kbps = (video size * 8 / 1000) /
259*e7b8153eSMauro Carvalho Chehab 		 *                   (video duration / 10000)
260*e7b8153eSMauro Carvalho Chehab 		 *                 = video size * 80 / video duration
261*e7b8153eSMauro Carvalho Chehab 		 */
262*e7b8153eSMauro Carvalho Chehab 		div = (u64)dbg->total_stream_size * 80;
263*e7b8153eSMauro Carvalho Chehab 		do_div(div, dbg->total_period);
264*e7b8153eSMauro Carvalho Chehab 		dbg->avg_bitrate = (u32)div;
265*e7b8153eSMauro Carvalho Chehab 	} else {
266*e7b8153eSMauro Carvalho Chehab 		dbg->avg_bitrate = 0;
267*e7b8153eSMauro Carvalho Chehab 	}
268*e7b8153eSMauro Carvalho Chehab }
269*e7b8153eSMauro Carvalho Chehab 
270*e7b8153eSMauro Carvalho Chehab /*
271*e7b8153eSMauro Carvalho Chehab  * device debug info
272*e7b8153eSMauro Carvalho Chehab  */
273*e7b8153eSMauro Carvalho Chehab 
device_show(struct seq_file * s,void * data)274*e7b8153eSMauro Carvalho Chehab static int device_show(struct seq_file *s, void *data)
275*e7b8153eSMauro Carvalho Chehab {
276*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = s->private;
277*e7b8153eSMauro Carvalho Chehab 
278*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "[%s]\n", hva->v4l2_dev.name);
279*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "registered as /dev/video%d\n", hva->vdev->num);
280*e7b8153eSMauro Carvalho Chehab 
281*e7b8153eSMauro Carvalho Chehab 	return 0;
282*e7b8153eSMauro Carvalho Chehab }
283*e7b8153eSMauro Carvalho Chehab 
encoders_show(struct seq_file * s,void * data)284*e7b8153eSMauro Carvalho Chehab static int encoders_show(struct seq_file *s, void *data)
285*e7b8153eSMauro Carvalho Chehab {
286*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = s->private;
287*e7b8153eSMauro Carvalho Chehab 	unsigned int i = 0;
288*e7b8153eSMauro Carvalho Chehab 
289*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "[encoders]\n|- %d registered encoders:\n",
290*e7b8153eSMauro Carvalho Chehab 		   hva->nb_of_encoders);
291*e7b8153eSMauro Carvalho Chehab 
292*e7b8153eSMauro Carvalho Chehab 	while (hva->encoders[i]) {
293*e7b8153eSMauro Carvalho Chehab 		seq_printf(s, "|- %s: %4.4s => %4.4s\n", hva->encoders[i]->name,
294*e7b8153eSMauro Carvalho Chehab 			   (char *)&hva->encoders[i]->pixelformat,
295*e7b8153eSMauro Carvalho Chehab 			   (char *)&hva->encoders[i]->streamformat);
296*e7b8153eSMauro Carvalho Chehab 		i++;
297*e7b8153eSMauro Carvalho Chehab 	}
298*e7b8153eSMauro Carvalho Chehab 
299*e7b8153eSMauro Carvalho Chehab 	return 0;
300*e7b8153eSMauro Carvalho Chehab }
301*e7b8153eSMauro Carvalho Chehab 
last_show(struct seq_file * s,void * data)302*e7b8153eSMauro Carvalho Chehab static int last_show(struct seq_file *s, void *data)
303*e7b8153eSMauro Carvalho Chehab {
304*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = s->private;
305*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx *last_ctx = &hva->dbg.last_ctx;
306*e7b8153eSMauro Carvalho Chehab 
307*e7b8153eSMauro Carvalho Chehab 	if (last_ctx->flags & HVA_FLAG_STREAMINFO) {
308*e7b8153eSMauro Carvalho Chehab 		seq_puts(s, "[last encoding]\n");
309*e7b8153eSMauro Carvalho Chehab 
310*e7b8153eSMauro Carvalho Chehab 		hva_dbg_perf_compute(last_ctx);
311*e7b8153eSMauro Carvalho Chehab 		format_ctx(s, last_ctx);
312*e7b8153eSMauro Carvalho Chehab 	} else {
313*e7b8153eSMauro Carvalho Chehab 		seq_puts(s, "[no information recorded about last encoding]\n");
314*e7b8153eSMauro Carvalho Chehab 	}
315*e7b8153eSMauro Carvalho Chehab 
316*e7b8153eSMauro Carvalho Chehab 	return 0;
317*e7b8153eSMauro Carvalho Chehab }
318*e7b8153eSMauro Carvalho Chehab 
regs_show(struct seq_file * s,void * data)319*e7b8153eSMauro Carvalho Chehab static int regs_show(struct seq_file *s, void *data)
320*e7b8153eSMauro Carvalho Chehab {
321*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = s->private;
322*e7b8153eSMauro Carvalho Chehab 
323*e7b8153eSMauro Carvalho Chehab 	hva_hw_dump_regs(hva, s);
324*e7b8153eSMauro Carvalho Chehab 
325*e7b8153eSMauro Carvalho Chehab 	return 0;
326*e7b8153eSMauro Carvalho Chehab }
327*e7b8153eSMauro Carvalho Chehab 
328*e7b8153eSMauro Carvalho Chehab #define hva_dbg_create_entry(name)					 \
329*e7b8153eSMauro Carvalho Chehab 	debugfs_create_file(#name, 0444, hva->dbg.debugfs_entry, hva, \
330*e7b8153eSMauro Carvalho Chehab 			    &name##_fops)
331*e7b8153eSMauro Carvalho Chehab 
332*e7b8153eSMauro Carvalho Chehab DEFINE_SHOW_ATTRIBUTE(device);
333*e7b8153eSMauro Carvalho Chehab DEFINE_SHOW_ATTRIBUTE(encoders);
334*e7b8153eSMauro Carvalho Chehab DEFINE_SHOW_ATTRIBUTE(last);
335*e7b8153eSMauro Carvalho Chehab DEFINE_SHOW_ATTRIBUTE(regs);
336*e7b8153eSMauro Carvalho Chehab 
hva_debugfs_create(struct hva_dev * hva)337*e7b8153eSMauro Carvalho Chehab void hva_debugfs_create(struct hva_dev *hva)
338*e7b8153eSMauro Carvalho Chehab {
339*e7b8153eSMauro Carvalho Chehab 	hva->dbg.debugfs_entry = debugfs_create_dir(HVA_NAME, NULL);
340*e7b8153eSMauro Carvalho Chehab 
341*e7b8153eSMauro Carvalho Chehab 	hva_dbg_create_entry(device);
342*e7b8153eSMauro Carvalho Chehab 	hva_dbg_create_entry(encoders);
343*e7b8153eSMauro Carvalho Chehab 	hva_dbg_create_entry(last);
344*e7b8153eSMauro Carvalho Chehab 	hva_dbg_create_entry(regs);
345*e7b8153eSMauro Carvalho Chehab }
346*e7b8153eSMauro Carvalho Chehab 
hva_debugfs_remove(struct hva_dev * hva)347*e7b8153eSMauro Carvalho Chehab void hva_debugfs_remove(struct hva_dev *hva)
348*e7b8153eSMauro Carvalho Chehab {
349*e7b8153eSMauro Carvalho Chehab 	debugfs_remove_recursive(hva->dbg.debugfs_entry);
350*e7b8153eSMauro Carvalho Chehab 	hva->dbg.debugfs_entry = NULL;
351*e7b8153eSMauro Carvalho Chehab }
352*e7b8153eSMauro Carvalho Chehab 
353*e7b8153eSMauro Carvalho Chehab /*
354*e7b8153eSMauro Carvalho Chehab  * context (instance) debug info
355*e7b8153eSMauro Carvalho Chehab  */
356*e7b8153eSMauro Carvalho Chehab 
ctx_show(struct seq_file * s,void * data)357*e7b8153eSMauro Carvalho Chehab static int ctx_show(struct seq_file *s, void *data)
358*e7b8153eSMauro Carvalho Chehab {
359*e7b8153eSMauro Carvalho Chehab 	struct hva_ctx *ctx = s->private;
360*e7b8153eSMauro Carvalho Chehab 
361*e7b8153eSMauro Carvalho Chehab 	seq_printf(s, "[running encoding %d]\n", ctx->id);
362*e7b8153eSMauro Carvalho Chehab 
363*e7b8153eSMauro Carvalho Chehab 	hva_dbg_perf_compute(ctx);
364*e7b8153eSMauro Carvalho Chehab 	format_ctx(s, ctx);
365*e7b8153eSMauro Carvalho Chehab 
366*e7b8153eSMauro Carvalho Chehab 	return 0;
367*e7b8153eSMauro Carvalho Chehab }
368*e7b8153eSMauro Carvalho Chehab 
369*e7b8153eSMauro Carvalho Chehab DEFINE_SHOW_ATTRIBUTE(ctx);
370*e7b8153eSMauro Carvalho Chehab 
hva_dbg_ctx_create(struct hva_ctx * ctx)371*e7b8153eSMauro Carvalho Chehab void hva_dbg_ctx_create(struct hva_ctx *ctx)
372*e7b8153eSMauro Carvalho Chehab {
373*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = ctx->hva_dev;
374*e7b8153eSMauro Carvalho Chehab 	char name[4] = "";
375*e7b8153eSMauro Carvalho Chehab 
376*e7b8153eSMauro Carvalho Chehab 	ctx->dbg.min_duration = UINT_MAX;
377*e7b8153eSMauro Carvalho Chehab 	ctx->dbg.min_period = UINT_MAX;
378*e7b8153eSMauro Carvalho Chehab 	ctx->dbg.min_bitrate = UINT_MAX;
379*e7b8153eSMauro Carvalho Chehab 
380*e7b8153eSMauro Carvalho Chehab 	snprintf(name, sizeof(name), "%d", hva->instance_id);
381*e7b8153eSMauro Carvalho Chehab 
382*e7b8153eSMauro Carvalho Chehab 	ctx->dbg.debugfs_entry = debugfs_create_file(name, 0444,
383*e7b8153eSMauro Carvalho Chehab 						     hva->dbg.debugfs_entry,
384*e7b8153eSMauro Carvalho Chehab 						     ctx, &ctx_fops);
385*e7b8153eSMauro Carvalho Chehab }
386*e7b8153eSMauro Carvalho Chehab 
hva_dbg_ctx_remove(struct hva_ctx * ctx)387*e7b8153eSMauro Carvalho Chehab void hva_dbg_ctx_remove(struct hva_ctx *ctx)
388*e7b8153eSMauro Carvalho Chehab {
389*e7b8153eSMauro Carvalho Chehab 	struct hva_dev *hva = ctx->hva_dev;
390*e7b8153eSMauro Carvalho Chehab 
391*e7b8153eSMauro Carvalho Chehab 	if (ctx->flags & HVA_FLAG_STREAMINFO)
392*e7b8153eSMauro Carvalho Chehab 		/* save context before removing */
393*e7b8153eSMauro Carvalho Chehab 		memcpy(&hva->dbg.last_ctx, ctx, sizeof(*ctx));
394*e7b8153eSMauro Carvalho Chehab 
395*e7b8153eSMauro Carvalho Chehab 	debugfs_remove(ctx->dbg.debugfs_entry);
396*e7b8153eSMauro Carvalho Chehab }
397