/*
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <drm/amdgpu_drm.h>
#include "amdgpu.h"
#include "atomfirmware.h"
#include "amdgpu_atomfirmware.h"
#include "atom.h"
#include "atombios.h"
#include "soc15_hw_ip.h"

union firmware_info {
	struct atom_firmware_info_v3_1 v31;
	struct atom_firmware_info_v3_2 v32;
	struct atom_firmware_info_v3_3 v33;
	struct atom_firmware_info_v3_4 v34;
	struct atom_firmware_info_v3_5 v35;
};

/*
 * Helper function to query firmware capability
 *
 * @adev: amdgpu_device pointer
 *
 * Return firmware_capability in firmwareinfo table on success or 0 if not
 */
uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *adev)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index;
	u16 data_offset, size;
	union firmware_info *firmware_info;
	u8 frev, crev;
	u32 fw_cap = 0;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
			firmwareinfo);

	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
				index, &size, &frev, &crev, &data_offset)) {
		/* support firmware_info 3.1 + */
		if ((frev == 3 && crev >= 1) || (frev > 3)) {
			firmware_info = (union firmware_info *)
				(mode_info->atom_context->bios + data_offset);
			fw_cap = le32_to_cpu(firmware_info->v31.firmware_capability);
		}
	}

	return fw_cap;
}

/*
 * Helper function to query gpu virtualizaiton capability
 *
 * @adev: amdgpu_device pointer
 *
 * Return true if gpu virtualization is supported or false if not
 */
bool amdgpu_atomfirmware_gpu_virtualization_supported(struct amdgpu_device *adev)
{
	u32 fw_cap;

	fw_cap = adev->mode_info.firmware_flags;

	return (fw_cap & ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION) ? true : false;
}

void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
{
	int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
						firmwareinfo);
	uint16_t data_offset;

	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL,
					  NULL, NULL, &data_offset)) {
		struct atom_firmware_info_v3_1 *firmware_info =
			(struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios +
							   data_offset);

		adev->bios_scratch_reg_offset =
			le32_to_cpu(firmware_info->bios_scratch_reg_startaddr);
	}
}

static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev,
	struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes)
{
	u32 start_addr, fw_size, drv_size;

	start_addr = le32_to_cpu(fw_usage->start_address_in_kb);
	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
	drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb);

	DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n",
			  start_addr,
			  fw_size,
			  drv_size);

	if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
		(u32)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
		/* Firmware request VRAM reservation for SR-IOV */
		adev->mman.fw_vram_usage_start_offset = (start_addr &
			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
		adev->mman.fw_vram_usage_size = fw_size << 10;
		/* Use the default scratch size */
		*usage_bytes = 0;
	} else {
		*usage_bytes = drv_size << 10;
	}
	return 0;
}

static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev,
		struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes)
{
	u32 fw_start_addr, fw_size, drv_start_addr, drv_size;

	fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb);
	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);

	drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb);
	drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb);

	DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n",
			  fw_start_addr,
			  fw_size,
			  drv_start_addr,
			  drv_size);

	if (amdgpu_sriov_vf(adev) &&
	    ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
		/* Firmware request VRAM reservation for SR-IOV */
		adev->mman.fw_vram_usage_start_offset = (fw_start_addr &
			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
		adev->mman.fw_vram_usage_size = fw_size << 10;
	}

	if (amdgpu_sriov_vf(adev) &&
	    ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
		/* driver request VRAM reservation for SR-IOV */
		adev->mman.drv_vram_usage_start_offset = (drv_start_addr &
			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
		adev->mman.drv_vram_usage_size = drv_size << 10;
	}

	*usage_bytes = 0;
	return 0;
}

int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
{
	struct atom_context *ctx = adev->mode_info.atom_context;
	int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
						vram_usagebyfirmware);
	struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1;
	struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2;
	u16 data_offset;
	u8 frev, crev;
	int usage_bytes = 0;

	if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
		if (frev == 2 && crev == 1) {
			fw_usage_v2_1 =
				(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
			amdgpu_atomfirmware_allocate_fb_v2_1(adev,
					fw_usage_v2_1,
					&usage_bytes);
		} else if (frev >= 2 && crev >= 2) {
			fw_usage_v2_2 =
				(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
			amdgpu_atomfirmware_allocate_fb_v2_2(adev,
					fw_usage_v2_2,
					&usage_bytes);
		}
	}

	ctx->scratch_size_bytes = 0;
	if (usage_bytes == 0)
		usage_bytes = 20 * 1024;
	/* allocate some scratch memory */
	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
	if (!ctx->scratch)
		return -ENOMEM;
	ctx->scratch_size_bytes = usage_bytes;
	return 0;
}

union igp_info {
	struct atom_integrated_system_info_v1_11 v11;
	struct atom_integrated_system_info_v1_12 v12;
	struct atom_integrated_system_info_v2_1 v21;
	struct atom_integrated_system_info_v2_3 v23;
};

union umc_info {
	struct atom_umc_info_v3_1 v31;
	struct atom_umc_info_v3_2 v32;
	struct atom_umc_info_v3_3 v33;
	struct atom_umc_info_v4_0 v40;
};

union vram_info {
	struct atom_vram_info_header_v2_3 v23;
	struct atom_vram_info_header_v2_4 v24;
	struct atom_vram_info_header_v2_5 v25;
	struct atom_vram_info_header_v2_6 v26;
	struct atom_vram_info_header_v3_0 v30;
};

union vram_module {
	struct atom_vram_module_v9 v9;
	struct atom_vram_module_v10 v10;
	struct atom_vram_module_v11 v11;
	struct atom_vram_module_v3_0 v30;
};

static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
					      int atom_mem_type)
{
	int vram_type;

	if (adev->flags & AMD_IS_APU) {
		switch (atom_mem_type) {
		case Ddr2MemType:
		case LpDdr2MemType:
			vram_type = AMDGPU_VRAM_TYPE_DDR2;
			break;
		case Ddr3MemType:
		case LpDdr3MemType:
			vram_type = AMDGPU_VRAM_TYPE_DDR3;
			break;
		case Ddr4MemType:
			vram_type = AMDGPU_VRAM_TYPE_DDR4;
			break;
		case LpDdr4MemType:
			vram_type = AMDGPU_VRAM_TYPE_LPDDR4;
			break;
		case Ddr5MemType:
			vram_type = AMDGPU_VRAM_TYPE_DDR5;
			break;
		case LpDdr5MemType:
			vram_type = AMDGPU_VRAM_TYPE_LPDDR5;
			break;
		default:
			vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
			break;
		}
	} else {
		switch (atom_mem_type) {
		case ATOM_DGPU_VRAM_TYPE_GDDR5:
			vram_type = AMDGPU_VRAM_TYPE_GDDR5;
			break;
		case ATOM_DGPU_VRAM_TYPE_HBM2:
		case ATOM_DGPU_VRAM_TYPE_HBM2E:
		case ATOM_DGPU_VRAM_TYPE_HBM3:
			vram_type = AMDGPU_VRAM_TYPE_HBM;
			break;
		case ATOM_DGPU_VRAM_TYPE_GDDR6:
			vram_type = AMDGPU_VRAM_TYPE_GDDR6;
			break;
		default:
			vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
			break;
		}
	}

	return vram_type;
}

