From: Charlene Liu <charlene....@amd.com>

add dc_set_clock
add dc_get_clock

this is for testing and diagnostics to get/set DPPCLK and DISPCLK.

Signed-off-by: Charlene Liu <charlene....@amd.com>
Reviewed-by: Dmytro Laktyushkin <dmytro.laktyush...@amd.com>
Acked-by: Leo Li <sunpeng...@amd.com>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 23 +++++++-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h  |  5 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 11 ++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  5 ++
 drivers/gpu/drm/amd/display/dc/dc_types.h     | 13 +++++
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 53 ++++++++++++++++++-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  5 ++
 .../gpu/drm/amd/display/dc/inc/core_status.h  |  3 ++
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |  7 +++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  9 ++++
 10 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index e9a7a7af11df..9a873e2b3736 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -316,11 +316,32 @@ void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base)
        }
 }
 
+void dcn2_get_clock(struct clk_mgr *clk_mgr,
+               struct dc_state *context,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg)
+{
+
+       if (clock_type == DC_CLOCK_TYPE_DISPCLK) {
+               clock_cfg->max_clock_khz = 
context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz;
+               clock_cfg->min_clock_khz = DCN_MINIMUM_DISPCLK_Khz;
+               clock_cfg->current_clock_khz = clk_mgr->clks.dispclk_khz;
+               clock_cfg->bw_requirequired_clock_khz = 
context->bw_ctx.bw.dcn.clk.bw_dispclk_khz;
+       }
+       if (clock_type == DC_CLOCK_TYPE_DPPCLK) {
+               clock_cfg->max_clock_khz = 
context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
+               clock_cfg->min_clock_khz = DCN_MINIMUM_DPPCLK_Khz;
+               clock_cfg->current_clock_khz = clk_mgr->clks.dppclk_khz;
+               clock_cfg->bw_requirequired_clock_khz = 
context->bw_ctx.bw.dcn.clk.bw_dppclk_khz;
+       }
+}
+
 static struct clk_mgr_funcs dcn2_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .update_clocks = dcn2_update_clocks,
        .init_clocks = dcn2_init_clocks,
-       .enable_pme_wa = dcn2_enable_pme_wa
+       .enable_pme_wa = dcn2_enable_pme_wa,
+       .get_clock = dcn2_get_clock,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
index 5661a5a89847..ac31a9787305 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
@@ -45,4 +45,9 @@ void dcn20_clk_mgr_construct(struct dc_context *ctx,
 
 uint32_t dentist_get_did_from_divider(int divider);
 
+void dcn2_get_clock(struct clk_mgr *clk_mgr,
+               struct dc_state *context,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg);
+
 #endif //__DCN20_CLK_MGR_H__
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index b57e4550e73f..b2004b3056af 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2429,3 +2429,14 @@ void get_clock_requirements_for_state(struct dc_state 
*state, struct AsicStateEx
        info->fClock                                    = (unsigned 
int)state->bw_ctx.bw.dcn.clk.fclk_khz;
        info->phyClock                                  = (unsigned 
int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
 }
+enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, 
uint32_t clk_khz, uint32_t stepping)
+{
+       if (dc->hwss.set_clock)
+               return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
+       return DC_ERROR_UNEXPECTED;
+}
+void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct 
dc_clock_config *clock_cfg)
+{
+       if (dc->hwss.get_clock)
+               dc->hwss.get_clock(dc, clock_type, clock_cfg);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index b314fd2869dd..a5b5afd48a7b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -252,7 +252,10 @@ enum wm_report_mode {
 struct dc_clocks {
        int dispclk_khz;
        int max_supported_dppclk_khz;
+       int max_supported_dispclk_khz;
        int dppclk_khz;
+       int bw_dppclk_khz; /*a copy of dppclk_khz*/
+       int bw_dispclk_khz;
        int dcfclk_khz;
        int socclk_khz;
        int dcfclk_deep_sleep_khz;
@@ -1041,6 +1044,8 @@ unsigned int dc_get_target_backlight_pwm(struct dc *dc);
 
 bool dc_is_dmcu_initialized(struct dc *dc);
 
+enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, 
uint32_t clk_khz, uint32_t stepping);
+void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct 
dc_clock_config *clock_cfg);
 #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
 
/*******************************************************************************
  * DSC Interfaces
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index ce6d73d21cca..b273735b6a3e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -726,6 +726,19 @@ struct AsicStateEx {
        unsigned int phyClock;
 };
 
+
+enum dc_clock_type {
+       DC_CLOCK_TYPE_DISPCLK = 0,
+       DC_CLOCK_TYPE_DPPCLK        = 1,
+};
+
+struct dc_clock_config {
+       uint32_t max_clock_khz;
+       uint32_t min_clock_khz;
+       uint32_t bw_requirequired_clock_khz;
+       uint32_t current_clock_khz;/*current clock in use*/
+};
+
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 /* DSC DPCD capabilities */
 union dsc_slice_caps1 {
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 c22fc1568184..58d118a3ee8e 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
@@ -3068,6 +3068,56 @@ static void dcn10_send_immediate_sdp_message(struct 
pipe_ctx *pipe_ctx,
                                sdp_message_size);
        }
 }
