cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clk_mgr_internal.h (10177B)


      1/*
      2 * Copyright 2018 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#ifndef __DAL_CLK_MGR_INTERNAL_H__
     27#define __DAL_CLK_MGR_INTERNAL_H__
     28
     29#include "clk_mgr.h"
     30#include "dc.h"
     31
     32/*
     33 * only thing needed from here is MEMORY_TYPE_MULTIPLIER_CZ, which is also
     34 * used in resource, perhaps this should be defined somewhere more common.
     35 */
     36#include "resource.h"
     37
     38
     39/* Starting DID for each range */
     40enum dentist_base_divider_id {
     41	DENTIST_BASE_DID_1 = 0x08,
     42	DENTIST_BASE_DID_2 = 0x40,
     43	DENTIST_BASE_DID_3 = 0x60,
     44	DENTIST_BASE_DID_4 = 0x7e,
     45	DENTIST_MAX_DID = 0x7f
     46};
     47
     48/* Starting point and step size for each divider range.*/
     49enum dentist_divider_range {
     50	DENTIST_DIVIDER_RANGE_1_START = 8,   /* 2.00  */
     51	DENTIST_DIVIDER_RANGE_1_STEP  = 1,   /* 0.25  */
     52	DENTIST_DIVIDER_RANGE_2_START = 64,  /* 16.00 */
     53	DENTIST_DIVIDER_RANGE_2_STEP  = 2,   /* 0.50  */
     54	DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */
     55	DENTIST_DIVIDER_RANGE_3_STEP  = 4,   /* 1.00  */
     56	DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */
     57	DENTIST_DIVIDER_RANGE_4_STEP  = 264, /* 66.00 */
     58	DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4
     59};
     60
     61/*
     62 ***************************************************************************************
     63 ****************** Clock Manager Private Macros and Defines ***************************
     64 ***************************************************************************************
     65 */
     66
     67/* Macros */
     68
     69#define TO_CLK_MGR_INTERNAL(clk_mgr)\
     70	container_of(clk_mgr, struct clk_mgr_internal, base)
     71
     72#define CTX \
     73	clk_mgr->base.ctx
     74
     75#define DC_LOGGER \
     76	clk_mgr->base.ctx->logger
     77
     78
     79
     80
     81#define CLK_BASE(inst) \
     82	CLK_BASE_INNER(inst)
     83
     84#define CLK_SRI(reg_name, block, inst)\
     85	.reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \
     86					mm ## block ## _ ## inst ## _ ## reg_name
     87
     88#define CLK_COMMON_REG_LIST_DCE_BASE() \
     89	.DPREFCLK_CNTL = mmDPREFCLK_CNTL, \
     90	.DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL
     91
     92#if defined(CONFIG_DRM_AMD_DC_SI)
     93#define CLK_COMMON_REG_LIST_DCE60_BASE() \
     94	SR(DENTIST_DISPCLK_CNTL)
     95#endif
     96
     97#define CLK_COMMON_REG_LIST_DCN_BASE() \
     98	SR(DENTIST_DISPCLK_CNTL)
     99
    100#define VBIOS_SMU_MSG_BOX_REG_LIST_RV() \
    101	.MP1_SMN_C2PMSG_91 = mmMP1_SMN_C2PMSG_91, \
    102	.MP1_SMN_C2PMSG_83 = mmMP1_SMN_C2PMSG_83, \
    103	.MP1_SMN_C2PMSG_67 = mmMP1_SMN_C2PMSG_67
    104
    105#define CLK_COMMON_REG_LIST_DCN_201() \
    106	SR(DENTIST_DISPCLK_CNTL), \
    107	CLK_SRI(CLK4_CLK_PLL_REQ, CLK4, 0), \
    108	CLK_SRI(CLK4_CLK2_CURRENT_CNT, CLK4, 0)
    109
    110#define CLK_REG_LIST_NV10() \
    111	SR(DENTIST_DISPCLK_CNTL), \
    112	CLK_SRI(CLK3_CLK_PLL_REQ, CLK3, 0), \
    113	CLK_SRI(CLK3_CLK2_DFS_CNTL, CLK3, 0)
    114
    115// TODO:
    116#define CLK_REG_LIST_DCN3()	  \
    117	SR(DENTIST_DISPCLK_CNTL)
    118
    119#define CLK_SF(reg_name, field_name, post_fix)\
    120	.field_name = reg_name ## __ ## field_name ## post_fix
    121
    122#define CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
    123	CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \
    124	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh)
    125
    126#if defined(CONFIG_DRM_AMD_DC_SI)
    127#define CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(mask_sh) \
    128	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
    129	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
    130#endif
    131
    132#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \
    133	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
    134	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
    135
    136#define CLK_MASK_SH_LIST_RV1(mask_sh) \
    137	CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\
    138	CLK_SF(MP1_SMN_C2PMSG_67, CONTENT, mask_sh),\
    139	CLK_SF(MP1_SMN_C2PMSG_83, CONTENT, mask_sh),\
    140	CLK_SF(MP1_SMN_C2PMSG_91, CONTENT, mask_sh),
    141
    142#define CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh) \
    143	CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\
    144	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\
    145	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh)
    146
    147#define CLK_MASK_SH_LIST_NV10(mask_sh) \
    148	CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\
    149	CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_int, mask_sh),\
    150	CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_frac, mask_sh)
    151
    152#define CLK_COMMON_MASK_SH_LIST_DCN201_BASE(mask_sh) \
    153	CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\
    154	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\
    155	CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh),\
    156	CLK_SF(CLK4_0_CLK4_CLK_PLL_REQ, FbMult_int, mask_sh)
    157
    158#define CLK_REG_FIELD_LIST(type) \
    159	type DPREFCLK_SRC_SEL; \
    160	type DENTIST_DPREFCLK_WDIVIDER; \
    161	type DENTIST_DISPCLK_WDIVIDER; \
    162	type DENTIST_DISPCLK_CHG_DONE;
    163
    164/*
    165 ***************************************************************************************
    166 ****************** Clock Manager Private Structures ***********************************
    167 ***************************************************************************************
    168 */
    169#define CLK20_REG_FIELD_LIST(type) \
    170	type DENTIST_DPPCLK_WDIVIDER; \
    171	type DENTIST_DPPCLK_CHG_DONE; \
    172	type FbMult_int; \
    173	type FbMult_frac;
    174
    175#define VBIOS_SMU_REG_FIELD_LIST(type) \
    176	type CONTENT;
    177
    178struct clk_mgr_shift {
    179	CLK_REG_FIELD_LIST(uint8_t)
    180	CLK20_REG_FIELD_LIST(uint8_t)
    181	VBIOS_SMU_REG_FIELD_LIST(uint32_t)
    182};
    183
    184struct clk_mgr_mask {
    185	CLK_REG_FIELD_LIST(uint32_t)
    186	CLK20_REG_FIELD_LIST(uint32_t)
    187	VBIOS_SMU_REG_FIELD_LIST(uint32_t)
    188};
    189
    190struct clk_mgr_registers {
    191	uint32_t DPREFCLK_CNTL;
    192	uint32_t DENTIST_DISPCLK_CNTL;
    193	uint32_t CLK4_CLK2_CURRENT_CNT;
    194	uint32_t CLK4_CLK_PLL_REQ;
    195
    196	uint32_t CLK3_CLK2_DFS_CNTL;
    197	uint32_t CLK3_CLK_PLL_REQ;
    198
    199	uint32_t CLK0_CLK2_DFS_CNTL;
    200	uint32_t CLK0_CLK_PLL_REQ;
    201
    202	uint32_t MP1_SMN_C2PMSG_67;
    203	uint32_t MP1_SMN_C2PMSG_83;
    204	uint32_t MP1_SMN_C2PMSG_91;
    205};
    206
    207enum clock_type {
    208	clock_type_dispclk = 1,
    209	clock_type_dcfclk,
    210	clock_type_socclk,
    211	clock_type_pixelclk,
    212	clock_type_phyclk,
    213	clock_type_dppclk,
    214	clock_type_fclk,
    215	clock_type_dcfdsclk,
    216	clock_type_dscclk,
    217	clock_type_uclk,
    218	clock_type_dramclk,
    219};
    220
    221
    222struct state_dependent_clocks {
    223	int display_clk_khz;
    224	int pixel_clk_khz;
    225};
    226
    227struct clk_mgr_internal {
    228	struct clk_mgr base;
    229	int smu_ver;
    230	struct pp_smu_funcs *pp_smu;
    231	struct clk_mgr_internal_funcs *funcs;
    232
    233	struct dccg *dccg;
    234
    235	/*
    236	 * For backwards compatbility with previous implementation
    237	 * TODO: remove these after everything transitions to new pattern
    238	 * Rationale is that clk registers change a lot across DCE versions
    239	 * and a shared data structure doesn't really make sense.
    240	 */
    241	const struct clk_mgr_registers *regs;
    242	const struct clk_mgr_shift *clk_mgr_shift;
    243	const struct clk_mgr_mask *clk_mgr_mask;
    244
    245	struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES];
    246
    247	/*TODO: figure out which of the below fields should be here vs in asic specific portion */
    248	/* Cache the status of DFS-bypass feature*/
    249	bool dfs_bypass_enabled;
    250	/* True if the DFS-bypass feature is enabled and active. */
    251	bool dfs_bypass_active;
    252
    253	uint32_t dfs_ref_freq_khz;
    254	/*
    255	 * Cache the display clock returned by VBIOS if DFS-bypass is enabled.
    256	 * This is basically "Crystal Frequency In KHz" (XTALIN) frequency
    257	 */
    258	int dfs_bypass_disp_clk;
    259
    260	/**
    261	 * @ss_on_dprefclk:
    262	 *
    263	 * True if spread spectrum is enabled on the DP ref clock.
    264	 */
    265	bool ss_on_dprefclk;
    266
    267	/**
    268	 * @xgmi_enabled:
    269	 *
    270	 * True if xGMI is enabled. On VG20, both audio and display clocks need
    271	 * to be adjusted with the WAFL link's SS info if xGMI is enabled.
    272	 */
    273	bool xgmi_enabled;
    274
    275	/**
    276	 * @dprefclk_ss_percentage:
    277	 *
    278	 * DPREFCLK SS percentage (if down-spread enabled).
    279	 *
    280	 * Note that if XGMI is enabled, the SS info (percentage and divider)
    281	 * from the WAFL link is used instead. This is decided during
    282	 * dce_clk_mgr initialization.
    283	 */
    284	int dprefclk_ss_percentage;
    285
    286	/**
    287	 * @dprefclk_ss_divider:
    288	 *
    289	 * DPREFCLK SS percentage Divider (100 or 1000).
    290	 */
    291	int dprefclk_ss_divider;
    292
    293	enum dm_pp_clocks_state max_clks_state;
    294	enum dm_pp_clocks_state cur_min_clks_state;
    295	bool periodic_retraining_disabled;
    296
    297	unsigned int cur_phyclk_req_table[MAX_PIPES * 2];
    298
    299	bool smu_present;
    300	void *wm_range_table;
    301	long long wm_range_table_addr;
    302};
    303
    304struct clk_mgr_internal_funcs {
    305	int (*set_dispclk)(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
    306	int (*set_dprefclk)(struct clk_mgr_internal *clk_mgr);
    307};
    308
    309
    310/*
    311 ***************************************************************************************
    312 ****************** Clock Manager Level Helper functions *******************************
    313 ***************************************************************************************
    314 */
    315
    316
    317static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk)
    318{
    319	return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk);
    320}
    321
    322static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support)
    323{
    324	if (cur_support != calc_support) {
    325		if (calc_support && safe_to_lower)
    326			return true;
    327		else if (!calc_support && !safe_to_lower)
    328			return true;
    329	}
    330
    331	return false;
    332}
    333
    334static inline int khz_to_mhz_ceil(int khz)
    335{
    336	return (khz + 999) / 1000;
    337}
    338
    339int clk_mgr_helper_get_active_display_cnt(
    340		struct dc *dc,
    341		struct dc_state *context);
    342
    343int clk_mgr_helper_get_active_plane_cnt(
    344		struct dc *dc,
    345		struct dc_state *context);
    346
    347
    348
    349#endif //__DAL_CLK_MGR_INTERNAL_H__