File Index
Files and directories
Sign in
FILE

amdgpu_atomfirmware.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c C
   1/*
   2 * Copyright 2016 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 */
  23
  24#include <drm/amdgpu_drm.h>
  25#include "amdgpu.h"
  26#include "atomfirmware.h"
  27#include "amdgpu_atomfirmware.h"
  28#include "atom.h"
  29#include "atombios.h"
  30#include "soc15_hw_ip.h"
  31
  32union firmware_info {
  33	struct atom_firmware_info_v3_1 v31;
  34	struct atom_firmware_info_v3_2 v32;
  35	struct atom_firmware_info_v3_3 v33;
  36	struct atom_firmware_info_v3_4 v34;
  37	struct atom_firmware_info_v3_5 v35;
  38};
  39
  40/*
  41 * Helper function to query firmware capability
  42 *
  43 * @adev: amdgpu_device pointer
  44 *
  45 * Return firmware_capability in firmwareinfo table on success or 0 if not
  46 */
  47uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *adev)
  48{
  49	struct amdgpu_mode_info *mode_info = &adev->mode_info;
  50	int index;
  51	u16 data_offset, size;
  52	union firmware_info *firmware_info;
  53	u8 frev, crev;
  54	u32 fw_cap = 0;
  55
  56	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
  57			firmwareinfo);
  58
  59	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
  60				index, &size, &frev, &crev, &data_offset)) {
  61		/* support firmware_info 3.1 + */
  62		if ((frev == 3 && crev >= 1) || (frev > 3)) {
  63			firmware_info = (union firmware_info *)
  64				(mode_info->atom_context->bios + data_offset);
  65			fw_cap = le32_to_cpu(firmware_info->v31.firmware_capability);
  66		}
  67	}
  68
  69	return fw_cap;
  70}
  71
  72/*
  73 * Helper function to query gpu virtualizaiton capability
  74 *
  75 * @adev: amdgpu_device pointer
  76 *
  77 * Return true if gpu virtualization is supported or false if not
  78 */
  79bool amdgpu_atomfirmware_gpu_virtualization_supported(struct amdgpu_device *adev)
  80{
  81	u32 fw_cap;
  82
  83	fw_cap = adev->mode_info.firmware_flags;
  84
  85	return (fw_cap & ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION) ? true : false;
  86}
  87
  88void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
  89{
  90	int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
  91						firmwareinfo);
  92	uint16_t data_offset;
  93
  94	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL,
  95					  NULL, NULL, &data_offset)) {
  96		struct atom_firmware_info_v3_1 *firmware_info =
  97			(struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios +
  98							   data_offset);
  99
 100		adev->bios_scratch_reg_offset =
 101			le32_to_cpu(firmware_info->bios_scratch_reg_startaddr);
 102	}
 103}
 104
 105static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev,
 106	struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes)
 107{
 108	u32 start_addr, fw_size, drv_size;
 109
 110	start_addr = le32_to_cpu(fw_usage->start_address_in_kb);
 111	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
 112	drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb);
 113
 114	DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n",
 115			  start_addr,
 116			  fw_size,
 117			  drv_size);
 118
 119	if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
 120		(u32)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
 121		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
 122		/* Firmware request VRAM reservation for SR-IOV */
 123		adev->mman.fw_vram_usage_start_offset = (start_addr &
 124			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
 125		adev->mman.fw_vram_usage_size = fw_size << 10;
 126		/* Use the default scratch size */
 127		*usage_bytes = 0;
 128	} else {
 129		*usage_bytes = drv_size << 10;
 130	}
 131	return 0;
 132}
 133
 134static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev,
 135		struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes)
 136{
 137	u32 fw_start_addr, fw_size, drv_start_addr, drv_size;
 138
 139	fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb);
 140	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
 141
 142	drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb);
 143	drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb);
 144
 145	DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n",
 146			  fw_start_addr,
 147			  fw_size,
 148			  drv_start_addr,
 149			  drv_size);
 150
 151	if (amdgpu_sriov_vf(adev) &&
 152	    ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
 153		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
 154		/* Firmware request VRAM reservation for SR-IOV */
 155		adev->mman.fw_vram_usage_start_offset = (fw_start_addr &
 156			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
 157		adev->mman.fw_vram_usage_size = fw_size << 10;
 158	}
 159
 160	if (amdgpu_sriov_vf(adev) &&
 161	    ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
 162		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
 163		/* driver request VRAM reservation for SR-IOV */
 164		adev->mman.drv_vram_usage_start_offset = (drv_start_addr &
 165			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
 166		adev->mman.drv_vram_usage_size = drv_size << 10;
 167	}
 168
 169	*usage_bytes = 0;
 170	return 0;
 171}
 172
 173int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
 174{
 175	struct atom_context *ctx = adev->mode_info.atom_context;
 176	int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 177						vram_usagebyfirmware);
 178	struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1;
 179	struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2;
 180	u16 data_offset;
 181	u8 frev, crev;
 182	int usage_bytes = 0;
 183
 184	/* Skip atomfirmware allocation for SRIOV VFs when dynamic crit regn is enabled */
 185	if (!(amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled)) {
 186		if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
 187			if (frev == 2 && crev == 1) {
 188				fw_usage_v2_1 =
 189					(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
 190				amdgpu_atomfirmware_allocate_fb_v2_1(adev,
 191						fw_usage_v2_1,
 192						&usage_bytes);
 193			} else if (frev >= 2 && crev >= 2) {
 194				fw_usage_v2_2 =
 195					(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
 196				amdgpu_atomfirmware_allocate_fb_v2_2(adev,
 197						fw_usage_v2_2,
 198						&usage_bytes);
 199			}
 200		}
 201	}
 202
 203	ctx->scratch_size_bytes = 0;
 204	if (usage_bytes == 0)
 205		usage_bytes = 20 * 1024;
 206	/* allocate some scratch memory */
 207	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
 208	if (!ctx->scratch)
 209		return -ENOMEM;
 210	ctx->scratch_size_bytes = usage_bytes;
 211	return 0;
 212}
 213
 214union igp_info {
 215	struct atom_integrated_system_info_v1_11 v11;
 216	struct atom_integrated_system_info_v1_12 v12;
 217	struct atom_integrated_system_info_v2_1 v21;
 218	struct atom_integrated_system_info_v2_3 v23;
 219};
 220
 221union umc_info {
 222	struct atom_umc_info_v3_1 v31;
 223	struct atom_umc_info_v3_2 v32;
 224	struct atom_umc_info_v3_3 v33;
 225	struct atom_umc_info_v4_0 v40;
 226};
 227
 228union vram_info {
 229	struct atom_vram_info_header_v2_3 v23;
 230	struct atom_vram_info_header_v2_4 v24;
 231	struct atom_vram_info_header_v2_5 v25;
 232	struct atom_vram_info_header_v2_6 v26;
 233	struct atom_vram_info_header_v3_0 v30;
 234};
 235
 236union vram_module {
 237	struct atom_vram_module_v9 v9;
 238	struct atom_vram_module_v10 v10;
 239	struct atom_vram_module_v11 v11;
 240	struct atom_vram_module_v3_0 v30;
 241};
 242
 243static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
 244					      int atom_mem_type)
 245{
 246	int vram_type;
 247
 248	if (adev->flags & AMD_IS_APU) {
 249		switch (atom_mem_type) {
 250		case Ddr2MemType:
 251		case LpDdr2MemType:
 252			vram_type = AMDGPU_VRAM_TYPE_DDR2;
 253			break;
 254		case Ddr3MemType:
 255		case LpDdr3MemType:
 256			vram_type = AMDGPU_VRAM_TYPE_DDR3;
 257			break;
 258		case Ddr4MemType:
 259			vram_type = AMDGPU_VRAM_TYPE_DDR4;
 260			break;
 261		case LpDdr4MemType:
 262			vram_type = AMDGPU_VRAM_TYPE_LPDDR4;
 263			break;
 264		case Ddr5MemType:
 265			vram_type = AMDGPU_VRAM_TYPE_DDR5;
 266			break;
 267		case LpDdr5MemType:
 268			vram_type = AMDGPU_VRAM_TYPE_LPDDR5;
 269			break;
 270		default:
 271			vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
 272			break;
 273		}
 274	} else {
 275		switch (atom_mem_type) {
 276		case ATOM_DGPU_VRAM_TYPE_GDDR5:
 277			vram_type = AMDGPU_VRAM_TYPE_GDDR5;
 278			break;
 279		case ATOM_DGPU_VRAM_TYPE_HBM2:
 280		case ATOM_DGPU_VRAM_TYPE_HBM2E:
 281		case ATOM_DGPU_VRAM_TYPE_HBM3:
 282			vram_type = AMDGPU_VRAM_TYPE_HBM;
 283			break;
 284		case ATOM_DGPU_VRAM_TYPE_GDDR6:
 285			vram_type = AMDGPU_VRAM_TYPE_GDDR6;
 286			break;
 287		case ATOM_DGPU_VRAM_TYPE_HBM3E:
 288			vram_type = AMDGPU_VRAM_TYPE_HBM3E;
 289			break;
 290		default:
 291			vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
 292			break;
 293		}
 294	}
 295
 296	return vram_type;
 297}
 298
 299int
 300amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
 301				  int *vram_width, int *vram_type,
 302				  int *vram_vendor)
 303{
 304	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 305	int index, i = 0;
 306	u16 data_offset, size;
 307	union igp_info *igp_info;
 308	union vram_info *vram_info;
 309	union umc_info *umc_info;
 310	union vram_module *vram_module;
 311	u8 frev, crev;
 312	u8 mem_type;
 313	u8 mem_vendor;
 314	u32 mem_channel_number;
 315	u32 mem_channel_width;
 316	u32 module_id;
 317
 318	if (adev->flags & AMD_IS_APU)
 319		index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 320						    integratedsysteminfo);
 321	else {
 322		switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 323		case IP_VERSION(12, 0, 0):
 324		case IP_VERSION(12, 0, 1):
 325			index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, umc_info);
 326			break;
 327		default:
 328			index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, vram_info);
 329		}
 330	}
 331	if (amdgpu_atom_parse_data_header(mode_info->atom_context,
 332					  index, &size,
 333					  &frev, &crev, &data_offset)) {
 334		if (adev->flags & AMD_IS_APU) {
 335			igp_info = (union igp_info *)
 336				(mode_info->atom_context->bios + data_offset);
 337			switch (frev) {
 338			case 1:
 339				switch (crev) {
 340				case 11:
 341				case 12:
 342					mem_channel_number = igp_info->v11.umachannelnumber;
 343					if (!mem_channel_number)
 344						mem_channel_number = 1;
 345					mem_type = igp_info->v11.memorytype;
 346					if (mem_type == LpDdr5MemType)
 347						mem_channel_width = 32;
 348					else
 349						mem_channel_width = 64;
 350					if (vram_width)
 351						*vram_width = mem_channel_number * mem_channel_width;
 352					if (vram_type)
 353						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 354					break;
 355				default:
 356					return -EINVAL;
 357				}
 358				break;
 359			case 2:
 360				switch (crev) {
 361				case 1:
 362				case 2:
 363					mem_channel_number = igp_info->v21.umachannelnumber;
 364					if (!mem_channel_number)
 365						mem_channel_number = 1;
 366					mem_type = igp_info->v21.memorytype;
 367					if (mem_type == LpDdr5MemType)
 368						mem_channel_width = 32;
 369					else
 370						mem_channel_width = 64;
 371					if (vram_width)
 372						*vram_width = mem_channel_number * mem_channel_width;
 373					if (vram_type)
 374						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 375					break;
 376				case 3:
 377					mem_channel_number = igp_info->v23.umachannelnumber;
 378					if (!mem_channel_number)
 379						mem_channel_number = 1;
 380					mem_type = igp_info->v23.memorytype;
 381					if (mem_type == LpDdr5MemType)
 382						mem_channel_width = 32;
 383					else
 384						mem_channel_width = 64;
 385					if (vram_width)
 386						*vram_width = mem_channel_number * mem_channel_width;
 387					if (vram_type)
 388						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 389					break;
 390				default:
 391					return -EINVAL;
 392				}
 393				break;
 394			default:
 395				return -EINVAL;
 396			}
 397		} else {
 398			switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 399			case IP_VERSION(12, 0, 0):
 400			case IP_VERSION(12, 0, 1):
 401				umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset);
 402
 403				if (frev == 4) {
 404					switch (crev) {
 405					case 0:
 406						mem_channel_number = le32_to_cpu(umc_info->v40.channel_num);
 407						mem_type = le32_to_cpu(umc_info->v40.vram_type);
 408						mem_channel_width = le32_to_cpu(umc_info->v40.channel_width);
 409						mem_vendor = RREG32(adev->bios_scratch_reg_offset + 4) & 0xF;
 410						if (vram_vendor)
 411							*vram_vendor = mem_vendor;
 412						if (vram_type)
 413							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 414						if (vram_width)
 415							*vram_width = mem_channel_number * (1 << mem_channel_width);
 416						break;
 417					default:
 418						return -EINVAL;
 419					}
 420				} else
 421					return -EINVAL;
 422				break;
 423			default:
 424				vram_info = (union vram_info *)
 425					(mode_info->atom_context->bios + data_offset);
 426
 427				module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16;
 428				if (frev == 3) {
 429					switch (crev) {
 430					/* v30 */
 431					case 0:
 432						vram_module = (union vram_module *)vram_info->v30.vram_module;
 433						mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF;
 434						if (vram_vendor)
 435							*vram_vendor = mem_vendor;
 436						mem_type = vram_info->v30.memory_type;
 437						if (vram_type)
 438							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 439						mem_channel_number = vram_info->v30.channel_num;
 440						mem_channel_width = vram_info->v30.channel_width;
 441						if (vram_width)
 442							*vram_width = mem_channel_number * 16;
 443						break;
 444					default:
 445						return -EINVAL;
 446					}
 447				} else if (frev == 2) {
 448					switch (crev) {
 449					/* v23 */
 450					case 3:
 451						if (module_id > vram_info->v23.vram_module_num)
 452							module_id = 0;
 453						vram_module = (union vram_module *)vram_info->v23.vram_module;
 454						while (i < module_id) {
 455							vram_module = (union vram_module *)
 456								((u8 *)vram_module + vram_module->v9.vram_module_size);
 457							i++;
 458						}
 459						mem_type = vram_module->v9.memory_type;
 460						if (vram_type)
 461							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 462						mem_channel_number = vram_module->v9.channel_num;
 463						mem_channel_width = vram_module->v9.channel_width;
 464						if (vram_width)
 465							*vram_width = mem_channel_number * (1 << mem_channel_width);
 466						mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
 467						if (vram_vendor)
 468							*vram_vendor = mem_vendor;
 469						break;
 470					/* v24 */
 471					case 4:
 472						if (module_id > vram_info->v24.vram_module_num)
 473							module_id = 0;
 474						vram_module = (union vram_module *)vram_info->v24.vram_module;
 475						while (i < module_id) {
 476							vram_module = (union vram_module *)
 477								((u8 *)vram_module + vram_module->v10.vram_module_size);
 478							i++;
 479						}
 480						mem_type = vram_module->v10.memory_type;
 481						if (vram_type)
 482							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 483						mem_channel_number = vram_module->v10.channel_num;
 484						mem_channel_width = vram_module->v10.channel_width;
 485						if (vram_width)
 486							*vram_width = mem_channel_number * (1 << mem_channel_width);
 487						mem_vendor = (vram_module->v10.vender_rev_id) & 0xF;
 488						if (vram_vendor)
 489							*vram_vendor = mem_vendor;
 490						break;
 491					/* v25 */
 492					case 5:
 493						if (module_id > vram_info->v25.vram_module_num)
 494							module_id = 0;
 495						vram_module = (union vram_module *)vram_info->v25.vram_module;
 496						while (i < module_id) {
 497							vram_module = (union vram_module *)
 498								((u8 *)vram_module + vram_module->v11.vram_module_size);
 499							i++;
 500						}
 501						mem_type = vram_module->v11.memory_type;
 502						if (vram_type)
 503							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 504						mem_channel_number = vram_module->v11.channel_num;
 505						mem_channel_width = vram_module->v11.channel_width;
 506						if (vram_width)
 507							*vram_width = mem_channel_number * (1 << mem_channel_width);
 508						mem_vendor = (vram_module->v11.vender_rev_id) & 0xF;
 509						if (vram_vendor)
 510							*vram_vendor = mem_vendor;
 511						break;
 512					/* v26 */
 513					case 6:
 514						if (module_id > vram_info->v26.vram_module_num)
 515							module_id = 0;
 516						vram_module = (union vram_module *)vram_info->v26.vram_module;
 517						while (i < module_id) {
 518							vram_module = (union vram_module *)
 519								((u8 *)vram_module + vram_module->v9.vram_module_size);
 520							i++;
 521						}
 522						mem_type = vram_module->v9.memory_type;
 523						if (vram_type)
 524							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 525						mem_channel_number = vram_module->v9.channel_num;
 526						mem_channel_width = vram_module->v9.channel_width;
 527						if (vram_width)
 528							*vram_width = mem_channel_number * (1 << mem_channel_width);
 529						mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
 530						if (vram_vendor)
 531							*vram_vendor = mem_vendor;
 532						break;
 533					default:
 534						return -EINVAL;
 535					}
 536				} else {
 537					/* invalid frev */
 538					return -EINVAL;
 539				}
 540			}
 541		}
 542	}
 543
 544	return 0;
 545}
 546
 547/*
 548 * Return true if vbios enabled ecc by default, if umc info table is available
 549 * or false if ecc is not enabled or umc info table is not available
 550 */
 551bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
 552{
 553	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 554	int index;
 555	u16 data_offset, size;
 556	union umc_info *umc_info;
 557	u8 frev, crev;
 558	bool mem_ecc_enabled = false;
 559	u8 umc_config;
 560	u32 umc_config1;
 561	adev->ras_default_ecc_enabled = false;
 562
 563	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 564			umc_info);
 565
 566	if (amdgpu_atom_parse_data_header(mode_info->atom_context,
 567				index, &size, &frev, &crev, &data_offset)) {
 568		umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset);
 569		if (frev == 3) {
 570			switch (crev) {
 571			case 1:
 572				umc_config = le32_to_cpu(umc_info->v31.umc_config);
 573				mem_ecc_enabled =
 574					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
 575				break;
 576			case 2:
 577				umc_config = le32_to_cpu(umc_info->v32.umc_config);
 578				mem_ecc_enabled =
 579					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
 580				break;
 581			case 3:
 582				umc_config = le32_to_cpu(umc_info->v33.umc_config);
 583				umc_config1 = le32_to_cpu(umc_info->v33.umc_config1);
 584				mem_ecc_enabled =
 585					((umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ||
 586					 (umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE)) ? true : false;
 587				adev->ras_default_ecc_enabled =
 588					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
 589				break;
 590			default:
 591				/* unsupported crev */
 592				return false;
 593			}
 594		} else if (frev == 4) {
 595			switch (crev) {
 596			case 0:
 597				umc_config = le32_to_cpu(umc_info->v40.umc_config);
 598				umc_config1 = le32_to_cpu(umc_info->v40.umc_config1);
 599				mem_ecc_enabled =
 600					(umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE) ? true : false;
 601				adev->ras_default_ecc_enabled =
 602					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
 603				break;
 604			default:
 605				/* unsupported crev */
 606				return false;
 607			}
 608		} else {
 609			/* unsupported frev */
 610			return false;
 611		}
 612	}
 613
 614	return mem_ecc_enabled;
 615}
 616
 617/*
 618 * Helper function to query sram ecc capablity
 619 *
 620 * @adev: amdgpu_device pointer
 621 *
 622 * Return true if vbios supports sram ecc or false if not
 623 */
 624bool amdgpu_atomfirmware_sram_ecc_supported(struct amdgpu_device *adev)
 625{
 626	u32 fw_cap;
 627
 628	fw_cap = adev->mode_info.firmware_flags;
 629
 630	return (fw_cap & ATOM_FIRMWARE_CAP_SRAM_ECC) ? true : false;
 631}
 632
 633/*
 634 * Helper function to query dynamic boot config capability
 635 *
 636 * @adev: amdgpu_device pointer
 637 *
 638 * Return true if vbios supports dynamic boot config or false if not
 639 */
 640bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *adev)
 641{
 642	u32 fw_cap;
 643
 644	fw_cap = adev->mode_info.firmware_flags;
 645
 646	return (fw_cap & ATOM_FIRMWARE_CAP_DYNAMIC_BOOT_CFG_ENABLE) ? true : false;
 647}
 648
 649/**
 650 * amdgpu_atomfirmware_ras_rom_addr -- Get the RAS EEPROM addr from VBIOS
 651 * @adev: amdgpu_device pointer
 652 * @i2c_address: pointer to u8; if not NULL, will contain
 653 *    the RAS EEPROM address if the function returns true
 654 *
 655 * Return true if VBIOS supports RAS EEPROM address reporting,
 656 * else return false. If true and @i2c_address is not NULL,
 657 * will contain the RAS ROM address.
 658 */
 659bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev,
 660				      u8 *i2c_address)
 661{
 662	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 663	int index;
 664	u16 data_offset, size;
 665	union firmware_info *firmware_info;
 666	u8 frev, crev;
 667
 668	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 669					    firmwareinfo);
 670
 671	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
 672					  index, &size, &frev, &crev,
 673					  &data_offset)) {
 674		/* support firmware_info 3.4 + */
 675		if ((frev == 3 && crev >= 4) || (frev > 3)) {
 676			firmware_info = (union firmware_info *)
 677				(mode_info->atom_context->bios + data_offset);
 678			/* The ras_rom_i2c_slave_addr should ideally
 679			 * be a 19-bit EEPROM address, which would be
 680			 * used as is by the driver; see top of
 681			 * amdgpu_eeprom.c.
 682			 *
 683			 * When this is the case, 0 is of course a
 684			 * valid RAS EEPROM address, in which case,
 685			 * we'll drop the first "if (firm...)" and only
 686			 * leave the check for the pointer.
 687			 *
 688			 * The reason this works right now is because
 689			 * ras_rom_i2c_slave_addr contains the EEPROM
 690			 * device type qualifier 1010b in the top 4
 691			 * bits.
 692			 */
 693			if (firmware_info->v34.ras_rom_i2c_slave_addr) {
 694				if (i2c_address)
 695					*i2c_address = firmware_info->v34.ras_rom_i2c_slave_addr;
 696				return true;
 697			}
 698		}
 699	}
 700
 701	return false;
 702}
 703
 704
 705union smu_info {
 706	struct atom_smu_info_v3_1 v31;
 707	struct atom_smu_info_v4_0 v40;
 708};
 709
 710union gfx_info {
 711	struct atom_gfx_info_v2_2 v22;
 712	struct atom_gfx_info_v2_4 v24;
 713	struct atom_gfx_info_v2_7 v27;
 714	struct atom_gfx_info_v3_0 v30;
 715};
 716
 717int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
 718{
 719	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 720	struct amdgpu_pll *spll = &adev->clock.spll;
 721	struct amdgpu_pll *mpll = &adev->clock.mpll;
 722	uint8_t frev, crev;
 723	uint16_t data_offset;
 724	int ret = -EINVAL, index;
 725
 726	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 727					    firmwareinfo);
 728	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 729				   &frev, &crev, &data_offset)) {
 730		union firmware_info *firmware_info =
 731			(union firmware_info *)(mode_info->atom_context->bios +
 732						data_offset);
 733
 734		adev->clock.default_sclk =
 735			le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
 736		adev->clock.default_mclk =
 737			le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
 738
 739		adev->pm.current_sclk = adev->clock.default_sclk;
 740		adev->pm.current_mclk = adev->clock.default_mclk;
 741
 742		ret = 0;
 743	}
 744
 745	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 746					    smu_info);
 747	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 748				   &frev, &crev, &data_offset)) {
 749		union smu_info *smu_info =
 750			(union smu_info *)(mode_info->atom_context->bios +
 751					   data_offset);
 752
 753		/* system clock */
 754		if (frev == 3)
 755			spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz);
 756		else if (frev == 4)
 757			spll->reference_freq = le32_to_cpu(smu_info->v40.core_refclk_10khz);
 758
 759		spll->reference_div = 0;
 760		spll->min_post_div = 1;
 761		spll->max_post_div = 1;
 762		spll->min_ref_div = 2;
 763		spll->max_ref_div = 0xff;
 764		spll->min_feedback_div = 4;
 765		spll->max_feedback_div = 0xff;
 766		spll->best_vco = 0;
 767
 768		ret = 0;
 769	}
 770
 771	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 772					    umc_info);
 773	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 774				   &frev, &crev, &data_offset)) {
 775		union umc_info *umc_info =
 776			(union umc_info *)(mode_info->atom_context->bios +
 777					   data_offset);
 778
 779		/* memory clock */
 780		mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz);
 781
 782		mpll->reference_div = 0;
 783		mpll->min_post_div = 1;
 784		mpll->max_post_div = 1;
 785		mpll->min_ref_div = 2;
 786		mpll->max_ref_div = 0xff;
 787		mpll->min_feedback_div = 4;
 788		mpll->max_feedback_div = 0xff;
 789		mpll->best_vco = 0;
 790
 791		ret = 0;
 792	}
 793
 794	/* if asic is Navi+, the rlc reference clock is used for system clock
 795	 * from vbios gfx_info table */
 796	if (adev->asic_type >= CHIP_NAVI10) {
 797		index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 798						   gfx_info);
 799		if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 800					  &frev, &crev, &data_offset)) {
 801			union gfx_info *gfx_info = (union gfx_info *)
 802				(mode_info->atom_context->bios + data_offset);
 803			if ((frev == 3) ||
 804			    (frev == 2 && crev == 6)) {
 805				spll->reference_freq = le32_to_cpu(gfx_info->v30.golden_tsc_count_lower_refclk);
 806				ret = 0;
 807			} else if ((frev == 2) &&
 808				   (crev >= 2) &&
 809				   (crev != 6)) {
 810				spll->reference_freq = le32_to_cpu(gfx_info->v22.rlc_gpu_timer_refclk);
 811				ret = 0;
 812			} else {
 813				BUG();
 814			}
 815		}
 816	}
 817
 818	return ret;
 819}
 820
 821int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
 822{
 823	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 824	int index;
 825	uint8_t frev, crev;
 826	uint16_t data_offset;
 827
 828	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 829					    gfx_info);
 830	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 831				   &frev, &crev, &data_offset)) {
 832		union gfx_info *gfx_info = (union gfx_info *)
 833			(mode_info->atom_context->bios + data_offset);
 834		if (frev == 2) {
 835			switch (crev) {
 836			case 4:
 837				adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines;
 838				adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh;
 839				adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se;
 840				adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se;
 841				adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches;
 842				adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs);
 843				adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds;
 844				adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth;
 845				adev->gfx.config.gs_prim_buffer_depth =
 846					le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth);
 847				adev->gfx.config.double_offchip_lds_buf =
 848					gfx_info->v24.gc_double_offchip_lds_buffer;
 849				adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size);
 850				adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd);
 851				adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu;
 852				adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size);
 853				return 0;
 854			case 7:
 855				adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines;
 856				adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh;
 857				adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se;
 858				adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se;
 859				adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches;
 860				adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs);
 861				adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds;
 862				adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth;
 863				adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth);
 864				adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer;
 865				adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size);
 866				adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd);
 867				adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu;
 868				adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size);
 869				return 0;
 870			default:
 871				return -EINVAL;
 872			}
 873		} else if (frev == 3) {
 874			switch (crev) {
 875			case 0:
 876				adev->gfx.config.max_shader_engines = gfx_info->v30.max_shader_engines;
 877				adev->gfx.config.max_cu_per_sh = gfx_info->v30.max_cu_per_sh;
 878				adev->gfx.config.max_sh_per_se = gfx_info->v30.max_sh_per_se;
 879				adev->gfx.config.max_backends_per_se = gfx_info->v30.max_backends_per_se;
 880				adev->gfx.config.max_texture_channel_caches = gfx_info->v30.max_texture_channel_caches;
 881				return 0;
 882			default:
 883				return -EINVAL;
 884			}
 885		} else {
 886			return -EINVAL;
 887		}
 888
 889	}
 890	return -EINVAL;
 891}
 892
 893/*
 894 * Helper function to query two stage mem training capability
 895 *
 896 * @adev: amdgpu_device pointer
 897 *
 898 * Return true if two stage mem training is supported or false if not
 899 */
 900bool amdgpu_atomfirmware_mem_training_supported(struct amdgpu_device *adev)
 901{
 902	u32 fw_cap;
 903
 904	fw_cap = adev->mode_info.firmware_flags;
 905
 906	return (fw_cap & ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) ? true : false;
 907}
 908
 909int amdgpu_atomfirmware_get_fw_reserved_fb_size(struct amdgpu_device *adev)
 910{
 911	struct atom_context *ctx = adev->mode_info.atom_context;
 912	union firmware_info *firmware_info;
 913	int index;
 914	u16 data_offset, size;
 915	u8 frev, crev;
 916	int fw_reserved_fb_size;
 917
 918	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 919			firmwareinfo);
 920
 921	if (!amdgpu_atom_parse_data_header(ctx, index, &size,
 922				&frev, &crev, &data_offset))
 923		/* fail to parse data_header */
 924		return 0;
 925
 926	firmware_info = (union firmware_info *)(ctx->bios + data_offset);
 927
 928	if (frev != 3)
 929		return -EINVAL;
 930
 931	switch (crev) {
 932	case 4:
 933		fw_reserved_fb_size =
 934			(firmware_info->v34.fw_reserved_size_in_kb << 10);
 935		break;
 936	case 5:
 937		fw_reserved_fb_size =
 938			(firmware_info->v35.fw_reserved_size_in_kb << 10);
 939		break;
 940	default:
 941		fw_reserved_fb_size = 0;
 942		break;
 943	}
 944
 945	return fw_reserved_fb_size;
 946}
 947
 948/*
 949 * Helper function to execute asic_init table
 950 *
 951 * @adev: amdgpu_device pointer
 952 * @fb_reset: flag to indicate whether fb is reset or not
 953 *
 954 * Return 0 if succeed, otherwise failed
 955 */
 956int amdgpu_atomfirmware_asic_init(struct amdgpu_device *adev, bool fb_reset)
 957{
 958	struct amdgpu_mode_info *mode_info = &adev->mode_info;
 959	struct atom_context *ctx;
 960	uint8_t frev, crev;
 961	uint16_t data_offset;
 962	uint32_t bootup_sclk_in10khz, bootup_mclk_in10khz;
 963	struct asic_init_ps_allocation_v2_1 asic_init_ps_v2_1;
 964	int index;
 965
 966	if (!mode_info)
 967		return -EINVAL;
 968
 969	ctx = mode_info->atom_context;
 970	if (!ctx)
 971		return -EINVAL;
 972
 973	/* query bootup sclk/mclk from firmware_info table */
 974	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 975					    firmwareinfo);
 976	if (amdgpu_atom_parse_data_header(ctx, index, NULL,
 977				&frev, &crev, &data_offset)) {
 978		union firmware_info *firmware_info =
 979			(union firmware_info *)(ctx->bios +
 980						data_offset);
 981
 982		bootup_sclk_in10khz =
 983			le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
 984		bootup_mclk_in10khz =
 985			le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
 986	} else {
 987		return -EINVAL;
 988	}
 989
 990	index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1,
 991					asic_init);
 992	if (amdgpu_atom_parse_cmd_header(mode_info->atom_context, index, &frev, &crev)) {
 993		if (frev == 2 && crev >= 1) {
 994			memset(&asic_init_ps_v2_1, 0, sizeof(asic_init_ps_v2_1));
 995			asic_init_ps_v2_1.param.engineparam.sclkfreqin10khz = bootup_sclk_in10khz;
 996			asic_init_ps_v2_1.param.memparam.mclkfreqin10khz = bootup_mclk_in10khz;
 997			asic_init_ps_v2_1.param.engineparam.engineflag = b3NORMAL_ENGINE_INIT;
 998			if (!fb_reset)
 999				asic_init_ps_v2_1.param.memparam.memflag = b3DRAM_SELF_REFRESH_EXIT;
1000			else
1001				asic_init_ps_v2_1.param.memparam.memflag = 0;
1002		} else {
1003			return -EINVAL;
1004		}
1005	} else {
1006		return -EINVAL;
1007	}
1008
1009	return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1,
1010		sizeof(asic_init_ps_v2_1));
1011}
~/ Read-only file preview.