1
0
Fork 0

drm/amdgpu: Add support for CIK parts

This patch adds support for CIK parts.  These parts
are also supported by radeon which is the preferred
option, so there is a config option to enable support
for CIK parts in amdgpu for testing.

Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
hifive-unleashed-5.1
Alex Deucher 2015-04-20 17:09:27 -04:00
parent 18da4340e6
commit a2e73f56fa
29 changed files with 30008 additions and 0 deletions

View File

@ -18,6 +18,9 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o gmc_v7_0.o cik_ih.o kv_smc.o kv_dpm.o \
ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o
# add IH block
amdgpu-y += \
amdgpu_irq.o \

View File

@ -38,6 +38,9 @@
#include "amdgpu_i2c.h"
#include "atom.h"
#include "amdgpu_atombios.h"
#ifdef CONFIG_DRM_AMDGPU_CIK
#include "cik.h"
#endif
#include "bif/bif_4_1_d.h"
static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
@ -1154,6 +1157,22 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
int i, r = -EINVAL;
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_BONAIRE:
case CHIP_HAWAII:
case CHIP_KAVERI:
case CHIP_KABINI:
case CHIP_MULLINS:
if ((adev->asic_type == CHIP_BONAIRE) || (adev->asic_type == CHIP_HAWAII))
adev->family = AMDGPU_FAMILY_CI;
else
adev->family = AMDGPU_FAMILY_KV;
r = cik_set_ip_blocks(adev);
if (r)
return r;
break;
#endif
default:
/* FIXME: not supported yet */
return -EINVAL;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,348 @@
/*
* Copyright 2013 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 __CI_DPM_H__
#define __CI_DPM_H__
#include "amdgpu_atombios.h"
#include "ppsmc.h"
#define SMU__NUM_SCLK_DPM_STATE 8
#define SMU__NUM_MCLK_DPM_LEVELS 6
#define SMU__NUM_LCLK_DPM_LEVELS 8
#define SMU__NUM_PCIE_DPM_LEVELS 8
#include "smu7_discrete.h"
#define CISLANDS_MAX_HARDWARE_POWERLEVELS 2
#define CISLANDS_UNUSED_GPIO_PIN 0x7F
struct ci_pl {
u32 mclk;
u32 sclk;
enum amdgpu_pcie_gen pcie_gen;
u16 pcie_lane;
};
struct ci_ps {
u16 performance_level_count;
bool dc_compatible;
u32 sclk_t;
struct ci_pl performance_levels[CISLANDS_MAX_HARDWARE_POWERLEVELS];
};
struct ci_dpm_level {
bool enabled;
u32 value;
u32 param1;
};
#define CISLAND_MAX_DEEPSLEEP_DIVIDER_ID 5
#define MAX_REGULAR_DPM_NUMBER 8
#define CISLAND_MINIMUM_ENGINE_CLOCK 800
struct ci_single_dpm_table {
u32 count;
struct ci_dpm_level dpm_levels[MAX_REGULAR_DPM_NUMBER];
};
struct ci_dpm_table {
struct ci_single_dpm_table sclk_table;
struct ci_single_dpm_table mclk_table;
struct ci_single_dpm_table pcie_speed_table;
struct ci_single_dpm_table vddc_table;
struct ci_single_dpm_table vddci_table;
struct ci_single_dpm_table mvdd_table;
};
struct ci_mc_reg_entry {
u32 mclk_max;
u32 mc_data[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
};
struct ci_mc_reg_table {
u8 last;
u8 num_entries;
u16 valid_flag;
struct ci_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
SMU7_Discrete_MCRegisterAddress mc_reg_address[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
};
struct ci_ulv_parm
{
bool supported;
u32 cg_ulv_parameter;
u32 volt_change_delay;
struct ci_pl pl;
};
#define CISLANDS_MAX_LEAKAGE_COUNT 8
struct ci_leakage_voltage {
u16 count;
u16 leakage_id[CISLANDS_MAX_LEAKAGE_COUNT];
u16 actual_voltage[CISLANDS_MAX_LEAKAGE_COUNT];
};
struct ci_dpm_level_enable_mask {
u32 uvd_dpm_enable_mask;
u32 vce_dpm_enable_mask;
u32 acp_dpm_enable_mask;
u32 samu_dpm_enable_mask;
u32 sclk_dpm_enable_mask;
u32 mclk_dpm_enable_mask;
u32 pcie_dpm_enable_mask;
};
struct ci_vbios_boot_state
{
u16 mvdd_bootup_value;
u16 vddc_bootup_value;
u16 vddci_bootup_value;
u32 sclk_bootup_value;
u32 mclk_bootup_value;
u16 pcie_gen_bootup_value;
u16 pcie_lane_bootup_value;
};
struct ci_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 dll_cntl;
u32 mclk_pwrmgt_cntl;
u32 mpll_ad_func_cntl;
u32 mpll_dq_func_cntl;
u32 mpll_func_cntl;
u32 mpll_func_cntl_1;
u32 mpll_func_cntl_2;
u32 mpll_ss1;
u32 mpll_ss2;
};
struct ci_thermal_temperature_setting {
s32 temperature_low;
s32 temperature_high;
s32 temperature_shutdown;
};
struct ci_pcie_perf_range {
u16 max;
u16 min;
};
enum ci_pt_config_reg_type {
CISLANDS_CONFIGREG_MMR = 0,
CISLANDS_CONFIGREG_SMC_IND,
CISLANDS_CONFIGREG_DIDT_IND,
CISLANDS_CONFIGREG_CACHE,
CISLANDS_CONFIGREG_MAX
};
#define POWERCONTAINMENT_FEATURE_BAPM 0x00000001
#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
#define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004
struct ci_pt_config_reg {
u32 offset;
u32 mask;
u32 shift;
u32 value;
enum ci_pt_config_reg_type type;
};
struct ci_pt_defaults {
u8 svi_load_line_en;
u8 svi_load_line_vddc;
u8 tdc_vddc_throttle_release_limit_perc;
u8 tdc_mawt;
u8 tdc_waterfall_ctl;
u8 dte_ambient_temp_base;
u32 display_cac;
u32 bapm_temp_gradient;
u16 bapmti_r[SMU7_DTE_ITERATIONS * SMU7_DTE_SOURCES * SMU7_DTE_SINKS];
u16 bapmti_rc[SMU7_DTE_ITERATIONS * SMU7_DTE_SOURCES * SMU7_DTE_SINKS];
};
#define DPMTABLE_OD_UPDATE_SCLK 0x00000001
#define DPMTABLE_OD_UPDATE_MCLK 0x00000002
#define DPMTABLE_UPDATE_SCLK 0x00000004
#define DPMTABLE_UPDATE_MCLK 0x00000008
struct ci_power_info {
struct ci_dpm_table dpm_table;
u32 voltage_control;
u32 mvdd_control;
u32 vddci_control;
u32 active_auto_throttle_sources;
struct ci_clock_registers clock_registers;
u16 acpi_vddc;
u16 acpi_vddci;
enum amdgpu_pcie_gen force_pcie_gen;
enum amdgpu_pcie_gen acpi_pcie_gen;
struct ci_leakage_voltage vddc_leakage;
struct ci_leakage_voltage vddci_leakage;
u16 max_vddc_in_pp_table;
u16 min_vddc_in_pp_table;
u16 max_vddci_in_pp_table;
u16 min_vddci_in_pp_table;
u32 mclk_strobe_mode_threshold;
u32 mclk_stutter_mode_threshold;
u32 mclk_edc_enable_threshold;
u32 mclk_edc_wr_enable_threshold;
struct ci_vbios_boot_state vbios_boot_state;
/* smc offsets */
u32 sram_end;
u32 dpm_table_start;
u32 soft_regs_start;
u32 mc_reg_table_start;
u32 fan_table_start;
u32 arb_table_start;
/* smc tables */
SMU7_Discrete_DpmTable smc_state_table;
SMU7_Discrete_MCRegisters smc_mc_reg_table;
SMU7_Discrete_PmFuses smc_powertune_table;
/* other stuff */
struct ci_mc_reg_table mc_reg_table;
struct atom_voltage_table vddc_voltage_table;
struct atom_voltage_table vddci_voltage_table;
struct atom_voltage_table mvdd_voltage_table;
struct ci_ulv_parm ulv;
u32 power_containment_features;
const struct ci_pt_defaults *powertune_defaults;
u32 dte_tj_offset;
bool vddc_phase_shed_control;
struct ci_thermal_temperature_setting thermal_temp_setting;
struct ci_dpm_level_enable_mask dpm_level_enable_mask;
u32 need_update_smu7_dpm_table;
u32 sclk_dpm_key_disabled;
u32 mclk_dpm_key_disabled;
u32 pcie_dpm_key_disabled;
u32 thermal_sclk_dpm_enabled;
struct ci_pcie_perf_range pcie_gen_performance;
struct ci_pcie_perf_range pcie_lane_performance;
struct ci_pcie_perf_range pcie_gen_powersaving;
struct ci_pcie_perf_range pcie_lane_powersaving;
u32 activity_target[SMU7_MAX_LEVELS_GRAPHICS];
u32 mclk_activity_target;
u32 low_sclk_interrupt_t;
u32 last_mclk_dpm_enable_mask;
u32 sys_pcie_mask;
/* caps */
bool caps_power_containment;
bool caps_cac;
bool caps_sq_ramping;
bool caps_db_ramping;
bool caps_td_ramping;
bool caps_tcp_ramping;
bool caps_fps;
bool caps_sclk_ds;
bool caps_sclk_ss_support;
bool caps_mclk_ss_support;
bool caps_uvd_dpm;
bool caps_vce_dpm;
bool caps_samu_dpm;
bool caps_acp_dpm;
bool caps_automatic_dc_transition;
bool caps_sclk_throttle_low_notification;
bool caps_dynamic_ac_timing;
bool caps_od_fuzzy_fan_control_support;
/* flags */
bool thermal_protection;
bool pcie_performance_request;
bool dynamic_ss;
bool dll_default_on;
bool cac_enabled;
bool uvd_enabled;
bool battery_state;
bool pspp_notify_required;
bool enable_bapm_feature;
bool enable_tdc_limit_feature;
bool enable_pkg_pwr_tracking_feature;
bool use_pcie_performance_levels;
bool use_pcie_powersaving_levels;
bool uvd_power_gated;
/* driver states */
struct amdgpu_ps current_rps;
struct ci_ps current_ps;
struct amdgpu_ps requested_rps;
struct ci_ps requested_ps;
/* fan control */
bool fan_ctrl_is_in_default_mode;
bool fan_is_controlled_by_smc;
u32 t_min;
u32 fan_ctrl_default_mode;
};
#define CISLANDS_VOLTAGE_CONTROL_NONE 0x0
#define CISLANDS_VOLTAGE_CONTROL_BY_GPIO 0x1
#define CISLANDS_VOLTAGE_CONTROL_BY_SVID2 0x2
#define CISLANDS_Q88_FORMAT_CONVERSION_UNIT 256
#define CISLANDS_VRC_DFLT0 0x3FFFC000
#define CISLANDS_VRC_DFLT1 0x000400
#define CISLANDS_VRC_DFLT2 0xC00080
#define CISLANDS_VRC_DFLT3 0xC00200
#define CISLANDS_VRC_DFLT4 0xC01680
#define CISLANDS_VRC_DFLT5 0xC00033
#define CISLANDS_VRC_DFLT6 0xC00033
#define CISLANDS_VRC_DFLT7 0x3FFFC000
#define CISLANDS_CGULVPARAMETER_DFLT 0x00040035
#define CISLAND_TARGETACTIVITY_DFLT 30
#define CISLAND_MCLK_TARGETACTIVITY_DFLT 10
#define PCIE_PERF_REQ_REMOVE_REGISTRY 0
#define PCIE_PERF_REQ_FORCE_LOWPOWER 1
#define PCIE_PERF_REQ_PECI_GEN1 2
#define PCIE_PERF_REQ_PECI_GEN2 3
#define PCIE_PERF_REQ_PECI_GEN3 4
#define CISLANDS_SSTU_DFLT 0
#define CISLANDS_SST_DFLT 0x00C8
/* XXX are these ok? */
#define CISLANDS_TEMP_RANGE_MIN (90 * 1000)
#define CISLANDS_TEMP_RANGE_MAX (120 * 1000)
int amdgpu_ci_copy_bytes_to_smc(struct amdgpu_device *adev,
u32 smc_start_address,
const u8 *src, u32 byte_count, u32 limit);
void amdgpu_ci_start_smc(struct amdgpu_device *adev);
void amdgpu_ci_reset_smc(struct amdgpu_device *adev);
int amdgpu_ci_program_jump_on_start(struct amdgpu_device *adev);
void amdgpu_ci_stop_smc_clock(struct amdgpu_device *adev);
void amdgpu_ci_start_smc_clock(struct amdgpu_device *adev);
bool amdgpu_ci_is_smc_running(struct amdgpu_device *adev);
PPSMC_Result amdgpu_ci_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg);
PPSMC_Result amdgpu_ci_wait_for_smc_inactive(struct amdgpu_device *adev);
int amdgpu_ci_load_smc_ucode(struct amdgpu_device *adev, u32 limit);
int amdgpu_ci_read_smc_sram_dword(struct amdgpu_device *adev,
u32 smc_address, u32 *value, u32 limit);
int amdgpu_ci_write_smc_sram_dword(struct amdgpu_device *adev,
u32 smc_address, u32 value, u32 limit);
#endif

View File