int
amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
				  int *vram_width, int *vram_type,
				  int *vram_vendor)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index, i = 0;
	u16 data_offset, size;
	union igp_info *igp_info;
	union vram_info *vram_info;
	union umc_info *umc_info;
	union vram_module *vram_module;
	u8 frev, crev;
	u8 mem_type;
	u8 mem_vendor;
	u32 mem_channel_number;
	u32 mem_channel_width;
	u32 module_id;

	if (adev->flags & AMD_IS_APU)
		index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
						    integratedsysteminfo);
	else {
		switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
		case IP_VERSION(12, 0, 0):
		case IP_VERSION(12, 0, 1):
			index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, umc_info);
			break;
		default:
			index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, vram_info);
		}
	}
	if (amdgpu_atom_parse_data_header(mode_info->atom_context,
					  index, &size,
					  &frev, &crev, &data_offset)) {
		if (adev->flags & AMD_IS_APU) {
			igp_info = (union igp_info *)
				(mode_info->atom_context->bios + data_offset);
			switch (frev) {
			case 1:
				switch (crev) {
				case 11:
				case 12:
					mem_channel_number = igp_info->v11.umachannelnumber;
					if (!mem_channel_number)
						mem_channel_number = 1;
					mem_type = igp_info->v11.memorytype;
					if (mem_type == LpDdr5MemType)
						mem_channel_width = 32;
					else
						mem_channel_width = 64;
					if (vram_width)
						*vram_width = mem_channel_number * mem_channel_width;
					if (vram_type)
						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
					break;
				default:
					return -EINVAL;
				}
				break;
			case 2:
				switch (crev) {
				case 1:
				case 2:
					mem_channel_number = igp_info->v21.umachannelnumber;
					if (!mem_channel_number)
						mem_channel_number = 1;
					mem_type = igp_info->v21.memorytype;
					if (mem_type == LpDdr5MemType)
						mem_channel_width = 32;
					else
						mem_channel_width = 64;
					if (vram_width)
						*vram_width = mem_channel_number * mem_channel_width;
					if (vram_type)
						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
					break;
				case 3:
					mem_channel_number = igp_info->v23.umachannelnumber;
					if (!mem_channel_number)
						mem_channel_number = 1;
					mem_type = igp_info->v23.memorytype;
					if (mem_type == LpDdr5MemType)
						mem_channel_width = 32;
					else
						mem_channel_width = 64;
					if (vram_width)
						*vram_width = mem_channel_number * mem_channel_width;
					if (vram_type)
						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
					break;
				default:
					return -EINVAL;
				}
				break;
			default:
				return -EINVAL;
			}
		} else {
			switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
			case IP_VERSION(12, 0, 0):
			case IP_VERSION(12, 0, 1):
				umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset);

				if (frev == 4) {
					switch (crev) {
					case 0:
						mem_channel_number = le32_to_cpu(umc_info->v40.channel_num);
						mem_type = le32_to_cpu(umc_info->v40.vram_type);
						mem_channel_width = le32_to_cpu(umc_info->v40.channel_width);
						mem_vendor = RREG32(adev->bios_scratch_reg_offset + 4) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						if (vram_width)
							*vram_width = mem_channel_number * (1 << mem_channel_width);
						break;
					default:
						return -EINVAL;
					}
				} else
					return -EINVAL;
				break;
			default:
				vram_info = (union vram_info *)
					(mode_info->atom_context->bios + data_offset);

				module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16;
				if (frev == 3) {
					switch (crev) {
					/* v30 */
					case 0:
						vram_module = (union vram_module *)vram_info->v30.vram_module;
						mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						mem_type = vram_info->v30.memory_type;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						mem_channel_number = vram_info->v30.channel_num;
						mem_channel_width = vram_info->v30.channel_width;
						if (vram_width)
							*vram_width = mem_channel_number * 16;
						break;
					default:
						return -EINVAL;
					}
				} else if (frev == 2) {
					switch (crev) {
					/* v23 */
					case 3:
						if (module_id > vram_info->v23.vram_module_num)
							module_id = 0;
						vram_module = (union vram_module *)vram_info->v23.vram_module;
						while (i < module_id) {
							vram_module = (union vram_module *)
								((u8 *)vram_module + vram_module->v9.vram_module_size);
							i++;
						}
						mem_type = vram_module->v9.memory_type;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						mem_channel_number = vram_module->v9.channel_num;
						mem_channel_width = vram_module->v9.channel_width;
						if (vram_width)
							*vram_width = mem_channel_number * (1 << mem_channel_width);
						mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						break;
					/* v24 */
					case 4:
						if (module_id > vram_info->v24.vram_module_num)
							module_id = 0;
						vram_module = (union vram_module *)vram_info->v24.vram_module;
						while (i < module_id) {
							vram_module = (union vram_module *)
								((u8 *)vram_module + vram_module->v10.vram_module_size);
							i++;
						}
						mem_type = vram_module->v10.memory_type;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						mem_channel_number = vram_module->v10.channel_num;
						mem_channel_width = vram_module->v10.channel_width;
						if (vram_width)
							*vram_width = mem_channel_number * (1 << mem_channel_width);
						mem_vendor = (vram_module->v10.vender_rev_id) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						break;
					/* v25 */
					case 5:
						if (module_id > vram_info->v25.vram_module_num)
							module_id = 0;
						vram_module = (union vram_module *)vram_info->v25.vram_module;
						while (i < module_id) {
							vram_module = (union vram_module *)
								((u8 *)vram_module + vram_module->v11.vram_module_size);
							i++;
						}
						mem_type = vram_module->v11.memory_type;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						mem_channel_number = vram_module->v11.channel_num;
						mem_channel_width = vram_module->v11.channel_width;
						if (vram_width)
							*vram_width = mem_channel_number * (1 << mem_channel_width);
						mem_vendor = (vram_module->v11.vender_rev_id) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						break;
					/* v26 */
					case 6:
						if (module_id > vram_info->v26.vram_module_num)
							module_id = 0;
						vram_module = (union vram_module *)vram_info->v26.vram_module;
						while (i < module_id) {
							vram_module = (union vram_module *)
								((u8 *)vram_module + vram_module->v9.vram_module_size);
							i++;
						}
						mem_type = vram_module->v9.memory_type;
						if (vram_type)
							*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
						mem_channel_number = vram_module->v9.channel_num;
						mem_channel_width = vram_module->v9.channel_width;
						if (vram_width)
							*vram_width = mem_channel_number * (1 << mem_channel_width);
						mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
						if (vram_vendor)
							*vram_vendor = mem_vendor;
						break;
					default:
						return -EINVAL;
					}
				} else {
					/* invalid frev */
					return -EINVAL;
				}
			}
		}
	}

	return 0;
}

