Skip to content

Commit 6d9c1e9

Browse files
committed
drm/i915: Extract DIMM info on cnl+
We'll need information about the memory configuration on cnl+ too. Extend the code to parse the slightly changed register layout. v2: Document what cnl_get_dimm_size() returns (Jani) Reviewed-by: Jani Nikula <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 30a533e commit 6d9c1e9

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,39 @@ static int skl_get_dimm_ranks(u16 val)
11061106
return val + 1;
11071107
}
11081108

1109+
/* Returns total GB for the whole DIMM */
1110+
static int cnl_get_dimm_size(u16 val)
1111+
{
1112+
return (val & CNL_DRAM_SIZE_MASK) / 2;
1113+
}
1114+
1115+
static int cnl_get_dimm_width(u16 val)
1116+
{
1117+
if (cnl_get_dimm_size(val) == 0)
1118+
return 0;
1119+
1120+
switch (val & CNL_DRAM_WIDTH_MASK) {
1121+
case CNL_DRAM_WIDTH_X8:
1122+
case CNL_DRAM_WIDTH_X16:
1123+
case CNL_DRAM_WIDTH_X32:
1124+
val = (val & CNL_DRAM_WIDTH_MASK) >> CNL_DRAM_WIDTH_SHIFT;
1125+
return 8 << val;
1126+
default:
1127+
MISSING_CASE(val);
1128+
return 0;
1129+
}
1130+
}
1131+
1132+
static int cnl_get_dimm_ranks(u16 val)
1133+
{
1134+
if (cnl_get_dimm_size(val) == 0)
1135+
return 0;
1136+
1137+
val = (val & CNL_DRAM_RANK_MASK) >> CNL_DRAM_RANK_SHIFT;
1138+
1139+
return val + 1;
1140+
}
1141+
11091142
static bool
11101143
skl_is_16gb_dimm(const struct dram_dimm_info *dimm)
11111144
{
@@ -1114,24 +1147,34 @@ skl_is_16gb_dimm(const struct dram_dimm_info *dimm)
11141147
}
11151148

11161149
static void
1117-
skl_dram_get_dimm_info(struct dram_dimm_info *dimm,
1150+
skl_dram_get_dimm_info(struct drm_i915_private *dev_priv,
1151+
struct dram_dimm_info *dimm,
11181152
int channel, char dimm_name, u16 val)
11191153
{
1120-
dimm->size = skl_get_dimm_size(val);
1121-
dimm->width = skl_get_dimm_width(val);
1122-
dimm->ranks = skl_get_dimm_ranks(val);
1154+
if (INTEL_GEN(dev_priv) >= 10) {
1155+
dimm->size = cnl_get_dimm_size(val);
1156+
dimm->width = cnl_get_dimm_width(val);
1157+
dimm->ranks = cnl_get_dimm_ranks(val);
1158+
} else {
1159+
dimm->size = skl_get_dimm_size(val);
1160+
dimm->width = skl_get_dimm_width(val);
1161+
dimm->ranks = skl_get_dimm_ranks(val);
1162+
}
11231163

11241164
DRM_DEBUG_KMS("CH%u DIMM %c size: %u GB, width: X%u, ranks: %u, 16Gb DIMMs: %s\n",
11251165
channel, dimm_name, dimm->size, dimm->width, dimm->ranks,
11261166
yesno(skl_is_16gb_dimm(dimm)));
11271167
}
11281168

11291169
static int
1130-
skl_dram_get_channel_info(struct dram_channel_info *ch,
1170+
skl_dram_get_channel_info(struct drm_i915_private *dev_priv,
1171+
struct dram_channel_info *ch,
11311172
int channel, u32 val)
11321173
{
1133-
skl_dram_get_dimm_info(&ch->dimm_l, channel, 'L', val & 0xffff);
1134-
skl_dram_get_dimm_info(&ch->dimm_s, channel, 'S', val >> 16);
1174+
skl_dram_get_dimm_info(dev_priv, &ch->dimm_l,
1175+
channel, 'L', val & 0xffff);
1176+
skl_dram_get_dimm_info(dev_priv, &ch->dimm_s,
1177+
channel, 'S', val >> 16);
11351178

11361179
if (ch->dimm_l.size == 0 && ch->dimm_s.size == 0) {
11371180
DRM_DEBUG_KMS("CH%u not populated\n", channel);
@@ -1173,12 +1216,12 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
11731216
int ret;
11741217

11751218
val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
1176-
ret = skl_dram_get_channel_info(&ch0, 0, val);
1219+
ret = skl_dram_get_channel_info(dev_priv, &ch0, 0, val);
11771220
if (ret == 0)
11781221
dram_info->num_channels++;
11791222

11801223
val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
1181-
ret = skl_dram_get_channel_info(&ch1, 1, val);
1224+
ret = skl_dram_get_channel_info(dev_priv, &ch1, 1, val);
11821225
if (ret == 0)
11831226
dram_info->num_channels++;
11841227

@@ -1375,13 +1418,10 @@ intel_get_dram_info(struct drm_i915_private *dev_priv)
13751418
if (INTEL_GEN(dev_priv) < 9)
13761419
return;
13771420

1378-
/* Need to calculate bandwidth only for Gen9 */
13791421
if (IS_GEN9_LP(dev_priv))
13801422
ret = bxt_get_dram_info(dev_priv);
1381-
else if (IS_GEN(dev_priv, 9))
1382-
ret = skl_get_dram_info(dev_priv);
13831423
else
1384-
ret = skl_dram_get_channels_info(dev_priv);
1424+
ret = skl_get_dram_info(dev_priv);
13851425
if (ret)
13861426
return;
13871427

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9877,8 +9877,21 @@ enum skl_power_gate {
98779877
#define SKL_DRAM_WIDTH_X32 (0x2 << 8)
98789878
#define SKL_DRAM_RANK_MASK (0x1 << 10)
98799879
#define SKL_DRAM_RANK_SHIFT 10
9880-
#define SKL_DRAM_RANK_SINGLE (0x0 << 10)
9881-
#define SKL_DRAM_RANK_DUAL (0x1 << 10)
9880+
#define SKL_DRAM_RANK_1 (0x0 << 10)
9881+
#define SKL_DRAM_RANK_2 (0x1 << 10)
9882+
#define SKL_DRAM_RANK_MASK (0x1 << 10)
9883+
#define CNL_DRAM_SIZE_MASK 0x7F
9884+
#define CNL_DRAM_WIDTH_MASK (0x3 << 7)
9885+
#define CNL_DRAM_WIDTH_SHIFT 7
9886+
#define CNL_DRAM_WIDTH_X8 (0x0 << 7)
9887+
#define CNL_DRAM_WIDTH_X16 (0x1 << 7)
9888+
#define CNL_DRAM_WIDTH_X32 (0x2 << 7)
9889+
#define CNL_DRAM_RANK_MASK (0x3 << 9)
9890+
#define CNL_DRAM_RANK_SHIFT 9
9891+
#define CNL_DRAM_RANK_1 (0x0 << 9)
9892+
#define CNL_DRAM_RANK_2 (0x1 << 9)
9893+
#define CNL_DRAM_RANK_3 (0x2 << 9)
9894+
#define CNL_DRAM_RANK_4 (0x3 << 9)
98829895

98839896
/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
98849897
* since on HSW we can't write to it using I915_WRITE. */

0 commit comments

Comments
 (0)