root/drivers/media/platform/sti/hva/hva-debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. format_ctx
  2. hva_dbg_perf_begin
  3. hva_dbg_perf_end
  4. hva_dbg_perf_compute
  5. device_show
  6. encoders_show
  7. last_show
  8. regs_show
  9. hva_debugfs_create
  10. hva_debugfs_remove
  11. ctx_show
  12. hva_dbg_ctx_create
  13. hva_dbg_ctx_remove

   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 
  13 static 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  */
 119 void 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 
 175 void 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 
 219 static 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 
 274 static 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 
 284 static 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 
 302 static 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 
 319 static 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 
 332 DEFINE_SHOW_ATTRIBUTE(device);
 333 DEFINE_SHOW_ATTRIBUTE(encoders);
 334 DEFINE_SHOW_ATTRIBUTE(last);
 335 DEFINE_SHOW_ATTRIBUTE(regs);
 336 
 337 void hva_debugfs_create(struct hva_dev *hva)
 338 {
 339         hva->dbg.debugfs_entry = debugfs_create_dir(HVA_NAME, NULL);
 340         if (!hva->dbg.debugfs_entry)
 341                 goto err;
 342 
 343         if (!hva_dbg_create_entry(device))
 344                 goto err;
 345 
 346         if (!hva_dbg_create_entry(encoders))
 347                 goto err;
 348 
 349         if (!hva_dbg_create_entry(last))
 350                 goto err;
 351 
 352         if (!hva_dbg_create_entry(regs))
 353                 goto err;
 354 
 355         return;
 356 
 357 err:
 358         hva_debugfs_remove(hva);
 359 }
 360 
 361 void hva_debugfs_remove(struct hva_dev *hva)
 362 {
 363         debugfs_remove_recursive(hva->dbg.debugfs_entry);
 364         hva->dbg.debugfs_entry = NULL;
 365 }
 366 
 367 /*
 368  * context (instance) debug info
 369  */
 370 
 371 static int ctx_show(struct seq_file *s, void *data)
 372 {
 373         struct hva_ctx *ctx = s->private;
 374 
 375         seq_printf(s, "[running encoding %d]\n", ctx->id);
 376 
 377         hva_dbg_perf_compute(ctx);
 378         format_ctx(s, ctx);
 379 
 380         return 0;
 381 }
 382 
 383 DEFINE_SHOW_ATTRIBUTE(ctx);
 384 
 385 void hva_dbg_ctx_create(struct hva_ctx *ctx)
 386 {
 387         struct hva_dev *hva = ctx->hva_dev;
 388         char name[4] = "";
 389 
 390         ctx->dbg.min_duration = UINT_MAX;
 391         ctx->dbg.min_period = UINT_MAX;
 392         ctx->dbg.min_bitrate = UINT_MAX;
 393 
 394         snprintf(name, sizeof(name), "%d", hva->instance_id);
 395 
 396         ctx->dbg.debugfs_entry = debugfs_create_file(name, 0444,
 397                                                      hva->dbg.debugfs_entry,
 398                                                      ctx, &ctx_fops);
 399 }
 400 
 401 void hva_dbg_ctx_remove(struct hva_ctx *ctx)
 402 {
 403         struct hva_dev *hva = ctx->hva_dev;
 404 
 405         if (ctx->flags & HVA_FLAG_STREAMINFO)
 406                 /* save context before removing */
 407                 memcpy(&hva->dbg.last_ctx, ctx, sizeof(*ctx));
 408 
 409         debugfs_remove(ctx->dbg.debugfs_entry);
 410 }

/* [<][>][^][v][top][bottom][index][help] */