3ed2584f0b
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com> Acked-by: Rex Zhu <Rex.Zhu@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
214 lines
6.3 KiB
C
214 lines
6.3 KiB
C
/*
|
|
* Copyright 2015 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 "pp_debug.h"
|
|
#include <linux/types.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/gfp.h>
|
|
|
|
#include "smumgr.h"
|
|
#include "tonga_smumgr.h"
|
|
#include "smu_ucode_xfer_vi.h"
|
|
#include "tonga_ppsmc.h"
|
|
#include "smu/smu_7_1_2_d.h"
|
|
#include "smu/smu_7_1_2_sh_mask.h"
|
|
#include "cgs_common.h"
|
|
#include "tonga_smc.h"
|
|
#include "smu7_smumgr.h"
|
|
|
|
|
|
static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr)
|
|
{
|
|
int result;
|
|
|
|
/* Assert reset */
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_RESET_CNTL, rst_reg, 1);
|
|
|
|
result = smu7_upload_smu_firmware_image(smumgr);
|
|
if (result)
|
|
return result;
|
|
|
|
/* Clear status */
|
|
cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
|
|
ixSMU_STATUS, 0);
|
|
|
|
/* Enable clock */
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
|
|
|
|
/* De-assert reset */
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_RESET_CNTL, rst_reg, 0);
|
|
|
|
/* Set SMU Auto Start */
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMU_INPUT_DATA, AUTO_START, 1);
|
|
|
|
/* Clear firmware interrupt enable flag */
|
|
cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
|
|
ixFIRMWARE_FLAGS, 0);
|
|
|
|
SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
|
|
RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
|
|
|
|
/**
|
|
* Call Test SMU message with 0x20000 offset to trigger SMU start
|
|
*/
|
|
smu7_send_msg_to_smc_offset(smumgr);
|
|
|
|
/* Wait for done bit to be set */
|
|
SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
|
|
SMU_STATUS, SMU_DONE, 0);
|
|
|
|
/* Check pass/failed indicator */
|
|
if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
|
|
CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
|
|
pr_err("SMU Firmware start failed\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Wait for firmware to initialize */
|
|
SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
|
|
FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int tonga_start_in_non_protection_mode(struct pp_smumgr *smumgr)
|
|
{
|
|
int result = 0;
|
|
|
|
/* wait for smc boot up */
|
|
SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
|
|
RCU_UC_EVENTS, boot_seq_done, 0);
|
|
|
|
/*Clear firmware interrupt enable flag*/
|
|
cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
|
|
ixFIRMWARE_FLAGS, 0);
|
|
|
|
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_RESET_CNTL, rst_reg, 1);
|
|
|
|
result = smu7_upload_smu_firmware_image(smumgr);
|
|
|
|
if (result != 0)
|
|
return result;
|
|
|
|
/* Set smc instruct start point at 0x0 */
|
|
smu7_program_jump_on_start(smumgr);
|
|
|
|
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
|
|
|
|
/*De-assert reset*/
|
|
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMC_SYSCON_RESET_CNTL, rst_reg, 0);
|
|
|
|
/* Wait for firmware to initialize */
|
|
SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
|
|
FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
|
|
|
|
return result;
|
|
}
|
|
|
|
static int tonga_start_smu(struct pp_smumgr *smumgr)
|
|
{
|
|
int result;
|
|
|
|
/* Only start SMC if SMC RAM is not running */
|
|
if (!(smu7_is_smc_ram_running(smumgr) ||
|
|
cgs_is_virtualization_enabled(smumgr->device))) {
|
|
/*Check if SMU is running in protected mode*/
|
|
if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
|
SMU_FIRMWARE, SMU_MODE)) {
|
|
result = tonga_start_in_non_protection_mode(smumgr);
|
|
if (result)
|
|
return result;
|
|
} else {
|
|
result = tonga_start_in_protection_mode(smumgr);
|
|
if (result)
|
|
return result;
|
|
}
|
|
}
|
|
|
|
result = smu7_request_smu_load_fw(smumgr);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Write a 32bit value to the SMC SRAM space.
|
|
* ALL PARAMETERS ARE IN HOST BYTE ORDER.
|
|
* @param smumgr the address of the powerplay hardware manager.
|
|
* @param smcAddress the address in the SMC RAM to access.
|
|
* @param value to write to the SMC SRAM.
|
|
*/
|
|
static int tonga_smu_init(struct pp_smumgr *smumgr)
|
|
{
|
|
struct tonga_smumgr *tonga_priv = NULL;
|
|
int i;
|
|
|
|
tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
|
|
if (tonga_priv == NULL)
|
|
return -ENOMEM;
|
|
|
|
smumgr->backend = tonga_priv;
|
|
|
|
if (smu7_init(smumgr))
|
|
return -EINVAL;
|
|
|
|
for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++)
|
|
tonga_priv->activity_target[i] = 30;
|
|
|
|
return 0;
|
|
}
|
|
|
|
const struct pp_smumgr_func tonga_smu_funcs = {
|
|
.smu_init = &tonga_smu_init,
|
|
.smu_fini = &smu7_smu_fini,
|
|
.start_smu = &tonga_start_smu,
|
|
.check_fw_load_finish = &smu7_check_fw_load_finish,
|
|
.request_smu_load_fw = &smu7_request_smu_load_fw,
|
|
.request_smu_load_specific_fw = NULL,
|
|
.send_msg_to_smc = &smu7_send_msg_to_smc,
|
|
.send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
|
|
.download_pptable_settings = NULL,
|
|
.upload_pptable_settings = NULL,
|
|
.update_smc_table = tonga_update_smc_table,
|
|
.get_offsetof = tonga_get_offsetof,
|
|
.process_firmware_header = tonga_process_firmware_header,
|
|
.init_smc_table = tonga_init_smc_table,
|
|
.update_sclk_threshold = tonga_update_sclk_threshold,
|
|
.thermal_setup_fan_table = tonga_thermal_setup_fan_table,
|
|
.populate_all_graphic_levels = tonga_populate_all_graphic_levels,
|
|
.populate_all_memory_levels = tonga_populate_all_memory_levels,
|
|
.get_mac_definition = tonga_get_mac_definition,
|
|
.initialize_mc_reg_table = tonga_initialize_mc_reg_table,
|
|
.is_dpm_running = tonga_is_dpm_running,
|
|
.populate_requested_graphic_levels = tonga_populate_requested_graphic_levels,
|
|
};
|