Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ce65f52 authored by Harry Wentland's avatar Harry Wentland Committed by Alex Deucher
Browse files

drm/amdgpu: Read vram width from integrated system info table



On KB, KV, CZ we should read the vram width from integrated system
table, if we can. The NOOFCHAN in MC_SHARED_CHMAP is not accurate.

With this change we can enable two 4k displays on CZ again. This use
case was broken sometime in January when we started looking at
vram_width for bandwidth calculations instead of hardcoding this value.

v2:
  Return 0 if integrated system info table is not available.

Tested-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 83ca145d
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -754,6 +754,35 @@ union igp_info {
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_9 info_9;
};

/*
 * Return vram width from integrated system info table, if available,
 * or 0 if not.
 */
int amdgpu_atombios_get_vram_width(struct amdgpu_device *adev)
{
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
	u16 data_offset, size;
	union igp_info *igp_info;
	u8 frev, crev;

	/* get any igp specific overrides */
	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
				   &frev, &crev, &data_offset)) {
		igp_info = (union igp_info *)
			(mode_info->atom_context->bios + data_offset);
		switch (crev) {
		case 8:
		case 9:
			return igp_info->info_8.ucUMAChannelNumber * 64;
		default:
			return 0;
		}
	}

	return 0;
}

static void amdgpu_atombios_get_igp_ss_overrides(struct amdgpu_device *adev,
						 struct amdgpu_atom_ss *ss,
						 int id)
+2 −0
Original line number Diff line number Diff line
@@ -148,6 +148,8 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev);

int amdgpu_atombios_get_gfx_info(struct amdgpu_device *adev);

int amdgpu_atombios_get_vram_width(struct amdgpu_device *adev);

bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device *adev,
				      struct amdgpu_atom_ss *ss,
				      int id, u32 clock);
+46 −41
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"

#include "amdgpu_atombios.h"

static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev);
static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev);
static int gmc_v7_0_wait_for_idle(void *handle);
@@ -325,6 +327,8 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
 */
static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
{
	adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
	if (!adev->mc.vram_width) {
		u32 tmp;
		int chansize, numchan;

@@ -367,6 +371,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
			break;
		}
		adev->mc.vram_width = numchan * chansize;
	}
	/* Could aper size report 0 ? */
	adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
	adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
+46 −41
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#include "vid.h"
#include "vi.h"

#include "amdgpu_atombios.h"


static void gmc_v8_0_set_gart_funcs(struct amdgpu_device *adev);
static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev);
@@ -487,6 +489,8 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
 */
static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
{
	adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
	if (!adev->mc.vram_width) {
		u32 tmp;
		int chansize, numchan;

@@ -529,6 +533,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
			break;
		}
		adev->mc.vram_width = numchan * chansize;
	}
	/* Could aper size report 0 ? */
	adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
	adev->mc.aper_size = pci_resource_len(adev->pdev, 0);