summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylor Nelms <tknelms@google.com>2022-12-07 17:20:50 +0000
committerTaylor Nelms <tknelms@google.com>2023-01-26 18:44:16 +0000
commit8186e1c05ed1d51c5f61f517b17e6348bebed2a9 (patch)
tree680f2ad7052437dacf6d1b1b5486e61b8ae203ea
parent2cf063ed5749f7393ad1b7a4e9d87cf46a9d2af4 (diff)
downloaddisplay-8186e1c05ed1d51c5f61f517b17e6348bebed2a9.tar.gz
samsung: support sysfs counter node for decon
Bug: 240346564 Test: Build for C10 or O6 device, cat /sys/class/drm/card0/device/decon0/decon_counters or same with decon2 device Merged-In: Ief68f59dc5207367c731b75bc7cf550dd7629280 Change-Id: Ief68f59dc5207367c731b75bc7cf550dd7629280 Signed-off-by: Taylor Nelms <tknelms@google.com>
-rw-r--r--samsung/exynos_drm_debug.c35
-rw-r--r--samsung/exynos_drm_decon.c14
-rw-r--r--samsung/exynos_drm_decon.h9
3 files changed, 57 insertions, 1 deletions
diff --git a/samsung/exynos_drm_debug.c b/samsung/exynos_drm_debug.c
index fbd50e2..5765e9b 100644
--- a/samsung/exynos_drm_debug.c
+++ b/samsung/exynos_drm_debug.c
@@ -16,6 +16,7 @@
#include <linux/ktime.h>
#include <linux/moduleparam.h>
#include <linux/pm_runtime.h>
+#include <linux/sysfs.h>
#include <linux/time.h>
#include <video/mipi_display.h>
#include <drm/drm_print.h>
@@ -1415,6 +1416,34 @@ err:
debugfs_remove_recursive(dent_dir);
}
+static ssize_t decon_counters_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ uint32_t underrun_cnt, crc_cnt, ecc_cnt, idma_err_cnt;
+ const struct decon_device *decon = to_decon_device(dev);
+
+ if (!decon)
+ return -ENODEV;
+
+ underrun_cnt = decon->d.underrun_cnt;
+ crc_cnt = decon->d.crc_cnt;
+ ecc_cnt = decon->d.ecc_cnt;
+ idma_err_cnt = decon->d.idma_err_cnt;
+
+ return snprintf(buf, PAGE_SIZE,
+ "underrun_cnt: %u\n"
+ "crc_cnt: %u\n"
+ "ecc_cnt: %u\n"
+ "idma_err_cnt: %u\n",
+ underrun_cnt, crc_cnt, ecc_cnt, idma_err_cnt);
+}
+
+static DEVICE_ATTR_RO(decon_counters);
+
+static const struct attribute *decon_debug_attrs[] = {
+ &dev_attr_decon_counters.attr,
+ NULL
+};
+
static int hibernation_show(struct seq_file *s, void *unused)
{
struct decon_device *decon = s->private;
@@ -1572,6 +1601,7 @@ int dpu_init_debug(struct decon_device *decon)
struct exynos_dqe *dqe = decon->dqe;
struct dentry *debug_event;
struct dentry *urgent_dent;
+ int ret;
decon->d.event_log = NULL;
event_cnt = dpu_event_log_max;
@@ -1617,6 +1647,11 @@ int dpu_init_debug(struct decon_device *decon)
goto err_debugfs;
}
+ /* Create sysfs nodes */
+ ret = sysfs_create_files(&decon->dev->kobj, decon_debug_attrs);
+ if (ret)
+ pr_warn("unable to add decon_debug sysfs files (%d)\n", ret);
+
debugfs_create_file("force_te_on", 0664, crtc->debugfs_entry, decon, &force_te_fops);
debugfs_create_u32("underrun_cnt", 0664, crtc->debugfs_entry, &decon->d.underrun_cnt);
debugfs_create_u32("crc_cnt", 0444, crtc->debugfs_entry, &decon->d.crc_cnt);
diff --git a/samsung/exynos_drm_decon.c b/samsung/exynos_drm_decon.c
index 22c1871..cfc2999 100644
--- a/samsung/exynos_drm_decon.c
+++ b/samsung/exynos_drm_decon.c
@@ -1547,6 +1547,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
struct exynos_drm_private *priv = drm_to_exynos_dev(drm_dev);
struct drm_plane *default_plane;
int i;
+ char symlink_name_buffer[7];
decon->drm_dev = drm_dev;
@@ -1591,6 +1592,11 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
decon->bts.ops->init(decon);
}
+ /* Create symlink to decon device */
+ snprintf(symlink_name_buffer, 7, "decon%d", decon->id);
+ sysfs_create_link(&decon->drm_dev->dev->kobj, &decon->dev->kobj,
+ (const char *) symlink_name_buffer);
+
device_create_file(dev, &dev_attr_early_wakeup);
decon_debug(decon, "%s -\n", __func__);
return 0;
@@ -1599,9 +1605,15 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
static void decon_unbind(struct device *dev, struct device *master,
void *data)
{
+ char symlink_name_buffer[7];
struct decon_device *decon = dev_get_drvdata(dev);
-
decon_debug(decon, "%s +\n", __func__);
+
+ /* Remove symlink to decon device */
+ snprintf(symlink_name_buffer, 7, "decon%d", decon->id);
+ sysfs_remove_link(&decon->drm_dev->dev->kobj,
+ (const char *) symlink_name_buffer);
+
device_remove_file(dev, &dev_attr_early_wakeup);
if (IS_ENABLED(CONFIG_EXYNOS_BTS))
decon->bts.ops->deinit(decon);
diff --git a/samsung/exynos_drm_decon.h b/samsung/exynos_drm_decon.h
index 69f707d..7e52f44 100644
--- a/samsung/exynos_drm_decon.h
+++ b/samsung/exynos_drm_decon.h
@@ -482,6 +482,15 @@ struct decon_device {
struct exynos_partial *partial;
};
+static inline struct decon_device *to_decon_device(const struct device *dev)
+{
+ /* could skip with dev_get_drvdata directly, but using pdev because
+ that's how drvdata was set originally */
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct decon_device *)platform_get_drvdata(pdev);
+}
+
extern struct dpu_bts_ops dpu_bts_control;
extern struct decon_device *decon_drvdata[MAX_DECON_CNT];