]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/display: add set and get clock for testing purposes
authorCharlene Liu <charlene.liu@amd.com>
Thu, 27 Jun 2019 22:16:21 +0000 (18:16 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 18 Jul 2019 19:27:25 +0000 (14:27 -0500)
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.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/inc/core_status.h
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index e9a7a7af11dfbcc4389013a197d68ab352e2e072..9a873e2b373628676656b20d9536d4f58df646ee 100644 (file)
@@ -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,
 };
 
 
index 5661a5a89847ca5480b259828f4ff8463a5e71af..ac31a9787305b2d8dab55712213279911382536c 100644 (file)
@@ -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__
index a8516deb5ac3864bf114d347993f168388ce6f16..c86c86c07fd9f013443774b44fc30ce0d962d785 100644 (file)
@@ -2431,3 +2431,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);
+}
index b314fd2869ddc8d199cf05944e8c447cb2cbf053..a5b5afd48a7bf283ea3b8c1cb8b678cc147aa51a 100644 (file)
@@ -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
index ce6d73d21ccae0106854fa2f25b4a91e636cbe07..b273735b6a3ece1855484bc745280978391cfe6d 100644 (file)
@@ -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 {
index 89c958f00e9ab8ec0a9d2f55d98349e106349cf9..29db9b2d4412a3b01897eec1e21aec4e95c3bf60 100644 (file)
@@ -3069,6 +3069,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,
@@ -3123,7 +3173,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,
 };
 
 
index ae2545fb8eceaeaf65f0d58bd31b1d668080a941..6ff779256729c8352971597ffb67fe163b823ee8 100644 (file)
@@ -2398,6 +2398,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;
index 0a094d7c93805049284e9e9146737311a92cc7d3..fd39e2abe2ed652ac43a058b48acd3857bff7f85 100644 (file)
@@ -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
 };
index 36ebd5bc7863b75c883a1b00bde5954646e17d41..938bdc5c21a10cbe7a0c0b7cfb5af93035bd92a2 100644 (file)
@@ -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 {
index 4d56d48a317936c567d4ebf95b4ed8c2006b8c9e..36be08adae0502da2921476e618a06a1914e179f 100644 (file)
@@ -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(