/*
 * Return true if vbios enabled ecc by default, if umc info table is available
 * or false if ecc is not enabled or umc info table is not available
 */
bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index;
	u16 data_offset, size;
	union umc_info *umc_info;
	u8 frev, crev;
	bool ecc_default_enabled = false;
	u8 umc_config;
	u32 umc_config1;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
			umc_info);

	if (amdgpu_atom_parse_data_header(mode_info->atom_context,
				index, &size, &frev, &crev, &data_offset)) {
		umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset);
		if (frev == 3) {
			switch (crev) {
			case 1:
				umc_config = le32_to_cpu(umc_info->v31.umc_config);
				ecc_default_enabled =
					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
				break;
			case 2:
				umc_config = le32_to_cpu(umc_info->v32.umc_config);
				ecc_default_enabled =
					(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
				break;
			case 3:
				umc_config = le32_to_cpu(umc_info->v33.umc_config);
				umc_config1 = le32_to_cpu(umc_info->v33.umc_config1);
				ecc_default_enabled =
					((umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ||
					 (umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE)) ? true : false;
				break;
			default:
				/* unsupported crev */
				return false;
			}
		} else if (frev == 4) {
			switch (crev) {
			case 0:
				umc_config1 = le32_to_cpu(umc_info->v40.umc_config1);
				ecc_default_enabled =
					(umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE) ? true : false;
				break;
			default:
				/* unsupported crev */
				return false;
			}
		} else {
			/* unsupported frev */
			return false;
		}
	}

	return ecc_default_enabled;
}

/*
 * Helper function to query sram ecc capablity
 *
 * @adev: amdgpu_device pointer
 *
 * Return true if vbios supports sram ecc or false if not
 */
bool amdgpu_atomfirmware_sram_ecc_supported(struct amdgpu_device *adev)
{
	u32 fw_cap;

	fw_cap = adev->mode_info.firmware_flags;

	return (fw_cap & ATOM_FIRMWARE_CAP_SRAM_ECC) ? true : false;
}

/*
 * Helper function to query dynamic boot config capability
 *
 * @adev: amdgpu_device pointer
 *
 * Return true if vbios supports dynamic boot config or false if not
 */
bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *adev)
{
	u32 fw_cap;

	fw_cap = adev->mode_info.firmware_flags;

	return (fw_cap & ATOM_FIRMWARE_CAP_DYNAMIC_BOOT_CFG_ENABLE) ? true : false;
}

/**
 * amdgpu_atomfirmware_ras_rom_addr -- Get the RAS EEPROM addr from VBIOS
 * @adev: amdgpu_device pointer
 * @i2c_address: pointer to u8; if not NULL, will contain
 *    the RAS EEPROM address if the function returns true
 *
 * Return true if VBIOS supports RAS EEPROM address reporting,
 * else return false. If true and @i2c_address is not NULL,
 * will contain the RAS ROM address.
 */
bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev,
				      u8 *i2c_address)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index;
	u16 data_offset, size;
	union firmware_info *firmware_info;
	u8 frev, crev;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    firmwareinfo);

	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
					  index, &size, &frev, &crev,
					  &data_offset)) {
		/* support firmware_info 3.4 + */
		if ((frev == 3 && crev >= 4) || (frev > 3)) {
			firmware_info = (union firmware_info *)
				(mode_info->atom_context->bios + data_offset);
			/* The ras_rom_i2c_slave_addr should ideally
			 * be a 19-bit EEPROM address, which would be
			 * used as is by the driver; see top of
			 * amdgpu_eeprom.c.
			 *
			 * When this is the case, 0 is of course a
			 * valid RAS EEPROM address, in which case,
			 * we'll drop the first "if (firm...)" and only
			 * leave the check for the pointer.
			 *
			 * The reason this works right now is because
			 * ras_rom_i2c_slave_addr contains the EEPROM
			 * device type qualifier 1010b in the top 4
			 * bits.
			 */
			if (firmware_info->v34.ras_rom_i2c_slave_addr) {
				if (i2c_address)
					*i2c_address = firmware_info->v34.ras_rom_i2c_slave_addr;
				return true;
			}
		}
	}

	return false;
}


