diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 00c551d3e409..9e0cb995801f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3807,18 +3807,6 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
 	for (level = 0; level < num_levels; level++) {
 		unsigned int latency = wm[level];
 
-		/*
-		 * - WM1+ latency values in 0.5us units
-		 * - latencies are in us on gen9/vlv/chv
-		 */
-		if (INTEL_GEN(dev_priv) >= 9 ||
-		    IS_VALLEYVIEW(dev_priv) ||
-		    IS_CHERRYVIEW(dev_priv) ||
-		    IS_G4X(dev_priv))
-			latency *= 10;
-		else if (level > 0)
-			latency *= 5;
-
 		seq_printf(m, "WM%d %u (%u.%u usec)\n",
 			   level, wm[level], latency / 10, latency % 10);
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 794a8a03c7e6..e57b8cb8fa4d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1906,22 +1906,10 @@ struct drm_i915_private {
 	} sagv_status;
 
 	struct {
-		/*
-		 * Raw watermark latency values:
-		 * in 0.1us units for WM0,
-		 * in 0.5us units for WM1+.
-		 */
-		/* primary */
+		/* Watermark memory latency values in 0.1 us units */
 		uint16_t pri_latency[5];
-		/* sprite */
 		uint16_t spr_latency[5];
-		/* cursor */
 		uint16_t cur_latency[5];
-		/*
-		 * Raw watermark memory latency values
-		 * for SKL for all 8 levels
-		 * in 1us units.
-		 */
 		uint16_t skl_latency[8];
 
 		/* current hardware state */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1392aa56a55a..f871a6f152c3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -801,6 +801,27 @@ static int intel_wm_num_levels(struct drm_i915_private *dev_priv)
 	return dev_priv->wm.max_level + 1;
 }
 
+static int intel_plane_wm_latency(struct intel_plane *plane,
+				  int level)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+
+	if (INTEL_GEN(dev_priv) >= 9)
+		return dev_priv->wm.skl_latency[level];
+
+	if (HAS_GMCH_DISPLAY(dev_priv))
+		return dev_priv->wm.pri_latency[level];
+
+	switch (plane->id) {
+	case PLANE_PRIMARY:
+		return dev_priv->wm.pri_latency[level];
+	case PLANE_CURSOR:
+		return dev_priv->wm.cur_latency[level];
+	default:
+		return dev_priv->wm.spr_latency[level];
+	}
+}
+
 static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
 				   const struct intel_plane_state *plane_state)
 {
@@ -1039,10 +1060,10 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
 
 static void g4x_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
-	/* all latencies in usec */
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5;
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_SR] = 12;
-	dev_priv->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35;
+	/* all latencies in .1 usec */
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 50;
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_SR] = 120;
+	dev_priv->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 350;
 
 	dev_priv->wm.max_level = G4X_WM_LEVEL_HPLL;
 }
@@ -1097,7 +1118,7 @@ static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->base.adjusted_mode;
-	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
+	int latency = intel_plane_wm_latency(plane, level);
 	unsigned int clock, htotal, cpp, width, wm;
 
 	if (latency == 0)
@@ -1586,14 +1607,14 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate,
 
 static void vlv_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
-	/* all latencies in usec */
-	dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
+	/* all latencies in .1 usec */
+	dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 30;
 
 	dev_priv->wm.max_level = VLV_WM_LEVEL_PM2;
 
 	if (IS_CHERRYVIEW(dev_priv)) {
-		dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
-		dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 120;
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 330;
 
 		dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS;
 	}
@@ -1604,12 +1625,12 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 				     int level)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->base.adjusted_mode;
+	int latency = intel_plane_wm_latency(plane, level);
 	unsigned int clock, htotal, cpp, width, wm;
 
-	if (dev_priv->wm.pri_latency[level] == 0)
+	if (latency == 0)
 		return USHRT_MAX;
 
 	if (!intel_wm_plane_visible(crtc_state, plane_state))
@@ -1629,8 +1650,7 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 		 */
 		wm = 63;
 	} else {
-		wm = vlv_wm_method2(clock, htotal, width, cpp,
-				    dev_priv->wm.pri_latency[level] * 10);
+		wm = vlv_wm_method2(clock, htotal, width, cpp, latency);
 	}
 
 	return min_t(unsigned int, wm, USHRT_MAX);
@@ -2481,15 +2501,12 @@ struct ilk_wm_maximums {
 	uint16_t fbc;
 };
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value,
-				   bool is_lp)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	uint32_t method1, method2;
 	int cpp;
 
@@ -2498,27 +2515,25 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
 
 	cpp = pstate->base.fb->format->cpp[0];
 
-	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value);
+	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, latency);
 
-	if (!is_lp)
+	if (level == 0)
 		return method1;
 
 	method2 = ilk_wm_method2(cstate->pixel_rate,
 				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->base.dst),
-				 cpp, mem_value);
+				 cpp, latency);
 
 	return min(method1, method2);
 }
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	uint32_t method1, method2;
 	int cpp;
 
@@ -2527,22 +2542,20 @@ static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
 
 	cpp = pstate->base.fb->format->cpp[0];
 
-	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value);
+	method1 = ilk_wm_method1(cstate->pixel_rate, cpp, latency);
 	method2 = ilk_wm_method2(cstate->pixel_rate,
 				 cstate->base.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&pstate->base.dst),
