Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[deliverable/linux.git] / drivers / gpu / drm / amd / amdgpu / cz_smc.c
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 #include <linux/firmware.h>
24 #include "drmP.h"
25 #include "amdgpu.h"
26 #include "smu8.h"
27 #include "smu8_fusion.h"
28 #include "cz_ppsmc.h"
29 #include "cz_smumgr.h"
30 #include "smu_ucode_xfer_cz.h"
31 #include "amdgpu_ucode.h"
32
33 #include "smu/smu_8_0_d.h"
34 #include "smu/smu_8_0_sh_mask.h"
35 #include "gca/gfx_8_0_d.h"
36 #include "gca/gfx_8_0_sh_mask.h"
37
38 uint32_t cz_get_argument(struct amdgpu_device *adev)
39 {
40 return RREG32(mmSMU_MP1_SRBM2P_ARG_0);
41 }
42
43 static struct cz_smu_private_data *cz_smu_get_priv(struct amdgpu_device *adev)
44 {
45 struct cz_smu_private_data *priv =
46 (struct cz_smu_private_data *)(adev->smu.priv);
47
48 return priv;
49 }
50
51 int cz_send_msg_to_smc_async(struct amdgpu_device *adev, u16 msg)
52 {
53 int i;
54 u32 content = 0, tmp;
55
56 for (i = 0; i < adev->usec_timeout; i++) {
57 tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
58 SMU_MP1_SRBM2P_RESP_0, CONTENT);
59 if (content != tmp)
60 break;
61 udelay(1);
62 }
63
64 /* timeout means wrong logic*/
65 if (i == adev->usec_timeout)
66 return -EINVAL;
67
68 WREG32(mmSMU_MP1_SRBM2P_RESP_0, 0);
69 WREG32(mmSMU_MP1_SRBM2P_MSG_0, msg);
70
71 return 0;
72 }
73
74 int cz_send_msg_to_smc(struct amdgpu_device *adev, u16 msg)
75 {
76 int i;
77 u32 content = 0, tmp = 0;
78
79 if (cz_send_msg_to_smc_async(adev, msg))
80 return -EINVAL;
81
82 for (i = 0; i < adev->usec_timeout; i++) {
83 tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
84 SMU_MP1_SRBM2P_RESP_0, CONTENT);
85 if (content != tmp)
86 break;
87 udelay(1);
88 }
89
90 /* timeout means wrong logic*/
91 if (i == adev->usec_timeout)
92 return -EINVAL;
93
94 if (PPSMC_Result_OK != tmp) {
95 dev_err(adev->dev, "SMC Failed to send Message.\n");
96 return -EINVAL;
97 }
98
99 return 0;
100 }
101
102 int cz_send_msg_to_smc_with_parameter_async(struct amdgpu_device *adev,
103 u16 msg, u32 parameter)
104 {
105 WREG32(mmSMU_MP1_SRBM2P_ARG_0, parameter);
106 return cz_send_msg_to_smc_async(adev, msg);
107 }
108
109 int cz_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
110 u16 msg, u32 parameter)
111 {
112 WREG32(mmSMU_MP1_SRBM2P_ARG_0, parameter);
113 return cz_send_msg_to_smc(adev, msg);
114 }
115
116 static int cz_set_smc_sram_address(struct amdgpu_device *adev,
117 u32 smc_address, u32 limit)
118 {
119 if (smc_address & 3)
120 return -EINVAL;
121 if ((smc_address + 3) > limit)
122 return -EINVAL;
123
124 WREG32(mmMP0PUB_IND_INDEX_0, SMN_MP1_SRAM_START_ADDR + smc_address);
125
126 return 0;
127 }
128
129 int cz_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
130 u32 *value, u32 limit)
131 {
132 int ret;
133
134 ret = cz_set_smc_sram_address(adev, smc_address, limit);
135 if (ret)
136 return ret;
137
138 *value = RREG32(mmMP0PUB_IND_DATA_0);
139
140 return 0;
141 }
142
143 int cz_write_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
144 u32 value, u32 limit)
145 {
146 int ret;
147
148 ret = cz_set_smc_sram_address(adev, smc_address, limit);
149 if (ret)
150 return ret;
151
152 WREG32(mmMP0PUB_IND_DATA_0, value);
153
154 return 0;
155 }
156
157 static int cz_smu_request_load_fw(struct amdgpu_device *adev)
158 {
159 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
160
161 uint32_t smc_addr = SMU8_FIRMWARE_HEADER_LOCATION +
162 offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
163
164 cz_write_smc_sram_dword(adev, smc_addr, 0, smc_addr + 4);
165
166 /*prepare toc buffers*/
167 cz_send_msg_to_smc_with_parameter(adev,
168 PPSMC_MSG_DriverDramAddrHi,
169 priv->toc_buffer.mc_addr_high);
170 cz_send_msg_to_smc_with_parameter(adev,
171 PPSMC_MSG_DriverDramAddrLo,
172 priv->toc_buffer.mc_addr_low);
173 cz_send_msg_to_smc(adev, PPSMC_MSG_InitJobs);
174
175 /*execute jobs*/
176 cz_send_msg_to_smc_with_parameter(adev,
177 PPSMC_MSG_ExecuteJob,
178 priv->toc_entry_aram);
179
180 cz_send_msg_to_smc_with_parameter(adev,
181 PPSMC_MSG_ExecuteJob,
182 priv->toc_entry_power_profiling_index);
183
184 cz_send_msg_to_smc_with_parameter(adev,
185 PPSMC_MSG_ExecuteJob,
186 priv->toc_entry_initialize_index);
187
188 return 0;
189 }
190
191 /*
192 *Check if the FW has been loaded, SMU will not return if loading
193 *has not finished.
194 */
195 static int cz_smu_check_fw_load_finish(struct amdgpu_device *adev,
196 uint32_t fw_mask)
197 {
198 int i;
199 uint32_t index = SMN_MP1_SRAM_START_ADDR +
200 SMU8_FIRMWARE_HEADER_LOCATION +
201 offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
202
203 WREG32(mmMP0PUB_IND_INDEX, index);
204
205 for (i = 0; i < adev->usec_timeout; i++) {
206 if (fw_mask == (RREG32(mmMP0PUB_IND_DATA) & fw_mask))
207 break;
208 udelay(1);
209 }
210
211 if (i >= adev->usec_timeout) {
212 dev_err(adev->dev,
213 "SMU check loaded firmware failed, expecting 0x%x, getting 0x%x",
214 fw_mask, RREG32(mmMP0PUB_IND_DATA));
215 return -EINVAL;
216 }
217
218 return 0;
219 }
220
221 /*
222 * interfaces for different ip blocks to check firmware loading status
223 * 0 for success otherwise failed
224 */
225 static int cz_smu_check_finished(struct amdgpu_device *adev,
226 enum AMDGPU_UCODE_ID id)
227 {
228 switch (id) {
229 case AMDGPU_UCODE_ID_SDMA0:
230 if (adev->smu.fw_flags & AMDGPU_SDMA0_UCODE_LOADED)
231 return 0;
232 break;
233 case AMDGPU_UCODE_ID_SDMA1:
234 if (adev->smu.fw_flags & AMDGPU_SDMA1_UCODE_LOADED)
235 return 0;
236 break;
237 case AMDGPU_UCODE_ID_CP_CE:
238 if (adev->smu.fw_flags & AMDGPU_CPCE_UCODE_LOADED)
239 return 0;
240 break;
241 case AMDGPU_UCODE_ID_CP_PFP:
242 if (adev->smu.fw_flags & AMDGPU_CPPFP_UCODE_LOADED)
243 return 0;
244 case AMDGPU_UCODE_ID_CP_ME:
245 if (adev->smu.fw_flags & AMDGPU_CPME_UCODE_LOADED)
246 return 0;
247 break;
248 case AMDGPU_UCODE_ID_CP_MEC1:
249 if (adev->smu.fw_flags & AMDGPU_CPMEC1_UCODE_LOADED)
250 return 0;
251 break;
252 case AMDGPU_UCODE_ID_CP_MEC2:
253 if (adev->smu.fw_flags & AMDGPU_CPMEC2_UCODE_LOADED)
254 return 0;
255 break;
256 case AMDGPU_UCODE_ID_RLC_G:
257 if (adev->smu.fw_flags & AMDGPU_CPRLC_UCODE_LOADED)
258 return 0;
259 break;
260 case AMDGPU_UCODE_ID_MAXIMUM:
261 default:
262 break;
263 }
264
265 return 1;
266 }
267
268 static int cz_load_mec_firmware(struct amdgpu_device *adev)
269 {
270 struct amdgpu_firmware_info *ucode =
271 &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
272 uint32_t reg_data;
273 uint32_t tmp;
274
275 if (ucode->fw == NULL)
276 return -EINVAL;
277
278 /* Disable MEC parsing/prefetching */
279 tmp = RREG32(mmCP_MEC_CNTL);
280 tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1);
281 tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1);
282 WREG32(mmCP_MEC_CNTL, tmp);
283
284 tmp = RREG32(mmCP_CPC_IC_BASE_CNTL);
285 tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0);
286 tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, ATC, 0);
287 tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
288 tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, MTYPE, 1);
289 WREG32(mmCP_CPC_IC_BASE_CNTL, tmp);
290
291 reg_data = lower_32_bits(ucode->mc_addr) &
292 REG_FIELD_MASK(CP_CPC_IC_BASE_LO, IC_BASE_LO);
293 WREG32(mmCP_CPC_IC_BASE_LO, reg_data);
294
295 reg_data = upper_32_bits(ucode->mc_addr) &
296 REG_FIELD_MASK(CP_CPC_IC_BASE_HI, IC_BASE_HI);
297 WREG32(mmCP_CPC_IC_BASE_HI, reg_data);
298
299 return 0;
300 }
301
302 int cz_smu_start(struct amdgpu_device *adev)
303 {
304 int ret = 0;
305
306 uint32_t fw_to_check = UCODE_ID_RLC_G_MASK |
307 UCODE_ID_SDMA0_MASK |
308 UCODE_ID_SDMA1_MASK |
309 UCODE_ID_CP_CE_MASK |
310 UCODE_ID_CP_ME_MASK |
311 UCODE_ID_CP_PFP_MASK |
312 UCODE_ID_CP_MEC_JT1_MASK |
313 UCODE_ID_CP_MEC_JT2_MASK;
314
315 cz_smu_request_load_fw(adev);
316 ret = cz_smu_check_fw_load_finish(adev, fw_to_check);
317 if (ret)
318 return ret;
319
320 /* manually load MEC firmware for CZ */
321 if (adev->asic_type == CHIP_CARRIZO) {
322 ret = cz_load_mec_firmware(adev);
323 if (ret) {
324 dev_err(adev->dev, "(%d) Mec Firmware load failed\n", ret);
325 return ret;
326 }
327 }
328
329 /* setup fw load flag */
330 adev->smu.fw_flags = AMDGPU_SDMA0_UCODE_LOADED |
331 AMDGPU_SDMA1_UCODE_LOADED |
332 AMDGPU_CPCE_UCODE_LOADED |
333 AMDGPU_CPPFP_UCODE_LOADED |
334 AMDGPU_CPME_UCODE_LOADED |
335 AMDGPU_CPMEC1_UCODE_LOADED |
336 AMDGPU_CPMEC2_UCODE_LOADED |
337 AMDGPU_CPRLC_UCODE_LOADED;
338
339 return ret;
340 }
341
342 static uint32_t cz_convert_fw_type(uint32_t fw_type)
343 {
344 enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
345
346 switch (fw_type) {
347 case UCODE_ID_SDMA0:
348 result = AMDGPU_UCODE_ID_SDMA0;
349 break;
350 case UCODE_ID_SDMA1:
351 result = AMDGPU_UCODE_ID_SDMA1;
352 break;
353 case UCODE_ID_CP_CE:
354 result = AMDGPU_UCODE_ID_CP_CE;
355 break;
356 case UCODE_ID_CP_PFP:
357 result = AMDGPU_UCODE_ID_CP_PFP;
358 break;
359 case UCODE_ID_CP_ME:
360 result = AMDGPU_UCODE_ID_CP_ME;
361 break;
362 case UCODE_ID_CP_MEC_JT1:
363 case UCODE_ID_CP_MEC_JT2:
364 result = AMDGPU_UCODE_ID_CP_MEC1;
365 break;
366 case UCODE_ID_RLC_G:
367 result = AMDGPU_UCODE_ID_RLC_G;
368 break;
369 default:
370 DRM_ERROR("UCode type is out of range!");
371 }
372
373 return result;
374 }
375
376 static uint8_t cz_smu_translate_firmware_enum_to_arg(
377 enum cz_scratch_entry firmware_enum)
378 {
379 uint8_t ret = 0;
380
381 switch (firmware_enum) {
382 case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0:
383 ret = UCODE_ID_SDMA0;
384 break;
385 case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1:
386 ret = UCODE_ID_SDMA1;
387 break;
388 case CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE:
389 ret = UCODE_ID_CP_CE;
390 break;
391 case CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP:
392 ret = UCODE_ID_CP_PFP;
393 break;
394 case CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME:
395 ret = UCODE_ID_CP_ME;
396 break;
397 case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1:
398 ret = UCODE_ID_CP_MEC_JT1;
399 break;
400 case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2:
401 ret = UCODE_ID_CP_MEC_JT2;
402 break;
403 case CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG:
404 ret = UCODE_ID_GMCON_RENG;
405 break;
406 case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G:
407 ret = UCODE_ID_RLC_G;
408 break;
409 case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH:
410 ret = UCODE_ID_RLC_SCRATCH;
411 break;
412 case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM:
413 ret = UCODE_ID_RLC_SRM_ARAM;
414 break;
415 case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM:
416 ret = UCODE_ID_RLC_SRM_DRAM;
417 break;
418 case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM:
419 ret = UCODE_ID_DMCU_ERAM;
420 break;
421 case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM:
422 ret = UCODE_ID_DMCU_IRAM;
423 break;
424 case CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING:
425 ret = TASK_ARG_INIT_MM_PWR_LOG;
426 break;
427 case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT:
428 case CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING:
429 case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS:
430 case CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT:
431 case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START:
432 case CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS:
433 ret = TASK_ARG_REG_MMIO;
434 break;
435 case CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE:
436 ret = TASK_ARG_INIT_CLK_TABLE;
437 break;
438 }
439
440 return ret;
441 }
442
443 static int cz_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
444 enum cz_scratch_entry firmware_enum,
445 struct cz_buffer_entry *entry)
446 {
447 uint64_t gpu_addr;
448 uint32_t data_size;
449 uint8_t ucode_id = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
450 enum AMDGPU_UCODE_ID id = cz_convert_fw_type(ucode_id);
451 struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
452 const struct gfx_firmware_header_v1_0 *header;
453
454 if (ucode->fw == NULL)
455 return -EINVAL;
456
457 gpu_addr = ucode->mc_addr;
458 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
459 data_size = le32_to_cpu(header->header.ucode_size_bytes);
460
461 if ((firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1) ||
462 (firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2)) {
463 gpu_addr += le32_to_cpu(header->jt_offset) << 2;
464 data_size = le32_to_cpu(header->jt_size) << 2;
465 }
466
467 entry->mc_addr_low = lower_32_bits(gpu_addr);
468 entry->mc_addr_high = upper_32_bits(gpu_addr);
469 entry->data_size = data_size;
470 entry->firmware_ID = firmware_enum;
471
472 return 0;
473 }
474
475 static int cz_smu_populate_single_scratch_entry(struct amdgpu_device *adev,
476 enum cz_scratch_entry scratch_type,
477 uint32_t size_in_byte,
478 struct cz_buffer_entry *entry)
479 {
480 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
481 uint64_t mc_addr = (((uint64_t) priv->smu_buffer.mc_addr_high) << 32) |
482 priv->smu_buffer.mc_addr_low;
483 mc_addr += size_in_byte;
484
485 priv->smu_buffer_used_bytes += size_in_byte;
486 entry->data_size = size_in_byte;
487 entry->kaddr = priv->smu_buffer.kaddr + priv->smu_buffer_used_bytes;
488 entry->mc_addr_low = lower_32_bits(mc_addr);
489 entry->mc_addr_high = upper_32_bits(mc_addr);
490 entry->firmware_ID = scratch_type;
491
492 return 0;
493 }
494
495 static int cz_smu_populate_single_ucode_load_task(struct amdgpu_device *adev,
496 enum cz_scratch_entry firmware_enum,
497 bool is_last)
498 {
499 uint8_t i;
500 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
501 struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
502 struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
503
504 task->type = TASK_TYPE_UCODE_LOAD;
505 task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
506 task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
507
508 for (i = 0; i < priv->driver_buffer_length; i++)
509 if (priv->driver_buffer[i].firmware_ID == firmware_enum)
510 break;
511
512 if (i >= priv->driver_buffer_length) {
513 dev_err(adev->dev, "Invalid Firmware Type\n");
514 return -EINVAL;
515 }
516
517 task->addr.low = priv->driver_buffer[i].mc_addr_low;
518 task->addr.high = priv->driver_buffer[i].mc_addr_high;
519 task->size_bytes = priv->driver_buffer[i].data_size;
520
521 return 0;
522 }
523
524 static int cz_smu_populate_single_scratch_task(struct amdgpu_device *adev,
525 enum cz_scratch_entry firmware_enum,
526 uint8_t type, bool is_last)
527 {
528 uint8_t i;
529 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
530 struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
531 struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
532
533 task->type = type;
534 task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
535 task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
536
537 for (i = 0; i < priv->scratch_buffer_length; i++)
538 if (priv->scratch_buffer[i].firmware_ID == firmware_enum)
539 break;
540
541 if (i >= priv->scratch_buffer_length) {
542 dev_err(adev->dev, "Invalid Firmware Type\n");
543 return -EINVAL;
544 }
545
546 task->addr.low = priv->scratch_buffer[i].mc_addr_low;
547 task->addr.high = priv->scratch_buffer[i].mc_addr_high;
548 task->size_bytes = priv->scratch_buffer[i].data_size;
549
550 if (CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS == firmware_enum) {
551 struct cz_ih_meta_data *pIHReg_restore =
552 (struct cz_ih_meta_data *)priv->scratch_buffer[i].kaddr;
553 pIHReg_restore->command =
554 METADATA_CMD_MODE0 | METADATA_PERFORM_ON_LOAD;
555 }
556
557 return 0;
558 }
559
560 static int cz_smu_construct_toc_for_rlc_aram_save(struct amdgpu_device *adev)
561 {
562 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
563 priv->toc_entry_aram = priv->toc_entry_used_count;
564 cz_smu_populate_single_scratch_task(adev,
565 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
566 TASK_TYPE_UCODE_SAVE, true);
567
568 return 0;
569 }
570
571 static int cz_smu_construct_toc_for_vddgfx_enter(struct amdgpu_device *adev)
572 {
573 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
574 struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
575
576 toc->JobList[JOB_GFX_SAVE] = (uint8_t)priv->toc_entry_used_count;
577 cz_smu_populate_single_scratch_task(adev,
578 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
579 TASK_TYPE_UCODE_SAVE, false);
580 cz_smu_populate_single_scratch_task(adev,
581 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
582 TASK_TYPE_UCODE_SAVE, true);
583
584 return 0;
585 }
586
587 static int cz_smu_construct_toc_for_vddgfx_exit(struct amdgpu_device *adev)
588 {
589 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
590 struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
591
592 toc->JobList[JOB_GFX_RESTORE] = (uint8_t)priv->toc_entry_used_count;
593
594 /* populate ucode */
595 if (adev->firmware.smu_load) {
596 cz_smu_populate_single_ucode_load_task(adev,
597 CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
598 cz_smu_populate_single_ucode_load_task(adev,
599 CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
600 cz_smu_populate_single_ucode_load_task(adev,
601 CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
602 cz_smu_populate_single_ucode_load_task(adev,
603 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
604 cz_smu_populate_single_ucode_load_task(adev,
605 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
606 cz_smu_populate_single_ucode_load_task(adev,
607 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, false);
608 }
609
610 /* populate scratch */
611 cz_smu_populate_single_scratch_task(adev,
612 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
613 TASK_TYPE_UCODE_LOAD, false);
614 cz_smu_populate_single_scratch_task(adev,
615 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
616 TASK_TYPE_UCODE_LOAD, false);
617 cz_smu_populate_single_scratch_task(adev,
618 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
619 TASK_TYPE_UCODE_LOAD, true);
620
621 return 0;
622 }
623
624 static int cz_smu_construct_toc_for_power_profiling(struct amdgpu_device *adev)
625 {
626 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
627
628 priv->toc_entry_power_profiling_index = priv->toc_entry_used_count;
629
630 cz_smu_populate_single_scratch_task(adev,
631 CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
632 TASK_TYPE_INITIALIZE, true);
633 return 0;
634 }
635
636 static int cz_smu_construct_toc_for_bootup(struct amdgpu_device *adev)
637 {
638 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
639
640 priv->toc_entry_initialize_index = priv->toc_entry_used_count;
641
642 if (adev->firmware.smu_load) {
643 cz_smu_populate_single_ucode_load_task(adev,
644 CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
645 cz_smu_populate_single_ucode_load_task(adev,
646 CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false);
647 cz_smu_populate_single_ucode_load_task(adev,
648 CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
649 cz_smu_populate_single_ucode_load_task(adev,
650 CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
651 cz_smu_populate_single_ucode_load_task(adev,
652 CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
653 cz_smu_populate_single_ucode_load_task(adev,
654 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
655 cz_smu_populate_single_ucode_load_task(adev,
656 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
657 cz_smu_populate_single_ucode_load_task(adev,
658 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, true);
659 }
660
661 return 0;
662 }
663
664 static int cz_smu_construct_toc_for_clock_table(struct amdgpu_device *adev)
665 {
666 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
667
668 priv->toc_entry_clock_table = priv->toc_entry_used_count;
669
670 cz_smu_populate_single_scratch_task(adev,
671 CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
672 TASK_TYPE_INITIALIZE, true);
673
674 return 0;
675 }
676
677 static int cz_smu_initialize_toc_empty_job_list(struct amdgpu_device *adev)
678 {
679 int i;
680 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
681 struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
682
683 for (i = 0; i < NUM_JOBLIST_ENTRIES; i++)
684 toc->JobList[i] = (uint8_t)IGNORE_JOB;
685
686 return 0;
687 }
688
689 /*
690 * cz smu uninitialization
691 */
692 int cz_smu_fini(struct amdgpu_device *adev)
693 {
694 amdgpu_bo_unref(&adev->smu.toc_buf);
695 amdgpu_bo_unref(&adev->smu.smu_buf);
696 kfree(adev->smu.priv);
697 adev->smu.priv = NULL;
698 if (adev->firmware.smu_load)
699 amdgpu_ucode_fini_bo(adev);
700
701 return 0;
702 }
703
704 int cz_smu_download_pptable(struct amdgpu_device *adev, void **table)
705 {
706 uint8_t i;
707 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
708
709 for (i = 0; i < priv->scratch_buffer_length; i++)
710 if (priv->scratch_buffer[i].firmware_ID ==
711 CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
712 break;
713
714 if (i >= priv->scratch_buffer_length) {
715 dev_err(adev->dev, "Invalid Scratch Type\n");
716 return -EINVAL;
717 }
718
719 *table = (struct SMU8_Fusion_ClkTable *)priv->scratch_buffer[i].kaddr;
720
721 /* prepare buffer for pptable */
722 cz_send_msg_to_smc_with_parameter(adev,
723 PPSMC_MSG_SetClkTableAddrHi,
724 priv->scratch_buffer[i].mc_addr_high);
725 cz_send_msg_to_smc_with_parameter(adev,
726 PPSMC_MSG_SetClkTableAddrLo,
727 priv->scratch_buffer[i].mc_addr_low);
728 cz_send_msg_to_smc_with_parameter(adev,
729 PPSMC_MSG_ExecuteJob,
730 priv->toc_entry_clock_table);
731
732 /* actual downloading */
733 cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToDram);
734
735 return 0;
736 }
737
738 int cz_smu_upload_pptable(struct amdgpu_device *adev)
739 {
740 uint8_t i;
741 struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
742
743 for (i = 0; i < priv->scratch_buffer_length; i++)
744 if (priv->scratch_buffer[i].firmware_ID ==
745 CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
746 break;
747
748 if (i >= priv->scratch_buffer_length) {
749 dev_err(adev->dev, "Invalid Scratch Type\n");
750 return -EINVAL;
751 }
752
753 /* prepare SMU */
754 cz_send_msg_to_smc_with_parameter(adev,
755 PPSMC_MSG_SetClkTableAddrHi,
756 priv->scratch_buffer[i].mc_addr_high);
757 cz_send_msg_to_smc_with_parameter(adev,
758 PPSMC_MSG_SetClkTableAddrLo,
759 priv->scratch_buffer[i].mc_addr_low);
760 cz_send_msg_to_smc_with_parameter(adev,
761 PPSMC_MSG_ExecuteJob,
762 priv->toc_entry_clock_table);
763
764 /* actual uploading */
765 cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToSmu);
766
767 return 0;
768 }
769
770 /*
771 * cz smumgr functions initialization
772 */
773 static const struct amdgpu_smumgr_funcs cz_smumgr_funcs = {
774 .check_fw_load_finish = cz_smu_check_finished,
775 .request_smu_load_fw = NULL,
776 .request_smu_specific_fw = NULL,
777 };
778
779 /*
780 * cz smu initialization
781 */
782 int cz_smu_init(struct amdgpu_device *adev)
783 {
784 int ret = -EINVAL;
785 uint64_t mc_addr = 0;
786 struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
787 struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
788 void *toc_buf_ptr = NULL;
789 void *smu_buf_ptr = NULL;
790
791 struct cz_smu_private_data *priv =
792 kzalloc(sizeof(struct cz_smu_private_data), GFP_KERNEL);
793 if (priv == NULL)
794 return -ENOMEM;
795
796 /* allocate firmware buffers */
797 if (adev->firmware.smu_load)
798 amdgpu_ucode_init_bo(adev);
799
800 adev->smu.priv = priv;
801 adev->smu.fw_flags = 0;
802 priv->toc_buffer.data_size = 4096;
803
804 priv->smu_buffer.data_size =
805 ALIGN(UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 32) +
806 ALIGN(UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 32) +
807 ALIGN(UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 32) +
808 ALIGN(sizeof(struct SMU8_MultimediaPowerLogData), 32) +
809 ALIGN(sizeof(struct SMU8_Fusion_ClkTable), 32);
810
811 /* prepare toc buffer and smu buffer:
812 * 1. create amdgpu_bo for toc buffer and smu buffer
813 * 2. pin mc address
814 * 3. map kernel virtual address
815 */
816 ret = amdgpu_bo_create(adev, priv->toc_buffer.data_size, PAGE_SIZE,
817 true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
818 toc_buf);
819
820 if (ret) {
821 dev_err(adev->dev, "(%d) SMC TOC buffer allocation failed\n", ret);
822 return ret;
823 }
824
825 ret = amdgpu_bo_create(adev, priv->smu_buffer.data_size, PAGE_SIZE,
826 true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
827 smu_buf);
828
829 if (ret) {
830 dev_err(adev->dev, "(%d) SMC Internal buffer allocation failed\n", ret);
831 return ret;
832 }
833
834 /* toc buffer reserve/pin/map */
835 ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
836 if (ret) {
837 amdgpu_bo_unref(&adev->smu.toc_buf);
838 dev_err(adev->dev, "(%d) SMC TOC buffer reserve failed\n", ret);
839 return ret;
840 }
841
842 ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
843 if (ret) {
844 amdgpu_bo_unreserve(adev->smu.toc_buf);
845 amdgpu_bo_unref(&adev->smu.toc_buf);
846 dev_err(adev->dev, "(%d) SMC TOC buffer pin failed\n", ret);
847 return ret;
848 }
849
850 ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
851 if (ret)
852 goto smu_init_failed;
853
854 amdgpu_bo_unreserve(adev->smu.toc_buf);
855
856 priv->toc_buffer.mc_addr_low = lower_32_bits(mc_addr);
857 priv->toc_buffer.mc_addr_high = upper_32_bits(mc_addr);
858 priv->toc_buffer.kaddr = toc_buf_ptr;
859
860 /* smu buffer reserve/pin/map */
861 ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
862 if (ret) {
863 amdgpu_bo_unref(&adev->smu.smu_buf);
864 dev_err(adev->dev, "(%d) SMC Internal buffer reserve failed\n", ret);
865 return ret;
866 }
867
868 ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
869 if (ret) {
870 amdgpu_bo_unreserve(adev->smu.smu_buf);
871 amdgpu_bo_unref(&adev->smu.smu_buf);
872 dev_err(adev->dev, "(%d) SMC Internal buffer pin failed\n", ret);
873 return ret;
874 }
875
876 ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
877 if (ret)
878 goto smu_init_failed;
879
880 amdgpu_bo_unreserve(adev->smu.smu_buf);
881
882 priv->smu_buffer.mc_addr_low = lower_32_bits(mc_addr);
883 priv->smu_buffer.mc_addr_high = upper_32_bits(mc_addr);
884 priv->smu_buffer.kaddr = smu_buf_ptr;
885
886 if (adev->firmware.smu_load) {
887 if (cz_smu_populate_single_firmware_entry(adev,
888 CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
889 &priv->driver_buffer[priv->driver_buffer_length++]))
890 goto smu_init_failed;
891 if (cz_smu_populate_single_firmware_entry(adev,
892 CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
893 &priv->driver_buffer[priv->driver_buffer_length++]))
894 goto smu_init_failed;
895 if (cz_smu_populate_single_firmware_entry(adev,
896 CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
897 &priv->driver_buffer[priv->driver_buffer_length++]))
898 goto smu_init_failed;
899 if (cz_smu_populate_single_firmware_entry(adev,
900 CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
901 &priv->driver_buffer[priv->driver_buffer_length++]))
902 goto smu_init_failed;
903 if (cz_smu_populate_single_firmware_entry(adev,
904 CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
905 &priv->driver_buffer[priv->driver_buffer_length++]))
906 goto smu_init_failed;
907 if (cz_smu_populate_single_firmware_entry(adev,
908 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
909 &priv->driver_buffer[priv->driver_buffer_length++]))
910 goto smu_init_failed;
911 if (cz_smu_populate_single_firmware_entry(adev,
912 CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
913 &priv->driver_buffer[priv->driver_buffer_length++]))
914 goto smu_init_failed;
915 if (cz_smu_populate_single_firmware_entry(adev,
916 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
917 &priv->driver_buffer[priv->driver_buffer_length++]))
918 goto smu_init_failed;
919 }
920
921 if (cz_smu_populate_single_scratch_entry(adev,
922 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
923 UCODE_ID_RLC_SCRATCH_SIZE_BYTE,
924 &priv->scratch_buffer[priv->scratch_buffer_length++]))
925 goto smu_init_failed;
926 if (cz_smu_populate_single_scratch_entry(adev,
927 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
928 UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE,
929 &priv->scratch_buffer[priv->scratch_buffer_length++]))
930 goto smu_init_failed;
931 if (cz_smu_populate_single_scratch_entry(adev,
932 CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
933 UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE,
934 &priv->scratch_buffer[priv->scratch_buffer_length++]))
935 goto smu_init_failed;
936 if (cz_smu_populate_single_scratch_entry(adev,
937 CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
938 sizeof(struct SMU8_MultimediaPowerLogData),
939 &priv->scratch_buffer[priv->scratch_buffer_length++]))
940 goto smu_init_failed;
941 if (cz_smu_populate_single_scratch_entry(adev,
942 CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
943 sizeof(struct SMU8_Fusion_ClkTable),
944 &priv->scratch_buffer[priv->scratch_buffer_length++]))
945 goto smu_init_failed;
946
947 cz_smu_initialize_toc_empty_job_list(adev);
948 cz_smu_construct_toc_for_rlc_aram_save(adev);
949 cz_smu_construct_toc_for_vddgfx_enter(adev);
950 cz_smu_construct_toc_for_vddgfx_exit(adev);
951 cz_smu_construct_toc_for_power_profiling(adev);
952 cz_smu_construct_toc_for_bootup(adev);
953 cz_smu_construct_toc_for_clock_table(adev);
954 /* init the smumgr functions */
955 adev->smu.smumgr_funcs = &cz_smumgr_funcs;
956
957 return 0;
958
959 smu_init_failed:
960 amdgpu_bo_unref(toc_buf);
961 amdgpu_bo_unref(smu_buf);
962
963 return ret;
964 }
This page took 0.058258 seconds and 5 git commands to generate.