brintos

brintos / linux-shallow public Read only

0
0
Text · 10.5 KiB · 2d06067 Raw
353 lines · c
1/*2 * Copyright 2012-16 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#ifndef __DAL_CLK_MGR_H__27#define __DAL_CLK_MGR_H__28 29#include "dc.h"30#include "dm_pp_smu.h"31 32/* Constants */33#define DDR4_DRAM_WIDTH   6434#define WM_A 035#define WM_B 136#define WM_C 237#define WM_D 338#define WM_SET_COUNT 439#define WM_1A 240#define WM_1B 341 42#define DCN_MINIMUM_DISPCLK_Khz 10000043#define DCN_MINIMUM_DPPCLK_Khz 10000044 45struct dcn3_clk_internal {46	int dummy;47//	TODO:48	uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk49	uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk50	uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk51	uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk52	uint32_t CLK1_CLK4_CURRENT_CNT;53	uint32_t CLK1_CLK3_DS_CNTL;	//dcf_deep_sleep_divider54	uint32_t CLK1_CLK3_ALLOW_DS;	//dcf_deep_sleep_allow55 56	uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass57	uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass58	uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass59	uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass60 61	uint32_t CLK4_CLK0_CURRENT_CNT; //fclk62};63 64struct dcn35_clk_internal {65	int dummy;66	uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk67	uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk68	uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk69	uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk70	uint32_t CLK1_CLK4_CURRENT_CNT; //dtbclk71	//uint32_t CLK1_CLK5_CURRENT_CNT; //dpiaclk72	//uint32_t CLK1_CLK6_CURRENT_CNT; //srdbgclk73	uint32_t CLK1_CLK3_DS_CNTL;	    //dcf_deep_sleep_divider74	uint32_t CLK1_CLK3_ALLOW_DS;	//dcf_deep_sleep_allow75 76	uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass77	uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass78	uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass79	uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass80	uint32_t CLK1_CLK4_BYPASS_CNTL; //dtbclk bypass81};82 83struct dcn301_clk_internal {84	int dummy;85	uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk86	uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk87	uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk88	uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk89	uint32_t CLK1_CLK3_DS_CNTL;	//dcf_deep_sleep_divider90	uint32_t CLK1_CLK3_ALLOW_DS;	//dcf_deep_sleep_allow91 92	uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass93	uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass94	uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass95	uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass96};97 98/* Will these bw structures be ASIC specific? */99 100#define MAX_NUM_DPM_LVL		8101#define WM_SET_COUNT 		4102 103 104struct clk_limit_table_entry {105	unsigned int voltage; /* milivolts withh 2 fractional bits */106	unsigned int dcfclk_mhz;107	unsigned int fclk_mhz;108	unsigned int memclk_mhz;109	unsigned int socclk_mhz;110	unsigned int dtbclk_mhz;111	unsigned int dispclk_mhz;112	unsigned int dppclk_mhz;113	unsigned int phyclk_mhz;114	unsigned int phyclk_d18_mhz;115	unsigned int wck_ratio;116};117 118struct clk_limit_num_entries {119	unsigned int num_dcfclk_levels;120	unsigned int num_fclk_levels;121	unsigned int num_memclk_levels;122	unsigned int num_socclk_levels;123	unsigned int num_dtbclk_levels;124	unsigned int num_dispclk_levels;125	unsigned int num_dppclk_levels;126	unsigned int num_phyclk_levels;127	unsigned int num_phyclk_d18_levels;128};129 130/* This table is contiguous */131struct clk_limit_table {132	struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];133	struct clk_limit_num_entries num_entries_per_clk;134	unsigned int num_entries; /* highest populated dpm level for back compatibility */135};136 137struct wm_range_table_entry {138	unsigned int wm_inst;139	unsigned int wm_type;140	double pstate_latency_us;141	double sr_exit_time_us;142	double sr_enter_plus_exit_time_us;143	bool valid;144};145 146struct nv_wm_range_entry {147	bool valid;148 149	struct {150		uint8_t wm_type;151		uint16_t min_dcfclk;152		uint16_t max_dcfclk;153		uint16_t min_uclk;154		uint16_t max_uclk;155	} pmfw_breakdown;156 157	struct {158		double pstate_latency_us;159		double sr_exit_time_us;160		double sr_enter_plus_exit_time_us;161		double fclk_change_latency_us;162	} dml_input;163};164 165struct clk_log_info {166	bool enabled;167	char *pBuf;168	unsigned int bufSize;169	unsigned int *sum_chars_printed;170};171 172struct clk_state_registers_and_bypass {173	uint32_t dcfclk;174	uint32_t dcf_deep_sleep_divider;175	uint32_t dcf_deep_sleep_allow;176	uint32_t dprefclk;177	uint32_t dispclk;178	uint32_t dppclk;179	uint32_t dtbclk;180	uint32_t fclk;181 182	uint32_t dppclk_bypass;183	uint32_t dcfclk_bypass;184	uint32_t dprefclk_bypass;185	uint32_t dispclk_bypass;186};187 188struct rv1_clk_internal {189	uint32_t CLK0_CLK8_CURRENT_CNT;  //dcfclk190	uint32_t CLK0_CLK8_DS_CNTL;		 //dcf_deep_sleep_divider191	uint32_t CLK0_CLK8_ALLOW_DS;	 //dcf_deep_sleep_allow192	uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk193	uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk194 195	uint32_t CLK0_CLK8_BYPASS_CNTL;  //dcfclk bypass196	uint32_t CLK0_CLK10_BYPASS_CNTL; //dprefclk bypass197	uint32_t CLK0_CLK11_BYPASS_CNTL; //dispclk bypass198};199 200struct rn_clk_internal {201	uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk202	uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk203	uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk204	uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk205	uint32_t CLK1_CLK3_DS_CNTL;		//dcf_deep_sleep_divider206	uint32_t CLK1_CLK3_ALLOW_DS;	//dcf_deep_sleep_allow207 208	uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass209	uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass210	uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass211	uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass212 213};214 215/* For dtn logging and debugging */216struct clk_state_registers {217		uint32_t CLK0_CLK8_CURRENT_CNT;  //dcfclk218		uint32_t CLK0_CLK8_DS_CNTL;		 //dcf_deep_sleep_divider219		uint32_t CLK0_CLK8_ALLOW_DS;	 //dcf_deep_sleep_allow220		uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk221		uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk222};223 224/* TODO: combine this with the above */225struct clk_bypass {226	uint32_t dcfclk_bypass;227	uint32_t dispclk_pypass;228	uint32_t dprefclk_bypass;229};230/*231 * This table is not contiguous, can have holes, each232 * entry correspond to one set of WM. For example if233 * we have 2 DPM and LPDDR, we will WM set A, B and234 * D occupied, C will be emptry.235 */236struct wm_table {237	union {238		struct nv_wm_range_entry nv_entries[WM_SET_COUNT];239		struct wm_range_table_entry entries[WM_SET_COUNT];240	};241};242 243struct dummy_pstate_entry {244	unsigned int dram_speed_mts;245	unsigned int dummy_pstate_latency_us;246};247 248struct clk_bw_params {249	unsigned int vram_type;250	unsigned int num_channels;251	unsigned int dram_channel_width_bytes;252	unsigned int dispclk_vco_khz;253	unsigned int dc_mode_softmax_memclk;254	unsigned int max_memclk_mhz;255	struct clk_limit_table clk_table;256	struct wm_table wm_table;257	struct dummy_pstate_entry dummy_pstate_table[4];258	struct clk_limit_table_entry dc_mode_limit;259};260/* Public interfaces */261 262struct clk_states {263	uint32_t dprefclk_khz;264};265 266struct clk_mgr_funcs {267	/*268	 * This function should set new clocks based on the input "safe_to_lower".269	 * If safe_to_lower == false, then only clocks which are to be increased270	 * should changed.271	 * If safe_to_lower == true, then only clocks which are to be decreased272	 * should be changed.273	 */274	void (*update_clocks)(struct clk_mgr *clk_mgr,275			struct dc_state *context,276			bool safe_to_lower);277 278	int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);279	int (*get_dtb_ref_clk_frequency)(struct clk_mgr *clk_mgr);280 281	void (*set_low_power_state)(struct clk_mgr *clk_mgr);282	void (*exit_low_power_state)(struct clk_mgr *clk_mgr);283	bool (*is_ips_supported)(struct clk_mgr *clk_mgr);284 285	void (*init_clocks)(struct clk_mgr *clk_mgr);286 287	void (*dump_clk_registers)(struct clk_state_registers_and_bypass *regs_and_bypass,288			struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info);289 290	void (*enable_pme_wa) (struct clk_mgr *clk_mgr);291	void (*get_clock)(struct clk_mgr *clk_mgr,292			struct dc_state *context,293			enum dc_clock_type clock_type,294			struct dc_clock_config *clock_cfg);295 296	bool (*are_clock_states_equal) (struct dc_clocks *a,297			struct dc_clocks *b);298	void (*notify_wm_ranges)(struct clk_mgr *clk_mgr);299 300	/* Notify clk_mgr of a change in link rate, update phyclk frequency if necessary */301	void (*notify_link_rate_change)(struct clk_mgr *clk_mgr, struct dc_link *link);302	/*303	 * Send message to PMFW to set hard min memclk frequency304	 * When current_mode = false, set DPM0305	 * When current_mode = true, set required clock for current mode306	 */307	void (*set_hard_min_memclk)(struct clk_mgr *clk_mgr, bool current_mode);308 309	/* Send message to PMFW to set hard max memclk frequency to highest DPM */310	void (*set_hard_max_memclk)(struct clk_mgr *clk_mgr);311 312	/* Custom set a memclk freq range*/313	void (*set_max_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz);314	void (*set_min_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz);315 316	/* Get current memclk states from PMFW, update relevant structures */317	void (*get_memclk_states_from_smu)(struct clk_mgr *clk_mgr);318 319	/* Get SMU present */320	bool (*is_smu_present)(struct clk_mgr *clk_mgr);321 322	int (*get_dispclk_from_dentist)(struct clk_mgr *clk_mgr_base);323 324};325 326struct clk_mgr {327	struct dc_context *ctx;328	struct clk_mgr_funcs *funcs;329	struct dc_clocks clks;330	bool psr_allow_active_cache;331	bool force_smu_not_present;332	bool dc_mode_softmax_enabled;333	int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes334	int dp_dto_source_clock_in_khz; // Used to program DP DTO with ss adjustment on DCN314335	int dentist_vco_freq_khz;336	struct clk_state_registers_and_bypass boot_snapshot;337	struct clk_bw_params *bw_params;338	struct pp_smu_wm_range_sets ranges;339};340 341/* forward declarations */342struct dccg;343 344struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg);345 346void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr);347 348void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr);349 350void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr);351 352#endif /* __DAL_CLK_MGR_H__ */353