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 \
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,7 +1168,7 @@ 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,
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
u32 clock, u16 max_voltage, u16 *voltage)
{
u32 i;
......@@ -1219,7 +1219,7 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
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,
u32 *sclk, u32 *mclk)
{
......@@ -1246,7 +1246,7 @@ 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,
struct rv7xx_pl *pl)
{
......@@ -1285,7 +1285,7 @@ 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,
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
u16 max_vddc, u16 max_vddci,
u16 *vddc, u16 *vddci)
{
......@@ -1417,7 +1417,7 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
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)
{
u32 i, length = count * 3;
......@@ -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,7 +600,7 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
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)
{
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)
......
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 @@
#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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment