brintos

brintos / linux-shallow public Read only

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