From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: paulo.r.zanoni@intel.com
Subject: [PATCH v4 3/8] drm/i915: Decode system memory bandwidth
Date: Thu, 13 Oct 2016 16:28:21 +0530 [thread overview]
Message-ID: <20161013105826.9710-4-mahesh1.kumar@intel.com> (raw)
In-Reply-To: <20161013105826.9710-1-mahesh1.kumar@intel.com>
This patch adds support to decode system memory bandwidth
which will be used for arbitrated display memory percentage
calculation in GEN9 based system.
Changes from v1:
- Address comments from Paulo
- implement decode function for SKL/KBL also
Signed-off-by: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
---
drivers/gpu/drm/i915/i915_drv.c | 170 ++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_drv.h | 14 ++++
drivers/gpu/drm/i915/i915_reg.h | 38 +++++++++
3 files changed, 222 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 89d3222..b5f601c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -979,6 +979,170 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
}
+static inline void skl_memdev_info_fill(struct memdev_info *info, uint32_t val)
+{
+ uint8_t channel_width, rank;
+
+ info->rank_valid = true;
+ channel_width = (val >> SKL_DRAM_CHANNEL_WIDTH_SHIFT) &
+ SKL_DRAM_CHANNEL_WIDTH_MASK;
+ if (channel_width == SKL_DRAM_WIDTH_1)
+ info->channel_width_bytes = 1;
+ else if (channel_width == SKL_DRAM_WIDTH_2)
+ info->channel_width_bytes = 2;
+ else
+ info->channel_width_bytes = 4;
+
+ rank = (val >> SKL_DRAM_RANK_SHIFT) & SKL_DRAM_RANK_MASK;
+ if (rank == SKL_DRAM_RANK_SINGLE)
+ info->rank = DRAM_RANK_SINGLE;
+ else
+ info->rank = DRAM_RANK_DUAL;
+}
+
+static int
+skl_get_memdev_info(struct drm_i915_private *dev_priv)
+{
+ uint32_t val = 0;
+ uint32_t mem_speed = 0;
+ struct memdev_info *memdev_info = &dev_priv->memdev_info;
+
+ val = I915_READ(SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
+ mem_speed = div_u64((uint64_t) (val & SKL_REQ_DATA_MASK) *
+ SKL_MEMORY_FREQ_MULTIPLIER, 1000);
+
+ if (mem_speed == 0)
+ return -EINVAL;
+
+ memdev_info->valid = true;
+ memdev_info->mem_speed_khz = mem_speed;
+ memdev_info->num_channels = 0;
+
+ memdev_info->rank_valid = false;
+ val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+
+ if (val != 0xFFFFFFFF) {
+ memdev_info->num_channels++;
+ skl_memdev_info_fill(memdev_info, val);
+ }
+
+ val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+
+ if (val != 0xFFFFFFFF) {
+ memdev_info->num_channels++;
+ if (!memdev_info->rank_valid)
+ skl_memdev_info_fill(memdev_info, val);
+ }
+
+ if (memdev_info->num_channels == 0)
+ memdev_info->valid = false;
+ return 0;
+}
+
+static int
+bxt_get_memdev_info(struct drm_i915_private *dev_priv)
+{
+ struct memdev_info *memdev_info = &dev_priv->memdev_info;
+ uint32_t dram_channel;
+ uint32_t mem_speed, val;
+ uint8_t num_channel, dram_type;
+ int i;
+
+ val = I915_READ(BXT_P_CR_MC_BIOS_REQ_0_0_0);
+ mem_speed = div_u64((uint64_t) (val & BXT_REQ_DATA_MASK) *
+ SKL_MEMORY_FREQ_MULTIPLIER, 1000);
+
+ if (mem_speed == 0)
+ return -EINVAL;
+
+ memdev_info->valid = true;
+ memdev_info->mem_speed_khz = mem_speed;
+ dram_type = (val >> BXT_DRAM_TYPE_SHIFT) & BXT_DRAM_TYPE_MASK;
+ dram_channel = (val >> BXT_DRAM_CHANNEL_SHIFT) & BXT_DRAM_CHANNEL_MASK;
+ num_channel = hweight32(dram_channel);
+
+ /*
+ * The lpddr3 and lpddr4 technologies can have 1-4 channels and the
+ * channels are 32bits wide; while ddr3l technologies can have 1-2
+ * channels and the channels are 64 bits wide. In case of single 64 bit
+ * wide DDR3L dimm sets two channel-active bits in
+ * P_CR_MC_BIOS_REQ_0_0_0 register and system with two DDR3L 64bit dimm
+ * will set all four channel-active bits in above register.
+ * In order to get actual number of channels in DDR3L DRAM we need to
+ * device total channel-active bits set by 2.
+ */
+
+ switch (dram_type) {
+ case BXT_DRAM_TYPE_LPDDR3:
+ case BXT_DRAM_TYPE_LPDDR4:
+ memdev_info->channel_width_bytes = 4;
+ memdev_info->num_channels = num_channel;
+ break;
+ case BXT_DRAM_TYPE_DDR3L:
+ memdev_info->channel_width_bytes = 8;
+ memdev_info->num_channels = num_channel / 2;
+ break;
+ default:
+ DRM_DEBUG_KMS("Unknown DRAM type\n");
+ memdev_info->valid = false;
+ return -EINVAL;
+ }
+
+ /*
+ * Now read each DUNIT8/9/10/11 to check the rank of each dimms.
+ * all the dimms should have same rank as in first valid Dimm
+ */
+ memdev_info->rank_valid = false;
+ for (i = 0; i < BXT_D_CR_DRP0_DUNIT_MAX; i++) {
+ val = I915_READ(BXT_D_CR_DRP0_DUNIT(i));
+ if (val != 0xFFFFFFFF) {
+ uint8_t rank;
+
+ memdev_info->rank_valid = true;
+ rank = val & BXT_DRAM_RANK_MASK;
+ if (rank == BXT_DRAM_RANK_SINGLE)
+ memdev_info->rank = DRAM_RANK_SINGLE;
+ else if (rank == BXT_DRAM_RANK_DUAL)
+ memdev_info->rank = DRAM_RANK_DUAL;
+ else
+ memdev_info->rank = DRAM_RANK_NONE;
+
+ break;
+ }
+ }
+ return 0;
+}
+
+static void
+intel_get_memdev_info(struct drm_i915_private *dev_priv)
+{
+ struct memdev_info *memdev_info = &dev_priv->memdev_info;
+ int ret;
+
+ memdev_info->valid = false;
+ if (!IS_GEN9(dev_priv))
+ return;
+
+ if (IS_BROXTON(dev_priv))
+ ret = bxt_get_memdev_info(dev_priv);
+ else
+ ret = skl_get_memdev_info(dev_priv);
+ if (ret)
+ return;
+
+ if (memdev_info->valid) {
+ DRM_DEBUG_DRIVER("DRAM speed-%d Khz total-channels-%d channel-width-%d bytes\n",
+ memdev_info->mem_speed_khz,
+ memdev_info->num_channels,
+ memdev_info->channel_width_bytes);
+ if (memdev_info->rank_valid)
+ DRM_DEBUG_DRIVER("DRAM rank-%s\n",
+ (memdev_info->rank == DRAM_RANK_DUAL) ?
+ "dual" : "single");
+ }
+}
+
+
/**
* i915_driver_init_hw - setup state requiring device access
* @dev_priv: device private
@@ -1082,6 +1246,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
DRM_DEBUG_DRIVER("can't enable MSI");
}
+ /*
+ * Fill the memdev structure to get the system raw bandwidth
+ * This will be used by WM algorithm, to implement GEN9 based WA
+ */
+ intel_get_memdev_info(dev_priv);
+
return 0;
out_ggtt:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a219a35..adbd9aa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2057,6 +2057,20 @@ struct drm_i915_private {
bool distrust_bios_wm;
} wm;
+ struct memdev_info {
+ bool valid;
+ uint32_t mem_speed_khz;
+ uint8_t channel_width_bytes;
+ uint8_t num_channels;
+ bool rank_valid;
+ enum {
+ DRAM_RANK_NONE = 0,
+ DRAM_RANK_SINGLE,
+ DRAM_RANK_DUAL
+ } rank;
+ } memdev_info;
+
+
struct i915_runtime_pm pm;
/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index acc767a..a9c467c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7721,6 +7721,44 @@ enum {
#define DC_STATE_DEBUG_MASK_CORES (1<<0)
#define DC_STATE_DEBUG_MASK_MEMORY_UP (1<<1)
+#define _MMIO_MCHBAR_PIPE(x, a, b) _MMIO(MCHBAR_MIRROR_BASE_SNB + _PIPE(x, a, b))
+#define BXT_P_CR_MC_BIOS_REQ_0_0_0 _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x7114)
+#define BXT_REQ_DATA_MASK (0x3F << 0)
+#define BXT_DRAM_TYPE_SHIFT 24
+#define BXT_DRAM_TYPE_MASK 0x7
+#define BXT_DRAM_CHANNEL_SHIFT 12
+#define BXT_DRAM_CHANNEL_MASK 0xF
+
+#define BXT_DRAM_TYPE_LPDDR3 0x1
+#define BXT_DRAM_TYPE_LPDDR4 0x2
+#define BXT_DRAM_TYPE_DDR3L 0x4
+/*
+ * BIOS programs this field of REQ_DATA [5:0] in integer
+ * multiple of 133330 KHz (133.33MHz)
+ */
+#define SKL_MEMORY_FREQ_MULTIPLIER 0x208D2
+#define BXT_D_CR_DRP0_DUNIT8 0x1000
+#define BXT_D_CR_DRP0_DUNIT9 0x1200
+#define BXT_D_CR_DRP0_DUNIT_MAX 4
+#define BXT_D_CR_DRP0_DUNIT(x) _MMIO_MCHBAR_PIPE(x, BXT_D_CR_DRP0_DUNIT8, BXT_D_CR_DRP0_DUNIT9)
+#define BXT_DRAM_RANK_MASK 0x3
+#define BXT_DRAM_RANK_SINGLE 0x1
+#define BXT_DRAM_RANK_DUAL 0x3
+
+#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_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_CHANNEL_WIDTH_MASK 0x3
+#define SKL_DRAM_CHANNEL_WIDTH_SHIFT 8
+#define SKL_DRAM_WIDTH_1 0x0
+#define SKL_DRAM_WIDTH_2 0x1
+#define SKL_DRAM_WIDTH_4 0x2
+#define SKL_DRAM_RANK_MASK 0x1
+#define SKL_DRAM_RANK_SHIFT 10
+#define SKL_DRAM_RANK_SINGLE 0x0
+#define SKL_DRAM_RANK_DUAL 0x1
+
/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
* since on HSW we can't write to it using I915_WRITE. */
#define D_COMP_HSW _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
--
2.10.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-10-13 10:58 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-13 10:58 [PATCH v4 0/8] New DDB Algo and WM fixes Kumar, Mahesh
2016-10-13 10:58 ` [PATCH v4 1/8] drm/i915/skl+: use linetime latency instead of ddb size Kumar, Mahesh
2016-10-31 18:03 ` Paulo Zanoni
2016-11-09 14:58 ` Mahesh Kumar
2016-11-09 17:02 ` Paulo Zanoni
2016-10-13 10:58 ` [PATCH v4 2/8] drm/i915/skl: New ddb allocation algorithm Kumar, Mahesh
2016-11-04 19:25 ` Paulo Zanoni
2016-10-13 10:58 ` Kumar, Mahesh [this message]
2016-11-03 19:06 ` [PATCH v4 3/8] drm/i915: Decode system memory bandwidth Paulo Zanoni
2016-11-16 11:48 ` Mahesh Kumar
2016-10-13 10:58 ` [PATCH v4 4/8] drm/i915/gen9: WM memory bandwidth related workaround Kumar, Mahesh
2016-11-04 17:09 ` Paulo Zanoni
2016-11-04 17:22 ` Ville Syrjälä
2016-11-10 5:54 ` Mahesh Kumar
2016-11-16 12:36 ` Paulo Zanoni
2016-10-13 10:58 ` [PATCH v4 5/8] drm/i915/skl+: reset y_plane ddb structure also during calculation Kumar, Mahesh
2016-11-04 17:39 ` Paulo Zanoni
2016-10-13 10:58 ` [PATCH v4 6/8] drm/i915/skl: Add variables to check x_tile and y_tile Kumar, Mahesh
2016-11-04 17:45 ` Paulo Zanoni
2016-10-13 10:58 ` [PATCH v4 7/8] drm/i915/skl+: change WM calc to fixed point 16.16 Kumar, Mahesh
2016-11-04 19:03 ` Paulo Zanoni
2016-10-13 10:58 ` [PATCH v4 8/8] drm/i915/bxt: Enable IPC support Kumar, Mahesh
2016-10-13 11:19 ` Maarten Lankhorst
2016-10-13 13:01 ` Mahesh Kumar
2016-10-13 15:36 ` Daniel Vetter
2016-11-04 19:20 ` Paulo Zanoni
2016-10-13 13:50 ` ✗ Fi.CI.BAT: warning for New DDB Algo and WM fixes (rev4) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161013105826.9710-4-mahesh1.kumar@intel.com \
--to=mahesh1.kumar@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=paulo.r.zanoni@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.