drm/amd/display: Add function and debugfs to dump DCC_EN bit
authorVictor Lu <victorchengchi.lu@amd.com>
Wed, 22 Jul 2020 20:16:48 +0000 (16:16 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 9 Apr 2021 20:52:03 +0000 (16:52 -0400)
[why]
Currently to view the DCC_EN bit the entire DTN log
must be dumped. A compact method to view the DCC_EN
bit is desirable.

[how]
Introduce new debugfs interface that only dumps the
DCC_EN bit.

Example usage:
cat /sys/kernel/debug/dri/0/amdgpu_dm_dcc_en

Signed-off-by: Victor Lu <victorchengchi.lu@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index 32f05ae..4a95d02 100644 (file)
@@ -3043,6 +3043,64 @@ DEFINE_SHOW_ATTRIBUTE(mst_topo);
 DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
                         visual_confirm_set, "%llu\n");
 
+/*
+ * Dumps the DCC_EN bit for each pipe.
+ * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dcc_en
+ */
+static ssize_t dcc_en_bits_read(
+       struct file *f,
+       char __user *buf,
+       size_t size,
+       loff_t *pos)
+{
+       struct amdgpu_device *adev = file_inode(f)->i_private;
+       struct dc *dc = adev->dm.dc;
+       char *rd_buf = NULL;
+       const uint32_t rd_buf_size = 32;
+       uint32_t result = 0;
+       int offset = 0;
+       int num_pipes = dc->res_pool->pipe_count;
+       int *dcc_en_bits;
+       int i, r;
+
+       dcc_en_bits = kcalloc(num_pipes, sizeof(int), GFP_KERNEL);
+       if (!dcc_en_bits)
+               return -ENOMEM;
+
+       if (!dc->hwss.get_dcc_en_bits) {
+               kfree(dcc_en_bits);
+               return 0;
+       }
+
+       dc->hwss.get_dcc_en_bits(dc, dcc_en_bits);
+
+       rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
+       if (!rd_buf)
+               return -ENOMEM;
+
+       for (i = 0; i < num_pipes; i++)
+               offset += snprintf(rd_buf + offset, rd_buf_size - offset,
+                                  "%d  ", dcc_en_bits[i]);
+       rd_buf[strlen(rd_buf)] = '\n';
+
+       kfree(dcc_en_bits);
+
+       while (size) {
+               if (*pos >= rd_buf_size)
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+               if (r)
+                       return r; /* r = -EFAULT */
+               buf += 1;
+               size -= 1;
+               *pos += 1;
+               result += 1;
+       }
+
+       kfree(rd_buf);
+       return result;
+}
+
 void dtn_debugfs_init(struct amdgpu_device *adev)
 {
        static const struct file_operations dtn_log_fops = {
@@ -3051,6 +3109,11 @@ void dtn_debugfs_init(struct amdgpu_device *adev)
                .write = dtn_log_write,
                .llseek = default_llseek
        };
+       static const struct file_operations dcc_en_bits_fops = {
+               .owner = THIS_MODULE,
+               .read = dcc_en_bits_read,
+               .llseek = default_llseek
+       };
 
        struct drm_minor *minor = adev_to_drm(adev)->primary;
        struct dentry *root = minor->debugfs_root;
@@ -3078,4 +3141,7 @@ void dtn_debugfs_init(struct amdgpu_device *adev)
 
        debugfs_create_file_unsafe("amdgpu_dm_dmcub_trace_event_en", 0644, root,
                                   adev, &dmcub_trace_event_state_fops);
+
+       debugfs_create_file_unsafe("amdgpu_dm_dcc_en", 0644, root, adev,
+                                  &dcc_en_bits_fops);
 }
index e1f33f9..7c939c0 100644 (file)
@@ -3979,3 +3979,19 @@ void dcn10_get_clock(struct dc *dc,
                                dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);
 
 }
+
+void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits)
+{
+       struct resource_pool *pool = dc->res_pool;
+       int i;
+
+       for (i = 0; i < pool->pipe_count; i++) {
+               struct hubp *hubp = pool->hubps[i];
+               struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
+
+               hubp->funcs->hubp_read_state(hubp);
+
+               if (!s->blank_en)
+                       dcc_en_bits[i] = s->dcc_en ? 1 : 0;
+       }
+}
index ff1ce20..37bec42 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright 2016 Advanced Micro Devices, Inc.
+* Copyright 2016-2020 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -209,4 +209,6 @@ void dcn10_wait_for_pending_cleared(struct dc *dc,
 void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx);
 void dcn10_verify_allow_pstate_change_high(struct dc *dc);
 
+void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits);
+
 #endif /* __DC_HWSS_DCN10_H__ */
index 254300b..d532c78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Advanced Micro Devices, Inc.
+ * Copyright 2016-2020 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -79,6 +79,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
        .set_pipe = dce110_set_pipe,
+       .get_dcc_en_bits = dcn10_get_dcc_en_bits,
 };
 
 static const struct hwseq_private_funcs dcn10_private_funcs = {
index 7218ed9..b5bb613 100644 (file)
@@ -95,6 +95,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
        .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
 #endif
        .set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
+       .get_dcc_en_bits = dcn10_get_dcc_en_bits,
 };
 
 static const struct hwseq_private_funcs dcn20_private_funcs = {
index 074e271..4f20a85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Advanced Micro Devices, Inc.
+ * Copyright 2016-2020 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -99,6 +99,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
 #endif
        .is_abm_supported = dcn21_is_abm_supported,
        .set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
+       .get_dcc_en_bits = dcn10_get_dcc_en_bits,
 };
 
 static const struct hwseq_private_funcs dcn21_private_funcs = {
index c4c14e9..bf7fa98 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2016-2020 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
        .hardware_release = dcn30_hardware_release,
        .set_pipe = dcn21_set_pipe,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
+       .get_dcc_en_bits = dcn10_get_dcc_en_bits,
 };
 
 static const struct hwseq_private_funcs dcn30_private_funcs = {
index bdad721..0d90523 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2016-2020 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .set_pipe = dcn21_set_pipe,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
+       .get_dcc_en_bits = dcn10_get_dcc_en_bits,
 };
 
 static const struct hwseq_private_funcs dcn301_private_funcs = {
index 1a6366a..1d5853c 100644 (file)
@@ -217,6 +217,8 @@ struct hw_sequencer_funcs {
 
        void (*set_pipe)(struct pipe_ctx *pipe_ctx);
 
+       void (*get_dcc_en_bits)(struct dc *dc, int *dcc_en_bits);
+
        /* Idle Optimization Related */
        bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable);