Commit 02c3060e authored by Gangliang Xie's avatar Gangliang Xie Committed by Alex Deucher
Browse files

drm/amdgpu: add support to query vram info from firmware



add support to query vram info from firmware

v2: change APU vram type, add multi-aid check
v3: seperate vram info query function into 3 parts and
    call them in a helper func when requirements
    are met.
v4: calculate vram_width for v9.x

Signed-off-by: default avatarGangliang Xie <ganglxie@amd.com>
Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7b82e92d
Loading
Loading
Loading
Loading
+245 −214
Original line number Diff line number Diff line
@@ -373,42 +373,24 @@ int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
	return -ENODEV;
}

int
amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
int amdgpu_atomfirmware_get_integrated_system_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;
	int index;
	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) {
@@ -472,9 +454,30 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
			return -EINVAL;
		}
	} else {
			switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
			case IP_VERSION(12, 0, 0):
			case IP_VERSION(12, 0, 1):
		return -EINVAL;
	}
	return 0;
}

int amdgpu_atomfirmware_get_umc_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;
	u16 data_offset, size;
	union umc_info *umc_info;
	u8 frev, crev;
	u8 mem_type;
	u8 mem_vendor;
	u32 mem_channel_number;
	u32 mem_channel_width;

	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 == 4) {
@@ -494,10 +497,37 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
			default:
				return -EINVAL;
			}
				} else
		} else {
			return -EINVAL;
				break;
			default:
		}
	} else {
		return -EINVAL;
	}

	return 0;
}

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 vram_info *vram_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;

	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)) {
		vram_info = (union vram_info *)
			(mode_info->atom_context->bios + data_offset);

@@ -614,8 +644,9 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
			/* invalid frev */
			return -EINVAL;
		}
			}
		}

	} else {
		return -EINVAL;
	}

	return 0;
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *ade
bool amdgpu_atomfirmware_gpu_virtualization_supported(struct amdgpu_device *adev);
void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_integrated_system_info(struct amdgpu_device *adev,
	int *vram_width, int *vram_type, int *vram_vendor);
int amdgpu_atomfirmware_get_umc_info(struct amdgpu_device *adev,
	int *vram_width, int *vram_type, int *vram_vendor);
int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
	int *vram_width, int *vram_type, int *vram_vendor);
int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
+29 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include "amdgpu_ras.h"
#include "amdgpu_reset.h"
#include "amdgpu_xgmi.h"
#include "amdgpu_atomfirmware.h"

#include <drm/drm_drv.h>
#include <drm/ttm/ttm_tt.h>
@@ -1747,3 +1748,31 @@ int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev)

	return 0;
}

int amdgpu_gmc_get_vram_info(struct amdgpu_device *adev,
		int *vram_width, int *vram_type, int *vram_vendor)
{
	int ret = 0;

	if (adev->flags & AMD_IS_APU)
		return amdgpu_atomfirmware_get_integrated_system_info(adev,
							vram_width, vram_type, vram_vendor);
	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
	case IP_VERSION(12, 0, 0):
	case IP_VERSION(12, 0, 1):
		return amdgpu_atomfirmware_get_umc_info(adev,
								vram_width, vram_type, vram_vendor);
	case IP_VERSION(9, 5, 0):
	case IP_VERSION(9, 4, 4):
	case IP_VERSION(9, 4, 3):
		ret = amdgpu_atomfirmware_get_umc_info(adev,
								vram_width, vram_type, vram_vendor);
		if (vram_width && !ret)
			*vram_width *= hweight32(adev->aid_mask);
		return ret;
	default:
		return amdgpu_atomfirmware_get_vram_info(adev,
								vram_width, vram_type, vram_vendor);
	}
	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -482,4 +482,6 @@ amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev);
int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev);
void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev,
				   struct amdgpu_mem_partition_info *mem_ranges);
int amdgpu_gmc_get_vram_info(struct amdgpu_device *adev,
		int *vram_width, int *vram_type, int *vram_vendor);
#endif
+1 −1
Original line number Diff line number Diff line
@@ -767,7 +767,7 @@ static int gmc_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
		adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6;
		adev->gmc.vram_width = 1 * 128; /* numchan * chansize */
	} else {
		r = amdgpu_atomfirmware_get_vram_info(adev,
		r = amdgpu_gmc_get_vram_info(adev,
				&vram_width, &vram_type, &vram_vendor);
		adev->gmc.vram_width = vram_width;

Loading