162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright © 2020 Intel Corporation
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/string_helpers.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "i915_drv.h"
962306a36Sopenharmony_ci#include "i915_reg.h"
1062306a36Sopenharmony_ci#include "intel_dram.h"
1162306a36Sopenharmony_ci#include "intel_mchbar_regs.h"
1262306a36Sopenharmony_ci#include "intel_pcode.h"
1362306a36Sopenharmony_ci#include "vlv_sideband.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct dram_dimm_info {
1662306a36Sopenharmony_ci	u16 size;
1762306a36Sopenharmony_ci	u8 width, ranks;
1862306a36Sopenharmony_ci};
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistruct dram_channel_info {
2162306a36Sopenharmony_ci	struct dram_dimm_info dimm_l, dimm_s;
2262306a36Sopenharmony_ci	u8 ranks;
2362306a36Sopenharmony_ci	bool is_16gb_dimm;
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define DRAM_TYPE_STR(type) [INTEL_DRAM_ ## type] = #type
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic const char *intel_dram_type_str(enum intel_dram_type type)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	static const char * const str[] = {
3162306a36Sopenharmony_ci		DRAM_TYPE_STR(UNKNOWN),
3262306a36Sopenharmony_ci		DRAM_TYPE_STR(DDR3),
3362306a36Sopenharmony_ci		DRAM_TYPE_STR(DDR4),
3462306a36Sopenharmony_ci		DRAM_TYPE_STR(LPDDR3),
3562306a36Sopenharmony_ci		DRAM_TYPE_STR(LPDDR4),
3662306a36Sopenharmony_ci	};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	if (type >= ARRAY_SIZE(str))
3962306a36Sopenharmony_ci		type = INTEL_DRAM_UNKNOWN;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	return str[type];
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#undef DRAM_TYPE_STR
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic void pnv_detect_mem_freq(struct drm_i915_private *dev_priv)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	u32 tmp;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	switch (tmp & CLKCFG_FSB_MASK) {
5362306a36Sopenharmony_ci	case CLKCFG_FSB_533:
5462306a36Sopenharmony_ci		dev_priv->fsb_freq = 533; /* 133*4 */
5562306a36Sopenharmony_ci		break;
5662306a36Sopenharmony_ci	case CLKCFG_FSB_800:
5762306a36Sopenharmony_ci		dev_priv->fsb_freq = 800; /* 200*4 */
5862306a36Sopenharmony_ci		break;
5962306a36Sopenharmony_ci	case CLKCFG_FSB_667:
6062306a36Sopenharmony_ci		dev_priv->fsb_freq =  667; /* 167*4 */
6162306a36Sopenharmony_ci		break;
6262306a36Sopenharmony_ci	case CLKCFG_FSB_400:
6362306a36Sopenharmony_ci		dev_priv->fsb_freq = 400; /* 100*4 */
6462306a36Sopenharmony_ci		break;
6562306a36Sopenharmony_ci	}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	switch (tmp & CLKCFG_MEM_MASK) {
6862306a36Sopenharmony_ci	case CLKCFG_MEM_533:
6962306a36Sopenharmony_ci		dev_priv->mem_freq = 533;
7062306a36Sopenharmony_ci		break;
7162306a36Sopenharmony_ci	case CLKCFG_MEM_667:
7262306a36Sopenharmony_ci		dev_priv->mem_freq = 667;
7362306a36Sopenharmony_ci		break;
7462306a36Sopenharmony_ci	case CLKCFG_MEM_800:
7562306a36Sopenharmony_ci		dev_priv->mem_freq = 800;
7662306a36Sopenharmony_ci		break;
7762306a36Sopenharmony_ci	}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/* detect pineview DDR3 setting */
8062306a36Sopenharmony_ci	tmp = intel_uncore_read(&dev_priv->uncore, CSHRDDR3CTL);
8162306a36Sopenharmony_ci	dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic void ilk_detect_mem_freq(struct drm_i915_private *dev_priv)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	u16 ddrpll, csipll;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1);
8962306a36Sopenharmony_ci	switch (ddrpll & 0xff) {
9062306a36Sopenharmony_ci	case 0xc:
9162306a36Sopenharmony_ci		dev_priv->mem_freq = 800;
9262306a36Sopenharmony_ci		break;
9362306a36Sopenharmony_ci	case 0x10:
9462306a36Sopenharmony_ci		dev_priv->mem_freq = 1066;
9562306a36Sopenharmony_ci		break;
9662306a36Sopenharmony_ci	case 0x14:
9762306a36Sopenharmony_ci		dev_priv->mem_freq = 1333;
9862306a36Sopenharmony_ci		break;
9962306a36Sopenharmony_ci	case 0x18:
10062306a36Sopenharmony_ci		dev_priv->mem_freq = 1600;
10162306a36Sopenharmony_ci		break;
10262306a36Sopenharmony_ci	default:
10362306a36Sopenharmony_ci		drm_dbg(&dev_priv->drm, "unknown memory frequency 0x%02x\n",
10462306a36Sopenharmony_ci			ddrpll & 0xff);
10562306a36Sopenharmony_ci		dev_priv->mem_freq = 0;
10662306a36Sopenharmony_ci		break;
10762306a36Sopenharmony_ci	}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	csipll = intel_uncore_read16(&dev_priv->uncore, CSIPLL0);
11062306a36Sopenharmony_ci	switch (csipll & 0x3ff) {
11162306a36Sopenharmony_ci	case 0x00c:
11262306a36Sopenharmony_ci		dev_priv->fsb_freq = 3200;
11362306a36Sopenharmony_ci		break;
11462306a36Sopenharmony_ci	case 0x00e:
11562306a36Sopenharmony_ci		dev_priv->fsb_freq = 3733;
11662306a36Sopenharmony_ci		break;
11762306a36Sopenharmony_ci	case 0x010:
11862306a36Sopenharmony_ci		dev_priv->fsb_freq = 4266;
11962306a36Sopenharmony_ci		break;
12062306a36Sopenharmony_ci	case 0x012:
12162306a36Sopenharmony_ci		dev_priv->fsb_freq = 4800;
12262306a36Sopenharmony_ci		break;
12362306a36Sopenharmony_ci	case 0x014:
12462306a36Sopenharmony_ci		dev_priv->fsb_freq = 5333;
12562306a36Sopenharmony_ci		break;
12662306a36Sopenharmony_ci	case 0x016:
12762306a36Sopenharmony_ci		dev_priv->fsb_freq = 5866;
12862306a36Sopenharmony_ci		break;
12962306a36Sopenharmony_ci	case 0x018:
13062306a36Sopenharmony_ci		dev_priv->fsb_freq = 6400;
13162306a36Sopenharmony_ci		break;
13262306a36Sopenharmony_ci	default:
13362306a36Sopenharmony_ci		drm_dbg(&dev_priv->drm, "unknown fsb frequency 0x%04x\n",
13462306a36Sopenharmony_ci			csipll & 0x3ff);
13562306a36Sopenharmony_ci		dev_priv->fsb_freq = 0;
13662306a36Sopenharmony_ci		break;
13762306a36Sopenharmony_ci	}
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic void chv_detect_mem_freq(struct drm_i915_private *i915)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	u32 val;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_CCK));
14562306a36Sopenharmony_ci	val = vlv_cck_read(i915, CCK_FUSE_REG);
14662306a36Sopenharmony_ci	vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_CCK));
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	switch ((val >> 2) & 0x7) {
14962306a36Sopenharmony_ci	case 3:
15062306a36Sopenharmony_ci		i915->mem_freq = 2000;
15162306a36Sopenharmony_ci		break;
15262306a36Sopenharmony_ci	default:
15362306a36Sopenharmony_ci		i915->mem_freq = 1600;
15462306a36Sopenharmony_ci		break;
15562306a36Sopenharmony_ci	}
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic void vlv_detect_mem_freq(struct drm_i915_private *i915)
15962306a36Sopenharmony_ci{
16062306a36Sopenharmony_ci	u32 val;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_PUNIT));
16362306a36Sopenharmony_ci	val = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
16462306a36Sopenharmony_ci	vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_PUNIT));
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	switch ((val >> 6) & 3) {
16762306a36Sopenharmony_ci	case 0:
16862306a36Sopenharmony_ci	case 1:
16962306a36Sopenharmony_ci		i915->mem_freq = 800;
17062306a36Sopenharmony_ci		break;
17162306a36Sopenharmony_ci	case 2:
17262306a36Sopenharmony_ci		i915->mem_freq = 1066;
17362306a36Sopenharmony_ci		break;
17462306a36Sopenharmony_ci	case 3:
17562306a36Sopenharmony_ci		i915->mem_freq = 1333;
17662306a36Sopenharmony_ci		break;
17762306a36Sopenharmony_ci	}
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_cistatic void detect_mem_freq(struct drm_i915_private *i915)
18162306a36Sopenharmony_ci{
18262306a36Sopenharmony_ci	if (IS_PINEVIEW(i915))
18362306a36Sopenharmony_ci		pnv_detect_mem_freq(i915);
18462306a36Sopenharmony_ci	else if (GRAPHICS_VER(i915) == 5)
18562306a36Sopenharmony_ci		ilk_detect_mem_freq(i915);
18662306a36Sopenharmony_ci	else if (IS_CHERRYVIEW(i915))
18762306a36Sopenharmony_ci		chv_detect_mem_freq(i915);
18862306a36Sopenharmony_ci	else if (IS_VALLEYVIEW(i915))
18962306a36Sopenharmony_ci		vlv_detect_mem_freq(i915);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	if (i915->mem_freq)
19262306a36Sopenharmony_ci		drm_dbg(&i915->drm, "DDR speed: %d MHz\n", i915->mem_freq);
19362306a36Sopenharmony_ci}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_cistatic int intel_dimm_num_devices(const struct dram_dimm_info *dimm)
19662306a36Sopenharmony_ci{
19762306a36Sopenharmony_ci	return dimm->ranks * 64 / (dimm->width ?: 1);
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci/* Returns total Gb for the whole DIMM */
20162306a36Sopenharmony_cistatic int skl_get_dimm_size(u16 val)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	return (val & SKL_DRAM_SIZE_MASK) * 8;
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic int skl_get_dimm_width(u16 val)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	if (skl_get_dimm_size(val) == 0)
20962306a36Sopenharmony_ci		return 0;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	switch (val & SKL_DRAM_WIDTH_MASK) {
21262306a36Sopenharmony_ci	case SKL_DRAM_WIDTH_X8:
21362306a36Sopenharmony_ci	case SKL_DRAM_WIDTH_X16:
21462306a36Sopenharmony_ci	case SKL_DRAM_WIDTH_X32:
21562306a36Sopenharmony_ci		val = (val & SKL_DRAM_WIDTH_MASK) >> SKL_DRAM_WIDTH_SHIFT;
21662306a36Sopenharmony_ci		return 8 << val;
21762306a36Sopenharmony_ci	default:
21862306a36Sopenharmony_ci		MISSING_CASE(val);
21962306a36Sopenharmony_ci		return 0;
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistatic int skl_get_dimm_ranks(u16 val)
22462306a36Sopenharmony_ci{
22562306a36Sopenharmony_ci	if (skl_get_dimm_size(val) == 0)
22662306a36Sopenharmony_ci		return 0;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	val = (val & SKL_DRAM_RANK_MASK) >> SKL_DRAM_RANK_SHIFT;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	return val + 1;
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/* Returns total Gb for the whole DIMM */
23462306a36Sopenharmony_cistatic int icl_get_dimm_size(u16 val)
23562306a36Sopenharmony_ci{
23662306a36Sopenharmony_ci	return (val & ICL_DRAM_SIZE_MASK) * 8 / 2;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic int icl_get_dimm_width(u16 val)
24062306a36Sopenharmony_ci{
24162306a36Sopenharmony_ci	if (icl_get_dimm_size(val) == 0)
24262306a36Sopenharmony_ci		return 0;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	switch (val & ICL_DRAM_WIDTH_MASK) {
24562306a36Sopenharmony_ci	case ICL_DRAM_WIDTH_X8:
24662306a36Sopenharmony_ci	case ICL_DRAM_WIDTH_X16:
24762306a36Sopenharmony_ci	case ICL_DRAM_WIDTH_X32:
24862306a36Sopenharmony_ci		val = (val & ICL_DRAM_WIDTH_MASK) >> ICL_DRAM_WIDTH_SHIFT;
24962306a36Sopenharmony_ci		return 8 << val;
25062306a36Sopenharmony_ci	default:
25162306a36Sopenharmony_ci		MISSING_CASE(val);
25262306a36Sopenharmony_ci		return 0;
25362306a36Sopenharmony_ci	}
25462306a36Sopenharmony_ci}
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic int icl_get_dimm_ranks(u16 val)
25762306a36Sopenharmony_ci{
25862306a36Sopenharmony_ci	if (icl_get_dimm_size(val) == 0)
25962306a36Sopenharmony_ci		return 0;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	val = (val & ICL_DRAM_RANK_MASK) >> ICL_DRAM_RANK_SHIFT;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	return val + 1;
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic bool
26762306a36Sopenharmony_ciskl_is_16gb_dimm(const struct dram_dimm_info *dimm)
26862306a36Sopenharmony_ci{
26962306a36Sopenharmony_ci	/* Convert total Gb to Gb per DRAM device */
27062306a36Sopenharmony_ci	return dimm->size / (intel_dimm_num_devices(dimm) ?: 1) == 16;
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_cistatic void
27462306a36Sopenharmony_ciskl_dram_get_dimm_info(struct drm_i915_private *i915,
27562306a36Sopenharmony_ci		       struct dram_dimm_info *dimm,
27662306a36Sopenharmony_ci		       int channel, char dimm_name, u16 val)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	if (GRAPHICS_VER(i915) >= 11) {
27962306a36Sopenharmony_ci		dimm->size = icl_get_dimm_size(val);
28062306a36Sopenharmony_ci		dimm->width = icl_get_dimm_width(val);
28162306a36Sopenharmony_ci		dimm->ranks = icl_get_dimm_ranks(val);
28262306a36Sopenharmony_ci	} else {
28362306a36Sopenharmony_ci		dimm->size = skl_get_dimm_size(val);
28462306a36Sopenharmony_ci		dimm->width = skl_get_dimm_width(val);
28562306a36Sopenharmony_ci		dimm->ranks = skl_get_dimm_ranks(val);
28662306a36Sopenharmony_ci	}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm,
28962306a36Sopenharmony_ci		    "CH%u DIMM %c size: %u Gb, width: X%u, ranks: %u, 16Gb DIMMs: %s\n",
29062306a36Sopenharmony_ci		    channel, dimm_name, dimm->size, dimm->width, dimm->ranks,
29162306a36Sopenharmony_ci		    str_yes_no(skl_is_16gb_dimm(dimm)));
29262306a36Sopenharmony_ci}
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistatic int
29562306a36Sopenharmony_ciskl_dram_get_channel_info(struct drm_i915_private *i915,
29662306a36Sopenharmony_ci			  struct dram_channel_info *ch,
29762306a36Sopenharmony_ci			  int channel, u32 val)
29862306a36Sopenharmony_ci{
29962306a36Sopenharmony_ci	skl_dram_get_dimm_info(i915, &ch->dimm_l,
30062306a36Sopenharmony_ci			       channel, 'L', val & 0xffff);
30162306a36Sopenharmony_ci	skl_dram_get_dimm_info(i915, &ch->dimm_s,
30262306a36Sopenharmony_ci			       channel, 'S', val >> 16);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	if (ch->dimm_l.size == 0 && ch->dimm_s.size == 0) {
30562306a36Sopenharmony_ci		drm_dbg_kms(&i915->drm, "CH%u not populated\n", channel);
30662306a36Sopenharmony_ci		return -EINVAL;
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	if (ch->dimm_l.ranks == 2 || ch->dimm_s.ranks == 2)
31062306a36Sopenharmony_ci		ch->ranks = 2;
31162306a36Sopenharmony_ci	else if (ch->dimm_l.ranks == 1 && ch->dimm_s.ranks == 1)
31262306a36Sopenharmony_ci		ch->ranks = 2;
31362306a36Sopenharmony_ci	else
31462306a36Sopenharmony_ci		ch->ranks = 1;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	ch->is_16gb_dimm = skl_is_16gb_dimm(&ch->dimm_l) ||
31762306a36Sopenharmony_ci		skl_is_16gb_dimm(&ch->dimm_s);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm, "CH%u ranks: %u, 16Gb DIMMs: %s\n",
32062306a36Sopenharmony_ci		    channel, ch->ranks, str_yes_no(ch->is_16gb_dimm));
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	return 0;
32362306a36Sopenharmony_ci}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_cistatic bool
32662306a36Sopenharmony_ciintel_is_dram_symmetric(const struct dram_channel_info *ch0,
32762306a36Sopenharmony_ci			const struct dram_channel_info *ch1)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	return !memcmp(ch0, ch1, sizeof(*ch0)) &&
33062306a36Sopenharmony_ci		(ch0->dimm_s.size == 0 ||
33162306a36Sopenharmony_ci		 !memcmp(&ch0->dimm_l, &ch0->dimm_s, sizeof(ch0->dimm_l)));
33262306a36Sopenharmony_ci}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_cistatic int
33562306a36Sopenharmony_ciskl_dram_get_channels_info(struct drm_i915_private *i915)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	struct dram_info *dram_info = &i915->dram_info;
33862306a36Sopenharmony_ci	struct dram_channel_info ch0 = {}, ch1 = {};
33962306a36Sopenharmony_ci	u32 val;
34062306a36Sopenharmony_ci	int ret;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	val = intel_uncore_read(&i915->uncore,
34362306a36Sopenharmony_ci				SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
34462306a36Sopenharmony_ci	ret = skl_dram_get_channel_info(i915, &ch0, 0, val);
34562306a36Sopenharmony_ci	if (ret == 0)
34662306a36Sopenharmony_ci		dram_info->num_channels++;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	val = intel_uncore_read(&i915->uncore,
34962306a36Sopenharmony_ci				SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
35062306a36Sopenharmony_ci	ret = skl_dram_get_channel_info(i915, &ch1, 1, val);
35162306a36Sopenharmony_ci	if (ret == 0)
35262306a36Sopenharmony_ci		dram_info->num_channels++;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	if (dram_info->num_channels == 0) {
35562306a36Sopenharmony_ci		drm_info(&i915->drm, "Number of memory channels is zero\n");
35662306a36Sopenharmony_ci		return -EINVAL;
35762306a36Sopenharmony_ci	}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	if (ch0.ranks == 0 && ch1.ranks == 0) {
36062306a36Sopenharmony_ci		drm_info(&i915->drm, "couldn't get memory rank information\n");
36162306a36Sopenharmony_ci		return -EINVAL;
36262306a36Sopenharmony_ci	}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	dram_info->wm_lv_0_adjust_needed = ch0.is_16gb_dimm || ch1.is_16gb_dimm;
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	dram_info->symmetric_memory = intel_is_dram_symmetric(&ch0, &ch1);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm, "Memory configuration is symmetric? %s\n",
36962306a36Sopenharmony_ci		    str_yes_no(dram_info->symmetric_memory));
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	return 0;
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_cistatic enum intel_dram_type
37562306a36Sopenharmony_ciskl_get_dram_type(struct drm_i915_private *i915)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	u32 val;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	val = intel_uncore_read(&i915->uncore,
38062306a36Sopenharmony_ci				SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN);
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	switch (val & SKL_DRAM_DDR_TYPE_MASK) {
38362306a36Sopenharmony_ci	case SKL_DRAM_DDR_TYPE_DDR3:
38462306a36Sopenharmony_ci		return INTEL_DRAM_DDR3;
38562306a36Sopenharmony_ci	case SKL_DRAM_DDR_TYPE_DDR4:
38662306a36Sopenharmony_ci		return INTEL_DRAM_DDR4;
38762306a36Sopenharmony_ci	case SKL_DRAM_DDR_TYPE_LPDDR3:
38862306a36Sopenharmony_ci		return INTEL_DRAM_LPDDR3;
38962306a36Sopenharmony_ci	case SKL_DRAM_DDR_TYPE_LPDDR4:
39062306a36Sopenharmony_ci		return INTEL_DRAM_LPDDR4;
39162306a36Sopenharmony_ci	default:
39262306a36Sopenharmony_ci		MISSING_CASE(val);
39362306a36Sopenharmony_ci		return INTEL_DRAM_UNKNOWN;
39462306a36Sopenharmony_ci	}
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic int
39862306a36Sopenharmony_ciskl_get_dram_info(struct drm_i915_private *i915)
39962306a36Sopenharmony_ci{
40062306a36Sopenharmony_ci	struct dram_info *dram_info = &i915->dram_info;
40162306a36Sopenharmony_ci	int ret;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	dram_info->type = skl_get_dram_type(i915);
40462306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm, "DRAM type: %s\n",
40562306a36Sopenharmony_ci		    intel_dram_type_str(dram_info->type));
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	ret = skl_dram_get_channels_info(i915);
40862306a36Sopenharmony_ci	if (ret)
40962306a36Sopenharmony_ci		return ret;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	return 0;
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci/* Returns Gb per DRAM device */
41562306a36Sopenharmony_cistatic int bxt_get_dimm_size(u32 val)
41662306a36Sopenharmony_ci{
41762306a36Sopenharmony_ci	switch (val & BXT_DRAM_SIZE_MASK) {
41862306a36Sopenharmony_ci	case BXT_DRAM_SIZE_4GBIT:
41962306a36Sopenharmony_ci		return 4;
42062306a36Sopenharmony_ci	case BXT_DRAM_SIZE_6GBIT:
42162306a36Sopenharmony_ci		return 6;
42262306a36Sopenharmony_ci	case BXT_DRAM_SIZE_8GBIT:
42362306a36Sopenharmony_ci		return 8;
42462306a36Sopenharmony_ci	case BXT_DRAM_SIZE_12GBIT:
42562306a36Sopenharmony_ci		return 12;
42662306a36Sopenharmony_ci	case BXT_DRAM_SIZE_16GBIT:
42762306a36Sopenharmony_ci		return 16;
42862306a36Sopenharmony_ci	default:
42962306a36Sopenharmony_ci		MISSING_CASE(val);
43062306a36Sopenharmony_ci		return 0;
43162306a36Sopenharmony_ci	}
43262306a36Sopenharmony_ci}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_cistatic int bxt_get_dimm_width(u32 val)
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci	if (!bxt_get_dimm_size(val))
43762306a36Sopenharmony_ci		return 0;
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci	val = (val & BXT_DRAM_WIDTH_MASK) >> BXT_DRAM_WIDTH_SHIFT;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	return 8 << val;
44262306a36Sopenharmony_ci}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic int bxt_get_dimm_ranks(u32 val)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	if (!bxt_get_dimm_size(val))
44762306a36Sopenharmony_ci		return 0;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	switch (val & BXT_DRAM_RANK_MASK) {
45062306a36Sopenharmony_ci	case BXT_DRAM_RANK_SINGLE:
45162306a36Sopenharmony_ci		return 1;
45262306a36Sopenharmony_ci	case BXT_DRAM_RANK_DUAL:
45362306a36Sopenharmony_ci		return 2;
45462306a36Sopenharmony_ci	default:
45562306a36Sopenharmony_ci		MISSING_CASE(val);
45662306a36Sopenharmony_ci		return 0;
45762306a36Sopenharmony_ci	}
45862306a36Sopenharmony_ci}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_cistatic enum intel_dram_type bxt_get_dimm_type(u32 val)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	if (!bxt_get_dimm_size(val))
46362306a36Sopenharmony_ci		return INTEL_DRAM_UNKNOWN;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	switch (val & BXT_DRAM_TYPE_MASK) {
46662306a36Sopenharmony_ci	case BXT_DRAM_TYPE_DDR3:
46762306a36Sopenharmony_ci		return INTEL_DRAM_DDR3;
46862306a36Sopenharmony_ci	case BXT_DRAM_TYPE_LPDDR3:
46962306a36Sopenharmony_ci		return INTEL_DRAM_LPDDR3;
47062306a36Sopenharmony_ci	case BXT_DRAM_TYPE_DDR4:
47162306a36Sopenharmony_ci		return INTEL_DRAM_DDR4;
47262306a36Sopenharmony_ci	case BXT_DRAM_TYPE_LPDDR4:
47362306a36Sopenharmony_ci		return INTEL_DRAM_LPDDR4;
47462306a36Sopenharmony_ci	default:
47562306a36Sopenharmony_ci		MISSING_CASE(val);
47662306a36Sopenharmony_ci		return INTEL_DRAM_UNKNOWN;
47762306a36Sopenharmony_ci	}
47862306a36Sopenharmony_ci}
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_cistatic void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val)
48162306a36Sopenharmony_ci{
48262306a36Sopenharmony_ci	dimm->width = bxt_get_dimm_width(val);
48362306a36Sopenharmony_ci	dimm->ranks = bxt_get_dimm_ranks(val);
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	/*
48662306a36Sopenharmony_ci	 * Size in register is Gb per DRAM device. Convert to total
48762306a36Sopenharmony_ci	 * Gb to match the way we report this for non-LP platforms.
48862306a36Sopenharmony_ci	 */
48962306a36Sopenharmony_ci	dimm->size = bxt_get_dimm_size(val) * intel_dimm_num_devices(dimm);
49062306a36Sopenharmony_ci}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistatic int bxt_get_dram_info(struct drm_i915_private *i915)
49362306a36Sopenharmony_ci{
49462306a36Sopenharmony_ci	struct dram_info *dram_info = &i915->dram_info;
49562306a36Sopenharmony_ci	u32 val;
49662306a36Sopenharmony_ci	u8 valid_ranks = 0;
49762306a36Sopenharmony_ci	int i;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	/*
50062306a36Sopenharmony_ci	 * Now read each DUNIT8/9/10/11 to check the rank of each dimms.
50162306a36Sopenharmony_ci	 */
50262306a36Sopenharmony_ci	for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) {
50362306a36Sopenharmony_ci		struct dram_dimm_info dimm;
50462306a36Sopenharmony_ci		enum intel_dram_type type;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci		val = intel_uncore_read(&i915->uncore, BXT_D_CR_DRP0_DUNIT(i));
50762306a36Sopenharmony_ci		if (val == 0xFFFFFFFF)
50862306a36Sopenharmony_ci			continue;
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci		dram_info->num_channels++;
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci		bxt_get_dimm_info(&dimm, val);
51362306a36Sopenharmony_ci		type = bxt_get_dimm_type(val);
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci		drm_WARN_ON(&i915->drm, type != INTEL_DRAM_UNKNOWN &&
51662306a36Sopenharmony_ci			    dram_info->type != INTEL_DRAM_UNKNOWN &&
51762306a36Sopenharmony_ci			    dram_info->type != type);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci		drm_dbg_kms(&i915->drm,
52062306a36Sopenharmony_ci			    "CH%u DIMM size: %u Gb, width: X%u, ranks: %u, type: %s\n",
52162306a36Sopenharmony_ci			    i - BXT_D_CR_DRP0_DUNIT_START,
52262306a36Sopenharmony_ci			    dimm.size, dimm.width, dimm.ranks,
52362306a36Sopenharmony_ci			    intel_dram_type_str(type));
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci		if (valid_ranks == 0)
52662306a36Sopenharmony_ci			valid_ranks = dimm.ranks;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci		if (type != INTEL_DRAM_UNKNOWN)
52962306a36Sopenharmony_ci			dram_info->type = type;
53062306a36Sopenharmony_ci	}
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	if (dram_info->type == INTEL_DRAM_UNKNOWN || valid_ranks == 0) {
53362306a36Sopenharmony_ci		drm_info(&i915->drm, "couldn't get memory information\n");
53462306a36Sopenharmony_ci		return -EINVAL;
53562306a36Sopenharmony_ci	}
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	return 0;
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv)
54162306a36Sopenharmony_ci{
54262306a36Sopenharmony_ci	struct dram_info *dram_info = &dev_priv->dram_info;
54362306a36Sopenharmony_ci	u32 val = 0;
54462306a36Sopenharmony_ci	int ret;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
54762306a36Sopenharmony_ci			     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL);
54862306a36Sopenharmony_ci	if (ret)
54962306a36Sopenharmony_ci		return ret;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	if (GRAPHICS_VER(dev_priv) == 12) {
55262306a36Sopenharmony_ci		switch (val & 0xf) {
55362306a36Sopenharmony_ci		case 0:
55462306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_DDR4;
55562306a36Sopenharmony_ci			break;
55662306a36Sopenharmony_ci		case 1:
55762306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_DDR5;
55862306a36Sopenharmony_ci			break;
55962306a36Sopenharmony_ci		case 2:
56062306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_LPDDR5;
56162306a36Sopenharmony_ci			break;
56262306a36Sopenharmony_ci		case 3:
56362306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_LPDDR4;
56462306a36Sopenharmony_ci			break;
56562306a36Sopenharmony_ci		case 4:
56662306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_DDR3;
56762306a36Sopenharmony_ci			break;
56862306a36Sopenharmony_ci		case 5:
56962306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_LPDDR3;
57062306a36Sopenharmony_ci			break;
57162306a36Sopenharmony_ci		default:
57262306a36Sopenharmony_ci			MISSING_CASE(val & 0xf);
57362306a36Sopenharmony_ci			return -EINVAL;
57462306a36Sopenharmony_ci		}
57562306a36Sopenharmony_ci	} else {
57662306a36Sopenharmony_ci		switch (val & 0xf) {
57762306a36Sopenharmony_ci		case 0:
57862306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_DDR4;
57962306a36Sopenharmony_ci			break;
58062306a36Sopenharmony_ci		case 1:
58162306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_DDR3;
58262306a36Sopenharmony_ci			break;
58362306a36Sopenharmony_ci		case 2:
58462306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_LPDDR3;
58562306a36Sopenharmony_ci			break;
58662306a36Sopenharmony_ci		case 3:
58762306a36Sopenharmony_ci			dram_info->type = INTEL_DRAM_LPDDR4;
58862306a36Sopenharmony_ci			break;
58962306a36Sopenharmony_ci		default:
59062306a36Sopenharmony_ci			MISSING_CASE(val & 0xf);
59162306a36Sopenharmony_ci			return -EINVAL;
59262306a36Sopenharmony_ci		}
59362306a36Sopenharmony_ci	}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	dram_info->num_channels = (val & 0xf0) >> 4;
59662306a36Sopenharmony_ci	dram_info->num_qgv_points = (val & 0xf00) >> 8;
59762306a36Sopenharmony_ci	dram_info->num_psf_gv_points = (val & 0x3000) >> 12;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	return 0;
60062306a36Sopenharmony_ci}
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_cistatic int gen11_get_dram_info(struct drm_i915_private *i915)
60362306a36Sopenharmony_ci{
60462306a36Sopenharmony_ci	int ret = skl_get_dram_info(i915);
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	if (ret)
60762306a36Sopenharmony_ci		return ret;
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	return icl_pcode_read_mem_global_info(i915);
61062306a36Sopenharmony_ci}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_cistatic int gen12_get_dram_info(struct drm_i915_private *i915)
61362306a36Sopenharmony_ci{
61462306a36Sopenharmony_ci	i915->dram_info.wm_lv_0_adjust_needed = false;
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci	return icl_pcode_read_mem_global_info(i915);
61762306a36Sopenharmony_ci}
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_cistatic int xelpdp_get_dram_info(struct drm_i915_private *i915)
62062306a36Sopenharmony_ci{
62162306a36Sopenharmony_ci	u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
62262306a36Sopenharmony_ci	struct dram_info *dram_info = &i915->dram_info;
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
62562306a36Sopenharmony_ci	case 0:
62662306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_DDR4;
62762306a36Sopenharmony_ci		break;
62862306a36Sopenharmony_ci	case 1:
62962306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_DDR5;
63062306a36Sopenharmony_ci		break;
63162306a36Sopenharmony_ci	case 2:
63262306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_LPDDR5;
63362306a36Sopenharmony_ci		break;
63462306a36Sopenharmony_ci	case 3:
63562306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_LPDDR4;
63662306a36Sopenharmony_ci		break;
63762306a36Sopenharmony_ci	case 4:
63862306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_DDR3;
63962306a36Sopenharmony_ci		break;
64062306a36Sopenharmony_ci	case 5:
64162306a36Sopenharmony_ci		dram_info->type = INTEL_DRAM_LPDDR3;
64262306a36Sopenharmony_ci		break;
64362306a36Sopenharmony_ci	default:
64462306a36Sopenharmony_ci		MISSING_CASE(val);
64562306a36Sopenharmony_ci		return -EINVAL;
64662306a36Sopenharmony_ci	}
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	dram_info->num_channels = REG_FIELD_GET(MTL_N_OF_POPULATED_CH_MASK, val);
64962306a36Sopenharmony_ci	dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
65062306a36Sopenharmony_ci	/* PSF GV points not supported in D14+ */
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	return 0;
65362306a36Sopenharmony_ci}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_civoid intel_dram_detect(struct drm_i915_private *i915)
65662306a36Sopenharmony_ci{
65762306a36Sopenharmony_ci	struct dram_info *dram_info = &i915->dram_info;
65862306a36Sopenharmony_ci	int ret;
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci	detect_mem_freq(i915);
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	if (GRAPHICS_VER(i915) < 9 || IS_DG2(i915) || !HAS_DISPLAY(i915))
66362306a36Sopenharmony_ci		return;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	/*
66662306a36Sopenharmony_ci	 * Assume level 0 watermark latency adjustment is needed until proven
66762306a36Sopenharmony_ci	 * otherwise, this w/a is not needed by bxt/glk.
66862306a36Sopenharmony_ci	 */
66962306a36Sopenharmony_ci	dram_info->wm_lv_0_adjust_needed = !IS_GEN9_LP(i915);
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	if (DISPLAY_VER(i915) >= 14)
67262306a36Sopenharmony_ci		ret = xelpdp_get_dram_info(i915);
67362306a36Sopenharmony_ci	else if (GRAPHICS_VER(i915) >= 12)
67462306a36Sopenharmony_ci		ret = gen12_get_dram_info(i915);
67562306a36Sopenharmony_ci	else if (GRAPHICS_VER(i915) >= 11)
67662306a36Sopenharmony_ci		ret = gen11_get_dram_info(i915);
67762306a36Sopenharmony_ci	else if (IS_GEN9_LP(i915))
67862306a36Sopenharmony_ci		ret = bxt_get_dram_info(i915);
67962306a36Sopenharmony_ci	else
68062306a36Sopenharmony_ci		ret = skl_get_dram_info(i915);
68162306a36Sopenharmony_ci	if (ret)
68262306a36Sopenharmony_ci		return;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm, "DRAM channels: %u\n", dram_info->num_channels);
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	drm_dbg_kms(&i915->drm, "Watermark level 0 adjustment needed: %s\n",
68762306a36Sopenharmony_ci		    str_yes_no(dram_info->wm_lv_0_adjust_needed));
68862306a36Sopenharmony_ci}
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_cistatic u32 gen9_edram_size_mb(struct drm_i915_private *i915, u32 cap)
69162306a36Sopenharmony_ci{
69262306a36Sopenharmony_ci	static const u8 ways[8] = { 4, 8, 12, 16, 16, 16, 16, 16 };
69362306a36Sopenharmony_ci	static const u8 sets[4] = { 1, 1, 2, 2 };
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	return EDRAM_NUM_BANKS(cap) *
69662306a36Sopenharmony_ci		ways[EDRAM_WAYS_IDX(cap)] *
69762306a36Sopenharmony_ci		sets[EDRAM_SETS_IDX(cap)];
69862306a36Sopenharmony_ci}
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_civoid intel_dram_edram_detect(struct drm_i915_private *i915)
70162306a36Sopenharmony_ci{
70262306a36Sopenharmony_ci	u32 edram_cap = 0;
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci	if (!(IS_HASWELL(i915) || IS_BROADWELL(i915) || GRAPHICS_VER(i915) >= 9))
70562306a36Sopenharmony_ci		return;
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	edram_cap = intel_uncore_read_fw(&i915->uncore, HSW_EDRAM_CAP);
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	/* NB: We can't write IDICR yet because we don't have gt funcs set up */
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	if (!(edram_cap & EDRAM_ENABLED))
71262306a36Sopenharmony_ci		return;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	/*
71562306a36Sopenharmony_ci	 * The needed capability bits for size calculation are not there with
71662306a36Sopenharmony_ci	 * pre gen9 so return 128MB always.
71762306a36Sopenharmony_ci	 */
71862306a36Sopenharmony_ci	if (GRAPHICS_VER(i915) < 9)
71962306a36Sopenharmony_ci		i915->edram_size_mb = 128;
72062306a36Sopenharmony_ci	else
72162306a36Sopenharmony_ci		i915->edram_size_mb = gen9_edram_size_mb(i915, edram_cap);
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	drm_info(&i915->drm, "Found %uMB of eDRAM\n", i915->edram_size_mb);
72462306a36Sopenharmony_ci}
725