diff options
author | Eric Yang <Eric.Yang2@amd.com> | 2019-04-22 19:39:35 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-05-31 10:39:29 -0500 |
commit | dc88b4a684d284a200c0ecfd8d87179d6f6c89a3 (patch) | |
tree | 9703a3044486320eecac4ee174d54458d00bcf09 /drivers/gpu/drm/amd/display/dc/inc | |
parent | 789142eb8bae10ad17872f08b2bd08b8d24743ae (diff) | |
download | linux-dc88b4a684d284a200c0ecfd8d87179d6f6c89a3.tar.gz |
drm/amd/display: make clk mgr soc specific
[Why]
First step of refactoring clk mgr to better handle different
ways of handling clock operations. Clock operation policies are
soc specific and not just DCN vesion specific. It is not a hw resource,
should not be in the resource pool.
[How]
Change clock manager creation to be based on HW internal ID, rename
clock manager members to be more clear. Move clock manager out of
resource.
Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/inc')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h | 208 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/resource.h | 2 |
5 files changed, 233 insertions, 13 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 539d34d3439c..80709c9343c1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -82,7 +82,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); /********** DAL Core*********************/ -#include "hw/clk_mgr.h" #include "transform.h" #include "dpp.h" @@ -178,7 +177,6 @@ struct resource_pool { unsigned int audio_count; struct audio_support audio_support; - struct clk_mgr *clk_mgr; struct dccg *dccg; struct irq_service *irqs; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index 263c09630c06..806f3041db14 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -32,7 +32,7 @@ #include "bw_fixed.h" #include "../dml/display_mode_lib.h" -#include "hw/clk_mgr.h" + struct dc; struct dc_state; 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 f3fd3f8cac26..0a2346a009ad 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 @@ -26,17 +26,18 @@ #ifndef __DAL_CLK_MGR_H__ #define __DAL_CLK_MGR_H__ -#include "dm_services_types.h" #include "dc.h" -struct clk_mgr { - struct dc_context *ctx; - struct clk_mgr_funcs *funcs; - - struct dc_clocks clks; -}; +/* Public interfaces */ struct clk_mgr_funcs { + /* + * This function should set new clocks based on the input "safe_to_lower". + * If safe_to_lower == false, then only clocks which are to be increased + * should changed. + * If safe_to_lower == true, then only clocks which are to be decreased + * should be changed. + */ void (*update_clocks)(struct clk_mgr *clk_mgr, struct dc_state *context, bool safe_to_lower); @@ -45,11 +46,22 @@ struct clk_mgr_funcs { void (*init_clocks)(struct clk_mgr *clk_mgr); - /* Returns actual clk that's set */ - int (*set_dispclk)(struct clk_mgr *clk_mgr, int requested_dispclk_khz); - int (*set_dprefclk)(struct clk_mgr *clk_mgr); }; +void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr_base); + +struct clk_mgr { + struct dc_context *ctx; + struct clk_mgr_funcs *funcs; + struct dc_clocks clks; + int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes +}; + +/* forward declarations */ +struct dccg; + +struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); +void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr); #endif /* __DAL_CLK_MGR_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h new file mode 100644 index 000000000000..42f72c44e6f9 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -0,0 +1,208 @@ +/* + * Copyright 2018 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_CLK_MGR_INTERNAL_H__ +#define __DAL_CLK_MGR_INTERNAL_H__ + +#include "clk_mgr.h" + +/* + * only thing needed from here is MEMORY_TYPE_MULTIPLIER_CZ, which is also + * used in resource, perhaps this should be defined somewhere more common. + */ +#include "resource.h" + +/* + *************************************************************************************** + ****************** Clock Manager Private Macros and Defines *************************** + *************************************************************************************** + */ + +#define TO_CLK_MGR_INTERNAL(clk_mgr)\ + container_of(clk_mgr, struct clk_mgr_internal, base) + +#define CTX \ + clk_mgr->base.ctx +#define DC_LOGGER \ + clk_mgr->ctx->logger + + +#define CLK_BASE_INNER(inst) \ + CLK_BASE__INST ## inst ## _SEG0 + +#define CLK_BASE(inst) \ + CLK_BASE_INNER(inst) + +#define CLK_SRI(reg_name, block, inst)\ + .reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## _ ## inst ## _ ## reg_name + +#define CLK_COMMON_REG_LIST_DCE_BASE() \ + .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ + .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL + +#define CLK_COMMON_REG_LIST_DCN_BASE() \ + SR(DENTIST_DISPCLK_CNTL) + +#define CLK_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \ + CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) + +#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) + +#define CLK_MASK_SH_LIST_RV1(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_67, CONTENT, mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_83, CONTENT, mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_91, CONTENT, mask_sh), + + +#define CLK_REG_FIELD_LIST(type) \ + type DPREFCLK_SRC_SEL; \ + type DENTIST_DPREFCLK_WDIVIDER; \ + type DENTIST_DISPCLK_WDIVIDER; \ + type DENTIST_DISPCLK_CHG_DONE; + +/* + *************************************************************************************** + ****************** Clock Manager Private Structures *********************************** + *************************************************************************************** + */ + +struct clk_mgr_registers { + uint32_t DPREFCLK_CNTL; + uint32_t DENTIST_DISPCLK_CNTL; + +}; + +struct clk_mgr_shift { + CLK_REG_FIELD_LIST(uint8_t) +}; + +struct clk_mgr_mask { + CLK_REG_FIELD_LIST(uint32_t) +}; + + +struct state_dependent_clocks { + int display_clk_khz; + int pixel_clk_khz; +}; + +struct clk_mgr_internal { + struct clk_mgr base; + struct pp_smu_funcs *pp_smu; + struct clk_mgr_internal_funcs *funcs; + + struct dccg *dccg; + + /* + * For backwards compatbility with previous implementation + * TODO: remove these after everything transitions to new pattern + * Rationale is that clk registers change a lot across DCE versions + * and a shared data structure doesn't really make sense. + */ + const struct clk_mgr_registers *regs; + const struct clk_mgr_shift *clk_mgr_shift; + const struct clk_mgr_mask *clk_mgr_mask; + + struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; + + /*TODO: figure out which of the below fields should be here vs in asic specific portion */ + int dentist_vco_freq_khz; + + /* Cache the status of DFS-bypass feature*/ + bool dfs_bypass_enabled; + /* True if the DFS-bypass feature is enabled and active. */ + bool dfs_bypass_active; + /* + * Cache the display clock returned by VBIOS if DFS-bypass is enabled. + * This is basically "Crystal Frequency In KHz" (XTALIN) frequency + */ + int dfs_bypass_disp_clk; + + /** + * @ss_on_dprefclk: + * + * True if spread spectrum is enabled on the DP ref clock. + */ + bool ss_on_dprefclk; + + /** + * @xgmi_enabled: + * + * True if xGMI is enabled. On VG20, both audio and display clocks need + * to be adjusted with the WAFL link's SS info if xGMI is enabled. + */ + bool xgmi_enabled; + + /** + * @dprefclk_ss_percentage: + * + * DPREFCLK SS percentage (if down-spread enabled). + * + * Note that if XGMI is enabled, the SS info (percentage and divider) + * from the WAFL link is used instead. This is decided during + * dce_clk_mgr initialization. + */ + int dprefclk_ss_percentage; + + /** + * @dprefclk_ss_divider: + * + * DPREFCLK SS percentage Divider (100 or 1000). + */ + int dprefclk_ss_divider; + + enum dm_pp_clocks_state max_clks_state; + enum dm_pp_clocks_state cur_min_clks_state; +}; + +struct clk_mgr_internal_funcs { + int (*set_dispclk)(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz); + int (*set_dprefclk)(struct clk_mgr_internal *clk_mgr); +}; + + +/* + *************************************************************************************** + ****************** Clock Manager Level Helper functions ******************************* + *************************************************************************************** + */ + + +static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) +{ + return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); +} + + + +#endif //__DAL_CLK_MGR_INTERNAL_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 3ce0a4fc5822..08915b737799 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -30,6 +30,8 @@ #include "dal_asic_id.h" #include "dm_pp_smu.h" +#define MEMORY_TYPE_MULTIPLIER_CZ 4 + enum dce_version resource_parse_asic_id( struct hw_asic_id asic_id); |