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