diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b854af2..05c9fcb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -32,6 +32,7 @@
 #include "i915_vgpu.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include "intel_mocs.h"
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
@@ -4882,6 +4883,8 @@ i915_gem_init_hw(struct drm_device *dev)
 			goto out;
 	}
 
+	intel_program_mocs_engines(dev);
+
 	/* We can't enable contexts until all firmware is loaded */
 	if (HAS_GUC_UCODE(dev)) {
 		ret = intel_guc_ucode_load(dev);
diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c
index fed7bea..cd01682 100644
--- a/drivers/gpu/drm/i915/intel_mocs.c
+++ b/drivers/gpu/drm/i915/intel_mocs.c
@@ -128,9 +128,9 @@ static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
 
 /**
  * get_mocs_settings()
- * @dev:        DRM device.
+ * @dev:	DRM device.
  * @table:      Output table that will be made to point at appropriate
- *              MOCS values for the device.
+ *	      MOCS values for the device.
  *
  * This function will return the values of the MOCS table that needs to
  * be programmed for the platform. It will return the values that need
@@ -179,6 +179,48 @@ static i915_reg_t mocs_register(enum intel_ring_id ring, int index)
 }
 
 /**
+ * program_mocs_control_table() - emit the mocs control table
+ * @req:	Request to set up the MOCS table for.
+ * @table:	The values to program into the control regs.
+ * @ring:	The engine for whom to emit the registers.
+ *
+ * This function simply emits a MI_LOAD_REGISTER_IMM command for the
+ * given table starting at the given address.
+ *
+ * Return: 0 on success, otherwise the error status.
+ */
+static int program_mocs_control_table(struct drm_device *dev,
+				   const struct drm_i915_mocs_table *table,
+				   enum intel_ring_id ring)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned int index;
+
+	if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
+		return -ENODEV;
+
+	for (index = 0; index < table->size; index++) {
+		I915_WRITE(mocs_register(ring, index),
+			table->table[index].control_value);
+	}
+
+	/*
+	 * Ok, now set the unused entries to uncached. These entries
+	 * are officially undefined and no contract for the contents
+	 * and settings is given for these entries.
+	 *
+	 * Entry 0 in the table is uncached - so we are just writing
+	 * that value to all the used entries.
+	 */
+	for (; index < GEN9_NUM_MOCS_ENTRIES; index++) {
+		I915_WRITE(mocs_register(ring, index),
+					table->table[0].control_value);
+	}
+
+	return 0;
+}
+
+/**
  * emit_mocs_control_table() - emit the mocs control table
  * @req:	Request to set up the MOCS table for.
  * @table:	The values to program into the control regs.
@@ -302,6 +344,84 @@ static int emit_mocs_l3cc_table(struct drm_i915_gem_request *req,
 }
 
 /**
+ * program_mocs_l3cc_table() - program the mocs control table
+ * @dev:      The the device to be programmed.
+ * @table:    The values to program into the control regs.
+ *
+ * This function simply programs the mocs registers for the given table
+ * starting at the given address. This register set is  programmed in pairs.
+ *
+ * These registers may get programmed more than once, it is simpler to
+ * re-program 32 registers than maintain the state of when they were programmed.
+ * We are always reprogramming with the same values and this only on context
+ * start.
+ *
+ * Return: Nothing.
+ */
+static void program_mocs_l3cc_table(struct drm_device *dev,
+			      struct drm_i915_mocs_table *table)
+{
+	unsigned int count;
+	unsigned int i;
+	u32 value;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 filler = (table->table[0].l3cc_value & 0xffff) |
+			((table->table[0].l3cc_value & 0xffff) << 16);
+
+	for (i = 0, count = 0; i < table->size / 2; i++, count += 2) {
+		value = (table->table[count].l3cc_value & 0xffff) |
+			((table->table[count + 1].l3cc_value & 0xffff) << 16);
+
+		I915_WRITE(GEN9_LNCFCMOCS(i), value);
+	}
+
+	if (table->size & 0x01) {
+		/* Odd table size - 1 left over */
+		value = (table->table[count].l3cc_value & 0xffff) |
+			((table->table[0].l3cc_value & 0xffff) << 16);
+	} else
+		value = filler;
+
+	/*
+	 * Now set the rest of the table to uncached - use entry 0 as this
+	 * will be uncached. Leave the last pair as initialised as they are
+	 * reserved by the hardware.
+	 */
+	for (; i < (GEN9_NUM_MOCS_ENTRIES / 2); i++) {
+		I915_WRITE(GEN9_LNCFCMOCS(i), value);
+		value = filler;
+	}
+}
+
+/*
+ * intel_program_mocs_engines() - program all the MOCS register.
+ *
+ * This function will program the MOCS registers with the correct values.
+ * For the initialised engines, this means that some of the MOCS hw registers
+ * will be left at the hardware defaults.
+ *
+ * Return: Nothing.
+ */
+void intel_program_mocs_engines(struct drm_device *dev)
+{
+	struct drm_i915_mocs_table t;
+
+	if (get_mocs_settings(dev, &t)) {
+		struct drm_i915_private *dev_priv = dev->dev_private;
+		struct intel_engine_cs *ring;
+		enum intel_ring_id ring_id;
+
+		/* Program the control registers */
+		for_each_ring(ring, dev_priv, ring_id) {
+			program_mocs_control_table(dev, &t, ring_id);
+		}
+
+		/* Now program the l3cc registers */
+		program_mocs_l3cc_table(dev, &t);
+	}
+}
+
+/**
  * intel_rcs_context_init_mocs() - program the MOCS register.
  * @req:	Request to set up the MOCS tables for.
  *
@@ -323,16 +443,10 @@ int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req)
 	int ret;
 
 	if (get_mocs_settings(req->ring->dev, &t)) {
-		struct drm_i915_private *dev_priv = req->i915;
-		struct intel_engine_cs *ring;
-		enum intel_ring_id ring_id;
-
-		/* Program the control registers */
-		for_each_ring(ring, dev_priv, ring_id) {
-			ret = emit_mocs_control_table(req, &t, ring_id);
-			if (ret)
-				return ret;
-		}
+		/* Program the RCS control registers */
+		ret = emit_mocs_control_table(req, &t, RCS);
+		if (ret)
+			return ret;
 
 		/* Now program the l3cc registers */
 		ret = emit_mocs_l3cc_table(req, &t);
diff --git a/drivers/gpu/drm/i915/intel_mocs.h b/drivers/gpu/drm/i915/intel_mocs.h
index 76e45b1..d20e16d 100644
--- a/drivers/gpu/drm/i915/intel_mocs.h
+++ b/drivers/gpu/drm/i915/intel_mocs.h
@@ -53,5 +53,6 @@
 #include "i915_drv.h"
 
 int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req);
+void intel_program_mocs_engines(struct drm_device *dev);
 
 #endif