union smu_info {
	struct atom_smu_info_v3_1 v31;
	struct atom_smu_info_v4_0 v40;
};

union gfx_info {
	struct atom_gfx_info_v2_2 v22;
	struct atom_gfx_info_v2_4 v24;
	struct atom_gfx_info_v2_7 v27;
	struct atom_gfx_info_v3_0 v30;
};

int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	struct amdgpu_pll *spll = &adev->clock.spll;
	struct amdgpu_pll *mpll = &adev->clock.mpll;
	uint8_t frev, crev;
	uint16_t data_offset;
	int ret = -EINVAL, index;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    firmwareinfo);
	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
				   &frev, &crev, &data_offset)) {
		union firmware_info *firmware_info =
			(union firmware_info *)(mode_info->atom_context->bios +
						data_offset);

		adev->clock.default_sclk =
			le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
		adev->clock.default_mclk =
			le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);

		adev->pm.current_sclk = adev->clock.default_sclk;
		adev->pm.current_mclk = adev->clock.default_mclk;

		ret = 0;
	}

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    smu_info);
	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
				   &frev, &crev, &data_offset)) {
		union smu_info *smu_info =
			(union smu_info *)(mode_info->atom_context->bios +
					   data_offset);

		/* system clock */
		if (frev == 3)
			spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz);
		else if (frev == 4)
			spll->reference_freq = le32_to_cpu(smu_info->v40.core_refclk_10khz);

		spll->reference_div = 0;
		spll->min_post_div = 1;
		spll->max_post_div = 1;
		spll->min_ref_div = 2;
		spll->max_ref_div = 0xff;
		spll->min_feedback_div = 4;
		spll->max_feedback_div = 0xff;
		spll->best_vco = 0;

		ret = 0;
	}

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    umc_info);
	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
				   &frev, &crev, &data_offset)) {
		union umc_info *umc_info =
			(union umc_info *)(mode_info->atom_context->bios +
					   data_offset);

		/* memory clock */
		mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz);

		mpll->reference_div = 0;
		mpll->min_post_div = 1;
		mpll->max_post_div = 1;
		mpll->min_ref_div = 2;
		mpll->max_ref_div = 0xff;
		mpll->min_feedback_div = 4;
		mpll->max_feedback_div = 0xff;
		mpll->best_vco = 0;

		ret = 0;
	}

	/* if asic is Navi+, the rlc reference clock is used for system clock
	 * from vbios gfx_info table */
	if (adev->asic_type >= CHIP_NAVI10) {
		index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
						   gfx_info);
		if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
					  &frev, &crev, &data_offset)) {
			union gfx_info *gfx_info = (union gfx_info *)
				(mode_info->atom_context->bios + data_offset);
			if ((frev == 3) ||
			    (frev == 2 && crev == 6)) {
				spll->reference_freq = le32_to_cpu(gfx_info->v30.golden_tsc_count_lower_refclk);
				ret = 0;
			} else if ((frev == 2) &&
				   (crev >= 2) &&
				   (crev != 6)) {
				spll->reference_freq = le32_to_cpu(gfx_info->v22.rlc_gpu_timer_refclk);
				ret = 0;
			} else {
				BUG();
			}
		}
	}

	return ret;
}

int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index;
	uint8_t frev, crev;
	uint16_t data_offset;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    gfx_info);
	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
				   &frev, &crev, &data_offset)) {
		union gfx_info *gfx_info = (union gfx_info *)
			(mode_info->atom_context->bios + data_offset);
		if (frev == 2) {
			switch (crev) {
			case 4:
				adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines;
				adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh;
				adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se;
				adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se;
				adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches;
				adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs);
				adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds;
				adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth;
				adev->gfx.config.gs_prim_buffer_depth =
					le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth);
				adev->gfx.config.double_offchip_lds_buf =
					gfx_info->v24.gc_double_offchip_lds_buffer;
				adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size);
				adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd);
				adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu;
				adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size);
				return 0;
			case 7:
				adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines;
				adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh;
				adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se;
				adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se;
				adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches;
				adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs);
				adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds;
				adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth;
				adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth);
				adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer;
				adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size);
				adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd);
				adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu;
				adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size);
				return 0;
			default:
				return -EINVAL;
			}
		} else if (frev == 3) {
			switch (crev) {
			case 0:
				adev->gfx.config.max_shader_engines = gfx_info->v30.max_shader_engines;
				adev->gfx.config.max_cu_per_sh = gfx_info->v30.max_cu_per_sh;
				adev->gfx.config.max_sh_per_se = gfx_info->v30.max_sh_per_se;
				adev->gfx.config.max_backends_per_se = gfx_info->v30.max_backends_per_se;
				adev->gfx.config.max_texture_channel_caches = gfx_info->v30.max_texture_channel_caches;
				return 0;
			default:
				return -EINVAL;
			}
		} else {
			return -EINVAL;
		}

	}
	return -EINVAL;
}

