1 /* $NetBSD: amdgpu_smu8_smumgr.c,v 1.3 2021/12/19 12:21:30 riastradh Exp $ */ 2 3 /* 4 * Copyright 2015 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: amdgpu_smu8_smumgr.c,v 1.3 2021/12/19 12:21:30 riastradh Exp $"); 28 29 #include <linux/delay.h> 30 #include <linux/gfp.h> 31 #include <linux/kernel.h> 32 #include <linux/ktime.h> 33 #include <linux/slab.h> 34 #include <linux/types.h> 35 36 #include "cgs_common.h" 37 #include "smu/smu_8_0_d.h" 38 #include "smu/smu_8_0_sh_mask.h" 39 #include "smu8.h" 40 #include "smu8_fusion.h" 41 #include "smu8_smumgr.h" 42 #include "cz_ppsmc.h" 43 #include "smu_ucode_xfer_cz.h" 44 #include "gca/gfx_8_0_d.h" 45 #include "gca/gfx_8_0_sh_mask.h" 46 #include "smumgr.h" 47 48 #include <linux/nbsd-namespace.h> 49 50 #define SIZE_ALIGN_32(x) (((x) + 31) / 32 * 32) 51 52 static const enum smu8_scratch_entry firmware_list[] = { 53 SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA0, 54 SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA1, 55 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_CE, 56 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_PFP, 57 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_ME, 58 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, 59 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, 60 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G, 61 }; 62 63 static uint32_t smu8_get_argument(struct pp_hwmgr *hwmgr) 64 { 65 if (hwmgr == NULL || hwmgr->device == NULL) 66 return 0; 67 68 return cgs_read_register(hwmgr->device, 69 mmSMU_MP1_SRBM2P_ARG_0); 70 } 71 72 /* Send a message to the SMC, and wait for its response.*/ 73 static int smu8_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, 74 uint16_t msg, uint32_t parameter) 75 { 76 int result = 0; 77 ktime_t t_start; 78 s64 elapsed_us; 79 80 if (hwmgr == NULL || hwmgr->device == NULL) 81 return -EINVAL; 82 83 result = PHM_WAIT_FIELD_UNEQUAL(hwmgr, 84 SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); 85 if (result != 0) { 86 /* Read the last message to SMU, to report actual cause */ 87 uint32_t val = cgs_read_register(hwmgr->device, 88 mmSMU_MP1_SRBM2P_MSG_0); 89 pr_err("%s(0x%04x) aborted; SMU still servicing msg (0x%04x)\n", 90 __func__, msg, val); 91 return result; 92 } 93 t_start = ktime_get(); 94 95 cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0, parameter); 96 97 cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_RESP_0, 0); 98 cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_MSG_0, msg); 99 100 result = PHM_WAIT_FIELD_UNEQUAL(hwmgr, 101 SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); 102 103 elapsed_us = ktime_us_delta(ktime_get(), t_start); 104 105 WARN(result, "%s(0x%04x, %#x) timed out after %"PRId64" us\n", 106 __func__, msg, parameter, elapsed_us); 107 108 return result; 109 } 110 111 static int smu8_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) 112 { 113 return smu8_send_msg_to_smc_with_parameter(hwmgr, msg, 0); 114 } 115 116 static int smu8_set_smc_sram_address(struct pp_hwmgr *hwmgr, 117 uint32_t smc_address, uint32_t limit) 118 { 119 if (hwmgr == NULL || hwmgr->device == NULL) 120 return -EINVAL; 121 122 if (0 != (3 & smc_address)) { 123 pr_err("SMC address must be 4 byte aligned\n"); 124 return -EINVAL; 125 } 126 127 if (limit <= (smc_address + 3)) { 128 pr_err("SMC address beyond the SMC RAM area\n"); 129 return -EINVAL; 130 } 131 132 cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX_0, 133 SMN_MP1_SRAM_START_ADDR + smc_address); 134 135 return 0; 136 } 137 138 static int smu8_write_smc_sram_dword(struct pp_hwmgr *hwmgr, 139 uint32_t smc_address, uint32_t value, uint32_t limit) 140 { 141 int result; 142 143 if (hwmgr == NULL || hwmgr->device == NULL) 144 return -EINVAL; 145 146 result = smu8_set_smc_sram_address(hwmgr, smc_address, limit); 147 if (!result) 148 cgs_write_register(hwmgr->device, mmMP0PUB_IND_DATA_0, value); 149 150 return result; 151 } 152 153 static int smu8_check_fw_load_finish(struct pp_hwmgr *hwmgr, 154 uint32_t firmware) 155 { 156 int i; 157 uint32_t index = SMN_MP1_SRAM_START_ADDR + 158 SMU8_FIRMWARE_HEADER_LOCATION + 159 offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus); 160 161 if (hwmgr == NULL || hwmgr->device == NULL) 162 return -EINVAL; 163 164 cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); 165 166 for (i = 0; i < hwmgr->usec_timeout; i++) { 167 if (firmware == 168 (cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA) & firmware)) 169 break; 170 udelay(1); 171 } 172 173 if (i >= hwmgr->usec_timeout) { 174 pr_err("SMU check loaded firmware failed.\n"); 175 return -EINVAL; 176 } 177 178 return 0; 179 } 180 181 static int smu8_load_mec_firmware(struct pp_hwmgr *hwmgr) 182 { 183 uint32_t reg_data; 184 uint32_t tmp; 185 int ret = 0; 186 struct cgs_firmware_info info = {0}; 187 188 if (hwmgr == NULL || hwmgr->device == NULL) 189 return -EINVAL; 190 191 ret = cgs_get_firmware_info(hwmgr->device, 192 CGS_UCODE_ID_CP_MEC, &info); 193 194 if (ret) 195 return -EINVAL; 196 197 /* Disable MEC parsing/prefetching */ 198 tmp = cgs_read_register(hwmgr->device, 199 mmCP_MEC_CNTL); 200 tmp = PHM_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1); 201 tmp = PHM_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1); 202 cgs_write_register(hwmgr->device, mmCP_MEC_CNTL, tmp); 203 204 tmp = cgs_read_register(hwmgr->device, 205 mmCP_CPC_IC_BASE_CNTL); 206 207 tmp = PHM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0); 208 tmp = PHM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, ATC, 0); 209 tmp = PHM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0); 210 tmp = PHM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, MTYPE, 1); 211 cgs_write_register(hwmgr->device, mmCP_CPC_IC_BASE_CNTL, tmp); 212 213 reg_data = lower_32_bits(info.mc_addr) & 214 PHM_FIELD_MASK(CP_CPC_IC_BASE_LO, IC_BASE_LO); 215 cgs_write_register(hwmgr->device, mmCP_CPC_IC_BASE_LO, reg_data); 216 217 reg_data = upper_32_bits(info.mc_addr) & 218 PHM_FIELD_MASK(CP_CPC_IC_BASE_HI, IC_BASE_HI); 219 cgs_write_register(hwmgr->device, mmCP_CPC_IC_BASE_HI, reg_data); 220 221 return 0; 222 } 223 224 static uint8_t smu8_translate_firmware_enum_to_arg(struct pp_hwmgr *hwmgr, 225 enum smu8_scratch_entry firmware_enum) 226 { 227 uint8_t ret = 0; 228 229 switch (firmware_enum) { 230 case SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA0: 231 ret = UCODE_ID_SDMA0; 232 break; 233 case SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA1: 234 if (hwmgr->chip_id == CHIP_STONEY) 235 ret = UCODE_ID_SDMA0; 236 else 237 ret = UCODE_ID_SDMA1; 238 break; 239 case SMU8_SCRATCH_ENTRY_UCODE_ID_CP_CE: 240 ret = UCODE_ID_CP_CE; 241 break; 242 case SMU8_SCRATCH_ENTRY_UCODE_ID_CP_PFP: 243 ret = UCODE_ID_CP_PFP; 244 break; 245 case SMU8_SCRATCH_ENTRY_UCODE_ID_CP_ME: 246 ret = UCODE_ID_CP_ME; 247 break; 248 case SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1: 249 ret = UCODE_ID_CP_MEC_JT1; 250 break; 251 case SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2: 252 if (hwmgr->chip_id == CHIP_STONEY) 253 ret = UCODE_ID_CP_MEC_JT1; 254 else 255 ret = UCODE_ID_CP_MEC_JT2; 256 break; 257 case SMU8_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG: 258 ret = UCODE_ID_GMCON_RENG; 259 break; 260 case SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G: 261 ret = UCODE_ID_RLC_G; 262 break; 263 case SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH: 264 ret = UCODE_ID_RLC_SCRATCH; 265 break; 266 case SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM: 267 ret = UCODE_ID_RLC_SRM_ARAM; 268 break; 269 case SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM: 270 ret = UCODE_ID_RLC_SRM_DRAM; 271 break; 272 case SMU8_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM: 273 ret = UCODE_ID_DMCU_ERAM; 274 break; 275 case SMU8_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM: 276 ret = UCODE_ID_DMCU_IRAM; 277 break; 278 case SMU8_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING: 279 ret = TASK_ARG_INIT_MM_PWR_LOG; 280 break; 281 case SMU8_SCRATCH_ENTRY_DATA_ID_SDMA_HALT: 282 case SMU8_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING: 283 case SMU8_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS: 284 case SMU8_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT: 285 case SMU8_SCRATCH_ENTRY_DATA_ID_SDMA_START: 286 case SMU8_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS: 287 ret = TASK_ARG_REG_MMIO; 288 break; 289 case SMU8_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE: 290 ret = TASK_ARG_INIT_CLK_TABLE; 291 break; 292 } 293 294 return ret; 295 } 296 297 static enum cgs_ucode_id smu8_convert_fw_type_to_cgs(uint32_t fw_type) 298 { 299 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; 300 301 switch (fw_type) { 302 case UCODE_ID_SDMA0: 303 result = CGS_UCODE_ID_SDMA0; 304 break; 305 case UCODE_ID_SDMA1: 306 result = CGS_UCODE_ID_SDMA1; 307 break; 308 case UCODE_ID_CP_CE: 309 result = CGS_UCODE_ID_CP_CE; 310 break; 311 case UCODE_ID_CP_PFP: 312 result = CGS_UCODE_ID_CP_PFP; 313 break; 314 case UCODE_ID_CP_ME: 315 result = CGS_UCODE_ID_CP_ME; 316 break; 317 case UCODE_ID_CP_MEC_JT1: 318 result = CGS_UCODE_ID_CP_MEC_JT1; 319 break; 320 case UCODE_ID_CP_MEC_JT2: 321 result = CGS_UCODE_ID_CP_MEC_JT2; 322 break; 323 case UCODE_ID_RLC_G: 324 result = CGS_UCODE_ID_RLC_G; 325 break; 326 default: 327 break; 328 } 329 330 return result; 331 } 332 333 static int smu8_smu_populate_single_scratch_task( 334 struct pp_hwmgr *hwmgr, 335 enum smu8_scratch_entry fw_enum, 336 uint8_t type, bool is_last) 337 { 338 uint8_t i; 339 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 340 struct TOC *toc = (struct TOC *)smu8_smu->toc_buffer.kaddr; 341 struct SMU_Task *task = &toc->tasks[smu8_smu->toc_entry_used_count++]; 342 343 task->type = type; 344 task->arg = smu8_translate_firmware_enum_to_arg(hwmgr, fw_enum); 345 task->next = is_last ? END_OF_TASK_LIST : smu8_smu->toc_entry_used_count; 346 347 for (i = 0; i < smu8_smu->scratch_buffer_length; i++) 348 if (smu8_smu->scratch_buffer[i].firmware_ID == fw_enum) 349 break; 350 351 if (i >= smu8_smu->scratch_buffer_length) { 352 pr_err("Invalid Firmware Type\n"); 353 return -EINVAL; 354 } 355 356 task->addr.low = lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr); 357 task->addr.high = upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr); 358 task->size_bytes = smu8_smu->scratch_buffer[i].data_size; 359 360 if (SMU8_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS == fw_enum) { 361 struct smu8_ih_meta_data *pIHReg_restore = 362 (struct smu8_ih_meta_data *)smu8_smu->scratch_buffer[i].kaddr; 363 pIHReg_restore->command = 364 METADATA_CMD_MODE0 | METADATA_PERFORM_ON_LOAD; 365 } 366 367 return 0; 368 } 369 370 static int smu8_smu_populate_single_ucode_load_task( 371 struct pp_hwmgr *hwmgr, 372 enum smu8_scratch_entry fw_enum, 373 bool is_last) 374 { 375 uint8_t i; 376 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 377 struct TOC *toc = (struct TOC *)smu8_smu->toc_buffer.kaddr; 378 struct SMU_Task *task = &toc->tasks[smu8_smu->toc_entry_used_count++]; 379 380 task->type = TASK_TYPE_UCODE_LOAD; 381 task->arg = smu8_translate_firmware_enum_to_arg(hwmgr, fw_enum); 382 task->next = is_last ? END_OF_TASK_LIST : smu8_smu->toc_entry_used_count; 383 384 for (i = 0; i < smu8_smu->driver_buffer_length; i++) 385 if (smu8_smu->driver_buffer[i].firmware_ID == fw_enum) 386 break; 387 388 if (i >= smu8_smu->driver_buffer_length) { 389 pr_err("Invalid Firmware Type\n"); 390 return -EINVAL; 391 } 392 393 task->addr.low = lower_32_bits(smu8_smu->driver_buffer[i].mc_addr); 394 task->addr.high = upper_32_bits(smu8_smu->driver_buffer[i].mc_addr); 395 task->size_bytes = smu8_smu->driver_buffer[i].data_size; 396 397 return 0; 398 } 399 400 static int smu8_smu_construct_toc_for_rlc_aram_save(struct pp_hwmgr *hwmgr) 401 { 402 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 403 404 smu8_smu->toc_entry_aram = smu8_smu->toc_entry_used_count; 405 smu8_smu_populate_single_scratch_task(hwmgr, 406 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM, 407 TASK_TYPE_UCODE_SAVE, true); 408 409 return 0; 410 } 411 412 static int smu8_smu_initialize_toc_empty_job_list(struct pp_hwmgr *hwmgr) 413 { 414 int i; 415 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 416 struct TOC *toc = (struct TOC *)smu8_smu->toc_buffer.kaddr; 417 418 for (i = 0; i < NUM_JOBLIST_ENTRIES; i++) 419 toc->JobList[i] = (uint8_t)IGNORE_JOB; 420 421 return 0; 422 } 423 424 static int smu8_smu_construct_toc_for_vddgfx_enter(struct pp_hwmgr *hwmgr) 425 { 426 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 427 struct TOC *toc = (struct TOC *)smu8_smu->toc_buffer.kaddr; 428 429 toc->JobList[JOB_GFX_SAVE] = (uint8_t)smu8_smu->toc_entry_used_count; 430 smu8_smu_populate_single_scratch_task(hwmgr, 431 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH, 432 TASK_TYPE_UCODE_SAVE, false); 433 434 smu8_smu_populate_single_scratch_task(hwmgr, 435 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM, 436 TASK_TYPE_UCODE_SAVE, true); 437 438 return 0; 439 } 440 441 442 static int smu8_smu_construct_toc_for_vddgfx_exit(struct pp_hwmgr *hwmgr) 443 { 444 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 445 struct TOC *toc = (struct TOC *)smu8_smu->toc_buffer.kaddr; 446 447 toc->JobList[JOB_GFX_RESTORE] = (uint8_t)smu8_smu->toc_entry_used_count; 448 449 smu8_smu_populate_single_ucode_load_task(hwmgr, 450 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_CE, false); 451 smu8_smu_populate_single_ucode_load_task(hwmgr, 452 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false); 453 smu8_smu_populate_single_ucode_load_task(hwmgr, 454 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_ME, false); 455 smu8_smu_populate_single_ucode_load_task(hwmgr, 456 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); 457 458 if (hwmgr->chip_id == CHIP_STONEY) 459 smu8_smu_populate_single_ucode_load_task(hwmgr, 460 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); 461 else 462 smu8_smu_populate_single_ucode_load_task(hwmgr, 463 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false); 464 465 smu8_smu_populate_single_ucode_load_task(hwmgr, 466 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G, false); 467 468 /* populate scratch */ 469 smu8_smu_populate_single_scratch_task(hwmgr, 470 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH, 471 TASK_TYPE_UCODE_LOAD, false); 472 473 smu8_smu_populate_single_scratch_task(hwmgr, 474 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM, 475 TASK_TYPE_UCODE_LOAD, false); 476 477 smu8_smu_populate_single_scratch_task(hwmgr, 478 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM, 479 TASK_TYPE_UCODE_LOAD, true); 480 481 return 0; 482 } 483 484 static int smu8_smu_construct_toc_for_power_profiling(struct pp_hwmgr *hwmgr) 485 { 486 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 487 488 smu8_smu->toc_entry_power_profiling_index = smu8_smu->toc_entry_used_count; 489 490 smu8_smu_populate_single_scratch_task(hwmgr, 491 SMU8_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING, 492 TASK_TYPE_INITIALIZE, true); 493 return 0; 494 } 495 496 static int smu8_smu_construct_toc_for_bootup(struct pp_hwmgr *hwmgr) 497 { 498 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 499 500 smu8_smu->toc_entry_initialize_index = smu8_smu->toc_entry_used_count; 501 502 smu8_smu_populate_single_ucode_load_task(hwmgr, 503 SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA0, false); 504 if (hwmgr->chip_id != CHIP_STONEY) 505 smu8_smu_populate_single_ucode_load_task(hwmgr, 506 SMU8_SCRATCH_ENTRY_UCODE_ID_SDMA1, false); 507 smu8_smu_populate_single_ucode_load_task(hwmgr, 508 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_CE, false); 509 smu8_smu_populate_single_ucode_load_task(hwmgr, 510 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false); 511 smu8_smu_populate_single_ucode_load_task(hwmgr, 512 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_ME, false); 513 smu8_smu_populate_single_ucode_load_task(hwmgr, 514 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); 515 if (hwmgr->chip_id != CHIP_STONEY) 516 smu8_smu_populate_single_ucode_load_task(hwmgr, 517 SMU8_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false); 518 smu8_smu_populate_single_ucode_load_task(hwmgr, 519 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G, true); 520 521 return 0; 522 } 523 524 static int smu8_smu_construct_toc_for_clock_table(struct pp_hwmgr *hwmgr) 525 { 526 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 527 528 smu8_smu->toc_entry_clock_table = smu8_smu->toc_entry_used_count; 529 530 smu8_smu_populate_single_scratch_task(hwmgr, 531 SMU8_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE, 532 TASK_TYPE_INITIALIZE, true); 533 534 return 0; 535 } 536 537 static int smu8_smu_construct_toc(struct pp_hwmgr *hwmgr) 538 { 539 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 540 541 smu8_smu->toc_entry_used_count = 0; 542 smu8_smu_initialize_toc_empty_job_list(hwmgr); 543 smu8_smu_construct_toc_for_rlc_aram_save(hwmgr); 544 smu8_smu_construct_toc_for_vddgfx_enter(hwmgr); 545 smu8_smu_construct_toc_for_vddgfx_exit(hwmgr); 546 smu8_smu_construct_toc_for_power_profiling(hwmgr); 547 smu8_smu_construct_toc_for_bootup(hwmgr); 548 smu8_smu_construct_toc_for_clock_table(hwmgr); 549 550 return 0; 551 } 552 553 static int smu8_smu_populate_firmware_entries(struct pp_hwmgr *hwmgr) 554 { 555 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 556 uint32_t firmware_type; 557 uint32_t i; 558 int ret; 559 enum cgs_ucode_id ucode_id; 560 struct cgs_firmware_info info = {0}; 561 562 smu8_smu->driver_buffer_length = 0; 563 564 for (i = 0; i < ARRAY_SIZE(firmware_list); i++) { 565 566 firmware_type = smu8_translate_firmware_enum_to_arg(hwmgr, 567 firmware_list[i]); 568 569 ucode_id = smu8_convert_fw_type_to_cgs(firmware_type); 570 571 ret = cgs_get_firmware_info(hwmgr->device, 572 ucode_id, &info); 573 574 if (ret == 0) { 575 smu8_smu->driver_buffer[i].mc_addr = info.mc_addr; 576 577 smu8_smu->driver_buffer[i].data_size = info.image_size; 578 579 smu8_smu->driver_buffer[i].firmware_ID = firmware_list[i]; 580 smu8_smu->driver_buffer_length++; 581 } 582 } 583 584 return 0; 585 } 586 587 static int smu8_smu_populate_single_scratch_entry( 588 struct pp_hwmgr *hwmgr, 589 enum smu8_scratch_entry scratch_type, 590 uint32_t ulsize_byte, 591 struct smu8_buffer_entry *entry) 592 { 593 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 594 uint32_t ulsize_aligned = SIZE_ALIGN_32(ulsize_byte); 595 596 entry->data_size = ulsize_byte; 597 entry->kaddr = (char *) smu8_smu->smu_buffer.kaddr + 598 smu8_smu->smu_buffer_used_bytes; 599 entry->mc_addr = smu8_smu->smu_buffer.mc_addr + smu8_smu->smu_buffer_used_bytes; 600 entry->firmware_ID = scratch_type; 601 602 smu8_smu->smu_buffer_used_bytes += ulsize_aligned; 603 604 return 0; 605 } 606 607 static int smu8_download_pptable_settings(struct pp_hwmgr *hwmgr, void **table) 608 { 609 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 610 unsigned long i; 611 612 for (i = 0; i < smu8_smu->scratch_buffer_length; i++) { 613 if (smu8_smu->scratch_buffer[i].firmware_ID 614 == SMU8_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE) 615 break; 616 } 617 618 *table = (struct SMU8_Fusion_ClkTable *)smu8_smu->scratch_buffer[i].kaddr; 619 620 smu8_send_msg_to_smc_with_parameter(hwmgr, 621 PPSMC_MSG_SetClkTableAddrHi, 622 upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr)); 623 624 smu8_send_msg_to_smc_with_parameter(hwmgr, 625 PPSMC_MSG_SetClkTableAddrLo, 626 lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr)); 627 628 smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob, 629 smu8_smu->toc_entry_clock_table); 630 631 smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToDram); 632 633 return 0; 634 } 635 636 static int smu8_upload_pptable_settings(struct pp_hwmgr *hwmgr) 637 { 638 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 639 unsigned long i; 640 641 for (i = 0; i < smu8_smu->scratch_buffer_length; i++) { 642 if (smu8_smu->scratch_buffer[i].firmware_ID 643 == SMU8_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE) 644 break; 645 } 646 647 smu8_send_msg_to_smc_with_parameter(hwmgr, 648 PPSMC_MSG_SetClkTableAddrHi, 649 upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr)); 650 651 smu8_send_msg_to_smc_with_parameter(hwmgr, 652 PPSMC_MSG_SetClkTableAddrLo, 653 lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr)); 654 655 smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob, 656 smu8_smu->toc_entry_clock_table); 657 658 smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToSmu); 659 660 return 0; 661 } 662 663 static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr) 664 { 665 struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; 666 uint32_t smc_address; 667 uint32_t fw_to_check = 0; 668 int ret; 669 670 amdgpu_ucode_init_bo(hwmgr->adev); 671 672 smu8_smu_populate_firmware_entries(hwmgr); 673 674 smu8_smu_construct_toc(hwmgr); 675 676 smc_address = SMU8_FIRMWARE_HEADER_LOCATION + 677 offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus); 678 679 smu8_write_smc_sram_dword(hwmgr, smc_address, 0, smc_address+4); 680 681 smu8_send_msg_to_smc_with_parameter(hwmgr, 682 PPSMC_MSG_DriverDramAddrHi, 683 upper_32_bits(smu8_smu->toc_buffer.mc_addr)); 684 685 smu8_send_msg_to_smc_with_parameter(hwmgr, 686 PPSMC_MSG_DriverDramAddrLo, 687 lower_32_bits(smu8_smu->toc_buffer.mc_addr)); 688 689 smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_InitJobs); 690 691 smu8_send_msg_to_smc_with_parameter(hwmgr, 692 PPSMC_MSG_ExecuteJob, 693 smu8_smu->toc_entry_aram); 694 smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob, 695 smu8_smu->toc_entry_power_profiling_index); 696 697 smu8_send_msg_to_smc_with_parameter(hwmgr, 698 PPSMC_MSG_ExecuteJob, 699 smu8_smu->toc_entry_initialize_index); 700 701 fw_to_check = UCODE_ID_RLC_G_MASK | 702 UCODE_ID_SDMA0_MASK | 703 UCODE_ID_SDMA1_MASK | 704 UCODE_ID_CP_CE_MASK | 705 UCODE_ID_CP_ME_MASK | 706 UCODE_ID_CP_PFP_MASK | 707 UCODE_ID_CP_MEC_JT1_MASK | 708 UCODE_ID_CP_MEC_JT2_MASK; 709 710 if (hwmgr->chip_id == CHIP_STONEY) 711 fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK); 712 713 ret = smu8_check_fw_load_finish(hwmgr, fw_to_check); 714 if (ret) { 715 pr_err("SMU firmware load failed\n"); 716 return ret; 717 } 718 719 ret = smu8_load_mec_firmware(hwmgr); 720 if (ret) { 721 pr_err("Mec Firmware load failed\n"); 722 return ret; 723 } 724 725 return 0; 726 } 727 728 static int smu8_start_smu(struct pp_hwmgr *hwmgr) 729 { 730 struct amdgpu_device *adev; 731 732 uint32_t index = SMN_MP1_SRAM_START_ADDR + 733 SMU8_FIRMWARE_HEADER_LOCATION + 734 offsetof(struct SMU8_Firmware_Header, Version); 735 736 if (hwmgr == NULL || hwmgr->device == NULL) 737 return -EINVAL; 738 739 adev = hwmgr->adev; 740 741 cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); 742 hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA); 743 pr_info("smu version %02d.%02d.%02d\n", 744 ((hwmgr->smu_version >> 16) & 0xFF), 745 ((hwmgr->smu_version >> 8) & 0xFF), 746 (hwmgr->smu_version & 0xFF)); 747 adev->pm.fw_version = hwmgr->smu_version >> 8; 748 749 return smu8_request_smu_load_fw(hwmgr); 750 } 751 752 static int smu8_smu_init(struct pp_hwmgr *hwmgr) 753 { 754 int ret = 0; 755 struct smu8_smumgr *smu8_smu; 756 757 smu8_smu = kzalloc(sizeof(struct smu8_smumgr), GFP_KERNEL); 758 if (smu8_smu == NULL) 759 return -ENOMEM; 760 761 hwmgr->smu_backend = smu8_smu; 762 763 smu8_smu->toc_buffer.data_size = 4096; 764 smu8_smu->smu_buffer.data_size = 765 ALIGN(UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 32) + 766 ALIGN(UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 32) + 767 ALIGN(UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 32) + 768 ALIGN(sizeof(struct SMU8_MultimediaPowerLogData), 32) + 769 ALIGN(sizeof(struct SMU8_Fusion_ClkTable), 32); 770 771 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, 772 smu8_smu->toc_buffer.data_size, 773 PAGE_SIZE, 774 AMDGPU_GEM_DOMAIN_VRAM, 775 &smu8_smu->toc_buffer.handle, 776 &smu8_smu->toc_buffer.mc_addr, 777 &smu8_smu->toc_buffer.kaddr); 778 if (ret) 779 goto err2; 780 781 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, 782 smu8_smu->smu_buffer.data_size, 783 PAGE_SIZE, 784 AMDGPU_GEM_DOMAIN_VRAM, 785 &smu8_smu->smu_buffer.handle, 786 &smu8_smu->smu_buffer.mc_addr, 787 &smu8_smu->smu_buffer.kaddr); 788 if (ret) 789 goto err1; 790 791 if (0 != smu8_smu_populate_single_scratch_entry(hwmgr, 792 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH, 793 UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 794 &smu8_smu->scratch_buffer[smu8_smu->scratch_buffer_length++])) { 795 pr_err("Error when Populate Firmware Entry.\n"); 796 goto err0; 797 } 798 799 if (0 != smu8_smu_populate_single_scratch_entry(hwmgr, 800 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM, 801 UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 802 &smu8_smu->scratch_buffer[smu8_smu->scratch_buffer_length++])) { 803 pr_err("Error when Populate Firmware Entry.\n"); 804 goto err0; 805 } 806 if (0 != smu8_smu_populate_single_scratch_entry(hwmgr, 807 SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM, 808 UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 809 &smu8_smu->scratch_buffer[smu8_smu->scratch_buffer_length++])) { 810 pr_err("Error when Populate Firmware Entry.\n"); 811 goto err0; 812 } 813 814 if (0 != smu8_smu_populate_single_scratch_entry(hwmgr, 815 SMU8_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING, 816 sizeof(struct SMU8_MultimediaPowerLogData), 817 &smu8_smu->scratch_buffer[smu8_smu->scratch_buffer_length++])) { 818 pr_err("Error when Populate Firmware Entry.\n"); 819 goto err0; 820 } 821 822 if (0 != smu8_smu_populate_single_scratch_entry(hwmgr, 823 SMU8_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE, 824 sizeof(struct SMU8_Fusion_ClkTable), 825 &smu8_smu->scratch_buffer[smu8_smu->scratch_buffer_length++])) { 826 pr_err("Error when Populate Firmware Entry.\n"); 827 goto err0; 828 } 829 830 return 0; 831 832 err0: 833 amdgpu_bo_free_kernel(&smu8_smu->smu_buffer.handle, 834 &smu8_smu->smu_buffer.mc_addr, 835 &smu8_smu->smu_buffer.kaddr); 836 err1: 837 amdgpu_bo_free_kernel(&smu8_smu->toc_buffer.handle, 838 &smu8_smu->toc_buffer.mc_addr, 839 &smu8_smu->toc_buffer.kaddr); 840 err2: 841 kfree(smu8_smu); 842 return -EINVAL; 843 } 844 845 static int smu8_smu_fini(struct pp_hwmgr *hwmgr) 846 { 847 struct smu8_smumgr *smu8_smu; 848 849 if (hwmgr == NULL || hwmgr->device == NULL) 850 return -EINVAL; 851 852 smu8_smu = hwmgr->smu_backend; 853 if (smu8_smu) { 854 amdgpu_bo_free_kernel(&smu8_smu->toc_buffer.handle, 855 &smu8_smu->toc_buffer.mc_addr, 856 &smu8_smu->toc_buffer.kaddr); 857 amdgpu_bo_free_kernel(&smu8_smu->smu_buffer.handle, 858 &smu8_smu->smu_buffer.mc_addr, 859 &smu8_smu->smu_buffer.kaddr); 860 kfree(smu8_smu); 861 } 862 863 return 0; 864 } 865 866 static bool smu8_dpm_check_smu_features(struct pp_hwmgr *hwmgr, 867 unsigned long check_feature) 868 { 869 int result; 870 unsigned long features; 871 872 result = smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetFeatureStatus, 0); 873 if (result == 0) { 874 features = smum_get_argument(hwmgr); 875 if (features & check_feature) 876 return true; 877 } 878 879 return false; 880 } 881 882 static bool smu8_is_dpm_running(struct pp_hwmgr *hwmgr) 883 { 884 if (smu8_dpm_check_smu_features(hwmgr, SMU_EnabledFeatureScoreboard_SclkDpmOn)) 885 return true; 886 return false; 887 } 888 889 const struct pp_smumgr_func smu8_smu_funcs = { 890 .name = "smu8_smu", 891 .smu_init = smu8_smu_init, 892 .smu_fini = smu8_smu_fini, 893 .start_smu = smu8_start_smu, 894 .check_fw_load_finish = smu8_check_fw_load_finish, 895 .request_smu_load_fw = NULL, 896 .request_smu_load_specific_fw = NULL, 897 .get_argument = smu8_get_argument, 898 .send_msg_to_smc = smu8_send_msg_to_smc, 899 .send_msg_to_smc_with_parameter = smu8_send_msg_to_smc_with_parameter, 900 .download_pptable_settings = smu8_download_pptable_settings, 901 .upload_pptable_settings = smu8_upload_pptable_settings, 902 .is_dpm_running = smu8_is_dpm_running, 903 }; 904 905