@ -0,0 +1,279 @@
/*
* Copyright 2011 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.
*
* Authors: Alex Deucher
*/
#include <linux/firmware.h>
#include "drmP.h"
#include "amdgpu.h"
#include "cikd.h"
#include "ppsmc.h"
#include "amdgpu_ucode.h"
#include "ci_dpm.h"
#include "smu/smu_7_0_1_d.h"
#include "smu/smu_7_0_1_sh_mask.h"
static int ci_set_smc_sram_address(struct amdgpu_device *adev,
u32 smc_address, u32 limit)
{
if (smc_address & 3)
return -EINVAL;
if ((smc_address + 3) > limit)
return -EINVAL;
WREG32(mmSMC_IND_INDEX_0, smc_address);
WREG32_P(mmSMC_IND_ACCESS_CNTL, 0, ~SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK);
return 0;
}
int amdgpu_ci_copy_bytes_to_smc(struct amdgpu_device *adev,
u32 smc_start_address,
const u8 *src, u32 byte_count, u32 limit)
{
unsigned long flags;
u32 data, original_data;
u32 addr;
u32 extra_shift;
int ret = 0;
if (smc_start_address & 3)
return -EINVAL;
if ((smc_start_address + byte_count) > limit)
return -EINVAL;
addr = smc_start_address;
spin_lock_irqsave(&adev->smc_idx_lock, flags);
while (byte_count >= 4) {
/* SMC address space is BE */
data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
ret = ci_set_smc_sram_address(adev, addr, limit);
if (ret)
goto done;
WREG32(mmSMC_IND_DATA_0, data);
src += 4;
byte_count -= 4;
addr += 4;
}
/* RMW for the final bytes */
if (byte_count > 0) {
data = 0;
ret = ci_set_smc_sram_address(adev, addr, limit);
if (ret)
goto done;
original_data = RREG32(mmSMC_IND_DATA_0);
extra_shift = 8 * (4 - byte_count);
while (byte_count > 0) {
data = (data << 8) + *src++;
byte_count--;
}
data <<= extra_shift;
data |= (original_data & ~((~0UL) << extra_shift));
ret = ci_set_smc_sram_address(adev, addr, limit);
if (ret)
goto done;
WREG32(mmSMC_IND_DATA_0, data);
}
done:
spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
return ret;
}
void amdgpu_ci_start_smc(struct amdgpu_device *adev)
{
u32 tmp = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
tmp &= ~SMC_SYSCON_RESET_CNTL__rst_reg_MASK;
WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, tmp);
}
void amdgpu_ci_reset_smc(struct amdgpu_device *adev)
{
u32 tmp = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
tmp |= SMC_SYSCON_RESET_CNTL__rst_reg_MASK;
WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, tmp);
}
int amdgpu_ci_program_jump_on_start(struct amdgpu_device *adev)
{
static u8 data[] = { 0xE0, 0x00, 0x80, 0x40 };
return amdgpu_ci_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
}
void amdgpu_ci_stop_smc_clock(struct amdgpu_device *adev)
{
u32 tmp = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
tmp |= SMC_SYSCON_CLOCK_CNTL_0__ck_disable_MASK;
WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, tmp);
}
void amdgpu_ci_start_smc_clock(struct amdgpu_device *adev)
{
u32 tmp = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
tmp &= ~SMC_SYSCON_CLOCK_CNTL_0__ck_disable_MASK;
WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, tmp);
}
bool amdgpu_ci_is_smc_running(struct amdgpu_device *adev)
{
u32 clk = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
u32 pc_c = RREG32_SMC(ixSMC_PC_C);
if (!(clk & SMC_SYSCON_CLOCK_CNTL_0__ck_disable_MASK) && (0x20100 <= pc_c))
return true;
return false;
}
PPSMC_Result amdgpu_ci_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
{
u32 tmp;
int i;
if (!amdgpu_ci_is_smc_running(adev))
return PPSMC_Result_Failed;
WREG32(mmSMC_MESSAGE_0, msg);
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(mmSMC_RESP_0);
if (tmp != 0)
break;
udelay(1);
}
tmp = RREG32(mmSMC_RESP_0);
return (PPSMC_Result)tmp;
}
PPSMC_Result amdgpu_ci_wait_for_smc_inactive(struct amdgpu_device *adev)
{
u32 tmp;
int i;
if (!amdgpu_ci_is_smc_running(adev))
return PPSMC_Result_OK;
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
if ((tmp & SMC_SYSCON_CLOCK_CNTL_0__cken_MASK) == 0)
break;
udelay(1);
}
return PPSMC_Result_OK;
}
int amdgpu_ci_load_smc_ucode(struct amdgpu_device *adev, u32 limit)
{
const struct smc_firmware_header_v1_0 *hdr;
unsigned long flags;
u32 ucode_start_address;
u32 ucode_size;
const u8 *src;
u32 data;
if (!adev->pm.fw)
return -EINVAL;
hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
amdgpu_ucode_print_smc_hdr(&hdr->header);
adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
src = (const u8 *)
(adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
if (ucode_size & 3)
return -EINVAL;
spin_lock_irqsave(&adev->smc_idx_lock, flags);
WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
WREG32_P(mmSMC_IND_ACCESS_CNTL, SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK,
~SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK);
while (ucode_size >= 4) {
/* SMC address space is BE */
data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
WREG32(mmSMC_IND_DATA_0, data);
src += 4;
ucode_size -= 4;
}
WREG32_P(mmSMC_IND_ACCESS_CNTL, 0, ~SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK);
spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
return 0;
}
int amdgpu_ci_read_smc_sram_dword(struct amdgpu_device *adev,
u32 smc_address, u32 *value, u32 limit)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&adev->smc_idx_lock, flags);
ret = ci_set_smc_sram_address(adev, smc_address, limit);
if (ret == 0)
*value = RREG32(mmSMC_IND_DATA_0);
spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
return ret;
}
int amdgpu_ci_write_smc_sram_dword(struct amdgpu_device *adev,
u32 smc_address, u32 value, u32 limit)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&adev->smc_idx_lock, flags);
ret = ci_set_smc_sram_address(adev, smc_address, limit);
if (ret == 0)
WREG32(mmSMC_IND_DATA_0, value);
spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/*
* Copyright 2014 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 __CIK_H__
#define __CIK_H__
extern const struct amdgpu_ip_funcs cik_common_ip_funcs;
void cik_srbm_select(struct amdgpu_device *adev,
u32 me, u32 pipe, u32 queue, u32 vmid);
int cik_set_ip_blocks(struct amdgpu_device *adev);
#endif

View File

@ -0,0 +1,30 @@
/*
* Copyright 2014 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 __CIK_DPM_H__
#define __CIK_DPM_H__
extern const struct amdgpu_ip_funcs ci_dpm_ip_funcs;
extern const struct amdgpu_ip_funcs kv_dpm_ip_funcs;
#endif

View File

@ -0,0 +1,453 @@
/*
* 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.
*
*/
#include "drmP.h"
#include "amdgpu.h"
#include "amdgpu_ih.h"
#include "cikd.h"
#include "bif/bif_4_1_d.h"
#include "bif/bif_4_1_sh_mask.h"
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"
/*
* Interrupts
* Starting with r6xx, interrupts are handled via a ring buffer.
* Ring buffers are areas of GPU accessible memory that the GPU
* writes interrupt vectors into and the host reads vectors out of.
* There is a rptr (read pointer) that determines where the
* host is currently reading, and a wptr (write pointer)
* which determines where the GPU has written. When the
* pointers are equal, the ring is idle. When the GPU
* writes vectors to the ring buffer, it increments the
* wptr. When there is an interrupt, the host then starts
* fetching commands and processing them until the pointers are
* equal again at which point it updates the rptr.
*/
static void cik_ih_set_interrupt_funcs(struct amdgpu_device *adev);
/**
* cik_ih_enable_interrupts - Enable the interrupt ring buffer
*
* @adev: amdgpu_device pointer
*
* Enable the interrupt ring buffer (CIK).
*/
static void cik_ih_enable_interrupts(struct amdgpu_device *adev)
{
u32 ih_cntl = RREG32(mmIH_CNTL);
u32 ih_rb_cntl = RREG32(mmIH_RB_CNTL);
ih_cntl |= IH_CNTL__ENABLE_INTR_MASK;
ih_rb_cntl |= IH_RB_CNTL__RB_ENABLE_MASK;
WREG32(mmIH_CNTL, ih_cntl);
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
adev->irq.ih.enabled = true;
}
/**
* cik_ih_disable_interrupts - Disable the interrupt ring buffer
*
* @adev: amdgpu_device pointer
*
* Disable the interrupt ring buffer (CIK).
*/
static void cik_ih_disable_interrupts(struct amdgpu_device *adev)
{
u32 ih_rb_cntl = RREG32(mmIH_RB_CNTL);
u32 ih_cntl = RREG32(mmIH_CNTL);
ih_rb_cntl &= ~IH_RB_CNTL__RB_ENABLE_MASK;
ih_cntl &= ~IH_CNTL__ENABLE_INTR_MASK;
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
WREG32(mmIH_CNTL, ih_cntl);
/* set rptr, wptr to 0 */
WREG32(mmIH_RB_RPTR, 0);
WREG32(mmIH_RB_WPTR, 0);
adev->irq.ih.enabled = false;
adev->irq.ih.rptr = 0;
}
/**
* cik_ih_irq_init - init and enable the interrupt ring
*
* @adev: amdgpu_device pointer
*
* Allocate a ring buffer for the interrupt controller,
* enable the RLC, disable interrupts, enable the IH
* ring buffer and enable it (CIK).
* Called at device load and reume.
* Returns 0 for success, errors for failure.
*/
static int cik_ih_irq_init(struct amdgpu_device *adev)
{
int ret = 0;
int rb_bufsz;
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
u64 wptr_off;
/* disable irqs */
cik_ih_disable_interrupts(adev);
/* setup interrupt control */
WREG32(mmINTERRUPT_CNTL2, adev->dummy_page.addr >> 8);
interrupt_cntl = RREG32(mmINTERRUPT_CNTL);
/* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
*/
interrupt_cntl &= ~INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK;
/* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
interrupt_cntl &= ~INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK;
WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
ih_rb_cntl = (IH_RB_CNTL__WPTR_OVERFLOW_ENABLE_MASK |
IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK |
(rb_bufsz << 1));
ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK;
/* set the writeback address whether it's enabled or not */
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
/* set rptr, wptr to 0 */
WREG32(mmIH_RB_RPTR, 0);
WREG32(mmIH_RB_WPTR, 0);
/* Default settings for IH_CNTL (disabled at first) */
ih_cntl = (0x10 << IH_CNTL__MC_WRREQ_CREDIT__SHIFT) |
(0x10 << IH_CNTL__MC_WR_CLEAN_CNT__SHIFT) |
(0 << IH_CNTL__MC_VMID__SHIFT);
/* IH_CNTL__RPTR_REARM_MASK only works if msi's are enabled */
if (adev->irq.msi_enabled)
ih_cntl |= IH_CNTL__RPTR_REARM_MASK;
WREG32(mmIH_CNTL, ih_cntl);
pci_set_master(adev->pdev);
/* enable irqs */
cik_ih_enable_interrupts(adev);
return ret;
}
/**
* cik_ih_irq_disable - disable interrupts
*
* @adev: amdgpu_device pointer
*
* Disable interrupts on the hw (CIK).
*/
static void cik_ih_irq_disable(struct amdgpu_device *adev)
{
cik_ih_disable_interrupts(adev);
/* Wait and acknowledge irq */
mdelay(1);
}
/**
* cik_ih_get_wptr - get the IH ring buffer wptr
*
* @adev: amdgpu_device pointer
*
* Get the IH ring buffer wptr from either the register
* or the writeback memory buffer (CIK). Also check for
* ring buffer overflow and deal with it.
* Used by cik_irq_process().
* Returns the value of the wptr.
*/
static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
{
u32 wptr, tmp;
wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
/* When a ring buffer overflow happen start parsing interrupt
* from the last not overwritten vector (wptr + 16). Hopefully
* this should allow us to catchup.
*/
dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
tmp = RREG32(mmIH_RB_CNTL);
tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
WREG32(mmIH_RB_CNTL, tmp);
}
return (wptr & adev->irq.ih.ptr_mask);
}
/* CIK IV Ring
* Each IV ring entry is 128 bits:
* [7:0] - interrupt source id
* [31:8] - reserved
* [59:32] - interrupt source data
* [63:60] - reserved
* [71:64] - RINGID
* CP:
* ME_ID [1:0], PIPE_ID[1:0], QUEUE_ID[2:0]
* QUEUE_ID - for compute, which of the 8 queues owned by the dispatcher
* - for gfx, hw shader state (0=PS...5=LS, 6=CS)
* ME_ID - 0 = gfx, 1 = first 4 CS pipes, 2 = second 4 CS pipes
* PIPE_ID - ME0 0=3D
* - ME1&2 compute dispatcher (4 pipes each)
* SDMA:
* INSTANCE_ID [1:0], QUEUE_ID[1:0]
* INSTANCE_ID - 0 = sdma0, 1 = sdma1
* QUEUE_ID - 0 = gfx, 1 = rlc0, 2 = rlc1
* [79:72] - VMID
* [95:80] - PASID
* [127:96] - reserved
*/
/**
* cik_ih_decode_iv - decode an interrupt vector
*
* @adev: amdgpu_device pointer
*
* Decodes the interrupt vector at the current rptr
* position and also advance the position.
*/
static void cik_ih_decode_iv(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry)
{
/* wptr/rptr are in bytes! */
u32 ring_index = adev->irq.ih.rptr >> 2;
uint32_t dw[4];
dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
entry->src_id = dw[0] & 0xff;
entry->src_data = dw[1] & 0xfffffff;
entry->ring_id = dw[2] & 0xff;
entry->vm_id = (dw[2] >> 8) & 0xff;
entry->pas_id = (dw[2] >> 16) & 0xffff;
/* wptr/rptr are in bytes! */
adev->irq.ih.rptr += 16;
}
/**
* cik_ih_set_rptr - set the IH ring buffer rptr
*
* @adev: amdgpu_device pointer
*
* Set the IH ring buffer rptr.
*/
static void cik_ih_set_rptr(struct amdgpu_device *adev)
{
WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
}
static int cik_ih_early_init(struct amdgpu_device *adev)
{
cik_ih_set_interrupt_funcs(adev);
return 0;
}
static int cik_ih_sw_init(struct amdgpu_device *adev)
{
int r;
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
if (r)
return r;
r = amdgpu_irq_init(adev);
return r;
}
static int cik_ih_sw_fini(struct amdgpu_device *adev)
{
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev);
return 0;
}
static int cik_ih_hw_init(struct amdgpu_device *adev)
{
int r;
r = cik_ih_irq_init(adev);
if (r)
return r;
return 0;
}
static int cik_ih_hw_fini(struct amdgpu_device *adev)
{
cik_ih_irq_disable(adev);
return 0;
}
static int cik_ih_suspend(struct amdgpu_device *adev)
{
return cik_ih_hw_fini(adev);
}
static int cik_ih_resume(struct amdgpu_device *adev)
{
return cik_ih_hw_init(adev);
}
static bool cik_ih_is_idle(struct amdgpu_device *adev)
{
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__IH_BUSY_MASK)
return false;
return true;
}
static int cik_ih_wait_for_idle(struct amdgpu_device *adev)
{
unsigned i;
u32 tmp;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
tmp = RREG32(mmSRBM_STATUS) & SRBM_STATUS__IH_BUSY_MASK;
if (!tmp)
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static void cik_ih_print_status(struct amdgpu_device *adev)
{
dev_info(adev->dev, "CIK IH registers\n");
dev_info(adev->dev, " SRBM_STATUS=0x%08X\n",
RREG32(mmSRBM_STATUS));
dev_info(adev->dev, " SRBM_STATUS2=0x%08X\n",
RREG32(mmSRBM_STATUS2));
dev_info(adev->dev, " INTERRUPT_CNTL=0x%08X\n",
RREG32(mmINTERRUPT_CNTL));
dev_info(adev->dev, " INTERRUPT_CNTL2=0x%08X\n",
RREG32(mmINTERRUPT_CNTL2));
dev_info(adev->dev, " IH_CNTL=0x%08X\n",
RREG32(mmIH_CNTL));
dev_info(adev->dev, " IH_RB_CNTL=0x%08X\n",
RREG32(mmIH_RB_CNTL));
dev_info(adev->dev, " IH_RB_BASE=0x%08X\n",
RREG32(mmIH_RB_BASE));
dev_info(adev->dev, " IH_RB_WPTR_ADDR_LO=0x%08X\n",
RREG32(mmIH_RB_WPTR_ADDR_LO));
dev_info(adev->dev, " IH_RB_WPTR_ADDR_HI=0x%08X\n",
RREG32(mmIH_RB_WPTR_ADDR_HI));
dev_info(adev->dev, " IH_RB_RPTR=0x%08X\n",
RREG32(mmIH_RB_RPTR));
dev_info(adev->dev, " IH_RB_WPTR=0x%08X\n",
RREG32(mmIH_RB_WPTR));
}
static int cik_ih_soft_reset(struct amdgpu_device *adev)
{
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__IH_BUSY_MASK)
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_IH_MASK;
if (srbm_soft_reset) {
cik_ih_print_status(adev);
tmp = RREG32(mmSRBM_SOFT_RESET);
tmp |= srbm_soft_reset;
dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
WREG32(mmSRBM_SOFT_RESET, tmp);
tmp = RREG32(mmSRBM_SOFT_RESET);
udelay(50);
tmp &= ~srbm_soft_reset;
WREG32(mmSRBM_SOFT_RESET, tmp);
tmp = RREG32(mmSRBM_SOFT_RESET);
/* Wait a little for things to settle down */
udelay(50);
cik_ih_print_status(adev);
}
return 0;
}
static int cik_ih_set_clockgating_state(struct amdgpu_device *adev,
enum amdgpu_clockgating_state state)
{
return 0;
}
static int cik_ih_set_powergating_state(struct amdgpu_device *adev,
enum amdgpu_powergating_state state)
{
return 0;
}
const struct amdgpu_ip_funcs cik_ih_ip_funcs = {
.early_init = cik_ih_early_init,
.late_init = NULL,
.sw_init = cik_ih_sw_init,
.sw_fini = cik_ih_sw_fini,
.hw_init = cik_ih_hw_init,
.hw_fini = cik_ih_hw_fini,
.suspend = cik_ih_suspend,
.resume = cik_ih_resume,
.is_idle = cik_ih_is_idle,
.wait_for_idle = cik_ih_wait_for_idle,
.soft_reset = cik_ih_soft_reset,
.print_status = cik_ih_print_status,
.set_clockgating_state = cik_ih_set_clockgating_state,
.set_powergating_state = cik_ih_set_powergating_state,
};
static const struct amdgpu_ih_funcs cik_ih_funcs = {
.get_wptr = cik_ih_get_wptr,
.decode_iv = cik_ih_decode_iv,
.set_rptr = cik_ih_set_rptr
};
static void cik_ih_set_interrupt_funcs(struct amdgpu_device *adev)
{
if (adev->irq.ih_funcs == NULL)
adev->irq.ih_funcs = &cik_ih_funcs;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 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 __CIK_IH_H__
#define __CIK_IH_H__
extern const struct amdgpu_ip_funcs cik_ih_ip_funcs;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 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 __CIK_SDMA_H__
#define __CIK_SDMA_H__
extern const struct amdgpu_ip_funcs cik_sdma_ip_funcs;
#endif

View File

@ -0,0 +1,944 @@
/*
* Copyright 2013 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.
*
*/
static const unsigned int ci_SECT_CONTEXT_def_1[] =
{
0x00000000, // DB_RENDER_CONTROL
0x00000000, // DB_COUNT_CONTROL
0x00000000, // DB_DEPTH_VIEW
0x00000000, // DB_RENDER_OVERRIDE
0x00000000, // DB_RENDER_OVERRIDE2
0x00000000, // DB_HTILE_DATA_BASE
0, // HOLE
0, // HOLE
0x00000000, // DB_DEPTH_BOUNDS_MIN
0x00000000, // DB_DEPTH_BOUNDS_MAX
0x00000000, // DB_STENCIL_CLEAR
0x00000000, // DB_DEPTH_CLEAR
0x00000000, // PA_SC_SCREEN_SCISSOR_TL
0x40004000, // PA_SC_SCREEN_SCISSOR_BR
0, // HOLE
0x00000000, // DB_DEPTH_INFO
0x00000000, // DB_Z_INFO
0x00000000, // DB_STENCIL_INFO
0x00000000, // DB_Z_READ_BASE
0x00000000, // DB_STENCIL_READ_BASE
0x00000000, // DB_Z_WRITE_BASE
0x00000000, // DB_STENCIL_WRITE_BASE
0x00000000, // DB_DEPTH_SIZE
0x00000000, // DB_DEPTH_SLICE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // TA_BC_BASE_ADDR
0x00000000, // TA_BC_BASE_ADDR_HI
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // COHER_DEST_BASE_HI_0
0x00000000, // COHER_DEST_BASE_HI_1
0x00000000, // COHER_DEST_BASE_HI_2
0x00000000, // COHER_DEST_BASE_HI_3
0x00000000, // COHER_DEST_BASE_2
0x00000000, // COHER_DEST_BASE_3
0x00000000, // PA_SC_WINDOW_OFFSET
0x80000000, // PA_SC_WINDOW_SCISSOR_TL
0x40004000, // PA_SC_WINDOW_SCISSOR_BR
0x0000ffff, // PA_SC_CLIPRECT_RULE
0x00000000, // PA_SC_CLIPRECT_0_TL
0x40004000, // PA_SC_CLIPRECT_0_BR
0x00000000, // PA_SC_CLIPRECT_1_TL
0x40004000, // PA_SC_CLIPRECT_1_BR
0x00000000, // PA_SC_CLIPRECT_2_TL
0x40004000, // PA_SC_CLIPRECT_2_BR
0x00000000, // PA_SC_CLIPRECT_3_TL
0x40004000, // PA_SC_CLIPRECT_3_BR
0xaa99aaaa, // PA_SC_EDGERULE
0x00000000, // PA_SU_HARDWARE_SCREEN_OFFSET
0xffffffff, // CB_TARGET_MASK
0xffffffff, // CB_SHADER_MASK
0x80000000, // PA_SC_GENERIC_SCISSOR_TL
0x40004000, // PA_SC_GENERIC_SCISSOR_BR
0x00000000, // COHER_DEST_BASE_0
0x00000000, // COHER_DEST_BASE_1
0x80000000, // PA_SC_VPORT_SCISSOR_0_TL
0x40004000, // PA_SC_VPORT_SCISSOR_0_BR
0x80000000, // PA_SC_VPORT_SCISSOR_1_TL
0x40004000, // PA_SC_VPORT_SCISSOR_1_BR
0x80000000, // PA_SC_VPORT_SCISSOR_2_TL
0x40004000, // PA_SC_VPORT_SCISSOR_2_BR
0x80000000, // PA_SC_VPORT_SCISSOR_3_TL
0x40004000, // PA_SC_VPORT_SCISSOR_3_BR
0x80000000, // PA_SC_VPORT_SCISSOR_4_TL
0x40004000, // PA_SC_VPORT_SCISSOR_4_BR
0x80000000, // PA_SC_VPORT_SCISSOR_5_TL
0x40004000, // PA_SC_VPORT_SCISSOR_5_BR
0x80000000, // PA_SC_VPORT_SCISSOR_6_TL
0x40004000, // PA_SC_VPORT_SCISSOR_6_BR
0x80000000, // PA_SC_VPORT_SCISSOR_7_TL
0x40004000, // PA_SC_VPORT_SCISSOR_7_BR
0x80000000, // PA_SC_VPORT_SCISSOR_8_TL
0x40004000, // PA_SC_VPORT_SCISSOR_8_BR
0x80000000, // PA_SC_VPORT_SCISSOR_9_TL
0x40004000, // PA_SC_VPORT_SCISSOR_9_BR
0x80000000, // PA_SC_VPORT_SCISSOR_10_TL
0x40004000, // PA_SC_VPORT_SCISSOR_10_BR
0x80000000, // PA_SC_VPORT_SCISSOR_11_TL
0x40004000, // PA_SC_VPORT_SCISSOR_11_BR
0x80000000, // PA_SC_VPORT_SCISSOR_12_TL
0x40004000, // PA_SC_VPORT_SCISSOR_12_BR
0x80000000, // PA_SC_VPORT_SCISSOR_13_TL
0x40004000, // PA_SC_VPORT_SCISSOR_13_BR
0x80000000, // PA_SC_VPORT_SCISSOR_14_TL
0x40004000, // PA_SC_VPORT_SCISSOR_14_BR
0x80000000, // PA_SC_VPORT_SCISSOR_15_TL
0x40004000, // PA_SC_VPORT_SCISSOR_15_BR
0x00000000, // PA_SC_VPORT_ZMIN_0
0x3f800000, // PA_SC_VPORT_ZMAX_0
0x00000000, // PA_SC_VPORT_ZMIN_1
0x3f800000, // PA_SC_VPORT_ZMAX_1
0x00000000, // PA_SC_VPORT_ZMIN_2
0x3f800000, // PA_SC_VPORT_ZMAX_2
0x00000000, // PA_SC_VPORT_ZMIN_3
0x3f800000, // PA_SC_VPORT_ZMAX_3
0x00000000, // PA_SC_VPORT_ZMIN_4
0x3f800000, // PA_SC_VPORT_ZMAX_4
0x00000000, // PA_SC_VPORT_ZMIN_5
0x3f800000, // PA_SC_VPORT_ZMAX_5
0x00000000, // PA_SC_VPORT_ZMIN_6
0x3f800000, // PA_SC_VPORT_ZMAX_6
0x00000000, // PA_SC_VPORT_ZMIN_7
0x3f800000, // PA_SC_VPORT_ZMAX_7
0x00000000, // PA_SC_VPORT_ZMIN_8
0x3f800000, // PA_SC_VPORT_ZMAX_8
0x00000000, // PA_SC_VPORT_ZMIN_9
0x3f800000, // PA_SC_VPORT_ZMAX_9
0x00000000, // PA_SC_VPORT_ZMIN_10
0x3f800000, // PA_SC_VPORT_ZMAX_10
0x00000000, // PA_SC_VPORT_ZMIN_11
0x3f800000, // PA_SC_VPORT_ZMAX_11
0x00000000, // PA_SC_VPORT_ZMIN_12
0x3f800000, // PA_SC_VPORT_ZMAX_12
0x00000000, // PA_SC_VPORT_ZMIN_13
0x3f800000, // PA_SC_VPORT_ZMAX_13
0x00000000, // PA_SC_VPORT_ZMIN_14
0x3f800000, // PA_SC_VPORT_ZMAX_14
0x00000000, // PA_SC_VPORT_ZMIN_15
0x3f800000, // PA_SC_VPORT_ZMAX_15
};
static const unsigned int ci_SECT_CONTEXT_def_2[] =
{
0x00000000, // PA_SC_SCREEN_EXTENT_CONTROL
0, // HOLE
0x00000000, // CP_PERFMON_CNTX_CNTL
0x00000000, // CP_RINGID
0x00000000, // CP_VMID
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0xffffffff, // VGT_MAX_VTX_INDX
0x00000000, // VGT_MIN_VTX_INDX
0x00000000, // VGT_INDX_OFFSET
0x00000000, // VGT_MULTI_PRIM_IB_RESET_INDX
0, // HOLE
0x00000000, // CB_BLEND_RED
0x00000000, // CB_BLEND_GREEN
0x00000000, // CB_BLEND_BLUE
0x00000000, // CB_BLEND_ALPHA
0, // HOLE
0, // HOLE
0x00000000, // DB_STENCIL_CONTROL
0x00000000, // DB_STENCILREFMASK
0x00000000, // DB_STENCILREFMASK_BF
0, // HOLE
0x00000000, // PA_CL_VPORT_XSCALE
0x00000000, // PA_CL_VPORT_XOFFSET
0x00000000, // PA_CL_VPORT_YSCALE
0x00000000, // PA_CL_VPORT_YOFFSET
0x00000000, // PA_CL_VPORT_ZSCALE
0x00000000, // PA_CL_VPORT_ZOFFSET
0x00000000, // PA_CL_VPORT_XSCALE_1
0x00000000, // PA_CL_VPORT_XOFFSET_1
0x00000000, // PA_CL_VPORT_YSCALE_1
0x00000000, // PA_CL_VPORT_YOFFSET_1
0x00000000, // PA_CL_VPORT_ZSCALE_1
0x00000000, // PA_CL_VPORT_ZOFFSET_1
0x00000000, // PA_CL_VPORT_XSCALE_2
0x00000000, // PA_CL_VPORT_XOFFSET_2
0x00000000, // PA_CL_VPORT_YSCALE_2
0x00000000, // PA_CL_VPORT_YOFFSET_2
0x00000000, // PA_CL_VPORT_ZSCALE_2
0x00000000, // PA_CL_VPORT_ZOFFSET_2
0x00000000, // PA_CL_VPORT_XSCALE_3
0x00000000, // PA_CL_VPORT_XOFFSET_3
0x00000000, // PA_CL_VPORT_YSCALE_3
0x00000000, // PA_CL_VPORT_YOFFSET_3
0x00000000, // PA_CL_VPORT_ZSCALE_3
0x00000000, // PA_CL_VPORT_ZOFFSET_3
0x00000000, // PA_CL_VPORT_XSCALE_4
0x00000000, // PA_CL_VPORT_XOFFSET_4
0x00000000, // PA_CL_VPORT_YSCALE_4
0x00000000, // PA_CL_VPORT_YOFFSET_4
0x00000000, // PA_CL_VPORT_ZSCALE_4
0x00000000, // PA_CL_VPORT_ZOFFSET_4
0x00000000, // PA_CL_VPORT_XSCALE_5
0x00000000, // PA_CL_VPORT_XOFFSET_5
0x00000000, // PA_CL_VPORT_YSCALE_5
0x00000000, // PA_CL_VPORT_YOFFSET_5
0x00000000, // PA_CL_VPORT_ZSCALE_5
0x00000000, // PA_CL_VPORT_ZOFFSET_5
0x00000000, // PA_CL_VPORT_XSCALE_6
0x00000000, // PA_CL_VPORT_XOFFSET_6
0x00000000, // PA_CL_VPORT_YSCALE_6
0x00000000, // PA_CL_VPORT_YOFFSET_6
0x00000000, // PA_CL_VPORT_ZSCALE_6
0x00000000, // PA_CL_VPORT_ZOFFSET_6
0x00000000, // PA_CL_VPORT_XSCALE_7
0x00000000, // PA_CL_VPORT_XOFFSET_7
0x00000000, // PA_CL_VPORT_YSCALE_7
0x00000000, // PA_CL_VPORT_YOFFSET_7
0x00000000, // PA_CL_VPORT_ZSCALE_7
0x00000000, // PA_CL_VPORT_ZOFFSET_7
0x00000000, // PA_CL_VPORT_XSCALE_8
0x00000000, // PA_CL_VPORT_XOFFSET_8
0x00000000, // PA_CL_VPORT_YSCALE_8
0x00000000, // PA_CL_VPORT_YOFFSET_8
0x00000000, // PA_CL_VPORT_ZSCALE_8
0x00000000, // PA_CL_VPORT_ZOFFSET_8
0x00000000, // PA_CL_VPORT_XSCALE_9
0x00000000, // PA_CL_VPORT_XOFFSET_9
0x00000000, // PA_CL_VPORT_YSCALE_9
0x00000000, // PA_CL_VPORT_YOFFSET_9
0x00000000, // PA_CL_VPORT_ZSCALE_9
0x00000000, // PA_CL_VPORT_ZOFFSET_9
0x00000000, // PA_CL_VPORT_XSCALE_10
0x00000000, // PA_CL_VPORT_XOFFSET_10
0x00000000, // PA_CL_VPORT_YSCALE_10
0x00000000, // PA_CL_VPORT_YOFFSET_10
0x00000000, // PA_CL_VPORT_ZSCALE_10
0x00000000, // PA_CL_VPORT_ZOFFSET_10
0x00000000, // PA_CL_VPORT_XSCALE_11
0x00000000, // PA_CL_VPORT_XOFFSET_11
0x00000000, // PA_CL_VPORT_YSCALE_11
0x00000000, // PA_CL_VPORT_YOFFSET_11
0x00000000, // PA_CL_VPORT_ZSCALE_11
0x00000000, // PA_CL_VPORT_ZOFFSET_11
0x00000000, // PA_CL_VPORT_XSCALE_12
0x00000000, // PA_CL_VPORT_XOFFSET_12
0x00000000, // PA_CL_VPORT_YSCALE_12
0x00000000, // PA_CL_VPORT_YOFFSET_12
0x00000000, // PA_CL_VPORT_ZSCALE_12
0x00000000, // PA_CL_VPORT_ZOFFSET_12
0x00000000, // PA_CL_VPORT_XSCALE_13
0x00000000, // PA_CL_VPORT_XOFFSET_13
0x00000000, // PA_CL_VPORT_YSCALE_13
0x00000000, // PA_CL_VPORT_YOFFSET_13
0x00000000, // PA_CL_VPORT_ZSCALE_13
0x00000000, // PA_CL_VPORT_ZOFFSET_13
0x00000000, // PA_CL_VPORT_XSCALE_14
0x00000000, // PA_CL_VPORT_XOFFSET_14
0x00000000, // PA_CL_VPORT_YSCALE_14
0x00000000, // PA_CL_VPORT_YOFFSET_14
0x00000000, // PA_CL_VPORT_ZSCALE_14
0x00000000, // PA_CL_VPORT_ZOFFSET_14
0x00000000, // PA_CL_VPORT_XSCALE_15
0x00000000, // PA_CL_VPORT_XOFFSET_15
0x00000000, // PA_CL_VPORT_YSCALE_15
0x00000000, // PA_CL_VPORT_YOFFSET_15
0x00000000, // PA_CL_VPORT_ZSCALE_15
0x00000000, // PA_CL_VPORT_ZOFFSET_15
0x00000000, // PA_CL_UCP_0_X
0x00000000, // PA_CL_UCP_0_Y
0x00000000, // PA_CL_UCP_0_Z
0x00000000, // PA_CL_UCP_0_W
0x00000000, // PA_CL_UCP_1_X
0x00000000, // PA_CL_UCP_1_Y
0x00000000, // PA_CL_UCP_1_Z
0x00000000, // PA_CL_UCP_1_W
0x00000000, // PA_CL_UCP_2_X
0x00000000, // PA_CL_UCP_2_Y
0x00000000, // PA_CL_UCP_2_Z
0x00000000, // PA_CL_UCP_2_W
0x00000000, // PA_CL_UCP_3_X
0x00000000, // PA_CL_UCP_3_Y
0x00000000, // PA_CL_UCP_3_Z
0x00000000, // PA_CL_UCP_3_W
0x00000000, // PA_CL_UCP_4_X
0x00000000, // PA_CL_UCP_4_Y
0x00000000, // PA_CL_UCP_4_Z
0x00000000, // PA_CL_UCP_4_W
0x00000000, // PA_CL_UCP_5_X
0x00000000, // PA_CL_UCP_5_Y
0x00000000, // PA_CL_UCP_5_Z
0x00000000, // PA_CL_UCP_5_W
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // SPI_PS_INPUT_CNTL_0
0x00000000, // SPI_PS_INPUT_CNTL_1
0x00000000, // SPI_PS_INPUT_CNTL_2
0x00000000, // SPI_PS_INPUT_CNTL_3
0x00000000, // SPI_PS_INPUT_CNTL_4
0x00000000, // SPI_PS_INPUT_CNTL_5
0x00000000, // SPI_PS_INPUT_CNTL_6
0x00000000, // SPI_PS_INPUT_CNTL_7
0x00000000, // SPI_PS_INPUT_CNTL_8
0x00000000, // SPI_PS_INPUT_CNTL_9
0x00000000, // SPI_PS_INPUT_CNTL_10
0x00000000, // SPI_PS_INPUT_CNTL_11
0x00000000, // SPI_PS_INPUT_CNTL_12
0x00000000, // SPI_PS_INPUT_CNTL_13
0x00000000, // SPI_PS_INPUT_CNTL_14
0x00000000, // SPI_PS_INPUT_CNTL_15
0x00000000, // SPI_PS_INPUT_CNTL_16
0x00000000, // SPI_PS_INPUT_CNTL_17
0x00000000, // SPI_PS_INPUT_CNTL_18
0x00000000, // SPI_PS_INPUT_CNTL_19
0x00000000, // SPI_PS_INPUT_CNTL_20
0x00000000, // SPI_PS_INPUT_CNTL_21
0x00000000, // SPI_PS_INPUT_CNTL_22
0x00000000, // SPI_PS_INPUT_CNTL_23
0x00000000, // SPI_PS_INPUT_CNTL_24
0x00000000, // SPI_PS_INPUT_CNTL_25
0x00000000, // SPI_PS_INPUT_CNTL_26
0x00000000, // SPI_PS_INPUT_CNTL_27
0x00000000, // SPI_PS_INPUT_CNTL_28
0x00000000, // SPI_PS_INPUT_CNTL_29
0x00000000, // SPI_PS_INPUT_CNTL_30
0x00000000, // SPI_PS_INPUT_CNTL_31
0x00000000, // SPI_VS_OUT_CONFIG
0, // HOLE
0x00000000, // SPI_PS_INPUT_ENA
0x00000000, // SPI_PS_INPUT_ADDR
0x00000000, // SPI_INTERP_CONTROL_0
0x00000002, // SPI_PS_IN_CONTROL
0, // HOLE
0x00000000, // SPI_BARYC_CNTL
0, // HOLE
0x00000000, // SPI_TMPRING_SIZE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // SPI_SHADER_POS_FORMAT
0x00000000, // SPI_SHADER_Z_FORMAT
0x00000000, // SPI_SHADER_COL_FORMAT
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // CB_BLEND0_CONTROL
0x00000000, // CB_BLEND1_CONTROL
0x00000000, // CB_BLEND2_CONTROL
0x00000000, // CB_BLEND3_CONTROL
0x00000000, // CB_BLEND4_CONTROL
0x00000000, // CB_BLEND5_CONTROL
0x00000000, // CB_BLEND6_CONTROL
0x00000000, // CB_BLEND7_CONTROL
};
static const unsigned int ci_SECT_CONTEXT_def_3[] =
{
0x00000000, // PA_CL_POINT_X_RAD
0x00000000, // PA_CL_POINT_Y_RAD
0x00000000, // PA_CL_POINT_SIZE
0x00000000, // PA_CL_POINT_CULL_RAD
0x00000000, // VGT_DMA_BASE_HI
0x00000000, // VGT_DMA_BASE
};
static const unsigned int ci_SECT_CONTEXT_def_4[] =
{
0x00000000, // DB_DEPTH_CONTROL
0x00000000, // DB_EQAA
0x00000000, // CB_COLOR_CONTROL
0x00000000, // DB_SHADER_CONTROL
0x00090000, // PA_CL_CLIP_CNTL
0x00000004, // PA_SU_SC_MODE_CNTL
0x00000000, // PA_CL_VTE_CNTL
0x00000000, // PA_CL_VS_OUT_CNTL
0x00000000, // PA_CL_NANINF_CNTL
0x00000000, // PA_SU_LINE_STIPPLE_CNTL
0x00000000, // PA_SU_LINE_STIPPLE_SCALE
0x00000000, // PA_SU_PRIM_FILTER_CNTL
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // PA_SU_POINT_SIZE
0x00000000, // PA_SU_POINT_MINMAX
0x00000000, // PA_SU_LINE_CNTL
0x00000000, // PA_SC_LINE_STIPPLE
0x00000000, // VGT_OUTPUT_PATH_CNTL
0x00000000, // VGT_HOS_CNTL
0x00000000, // VGT_HOS_MAX_TESS_LEVEL
0x00000000, // VGT_HOS_MIN_TESS_LEVEL
0x00000000, // VGT_HOS_REUSE_DEPTH
0x00000000, // VGT_GROUP_PRIM_TYPE
0x00000000, // VGT_GROUP_FIRST_DECR
0x00000000, // VGT_GROUP_DECR
0x00000000, // VGT_GROUP_VECT_0_CNTL
0x00000000, // VGT_GROUP_VECT_1_CNTL
0x00000000, // VGT_GROUP_VECT_0_FMT_CNTL
0x00000000, // VGT_GROUP_VECT_1_FMT_CNTL
0x00000000, // VGT_GS_MODE
0x00000000, // VGT_GS_ONCHIP_CNTL
0x00000000, // PA_SC_MODE_CNTL_0
0x00000000, // PA_SC_MODE_CNTL_1
0x00000000, // VGT_ENHANCE
0x00000100, // VGT_GS_PER_ES
0x00000080, // VGT_ES_PER_GS
0x00000002, // VGT_GS_PER_VS
0x00000000, // VGT_GSVS_RING_OFFSET_1
0x00000000, // VGT_GSVS_RING_OFFSET_2
0x00000000, // VGT_GSVS_RING_OFFSET_3
0x00000000, // VGT_GS_OUT_PRIM_TYPE
0x00000000, // IA_ENHANCE
};
static const unsigned int ci_SECT_CONTEXT_def_5[] =
{
0x00000000, // WD_ENHANCE
0x00000000, // VGT_PRIMITIVEID_EN
};
static const unsigned int ci_SECT_CONTEXT_def_6[] =
{
0x00000000, // VGT_PRIMITIVEID_RESET
};
static const unsigned int ci_SECT_CONTEXT_def_7[] =
{
0x00000000, // VGT_MULTI_PRIM_IB_RESET_EN
0, // HOLE
0, // HOLE
0x00000000, // VGT_INSTANCE_STEP_RATE_0
0x00000000, // VGT_INSTANCE_STEP_RATE_1
0x000000ff, // IA_MULTI_VGT_PARAM
0x00000000, // VGT_ESGS_RING_ITEMSIZE
0x00000000, // VGT_GSVS_RING_ITEMSIZE
0x00000000, // VGT_REUSE_OFF
0x00000000, // VGT_VTX_CNT_EN
0x00000000, // DB_HTILE_SURFACE
0x00000000, // DB_SRESULTS_COMPARE_STATE0
0x00000000, // DB_SRESULTS_COMPARE_STATE1
0x00000000, // DB_PRELOAD_CONTROL
0, // HOLE
0x00000000, // VGT_STRMOUT_BUFFER_SIZE_0
0x00000000, // VGT_STRMOUT_VTX_STRIDE_0
0, // HOLE
0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_0
0x00000000, // VGT_STRMOUT_BUFFER_SIZE_1
0x00000000, // VGT_STRMOUT_VTX_STRIDE_1
0, // HOLE
0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_1
0x00000000, // VGT_STRMOUT_BUFFER_SIZE_2
0x00000000, // VGT_STRMOUT_VTX_STRIDE_2
0, // HOLE
0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_2
0x00000000, // VGT_STRMOUT_BUFFER_SIZE_3
0x00000000, // VGT_STRMOUT_VTX_STRIDE_3
0, // HOLE
0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_3
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_OFFSET
0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
0, // HOLE
0x00000000, // VGT_GS_MAX_VERT_OUT
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // VGT_SHADER_STAGES_EN
0x00000000, // VGT_LS_HS_CONFIG
0x00000000, // VGT_GS_VERT_ITEMSIZE
0x00000000, // VGT_GS_VERT_ITEMSIZE_1
0x00000000, // VGT_GS_VERT_ITEMSIZE_2
0x00000000, // VGT_GS_VERT_ITEMSIZE_3
0x00000000, // VGT_TF_PARAM
0x00000000, // DB_ALPHA_TO_MASK
0, // HOLE
0x00000000, // PA_SU_POLY_OFFSET_DB_FMT_CNTL
0x00000000, // PA_SU_POLY_OFFSET_CLAMP
0x00000000, // PA_SU_POLY_OFFSET_FRONT_SCALE
0x00000000, // PA_SU_POLY_OFFSET_FRONT_OFFSET
0x00000000, // PA_SU_POLY_OFFSET_BACK_SCALE
0x00000000, // PA_SU_POLY_OFFSET_BACK_OFFSET
0x00000000, // VGT_GS_INSTANCE_CNT
0x00000000, // VGT_STRMOUT_CONFIG
0x00000000, // VGT_STRMOUT_BUFFER_CONFIG
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x00000000, // PA_SC_CENTROID_PRIORITY_0
0x00000000, // PA_SC_CENTROID_PRIORITY_1
0x00001000, // PA_SC_LINE_CNTL
0x00000000, // PA_SC_AA_CONFIG
0x00000005, // PA_SU_VTX_CNTL
0x3f800000, // PA_CL_GB_VERT_CLIP_ADJ
0x3f800000, // PA_CL_GB_VERT_DISC_ADJ
0x3f800000, // PA_CL_GB_HORZ_CLIP_ADJ
0x3f800000, // PA_CL_GB_HORZ_DISC_ADJ
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2
0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3
0xffffffff, // PA_SC_AA_MASK_X0Y0_X1Y0
0xffffffff, // PA_SC_AA_MASK_X0Y1_X1Y1
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0, // HOLE
0x0000000e, // VGT_VERTEX_REUSE_BLOCK_CNTL
0x00000010, // VGT_OUT_DEALLOC_CNTL
0x00000000, // CB_COLOR0_BASE
0x00000000, // CB_COLOR0_PITCH
0x00000000, // CB_COLOR0_SLICE
0x00000000, // CB_COLOR0_VIEW
0x00000000, // CB_COLOR0_INFO
0x00000000, // CB_COLOR0_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR0_CMASK
0x00000000, // CB_COLOR0_CMASK_SLICE
0x00000000, // CB_COLOR0_FMASK
0x00000000, // CB_COLOR0_FMASK_SLICE
0x00000000, // CB_COLOR0_CLEAR_WORD0
0x00000000, // CB_COLOR0_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR1_BASE
0x00000000, // CB_COLOR1_PITCH
0x00000000, // CB_COLOR1_SLICE
0x00000000, // CB_COLOR1_VIEW
0x00000000, // CB_COLOR1_INFO
0x00000000, // CB_COLOR1_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR1_CMASK
0x00000000, // CB_COLOR1_CMASK_SLICE
0x00000000, // CB_COLOR1_FMASK
0x00000000, // CB_COLOR1_FMASK_SLICE
0x00000000, // CB_COLOR1_CLEAR_WORD0
0x00000000, // CB_COLOR1_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR2_BASE
0x00000000, // CB_COLOR2_PITCH
0x00000000, // CB_COLOR2_SLICE
0x00000000, // CB_COLOR2_VIEW
0x00000000, // CB_COLOR2_INFO
0x00000000, // CB_COLOR2_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR2_CMASK
0x00000000, // CB_COLOR2_CMASK_SLICE
0x00000000, // CB_COLOR2_FMASK
0x00000000, // CB_COLOR2_FMASK_SLICE
0x00000000, // CB_COLOR2_CLEAR_WORD0
0x00000000, // CB_COLOR2_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR3_BASE
0x00000000, // CB_COLOR3_PITCH
0x00000000, // CB_COLOR3_SLICE
0x00000000, // CB_COLOR3_VIEW
0x00000000, // CB_COLOR3_INFO
0x00000000, // CB_COLOR3_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR3_CMASK
0x00000000, // CB_COLOR3_CMASK_SLICE
0x00000000, // CB_COLOR3_FMASK
0x00000000, // CB_COLOR3_FMASK_SLICE
0x00000000, // CB_COLOR3_CLEAR_WORD0
0x00000000, // CB_COLOR3_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR4_BASE
0x00000000, // CB_COLOR4_PITCH
0x00000000, // CB_COLOR4_SLICE
0x00000000, // CB_COLOR4_VIEW
0x00000000, // CB_COLOR4_INFO
0x00000000, // CB_COLOR4_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR4_CMASK
0x00000000, // CB_COLOR4_CMASK_SLICE
0x00000000, // CB_COLOR4_FMASK
0x00000000, // CB_COLOR4_FMASK_SLICE
0x00000000, // CB_COLOR4_CLEAR_WORD0
0x00000000, // CB_COLOR4_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR5_BASE
0x00000000, // CB_COLOR5_PITCH
0x00000000, // CB_COLOR5_SLICE
0x00000000, // CB_COLOR5_VIEW
0x00000000, // CB_COLOR5_INFO
0x00000000, // CB_COLOR5_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR5_CMASK
0x00000000, // CB_COLOR5_CMASK_SLICE
0x00000000, // CB_COLOR5_FMASK
0x00000000, // CB_COLOR5_FMASK_SLICE
0x00000000, // CB_COLOR5_CLEAR_WORD0
0x00000000, // CB_COLOR5_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR6_BASE
0x00000000, // CB_COLOR6_PITCH
0x00000000, // CB_COLOR6_SLICE
0x00000000, // CB_COLOR6_VIEW
0x00000000, // CB_COLOR6_INFO
0x00000000, // CB_COLOR6_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR6_CMASK
0x00000000, // CB_COLOR6_CMASK_SLICE
0x00000000, // CB_COLOR6_FMASK
0x00000000, // CB_COLOR6_FMASK_SLICE
0x00000000, // CB_COLOR6_CLEAR_WORD0
0x00000000, // CB_COLOR6_CLEAR_WORD1
0, // HOLE
0, // HOLE
0x00000000, // CB_COLOR7_BASE
0x00000000, // CB_COLOR7_PITCH
0x00000000, // CB_COLOR7_SLICE
0x00000000, // CB_COLOR7_VIEW
0x00000000, // CB_COLOR7_INFO
0x00000000, // CB_COLOR7_ATTRIB
0, // HOLE
0x00000000, // CB_COLOR7_CMASK
0x00000000, // CB_COLOR7_CMASK_SLICE
0x00000000, // CB_COLOR7_FMASK
0x00000000, // CB_COLOR7_FMASK_SLICE
0x00000000, // CB_COLOR7_CLEAR_WORD0
0x00000000, // CB_COLOR7_CLEAR_WORD1
};
static const struct cs_extent_def ci_SECT_CONTEXT_defs[] =
{
{ci_SECT_CONTEXT_def_1, 0x0000a000, 212 },
{ci_SECT_CONTEXT_def_2, 0x0000a0d6, 274 },
{ci_SECT_CONTEXT_def_3, 0x0000a1f5, 6 },
{ci_SECT_CONTEXT_def_4, 0x0000a200, 157 },
{ci_SECT_CONTEXT_def_5, 0x0000a2a0, 2 },
{ci_SECT_CONTEXT_def_6, 0x0000a2a3, 1 },
{ci_SECT_CONTEXT_def_7, 0x0000a2a5, 233 },
{ 0, 0, 0 }
};
static const struct cs_section_def ci_cs_data[] = {
{ ci_SECT_CONTEXT_defs, SECT_CONTEXT },
{ 0, SECT_NONE }
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 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 __DCE_V8_0_H__
#define __DCE_V8_0_H__
extern const struct amdgpu_ip_funcs dce_v8_0_ip_funcs;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/*
* Copyright 2014 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 __GFX_V7_0_H__
#define __GFX_V7_0_H__
extern const struct amdgpu_ip_funcs gfx_v7_0_ip_funcs;
/* XXX these shouldn't be exported */
void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev);
void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev);
void gfx_v7_0_rlc_stop(struct amdgpu_device *adev);
uint64_t gfx_v7_0_get_gpu_clock_counter(struct amdgpu_device *adev);
void gfx_v7_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num);
int gfx_v7_0_get_cu_info(struct amdgpu_device *adev, struct amdgpu_cu_info *cu_info);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
/*
* Copyright 2014 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 __GMC_V7_0_H__
#define __GMC_V7_0_H__
extern const struct amdgpu_ip_funcs gmc_v7_0_ip_funcs;
/* XXX these shouldn't be exported */
void gmc_v7_0_mc_stop(struct amdgpu_device *adev,
struct amdgpu_mode_mc_save *save);
void gmc_v7_0_mc_resume(struct amdgpu_device *adev,
struct amdgpu_mode_mc_save *save);
int gmc_v7_0_mc_wait_for_idle(struct amdgpu_device *adev);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
/*
* Copyright 2013 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 __KV_DPM_H__
#define __KV_DPM_H__
#define SMU__NUM_SCLK_DPM_STATE 8
#define SMU__NUM_MCLK_DPM_LEVELS 4
#define SMU__NUM_LCLK_DPM_LEVELS 8
#define SMU__NUM_PCIE_DPM_LEVELS 0 /* ??? */
#include "smu7_fusion.h"
#include "ppsmc.h"
#define SUMO_MAX_HARDWARE_POWERLEVELS 5
#define SUMO_MAX_NUMBER_VOLTAGES 4
struct sumo_vid_mapping_entry {
u16 vid_2bit;
u16 vid_7bit;
};
struct sumo_vid_mapping_table {
u32 num_entries;
struct sumo_vid_mapping_entry entries[SUMO_MAX_NUMBER_VOLTAGES];
};
struct sumo_sclk_voltage_mapping_entry {
u32 sclk_frequency;
u16 vid_2bit;
u16 rsv;
};
struct sumo_sclk_voltage_mapping_table {
u32 num_max_dpm_entries;
struct sumo_sclk_voltage_mapping_entry entries[SUMO_MAX_HARDWARE_POWERLEVELS];
};
#define TRINITY_AT_DFLT 30
#define KV_NUM_NBPSTATES 4
enum kv_pt_config_reg_type {
KV_CONFIGREG_MMR = 0,
KV_CONFIGREG_SMC_IND,
KV_CONFIGREG_DIDT_IND,
KV_CONFIGREG_CACHE,
KV_CONFIGREG_MAX
};
struct kv_pt_config_reg {
u32 offset;
u32 mask;
u32 shift;
u32 value;
enum kv_pt_config_reg_type type;
};
struct kv_lcac_config_values {
u32 block_id;
u32 signal_id;
u32 t;
};
struct kv_lcac_config_reg {
u32 cntl;
u32 block_mask;
u32 block_shift;
u32 signal_mask;
u32 signal_shift;
u32 t_mask;
u32 t_shift;
u32 enable_mask;
u32 enable_shift;
};
struct kv_pl {
u32 sclk;
u8 vddc_index;
u8 ds_divider_index;
u8 ss_divider_index;
u8 allow_gnb_slow;
u8 force_nbp_state;
u8 display_wm;
u8 vce_wm;
};
struct kv_ps {
struct kv_pl levels[SUMO_MAX_HARDWARE_POWERLEVELS];
u32 num_levels;
bool need_dfs_bypass;
u8 dpm0_pg_nb_ps_lo;
u8 dpm0_pg_nb_ps_hi;
u8 dpmx_nb_ps_lo;
u8 dpmx_nb_ps_hi;
};
struct kv_sys_info {
u32 bootup_uma_clk;
u32 bootup_sclk;
u32 dentist_vco_freq;
u32 nb_dpm_enable;
u32 nbp_memory_clock[KV_NUM_NBPSTATES];
u32 nbp_n_clock[KV_NUM_NBPSTATES];
u16 bootup_nb_voltage_index;
u8 htc_tmp_lmt;
u8 htc_hyst_lmt;
struct sumo_sclk_voltage_mapping_table sclk_voltage_mapping_table;
struct sumo_vid_mapping_table vid_mapping_table;
u32 uma_channel_number;
};
struct kv_power_info {
u32 at[SUMO_MAX_HARDWARE_POWERLEVELS];
u32 voltage_drop_t;
struct kv_sys_info sys_info;
struct kv_pl boot_pl;
bool enable_nb_ps_policy;
bool disable_nb_ps3_in_battery;
bool video_start;
bool battery_state;
u32 lowest_valid;
u32 highest_valid;
u16 high_voltage_t;
bool cac_enabled;
bool bapm_enable;
/* smc offsets */
u32 sram_end;
u32 dpm_table_start;
u32 soft_regs_start;
/* dpm SMU tables */
u8 graphics_dpm_level_count;
u8 uvd_level_count;
u8 vce_level_count;
u8 acp_level_count;
u8 samu_level_count;
u16 fps_high_t;
SMU7_Fusion_GraphicsLevel graphics_level[SMU__NUM_SCLK_DPM_STATE];
SMU7_Fusion_ACPILevel acpi_level;
SMU7_Fusion_UvdLevel uvd_level[SMU7_MAX_LEVELS_UVD];
SMU7_Fusion_ExtClkLevel vce_level[SMU7_MAX_LEVELS_VCE];
SMU7_Fusion_ExtClkLevel acp_level[SMU7_MAX_LEVELS_ACP];
SMU7_Fusion_ExtClkLevel samu_level[SMU7_MAX_LEVELS_SAMU];
u8 uvd_boot_level;
u8 vce_boot_level;
u8 acp_boot_level;
u8 samu_boot_level;
u8 uvd_interval;
u8 vce_interval;
u8 acp_interval;
u8 samu_interval;
u8 graphics_boot_level;
u8 graphics_interval;
u8 graphics_therm_throttle_enable;
u8 graphics_voltage_change_enable;
u8 graphics_clk_slow_enable;
u8 graphics_clk_slow_divider;
u8 fps_low_t;
u32 low_sclk_interrupt_t;
bool uvd_power_gated;
bool vce_power_gated;
bool acp_power_gated;
bool samu_power_gated;
bool nb_dpm_enabled;
/* flags */
bool enable_didt;
bool enable_dpm;
bool enable_auto_thermal_throttling;
bool enable_nb_dpm;
/* caps */
bool caps_cac;
bool caps_power_containment;
bool caps_sq_ramping;
bool caps_db_ramping;
bool caps_td_ramping;
bool caps_tcp_ramping;
bool caps_sclk_throttle_low_notification;
bool caps_fps;
bool caps_uvd_dpm;
bool caps_uvd_pg;
bool caps_vce_pg;
bool caps_samu_pg;
bool caps_acp_pg;
bool caps_stable_p_state;
bool caps_enable_dfs_bypass;
bool caps_sclk_ds;
struct amdgpu_ps current_rps;
struct kv_ps current_ps;
struct amdgpu_ps requested_rps;
struct kv_ps requested_ps;
};
/* XXX are these ok? */
#define KV_TEMP_RANGE_MIN (90 * 1000)
#define KV_TEMP_RANGE_MAX (120 * 1000)
/* kv_smc.c */
int amdgpu_kv_notify_message_to_smu(struct amdgpu_device *adev, u32 id);
int amdgpu_kv_dpm_get_enable_mask(struct amdgpu_device *adev, u32 *enable_mask);
int amdgpu_kv_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
PPSMC_Msg msg, u32 parameter);
int amdgpu_kv_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
u32 *value, u32 limit);
int amdgpu_kv_smc_dpm_enable(struct amdgpu_device *adev, bool enable);
int amdgpu_kv_smc_bapm_enable(struct amdgpu_device *adev, bool enable);
int amdgpu_kv_copy_bytes_to_smc(struct amdgpu_device *adev,
u32 smc_start_address,
const u8 *src, u32 byte_count, u32 limit);
#endif

View File

@ -0,0 +1,219 @@
/*
* Copyright 2013 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.
*
* Authors: Alex Deucher
*/
#include "drmP.h"
#include "amdgpu.h"
#include "cikd.h"
#include "kv_dpm.h"
#include "smu/smu_7_0_0_d.h"
#include "smu/smu_7_0_0_sh_mask.h"
int amdgpu_kv_notify_message_to_smu(struct amdgpu_device *adev, u32 id)
{
u32 i;
u32 tmp = 0;
WREG32(mmSMC_MESSAGE_0, id & SMC_MESSAGE_0__SMC_MSG_MASK);
for (i = 0; i < adev->usec_timeout; i++) {
if ((RREG32(mmSMC_RESP_0) & SMC_RESP_0__SMC_RESP_MASK) != 0)
break;
udelay(1);
}
tmp = RREG32(mmSMC_RESP_0) & SMC_RESP_0__SMC_RESP_MASK;
if (tmp != 1) {
if (tmp == 0xFF)
return -EINVAL;
else if (tmp == 0xFE)
return -EINVAL;
}
return 0;
}
int amdgpu_kv_dpm_get_enable_mask(struct amdgpu_device *adev, u32 *enable_mask)
{
int ret;
ret = amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_SCLKDPM_GetEnabledMask);
if (ret == 0)
*enable_mask = RREG32_SMC(ixSMC_SYSCON_MSG_ARG_0);
return ret;
}
int amdgpu_kv_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
PPSMC_Msg msg, u32 parameter)
{
WREG32(mmSMC_MSG_ARG_0, parameter);
return amdgpu_kv_notify_message_to_smu(adev, msg);
}
static int kv_set_smc_sram_address(struct amdgpu_device *adev,
u32 smc_address, u32 limit)
{
if (smc_address & 3)
return -EINVAL;
if ((smc_address + 3) > limit)
return -EINVAL;
WREG32(mmSMC_IND_INDEX_0, smc_address);
WREG32_P(mmSMC_IND_ACCESS_CNTL, 0,
~SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK);
return 0;
}
int amdgpu_kv_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
u32 *value, u32 limit)
{
int ret;
ret = kv_set_smc_sram_address(adev, smc_address, limit);
if (ret)
return ret;
*value = RREG32(mmSMC_IND_DATA_0);
return 0;
}
int amdgpu_kv_smc_dpm_enable(struct amdgpu_device *adev, bool enable)
{
if (enable)
return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DPM_Enable);
else
return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DPM_Disable);
}
int amdgpu_kv_smc_bapm_enable(struct amdgpu_device *adev, bool enable)
{
if (enable)
return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_EnableBAPM);
else
return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DisableBAPM);
}
int amdgpu_kv_copy_bytes_to_smc(struct amdgpu_device *adev,
u32 smc_start_address,
const u8 *src, u32 byte_count, u32 limit)
{
int ret;
u32 data, original_data, addr, extra_shift, t_byte, count, mask;
if ((smc_start_address + byte_count) > limit)
return -EINVAL;
addr = smc_start_address;
t_byte = addr & 3;
/* RMW for the initial bytes */
if (t_byte != 0) {
addr -= t_byte;
ret = kv_set_smc_sram_address(adev, addr, limit);
if (ret)
return ret;
original_data = RREG32(mmSMC_IND_DATA_0);
data = 0;
mask = 0;
count = 4;
while (count > 0) {
if (t_byte > 0) {
mask = (mask << 8) | 0xff;
t_byte--;
} else if (byte_count > 0) {
data = (data << 8) + *src++;
byte_count--;
mask <<= 8;
} else {
data <<= 8;
mask = (mask << 8) | 0xff;
}
count--;
}
data |= original_data & mask;
ret = kv_set_smc_sram_address(adev, addr, limit);
if (ret)
return ret;
WREG32(mmSMC_IND_DATA_0, data);
addr += 4;
}
while (byte_count >= 4) {
/* SMC address space is BE */
data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
ret = kv_set_smc_sram_address(adev, addr, limit);
if (ret)
return ret;
WREG32(mmSMC_IND_DATA_0, data);
src += 4;
byte_count -= 4;
addr += 4;
}
/* RMW for the final bytes */
if (byte_count > 0) {
data = 0;
ret = kv_set_smc_sram_address(adev, addr, limit);
if (ret)
return ret;
original_data = RREG32(mmSMC_IND_DATA_0);
extra_shift = 8 * (4 - byte_count);
while (byte_count > 0) {
/* SMC address space is BE */
data = (data << 8) + *src++;
byte_count--;
}
data <<= extra_shift;
data |= (original_data & ~((~0UL) << extra_shift));
ret = kv_set_smc_sram_address(adev, addr, limit);
if (ret)
return ret;
WREG32(mmSMC_IND_DATA_0, data);
}
return 0;
}

