drm/amd/powerplay: delete dpm code for Cz/St.

The powerplay implementation has been the default for a
while now.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Rex Zhu 2016-12-23 14:07:25 +08:00 committed by Alex Deucher
parent 634a24d8af
commit db7da7aa3a
6 changed files with 2 additions and 3657 deletions

View File

@ -52,8 +52,7 @@ amdgpu-y += \
# add SMC block
amdgpu-y += \
amdgpu_dpm.o \
amdgpu_powerplay.o \
cz_smc.o cz_dpm.o
amdgpu_powerplay.o
# add DCE block
amdgpu-y += \

View File

@ -78,10 +78,6 @@ static int amdgpu_powerplay_init(struct amdgpu_device *adev)
amd_pp->ip_funcs = &kv_dpm_ip_funcs;
break;
#endif
case CHIP_CARRIZO:
case CHIP_STONEY:
amd_pp->ip_funcs = &cz_dpm_ip_funcs;
break;
default:
ret = -EINVAL;
break;
@ -102,11 +98,9 @@ static int amdgpu_pp_early_init(void *handle)
case CHIP_TONGA:
case CHIP_FIJI:
case CHIP_TOPAZ:
adev->pp_enabled = true;
break;
case CHIP_CARRIZO:
case CHIP_STONEY:
adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
adev->pp_enabled = true;
break;
/* These chips don't have powerplay implemenations */
case CHIP_BONAIRE:

File diff suppressed because it is too large Load Diff

View File

@ -1,239 +0,0 @@
/*
* 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 __CZ_DPM_H__
#define __CZ_DPM_H__
#include "smu8_fusion.h"
#define CZ_AT_DFLT 30
#define CZ_NUM_NBPSTATES 4
#define CZ_NUM_NBPMEMORY_CLOCK 2
#define CZ_MAX_HARDWARE_POWERLEVELS 8
#define CZ_MAX_DISPLAY_CLOCK_LEVEL 8
#define CZ_MAX_DISPLAYPHY_IDS 10
#define PPCZ_VOTINGRIGHTSCLIENTS_DFLT0 0x3FFFC102
#define SMC_RAM_END 0x40000
#define DPMFlags_SCLK_Enabled 0x00000001
#define DPMFlags_UVD_Enabled 0x00000002
#define DPMFlags_VCE_Enabled 0x00000004
#define DPMFlags_ACP_Enabled 0x00000008
#define DPMFlags_ForceHighestValid 0x40000000
#define DPMFlags_Debug 0x80000000
/* Do not change the following, it is also defined in SMU8.h */
#define SMU_EnabledFeatureScoreboard_AcpDpmOn 0x00000001
#define SMU_EnabledFeatureScoreboard_SclkDpmOn 0x00200000
#define SMU_EnabledFeatureScoreboard_UvdDpmOn 0x00800000
#define SMU_EnabledFeatureScoreboard_VceDpmOn 0x01000000
/* temporary solution to SetMinDeepSleepSclk
* should indicate by display adaptor
* 10k Hz unit*/
#define CZ_MIN_DEEP_SLEEP_SCLK 800
enum cz_pt_config_reg_type {
CZ_CONFIGREG_MMR = 0,
CZ_CONFIGREG_SMC_IND,
CZ_CONFIGREG_DIDT_IND,
CZ_CONFIGREG_CACHE,
CZ_CONFIGREG_MAX
};
struct cz_pt_config_reg {
uint32_t offset;
uint32_t mask;
uint32_t shift;
uint32_t value;
enum cz_pt_config_reg_type type;
};
struct cz_dpm_entry {
uint32_t soft_min_clk;
uint32_t hard_min_clk;
uint32_t soft_max_clk;
uint32_t hard_max_clk;
};
struct cz_pl {
uint32_t sclk;
uint8_t vddc_index;
uint8_t ds_divider_index;
uint8_t ss_divider_index;
uint8_t allow_gnb_slow;
uint8_t force_nbp_state;
uint8_t display_wm;
uint8_t vce_wm;
};
struct cz_ps {
struct cz_pl levels[CZ_MAX_HARDWARE_POWERLEVELS];
uint32_t num_levels;
bool need_dfs_bypass;
uint8_t dpm0_pg_nb_ps_lo;
uint8_t dpm0_pg_nb_ps_hi;
uint8_t dpmx_nb_ps_lo;
uint8_t dpmx_nb_ps_hi;
bool force_high;
};
struct cz_displayphy_entry {
uint8_t phy_present;
uint8_t active_lane_mapping;
uint8_t display_conf_type;
uint8_t num_active_lanes;
};
struct cz_displayphy_info {
bool phy_access_initialized;
struct cz_displayphy_entry entries[CZ_MAX_DISPLAYPHY_IDS];
};
struct cz_sys_info {
uint32_t bootup_uma_clk;
uint32_t bootup_sclk;
uint32_t dentist_vco_freq;
uint32_t nb_dpm_enable;
uint32_t nbp_memory_clock[CZ_NUM_NBPMEMORY_CLOCK];
uint32_t nbp_n_clock[CZ_NUM_NBPSTATES];
uint8_t nbp_voltage_index[CZ_NUM_NBPSTATES];
uint32_t display_clock[CZ_MAX_DISPLAY_CLOCK_LEVEL];
uint16_t bootup_nb_voltage_index;
uint8_t htc_tmp_lmt;
uint8_t htc_hyst_lmt;
uint32_t uma_channel_number;
};
struct cz_power_info {
uint32_t active_target[CZ_MAX_HARDWARE_POWERLEVELS];
struct cz_sys_info sys_info;
struct cz_pl boot_pl;
bool disable_nb_ps3_in_battery;
bool battery_state;
uint32_t lowest_valid;
uint32_t highest_valid;
uint16_t high_voltage_threshold;
/* smc offsets */
uint32_t sram_end;
uint32_t dpm_table_start;
uint32_t soft_regs_start;
/* dpm SMU tables */
uint8_t uvd_level_count;
uint8_t vce_level_count;
uint8_t acp_level_count;
uint32_t fps_high_threshold;
uint32_t fps_low_threshold;
/* dpm table */
uint32_t dpm_flags;
struct cz_dpm_entry sclk_dpm;
struct cz_dpm_entry uvd_dpm;
struct cz_dpm_entry vce_dpm;
struct cz_dpm_entry acp_dpm;
uint8_t uvd_boot_level;
uint8_t uvd_interval;
uint8_t vce_boot_level;
uint8_t vce_interval;
uint8_t acp_boot_level;
uint8_t acp_interval;
uint8_t graphics_boot_level;
uint8_t graphics_interval;
uint8_t graphics_therm_throttle_enable;
uint8_t graphics_voltage_change_enable;
uint8_t graphics_clk_slow_enable;
uint8_t graphics_clk_slow_divider;
uint32_t low_sclk_interrupt_threshold;
bool uvd_power_gated;
bool vce_power_gated;
bool acp_power_gated;
uint32_t active_process_mask;
uint32_t mgcg_cgtt_local0;
uint32_t mgcg_cgtt_local1;
uint32_t clock_slow_down_step;
uint32_t skip_clock_slow_down;
bool enable_nb_ps_policy;
uint32_t voting_clients;
uint32_t voltage_drop_threshold;
uint32_t gfx_pg_threshold;
uint32_t max_sclk_level;
uint32_t max_uvd_level;
uint32_t max_vce_level;
/* flags */
bool didt_enabled;
bool video_start;
bool cac_enabled;
bool bapm_enabled;
bool nb_dpm_enabled_by_driver;
bool nb_dpm_enabled;
bool auto_thermal_throttling_enabled;
bool dpm_enabled;
bool need_pptable_upload;
/* 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_dpm;
bool caps_vce_pg;
bool caps_acp_dpm;
bool caps_acp_pg;
bool caps_stable_power_state;
bool caps_enable_dfs_bypass;
bool caps_sclk_ds;
bool caps_voltage_island;
/* power state */
struct amdgpu_ps current_rps;
struct cz_ps current_ps;
struct amdgpu_ps requested_rps;
struct cz_ps requested_ps;
bool uvd_power_down;
bool vce_power_down;
bool acp_power_down;
bool uvd_dynamic_pg;
};
/* cz_smc.c */
uint32_t cz_get_argument(struct amdgpu_device *adev);
int cz_send_msg_to_smc(struct amdgpu_device *adev, uint16_t msg);
int cz_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
uint16_t msg, uint32_t parameter);
int cz_read_smc_sram_dword(struct amdgpu_device *adev,
uint32_t smc_address, uint32_t *value, uint32_t limit);
int cz_smu_upload_pptable(struct amdgpu_device *adev);
int cz_smu_download_pptable(struct amdgpu_device *adev, void **table);
#endif

View File

@ -1,995 +0,0 @@
/*
* 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.
*
*/
#include <linux/firmware.h>
#include "drmP.h"
#include "amdgpu.h"
#include "smu8.h"
#include "smu8_fusion.h"
#include "cz_ppsmc.h"
#include "cz_smumgr.h"
#include "smu_ucode_xfer_cz.h"
#include "amdgpu_ucode.h"
#include "cz_dpm.h"
#include "vi_dpm.h"
#include "smu/smu_8_0_d.h"
#include "smu/smu_8_0_sh_mask.h"
#include "gca/gfx_8_0_d.h"
#include "gca/gfx_8_0_sh_mask.h"
uint32_t cz_get_argument(struct amdgpu_device *adev)
{
return RREG32(mmSMU_MP1_SRBM2P_ARG_0);
}
static struct cz_smu_private_data *cz_smu_get_priv(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv =
(struct cz_smu_private_data *)(adev->smu.priv);
return priv;
}
static int cz_send_msg_to_smc_async(struct amdgpu_device *adev, u16 msg)
{
int i;
u32 content = 0, tmp;
for (i = 0; i < adev->usec_timeout; i++) {
tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
SMU_MP1_SRBM2P_RESP_0, CONTENT);
if (content != tmp)
break;
udelay(1);
}
/* timeout means wrong logic*/
if (i == adev->usec_timeout)
return -EINVAL;
WREG32(mmSMU_MP1_SRBM2P_RESP_0, 0);
WREG32(mmSMU_MP1_SRBM2P_MSG_0, msg);
return 0;
}
int cz_send_msg_to_smc(struct amdgpu_device *adev, u16 msg)
{
int i;
u32 content = 0, tmp = 0;
if (cz_send_msg_to_smc_async(adev, msg))
return -EINVAL;
for (i = 0; i < adev->usec_timeout; i++) {
tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
SMU_MP1_SRBM2P_RESP_0, CONTENT);
if (content != tmp)
break;
udelay(1);
}
/* timeout means wrong logic*/
if (i == adev->usec_timeout)
return -EINVAL;
if (PPSMC_Result_OK != tmp) {
dev_err(adev->dev, "SMC Failed to send Message.\n");
return -EINVAL;
}
return 0;
}
int cz_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
u16 msg, u32 parameter)
{
WREG32(mmSMU_MP1_SRBM2P_ARG_0, parameter);
return cz_send_msg_to_smc(adev, msg);
}
static int cz_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(mmMP0PUB_IND_INDEX_0, SMN_MP1_SRAM_START_ADDR + smc_address);
return 0;
}
int cz_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
u32 *value, u32 limit)
{
int ret;
ret = cz_set_smc_sram_address(adev, smc_address, limit);
if (ret)
return ret;
*value = RREG32(mmMP0PUB_IND_DATA_0);
return 0;
}
static int cz_write_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
u32 value, u32 limit)
{
int ret;
ret = cz_set_smc_sram_address(adev, smc_address, limit);
if (ret)
return ret;
WREG32(mmMP0PUB_IND_DATA_0, value);
return 0;
}
static int cz_smu_request_load_fw(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
uint32_t smc_addr = SMU8_FIRMWARE_HEADER_LOCATION +
offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
cz_write_smc_sram_dword(adev, smc_addr, 0, smc_addr + 4);
/*prepare toc buffers*/
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_DriverDramAddrHi,
priv->toc_buffer.mc_addr_high);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_DriverDramAddrLo,
priv->toc_buffer.mc_addr_low);
cz_send_msg_to_smc(adev, PPSMC_MSG_InitJobs);
/*execute jobs*/
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_ExecuteJob,
priv->toc_entry_aram);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_ExecuteJob,
priv->toc_entry_power_profiling_index);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_ExecuteJob,
priv->toc_entry_initialize_index);
return 0;
}
/*
*Check if the FW has been loaded, SMU will not return if loading
*has not finished.
*/
static int cz_smu_check_fw_load_finish(struct amdgpu_device *adev,
uint32_t fw_mask)
{
int i;
uint32_t index = SMN_MP1_SRAM_START_ADDR +
SMU8_FIRMWARE_HEADER_LOCATION +
offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
WREG32(mmMP0PUB_IND_INDEX, index);
for (i = 0; i < adev->usec_timeout; i++) {
if (fw_mask == (RREG32(mmMP0PUB_IND_DATA) & fw_mask))
break;
udelay(1);
}
if (i >= adev->usec_timeout) {
dev_err(adev->dev,
"SMU check loaded firmware failed, expecting 0x%x, getting 0x%x",
fw_mask, RREG32(mmMP0PUB_IND_DATA));
return -EINVAL;
}
return 0;
}
/*
* interfaces for different ip blocks to check firmware loading status
* 0 for success otherwise failed
*/
static int cz_smu_check_finished(struct amdgpu_device *adev,
enum AMDGPU_UCODE_ID id)
{
switch (id) {
case AMDGPU_UCODE_ID_SDMA0:
if (adev->smu.fw_flags & AMDGPU_SDMA0_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_SDMA1:
if (adev->smu.fw_flags & AMDGPU_SDMA1_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_CP_CE:
if (adev->smu.fw_flags & AMDGPU_CPCE_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_CP_PFP:
if (adev->smu.fw_flags & AMDGPU_CPPFP_UCODE_LOADED)
return 0;
case AMDGPU_UCODE_ID_CP_ME:
if (adev->smu.fw_flags & AMDGPU_CPME_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_CP_MEC1:
if (adev->smu.fw_flags & AMDGPU_CPMEC1_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_CP_MEC2:
if (adev->smu.fw_flags & AMDGPU_CPMEC2_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_RLC_G:
if (adev->smu.fw_flags & AMDGPU_CPRLC_UCODE_LOADED)
return 0;
break;
case AMDGPU_UCODE_ID_MAXIMUM:
default:
break;
}
return 1;
}
static int cz_load_mec_firmware(struct amdgpu_device *adev)
{
struct amdgpu_firmware_info *ucode =
&adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
uint32_t reg_data;
uint32_t tmp;
if (ucode->fw == NULL)
return -EINVAL;
/* Disable MEC parsing/prefetching */
tmp = RREG32(mmCP_MEC_CNTL);
tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1);
tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1);
WREG32(mmCP_MEC_CNTL, tmp);
tmp = RREG32(mmCP_CPC_IC_BASE_CNTL);
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0);
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, ATC, 0);
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, MTYPE, 1);
WREG32(mmCP_CPC_IC_BASE_CNTL, tmp);
reg_data = lower_32_bits(ucode->mc_addr) &
REG_FIELD_MASK(CP_CPC_IC_BASE_LO, IC_BASE_LO);
WREG32(mmCP_CPC_IC_BASE_LO, reg_data);
reg_data = upper_32_bits(ucode->mc_addr) &
REG_FIELD_MASK(CP_CPC_IC_BASE_HI, IC_BASE_HI);
WREG32(mmCP_CPC_IC_BASE_HI, reg_data);
return 0;
}
int cz_smu_start(struct amdgpu_device *adev)
{
int ret = 0;
uint32_t fw_to_check = UCODE_ID_RLC_G_MASK |
UCODE_ID_SDMA0_MASK |
UCODE_ID_SDMA1_MASK |
UCODE_ID_CP_CE_MASK |
UCODE_ID_CP_ME_MASK |
UCODE_ID_CP_PFP_MASK |
UCODE_ID_CP_MEC_JT1_MASK |
UCODE_ID_CP_MEC_JT2_MASK;
if (adev->asic_type == CHIP_STONEY)
fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK);
cz_smu_request_load_fw(adev);
ret = cz_smu_check_fw_load_finish(adev, fw_to_check);
if (ret)
return ret;
/* manually load MEC firmware for CZ */
if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY) {
ret = cz_load_mec_firmware(adev);
if (ret) {
dev_err(adev->dev, "(%d) Mec Firmware load failed\n", ret);
return ret;
}
}
/* setup fw load flag */
adev->smu.fw_flags = AMDGPU_SDMA0_UCODE_LOADED |
AMDGPU_SDMA1_UCODE_LOADED |
AMDGPU_CPCE_UCODE_LOADED |
AMDGPU_CPPFP_UCODE_LOADED |
AMDGPU_CPME_UCODE_LOADED |
AMDGPU_CPMEC1_UCODE_LOADED |
AMDGPU_CPMEC2_UCODE_LOADED |
AMDGPU_CPRLC_UCODE_LOADED;
if (adev->asic_type == CHIP_STONEY)
adev->smu.fw_flags &= ~(AMDGPU_SDMA1_UCODE_LOADED | AMDGPU_CPMEC2_UCODE_LOADED);
return ret;
}
static uint32_t cz_convert_fw_type(uint32_t fw_type)
{
enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
switch (fw_type) {
case UCODE_ID_SDMA0:
result = AMDGPU_UCODE_ID_SDMA0;
break;
case UCODE_ID_SDMA1:
result = AMDGPU_UCODE_ID_SDMA1;
break;
case UCODE_ID_CP_CE:
result = AMDGPU_UCODE_ID_CP_CE;
break;
case UCODE_ID_CP_PFP:
result = AMDGPU_UCODE_ID_CP_PFP;
break;
case UCODE_ID_CP_ME:
result = AMDGPU_UCODE_ID_CP_ME;
break;
case UCODE_ID_CP_MEC_JT1:
case UCODE_ID_CP_MEC_JT2:
result = AMDGPU_UCODE_ID_CP_MEC1;
break;
case UCODE_ID_RLC_G:
result = AMDGPU_UCODE_ID_RLC_G;
break;
default:
DRM_ERROR("UCode type is out of range!");
}
return result;
}
static uint8_t cz_smu_translate_firmware_enum_to_arg(
enum cz_scratch_entry firmware_enum)
{
uint8_t ret = 0;
switch (firmware_enum) {
case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0:
ret = UCODE_ID_SDMA0;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1:
ret = UCODE_ID_SDMA1;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE:
ret = UCODE_ID_CP_CE;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP:
ret = UCODE_ID_CP_PFP;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME:
ret = UCODE_ID_CP_ME;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1:
ret = UCODE_ID_CP_MEC_JT1;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2:
ret = UCODE_ID_CP_MEC_JT2;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG:
ret = UCODE_ID_GMCON_RENG;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G:
ret = UCODE_ID_RLC_G;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH:
ret = UCODE_ID_RLC_SCRATCH;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM:
ret = UCODE_ID_RLC_SRM_ARAM;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM:
ret = UCODE_ID_RLC_SRM_DRAM;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM:
ret = UCODE_ID_DMCU_ERAM;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM:
ret = UCODE_ID_DMCU_IRAM;
break;
case CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING:
ret = TASK_ARG_INIT_MM_PWR_LOG;
break;
case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT:
case CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING:
case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS:
case CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT:
case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START:
case CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS:
ret = TASK_ARG_REG_MMIO;
break;
case CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE:
ret = TASK_ARG_INIT_CLK_TABLE;
break;
}
return ret;
}
static int cz_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
enum cz_scratch_entry firmware_enum,
struct cz_buffer_entry *entry)
{
uint64_t gpu_addr;
uint32_t data_size;
uint8_t ucode_id = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
enum AMDGPU_UCODE_ID id = cz_convert_fw_type(ucode_id);
struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
const struct gfx_firmware_header_v1_0 *header;
if (ucode->fw == NULL)
return -EINVAL;
gpu_addr = ucode->mc_addr;
header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
data_size = le32_to_cpu(header->header.ucode_size_bytes);
if ((firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1) ||
(firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2)) {
gpu_addr += le32_to_cpu(header->jt_offset) << 2;
data_size = le32_to_cpu(header->jt_size) << 2;
}
entry->mc_addr_low = lower_32_bits(gpu_addr);
entry->mc_addr_high = upper_32_bits(gpu_addr);
entry->data_size = data_size;
entry->firmware_ID = firmware_enum;
return 0;
}
static int cz_smu_populate_single_scratch_entry(struct amdgpu_device *adev,
enum cz_scratch_entry scratch_type,
uint32_t size_in_byte,
struct cz_buffer_entry *entry)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
uint64_t mc_addr = (((uint64_t) priv->smu_buffer.mc_addr_high) << 32) |
priv->smu_buffer.mc_addr_low;
mc_addr += size_in_byte;
priv->smu_buffer_used_bytes += size_in_byte;
entry->data_size = size_in_byte;
entry->kaddr = priv->smu_buffer.kaddr + priv->smu_buffer_used_bytes;
entry->mc_addr_low = lower_32_bits(mc_addr);
entry->mc_addr_high = upper_32_bits(mc_addr);
entry->firmware_ID = scratch_type;
return 0;
}
static int cz_smu_populate_single_ucode_load_task(struct amdgpu_device *adev,
enum cz_scratch_entry firmware_enum,
bool is_last)
{
uint8_t i;
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
task->type = TASK_TYPE_UCODE_LOAD;
task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
for (i = 0; i < priv->driver_buffer_length; i++)
if (priv->driver_buffer[i].firmware_ID == firmware_enum)
break;
if (i >= priv->driver_buffer_length) {
dev_err(adev->dev, "Invalid Firmware Type\n");
return -EINVAL;
}
task->addr.low = priv->driver_buffer[i].mc_addr_low;
task->addr.high = priv->driver_buffer[i].mc_addr_high;
task->size_bytes = priv->driver_buffer[i].data_size;
return 0;
}
static int cz_smu_populate_single_scratch_task(struct amdgpu_device *adev,
enum cz_scratch_entry firmware_enum,
uint8_t type, bool is_last)
{
uint8_t i;
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
task->type = type;
task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
for (i = 0; i < priv->scratch_buffer_length; i++)
if (priv->scratch_buffer[i].firmware_ID == firmware_enum)
break;
if (i >= priv->scratch_buffer_length) {
dev_err(adev->dev, "Invalid Firmware Type\n");
return -EINVAL;
}
task->addr.low = priv->scratch_buffer[i].mc_addr_low;
task->addr.high = priv->scratch_buffer[i].mc_addr_high;
task->size_bytes = priv->scratch_buffer[i].data_size;
if (CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS == firmware_enum) {
struct cz_ih_meta_data *pIHReg_restore =
(struct cz_ih_meta_data *)priv->scratch_buffer[i].kaddr;
pIHReg_restore->command =
METADATA_CMD_MODE0 | METADATA_PERFORM_ON_LOAD;
}
return 0;
}
static int cz_smu_construct_toc_for_rlc_aram_save(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
priv->toc_entry_aram = priv->toc_entry_used_count;
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
TASK_TYPE_UCODE_SAVE, true);
return 0;
}
static int cz_smu_construct_toc_for_vddgfx_enter(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
toc->JobList[JOB_GFX_SAVE] = (uint8_t)priv->toc_entry_used_count;
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
TASK_TYPE_UCODE_SAVE, false);
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
TASK_TYPE_UCODE_SAVE, true);
return 0;
}
static int cz_smu_construct_toc_for_vddgfx_exit(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
toc->JobList[JOB_GFX_RESTORE] = (uint8_t)priv->toc_entry_used_count;
/* populate ucode */
if (adev->firmware.smu_load) {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
if (adev->asic_type == CHIP_STONEY) {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
} else {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
}
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, false);
}
/* populate scratch */
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
TASK_TYPE_UCODE_LOAD, false);
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
TASK_TYPE_UCODE_LOAD, false);
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
TASK_TYPE_UCODE_LOAD, true);
return 0;
}
static int cz_smu_construct_toc_for_power_profiling(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
priv->toc_entry_power_profiling_index = priv->toc_entry_used_count;
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
TASK_TYPE_INITIALIZE, true);
return 0;
}
static int cz_smu_construct_toc_for_bootup(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
priv->toc_entry_initialize_index = priv->toc_entry_used_count;
if (adev->firmware.smu_load) {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
if (adev->asic_type == CHIP_STONEY) {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
} else {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false);
}
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
if (adev->asic_type == CHIP_STONEY) {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
} else {
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
}
cz_smu_populate_single_ucode_load_task(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, true);
}
return 0;
}
static int cz_smu_construct_toc_for_clock_table(struct amdgpu_device *adev)
{
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
priv->toc_entry_clock_table = priv->toc_entry_used_count;
cz_smu_populate_single_scratch_task(adev,
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
TASK_TYPE_INITIALIZE, true);
return 0;
}
static int cz_smu_initialize_toc_empty_job_list(struct amdgpu_device *adev)
{
int i;
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
for (i = 0; i < NUM_JOBLIST_ENTRIES; i++)
toc->JobList[i] = (uint8_t)IGNORE_JOB;
return 0;
}
/*
* cz smu uninitialization
*/
int cz_smu_fini(struct amdgpu_device *adev)
{
amdgpu_bo_unref(&adev->smu.toc_buf);
amdgpu_bo_unref(&adev->smu.smu_buf);
kfree(adev->smu.priv);
adev->smu.priv = NULL;
if (adev->firmware.smu_load)
amdgpu_ucode_fini_bo(adev);
return 0;
}
int cz_smu_download_pptable(struct amdgpu_device *adev, void **table)
{
uint8_t i;
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
for (i = 0; i < priv->scratch_buffer_length; i++)
if (priv->scratch_buffer[i].firmware_ID ==
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
break;
if (i >= priv->scratch_buffer_length) {
dev_err(adev->dev, "Invalid Scratch Type\n");
return -EINVAL;
}
*table = (struct SMU8_Fusion_ClkTable *)priv->scratch_buffer[i].kaddr;
/* prepare buffer for pptable */
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_SetClkTableAddrHi,
priv->scratch_buffer[i].mc_addr_high);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_SetClkTableAddrLo,
priv->scratch_buffer[i].mc_addr_low);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_ExecuteJob,
priv->toc_entry_clock_table);
/* actual downloading */
cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToDram);
return 0;
}
int cz_smu_upload_pptable(struct amdgpu_device *adev)
{
uint8_t i;
struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
for (i = 0; i < priv->scratch_buffer_length; i++)
if (priv->scratch_buffer[i].firmware_ID ==
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
break;
if (i >= priv->scratch_buffer_length) {
dev_err(adev->dev, "Invalid Scratch Type\n");
return -EINVAL;
}
/* prepare SMU */
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_SetClkTableAddrHi,
priv->scratch_buffer[i].mc_addr_high);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_SetClkTableAddrLo,
priv->scratch_buffer[i].mc_addr_low);
cz_send_msg_to_smc_with_parameter(adev,
PPSMC_MSG_ExecuteJob,
priv->toc_entry_clock_table);
/* actual uploading */
cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToSmu);
return 0;
}
/*
* cz smumgr functions initialization
*/
static const struct amdgpu_smumgr_funcs cz_smumgr_funcs = {
.check_fw_load_finish = cz_smu_check_finished,
.request_smu_load_fw = NULL,
.request_smu_specific_fw = NULL,
};
/*
* cz smu initialization
*/
int cz_smu_init(struct amdgpu_device *adev)
{
int ret = -EINVAL;
uint64_t mc_addr = 0;
struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
void *toc_buf_ptr = NULL;
void *smu_buf_ptr = NULL;
struct cz_smu_private_data *priv =
kzalloc(sizeof(struct cz_smu_private_data), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
/* allocate firmware buffers */
if (adev->firmware.smu_load)
amdgpu_ucode_init_bo(adev);
adev->smu.priv = priv;
adev->smu.fw_flags = 0;
priv->toc_buffer.data_size = 4096;
priv->smu_buffer.data_size =
ALIGN(UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 32) +
ALIGN(UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 32) +
ALIGN(UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 32) +
ALIGN(sizeof(struct SMU8_MultimediaPowerLogData), 32) +
ALIGN(sizeof(struct SMU8_Fusion_ClkTable), 32);
/* prepare toc buffer and smu buffer:
* 1. create amdgpu_bo for toc buffer and smu buffer
* 2. pin mc address
* 3. map kernel virtual address
*/
ret = amdgpu_bo_create(adev, priv->toc_buffer.data_size, PAGE_SIZE,
true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
toc_buf);
if (ret) {
dev_err(adev->dev, "(%d) SMC TOC buffer allocation failed\n", ret);
return ret;
}
ret = amdgpu_bo_create(adev, priv->smu_buffer.data_size, PAGE_SIZE,
true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
smu_buf);
if (ret) {
dev_err(adev->dev, "(%d) SMC Internal buffer allocation failed\n", ret);
return ret;
}
/* toc buffer reserve/pin/map */
ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
if (ret) {
amdgpu_bo_unref(&adev->smu.toc_buf);
dev_err(adev->dev, "(%d) SMC TOC buffer reserve failed\n", ret);
return ret;
}
ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
if (ret) {
amdgpu_bo_unreserve(adev->smu.toc_buf);
amdgpu_bo_unref(&adev->smu.toc_buf);
dev_err(adev->dev, "(%d) SMC TOC buffer pin failed\n", ret);
return ret;
}
ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
if (ret)
goto smu_init_failed;
amdgpu_bo_unreserve(adev->smu.toc_buf);
priv->toc_buffer.mc_addr_low = lower_32_bits(mc_addr);
priv->toc_buffer.mc_addr_high = upper_32_bits(mc_addr);
priv->toc_buffer.kaddr = toc_buf_ptr;
/* smu buffer reserve/pin/map */
ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
if (ret) {
amdgpu_bo_unref(&adev->smu.smu_buf);
dev_err(adev->dev, "(%d) SMC Internal buffer reserve failed\n", ret);
return ret;
}
ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
if (ret) {
amdgpu_bo_unreserve(adev->smu.smu_buf);
amdgpu_bo_unref(&adev->smu.smu_buf);
dev_err(adev->dev, "(%d) SMC Internal buffer pin failed\n", ret);
return ret;
}
ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
if (ret)
goto smu_init_failed;
amdgpu_bo_unreserve(adev->smu.smu_buf);
priv->smu_buffer.mc_addr_low = lower_32_bits(mc_addr);
priv->smu_buffer.mc_addr_high = upper_32_bits(mc_addr);
priv->smu_buffer.kaddr = smu_buf_ptr;
if (adev->firmware.smu_load) {
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
if (adev->asic_type == CHIP_STONEY) {
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
} else {
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
}
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
if (adev->asic_type == CHIP_STONEY) {
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
} else {
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
}
if (cz_smu_populate_single_firmware_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
&priv->driver_buffer[priv->driver_buffer_length++]))
goto smu_init_failed;
}
if (cz_smu_populate_single_scratch_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
UCODE_ID_RLC_SCRATCH_SIZE_BYTE,
&priv->scratch_buffer[priv->scratch_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_scratch_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE,
&priv->scratch_buffer[priv->scratch_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_scratch_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE,
&priv->scratch_buffer[priv->scratch_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_scratch_entry(adev,
CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
sizeof(struct SMU8_MultimediaPowerLogData),
&priv->scratch_buffer[priv->scratch_buffer_length++]))
goto smu_init_failed;
if (cz_smu_populate_single_scratch_entry(adev,
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
sizeof(struct SMU8_Fusion_ClkTable),
&priv->scratch_buffer[priv->scratch_buffer_length++]))
goto smu_init_failed;
cz_smu_initialize_toc_empty_job_list(adev);
cz_smu_construct_toc_for_rlc_aram_save(adev);
cz_smu_construct_toc_for_vddgfx_enter(adev);
cz_smu_construct_toc_for_vddgfx_exit(adev);
cz_smu_construct_toc_for_power_profiling(adev);
cz_smu_construct_toc_for_bootup(adev);
cz_smu_construct_toc_for_clock_table(adev);
/* init the smumgr functions */
adev->smu.smumgr_funcs = &cz_smumgr_funcs;
return 0;
smu_init_failed:
amdgpu_bo_unref(toc_buf);
amdgpu_bo_unref(smu_buf);
return ret;
}

View File

@ -1,94 +0,0 @@
/*
* 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 __CZ_SMC_H__
#define __CZ_SMC_H__
#define MAX_NUM_FIRMWARE 8
#define MAX_NUM_SCRATCH 11
#define CZ_SCRATCH_SIZE_NONGFX_CLOCKGATING 1024
#define CZ_SCRATCH_SIZE_NONGFX_GOLDENSETTING 2048
#define CZ_SCRATCH_SIZE_SDMA_METADATA 1024
#define CZ_SCRATCH_SIZE_IH ((2*256+1)*4)
enum cz_scratch_entry {
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0 = 0,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM,
CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM,
CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT,
CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS,
CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START,
CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS,
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE
};
struct cz_buffer_entry {
uint32_t data_size;
uint32_t mc_addr_low;
uint32_t mc_addr_high;
void *kaddr;
enum cz_scratch_entry firmware_ID;
};
struct cz_register_index_data_pair {
uint32_t offset;
uint32_t value;
};
struct cz_ih_meta_data {
uint32_t command;
struct cz_register_index_data_pair register_index_value_pair[1];
};
struct cz_smu_private_data {
uint8_t driver_buffer_length;
uint8_t scratch_buffer_length;
uint16_t toc_entry_used_count;
uint16_t toc_entry_initialize_index;
uint16_t toc_entry_power_profiling_index;
uint16_t toc_entry_aram;
uint16_t toc_entry_ih_register_restore_task_index;
uint16_t toc_entry_clock_table;
uint16_t ih_register_restore_task_size;
uint16_t smu_buffer_used_bytes;
struct cz_buffer_entry toc_buffer;
struct cz_buffer_entry smu_buffer;
struct cz_buffer_entry driver_buffer[MAX_NUM_FIRMWARE];
struct cz_buffer_entry scratch_buffer[MAX_NUM_SCRATCH];
};
#endif