Message ID | 20190226175748.15625-1-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | None | expand |
On Tue, 26 Feb 2019, Ville Syrjala <ville.syrjala@linux.intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > We'll need to know the memory type in the system for some > bandwidth limitations and whatnot. Let's read that out on > gen9+. > > v2: Rebase > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_drv.c | 84 +++++++++++++++++++++++++++++++-- > drivers/gpu/drm/i915/i915_drv.h | 7 +++ > drivers/gpu/drm/i915/i915_reg.h | 13 +++++ > 3 files changed, 100 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 47d1a8734f2d..03ad9a8e32f4 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -1068,6 +1068,26 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) > intel_gvt_sanitize_options(dev_priv); > } > > +#define DRAM_TYPE_STR(type) [INTEL_DRAM_ ## type] = #type > + > +static const char *intel_dram_type_str(enum intel_dram_type type) > +{ > + static const char * const str[] = { > + DRAM_TYPE_STR(UNKNOWN), > + DRAM_TYPE_STR(DDR3), > + DRAM_TYPE_STR(DDR4), > + DRAM_TYPE_STR(LPDDR3), > + DRAM_TYPE_STR(LPDDR4), > + }; > + > + if (type >= ARRAY_SIZE(str)) > + type = INTEL_DRAM_UNKNOWN; > + > + return str[type]; > +} > + > +#undef DRAM_TYPE_STR > + > static int intel_dimm_num_devices(const struct dram_dimm_info *dimm) > { > return dimm->ranks * 64 / (dimm->width ?: 1); > @@ -1252,6 +1272,28 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv) > return 0; > } > > +static enum intel_dram_type > +skl_get_dram_type(struct drm_i915_private *dev_priv) > +{ > + u32 val; > + > + val = I915_READ(SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); > + > + switch (val & SKL_DRAM_DDR_TYPE_MASK) { > + case SKL_DRAM_DDR_TYPE_DDR3: > + return INTEL_DRAM_DDR3; > + case SKL_DRAM_DDR_TYPE_DDR4: > + return INTEL_DRAM_DDR4; > + case SKL_DRAM_DDR_TYPE_LPDDR3: > + return INTEL_DRAM_LPDDR3; > + case SKL_DRAM_DDR_TYPE_LPDDR4: > + return INTEL_DRAM_LPDDR4; > + default: > + MISSING_CASE(val); > + return INTEL_DRAM_UNKNOWN; > + } > +} > + > static int > skl_get_dram_info(struct drm_i915_private *dev_priv) > { > @@ -1259,6 +1301,9 @@ skl_get_dram_info(struct drm_i915_private *dev_priv) > u32 mem_freq_khz, val; > int ret; > > + dram_info->type = skl_get_dram_type(dev_priv); > + DRM_DEBUG_KMS("DRAM type: %s\n", intel_dram_type_str(dram_info->type)); > + > ret = skl_dram_get_channels_info(dev_priv); > if (ret) > return ret; > @@ -1324,6 +1369,26 @@ static int bxt_get_dimm_ranks(u32 val) > } > } > > +static enum intel_dram_type bxt_get_dimm_type(u32 val) > +{ > + if (!bxt_get_dimm_size(val)) > + return INTEL_DRAM_UNKNOWN; > + > + switch (val & BXT_DRAM_TYPE_MASK) { > + case BXT_DRAM_TYPE_DDR3: > + return INTEL_DRAM_DDR3; > + case BXT_DRAM_TYPE_LPDDR3: > + return INTEL_DRAM_LPDDR3; > + case BXT_DRAM_TYPE_DDR4: > + return INTEL_DRAM_DDR4; > + case BXT_DRAM_TYPE_LPDDR4: > + return INTEL_DRAM_LPDDR4; > + default: > + MISSING_CASE(val); > + return INTEL_DRAM_UNKNOWN; > + } > +} > + > static void bxt_get_dimm_info(struct dram_dimm_info *dimm, > u32 val) > { > @@ -1366,6 +1431,7 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) > */ > for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) { > struct dram_dimm_info dimm; > + enum intel_dram_type type; > > val = I915_READ(BXT_D_CR_DRP0_DUNIT(i)); > if (val == 0xFFFFFFFF) > @@ -1374,10 +1440,16 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) > dram_info->num_channels++; > > bxt_get_dimm_info(&dimm, val); > + type = bxt_get_dimm_type(val); > + > + WARN_ON(type != INTEL_DRAM_UNKNOWN && > + dram_info->type != INTEL_DRAM_UNKNOWN && > + dram_info->type != type); > > - DRM_DEBUG_KMS("CH%d DIMM size: %d GB, width: X%d, ranks: %d\n", > + DRM_DEBUG_KMS("CH%d DIMM size: % dGB, width: X%d, ranks: %d, type: %s\n", > i - BXT_D_CR_DRP0_DUNIT_START, > - dimm.size, dimm.width, dimm.ranks); > + dimm.size, dimm.width, dimm.ranks, > + intel_dram_type_str(type)); > > /* > * If any of the channel is single rank channel, > @@ -1388,10 +1460,14 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) > dram_info->ranks = dimm.ranks; > else if (dimm.ranks == 1) > dram_info->ranks = 1; > + > + if (type != INTEL_DRAM_UNKNOWN) > + dram_info->type = type; > } > > - if (dram_info->ranks == 0) { > - DRM_INFO("couldn't get memory rank information\n"); > + if (dram_info->type == INTEL_DRAM_UNKNOWN || > + dram_info->ranks == 0) { > + DRM_INFO("couldn't get memory information\n"); > return -EINVAL; > } > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 89881b68dcb4..67a283ad54b1 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1836,6 +1836,13 @@ struct drm_i915_private { > u8 ranks; > u32 bandwidth_kbps; > bool symmetric_memory; > + enum intel_dram_type { > + INTEL_DRAM_UNKNOWN, > + INTEL_DRAM_DDR3, > + INTEL_DRAM_DDR4, > + INTEL_DRAM_LPDDR3, > + INTEL_DRAM_LPDDR4 > + } type; > } dram_info; > > struct i915_runtime_pm runtime_pm; > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index b35b0220764f..1a6904176fc6 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -9859,11 +9859,24 @@ enum skl_power_gate { > #define BXT_DRAM_SIZE_8GB (0x2 << 6) > #define BXT_DRAM_SIZE_12GB (0x3 << 6) > #define BXT_DRAM_SIZE_16GB (0x4 << 6) > +#define BXT_DRAM_TYPE_MASK (0x7 << 22) > +#define BXT_DRAM_TYPE_SHIFT 22 > +#define BXT_DRAM_TYPE_DDR3 (0x0 << 6) > +#define BXT_DRAM_TYPE_LPDDR3 (0x1 << 6) > +#define BXT_DRAM_TYPE_LPDDR4 (0x2 << 6) > +#define BXT_DRAM_TYPE_DDR4 (0x4 << 6) Copy-paste fail with the shifts. With those fixed, Reviewed-by: Jani Nikula <jani.nikula@intel.com> > > #define SKL_MEMORY_FREQ_MULTIPLIER_HZ 266666666 > #define SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5E04) > #define SKL_REQ_DATA_MASK (0xF << 0) > > +#define SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5000) > +#define SKL_DRAM_DDR_TYPE_MASK (0x3 << 0) > +#define SKL_DRAM_DDR_TYPE_DDR4 (0 << 0) > +#define SKL_DRAM_DDR_TYPE_DDR3 (1 << 0) > +#define SKL_DRAM_DDR_TYPE_LPDDR3 (2 << 0) > +#define SKL_DRAM_DDR_TYPE_LPDDR4 (3 << 0) > + > #define SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x500C) > #define SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5010) > #define SKL_DRAM_S_SHIFT 16
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 47d1a8734f2d..03ad9a8e32f4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1068,6 +1068,26 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) intel_gvt_sanitize_options(dev_priv); } +#define DRAM_TYPE_STR(type) [INTEL_DRAM_ ## type] = #type + +static const char *intel_dram_type_str(enum intel_dram_type type) +{ + static const char * const str[] = { + DRAM_TYPE_STR(UNKNOWN), + DRAM_TYPE_STR(DDR3), + DRAM_TYPE_STR(DDR4), + DRAM_TYPE_STR(LPDDR3), + DRAM_TYPE_STR(LPDDR4), + }; + + if (type >= ARRAY_SIZE(str)) + type = INTEL_DRAM_UNKNOWN; + + return str[type]; +} + +#undef DRAM_TYPE_STR + static int intel_dimm_num_devices(const struct dram_dimm_info *dimm) { return dimm->ranks * 64 / (dimm->width ?: 1); @@ -1252,6 +1272,28 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv) return 0; } +static enum intel_dram_type +skl_get_dram_type(struct drm_i915_private *dev_priv) +{ + u32 val; + + val = I915_READ(SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); + + switch (val & SKL_DRAM_DDR_TYPE_MASK) { + case SKL_DRAM_DDR_TYPE_DDR3: + return INTEL_DRAM_DDR3; + case SKL_DRAM_DDR_TYPE_DDR4: + return INTEL_DRAM_DDR4; + case SKL_DRAM_DDR_TYPE_LPDDR3: + return INTEL_DRAM_LPDDR3; + case SKL_DRAM_DDR_TYPE_LPDDR4: + return INTEL_DRAM_LPDDR4; + default: + MISSING_CASE(val); + return INTEL_DRAM_UNKNOWN; + } +} + static int skl_get_dram_info(struct drm_i915_private *dev_priv) { @@ -1259,6 +1301,9 @@ skl_get_dram_info(struct drm_i915_private *dev_priv) u32 mem_freq_khz, val; int ret; + dram_info->type = skl_get_dram_type(dev_priv); + DRM_DEBUG_KMS("DRAM type: %s\n", intel_dram_type_str(dram_info->type)); + ret = skl_dram_get_channels_info(dev_priv); if (ret) return ret; @@ -1324,6 +1369,26 @@ static int bxt_get_dimm_ranks(u32 val) } } +static enum intel_dram_type bxt_get_dimm_type(u32 val) +{ + if (!bxt_get_dimm_size(val)) + return INTEL_DRAM_UNKNOWN; + + switch (val & BXT_DRAM_TYPE_MASK) { + case BXT_DRAM_TYPE_DDR3: + return INTEL_DRAM_DDR3; + case BXT_DRAM_TYPE_LPDDR3: + return INTEL_DRAM_LPDDR3; + case BXT_DRAM_TYPE_DDR4: + return INTEL_DRAM_DDR4; + case BXT_DRAM_TYPE_LPDDR4: + return INTEL_DRAM_LPDDR4; + default: + MISSING_CASE(val); + return INTEL_DRAM_UNKNOWN; + } +} + static void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val) { @@ -1366,6 +1431,7 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) */ for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) { struct dram_dimm_info dimm; + enum intel_dram_type type; val = I915_READ(BXT_D_CR_DRP0_DUNIT(i)); if (val == 0xFFFFFFFF) @@ -1374,10 +1440,16 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) dram_info->num_channels++; bxt_get_dimm_info(&dimm, val); + type = bxt_get_dimm_type(val); + + WARN_ON(type != INTEL_DRAM_UNKNOWN && + dram_info->type != INTEL_DRAM_UNKNOWN && + dram_info->type != type); - DRM_DEBUG_KMS("CH%d DIMM size: %d GB, width: X%d, ranks: %d\n", + DRM_DEBUG_KMS("CH%d DIMM size: % dGB, width: X%d, ranks: %d, type: %s\n", i - BXT_D_CR_DRP0_DUNIT_START, - dimm.size, dimm.width, dimm.ranks); + dimm.size, dimm.width, dimm.ranks, + intel_dram_type_str(type)); /* * If any of the channel is single rank channel, @@ -1388,10 +1460,14 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv) dram_info->ranks = dimm.ranks; else if (dimm.ranks == 1) dram_info->ranks = 1; + + if (type != INTEL_DRAM_UNKNOWN) + dram_info->type = type; } - if (dram_info->ranks == 0) { - DRM_INFO("couldn't get memory rank information\n"); + if (dram_info->type == INTEL_DRAM_UNKNOWN || + dram_info->ranks == 0) { + DRM_INFO("couldn't get memory information\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 89881b68dcb4..67a283ad54b1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1836,6 +1836,13 @@ struct drm_i915_private { u8 ranks; u32 bandwidth_kbps; bool symmetric_memory; + enum intel_dram_type { + INTEL_DRAM_UNKNOWN, + INTEL_DRAM_DDR3, + INTEL_DRAM_DDR4, + INTEL_DRAM_LPDDR3, + INTEL_DRAM_LPDDR4 + } type; } dram_info; struct i915_runtime_pm runtime_pm; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b35b0220764f..1a6904176fc6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9859,11 +9859,24 @@ enum skl_power_gate { #define BXT_DRAM_SIZE_8GB (0x2 << 6) #define BXT_DRAM_SIZE_12GB (0x3 << 6) #define BXT_DRAM_SIZE_16GB (0x4 << 6) +#define BXT_DRAM_TYPE_MASK (0x7 << 22) +#define BXT_DRAM_TYPE_SHIFT 22 +#define BXT_DRAM_TYPE_DDR3 (0x0 << 6) +#define BXT_DRAM_TYPE_LPDDR3 (0x1 << 6) +#define BXT_DRAM_TYPE_LPDDR4 (0x2 << 6) +#define BXT_DRAM_TYPE_DDR4 (0x4 << 6) #define SKL_MEMORY_FREQ_MULTIPLIER_HZ 266666666 #define SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5E04) #define SKL_REQ_DATA_MASK (0xF << 0) +#define SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5000) +#define SKL_DRAM_DDR_TYPE_MASK (0x3 << 0) +#define SKL_DRAM_DDR_TYPE_DDR4 (0 << 0) +#define SKL_DRAM_DDR_TYPE_DDR3 (1 << 0) +#define SKL_DRAM_DDR_TYPE_LPDDR3 (2 << 0) +#define SKL_DRAM_DDR_TYPE_LPDDR4 (3 << 0) + #define SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x500C) #define SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5010) #define SKL_DRAM_S_SHIFT 16