1/* $NetBSD: amdgpu_atomfirmware.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $ */ 2 3/* 4 * Copyright 2016 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_atomfirmware.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $"); 28 29#include <drm/amdgpu_drm.h> 30#include "amdgpu.h" 31#include "atomfirmware.h" 32#include "amdgpu_atomfirmware.h" 33#include "atom.h" 34#include "atombios.h" 35#include "soc15_hw_ip.h" 36 37bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev) 38{ 39 int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 40 firmwareinfo); 41 uint16_t data_offset; 42 43 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL, 44 NULL, NULL, &data_offset)) { 45 struct atom_firmware_info_v3_1 *firmware_info = 46 (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios + 47 data_offset); 48 49 if (le32_to_cpu(firmware_info->firmware_capability) & 50 ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION) 51 return true; 52 } 53 return false; 54} 55 56void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev) 57{ 58 int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 59 firmwareinfo); 60 uint16_t data_offset; 61 62 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL, 63 NULL, NULL, &data_offset)) { 64 struct atom_firmware_info_v3_1 *firmware_info = 65 (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios + 66 data_offset); 67 68 adev->bios_scratch_reg_offset = 69 le32_to_cpu(firmware_info->bios_scratch_reg_startaddr); 70 } 71} 72 73int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) 74{ 75 struct atom_context *ctx = adev->mode_info.atom_context; 76 int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 77 vram_usagebyfirmware); 78 struct vram_usagebyfirmware_v2_1 * firmware_usage; 79 uint32_t start_addr, size; 80 uint16_t data_offset; 81 int usage_bytes = 0; 82 83 if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { 84 firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); 85 DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", 86 le32_to_cpu(firmware_usage->start_address_in_kb), 87 le16_to_cpu(firmware_usage->used_by_firmware_in_kb), 88 le16_to_cpu(firmware_usage->used_by_driver_in_kb)); 89 90 start_addr = le32_to_cpu(firmware_usage->start_address_in_kb); 91 size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb); 92 93 if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == 94 (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << 95 ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { 96 /* Firmware request VRAM reservation for SR-IOV */ 97 adev->fw_vram_usage.start_offset = (start_addr & 98 (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; 99 adev->fw_vram_usage.size = size << 10; 100 /* Use the default scratch size */ 101 usage_bytes = 0; 102 } else { 103 usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; 104 } 105 } 106 ctx->scratch_size_bytes = 0; 107 if (usage_bytes == 0) 108 usage_bytes = 20 * 1024; 109 /* allocate some scratch memory */ 110 ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); 111 if (!ctx->scratch) 112 return -ENOMEM; 113 ctx->scratch_size_bytes = usage_bytes; 114 return 0; 115} 116 117union igp_info { 118 struct atom_integrated_system_info_v1_11 v11; 119}; 120 121union umc_info { 122 struct atom_umc_info_v3_1 v31; 123}; 124 125union vram_info { 126 struct atom_vram_info_header_v2_3 v23; 127 struct atom_vram_info_header_v2_4 v24; 128}; 129 130union vram_module { 131 struct atom_vram_module_v9 v9; 132 struct atom_vram_module_v10 v10; 133}; 134 135static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev, 136 int atom_mem_type) 137{ 138 int vram_type; 139 140 if (adev->flags & AMD_IS_APU) { 141 switch (atom_mem_type) { 142 case Ddr2MemType: 143 case LpDdr2MemType: 144 vram_type = AMDGPU_VRAM_TYPE_DDR2; 145 break; 146 case Ddr3MemType: 147 case LpDdr3MemType: 148 vram_type = AMDGPU_VRAM_TYPE_DDR3; 149 break; 150 case Ddr4MemType: 151 case LpDdr4MemType: 152 vram_type = AMDGPU_VRAM_TYPE_DDR4; 153 break; 154 default: 155 vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; 156 break; 157 } 158 } else { 159 switch (atom_mem_type) { 160 case ATOM_DGPU_VRAM_TYPE_GDDR5: 161 vram_type = AMDGPU_VRAM_TYPE_GDDR5; 162 break; 163 case ATOM_DGPU_VRAM_TYPE_HBM2: 164 vram_type = AMDGPU_VRAM_TYPE_HBM; 165 break; 166 case ATOM_DGPU_VRAM_TYPE_GDDR6: 167 vram_type = AMDGPU_VRAM_TYPE_GDDR6; 168 break; 169 default: 170 vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; 171 break; 172 } 173 } 174 175 return vram_type; 176} 177 178 179int 180amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, 181 int *vram_width, int *vram_type, 182 int *vram_vendor) 183{ 184 struct amdgpu_mode_info *mode_info = &adev->mode_info; 185 int index, i = 0; 186 u16 data_offset, size; 187 union igp_info *igp_info; 188 union vram_info *vram_info; 189 union vram_module *vram_module; 190 u8 frev, crev; 191 u8 mem_type; 192 u8 mem_vendor; 193 u32 mem_channel_number; 194 u32 mem_channel_width; 195 u32 module_id; 196 197 if (adev->flags & AMD_IS_APU) 198 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 199 integratedsysteminfo); 200 else 201 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 202 vram_info); 203 204 if (amdgpu_atom_parse_data_header(mode_info->atom_context, 205 index, &size, 206 &frev, &crev, &data_offset)) { 207 if (adev->flags & AMD_IS_APU) { 208 igp_info = (union igp_info *) 209 (mode_info->atom_context->bios + data_offset); 210 switch (crev) { 211 case 11: 212 mem_channel_number = igp_info->v11.umachannelnumber; 213 /* channel width is 64 */ 214 if (vram_width) 215 *vram_width = mem_channel_number * 64; 216 mem_type = igp_info->v11.memorytype; 217 if (vram_type) 218 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); 219 break; 220 default: 221 return -EINVAL; 222 } 223 } else { 224 vram_info = (union vram_info *) 225 (mode_info->atom_context->bios + data_offset); 226 module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16; 227 switch (crev) { 228 case 3: 229 if (module_id > vram_info->v23.vram_module_num) 230 module_id = 0; 231 vram_module = (union vram_module *)vram_info->v23.vram_module; 232 while (i < module_id) { 233 vram_module = (union vram_module *) 234 ((u8 *)vram_module + vram_module->v9.vram_module_size); 235 i++; 236 } 237 mem_type = vram_module->v9.memory_type; 238 if (vram_type) 239 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); 240 mem_channel_number = vram_module->v9.channel_num; 241 mem_channel_width = vram_module->v9.channel_width; 242 if (vram_width) 243 *vram_width = mem_channel_number * (1 << mem_channel_width); 244 mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; 245 if (vram_vendor) 246 *vram_vendor = mem_vendor; 247 break; 248 case 4: 249 if (module_id > vram_info->v24.vram_module_num) 250 module_id = 0; 251 vram_module = (union vram_module *)vram_info->v24.vram_module; 252 while (i < module_id) { 253 vram_module = (union vram_module *) 254 ((u8 *)vram_module + vram_module->v10.vram_module_size); 255 i++; 256 } 257 mem_type = vram_module->v10.memory_type; 258 if (vram_type) 259 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); 260 mem_channel_number = vram_module->v10.channel_num; 261 mem_channel_width = vram_module->v10.channel_width; 262 if (vram_width) 263 *vram_width = mem_channel_number * (1 << mem_channel_width); 264 mem_vendor = (vram_module->v10.vender_rev_id) & 0xF; 265 if (vram_vendor) 266 *vram_vendor = mem_vendor; 267 break; 268 default: 269 return -EINVAL; 270 } 271 } 272 273 } 274 275 return 0; 276} 277 278/* 279 * Return true if vbios enabled ecc by default, if umc info table is available 280 * or false if ecc is not enabled or umc info table is not available 281 */ 282bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev) 283{ 284 struct amdgpu_mode_info *mode_info = &adev->mode_info; 285 int index; 286 u16 data_offset, size; 287 union umc_info *umc_info; 288 u8 frev, crev; 289 bool ecc_default_enabled = false; 290 291 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 292 umc_info); 293 294 if (amdgpu_atom_parse_data_header(mode_info->atom_context, 295 index, &size, &frev, &crev, &data_offset)) { 296 /* support umc_info 3.1+ */ 297 if ((frev == 3 && crev >= 1) || (frev > 3)) { 298 umc_info = (union umc_info *) 299 (mode_info->atom_context->bios + data_offset); 300 ecc_default_enabled = 301 (le32_to_cpu(umc_info->v31.umc_config) & 302 UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false; 303 } 304 } 305 306 return ecc_default_enabled; 307} 308 309union firmware_info { 310 struct atom_firmware_info_v3_1 v31; 311}; 312 313/* 314 * Return true if vbios supports sram ecc or false if not 315 */ 316bool amdgpu_atomfirmware_sram_ecc_supported(struct amdgpu_device *adev) 317{ 318 struct amdgpu_mode_info *mode_info = &adev->mode_info; 319 int index; 320 u16 data_offset, size; 321 union firmware_info *firmware_info; 322 u8 frev, crev; 323 bool sram_ecc_supported = false; 324 325 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 326 firmwareinfo); 327 328 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, 329 index, &size, &frev, &crev, &data_offset)) { 330 /* support firmware_info 3.1 + */ 331 if ((frev == 3 && crev >=1) || (frev > 3)) { 332 firmware_info = (union firmware_info *) 333 (mode_info->atom_context->bios + data_offset); 334 sram_ecc_supported = 335 (le32_to_cpu(firmware_info->v31.firmware_capability) & 336 ATOM_FIRMWARE_CAP_SRAM_ECC) ? true : false; 337 } 338 } 339 340 return sram_ecc_supported; 341} 342 343union smu_info { 344 struct atom_smu_info_v3_1 v31; 345}; 346 347int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) 348{ 349 struct amdgpu_mode_info *mode_info = &adev->mode_info; 350 struct amdgpu_pll *spll = &adev->clock.spll; 351 struct amdgpu_pll *mpll = &adev->clock.mpll; 352 uint8_t frev, crev; 353 uint16_t data_offset; 354 int ret = -EINVAL, index; 355 356 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 357 firmwareinfo); 358 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, 359 &frev, &crev, &data_offset)) { 360 union firmware_info *firmware_info = 361 (union firmware_info *)(mode_info->atom_context->bios + 362 data_offset); 363 364 adev->clock.default_sclk = 365 le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz); 366 adev->clock.default_mclk = 367 le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz); 368 369 adev->pm.current_sclk = adev->clock.default_sclk; 370 adev->pm.current_mclk = adev->clock.default_mclk; 371 372 /* not technically a clock, but... */ 373 adev->mode_info.firmware_flags = 374 le32_to_cpu(firmware_info->v31.firmware_capability); 375 376 ret = 0; 377 } 378 379 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 380 smu_info); 381 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, 382 &frev, &crev, &data_offset)) { 383 union smu_info *smu_info = 384 (union smu_info *)(mode_info->atom_context->bios + 385 data_offset); 386 387 /* system clock */ 388 spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz); 389 390 spll->reference_div = 0; 391 spll->min_post_div = 1; 392 spll->max_post_div = 1; 393 spll->min_ref_div = 2; 394 spll->max_ref_div = 0xff; 395 spll->min_feedback_div = 4; 396 spll->max_feedback_div = 0xff; 397 spll->best_vco = 0; 398 399 ret = 0; 400 } 401 402 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 403 umc_info); 404 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, 405 &frev, &crev, &data_offset)) { 406 union umc_info *umc_info = 407 (union umc_info *)(mode_info->atom_context->bios + 408 data_offset); 409 410 /* memory clock */ 411 mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz); 412 413 mpll->reference_div = 0; 414 mpll->min_post_div = 1; 415 mpll->max_post_div = 1; 416 mpll->min_ref_div = 2; 417 mpll->max_ref_div = 0xff; 418 mpll->min_feedback_div = 4; 419 mpll->max_feedback_div = 0xff; 420 mpll->best_vco = 0; 421 422 ret = 0; 423 } 424 425 return ret; 426} 427 428union gfx_info { 429 struct atom_gfx_info_v2_4 v24; 430}; 431 432int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) 433{ 434 struct amdgpu_mode_info *mode_info = &adev->mode_info; 435 int index; 436 uint8_t frev, crev; 437 uint16_t data_offset; 438 439 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 440 gfx_info); 441 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, 442 &frev, &crev, &data_offset)) { 443 union gfx_info *gfx_info = (union gfx_info *) 444 (mode_info->atom_context->bios + data_offset); 445 switch (crev) { 446 case 4: 447 adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines; 448 adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh; 449 adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se; 450 adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se; 451 adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches; 452 adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs); 453 adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds; 454 adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth; 455 adev->gfx.config.gs_prim_buffer_depth = 456 le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth); 457 adev->gfx.config.double_offchip_lds_buf = 458 gfx_info->v24.gc_double_offchip_lds_buffer; 459 adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size); 460 adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd); 461 adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu; 462 adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size); 463 return 0; 464 default: 465 return -EINVAL; 466 } 467 468 } 469 return -EINVAL; 470} 471 472/* 473 * Check if VBIOS supports GDDR6 training data save/restore 474 */ 475static bool gddr6_mem_train_vbios_support(struct amdgpu_device *adev) 476{ 477 uint16_t data_offset; 478 int index; 479 480 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 481 firmwareinfo); 482 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL, 483 NULL, NULL, &data_offset)) { 484 struct atom_firmware_info_v3_1 *firmware_info = 485 (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios + 486 data_offset); 487 488 DRM_DEBUG("atom firmware capability:0x%08x.\n", 489 le32_to_cpu(firmware_info->firmware_capability)); 490 491 if (le32_to_cpu(firmware_info->firmware_capability) & 492 ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) 493 return true; 494 } 495 496 return false; 497} 498 499static int gddr6_mem_train_support(struct amdgpu_device *adev) 500{ 501 int ret; 502 uint32_t major, minor, revision, hw_v; 503 504 if (gddr6_mem_train_vbios_support(adev)) { 505 amdgpu_discovery_get_ip_version(adev, MP0_HWID, &major, &minor, &revision); 506 hw_v = HW_REV(major, minor, revision); 507 /* 508 * treat 0 revision as a special case since register for MP0 and MMHUB is missing 509 * for some Navi10 A0, preventing driver from discovering the hwip information since 510 * none of the functions will be initialized, it should not cause any problems 511 */ 512 switch (hw_v) { 513 case HW_REV(11, 0, 0): 514 case HW_REV(11, 0, 5): 515 ret = 1; 516 break; 517 default: 518 DRM_ERROR("memory training vbios supports but psp hw(%08x)" 519 " doesn't support!\n", hw_v); 520 ret = -1; 521 break; 522 } 523 } else { 524 ret = 0; 525 hw_v = -1; 526 } 527 528 529 DRM_DEBUG("mp0 hw_v %08x, ret:%d.\n", hw_v, ret); 530 return ret; 531} 532 533int amdgpu_atomfirmware_get_mem_train_info(struct amdgpu_device *adev) 534{ 535 struct atom_context *ctx = adev->mode_info.atom_context; 536 int index; 537 uint8_t frev, crev; 538 uint16_t data_offset, size; 539 int ret; 540 541 adev->fw_vram_usage.mem_train_support = false; 542 543 if (adev->asic_type != CHIP_NAVI10 && 544 adev->asic_type != CHIP_NAVI14) 545 return 0; 546 547 if (amdgpu_sriov_vf(adev)) 548 return 0; 549 550 ret = gddr6_mem_train_support(adev); 551 if (ret == -1) 552 return -EINVAL; 553 else if (ret == 0) 554 return 0; 555 556 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 557 vram_usagebyfirmware); 558 ret = amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, 559 &data_offset); 560 if (ret == 0) { 561 DRM_ERROR("parse data header failed.\n"); 562 return -EINVAL; 563 } 564 565 DRM_DEBUG("atom firmware common table header size:0x%04x, frev:0x%02x," 566 " crev:0x%02x, data_offset:0x%04x.\n", size, frev, crev, data_offset); 567 /* only support 2.1+ */ 568 if (((uint16_t)frev << 8 | crev) < 0x0201) { 569 DRM_ERROR("frev:0x%02x, crev:0x%02x < 2.1 !\n", frev, crev); 570 return -EINVAL; 571 } 572 573 adev->fw_vram_usage.mem_train_support = true; 574 return 0; 575} 576