aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2016-09-19 03:44:50 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-09-22 10:24:20 -0400
commit9487dd1548d600161485ee5528cec36ccff96edd (patch)
treefa82f7a168eeb680c2fabf3ff1558c5487e55156
parenta8ca34136453b5a570b514e466f8b0b9efd71df2 (diff)
drm/amdgpu: use powerplay module for dgpu in Vi.
delete non-pp code and files. It was just a temporary solution and not support dynamic power management. Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/fiji_dpm.c186
-rw-r--r--drivers/gpu/drm/amd/amdgpu/fiji_smc.c863
-rw-r--r--drivers/gpu/drm/amd/amdgpu/fiji_smum.h42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/iceland_dpm.c200
-rw-r--r--drivers/gpu/drm/amd/amdgpu/iceland_smc.c677
-rw-r--r--drivers/gpu/drm/amd/amdgpu/iceland_smum.h41
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_dpm.c186
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_smc.c862
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_smum.h42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c3
12 files changed, 6 insertions, 3114 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index dc6df075bafc..d15e9b080ce1 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -52,10 +52,7 @@ amdgpu-y += \
52amdgpu-y += \ 52amdgpu-y += \
53 amdgpu_dpm.o \ 53 amdgpu_dpm.o \
54 amdgpu_powerplay.o \ 54 amdgpu_powerplay.o \
55 cz_smc.o cz_dpm.o \ 55 cz_smc.o cz_dpm.o
56 tonga_smc.o tonga_dpm.o \
57 fiji_smc.o fiji_dpm.o \
58 iceland_smc.o iceland_dpm.o
59 56
60# add DCE block 57# add DCE block
61amdgpu-y += \ 58amdgpu-y += \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
index 1e7f160f23d8..68ad24101a36 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
@@ -80,15 +80,6 @@ static int amdgpu_powerplay_init(struct amdgpu_device *adev)
80 amd_pp->ip_funcs = &kv_dpm_ip_funcs; 80 amd_pp->ip_funcs = &kv_dpm_ip_funcs;
81 break; 81 break;
82#endif 82#endif
83 case CHIP_TOPAZ:
84 amd_pp->ip_funcs = &iceland_dpm_ip_funcs;
85 break;
86 case CHIP_TONGA:
87 amd_pp->ip_funcs = &tonga_dpm_ip_funcs;
88 break;
89 case CHIP_FIJI:
90 amd_pp->ip_funcs = &fiji_dpm_ip_funcs;
91 break;
92 case CHIP_CARRIZO: 83 case CHIP_CARRIZO:
93 case CHIP_STONEY: 84 case CHIP_STONEY:
94 amd_pp->ip_funcs = &cz_dpm_ip_funcs; 85 amd_pp->ip_funcs = &cz_dpm_ip_funcs;
@@ -110,11 +101,11 @@ static int amdgpu_pp_early_init(void *handle)
110 switch (adev->asic_type) { 101 switch (adev->asic_type) {
111 case CHIP_POLARIS11: 102 case CHIP_POLARIS11:
112 case CHIP_POLARIS10: 103 case CHIP_POLARIS10:
113 adev->pp_enabled = true;
114 break;
115 case CHIP_TONGA: 104 case CHIP_TONGA:
116 case CHIP_FIJI: 105 case CHIP_FIJI:
117 case CHIP_TOPAZ: 106 case CHIP_TOPAZ:
107 adev->pp_enabled = true;
108 break;
118 case CHIP_CARRIZO: 109 case CHIP_CARRIZO:
119 case CHIP_STONEY: 110 case CHIP_STONEY:
120 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true; 111 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
deleted file mode 100644
index ed03b75175d4..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "fiji_smum.h"
28
29MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
30
31static void fiji_dpm_set_funcs(struct amdgpu_device *adev);
32
33static int fiji_dpm_early_init(void *handle)
34{
35 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
36
37 fiji_dpm_set_funcs(adev);
38
39 return 0;
40}
41
42static int fiji_dpm_init_microcode(struct amdgpu_device *adev)
43{
44 char fw_name[30] = "amdgpu/fiji_smc.bin";
45 int err;
46
47 err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
48 if (err)
49 goto out;
50 err = amdgpu_ucode_validate(adev->pm.fw);
51
52out:
53 if (err) {
54 DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
55 release_firmware(adev->pm.fw);
56 adev->pm.fw = NULL;
57 }
58 return err;
59}
60
61static int fiji_dpm_sw_init(void *handle)
62{
63 int ret;
64 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
65
66 ret = fiji_dpm_init_microcode(adev);
67 if (ret)
68 return ret;
69
70 return 0;
71}
72
73static int fiji_dpm_sw_fini(void *handle)
74{
75 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
76
77 release_firmware(adev->pm.fw);
78 adev->pm.fw = NULL;
79
80 return 0;
81}
82
83static int fiji_dpm_hw_init(void *handle)
84{
85 int ret;
86 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
87
88 mutex_lock(&adev->pm.mutex);
89
90 ret = fiji_smu_init(adev);
91 if (ret) {
92 DRM_ERROR("SMU initialization failed\n");
93 goto fail;
94 }
95
96 ret = fiji_smu_start(adev);
97 if (ret) {
98 DRM_ERROR("SMU start failed\n");
99 goto fail;
100 }
101
102 mutex_unlock(&adev->pm.mutex);
103 return 0;
104
105fail:
106 adev->firmware.smu_load = false;
107 mutex_unlock(&adev->pm.mutex);
108 return -EINVAL;
109}
110
111static int fiji_dpm_hw_fini(void *handle)
112{
113 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
114 mutex_lock(&adev->pm.mutex);
115 fiji_smu_fini(adev);
116 mutex_unlock(&adev->pm.mutex);
117 return 0;
118}
119
120static int fiji_dpm_suspend(void *handle)
121{
122 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
123
124 fiji_dpm_hw_fini(adev);
125
126 return 0;
127}
128
129static int fiji_dpm_resume(void *handle)
130{
131 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
132
133 fiji_dpm_hw_init(adev);
134
135 return 0;
136}
137
138static int fiji_dpm_set_clockgating_state(void *handle,
139 enum amd_clockgating_state state)
140{
141 return 0;
142}
143
144static int fiji_dpm_set_powergating_state(void *handle,
145 enum amd_powergating_state state)
146{
147 return 0;
148}
149
150const struct amd_ip_funcs fiji_dpm_ip_funcs = {
151 .name = "fiji_dpm",
152 .early_init = fiji_dpm_early_init,
153 .late_init = NULL,
154 .sw_init = fiji_dpm_sw_init,
155 .sw_fini = fiji_dpm_sw_fini,
156 .hw_init = fiji_dpm_hw_init,
157 .hw_fini = fiji_dpm_hw_fini,
158 .suspend = fiji_dpm_suspend,
159 .resume = fiji_dpm_resume,
160 .is_idle = NULL,
161 .wait_for_idle = NULL,
162 .soft_reset = NULL,
163 .set_clockgating_state = fiji_dpm_set_clockgating_state,
164 .set_powergating_state = fiji_dpm_set_powergating_state,
165};
166
167static const struct amdgpu_dpm_funcs fiji_dpm_funcs = {
168 .get_temperature = NULL,
169 .pre_set_power_state = NULL,
170 .set_power_state = NULL,
171 .post_set_power_state = NULL,
172 .display_configuration_changed = NULL,
173 .get_sclk = NULL,
174 .get_mclk = NULL,
175 .print_power_state = NULL,
176 .debugfs_print_current_performance_level = NULL,
177 .force_performance_level = NULL,
178 .vblank_too_short = NULL,
179 .powergate_uvd = NULL,
180};
181
182static void fiji_dpm_set_funcs(struct amdgpu_device *adev)
183{
184 if (NULL == adev->pm.funcs)
185 adev->pm.funcs = &fiji_dpm_funcs;
186}
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
deleted file mode 100644
index 8cfb0a3cf725..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
+++ /dev/null
@@ -1,863 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "fiji_ppsmc.h"
28#include "fiji_smum.h"
29#include "smu_ucode_xfer_vi.h"
30#include "amdgpu_ucode.h"
31
32#include "smu/smu_7_1_3_d.h"
33#include "smu/smu_7_1_3_sh_mask.h"
34
35#define FIJI_SMC_SIZE 0x20000
36
37static int fiji_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit)
38{
39 uint32_t val;
40
41 if (smc_address & 3)
42 return -EINVAL;
43
44 if ((smc_address + 3) > limit)
45 return -EINVAL;
46
47 WREG32(mmSMC_IND_INDEX_0, smc_address);
48
49 val = RREG32(mmSMC_IND_ACCESS_CNTL);
50 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
51 WREG32(mmSMC_IND_ACCESS_CNTL, val);
52
53 return 0;
54}
55
56static int fiji_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit)
57{
58 uint32_t addr;
59 uint32_t data, orig_data;
60 int result = 0;
61 uint32_t extra_shift;
62 unsigned long flags;
63
64 if (smc_start_address & 3)
65 return -EINVAL;
66
67 if ((smc_start_address + byte_count) > limit)
68 return -EINVAL;
69
70 addr = smc_start_address;
71
72 spin_lock_irqsave(&adev->smc_idx_lock, flags);
73 while (byte_count >= 4) {
74 /* Bytes are written into the SMC addres space with the MSB first */
75 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
76
77 result = fiji_set_smc_sram_address(adev, addr, limit);
78
79 if (result)
80 goto out;
81
82 WREG32(mmSMC_IND_DATA_0, data);
83
84 src += 4;
85 byte_count -= 4;
86 addr += 4;
87 }
88
89 if (0 != byte_count) {
90 /* Now write odd bytes left, do a read modify write cycle */
91 data = 0;
92
93 result = fiji_set_smc_sram_address(adev, addr, limit);
94 if (result)
95 goto out;
96
97 orig_data = RREG32(mmSMC_IND_DATA_0);
98 extra_shift = 8 * (4 - byte_count);
99
100 while (byte_count > 0) {
101 data = (data << 8) + *src++;
102 byte_count--;
103 }
104
105 data <<= extra_shift;
106 data |= (orig_data & ~((~0UL) << extra_shift));
107
108 result = fiji_set_smc_sram_address(adev, addr, limit);
109 if (result)
110 goto out;
111
112 WREG32(mmSMC_IND_DATA_0, data);
113 }
114
115out:
116 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
117 return result;
118}
119
120static int fiji_program_jump_on_start(struct amdgpu_device *adev)
121{
122 static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40};
123 fiji_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
124
125 return 0;
126}
127
128static bool fiji_is_smc_ram_running(struct amdgpu_device *adev)
129{
130 uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
131 val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
132
133 return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C)));
134}
135
136static int wait_smu_response(struct amdgpu_device *adev)
137{
138 int i;
139 uint32_t val;
140
141 for (i = 0; i < adev->usec_timeout; i++) {
142 val = RREG32(mmSMC_RESP_0);
143 if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP))
144 break;
145 udelay(1);
146 }
147
148 if (i == adev->usec_timeout)
149 return -EINVAL;
150
151 return 0;
152}
153
154static int fiji_send_msg_to_smc_offset(struct amdgpu_device *adev)
155{
156 if (wait_smu_response(adev)) {
157 DRM_ERROR("Failed to send previous message\n");
158 return -EINVAL;
159 }
160
161 WREG32(mmSMC_MSG_ARG_0, 0x20000);
162 WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test);
163
164 if (wait_smu_response(adev)) {
165 DRM_ERROR("Failed to send message\n");
166 return -EINVAL;
167 }
168
169 return 0;
170}
171
172static int fiji_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
173{
174 if (!fiji_is_smc_ram_running(adev))
175 {
176 return -EINVAL;
177 }
178
179 if (wait_smu_response(adev)) {
180 DRM_ERROR("Failed to send previous message\n");
181 return -EINVAL;
182 }
183
184 WREG32(mmSMC_MESSAGE_0, msg);
185
186 if (wait_smu_response(adev)) {
187 DRM_ERROR("Failed to send message\n");
188 return -EINVAL;
189 }
190
191 return 0;
192}
193
194static int fiji_send_msg_to_smc_without_waiting(struct amdgpu_device *adev,
195 PPSMC_Msg msg)
196{
197 if (wait_smu_response(adev)) {
198 DRM_ERROR("Failed to send previous message\n");
199 return -EINVAL;
200 }
201
202 WREG32(mmSMC_MESSAGE_0, msg);
203
204 return 0;
205}
206
207static int fiji_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
208 PPSMC_Msg msg,
209 uint32_t parameter)
210{
211 if (!fiji_is_smc_ram_running(adev))
212 return -EINVAL;
213
214 if (wait_smu_response(adev)) {
215 DRM_ERROR("Failed to send previous message\n");
216 return -EINVAL;
217 }
218
219 WREG32(mmSMC_MSG_ARG_0, parameter);
220
221 return fiji_send_msg_to_smc(adev, msg);
222}
223
224static int fiji_send_msg_to_smc_with_parameter_without_waiting(
225 struct amdgpu_device *adev,
226 PPSMC_Msg msg, uint32_t parameter)
227{
228 if (wait_smu_response(adev)) {
229 DRM_ERROR("Failed to send previous message\n");
230 return -EINVAL;
231 }
232
233 WREG32(mmSMC_MSG_ARG_0, parameter);
234
235 return fiji_send_msg_to_smc_without_waiting(adev, msg);
236}
237
238#if 0 /* not used yet */
239static int fiji_wait_for_smc_inactive(struct amdgpu_device *adev)
240{
241 int i;
242 uint32_t val;
243
244 if (!fiji_is_smc_ram_running(adev))
245 return -EINVAL;
246
247 for (i = 0; i < adev->usec_timeout; i++) {
248 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
249 if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0)
250 break;
251 udelay(1);
252 }
253
254 if (i == adev->usec_timeout)
255 return -EINVAL;
256
257 return 0;
258}
259#endif
260
261static int fiji_smu_upload_firmware_image(struct amdgpu_device *adev)
262{
263 const struct smc_firmware_header_v1_0 *hdr;
264 uint32_t ucode_size;
265 uint32_t ucode_start_address;
266 const uint8_t *src;
267 uint32_t val;
268 uint32_t byte_count;
269 uint32_t *data;
270 unsigned long flags;
271
272 if (!adev->pm.fw)
273 return -EINVAL;
274
275 /* Skip SMC ucode loading on SR-IOV capable boards.
276 * vbios does this for us in asic_init in that case.
277 */
278 if (amdgpu_sriov_bios(adev))
279 return 0;
280
281 hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
282 amdgpu_ucode_print_smc_hdr(&hdr->header);
283
284 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
285 ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
286 ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
287 src = (const uint8_t *)
288 (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
289
290 if (ucode_size & 3) {
291 DRM_ERROR("SMC ucode is not 4 bytes aligned\n");
292 return -EINVAL;
293 }
294
295 if (ucode_size > FIJI_SMC_SIZE) {
296 DRM_ERROR("SMC address is beyond the SMC RAM area\n");
297 return -EINVAL;
298 }
299
300 spin_lock_irqsave(&adev->smc_idx_lock, flags);
301 WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
302
303 val = RREG32(mmSMC_IND_ACCESS_CNTL);
304 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
305 WREG32(mmSMC_IND_ACCESS_CNTL, val);
306
307 byte_count = ucode_size;
308 data = (uint32_t *)src;
309 for (; byte_count >= 4; data++, byte_count -= 4)
310 WREG32(mmSMC_IND_DATA_0, data[0]);
311
312 val = RREG32(mmSMC_IND_ACCESS_CNTL);
313 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
314 WREG32(mmSMC_IND_ACCESS_CNTL, val);
315 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
316
317 return 0;
318}
319
320#if 0 /* not used yet */
321static int fiji_read_smc_sram_dword(struct amdgpu_device *adev,
322 uint32_t smc_address,
323 uint32_t *value,
324 uint32_t limit)
325{
326 int result;
327 unsigned long flags;
328
329 spin_lock_irqsave(&adev->smc_idx_lock, flags);
330 result = fiji_set_smc_sram_address(adev, smc_address, limit);
331 if (result == 0)
332 *value = RREG32(mmSMC_IND_DATA_0);
333 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
334 return result;
335}
336
337static int fiji_write_smc_sram_dword(struct amdgpu_device *adev,
338 uint32_t smc_address,
339 uint32_t value,
340 uint32_t limit)
341{
342 int result;
343 unsigned long flags;
344
345 spin_lock_irqsave(&adev->smc_idx_lock, flags);
346 result = fiji_set_smc_sram_address(adev, smc_address, limit);
347 if (result == 0)
348 WREG32(mmSMC_IND_DATA_0, value);
349 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
350 return result;
351}
352
353static int fiji_smu_stop_smc(struct amdgpu_device *adev)
354{
355 uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
356 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
357 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
358
359 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
360 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1);
361 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
362
363 return 0;
364}
365#endif
366
367static enum AMDGPU_UCODE_ID fiji_convert_fw_type(uint32_t fw_type)
368{
369 switch (fw_type) {
370 case UCODE_ID_SDMA0:
371 return AMDGPU_UCODE_ID_SDMA0;
372 case UCODE_ID_SDMA1:
373 return AMDGPU_UCODE_ID_SDMA1;
374 case UCODE_ID_CP_CE:
375 return AMDGPU_UCODE_ID_CP_CE;
376 case UCODE_ID_CP_PFP:
377 return AMDGPU_UCODE_ID_CP_PFP;
378 case UCODE_ID_CP_ME:
379 return AMDGPU_UCODE_ID_CP_ME;
380 case UCODE_ID_CP_MEC:
381 case UCODE_ID_CP_MEC_JT1:
382 case UCODE_ID_CP_MEC_JT2:
383 return AMDGPU_UCODE_ID_CP_MEC1;
384 case UCODE_ID_RLC_G:
385 return AMDGPU_UCODE_ID_RLC_G;
386 default:
387 DRM_ERROR("ucode type is out of range!\n");
388 return AMDGPU_UCODE_ID_MAXIMUM;
389 }
390}
391
392static int fiji_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
393 uint32_t fw_type,
394 struct SMU_Entry *entry)
395{
396 enum AMDGPU_UCODE_ID id = fiji_convert_fw_type(fw_type);
397 struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
398 const struct gfx_firmware_header_v1_0 *header = NULL;
399 uint64_t gpu_addr;
400 uint32_t data_size;
401
402 if (ucode->fw == NULL)
403 return -EINVAL;
404 gpu_addr = ucode->mc_addr;
405 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
406 data_size = le32_to_cpu(header->header.ucode_size_bytes);
407
408 if ((fw_type == UCODE_ID_CP_MEC_JT1) ||
409 (fw_type == UCODE_ID_CP_MEC_JT2)) {
410 gpu_addr += le32_to_cpu(header->jt_offset) << 2;
411 data_size = le32_to_cpu(header->jt_size) << 2;
412 }
413
414 entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
415 entry->id = (uint16_t)fw_type;
416 entry->image_addr_high = upper_32_bits(gpu_addr);
417 entry->image_addr_low = lower_32_bits(gpu_addr);
418 entry->meta_data_addr_high = 0;
419 entry->meta_data_addr_low = 0;
420 entry->data_size_byte = data_size;
421 entry->num_register_entries = 0;
422
423 if (fw_type == UCODE_ID_RLC_G)
424 entry->flags = 1;
425 else
426 entry->flags = 0;
427
428 return 0;
429}
430
431static int fiji_smu_request_load_fw(struct amdgpu_device *adev)
432{
433 struct fiji_smu_private_data *private = (struct fiji_smu_private_data *)adev->smu.priv;
434 struct SMU_DRAMData_TOC *toc;
435 uint32_t fw_to_load;
436
437 WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0);
438
439 fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high);
440 fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low);
441
442 toc = (struct SMU_DRAMData_TOC *)private->header;
443 toc->num_entries = 0;
444 toc->structure_version = 1;
445
446 if (!adev->firmware.smu_load)
447 return 0;
448
449 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G,
450 &toc->entry[toc->num_entries++])) {
451 DRM_ERROR("Failed to get firmware entry for RLC\n");
452 return -EINVAL;
453 }
454
455 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE,
456 &toc->entry[toc->num_entries++])) {
457 DRM_ERROR("Failed to get firmware entry for CE\n");
458 return -EINVAL;
459 }
460
461 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP,
462 &toc->entry[toc->num_entries++])) {
463 DRM_ERROR("Failed to get firmware entry for PFP\n");
464 return -EINVAL;
465 }
466
467 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME,
468 &toc->entry[toc->num_entries++])) {
469 DRM_ERROR("Failed to get firmware entry for ME\n");
470 return -EINVAL;
471 }
472
473 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC,
474 &toc->entry[toc->num_entries++])) {
475 DRM_ERROR("Failed to get firmware entry for MEC\n");
476 return -EINVAL;
477 }
478
479 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1,
480 &toc->entry[toc->num_entries++])) {
481 DRM_ERROR("Failed to get firmware entry for MEC_JT1\n");
482 return -EINVAL;
483 }
484
485 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2,
486 &toc->entry[toc->num_entries++])) {
487 DRM_ERROR("Failed to get firmware entry for MEC_JT2\n");
488 return -EINVAL;
489 }
490
491 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
492 &toc->entry[toc->num_entries++])) {
493 DRM_ERROR("Failed to get firmware entry for SDMA0\n");
494 return -EINVAL;
495 }
496
497 if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1,
498 &toc->entry[toc->num_entries++])) {
499 DRM_ERROR("Failed to get firmware entry for SDMA1\n");
500 return -EINVAL;
501 }
502
503 fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high);
504 fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low);
505
506 fw_to_load = UCODE_ID_RLC_G_MASK |
507 UCODE_ID_SDMA0_MASK |
508 UCODE_ID_SDMA1_MASK |
509 UCODE_ID_CP_CE_MASK |
510 UCODE_ID_CP_ME_MASK |
511 UCODE_ID_CP_PFP_MASK |
512 UCODE_ID_CP_MEC_MASK;
513
514 if (fiji_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
515 DRM_ERROR("Fail to request SMU load ucode\n");
516 return -EINVAL;
517 }
518
519 return 0;
520}
521
522static uint32_t fiji_smu_get_mask_for_fw_type(uint32_t fw_type)
523{
524 switch (fw_type) {
525 case AMDGPU_UCODE_ID_SDMA0:
526 return UCODE_ID_SDMA0_MASK;
527 case AMDGPU_UCODE_ID_SDMA1:
528 return UCODE_ID_SDMA1_MASK;
529 case AMDGPU_UCODE_ID_CP_CE:
530 return UCODE_ID_CP_CE_MASK;
531 case AMDGPU_UCODE_ID_CP_PFP:
532 return UCODE_ID_CP_PFP_MASK;
533 case AMDGPU_UCODE_ID_CP_ME:
534 return UCODE_ID_CP_ME_MASK;
535 case AMDGPU_UCODE_ID_CP_MEC1:
536 return UCODE_ID_CP_MEC_MASK;
537 case AMDGPU_UCODE_ID_CP_MEC2:
538 return UCODE_ID_CP_MEC_MASK;
539 case AMDGPU_UCODE_ID_RLC_G:
540 return UCODE_ID_RLC_G_MASK;
541 default:
542 DRM_ERROR("ucode type is out of range!\n");
543 return 0;
544 }
545}
546
547static int fiji_smu_check_fw_load_finish(struct amdgpu_device *adev,
548 uint32_t fw_type)
549{
550 uint32_t fw_mask = fiji_smu_get_mask_for_fw_type(fw_type);
551 int i;
552
553 for (i = 0; i < adev->usec_timeout; i++) {
554 if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask))
555 break;
556 udelay(1);
557 }
558
559 if (i == adev->usec_timeout) {
560 DRM_ERROR("check firmware loading failed\n");
561 return -EINVAL;
562 }
563
564 return 0;
565}
566
567static int fiji_smu_start_in_protection_mode(struct amdgpu_device *adev)
568{
569 int result;
570 uint32_t val;
571 int i;
572
573 /* Assert reset */
574 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
575 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
576 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
577
578 result = fiji_smu_upload_firmware_image(adev);
579 if (result)
580 return result;
581
582 /* Clear status */
583 WREG32_SMC(ixSMU_STATUS, 0);
584
585 /* Enable clock */
586 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
587 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
588 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
589
590 /* De-assert reset */
591 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
592 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
593 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
594
595 /* Set SMU Auto Start */
596 val = RREG32_SMC(ixSMU_INPUT_DATA);
597 val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1);
598 WREG32_SMC(ixSMU_INPUT_DATA, val);
599
600 /* Clear firmware interrupt enable flag */
601 WREG32_SMC(ixFIRMWARE_FLAGS, 0);
602
603 for (i = 0; i < adev->usec_timeout; i++) {
604 val = RREG32_SMC(ixRCU_UC_EVENTS);
605 if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED))
606 break;
607 udelay(1);
608 }
609
610 if (i == adev->usec_timeout) {
611 DRM_ERROR("Interrupt is not enabled by firmware\n");
612 return -EINVAL;
613 }
614
615 /* Call Test SMU message with 0x20000 offset
616 * to trigger SMU start
617 */
618 fiji_send_msg_to_smc_offset(adev);
619 DRM_INFO("[FM]try triger smu start\n");
620 /* Wait for done bit to be set */
621 for (i = 0; i < adev->usec_timeout; i++) {
622 val = RREG32_SMC(ixSMU_STATUS);
623 if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE))
624 break;
625 udelay(1);
626 }
627
628 if (i == adev->usec_timeout) {
629 DRM_ERROR("Timeout for SMU start\n");
630 return -EINVAL;
631 }
632
633 /* Check pass/failed indicator */
634 val = RREG32_SMC(ixSMU_STATUS);
635 if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) {
636 DRM_ERROR("SMU Firmware start failed\n");
637 return -EINVAL;
638 }
639 DRM_INFO("[FM]smu started\n");
640 /* Wait for firmware to initialize */
641 for (i = 0; i < adev->usec_timeout; i++) {
642 val = RREG32_SMC(ixFIRMWARE_FLAGS);
643 if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
644 break;
645 udelay(1);
646 }
647
648 if (i == adev->usec_timeout) {
649 DRM_ERROR("SMU firmware initialization failed\n");
650 return -EINVAL;
651 }
652 DRM_INFO("[FM]smu initialized\n");
653
654 return 0;
655}
656
657static int fiji_smu_start_in_non_protection_mode(struct amdgpu_device *adev)
658{
659 int i, result;
660 uint32_t val;
661
662 /* wait for smc boot up */
663 for (i = 0; i < adev->usec_timeout; i++) {
664 val = RREG32_SMC(ixRCU_UC_EVENTS);
665 val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done);
666 if (val)
667 break;
668 udelay(1);
669 }
670
671 if (i == adev->usec_timeout) {
672 DRM_ERROR("SMC boot sequence is not completed\n");
673 return -EINVAL;
674 }
675
676 /* Clear firmware interrupt enable flag */
677 WREG32_SMC(ixFIRMWARE_FLAGS, 0);
678
679 /* Assert reset */
680 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
681 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
682 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
683
684 result = fiji_smu_upload_firmware_image(adev);
685 if (result)
686 return result;
687
688 /* Set smc instruct start point at 0x0 */
689 fiji_program_jump_on_start(adev);
690
691 /* Enable clock */
692 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
693 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
694 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
695
696 /* De-assert reset */
697 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
698 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
699 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
700
701 /* Wait for firmware to initialize */
702 for (i = 0; i < adev->usec_timeout; i++) {
703 val = RREG32_SMC(ixFIRMWARE_FLAGS);
704 if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
705 break;
706 udelay(1);
707 }
708
709 if (i == adev->usec_timeout) {
710 DRM_ERROR("Timeout for SMC firmware initialization\n");
711 return -EINVAL;
712 }
713
714 return 0;
715}
716
717int fiji_smu_start(struct amdgpu_device *adev)
718{
719 int result;
720 uint32_t val;
721
722 if (!fiji_is_smc_ram_running(adev)) {
723 val = RREG32_SMC(ixSMU_FIRMWARE);
724 if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) {
725 DRM_INFO("[FM]start smu in nonprotection mode\n");
726 result = fiji_smu_start_in_non_protection_mode(adev);
727 if (result)
728 return result;
729 } else {
730 DRM_INFO("[FM]start smu in protection mode\n");
731 result = fiji_smu_start_in_protection_mode(adev);
732 if (result)
733 return result;
734 }
735 }
736
737 return fiji_smu_request_load_fw(adev);
738}
739
740static const struct amdgpu_smumgr_funcs fiji_smumgr_funcs = {
741 .check_fw_load_finish = fiji_smu_check_fw_load_finish,
742 .request_smu_load_fw = NULL,
743 .request_smu_specific_fw = NULL,
744};
745
746int fiji_smu_init(struct amdgpu_device *adev)
747{
748 struct fiji_smu_private_data *private;
749 uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
750 uint32_t smu_internal_buffer_size = 200*4096;
751 struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
752 struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
753 uint64_t mc_addr;
754 void *toc_buf_ptr;
755 void *smu_buf_ptr;
756 int ret;
757
758 private = kzalloc(sizeof(struct fiji_smu_private_data), GFP_KERNEL);
759 if (NULL == private)
760 return -ENOMEM;
761
762 /* allocate firmware buffers */
763 if (adev->firmware.smu_load)
764 amdgpu_ucode_init_bo(adev);
765
766 adev->smu.priv = private;
767 adev->smu.fw_flags = 0;
768
769 /* Allocate FW image data structure and header buffer */
770 ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,
771 true, AMDGPU_GEM_DOMAIN_VRAM,
772 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
773 NULL, NULL, toc_buf);
774 if (ret) {
775 DRM_ERROR("Failed to allocate memory for TOC buffer\n");
776 return -ENOMEM;
777 }
778
779 /* Allocate buffer for SMU internal buffer */
780 ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,
781 true, AMDGPU_GEM_DOMAIN_VRAM,
782 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
783 NULL, NULL, smu_buf);
784 if (ret) {
785 DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");
786 return -ENOMEM;
787 }
788
789 /* Retrieve GPU address for header buffer and internal buffer */
790 ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
791 if (ret) {
792 amdgpu_bo_unref(&adev->smu.toc_buf);
793 DRM_ERROR("Failed to reserve the TOC buffer\n");
794 return -EINVAL;
795 }
796
797 ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
798 if (ret) {
799 amdgpu_bo_unreserve(adev->smu.toc_buf);
800 amdgpu_bo_unref(&adev->smu.toc_buf);
801 DRM_ERROR("Failed to pin the TOC buffer\n");
802 return -EINVAL;
803 }
804
805 ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
806 if (ret) {
807 amdgpu_bo_unreserve(adev->smu.toc_buf);
808 amdgpu_bo_unref(&adev->smu.toc_buf);
809 DRM_ERROR("Failed to map the TOC buffer\n");
810 return -EINVAL;
811 }
812
813 amdgpu_bo_unreserve(adev->smu.toc_buf);
814 private->header_addr_low = lower_32_bits(mc_addr);
815 private->header_addr_high = upper_32_bits(mc_addr);
816 private->header = toc_buf_ptr;
817
818 ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
819 if (ret) {
820 amdgpu_bo_unref(&adev->smu.smu_buf);
821 amdgpu_bo_unref(&adev->smu.toc_buf);
822 DRM_ERROR("Failed to reserve the SMU internal buffer\n");
823 return -EINVAL;
824 }
825
826 ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
827 if (ret) {
828 amdgpu_bo_unreserve(adev->smu.smu_buf);
829 amdgpu_bo_unref(&adev->smu.smu_buf);
830 amdgpu_bo_unref(&adev->smu.toc_buf);
831 DRM_ERROR("Failed to pin the SMU internal buffer\n");
832 return -EINVAL;
833 }
834
835 ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
836 if (ret) {
837 amdgpu_bo_unreserve(adev->smu.smu_buf);
838 amdgpu_bo_unref(&adev->smu.smu_buf);
839 amdgpu_bo_unref(&adev->smu.toc_buf);
840 DRM_ERROR("Failed to map the SMU internal buffer\n");
841 return -EINVAL;
842 }
843
844 amdgpu_bo_unreserve(adev->smu.smu_buf);
845 private->smu_buffer_addr_low = lower_32_bits(mc_addr);
846 private->smu_buffer_addr_high = upper_32_bits(mc_addr);
847
848 adev->smu.smumgr_funcs = &fiji_smumgr_funcs;
849
850 return 0;
851}
852
853int fiji_smu_fini(struct amdgpu_device *adev)
854{
855 amdgpu_bo_unref(&adev->smu.toc_buf);
856 amdgpu_bo_unref(&adev->smu.smu_buf);
857 kfree(adev->smu.priv);
858 adev->smu.priv = NULL;
859 if (adev->firmware.fw_buf)
860 amdgpu_ucode_fini_bo(adev);
861
862 return 0;
863}
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smum.h b/drivers/gpu/drm/amd/amdgpu/fiji_smum.h
deleted file mode 100644
index 1cef03deeac3..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/fiji_smum.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright 2014 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
24#ifndef FIJI_SMUMGR_H
25#define FIJI_SMUMGR_H
26
27#include "fiji_ppsmc.h"
28
29int fiji_smu_init(struct amdgpu_device *adev);
30int fiji_smu_fini(struct amdgpu_device *adev);
31int fiji_smu_start(struct amdgpu_device *adev);
32
33struct fiji_smu_private_data
34{
35 uint8_t *header;
36 uint32_t smu_buffer_addr_high;
37 uint32_t smu_buffer_addr_low;
38 uint32_t header_addr_high;
39 uint32_t header_addr_low;
40};
41
42#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
deleted file mode 100644
index 2f078ad6095c..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
+++ /dev/null
@@ -1,200 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "iceland_smum.h"
28
29MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
30
31static void iceland_dpm_set_funcs(struct amdgpu_device *adev);
32
33static int iceland_dpm_early_init(void *handle)
34{
35 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
36
37 iceland_dpm_set_funcs(adev);
38
39 return 0;
40}
41
42static int iceland_dpm_init_microcode(struct amdgpu_device *adev)
43{
44 char fw_name[30] = "amdgpu/topaz_smc.bin";
45 int err;
46
47 err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
48 if (err)
49 goto out;
50 err = amdgpu_ucode_validate(adev->pm.fw);
51
52out:
53 if (err) {
54 DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
55 release_firmware(adev->pm.fw);
56 adev->pm.fw = NULL;
57 }
58 return err;
59}
60
61static int iceland_dpm_sw_init(void *handle)
62{
63 int ret;
64 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
65
66 ret = iceland_dpm_init_microcode(adev);
67 if (ret)
68 return ret;
69
70 return 0;
71}
72
73static int iceland_dpm_sw_fini(void *handle)
74{
75 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
76
77 release_firmware(adev->pm.fw);
78 adev->pm.fw = NULL;
79
80 return 0;
81}
82
83static int iceland_dpm_hw_init(void *handle)
84{
85 int ret;
86 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
87
88 mutex_lock(&adev->pm.mutex);
89
90 /* smu init only needs to be called at startup, not resume.
91 * It should be in sw_init, but requires the fw info gathered
92 * in sw_init from other IP modules.
93 */
94 ret = iceland_smu_init(adev);
95 if (ret) {
96 DRM_ERROR("SMU initialization failed\n");
97 goto fail;
98 }
99
100 ret = iceland_smu_start(adev);
101 if (ret) {
102 DRM_ERROR("SMU start failed\n");
103 goto fail;
104 }
105
106 mutex_unlock(&adev->pm.mutex);
107 return 0;
108
109fail:
110 adev->firmware.smu_load = false;
111 mutex_unlock(&adev->pm.mutex);
112 return -EINVAL;
113}
114
115static int iceland_dpm_hw_fini(void *handle)
116{
117 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
118
119 mutex_lock(&adev->pm.mutex);
120 /* smu fini only needs to be called at teardown, not suspend.
121 * It should be in sw_fini, but we put it here for symmetry
122 * with smu init.
123 */
124 iceland_smu_fini(adev);
125 mutex_unlock(&adev->pm.mutex);
126 return 0;
127}
128
129static int iceland_dpm_suspend(void *handle)
130{
131 return 0;
132}
133
134static int iceland_dpm_resume(void *handle)
135{
136 int ret;
137 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
138
139 mutex_lock(&adev->pm.mutex);
140
141 ret = iceland_smu_start(adev);
142 if (ret) {
143 DRM_ERROR("SMU start failed\n");
144 goto fail;
145 }
146
147fail:
148 mutex_unlock(&adev->pm.mutex);
149 return ret;
150}
151
152static int iceland_dpm_set_clockgating_state(void *handle,
153 enum amd_clockgating_state state)
154{
155 return 0;
156}
157
158static int iceland_dpm_set_powergating_state(void *handle,
159 enum amd_powergating_state state)
160{
161 return 0;
162}
163
164const struct amd_ip_funcs iceland_dpm_ip_funcs = {
165 .name = "iceland_dpm",
166 .early_init = iceland_dpm_early_init,
167 .late_init = NULL,
168 .sw_init = iceland_dpm_sw_init,
169 .sw_fini = iceland_dpm_sw_fini,
170 .hw_init = iceland_dpm_hw_init,
171 .hw_fini = iceland_dpm_hw_fini,
172 .suspend = iceland_dpm_suspend,
173 .resume = iceland_dpm_resume,
174 .is_idle = NULL,
175 .wait_for_idle = NULL,
176 .soft_reset = NULL,
177 .set_clockgating_state = iceland_dpm_set_clockgating_state,
178 .set_powergating_state = iceland_dpm_set_powergating_state,
179};
180
181static const struct amdgpu_dpm_funcs iceland_dpm_funcs = {
182 .get_temperature = NULL,
183 .pre_set_power_state = NULL,
184 .set_power_state = NULL,
185 .post_set_power_state = NULL,
186 .display_configuration_changed = NULL,
187 .get_sclk = NULL,
188 .get_mclk = NULL,
189 .print_power_state = NULL,
190 .debugfs_print_current_performance_level = NULL,
191 .force_performance_level = NULL,
192 .vblank_too_short = NULL,
193 .powergate_uvd = NULL,
194};
195
196static void iceland_dpm_set_funcs(struct amdgpu_device *adev)
197{
198 if (NULL == adev->pm.funcs)
199 adev->pm.funcs = &iceland_dpm_funcs;
200}
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
deleted file mode 100644
index c6e004a3f557..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
+++ /dev/null
@@ -1,677 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "ppsmc.h"
28#include "iceland_smum.h"
29#include "smu_ucode_xfer_vi.h"
30#include "amdgpu_ucode.h"
31
32#include "smu/smu_7_1_1_d.h"
33#include "smu/smu_7_1_1_sh_mask.h"
34
35#define ICELAND_SMC_SIZE 0x20000
36
37static int iceland_set_smc_sram_address(struct amdgpu_device *adev,
38 uint32_t smc_address, uint32_t limit)
39{
40 uint32_t val;
41
42 if (smc_address & 3)
43 return -EINVAL;
44
45 if ((smc_address + 3) > limit)
46 return -EINVAL;
47
48 WREG32(mmSMC_IND_INDEX_0, smc_address);
49
50 val = RREG32(mmSMC_IND_ACCESS_CNTL);
51 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
52 WREG32(mmSMC_IND_ACCESS_CNTL, val);
53
54 return 0;
55}
56
57static int iceland_copy_bytes_to_smc(struct amdgpu_device *adev,
58 uint32_t smc_start_address,
59 const uint8_t *src,
60 uint32_t byte_count, uint32_t limit)
61{
62 uint32_t addr;
63 uint32_t data, orig_data;
64 int result = 0;
65 uint32_t extra_shift;
66 unsigned long flags;
67
68 if (smc_start_address & 3)
69 return -EINVAL;
70
71 if ((smc_start_address + byte_count) > limit)
72 return -EINVAL;
73
74 addr = smc_start_address;
75
76 spin_lock_irqsave(&adev->smc_idx_lock, flags);
77 while (byte_count >= 4) {
78 /* Bytes are written into the SMC addres space with the MSB first */
79 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
80
81 result = iceland_set_smc_sram_address(adev, addr, limit);
82
83 if (result)
84 goto out;
85
86 WREG32(mmSMC_IND_DATA_0, data);
87
88 src += 4;
89 byte_count -= 4;
90 addr += 4;
91 }
92
93 if (0 != byte_count) {
94 /* Now write odd bytes left, do a read modify write cycle */
95 data = 0;
96
97 result = iceland_set_smc_sram_address(adev, addr, limit);
98 if (result)
99 goto out;
100
101 orig_data = RREG32(mmSMC_IND_DATA_0);
102 extra_shift = 8 * (4 - byte_count);
103
104 while (byte_count > 0) {
105 data = (data << 8) + *src++;
106 byte_count--;
107 }
108
109 data <<= extra_shift;
110 data |= (orig_data & ~((~0UL) << extra_shift));
111
112 result = iceland_set_smc_sram_address(adev, addr, limit);
113 if (result)
114 goto out;
115
116 WREG32(mmSMC_IND_DATA_0, data);
117 }
118
119out:
120 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
121 return result;
122}
123
124static void iceland_start_smc(struct amdgpu_device *adev)
125{
126 uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
127
128 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
129 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
130}
131
132static void iceland_reset_smc(struct amdgpu_device *adev)
133{
134 uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
135
136 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
137 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
138}
139
140static int iceland_program_jump_on_start(struct amdgpu_device *adev)
141{
142 static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40};
143 iceland_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
144
145 return 0;
146}
147
148static void iceland_stop_smc_clock(struct amdgpu_device *adev)
149{
150 uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
151
152 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1);
153 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
154}
155
156static void iceland_start_smc_clock(struct amdgpu_device *adev)
157{
158 uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
159
160 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
161 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
162}
163
164static bool iceland_is_smc_ram_running(struct amdgpu_device *adev)
165{
166 uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
167 val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
168
169 return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C)));
170}
171
172static int wait_smu_response(struct amdgpu_device *adev)
173{
174 int i;
175 uint32_t val;
176
177 for (i = 0; i < adev->usec_timeout; i++) {
178 val = RREG32(mmSMC_RESP_0);
179 if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP))
180 break;
181 udelay(1);
182 }
183
184 if (i == adev->usec_timeout)
185 return -EINVAL;
186
187 return 0;
188}
189
190static int iceland_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
191{
192 if (!iceland_is_smc_ram_running(adev))
193 return -EINVAL;
194
195 if (wait_smu_response(adev)) {
196 DRM_ERROR("Failed to send previous message\n");
197 return -EINVAL;
198 }
199
200 WREG32(mmSMC_MESSAGE_0, msg);
201
202 if (wait_smu_response(adev)) {
203 DRM_ERROR("Failed to send message\n");
204 return -EINVAL;
205 }
206
207 return 0;
208}
209
210static int iceland_send_msg_to_smc_without_waiting(struct amdgpu_device *adev,
211 PPSMC_Msg msg)
212{
213 if (!iceland_is_smc_ram_running(adev))
214 return -EINVAL;
215
216 if (wait_smu_response(adev)) {
217 DRM_ERROR("Failed to send previous message\n");
218 return -EINVAL;
219 }
220
221 WREG32(mmSMC_MESSAGE_0, msg);
222
223 return 0;
224}
225
226static int iceland_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
227 PPSMC_Msg msg,
228 uint32_t parameter)
229{
230 WREG32(mmSMC_MSG_ARG_0, parameter);
231
232 return iceland_send_msg_to_smc(adev, msg);
233}
234
235static int iceland_send_msg_to_smc_with_parameter_without_waiting(
236 struct amdgpu_device *adev,
237 PPSMC_Msg msg, uint32_t parameter)
238{
239 WREG32(mmSMC_MSG_ARG_0, parameter);
240
241 return iceland_send_msg_to_smc_without_waiting(adev, msg);
242}
243
244#if 0 /* not used yet */
245static int iceland_wait_for_smc_inactive(struct amdgpu_device *adev)
246{
247 int i;
248 uint32_t val;
249
250 if (!iceland_is_smc_ram_running(adev))
251 return -EINVAL;
252
253 for (i = 0; i < adev->usec_timeout; i++) {
254 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
255 if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0)
256 break;
257 udelay(1);
258 }
259
260 if (i == adev->usec_timeout)
261 return -EINVAL;
262
263 return 0;
264}
265#endif
266
267static int iceland_smu_upload_firmware_image(struct amdgpu_device *adev)
268{
269 const struct smc_firmware_header_v1_0 *hdr;
270 uint32_t ucode_size;
271 uint32_t ucode_start_address;
272 const uint8_t *src;
273 uint32_t val;
274 uint32_t byte_count;
275 uint32_t data;
276 unsigned long flags;
277 int i;
278
279 if (!adev->pm.fw)
280 return -EINVAL;
281
282 /* Skip SMC ucode loading on SR-IOV capable boards.
283 * vbios does this for us in asic_init in that case.
284 */
285 if (amdgpu_sriov_bios(adev))
286 return 0;
287
288 hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
289 amdgpu_ucode_print_smc_hdr(&hdr->header);
290
291 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
292 ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
293 ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
294 src = (const uint8_t *)
295 (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
296
297 if (ucode_size & 3) {
298 DRM_ERROR("SMC ucode is not 4 bytes aligned\n");
299 return -EINVAL;
300 }
301
302 if (ucode_size > ICELAND_SMC_SIZE) {
303 DRM_ERROR("SMC address is beyond the SMC RAM area\n");
304 return -EINVAL;
305 }
306
307 for (i = 0; i < adev->usec_timeout; i++) {
308 val = RREG32_SMC(ixRCU_UC_EVENTS);
309 if (REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done) == 0)
310 break;
311 udelay(1);
312 }
313 val = RREG32_SMC(ixSMC_SYSCON_MISC_CNTL);
314 WREG32_SMC(ixSMC_SYSCON_MISC_CNTL, val | 1);
315
316 iceland_stop_smc_clock(adev);
317 iceland_reset_smc(adev);
318
319 spin_lock_irqsave(&adev->smc_idx_lock, flags);
320 WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
321
322 val = RREG32(mmSMC_IND_ACCESS_CNTL);
323 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
324 WREG32(mmSMC_IND_ACCESS_CNTL, val);
325
326 byte_count = ucode_size;
327 while (byte_count >= 4) {
328 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
329 WREG32(mmSMC_IND_DATA_0, data);
330 src += 4;
331 byte_count -= 4;
332 }
333 val = RREG32(mmSMC_IND_ACCESS_CNTL);
334 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
335 WREG32(mmSMC_IND_ACCESS_CNTL, val);
336 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
337
338 return 0;
339}
340
341#if 0 /* not used yet */
342static int iceland_read_smc_sram_dword(struct amdgpu_device *adev,
343 uint32_t smc_address,
344 uint32_t *value,
345 uint32_t limit)
346{
347 int result;
348 unsigned long flags;
349
350 spin_lock_irqsave(&adev->smc_idx_lock, flags);
351 result = iceland_set_smc_sram_address(adev, smc_address, limit);
352 if (result == 0)
353 *value = RREG32(mmSMC_IND_DATA_0);
354 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
355 return result;
356}
357
358static int iceland_write_smc_sram_dword(struct amdgpu_device *adev,
359 uint32_t smc_address,
360 uint32_t value,
361 uint32_t limit)
362{
363 int result;
364 unsigned long flags;
365
366 spin_lock_irqsave(&adev->smc_idx_lock, flags);
367 result = iceland_set_smc_sram_address(adev, smc_address, limit);
368 if (result == 0)
369 WREG32(mmSMC_IND_DATA_0, value);
370 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
371 return result;
372}
373
374static int iceland_smu_stop_smc(struct amdgpu_device *adev)
375{
376 iceland_reset_smc(adev);
377 iceland_stop_smc_clock(adev);
378
379 return 0;
380}
381#endif
382
383static int iceland_smu_start_smc(struct amdgpu_device *adev)
384{
385 int i;
386 uint32_t val;
387
388 iceland_program_jump_on_start(adev);
389 iceland_start_smc_clock(adev);
390 iceland_start_smc(adev);
391
392 for (i = 0; i < adev->usec_timeout; i++) {
393 val = RREG32_SMC(ixFIRMWARE_FLAGS);
394 if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED) == 1)
395 break;
396 udelay(1);
397 }
398 return 0;
399}
400
401static enum AMDGPU_UCODE_ID iceland_convert_fw_type(uint32_t fw_type)
402{
403 switch (fw_type) {
404 case UCODE_ID_SDMA0:
405 return AMDGPU_UCODE_ID_SDMA0;
406 case UCODE_ID_SDMA1:
407 return AMDGPU_UCODE_ID_SDMA1;
408 case UCODE_ID_CP_CE:
409 return AMDGPU_UCODE_ID_CP_CE;
410 case UCODE_ID_CP_PFP:
411 return AMDGPU_UCODE_ID_CP_PFP;
412 case UCODE_ID_CP_ME:
413 return AMDGPU_UCODE_ID_CP_ME;
414 case UCODE_ID_CP_MEC:
415 case UCODE_ID_CP_MEC_JT1:
416 return AMDGPU_UCODE_ID_CP_MEC1;
417 case UCODE_ID_CP_MEC_JT2:
418 return AMDGPU_UCODE_ID_CP_MEC2;
419 case UCODE_ID_RLC_G:
420 return AMDGPU_UCODE_ID_RLC_G;
421 default:
422 DRM_ERROR("ucode type is out of range!\n");
423 return AMDGPU_UCODE_ID_MAXIMUM;
424 }
425}
426
427static uint32_t iceland_smu_get_mask_for_fw_type(uint32_t fw_type)
428{
429 switch (fw_type) {
430 case AMDGPU_UCODE_ID_SDMA0:
431 return UCODE_ID_SDMA0_MASK;
432 case AMDGPU_UCODE_ID_SDMA1:
433 return UCODE_ID_SDMA1_MASK;
434 case AMDGPU_UCODE_ID_CP_CE:
435 return UCODE_ID_CP_CE_MASK;
436 case AMDGPU_UCODE_ID_CP_PFP:
437 return UCODE_ID_CP_PFP_MASK;
438 case AMDGPU_UCODE_ID_CP_ME:
439 return UCODE_ID_CP_ME_MASK;
440 case AMDGPU_UCODE_ID_CP_MEC1:
441 return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK;
442 case AMDGPU_UCODE_ID_CP_MEC2:
443 return UCODE_ID_CP_MEC_MASK;
444 case AMDGPU_UCODE_ID_RLC_G:
445 return UCODE_ID_RLC_G_MASK;
446 default:
447 DRM_ERROR("ucode type is out of range!\n");
448 return 0;
449 }
450}
451
452static int iceland_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
453 uint32_t fw_type,
454 struct SMU_Entry *entry)
455{
456 enum AMDGPU_UCODE_ID id = iceland_convert_fw_type(fw_type);
457 struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
458 const struct gfx_firmware_header_v1_0 *header = NULL;
459 uint64_t gpu_addr;
460 uint32_t data_size;
461
462 if (ucode->fw == NULL)
463 return -EINVAL;
464
465 gpu_addr = ucode->mc_addr;
466 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
467 data_size = le32_to_cpu(header->header.ucode_size_bytes);
468
469 entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
470 entry->id = (uint16_t)fw_type;
471 entry->image_addr_high = upper_32_bits(gpu_addr);
472 entry->image_addr_low = lower_32_bits(gpu_addr);
473 entry->meta_data_addr_high = 0;
474 entry->meta_data_addr_low = 0;
475 entry->data_size_byte = data_size;
476 entry->num_register_entries = 0;
477 entry->flags = 0;
478
479 return 0;
480}
481
482static int iceland_smu_request_load_fw(struct amdgpu_device *adev)
483{
484 struct iceland_smu_private_data *private = (struct iceland_smu_private_data *)adev->smu.priv;
485 struct SMU_DRAMData_TOC *toc;
486 uint32_t fw_to_load;
487
488 toc = (struct SMU_DRAMData_TOC *)private->header;
489 toc->num_entries = 0;
490 toc->structure_version = 1;
491
492 if (!adev->firmware.smu_load)
493 return 0;
494
495 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G,
496 &toc->entry[toc->num_entries++])) {
497 DRM_ERROR("Failed to get firmware entry for RLC\n");
498 return -EINVAL;
499 }
500
501 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE,
502 &toc->entry[toc->num_entries++])) {
503 DRM_ERROR("Failed to get firmware entry for CE\n");
504 return -EINVAL;
505 }
506
507 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP,
508 &toc->entry[toc->num_entries++])) {
509 DRM_ERROR("Failed to get firmware entry for PFP\n");
510 return -EINVAL;
511 }
512
513 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME,
514 &toc->entry[toc->num_entries++])) {
515 DRM_ERROR("Failed to get firmware entry for ME\n");
516 return -EINVAL;
517 }
518
519 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC,
520 &toc->entry[toc->num_entries++])) {
521 DRM_ERROR("Failed to get firmware entry for MEC\n");
522 return -EINVAL;
523 }
524
525 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1,
526 &toc->entry[toc->num_entries++])) {
527 DRM_ERROR("Failed to get firmware entry for MEC_JT1\n");
528 return -EINVAL;
529 }
530
531 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
532 &toc->entry[toc->num_entries++])) {
533 DRM_ERROR("Failed to get firmware entry for SDMA0\n");
534 return -EINVAL;
535 }
536
537 if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1,
538 &toc->entry[toc->num_entries++])) {
539 DRM_ERROR("Failed to get firmware entry for SDMA1\n");
540 return -EINVAL;
541 }
542
543 iceland_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high);
544 iceland_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low);
545
546 fw_to_load = UCODE_ID_RLC_G_MASK |
547 UCODE_ID_SDMA0_MASK |
548 UCODE_ID_SDMA1_MASK |
549 UCODE_ID_CP_CE_MASK |
550 UCODE_ID_CP_ME_MASK |
551 UCODE_ID_CP_PFP_MASK |
552 UCODE_ID_CP_MEC_MASK |
553 UCODE_ID_CP_MEC_JT1_MASK;
554
555
556 if (iceland_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
557 DRM_ERROR("Fail to request SMU load ucode\n");
558 return -EINVAL;
559 }
560
561 return 0;
562}
563
564static int iceland_smu_check_fw_load_finish(struct amdgpu_device *adev,
565 uint32_t fw_type)
566{
567 uint32_t fw_mask = iceland_smu_get_mask_for_fw_type(fw_type);
568 int i;
569
570 for (i = 0; i < adev->usec_timeout; i++) {
571 if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_27) & fw_mask))
572 break;
573 udelay(1);
574 }
575
576 if (i == adev->usec_timeout) {
577 DRM_ERROR("check firmware loading failed\n");
578 return -EINVAL;
579 }
580
581 return 0;
582}
583
584int iceland_smu_start(struct amdgpu_device *adev)
585{
586 int result;
587
588 result = iceland_smu_upload_firmware_image(adev);
589 if (result)
590 return result;
591 result = iceland_smu_start_smc(adev);
592 if (result)
593 return result;
594
595 return iceland_smu_request_load_fw(adev);
596}
597
598static const struct amdgpu_smumgr_funcs iceland_smumgr_funcs = {
599 .check_fw_load_finish = iceland_smu_check_fw_load_finish,
600 .request_smu_load_fw = NULL,
601 .request_smu_specific_fw = NULL,
602};
603
604int iceland_smu_init(struct amdgpu_device *adev)
605{
606 struct iceland_smu_private_data *private;
607 uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
608 struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
609 uint64_t mc_addr;
610 void *toc_buf_ptr;
611 int ret;
612
613 private = kzalloc(sizeof(struct iceland_smu_private_data), GFP_KERNEL);
614 if (NULL == private)
615 return -ENOMEM;
616
617 /* allocate firmware buffers */
618 if (adev->firmware.smu_load)
619 amdgpu_ucode_init_bo(adev);
620
621 adev->smu.priv = private;
622 adev->smu.fw_flags = 0;
623
624 /* Allocate FW image data structure and header buffer */
625 ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,
626 true, AMDGPU_GEM_DOMAIN_VRAM,
627 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
628 NULL, NULL, toc_buf);
629 if (ret) {
630 DRM_ERROR("Failed to allocate memory for TOC buffer\n");
631 return -ENOMEM;
632 }
633
634 /* Retrieve GPU address for header buffer and internal buffer */
635 ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
636 if (ret) {
637 amdgpu_bo_unref(&adev->smu.toc_buf);
638 DRM_ERROR("Failed to reserve the TOC buffer\n");
639 return -EINVAL;
640 }
641
642 ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
643 if (ret) {
644 amdgpu_bo_unreserve(adev->smu.toc_buf);
645 amdgpu_bo_unref(&adev->smu.toc_buf);
646 DRM_ERROR("Failed to pin the TOC buffer\n");
647 return -EINVAL;
648 }
649
650 ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
651 if (ret) {
652 amdgpu_bo_unreserve(adev->smu.toc_buf);
653 amdgpu_bo_unref(&adev->smu.toc_buf);
654 DRM_ERROR("Failed to map the TOC buffer\n");
655 return -EINVAL;
656 }
657
658 amdgpu_bo_unreserve(adev->smu.toc_buf);
659 private->header_addr_low = lower_32_bits(mc_addr);
660 private->header_addr_high = upper_32_bits(mc_addr);
661 private->header = toc_buf_ptr;
662
663 adev->smu.smumgr_funcs = &iceland_smumgr_funcs;
664
665 return 0;
666}
667
668int iceland_smu_fini(struct amdgpu_device *adev)
669{
670 amdgpu_bo_unref(&adev->smu.toc_buf);
671 kfree(adev->smu.priv);
672 adev->smu.priv = NULL;
673 if (adev->firmware.fw_buf)
674 amdgpu_ucode_fini_bo(adev);
675
676 return 0;
677}
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smum.h b/drivers/gpu/drm/amd/amdgpu/iceland_smum.h
deleted file mode 100644
index 5983e3150cc5..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/iceland_smum.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright 2014 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
24#ifndef ICELAND_SMUM_H
25#define ICELAND_SMUM_H
26
27#include "ppsmc.h"
28
29extern int iceland_smu_init(struct amdgpu_device *adev);
30extern int iceland_smu_fini(struct amdgpu_device *adev);
31extern int iceland_smu_start(struct amdgpu_device *adev);
32
33struct iceland_smu_private_data
34{
35 uint8_t *header;
36 uint8_t *mec_image;
37 uint32_t header_addr_high;
38 uint32_t header_addr_low;
39};
40
41#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
deleted file mode 100644
index f06f6f4dc3a8..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "tonga_smum.h"
28
29MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
30
31static void tonga_dpm_set_funcs(struct amdgpu_device *adev);
32
33static int tonga_dpm_early_init(void *handle)
34{
35 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
36
37 tonga_dpm_set_funcs(adev);
38
39 return 0;
40}
41
42static int tonga_dpm_init_microcode(struct amdgpu_device *adev)
43{
44 char fw_name[30] = "amdgpu/tonga_smc.bin";
45 int err;
46 err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
47 if (err)
48 goto out;
49 err = amdgpu_ucode_validate(adev->pm.fw);
50
51out:
52 if (err) {
53 DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
54 release_firmware(adev->pm.fw);
55 adev->pm.fw = NULL;
56 }
57 return err;
58}
59
60static int tonga_dpm_sw_init(void *handle)
61{
62 int ret;
63 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
64
65 ret = tonga_dpm_init_microcode(adev);
66 if (ret)
67 return ret;
68
69 return 0;
70}
71
72static int tonga_dpm_sw_fini(void *handle)
73{
74 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
75
76 release_firmware(adev->pm.fw);
77 adev->pm.fw = NULL;
78
79 return 0;
80}
81
82static int tonga_dpm_hw_init(void *handle)
83{
84 int ret;
85 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
86
87 mutex_lock(&adev->pm.mutex);
88
89 /* smu init only needs to be called at startup, not resume.
90 * It should be in sw_init, but requires the fw info gathered
91 * in sw_init from other IP modules.
92 */
93 ret = tonga_smu_init(adev);
94 if (ret) {
95 DRM_ERROR("SMU initialization failed\n");
96 goto fail;
97 }
98
99 ret = tonga_smu_start(adev);
100 if (ret) {
101 DRM_ERROR("SMU start failed\n");
102 goto fail;
103 }
104
105 mutex_unlock(&adev->pm.mutex);
106 return 0;
107
108fail:
109 adev->firmware.smu_load = false;
110 mutex_unlock(&adev->pm.mutex);
111 return -EINVAL;
112}
113
114static int tonga_dpm_hw_fini(void *handle)
115{
116 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
117
118 mutex_lock(&adev->pm.mutex);
119 /* smu fini only needs to be called at teardown, not suspend.
120 * It should be in sw_fini, but we put it here for symmetry
121 * with smu init.
122 */
123 tonga_smu_fini(adev);
124 mutex_unlock(&adev->pm.mutex);
125 return 0;
126}
127
128static int tonga_dpm_suspend(void *handle)
129{
130 return tonga_dpm_hw_fini(handle);
131}
132
133static int tonga_dpm_resume(void *handle)
134{
135 return tonga_dpm_hw_init(handle);
136}
137
138static int tonga_dpm_set_clockgating_state(void *handle,
139 enum amd_clockgating_state state)
140{
141 return 0;
142}
143
144static int tonga_dpm_set_powergating_state(void *handle,
145 enum amd_powergating_state state)
146{
147 return 0;
148}
149
150const struct amd_ip_funcs tonga_dpm_ip_funcs = {
151 .name = "tonga_dpm",
152 .early_init = tonga_dpm_early_init,
153 .late_init = NULL,
154 .sw_init = tonga_dpm_sw_init,
155 .sw_fini = tonga_dpm_sw_fini,
156 .hw_init = tonga_dpm_hw_init,
157 .hw_fini = tonga_dpm_hw_fini,
158 .suspend = tonga_dpm_suspend,
159 .resume = tonga_dpm_resume,
160 .is_idle = NULL,
161 .wait_for_idle = NULL,
162 .soft_reset = NULL,
163 .set_clockgating_state = tonga_dpm_set_clockgating_state,
164 .set_powergating_state = tonga_dpm_set_powergating_state,
165};
166
167static const struct amdgpu_dpm_funcs tonga_dpm_funcs = {
168 .get_temperature = NULL,
169 .pre_set_power_state = NULL,
170 .set_power_state = NULL,
171 .post_set_power_state = NULL,
172 .display_configuration_changed = NULL,
173 .get_sclk = NULL,
174 .get_mclk = NULL,
175 .print_power_state = NULL,
176 .debugfs_print_current_performance_level = NULL,
177 .force_performance_level = NULL,
178 .vblank_too_short = NULL,
179 .powergate_uvd = NULL,
180};
181
182static void tonga_dpm_set_funcs(struct amdgpu_device *adev)
183{
184 if (NULL == adev->pm.funcs)
185 adev->pm.funcs = &tonga_dpm_funcs;
186}
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
deleted file mode 100644
index 1e71e819468b..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
+++ /dev/null
@@ -1,862 +0,0 @@
1/*
2 * Copyright 2014 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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "tonga_ppsmc.h"
28#include "tonga_smum.h"
29#include "smu_ucode_xfer_vi.h"
30#include "amdgpu_ucode.h"
31
32#include "smu/smu_7_1_2_d.h"
33#include "smu/smu_7_1_2_sh_mask.h"
34
35#define TONGA_SMC_SIZE 0x20000
36
37static int tonga_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit)
38{
39 uint32_t val;
40
41 if (smc_address & 3)
42 return -EINVAL;
43
44 if ((smc_address + 3) > limit)
45 return -EINVAL;
46
47 WREG32(mmSMC_IND_INDEX_0, smc_address);
48
49 val = RREG32(mmSMC_IND_ACCESS_CNTL);
50 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
51 WREG32(mmSMC_IND_ACCESS_CNTL, val);
52
53 return 0;
54}
55
56static int tonga_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit)
57{
58 uint32_t addr;
59 uint32_t data, orig_data;
60 int result = 0;
61 uint32_t extra_shift;
62 unsigned long flags;
63
64 if (smc_start_address & 3)
65 return -EINVAL;
66
67 if ((smc_start_address + byte_count) > limit)
68 return -EINVAL;
69
70 addr = smc_start_address;
71
72 spin_lock_irqsave(&adev->smc_idx_lock, flags);
73 while (byte_count >= 4) {
74 /* Bytes are written into the SMC addres space with the MSB first */
75 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
76
77 result = tonga_set_smc_sram_address(adev, addr, limit);
78
79 if (result)
80 goto out;
81
82 WREG32(mmSMC_IND_DATA_0, data);
83
84 src += 4;
85 byte_count -= 4;
86 addr += 4;
87 }
88
89 if (0 != byte_count) {
90 /* Now write odd bytes left, do a read modify write cycle */
91 data = 0;
92
93 result = tonga_set_smc_sram_address(adev, addr, limit);
94 if (result)
95 goto out;
96
97 orig_data = RREG32(mmSMC_IND_DATA_0);
98 extra_shift = 8 * (4 - byte_count);
99
100 while (byte_count > 0) {
101 data = (data << 8) + *src++;
102 byte_count--;
103 }
104
105 data <<= extra_shift;
106 data |= (orig_data & ~((~0UL) << extra_shift));
107
108 result = tonga_set_smc_sram_address(adev, addr, limit);
109 if (result)
110 goto out;
111
112 WREG32(mmSMC_IND_DATA_0, data);
113 }
114
115out:
116 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
117 return result;
118}
119
120static int tonga_program_jump_on_start(struct amdgpu_device *adev)
121{
122 static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40};
123 tonga_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
124
125 return 0;
126}
127
128static bool tonga_is_smc_ram_running(struct amdgpu_device *adev)
129{
130 uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
131 val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
132
133 return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C)));
134}
135
136static int wait_smu_response(struct amdgpu_device *adev)
137{
138 int i;
139 uint32_t val;
140
141 for (i = 0; i < adev->usec_timeout; i++) {
142 val = RREG32(mmSMC_RESP_0);
143 if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP))
144 break;
145 udelay(1);
146 }
147
148 if (i == adev->usec_timeout)
149 return -EINVAL;
150
151 return 0;
152}
153
154static int tonga_send_msg_to_smc_offset(struct amdgpu_device *adev)
155{
156 if (wait_smu_response(adev)) {
157 DRM_ERROR("Failed to send previous message\n");
158 return -EINVAL;
159 }
160
161 WREG32(mmSMC_MSG_ARG_0, 0x20000);
162 WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test);
163
164 if (wait_smu_response(adev)) {
165 DRM_ERROR("Failed to send message\n");
166 return -EINVAL;
167 }
168
169 return 0;
170}
171
172static int tonga_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
173{
174 if (!tonga_is_smc_ram_running(adev))
175 {
176 return -EINVAL;
177 }
178
179 if (wait_smu_response(adev)) {
180 DRM_ERROR("Failed to send previous message\n");
181 return -EINVAL;
182 }
183
184 WREG32(mmSMC_MESSAGE_0, msg);
185
186 if (wait_smu_response(adev)) {
187 DRM_ERROR("Failed to send message\n");
188 return -EINVAL;
189 }
190
191 return 0;
192}
193
194static int tonga_send_msg_to_smc_without_waiting(struct amdgpu_device *adev,
195 PPSMC_Msg msg)
196{
197 if (wait_smu_response(adev)) {
198 DRM_ERROR("Failed to send previous message\n");
199 return -EINVAL;
200 }
201
202 WREG32(mmSMC_MESSAGE_0, msg);
203
204 return 0;
205}
206
207static int tonga_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
208 PPSMC_Msg msg,
209 uint32_t parameter)
210{
211 if (!tonga_is_smc_ram_running(adev))
212 return -EINVAL;
213
214 if (wait_smu_response(adev)) {
215 DRM_ERROR("Failed to send previous message\n");
216 return -EINVAL;
217 }
218
219 WREG32(mmSMC_MSG_ARG_0, parameter);
220
221 return tonga_send_msg_to_smc(adev, msg);
222}
223
224static int tonga_send_msg_to_smc_with_parameter_without_waiting(
225 struct amdgpu_device *adev,
226 PPSMC_Msg msg, uint32_t parameter)
227{
228 if (wait_smu_response(adev)) {
229 DRM_ERROR("Failed to send previous message\n");
230 return -EINVAL;
231 }
232
233 WREG32(mmSMC_MSG_ARG_0, parameter);
234
235 return tonga_send_msg_to_smc_without_waiting(adev, msg);
236}
237
238#if 0 /* not used yet */
239static int tonga_wait_for_smc_inactive(struct amdgpu_device *adev)
240{
241 int i;
242 uint32_t val;
243
244 if (!tonga_is_smc_ram_running(adev))
245 return -EINVAL;
246
247 for (i = 0; i < adev->usec_timeout; i++) {
248 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
249 if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0)
250 break;
251 udelay(1);
252 }
253
254 if (i == adev->usec_timeout)
255 return -EINVAL;
256
257 return 0;
258}
259#endif
260
261static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev)
262{
263 const struct smc_firmware_header_v1_0 *hdr;
264 uint32_t ucode_size;
265 uint32_t ucode_start_address;
266 const uint8_t *src;
267 uint32_t val;
268 uint32_t byte_count;
269 uint32_t *data;
270 unsigned long flags;
271
272 if (!adev->pm.fw)
273 return -EINVAL;
274
275 /* Skip SMC ucode loading on SR-IOV capable boards.
276 * vbios does this for us in asic_init in that case.
277 */
278 if (amdgpu_sriov_bios(adev))
279 return 0;
280
281 hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
282 amdgpu_ucode_print_smc_hdr(&hdr->header);
283
284 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
285 ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
286 ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
287 src = (const uint8_t *)
288 (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
289
290 if (ucode_size & 3) {
291 DRM_ERROR("SMC ucode is not 4 bytes aligned\n");
292 return -EINVAL;
293 }
294
295 if (ucode_size > TONGA_SMC_SIZE) {
296 DRM_ERROR("SMC address is beyond the SMC RAM area\n");
297 return -EINVAL;
298 }
299
300 spin_lock_irqsave(&adev->smc_idx_lock, flags);
301 WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
302
303 val = RREG32(mmSMC_IND_ACCESS_CNTL);
304 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
305 WREG32(mmSMC_IND_ACCESS_CNTL, val);
306
307 byte_count = ucode_size;
308 data = (uint32_t *)src;
309 for (; byte_count >= 4; data++, byte_count -= 4)
310 WREG32(mmSMC_IND_DATA_0, data[0]);
311
312 val = RREG32(mmSMC_IND_ACCESS_CNTL);
313 val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
314 WREG32(mmSMC_IND_ACCESS_CNTL, val);
315 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
316
317 return 0;
318}
319
320#if 0 /* not used yet */
321static int tonga_read_smc_sram_dword(struct amdgpu_device *adev,
322 uint32_t smc_address,
323 uint32_t *value,
324 uint32_t limit)
325{
326 int result;
327 unsigned long flags;
328
329 spin_lock_irqsave(&adev->smc_idx_lock, flags);
330 result = tonga_set_smc_sram_address(adev, smc_address, limit);
331 if (result == 0)
332 *value = RREG32(mmSMC_IND_DATA_0);
333 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
334 return result;
335}
336
337static int tonga_write_smc_sram_dword(struct amdgpu_device *adev,
338 uint32_t smc_address,
339 uint32_t value,
340 uint32_t limit)
341{
342 int result;
343 unsigned long flags;
344
345 spin_lock_irqsave(&adev->smc_idx_lock, flags);
346 result = tonga_set_smc_sram_address(adev, smc_address, limit);
347 if (result == 0)
348 WREG32(mmSMC_IND_DATA_0, value);
349 spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
350 return result;
351}
352
353static int tonga_smu_stop_smc(struct amdgpu_device *adev)
354{
355 uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
356 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
357 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
358
359 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
360 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1);
361 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
362
363 return 0;
364}
365#endif
366
367static enum AMDGPU_UCODE_ID tonga_convert_fw_type(uint32_t fw_type)
368{
369 switch (fw_type) {
370 case UCODE_ID_SDMA0:
371 return AMDGPU_UCODE_ID_SDMA0;
372 case UCODE_ID_SDMA1:
373 return AMDGPU_UCODE_ID_SDMA1;
374 case UCODE_ID_CP_CE:
375 return AMDGPU_UCODE_ID_CP_CE;
376 case UCODE_ID_CP_PFP:
377 return AMDGPU_UCODE_ID_CP_PFP;
378 case UCODE_ID_CP_ME:
379 return AMDGPU_UCODE_ID_CP_ME;
380 case UCODE_ID_CP_MEC:
381 case UCODE_ID_CP_MEC_JT1:
382 return AMDGPU_UCODE_ID_CP_MEC1;
383 case UCODE_ID_CP_MEC_JT2:
384 return AMDGPU_UCODE_ID_CP_MEC2;
385 case UCODE_ID_RLC_G:
386 return AMDGPU_UCODE_ID_RLC_G;
387 default:
388 DRM_ERROR("ucode type is out of range!\n");
389 return AMDGPU_UCODE_ID_MAXIMUM;
390 }
391}
392
393static int tonga_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
394 uint32_t fw_type,
395 struct SMU_Entry *entry)
396{
397 enum AMDGPU_UCODE_ID id = tonga_convert_fw_type(fw_type);
398 struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
399 const struct gfx_firmware_header_v1_0 *header = NULL;
400 uint64_t gpu_addr;
401 uint32_t data_size;
402
403 if (ucode->fw == NULL)
404 return -EINVAL;
405
406 gpu_addr = ucode->mc_addr;
407 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
408 data_size = le32_to_cpu(header->header.ucode_size_bytes);
409
410 if ((fw_type == UCODE_ID_CP_MEC_JT1) ||
411 (fw_type == UCODE_ID_CP_MEC_JT2)) {
412 gpu_addr += le32_to_cpu(header->jt_offset) << 2;
413 data_size = le32_to_cpu(header->jt_size) << 2;
414 }
415
416 entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
417 entry->id = (uint16_t)fw_type;
418 entry->image_addr_high = upper_32_bits(gpu_addr);
419 entry->image_addr_low = lower_32_bits(gpu_addr);
420 entry->meta_data_addr_high = 0;
421 entry->meta_data_addr_low = 0;
422 entry->data_size_byte = data_size;
423 entry->num_register_entries = 0;
424
425 if (fw_type == UCODE_ID_RLC_G)
426 entry->flags = 1;
427 else
428 entry->flags = 0;
429
430 return 0;
431}
432
433static int tonga_smu_request_load_fw(struct amdgpu_device *adev)
434{
435 struct tonga_smu_private_data *private = (struct tonga_smu_private_data *)adev->smu.priv;
436 struct SMU_DRAMData_TOC *toc;
437 uint32_t fw_to_load;
438
439 WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0);
440
441 tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high);
442 tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low);
443
444 toc = (struct SMU_DRAMData_TOC *)private->header;
445 toc->num_entries = 0;
446 toc->structure_version = 1;
447
448 if (!adev->firmware.smu_load)
449 return 0;
450
451 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G,
452 &toc->entry[toc->num_entries++])) {
453 DRM_ERROR("Failed to get firmware entry for RLC\n");
454 return -EINVAL;
455 }
456
457 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE,
458 &toc->entry[toc->num_entries++])) {
459 DRM_ERROR("Failed to get firmware entry for CE\n");
460 return -EINVAL;
461 }
462
463 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP,
464 &toc->entry[toc->num_entries++])) {
465 DRM_ERROR("Failed to get firmware entry for PFP\n");
466 return -EINVAL;
467 }
468
469 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME,
470 &toc->entry[toc->num_entries++])) {
471 DRM_ERROR("Failed to get firmware entry for ME\n");
472 return -EINVAL;
473 }
474
475 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC,
476 &toc->entry[toc->num_entries++])) {
477 DRM_ERROR("Failed to get firmware entry for MEC\n");
478 return -EINVAL;
479 }
480
481 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1,
482 &toc->entry[toc->num_entries++])) {
483 DRM_ERROR("Failed to get firmware entry for MEC_JT1\n");
484 return -EINVAL;
485 }
486
487 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2,
488 &toc->entry[toc->num_entries++])) {
489 DRM_ERROR("Failed to get firmware entry for MEC_JT2\n");
490 return -EINVAL;
491 }
492
493 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
494 &toc->entry[toc->num_entries++])) {
495 DRM_ERROR("Failed to get firmware entry for SDMA0\n");
496 return -EINVAL;
497 }
498
499 if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1,
500 &toc->entry[toc->num_entries++])) {
501 DRM_ERROR("Failed to get firmware entry for SDMA1\n");
502 return -EINVAL;
503 }
504
505 tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high);
506 tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low);
507
508 fw_to_load = UCODE_ID_RLC_G_MASK |
509 UCODE_ID_SDMA0_MASK |
510 UCODE_ID_SDMA1_MASK |
511 UCODE_ID_CP_CE_MASK |
512 UCODE_ID_CP_ME_MASK |
513 UCODE_ID_CP_PFP_MASK |
514 UCODE_ID_CP_MEC_MASK;
515
516 if (tonga_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
517 DRM_ERROR("Fail to request SMU load ucode\n");
518 return -EINVAL;
519 }
520
521 return 0;
522}
523
524static uint32_t tonga_smu_get_mask_for_fw_type(uint32_t fw_type)
525{
526 switch (fw_type) {
527 case AMDGPU_UCODE_ID_SDMA0:
528 return UCODE_ID_SDMA0_MASK;
529 case AMDGPU_UCODE_ID_SDMA1:
530 return UCODE_ID_SDMA1_MASK;
531 case AMDGPU_UCODE_ID_CP_CE:
532 return UCODE_ID_CP_CE_MASK;
533 case AMDGPU_UCODE_ID_CP_PFP:
534 return UCODE_ID_CP_PFP_MASK;
535 case AMDGPU_UCODE_ID_CP_ME:
536 return UCODE_ID_CP_ME_MASK;
537 case AMDGPU_UCODE_ID_CP_MEC1:
538 return UCODE_ID_CP_MEC_MASK;
539 case AMDGPU_UCODE_ID_CP_MEC2:
540 return UCODE_ID_CP_MEC_MASK;
541 case AMDGPU_UCODE_ID_RLC_G:
542 return UCODE_ID_RLC_G_MASK;
543 default:
544 DRM_ERROR("ucode type is out of range!\n");
545 return 0;
546 }
547}
548
549static int tonga_smu_check_fw_load_finish(struct amdgpu_device *adev,
550 uint32_t fw_type)
551{
552 uint32_t fw_mask = tonga_smu_get_mask_for_fw_type(fw_type);
553 int i;
554
555 for (i = 0; i < adev->usec_timeout; i++) {
556 if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask))
557 break;
558 udelay(1);
559 }
560
561 if (i == adev->usec_timeout) {
562 DRM_ERROR("check firmware loading failed\n");
563 return -EINVAL;
564 }
565
566 return 0;
567}
568
569static int tonga_smu_start_in_protection_mode(struct amdgpu_device *adev)
570{
571 int result;
572 uint32_t val;
573 int i;
574
575 /* Assert reset */
576 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
577 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
578 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
579
580 result = tonga_smu_upload_firmware_image(adev);
581 if (result)
582 return result;
583
584 /* Clear status */
585 WREG32_SMC(ixSMU_STATUS, 0);
586
587 /* Enable clock */
588 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
589 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
590 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
591
592 /* De-assert reset */
593 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
594 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
595 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
596
597 /* Set SMU Auto Start */
598 val = RREG32_SMC(ixSMU_INPUT_DATA);
599 val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1);
600 WREG32_SMC(ixSMU_INPUT_DATA, val);
601
602 /* Clear firmware interrupt enable flag */
603 WREG32_SMC(ixFIRMWARE_FLAGS, 0);
604
605 for (i = 0; i < adev->usec_timeout; i++) {
606 val = RREG32_SMC(ixRCU_UC_EVENTS);
607 if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED))
608 break;
609 udelay(1);
610 }
611
612 if (i == adev->usec_timeout) {
613 DRM_ERROR("Interrupt is not enabled by firmware\n");
614 return -EINVAL;
615 }
616
617 /* Call Test SMU message with 0x20000 offset
618 * to trigger SMU start
619 */
620 tonga_send_msg_to_smc_offset(adev);
621
622 /* Wait for done bit to be set */
623 for (i = 0; i < adev->usec_timeout; i++) {
624 val = RREG32_SMC(ixSMU_STATUS);
625 if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE))
626 break;
627 udelay(1);
628 }
629
630 if (i == adev->usec_timeout) {
631 DRM_ERROR("Timeout for SMU start\n");
632 return -EINVAL;
633 }
634
635 /* Check pass/failed indicator */
636 val = RREG32_SMC(ixSMU_STATUS);
637 if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) {
638 DRM_ERROR("SMU Firmware start failed\n");
639 return -EINVAL;
640 }
641
642 /* Wait for firmware to initialize */
643 for (i = 0; i < adev->usec_timeout; i++) {
644 val = RREG32_SMC(ixFIRMWARE_FLAGS);
645 if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
646 break;
647 udelay(1);
648 }
649
650 if (i == adev->usec_timeout) {
651 DRM_ERROR("SMU firmware initialization failed\n");
652 return -EINVAL;
653 }
654
655 return 0;
656}
657
658static int tonga_smu_start_in_non_protection_mode(struct amdgpu_device *adev)
659{
660 int i, result;
661 uint32_t val;
662
663 /* wait for smc boot up */
664 for (i = 0; i < adev->usec_timeout; i++) {
665 val = RREG32_SMC(ixRCU_UC_EVENTS);
666 val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done);
667 if (val)
668 break;
669 udelay(1);
670 }
671
672 if (i == adev->usec_timeout) {
673 DRM_ERROR("SMC boot sequence is not completed\n");
674 return -EINVAL;
675 }
676
677 /* Clear firmware interrupt enable flag */
678 WREG32_SMC(ixFIRMWARE_FLAGS, 0);
679
680 /* Assert reset */
681 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
682 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
683 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
684
685 result = tonga_smu_upload_firmware_image(adev);
686 if (result)
687 return result;
688
689 /* Set smc instruct start point at 0x0 */
690 tonga_program_jump_on_start(adev);
691
692 /* Enable clock */
693 val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
694 val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
695 WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
696
697 /* De-assert reset */
698 val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
699 val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
700 WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
701
702 /* Wait for firmware to initialize */
703 for (i = 0; i < adev->usec_timeout; i++) {
704 val = RREG32_SMC(ixFIRMWARE_FLAGS);
705 if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
706 break;
707 udelay(1);
708 }
709
710 if (i == adev->usec_timeout) {
711 DRM_ERROR("Timeout for SMC firmware initialization\n");
712 return -EINVAL;
713 }
714
715 return 0;
716}
717
718int tonga_smu_start(struct amdgpu_device *adev)
719{
720 int result;
721 uint32_t val;
722
723 if (!tonga_is_smc_ram_running(adev)) {
724 val = RREG32_SMC(ixSMU_FIRMWARE);
725 if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) {
726 result = tonga_smu_start_in_non_protection_mode(adev);
727 if (result)
728 return result;
729 } else {
730 result = tonga_smu_start_in_protection_mode(adev);
731 if (result)
732 return result;
733 }
734 }
735
736 return tonga_smu_request_load_fw(adev);
737}
738
739static const struct amdgpu_smumgr_funcs tonga_smumgr_funcs = {
740 .check_fw_load_finish = tonga_smu_check_fw_load_finish,
741 .request_smu_load_fw = NULL,
742 .request_smu_specific_fw = NULL,
743};
744
745int tonga_smu_init(struct amdgpu_device *adev)
746{
747 struct tonga_smu_private_data *private;
748 uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
749 uint32_t smu_internal_buffer_size = 200*4096;
750 struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
751 struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
752 uint64_t mc_addr;
753 void *toc_buf_ptr;
754 void *smu_buf_ptr;
755 int ret;
756
757 private = kzalloc(sizeof(struct tonga_smu_private_data), GFP_KERNEL);
758 if (NULL == private)
759 return -ENOMEM;
760
761 /* allocate firmware buffers */
762 if (adev->firmware.smu_load)
763 amdgpu_ucode_init_bo(adev);
764
765 adev->smu.priv = private;
766 adev->smu.fw_flags = 0;
767
768 /* Allocate FW image data structure and header buffer */
769 ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,
770 true, AMDGPU_GEM_DOMAIN_VRAM,
771 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
772 NULL, NULL, toc_buf);
773 if (ret) {
774 DRM_ERROR("Failed to allocate memory for TOC buffer\n");
775 return -ENOMEM;
776 }
777
778 /* Allocate buffer for SMU internal buffer */
779 ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,
780 true, AMDGPU_GEM_DOMAIN_VRAM,
781 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
782 NULL, NULL, smu_buf);
783 if (ret) {
784 DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");
785 return -ENOMEM;
786 }
787
788 /* Retrieve GPU address for header buffer and internal buffer */
789 ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
790 if (ret) {
791 amdgpu_bo_unref(&adev->smu.toc_buf);
792 DRM_ERROR("Failed to reserve the TOC buffer\n");
793 return -EINVAL;
794 }
795
796 ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
797 if (ret) {
798 amdgpu_bo_unreserve(adev->smu.toc_buf);
799 amdgpu_bo_unref(&adev->smu.toc_buf);
800 DRM_ERROR("Failed to pin the TOC buffer\n");
801 return -EINVAL;
802 }
803
804 ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
805 if (ret) {
806 amdgpu_bo_unreserve(adev->smu.toc_buf);
807 amdgpu_bo_unref(&adev->smu.toc_buf);
808 DRM_ERROR("Failed to map the TOC buffer\n");
809 return -EINVAL;
810 }
811
812 amdgpu_bo_unreserve(adev->smu.toc_buf);
813 private->header_addr_low = lower_32_bits(mc_addr);
814 private->header_addr_high = upper_32_bits(mc_addr);
815 private->header = toc_buf_ptr;
816
817 ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
818 if (ret) {
819 amdgpu_bo_unref(&adev->smu.smu_buf);
820 amdgpu_bo_unref(&adev->smu.toc_buf);
821 DRM_ERROR("Failed to reserve the SMU internal buffer\n");
822 return -EINVAL;
823 }
824
825 ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
826 if (ret) {
827 amdgpu_bo_unreserve(adev->smu.smu_buf);
828 amdgpu_bo_unref(&adev->smu.smu_buf);
829 amdgpu_bo_unref(&adev->smu.toc_buf);
830 DRM_ERROR("Failed to pin the SMU internal buffer\n");
831 return -EINVAL;
832 }
833
834 ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
835 if (ret) {
836 amdgpu_bo_unreserve(adev->smu.smu_buf);
837 amdgpu_bo_unref(&adev->smu.smu_buf);
838 amdgpu_bo_unref(&adev->smu.toc_buf);
839 DRM_ERROR("Failed to map the SMU internal buffer\n");
840 return -EINVAL;
841 }
842
843 amdgpu_bo_unreserve(adev->smu.smu_buf);
844 private->smu_buffer_addr_low = lower_32_bits(mc_addr);
845 private->smu_buffer_addr_high = upper_32_bits(mc_addr);
846
847 adev->smu.smumgr_funcs = &tonga_smumgr_funcs;
848
849 return 0;
850}
851
852int tonga_smu_fini(struct amdgpu_device *adev)
853{
854 amdgpu_bo_unref(&adev->smu.toc_buf);
855 amdgpu_bo_unref(&adev->smu.smu_buf);
856 kfree(adev->smu.priv);
857 adev->smu.priv = NULL;
858 if (adev->firmware.fw_buf)
859 amdgpu_ucode_fini_bo(adev);
860
861 return 0;
862}
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smum.h b/drivers/gpu/drm/amd/amdgpu/tonga_smum.h
deleted file mode 100644
index c031ff99fe3e..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/tonga_smum.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright 2014 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
24#ifndef TONGA_SMUMGR_H
25#define TONGA_SMUMGR_H
26
27#include "tonga_ppsmc.h"
28
29int tonga_smu_init(struct amdgpu_device *adev);
30int tonga_smu_fini(struct amdgpu_device *adev);
31int tonga_smu_start(struct amdgpu_device *adev);
32
33struct tonga_smu_private_data
34{
35 uint8_t *header;
36 uint32_t smu_buffer_addr_high;
37 uint32_t smu_buffer_addr_low;
38 uint32_t header_addr_high;
39 uint32_t header_addr_low;
40};
41
42#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 63ce7f08d1d5..c0d9aad7126f 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -79,6 +79,9 @@
79#endif 79#endif
80#include "dce_virtual.h" 80#include "dce_virtual.h"
81 81
82MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
83MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
84MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
82MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); 85MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
83MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); 86MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
84MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); 87MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");