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
static int tonga_start_in_protection_mode(struct pp_hwmgr *hwmgr)
41 42 43 44
{
	int result;

	/* Assert reset */
45
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
46 47
		SMC_SYSCON_RESET_CNTL, rst_reg, 1);

48
	result = smu7_upload_smu_firmware_image(hwmgr);
49 50 51 52
	if (result)
		return result;

	/* Clear status */
53
	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
54 55 56
		ixSMU_STATUS, 0);

	/* Enable clock */
57
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
58 59 60
		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);

	/* De-assert reset */
61
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
62 63 64
		SMC_SYSCON_RESET_CNTL, rst_reg, 0);

	/* Set SMU Auto Start */
65
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
66 67 68
		SMU_INPUT_DATA, AUTO_START, 1);

	/* Clear firmware interrupt enable flag */
69
	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
70 71
		ixFIRMWARE_FLAGS, 0);

72
	SMUM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
73 74 75 76 77
		RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);

	/**
	 * Call Test SMU message with 0x20000 offset to trigger SMU start
	 */
78
	smu7_send_msg_to_smc_offset(hwmgr);
79 80

	/* Wait for done bit to be set */
81
	PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND,
82 83 84
		SMU_STATUS, SMU_DONE, 0);

	/* Check pass/failed indicator */
85
	if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
86
				CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
87
		pr_err("SMU Firmware start failed\n");
88 89 90 91
		return -EINVAL;
	}

	/* Wait for firmware to initialize */
92
	SMUM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
93 94 95 96 97 98
		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);

	return 0;
}


99
static int tonga_start_in_non_protection_mode(struct pp_hwmgr *hwmgr)
100 101 102 103
{
	int result = 0;

	/* wait for smc boot up */
104
	PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND,
105 106 107
		RCU_UC_EVENTS, boot_seq_done, 0);

	/*Clear firmware interrupt enable flag*/
108
	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
109 110 111
		ixFIRMWARE_FLAGS, 0);


112
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
113 114
		SMC_SYSCON_RESET_CNTL, rst_reg, 1);

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

	if (result != 0)
		return result;

	/* Set smc instruct start point at 0x0 */
121
	smu7_program_jump_on_start(hwmgr);
122 123


124
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
125 126 127
		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);

	/*De-assert reset*/
128
	SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
129 130 131
		SMC_SYSCON_RESET_CNTL, rst_reg, 0);

	/* Wait for firmware to initialize */
132
	SMUM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
133 134 135 136 137
		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);

	return result;
}

138
static int tonga_start_smu(struct pp_hwmgr *hwmgr)
139 140 141 142
{
	int result;

	/* Only start SMC if SMC RAM is not running */
143 144
	if (!(smu7_is_smc_ram_running(hwmgr) ||
		cgs_is_virtualization_enabled(hwmgr->device))) {
145
		/*Check if SMU is running in protected mode*/
146
		if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
147
					SMU_FIRMWARE, SMU_MODE)) {
148
			result = tonga_start_in_non_protection_mode(hwmgr);
149 150 151
			if (result)
				return result;
		} else {
152
			result = tonga_start_in_protection_mode(hwmgr);
153 154 155 156 157
			if (result)
				return result;
		}
	}

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

	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.
 */
170
static int tonga_smu_init(struct pp_hwmgr *hwmgr)
171
{
R
Rex Zhu 已提交
172 173
	struct tonga_smumgr *tonga_priv = NULL;
	int  i;
174

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

179
	hwmgr->smu_backend = tonga_priv;
180

181
	if (smu7_init(hwmgr))
182
		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
	.populate_requested_graphic_levels = tonga_populate_requested_graphic_levels,
213
};