Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: aspeed: add debugfs

To show video real-time information as below:

Capture:
Signal : Unlock
Width : 1920
Height : 1080
FRC : 30

Performance:
Frame# : 0
Frame Duration(ms) :
Now : 0
Min : 0
Max : 0
FPS : 0

[hverkuil: make aspeed_video_proc_open() static, fixes sparse warning]

Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

authored by

Jammy Huang and committed by
Mauro Carvalho Chehab
52fed10a 67f85135

+100
+100
drivers/media/platform/aspeed-video.c
··· 23 23 #include <linux/videodev2.h> 24 24 #include <linux/wait.h> 25 25 #include <linux/workqueue.h> 26 + #include <linux/debugfs.h> 27 + #include <linux/ktime.h> 26 28 #include <media/v4l2-ctrls.h> 27 29 #include <media/v4l2-dev.h> 28 30 #include <media/v4l2-device.h> ··· 203 201 struct list_head link; 204 202 }; 205 203 204 + struct aspeed_video_perf { 205 + ktime_t last_sample; 206 + u32 totaltime; 207 + u32 duration; 208 + u32 duration_min; 209 + u32 duration_max; 210 + }; 211 + 206 212 #define to_aspeed_video_buffer(x) \ 207 213 container_of((x), struct aspeed_video_buffer, vb) 208 214 ··· 252 242 unsigned int frame_left; 253 243 unsigned int frame_right; 254 244 unsigned int frame_top; 245 + 246 + struct aspeed_video_perf perf; 255 247 }; 256 248 257 249 #define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev) ··· 477 465 readl(video->base + reg)); 478 466 } 479 467 468 + static void update_perf(struct aspeed_video_perf *p) 469 + { 470 + p->duration = 471 + ktime_to_ms(ktime_sub(ktime_get(), p->last_sample)); 472 + p->totaltime += p->duration; 473 + 474 + p->duration_max = max(p->duration, p->duration_max); 475 + p->duration_min = min(p->duration, p->duration_min); 476 + } 477 + 480 478 static int aspeed_video_start_frame(struct aspeed_video *video) 481 479 { 482 480 dma_addr_t addr; ··· 524 502 525 503 aspeed_video_update(video, VE_INTERRUPT_CTRL, 0, 526 504 VE_INTERRUPT_COMP_COMPLETE); 505 + 506 + video->perf.last_sample = ktime_get(); 527 507 528 508 aspeed_video_update(video, VE_SEQ_CTRL, 0, 529 509 VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP); ··· 641 617 struct aspeed_video_buffer *buf; 642 618 u32 frame_size = aspeed_video_read(video, 643 619 video->comp_size_read); 620 + 621 + update_perf(&video->perf); 644 622 645 623 spin_lock(&video->lock); 646 624 clear_bit(VIDEO_FRAME_INPRG, &video->flags); ··· 801 775 det->width = MIN_WIDTH; 802 776 det->height = MIN_HEIGHT; 803 777 video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL; 778 + memset(&video->perf, 0, sizeof(video->perf)); 804 779 805 780 do { 806 781 if (tries) { ··· 1492 1465 struct aspeed_video *video = vb2_get_drv_priv(q); 1493 1466 1494 1467 video->sequence = 0; 1468 + video->perf.duration_max = 0; 1469 + video->perf.duration_min = 0xffffffff; 1495 1470 1496 1471 rc = aspeed_video_start_frame(video); 1497 1472 if (rc) { ··· 1560 1531 .stop_streaming = aspeed_video_stop_streaming, 1561 1532 .buf_queue = aspeed_video_buf_queue, 1562 1533 }; 1534 + 1535 + #ifdef CONFIG_DEBUG_FS 1536 + static int aspeed_video_debugfs_show(struct seq_file *s, void *data) 1537 + { 1538 + struct aspeed_video *v = s->private; 1539 + 1540 + seq_puts(s, "\n"); 1541 + 1542 + seq_printf(s, " %-20s:\t%s\n", "Signal", 1543 + v->v4l2_input_status ? "Unlock" : "Lock"); 1544 + seq_printf(s, " %-20s:\t%d\n", "Width", v->pix_fmt.width); 1545 + seq_printf(s, " %-20s:\t%d\n", "Height", v->pix_fmt.height); 1546 + seq_printf(s, " %-20s:\t%d\n", "FRC", v->frame_rate); 1547 + 1548 + seq_puts(s, "\n"); 1549 + 1550 + seq_puts(s, "Performance:\n"); 1551 + seq_printf(s, " %-20s:\t%d\n", "Frame#", v->sequence); 1552 + seq_printf(s, " %-20s:\n", "Frame Duration(ms)"); 1553 + seq_printf(s, " %-18s:\t%d\n", "Now", v->perf.duration); 1554 + seq_printf(s, " %-18s:\t%d\n", "Min", v->perf.duration_min); 1555 + seq_printf(s, " %-18s:\t%d\n", "Max", v->perf.duration_max); 1556 + seq_printf(s, " %-20s:\t%d\n", "FPS", 1000 / (v->perf.totaltime / v->sequence)); 1557 + 1558 + return 0; 1559 + } 1560 + 1561 + static int aspeed_video_proc_open(struct inode *inode, struct file *file) 1562 + { 1563 + return single_open(file, aspeed_video_debugfs_show, inode->i_private); 1564 + } 1565 + 1566 + static const struct file_operations aspeed_video_debugfs_ops = { 1567 + .owner = THIS_MODULE, 1568 + .open = aspeed_video_proc_open, 1569 + .read = seq_read, 1570 + .llseek = seq_lseek, 1571 + .release = single_release, 1572 + }; 1573 + 1574 + static struct dentry *debugfs_entry; 1575 + 1576 + static void aspeed_video_debugfs_remove(struct aspeed_video *video) 1577 + { 1578 + debugfs_remove_recursive(debugfs_entry); 1579 + debugfs_entry = NULL; 1580 + } 1581 + 1582 + static int aspeed_video_debugfs_create(struct aspeed_video *video) 1583 + { 1584 + debugfs_entry = debugfs_create_file(DEVICE_NAME, 0444, NULL, 1585 + video, 1586 + &aspeed_video_debugfs_ops); 1587 + if (!debugfs_entry) 1588 + aspeed_video_debugfs_remove(video); 1589 + 1590 + return !debugfs_entry ? -EIO : 0; 1591 + } 1592 + #else 1593 + static void aspeed_video_debugfs_remove(struct aspeed_video *video) { } 1594 + static int aspeed_video_debugfs_create(struct aspeed_video *video) 1595 + { 1596 + return 0; 1597 + } 1598 + #endif /* CONFIG_DEBUG_FS */ 1563 1599 1564 1600 static int aspeed_video_setup_video(struct aspeed_video *video) 1565 1601 { ··· 1830 1736 return rc; 1831 1737 } 1832 1738 1739 + rc = aspeed_video_debugfs_create(video); 1740 + if (rc) 1741 + dev_err(video->dev, "debugfs create failed\n"); 1742 + 1833 1743 return 0; 1834 1744 } 1835 1745 ··· 1844 1746 struct aspeed_video *video = to_aspeed_video(v4l2_dev); 1845 1747 1846 1748 aspeed_video_off(video); 1749 + 1750 + aspeed_video_debugfs_remove(video); 1847 1751 1848 1752 clk_unprepare(video->vclk); 1849 1753 clk_unprepare(video->eclk);