tonga_smumgr.c 6.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * 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.
 *
 */
23
#include "pp_debug.h"
24 25 26 27 28 29 30 31 32 33 34 35
#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"
36
#include "tonga_smc.h"
37
#include "smu7_smumgr.h"
38 39 40 41 42 43 44 45 46 47


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);

48
	result = smu7_upload_smu_firmware_image(smumgr);
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	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
	 */
78
	smu7_send_msg_to_smc_offset(smumgr);
79 80 81 82 83 84 85 86

	/* 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)) {
87
		pr_err("SMU Firmware start failed\n");
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
		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);

115
	result = smu7_upload_smu_firmware_image(smumgr);
116 117 118 119 120

	if (result != 0)
		return result;

	/* Set smc instruct start point at 0x0 */
121
	smu7_program_jump_on_start(smumgr);
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142


	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 */
143 144
	if (!(smu7_is_smc_ram_running(smumgr) ||
		cgs_is_virtualization_enabled(smumgr->device))) {
145 146 147 148 149 150 151 152 153 154 155 156 157
		/*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;
		}
	}

158
	result = smu7_request_smu_load_fw(smumgr);
159 160 161 162 163 164 165 166 167 168 169 170 171

	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)
{
R
Rex Zhu 已提交
172 173
	struct tonga_smumgr *tonga_priv = NULL;
	int  i;
174

R
Rex Zhu 已提交
175 176 177 178 179
	tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
	if (tonga_priv == NULL)
		return -ENOMEM;

	smumgr->backend = tonga_priv;
180

181 182
	if (smu7_init(smumgr))
		return -EINVAL;
183

184
	for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++)
R
Rex Zhu 已提交
185
		tonga_priv->activity_target[i] = 30;
186

187 188 189
	return 0;
}

R
Rex Zhu 已提交
190
const struct pp_smumgr_func tonga_smu_funcs = {
191
	.smu_init = &tonga_smu_init,
192
	.smu_fini = &smu7_smu_fini,
193
	.start_smu = &tonga_start_smu,
194 195 196 197 198
	.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,
199 200
	.download_pptable_settings = NULL,
	.upload_pptable_settings = NULL,
201 202 203 204 205 206 207 208 209 210 211
	.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,
212
};