提交 69e0b57a 编写于 作者: A 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: NAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: NJerome Glisse <jglisse@redhat.com>
上级 d22b7e40
......@@ -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 \
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 \
trinity_smc.o
trinity_smc.o ni_dpm.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
......
......@@ -1152,7 +1152,7 @@ static const u32 turks_sysls_enable[] =
#endif
u32 btc_valid_sclk[] =
u32 btc_valid_sclk[40] =
{
5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000,
55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000,
......@@ -1168,8 +1168,8 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
{ 25000, 30000, RADEON_SCLK_UP }
};
static void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
u32 clock, u16 max_voltage, u16 *voltage)
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
u32 clock, u16 max_voltage, u16 *voltage)
{
u32 i;
......@@ -1219,9 +1219,9 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
max_sclk, requested_sclk);
}
static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
const u32 max_sclk, const u32 max_mclk,
u32 *sclk, u32 *mclk)
void btc_skip_blacklist_clocks(struct radeon_device *rdev,
const u32 max_sclk, const u32 max_mclk,
u32 *sclk, u32 *mclk)
{
int i, num_blacklist_clocks;
......@@ -1246,9 +1246,9 @@ static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
}
}
static void btc_adjust_clock_combinations(struct radeon_device *rdev,
const struct radeon_clock_and_voltage_limits *max_limits,
struct rv7xx_pl *pl)
void btc_adjust_clock_combinations(struct radeon_device *rdev,
const struct radeon_clock_and_voltage_limits *max_limits,
struct rv7xx_pl *pl)
{
if ((pl->mclk == 0) || (pl->sclk == 0))
......@@ -1285,9 +1285,9 @@ static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
return table->entries[table->count - 1].value;
}
static void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
u16 max_vddc, u16 max_vddci,
u16 *vddc, u16 *vddci)
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
u16 max_vddc, u16 max_vddci,
u16 *vddc, u16 *vddci)
{
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
u16 new_voltage;
......@@ -1417,8 +1417,8 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
return ret;
}
static void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
const u32 *sequence, u32 count)
void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
const u32 *sequence, u32 count)
{
u32 i, length = count * 3;
u32 tmp;
......@@ -1596,7 +1596,7 @@ static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
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))
return true;
......@@ -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 evergreen_power_info *eg_pi = evergreen_get_pi(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)
return -EINVAL;
......@@ -1730,7 +1730,7 @@ static void btc_stop_smc(struct radeon_device *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_arb_registers *arb_registers =
......
......@@ -33,6 +33,24 @@
#define BTC_CGULVPARAMETER_DFLT 0x00040035
#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
......@@ -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 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,
bool enable)
{
......@@ -416,7 +413,7 @@ static int cypress_populate_voltage_value(struct radeon_device *rdev,
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);
u8 result = 0;
......@@ -434,7 +431,7 @@ static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
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 vco = clkf * ref_clk;
......@@ -603,8 +600,8 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
return 0;
}
static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u32 memory_clock, bool strobe_mode)
u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u32 memory_clock, bool strobe_mode)
{
u8 mc_para_index;
......
......@@ -141,5 +141,9 @@ void cypress_enable_mclk_control(struct radeon_device *rdev,
bool enable);
void cypress_start_dpm(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
......@@ -194,6 +194,7 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
MODULE_FIRMWARE("radeon/ARUBA_me.bin");
MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
......@@ -734,6 +735,7 @@ int ni_init_microcode(struct radeon_device *rdev)
me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
break;
case CHIP_ARUBA:
chip_name = "ARUBA";
......@@ -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);
err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
if (err)
......
此差异已折叠。
/*
* 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
此差异已折叠。
/*
* 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 __NISLANDS_SMC_H__
#define __NISLANDS_SMC_H__
#pragma pack(push, 1)
#define NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 16
struct PP_NIslands_Dpm2PerfLevel
{
uint8_t MaxPS;
uint8_t TgtAct;
uint8_t MaxPS_StepInc;
uint8_t MaxPS_StepDec;
uint8_t PSST;
uint8_t NearTDPDec;
uint8_t AboveSafeInc;
uint8_t BelowSafeInc;
uint8_t PSDeltaLimit;
uint8_t PSDeltaWin;
uint8_t Reserved[6];
};
typedef struct PP_NIslands_Dpm2PerfLevel PP_NIslands_Dpm2PerfLevel;
struct PP_NIslands_DPM2Parameters
{
uint32_t TDPLimit;
uint32_t NearTDPLimit;
uint32_t SafePowerLimit;
uint32_t PowerBoostLimit;
};
typedef struct PP_NIslands_DPM2Parameters PP_NIslands_DPM2Parameters;
struct NISLANDS_SMC_SCLK_VALUE
{
uint32_t vCG_SPLL_FUNC_CNTL;
uint32_t vCG_SPLL_FUNC_CNTL_2;
uint32_t vCG_SPLL_FUNC_CNTL_3;
uint32_t vCG_SPLL_FUNC_CNTL_4;
uint32_t vCG_SPLL_SPREAD_SPECTRUM;
uint32_t vCG_SPLL_SPREAD_SPECTRUM_2;
uint32_t sclk_value;
};
typedef struct NISLANDS_SMC_SCLK_VALUE NISLANDS_SMC_SCLK_VALUE;
struct NISLANDS_SMC_MCLK_VALUE
{
uint32_t vMPLL_FUNC_CNTL;
uint32_t vMPLL_FUNC_CNTL_1;
uint32_t vMPLL_FUNC_CNTL_2;
uint32_t vMPLL_AD_FUNC_CNTL;
uint32_t vMPLL_AD_FUNC_CNTL_2;
uint32_t vMPLL_DQ_FUNC_CNTL;
uint32_t vMPLL_DQ_FUNC_CNTL_2;
uint32_t vMCLK_PWRMGT_CNTL;
uint32_t vDLL_CNTL;
uint32_t vMPLL_SS;
uint32_t vMPLL_SS2;
uint32_t mclk_value;
};
typedef struct NISLANDS_SMC_MCLK_VALUE NISLANDS_SMC_MCLK_VALUE;
struct NISLANDS_SMC_VOLTAGE_VALUE
{
uint16_t value;
uint8_t index;
uint8_t padding;
};
typedef struct NISLANDS_SMC_VOLTAGE_VALUE NISLANDS_SMC_VOLTAGE_VALUE;
struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL
{
uint8_t arbValue;
uint8_t ACIndex;
uint8_t displayWatermark;
uint8_t gen2PCIE;
uint8_t reserved1;
uint8_t reserved2;
uint8_t strobeMode;
uint8_t mcFlags;
uint32_t aT;
uint32_t bSP;
NISLANDS_SMC_SCLK_VALUE sclk;
NISLANDS_SMC_MCLK_VALUE mclk;
NISLANDS_SMC_VOLTAGE_VALUE vddc;
NISLANDS_SMC_VOLTAGE_VALUE mvdd;
NISLANDS_SMC_VOLTAGE_VALUE vddci;
NISLANDS_SMC_VOLTAGE_VALUE std_vddc;
uint32_t powergate_en;
uint8_t hUp;
uint8_t hDown;
uint8_t stateFlags;
uint8_t arbRefreshState;
uint32_t SQPowerThrottle;
uint32_t SQPowerThrottle_2;
uint32_t reserved[2];
PP_NIslands_Dpm2PerfLevel dpm2;
};
#define NISLANDS_SMC_STROBE_RATIO 0x0F
#define NISLANDS_SMC_STROBE_ENABLE 0x10
#define NISLANDS_SMC_MC_EDC_RD_FLAG 0x01
#define NISLANDS_SMC_MC_EDC_WR_FLAG 0x02
#define NISLANDS_SMC_MC_RTT_ENABLE 0x04
#define NISLANDS_SMC_MC_STUTTER_EN 0x08
typedef struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL NISLANDS_SMC_HW_PERFORMANCE_LEVEL;
struct NISLANDS_SMC_SWSTATE
{
uint8_t flags;
uint8_t levelCount;
uint8_t padding2;
uint8_t padding3;
NISLANDS_SMC_HW_PERFORMANCE_LEVEL levels[1];
};
typedef struct NISLANDS_SMC_SWSTATE NISLANDS_SMC_SWSTATE;
#define NISLANDS_SMC_VOLTAGEMASK_VDDC 0
#define NISLANDS_SMC_VOLTAGEMASK_MVDD 1
#define NISLANDS_SMC_VOLTAGEMASK_VDDCI 2
#define NISLANDS_SMC_VOLTAGEMASK_MAX 4
struct NISLANDS_SMC_VOLTAGEMASKTABLE
{
uint8_t highMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
uint32_t lowMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
};
typedef struct NISLANDS_SMC_VOLTAGEMASKTABLE NISLANDS_SMC_VOLTAGEMASKTABLE;
#define NISLANDS_MAX_NO_VREG_STEPS 32
struct NISLANDS_SMC_STATETABLE
{
uint8_t thermalProtectType;
uint8_t systemFlags;
uint8_t maxVDDCIndexInPPTable;
uint8_t extraFlags;
uint8_t highSMIO[NISLANDS_MAX_NO_VREG_STEPS];
uint32_t lowSMIO[NISLANDS_MAX_NO_VREG_STEPS];
NISLANDS_SMC_VOLTAGEMASKTABLE voltageMaskTable;
PP_NIslands_DPM2Parameters dpm2Params;
NISLANDS_SMC_SWSTATE initialState;
NISLANDS_SMC_SWSTATE ACPIState;
NISLANDS_SMC_SWSTATE ULVState;
NISLANDS_SMC_SWSTATE driverState;
NISLANDS_SMC_HW_PERFORMANCE_LEVEL dpmLevels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1];
};
typedef struct NISLANDS_SMC_STATETABLE NISLANDS_SMC_STATETABLE;
#define NI_SMC_SOFT_REGISTERS_START 0x108
#define NI_SMC_SOFT_REGISTER_mclk_chg_timeout 0x0
#define NI_SMC_SOFT_REGISTER_delay_bbias 0xC
#define NI_SMC_SOFT_REGISTER_delay_vreg 0x10
#define NI_SMC_SOFT_REGISTER_delay_acpi 0x2C
#define NI_SMC_SOFT_REGISTER_seq_index 0x64
#define NI_SMC_SOFT_REGISTER_mvdd_chg_time 0x68
#define NI_SMC_SOFT_REGISTER_mclk_switch_lim 0x78
#define NI_SMC_SOFT_REGISTER_watermark_threshold 0x80
#define NI_SMC_SOFT_REGISTER_mc_block_delay 0x84
#define NI_SMC_SOFT_REGISTER_uvd_enabled 0x98
#define SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES 16
#define SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
#define SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
#define SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES 4
struct SMC_NISLANDS_MC_TPP_CAC_TABLE
{
uint32_t tpp[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
uint32_t cacValue[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
};
typedef struct SMC_NISLANDS_MC_TPP_CAC_TABLE SMC_NISLANDS_MC_TPP_CAC_TABLE;
struct PP_NIslands_CACTABLES
{
uint32_t cac_bif_lut[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
uint32_t cac_lkge_lut[SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES][SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES];
uint32_t pwr_const;
uint32_t dc_cacValue;
uint32_t bif_cacValue;
uint32_t lkge_pwr;
uint8_t cac_width;
uint8_t window_size_p2;
uint8_t num_drop_lsb;
uint8_t padding_0;
uint32_t last_power;
uint8_t AllowOvrflw;
uint8_t MCWrWeight;
uint8_t MCRdWeight;
uint8_t padding_1[9];
uint8_t enableWinAvg;
uint8_t numWin_TDP;
uint8_t l2numWin_TDP;
uint8_t WinIndex;
uint32_t dynPwr_TDP[4];
uint32_t lkgePwr_TDP[4];
uint32_t power_TDP[4];
uint32_t avg_dynPwr_TDP;
uint32_t avg_lkgePwr_TDP;
uint32_t avg_power_TDP;
uint32_t lts_power_TDP;
uint8_t lts_truncate_n;
uint8_t padding_2[7];
};
typedef struct PP_NIslands_CACTABLES PP_NIslands_CACTABLES;
#define SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE 32
#define SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT 20
struct SMC_NIslands_MCRegisterAddress
{
uint16_t s0;
uint16_t s1;
};
typedef struct SMC_NIslands_MCRegisterAddress SMC_NIslands_MCRegisterAddress;
struct SMC_NIslands_MCRegisterSet
{
uint32_t value[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
};
typedef struct SMC_NIslands_MCRegisterSet SMC_NIslands_MCRegisterSet;
struct SMC_NIslands_MCRegisters
{
uint8_t last;
uint8_t reserved[3];
SMC_NIslands_MCRegisterAddress address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
SMC_NIslands_MCRegisterSet data[SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT];
};
typedef struct SMC_NIslands_MCRegisters SMC_NIslands_MCRegisters;
struct SMC_NIslands_MCArbDramTimingRegisterSet
{
uint32_t mc_arb_dram_timing;
uint32_t mc_arb_dram_timing2;
uint8_t mc_arb_rfsh_rate;
uint8_t padding[3];
};
typedef struct SMC_NIslands_MCArbDramTimingRegisterSet SMC_NIslands_MCArbDramTimingRegisterSet;
struct SMC_NIslands_MCArbDramTimingRegisters
{
uint8_t arb_current;
uint8_t reserved[3];
SMC_NIslands_MCArbDramTimingRegisterSet data[20];
};
typedef struct SMC_NIslands_MCArbDramTimingRegisters SMC_NIslands_MCArbDramTimingRegisters;
struct SMC_NISLANDS_SPLL_DIV_TABLE
{
uint32_t freq[256];
uint32_t ss[256];
};
#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK 0x01ffffff
#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT 0
#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK 0xfe000000
#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT 25
#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK 0x000fffff
#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT 0
#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK 0xfff00000
#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT 20
typedef struct SMC_NISLANDS_SPLL_DIV_TABLE SMC_NISLANDS_SPLL_DIV_TABLE;
#define NISLANDS_SMC_FIRMWARE_HEADER_LOCATION 0x100
#define NISLANDS_SMC_FIRMWARE_HEADER_version 0x0
#define NISLANDS_SMC_FIRMWARE_HEADER_flags 0x4
#define NISLANDS_SMC_FIRMWARE_HEADER_softRegisters 0x8
#define NISLANDS_SMC_FIRMWARE_HEADER_stateTable 0xC
#define NISLANDS_SMC_FIRMWARE_HEADER_fanTable 0x10
#define NISLANDS_SMC_FIRMWARE_HEADER_cacTable 0x14
#define NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable 0x20
#define NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable 0x2C
#define NISLANDS_SMC_FIRMWARE_HEADER_spllTable 0x30
#pragma pack(pop)
#endif
......@@ -46,6 +46,7 @@
#define PPSMC_DISPLAY_WATERMARK_HIGH 1
#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01
#define PPSMC_STATEFLAG_POWERBOOST 0x02
#define PPSMC_Result_OK ((uint8_t)0x01)
#define PPSMC_Result_Failed ((uint8_t)0xFF)
......@@ -58,17 +59,29 @@ typedef uint8_t PPSMC_Result;
#define PPSMC_MSG_OneLevelsDisabled ((uint8_t)0x14)
#define PPSMC_MSG_TwoLevelsDisabled ((uint8_t)0x15)
#define PPSMC_MSG_EnableThermalInterrupt ((uint8_t)0x16)
#define PPSMC_MSG_RunningOnAC ((uint8_t)0x17)
#define PPSMC_MSG_SwitchToSwState ((uint8_t)0x20)
#define PPSMC_MSG_SwitchToInitialState ((uint8_t)0x40)
#define PPSMC_MSG_NoForcedLevel ((uint8_t)0x41)
#define PPSMC_MSG_SwitchToMinimumPower ((uint8_t)0x51)
#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_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_DisableULV ((uint8_t)0x63)
#define PPSMC_MSG_EnterULV ((uint8_t)0x64)
#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)
/* TN */
......
......@@ -1906,6 +1906,18 @@ static struct radeon_asic cayman_asic = {
.set_uvd_clocks = &evergreen_set_uvd_clocks,
.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 = {
.pre_page_flip = &evergreen_pre_page_flip,
.page_flip = &evergreen_page_flip,
......
......@@ -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);
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_enable(struct radeon_device *rdev);
void trinity_dpm_disable(struct radeon_device *rdev);
......
......@@ -1097,6 +1097,7 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
case CHIP_CAYMAN:
case CHIP_ARUBA:
if (radeon_dpm == 1)
rdev->pm.pm_method = PM_METHOD_DPM;
......
......@@ -100,4 +100,9 @@
#define CAICOS_SMC_INT_VECTOR_START 0xffc0
#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
......@@ -254,6 +254,26 @@ static const u8 caicos_smc_int_vectors[] =
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,
u16 smc_address, u16 limit)
{
......@@ -544,6 +564,13 @@ int rv770_load_smc_ucode(struct radeon_device *rdev,
int_vect_start_address = CAICOS_SMC_INT_VECTOR_START;
int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE;
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:
DRM_ERROR("unknown asic in smc ucode loader\n");
BUG();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册