• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/slab.h>
26 #include <linux/gfp.h>
27 
28 #include "smumgr.h"
29 #include "tonga_smumgr.h"
30 #include "pp_debug.h"
31 #include "smu_ucode_xfer_vi.h"
32 #include "tonga_ppsmc.h"
33 #include "smu/smu_7_1_2_d.h"
34 #include "smu/smu_7_1_2_sh_mask.h"
35 #include "cgs_common.h"
36 #include "tonga_smc.h"
37 #include "smu7_smumgr.h"
38 
39 
tonga_start_in_protection_mode(struct pp_smumgr * smumgr)40 static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr)
41 {
42 	int result;
43 
44 	/* Assert reset */
45 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
46 		SMC_SYSCON_RESET_CNTL, rst_reg, 1);
47 
48 	result = smu7_upload_smu_firmware_image(smumgr);
49 	if (result)
50 		return result;
51 
52 	/* Clear status */
53 	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
54 		ixSMU_STATUS, 0);
55 
56 	/* Enable clock */
57 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
58 		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
59 
60 	/* De-assert reset */
61 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
62 		SMC_SYSCON_RESET_CNTL, rst_reg, 0);
63 
64 	/* Set SMU Auto Start */
65 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
66 		SMU_INPUT_DATA, AUTO_START, 1);
67 
68 	/* Clear firmware interrupt enable flag */
69 	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
70 		ixFIRMWARE_FLAGS, 0);
71 
72 	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
73 		RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
74 
75 	/**
76 	 * Call Test SMU message with 0x20000 offset to trigger SMU start
77 	 */
78 	smu7_send_msg_to_smc_offset(smumgr);
79 
80 	/* Wait for done bit to be set */
81 	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
82 		SMU_STATUS, SMU_DONE, 0);
83 
84 	/* Check pass/failed indicator */
85 	if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
86 				CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
87 		printk(KERN_ERR "[ powerplay ] SMU Firmware start failed\n");
88 		return -EINVAL;
89 	}
90 
91 	/* Wait for firmware to initialize */
92 	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
93 		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
94 
95 	return 0;
96 }
97 
98 
tonga_start_in_non_protection_mode(struct pp_smumgr * smumgr)99 static int tonga_start_in_non_protection_mode(struct pp_smumgr *smumgr)
100 {
101 	int result = 0;
102 
103 	/* wait for smc boot up */
104 	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
105 		RCU_UC_EVENTS, boot_seq_done, 0);
106 
107 	/*Clear firmware interrupt enable flag*/
108 	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
109 		ixFIRMWARE_FLAGS, 0);
110 
111 
112 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
113 		SMC_SYSCON_RESET_CNTL, rst_reg, 1);
114 
115 	result = smu7_upload_smu_firmware_image(smumgr);
116 
117 	if (result != 0)
118 		return result;
119 
120 	/* Set smc instruct start point at 0x0 */
121 	smu7_program_jump_on_start(smumgr);
122 
123 
124 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
125 		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
126 
127 	/*De-assert reset*/
128 	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
129 		SMC_SYSCON_RESET_CNTL, rst_reg, 0);
130 
131 	/* Wait for firmware to initialize */
132 	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
133 		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
134 
135 	return result;
136 }
137 
tonga_start_smu(struct pp_smumgr * smumgr)138 static int tonga_start_smu(struct pp_smumgr *smumgr)
139 {
140 	int result;
141 
142 	/* Only start SMC if SMC RAM is not running */
143 	if (!smu7_is_smc_ram_running(smumgr)) {
144 		/*Check if SMU is running in protected mode*/
145 		if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
146 					SMU_FIRMWARE, SMU_MODE)) {
147 			result = tonga_start_in_non_protection_mode(smumgr);
148 			if (result)
149 				return result;
150 		} else {
151 			result = tonga_start_in_protection_mode(smumgr);
152 			if (result)
153 				return result;
154 		}
155 	}
156 
157 	result = smu7_request_smu_load_fw(smumgr);
158 
159 	return result;
160 }
161 
162 /**
163  * Write a 32bit value to the SMC SRAM space.
164  * ALL PARAMETERS ARE IN HOST BYTE ORDER.
165  * @param    smumgr  the address of the powerplay hardware manager.
166  * @param    smcAddress the address in the SMC RAM to access.
167  * @param    value to write to the SMC SRAM.
168  */
tonga_smu_init(struct pp_smumgr * smumgr)169 static int tonga_smu_init(struct pp_smumgr *smumgr)
170 {
171 	struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(smumgr->backend);
172 
173 	int i;
174 
175 	if (smu7_init(smumgr))
176 		return -EINVAL;
177 
178 	for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++)
179 		smu_data->activity_target[i] = 30;
180 
181 	return 0;
182 }
183 
184 static const struct pp_smumgr_func tonga_smu_funcs = {
185 	.smu_init = &tonga_smu_init,
186 	.smu_fini = &smu7_smu_fini,
187 	.start_smu = &tonga_start_smu,
188 	.check_fw_load_finish = &smu7_check_fw_load_finish,
189 	.request_smu_load_fw = &smu7_request_smu_load_fw,
190 	.request_smu_load_specific_fw = NULL,
191 	.send_msg_to_smc = &smu7_send_msg_to_smc,
192 	.send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
193 	.download_pptable_settings = NULL,
194 	.upload_pptable_settings = NULL,
195 	.update_smc_table = tonga_update_smc_table,
196 	.get_offsetof = tonga_get_offsetof,
197 	.process_firmware_header = tonga_process_firmware_header,
198 	.init_smc_table = tonga_init_smc_table,
199 	.update_sclk_threshold = tonga_update_sclk_threshold,
200 	.thermal_setup_fan_table = tonga_thermal_setup_fan_table,
201 	.populate_all_graphic_levels = tonga_populate_all_graphic_levels,
202 	.populate_all_memory_levels = tonga_populate_all_memory_levels,
203 	.get_mac_definition = tonga_get_mac_definition,
204 	.initialize_mc_reg_table = tonga_initialize_mc_reg_table,
205 	.is_dpm_running = tonga_is_dpm_running,
206 };
207 
tonga_smum_init(struct pp_smumgr * smumgr)208 int tonga_smum_init(struct pp_smumgr *smumgr)
209 {
210 	struct tonga_smumgr *tonga_smu = NULL;
211 
212 	tonga_smu = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
213 
214 	if (tonga_smu == NULL)
215 		return -ENOMEM;
216 
217 	smumgr->backend = tonga_smu;
218 	smumgr->smumgr_funcs = &tonga_smu_funcs;
219 
220 	return 0;
221 }
222