Commit 69e0b57a authored by Alex Deucher's avatar Alex Deucher

drm/radeon/kms: add dpm support for cayman (v5)

This adds dpm support for cayman asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching (requires additional acpi support)
- power containment
- shader power scaling

Set radeon.dpm=1 to enable.

v2: fold in tdp fix
v3: fix indentation
v4: fix 64 bit div
v5: attempt to fix state enable
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
parent d22b7e40
...@@ -79,7 +79,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ ...@@ -79,7 +79,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
trinity_smc.o trinity_smc.o ni_dpm.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
......
...@@ -1152,7 +1152,7 @@ static const u32 turks_sysls_enable[] = ...@@ -1152,7 +1152,7 @@ static const u32 turks_sysls_enable[] =
#endif #endif
u32 btc_valid_sclk[] = u32 btc_valid_sclk[40] =
{ {
5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000,
55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000,
...@@ -1168,8 +1168,8 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = ...@@ -1168,8 +1168,8 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
{ 25000, 30000, RADEON_SCLK_UP } { 25000, 30000, RADEON_SCLK_UP }
}; };
static void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
u32 clock, u16 max_voltage, u16 *voltage) u32 clock, u16 max_voltage, u16 *voltage)
{ {
u32 i; u32 i;
...@@ -1219,9 +1219,9 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev, ...@@ -1219,9 +1219,9 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
max_sclk, requested_sclk); max_sclk, requested_sclk);
} }
static void btc_skip_blacklist_clocks(struct radeon_device *rdev, void btc_skip_blacklist_clocks(struct radeon_device *rdev,
const u32 max_sclk, const u32 max_mclk, const u32 max_sclk, const u32 max_mclk,
u32 *sclk, u32 *mclk) u32 *sclk, u32 *mclk)
{ {
int i, num_blacklist_clocks; int i, num_blacklist_clocks;
...@@ -1246,9 +1246,9 @@ static void btc_skip_blacklist_clocks(struct radeon_device *rdev, ...@@ -1246,9 +1246,9 @@ static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
} }
} }
static void btc_adjust_clock_combinations(struct radeon_device *rdev, void btc_adjust_clock_combinations(struct radeon_device *rdev,
const struct radeon_clock_and_voltage_limits *max_limits, const struct radeon_clock_and_voltage_limits *max_limits,
struct rv7xx_pl *pl) struct rv7xx_pl *pl)
{ {
if ((pl->mclk == 0) || (pl->sclk == 0)) if ((pl->mclk == 0) || (pl->sclk == 0))
...@@ -1285,9 +1285,9 @@ static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage) ...@@ -1285,9 +1285,9 @@ static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
return table->entries[table->count - 1].value; return table->entries[table->count - 1].value;
} }
static void btc_apply_voltage_delta_rules(struct radeon_device *rdev, void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
u16 max_vddc, u16 max_vddci, u16 max_vddc, u16 max_vddci,
u16 *vddc, u16 *vddci) u16 *vddc, u16 *vddci)
{ {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
u16 new_voltage; u16 new_voltage;
...@@ -1417,8 +1417,8 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev, ...@@ -1417,8 +1417,8 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
return ret; return ret;
} }
static void btc_program_mgcg_hw_sequence(struct radeon_device *rdev, void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
const u32 *sequence, u32 count) const u32 *sequence, u32 count)
{ {
u32 i, length = count * 3; u32 i, length = count * 3;
u32 tmp; u32 tmp;
...@@ -1596,7 +1596,7 @@ static void btc_ls_clock_gating_enable(struct radeon_device *rdev, ...@@ -1596,7 +1596,7 @@ static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
btc_program_mgcg_hw_sequence(rdev, p, count); btc_program_mgcg_hw_sequence(rdev, p, count);
} }
static bool btc_dpm_enabled(struct radeon_device *rdev) bool btc_dpm_enabled(struct radeon_device *rdev)
{ {
if (rv770_is_smc_running(rdev)) if (rv770_is_smc_running(rdev))
return true; return true;
...@@ -1692,7 +1692,7 @@ static void btc_set_at_for_uvd(struct radeon_device *rdev) ...@@ -1692,7 +1692,7 @@ static void btc_set_at_for_uvd(struct radeon_device *rdev)
} }
static void btc_notify_uvd_to_smc(struct radeon_device *rdev) void btc_notify_uvd_to_smc(struct radeon_device *rdev)
{ {
struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
...@@ -1708,7 +1708,7 @@ static void btc_notify_uvd_to_smc(struct radeon_device *rdev) ...@@ -1708,7 +1708,7 @@ static void btc_notify_uvd_to_smc(struct radeon_device *rdev)
} }
} }
static int btc_reset_to_default(struct radeon_device *rdev) int btc_reset_to_default(struct radeon_device *rdev)
{ {
if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK) if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
return -EINVAL; return -EINVAL;
...@@ -1730,7 +1730,7 @@ static void btc_stop_smc(struct radeon_device *rdev) ...@@ -1730,7 +1730,7 @@ static void btc_stop_smc(struct radeon_device *rdev)
r7xx_stop_smc(rdev); r7xx_stop_smc(rdev);
} }
static void btc_read_arb_registers(struct radeon_device *rdev) void btc_read_arb_registers(struct radeon_device *rdev)
{ {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct evergreen_arb_registers *arb_registers = struct evergreen_arb_registers *arb_registers =
......
...@@ -33,6 +33,24 @@ ...@@ -33,6 +33,24 @@
#define BTC_CGULVPARAMETER_DFLT 0x00040035 #define BTC_CGULVPARAMETER_DFLT 0x00040035
#define BTC_CGULVCONTROL_DFLT 0x00001450 #define BTC_CGULVCONTROL_DFLT 0x00001450
extern u32 btc_valid_sclk[]; extern u32 btc_valid_sclk[40];
void btc_read_arb_registers(struct radeon_device *rdev);
void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
const u32 *sequence, u32 count);
void btc_skip_blacklist_clocks(struct radeon_device *rdev,
const u32 max_sclk, const u32 max_mclk,
u32 *sclk, u32 *mclk);
void btc_adjust_clock_combinations(struct radeon_device *rdev,
const struct radeon_clock_and_voltage_limits *max_limits,
struct rv7xx_pl *pl);
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
u32 clock, u16 max_voltage, u16 *voltage);
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
u16 max_vddc, u16 max_vddci,
u16 *vddc, u16 *vddci);
bool btc_dpm_enabled(struct radeon_device *rdev);
int btc_reset_to_default(struct radeon_device *rdev);
void btc_notify_uvd_to_smc(struct radeon_device *rdev);
#endif #endif
...@@ -45,9 +45,6 @@ struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); ...@@ -45,9 +45,6 @@ struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev); struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u32 memory_clock, bool strobe_mode);
static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
bool enable) bool enable)
{ {
...@@ -416,7 +413,7 @@ static int cypress_populate_voltage_value(struct radeon_device *rdev, ...@@ -416,7 +413,7 @@ static int cypress_populate_voltage_value(struct radeon_device *rdev,
return 0; return 0;
} }
static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk) u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
{ {
struct rv7xx_power_info *pi = rv770_get_pi(rdev); struct rv7xx_power_info *pi = rv770_get_pi(rdev);
u8 result = 0; u8 result = 0;
...@@ -434,7 +431,7 @@ static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk) ...@@ -434,7 +431,7 @@ static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
return result; return result;
} }
static u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf) u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
{ {
u32 ref_clk = rdev->clock.mpll.reference_freq; u32 ref_clk = rdev->clock.mpll.reference_freq;
u32 vco = clkf * ref_clk; u32 vco = clkf * ref_clk;
...@@ -603,8 +600,8 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev, ...@@ -603,8 +600,8 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
return 0; return 0;
} }
static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev, u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u32 memory_clock, bool strobe_mode) u32 memory_clock, bool strobe_mode)
{ {
u8 mc_para_index; u8 mc_para_index;
......
...@@ -141,5 +141,9 @@ void cypress_enable_mclk_control(struct radeon_device *rdev, ...@@ -141,5 +141,9 @@ void cypress_enable_mclk_control(struct radeon_device *rdev,
bool enable); bool enable);
void cypress_start_dpm(struct radeon_device *rdev); void cypress_start_dpm(struct radeon_device *rdev);
void cypress_advertise_gen2_capability(struct radeon_device *rdev); void cypress_advertise_gen2_capability(struct radeon_device *rdev);
u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u32 memory_clock, bool strobe_mode);
u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk);
#endif #endif
...@@ -194,6 +194,7 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); ...@@ -194,6 +194,7 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
MODULE_FIRMWARE("radeon/ARUBA_pfp.bin"); MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
MODULE_FIRMWARE("radeon/ARUBA_me.bin"); MODULE_FIRMWARE("radeon/ARUBA_me.bin");
MODULE_FIRMWARE("radeon/ARUBA_rlc.bin"); MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
...@@ -734,6 +735,7 @@ int ni_init_microcode(struct radeon_device *rdev) ...@@ -734,6 +735,7 @@ int ni_init_microcode(struct radeon_device *rdev)
me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
break; break;
case CHIP_ARUBA: case CHIP_ARUBA:
chip_name = "ARUBA"; chip_name = "ARUBA";
...@@ -797,7 +799,7 @@ int ni_init_microcode(struct radeon_device *rdev) ...@@ -797,7 +799,7 @@ int ni_init_microcode(struct radeon_device *rdev)
} }
} }
if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAICOS)) { if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev); err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
if (err) if (err)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2012 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.
*
*/
#ifndef __NI_DPM_H__
#define __NI_DPM_H__
#include "cypress_dpm.h"
#include "btc_dpm.h"
#include "nislands_smc.h"
struct ni_clock_registers {
u32 cg_spll_func_cntl;
u32 cg_spll_func_cntl_2;
u32 cg_spll_func_cntl_3;
u32 cg_spll_func_cntl_4;
u32 cg_spll_spread_spectrum;
u32 cg_spll_spread_spectrum_2;
u32 mclk_pwrmgt_cntl;
u32 dll_cntl;
u32 mpll_ad_func_cntl;
u32 mpll_ad_func_cntl_2;
u32 mpll_dq_func_cntl;
u32 mpll_dq_func_cntl_2;
u32 mpll_ss1;
u32 mpll_ss2;
};
struct ni_mc_reg_entry {
u32 mclk_max;
u32 mc_data[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
};
struct ni_mc_reg_table {
u8 last;
u8 num_entries;
u16 valid_flag;
struct ni_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
SMC_NIslands_MCRegisterAddress mc_reg_address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
};
#define NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT 2
enum ni_dc_cac_level
{
NISLANDS_DCCAC_LEVEL_0 = 0,
NISLANDS_DCCAC_LEVEL_1,
NISLANDS_DCCAC_LEVEL_2,
NISLANDS_DCCAC_LEVEL_3,
NISLANDS_DCCAC_LEVEL_4,
NISLANDS_DCCAC_LEVEL_5,
NISLANDS_DCCAC_LEVEL_6,
NISLANDS_DCCAC_LEVEL_7,
NISLANDS_DCCAC_MAX_LEVELS
};
struct ni_leakage_coeffients
{
u32 at;
u32 bt;
u32 av;
u32 bv;
s32 t_slope;
s32 t_intercept;
u32 t_ref;
};
struct ni_cac_data
{
struct ni_leakage_coeffients leakage_coefficients;
u32 i_leakage;
s32 leakage_minimum_temperature;
u32 pwr_const;
u32 dc_cac_value;
u32 bif_cac_value;
u32 lkge_pwr;
u8 mc_wr_weight;
u8 mc_rd_weight;
u8 allow_ovrflw;
u8 num_win_tdp;
u8 l2num_win_tdp;
u8 lts_truncate_n;
};
struct ni_cac_weights
{
u32 weight_tcp_sig0;
u32 weight_tcp_sig1;
u32 weight_ta_sig;
u32 weight_tcc_en0;
u32 weight_tcc_en1;
u32 weight_tcc_en2;
u32 weight_cb_en0;
u32 weight_cb_en1;
u32 weight_cb_en2;
u32 weight_cb_en3;
u32 weight_db_sig0;
u32 weight_db_sig1;
u32 weight_db_sig2;
u32 weight_db_sig3;
u32 weight_sxm_sig0;
u32 weight_sxm_sig1;
u32 weight_sxm_sig2;
u32 weight_sxs_sig0;
u32 weight_sxs_sig1;
u32 weight_xbr_0;
u32 weight_xbr_1;
u32 weight_xbr_2;
u32 weight_spi_sig0;
u32 weight_spi_sig1;
u32 weight_spi_sig2;
u32 weight_spi_sig3;
u32 weight_spi_sig4;
u32 weight_spi_sig5;
u32 weight_lds_sig0;
u32 weight_lds_sig1;
u32 weight_sc;
u32 weight_bif;
u32 weight_cp;
u32 weight_pa_sig0;
u32 weight_pa_sig1;
u32 weight_vgt_sig0;
u32 weight_vgt_sig1;
u32 weight_vgt_sig2;
u32 weight_dc_sig0;
u32 weight_dc_sig1;
u32 weight_dc_sig2;
u32 weight_dc_sig3;
u32 weight_uvd_sig0;
u32 weight_uvd_sig1;
u32 weight_spare0;
u32 weight_spare1;
u32 weight_sq_vsp;
u32 weight_sq_vsp0;
u32 weight_sq_gpr;
u32 ovr_mode_spare_0;
u32 ovr_val_spare_0;
u32 ovr_mode_spare_1;
u32 ovr_val_spare_1;
u32 vsp;
u32 vsp0;
u32 gpr;
u8 mc_read_weight;
u8 mc_write_weight;
u32 tid_cnt;
u32 tid_unit;
u32 l2_lta_window_size;
u32 lts_truncate;
u32 dc_cac[NISLANDS_DCCAC_MAX_LEVELS];
u32 pcie_cac[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
bool enable_power_containment_by_default;
};
struct ni_ps {
u16 performance_level_count;
bool dc_compatible;
struct rv7xx_pl performance_levels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
};
struct ni_power_info {
/* must be first! */
struct evergreen_power_info eg;
struct ni_clock_registers clock_registers;
struct ni_mc_reg_table mc_reg_table;
u32 mclk_rtt_mode_threshold;
/* flags */
bool use_power_boost_limit;
bool support_cac_long_term_average;
bool cac_enabled;
bool cac_configuration_required;
bool driver_calculate_cac_leakage;
bool pc_enabled;
bool enable_power_containment;
bool enable_cac;
bool enable_sq_ramping;
/* smc offsets */
u16 arb_table_start;
u16 fan_table_start;
u16 cac_table_start;
u16 spll_table_start;
/* CAC stuff */
struct ni_cac_data cac_data;
u32 dc_cac_table[NISLANDS_DCCAC_MAX_LEVELS];
const struct ni_cac_weights *cac_weights;
u8 lta_window_size;
u8 lts_truncate;
struct ni_ps hw_ps;
/* scratch structs */
SMC_NIslands_MCRegisters smc_mc_reg_table;
NISLANDS_SMC_STATETABLE smc_statetable;
};
#define NISLANDS_INITIAL_STATE_ARB_INDEX 0
#define NISLANDS_ACPI_STATE_ARB_INDEX 1
#define NISLANDS_ULV_STATE_ARB_INDEX 2
#define NISLANDS_DRIVER_STATE_ARB_INDEX 3
#define NISLANDS_DPM2_MAX_PULSE_SKIP 256
#define NISLANDS_DPM2_NEAR_TDP_DEC 10
#define NISLANDS_DPM2_ABOVE_SAFE_INC 5
#define NISLANDS_DPM2_BELOW_SAFE_INC 20
#define NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT 80
#define NISLANDS_DPM2_MAXPS_PERCENT_H 90
#define NISLANDS_DPM2_MAXPS_PERCENT_M 0
#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER 0x3FFF
#define NISLANDS_DPM2_SQ_RAMP_MIN_POWER 0x12
#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA 0x15
#define NISLANDS_DPM2_SQ_RAMP_STI_SIZE 0x1E
#define NISLANDS_DPM2_SQ_RAMP_LTI_RATIO 0xF
#endif
This diff is collapsed.
This diff is collapsed.
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#define PPSMC_DISPLAY_WATERMARK_HIGH 1 #define PPSMC_DISPLAY_WATERMARK_HIGH 1
#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01 #define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01
#define PPSMC_STATEFLAG_POWERBOOST 0x02
#define PPSMC_Result_OK ((uint8_t)0x01) #define PPSMC_Result_OK ((uint8_t)0x01)
#define PPSMC_Result_Failed ((uint8_t)0xFF) #define PPSMC_Result_Failed ((uint8_t)0xFF)
...@@ -58,17 +59,29 @@ typedef uint8_t PPSMC_Result; ...@@ -58,17 +59,29 @@ typedef uint8_t PPSMC_Result;
#define PPSMC_MSG_OneLevelsDisabled ((uint8_t)0x14) #define PPSMC_MSG_OneLevelsDisabled ((uint8_t)0x14)
#define PPSMC_MSG_TwoLevelsDisabled ((uint8_t)0x15) #define PPSMC_MSG_TwoLevelsDisabled ((uint8_t)0x15)
#define PPSMC_MSG_EnableThermalInterrupt ((uint8_t)0x16) #define PPSMC_MSG_EnableThermalInterrupt ((uint8_t)0x16)
#define PPSMC_MSG_RunningOnAC ((uint8_t)0x17)
#define PPSMC_MSG_SwitchToSwState ((uint8_t)0x20) #define PPSMC_MSG_SwitchToSwState ((uint8_t)0x20)
#define PPSMC_MSG_SwitchToInitialState ((uint8_t)0x40) #define PPSMC_MSG_SwitchToInitialState ((uint8_t)0x40)
#define PPSMC_MSG_NoForcedLevel ((uint8_t)0x41) #define PPSMC_MSG_NoForcedLevel ((uint8_t)0x41)
#define PPSMC_MSG_SwitchToMinimumPower ((uint8_t)0x51) #define PPSMC_MSG_SwitchToMinimumPower ((uint8_t)0x51)
#define PPSMC_MSG_ResumeFromMinimumPower ((uint8_t)0x52) #define PPSMC_MSG_ResumeFromMinimumPower ((uint8_t)0x52)
#define PPSMC_MSG_EnableCac ((uint8_t)0x53)
#define PPSMC_MSG_DisableCac ((uint8_t)0x54)
#define PPSMC_TDPClampingActive ((uint8_t)0x59)
#define PPSMC_TDPClampingInactive ((uint8_t)0x5A)
#define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D)
#define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E)
#define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60)
#define PPSMC_MSG_UVDPowerON ((uint8_t)0x61)
#define PPSMC_MSG_EnableULV ((uint8_t)0x62) #define PPSMC_MSG_EnableULV ((uint8_t)0x62)
#define PPSMC_MSG_DisableULV ((uint8_t)0x63) #define PPSMC_MSG_DisableULV ((uint8_t)0x63)
#define PPSMC_MSG_EnterULV ((uint8_t)0x64) #define PPSMC_MSG_EnterULV ((uint8_t)0x64)
#define PPSMC_MSG_ExitULV ((uint8_t)0x65) #define PPSMC_MSG_ExitULV ((uint8_t)0x65)
#define PPSMC_CACLongTermAvgEnable ((uint8_t)0x6E)
#define PPSMC_CACLongTermAvgDisable ((uint8_t)0x6F)
#define PPSMC_MSG_CollectCAC_PowerCorreln ((uint8_t)0x7A)
#define PPSMC_MSG_SetEnabledLevels ((uint8_t)0x82)
#define PPSMC_MSG_SetForcedLevels ((uint8_t)0x83)
#define PPSMC_MSG_ResetToDefaults ((uint8_t)0x84) #define PPSMC_MSG_ResetToDefaults ((uint8_t)0x84)
/* TN */ /* TN */
......
...@@ -1906,6 +1906,18 @@ static struct radeon_asic cayman_asic = { ...@@ -1906,6 +1906,18 @@ static struct radeon_asic cayman_asic = {
.set_uvd_clocks = &evergreen_set_uvd_clocks, .set_uvd_clocks = &evergreen_set_uvd_clocks,
.get_temperature = &evergreen_get_temp, .get_temperature = &evergreen_get_temp,
}, },
.dpm = {
.init = &ni_dpm_init,
.setup_asic = &ni_dpm_setup_asic,
.enable = &ni_dpm_enable,
.disable = &ni_dpm_disable,
.set_power_state = &ni_dpm_set_power_state,
.display_configuration_changed = &cypress_dpm_display_configuration_changed,
.fini = &ni_dpm_fini,
.get_sclk = &ni_dpm_get_sclk,
.get_mclk = &ni_dpm_get_mclk,
.print_power_state = &ni_dpm_print_power_state,
},
.pflip = { .pflip = {
.pre_page_flip = &evergreen_pre_page_flip, .pre_page_flip = &evergreen_pre_page_flip,
.page_flip = &evergreen_page_flip, .page_flip = &evergreen_page_flip,
......
...@@ -587,6 +587,16 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); ...@@ -587,6 +587,16 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int ni_dpm_init(struct radeon_device *rdev);
void ni_dpm_setup_asic(struct radeon_device *rdev);
int ni_dpm_enable(struct radeon_device *rdev);
void ni_dpm_disable(struct radeon_device *rdev);
int ni_dpm_set_power_state(struct radeon_device *rdev);
void ni_dpm_fini(struct radeon_device *rdev);
u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low);
void ni_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
int trinity_dpm_init(struct radeon_device *rdev); int trinity_dpm_init(struct radeon_device *rdev);
int trinity_dpm_enable(struct radeon_device *rdev); int trinity_dpm_enable(struct radeon_device *rdev);
void trinity_dpm_disable(struct radeon_device *rdev); void trinity_dpm_disable(struct radeon_device *rdev);
......
...@@ -1097,6 +1097,7 @@ int radeon_pm_init(struct radeon_device *rdev) ...@@ -1097,6 +1097,7 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_BARTS: case CHIP_BARTS:
case CHIP_TURKS: case CHIP_TURKS:
case CHIP_CAICOS: case CHIP_CAICOS:
case CHIP_CAYMAN:
case CHIP_ARUBA: case CHIP_ARUBA:
if (radeon_dpm == 1) if (radeon_dpm == 1)
rdev->pm.pm_method = PM_METHOD_DPM; rdev->pm.pm_method = PM_METHOD_DPM;
......
...@@ -100,4 +100,9 @@ ...@@ -100,4 +100,9 @@
#define CAICOS_SMC_INT_VECTOR_START 0xffc0 #define CAICOS_SMC_INT_VECTOR_START 0xffc0
#define CAICOS_SMC_INT_VECTOR_SIZE 0x0040 #define CAICOS_SMC_INT_VECTOR_SIZE 0x0040
#define CAYMAN_SMC_UCODE_START 0x0100
#define CAYMAN_SMC_UCODE_SIZE 0x79ec
#define CAYMAN_SMC_INT_VECTOR_START 0xffc0
#define CAYMAN_SMC_INT_VECTOR_SIZE 0x0040
#endif #endif
...@@ -254,6 +254,26 @@ static const u8 caicos_smc_int_vectors[] = ...@@ -254,6 +254,26 @@ static const u8 caicos_smc_int_vectors[] =
0x05, 0x0A, 0x05, 0x0A 0x05, 0x0A, 0x05, 0x0A
}; };
static const u8 cayman_smc_int_vectors[] =
{
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x12, 0x05,
0x12, 0x05, 0x18, 0xEA,
0x12, 0x20, 0x1C, 0x34,
0x1C, 0x34, 0x08, 0x72,
0x08, 0x72, 0x08, 0x72
};
int rv770_set_smc_sram_address(struct radeon_device *rdev, int rv770_set_smc_sram_address(struct radeon_device *rdev,
u16 smc_address, u16 limit) u16 smc_address, u16 limit)
{ {
...@@ -544,6 +564,13 @@ int rv770_load_smc_ucode(struct radeon_device *rdev, ...@@ -544,6 +564,13 @@ int rv770_load_smc_ucode(struct radeon_device *rdev,
int_vect_start_address = CAICOS_SMC_INT_VECTOR_START; int_vect_start_address = CAICOS_SMC_INT_VECTOR_START;
int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE; int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE;
break; break;
case CHIP_CAYMAN:
ucode_start_address = CAYMAN_SMC_UCODE_START;
ucode_size = CAYMAN_SMC_UCODE_SIZE;
int_vect = (const u8 *)&cayman_smc_int_vectors;
int_vect_start_address = CAYMAN_SMC_INT_VECTOR_START;
int_vect_size = CAYMAN_SMC_INT_VECTOR_SIZE;
break;
default: default:
DRM_ERROR("unknown asic in smc ucode loader\n"); DRM_ERROR("unknown asic in smc ucode loader\n");
BUG(); BUG();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment