From 712343cd21ea709ba63869f74246466524172ad4 Mon Sep 17 00:00:00 2001 From: Victor Lu Date: Wed, 22 Jul 2020 16:16:48 -0400 Subject: [PATCH] drm/amd/display: Add function and debugfs to dump DCC_EN bit [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 Reviewed-by: Harry Wentland Acked-by: Qingqing Zhuo Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 66 +++++++++++++++++++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 16 +++++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 4 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 3 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 3 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c | 3 +- .../drm/amd/display/dc/dcn301/dcn301_init.c | 3 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 + 9 files changed, 96 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 32f05aefda17..4a95d02ce933 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -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); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index e1f33f908b5b..7c939c0a977b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -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; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index ff1ce200432f..37bec421fde8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -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__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index 254300b06b43..d532c78ee764 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -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 = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index 7218ed9e43dc..b5bb613eed4d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -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 = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index 074e2713257f..4f20a85ff396 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -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 = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index c4c14e9c1309..bf7fa98b39eb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -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 = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c index bdad72140cbc..0d90523c7cdc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -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 = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 1a6366a6da1d..1d5853c95448 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -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); -- 2.20.1