-				 cpp, mem_value);
+				 cpp, latency);
 	return min(method1, method2);
 }
 
-/*
- * For both WM_PIPE and WM_LP.
- * mem_value must be in 0.1us units.
- */
 static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 				   const struct intel_plane_state *pstate,
-				   uint32_t mem_value)
+				   int level)
 {
+	struct intel_plane *plane = to_intel_plane(pstate->base.plane);
+	int latency = intel_plane_wm_latency(plane, level);
 	int cpp;
 
 	if (!intel_wm_plane_visible(cstate, pstate))
@@ -2552,7 +2565,7 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
 
 	return ilk_wm_method2(cstate->pixel_rate,
 			      cstate->base.adjusted_mode.crtc_htotal,
-			      pstate->base.crtc_w, cpp, mem_value);
+			      pstate->base.crtc_w, cpp, latency);
 }
 
 /* Only for WM_LP. */
@@ -2743,28 +2756,16 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 				 const struct intel_plane_state *curstate,
 				 struct intel_wm_level *result)
 {
-	uint16_t pri_latency = dev_priv->wm.pri_latency[level];
-	uint16_t spr_latency = dev_priv->wm.spr_latency[level];
-	uint16_t cur_latency = dev_priv->wm.cur_latency[level];
-
-	/* WM1+ latency values stored in 0.5us units */
-	if (level > 0) {
-		pri_latency *= 5;
-		spr_latency *= 5;
-		cur_latency *= 5;
-	}
-
 	if (pristate) {
-		result->pri_val = ilk_compute_pri_wm(cstate, pristate,
-						     pri_latency, level);
+		result->pri_val = ilk_compute_pri_wm(cstate, pristate, level);
 		result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
 	}
 
 	if (sprstate)
-		result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
+		result->spr_val = ilk_compute_spr_wm(cstate, sprstate, level);
 
 	if (curstate)
-		result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
+		result->cur_val = ilk_compute_cur_wm(cstate, curstate, level);
 
 	result->enable = true;
 }
@@ -2930,6 +2931,16 @@ static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv,
 		wm[0] = 13;
 }
 
+static void ilk_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
+				       u16 wm[5])
+{
+	int level, num_levels = ilk_wm_max_level(dev_priv) + 1;
+
+	/* convert .5 usec to .1 usec units */
+	for (level = 1; level < num_levels; level++)
+		wm[level] *= 5;
+}
+
 int ilk_wm_max_level(const struct drm_i915_private *dev_priv)
 {
 	/* how many WM levels are we expecting */
@@ -2958,15 +2969,6 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
 			continue;
 		}
 
-		/*
-		 * - latencies are in us on gen9.
-		 * - before then, WM1+ latency values are in 0.5us units
-		 */
-		if (INTEL_GEN(dev_priv) >= 9)
-			latency *= 10;
-		else if (level > 0)
-			latency *= 5;
-
 		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
 			      name, level, wm[level],
 			      latency / 10, latency % 10);
@@ -2982,8 +2984,12 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
 		return false;
 
 	wm[0] = max(wm[0], min);
+
+	/* WM1+ latencies must be multiples of .5 usec */
+	min = roundup(min, 5);
+
 	for (level = 1; level <= max_level; level++)
-		wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
+		wm[level] = max(wm[level], min);
 
 	return true;
 }
@@ -3013,6 +3019,8 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
 	intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
 
+	ilk_fixup_wm_latency_units(dev_priv, dev_priv->wm.pri_latency);
+
 	memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency,
 	       sizeof(dev_priv->wm.pri_latency));
 	memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency,
@@ -3029,9 +3037,22 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
 		snb_wm_latency_quirk(dev_priv);
 }
 
+static void skl_fixup_wm_latency_units(struct drm_i915_private *dev_priv,
+				       u16 wm[8])
+{
+	int level, num_levels = ilk_wm_max_level(dev_priv) + 1;
+
+	/* convert usec to .1 usec units */
+	for (level = 0; level < num_levels; level++)
+		wm[level] *= 10;
+}
+
 static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
 {
 	intel_read_wm_latency(dev_priv, dev_priv->wm.skl_latency);
+
+	skl_fixup_wm_latency_units(dev_priv, dev_priv->wm.skl_latency);
+
 	intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency);
 }
 
@@ -3303,7 +3324,8 @@ static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level)
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 		return 2 * level;
 	else
-		return dev_priv->wm.pri_latency[level];
+		/* specified in .5 usec units */
+		return dev_priv->wm.pri_latency[level] / 5;
 }
 
 static void ilk_compute_wm_results(struct drm_device *dev,
@@ -3763,7 +3785,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
 		     !wm->wm[level].plane_en; --level)
 		     { }
 
-		latency = dev_priv->wm.skl_latency[level];
+		latency = intel_plane_wm_latency(plane, level);
 
 		if (skl_needs_memory_bw_wa(intel_state) &&
 		    plane->base.state->fb->modifier ==
@@ -4636,7 +4658,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 				struct skl_wm_level *result /* out */)
 {
 	const struct drm_plane_state *pstate = &intel_pstate->base;
-	uint32_t latency = dev_priv->wm.skl_latency[level];
+	uint32_t latency = intel_plane_wm_latency(to_intel_plane(pstate->plane),
+						  level);
 	uint_fixed_16_16_t method1, method2;
 	uint_fixed_16_16_t selected_result;
 	uint32_t res_blocks, res_lines;
