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

bdisp-debug.c (15993B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) STMicroelectronics SA 2014
      4 * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
      5 */
      6
      7#include <linux/debugfs.h>
      8#include <linux/pm_runtime.h>
      9
     10#include "bdisp.h"
     11#include "bdisp-filter.h"
     12#include "bdisp-reg.h"
     13
     14void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp)
     15{
     16	bdisp->dbg.hw_start = ktime_get();
     17}
     18
     19void bdisp_dbg_perf_end(struct bdisp_dev *bdisp)
     20{
     21	s64 time_us;
     22
     23	time_us = ktime_us_delta(ktime_get(), bdisp->dbg.hw_start);
     24
     25	if (!bdisp->dbg.min_duration)
     26		bdisp->dbg.min_duration = time_us;
     27	else
     28		bdisp->dbg.min_duration = min(time_us, bdisp->dbg.min_duration);
     29
     30	bdisp->dbg.last_duration = time_us;
     31	bdisp->dbg.max_duration = max(time_us, bdisp->dbg.max_duration);
     32	bdisp->dbg.tot_duration += time_us;
     33}
     34
     35static void bdisp_dbg_dump_ins(struct seq_file *s, u32 val)
     36{
     37	seq_printf(s, "INS\t0x%08X\t", val);
     38
     39	switch (val & BLT_INS_S1_MASK) {
     40	case BLT_INS_S1_OFF:
     41		break;
     42	case BLT_INS_S1_MEM:
     43		seq_puts(s, "SRC1=mem - ");
     44		break;
     45	case BLT_INS_S1_CF:
     46		seq_puts(s, "SRC1=ColorFill - ");
     47		break;
     48	case BLT_INS_S1_COPY:
     49		seq_puts(s, "SRC1=copy - ");
     50		break;
     51	case BLT_INS_S1_FILL:
     52		seq_puts(s, "SRC1=fil - ");
     53		break;
     54	default:
     55		seq_puts(s, "SRC1=??? - ");
     56		break;
     57	}
     58
     59	switch (val & BLT_INS_S2_MASK) {
     60	case BLT_INS_S2_OFF:
     61		break;
     62	case BLT_INS_S2_MEM:
     63		seq_puts(s, "SRC2=mem - ");
     64		break;
     65	case BLT_INS_S2_CF:
     66		seq_puts(s, "SRC2=ColorFill - ");
     67		break;
     68	default:
     69		seq_puts(s, "SRC2=??? - ");
     70		break;
     71	}
     72
     73	if ((val & BLT_INS_S3_MASK) == BLT_INS_S3_MEM)
     74		seq_puts(s, "SRC3=mem - ");
     75
     76	if (val & BLT_INS_IVMX)
     77		seq_puts(s, "IVMX - ");
     78	if (val & BLT_INS_CLUT)
     79		seq_puts(s, "CLUT - ");
     80	if (val & BLT_INS_SCALE)
     81		seq_puts(s, "Scale - ");
     82	if (val & BLT_INS_FLICK)
     83		seq_puts(s, "Flicker - ");
     84	if (val & BLT_INS_CLIP)
     85		seq_puts(s, "Clip - ");
     86	if (val & BLT_INS_CKEY)
     87		seq_puts(s, "ColorKey - ");
     88	if (val & BLT_INS_OVMX)
     89		seq_puts(s, "OVMX - ");
     90	if (val & BLT_INS_DEI)
     91		seq_puts(s, "Deint - ");
     92	if (val & BLT_INS_PMASK)
     93		seq_puts(s, "PlaneMask - ");
     94	if (val & BLT_INS_VC1R)
     95		seq_puts(s, "VC1R - ");
     96	if (val & BLT_INS_ROTATE)
     97		seq_puts(s, "Rotate - ");
     98	if (val & BLT_INS_GRAD)
     99		seq_puts(s, "GradFill - ");
    100	if (val & BLT_INS_AQLOCK)
    101		seq_puts(s, "AQLock - ");
    102	if (val & BLT_INS_PACE)
    103		seq_puts(s, "Pace - ");
    104	if (val & BLT_INS_IRQ)
    105		seq_puts(s, "IRQ - ");
    106
    107	seq_putc(s, '\n');
    108}
    109
    110static void bdisp_dbg_dump_tty(struct seq_file *s, u32 val)
    111{
    112	seq_printf(s, "TTY\t0x%08X\t", val);
    113	seq_printf(s, "Pitch=%d - ", val & 0xFFFF);
    114
    115	switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) {
    116	case BDISP_RGB565:
    117		seq_puts(s, "RGB565 - ");
    118		break;
    119	case BDISP_RGB888:
    120		seq_puts(s, "RGB888 - ");
    121		break;
    122	case BDISP_XRGB8888:
    123		seq_puts(s, "xRGB888 - ");
    124		break;
    125	case BDISP_ARGB8888:
    126		seq_puts(s, "ARGB8888 - ");
    127		break;
    128	case BDISP_NV12:
    129		seq_puts(s, "NV12 - ");
    130		break;
    131	case BDISP_YUV_3B:
    132		seq_puts(s, "YUV420P - ");
    133		break;
    134	default:
    135		seq_puts(s, "ColorFormat ??? - ");
    136		break;
    137	}
    138
    139	if (val & BLT_TTY_ALPHA_R)
    140		seq_puts(s, "AlphaRange - ");
    141	if (val & BLT_TTY_CR_NOT_CB)
    142		seq_puts(s, "CrNotCb - ");
    143	if (val & BLT_TTY_MB)
    144		seq_puts(s, "MB - ");
    145	if (val & BLT_TTY_HSO)
    146		seq_puts(s, "HSO inverse - ");
    147	if (val & BLT_TTY_VSO)
    148		seq_puts(s, "VSO inverse - ");
    149	if (val & BLT_TTY_DITHER)
    150		seq_puts(s, "Dither - ");
    151	if (val & BLT_TTY_CHROMA)
    152		seq_puts(s, "Write CHROMA - ");
    153	if (val & BLT_TTY_BIG_END)
    154		seq_puts(s, "BigEndian - ");
    155
    156	seq_putc(s, '\n');
    157}
    158
    159static void bdisp_dbg_dump_xy(struct seq_file *s, u32 val, char *name)
    160{
    161	seq_printf(s, "%s\t0x%08X\t", name, val);
    162	seq_printf(s, "(%d,%d)\n", val & 0xFFFF, (val >> 16));
    163}
    164
    165static void bdisp_dbg_dump_sz(struct seq_file *s, u32 val, char *name)
    166{
    167	seq_printf(s, "%s\t0x%08X\t", name, val);
    168	seq_printf(s, "%dx%d\n", val & 0x1FFF, (val >> 16) & 0x1FFF);
    169}
    170
    171static void bdisp_dbg_dump_sty(struct seq_file *s,
    172			       u32 val, u32 addr, char *name)
    173{
    174	bool s1, s2, s3;
    175
    176	seq_printf(s, "%s\t0x%08X\t", name, val);
    177
    178	if (!addr || !name || (strlen(name) < 2))
    179		goto done;
    180
    181	s1 = name[strlen(name) - 1] == '1';
    182	s2 = name[strlen(name) - 1] == '2';
    183	s3 = name[strlen(name) - 1] == '3';
    184
    185	seq_printf(s, "Pitch=%d - ", val & 0xFFFF);
    186
    187	switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) {
    188	case BDISP_RGB565:
    189		seq_puts(s, "RGB565 - ");
    190		break;
    191	case BDISP_RGB888:
    192		seq_puts(s, "RGB888 - ");
    193		break;
    194	case BDISP_XRGB8888:
    195		seq_puts(s, "xRGB888 - ");
    196		break;
    197	case BDISP_ARGB8888:
    198		seq_puts(s, "ARGB888 - ");
    199		break;
    200	case BDISP_NV12:
    201		seq_puts(s, "NV12 - ");
    202		break;
    203	case BDISP_YUV_3B:
    204		seq_puts(s, "YUV420P - ");
    205		break;
    206	default:
    207		seq_puts(s, "ColorFormat ??? - ");
    208		break;
    209	}
    210
    211	if ((val & BLT_TTY_ALPHA_R) && !s3)
    212		seq_puts(s, "AlphaRange - ");
    213	if ((val & BLT_S1TY_A1_SUBSET) && !s3)
    214		seq_puts(s, "A1SubSet - ");
    215	if ((val & BLT_TTY_MB) && !s1)
    216		seq_puts(s, "MB - ");
    217	if (val & BLT_TTY_HSO)
    218		seq_puts(s, "HSO inverse - ");
    219	if (val & BLT_TTY_VSO)
    220		seq_puts(s, "VSO inverse - ");
    221	if ((val & BLT_S1TY_CHROMA_EXT) && (s1 || s2))
    222		seq_puts(s, "ChromaExt - ");
    223	if ((val & BLT_S3TY_BLANK_ACC) && s3)
    224		seq_puts(s, "Blank Acc - ");
    225	if ((val & BTL_S1TY_SUBBYTE) && !s3)
    226		seq_puts(s, "SubByte - ");
    227	if ((val & BLT_S1TY_RGB_EXP) && !s3)
    228		seq_puts(s, "RGBExpand - ");
    229	if ((val & BLT_TTY_BIG_END) && !s3)
    230		seq_puts(s, "BigEndian - ");
    231
    232done:
    233	seq_putc(s, '\n');
    234}
    235
    236static void bdisp_dbg_dump_fctl(struct seq_file *s, u32 val)
    237{
    238	seq_printf(s, "FCTL\t0x%08X\t", val);
    239
    240	if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SCALE)
    241		seq_puts(s, "Resize Luma - ");
    242	else if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SAMPLE)
    243		seq_puts(s, "Sample Luma - ");
    244
    245	if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SCALE)
    246		seq_puts(s, "Resize Chroma");
    247	else if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SAMPLE)
    248		seq_puts(s, "Sample Chroma");
    249
    250	seq_putc(s, '\n');
    251}
    252
    253static void bdisp_dbg_dump_rsf(struct seq_file *s, u32 val, char *name)
    254{
    255	u32 inc;
    256
    257	seq_printf(s, "%s\t0x%08X\t", name, val);
    258
    259	if (!val)
    260		goto done;
    261
    262	inc = val & 0xFFFF;
    263	seq_printf(s, "H: %d(6.10) / scale~%dx0.1 - ", inc, 1024 * 10 / inc);
    264
    265	inc = val >> 16;
    266	seq_printf(s, "V: %d(6.10) / scale~%dx0.1", inc, 1024 * 10 / inc);
    267
    268done:
    269	seq_putc(s, '\n');
    270}
    271
    272static void bdisp_dbg_dump_rzi(struct seq_file *s, u32 val, char *name)
    273{
    274	seq_printf(s, "%s\t0x%08X\t", name, val);
    275
    276	if (!val)
    277		goto done;
    278
    279	seq_printf(s, "H: init=%d repeat=%d - ", val & 0x3FF, (val >> 12) & 7);
    280	val >>= 16;
    281	seq_printf(s, "V: init=%d repeat=%d", val & 0x3FF, (val >> 12) & 7);
    282
    283done:
    284	seq_putc(s, '\n');
    285}
    286
    287static void bdisp_dbg_dump_ivmx(struct seq_file *s,
    288				u32 c0, u32 c1, u32 c2, u32 c3)
    289{
    290	seq_printf(s, "IVMX0\t0x%08X\n", c0);
    291	seq_printf(s, "IVMX1\t0x%08X\n", c1);
    292	seq_printf(s, "IVMX2\t0x%08X\n", c2);
    293	seq_printf(s, "IVMX3\t0x%08X\t", c3);
    294
    295	if (!c0 && !c1 && !c2 && !c3) {
    296		seq_putc(s, '\n');
    297		return;
    298	}
    299
    300	if ((c0 == bdisp_rgb_to_yuv[0]) &&
    301	    (c1 == bdisp_rgb_to_yuv[1]) &&
    302	    (c2 == bdisp_rgb_to_yuv[2]) &&
    303	    (c3 == bdisp_rgb_to_yuv[3])) {
    304		seq_puts(s, "RGB to YUV\n");
    305		return;
    306	}
    307
    308	if ((c0 == bdisp_yuv_to_rgb[0]) &&
    309	    (c1 == bdisp_yuv_to_rgb[1]) &&
    310	    (c2 == bdisp_yuv_to_rgb[2]) &&
    311	    (c3 == bdisp_yuv_to_rgb[3])) {
    312		seq_puts(s, "YUV to RGB\n");
    313		return;
    314	}
    315	seq_puts(s, "Unknown conversion\n");
    316}
    317
    318static int last_nodes_show(struct seq_file *s, void *data)
    319{
    320	/* Not dumping all fields, focusing on significant ones */
    321	struct bdisp_dev *bdisp = s->private;
    322	struct bdisp_node *node;
    323	int i = 0;
    324
    325	if (!bdisp->dbg.copy_node[0]) {
    326		seq_puts(s, "No node built yet\n");
    327		return 0;
    328	}
    329
    330	do {
    331		node = bdisp->dbg.copy_node[i];
    332		if (!node)
    333			break;
    334		seq_printf(s, "--------\nNode %d:\n", i);
    335		seq_puts(s, "-- General --\n");
    336		seq_printf(s, "NIP\t0x%08X\n", node->nip);
    337		seq_printf(s, "CIC\t0x%08X\n", node->cic);
    338		bdisp_dbg_dump_ins(s, node->ins);
    339		seq_printf(s, "ACK\t0x%08X\n", node->ack);
    340		seq_puts(s, "-- Target --\n");
    341		seq_printf(s, "TBA\t0x%08X\n", node->tba);
    342		bdisp_dbg_dump_tty(s, node->tty);
    343		bdisp_dbg_dump_xy(s, node->txy, "TXY");
    344		bdisp_dbg_dump_sz(s, node->tsz, "TSZ");
    345		/* Color Fill not dumped */
    346		seq_puts(s, "-- Source 1 --\n");
    347		seq_printf(s, "S1BA\t0x%08X\n", node->s1ba);
    348		bdisp_dbg_dump_sty(s, node->s1ty, node->s1ba, "S1TY");
    349		bdisp_dbg_dump_xy(s, node->s1xy, "S1XY");
    350		seq_puts(s, "-- Source 2 --\n");
    351		seq_printf(s, "S2BA\t0x%08X\n", node->s2ba);
    352		bdisp_dbg_dump_sty(s, node->s2ty, node->s2ba, "S2TY");
    353		bdisp_dbg_dump_xy(s, node->s2xy, "S2XY");
    354		bdisp_dbg_dump_sz(s, node->s2sz, "S2SZ");
    355		seq_puts(s, "-- Source 3 --\n");
    356		seq_printf(s, "S3BA\t0x%08X\n", node->s3ba);
    357		bdisp_dbg_dump_sty(s, node->s3ty, node->s3ba, "S3TY");
    358		bdisp_dbg_dump_xy(s, node->s3xy, "S3XY");
    359		bdisp_dbg_dump_sz(s, node->s3sz, "S3SZ");
    360		/* Clipping not dumped */
    361		/* CLUT not dumped */
    362		seq_puts(s, "-- Filter & Mask --\n");
    363		bdisp_dbg_dump_fctl(s, node->fctl);
    364		/* PMK not dumped */
    365		seq_puts(s, "-- Chroma Filter --\n");
    366		bdisp_dbg_dump_rsf(s, node->rsf, "RSF");
    367		bdisp_dbg_dump_rzi(s, node->rzi, "RZI");
    368		seq_printf(s, "HFP\t0x%08X\n", node->hfp);
    369		seq_printf(s, "VFP\t0x%08X\n", node->vfp);
    370		seq_puts(s, "-- Luma Filter --\n");
    371		bdisp_dbg_dump_rsf(s, node->y_rsf, "Y_RSF");
    372		bdisp_dbg_dump_rzi(s, node->y_rzi, "Y_RZI");
    373		seq_printf(s, "Y_HFP\t0x%08X\n", node->y_hfp);
    374		seq_printf(s, "Y_VFP\t0x%08X\n", node->y_vfp);
    375		/* Flicker not dumped */
    376		/* Color key not dumped */
    377		/* Reserved not dumped */
    378		/* Static Address & User not dumped */
    379		seq_puts(s, "-- Input Versatile Matrix --\n");
    380		bdisp_dbg_dump_ivmx(s, node->ivmx0, node->ivmx1,
    381				    node->ivmx2, node->ivmx3);
    382		/* Output Versatile Matrix not dumped */
    383		/* Pace not dumped */
    384		/* VC1R & DEI not dumped */
    385		/* Gradient Fill not dumped */
    386	} while ((++i < MAX_NB_NODE) && node->nip);
    387
    388	return 0;
    389}
    390
    391static int last_nodes_raw_show(struct seq_file *s, void *data)
    392{
    393	struct bdisp_dev *bdisp = s->private;
    394	struct bdisp_node *node;
    395	u32 *val;
    396	int j, i = 0;
    397
    398	if (!bdisp->dbg.copy_node[0]) {
    399		seq_puts(s, "No node built yet\n");
    400		return 0;
    401	}
    402
    403	do {
    404		node = bdisp->dbg.copy_node[i];
    405		if (!node)
    406			break;
    407
    408		seq_printf(s, "--------\nNode %d:\n", i);
    409		val = (u32 *)node;
    410		for (j = 0; j < sizeof(struct bdisp_node) / sizeof(u32); j++)
    411			seq_printf(s, "0x%08X\n", *val++);
    412	} while ((++i < MAX_NB_NODE) && node->nip);
    413
    414	return 0;
    415}
    416
    417static const char *bdisp_fmt_to_str(struct bdisp_frame frame)
    418{
    419	switch (frame.fmt->pixelformat) {
    420	case V4L2_PIX_FMT_YUV420:
    421		return "YUV420P";
    422	case V4L2_PIX_FMT_NV12:
    423		if (frame.field == V4L2_FIELD_INTERLACED)
    424			return "NV12 interlaced";
    425		else
    426			return "NV12";
    427	case V4L2_PIX_FMT_RGB565:
    428		return "RGB16";
    429	case V4L2_PIX_FMT_RGB24:
    430		return "RGB24";
    431	case V4L2_PIX_FMT_XBGR32:
    432		return "XRGB";
    433	case V4L2_PIX_FMT_ABGR32:
    434		return "ARGB";
    435	default:
    436		return "????";
    437	}
    438}
    439
    440static int last_request_show(struct seq_file *s, void *data)
    441{
    442	struct bdisp_dev *bdisp = s->private;
    443	struct bdisp_request *request = &bdisp->dbg.copy_request;
    444	struct bdisp_frame src, dst;
    445
    446	if (!request->nb_req) {
    447		seq_puts(s, "No request\n");
    448		return 0;
    449	}
    450
    451	src = request->src;
    452	dst = request->dst;
    453
    454	seq_printf(s, "\nRequest #%d\n", request->nb_req);
    455
    456	seq_printf(s, "Format:    %s\t\t\t%s\n",
    457		   bdisp_fmt_to_str(src), bdisp_fmt_to_str(dst));
    458	seq_printf(s, "Crop area: %dx%d @ %d,%d  ==>\t%dx%d @ %d,%d\n",
    459		   src.crop.width, src.crop.height,
    460		   src.crop.left, src.crop.top,
    461		   dst.crop.width, dst.crop.height,
    462		   dst.crop.left, dst.crop.top);
    463	seq_printf(s, "Buff size: %dx%d\t\t%dx%d\n\n",
    464		   src.width, src.height, dst.width, dst.height);
    465
    466	if (request->hflip)
    467		seq_puts(s, "Horizontal flip\n\n");
    468
    469	if (request->vflip)
    470		seq_puts(s, "Vertical flip\n\n");
    471
    472	return 0;
    473}
    474
    475#define DUMP(reg) seq_printf(s, #reg " \t0x%08X\n", readl(bdisp->regs + reg))
    476
    477static int regs_show(struct seq_file *s, void *data)
    478{
    479	struct bdisp_dev *bdisp = s->private;
    480	int ret;
    481	unsigned int i;
    482
    483	ret = pm_runtime_resume_and_get(bdisp->dev);
    484	if (ret < 0) {
    485		seq_puts(s, "Cannot wake up IP\n");
    486		return 0;
    487	}
    488
    489	seq_printf(s, "Reg @ = 0x%p\n", bdisp->regs);
    490
    491	seq_puts(s, "\nStatic:\n");
    492	DUMP(BLT_CTL);
    493	DUMP(BLT_ITS);
    494	DUMP(BLT_STA1);
    495	DUMP(BLT_AQ1_CTL);
    496	DUMP(BLT_AQ1_IP);
    497	DUMP(BLT_AQ1_LNA);
    498	DUMP(BLT_AQ1_STA);
    499	DUMP(BLT_ITM0);
    500
    501	seq_puts(s, "\nPlugs:\n");
    502	DUMP(BLT_PLUGS1_OP2);
    503	DUMP(BLT_PLUGS1_CHZ);
    504	DUMP(BLT_PLUGS1_MSZ);
    505	DUMP(BLT_PLUGS1_PGZ);
    506	DUMP(BLT_PLUGS2_OP2);
    507	DUMP(BLT_PLUGS2_CHZ);
    508	DUMP(BLT_PLUGS2_MSZ);
    509	DUMP(BLT_PLUGS2_PGZ);
    510	DUMP(BLT_PLUGS3_OP2);
    511	DUMP(BLT_PLUGS3_CHZ);
    512	DUMP(BLT_PLUGS3_MSZ);
    513	DUMP(BLT_PLUGS3_PGZ);
    514	DUMP(BLT_PLUGT_OP2);
    515	DUMP(BLT_PLUGT_CHZ);
    516	DUMP(BLT_PLUGT_MSZ);
    517	DUMP(BLT_PLUGT_PGZ);
    518
    519	seq_puts(s, "\nNode:\n");
    520	DUMP(BLT_NIP);
    521	DUMP(BLT_CIC);
    522	DUMP(BLT_INS);
    523	DUMP(BLT_ACK);
    524	DUMP(BLT_TBA);
    525	DUMP(BLT_TTY);
    526	DUMP(BLT_TXY);
    527	DUMP(BLT_TSZ);
    528	DUMP(BLT_S1BA);
    529	DUMP(BLT_S1TY);
    530	DUMP(BLT_S1XY);
    531	DUMP(BLT_S2BA);
    532	DUMP(BLT_S2TY);
    533	DUMP(BLT_S2XY);
    534	DUMP(BLT_S2SZ);
    535	DUMP(BLT_S3BA);
    536	DUMP(BLT_S3TY);
    537	DUMP(BLT_S3XY);
    538	DUMP(BLT_S3SZ);
    539	DUMP(BLT_FCTL);
    540	DUMP(BLT_RSF);
    541	DUMP(BLT_RZI);
    542	DUMP(BLT_HFP);
    543	DUMP(BLT_VFP);
    544	DUMP(BLT_Y_RSF);
    545	DUMP(BLT_Y_RZI);
    546	DUMP(BLT_Y_HFP);
    547	DUMP(BLT_Y_VFP);
    548	DUMP(BLT_IVMX0);
    549	DUMP(BLT_IVMX1);
    550	DUMP(BLT_IVMX2);
    551	DUMP(BLT_IVMX3);
    552	DUMP(BLT_OVMX0);
    553	DUMP(BLT_OVMX1);
    554	DUMP(BLT_OVMX2);
    555	DUMP(BLT_OVMX3);
    556	DUMP(BLT_DEI);
    557
    558	seq_puts(s, "\nFilter:\n");
    559	for (i = 0; i < BLT_NB_H_COEF; i++) {
    560		seq_printf(s, "BLT_HFC%d \t0x%08X\n", i,
    561			   readl(bdisp->regs + BLT_HFC_N + i * 4));
    562	}
    563	for (i = 0; i < BLT_NB_V_COEF; i++) {
    564		seq_printf(s, "BLT_VFC%d \t0x%08X\n", i,
    565			   readl(bdisp->regs + BLT_VFC_N + i * 4));
    566	}
    567
    568	seq_puts(s, "\nLuma filter:\n");
    569	for (i = 0; i < BLT_NB_H_COEF; i++) {
    570		seq_printf(s, "BLT_Y_HFC%d \t0x%08X\n", i,
    571			   readl(bdisp->regs + BLT_Y_HFC_N + i * 4));
    572	}
    573	for (i = 0; i < BLT_NB_V_COEF; i++) {
    574		seq_printf(s, "BLT_Y_VFC%d \t0x%08X\n", i,
    575			   readl(bdisp->regs + BLT_Y_VFC_N + i * 4));
    576	}
    577
    578	pm_runtime_put(bdisp->dev);
    579
    580	return 0;
    581}
    582
    583#define SECOND 1000000
    584
    585static int perf_show(struct seq_file *s, void *data)
    586{
    587	struct bdisp_dev *bdisp = s->private;
    588	struct bdisp_request *request = &bdisp->dbg.copy_request;
    589	s64 avg_time_us;
    590	int avg_fps, min_fps, max_fps, last_fps;
    591
    592	if (!request->nb_req) {
    593		seq_puts(s, "No request\n");
    594		return 0;
    595	}
    596
    597	avg_time_us = div64_s64(bdisp->dbg.tot_duration, request->nb_req);
    598	if (avg_time_us > SECOND)
    599		avg_fps = 0;
    600	else
    601		avg_fps = SECOND / (s32)avg_time_us;
    602
    603	if (bdisp->dbg.min_duration > SECOND)
    604		min_fps = 0;
    605	else
    606		min_fps = SECOND / (s32)bdisp->dbg.min_duration;
    607
    608	if (bdisp->dbg.max_duration > SECOND)
    609		max_fps = 0;
    610	else
    611		max_fps = SECOND / (s32)bdisp->dbg.max_duration;
    612
    613	if (bdisp->dbg.last_duration > SECOND)
    614		last_fps = 0;
    615	else
    616		last_fps = SECOND / (s32)bdisp->dbg.last_duration;
    617
    618	seq_printf(s, "HW processing (%d requests):\n", request->nb_req);
    619	seq_printf(s, " Average: %5lld us  (%3d fps)\n",
    620		   avg_time_us, avg_fps);
    621	seq_printf(s, " Min-Max: %5lld us  (%3d fps) - %5lld us  (%3d fps)\n",
    622		   bdisp->dbg.min_duration, min_fps,
    623		   bdisp->dbg.max_duration, max_fps);
    624	seq_printf(s, " Last:    %5lld us  (%3d fps)\n",
    625		   bdisp->dbg.last_duration, last_fps);
    626
    627	return 0;
    628}
    629
    630#define bdisp_dbg_create_entry(name) \
    631	debugfs_create_file(#name, S_IRUGO, bdisp->dbg.debugfs_entry, bdisp, \
    632			    &name##_fops)
    633
    634DEFINE_SHOW_ATTRIBUTE(regs);
    635DEFINE_SHOW_ATTRIBUTE(last_nodes);
    636DEFINE_SHOW_ATTRIBUTE(last_nodes_raw);
    637DEFINE_SHOW_ATTRIBUTE(last_request);
    638DEFINE_SHOW_ATTRIBUTE(perf);
    639
    640void bdisp_debugfs_create(struct bdisp_dev *bdisp)
    641{
    642	char dirname[16];
    643
    644	snprintf(dirname, sizeof(dirname), "%s%d", BDISP_NAME, bdisp->id);
    645	bdisp->dbg.debugfs_entry = debugfs_create_dir(dirname, NULL);
    646
    647	bdisp_dbg_create_entry(regs);
    648	bdisp_dbg_create_entry(last_nodes);
    649	bdisp_dbg_create_entry(last_nodes_raw);
    650	bdisp_dbg_create_entry(last_request);
    651	bdisp_dbg_create_entry(perf);
    652}
    653
    654void bdisp_debugfs_remove(struct bdisp_dev *bdisp)
    655{
    656	debugfs_remove_recursive(bdisp->dbg.debugfs_entry);
    657	bdisp->dbg.debugfs_entry = NULL;
    658}