brintos

brintos / linux-shallow public Read only

0
0
Text · 15.6 KiB · a27f638 Raw
659 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) STMicroelectronics SA 20144 * 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	else28		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		else426			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 1000000584 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	else601		avg_fps = SECOND / (s32)avg_time_us;602 603	if (bdisp->dbg.min_duration > SECOND)604		min_fps = 0;605	else606		min_fps = SECOND / (s32)bdisp->dbg.min_duration;607 608	if (bdisp->dbg.max_duration > SECOND)609		max_fps = 0;610	else611		max_fps = SECOND / (s32)bdisp->dbg.max_duration;612 613	if (bdisp->dbg.last_duration > SECOND)614		last_fps = 0;615	else616		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}659