1*57e252bfSMichael Neumann /* 2*57e252bfSMichael Neumann * Copyright 2011 Advanced Micro Devices, Inc. 3*57e252bfSMichael Neumann * 4*57e252bfSMichael Neumann * Permission is hereby granted, free of charge, to any person obtaining a 5*57e252bfSMichael Neumann * copy of this software and associated documentation files (the "Software"), 6*57e252bfSMichael Neumann * to deal in the Software without restriction, including without limitation 7*57e252bfSMichael Neumann * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*57e252bfSMichael Neumann * and/or sell copies of the Software, and to permit persons to whom the 9*57e252bfSMichael Neumann * Software is furnished to do so, subject to the following conditions: 10*57e252bfSMichael Neumann * 11*57e252bfSMichael Neumann * The above copyright notice and this permission notice shall be included in 12*57e252bfSMichael Neumann * all copies or substantial portions of the Software. 13*57e252bfSMichael Neumann * 14*57e252bfSMichael Neumann * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*57e252bfSMichael Neumann * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*57e252bfSMichael Neumann * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*57e252bfSMichael Neumann * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*57e252bfSMichael Neumann * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*57e252bfSMichael Neumann * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*57e252bfSMichael Neumann * OTHER DEALINGS IN THE SOFTWARE. 21*57e252bfSMichael Neumann * 22*57e252bfSMichael Neumann */ 23*57e252bfSMichael Neumann #ifndef __RV770_DPM_H__ 24*57e252bfSMichael Neumann #define __RV770_DPM_H__ 25*57e252bfSMichael Neumann 26*57e252bfSMichael Neumann #include "rv770_smc.h" 27*57e252bfSMichael Neumann 28*57e252bfSMichael Neumann struct rv770_clock_registers { 29*57e252bfSMichael Neumann u32 cg_spll_func_cntl; 30*57e252bfSMichael Neumann u32 cg_spll_func_cntl_2; 31*57e252bfSMichael Neumann u32 cg_spll_func_cntl_3; 32*57e252bfSMichael Neumann u32 cg_spll_spread_spectrum; 33*57e252bfSMichael Neumann u32 cg_spll_spread_spectrum_2; 34*57e252bfSMichael Neumann u32 mpll_ad_func_cntl; 35*57e252bfSMichael Neumann u32 mpll_ad_func_cntl_2; 36*57e252bfSMichael Neumann u32 mpll_dq_func_cntl; 37*57e252bfSMichael Neumann u32 mpll_dq_func_cntl_2; 38*57e252bfSMichael Neumann u32 mclk_pwrmgt_cntl; 39*57e252bfSMichael Neumann u32 dll_cntl; 40*57e252bfSMichael Neumann u32 mpll_ss1; 41*57e252bfSMichael Neumann u32 mpll_ss2; 42*57e252bfSMichael Neumann }; 43*57e252bfSMichael Neumann 44*57e252bfSMichael Neumann struct rv730_clock_registers { 45*57e252bfSMichael Neumann u32 cg_spll_func_cntl; 46*57e252bfSMichael Neumann u32 cg_spll_func_cntl_2; 47*57e252bfSMichael Neumann u32 cg_spll_func_cntl_3; 48*57e252bfSMichael Neumann u32 cg_spll_spread_spectrum; 49*57e252bfSMichael Neumann u32 cg_spll_spread_spectrum_2; 50*57e252bfSMichael Neumann u32 mclk_pwrmgt_cntl; 51*57e252bfSMichael Neumann u32 dll_cntl; 52*57e252bfSMichael Neumann u32 mpll_func_cntl; 53*57e252bfSMichael Neumann u32 mpll_func_cntl2; 54*57e252bfSMichael Neumann u32 mpll_func_cntl3; 55*57e252bfSMichael Neumann u32 mpll_ss; 56*57e252bfSMichael Neumann u32 mpll_ss2; 57*57e252bfSMichael Neumann }; 58*57e252bfSMichael Neumann 59*57e252bfSMichael Neumann union r7xx_clock_registers { 60*57e252bfSMichael Neumann struct rv770_clock_registers rv770; 61*57e252bfSMichael Neumann struct rv730_clock_registers rv730; 62*57e252bfSMichael Neumann }; 63*57e252bfSMichael Neumann 64*57e252bfSMichael Neumann struct vddc_table_entry { 65*57e252bfSMichael Neumann u16 vddc; 66*57e252bfSMichael Neumann u8 vddc_index; 67*57e252bfSMichael Neumann u8 high_smio; 68*57e252bfSMichael Neumann u32 low_smio; 69*57e252bfSMichael Neumann }; 70*57e252bfSMichael Neumann 71*57e252bfSMichael Neumann #define MAX_NO_OF_MVDD_VALUES 2 72*57e252bfSMichael Neumann #define MAX_NO_VREG_STEPS 32 73*57e252bfSMichael Neumann 74*57e252bfSMichael Neumann struct rv7xx_power_info { 75*57e252bfSMichael Neumann /* flags */ 76*57e252bfSMichael Neumann bool mem_gddr5; 77*57e252bfSMichael Neumann bool pcie_gen2; 78*57e252bfSMichael Neumann bool dynamic_pcie_gen2; 79*57e252bfSMichael Neumann bool acpi_pcie_gen2; 80*57e252bfSMichael Neumann bool boot_in_gen2; 81*57e252bfSMichael Neumann bool voltage_control; /* vddc */ 82*57e252bfSMichael Neumann bool mvdd_control; 83*57e252bfSMichael Neumann bool sclk_ss; 84*57e252bfSMichael Neumann bool mclk_ss; 85*57e252bfSMichael Neumann bool dynamic_ss; 86*57e252bfSMichael Neumann bool gfx_clock_gating; 87*57e252bfSMichael Neumann bool mg_clock_gating; 88*57e252bfSMichael Neumann bool mgcgtssm; 89*57e252bfSMichael Neumann bool power_gating; 90*57e252bfSMichael Neumann bool thermal_protection; 91*57e252bfSMichael Neumann bool display_gap; 92*57e252bfSMichael Neumann bool dcodt; 93*57e252bfSMichael Neumann bool ulps; 94*57e252bfSMichael Neumann /* registers */ 95*57e252bfSMichael Neumann union r7xx_clock_registers clk_regs; 96*57e252bfSMichael Neumann u32 s0_vid_lower_smio_cntl; 97*57e252bfSMichael Neumann /* voltage */ 98*57e252bfSMichael Neumann u32 vddc_mask_low; 99*57e252bfSMichael Neumann u32 mvdd_mask_low; 100*57e252bfSMichael Neumann u32 mvdd_split_frequency; 101*57e252bfSMichael Neumann u32 mvdd_low_smio[MAX_NO_OF_MVDD_VALUES]; 102*57e252bfSMichael Neumann u16 max_vddc; 103*57e252bfSMichael Neumann u16 max_vddc_in_table; 104*57e252bfSMichael Neumann u16 min_vddc_in_table; 105*57e252bfSMichael Neumann struct vddc_table_entry vddc_table[MAX_NO_VREG_STEPS]; 106*57e252bfSMichael Neumann u8 valid_vddc_entries; 107*57e252bfSMichael Neumann /* dc odt */ 108*57e252bfSMichael Neumann u32 mclk_odt_threshold; 109*57e252bfSMichael Neumann u8 odt_value_0[2]; 110*57e252bfSMichael Neumann u8 odt_value_1[2]; 111*57e252bfSMichael Neumann /* stored values */ 112*57e252bfSMichael Neumann u32 boot_sclk; 113*57e252bfSMichael Neumann u16 acpi_vddc; 114*57e252bfSMichael Neumann u32 ref_div; 115*57e252bfSMichael Neumann u32 active_auto_throttle_sources; 116*57e252bfSMichael Neumann u32 mclk_stutter_mode_threshold; 117*57e252bfSMichael Neumann u32 mclk_strobe_mode_threshold; 118*57e252bfSMichael Neumann u32 mclk_edc_enable_threshold; 119*57e252bfSMichael Neumann u32 bsp; 120*57e252bfSMichael Neumann u32 bsu; 121*57e252bfSMichael Neumann u32 pbsp; 122*57e252bfSMichael Neumann u32 pbsu; 123*57e252bfSMichael Neumann u32 dsp; 124*57e252bfSMichael Neumann u32 psp; 125*57e252bfSMichael Neumann u32 asi; 126*57e252bfSMichael Neumann u32 pasi; 127*57e252bfSMichael Neumann u32 vrc; 128*57e252bfSMichael Neumann u32 restricted_levels; 129*57e252bfSMichael Neumann u32 rlp; 130*57e252bfSMichael Neumann u32 rmp; 131*57e252bfSMichael Neumann u32 lhp; 132*57e252bfSMichael Neumann u32 lmp; 133*57e252bfSMichael Neumann /* smc offsets */ 134*57e252bfSMichael Neumann u16 state_table_start; 135*57e252bfSMichael Neumann u16 soft_regs_start; 136*57e252bfSMichael Neumann u16 sram_end; 137*57e252bfSMichael Neumann /* scratch structs */ 138*57e252bfSMichael Neumann RV770_SMC_STATETABLE smc_statetable; 139*57e252bfSMichael Neumann }; 140*57e252bfSMichael Neumann 141*57e252bfSMichael Neumann struct rv7xx_pl { 142*57e252bfSMichael Neumann u32 sclk; 143*57e252bfSMichael Neumann u32 mclk; 144*57e252bfSMichael Neumann u16 vddc; 145*57e252bfSMichael Neumann u16 vddci; /* eg+ only */ 146*57e252bfSMichael Neumann u32 flags; 147*57e252bfSMichael Neumann enum radeon_pcie_gen pcie_gen; /* si+ only */ 148*57e252bfSMichael Neumann }; 149*57e252bfSMichael Neumann 150*57e252bfSMichael Neumann struct rv7xx_ps { 151*57e252bfSMichael Neumann struct rv7xx_pl high; 152*57e252bfSMichael Neumann struct rv7xx_pl medium; 153*57e252bfSMichael Neumann struct rv7xx_pl low; 154*57e252bfSMichael Neumann bool dc_compatible; 155*57e252bfSMichael Neumann }; 156*57e252bfSMichael Neumann 157*57e252bfSMichael Neumann #define RV770_RLP_DFLT 10 158*57e252bfSMichael Neumann #define RV770_RMP_DFLT 25 159*57e252bfSMichael Neumann #define RV770_LHP_DFLT 25 160*57e252bfSMichael Neumann #define RV770_LMP_DFLT 10 161*57e252bfSMichael Neumann #define RV770_VRC_DFLT 0x003f 162*57e252bfSMichael Neumann #define RV770_ASI_DFLT 1000 163*57e252bfSMichael Neumann #define RV770_HASI_DFLT 200000 164*57e252bfSMichael Neumann #define RV770_MGCGTTLOCAL0_DFLT 0x00100000 165*57e252bfSMichael Neumann #define RV7XX_MGCGTTLOCAL0_DFLT 0 166*57e252bfSMichael Neumann #define RV770_MGCGTTLOCAL1_DFLT 0xFFFF0000 167*57e252bfSMichael Neumann #define RV770_MGCGCGTSSMCTRL_DFLT 0x55940000 168*57e252bfSMichael Neumann 169*57e252bfSMichael Neumann #define MVDD_LOW_INDEX 0 170*57e252bfSMichael Neumann #define MVDD_HIGH_INDEX 1 171*57e252bfSMichael Neumann 172*57e252bfSMichael Neumann #define MVDD_LOW_VALUE 0 173*57e252bfSMichael Neumann #define MVDD_HIGH_VALUE 0xffff 174*57e252bfSMichael Neumann 175*57e252bfSMichael Neumann #define RV770_DEFAULT_VCLK_FREQ 53300 /* 10 khz */ 176*57e252bfSMichael Neumann #define RV770_DEFAULT_DCLK_FREQ 40000 /* 10 khz */ 177*57e252bfSMichael Neumann 178*57e252bfSMichael Neumann /* rv730/rv710 */ 179*57e252bfSMichael Neumann int rv730_populate_sclk_value(struct radeon_device *rdev, 180*57e252bfSMichael Neumann u32 engine_clock, 181*57e252bfSMichael Neumann RV770_SMC_SCLK_VALUE *sclk); 182*57e252bfSMichael Neumann int rv730_populate_mclk_value(struct radeon_device *rdev, 183*57e252bfSMichael Neumann u32 engine_clock, u32 memory_clock, 184*57e252bfSMichael Neumann LPRV7XX_SMC_MCLK_VALUE mclk); 185*57e252bfSMichael Neumann void rv730_read_clock_registers(struct radeon_device *rdev); 186*57e252bfSMichael Neumann int rv730_populate_smc_acpi_state(struct radeon_device *rdev, 187*57e252bfSMichael Neumann RV770_SMC_STATETABLE *table); 188*57e252bfSMichael Neumann int rv730_populate_smc_initial_state(struct radeon_device *rdev, 189*57e252bfSMichael Neumann struct radeon_ps *radeon_initial_state, 190*57e252bfSMichael Neumann RV770_SMC_STATETABLE *table); 191*57e252bfSMichael Neumann void rv730_program_memory_timing_parameters(struct radeon_device *rdev, 192*57e252bfSMichael Neumann struct radeon_ps *radeon_state); 193*57e252bfSMichael Neumann void rv730_power_gating_enable(struct radeon_device *rdev, 194*57e252bfSMichael Neumann bool enable); 195*57e252bfSMichael Neumann void rv730_start_dpm(struct radeon_device *rdev); 196*57e252bfSMichael Neumann void rv730_stop_dpm(struct radeon_device *rdev); 197*57e252bfSMichael Neumann void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt); 198*57e252bfSMichael Neumann void rv730_get_odt_values(struct radeon_device *rdev); 199*57e252bfSMichael Neumann 200*57e252bfSMichael Neumann /* rv740 */ 201*57e252bfSMichael Neumann int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock, 202*57e252bfSMichael Neumann RV770_SMC_SCLK_VALUE *sclk); 203*57e252bfSMichael Neumann int rv740_populate_mclk_value(struct radeon_device *rdev, 204*57e252bfSMichael Neumann u32 engine_clock, u32 memory_clock, 205*57e252bfSMichael Neumann RV7XX_SMC_MCLK_VALUE *mclk); 206*57e252bfSMichael Neumann void rv740_read_clock_registers(struct radeon_device *rdev); 207*57e252bfSMichael Neumann int rv740_populate_smc_acpi_state(struct radeon_device *rdev, 208*57e252bfSMichael Neumann RV770_SMC_STATETABLE *table); 209*57e252bfSMichael Neumann void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev, 210*57e252bfSMichael Neumann bool enable); 211*57e252bfSMichael Neumann u8 rv740_get_mclk_frequency_ratio(u32 memory_clock); 212*57e252bfSMichael Neumann u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock); 213*57e252bfSMichael Neumann u32 rv740_get_decoded_reference_divider(u32 encoded_ref); 214*57e252bfSMichael Neumann 215*57e252bfSMichael Neumann /* rv770 */ 216*57e252bfSMichael Neumann u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf); 217*57e252bfSMichael Neumann int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc, 218*57e252bfSMichael Neumann RV770_SMC_VOLTAGE_VALUE *voltage); 219*57e252bfSMichael Neumann int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk, 220*57e252bfSMichael Neumann RV770_SMC_VOLTAGE_VALUE *voltage); 221*57e252bfSMichael Neumann u8 rv770_get_seq_value(struct radeon_device *rdev, 222*57e252bfSMichael Neumann struct rv7xx_pl *pl); 223*57e252bfSMichael Neumann int rv770_populate_initial_mvdd_value(struct radeon_device *rdev, 224*57e252bfSMichael Neumann RV770_SMC_VOLTAGE_VALUE *voltage); 225*57e252bfSMichael Neumann u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev, 226*57e252bfSMichael Neumann u32 engine_clock); 227*57e252bfSMichael Neumann void rv770_program_response_times(struct radeon_device *rdev); 228*57e252bfSMichael Neumann int rv770_populate_smc_sp(struct radeon_device *rdev, 229*57e252bfSMichael Neumann struct radeon_ps *radeon_state, 230*57e252bfSMichael Neumann RV770_SMC_SWSTATE *smc_state); 231*57e252bfSMichael Neumann int rv770_populate_smc_t(struct radeon_device *rdev, 232*57e252bfSMichael Neumann struct radeon_ps *radeon_state, 233*57e252bfSMichael Neumann RV770_SMC_SWSTATE *smc_state); 234*57e252bfSMichael Neumann void rv770_read_voltage_smio_registers(struct radeon_device *rdev); 235*57e252bfSMichael Neumann void rv770_get_memory_type(struct radeon_device *rdev); 236*57e252bfSMichael Neumann void r7xx_start_smc(struct radeon_device *rdev); 237*57e252bfSMichael Neumann u8 rv770_get_memory_module_index(struct radeon_device *rdev); 238*57e252bfSMichael Neumann void rv770_get_max_vddc(struct radeon_device *rdev); 239*57e252bfSMichael Neumann void rv770_get_pcie_gen2_status(struct radeon_device *rdev); 240*57e252bfSMichael Neumann void rv770_enable_acpi_pm(struct radeon_device *rdev); 241*57e252bfSMichael Neumann void rv770_restore_cgcg(struct radeon_device *rdev); 242*57e252bfSMichael Neumann bool rv770_dpm_enabled(struct radeon_device *rdev); 243*57e252bfSMichael Neumann void rv770_enable_voltage_control(struct radeon_device *rdev, 244*57e252bfSMichael Neumann bool enable); 245*57e252bfSMichael Neumann void rv770_enable_backbias(struct radeon_device *rdev, 246*57e252bfSMichael Neumann bool enable); 247*57e252bfSMichael Neumann void rv770_enable_thermal_protection(struct radeon_device *rdev, 248*57e252bfSMichael Neumann bool enable); 249*57e252bfSMichael Neumann void rv770_enable_auto_throttle_source(struct radeon_device *rdev, 250*57e252bfSMichael Neumann enum radeon_dpm_auto_throttle_src source, 251*57e252bfSMichael Neumann bool enable); 252*57e252bfSMichael Neumann void rv770_setup_bsp(struct radeon_device *rdev); 253*57e252bfSMichael Neumann void rv770_program_git(struct radeon_device *rdev); 254*57e252bfSMichael Neumann void rv770_program_tp(struct radeon_device *rdev); 255*57e252bfSMichael Neumann void rv770_program_tpp(struct radeon_device *rdev); 256*57e252bfSMichael Neumann void rv770_program_sstp(struct radeon_device *rdev); 257*57e252bfSMichael Neumann void rv770_program_engine_speed_parameters(struct radeon_device *rdev); 258*57e252bfSMichael Neumann void rv770_program_vc(struct radeon_device *rdev); 259*57e252bfSMichael Neumann void rv770_clear_vc(struct radeon_device *rdev); 260*57e252bfSMichael Neumann int rv770_upload_firmware(struct radeon_device *rdev); 261*57e252bfSMichael Neumann void rv770_stop_dpm(struct radeon_device *rdev); 262*57e252bfSMichael Neumann void r7xx_stop_smc(struct radeon_device *rdev); 263*57e252bfSMichael Neumann void rv770_reset_smio_status(struct radeon_device *rdev); 264*57e252bfSMichael Neumann int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev); 265*57e252bfSMichael Neumann int rv770_dpm_force_performance_level(struct radeon_device *rdev, 266*57e252bfSMichael Neumann enum radeon_dpm_forced_level level); 267*57e252bfSMichael Neumann int rv770_halt_smc(struct radeon_device *rdev); 268*57e252bfSMichael Neumann int rv770_resume_smc(struct radeon_device *rdev); 269*57e252bfSMichael Neumann int rv770_set_sw_state(struct radeon_device *rdev); 270*57e252bfSMichael Neumann int rv770_set_boot_state(struct radeon_device *rdev); 271*57e252bfSMichael Neumann int rv7xx_parse_power_table(struct radeon_device *rdev); 272*57e252bfSMichael Neumann void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev, 273*57e252bfSMichael Neumann struct radeon_ps *new_ps, 274*57e252bfSMichael Neumann struct radeon_ps *old_ps); 275*57e252bfSMichael Neumann void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, 276*57e252bfSMichael Neumann struct radeon_ps *new_ps, 277*57e252bfSMichael Neumann struct radeon_ps *old_ps); 278*57e252bfSMichael Neumann void rv770_get_engine_memory_ss(struct radeon_device *rdev); 279*57e252bfSMichael Neumann 280*57e252bfSMichael Neumann /* smc */ 281*57e252bfSMichael Neumann int rv770_write_smc_soft_register(struct radeon_device *rdev, 282*57e252bfSMichael Neumann u16 reg_offset, u32 value); 283*57e252bfSMichael Neumann 284*57e252bfSMichael Neumann #endif 285