+static enum dc_status dcn10_set_clock(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       uint32_t clk_khz,
+                       uint32_t stepping)
+{
+       struct dc_state *context = dc->current_state;
+       struct dc_clock_config clock_cfg = {0};
+       struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+                               dc->clk_mgr->funcs->get_clock(dc->clk_mgr,
+                                               context, clock_type, 
&clock_cfg);
+
+       if (!dc->clk_mgr->funcs->get_clock)
+               return DC_FAIL_UNSUPPORTED_1;
+
+       if (clk_khz > clock_cfg.max_clock_khz)
+               return DC_FAIL_CLK_EXCEED_MAX;
+
+       if (clk_khz < clock_cfg.min_clock_khz)
+               return DC_FAIL_CLK_BELOW_MIN;
+
+       if (clk_khz < clock_cfg.bw_requirequired_clock_khz)
+               return DC_FAIL_CLK_BELOW_CFG_REQUIRED;
+
+       /*update internal request clock for update clock use*/
+       if (clock_type == DC_CLOCK_TYPE_DISPCLK)
+               current_clocks->dispclk_khz = clk_khz;
+       else if (clock_type == DC_CLOCK_TYPE_DPPCLK)
+               current_clocks->dppclk_khz = clk_khz;
+       else
+               return DC_ERROR_UNEXPECTED;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks)
+                               dc->clk_mgr->funcs->update_clocks(dc->clk_mgr,
+                               context, true);
+       return DC_OK;
+
+}
+
+static void dcn10_get_clock(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg)
+{
+       struct dc_state *context = dc->current_state;
+
+       if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+                               dc->clk_mgr->funcs->get_clock(dc->clk_mgr, 
context, clock_type, clock_cfg);
+
+}
 
 static const struct hw_sequencer_funcs dcn10_funcs = {
        .program_gamut_remap = program_gamut_remap,
@@ -3122,7 +3172,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .enable_stream_gating = NULL,
        .setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
        .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
-       .did_underflow_occur = dcn10_did_underflow_occur
+       .set_clock = dcn10_set_clock,
+       .get_clock = dcn10_get_clock,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 022d0f38723b..158743b165e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2396,6 +2396,11 @@ void dcn20_calculate_dlg_params(
                context->res_ctx.pipe_ctx[i].pipe_dlg_param = 
pipes[pipe_idx].pipe.dest;
                pipe_idx++;
        }
+       /*save a original dppclock copy*/
+       context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = 
context->bw_ctx.bw.dcn.clk.dppclk_khz;
+       context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = 
context->bw_ctx.bw.dcn.clk.dispclk_khz;
+       context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = 
context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz*1000;
+       context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = 
context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz*1000;
 
        for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
                bool cstate_en = 
context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
 != 2;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h 
b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
index 0a094d7c9380..fd39e2abe2ed 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
@@ -48,6 +48,9 @@ enum dc_status {
        DC_NO_DSC_RESOURCE = 17,
 #endif
        DC_FAIL_UNSUPPORTED_1 = 18,
+       DC_FAIL_CLK_EXCEED_MAX = 21,
+       DC_FAIL_CLK_BELOW_MIN = 22, /*THIS IS MIN PER IP*/
+       DC_FAIL_CLK_BELOW_CFG_REQUIRED = 23, /*THIS IS hard_min in PPLIB*/
 
        DC_ERROR_UNEXPECTED = -1
 };
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index 36ebd5bc7863..938bdc5c21a1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -28,6 +28,9 @@
 
 #include "dc.h"
 
+#define DCN_MINIMUM_DISPCLK_Khz 100000
+#define DCN_MINIMUM_DPPCLK_Khz 100000
+
 /* Public interfaces */
 
 struct clk_states {
@@ -51,6 +54,10 @@ struct clk_mgr_funcs {
        void (*init_clocks)(struct clk_mgr *clk_mgr);
 
        void (*enable_pme_wa) (struct clk_mgr *clk_mgr);
+       void (*get_clock)(struct clk_mgr *clk_mgr,
+                       struct dc_state *context,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg);
 };
 
 struct clk_mgr {
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 4d56d48a3179..36be08adae05 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -294,6 +294,15 @@ struct hw_sequencer_funcs {
        void (*disable_writeback)(struct dc *dc,
                        unsigned int dwb_pipe_inst);
 #endif
+       enum dc_status (*set_clock)(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       uint32_t clk_khz,
+                       uint32_t stepping);
+
+       void (*get_clock)(struct dc *dc,
+                       enum dc_clock_type clock_type,
+                       struct dc_clock_config *clock_cfg);
+
 };
 
 void color_space_to_black_color(
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to