View File

@ -0,0 +1,170 @@
/*
* Copyright 2013 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 SMU7_H
#define SMU7_H
#pragma pack(push, 1)
#define SMU7_CONTEXT_ID_SMC 1
#define SMU7_CONTEXT_ID_VBIOS 2
#define SMU7_CONTEXT_ID_SMC 1
#define SMU7_CONTEXT_ID_VBIOS 2
#define SMU7_MAX_LEVELS_VDDC 8
#define SMU7_MAX_LEVELS_VDDCI 4
#define SMU7_MAX_LEVELS_MVDD 4
#define SMU7_MAX_LEVELS_VDDNB 8
#define SMU7_MAX_LEVELS_GRAPHICS SMU__NUM_SCLK_DPM_STATE // SCLK + SQ DPM + ULV
#define SMU7_MAX_LEVELS_MEMORY SMU__NUM_MCLK_DPM_LEVELS // MCLK Levels DPM
#define SMU7_MAX_LEVELS_GIO SMU__NUM_LCLK_DPM_LEVELS // LCLK Levels
#define SMU7_MAX_LEVELS_LINK SMU__NUM_PCIE_DPM_LEVELS // PCIe speed and number of lanes.
#define SMU7_MAX_LEVELS_UVD 8 // VCLK/DCLK levels for UVD.
#define SMU7_MAX_LEVELS_VCE 8 // ECLK levels for VCE.
#define SMU7_MAX_LEVELS_ACP 8 // ACLK levels for ACP.
#define SMU7_MAX_LEVELS_SAMU 8 // SAMCLK levels for SAMU.
#define SMU7_MAX_ENTRIES_SMIO 32 // Number of entries in SMIO table.
#define DPM_NO_LIMIT 0
#define DPM_NO_UP 1
#define DPM_GO_DOWN 2
#define DPM_GO_UP 3
#define SMU7_FIRST_DPM_GRAPHICS_LEVEL 0
#define SMU7_FIRST_DPM_MEMORY_LEVEL 0
#define GPIO_CLAMP_MODE_VRHOT 1
#define GPIO_CLAMP_MODE_THERM 2
#define GPIO_CLAMP_MODE_DC 4
#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
#define SCRATCH_B_TARG_PCIE_INDEX_MASK (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
#define SCRATCH_B_CURR_PCIE_INDEX_MASK (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
#define SCRATCH_B_TARG_UVD_INDEX_SHIFT 6
#define SCRATCH_B_TARG_UVD_INDEX_MASK (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
#define SCRATCH_B_CURR_UVD_INDEX_SHIFT 9
#define SCRATCH_B_CURR_UVD_INDEX_MASK (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
#define SCRATCH_B_TARG_VCE_INDEX_SHIFT 12
#define SCRATCH_B_TARG_VCE_INDEX_MASK (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
#define SCRATCH_B_CURR_VCE_INDEX_SHIFT 15
#define SCRATCH_B_CURR_VCE_INDEX_MASK (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
#define SCRATCH_B_TARG_ACP_INDEX_SHIFT 18
#define SCRATCH_B_TARG_ACP_INDEX_MASK (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
#define SCRATCH_B_CURR_ACP_INDEX_SHIFT 21
#define SCRATCH_B_CURR_ACP_INDEX_MASK (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
#define SCRATCH_B_TARG_SAMU_INDEX_MASK (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
#define SCRATCH_B_CURR_SAMU_INDEX_MASK (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
struct SMU7_PIDController
{
uint32_t Ki;
int32_t LFWindupUL;
int32_t LFWindupLL;
uint32_t StatePrecision;
uint32_t LfPrecision;
uint32_t LfOffset;
uint32_t MaxState;
uint32_t MaxLfFraction;
uint32_t StateShift;
};
typedef struct SMU7_PIDController SMU7_PIDController;
// -------------------------------------------------------------------------------------------------------------------------
#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
#define SMU7_SCLK_DPM_CONFIG_MASK 0x01
#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK 0x02
#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK 0x04
#define SMU7_MCLK_DPM_CONFIG_MASK 0x08
#define SMU7_UVD_DPM_CONFIG_MASK 0x10
#define SMU7_VCE_DPM_CONFIG_MASK 0x20
#define SMU7_ACP_DPM_CONFIG_MASK 0x40
#define SMU7_SAMU_DPM_CONFIG_MASK 0x80
#define SMU7_PCIEGEN_DPM_CONFIG_MASK 0x100
#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE 0x00000001
#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE 0x00000002
#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE 0x00000100
#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE 0x00000200
#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE 0x00010000
#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000
struct SMU7_Firmware_Header
{
uint32_t Digest[5];
uint32_t Version;
uint32_t HeaderSize;
uint32_t Flags;
uint32_t EntryPoint;
uint32_t CodeSize;
uint32_t ImageSize;
uint32_t Rtos;
uint32_t SoftRegisters;
uint32_t DpmTable;
uint32_t FanTable;
uint32_t CacConfigTable;
uint32_t CacStatusTable;
uint32_t mcRegisterTable;
uint32_t mcArbDramTimingTable;
uint32_t PmFuseTable;
uint32_t Globals;
uint32_t Reserved[42];
uint32_t Signature;
};
typedef struct SMU7_Firmware_Header SMU7_Firmware_Header;
#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000
enum DisplayConfig {
PowerDown = 1,
DP54x4,
DP54x2,
DP54x1,
DP27x4,
DP27x2,
DP27x1,
HDMI297,
HDMI162,
LVDS,
DP324x4,
DP324x2,
DP324x1
};
#pragma pack(pop)
#endif

View File

@ -0,0 +1,514 @@
/*
* Copyright 2013 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 SMU7_DISCRETE_H
#define SMU7_DISCRETE_H
#include "smu7.h"
#pragma pack(push, 1)
#define SMU7_DTE_ITERATIONS 5
#define SMU7_DTE_SOURCES 3
#define SMU7_DTE_SINKS 1
#define SMU7_NUM_CPU_TES 0
#define SMU7_NUM_GPU_TES 1
#define SMU7_NUM_NON_TES 2
struct SMU7_SoftRegisters
{
uint32_t RefClockFrequency;
uint32_t PmTimerP;
uint32_t FeatureEnables;
uint32_t PreVBlankGap;
uint32_t VBlankTimeout;
uint32_t TrainTimeGap;
uint32_t MvddSwitchTime;
uint32_t LongestAcpiTrainTime;
uint32_t AcpiDelay;
uint32_t G5TrainTime;
uint32_t DelayMpllPwron;
uint32_t VoltageChangeTimeout;
uint32_t HandshakeDisables;
uint8_t DisplayPhy1Config;
uint8_t DisplayPhy2Config;
uint8_t DisplayPhy3Config;
uint8_t DisplayPhy4Config;
uint8_t DisplayPhy5Config;
uint8_t DisplayPhy6Config;
uint8_t DisplayPhy7Config;
uint8_t DisplayPhy8Config;
uint32_t AverageGraphicsA;
uint32_t AverageMemoryA;
uint32_t AverageGioA;
uint8_t SClkDpmEnabledLevels;
uint8_t MClkDpmEnabledLevels;
uint8_t LClkDpmEnabledLevels;
uint8_t PCIeDpmEnabledLevels;
uint8_t UVDDpmEnabledLevels;
uint8_t SAMUDpmEnabledLevels;
uint8_t ACPDpmEnabledLevels;
uint8_t VCEDpmEnabledLevels;
uint32_t DRAM_LOG_ADDR_H;
uint32_t DRAM_LOG_ADDR_L;
uint32_t DRAM_LOG_PHY_ADDR_H;
uint32_t DRAM_LOG_PHY_ADDR_L;
uint32_t DRAM_LOG_BUFF_SIZE;
uint32_t UlvEnterC;
uint32_t UlvTime;
uint32_t Reserved[3];
};
typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
struct SMU7_Discrete_VoltageLevel
{
uint16_t Voltage;
uint16_t StdVoltageHiSidd;
uint16_t StdVoltageLoSidd;
uint8_t Smio;
uint8_t padding;
};
typedef struct SMU7_Discrete_VoltageLevel SMU7_Discrete_VoltageLevel;
struct SMU7_Discrete_GraphicsLevel
{
uint32_t Flags;
uint32_t MinVddc;
uint32_t MinVddcPhases;
uint32_t SclkFrequency;
uint8_t padding1[2];
uint16_t ActivityLevel;
uint32_t CgSpllFuncCntl3;
uint32_t CgSpllFuncCntl4;
uint32_t SpllSpreadSpectrum;
uint32_t SpllSpreadSpectrum2;
uint32_t CcPwrDynRm;
uint32_t CcPwrDynRm1;
uint8_t SclkDid;
uint8_t DisplayWatermark;
uint8_t EnabledForActivity;
uint8_t EnabledForThrottle;
uint8_t UpH;
uint8_t DownH;
uint8_t VoltageDownH;
uint8_t PowerThrottle;
uint8_t DeepSleepDivId;
uint8_t padding[3];
};
typedef struct SMU7_Discrete_GraphicsLevel SMU7_Discrete_GraphicsLevel;
struct SMU7_Discrete_ACPILevel
{
uint32_t Flags;
uint32_t MinVddc;
uint32_t MinVddcPhases;
uint32_t SclkFrequency;
uint8_t SclkDid;
uint8_t DisplayWatermark;
uint8_t DeepSleepDivId;
uint8_t padding;
uint32_t CgSpllFuncCntl;
uint32_t CgSpllFuncCntl2;
uint32_t CgSpllFuncCntl3;
uint32_t CgSpllFuncCntl4;
uint32_t SpllSpreadSpectrum;
uint32_t SpllSpreadSpectrum2;
uint32_t CcPwrDynRm;
uint32_t CcPwrDynRm1;
};
typedef struct SMU7_Discrete_ACPILevel SMU7_Discrete_ACPILevel;
struct SMU7_Discrete_Ulv
{
uint32_t CcPwrDynRm;
uint32_t CcPwrDynRm1;
uint16_t VddcOffset;
uint8_t VddcOffsetVid;
uint8_t VddcPhase;
uint32_t Reserved;
};
typedef struct SMU7_Discrete_Ulv SMU7_Discrete_Ulv;
struct SMU7_Discrete_MemoryLevel
{
uint32_t MinVddc;
uint32_t MinVddcPhases;
uint32_t MinVddci;
uint32_t MinMvdd;
uint32_t MclkFrequency;
uint8_t EdcReadEnable;
uint8_t EdcWriteEnable;
uint8_t RttEnable;
uint8_t StutterEnable;
uint8_t StrobeEnable;
uint8_t StrobeRatio;
uint8_t EnabledForThrottle;
uint8_t EnabledForActivity;
uint8_t UpH;
uint8_t DownH;
uint8_t VoltageDownH;
uint8_t padding;
uint16_t ActivityLevel;
uint8_t DisplayWatermark;
uint8_t padding1;
uint32_t MpllFuncCntl;
uint32_t MpllFuncCntl_1;
uint32_t MpllFuncCntl_2;
uint32_t MpllAdFuncCntl;
uint32_t MpllDqFuncCntl;
uint32_t MclkPwrmgtCntl;
uint32_t DllCntl;
uint32_t MpllSs1;
uint32_t MpllSs2;
};
typedef struct SMU7_Discrete_MemoryLevel SMU7_Discrete_MemoryLevel;
struct SMU7_Discrete_LinkLevel
{
uint8_t PcieGenSpeed;
uint8_t PcieLaneCount;
uint8_t EnabledForActivity;
uint8_t Padding;
uint32_t DownT;
uint32_t UpT;
uint32_t Reserved;
};
typedef struct SMU7_Discrete_LinkLevel SMU7_Discrete_LinkLevel;
struct SMU7_Discrete_MCArbDramTimingTableEntry
{
uint32_t McArbDramTiming;
uint32_t McArbDramTiming2;
uint8_t McArbBurstTime;
uint8_t padding[3];
};
typedef struct SMU7_Discrete_MCArbDramTimingTableEntry SMU7_Discrete_MCArbDramTimingTableEntry;
struct SMU7_Discrete_MCArbDramTimingTable
{
SMU7_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
};
typedef struct SMU7_Discrete_MCArbDramTimingTable SMU7_Discrete_MCArbDramTimingTable;
struct SMU7_Discrete_UvdLevel
{
uint32_t VclkFrequency;
uint32_t DclkFrequency;
uint16_t MinVddc;
uint8_t MinVddcPhases;
uint8_t VclkDivider;
uint8_t DclkDivider;
uint8_t padding[3];
};
typedef struct SMU7_Discrete_UvdLevel SMU7_Discrete_UvdLevel;
struct SMU7_Discrete_ExtClkLevel
{
uint32_t Frequency;
uint16_t MinVoltage;
uint8_t MinPhases;
uint8_t Divider;
};
typedef struct SMU7_Discrete_ExtClkLevel SMU7_Discrete_ExtClkLevel;
struct SMU7_Discrete_StateInfo
{
uint32_t SclkFrequency;
uint32_t MclkFrequency;
uint32_t VclkFrequency;
uint32_t DclkFrequency;
uint32_t SamclkFrequency;
uint32_t AclkFrequency;
uint32_t EclkFrequency;
uint16_t MvddVoltage;
uint16_t padding16;
uint8_t DisplayWatermark;
uint8_t McArbIndex;
uint8_t McRegIndex;
uint8_t SeqIndex;
uint8_t SclkDid;
int8_t SclkIndex;
int8_t MclkIndex;
uint8_t PCIeGen;
};
typedef struct SMU7_Discrete_StateInfo SMU7_Discrete_StateInfo;
struct SMU7_Discrete_DpmTable
{
SMU7_PIDController GraphicsPIDController;
SMU7_PIDController MemoryPIDController;
SMU7_PIDController LinkPIDController;
uint32_t SystemFlags;
uint32_t SmioMaskVddcVid;
uint32_t SmioMaskVddcPhase;
uint32_t SmioMaskVddciVid;
uint32_t SmioMaskMvddVid;
uint32_t VddcLevelCount;
uint32_t VddciLevelCount;
uint32_t MvddLevelCount;
SMU7_Discrete_VoltageLevel VddcLevel [SMU7_MAX_LEVELS_VDDC];
// SMU7_Discrete_VoltageLevel VddcStandardReference [SMU7_MAX_LEVELS_VDDC];
SMU7_Discrete_VoltageLevel VddciLevel [SMU7_MAX_LEVELS_VDDCI];
SMU7_Discrete_VoltageLevel MvddLevel [SMU7_MAX_LEVELS_MVDD];
uint8_t GraphicsDpmLevelCount;
uint8_t MemoryDpmLevelCount;
uint8_t LinkLevelCount;
uint8_t UvdLevelCount;
uint8_t VceLevelCount;
uint8_t AcpLevelCount;
uint8_t SamuLevelCount;
uint8_t MasterDeepSleepControl;
uint32_t Reserved[5];
// uint32_t SamuDefaultLevel;
SMU7_Discrete_GraphicsLevel GraphicsLevel [SMU7_MAX_LEVELS_GRAPHICS];
SMU7_Discrete_MemoryLevel MemoryACPILevel;
SMU7_Discrete_MemoryLevel MemoryLevel [SMU7_MAX_LEVELS_MEMORY];
SMU7_Discrete_LinkLevel LinkLevel [SMU7_MAX_LEVELS_LINK];
SMU7_Discrete_ACPILevel ACPILevel;
SMU7_Discrete_UvdLevel UvdLevel [SMU7_MAX_LEVELS_UVD];
SMU7_Discrete_ExtClkLevel VceLevel [SMU7_MAX_LEVELS_VCE];
SMU7_Discrete_ExtClkLevel AcpLevel [SMU7_MAX_LEVELS_ACP];
SMU7_Discrete_ExtClkLevel SamuLevel [SMU7_MAX_LEVELS_SAMU];
SMU7_Discrete_Ulv Ulv;
uint32_t SclkStepSize;
uint32_t Smio [SMU7_MAX_ENTRIES_SMIO];
uint8_t UvdBootLevel;
uint8_t VceBootLevel;
uint8_t AcpBootLevel;
uint8_t SamuBootLevel;
uint8_t UVDInterval;
uint8_t VCEInterval;
uint8_t ACPInterval;
uint8_t SAMUInterval;
uint8_t GraphicsBootLevel;
uint8_t GraphicsVoltageChangeEnable;
uint8_t GraphicsThermThrottleEnable;
uint8_t GraphicsInterval;
uint8_t VoltageInterval;
uint8_t ThermalInterval;
uint16_t TemperatureLimitHigh;
uint16_t TemperatureLimitLow;
uint8_t MemoryBootLevel;
uint8_t MemoryVoltageChangeEnable;
uint8_t MemoryInterval;
uint8_t MemoryThermThrottleEnable;
uint16_t VddcVddciDelta;
uint16_t VoltageResponseTime;
uint16_t PhaseResponseTime;
uint8_t PCIeBootLinkLevel;
uint8_t PCIeGenInterval;
uint8_t DTEInterval;
uint8_t DTEMode;
uint8_t SVI2Enable;
uint8_t VRHotGpio;
uint8_t AcDcGpio;
uint8_t ThermGpio;
uint16_t PPM_PkgPwrLimit;
uint16_t PPM_TemperatureLimit;
uint16_t DefaultTdp;
uint16_t TargetTdp;
uint16_t FpsHighT;
uint16_t FpsLowT;
uint16_t BAPMTI_R [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
uint16_t BAPMTI_RC [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
uint8_t DTEAmbientTempBase;
uint8_t DTETjOffset;
uint8_t GpuTjMax;
uint8_t GpuTjHyst;
uint16_t BootVddc;
uint16_t BootVddci;
uint16_t BootMVdd;
uint16_t padding;
uint32_t BAPM_TEMP_GRADIENT;
uint32_t LowSclkInterruptT;
};
typedef struct SMU7_Discrete_DpmTable SMU7_Discrete_DpmTable;
#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE 16
#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU7_MAX_LEVELS_MEMORY
struct SMU7_Discrete_MCRegisterAddress
{
uint16_t s0;
uint16_t s1;
};
typedef struct SMU7_Discrete_MCRegisterAddress SMU7_Discrete_MCRegisterAddress;
struct SMU7_Discrete_MCRegisterSet
{
uint32_t value[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
};
typedef struct SMU7_Discrete_MCRegisterSet SMU7_Discrete_MCRegisterSet;
struct SMU7_Discrete_MCRegisters
{
uint8_t last;
uint8_t reserved[3];
SMU7_Discrete_MCRegisterAddress address[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
SMU7_Discrete_MCRegisterSet data[SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT];
};
typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters;
struct SMU7_Discrete_FanTable
{
uint16_t FdoMode;
int16_t TempMin;
int16_t TempMed;
int16_t TempMax;
int16_t Slope1;
int16_t Slope2;
int16_t FdoMin;
int16_t HystUp;
int16_t HystDown;
int16_t HystSlope;
int16_t TempRespLim;
int16_t TempCurr;
int16_t SlopeCurr;
int16_t PwmCurr;
uint32_t RefreshPeriod;
int16_t FdoMax;
uint8_t TempSrc;
int8_t Padding;
};
typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable;
struct SMU7_Discrete_PmFuses {
// dw0-dw1
uint8_t BapmVddCVidHiSidd[8];
// dw2-dw3
uint8_t BapmVddCVidLoSidd[8];
// dw4-dw5
uint8_t VddCVid[8];
// dw6
uint8_t SviLoadLineEn;
uint8_t SviLoadLineVddC;
uint8_t SviLoadLineTrimVddC;
uint8_t SviLoadLineOffsetVddC;
// dw7
uint16_t TDC_VDDC_PkgLimit;
uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
uint8_t TDC_MAWt;
// dw8
uint8_t TdcWaterfallCtl;
uint8_t LPMLTemperatureMin;
uint8_t LPMLTemperatureMax;
uint8_t Reserved;
// dw9-dw10
uint8_t BapmVddCVidHiSidd2[8];
// dw11-dw12
int16_t FuzzyFan_ErrorSetDelta;
int16_t FuzzyFan_ErrorRateSetDelta;
int16_t FuzzyFan_PwmSetDelta;
uint16_t CalcMeasPowerBlend;
// dw13-dw16
uint8_t GnbLPML[16];
// dw17
uint8_t GnbLPMLMaxVid;
uint8_t GnbLPMLMinVid;
uint8_t Reserved1[2];
// dw18
uint16_t BapmVddCBaseLeakageHiSidd;
uint16_t BapmVddCBaseLeakageLoSidd;
};
typedef struct SMU7_Discrete_PmFuses SMU7_Discrete_PmFuses;
#pragma pack(pop)
#endif

View File

@ -0,0 +1,300 @@
/*
* Copyright 2013 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 SMU7_FUSION_H
#define SMU7_FUSION_H
#include "smu7.h"
#pragma pack(push, 1)
#define SMU7_DTE_ITERATIONS 5
#define SMU7_DTE_SOURCES 5
#define SMU7_DTE_SINKS 3
#define SMU7_NUM_CPU_TES 2
#define SMU7_NUM_GPU_TES 1
#define SMU7_NUM_NON_TES 2
// All 'soft registers' should be uint32_t.
struct SMU7_SoftRegisters
{
uint32_t RefClockFrequency;
uint32_t PmTimerP;
uint32_t FeatureEnables;
uint32_t HandshakeDisables;
uint8_t DisplayPhy1Config;
uint8_t DisplayPhy2Config;
uint8_t DisplayPhy3Config;
uint8_t DisplayPhy4Config;
uint8_t DisplayPhy5Config;
uint8_t DisplayPhy6Config;
uint8_t DisplayPhy7Config;
uint8_t DisplayPhy8Config;
uint32_t AverageGraphicsA;
uint32_t AverageMemoryA;
uint32_t AverageGioA;
uint8_t SClkDpmEnabledLevels;
uint8_t MClkDpmEnabledLevels;
uint8_t LClkDpmEnabledLevels;
uint8_t PCIeDpmEnabledLevels;
uint8_t UVDDpmEnabledLevels;
uint8_t SAMUDpmEnabledLevels;
uint8_t ACPDpmEnabledLevels;
uint8_t VCEDpmEnabledLevels;
uint32_t DRAM_LOG_ADDR_H;
uint32_t DRAM_LOG_ADDR_L;
uint32_t DRAM_LOG_PHY_ADDR_H;
uint32_t DRAM_LOG_PHY_ADDR_L;
uint32_t DRAM_LOG_BUFF_SIZE;
uint32_t UlvEnterC;
uint32_t UlvTime;
uint32_t Reserved[3];
};
typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
struct SMU7_Fusion_GraphicsLevel
{
uint32_t MinVddNb;
uint32_t SclkFrequency;
uint8_t Vid;
uint8_t VidOffset;
uint16_t AT;
uint8_t PowerThrottle;
uint8_t GnbSlow;
uint8_t ForceNbPs1;
uint8_t SclkDid;
uint8_t DisplayWatermark;
uint8_t EnabledForActivity;
uint8_t EnabledForThrottle;
uint8_t UpH;
uint8_t DownH;
uint8_t VoltageDownH;
uint8_t DeepSleepDivId;
uint8_t ClkBypassCntl;
uint32_t reserved;
};
typedef struct SMU7_Fusion_GraphicsLevel SMU7_Fusion_GraphicsLevel;
struct SMU7_Fusion_GIOLevel
{
uint8_t EnabledForActivity;
uint8_t LclkDid;
uint8_t Vid;
uint8_t VoltageDownH;
uint32_t MinVddNb;
uint16_t ResidencyCounter;
uint8_t UpH;
uint8_t DownH;
uint32_t LclkFrequency;
uint8_t ActivityLevel;
uint8_t EnabledForThrottle;
uint8_t ClkBypassCntl;
uint8_t padding;
};
typedef struct SMU7_Fusion_GIOLevel SMU7_Fusion_GIOLevel;
// UVD VCLK/DCLK state (level) definition.
struct SMU7_Fusion_UvdLevel
{
uint32_t VclkFrequency;
uint32_t DclkFrequency;
uint16_t MinVddNb;
uint8_t VclkDivider;
uint8_t DclkDivider;
uint8_t VClkBypassCntl;
uint8_t DClkBypassCntl;
uint8_t padding[2];
};
typedef struct SMU7_Fusion_UvdLevel SMU7_Fusion_UvdLevel;
// Clocks for other external blocks (VCE, ACP, SAMU).
struct SMU7_Fusion_ExtClkLevel
{
uint32_t Frequency;
uint16_t MinVoltage;
uint8_t Divider;
uint8_t ClkBypassCntl;
uint32_t Reserved;
};
typedef struct SMU7_Fusion_ExtClkLevel SMU7_Fusion_ExtClkLevel;
struct SMU7_Fusion_ACPILevel
{
uint32_t Flags;
uint32_t MinVddNb;
uint32_t SclkFrequency;
uint8_t SclkDid;
uint8_t GnbSlow;
uint8_t ForceNbPs1;
uint8_t DisplayWatermark;
uint8_t DeepSleepDivId;
uint8_t padding[3];
};
typedef struct SMU7_Fusion_ACPILevel SMU7_Fusion_ACPILevel;
struct SMU7_Fusion_NbDpm
{
uint8_t DpmXNbPsHi;
uint8_t DpmXNbPsLo;
uint8_t Dpm0PgNbPsHi;
uint8_t Dpm0PgNbPsLo;
uint8_t EnablePsi1;
uint8_t SkipDPM0;
uint8_t SkipPG;
uint8_t Hysteresis;
uint8_t EnableDpmPstatePoll;
uint8_t padding[3];
};
typedef struct SMU7_Fusion_NbDpm SMU7_Fusion_NbDpm;
struct SMU7_Fusion_StateInfo
{
uint32_t SclkFrequency;
uint32_t LclkFrequency;
uint32_t VclkFrequency;
uint32_t DclkFrequency;
uint32_t SamclkFrequency;
uint32_t AclkFrequency;
uint32_t EclkFrequency;
uint8_t DisplayWatermark;
uint8_t McArbIndex;
int8_t SclkIndex;
int8_t MclkIndex;
};
typedef struct SMU7_Fusion_StateInfo SMU7_Fusion_StateInfo;
struct SMU7_Fusion_DpmTable
{
uint32_t SystemFlags;
SMU7_PIDController GraphicsPIDController;
SMU7_PIDController GioPIDController;
uint8_t GraphicsDpmLevelCount;
uint8_t GIOLevelCount;
uint8_t UvdLevelCount;
uint8_t VceLevelCount;
uint8_t AcpLevelCount;
uint8_t SamuLevelCount;
uint16_t FpsHighT;
SMU7_Fusion_GraphicsLevel GraphicsLevel [SMU__NUM_SCLK_DPM_STATE];
SMU7_Fusion_ACPILevel ACPILevel;
SMU7_Fusion_UvdLevel UvdLevel [SMU7_MAX_LEVELS_UVD];
SMU7_Fusion_ExtClkLevel VceLevel [SMU7_MAX_LEVELS_VCE];
SMU7_Fusion_ExtClkLevel AcpLevel [SMU7_MAX_LEVELS_ACP];
SMU7_Fusion_ExtClkLevel SamuLevel [SMU7_MAX_LEVELS_SAMU];
uint8_t UvdBootLevel;
uint8_t VceBootLevel;
uint8_t AcpBootLevel;
uint8_t SamuBootLevel;
uint8_t UVDInterval;
uint8_t VCEInterval;
uint8_t ACPInterval;
uint8_t SAMUInterval;
uint8_t GraphicsBootLevel;
uint8_t GraphicsInterval;
uint8_t GraphicsThermThrottleEnable;
uint8_t GraphicsVoltageChangeEnable;
uint8_t GraphicsClkSlowEnable;
uint8_t GraphicsClkSlowDivider;
uint16_t FpsLowT;
uint32_t DisplayCac;
uint32_t LowSclkInterruptT;
uint32_t DRAM_LOG_ADDR_H;
uint32_t DRAM_LOG_ADDR_L;
uint32_t DRAM_LOG_PHY_ADDR_H;
uint32_t DRAM_LOG_PHY_ADDR_L;
uint32_t DRAM_LOG_BUFF_SIZE;
};
struct SMU7_Fusion_GIODpmTable
{
SMU7_Fusion_GIOLevel GIOLevel [SMU7_MAX_LEVELS_GIO];
SMU7_PIDController GioPIDController;
uint32_t GIOLevelCount;
uint8_t Enable;
uint8_t GIOVoltageChangeEnable;
uint8_t GIOBootLevel;
uint8_t padding;
uint8_t padding1[2];
uint8_t TargetState;
uint8_t CurrenttState;
uint8_t ThrottleOnHtc;
uint8_t ThermThrottleStatus;
uint8_t ThermThrottleTempSelect;
uint8_t ThermThrottleEnable;
uint16_t TemperatureLimitHigh;
uint16_t TemperatureLimitLow;
};
typedef struct SMU7_Fusion_DpmTable SMU7_Fusion_DpmTable;
typedef struct SMU7_Fusion_GIODpmTable SMU7_Fusion_GIODpmTable;
#pragma pack(pop)
#endif

View File

@ -0,0 +1,888 @@
/*
* Copyright 2013 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.
*
* Authors: Christian König <christian.koenig@amd.com>
*/
#include <linux/firmware.h>
#include <drm/drmP.h>
#include "amdgpu.h"
#include "amdgpu_uvd.h"
#include "cikd.h"
#include "uvd/uvd_4_2_d.h"
#include "uvd/uvd_4_2_sh_mask.h"
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"
static void uvd_v4_2_mc_resume(struct amdgpu_device *adev);
static void uvd_v4_2_init_cg(struct amdgpu_device *adev);
static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev);
static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev);
static int uvd_v4_2_start(struct amdgpu_device *adev);
static void uvd_v4_2_stop(struct amdgpu_device *adev);
/**
* uvd_v4_2_ring_get_rptr - get read pointer
*
* @ring: amdgpu_ring pointer
*
* Returns the current hardware read pointer
*/
static uint32_t uvd_v4_2_ring_get_rptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
return RREG32(mmUVD_RBC_RB_RPTR);
}
/**
* uvd_v4_2_ring_get_wptr - get write pointer
*
* @ring: amdgpu_ring pointer
*
* Returns the current hardware write pointer
*/
static uint32_t uvd_v4_2_ring_get_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
return RREG32(mmUVD_RBC_RB_WPTR);
}
/**
* uvd_v4_2_ring_set_wptr - set write pointer
*
* @ring: amdgpu_ring pointer
*
* Commits the write pointer to the hardware
*/
static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
WREG32(mmUVD_RBC_RB_WPTR, ring->wptr);
}
static int uvd_v4_2_early_init(struct amdgpu_device *adev)
{
uvd_v4_2_set_ring_funcs(adev);
uvd_v4_2_set_irq_funcs(adev);
return 0;
}
static int uvd_v4_2_sw_init(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
int r;
/* UVD TRAP */
r = amdgpu_irq_add_id(adev, 124, &adev->uvd.irq);
if (r)
return r;
r = amdgpu_uvd_sw_init(adev);
if (r)
return r;
r = amdgpu_uvd_resume(adev);
if (r)
return r;
ring = &adev->uvd.ring;
sprintf(ring->name, "uvd");
r = amdgpu_ring_init(adev, ring, 4096, CP_PACKET2, 0xf,
&adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD);
return r;
}
static int uvd_v4_2_sw_fini(struct amdgpu_device *adev)
{
int r;
r = amdgpu_uvd_suspend(adev);
if (r)
return r;
r = amdgpu_uvd_sw_fini(adev);
if (r)
return r;
return r;
}
/**
* uvd_v4_2_hw_init - start and test UVD block
*
* @adev: amdgpu_device pointer
*
* Initialize the hardware, boot up the VCPU and do some testing
*/
static int uvd_v4_2_hw_init(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring = &adev->uvd.ring;
uint32_t tmp;
int r;
/* raise clocks while booting up the VCPU */
amdgpu_asic_set_uvd_clocks(adev, 53300, 40000);
r = uvd_v4_2_start(adev);
if (r)
goto done;
ring->ready = true;
r = amdgpu_ring_test_ring(ring);
if (r) {
ring->ready = false;
goto done;
}
r = amdgpu_ring_lock(ring, 10);
if (r) {
DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r);
goto done;
}
tmp = PACKET0(mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
amdgpu_ring_write(ring, tmp);
amdgpu_ring_write(ring, 0xFFFFF);
tmp = PACKET0(mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
amdgpu_ring_write(ring, tmp);
amdgpu_ring_write(ring, 0xFFFFF);
tmp = PACKET0(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
amdgpu_ring_write(ring, tmp);
amdgpu_ring_write(ring, 0xFFFFF);
/* Clear timeout status bits */
amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_TIMEOUT_STATUS, 0));
amdgpu_ring_write(ring, 0x8);
amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0));
amdgpu_ring_write(ring, 3);
amdgpu_ring_unlock_commit(ring);
done:
/* lower clocks again */
amdgpu_asic_set_uvd_clocks(adev, 0, 0);
if (!r)
DRM_INFO("UVD initialized successfully.\n");
return r;
}
/**
* uvd_v4_2_hw_fini - stop the hardware block
*
* @adev: amdgpu_device pointer
*
* Stop the UVD block, mark ring as not ready any more
*/
static int uvd_v4_2_hw_fini(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring = &adev->uvd.ring;
uvd_v4_2_stop(adev);
ring->ready = false;
return 0;
}
static int uvd_v4_2_suspend(struct amdgpu_device *adev)
{
int r;
r = uvd_v4_2_hw_fini(adev);
if (r)
return r;
r = amdgpu_uvd_suspend(adev);
if (r)
return r;
return r;
}
static int uvd_v4_2_resume(struct amdgpu_device *adev)
{
int r;
r = amdgpu_uvd_resume(adev);
if (r)
return r;
r = uvd_v4_2_hw_init(adev);
if (r)
return r;
return r;
}
/**
* uvd_v4_2_start - start UVD block
*
* @adev: amdgpu_device pointer
*
* Setup and start the UVD block
*/
static int uvd_v4_2_start(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring = &adev->uvd.ring;
uint32_t rb_bufsz;
int i, j, r;
/* disable byte swapping */
u32 lmi_swap_cntl = 0;
u32 mp_swap_cntl = 0;
uvd_v4_2_mc_resume(adev);
/* disable clock gating */
WREG32(mmUVD_CGC_GATE, 0);
/* disable interupt */
WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
/* Stall UMC and register bus before resetting VCPU */
WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
mdelay(1);
/* put LMI, VCPU, RBC etc... into reset */
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
mdelay(5);
/* take UVD block out of reset */
WREG32_P(mmSRBM_SOFT_RESET, 0, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
mdelay(5);
/* initialize UVD memory controller */
WREG32(mmUVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
(1 << 21) | (1 << 9) | (1 << 20));
#ifdef __BIG_ENDIAN
/* swap (8 in 32) RB and IB */
lmi_swap_cntl = 0xa;
mp_swap_cntl = 0;
#endif
WREG32(mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
WREG32(mmUVD_MP_SWAP_CNTL, mp_swap_cntl);
WREG32(mmUVD_MPC_SET_MUXA0, 0x40c2040);
WREG32(mmUVD_MPC_SET_MUXA1, 0x0);
WREG32(mmUVD_MPC_SET_MUXB0, 0x40c2040);
WREG32(mmUVD_MPC_SET_MUXB1, 0x0);
WREG32(mmUVD_MPC_SET_ALU, 0);
WREG32(mmUVD_MPC_SET_MUX, 0x88);
/* take all subblocks out of reset, except VCPU */
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
mdelay(5);
/* enable VCPU clock */
WREG32(mmUVD_VCPU_CNTL, 1 << 9);
/* enable UMC */
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
/* boot up the VCPU */
WREG32(mmUVD_SOFT_RESET, 0);
mdelay(10);
for (i = 0; i < 10; ++i) {
uint32_t status;
for (j = 0; j < 100; ++j) {
status = RREG32(mmUVD_STATUS);
if (status & 2)
break;
mdelay(10);
}
r = 0;
if (status & 2)
break;
DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
WREG32_P(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
mdelay(10);
WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
mdelay(10);
r = -1;
}
if (r) {
DRM_ERROR("UVD not responding, giving up!!!\n");
return r;
}
/* enable interupt */
WREG32_P(mmUVD_MASTINT_EN, 3<<1, ~(3 << 1));
/* force RBC into idle state */
WREG32(mmUVD_RBC_RB_CNTL, 0x11010101);
/* Set the write pointer delay */
WREG32(mmUVD_RBC_RB_WPTR_CNTL, 0);
/* programm the 4GB memory segment for rptr and ring buffer */
WREG32(mmUVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
(0x7 << 16) | (0x1 << 31));
/* Initialize the ring buffer's read and write pointers */
WREG32(mmUVD_RBC_RB_RPTR, 0x0);
ring->wptr = RREG32(mmUVD_RBC_RB_RPTR);
WREG32(mmUVD_RBC_RB_WPTR, ring->wptr);
/* set the ring address */
WREG32(mmUVD_RBC_RB_BASE, ring->gpu_addr);
/* Set ring buffer size */
rb_bufsz = order_base_2(ring->ring_size);
rb_bufsz = (0x1 << 8) | rb_bufsz;
WREG32_P(mmUVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
return 0;
}
/**
* uvd_v4_2_stop - stop UVD block
*
* @adev: amdgpu_device pointer
*
* stop the UVD block
*/
static void uvd_v4_2_stop(struct amdgpu_device *adev)
{
/* force RBC into idle state */
WREG32(mmUVD_RBC_RB_CNTL, 0x11010101);
/* Stall UMC and register bus before resetting VCPU */
WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
mdelay(1);
/* put VCPU into reset */
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
mdelay(5);
/* disable VCPU clock */
WREG32(mmUVD_VCPU_CNTL, 0x0);
/* Unstall UMC and register bus */
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
}
/**
* uvd_v4_2_ring_emit_fence - emit an fence & trap command
*
* @ring: amdgpu_ring pointer
* @fence: fence to emit
*
* Write a fence and a trap command to the ring.
*/
static void uvd_v4_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
bool write64bit)
{
WARN_ON(write64bit);
amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0));
amdgpu_ring_write(ring, seq);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
amdgpu_ring_write(ring, addr & 0xffffffff);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
amdgpu_ring_write(ring, 2);
}
/**
* uvd_v4_2_ring_emit_semaphore - emit semaphore command
*
* @ring: amdgpu_ring pointer
* @semaphore: semaphore to emit commands for
* @emit_wait: true if we should emit a wait command
*
* Emit a semaphore command (either wait or signal) to the UVD ring.
*/
static bool uvd_v4_2_ring_emit_semaphore(struct amdgpu_ring *ring,
struct amdgpu_semaphore *semaphore,
bool emit_wait)
{
uint64_t addr = semaphore->gpu_addr;
amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_LOW, 0));
amdgpu_ring_write(ring, (addr >> 3) & 0x000FFFFF);
amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_HIGH, 0));
amdgpu_ring_write(ring, (addr >> 23) & 0x000FFFFF);
amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CMD, 0));
amdgpu_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
return true;
}
/**
* uvd_v4_2_ring_test_ring - register write test
*
* @ring: amdgpu_ring pointer
*
* Test if we can successfully write to the context register
*/
static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
uint32_t tmp = 0;
unsigned i;
int r;
WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD);
r = amdgpu_ring_lock(ring, 3);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
ring->idx, r);
return r;
}
amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0));
amdgpu_ring_write(ring, 0xDEADBEEF);
amdgpu_ring_unlock_commit(ring);
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(mmUVD_CONTEXT_ID);
if (tmp == 0xDEADBEEF)
break;
DRM_UDELAY(1);
}
if (i < adev->usec_timeout) {
DRM_INFO("ring test on %d succeeded in %d usecs\n",
ring->idx, i);
} else {
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
ring->idx, tmp);
r = -EINVAL;
}
return r;
}
/**
* uvd_v4_2_ring_emit_ib - execute indirect buffer
*
* @ring: amdgpu_ring pointer
* @ib: indirect buffer to execute
*
* Write ring commands to execute the indirect buffer
*/
static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring,
struct amdgpu_ib *ib)
{
amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_BASE, 0));
amdgpu_ring_write(ring, ib->gpu_addr);
amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_SIZE, 0));
amdgpu_ring_write(ring, ib->length_dw);
}
/**
* uvd_v4_2_ring_test_ib - test ib execution
*
* @ring: amdgpu_ring pointer
*
* Test if we can successfully execute an IB
*/
static int uvd_v4_2_ring_test_ib(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_fence *fence = NULL;
int r;
r = amdgpu_asic_set_uvd_clocks(adev, 53300, 40000);
if (r) {
DRM_ERROR("amdgpu: failed to raise UVD clocks (%d).\n", r);
return r;
}
r = amdgpu_uvd_get_create_msg(ring, 1, NULL);
if (r) {
DRM_ERROR("amdgpu: failed to get create msg (%d).\n", r);
goto error;
}
r = amdgpu_uvd_get_destroy_msg(ring, 1, &fence);
if (r) {
DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r);
goto error;
}
r = amdgpu_fence_wait(fence, false);
if (r) {
DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
goto error;
}
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
error:
amdgpu_fence_unref(&fence);
amdgpu_asic_set_uvd_clocks(adev, 0, 0);
return r;
}
/**
* uvd_v4_2_mc_resume - memory controller programming
*
* @adev: amdgpu_device pointer
*
* Let the UVD memory controller know it's offsets
*/
static void uvd_v4_2_mc_resume(struct amdgpu_device *adev)
{
uint64_t addr;
uint32_t size;
/* programm the VCPU memory controller bits 0-27 */
addr = (adev->uvd.gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3;
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4) >> 3;
WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr);
WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = AMDGPU_UVD_STACK_SIZE >> 3;
WREG32(mmUVD_VCPU_CACHE_OFFSET1, addr);
WREG32(mmUVD_VCPU_CACHE_SIZE1, size);
addr += size;
size = AMDGPU_UVD_HEAP_SIZE >> 3;
WREG32(mmUVD_VCPU_CACHE_OFFSET2, addr);
WREG32(mmUVD_VCPU_CACHE_SIZE2, size);
/* bits 28-31 */
addr = (adev->uvd.gpu_addr >> 28) & 0xF;
WREG32(mmUVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
/* bits 32-39 */
addr = (adev->uvd.gpu_addr >> 32) & 0xFF;
WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
uvd_v4_2_init_cg(adev);
}
static void uvd_v4_2_enable_mgcg(struct amdgpu_device *adev,
bool enable)
{
u32 orig, data;
if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG)) {
data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL);
data = 0xfff;
WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data);
orig = data = RREG32(mmUVD_CGC_CTRL);
data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
if (orig != data)
WREG32(mmUVD_CGC_CTRL, data);
} else {
data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL);
data &= ~0xfff;
WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data);
orig = data = RREG32(mmUVD_CGC_CTRL);
data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
if (orig != data)
WREG32(mmUVD_CGC_CTRL, data);
}
}
static void uvd_v4_2_set_dcm(struct amdgpu_device *adev,
bool sw_mode)
{
u32 tmp, tmp2;
tmp = RREG32(mmUVD_CGC_CTRL);
tmp &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK);
tmp |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK |
(1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT) |
(4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT);
if (sw_mode) {
tmp &= ~0x7ffff800;
tmp2 = UVD_CGC_CTRL2__DYN_OCLK_RAMP_EN_MASK |
UVD_CGC_CTRL2__DYN_RCLK_RAMP_EN_MASK |
(7 << UVD_CGC_CTRL2__GATER_DIV_ID__SHIFT);
} else {
tmp |= 0x7ffff800;
tmp2 = 0;
}
WREG32(mmUVD_CGC_CTRL, tmp);
WREG32_UVD_CTX(ixUVD_CGC_CTRL2, tmp2);
}
static void uvd_v4_2_init_cg(struct amdgpu_device *adev)
{
bool hw_mode = true;
if (hw_mode) {
uvd_v4_2_set_dcm(adev, false);
} else {
u32 tmp = RREG32(mmUVD_CGC_CTRL);
tmp &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
WREG32(mmUVD_CGC_CTRL, tmp);
}
}
static bool uvd_v4_2_is_idle(struct amdgpu_device *adev)
{
return !(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK);
}
static int uvd_v4_2_wait_for_idle(struct amdgpu_device *adev)
{
unsigned i;
for (i = 0; i < adev->usec_timeout; i++) {
if (!(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK))
return 0;
}
return -ETIMEDOUT;
}
static int uvd_v4_2_soft_reset(struct amdgpu_device *adev)
{
uvd_v4_2_stop(adev);
WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK,
~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
mdelay(5);
return uvd_v4_2_start(adev);
}
static void uvd_v4_2_print_status(struct amdgpu_device *adev)
{
dev_info(adev->dev, "UVD 4.2 registers\n");
dev_info(adev->dev, " UVD_SEMA_ADDR_LOW=0x%08X\n",
RREG32(mmUVD_SEMA_ADDR_LOW));
dev_info(adev->dev, " UVD_SEMA_ADDR_HIGH=0x%08X\n",
RREG32(mmUVD_SEMA_ADDR_HIGH));
dev_info(adev->dev, " UVD_SEMA_CMD=0x%08X\n",
RREG32(mmUVD_SEMA_CMD));
dev_info(adev->dev, " UVD_GPCOM_VCPU_CMD=0x%08X\n",
RREG32(mmUVD_GPCOM_VCPU_CMD));
dev_info(adev->dev, " UVD_GPCOM_VCPU_DATA0=0x%08X\n",
RREG32(mmUVD_GPCOM_VCPU_DATA0));
dev_info(adev->dev, " UVD_GPCOM_VCPU_DATA1=0x%08X\n",
RREG32(mmUVD_GPCOM_VCPU_DATA1));
dev_info(adev->dev, " UVD_ENGINE_CNTL=0x%08X\n",
RREG32(mmUVD_ENGINE_CNTL));
dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n",
RREG32(mmUVD_UDEC_ADDR_CONFIG));
dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n",
RREG32(mmUVD_UDEC_DB_ADDR_CONFIG));
dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n",
RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG));
dev_info(adev->dev, " UVD_SEMA_CNTL=0x%08X\n",
RREG32(mmUVD_SEMA_CNTL));
dev_info(adev->dev, " UVD_LMI_EXT40_ADDR=0x%08X\n",
RREG32(mmUVD_LMI_EXT40_ADDR));
dev_info(adev->dev, " UVD_CTX_INDEX=0x%08X\n",
RREG32(mmUVD_CTX_INDEX));
dev_info(adev->dev, " UVD_CTX_DATA=0x%08X\n",
RREG32(mmUVD_CTX_DATA));
dev_info(adev->dev, " UVD_CGC_GATE=0x%08X\n",
RREG32(mmUVD_CGC_GATE));
dev_info(adev->dev, " UVD_CGC_CTRL=0x%08X\n",
RREG32(mmUVD_CGC_CTRL));
dev_info(adev->dev, " UVD_LMI_CTRL2=0x%08X\n",
RREG32(mmUVD_LMI_CTRL2));
dev_info(adev->dev, " UVD_MASTINT_EN=0x%08X\n",
RREG32(mmUVD_MASTINT_EN));
dev_info(adev->dev, " UVD_LMI_ADDR_EXT=0x%08X\n",
RREG32(mmUVD_LMI_ADDR_EXT));
dev_info(adev->dev, " UVD_LMI_CTRL=0x%08X\n",
RREG32(mmUVD_LMI_CTRL));
dev_info(adev->dev, " UVD_LMI_SWAP_CNTL=0x%08X\n",
RREG32(mmUVD_LMI_SWAP_CNTL));
dev_info(adev->dev, " UVD_MP_SWAP_CNTL=0x%08X\n",
RREG32(mmUVD_MP_SWAP_CNTL));
dev_info(adev->dev, " UVD_MPC_SET_MUXA0=0x%08X\n",
RREG32(mmUVD_MPC_SET_MUXA0));
dev_info(adev->dev, " UVD_MPC_SET_MUXA1=0x%08X\n",
RREG32(mmUVD_MPC_SET_MUXA1));
dev_info(adev->dev, " UVD_MPC_SET_MUXB0=0x%08X\n",
RREG32(mmUVD_MPC_SET_MUXB0));
dev_info(adev->dev, " UVD_MPC_SET_MUXB1=0x%08X\n",
RREG32(mmUVD_MPC_SET_MUXB1));
dev_info(adev->dev, " UVD_MPC_SET_MUX=0x%08X\n",
RREG32(mmUVD_MPC_SET_MUX));
dev_info(adev->dev, " UVD_MPC_SET_ALU=0x%08X\n",
RREG32(mmUVD_MPC_SET_ALU));
dev_info(adev->dev, " UVD_VCPU_CACHE_OFFSET0=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_OFFSET0));
dev_info(adev->dev, " UVD_VCPU_CACHE_SIZE0=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_SIZE0));
dev_info(adev->dev, " UVD_VCPU_CACHE_OFFSET1=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_OFFSET1));
dev_info(adev->dev, " UVD_VCPU_CACHE_SIZE1=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_SIZE1));
dev_info(adev->dev, " UVD_VCPU_CACHE_OFFSET2=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_OFFSET2));
dev_info(adev->dev, " UVD_VCPU_CACHE_SIZE2=0x%08X\n",
RREG32(mmUVD_VCPU_CACHE_SIZE2));
dev_info(adev->dev, " UVD_VCPU_CNTL=0x%08X\n",
RREG32(mmUVD_VCPU_CNTL));
dev_info(adev->dev, " UVD_SOFT_RESET=0x%08X\n",
RREG32(mmUVD_SOFT_RESET));
dev_info(adev->dev, " UVD_RBC_IB_BASE=0x%08X\n",
RREG32(mmUVD_RBC_IB_BASE));
dev_info(adev->dev, " UVD_RBC_IB_SIZE=0x%08X\n",
RREG32(mmUVD_RBC_IB_SIZE));
dev_info(adev->dev, " UVD_RBC_RB_BASE=0x%08X\n",
RREG32(mmUVD_RBC_RB_BASE));
dev_info(adev->dev, " UVD_RBC_RB_RPTR=0x%08X\n",
RREG32(mmUVD_RBC_RB_RPTR));
dev_info(adev->dev, " UVD_RBC_RB_WPTR=0x%08X\n",
RREG32(mmUVD_RBC_RB_WPTR));
dev_info(adev->dev, " UVD_RBC_RB_WPTR_CNTL=0x%08X\n",
RREG32(mmUVD_RBC_RB_WPTR_CNTL));
dev_info(adev->dev, " UVD_RBC_RB_CNTL=0x%08X\n",
RREG32(mmUVD_RBC_RB_CNTL));
dev_info(adev->dev, " UVD_STATUS=0x%08X\n",
RREG32(mmUVD_STATUS));
dev_info(adev->dev, " UVD_SEMA_TIMEOUT_STATUS=0x%08X\n",
RREG32(mmUVD_SEMA_TIMEOUT_STATUS));
dev_info(adev->dev, " UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL=0x%08X\n",
RREG32(mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL));
dev_info(adev->dev, " UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL=0x%08X\n",
RREG32(mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL));
dev_info(adev->dev, " UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL=0x%08X\n",
RREG32(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL));
dev_info(adev->dev, " UVD_CONTEXT_ID=0x%08X\n",
RREG32(mmUVD_CONTEXT_ID));
}
static int uvd_v4_2_set_interrupt_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
unsigned type,
enum amdgpu_interrupt_state state)
{
// TODO
return 0;
}
static int uvd_v4_2_process_interrupt(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
DRM_DEBUG("IH: UVD TRAP\n");
amdgpu_fence_process(&adev->uvd.ring);
return 0;
}
static int uvd_v4_2_set_clockgating_state(struct amdgpu_device *adev,
enum amdgpu_clockgating_state state)
{
bool gate = false;
if (state == AMDGPU_CG_STATE_GATE)
gate = true;
uvd_v4_2_enable_mgcg(adev, gate);
return 0;
}
static int uvd_v4_2_set_powergating_state(struct amdgpu_device *adev,
enum amdgpu_powergating_state state)
{
/* This doesn't actually powergate the UVD block.
* That's done in the dpm code via the SMC. This
* just re-inits the block as necessary. The actual
* gating still happens in the dpm code. We should
* revisit this when there is a cleaner line between
* the smc and the hw blocks
*/
if (state == AMDGPU_PG_STATE_GATE) {
uvd_v4_2_stop(adev);
return 0;
} else {
return uvd_v4_2_start(adev);
}
}
const struct amdgpu_ip_funcs uvd_v4_2_ip_funcs = {
.early_init = uvd_v4_2_early_init,
.late_init = NULL,
.sw_init = uvd_v4_2_sw_init,
.sw_fini = uvd_v4_2_sw_fini,
.hw_init = uvd_v4_2_hw_init,
.hw_fini = uvd_v4_2_hw_fini,
.suspend = uvd_v4_2_suspend,
.resume = uvd_v4_2_resume,
.is_idle = uvd_v4_2_is_idle,
.wait_for_idle = uvd_v4_2_wait_for_idle,
.soft_reset = uvd_v4_2_soft_reset,
.print_status = uvd_v4_2_print_status,
.set_clockgating_state = uvd_v4_2_set_clockgating_state,
.set_powergating_state = uvd_v4_2_set_powergating_state,
};
static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = {
.get_rptr = uvd_v4_2_ring_get_rptr,
.get_wptr = uvd_v4_2_ring_get_wptr,
.set_wptr = uvd_v4_2_ring_set_wptr,
.parse_cs = amdgpu_uvd_ring_parse_cs,
.emit_ib = uvd_v4_2_ring_emit_ib,
.emit_fence = uvd_v4_2_ring_emit_fence,
.emit_semaphore = uvd_v4_2_ring_emit_semaphore,
.test_ring = uvd_v4_2_ring_test_ring,
.test_ib = uvd_v4_2_ring_test_ib,
.is_lockup = amdgpu_ring_test_lockup,
};
static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev)
{
adev->uvd.ring.funcs = &uvd_v4_2_ring_funcs;
}
static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = {
.set = uvd_v4_2_set_interrupt_state,
.process = uvd_v4_2_process_interrupt,
};
static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev)
{
adev->uvd.irq.num_types = 1;
adev->uvd.irq.funcs = &uvd_v4_2_irq_funcs;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 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 __UVD_V4_2_H__
#define __UVD_V4_2_H__
extern const struct amdgpu_ip_funcs uvd_v4_2_ip_funcs;
#endif

View File

@ -0,0 +1,642 @@
/*
* Copyright 2013 Advanced Micro Devices, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* Authors: Christian König <christian.koenig@amd.com>
*/
#include <linux/firmware.h>
#include <drm/drmP.h>
#include "amdgpu.h"
#include "amdgpu_vce.h"
#include "cikd.h"
#include "vce/vce_2_0_d.h"
#include "vce/vce_2_0_sh_mask.h"
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"
static void vce_v2_0_mc_resume(struct amdgpu_device *adev);
static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev);
static void vce_v2_0_set_irq_funcs(struct amdgpu_device *adev);
/**
* vce_v2_0_ring_get_rptr - get read pointer
*
* @ring: amdgpu_ring pointer
*
* Returns the current hardware read pointer
*/
static uint32_t vce_v2_0_ring_get_rptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
if (ring == &adev->vce.ring[0])
return RREG32(mmVCE_RB_RPTR);
else
return RREG32(mmVCE_RB_RPTR2);
}
/**
* vce_v2_0_ring_get_wptr - get write pointer
*
* @ring: amdgpu_ring pointer
*
* Returns the current hardware write pointer
*/
static uint32_t vce_v2_0_ring_get_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
if (ring == &adev->vce.ring[0])
return RREG32(mmVCE_RB_WPTR);
else
return RREG32(mmVCE_RB_WPTR2);
}
/**
* vce_v2_0_ring_set_wptr - set write pointer
*
* @ring: amdgpu_ring pointer
*
* Commits the write pointer to the hardware
*/
static void vce_v2_0_ring_set_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
if (ring == &adev->vce.ring[0])
WREG32(mmVCE_RB_WPTR, ring->wptr);
else
WREG32(mmVCE_RB_WPTR2, ring->wptr);
}
/**
* vce_v2_0_start - start VCE block
*
* @adev: amdgpu_device pointer
*
* Setup and start the VCE block
*/
static int vce_v2_0_start(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
int i, j, r;
vce_v2_0_mc_resume(adev);
/* set BUSY flag */
WREG32_P(mmVCE_STATUS, 1, ~1);
ring = &adev->vce.ring[0];
WREG32(mmVCE_RB_RPTR, ring->wptr);
WREG32(mmVCE_RB_WPTR, ring->wptr);
WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
ring = &adev->vce.ring[1];
WREG32(mmVCE_RB_RPTR2, ring->wptr);
WREG32(mmVCE_RB_WPTR2, ring->wptr);
WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK);
WREG32_P(mmVCE_SOFT_RESET,
VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
mdelay(100);
WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
for (i = 0; i < 10; ++i) {
uint32_t status;
for (j = 0; j < 100; ++j) {
status = RREG32(mmVCE_STATUS);
if (status & 2)
break;
mdelay(10);
}
r = 0;
if (status & 2)
break;
DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
mdelay(10);
WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
mdelay(10);
r = -1;
}
/* clear BUSY flag */
WREG32_P(mmVCE_STATUS, 0, ~1);
if (r) {
DRM_ERROR("VCE not responding, giving up!!!\n");
return r;
}
return 0;
}
static int vce_v2_0_early_init(struct amdgpu_device *adev)
{
vce_v2_0_set_ring_funcs(adev);
vce_v2_0_set_irq_funcs(adev);
return 0;
}
static int vce_v2_0_sw_init(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
int r;
/* VCE */
r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq);
if (r)
return r;
r = amdgpu_vce_sw_init(adev);
if (r)
return r;
r = amdgpu_vce_resume(adev);
if (r)
return r;
ring = &adev->vce.ring[0];
sprintf(ring->name, "vce0");
r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
&adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
if (r)
return r;
ring = &adev->vce.ring[1];
sprintf(ring->name, "vce1");
r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
&adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
if (r)
return r;
return r;
}
static int vce_v2_0_sw_fini(struct amdgpu_device *adev)
{
int r;
r = amdgpu_vce_suspend(adev);
if (r)
return r;
r = amdgpu_vce_sw_fini(adev);
if (r)
return r;
return r;
}
static int vce_v2_0_hw_init(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
int r;
r = vce_v2_0_start(adev);
if (r)
return r;
ring = &adev->vce.ring[0];
ring->ready = true;
r = amdgpu_ring_test_ring(ring);
if (r) {
ring->ready = false;
return r;
}
ring = &adev->vce.ring[1];
ring->ready = true;
r = amdgpu_ring_test_ring(ring);
if (r) {
ring->ready = false;
return r;
}
DRM_INFO("VCE initialized successfully.\n");
return 0;
}
static int vce_v2_0_hw_fini(struct amdgpu_device *adev)
{
// TODO
return 0;
}
static int vce_v2_0_suspend(struct amdgpu_device *adev)
{
int r;
r = vce_v2_0_hw_fini(adev);
if (r)
return r;
r = amdgpu_vce_suspend(adev);
if (r)
return r;
return r;
}
static int vce_v2_0_resume(struct amdgpu_device *adev)
{
int r;
r = amdgpu_vce_resume(adev);
if (r)
return r;
r = vce_v2_0_hw_init(adev);
if (r)
return r;
return r;
}
static void vce_v2_0_set_sw_cg(struct amdgpu_device *adev, bool gated)
{
u32 tmp;
if (gated) {
tmp = RREG32(mmVCE_CLOCK_GATING_B);
tmp |= 0xe70000;
WREG32(mmVCE_CLOCK_GATING_B, tmp);
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
tmp |= 0xff000000;
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
tmp &= ~0x3fc;
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
} else {
tmp = RREG32(mmVCE_CLOCK_GATING_B);
tmp |= 0xe7;
tmp &= ~0xe70000;
WREG32(mmVCE_CLOCK_GATING_B, tmp);
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
tmp |= 0x1fe000;
tmp &= ~0xff000000;
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
tmp |= 0x3fc;
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
}
}
static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated)
{
u32 orig, tmp;
tmp = RREG32(mmVCE_CLOCK_GATING_B);
tmp &= ~0x00060006;
if (gated) {
tmp |= 0xe10000;
} else {
tmp |= 0xe1;
tmp &= ~0xe10000;
}
WREG32(mmVCE_CLOCK_GATING_B, tmp);
orig = tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
tmp &= ~0x1fe000;
tmp &= ~0xff000000;
if (tmp != orig)
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
orig = tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
tmp &= ~0x3fc;
if (tmp != orig)
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
if (gated)
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
}
static void vce_v2_0_disable_cg(struct amdgpu_device *adev)
{
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 7);
}
static void vce_v2_0_enable_mgcg(struct amdgpu_device *adev, bool enable)
{
bool sw_cg = false;
if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG)) {
if (sw_cg)
vce_v2_0_set_sw_cg(adev, true);
else
vce_v2_0_set_dyn_cg(adev, true);
} else {
vce_v2_0_disable_cg(adev);
if (sw_cg)
vce_v2_0_set_sw_cg(adev, false);
else
vce_v2_0_set_dyn_cg(adev, false);
}
}
static void vce_v2_0_init_cg(struct amdgpu_device *adev)
{
u32 tmp;
tmp = RREG32(mmVCE_CLOCK_GATING_A);
tmp &= ~0xfff;
tmp |= ((0 << 0) | (4 << 4));
tmp |= 0x40000;
WREG32(mmVCE_CLOCK_GATING_A, tmp);
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
tmp &= ~0xfff;
tmp |= ((0 << 0) | (4 << 4));
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
tmp = RREG32(mmVCE_CLOCK_GATING_B);
tmp |= 0x10;
tmp &= ~0x100000;
WREG32(mmVCE_CLOCK_GATING_B, tmp);
}
static void vce_v2_0_mc_resume(struct amdgpu_device *adev)
{
uint64_t addr = adev->vce.gpu_addr;
uint32_t size;
WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
WREG32(mmVCE_LMI_CTRL, 0x00398000);
WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
WREG32(mmVCE_LMI_SWAP_CNTL, 0);
WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
WREG32(mmVCE_LMI_VM_CTRL, 0);
addr += AMDGPU_VCE_FIRMWARE_OFFSET;
size = AMDGPU_GPU_PAGE_ALIGN(adev->vce.fw->size);
WREG32(mmVCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
addr += size;
size = AMDGPU_VCE_STACK_SIZE;
WREG32(mmVCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
addr += size;
size = AMDGPU_VCE_HEAP_SIZE;
WREG32(mmVCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
vce_v2_0_init_cg(adev);
}
static bool vce_v2_0_is_idle(struct amdgpu_device *adev)
{
return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
}
static int vce_v2_0_wait_for_idle(struct amdgpu_device *adev)
{
unsigned i;
for (i = 0; i < adev->usec_timeout; i++) {
if (!(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK))
return 0;
}
return -ETIMEDOUT;
}
static int vce_v2_0_soft_reset(struct amdgpu_device *adev)
{
WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK,
~SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK);
mdelay(5);
return vce_v2_0_start(adev);
}
static void vce_v2_0_print_status(struct amdgpu_device *adev)
{
dev_info(adev->dev, "VCE 2.0 registers\n");
dev_info(adev->dev, " VCE_STATUS=0x%08X\n",
RREG32(mmVCE_STATUS));
dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n",
RREG32(mmVCE_VCPU_CNTL));
dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_OFFSET0));
dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_SIZE0));
dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_OFFSET1));
dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_SIZE1));
dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_OFFSET2));
dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n",
RREG32(mmVCE_VCPU_CACHE_SIZE2));
dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n",
RREG32(mmVCE_SOFT_RESET));
dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n",
RREG32(mmVCE_RB_BASE_LO2));
dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n",
RREG32(mmVCE_RB_BASE_HI2));
dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n",
RREG32(mmVCE_RB_SIZE2));
dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n",
RREG32(mmVCE_RB_RPTR2));
dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n",
RREG32(mmVCE_RB_WPTR2));
dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n",
RREG32(mmVCE_RB_BASE_LO));
dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n",
RREG32(mmVCE_RB_BASE_HI));
dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n",
RREG32(mmVCE_RB_SIZE));
dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n",
RREG32(mmVCE_RB_RPTR));
dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n",
RREG32(mmVCE_RB_WPTR));
dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n",
RREG32(mmVCE_CLOCK_GATING_A));
dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n",
RREG32(mmVCE_CLOCK_GATING_B));
dev_info(adev->dev, " VCE_CGTT_CLK_OVERRIDE=0x%08X\n",
RREG32(mmVCE_CGTT_CLK_OVERRIDE));
dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n",
RREG32(mmVCE_UENC_CLOCK_GATING));
dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n",
RREG32(mmVCE_UENC_REG_CLOCK_GATING));
dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n",
RREG32(mmVCE_SYS_INT_EN));
dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n",
RREG32(mmVCE_LMI_CTRL2));
dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n",
RREG32(mmVCE_LMI_CTRL));
dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n",
RREG32(mmVCE_LMI_VM_CTRL));
dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n",
RREG32(mmVCE_LMI_SWAP_CNTL));
dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n",
RREG32(mmVCE_LMI_SWAP_CNTL1));
dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n",
RREG32(mmVCE_LMI_CACHE_CTRL));
}
static int vce_v2_0_set_interrupt_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
unsigned type,
enum amdgpu_interrupt_state state)
{
uint32_t val = 0;
if (state == AMDGPU_IRQ_STATE_ENABLE)
val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
return 0;
}
static int vce_v2_0_process_interrupt(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
DRM_DEBUG("IH: VCE\n");
switch (entry->src_data) {
case 0:
amdgpu_fence_process(&adev->vce.ring[0]);
break;
case 1:
amdgpu_fence_process(&adev->vce.ring[1]);
break;
default:
DRM_ERROR("Unhandled interrupt: %d %d\n",
entry->src_id, entry->src_data);
break;
}
return 0;
}
static int vce_v2_0_set_clockgating_state(struct amdgpu_device *adev,
enum amdgpu_clockgating_state state)
{
bool gate = false;
if (state == AMDGPU_CG_STATE_GATE)
gate = true;
vce_v2_0_enable_mgcg(adev, gate);
return 0;
}
static int vce_v2_0_set_powergating_state(struct amdgpu_device *adev,
enum amdgpu_powergating_state state)
{
/* This doesn't actually powergate the VCE block.
* That's done in the dpm code via the SMC. This
* just re-inits the block as necessary. The actual
* gating still happens in the dpm code. We should
* revisit this when there is a cleaner line between
* the smc and the hw blocks
*/
if (state == AMDGPU_PG_STATE_GATE)
/* XXX do we need a vce_v2_0_stop()? */
return 0;
else
return vce_v2_0_start(adev);
}
const struct amdgpu_ip_funcs vce_v2_0_ip_funcs = {
.early_init = vce_v2_0_early_init,
.late_init = NULL,
.sw_init = vce_v2_0_sw_init,
.sw_fini = vce_v2_0_sw_fini,
.hw_init = vce_v2_0_hw_init,
.hw_fini = vce_v2_0_hw_fini,
.suspend = vce_v2_0_suspend,
.resume = vce_v2_0_resume,
.is_idle = vce_v2_0_is_idle,
.wait_for_idle = vce_v2_0_wait_for_idle,
.soft_reset = vce_v2_0_soft_reset,
.print_status = vce_v2_0_print_status,
.set_clockgating_state = vce_v2_0_set_clockgating_state,
.set_powergating_state = vce_v2_0_set_powergating_state,
};
static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = {
.get_rptr = vce_v2_0_ring_get_rptr,
.get_wptr = vce_v2_0_ring_get_wptr,
.set_wptr = vce_v2_0_ring_set_wptr,
.parse_cs = amdgpu_vce_ring_parse_cs,
.emit_ib = amdgpu_vce_ring_emit_ib,
.emit_fence = amdgpu_vce_ring_emit_fence,
.emit_semaphore = amdgpu_vce_ring_emit_semaphore,
.test_ring = amdgpu_vce_ring_test_ring,
.test_ib = amdgpu_vce_ring_test_ib,
.is_lockup = amdgpu_ring_test_lockup,
};
static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev)
{
adev->vce.ring[0].funcs = &vce_v2_0_ring_funcs;
adev->vce.ring[1].funcs = &vce_v2_0_ring_funcs;
}
static const struct amdgpu_irq_src_funcs vce_v2_0_irq_funcs = {
.set = vce_v2_0_set_interrupt_state,
.process = vce_v2_0_process_interrupt,
};
static void vce_v2_0_set_irq_funcs(struct amdgpu_device *adev)
{
adev->vce.irq.num_types = 1;
adev->vce.irq.funcs = &vce_v2_0_irq_funcs;
};

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 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 __VCE_V2_0_H__
#define __VCE_V2_0_H__
extern const struct amdgpu_ip_funcs vce_v2_0_ip_funcs;
#endif