162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2011 Advanced Micro Devices, Inc.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1262306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_ci#ifndef __RV770_DPM_H__
2462306a36Sopenharmony_ci#define __RV770_DPM_H__
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include "radeon.h"
2762306a36Sopenharmony_ci#include "rv770_smc.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct rv770_clock_registers {
3062306a36Sopenharmony_ci	u32 cg_spll_func_cntl;
3162306a36Sopenharmony_ci	u32 cg_spll_func_cntl_2;
3262306a36Sopenharmony_ci	u32 cg_spll_func_cntl_3;
3362306a36Sopenharmony_ci	u32 cg_spll_spread_spectrum;
3462306a36Sopenharmony_ci	u32 cg_spll_spread_spectrum_2;
3562306a36Sopenharmony_ci	u32 mpll_ad_func_cntl;
3662306a36Sopenharmony_ci	u32 mpll_ad_func_cntl_2;
3762306a36Sopenharmony_ci	u32 mpll_dq_func_cntl;
3862306a36Sopenharmony_ci	u32 mpll_dq_func_cntl_2;
3962306a36Sopenharmony_ci	u32 mclk_pwrmgt_cntl;
4062306a36Sopenharmony_ci	u32 dll_cntl;
4162306a36Sopenharmony_ci	u32 mpll_ss1;
4262306a36Sopenharmony_ci	u32 mpll_ss2;
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct rv730_clock_registers {
4662306a36Sopenharmony_ci	u32 cg_spll_func_cntl;
4762306a36Sopenharmony_ci	u32 cg_spll_func_cntl_2;
4862306a36Sopenharmony_ci	u32 cg_spll_func_cntl_3;
4962306a36Sopenharmony_ci	u32 cg_spll_spread_spectrum;
5062306a36Sopenharmony_ci	u32 cg_spll_spread_spectrum_2;
5162306a36Sopenharmony_ci	u32 mclk_pwrmgt_cntl;
5262306a36Sopenharmony_ci	u32 dll_cntl;
5362306a36Sopenharmony_ci	u32 mpll_func_cntl;
5462306a36Sopenharmony_ci	u32 mpll_func_cntl2;
5562306a36Sopenharmony_ci	u32 mpll_func_cntl3;
5662306a36Sopenharmony_ci	u32 mpll_ss;
5762306a36Sopenharmony_ci	u32 mpll_ss2;
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciunion r7xx_clock_registers {
6162306a36Sopenharmony_ci	struct rv770_clock_registers rv770;
6262306a36Sopenharmony_ci	struct rv730_clock_registers rv730;
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistruct vddc_table_entry {
6662306a36Sopenharmony_ci	u16 vddc;
6762306a36Sopenharmony_ci	u8 vddc_index;
6862306a36Sopenharmony_ci	u8 high_smio;
6962306a36Sopenharmony_ci	u32 low_smio;
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci#define MAX_NO_OF_MVDD_VALUES 2
7362306a36Sopenharmony_ci#define MAX_NO_VREG_STEPS 32
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistruct rv7xx_power_info {
7662306a36Sopenharmony_ci	/* flags */
7762306a36Sopenharmony_ci	bool mem_gddr5;
7862306a36Sopenharmony_ci	bool pcie_gen2;
7962306a36Sopenharmony_ci	bool dynamic_pcie_gen2;
8062306a36Sopenharmony_ci	bool acpi_pcie_gen2;
8162306a36Sopenharmony_ci	bool boot_in_gen2;
8262306a36Sopenharmony_ci	bool voltage_control; /* vddc */
8362306a36Sopenharmony_ci	bool mvdd_control;
8462306a36Sopenharmony_ci	bool sclk_ss;
8562306a36Sopenharmony_ci	bool mclk_ss;
8662306a36Sopenharmony_ci	bool dynamic_ss;
8762306a36Sopenharmony_ci	bool gfx_clock_gating;
8862306a36Sopenharmony_ci	bool mg_clock_gating;
8962306a36Sopenharmony_ci	bool mgcgtssm;
9062306a36Sopenharmony_ci	bool power_gating;
9162306a36Sopenharmony_ci	bool thermal_protection;
9262306a36Sopenharmony_ci	bool display_gap;
9362306a36Sopenharmony_ci	bool dcodt;
9462306a36Sopenharmony_ci	bool ulps;
9562306a36Sopenharmony_ci	/* registers */
9662306a36Sopenharmony_ci	union r7xx_clock_registers clk_regs;
9762306a36Sopenharmony_ci	u32 s0_vid_lower_smio_cntl;
9862306a36Sopenharmony_ci	/* voltage */
9962306a36Sopenharmony_ci	u32 vddc_mask_low;
10062306a36Sopenharmony_ci	u32 mvdd_mask_low;
10162306a36Sopenharmony_ci	u32 mvdd_split_frequency;
10262306a36Sopenharmony_ci	u32 mvdd_low_smio[MAX_NO_OF_MVDD_VALUES];
10362306a36Sopenharmony_ci	u16 max_vddc;
10462306a36Sopenharmony_ci	u16 max_vddc_in_table;
10562306a36Sopenharmony_ci	u16 min_vddc_in_table;
10662306a36Sopenharmony_ci	struct vddc_table_entry vddc_table[MAX_NO_VREG_STEPS];
10762306a36Sopenharmony_ci	u8 valid_vddc_entries;
10862306a36Sopenharmony_ci	/* dc odt */
10962306a36Sopenharmony_ci	u32 mclk_odt_threshold;
11062306a36Sopenharmony_ci	u8 odt_value_0[2];
11162306a36Sopenharmony_ci	u8 odt_value_1[2];
11262306a36Sopenharmony_ci	/* stored values */
11362306a36Sopenharmony_ci	u32 boot_sclk;
11462306a36Sopenharmony_ci	u16 acpi_vddc;
11562306a36Sopenharmony_ci	u32 ref_div;
11662306a36Sopenharmony_ci	u32 active_auto_throttle_sources;
11762306a36Sopenharmony_ci	u32 mclk_stutter_mode_threshold;
11862306a36Sopenharmony_ci	u32 mclk_strobe_mode_threshold;
11962306a36Sopenharmony_ci	u32 mclk_edc_enable_threshold;
12062306a36Sopenharmony_ci	u32 bsp;
12162306a36Sopenharmony_ci	u32 bsu;
12262306a36Sopenharmony_ci	u32 pbsp;
12362306a36Sopenharmony_ci	u32 pbsu;
12462306a36Sopenharmony_ci	u32 dsp;
12562306a36Sopenharmony_ci	u32 psp;
12662306a36Sopenharmony_ci	u32 asi;
12762306a36Sopenharmony_ci	u32 pasi;
12862306a36Sopenharmony_ci	u32 vrc;
12962306a36Sopenharmony_ci	u32 restricted_levels;
13062306a36Sopenharmony_ci	u32 rlp;
13162306a36Sopenharmony_ci	u32 rmp;
13262306a36Sopenharmony_ci	u32 lhp;
13362306a36Sopenharmony_ci	u32 lmp;
13462306a36Sopenharmony_ci	/* smc offsets */
13562306a36Sopenharmony_ci	u16 state_table_start;
13662306a36Sopenharmony_ci	u16 soft_regs_start;
13762306a36Sopenharmony_ci	u16 sram_end;
13862306a36Sopenharmony_ci	/* scratch structs */
13962306a36Sopenharmony_ci	RV770_SMC_STATETABLE smc_statetable;
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistruct rv7xx_pl {
14362306a36Sopenharmony_ci	u32 sclk;
14462306a36Sopenharmony_ci	u32 mclk;
14562306a36Sopenharmony_ci	u16 vddc;
14662306a36Sopenharmony_ci	u16 vddci; /* eg+ only */
14762306a36Sopenharmony_ci	u32 flags;
14862306a36Sopenharmony_ci	enum radeon_pcie_gen pcie_gen; /* si+ only */
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistruct rv7xx_ps {
15262306a36Sopenharmony_ci	struct rv7xx_pl high;
15362306a36Sopenharmony_ci	struct rv7xx_pl medium;
15462306a36Sopenharmony_ci	struct rv7xx_pl low;
15562306a36Sopenharmony_ci	bool dc_compatible;
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci#define RV770_RLP_DFLT                                10
15962306a36Sopenharmony_ci#define RV770_RMP_DFLT                                25
16062306a36Sopenharmony_ci#define RV770_LHP_DFLT                                25
16162306a36Sopenharmony_ci#define RV770_LMP_DFLT                                10
16262306a36Sopenharmony_ci#define RV770_VRC_DFLT                                0x003f
16362306a36Sopenharmony_ci#define RV770_ASI_DFLT                                1000
16462306a36Sopenharmony_ci#define RV770_HASI_DFLT                               200000
16562306a36Sopenharmony_ci#define RV770_MGCGTTLOCAL0_DFLT                       0x00100000
16662306a36Sopenharmony_ci#define RV7XX_MGCGTTLOCAL0_DFLT                       0
16762306a36Sopenharmony_ci#define RV770_MGCGTTLOCAL1_DFLT                       0xFFFF0000
16862306a36Sopenharmony_ci#define RV770_MGCGCGTSSMCTRL_DFLT                     0x55940000
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci#define MVDD_LOW_INDEX  0
17162306a36Sopenharmony_ci#define MVDD_HIGH_INDEX 1
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci#define MVDD_LOW_VALUE  0
17462306a36Sopenharmony_ci#define MVDD_HIGH_VALUE 0xffff
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci#define RV770_DEFAULT_VCLK_FREQ  53300 /* 10 khz */
17762306a36Sopenharmony_ci#define RV770_DEFAULT_DCLK_FREQ  40000 /* 10 khz */
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/* rv730/rv710 */
18062306a36Sopenharmony_ciint rv730_populate_sclk_value(struct radeon_device *rdev,
18162306a36Sopenharmony_ci			      u32 engine_clock,
18262306a36Sopenharmony_ci			      RV770_SMC_SCLK_VALUE *sclk);
18362306a36Sopenharmony_ciint rv730_populate_mclk_value(struct radeon_device *rdev,
18462306a36Sopenharmony_ci			      u32 engine_clock, u32 memory_clock,
18562306a36Sopenharmony_ci			      LPRV7XX_SMC_MCLK_VALUE mclk);
18662306a36Sopenharmony_civoid rv730_read_clock_registers(struct radeon_device *rdev);
18762306a36Sopenharmony_ciint rv730_populate_smc_acpi_state(struct radeon_device *rdev,
18862306a36Sopenharmony_ci				  RV770_SMC_STATETABLE *table);
18962306a36Sopenharmony_ciint rv730_populate_smc_initial_state(struct radeon_device *rdev,
19062306a36Sopenharmony_ci				     struct radeon_ps *radeon_initial_state,
19162306a36Sopenharmony_ci				     RV770_SMC_STATETABLE *table);
19262306a36Sopenharmony_civoid rv730_program_memory_timing_parameters(struct radeon_device *rdev,
19362306a36Sopenharmony_ci					    struct radeon_ps *radeon_state);
19462306a36Sopenharmony_civoid rv730_power_gating_enable(struct radeon_device *rdev,
19562306a36Sopenharmony_ci			       bool enable);
19662306a36Sopenharmony_civoid rv730_start_dpm(struct radeon_device *rdev);
19762306a36Sopenharmony_civoid rv730_stop_dpm(struct radeon_device *rdev);
19862306a36Sopenharmony_civoid rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt);
19962306a36Sopenharmony_civoid rv730_get_odt_values(struct radeon_device *rdev);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/* rv740 */
20262306a36Sopenharmony_ciint rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock,
20362306a36Sopenharmony_ci			      RV770_SMC_SCLK_VALUE *sclk);
20462306a36Sopenharmony_ciint rv740_populate_mclk_value(struct radeon_device *rdev,
20562306a36Sopenharmony_ci			      u32 engine_clock, u32 memory_clock,
20662306a36Sopenharmony_ci			      RV7XX_SMC_MCLK_VALUE *mclk);
20762306a36Sopenharmony_civoid rv740_read_clock_registers(struct radeon_device *rdev);
20862306a36Sopenharmony_ciint rv740_populate_smc_acpi_state(struct radeon_device *rdev,
20962306a36Sopenharmony_ci				  RV770_SMC_STATETABLE *table);
21062306a36Sopenharmony_civoid rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev,
21162306a36Sopenharmony_ci				       bool enable);
21262306a36Sopenharmony_ciu8 rv740_get_mclk_frequency_ratio(u32 memory_clock);
21362306a36Sopenharmony_ciu32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock);
21462306a36Sopenharmony_ciu32 rv740_get_decoded_reference_divider(u32 encoded_ref);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci/* rv770 */
21762306a36Sopenharmony_ciu32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
21862306a36Sopenharmony_ciint rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
21962306a36Sopenharmony_ci			      RV770_SMC_VOLTAGE_VALUE *voltage);
22062306a36Sopenharmony_ciint rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
22162306a36Sopenharmony_ci			      RV770_SMC_VOLTAGE_VALUE *voltage);
22262306a36Sopenharmony_ciu8 rv770_get_seq_value(struct radeon_device *rdev,
22362306a36Sopenharmony_ci		       struct rv7xx_pl *pl);
22462306a36Sopenharmony_ciint rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
22562306a36Sopenharmony_ci				      RV770_SMC_VOLTAGE_VALUE *voltage);
22662306a36Sopenharmony_ciu32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
22762306a36Sopenharmony_ci					u32 engine_clock);
22862306a36Sopenharmony_civoid rv770_program_response_times(struct radeon_device *rdev);
22962306a36Sopenharmony_ciint rv770_populate_smc_sp(struct radeon_device *rdev,
23062306a36Sopenharmony_ci			  struct radeon_ps *radeon_state,
23162306a36Sopenharmony_ci			  RV770_SMC_SWSTATE *smc_state);
23262306a36Sopenharmony_ciint rv770_populate_smc_t(struct radeon_device *rdev,
23362306a36Sopenharmony_ci			 struct radeon_ps *radeon_state,
23462306a36Sopenharmony_ci			 RV770_SMC_SWSTATE *smc_state);
23562306a36Sopenharmony_civoid rv770_read_voltage_smio_registers(struct radeon_device *rdev);
23662306a36Sopenharmony_civoid rv770_get_memory_type(struct radeon_device *rdev);
23762306a36Sopenharmony_civoid r7xx_start_smc(struct radeon_device *rdev);
23862306a36Sopenharmony_ciu8 rv770_get_memory_module_index(struct radeon_device *rdev);
23962306a36Sopenharmony_civoid rv770_get_max_vddc(struct radeon_device *rdev);
24062306a36Sopenharmony_civoid rv770_get_pcie_gen2_status(struct radeon_device *rdev);
24162306a36Sopenharmony_civoid rv770_enable_acpi_pm(struct radeon_device *rdev);
24262306a36Sopenharmony_civoid rv770_restore_cgcg(struct radeon_device *rdev);
24362306a36Sopenharmony_cibool rv770_dpm_enabled(struct radeon_device *rdev);
24462306a36Sopenharmony_civoid rv770_enable_voltage_control(struct radeon_device *rdev,
24562306a36Sopenharmony_ci				  bool enable);
24662306a36Sopenharmony_civoid rv770_enable_backbias(struct radeon_device *rdev,
24762306a36Sopenharmony_ci			   bool enable);
24862306a36Sopenharmony_civoid rv770_enable_thermal_protection(struct radeon_device *rdev,
24962306a36Sopenharmony_ci				     bool enable);
25062306a36Sopenharmony_civoid rv770_enable_auto_throttle_source(struct radeon_device *rdev,
25162306a36Sopenharmony_ci				       enum radeon_dpm_auto_throttle_src source,
25262306a36Sopenharmony_ci				       bool enable);
25362306a36Sopenharmony_civoid rv770_setup_bsp(struct radeon_device *rdev);
25462306a36Sopenharmony_civoid rv770_program_git(struct radeon_device *rdev);
25562306a36Sopenharmony_civoid rv770_program_tp(struct radeon_device *rdev);
25662306a36Sopenharmony_civoid rv770_program_tpp(struct radeon_device *rdev);
25762306a36Sopenharmony_civoid rv770_program_sstp(struct radeon_device *rdev);
25862306a36Sopenharmony_civoid rv770_program_engine_speed_parameters(struct radeon_device *rdev);
25962306a36Sopenharmony_civoid rv770_program_vc(struct radeon_device *rdev);
26062306a36Sopenharmony_civoid rv770_clear_vc(struct radeon_device *rdev);
26162306a36Sopenharmony_ciint rv770_upload_firmware(struct radeon_device *rdev);
26262306a36Sopenharmony_civoid rv770_stop_dpm(struct radeon_device *rdev);
26362306a36Sopenharmony_civoid r7xx_stop_smc(struct radeon_device *rdev);
26462306a36Sopenharmony_civoid rv770_reset_smio_status(struct radeon_device *rdev);
26562306a36Sopenharmony_ciint rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev);
26662306a36Sopenharmony_ciint rv770_dpm_force_performance_level(struct radeon_device *rdev,
26762306a36Sopenharmony_ci				      enum radeon_dpm_forced_level level);
26862306a36Sopenharmony_ciint rv770_halt_smc(struct radeon_device *rdev);
26962306a36Sopenharmony_ciint rv770_resume_smc(struct radeon_device *rdev);
27062306a36Sopenharmony_ciint rv770_set_sw_state(struct radeon_device *rdev);
27162306a36Sopenharmony_ciint rv770_set_boot_state(struct radeon_device *rdev);
27262306a36Sopenharmony_ciint rv7xx_parse_power_table(struct radeon_device *rdev);
27362306a36Sopenharmony_civoid rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
27462306a36Sopenharmony_ci					      struct radeon_ps *new_ps,
27562306a36Sopenharmony_ci					      struct radeon_ps *old_ps);
27662306a36Sopenharmony_civoid rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
27762306a36Sopenharmony_ci					     struct radeon_ps *new_ps,
27862306a36Sopenharmony_ci					     struct radeon_ps *old_ps);
27962306a36Sopenharmony_civoid rv770_get_engine_memory_ss(struct radeon_device *rdev);
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci/* smc */
28262306a36Sopenharmony_ciint rv770_write_smc_soft_register(struct radeon_device *rdev,
28362306a36Sopenharmony_ci				  u16 reg_offset, u32 value);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci#endif
286