diff --git a/src/mesa/drivers/dri/i965/brw_mocs.c b/src/mesa/drivers/dri/i965/brw_mocs.c
index 5df154eb86..b7bfdab671 100644
--- a/src/mesa/drivers/dri/i965/brw_mocs.c
+++ b/src/mesa/drivers/dri/i965/brw_mocs.c
@@ -14,6 +14,9 @@
 /* Skylake: MOCS is now an index into an array of 62 different caching
  * configurations programmed by the kernel.
  */
+
+/* TC=PTE, LeCC=PTE, LRUM=3, L3CC=WB */
+#define SKL_MOCS_PTE_PTE (3 << 1)
 /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */
 #define SKL_MOCS_WB  (2 << 1)
 /* TC=LLC/eLLC, LeCC=PTE, LRUM=3, L3CC=WB */
@@ -26,6 +29,9 @@ brw_mocs_get_control_state(const struct brw_context *brw,
    switch (brw->gen) {
    default:
    case 9:
+      if (brw->intelScreen->mocs_version > 1)
+         return SKL_MOCS_PTE_PTE;
+
       return type == INTEL_MOCS_PTE ? SKL_MOCS_PTE : SKL_MOCS_WB;
    case 8:
       return type == INTEL_MOCS_PTE ? BDW_MOCS_PTE : BDW_MOCS_WB;

tl;dr: A versioned MOCS table will allow userspace to be aware of new
and potentially interesting cacheability settings. Next GEN platforms
will not be considered production worthy until the MOCS table is
finalized.

v2: Update 1.5 year old patch. Add comments. Update commit message.

Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c |  3 +++
 drivers/gpu/drm/i915/i915_drv.h |  2 ++
 drivers/gpu/drm/i915/i915_pci.c | 13 +++++++++----
 include/uapi/drm/i915_drm.h     |  8 ++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 9167a73f3c69..26c27b6ae814 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -401,6 +401,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
 		if (!value)
 			return -ENODEV;
 		break;
+	case I915_PARAM_MOCS_TABLE_VERSION:
+		value = INTEL_INFO(dev_priv)->mocs_version;
+		break;
 	default:
 		DRM_DEBUG("Unknown parameter %d\n", param->param);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index effbe4f72a64..9b30f6e6ef9b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -859,6 +859,8 @@ struct intel_device_info {
 		u16 degamma_lut_size;
 		u16 gamma_lut_size;
 	} color;
+
+	u8 mocs_version;
 };
 
 struct intel_display_error_state;
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 04aaf553e3fa..9697eb91d972 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -356,7 +356,8 @@ static const struct intel_device_info intel_cherryview_info = {
 	.platform = INTEL_SKYLAKE, \
 	.has_csr = 1, \
 	.has_guc = 1, \
-	.ddb_size = 896
+	.ddb_size = 896, \
+	.mocs_version = MOCS_TABLE_VERSION
 
 static const struct intel_device_info intel_skylake_info = {
 	SKL_PLATFORM,
@@ -390,6 +391,7 @@ static const struct intel_device_info intel_skylake_gt3_info = {
 	.has_full_ppgtt = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_reset_engine = 1, \
+	.mocs_version = MOCS_TABLE_VERSION, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	IVB_CURSOR_OFFSETS, \
 	BDW_COLORS
@@ -413,7 +415,8 @@ static const struct intel_device_info intel_geminilake_info = {
 	.platform = INTEL_KABYLAKE, \
 	.has_csr = 1, \
 	.has_guc = 1, \
-	.ddb_size = 896
+	.ddb_size = 896, \
+	.mocs_version = MOCS_TABLE_VERSION
 
 static const struct intel_device_info intel_kabylake_info = {
 	KBL_PLATFORM,
@@ -431,7 +434,8 @@ static const struct intel_device_info intel_kabylake_gt3_info = {
 	.platform = INTEL_COFFEELAKE, \
 	.has_csr = 1, \
 	.has_guc = 1, \
-	.ddb_size = 896
+	.ddb_size = 896, \
+	.mocs_version = MOCS_TABLE_VERSION
 
 static const struct intel_device_info intel_coffeelake_info = {
 	CFL_PLATFORM,
@@ -448,7 +452,8 @@ static const struct intel_device_info intel_cannonlake_info = {
 	.platform = INTEL_CANNONLAKE,
 	.gen = 10,
 	.ddb_size = 1024,
-	.has_csr = 1,
+	.has_csr = 1, \
+	.mocs_version = MOCS_TABLE_VERSION
 };
 
 /*
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 7ccbd6a2bbe0..2e370c40e48d 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -431,6 +431,14 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_HAS_EXEC_BATCH_FIRST	 48
 
+/* What version of the MOCS table we have. For GEN9 GPUs, the PRM defined
+ * non-optimal settings for the MOCS table. As a result, we were required to use a
+ * small subset, and later add new settings. This param allows userspace to
+ * determine which settings are there.
+ */
+#define MOCS_TABLE_VERSION		  1 /* Build time MOCS table version */
+#define I915_PARAM_MOCS_TABLE_VERSION	 49
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