/*
 * Helper function to query two stage mem training capability
 *
 * @adev: amdgpu_device pointer
 *
 * Return true if two stage mem training is supported or false if not
 */
bool amdgpu_atomfirmware_mem_training_supported(struct amdgpu_device *adev)
{
	u32 fw_cap;

	fw_cap = adev->mode_info.firmware_flags;

	return (fw_cap & ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) ? true : false;
}

int amdgpu_atomfirmware_get_fw_reserved_fb_size(struct amdgpu_device *adev)
{
	struct atom_context *ctx = adev->mode_info.atom_context;
	union firmware_info *firmware_info;
	int index;
	u16 data_offset, size;
	u8 frev, crev;
	int fw_reserved_fb_size;

	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
			firmwareinfo);

	if (!amdgpu_atom_parse_data_header(ctx, index, &size,
				&frev, &crev, &data_offset))
		/* fail to parse data_header */
		return 0;

	firmware_info = (union firmware_info *)(ctx->bios + data_offset);

	if (frev != 3)
		return -EINVAL;

	switch (crev) {
	case 4:
		fw_reserved_fb_size =
			(firmware_info->v34.fw_reserved_size_in_kb << 10);
		break;
	case 5:
		fw_reserved_fb_size =
			(firmware_info->v35.fw_reserved_size_in_kb << 10);
		break;
	default:
		fw_reserved_fb_size = 0;
		break;
	}

	return fw_reserved_fb_size;
}

/*
 * Helper function to execute asic_init table
 *
 * @adev: amdgpu_device pointer
 * @fb_reset: flag to indicate whether fb is reset or not
 *
 * Return 0 if succeed, otherwise failed
 */
int amdgpu_atomfirmware_asic_init(struct amdgpu_device *adev, bool fb_reset)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	struct atom_context *ctx;
	uint8_t frev, crev;
	uint16_t data_offset;
	uint32_t bootup_sclk_in10khz, bootup_mclk_in10khz;
	struct asic_init_ps_allocation_v2_1 asic_init_ps_v2_1;
	int index;

	if (!mode_info)
		return -EINVAL;

	ctx = mode_info->atom_context;
	if (!ctx)
		return -EINVAL;

	/* query bootup sclk/mclk from firmware_info table */
	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
					    firmwareinfo);
	if (amdgpu_atom_parse_data_header(ctx, index, NULL,
				&frev, &crev, &data_offset)) {
		union firmware_info *firmware_info =
			(union firmware_info *)(ctx->bios +
						data_offset);

		bootup_sclk_in10khz =
			le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
		bootup_mclk_in10khz =
			le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
	} else {
		return -EINVAL;
	}

	index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1,
					asic_init);
	if (amdgpu_atom_parse_cmd_header(mode_info->atom_context, index, &frev, &crev)) {
		if (frev == 2 && crev >= 1) {
			memset(&asic_init_ps_v2_1, 0, sizeof(asic_init_ps_v2_1));
			asic_init_ps_v2_1.param.engineparam.sclkfreqin10khz = bootup_sclk_in10khz;
			asic_init_ps_v2_1.param.memparam.mclkfreqin10khz = bootup_mclk_in10khz;
			asic_init_ps_v2_1.param.engineparam.engineflag = b3NORMAL_ENGINE_INIT;
			if (!fb_reset)
				asic_init_ps_v2_1.param.memparam.memflag = b3DRAM_SELF_REFRESH_EXIT;
			else
				asic_init_ps_v2_1.param.memparam.memflag = 0;
		} else {
			return -EINVAL;
		}
	} else {
		return -EINVAL;
	}

	return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1,
		sizeof(asic_init_ps_v2_1));
}
