From 9ec4e21f2f615ef95b70a249569906799e36bace Mon Sep 17 00:00:00 2001
From: lin <lin@kickpi.com>
Date: Tue, 14 Jan 2025 07:24:21 +0000
Subject: [PATCH] feat(disp): add disp info support

---
 longan/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/dev_disp.c |  171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 170 insertions(+), 1 deletions(-)

diff --git a/longan/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/dev_disp.c b/longan/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/dev_disp.c
index 08dc1ce..22ffbb7 100755
--- a/longan/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/dev_disp.c
+++ b/longan/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/dev_disp.c
@@ -11,7 +11,7 @@
 */
 
 #include "dev_disp.h"
-
+#include "de/disp_display.h"
 disp_drv_info g_disp_drv;
 
 #define MY_BYTE_ALIGN(x) ( ( (x + (4*1024-1)) >> 12) << 12)             /* alloc based on 4K byte */
@@ -1312,6 +1312,175 @@
   return ret;
 }
 
+s32 bsp_disp_get_fps(u32 disp)
+{
+	u32 pre_time_index, cur_time_index;
+	u32 pre_time, cur_time;
+	u32 fps = 0xff;
+
+	pre_time_index = gdisp.screen[disp].health_info.sync_time_index;
+	cur_time_index = (pre_time_index == 0) ? (DEBUG_TIME_SIZE - 1) : (pre_time_index - 1);
+
+	pre_time = gdisp.screen[disp].health_info.sync_time[pre_time_index];
+	cur_time = gdisp.screen[disp].health_info.sync_time[cur_time_index];
+
+	if (pre_time != cur_time) {
+		fps = 10000 * DEBUG_TIME_SIZE / (cur_time - pre_time);
+	}
+
+	return fps;
+}
+
+
+s32 bsp_disp_get_health_info(u32 disp, disp_health_info *info)
+{
+	if (info)
+		memcpy(info, &gdisp.screen[disp].health_info, sizeof(disp_health_info));
+	return 0;
+}
+
+int do_sunxi_disp_sys(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+#define SYS_BUF_SIZE 5120
+	struct disp_manager *mgr = NULL;
+	struct disp_device *dispdev = NULL;
+	ssize_t count = 0;
+	int num_screens, screen_id;
+	int num_layers, layer_id;
+	int num_chans, chan_id;
+	char *buf = NULL;
+#if defined(CONFIG_DISP2_LCD_ESD_DETECT)
+	struct disp_lcd_esd_info esd_inf;
+
+	memset(&esd_inf, 0, sizeof(struct disp_lcd_esd_info));
+#endif
+	/* int hpd; */
+
+	buf = kmalloc(SYS_BUF_SIZE, GFP_KERNEL | __GFP_ZERO);
+	num_screens = bsp_disp_feat_get_num_screens();
+	for (screen_id = 0; screen_id < num_screens; screen_id++) {
+		u32 width = 0, height = 0;
+		int fps = 0;
+		disp_health_info info;
+
+		mgr = disp_get_layer_manager(screen_id);
+		if (mgr == NULL)
+			continue;
+		dispdev = mgr->device;
+		if (dispdev == NULL)
+			continue;
+		dispdev->get_resolution(dispdev, &width, &height);
+		fps = bsp_disp_get_fps(screen_id);
+		bsp_disp_get_health_info(screen_id, &info);
+
+		if (!dispdev->is_enabled(dispdev))
+			continue;
+		count += sprintf(buf + count, "screen %d:\n", screen_id);
+		count += sprintf(buf + count, "de_rate %d hz, ref_fps:%d\n",
+				 mgr->get_clk_rate(mgr),
+				 dispdev->get_fps(dispdev));
+		count += mgr->dump(mgr, buf + count);
+		/* output */
+		if (dispdev->type == DISP_OUTPUT_TYPE_LCD) {
+			count += sprintf(buf + count,
+				"\tlcd output\tbacklight(%3d)\tfps:%d.%d",
+				dispdev->get_bright(dispdev), fps / 10,
+				fps % 10);
+#if defined(CONFIG_DISP2_LCD_ESD_DETECT)
+			if (dispdev->get_esd_info) {
+				dispdev->get_esd_info(dispdev, &esd_inf);
+				count += sprintf(buf + count,
+				"\tesd level(%u)\tfreq(%u)\tpos(%u)\treset(%u)",
+				esd_inf.level, esd_inf.freq,
+				esd_inf.esd_check_func_pos, esd_inf.rst_cnt);
+			}
+#endif
+		} else if (dispdev->type == DISP_OUTPUT_TYPE_HDMI) {
+			int mode = dispdev->get_mode(dispdev);
+
+			count += sprintf(buf + count,
+					 "\thdmi output mode(%d)\tfps:%d.%d",
+					 mode, fps / 10, fps % 10);
+		} else if (dispdev->type == DISP_OUTPUT_TYPE_TV) {
+			int mode = dispdev->get_mode(dispdev);
+
+			count += sprintf(buf + count,
+					 "\ttv output mode(%d)\tfps:%d.%d",
+					 mode, fps / 10, fps % 10);
+		}
+/* else if (dispdev->type == DISP_OUTPUT_TYPE_VGA) {
+			int mode = dispdev->get_mode(dispdev);
+
+			count += sprintf(buf + count,
+					 "\tvga output mode(%d)\tfps:%d.%d",
+					 mode, fps / 10, fps % 10);
+		}  else if (dispdev->type == DISP_OUTPUT_TYPE_VDPO) {
+			int mode = dispdev->get_mode(dispdev);
+
+			count += sprintf(buf + count,
+					 "\tvdpo output mode(%d)\tfps:%d.%d",
+					 mode, fps / 10, fps % 10);
+		}  else if (dispdev->type == DISP_OUTPUT_TYPE_RTWB) {
+			int mode = dispdev->get_mode(dispdev);
+
+			count += sprintf(buf + count,
+					 "\trtwb output mode(%d)\tfps:%d.%d",
+					 mode, fps / 10, fps % 10);
+		} else if (dispdev->type == DISP_OUTPUT_TYPE_EDP) {
+			count += sprintf(
+			    buf + count, "\tEDP output(%s) \tfps:%d.%d",
+			    (dispdev->is_enabled(dispdev) == 1) ? "enable"
+								: "disable",
+			    fps / 10, fps % 10);
+		}
+*/
+		if (dispdev->type != DISP_OUTPUT_TYPE_NONE) {
+			count += sprintf(buf + count, "\t%4ux%4u\n",
+					 width, height);
+			count += sprintf(buf + count,
+					"\terr:%u\tskip:%u\tirq:%u\tvsync:%u\tvsync_skip:%u\t\n",
+					info.error_cnt, info.skip_cnt,
+					info.irq_cnt, info.vsync_cnt,
+					info.vsync_skip_cnt);
+		}
+
+		printf("%s\n", buf);
+		memset(buf, 0, SYS_BUF_SIZE);
+		count = 0;
+		num_chans = bsp_disp_feat_get_num_channels(screen_id);
+
+		/* layer info */
+		for (chan_id = 0; chan_id < num_chans; chan_id++) {
+			num_layers =
+			    bsp_disp_feat_get_num_layers_by_chn(screen_id,
+								chan_id);
+			for (layer_id = 0; layer_id < num_layers; layer_id++) {
+				struct disp_layer *lyr = NULL;
+				struct disp_layer_config config;
+
+				lyr = disp_get_layer(screen_id, chan_id,
+						     layer_id);
+				config.channel = chan_id;
+				config.layer_id = layer_id;
+				mgr->get_layer_config(mgr, &config, 1);
+				if (lyr && (true == config.enable) && lyr->dump) {
+					count += lyr->dump(lyr, buf + count);
+					printf("%s\n", buf);
+					memset(buf, 0, SYS_BUF_SIZE);
+					count = 0;
+				}
+			}
+		}
+	}
+	kfree(buf);
+	return 0;
+}
+
+U_BOOT_CMD(
+	disp,	3,	0,	do_sunxi_disp_sys,
+	"show display status",
+	"\nparameters  : NULL\n"
+);
 /*TODO:drv_disp_standby is useful??*/
 
 int do_sunxi_disp_colorbar(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])

--
Gitblit v1.6.2