cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hva-debugfs.c (10178B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) STMicroelectronics SA 2015
      4 * 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 info
    118 */
    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 the
    141		 * encoding period values upon a window of 32 samples
    142		 */
    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 / duration
    150			 */
    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 sequence
    170	 * - begin/end is a valid sequence
    171	 */
    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 size
    211	 * and the total encoding periods
    212	 */
    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 duration
    261		 */
    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 info
    272 */
    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 info
    355 */
    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}