--- /dev/null
+From cf6c525a31fac11b0775b8c06c00a508c6356d9b Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:32 -0300
+Subject: drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit cf6c525a31fac11b0775b8c06c00a508c6356d9b upstream.
+
+The confusing thing is that plane_blocks_per_line is listed as part of
+the method 2 calculation but is also used for other things. We
+calculated it in two different places and different ways: one inside
+skl_wm_method2() and the other inside skl_compute_plane_wm(). The
+skl_wm_method2() implementation is the one that matches the
+specification.
+
+With this patch we fix the skl_compute_plane_wm() calculation and just
+pass it as a parameter to skl_wm_method2(). We also take care to not
+modify the value of plane_bytes_per_line since we're going to rely on
+it having a correct value in later patches.
+
+This should affect the watermarks for Linear and Y-tiled.
+
+From my analysis, it looks like the two plane_blocks_per_line
+variables got out of sync on 0fda65680e92, but we can't really say
+that commit was a regression, it looks like just an incomplete fix.
+There's always the possibility that 0fda65680e92 matched our
+specification at that time, and then later the specification changed.
+
+v2: Try to add a "Fixes" tag (Maarten).
+
+Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling")
+Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Reviewed-by: Lyude <cpaul@redhat.com>
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-7-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 7a1a8aed67e0a60772defe3f6499eb340da48634)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 39 +++++++++++++++------------------------
+ 1 file changed, 15 insertions(+), 24 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3475,30 +3475,14 @@ static uint32_t skl_wm_method1(uint32_t
+ }
+
+ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+- uint32_t horiz_pixels, uint8_t cpp,
+- uint64_t tiling, uint32_t latency,
+- uint32_t y_min_scanlines)
++ uint32_t latency, uint32_t plane_blocks_per_line)
+ {
+ uint32_t ret;
+- uint32_t plane_bytes_per_line, plane_blocks_per_line;
+ uint32_t wm_intermediate_val;
+
+ if (latency == 0)
+ return UINT_MAX;
+
+- plane_bytes_per_line = horiz_pixels * cpp;
+-
+- if (tiling == I915_FORMAT_MOD_Y_TILED ||
+- tiling == I915_FORMAT_MOD_Yf_TILED) {
+- plane_bytes_per_line *= y_min_scanlines;
+- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+- plane_blocks_per_line /= y_min_scanlines;
+- } else if (tiling == DRM_FORMAT_MOD_NONE) {
+- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
+- } else {
+- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+- }
+-
+ wm_intermediate_val = latency * pixel_rate;
+ ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+ plane_blocks_per_line;
+@@ -3587,17 +3571,24 @@ static int skl_compute_plane_wm(const st
+ y_min_scanlines = 4;
+ }
+
++ plane_bytes_per_line = width * cpp;
++ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
++ plane_blocks_per_line =
++ DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
++ plane_blocks_per_line /= y_min_scanlines;
++ } else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
++ + 1;
++ } else {
++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
++ }
++
+ method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
+ method2 = skl_wm_method2(plane_pixel_rate,
+ cstate->base.adjusted_mode.crtc_htotal,
+- width,
+- cpp,
+- fb->modifier[0],
+ latency,
+- y_min_scanlines);
+-
+- plane_bytes_per_line = width * cpp;
+- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
++ plane_blocks_per_line);
+
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
--- /dev/null
+From 73fed0ef8567f1e1cba079994353e60208ded964 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:33 -0300
+Subject: drm/i915/gen9: fix the watermark res_blocks value
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit 73fed0ef8567f1e1cba079994353e60208ded964 upstream.
+
+We forgot the "res_blocks += y_tile_minimum" that's described on step
+V of our documentation.
+
+Again, this should only affect the Y tiling cases.
+
+It looks like the relevant code was introduced in 0fda65680e92, but
+there's always the possibility that it matched our specification when
+it was introduced, and then the specification changed while the code
+stayed the same. So we can't really say this was a regression, but
+let's try to add a "Fixes" tag anyway to help backporting.
+
+v2: Try to add a "Fixes" tag (Maarten).
+
+Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling")
+Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Reviewed-by: Lyude <cpaul@redhat.com>
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-8-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 75676ed423a6acf9e2b1df52fbc036a51e11fb7a)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3533,7 +3533,7 @@ static int skl_compute_plane_wm(const st
+ uint8_t cpp;
+ uint32_t width = 0, height = 0;
+ uint32_t plane_pixel_rate;
+- uint32_t y_min_scanlines;
++ uint32_t y_tile_minimum, y_min_scanlines;
+
+ if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
+ *enabled = false;
+@@ -3590,10 +3590,10 @@ static int skl_compute_plane_wm(const st
+ latency,
+ plane_blocks_per_line);
+
++ y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
++
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+- uint32_t y_tile_minimum = plane_blocks_per_line *
+- y_min_scanlines;
+ selected_result = max(method2, y_tile_minimum);
+ } else {
+ if ((ddb_allocation / plane_blocks_per_line) >= 1)
+@@ -3607,10 +3607,12 @@ static int skl_compute_plane_wm(const st
+
+ if (level >= 1 && level <= 7) {
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+- fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
++ res_blocks += y_tile_minimum;
+ res_lines += y_min_scanlines;
+- else
++ } else {
+ res_blocks++;
++ }
+ }
+
+ if (res_blocks >= ddb_allocation || res_lines > 31) {
--- /dev/null
+From 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:30 -0300
+Subject: drm/i915/gen9: fix the WaWmMemoryReadLatency implementation
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 upstream.
+
+Bspec says:
+ "The mailbox response data may not account for memory read latency.
+ If the mailbox response data for level 0 is 0us, add 2 microseconds
+ to the result for each valid level."
+
+This means we should only do the +2 in case wm[0] == 0, not always.
+
+So split the sanitizing implementation from the WA implementation and
+fix the WA implementation.
+
+v2: Add Fixes tag (Maarten).
+
+Fixes: 367294be7c25 ("drm/i915/gen9: Add 2us read latency to WM level")
+Cc: Vandana Kannan <vandana.kannan@intel.com>
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-5-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 0727e40a48a1d08cf54ce2c01e120864b92e59bf)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++--------------------
+ 1 file changed, 22 insertions(+), 20 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+
+ /*
++ * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
++ * need to be disabled. We make sure to sanitize the values out
++ * of the punit to satisfy this requirement.
++ */
++ for (level = 1; level <= max_level; level++) {
++ if (wm[level] == 0) {
++ for (i = level + 1; i <= max_level; i++)
++ wm[i] = 0;
++ break;
++ }
++ }
++
++ /*
+ * WaWmMemoryReadLatency:skl
+ *
+ * punit doesn't take into account the read latency so we need
+- * to add 2us to the various latency levels we retrieve from
+- * the punit.
+- * - W0 is a bit special in that it's the only level that
+- * can't be disabled if we want to have display working, so
+- * we always add 2us there.
+- * - For levels >=1, punit returns 0us latency when they are
+- * disabled, so we respect that and don't add 2us then
+- *
+- * Additionally, if a level n (n > 1) has a 0us latency, all
+- * levels m (m >= n) need to be disabled. We make sure to
+- * sanitize the values out of the punit to satisfy this
+- * requirement.
++ * to add 2us to the various latency levels we retrieve from the
++ * punit when level 0 response data us 0us.
+ */
+- wm[0] += 2;
+- for (level = 1; level <= max_level; level++)
+- if (wm[level] != 0)
++ if (wm[0] == 0) {
++ wm[0] += 2;
++ for (level = 1; level <= max_level; level++) {
++ if (wm[level] == 0)
++ break;
+ wm[level] += 2;
+- else {
+- for (i = level + 1; i <= max_level; i++)
+- wm[i] = 0;
+-
+- break;
+ }
++ }
++
+ } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ uint64_t sskpd = I915_READ64(MCH_SSKPD);
+
--- /dev/null
+From ccc1057477bc99678896b51adce6b6ee4019dc37 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:31 -0300
+Subject: drm/i915/gen9: minimum scanlines for Y tile is not always 4
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit ccc1057477bc99678896b51adce6b6ee4019dc37 upstream.
+
+During watermarks calculations, this value is used in 3 different
+places. Only one of them was not using a hardcoded 4. Move the code up
+so everybody can benefit from the actual value.
+
+This should only help on situations with Y tiling + 90/270 rotation +
+1 or 2 bpp or NV12.
+
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-6-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 1186fa85eb9b3cc0589990fbc39617e50e38759a)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 56 ++++++++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 24 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3476,7 +3476,8 @@ static uint32_t skl_wm_method1(uint32_t
+
+ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+ uint32_t horiz_pixels, uint8_t cpp,
+- uint64_t tiling, uint32_t latency)
++ uint64_t tiling, uint32_t latency,
++ uint32_t y_min_scanlines)
+ {
+ uint32_t ret;
+ uint32_t plane_bytes_per_line, plane_blocks_per_line;
+@@ -3489,9 +3490,9 @@ static uint32_t skl_wm_method2(uint32_t
+
+ if (tiling == I915_FORMAT_MOD_Y_TILED ||
+ tiling == I915_FORMAT_MOD_Yf_TILED) {
+- plane_bytes_per_line *= 4;
++ plane_bytes_per_line *= y_min_scanlines;
+ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+- plane_blocks_per_line /= 4;
++ plane_blocks_per_line /= y_min_scanlines;
+ } else if (tiling == DRM_FORMAT_MOD_NONE) {
+ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
+ } else {
+@@ -3548,6 +3549,7 @@ static int skl_compute_plane_wm(const st
+ uint8_t cpp;
+ uint32_t width = 0, height = 0;
+ uint32_t plane_pixel_rate;
++ uint32_t y_min_scanlines;
+
+ if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
+ *enabled = false;
+@@ -3563,38 +3565,44 @@ static int skl_compute_plane_wm(const st
+ cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+ plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
+
++ if (intel_rotation_90_or_270(pstate->rotation)) {
++ int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
++ drm_format_plane_cpp(fb->pixel_format, 1) :
++ drm_format_plane_cpp(fb->pixel_format, 0);
++
++ switch (cpp) {
++ case 1:
++ y_min_scanlines = 16;
++ break;
++ case 2:
++ y_min_scanlines = 8;
++ break;
++ default:
++ WARN(1, "Unsupported pixel depth for rotation");
++ case 4:
++ y_min_scanlines = 4;
++ break;
++ }
++ } else {
++ y_min_scanlines = 4;
++ }
++
+ method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
+ method2 = skl_wm_method2(plane_pixel_rate,
+ cstate->base.adjusted_mode.crtc_htotal,
+ width,
+ cpp,
+ fb->modifier[0],
+- latency);
++ latency,
++ y_min_scanlines);
+
+ plane_bytes_per_line = width * cpp;
+ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+- uint32_t min_scanlines = 4;
+- uint32_t y_tile_minimum;
+- if (intel_rotation_90_or_270(pstate->rotation)) {
+- int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
+- drm_format_plane_cpp(fb->pixel_format, 1) :
+- drm_format_plane_cpp(fb->pixel_format, 0);
+-
+- switch (cpp) {
+- case 1:
+- min_scanlines = 16;
+- break;
+- case 2:
+- min_scanlines = 8;
+- break;
+- case 8:
+- WARN(1, "Unsupported pixel depth for rotation");
+- }
+- }
+- y_tile_minimum = plane_blocks_per_line * min_scanlines;
++ uint32_t y_tile_minimum = plane_blocks_per_line *
++ y_min_scanlines;
+ selected_result = max(method2, y_tile_minimum);
+ } else {
+ if ((ddb_allocation / plane_blocks_per_line) >= 1)
+@@ -3609,7 +3617,7 @@ static int skl_compute_plane_wm(const st
+ if (level >= 1 && level <= 7) {
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
+- res_lines += 4;
++ res_lines += y_min_scanlines;
+ else
+ res_blocks++;
+ }
--- /dev/null
+From 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:28 -0300
+Subject: drm/i915: introduce intel_has_sagv()
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e upstream.
+
+And use it to move knowledge about the SAGV-supporting platforms from
+the callers to the SAGV code.
+
+We'll add more platforms to intel_has_sagv(), so IMHO it makes more
+sense to move all this to a single function instead of patching all
+the callers every time we add SAGV support to a new platform.
+
+v2: Move I915_SAGV_NOT_CONTROLLED to the new function (Lyude).
+
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-3-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 56feca91973459d0b62cbb2610b62d341025ed89)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 5 ++---
+ drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++----
+ 2 files changed, 20 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13891,7 +13891,7 @@ static void intel_atomic_commit_tail(str
+ * SKL workaround: bspec recommends we disable the SAGV when we
+ * have more then one pipe enabled
+ */
+- if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state))
++ if (!intel_can_enable_sagv(state))
+ intel_disable_sagv(dev_priv);
+
+ intel_modeset_verify_disabled(dev);
+@@ -13949,8 +13949,7 @@ static void intel_atomic_commit_tail(str
+ intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
+ }
+
+- if (IS_SKYLAKE(dev_priv) && intel_state->modeset &&
+- intel_can_enable_sagv(state))
++ if (intel_state->modeset && intel_can_enable_sagv(state))
+ intel_enable_sagv(dev_priv);
+
+ drm_atomic_helper_commit_hw_done(state);
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2878,6 +2878,13 @@ skl_wm_plane_id(const struct intel_plane
+ }
+ }
+
++static bool
++intel_has_sagv(struct drm_i915_private *dev_priv)
++{
++ return IS_SKYLAKE(dev_priv) &&
++ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED;
++}
++
+ /*
+ * SAGV dynamically adjusts the system agent voltage and clock frequencies
+ * depending on power and performance requirements. The display engine access
+@@ -2894,8 +2901,10 @@ intel_enable_sagv(struct drm_i915_privat
+ {
+ int ret;
+
+- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED ||
+- dev_priv->sagv_status == I915_SAGV_ENABLED)
++ if (!intel_has_sagv(dev_priv))
++ return 0;
++
++ if (dev_priv->sagv_status == I915_SAGV_ENABLED)
+ return 0;
+
+ DRM_DEBUG_KMS("Enabling the SAGV\n");
+@@ -2943,8 +2952,10 @@ intel_disable_sagv(struct drm_i915_priva
+ {
+ int ret, result;
+
+- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED ||
+- dev_priv->sagv_status == I915_SAGV_DISABLED)
++ if (!intel_has_sagv(dev_priv))
++ return 0;
++
++ if (dev_priv->sagv_status == I915_SAGV_DISABLED)
+ return 0;
+
+ DRM_DEBUG_KMS("Disabling the SAGV\n");
+@@ -2985,6 +2996,9 @@ bool intel_can_enable_sagv(struct drm_at
+ enum pipe pipe;
+ int level, plane;
+
++ if (!intel_has_sagv(dev_priv))
++ return false;
++
+ /*
+ * SKL workaround: bspec recommends we disable the SAGV when we have
+ * more then one pipe enabled
--- /dev/null
+From 17777d61f4a87d7b6d5585e8fdffa83773c594e7 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:29 -0300
+Subject: drm/i915/kbl: KBL also needs to run the SAGV code
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit 17777d61f4a87d7b6d5585e8fdffa83773c594e7 upstream.
+
+According to BSpec, it's the "core CPUs" that need the code, which
+means SKL and KBL, but not BXT.
+
+I don't have a KBL to test this patch on it.
+
+v2: Only SKL should have I915_SAGV_NOT_CONTROLLED.
+
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-4-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 6e3100ec21e7c774a0fc01e36a1e0739530c2f71)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2881,8 +2881,14 @@ skl_wm_plane_id(const struct intel_plane
+ static bool
+ intel_has_sagv(struct drm_i915_private *dev_priv)
+ {
+- return IS_SKYLAKE(dev_priv) &&
+- dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED;
++ if (IS_KABYLAKE(dev_priv))
++ return true;
++
++ if (IS_SKYLAKE(dev_priv) &&
++ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED)
++ return true;
++
++ return false;
+ }
+
+ /*
+@@ -2920,7 +2926,7 @@ intel_enable_sagv(struct drm_i915_privat
+ * Some skl systems, pre-release machines in particular,
+ * don't actually have an SAGV.
+ */
+- if (ret == -ENXIO) {
++ if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) {
+ DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ return 0;
+@@ -2974,7 +2980,7 @@ intel_disable_sagv(struct drm_i915_priva
+ * Some skl systems, pre-release machines in particular,
+ * don't actually have an SAGV.
+ */
+- if (result == -ENXIO) {
++ if (IS_SKYLAKE(dev_priv) && result == -ENXIO) {
+ DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ return 0;
--- /dev/null
+From 674f823b455cdb94d5773406c1caac170f87e1c4 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu, 22 Sep 2016 18:00:27 -0300
+Subject: drm/i915: SAGV is not SKL-only, so rename a few things
+
+From: Paulo Zanoni <paulo.r.zanoni@intel.com>
+
+commit 674f823b455cdb94d5773406c1caac170f87e1c4 upstream.
+
+The plan is to introduce intel_has_sagv() and then use it to discover
+which platforms actually support it.
+
+I thought about keeping the functions with their current skl names,
+but found two problems: (i) skl_has_sagv() would become a very
+confusing name, and (ii) intel_atomic_commit_tail() doesn't seem to be
+calling any functions whose name start with a platform name, so the
+"intel_" naming scheme seems make more sense than the "firstplatorm_"
+naming scheme here.
+
+Reviewed-by: Lyude <cpaul@redhat.com>
+Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-2-git-send-email-paulo.r.zanoni@intel.com
+(cherry picked from commit 16dcdc4edbcf5cb130004737f2548401776170f1)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h | 10 +++++-----
+ drivers/gpu/drm/i915/intel_display.c | 8 ++++----
+ drivers/gpu/drm/i915/intel_drv.h | 6 +++---
+ drivers/gpu/drm/i915/intel_pm.c | 26 +++++++++++++-------------
+ 4 files changed, 25 insertions(+), 25 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1967,11 +1967,11 @@ struct drm_i915_private {
+ struct vlv_s0ix_state vlv_s0ix_state;
+
+ enum {
+- I915_SKL_SAGV_UNKNOWN = 0,
+- I915_SKL_SAGV_DISABLED,
+- I915_SKL_SAGV_ENABLED,
+- I915_SKL_SAGV_NOT_CONTROLLED
+- } skl_sagv_status;
++ I915_SAGV_UNKNOWN = 0,
++ I915_SAGV_DISABLED,
++ I915_SAGV_ENABLED,
++ I915_SAGV_NOT_CONTROLLED
++ } sagv_status;
+
+ struct {
+ /*
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13891,8 +13891,8 @@ static void intel_atomic_commit_tail(str
+ * SKL workaround: bspec recommends we disable the SAGV when we
+ * have more then one pipe enabled
+ */
+- if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state))
+- skl_disable_sagv(dev_priv);
++ if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state))
++ intel_disable_sagv(dev_priv);
+
+ intel_modeset_verify_disabled(dev);
+ }
+@@ -13950,8 +13950,8 @@ static void intel_atomic_commit_tail(str
+ }
+
+ if (IS_SKYLAKE(dev_priv) && intel_state->modeset &&
+- skl_can_enable_sagv(state))
+- skl_enable_sagv(dev_priv);
++ intel_can_enable_sagv(state))
++ intel_enable_sagv(dev_priv);
+
+ drm_atomic_helper_commit_hw_done(state);
+
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -1717,9 +1717,9 @@ void ilk_wm_get_hw_state(struct drm_devi
+ void skl_wm_get_hw_state(struct drm_device *dev);
+ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb /* out */);
+-bool skl_can_enable_sagv(struct drm_atomic_state *state);
+-int skl_enable_sagv(struct drm_i915_private *dev_priv);
+-int skl_disable_sagv(struct drm_i915_private *dev_priv);
++bool intel_can_enable_sagv(struct drm_atomic_state *state);
++int intel_enable_sagv(struct drm_i915_private *dev_priv);
++int intel_disable_sagv(struct drm_i915_private *dev_priv);
+ bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
+ const struct skl_ddb_allocation *new,
+ enum pipe pipe);
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2890,12 +2890,12 @@ skl_wm_plane_id(const struct intel_plane
+ * - We're not using an interlaced display configuration
+ */
+ int
+-skl_enable_sagv(struct drm_i915_private *dev_priv)
++intel_enable_sagv(struct drm_i915_private *dev_priv)
+ {
+ int ret;
+
+- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
+- dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED)
++ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED ||
++ dev_priv->sagv_status == I915_SAGV_ENABLED)
+ return 0;
+
+ DRM_DEBUG_KMS("Enabling the SAGV\n");
+@@ -2913,19 +2913,19 @@ skl_enable_sagv(struct drm_i915_private
+ */
+ if (ret == -ENXIO) {
+ DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ return 0;
+ } else if (ret < 0) {
+ DRM_ERROR("Failed to enable the SAGV\n");
+ return ret;
+ }
+
+- dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED;
++ dev_priv->sagv_status = I915_SAGV_ENABLED;
+ return 0;
+ }
+
+ static int
+-skl_do_sagv_disable(struct drm_i915_private *dev_priv)
++intel_do_sagv_disable(struct drm_i915_private *dev_priv)
+ {
+ int ret;
+ uint32_t temp = GEN9_SAGV_DISABLE;
+@@ -2939,19 +2939,19 @@ skl_do_sagv_disable(struct drm_i915_priv
+ }
+
+ int
+-skl_disable_sagv(struct drm_i915_private *dev_priv)
++intel_disable_sagv(struct drm_i915_private *dev_priv)
+ {
+ int ret, result;
+
+- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
+- dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED)
++ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED ||
++ dev_priv->sagv_status == I915_SAGV_DISABLED)
+ return 0;
+
+ DRM_DEBUG_KMS("Disabling the SAGV\n");
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+ /* bspec says to keep retrying for at least 1 ms */
+- ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1);
++ ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ if (ret == -ETIMEDOUT) {
+@@ -2965,18 +2965,18 @@ skl_disable_sagv(struct drm_i915_private
+ */
+ if (result == -ENXIO) {
+ DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ return 0;
+ } else if (result < 0) {
+ DRM_ERROR("Failed to disable the SAGV\n");
+ return result;
+ }
+
+- dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED;
++ dev_priv->sagv_status = I915_SAGV_DISABLED;
+ return 0;
+ }
+
+-bool skl_can_enable_sagv(struct drm_atomic_state *state)
++bool intel_can_enable_sagv(struct drm_atomic_state *state)
+ {
+ struct drm_device *dev = state->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch
drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch
drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch
+drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch
+drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch
+drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch
+drm-i915-gen9-fix-the-watermark-res_blocks-value.patch
+drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch
+drm-i915-introduce-intel_has_sagv.patch
+drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch