summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--0001-drm-i915-Reorganize-WM-structs-unions-in-CRTC-state.patch198
-rw-r--r--0001-drm-mgag200-Black-screen-fix-for-G200e-rev-4.patch58
-rw-r--r--0002-drm-i915-Rename-s-skl_compute_pipe_wm-skl_build_pipe.patch60
-rw-r--r--0002-drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch138
-rw-r--r--0003-drm-i915-gen9-Cache-plane-data-rates-in-CRTC-state.patch214
-rw-r--r--0003-drm-nouveau-disp-sor-gf119-both-links-use-the-same-t.patch46
-rw-r--r--0004-drm-i915-gen9-Allow-calculation-of-data-rate-for-in-.patch141
-rw-r--r--0004-drm-nouveau-disp-sor-gm107-training-pattern-register.patch195
-rw-r--r--0005-drm-i915-gen9-Store-plane-minimum-blocks-in-CRTC-wm-.patch67
-rw-r--r--0005-i915-fbc-Disable-on-HSW-by-default-for-now.patch55
-rw-r--r--0006-drm-i915-Track-whether-an-atomic-transaction-changes.patch68
-rw-r--r--0007-drm-i915-gen9-Allow-skl_allocate_pipe_ddb-to-operate.patch352
-rw-r--r--0008-drm-i915-Add-distrust_bios_wm-flag-to-dev_priv-v2.patch94
-rw-r--r--0009-drm-i915-gen9-Compute-DDB-allocation-at-atomic-check.patch254
-rw-r--r--0010-drm-i915-gen9-Drop-re-allocation-of-DDB-at-atomic-co.patch389
-rw-r--r--0011-drm-i915-gen9-Calculate-plane-WM-s-from-state.patch91
-rw-r--r--0012-drm-i915-gen9-Allow-watermark-calculation-on-in-flig.patch156
-rw-r--r--0013-drm-i915-gen9-Use-a-bitmask-to-track-dirty-pipe-wate.patch91
-rw-r--r--0014-drm-i915-gen9-Propagate-watermark-calculation-failur.patch254
-rw-r--r--0015-drm-i915-gen9-Calculate-watermarks-during-atomic-che.patch321
-rw-r--r--0016-drm-i915-gen9-Reject-display-updates-that-exceed-wm-.patch63
-rw-r--r--0017-drm-i915-Remove-wm_config-from-dev_priv-intel_atomic.patch115
-rw-r--r--KEYS-potential-uninitialized-variable.patch30
-rw-r--r--bcm283x-upstream-fixes.patch400
-rw-r--r--config-arm-generic3
-rw-r--r--filter-aarch64.sh2
-rw-r--r--filter-armv7hl.sh2
-rw-r--r--hp-wmi-fix-wifi-cannot-be-hard-unblock.patch48
-rw-r--r--kernel.spec66
-rw-r--r--netfilter-x_tables-deal-with-bogus-nextoffset-values.patch150
-rw-r--r--sources2
-rw-r--r--tipc-check-nl-sock-before-parsing-nested-attributes.patch36
32 files changed, 3958 insertions, 201 deletions
diff --git a/0001-drm-i915-Reorganize-WM-structs-unions-in-CRTC-state.patch b/0001-drm-i915-Reorganize-WM-structs-unions-in-CRTC-state.patch
new file mode 100644
index 000000000..dc6e2e086
--- /dev/null
+++ b/0001-drm-i915-Reorganize-WM-structs-unions-in-CRTC-state.patch
@@ -0,0 +1,198 @@
+From 2a6f0971d09e2bb88d2ae40d91ceb2776090497d Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 11:11:50 +0200
+Subject: [PATCH 01/17] drm/i915: Reorganize WM structs/unions in CRTC state
+
+Upstream: since drm-intel-next-2016-05-22
+commit e8f1f02e7125220b99af8047703b63c11a7081d6
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:05:55 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:32:11 2016 -0700
+
+ drm/i915: Reorganize WM structs/unions in CRTC state
+
+ Reorganize the nested structures and unions we have for pipe watermark
+ data in intel_crtc_state so that platform-specific data can be added in
+ a more sensible manner (and save a bit of memory at the same time).
+
+ The change basically changes the organization from:
+
+ union {
+ struct intel_pipe_wm ilk;
+ struct intel_pipe_wm skl;
+ } optimal;
+
+ struct intel_pipe_wm intermediate /* ILK-only */
+
+ to
+
+ union {
+ struct {
+ struct intel_pipe_wm intermediate;
+ struct intel_pipe_wm optimal;
+ } ilk;
+
+ struct {
+ struct intel_pipe_wm optimal;
+ } skl;
+ }
+
+ There should be no functional change here, but it will allow us to add
+ more platform-specific fields going forward (and more easily extend to
+ other platform types like VLV).
+
+ While we're at it, let's move the entire watermark substructure out to
+ its own structure definition to make the code slightly more readable.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-2-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_drv.h | 48 +++++++++++++++++++++++++++++++---------
+ drivers/gpu/drm/i915/intel_pm.c | 16 +++++++-------
+ 2 files changed, 46 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 3a30b37..7d19baf 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -363,6 +363,40 @@ struct skl_pipe_wm {
+ uint32_t linetime;
+ };
+
++struct intel_crtc_wm_state {
++ union {
++ struct {
++ /*
++ * Intermediate watermarks; these can be
++ * programmed immediately since they satisfy
++ * both the current configuration we're
++ * switching away from and the new
++ * configuration we're switching to.
++ */
++ struct intel_pipe_wm intermediate;
++
++ /*
++ * Optimal watermarks, programmed post-vblank
++ * when this state is committed.
++ */
++ struct intel_pipe_wm optimal;
++ } ilk;
++
++ struct {
++ /* gen9+ only needs 1-step wm programming */
++ struct skl_pipe_wm optimal;
++ } skl;
++ };
++
++ /*
++ * Platforms with two-step watermark programming will need to
++ * update watermark programming post-vblank to switch from the
++ * safe intermediate watermarks to the optimal final
++ * watermarks.
++ */
++ bool need_postvbl_update;
++};
++
+ struct intel_crtc_state {
+ struct drm_crtc_state base;
+
+@@ -509,16 +543,10 @@ struct intel_crtc_state {
+ /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
+ bool disable_lp_wm;
+
+- struct {
+- /*
+- * optimal watermarks, programmed post-vblank when this state
+- * is committed
+- */
+- union {
+- struct intel_pipe_wm ilk;
+- struct skl_pipe_wm skl;
+- } optimal;
+- } wm;
++ struct intel_crtc_wm_state wm;
++
++ /* Gamma mode programmed on the pipe */
++ uint32_t gamma_mode;
+ };
+
+ struct vlv_wm_state {
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 54ab023..0da1d60 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2302,7 +2302,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc,
+ if (IS_ERR(cstate))
+ return PTR_ERR(cstate);
+
+- pipe_wm = &cstate->wm.optimal.ilk;
++ pipe_wm = &cstate->wm.ilk.optimal;
+ memset(pipe_wm, 0, sizeof(*pipe_wm));
+
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+@@ -2385,7 +2385,7 @@ static void ilk_merge_wm_level(struct drm_device *dev,
+ for_each_intel_crtc(dev, intel_crtc) {
+ const struct intel_crtc_state *cstate =
+ to_intel_crtc_state(intel_crtc->base.state);
+- const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
++ const struct intel_pipe_wm *active = &cstate->wm.ilk.optimal;
+ const struct intel_wm_level *wm = &active->wm[level];
+
+ if (!active->pipe_enabled)
+@@ -2536,12 +2536,12 @@ static void ilk_compute_wm_results(struct drm_device *dev,
+ const struct intel_crtc_state *cstate =
+ to_intel_crtc_state(intel_crtc->base.state);
+ enum pipe pipe = intel_crtc->pipe;
+- const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0];
++ const struct intel_wm_level *r = &cstate->wm.ilk.optimal.wm[0];
+
+ if (WARN_ON(!r->enable))
+ continue;
+
+- results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime;
++ results->wm_linetime[pipe] = cstate->wm.ilk.optimal.linetime;
+
+ results->wm_pipe[pipe] =
+ (r->pri_val << WM0_PIPE_PLANE_SHIFT) |
+@@ -3617,7 +3617,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_wm_values *results = &dev_priv->wm.skl_results;
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+- struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
++ struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
+
+
+ /* Clear all dirty flags */
+@@ -3711,7 +3711,7 @@ static void ilk_update_wm(struct drm_crtc *crtc)
+ intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
+ }
+
+- intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
++ intel_crtc->wm.active.ilk = cstate->wm.ilk.optimal;
+
+ ilk_program_watermarks(cstate);
+ }
+@@ -3767,7 +3767,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+ struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+- struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
++ struct skl_pipe_wm *active = &cstate->wm.skl.optimal;
+ enum pipe pipe = intel_crtc->pipe;
+ int level, i, max_level;
+ uint32_t temp;
+@@ -3833,7 +3833,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+ struct ilk_wm_values *hw = &dev_priv->wm.hw;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+- struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
++ struct intel_pipe_wm *active = &cstate->wm.ilk.optimal;
+ enum pipe pipe = intel_crtc->pipe;
+ static const i915_reg_t wm0_pipe_reg[] = {
+ [PIPE_A] = WM0_PIPEA_ILK,
+--
+2.7.4
+
diff --git a/0001-drm-mgag200-Black-screen-fix-for-G200e-rev-4.patch b/0001-drm-mgag200-Black-screen-fix-for-G200e-rev-4.patch
new file mode 100644
index 000000000..e583d09e8
--- /dev/null
+++ b/0001-drm-mgag200-Black-screen-fix-for-G200e-rev-4.patch
@@ -0,0 +1,58 @@
+From 1e5895f2c6068fb9ae5356e3a751a29a22af5f01 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 14:53:03 +0200
+Subject: [PATCH 1/6] drm/mgag200: Black screen fix for G200e rev 4
+
+Upstream: since drm-fixes-for-v4.7
+commit d3922b69617b62bb2509936b68301f837229d9f0
+
+Author: Mathieu Larouche <mathieu.larouche@matrox.com>
+AuthorDate: Fri May 27 15:12:50 2016 -0400
+Commit: Dave Airlie <airlied@redhat.com>
+CommitDate: Wed Jun 1 15:25:04 2016 +1000
+
+ drm/mgag200: Black screen fix for G200e rev 4
+
+ - Fixed black screen for some resolutions of G200e rev4
+ - Fixed testm & testn which had predetermined value.
+
+ Reported-by: Jan Beulich <jbeulich@suse.com>
+
+ Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com>
+ Cc: stable@vger.kernel.org
+ Signed-off-by: Dave Airlie <airlied@redhat.com>
+---
+ drivers/gpu/drm/mgag200/mgag200_mode.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
+index 14e64e0..d347dca 100644
+--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
++++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
+@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
+ }
+ }
+
+- fvv = pllreffreq * testn / testm;
++ fvv = pllreffreq * (n + 1) / (m + 1);
+ fvv = (fvv - 800000) / 50000;
+
+ if (fvv > 15)
+@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
+ WREG_DAC(MGA1064_PIX_PLLC_M, m);
+ WREG_DAC(MGA1064_PIX_PLLC_N, n);
+ WREG_DAC(MGA1064_PIX_PLLC_P, p);
++
++ if (mdev->unique_rev_id >= 0x04) {
++ WREG_DAC(0x1a, 0x09);
++ msleep(20);
++ WREG_DAC(0x1a, 0x01);
++
++ }
++
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/0002-drm-i915-Rename-s-skl_compute_pipe_wm-skl_build_pipe.patch b/0002-drm-i915-Rename-s-skl_compute_pipe_wm-skl_build_pipe.patch
new file mode 100644
index 000000000..f9eecb97a
--- /dev/null
+++ b/0002-drm-i915-Rename-s-skl_compute_pipe_wm-skl_build_pipe.patch
@@ -0,0 +1,60 @@
+From 4d428f0fd6aaaa75382885d897900f619b2dad35 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 11:12:56 +0200
+Subject: [PATCH 02/17] drm/i915: Rename
+ s/skl_compute_pipe_wm/skl_build_pipe_wm/
+
+Upstream: since drm-intel-next-2016-05-22
+commit e7649b54777ba6491204acbe1f1a34fce78637d5
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:05:56 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:32:27 2016 -0700
+
+ drm/i915: Rename s/skl_compute_pipe_wm/skl_build_pipe_wm/
+
+ When we added atomic watermarks, we added a new display vfunc
+ 'compute_pipe_wm' that is used to compute any pipe-specific watermark
+ information that we can at atomic check time. This was a somewhat poor
+ naming choice since we already had a 'skl_compute_pipe_wm' function that
+ doesn't quite fit this model --- the existing SKL function is something
+ that gets used at atomic commit time, after the DDB allocation has been
+ determined. Let's rename the existing SKL function to avoid confusion.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-3-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 0da1d60..8f081b2 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3266,9 +3266,9 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
+ }
+ }
+
+-static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,
+- struct skl_ddb_allocation *ddb,
+- struct skl_pipe_wm *pipe_wm)
++static void skl_build_pipe_wm(struct intel_crtc_state *cstate,
++ struct skl_ddb_allocation *ddb,
++ struct skl_pipe_wm *pipe_wm)
+ {
+ struct drm_device *dev = cstate->base.crtc->dev;
+ const struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -3535,7 +3535,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+
+ skl_allocate_pipe_ddb(cstate, ddb);
+- skl_compute_pipe_wm(cstate, ddb, pipe_wm);
++ skl_build_pipe_wm(cstate, ddb, pipe_wm);
+
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+ return false;
+--
+2.7.4
+
diff --git a/0002-drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch b/0002-drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch
new file mode 100644
index 000000000..d1c32b439
--- /dev/null
+++ b/0002-drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch
@@ -0,0 +1,138 @@
+From 02510a8805db2c3f8ca2926f90c4b3793934404a Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 14:51:45 +0200
+Subject: [PATCH 2/6] drm/nouveau/fbcon: fix out-of-bounds memory accesses
+
+Upstream: drm-fixes for 4.7 (and cc'd 4.6-stable)
+commit f045f459d925138fe7d6193a8c86406bda7e49da
+
+Author: Ben Skeggs <bskeggs@redhat.com>
+AuthorDate: Thu Jun 2 12:23:31 2016 +1000
+Commit: Ben Skeggs <bskeggs@redhat.com>
+CommitDate: Thu Jun 2 13:53:44 2016 +1000
+
+ drm/nouveau/fbcon: fix out-of-bounds memory accesses
+
+ Reported by KASAN.
+
+ Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+ Cc: stable@vger.kernel.org
+---
+ drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 +
+ drivers/gpu/drm/nouveau/nv04_fbcon.c | 7 ++-----
+ drivers/gpu/drm/nouveau/nv50_fbcon.c | 6 ++----
+ drivers/gpu/drm/nouveau/nvc0_fbcon.c | 6 ++----
+ 4 files changed, 7 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+index 59f27e7..bd89c86 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+@@ -557,6 +557,7 @@ nouveau_fbcon_init(struct drm_device *dev)
+ if (ret)
+ goto fini;
+
++ fbcon->helper.fbdev->pixmap.buf_align = 4;
+ return 0;
+
+ fini:
+diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
+index 789dc29..8f715fe 100644
+--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
+@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ uint32_t fg;
+ uint32_t bg;
+ uint32_t dsize;
+- uint32_t width;
+ uint32_t *data = (uint32_t *)image->data;
+ int ret;
+
+@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 8);
+- dsize = ALIGN(width * image->height, 32) >> 5;
+-
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
+@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ ((image->dx + image->width) & 0xffff));
+ OUT_RING(chan, bg);
+ OUT_RING(chan, fg);
+- OUT_RING(chan, (image->height << 16) | width);
++ OUT_RING(chan, (image->height << 16) | image->width);
+ OUT_RING(chan, (image->height << 16) | image->width);
+ OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+
++ dsize = ALIGN(image->width * image->height, 32) >> 5;
+ while (dsize) {
+ int iter_len = dsize > 128 ? 128 : dsize;
+
+diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
+index e05499d..a4e259a 100644
+--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
+@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ struct nouveau_fbdev *nfbdev = info->par;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
+- uint32_t width, dwords, *data = (uint32_t *)image->data;
++ uint32_t dwords, *data = (uint32_t *)image->data;
+ uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ uint32_t *palette = info->pseudo_palette;
+ int ret;
+@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 32);
+- dwords = (width * image->height) >> 5;
+-
+ BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ OUT_RING(chan, 0);
+ OUT_RING(chan, image->dy);
+
++ dwords = ALIGN(image->width * image->height, 32) >> 5;
+ while (dwords) {
+ int push = dwords > 2047 ? 2047 : dwords;
+
+diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+index c97395b..f28315e 100644
+--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ struct nouveau_fbdev *nfbdev = info->par;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
+- uint32_t width, dwords, *data = (uint32_t *)image->data;
++ uint32_t dwords, *data = (uint32_t *)image->data;
+ uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ uint32_t *palette = info->pseudo_palette;
+ int ret;
+@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 32);
+- dwords = (width * image->height) >> 5;
+-
+ BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ OUT_RING (chan, 0);
+ OUT_RING (chan, image->dy);
+
++ dwords = ALIGN(image->width * image->height, 32) >> 5;
+ while (dwords) {
+ int push = dwords > 2047 ? 2047 : dwords;
+
+--
+2.7.4
+
diff --git a/0003-drm-i915-gen9-Cache-plane-data-rates-in-CRTC-state.patch b/0003-drm-i915-gen9-Cache-plane-data-rates-in-CRTC-state.patch
new file mode 100644
index 000000000..9a9366c1c
--- /dev/null
+++ b/0003-drm-i915-gen9-Cache-plane-data-rates-in-CRTC-state.patch
@@ -0,0 +1,214 @@
+From 0206aec944641c69815562407b73b6f9df22f041 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 11:13:09 +0200
+Subject: [PATCH 03/17] drm/i915/gen9: Cache plane data rates in CRTC state
+
+Upstream: since drm-intel-next-2016-05-22
+commit a1de91e5f3039dfc32ac2b77ffb280a68646cbc7
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:05:57 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:32:35 2016 -0700
+
+ drm/i915/gen9: Cache plane data rates in CRTC state
+
+ This will be important when we start calculating CRTC data rates for
+ in-flight CRTC states since it will allow us to calculate the total data
+ rate without needing to grab the plane state for any planes that aren't
+ updated by the transaction.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-4-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_drv.h | 4 ++
+ drivers/gpu/drm/i915/intel_pm.c | 92 ++++++++++++++++++++++++++--------------
+ 2 files changed, 63 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 7d19baf..7c00ab6 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -385,6 +385,10 @@ struct intel_crtc_wm_state {
+ struct {
+ /* gen9+ only needs 1-step wm programming */
+ struct skl_pipe_wm optimal;
++
++ /* cached plane data rate */
++ unsigned plane_data_rate[I915_MAX_PLANES];
++ unsigned plane_y_data_rate[I915_MAX_PLANES];
+ } skl;
+ };
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 8f081b2..854f0a4 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2879,6 +2879,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
+ struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+ struct drm_framebuffer *fb = pstate->fb;
+ uint32_t width = 0, height = 0;
++ unsigned format = fb ? fb->pixel_format : DRM_FORMAT_XRGB8888;
++
++ if (!intel_pstate->visible)
++ return 0;
++ if (pstate->plane->type == DRM_PLANE_TYPE_CURSOR)
++ return 0;
++ if (y && format != DRM_FORMAT_NV12)
++ return 0;
+
+ width = drm_rect_width(&intel_pstate->src) >> 16;
+ height = drm_rect_height(&intel_pstate->src) >> 16;
+@@ -2887,17 +2895,17 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
+ swap(width, height);
+
+ /* for planar format */
+- if (fb->pixel_format == DRM_FORMAT_NV12) {
++ if (format == DRM_FORMAT_NV12) {
+ if (y) /* y-plane data rate */
+ return width * height *
+- drm_format_plane_cpp(fb->pixel_format, 0);
++ drm_format_plane_cpp(format, 0);
+ else /* uv-plane data rate */
+ return (width / 2) * (height / 2) *
+- drm_format_plane_cpp(fb->pixel_format, 1);
++ drm_format_plane_cpp(format, 1);
+ }
+
+ /* for packed formats */
+- return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
++ return width * height * drm_format_plane_cpp(format, 0);
+ }
+
+ /*
+@@ -2906,32 +2914,34 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
+ * 3 * 4096 * 8192 * 4 < 2^32
+ */
+ static unsigned int
+-skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
++skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
+ {
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+ struct drm_device *dev = intel_crtc->base.dev;
+ const struct intel_plane *intel_plane;
+- unsigned int total_data_rate = 0;
++ unsigned int rate, total_data_rate = 0;
+
++ /* Calculate and cache data rate for each plane */
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+ const struct drm_plane_state *pstate = intel_plane->base.state;
++ int id = skl_wm_plane_id(intel_plane);
+
+- if (pstate->fb == NULL)
+- continue;
++ /* packed/uv */
++ rate = skl_plane_relative_data_rate(cstate, pstate, 0);
++ cstate->wm.skl.plane_data_rate[id] = rate;
+
+- if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
+- continue;
++ /* y-plane */
++ rate = skl_plane_relative_data_rate(cstate, pstate, 1);
++ cstate->wm.skl.plane_y_data_rate[id] = rate;
++ }
+
+- /* packed/uv */
+- total_data_rate += skl_plane_relative_data_rate(cstate,
+- pstate,
+- 0);
++ /* Calculate CRTC's total data rate from cached values */
++ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
++ int id = skl_wm_plane_id(intel_plane);
+
+- if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
+- /* y-plane */
+- total_data_rate += skl_plane_relative_data_rate(cstate,
+- pstate,
+- 1);
++ /* packed/uv */
++ total_data_rate += cstate->wm.skl.plane_data_rate[id];
++ total_data_rate += cstate->wm.skl.plane_y_data_rate[id];
+ }
+
+ return total_data_rate;
+@@ -2995,6 +3005,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ * FIXME: we may not allocate every single block here.
+ */
+ total_data_rate = skl_get_total_relative_data_rate(cstate);
++ if (total_data_rate == 0)
++ return;
+
+ start = alloc->start;
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+@@ -3009,7 +3021,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ if (plane->type == DRM_PLANE_TYPE_CURSOR)
+ continue;
+
+- data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);
++ data_rate = cstate->wm.skl.plane_data_rate[id];
+
+ /*
+ * allocation for (packed formats) or (uv-plane part of planar format):
+@@ -3028,20 +3040,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ /*
+ * allocation for y_plane part of planar format:
+ */
+- if (pstate->fb->pixel_format == DRM_FORMAT_NV12) {
+- y_data_rate = skl_plane_relative_data_rate(cstate,
+- pstate,
+- 1);
+- y_plane_blocks = y_minimum[id];
+- y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
+- total_data_rate);
+-
+- ddb->y_plane[pipe][id].start = start;
+- ddb->y_plane[pipe][id].end = start + y_plane_blocks;
+-
+- start += y_plane_blocks;
+- }
++ y_data_rate = cstate->wm.skl.plane_y_data_rate[id];
++
++ y_plane_blocks = y_minimum[id];
++ y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
++ total_data_rate);
+
++ ddb->y_plane[pipe][id].start = start;
++ ddb->y_plane[pipe][id].end = start + y_plane_blocks;
++
++ start += y_plane_blocks;
+ }
+
+ }
+@@ -3820,10 +3828,28 @@ void skl_wm_get_hw_state(struct drm_device *dev)
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
+ struct drm_crtc *crtc;
++ struct intel_crtc *intel_crtc;
+
+ skl_ddb_get_hw_state(dev_priv, ddb);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ skl_pipe_wm_get_hw_state(crtc);
++
++ /* Calculate plane data rates */
++ for_each_intel_crtc(dev, intel_crtc) {
++ struct intel_crtc_state *cstate = intel_crtc->config;
++ struct intel_plane *intel_plane;
++
++ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
++ const struct drm_plane_state *pstate =
++ intel_plane->base.state;
++ int id = skl_wm_plane_id(intel_plane);
++
++ cstate->wm.skl.plane_data_rate[id] =
++ skl_plane_relative_data_rate(cstate, pstate, 0);
++ cstate->wm.skl.plane_y_data_rate[id] =
++ skl_plane_relative_data_rate(cstate, pstate, 1);
++ }
++ }
+ }
+
+ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+--
+2.7.4
+
diff --git a/0003-drm-nouveau-disp-sor-gf119-both-links-use-the-same-t.patch b/0003-drm-nouveau-disp-sor-gf119-both-links-use-the-same-t.patch
new file mode 100644
index 000000000..b93bdff17
--- /dev/null
+++ b/0003-drm-nouveau-disp-sor-gf119-both-links-use-the-same-t.patch
@@ -0,0 +1,46 @@
+From de35f524e89daf8862d49724b9045f9254bfdfea Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 14:52:01 +0200
+Subject: [PATCH 3/6] drm/nouveau/disp/sor/gf119: both links use the same
+ training register
+
+Upstream: drm-fixes for 4.7 (and cc'd 4.6-stable)
+commit a8953c52b95167b5d21a66f0859751570271d834
+
+Author: Ben Skeggs <bskeggs@redhat.com>
+AuthorDate: Fri Jun 3 14:37:40 2016 +1000
+Commit: Ben Skeggs <bskeggs@redhat.com>
+CommitDate: Tue Jun 7 08:11:14 2016 +1000
+
+ drm/nouveau/disp/sor/gf119: both links use the same training register
+
+ It appears that, for whatever reason, both link A and B use the same
+ register to control the training pattern. It's a little odd, as the
+ GPUs before this (Tesla/Fermi1) have per-link registers, as do newer
+ GPUs (Maxwell).
+
+ Fixes the third DP output on NVS 510 (GK107).
+
+ Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+ Cc: stable@vger.kernel.org
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+index b4b41b1..5111560 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -40,8 +40,7 @@ static int
+ gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+ {
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+- const u32 loff = gf119_sor_loff(outp);
+- nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
++ nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern);
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/0004-drm-i915-gen9-Allow-calculation-of-data-rate-for-in-.patch b/0004-drm-i915-gen9-Allow-calculation-of-data-rate-for-in-.patch
new file mode 100644
index 000000000..3a2b0aa1c
--- /dev/null
+++ b/0004-drm-i915-gen9-Allow-calculation-of-data-rate-for-in-.patch
@@ -0,0 +1,141 @@
+From a75a3c793e2cd3e7648597f2c77d87453f520f31 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 11:13:23 +0200
+Subject: [PATCH 04/17] drm/i915/gen9: Allow calculation of data rate for
+ in-flight state (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 9c74d82621c553f0da1f41bd5d90f5eab5659fdb
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:05:58 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:32:49 2016 -0700
+
+ drm/i915/gen9: Allow calculation of data rate for in-flight state (v2)
+
+ Our skl_get_total_relative_data_rate() function gets passed a crtc state
+ object to calculate the data rate for, but it currently always looks
+ up the committed plane states that correspond to that CRTC. Let's
+ check whether the CRTC state is an in-flight state (meaning
+ cstate->state is non-NULL) and if so, use the corresponding in-flight
+ plane states.
+
+ We'll soon be using this function exclusively for in-flight states; at
+ that time we'll be able to simplify the function a bit, but for now we
+ allow it to be used in either mode.
+
+ v2:
+ - Rebase on top of changes to cache plane data rates.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-5-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_pm.c | 74 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 60 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 854f0a4..b863bfc 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2914,25 +2914,69 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
+ * 3 * 4096 * 8192 * 4 < 2^32
+ */
+ static unsigned int
+-skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
++skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
+ {
+- struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+- struct drm_device *dev = intel_crtc->base.dev;
++ struct drm_crtc_state *cstate = &intel_cstate->base;
++ struct drm_atomic_state *state = cstate->state;
++ struct drm_crtc *crtc = cstate->crtc;
++ struct drm_device *dev = crtc->dev;
++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ const struct intel_plane *intel_plane;
+ unsigned int rate, total_data_rate = 0;
++ int id;
+
+ /* Calculate and cache data rate for each plane */
+- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+- const struct drm_plane_state *pstate = intel_plane->base.state;
+- int id = skl_wm_plane_id(intel_plane);
++ /*
++ * FIXME: At the moment this function can be called on either an
++ * in-flight or a committed state object. If it's in-flight then we
++ * only want to re-calculate the plane data rate for planes that are
++ * part of the transaction (i.e., we don't want to grab any additional
++ * plane states if we don't have to). If we're operating on committed
++ * state, we'll just go ahead and recalculate the plane data rate for
++ * all planes.
++ *
++ * Once we finish moving our DDB allocation to the atomic check phase,
++ * we'll only be calling this function on in-flight state objects, so
++ * the 'else' branch here will go away.
++ */
++ if (state) {
++ struct drm_plane *plane;
++ struct drm_plane_state *pstate;
++ int i;
++
++ for_each_plane_in_state(state, plane, pstate, i) {
++ intel_plane = to_intel_plane(plane);
++ id = skl_wm_plane_id(intel_plane);
++
++ if (intel_plane->pipe != intel_crtc->pipe)
++ continue;
++
++ /* packed/uv */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 0);
++ intel_cstate->wm.skl.plane_data_rate[id] = rate;
++
++ /* y-plane */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 1);
++ intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
++ }
++ } else {
++ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
++ const struct drm_plane_state *pstate =
++ intel_plane->base.state;
++ int id = skl_wm_plane_id(intel_plane);
+
+- /* packed/uv */
+- rate = skl_plane_relative_data_rate(cstate, pstate, 0);
+- cstate->wm.skl.plane_data_rate[id] = rate;
++ /* packed/uv */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 0);
++ intel_cstate->wm.skl.plane_data_rate[id] = rate;
+
+- /* y-plane */
+- rate = skl_plane_relative_data_rate(cstate, pstate, 1);
+- cstate->wm.skl.plane_y_data_rate[id] = rate;
++ /* y-plane */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 1);
++ intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
++ }
+ }
+
+ /* Calculate CRTC's total data rate from cached values */
+@@ -2940,10 +2984,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
+ int id = skl_wm_plane_id(intel_plane);
+
+ /* packed/uv */
+- total_data_rate += cstate->wm.skl.plane_data_rate[id];
+- total_data_rate += cstate->wm.skl.plane_y_data_rate[id];
++ total_data_rate += intel_cstate->wm.skl.plane_data_rate[id];
++ total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id];
+ }
+
++ WARN_ON(cstate->plane_mask && total_data_rate == 0);
++
+ return total_data_rate;
+ }
+
+--
+2.7.4
+
diff --git a/0004-drm-nouveau-disp-sor-gm107-training-pattern-register.patch b/0004-drm-nouveau-disp-sor-gm107-training-pattern-register.patch
new file mode 100644
index 000000000..a0b6171d8
--- /dev/null
+++ b/0004-drm-nouveau-disp-sor-gm107-training-pattern-register.patch
@@ -0,0 +1,195 @@
+From eb4668302adce316f53896b0fd8144ffe380a3ad Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 14:52:06 +0200
+Subject: [PATCH 4/6] drm/nouveau/disp/sor/gm107: training pattern registers
+ are like gm200
+
+Upstream: drm-fixes for 4.7 (and cc'd 4.6-stable)
+commit 4691409b3e2250ed66aa8dcefa23fe765daf7add
+
+Author: Ben Skeggs <bskeggs@redhat.com>
+AuthorDate: Fri Jun 3 15:05:52 2016 +1000
+Commit: Ben Skeggs <bskeggs@redhat.com>
+CommitDate: Tue Jun 7 08:11:25 2016 +1000
+
+ drm/nouveau/disp/sor/gm107: training pattern registers are like gm200
+
+ Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+ Cc: stable@vger.kernel.org
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 +
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 2 +-
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h | 9 +++-
+ .../gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 2 +-
+ .../nvkm/engine/disp/{gm107.c => sorgm107.c} | 50 +++++++++++-----------
+ .../gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | 15 +------
+ 6 files changed, 36 insertions(+), 43 deletions(-)
+ copy drivers/gpu/drm/nouveau/nvkm/engine/disp/{gm107.c => sorgm107.c} (55%)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+index a74c5dd..e2a64ed 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o
+ nvkm-y += nvkm/engine/disp/sornv50.o
+ nvkm-y += nvkm/engine/disp/sorg94.o
+ nvkm-y += nvkm/engine/disp/sorgf119.o
++nvkm-y += nvkm/engine/disp/sorgm107.o
+ nvkm-y += nvkm/engine/disp/sorgm200.o
+ nvkm-y += nvkm/engine/disp/dport.o
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+index b694414..f4b9cf8 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+@@ -36,7 +36,7 @@ gm107_disp = {
+ .outp.internal.crt = nv50_dac_output_new,
+ .outp.internal.tmds = nv50_sor_output_new,
+ .outp.internal.lvds = nv50_sor_output_new,
+- .outp.internal.dp = gf119_sor_dp_new,
++ .outp.internal.dp = gm107_sor_dp_new,
+ .dac.nr = 3,
+ .dac.power = nv50_dac_power,
+ .dac.sense = nv50_dac_sense,
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
+index e9067ba..4e983f6 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
+@@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
+ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+ struct nvkm_output **);
+ int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
++int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int);
+
+-int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+- struct nvkm_output **);
++int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++ struct nvkm_output **);
++int gm107_sor_dp_pattern(struct nvkm_output_dp *, int);
++
++int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++ struct nvkm_output **);
+ #endif
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+index 5111560..22706c0 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -63,7 +63,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
+ return 0;
+ }
+
+-static int
++int
+ gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ int ln, int vs, int pe, int pc)
+ {
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+similarity index 55%
+copy from drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+copy to drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+index b694414..37790b2 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2012 Red Hat Inc.
++ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+@@ -19,35 +19,35 @@
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+- * Authors: Ben Skeggs
++ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+ #include "nv50.h"
+-#include "rootnv50.h"
++#include "outpdp.h"
+
+-static const struct nv50_disp_func
+-gm107_disp = {
+- .intr = gf119_disp_intr,
+- .uevent = &gf119_disp_chan_uevent,
+- .super = gf119_disp_intr_supervisor,
+- .root = &gm107_disp_root_oclass,
+- .head.vblank_init = gf119_disp_vblank_init,
+- .head.vblank_fini = gf119_disp_vblank_fini,
+- .head.scanoutpos = gf119_disp_root_scanoutpos,
+- .outp.internal.crt = nv50_dac_output_new,
+- .outp.internal.tmds = nv50_sor_output_new,
+- .outp.internal.lvds = nv50_sor_output_new,
+- .outp.internal.dp = gf119_sor_dp_new,
+- .dac.nr = 3,
+- .dac.power = nv50_dac_power,
+- .dac.sense = nv50_dac_sense,
+- .sor.nr = 4,
+- .sor.power = nv50_sor_power,
+- .sor.hda_eld = gf119_hda_eld,
+- .sor.hdmi = gk104_hdmi_ctrl,
++int
++gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
++{
++ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
++ const u32 soff = outp->base.or * 0x800;
++ const u32 data = 0x01010101 * pattern;
++ if (outp->base.info.sorconf.link & 1)
++ nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
++ else
++ nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
++ return 0;
++}
++
++static const struct nvkm_output_dp_func
++gm107_sor_dp_func = {
++ .pattern = gm107_sor_dp_pattern,
++ .lnk_pwr = g94_sor_dp_lnk_pwr,
++ .lnk_ctl = gf119_sor_dp_lnk_ctl,
++ .drv_ctl = gf119_sor_dp_drv_ctl,
+ };
+
+ int
+-gm107_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
++gm107_sor_dp_new(struct nvkm_disp *disp, int index,
++ struct dcb_output *dcbE, struct nvkm_output **poutp)
+ {
+- return gf119_disp_new_(&gm107_disp, device, index, pdisp);
++ return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp);
+ }
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+index 2cfbef9..c44fa7e 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+@@ -57,19 +57,6 @@ gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
+ }
+
+ static int
+-gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+-{
+- struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+- const u32 soff = gm200_sor_soff(outp);
+- const u32 data = 0x01010101 * pattern;
+- if (outp->base.info.sorconf.link & 1)
+- nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
+- else
+- nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
+- return 0;
+-}
+-
+-static int
+ gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
+ {
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+@@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+
+ static const struct nvkm_output_dp_func
+ gm200_sor_dp_func = {
+- .pattern = gm200_sor_dp_pattern,
++ .pattern = gm107_sor_dp_pattern,
+ .lnk_pwr = gm200_sor_dp_lnk_pwr,
+ .lnk_ctl = gf119_sor_dp_lnk_ctl,
+ .drv_ctl = gm200_sor_dp_drv_ctl,
+--
+2.7.4
+
diff --git a/0005-drm-i915-gen9-Store-plane-minimum-blocks-in-CRTC-wm-.patch b/0005-drm-i915-gen9-Store-plane-minimum-blocks-in-CRTC-wm-.patch
new file mode 100644
index 000000000..7b1fcb144
--- /dev/null
+++ b/0005-drm-i915-gen9-Store-plane-minimum-blocks-in-CRTC-wm-.patch
@@ -0,0 +1,67 @@
+From cd21ce996b94fd149b3487398e5250e9f0cc8811 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:39:24 +0200
+Subject: [PATCH 05/17] drm/i915/gen9: Store plane minimum blocks in CRTC wm
+ state (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 86a2100a8b96594902bb59b90614377df4f64ce0
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:05:59 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:32:56 2016 -0700
+
+ drm/i915/gen9: Store plane minimum blocks in CRTC wm state (v2)
+
+ This will eventually allow us to re-use old values without
+ re-calculating them for unchanged planes (which also helps us avoid
+ re-grabbing extra plane states).
+
+ v2:
+ - Drop unnecessary memset's; they were meant for a later patch (which
+ got reworked anyway to not need them, but were mis-rebased into this
+ one. (Maarten)
+
+ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-6-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_drv.h | 4 ++++
+ drivers/gpu/drm/i915/intel_pm.c | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 7c00ab6..d246308 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -389,6 +389,10 @@ struct intel_crtc_wm_state {
+ /* cached plane data rate */
+ unsigned plane_data_rate[I915_MAX_PLANES];
+ unsigned plane_y_data_rate[I915_MAX_PLANES];
++
++ /* minimum block allocation */
++ uint16_t minimum_blocks[I915_MAX_PLANES];
++ uint16_t minimum_y_blocks[I915_MAX_PLANES];
+ } skl;
+ };
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index b863bfc..00db6e9 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3006,8 +3006,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ enum pipe pipe = intel_crtc->pipe;
+ struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
+ uint16_t alloc_size, start, cursor_blocks;
+- uint16_t minimum[I915_MAX_PLANES];
+- uint16_t y_minimum[I915_MAX_PLANES];
++ uint16_t *minimum = cstate->wm.skl.minimum_blocks;
++ uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
+ unsigned int total_data_rate;
+
+ skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
+--
+2.7.4
+
diff --git a/0005-i915-fbc-Disable-on-HSW-by-default-for-now.patch b/0005-i915-fbc-Disable-on-HSW-by-default-for-now.patch
new file mode 100644
index 000000000..d95f2f4d0
--- /dev/null
+++ b/0005-i915-fbc-Disable-on-HSW-by-default-for-now.patch
@@ -0,0 +1,55 @@
+From 28d0147bded959b2c4d3eb1aa957452d5dbb0cc9 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 14:52:10 +0200
+Subject: [PATCH 5/6] i915/fbc: Disable on HSW by default for now
+
+Upstream: posted on dri-devel (and r-b'd)
+
+Author: cpaul@redhat.com <cpaul@redhat.com>
+AuthorDate: Thu Jun 9 11:58:15 2016 -0400
+Commit: Rob Clark <rclark@redhat.com>
+CommitDate: Thu Jun 9 15:43:07 2016 -0400
+
+ i915/fbc: Disable on HSW by default for now
+
+ >From https://bugs.freedesktop.org/show_bug.cgi?id=96461 :
+
+ This was kind of a difficult bug to track down. If you're using a
+ Haswell system running GNOME and you have fbc completely enabled and
+ working, playing videos can result in video artifacts. Steps to
+ reproduce:
+
+ - Run GNOME
+ - Ensure FBC is enabled and active
+ - Download a movie, I used the ogg version of Big Buck Bunny for this
+ - Run `gst-launch-1.0 filesrc location='some_movie.ogg' ! decodebin !
+ glimagesink` in a terminal
+ - Watch for about over a minute, you'll see small horizontal lines go
+ down the screen.
+
+ For the time being, disable FBC for Haswell by default.
+
+ Signed-off-by: Lyude <cpaul@redhat.com>
+ Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+ Cc: stable@vger.kernel.org
+---
+ drivers/gpu/drm/i915/intel_fbc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
+index 0f0492f..28f4407 100644
+--- a/drivers/gpu/drm/i915/intel_fbc.c
++++ b/drivers/gpu/drm/i915/intel_fbc.c
+@@ -823,8 +823,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc)
+ {
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct intel_fbc *fbc = &dev_priv->fbc;
+- bool enable_by_default = IS_HASWELL(dev_priv) ||
+- IS_BROADWELL(dev_priv);
++ bool enable_by_default = IS_BROADWELL(dev_priv);
+
+ if (intel_vgpu_active(dev_priv->dev)) {
+ fbc->no_fbc_reason = "VGPU is active";
+--
+2.7.4
+
diff --git a/0006-drm-i915-Track-whether-an-atomic-transaction-changes.patch b/0006-drm-i915-Track-whether-an-atomic-transaction-changes.patch
new file mode 100644
index 000000000..7320abf6d
--- /dev/null
+++ b/0006-drm-i915-Track-whether-an-atomic-transaction-changes.patch
@@ -0,0 +1,68 @@
+From 00edb23bcefa3ad6931f2a2855fe0801a55523f7 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:39:40 +0200
+Subject: [PATCH 06/17] drm/i915: Track whether an atomic transaction changes
+ the active CRTC's
+
+Upstream: since drm-intel-next-2016-05-22
+commit 8b4a7d0597cd9910d7127ffae6ae91d21853a8a2
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:00 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:33:10 2016 -0700
+
+ drm/i915: Track whether an atomic transaction changes the active CRTC's
+
+ For the purposes of DDB re-allocation we need to know whether a
+ transaction changes the list of CRTC's that are active. While
+ state->modeset could be used for this purpose, that would be slightly
+ too aggressive since it would lead us to re-allocate the DDB when a
+ CRTC's mode changes, but not its final active state.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-7-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_display.c | 3 +++
+ drivers/gpu/drm/i915/intel_drv.h | 10 ++++++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 7d855ba..f53df81 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13183,6 +13183,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
+ intel_state->active_crtcs |= 1 << i;
+ else
+ intel_state->active_crtcs &= ~(1 << i);
++
++ if (crtc_state->active != crtc->state->active)
++ intel_state->active_pipe_changes |= drm_crtc_mask(crtc);
+ }
+
+ /*
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index d246308..672ca56 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -256,6 +256,16 @@ struct intel_atomic_state {
+
+ bool dpll_set, modeset;
+
++ /*
++ * Does this transaction change the pipes that are active? This mask
++ * tracks which CRTC's have changed their active state at the end of
++ * the transaction (not counting the temporary disable during modesets).
++ * This mask should only be non-zero when intel_state->modeset is true,
++ * but the converse is not necessarily true; simply changing a mode may
++ * not flip the final active status of any CRTC's
++ */
++ unsigned int active_pipe_changes;
++
+ unsigned int active_crtcs;
+ unsigned int min_pixclk[I915_MAX_PIPES];
+
+--
+2.7.4
+
diff --git a/0007-drm-i915-gen9-Allow-skl_allocate_pipe_ddb-to-operate.patch b/0007-drm-i915-gen9-Allow-skl_allocate_pipe_ddb-to-operate.patch
new file mode 100644
index 000000000..deb90fb01
--- /dev/null
+++ b/0007-drm-i915-gen9-Allow-skl_allocate_pipe_ddb-to-operate.patch
@@ -0,0 +1,352 @@
+From 99dd9c3733696d4a2536b21988c9b1b8f5195c5b Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:40:00 +0200
+Subject: [PATCH 07/17] drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate
+ on in-flight state (v3)
+
+Upstream: since drm-intel-next-2016-05-22
+commit c107acfeb03187873657ccc8af4fc5c704b3626b
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:01 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:33:16 2016 -0700
+
+ drm/i915/gen9: Allow skl_allocate_pipe_ddb() to operate on in-flight state (v3)
+
+ We eventually want to calculate watermark values at atomic 'check' time
+ instead of atomic 'commit' time so that any requested configurations
+ that result in impossible watermark requirements are properly rejected.
+ The first step along this path is to allocate the DDB at atomic 'check'
+ time. As we perform this transition, allow the main allocation function
+ to operate successfully on either an in-flight state or an
+ already-commited state. Once we complete the transition in a future
+ patch, we'll come back and remove the unnecessary logic for the
+ already-committed case.
+
+ v2: Rebase/refactor; we should no longer need to grab extra plane states
+ while allocating the DDB since we can pull cached data rates and
+ minimum block counts from the CRTC state for any planes that aren't
+ being modified by this transaction.
+
+ v3:
+ - Simplify memsets to clear DDB plane entries. (Maarten)
+ - Drop a redundant memset of plane[pipe][PLANE_CURSOR] that was added
+ by an earlier Coccinelle patch. (Maarten)
+ - Assign *num_active at the top of skl_ddb_get_pipe_allocation_limits()
+ so that no code paths return without setting it. (kbuild robot)
+
+ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-8-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/i915_drv.h | 6 ++
+ drivers/gpu/drm/i915/intel_pm.c | 179 +++++++++++++++++++++++++++++-----------
+ 2 files changed, 139 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index daba7eb..804af6f 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -281,6 +281,12 @@ struct i915_hotplug {
+ &dev->mode_config.plane_list, \
+ base.head)
+
++#define for_each_intel_plane_mask(dev, intel_plane, plane_mask) \
++ list_for_each_entry(intel_plane, &dev->mode_config.plane_list, \
++ base.head) \
++ for_each_if ((plane_mask) & \
++ (1 << drm_plane_index(&intel_plane->base)))
++
+ #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) \
+ list_for_each_entry(intel_plane, \
+ &(dev)->mode_config.plane_list, \
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 00db6e9..ee82b1f 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2788,13 +2788,25 @@ skl_wm_plane_id(const struct intel_plane *plane)
+ static void
+ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+ const struct intel_crtc_state *cstate,
+- const struct intel_wm_config *config,
+- struct skl_ddb_entry *alloc /* out */)
++ struct intel_wm_config *config,
++ struct skl_ddb_entry *alloc, /* out */
++ int *num_active /* out */)
+ {
++ struct drm_atomic_state *state = cstate->base.state;
++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
++ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct drm_crtc *for_crtc = cstate->base.crtc;
+ struct drm_crtc *crtc;
+ unsigned int pipe_size, ddb_size;
+ int nth_active_pipe;
++ int pipe = to_intel_crtc(for_crtc)->pipe;
++
++ if (intel_state && intel_state->active_pipe_changes)
++ *num_active = hweight32(intel_state->active_crtcs);
++ else if (intel_state)
++ *num_active = hweight32(dev_priv->active_crtcs);
++ else
++ *num_active = config->num_pipes_active;
+
+ if (!cstate->base.active) {
+ alloc->start = 0;
+@@ -2809,25 +2821,56 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+
+ ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+- nth_active_pipe = 0;
+- for_each_crtc(dev, crtc) {
+- if (!to_intel_crtc(crtc)->active)
+- continue;
++ /*
++ * FIXME: At the moment we may be called on either in-flight or fully
++ * committed cstate's. Once we fully move DDB allocation in the check
++ * phase, we'll only be called on in-flight states and the 'else'
++ * branch here will go away.
++ *
++ * The 'else' branch is slightly racy here, but it was racy to begin
++ * with; since it's going away soon, no effort is made to address that.
++ */
++ if (state) {
++ /*
++ * If the state doesn't change the active CRTC's, then there's
++ * no need to recalculate; the existing pipe allocation limits
++ * should remain unchanged. Note that we're safe from racing
++ * commits since any racing commit that changes the active CRTC
++ * list would need to grab _all_ crtc locks, including the one
++ * we currently hold.
++ */
++ if (!intel_state->active_pipe_changes) {
++ *alloc = dev_priv->wm.skl_hw.ddb.pipe[pipe];
++ return;
++ }
+
+- if (crtc == for_crtc)
+- break;
++ nth_active_pipe = hweight32(intel_state->active_crtcs &
++ (drm_crtc_mask(for_crtc) - 1));
++ pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
++ alloc->start = nth_active_pipe * ddb_size / *num_active;
++ alloc->end = alloc->start + pipe_size;
++ } else {
++ nth_active_pipe = 0;
++ for_each_crtc(dev, crtc) {
++ if (!to_intel_crtc(crtc)->active)
++ continue;
+
+- nth_active_pipe++;
+- }
++ if (crtc == for_crtc)
++ break;
++
++ nth_active_pipe++;
++ }
+
+- pipe_size = ddb_size / config->num_pipes_active;
+- alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
+- alloc->end = alloc->start + pipe_size;
++ pipe_size = ddb_size / config->num_pipes_active;
++ alloc->start = nth_active_pipe * ddb_size /
++ config->num_pipes_active;
++ alloc->end = alloc->start + pipe_size;
++ }
+ }
+
+-static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
++static unsigned int skl_cursor_allocation(int num_active)
+ {
+- if (config->num_pipes_active == 1)
++ if (num_active == 1)
+ return 32;
+
+ return 8;
+@@ -2993,33 +3036,44 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
+ return total_data_rate;
+ }
+
+-static void
++static int
+ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_ddb_allocation *ddb /* out */)
+ {
++ struct drm_atomic_state *state = cstate->base.state;
+ struct drm_crtc *crtc = cstate->base.crtc;
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_wm_config *config = &dev_priv->wm.config;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_plane *intel_plane;
++ struct drm_plane *plane;
++ struct drm_plane_state *pstate;
+ enum pipe pipe = intel_crtc->pipe;
+ struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
+ uint16_t alloc_size, start, cursor_blocks;
+ uint16_t *minimum = cstate->wm.skl.minimum_blocks;
+ uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
+ unsigned int total_data_rate;
++ int num_active;
++ int id, i;
++
++ if (!cstate->base.active) {
++ ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
++ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
++ memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
++ return 0;
++ }
+
+- skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
++ skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc,
++ &num_active);
+ alloc_size = skl_ddb_entry_size(alloc);
+ if (alloc_size == 0) {
+ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+- memset(&ddb->plane[pipe][PLANE_CURSOR], 0,
+- sizeof(ddb->plane[pipe][PLANE_CURSOR]));
+- return;
++ return 0;
+ }
+
+- cursor_blocks = skl_cursor_allocation(config);
++ cursor_blocks = skl_cursor_allocation(num_active);
+ ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks;
+ ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
+
+@@ -3027,21 +3081,55 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ alloc->end -= cursor_blocks;
+
+ /* 1. Allocate the mininum required blocks for each active plane */
+- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+- struct drm_plane *plane = &intel_plane->base;
+- struct drm_framebuffer *fb = plane->state->fb;
+- int id = skl_wm_plane_id(intel_plane);
++ /*
++ * TODO: Remove support for already-committed state once we
++ * only allocate DDB on in-flight states.
++ */
++ if (state) {
++ for_each_plane_in_state(state, plane, pstate, i) {
++ intel_plane = to_intel_plane(plane);
++ id = skl_wm_plane_id(intel_plane);
+
+- if (!to_intel_plane_state(plane->state)->visible)
+- continue;
++ if (intel_plane->pipe != pipe)
++ continue;
+
+- if (plane->type == DRM_PLANE_TYPE_CURSOR)
+- continue;
++ if (!to_intel_plane_state(pstate)->visible) {
++ minimum[id] = 0;
++ y_minimum[id] = 0;
++ continue;
++ }
++ if (plane->type == DRM_PLANE_TYPE_CURSOR) {
++ minimum[id] = 0;
++ y_minimum[id] = 0;
++ continue;
++ }
+
+- minimum[id] = 8;
+- alloc_size -= minimum[id];
+- y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
+- alloc_size -= y_minimum[id];
++ minimum[id] = 8;
++ if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
++ y_minimum[id] = 8;
++ else
++ y_minimum[id] = 0;
++ }
++ } else {
++ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
++ struct drm_plane *plane = &intel_plane->base;
++ struct drm_framebuffer *fb = plane->state->fb;
++ int id = skl_wm_plane_id(intel_plane);
++
++ if (!to_intel_plane_state(plane->state)->visible)
++ continue;
++
++ if (plane->type == DRM_PLANE_TYPE_CURSOR)
++ continue;
++
++ minimum[id] = 8;
++ y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
++ }
++ }
++
++ for (i = 0; i < PLANE_CURSOR; i++) {
++ alloc_size -= minimum[i];
++ alloc_size -= y_minimum[i];
+ }
+
+ /*
+@@ -3052,21 +3140,14 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ */
+ total_data_rate = skl_get_total_relative_data_rate(cstate);
+ if (total_data_rate == 0)
+- return;
++ return 0;
+
+ start = alloc->start;
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+- struct drm_plane *plane = &intel_plane->base;
+- struct drm_plane_state *pstate = intel_plane->base.state;
+ unsigned int data_rate, y_data_rate;
+ uint16_t plane_blocks, y_plane_blocks = 0;
+ int id = skl_wm_plane_id(intel_plane);
+
+- if (!to_intel_plane_state(pstate)->visible)
+- continue;
+- if (plane->type == DRM_PLANE_TYPE_CURSOR)
+- continue;
+-
+ data_rate = cstate->wm.skl.plane_data_rate[id];
+
+ /*
+@@ -3078,8 +3159,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
+ total_data_rate);
+
+- ddb->plane[pipe][id].start = start;
+- ddb->plane[pipe][id].end = start + plane_blocks;
++ /* Leave disabled planes at (0,0) */
++ if (data_rate) {
++ ddb->plane[pipe][id].start = start;
++ ddb->plane[pipe][id].end = start + plane_blocks;
++ }
+
+ start += plane_blocks;
+
+@@ -3092,12 +3176,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
+ total_data_rate);
+
+- ddb->y_plane[pipe][id].start = start;
+- ddb->y_plane[pipe][id].end = start + y_plane_blocks;
++ if (y_data_rate) {
++ ddb->y_plane[pipe][id].start = start;
++ ddb->y_plane[pipe][id].end = start + y_plane_blocks;
++ }
+
+ start += y_plane_blocks;
+ }
+
++ return 0;
+ }
+
+ static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
+@@ -3588,7 +3675,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+
+- skl_allocate_pipe_ddb(cstate, ddb);
++ WARN_ON(skl_allocate_pipe_ddb(cstate, ddb) != 0);
+ skl_build_pipe_wm(cstate, ddb, pipe_wm);
+
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+--
+2.7.4
+
diff --git a/0008-drm-i915-Add-distrust_bios_wm-flag-to-dev_priv-v2.patch b/0008-drm-i915-Add-distrust_bios_wm-flag-to-dev_priv-v2.patch
new file mode 100644
index 000000000..7a45a28a4
--- /dev/null
+++ b/0008-drm-i915-Add-distrust_bios_wm-flag-to-dev_priv-v2.patch
@@ -0,0 +1,94 @@
+From 0126336af286ea85c1137ad13882f8c93d74c6c3 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:40:13 +0200
+Subject: [PATCH 08/17] drm/i915: Add distrust_bios_wm flag to dev_priv (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 279e99d76e6097ee7b531114777fa9b030496d81
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:02 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:33:54 2016 -0700
+
+ drm/i915: Add distrust_bios_wm flag to dev_priv (v2)
+
+ SKL-style platforms can't fully trust the watermark/DDB settings
+ programmed by the BIOS and need to do extra sanitization on their first
+ atomic update. Add a flag to dev_priv that is set during hardware
+ readout and cleared at the end of the first commit.
+
+ Note that for the somewhat common case where everything is turned off
+ when the driver starts up, we don't need to bother with a recompute...we
+ know exactly what the DDB should be (all zero's) so just setup the DDB
+ directly in that case.
+
+ v2:
+ - Move clearing of distrust_bios_wm up below the swap_state call since
+ it's a more natural / self-explanatory location. (Maarten)
+ - Use dev_priv->active_crtcs to test whether any CRTC's are turned on
+ during HW WM readout rather than trying to count the active CRTC's
+ again ourselves. (Maarten)
+
+ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-9-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/i915_drv.h | 7 +++++++
+ drivers/gpu/drm/i915/intel_display.c | 1 +
+ drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 804af6f..ae7932a 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1986,6 +1986,13 @@ struct drm_i915_private {
+ };
+
+ uint8_t max_level;
++
++ /*
++ * Set during HW readout of watermarks/DDB. Some platforms
++ * need to know when we're still using BIOS-provided values
++ * (which we don't fully trust).
++ */
++ bool distrust_bios_wm;
+ } wm;
+
+ struct i915_runtime_pm pm;
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index f53df81..786f3d9 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13516,6 +13516,7 @@ static int intel_atomic_commit(struct drm_device *dev,
+
+ drm_atomic_helper_swap_state(dev, state);
+ dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
++ dev_priv->wm.distrust_bios_wm = false;
+
+ if (intel_state->modeset) {
+ memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index ee82b1f..6a09d7a 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3967,6 +3967,14 @@ void skl_wm_get_hw_state(struct drm_device *dev)
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ skl_pipe_wm_get_hw_state(crtc);
+
++ if (dev_priv->active_crtcs) {
++ /* Fully recompute DDB on first atomic commit */
++ dev_priv->wm.distrust_bios_wm = true;
++ } else {
++ /* Easy/common case; just sanitize DDB now if everything off */
++ memset(ddb, 0, sizeof(*ddb));
++ }
++
+ /* Calculate plane data rates */
+ for_each_intel_crtc(dev, intel_crtc) {
+ struct intel_crtc_state *cstate = intel_crtc->config;
+--
+2.7.4
+
diff --git a/0009-drm-i915-gen9-Compute-DDB-allocation-at-atomic-check.patch b/0009-drm-i915-gen9-Compute-DDB-allocation-at-atomic-check.patch
new file mode 100644
index 000000000..53fb0cd7a
--- /dev/null
+++ b/0009-drm-i915-gen9-Compute-DDB-allocation-at-atomic-check.patch
@@ -0,0 +1,254 @@
+From 0e9cf00438e4df1d97af44d3c52cc1cacc4dd2c9 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:40:26 +0200
+Subject: [PATCH 09/17] drm/i915/gen9: Compute DDB allocation at atomic check
+ time (v4)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 98d39494d3759f84ce50e505059bc80f54c1c47b
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:03 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:00 2016 -0700
+
+ drm/i915/gen9: Compute DDB allocation at atomic check time (v4)
+
+ Calculate the DDB blocks needed to satisfy the current atomic
+ transaction at atomic check time. This is a prerequisite to calculating
+ SKL watermarks during the 'check' phase and rejecting any configurations
+ that we can't find valid watermarks for.
+
+ Due to the nature of DDB allocation, it's possible for the addition of a
+ new CRTC to make the watermark configuration already in use on another,
+ unchanged CRTC become invalid. A change in which CRTC's are active
+ triggers a recompute of the entire DDB, which unfortunately means we
+ need to disallow any other atomic commits from racing with such an
+ update. If the active CRTC's change, we need to grab the lock on all
+ CRTC's and run all CRTC's through their 'check' handler to recompute and
+ re-check their per-CRTC DDB allocations.
+
+ Note that with this patch we only compute the DDB allocation but we
+ don't actually use the computed values during watermark programming yet.
+ For ease of review/testing/bisecting, we still recompute the DDB at
+ watermark programming time and just WARN() if it doesn't match the
+ precomputed values. A future patch will switch over to using the
+ precomputed values once we're sure they're being properly computed.
+
+ Another clarifying note: DDB allocation itself shouldn't ever fail with
+ the algorithm we use today (i.e., we have enough DDB blocks on BXT to
+ support the minimum needs of the worst-case scenario of every pipe/plane
+ enabled at full size). However the watermarks calculations based on the
+ DDB may fail and we'll be moving those to the atomic check as well in
+ future patches.
+
+ v2:
+ - Skip DDB calculations in the rare case where our transaction doesn't
+ actually touch any CRTC's at all. Assuming at least one CRTC state
+ is present in our transaction, then it means we can't race with any
+ transactions that would update dev_priv->active_crtcs (which requires
+ _all_ CRTC locks).
+
+ v3:
+ - Also calculate DDB during initial hw readout, to prevent using
+ incorrect bios values. (Maarten)
+
+ v4:
+ - Use new distrust_bios_wm flag instead of skip_initial_wm (which was
+ never actually set).
+ - Set intel_state->active_pipe_changes instead of just realloc_pipes
+
+ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Cc: Lyude Paul <cpaul@redhat.com>
+ Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-10-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/i915_drv.h | 5 +++
+ drivers/gpu/drm/i915/intel_display.c | 18 ++++++++
+ drivers/gpu/drm/i915/intel_drv.h | 3 ++
+ drivers/gpu/drm/i915/intel_pm.c | 79 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 105 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index ae7932a..237df9f 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -296,6 +296,10 @@ struct i915_hotplug {
+ #define for_each_intel_crtc(dev, intel_crtc) \
+ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
+
++#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \
++ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) \
++ for_each_if ((crtc_mask) & (1 << drm_crtc_index(&intel_crtc->base)))
++
+ #define for_each_intel_encoder(dev, intel_encoder) \
+ list_for_each_entry(intel_encoder, \
+ &(dev)->mode_config.encoder_list, \
+@@ -638,6 +642,7 @@ struct drm_i915_display_funcs {
+ int (*compute_pipe_wm)(struct intel_crtc *crtc,
+ struct drm_atomic_state *state);
+ void (*program_watermarks)(struct intel_crtc_state *cstate);
++ int (*compute_global_watermarks)(struct drm_atomic_state *state);
+ void (*update_wm)(struct drm_crtc *crtc);
+ int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
+ void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 786f3d9..03e2635 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13225,6 +13225,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
+ static void calc_watermark_data(struct drm_atomic_state *state)
+ {
+ struct drm_device *dev = state->dev;
++ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *cstate;
+@@ -13254,6 +13255,10 @@ static void calc_watermark_data(struct drm_atomic_state *state)
+ pstate->crtc_h != pstate->src_h >> 16)
+ intel_state->wm_config.sprites_scaled = true;
+ }
++
++ /* Is there platform-specific watermark information to calculate? */
++ if (dev_priv->display.compute_global_watermarks)
++ dev_priv->display.compute_global_watermarks(state);
+ }
+
+ /**
+@@ -13616,6 +13621,19 @@ static int intel_atomic_commit(struct drm_device *dev,
+ modeset_put_power_domains(dev_priv, put_domains[i]);
+ }
+
++ /*
++ * Temporary sanity check: make sure our pre-computed DDB matches the
++ * one we actually wind up programming.
++ *
++ * Not a great place to put this, but the easiest place we have access
++ * to both the pre-computed and final DDB's; we'll be removing this
++ * check in the next patch anyway.
++ */
++ WARN(IS_GEN9(dev) &&
++ memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
++ sizeof(intel_state->ddb)),
++ "Pre-computed DDB does not match final DDB!\n");
++
+ if (intel_state->modeset)
+ intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
+
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 672ca56..4d6336a 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -271,6 +271,9 @@ struct intel_atomic_state {
+
+ struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+ struct intel_wm_config wm_config;
++
++ /* Gen9+ only */
++ struct skl_ddb_allocation ddb;
+ };
+
+ struct intel_plane_state {
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 6a09d7a..f60519d 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3751,6 +3751,84 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
+
+ }
+
++static int
++skl_compute_ddb(struct drm_atomic_state *state)
++{
++ struct drm_device *dev = state->dev;
++ struct drm_i915_private *dev_priv = to_i915(dev);
++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
++ struct intel_crtc *intel_crtc;
++ unsigned realloc_pipes = dev_priv->active_crtcs;
++ int ret;
++
++ /*
++ * If this is our first atomic update following hardware readout,
++ * we can't trust the DDB that the BIOS programmed for us. Let's
++ * pretend that all pipes switched active status so that we'll
++ * ensure a full DDB recompute.
++ */
++ if (dev_priv->wm.distrust_bios_wm)
++ intel_state->active_pipe_changes = ~0;
++
++ /*
++ * If the modeset changes which CRTC's are active, we need to
++ * recompute the DDB allocation for *all* active pipes, even
++ * those that weren't otherwise being modified in any way by this
++ * atomic commit. Due to the shrinking of the per-pipe allocations
++ * when new active CRTC's are added, it's possible for a pipe that
++ * we were already using and aren't changing at all here to suddenly
++ * become invalid if its DDB needs exceeds its new allocation.
++ *
++ * Note that if we wind up doing a full DDB recompute, we can't let
++ * any other display updates race with this transaction, so we need
++ * to grab the lock on *all* CRTC's.
++ */
++ if (intel_state->active_pipe_changes)
++ realloc_pipes = ~0;
++
++ for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
++ struct intel_crtc_state *cstate;
++
++ cstate = intel_atomic_get_crtc_state(state, intel_crtc);
++ if (IS_ERR(cstate))
++ return PTR_ERR(cstate);
++
++ ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static int
++skl_compute_wm(struct drm_atomic_state *state)
++{
++ struct drm_crtc *crtc;
++ struct drm_crtc_state *cstate;
++ int ret, i;
++ bool changed = false;
++
++ /*
++ * If this transaction isn't actually touching any CRTC's, don't
++ * bother with watermark calculation. Note that if we pass this
++ * test, we're guaranteed to hold at least one CRTC state mutex,
++ * which means we can safely use values like dev_priv->active_crtcs
++ * since any racing commits that want to update them would need to
++ * hold _all_ CRTC state mutexes.
++ */
++ for_each_crtc_in_state(state, crtc, cstate, i)
++ changed = true;
++ if (!changed)
++ return 0;
++
++ ret = skl_compute_ddb(state);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
+ static void skl_update_wm(struct drm_crtc *crtc)
+ {
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+@@ -7258,6 +7336,7 @@ void intel_init_pm(struct drm_device *dev)
+ dev_priv->display.init_clock_gating =
+ bxt_init_clock_gating;
+ dev_priv->display.update_wm = skl_update_wm;
++ dev_priv->display.compute_global_watermarks = skl_compute_wm;
+ } else if (HAS_PCH_SPLIT(dev)) {
+ ilk_setup_wm_latency(dev);
+
+--
+2.7.4
+
diff --git a/0010-drm-i915-gen9-Drop-re-allocation-of-DDB-at-atomic-co.patch b/0010-drm-i915-gen9-Drop-re-allocation-of-DDB-at-atomic-co.patch
new file mode 100644
index 000000000..4d40a4e93
--- /dev/null
+++ b/0010-drm-i915-gen9-Drop-re-allocation-of-DDB-at-atomic-co.patch
@@ -0,0 +1,389 @@
+From 6a86f1d01bb25a687c59dd6b3e6deea362cf0ee1 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:40:40 +0200
+Subject: [PATCH 10/17] drm/i915/gen9: Drop re-allocation of DDB at atomic
+ commit (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit a6d3460e62d17098a815a53f23e44d814cb347e0
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:04 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:06 2016 -0700
+
+ drm/i915/gen9: Drop re-allocation of DDB at atomic commit (v2)
+
+ Now that we're properly pre-allocating the DDB during the atomic check
+ phase and we trust that the allocation is appropriate, let's actually
+ use the allocation computed and not duplicate that work during the
+ commit phase.
+
+ v2:
+ - Significant rebasing now that we can use cached data rates and
+ minimum block allocations to avoid grabbing additional plane states.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-11-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_display.c | 14 +--
+ drivers/gpu/drm/i915/intel_pm.c | 224 +++++++++++------------------------
+ 2 files changed, 67 insertions(+), 171 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 03e2635..b484fda 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13522,6 +13522,7 @@ static int intel_atomic_commit(struct drm_device *dev,
+ drm_atomic_helper_swap_state(dev, state);
+ dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
+ dev_priv->wm.distrust_bios_wm = false;
++ dev_priv->wm.skl_results.ddb = intel_state->ddb;
+
+ if (intel_state->modeset) {
+ memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
+@@ -13621,19 +13622,6 @@ static int intel_atomic_commit(struct drm_device *dev,
+ modeset_put_power_domains(dev_priv, put_domains[i]);
+ }
+
+- /*
+- * Temporary sanity check: make sure our pre-computed DDB matches the
+- * one we actually wind up programming.
+- *
+- * Not a great place to put this, but the easiest place we have access
+- * to both the pre-computed and final DDB's; we'll be removing this
+- * check in the next patch anyway.
+- */
+- WARN(IS_GEN9(dev) &&
+- memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
+- sizeof(intel_state->ddb)),
+- "Pre-computed DDB does not match final DDB!\n");
+-
+ if (intel_state->modeset)
+ intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index f60519d..80f9f18 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2788,7 +2788,6 @@ skl_wm_plane_id(const struct intel_plane *plane)
+ static void
+ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+ const struct intel_crtc_state *cstate,
+- struct intel_wm_config *config,
+ struct skl_ddb_entry *alloc, /* out */
+ int *num_active /* out */)
+ {
+@@ -2796,24 +2795,22 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct drm_crtc *for_crtc = cstate->base.crtc;
+- struct drm_crtc *crtc;
+ unsigned int pipe_size, ddb_size;
+ int nth_active_pipe;
+ int pipe = to_intel_crtc(for_crtc)->pipe;
+
+- if (intel_state && intel_state->active_pipe_changes)
+- *num_active = hweight32(intel_state->active_crtcs);
+- else if (intel_state)
+- *num_active = hweight32(dev_priv->active_crtcs);
+- else
+- *num_active = config->num_pipes_active;
+-
+- if (!cstate->base.active) {
++ if (WARN_ON(!state) || !cstate->base.active) {
+ alloc->start = 0;
+ alloc->end = 0;
++ *num_active = hweight32(dev_priv->active_crtcs);
+ return;
+ }
+
++ if (intel_state->active_pipe_changes)
++ *num_active = hweight32(intel_state->active_crtcs);
++ else
++ *num_active = hweight32(dev_priv->active_crtcs);
++
+ if (IS_BROXTON(dev))
+ ddb_size = BXT_DDB_SIZE;
+ else
+@@ -2822,50 +2819,23 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+ ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+ /*
+- * FIXME: At the moment we may be called on either in-flight or fully
+- * committed cstate's. Once we fully move DDB allocation in the check
+- * phase, we'll only be called on in-flight states and the 'else'
+- * branch here will go away.
+- *
+- * The 'else' branch is slightly racy here, but it was racy to begin
+- * with; since it's going away soon, no effort is made to address that.
++ * If the state doesn't change the active CRTC's, then there's
++ * no need to recalculate; the existing pipe allocation limits
++ * should remain unchanged. Note that we're safe from racing
++ * commits since any racing commit that changes the active CRTC
++ * list would need to grab _all_ crtc locks, including the one
++ * we currently hold.
+ */
+- if (state) {
+- /*
+- * If the state doesn't change the active CRTC's, then there's
+- * no need to recalculate; the existing pipe allocation limits
+- * should remain unchanged. Note that we're safe from racing
+- * commits since any racing commit that changes the active CRTC
+- * list would need to grab _all_ crtc locks, including the one
+- * we currently hold.
+- */
+- if (!intel_state->active_pipe_changes) {
+- *alloc = dev_priv->wm.skl_hw.ddb.pipe[pipe];
+- return;
+- }
+-
+- nth_active_pipe = hweight32(intel_state->active_crtcs &
+- (drm_crtc_mask(for_crtc) - 1));
+- pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
+- alloc->start = nth_active_pipe * ddb_size / *num_active;
+- alloc->end = alloc->start + pipe_size;
+- } else {
+- nth_active_pipe = 0;
+- for_each_crtc(dev, crtc) {
+- if (!to_intel_crtc(crtc)->active)
+- continue;
+-
+- if (crtc == for_crtc)
+- break;
+-
+- nth_active_pipe++;
+- }
+-
+- pipe_size = ddb_size / config->num_pipes_active;
+- alloc->start = nth_active_pipe * ddb_size /
+- config->num_pipes_active;
+- alloc->end = alloc->start + pipe_size;
++ if (!intel_state->active_pipe_changes) {
++ *alloc = dev_priv->wm.skl_hw.ddb.pipe[pipe];
++ return;
+ }
++
++ nth_active_pipe = hweight32(intel_state->active_crtcs &
++ (drm_crtc_mask(for_crtc) - 1));
++ pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
++ alloc->start = nth_active_pipe * ddb_size / *num_active;
++ alloc->end = alloc->start + pipe_size;
+ }
+
+ static unsigned int skl_cursor_allocation(int num_active)
+@@ -2964,62 +2934,33 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
+ struct drm_crtc *crtc = cstate->crtc;
+ struct drm_device *dev = crtc->dev;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++ const struct drm_plane *plane;
+ const struct intel_plane *intel_plane;
++ struct drm_plane_state *pstate;
+ unsigned int rate, total_data_rate = 0;
+ int id;
++ int i;
++
++ if (WARN_ON(!state))
++ return 0;
+
+ /* Calculate and cache data rate for each plane */
+- /*
+- * FIXME: At the moment this function can be called on either an
+- * in-flight or a committed state object. If it's in-flight then we
+- * only want to re-calculate the plane data rate for planes that are
+- * part of the transaction (i.e., we don't want to grab any additional
+- * plane states if we don't have to). If we're operating on committed
+- * state, we'll just go ahead and recalculate the plane data rate for
+- * all planes.
+- *
+- * Once we finish moving our DDB allocation to the atomic check phase,
+- * we'll only be calling this function on in-flight state objects, so
+- * the 'else' branch here will go away.
+- */
+- if (state) {
+- struct drm_plane *plane;
+- struct drm_plane_state *pstate;
+- int i;
+-
+- for_each_plane_in_state(state, plane, pstate, i) {
+- intel_plane = to_intel_plane(plane);
+- id = skl_wm_plane_id(intel_plane);
+-
+- if (intel_plane->pipe != intel_crtc->pipe)
+- continue;
+-
+- /* packed/uv */
+- rate = skl_plane_relative_data_rate(intel_cstate,
+- pstate, 0);
+- intel_cstate->wm.skl.plane_data_rate[id] = rate;
+-
+- /* y-plane */
+- rate = skl_plane_relative_data_rate(intel_cstate,
+- pstate, 1);
+- intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
+- }
+- } else {
+- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+- const struct drm_plane_state *pstate =
+- intel_plane->base.state;
+- int id = skl_wm_plane_id(intel_plane);
++ for_each_plane_in_state(state, plane, pstate, i) {
++ id = skl_wm_plane_id(to_intel_plane(plane));
++ intel_plane = to_intel_plane(plane);
+
+- /* packed/uv */
+- rate = skl_plane_relative_data_rate(intel_cstate,
+- pstate, 0);
+- intel_cstate->wm.skl.plane_data_rate[id] = rate;
++ if (intel_plane->pipe != intel_crtc->pipe)
++ continue;
+
+- /* y-plane */
+- rate = skl_plane_relative_data_rate(intel_cstate,
+- pstate, 1);
+- intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
+- }
++ /* packed/uv */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 0);
++ intel_cstate->wm.skl.plane_data_rate[id] = rate;
++
++ /* y-plane */
++ rate = skl_plane_relative_data_rate(intel_cstate,
++ pstate, 1);
++ intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
+ }
+
+ /* Calculate CRTC's total data rate from cached values */
+@@ -3043,8 +2984,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct drm_atomic_state *state = cstate->base.state;
+ struct drm_crtc *crtc = cstate->base.crtc;
+ struct drm_device *dev = crtc->dev;
+- struct drm_i915_private *dev_priv = to_i915(dev);
+- struct intel_wm_config *config = &dev_priv->wm.config;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_plane *intel_plane;
+ struct drm_plane *plane;
+@@ -3058,6 +2997,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ int num_active;
+ int id, i;
+
++ if (WARN_ON(!state))
++ return 0;
++
+ if (!cstate->base.active) {
+ ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
+ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+@@ -3065,8 +3007,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ return 0;
+ }
+
+- skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc,
+- &num_active);
++ skl_ddb_get_pipe_allocation_limits(dev, cstate, alloc, &num_active);
+ alloc_size = skl_ddb_entry_size(alloc);
+ if (alloc_size == 0) {
+ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+@@ -3078,53 +3019,31 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
+
+ alloc_size -= cursor_blocks;
+- alloc->end -= cursor_blocks;
+
+ /* 1. Allocate the mininum required blocks for each active plane */
+- /*
+- * TODO: Remove support for already-committed state once we
+- * only allocate DDB on in-flight states.
+- */
+- if (state) {
+- for_each_plane_in_state(state, plane, pstate, i) {
+- intel_plane = to_intel_plane(plane);
+- id = skl_wm_plane_id(intel_plane);
+-
+- if (intel_plane->pipe != pipe)
+- continue;
+-
+- if (!to_intel_plane_state(pstate)->visible) {
+- minimum[id] = 0;
+- y_minimum[id] = 0;
+- continue;
+- }
+- if (plane->type == DRM_PLANE_TYPE_CURSOR) {
+- minimum[id] = 0;
+- y_minimum[id] = 0;
+- continue;
+- }
+-
+- minimum[id] = 8;
+- if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
+- y_minimum[id] = 8;
+- else
+- y_minimum[id] = 0;
+- }
+- } else {
+- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+- struct drm_plane *plane = &intel_plane->base;
+- struct drm_framebuffer *fb = plane->state->fb;
+- int id = skl_wm_plane_id(intel_plane);
+-
+- if (!to_intel_plane_state(plane->state)->visible)
+- continue;
++ for_each_plane_in_state(state, plane, pstate, i) {
++ intel_plane = to_intel_plane(plane);
++ id = skl_wm_plane_id(intel_plane);
+
+- if (plane->type == DRM_PLANE_TYPE_CURSOR)
+- continue;
++ if (intel_plane->pipe != pipe)
++ continue;
+
+- minimum[id] = 8;
+- y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
++ if (!to_intel_plane_state(pstate)->visible) {
++ minimum[id] = 0;
++ y_minimum[id] = 0;
++ continue;
++ }
++ if (plane->type == DRM_PLANE_TYPE_CURSOR) {
++ minimum[id] = 0;
++ y_minimum[id] = 0;
++ continue;
+ }
++
++ minimum[id] = 8;
++ if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
++ y_minimum[id] = 8;
++ else
++ y_minimum[id] = 0;
+ }
+
+ for (i = 0; i < PLANE_CURSOR; i++) {
+@@ -3675,7 +3594,6 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+
+- WARN_ON(skl_allocate_pipe_ddb(cstate, ddb) != 0);
+ skl_build_pipe_wm(cstate, ddb, pipe_wm);
+
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+@@ -3739,16 +3657,6 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
+ memset(watermarks->plane_trans[pipe],
+ 0, sizeof(uint32_t) * I915_MAX_PLANES);
+ watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
+-
+- /* Clear ddb entries for pipe */
+- memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
+- memset(&watermarks->ddb.plane[pipe], 0,
+- sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
+- memset(&watermarks->ddb.y_plane[pipe], 0,
+- sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
+- memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0,
+- sizeof(struct skl_ddb_entry));
+-
+ }
+
+ static int
+--
+2.7.4
+
diff --git a/0011-drm-i915-gen9-Calculate-plane-WM-s-from-state.patch b/0011-drm-i915-gen9-Calculate-plane-WM-s-from-state.patch
new file mode 100644
index 000000000..9f839dfa2
--- /dev/null
+++ b/0011-drm-i915-gen9-Calculate-plane-WM-s-from-state.patch
@@ -0,0 +1,91 @@
+From eacd0ecb98a93e3ff83a4479eadeb9cda05d3579 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:41:01 +0200
+Subject: [PATCH 11/17] drm/i915/gen9: Calculate plane WM's from state
+
+Upstream: since drm-intel-next-2016-05-22
+commit 33815fa55b31a5de4b197c09926ecab3dfb79732
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:05 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:12 2016 -0700
+
+ drm/i915/gen9: Calculate plane WM's from state
+
+ In a future patch we'll want to calculate plane watermarks for in-flight
+ atomic state rather than the already-committed state.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-12-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 80f9f18..3164f30 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3179,16 +3179,14 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+
+ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ struct intel_crtc_state *cstate,
+- struct intel_plane *intel_plane,
++ struct intel_plane_state *intel_pstate,
+ uint16_t ddb_allocation,
+ int level,
+ uint16_t *out_blocks, /* out */
+ uint8_t *out_lines /* out */)
+ {
+- struct drm_plane *plane = &intel_plane->base;
+- struct drm_framebuffer *fb = plane->state->fb;
+- struct intel_plane_state *intel_pstate =
+- to_intel_plane_state(plane->state);
++ struct drm_plane_state *pstate = &intel_pstate->base;
++ struct drm_framebuffer *fb = pstate->fb;
+ uint32_t latency = dev_priv->wm.skl_latency[level];
+ uint32_t method1, method2;
+ uint32_t plane_bytes_per_line, plane_blocks_per_line;
+@@ -3203,7 +3201,7 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ width = drm_rect_width(&intel_pstate->src) >> 16;
+ height = drm_rect_height(&intel_pstate->src) >> 16;
+
+- if (intel_rotation_90_or_270(plane->state->rotation))
++ if (intel_rotation_90_or_270(pstate->rotation))
+ swap(width, height);
+
+ cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+@@ -3223,7 +3221,7 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+ uint32_t min_scanlines = 4;
+ uint32_t y_tile_minimum;
+- if (intel_rotation_90_or_270(plane->state->rotation)) {
++ 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);
+@@ -3277,17 +3275,19 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+ struct drm_device *dev = dev_priv->dev;
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+ struct intel_plane *intel_plane;
++ struct intel_plane_state *intel_pstate;
+ uint16_t ddb_blocks;
+ enum pipe pipe = intel_crtc->pipe;
+
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+ int i = skl_wm_plane_id(intel_plane);
+
++ intel_pstate = to_intel_plane_state(intel_plane->base.state);
+ ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+ result->plane_en[i] = skl_compute_plane_wm(dev_priv,
+ cstate,
+- intel_plane,
++ intel_pstate,
+ ddb_blocks,
+ level,
+ &result->plane_res_b[i],
+--
+2.7.4
+
diff --git a/0012-drm-i915-gen9-Allow-watermark-calculation-on-in-flig.patch b/0012-drm-i915-gen9-Allow-watermark-calculation-on-in-flig.patch
new file mode 100644
index 000000000..d0cb50bac
--- /dev/null
+++ b/0012-drm-i915-gen9-Allow-watermark-calculation-on-in-flig.patch
@@ -0,0 +1,156 @@
+From c3d2591095045a8230361d55fadf15ce5dc9127d Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:41:12 +0200
+Subject: [PATCH 12/17] drm/i915/gen9: Allow watermark calculation on in-flight
+ atomic state (v3)
+
+Upstream: since drm-intel-next-2016-05-22
+commit f4a967523ec7215a3ec867b7ed2e916bd34840e1
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:06 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:23 2016 -0700
+
+ drm/i915/gen9: Allow watermark calculation on in-flight atomic state (v3)
+
+ In an upcoming patch we'll move this calculation to the atomic 'check'
+ phase so that the display update can be rejected early if no valid
+ watermark programming is possible.
+
+ v2:
+ - Drop intel_pstate_for_cstate_plane() helper and add note about how
+ the code needs to evolve in the future if we start allowing more than
+ one pending commit against a CRTC. (Maarten)
+
+ v3:
+ - Only have skl_compute_wm_level calculate watermarks for enabled
+ planes; we can just set the other planes on a CRTC to disabled
+ without having to look at the plane state. This is important because
+ despite our CRTC lock we can still have racing commits that modify
+ a disabled plane's property without turning it on. (Maarten)
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-13-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_pm.c | 61 ++++++++++++++++++++++++++++++++---------
+ 1 file changed, 48 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 3164f30..cd29ab6 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3266,23 +3266,56 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ return true;
+ }
+
+-static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+- struct skl_ddb_allocation *ddb,
+- struct intel_crtc_state *cstate,
+- int level,
+- struct skl_wm_level *result)
++static int
++skl_compute_wm_level(const struct drm_i915_private *dev_priv,
++ struct skl_ddb_allocation *ddb,
++ struct intel_crtc_state *cstate,
++ int level,
++ struct skl_wm_level *result)
+ {
+ struct drm_device *dev = dev_priv->dev;
++ struct drm_atomic_state *state = cstate->base.state;
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
++ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ struct intel_plane_state *intel_pstate;
+ uint16_t ddb_blocks;
+ enum pipe pipe = intel_crtc->pipe;
+
+- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
++ /*
++ * We'll only calculate watermarks for planes that are actually
++ * enabled, so make sure all other planes are set as disabled.
++ */
++ memset(result, 0, sizeof(*result));
++
++ for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) {
+ int i = skl_wm_plane_id(intel_plane);
+
+- intel_pstate = to_intel_plane_state(intel_plane->base.state);
++ plane = &intel_plane->base;
++ intel_pstate = NULL;
++ if (state)
++ intel_pstate =
++ intel_atomic_get_existing_plane_state(state,
++ intel_plane);
++
++ /*
++ * Note: If we start supporting multiple pending atomic commits
++ * against the same planes/CRTC's in the future, plane->state
++ * will no longer be the correct pre-state to use for the
++ * calculations here and we'll need to change where we get the
++ * 'unchanged' plane data from.
++ *
++ * For now this is fine because we only allow one queued commit
++ * against a CRTC. Even if the plane isn't modified by this
++ * transaction and we don't have a plane lock, we still have
++ * the CRTC's lock, so we know that no other transactions are
++ * racing with us to update it.
++ */
++ if (!intel_pstate)
++ intel_pstate = to_intel_plane_state(plane->state);
++
++ WARN_ON(!intel_pstate->base.fb);
++
+ ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+ result->plane_en[i] = skl_compute_plane_wm(dev_priv,
+@@ -3293,6 +3326,8 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+ &result->plane_res_b[i],
+ &result->plane_res_l[i]);
+ }
++
++ return 0;
+ }
+
+ static uint32_t
+@@ -3587,14 +3622,14 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+ }
+ }
+
+-static bool skl_update_pipe_wm(struct drm_crtc *crtc,
++static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
+ struct skl_ddb_allocation *ddb, /* out */
+ struct skl_pipe_wm *pipe_wm /* out */)
+ {
+- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+- struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
++ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc);
++ struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
+
+- skl_build_pipe_wm(cstate, ddb, pipe_wm);
++ skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
+
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+ return false;
+@@ -3634,7 +3669,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
+ if (!intel_crtc->active)
+ continue;
+
+- wm_changed = skl_update_pipe_wm(&intel_crtc->base,
++ wm_changed = skl_update_pipe_wm(intel_crtc->base.state,
+ &r->ddb, &pipe_wm);
+
+ /*
+@@ -3752,7 +3787,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
+
+ skl_clear_wm(results, intel_crtc->pipe);
+
+- if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
++ if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm))
+ return;
+
+ skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
+--
+2.7.4
+
diff --git a/0013-drm-i915-gen9-Use-a-bitmask-to-track-dirty-pipe-wate.patch b/0013-drm-i915-gen9-Use-a-bitmask-to-track-dirty-pipe-wate.patch
new file mode 100644
index 000000000..959860f95
--- /dev/null
+++ b/0013-drm-i915-gen9-Use-a-bitmask-to-track-dirty-pipe-wate.patch
@@ -0,0 +1,91 @@
+From b43247a865f73fa3b73a878236b5055bfb864169 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:41:23 +0200
+Subject: [PATCH 13/17] drm/i915/gen9: Use a bitmask to track dirty pipe
+ watermarks
+
+Upstream: since drm-intel-next-2016-05-22
+commit 2b4b9f35d94b1b533bc23110b040b04316480b28
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:07 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:40 2016 -0700
+
+ drm/i915/gen9: Use a bitmask to track dirty pipe watermarks
+
+ Slightly easier to work with than an array of bools.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-14-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/i915_drv.h | 2 +-
+ drivers/gpu/drm/i915/intel_pm.c | 10 +++++-----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 237df9f..67c76b6 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1615,7 +1615,7 @@ struct skl_ddb_allocation {
+ };
+
+ struct skl_wm_values {
+- bool dirty[I915_MAX_PIPES];
++ unsigned dirty_pipes;
+ struct skl_ddb_allocation ddb;
+ uint32_t wm_linetime[I915_MAX_PIPES];
+ uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index cd29ab6..611c5a1 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3455,7 +3455,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+ int i, level, max_level = ilk_wm_max_level(dev);
+ enum pipe pipe = crtc->pipe;
+
+- if (!new->dirty[pipe])
++ if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0)
+ continue;
+
+ I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
+@@ -3680,7 +3680,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
+ WARN_ON(!wm_changed);
+
+ skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
+- r->dirty[intel_crtc->pipe] = true;
++ r->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
+ }
+ }
+
+@@ -3783,7 +3783,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
+
+
+ /* Clear all dirty flags */
+- memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES);
++ results->dirty_pipes = 0;
+
+ skl_clear_wm(results, intel_crtc->pipe);
+
+@@ -3791,7 +3791,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ return;
+
+ skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
+- results->dirty[intel_crtc->pipe] = true;
++ results->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
+
+ skl_update_other_pipe_wm(dev, crtc, results);
+ skl_write_wm_values(dev_priv, results);
+@@ -3952,7 +3952,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+ if (!intel_crtc->active)
+ return;
+
+- hw->dirty[pipe] = true;
++ hw->dirty_pipes |= drm_crtc_mask(crtc);
+
+ active->linetime = hw->wm_linetime[pipe];
+
+--
+2.7.4
+
diff --git a/0014-drm-i915-gen9-Propagate-watermark-calculation-failur.patch b/0014-drm-i915-gen9-Propagate-watermark-calculation-failur.patch
new file mode 100644
index 000000000..a868ebd1f
--- /dev/null
+++ b/0014-drm-i915-gen9-Propagate-watermark-calculation-failur.patch
@@ -0,0 +1,254 @@
+From 2dda82bdd570042820241e71c02ea36081835f67 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:41:35 +0200
+Subject: [PATCH 14/17] drm/i915/gen9: Propagate watermark calculation failures
+ up the call chain
+
+Upstream: since drm-intel-next-2016-05-22
+commit 55994c2c38a1101f84cdf277b228f830af8a9c1b
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:08 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:34:48 2016 -0700
+
+ drm/i915/gen9: Propagate watermark calculation failures up the call chain
+
+ Once we move watermark calculation to the atomic check phase, we'll want
+ to start rejecting display configurations that exceed out watermark
+ limits. At the moment we just assume that there's always a valid set of
+ watermarks, even though this may not actually be true. Let's prepare by
+ passing return codes up through the call stack in preparation.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-15-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_display.c | 10 ++--
+ drivers/gpu/drm/i915/intel_pm.c | 90 ++++++++++++++++++++++--------------
+ 2 files changed, 61 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index b484fda..9ac2346 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13222,7 +13222,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
+ * phase. The code here should be run after the per-crtc and per-plane 'check'
+ * handlers to ensure that all derived state has been updated.
+ */
+-static void calc_watermark_data(struct drm_atomic_state *state)
++static int calc_watermark_data(struct drm_atomic_state *state)
+ {
+ struct drm_device *dev = state->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+@@ -13258,7 +13258,9 @@ static void calc_watermark_data(struct drm_atomic_state *state)
+
+ /* Is there platform-specific watermark information to calculate? */
+ if (dev_priv->display.compute_global_watermarks)
+- dev_priv->display.compute_global_watermarks(state);
++ return dev_priv->display.compute_global_watermarks(state);
++
++ return 0;
+ }
+
+ /**
+@@ -13345,9 +13347,7 @@ static int intel_atomic_check(struct drm_device *dev,
+ return ret;
+
+ intel_fbc_choose_crtc(dev_priv, state);
+- calc_watermark_data(state);
+-
+- return 0;
++ return calc_watermark_data(state);
+ }
+
+ static int intel_atomic_prepare_commit(struct drm_device *dev,
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 611c5a1..ec22d93 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3177,13 +3177,14 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+ return false;
+ }
+
+-static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+- struct intel_crtc_state *cstate,
+- struct intel_plane_state *intel_pstate,
+- uint16_t ddb_allocation,
+- int level,
+- uint16_t *out_blocks, /* out */
+- uint8_t *out_lines /* out */)
++static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
++ struct intel_crtc_state *cstate,
++ struct intel_plane_state *intel_pstate,
++ uint16_t ddb_allocation,
++ int level,
++ uint16_t *out_blocks, /* out */
++ uint8_t *out_lines, /* out */
++ bool *enabled /* out */)
+ {
+ struct drm_plane_state *pstate = &intel_pstate->base;
+ struct drm_framebuffer *fb = pstate->fb;
+@@ -3195,8 +3196,10 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ uint8_t cpp;
+ uint32_t width = 0, height = 0;
+
+- if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
+- return false;
++ if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
++ *enabled = false;
++ return 0;
++ }
+
+ width = drm_rect_width(&intel_pstate->src) >> 16;
+ height = drm_rect_height(&intel_pstate->src) >> 16;
+@@ -3257,13 +3260,16 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ res_blocks++;
+ }
+
+- if (res_blocks >= ddb_allocation || res_lines > 31)
+- return false;
++ if (res_blocks >= ddb_allocation || res_lines > 31) {
++ *enabled = false;
++ return 0;
++ }
+
+ *out_blocks = res_blocks;
+ *out_lines = res_lines;
++ *enabled = true;
+
+- return true;
++ return 0;
+ }
+
+ static int
+@@ -3281,6 +3287,7 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+ struct intel_plane_state *intel_pstate;
+ uint16_t ddb_blocks;
+ enum pipe pipe = intel_crtc->pipe;
++ int ret;
+
+ /*
+ * We'll only calculate watermarks for planes that are actually
+@@ -3318,13 +3325,16 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+
+ ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+- result->plane_en[i] = skl_compute_plane_wm(dev_priv,
+- cstate,
+- intel_pstate,
+- ddb_blocks,
+- level,
+- &result->plane_res_b[i],
+- &result->plane_res_l[i]);
++ ret = skl_compute_plane_wm(dev_priv,
++ cstate,
++ intel_pstate,
++ ddb_blocks,
++ level,
++ &result->plane_res_b[i],
++ &result->plane_res_l[i],
++ &result->plane_en[i]);
++ if (ret)
++ return ret;
+ }
+
+ return 0;
+@@ -3361,21 +3371,26 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
+ }
+ }
+
+-static void skl_build_pipe_wm(struct intel_crtc_state *cstate,
+- struct skl_ddb_allocation *ddb,
+- struct skl_pipe_wm *pipe_wm)
++static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
++ struct skl_ddb_allocation *ddb,
++ struct skl_pipe_wm *pipe_wm)
+ {
+ struct drm_device *dev = cstate->base.crtc->dev;
+ const struct drm_i915_private *dev_priv = dev->dev_private;
+ int level, max_level = ilk_wm_max_level(dev);
++ int ret;
+
+ for (level = 0; level <= max_level; level++) {
+- skl_compute_wm_level(dev_priv, ddb, cstate,
+- level, &pipe_wm->wm[level]);
++ ret = skl_compute_wm_level(dev_priv, ddb, cstate,
++ level, &pipe_wm->wm[level]);
++ if (ret)
++ return ret;
+ }
+ pipe_wm->linetime = skl_compute_linetime_wm(cstate);
+
+ skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
++
++ return 0;
+ }
+
+ static void skl_compute_wm_results(struct drm_device *dev,
+@@ -3622,21 +3637,27 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+ }
+ }
+
+-static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
+- struct skl_ddb_allocation *ddb, /* out */
+- struct skl_pipe_wm *pipe_wm /* out */)
++static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
++ struct skl_ddb_allocation *ddb, /* out */
++ struct skl_pipe_wm *pipe_wm, /* out */
++ bool *changed /* out */)
+ {
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc);
+ struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);
++ int ret;
+
+- skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
++ ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);
++ if (ret)
++ return ret;
+
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+- return false;
++ *changed = false;
++ else
++ *changed = true;
+
+ intel_crtc->wm.active.skl = *pipe_wm;
+
+- return true;
++ return 0;
+ }
+
+ static void skl_update_other_pipe_wm(struct drm_device *dev,
+@@ -3669,8 +3690,8 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
+ if (!intel_crtc->active)
+ continue;
+
+- wm_changed = skl_update_pipe_wm(intel_crtc->base.state,
+- &r->ddb, &pipe_wm);
++ skl_update_pipe_wm(intel_crtc->base.state,
++ &r->ddb, &pipe_wm, &wm_changed);
+
+ /*
+ * If we end up re-computing the other pipe WM values, it's
+@@ -3780,14 +3801,15 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ struct skl_wm_values *results = &dev_priv->wm.skl_results;
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
+-
++ bool wm_changed;
+
+ /* Clear all dirty flags */
+ results->dirty_pipes = 0;
+
+ skl_clear_wm(results, intel_crtc->pipe);
+
+- if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm))
++ skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm, &wm_changed);
++ if (!wm_changed)
+ return;
+
+ skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
+--
+2.7.4
+
diff --git a/0015-drm-i915-gen9-Calculate-watermarks-during-atomic-che.patch b/0015-drm-i915-gen9-Calculate-watermarks-during-atomic-che.patch
new file mode 100644
index 000000000..b8f602e0e
--- /dev/null
+++ b/0015-drm-i915-gen9-Calculate-watermarks-during-atomic-che.patch
@@ -0,0 +1,321 @@
+From 71136125cc79dab464a0139dbf0c02891aa9ce6e Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:41:46 +0200
+Subject: [PATCH 15/17] drm/i915/gen9: Calculate watermarks during atomic
+ 'check' (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 734fa01f3a17ac80d2d53cee0b05b246c03df0e4
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 15:11:40 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:35:48 2016 -0700
+
+ drm/i915/gen9: Calculate watermarks during atomic 'check' (v2)
+
+ Moving watermark calculation into the check phase will allow us to to
+ reject display configurations for which there are no valid watermark
+ values before we start trying to program the hardware (although those
+ tests will come in a subsequent patch).
+
+ Another advantage of moving this calculation to the check phase is that
+ we can calculate the watermarks in a single shot as part of the atomic
+ transaction. The watermark interfaces we inherited from our legacy
+ modesetting days are a bit broken in the atomic design because they use
+ per-crtc entry points but actually re-calculate and re-program something
+ that is really more of a global state. That worked okay in the legacy
+ modesetting world because operations only ever updated a single CRTC at
+ a time. However in the atomic world, a transaction can involve multiple
+ CRTC's, which means we wind up computing and programming the watermarks
+ NxN times (where N is the number of CRTC's involved). With this patch
+ we eliminate the redundant re-calculation of watermark data for atomic
+ states (which was the cause of the WARN_ON(!wm_changed) problems that
+ have plagued us for a while).
+
+ We still need to work on the 'commit' side of watermark handling so that
+ we aren't doing redundant NxN programming of watermarks, but that's
+ content for future patches.
+
+ v2:
+ - Bail out of skl_write_wm_values() if the CRTC isn't active. Now that
+ we set dirty_pipes to ~0 if the active pipes change (because
+ we need to deal with DDB changes), we can now wind up here for
+ disabled pipes, whereas we couldn't before.
+
+ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89055
+ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92181
+ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Tested-by: Daniel Stone <daniels@collabora.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463091100-13747-1-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_display.c | 2 +-
+ drivers/gpu/drm/i915/intel_drv.h | 14 +++-
+ drivers/gpu/drm/i915/intel_pm.c | 135 ++++++++++++-----------------------
+ 3 files changed, 61 insertions(+), 90 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 9ac2346..1726ea4 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13522,7 +13522,7 @@ static int intel_atomic_commit(struct drm_device *dev,
+ drm_atomic_helper_swap_state(dev, state);
+ dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
+ dev_priv->wm.distrust_bios_wm = false;
+- dev_priv->wm.skl_results.ddb = intel_state->ddb;
++ dev_priv->wm.skl_results = intel_state->wm_results;
+
+ if (intel_state->modeset) {
+ memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 4d6336a..e5543b8 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -273,7 +273,7 @@ struct intel_atomic_state {
+ struct intel_wm_config wm_config;
+
+ /* Gen9+ only */
+- struct skl_ddb_allocation ddb;
++ struct skl_wm_values wm_results;
+ };
+
+ struct intel_plane_state {
+@@ -1661,6 +1661,18 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
+
+ return to_intel_crtc_state(crtc_state);
+ }
++
++static inline struct intel_plane_state *
++intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
++ struct intel_plane *plane)
++{
++ struct drm_plane_state *plane_state;
++
++ plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
++
++ return to_intel_plane_state(plane_state);
++}
++
+ int intel_atomic_setup_scalers(struct drm_device *dev,
+ struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *crtc_state);
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index ec22d93..73e5242 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3160,23 +3160,6 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+ return ret;
+ }
+
+-static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+- const struct intel_crtc *intel_crtc)
+-{
+- struct drm_device *dev = intel_crtc->base.dev;
+- struct drm_i915_private *dev_priv = dev->dev_private;
+- const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+-
+- /*
+- * If ddb allocation of pipes changed, it may require recalculation of
+- * watermarks
+- */
+- if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
+- return true;
+-
+- return false;
+-}
+-
+ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ struct intel_crtc_state *cstate,
+ struct intel_plane_state *intel_pstate,
+@@ -3472,6 +3455,8 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+
+ if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0)
+ continue;
++ if (!crtc->active)
++ continue;
+
+ I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
+
+@@ -3655,66 +3640,9 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
+ else
+ *changed = true;
+
+- intel_crtc->wm.active.skl = *pipe_wm;
+-
+ return 0;
+ }
+
+-static void skl_update_other_pipe_wm(struct drm_device *dev,
+- struct drm_crtc *crtc,
+- struct skl_wm_values *r)
+-{
+- struct intel_crtc *intel_crtc;
+- struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+-
+- /*
+- * If the WM update hasn't changed the allocation for this_crtc (the
+- * crtc we are currently computing the new WM values for), other
+- * enabled crtcs will keep the same allocation and we don't need to
+- * recompute anything for them.
+- */
+- if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
+- return;
+-
+- /*
+- * Otherwise, because of this_crtc being freshly enabled/disabled, the
+- * other active pipes need new DDB allocation and WM values.
+- */
+- for_each_intel_crtc(dev, intel_crtc) {
+- struct skl_pipe_wm pipe_wm = {};
+- bool wm_changed;
+-
+- if (this_crtc->pipe == intel_crtc->pipe)
+- continue;
+-
+- if (!intel_crtc->active)
+- continue;
+-
+- skl_update_pipe_wm(intel_crtc->base.state,
+- &r->ddb, &pipe_wm, &wm_changed);
+-
+- /*
+- * If we end up re-computing the other pipe WM values, it's
+- * because it was really needed, so we expect the WM values to
+- * be different.
+- */
+- WARN_ON(!wm_changed);
+-
+- skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
+- r->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
+- }
+-}
+-
+-static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
+-{
+- watermarks->wm_linetime[pipe] = 0;
+- memset(watermarks->plane[pipe], 0,
+- sizeof(uint32_t) * 8 * I915_MAX_PLANES);
+- memset(watermarks->plane_trans[pipe],
+- 0, sizeof(uint32_t) * I915_MAX_PLANES);
+- watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
+-}
+-
+ static int
+ skl_compute_ddb(struct drm_atomic_state *state)
+ {
+@@ -3722,6 +3650,7 @@ skl_compute_ddb(struct drm_atomic_state *state)
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+ struct intel_crtc *intel_crtc;
++ struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb;
+ unsigned realloc_pipes = dev_priv->active_crtcs;
+ int ret;
+
+@@ -3747,8 +3676,10 @@ skl_compute_ddb(struct drm_atomic_state *state)
+ * any other display updates race with this transaction, so we need
+ * to grab the lock on *all* CRTC's.
+ */
+- if (intel_state->active_pipe_changes)
++ if (intel_state->active_pipe_changes) {
+ realloc_pipes = ~0;
++ intel_state->wm_results.dirty_pipes = ~0;
++ }
+
+ for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
+ struct intel_crtc_state *cstate;
+@@ -3757,7 +3688,7 @@ skl_compute_ddb(struct drm_atomic_state *state)
+ if (IS_ERR(cstate))
+ return PTR_ERR(cstate);
+
+- ret = skl_allocate_pipe_ddb(cstate, &intel_state->ddb);
++ ret = skl_allocate_pipe_ddb(cstate, ddb);
+ if (ret)
+ return ret;
+ }
+@@ -3770,8 +3701,11 @@ skl_compute_wm(struct drm_atomic_state *state)
+ {
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *cstate;
+- int ret, i;
++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
++ struct skl_wm_values *results = &intel_state->wm_results;
++ struct skl_pipe_wm *pipe_wm;
+ bool changed = false;
++ int ret, i;
+
+ /*
+ * If this transaction isn't actually touching any CRTC's, don't
+@@ -3786,10 +3720,44 @@ skl_compute_wm(struct drm_atomic_state *state)
+ if (!changed)
+ return 0;
+
++ /* Clear all dirty flags */
++ results->dirty_pipes = 0;
++
+ ret = skl_compute_ddb(state);
+ if (ret)
+ return ret;
+
++ /*
++ * Calculate WM's for all pipes that are part of this transaction.
++ * Note that the DDB allocation above may have added more CRTC's that
++ * weren't otherwise being modified (and set bits in dirty_pipes) if
++ * pipe allocations had to change.
++ *
++ * FIXME: Now that we're doing this in the atomic check phase, we
++ * should allow skl_update_pipe_wm() to return failure in cases where
++ * no suitable watermark values can be found.
++ */
++ for_each_crtc_in_state(state, crtc, cstate, i) {
++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++ struct intel_crtc_state *intel_cstate =
++ to_intel_crtc_state(cstate);
++
++ pipe_wm = &intel_cstate->wm.skl.optimal;
++ ret = skl_update_pipe_wm(cstate, &results->ddb, pipe_wm,
++ &changed);
++ if (ret)
++ return ret;
++
++ if (changed)
++ results->dirty_pipes |= drm_crtc_mask(crtc);
++
++ if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
++ /* This pipe's WM's did not change */
++ continue;
++
++ skl_compute_wm_results(crtc->dev, pipe_wm, results, intel_crtc);
++ }
++
+ return 0;
+ }
+
+@@ -3801,21 +3769,12 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ struct skl_wm_values *results = &dev_priv->wm.skl_results;
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
+- bool wm_changed;
+
+- /* Clear all dirty flags */
+- results->dirty_pipes = 0;
+-
+- skl_clear_wm(results, intel_crtc->pipe);
+-
+- skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm, &wm_changed);
+- if (!wm_changed)
++ if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
+ return;
+
+- skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
+- results->dirty_pipes |= drm_crtc_mask(&intel_crtc->base);
++ intel_crtc->wm.active.skl = *pipe_wm;
+
+- skl_update_other_pipe_wm(dev, crtc, results);
+ skl_write_wm_values(dev_priv, results);
+ skl_flush_wm_values(dev_priv, results);
+
+--
+2.7.4
+
diff --git a/0016-drm-i915-gen9-Reject-display-updates-that-exceed-wm-.patch b/0016-drm-i915-gen9-Reject-display-updates-that-exceed-wm-.patch
new file mode 100644
index 000000000..fb59572bd
--- /dev/null
+++ b/0016-drm-i915-gen9-Reject-display-updates-that-exceed-wm-.patch
@@ -0,0 +1,63 @@
+From 7731c187f1f77501b7dddf419a06c1b42b0f1388 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:42:00 +0200
+Subject: [PATCH 16/17] drm/i915/gen9: Reject display updates that exceed wm
+ limitations (v2)
+
+Upstream: since drm-intel-next-2016-05-22
+commit 6b6bada7d476b586d85b1f9df43125804877e09f
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:10 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:36:04 2016 -0700
+
+ drm/i915/gen9: Reject display updates that exceed wm limitations (v2)
+
+ If we can't find any valid level 0 watermark values for the requested
+ atomic transaction, reject the configuration before we try to start
+ programming the hardware.
+
+ v2:
+ - Add extra debugging output when we reject level 0 watermarks so that
+ we can more easily debug how/why they were rejected.
+
+ Cc: Lyude Paul <cpaul@redhat.com>
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-17-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/intel_pm.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 73e5242..70dcd2e 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3245,7 +3245,22 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+
+ if (res_blocks >= ddb_allocation || res_lines > 31) {
+ *enabled = false;
+- return 0;
++
++ /*
++ * If there are no valid level 0 watermarks, then we can't
++ * support this display configuration.
++ */
++ if (level) {
++ return 0;
++ } else {
++ DRM_DEBUG_KMS("Requested display configuration exceeds system watermark limitations\n");
++ DRM_DEBUG_KMS("Plane %d.%d: blocks required = %u/%u, lines required = %u/31\n",
++ to_intel_crtc(cstate->base.crtc)->pipe,
++ skl_wm_plane_id(to_intel_plane(pstate->plane)),
++ res_blocks, ddb_allocation, res_lines);
++
++ return -EINVAL;
++ }
+ }
+
+ *out_blocks = res_blocks;
+--
+2.7.4
+
diff --git a/0017-drm-i915-Remove-wm_config-from-dev_priv-intel_atomic.patch b/0017-drm-i915-Remove-wm_config-from-dev_priv-intel_atomic.patch
new file mode 100644
index 000000000..e47725c25
--- /dev/null
+++ b/0017-drm-i915-Remove-wm_config-from-dev_priv-intel_atomic.patch
@@ -0,0 +1,115 @@
+From ebe515b1696401259781bc183e211a81287242f6 Mon Sep 17 00:00:00 2001
+From: Fedora Kernel Team <kernel-team@fedoraproject.org>
+Date: Mon, 20 Jun 2016 12:42:13 +0200
+Subject: [PATCH 17/17] drm/i915: Remove wm_config from
+ dev_priv/intel_atomic_state
+
+Upstream: since drm-intel-next-2016-05-22
+commit 5b483747a92570176259bb896dcf2468291f3e42
+
+Author: Matt Roper <matthew.d.roper@intel.com>
+AuthorDate: Thu May 12 07:06:11 2016 -0700
+Commit: Matt Roper <matthew.d.roper@intel.com>
+CommitDate: Fri May 13 07:36:05 2016 -0700
+
+ drm/i915: Remove wm_config from dev_priv/intel_atomic_state
+
+ We calculate the watermark config into intel_atomic_state and then save
+ it into dev_priv, but never actually use it from there. This is
+ left-over from some early ILK-style watermark programming designs that
+ got changed over time.
+
+ Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-18-git-send-email-matthew.d.roper@intel.com
+---
+ drivers/gpu/drm/i915/i915_drv.h | 3 ---
+ drivers/gpu/drm/i915/intel_display.c | 31 -------------------------------
+ drivers/gpu/drm/i915/intel_drv.h | 1 -
+ 3 files changed, 35 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 67c76b6..59092cb 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1973,9 +1973,6 @@ struct drm_i915_private {
+ */
+ uint16_t skl_latency[8];
+
+- /* Committed wm config */
+- struct intel_wm_config config;
+-
+ /*
+ * The skl_wm_values structure is a bit too big for stack
+ * allocation, so we keep the staging struct where we store
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 1726ea4..f5eefb1 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13226,35 +13226,6 @@ static int calc_watermark_data(struct drm_atomic_state *state)
+ {
+ struct drm_device *dev = state->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+- struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+- struct drm_crtc *crtc;
+- struct drm_crtc_state *cstate;
+- struct drm_plane *plane;
+- struct drm_plane_state *pstate;
+-
+- /*
+- * Calculate watermark configuration details now that derived
+- * plane/crtc state is all properly updated.
+- */
+- drm_for_each_crtc(crtc, dev) {
+- cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
+- crtc->state;
+-
+- if (cstate->active)
+- intel_state->wm_config.num_pipes_active++;
+- }
+- drm_for_each_legacy_plane(plane, dev) {
+- pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
+- plane->state;
+-
+- if (!to_intel_plane_state(pstate)->visible)
+- continue;
+-
+- intel_state->wm_config.sprites_enabled = true;
+- if (pstate->crtc_w != pstate->src_w >> 16 ||
+- pstate->crtc_h != pstate->src_h >> 16)
+- intel_state->wm_config.sprites_scaled = true;
+- }
+
+ /* Is there platform-specific watermark information to calculate? */
+ if (dev_priv->display.compute_global_watermarks)
+@@ -13520,7 +13491,6 @@ static int intel_atomic_commit(struct drm_device *dev,
+ }
+
+ drm_atomic_helper_swap_state(dev, state);
+- dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
+ dev_priv->wm.distrust_bios_wm = false;
+ dev_priv->wm.skl_results = intel_state->wm_results;
+
+@@ -15334,7 +15304,6 @@ retry:
+ }
+
+ /* Write calculated watermark values back */
+- to_i915(dev)->wm.config = to_intel_atomic_state(state)->wm_config;
+ for_each_crtc_in_state(state, crtc, cstate, i) {
+ struct intel_crtc_state *cs = to_intel_crtc_state(cstate);
+
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index e5543b8..148f79d 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -270,7 +270,6 @@ struct intel_atomic_state {
+ unsigned int min_pixclk[I915_MAX_PIPES];
+
+ struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+- struct intel_wm_config wm_config;
+
+ /* Gen9+ only */
+ struct skl_wm_values wm_results;
+--
+2.7.4
+
diff --git a/KEYS-potential-uninitialized-variable.patch b/KEYS-potential-uninitialized-variable.patch
new file mode 100644
index 000000000..23cabbb2e
--- /dev/null
+++ b/KEYS-potential-uninitialized-variable.patch
@@ -0,0 +1,30 @@
+From 82a50018782f84e733e718d4b24e1653d19333be Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 15 Jun 2016 09:31:45 -0400
+Subject: [PATCH] KEYS: potential uninitialized variable
+
+If __key_link_begin() failed then "edit" would be uninitialized. I've
+added a check to fix that.
+
+Fixes: f70e2e06196a ('KEYS: Do preallocation for __key_link()')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+---
+ security/keys/key.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/keys/key.c b/security/keys/key.c
+index bd5a272f28a6..346fbf201c22 100644
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -597,7 +597,7 @@ int key_reject_and_link(struct key *key,
+
+ mutex_unlock(&key_construction_mutex);
+
+- if (keyring)
++ if (keyring && link_ret == 0)
+ __key_link_end(keyring, &key->index_key, edit);
+
+ /* wake up anyone waiting for a key to be constructed */
+--
+2.5.5
+
diff --git a/bcm283x-upstream-fixes.patch b/bcm283x-upstream-fixes.patch
new file mode 100644
index 000000000..d8bb87ca0
--- /dev/null
+++ b/bcm283x-upstream-fixes.patch
@@ -0,0 +1,400 @@
+From 41135d2ce60509e53306e5b76afab98ddc15951b Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 2 Mar 2015 14:36:16 -0800
+Subject: [PATCH 26/36] ARM: bcm2835: Add VC4 to the device tree.
+
+VC4 is the GPU (display and 3D) present on the 283x.
+
+v2: Sort by register address, mark HDMI as disabled by default in the
+ SoC file and enable it from -rpi.
+v3: Add references to the pixel/HSM clocks for HDMI. Rename
+ compatibility strings and clean up node names.
+v4: Fix comment marking pv0's interrupt as pwa2 instead of pwa0.
+ Rename hpd-gpio to hpd-gpios.
+v5: Rebase on bcm283x.dtsi change, add v3d.
+v6: Make HDMI reference the power domain.
+v7: Fix the HDMI HPD gpios active value and HDMI enable for each RPI
+ board. Change V3D compatible string to 2835.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 4 +++
+ arch/arm/boot/dts/bcm2835-rpi-a.dts | 4 +++
+ arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 4 +++
+ arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 4 +++
+ arch/arm/boot/dts/bcm2835-rpi-b.dts | 4 +++
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 9 ++++++
+ arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 4 +++
+ arch/arm/boot/dts/bcm283x.dtsi | 47 ++++++++++++++++++++++++++++++++
+ 8 files changed, 80 insertions(+)
+
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+index 228614f..35ff4e7a 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+@@ -29,3 +29,7 @@
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++};
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
+index ddbbbbd..306a84e 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
+@@ -22,3 +22,7 @@
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
++};
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+index ef54050..57d313b 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+@@ -29,3 +29,7 @@
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++};
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+index 86f1f2f..cf2774e 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+@@ -22,3 +22,7 @@
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++};
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
+index 4859e9d..8b15f9c 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
+@@ -16,3 +16,7 @@
+ &gpio {
+ pinctrl-0 = <&gpioout &alt0 &alt3>;
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
++};
+diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+index 76bdbca..caf2707 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -74,3 +74,12 @@
+ &usb {
+ power-domains = <&power RPI_POWER_DOMAIN_USB>;
+ };
++
++&v3d {
++ power-domains = <&power RPI_POWER_DOMAIN_V3D>;
++};
++
++&hdmi {
++ power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
++ status = "okay";
++};
+diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+index ff94666..c4743f4 100644
+--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+@@ -33,3 +33,7 @@
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ };
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++};
+diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
+index fc67964..bbe4eab 100644
+--- a/arch/arm/boot/dts/bcm283x.dtsi
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -1,6 +1,7 @@
+ #include <dt-bindings/pinctrl/bcm2835.h>
+ #include <dt-bindings/clock/bcm2835.h>
+ #include <dt-bindings/clock/bcm2835-aux.h>
++#include <dt-bindings/gpio/gpio.h>
+ #include "skeleton.dtsi"
+
+ /* This include file covers the common peripherals and configuration between
+@@ -153,6 +154,18 @@
+ status = "disabled";
+ };
+
++ pixelvalve@7e206000 {
++ compatible = "brcm,bcm2835-pixelvalve0";
++ reg = <0x7e206000 0x100>;
++ interrupts = <2 13>; /* pwa0 */
++ };
++
++ pixelvalve@7e207000 {
++ compatible = "brcm,bcm2835-pixelvalve1";
++ reg = <0x7e207000 0x100>;
++ interrupts = <2 14>; /* pwa1 */
++ };
++
+ aux: aux@0x7e215000 {
+ compatible = "brcm,bcm2835-aux";
+ #clock-cells = <1>;
+@@ -206,6 +219,12 @@
+ status = "disabled";
+ };
+
++ hvs@7e400000 {
++ compatible = "brcm,bcm2835-hvs";
++ reg = <0x7e400000 0x6000>;
++ interrupts = <2 1>;
++ };
++
+ i2c1: i2c@7e804000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e804000 0x1000>;
+@@ -226,11 +245,39 @@
+ status = "disabled";
+ };
+
++ pixelvalve@7e807000 {
++ compatible = "brcm,bcm2835-pixelvalve2";
++ reg = <0x7e807000 0x100>;
++ interrupts = <2 10>; /* pixelvalve */
++ };
++
++ hdmi: hdmi@7e902000 {
++ compatible = "brcm,bcm2835-hdmi";
++ reg = <0x7e902000 0x600>,
++ <0x7e808000 0x100>;
++ interrupts = <2 8>, <2 9>;
++ ddc = <&i2c2>;
++ clocks = <&clocks BCM2835_PLLH_PIX>,
++ <&clocks BCM2835_CLOCK_HSM>;
++ clock-names = "pixel", "hdmi";
++ status = "disabled";
++ };
++
+ usb: usb@7e980000 {
+ compatible = "brcm,bcm2835-usb";
+ reg = <0x7e980000 0x10000>;
+ interrupts = <1 9>;
+ };
++
++ v3d: v3d@7ec00000 {
++ compatible = "brcm,bcm2835-v3d";
++ reg = <0x7ec00000 0x1000>;
++ interrupts = <1 10>;
++ };
++
++ vc4: gpu {
++ compatible = "brcm,bcm2835-vc4";
++ };
+ };
+
+ clocks {
+--
+2.7.3
+
+From da77f737f9f5a487f3a1f80f8546585ee18cd7b9 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 4 Mar 2016 10:39:28 -0800
+Subject: [PATCH 27/36] dt-bindings: Add root properties for Raspberry Pi 3
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Acked-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
+index 11d3056..6ffe087 100644
+--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
++++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
+@@ -30,6 +30,10 @@ Raspberry Pi 2 Model B
+ Required root node properties:
+ compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
+
++Raspberry Pi 3 Model B
++Required root node properties:
++compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
++
+ Raspberry Pi Compute Module
+ Required root node properties:
+ compatible = "raspberrypi,compute-module", "brcm,bcm2835";
+--
+2.7.3
+
+From b76b1cdf2e569cceab41dcf3b3f6a90965d0a02c Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 4 Mar 2016 10:39:29 -0800
+Subject: [PATCH 28/36] ARM: bcm2835: Add devicetree for the Raspberry Pi 3.
+
+For now this doesn't support the new hardware present on the Pi 3 (BT,
+wifi, GPIO expander). Since the GPIO expander isn't supported, we
+also don't have the LEDs like the other board files do.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Acked-by: Stephen Warren <swarren@wwwdotorg.org>
+---
+ arch/arm/boot/dts/Makefile | 3 +-
+ arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 22 ++++++++++++
+ arch/arm/boot/dts/bcm2837.dtsi | 68 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 92 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+ create mode 100644 arch/arm/boot/dts/bcm2837.dtsi
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index d000814..a8a0767 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -64,7 +64,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2835-rpi-b-rev2.dtb \
+ bcm2835-rpi-b-plus.dtb \
+ bcm2835-rpi-a-plus.dtb \
+- bcm2836-rpi-2-b.dtb
++ bcm2836-rpi-2-b.dtb \
++ bcm2837-rpi-3-b.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+ bcm4708-asus-rt-ac56u.dtb \
+ bcm4708-asus-rt-ac68u.dtb \
+diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+new file mode 100644
+index 0000000..5e8eafd
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+@@ -0,0 +1,22 @@
++/dts-v1/;
++#include "bcm2837.dtsi"
++#include "bcm2835-rpi.dtsi"
++
++/ {
++ compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
++ model = "Raspberry Pi 3 Model B";
++
++ memory {
++ reg = <0 0x40000000>;
++ };
++};
++
++&gpio {
++ pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
++
++ /* I2S interface */
++ i2s_alt0: i2s_alt0 {
++ brcm,pins = <28 29 30 31>;
++ brcm,function = <BCM2835_FSEL_ALT2>;
++ };
++};
+diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
+new file mode 100644
+index 0000000..2f36722
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2837.dtsi
+@@ -0,0 +1,68 @@
++#include "bcm283x.dtsi"
++
++/ {
++ compatible = "brcm,bcm2836";
++
++ soc {
++ ranges = <0x7e000000 0x3f000000 0x1000000>,
++ <0x40000000 0x40000000 0x00001000>;
++ dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
++
++ local_intc: local_intc {
++ compatible = "brcm,bcm2836-l1-intc";
++ reg = <0x40000000 0x100>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&local_intc>;
++ };
++ };
++
++ timer {
++ compatible = "arm,armv7-timer";
++ interrupt-parent = <&local_intc>;
++ interrupts = <0>, // PHYS_SECURE_PPI
++ <1>, // PHYS_NONSECURE_PPI
++ <3>, // VIRT_PPI
++ <2>; // HYP_PPI
++ always-on;
++ };
++
++ cpus: cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0>;
++ };
++
++ cpu1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <1>;
++ };
++
++ cpu2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <2>;
++ };
++
++ cpu3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <3>;
++ };
++ };
++};
++
++/* Make the BCM2835-style global interrupt controller be a child of the
++ * CPU-local interrupt controller.
++ */
++&intc {
++ compatible = "brcm,bcm2836-armctrl-ic";
++ reg = <0x7e00b200 0x200>;
++ interrupt-parent = <&local_intc>;
++ interrupts = <8>;
++};
+--
+2.7.3
+
+From 528285e99c25249456023d28f521689bf9e9eb8b Mon Sep 17 00:00:00 2001
+From: Peter Robinson <pbrobinson@gmail.com>
+Date: Wed, 30 Mar 2016 09:35:13 +0100
+Subject: [PATCH 32/36] drop usb power domain support for the moment, kills usb
+
+---
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+index caf2707..b1e8145 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -71,10 +71,6 @@
+ status = "okay";
+ };
+
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+ &v3d {
+ power-domains = <&power RPI_POWER_DOMAIN_V3D>;
+ };
+--
+2.7.3
+
diff --git a/config-arm-generic b/config-arm-generic
index 91d27ad92..9ea02cf1d 100644
--- a/config-arm-generic
+++ b/config-arm-generic
@@ -498,7 +498,6 @@ CONFIG_COMMON_CLK_SCPI=m
# core
-# CONFIG_INFINIBAND is not set
# CONFIG_ISDN is not set
# CONFIG_PCMCIA is not set
# CONFIG_PARPORT is not set
@@ -533,8 +532,6 @@ CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_CXGB3_ISCSI is not set
-# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BFA_FC is not set
# CONFIG_FUSION is not set
# CONFIG_SCSI_3W_9XXX is not set
diff --git a/filter-aarch64.sh b/filter-aarch64.sh
index 139d1791d..cc560ca97 100644
--- a/filter-aarch64.sh
+++ b/filter-aarch64.sh
@@ -13,4 +13,4 @@ driverdirs="atm auxdisplay bcma bluetooth firewire fmc infiniband isdn leds medi
ethdrvs="3com adaptec arc alteon atheros broadcom cadence calxeda chelsio cisco dec dlink emulex icplus marvell micrel myricom neterion nvidia oki-semi packetengines qlogic rdc renesas sfc silan sis smsc stmicro sun tehuti ti via wiznet xircom"
-singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs megaraid pmcraid qla1280 9pnet_rdma rpcrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject target_core_user sbp_target"
+singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs megaraid pmcraid qla1280 9pnet_rdma rpcrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject target_core_user sbp_target cxgbit iw_cxgb3 iw_cxgb4 cxgb3i cxgb3i cxgb3i_ddp cxgb4i"
diff --git a/filter-armv7hl.sh b/filter-armv7hl.sh
index 6de77659a..0ae6d925b 100644
--- a/filter-armv7hl.sh
+++ b/filter-armv7hl.sh
@@ -15,4 +15,4 @@ ethdrvs="3com adaptec alteon altera amd atheros broadcom cadence chelsio cisco d
drmdrvs="amd armada bridge ast exynos i2c imx mgag200 msm omapdrm panel nouveau radeon rockchip tegra tilcdc via"
-singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs megaraid pmcraid qla1280 9pnet_rdma rpcrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject target_core_user sbp_target"
+singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs megaraid pmcraid qla1280 9pnet_rdma rpcrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject target_core_user sbp_target cxgbit iw_cxgb3 iw_cxgb4 cxgb3i cxgb3i cxgb3i_ddp cxgb4i"
diff --git a/hp-wmi-fix-wifi-cannot-be-hard-unblock.patch b/hp-wmi-fix-wifi-cannot-be-hard-unblock.patch
new file mode 100644
index 000000000..27744a0c3
--- /dev/null
+++ b/hp-wmi-fix-wifi-cannot-be-hard-unblock.patch
@@ -0,0 +1,48 @@
+From patchwork Mon Jun 13 11:44:00 2016
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: hp-wmi: fix wifi cannot be hard-unblock
+From: Alex Hung <alex.hung@canonical.com>
+X-Patchwork-Id: 9172765
+Message-Id: <1465818240-11994-1-git-send-email-alex.hung@canonical.com>
+To: dvhart@infradead.org, platform-driver-x86@vger.kernel.org,
+ alex.hung@canonical.com, david.ward@ll.mit.edu
+Date: Mon, 13 Jun 2016 19:44:00 +0800
+
+Several users reported wifi cannot be unblocked as discussed in [1].
+This patch removes the useof 2009 flag by BIOS but uses the actual WMI
+function calls - it will be skipped if WMI reports unsupported
+
+[1] https://bugzilla.kernel.org/show_bug.cgi?id=69131
+
+Signed-off-by: Alex Hung <alex.hung@canonical.com>
+---
+ drivers/platform/x86/hp-wmi.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index 6f145f2..96ffda4 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -718,6 +718,11 @@ static int __init hp_wmi_rfkill_setup(struct platform_device *device)
+ if (err)
+ return err;
+
++ err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, &wireless,
++ sizeof(wireless), 0);
++ if (err)
++ return err;
++
+ if (wireless & 0x1) {
+ wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
+ RFKILL_TYPE_WLAN,
+@@ -882,7 +887,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
+ wwan_rfkill = NULL;
+ rfkill2_count = 0;
+
+- if (hp_wmi_bios_2009_later() || hp_wmi_rfkill_setup(device))
++ if (hp_wmi_rfkill_setup(device))
+ hp_wmi_rfkill2_setup(device);
+
+ err = device_create_file(&device->dev, &dev_attr_display);
diff --git a/kernel.spec b/kernel.spec
index d625253e7..86c830bf5 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -56,7 +56,7 @@ Summary: The Linux kernel
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
-%define stable_update 2
+%define stable_update 3
# Set rpm version accordingly
%if 0%{?stable_update}
%define stablerev %{stable_update}
@@ -520,8 +520,7 @@ Patch431: Fix-tegra-to-use-stdout-path-for-serial-console.patch
Patch432: arm-i.MX6-Utilite-device-dtb.patch
-# mvebu DSA switch fixes
-# http://www.spinics.net/lists/netdev/msg370841.html http://www.spinics.net/lists/netdev/msg370842.html
+Patch433: bcm283x-upstream-fixes.patch
Patch460: lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch
@@ -607,9 +606,6 @@ Patch571: ideapad-laptop-Add-Lenovo-ideapad-Y700-17ISK-to-no_h.patch
#Required for some persistent memory options
Patch641: disable-CONFIG_EXPERT-for-ZONE_DMA.patch
-#CVE-2016-3134 rhbz 1317383 1317384
-Patch665: netfilter-x_tables-deal-with-bogus-nextoffset-values.patch
-
#CVE-2016-4482 rhbz 1332931 1332932
Patch706: USB-usbfs-fix-potential-infoleak-in-devio.patch
@@ -621,15 +617,44 @@ Patch716: ALSA-timer-Fix-leak-in-events-via-snd_timer_user_tin.patch
#CVE-2016-4440 rhbz 1337806 1337807
Patch719: kvm-vmx-more-complete-state-update-on-APICv-on-off.patch
-#CVE-2016-4951 rhbz 1338625 1338626
-Patch720: tipc-check-nl-sock-before-parsing-nested-attributes.patch
-
#CVE-2016-5243 rhbz 1343338 1343335
Patch721: tipc-fix-an-infoleak-in-tipc_nl_compat_link_dump.patch
#CVE-2016-5244 rhbz 1343338 1343337
Patch722: rds-fix-an-infoleak-in-rds_inc_info_copy.txt
+#CVE-2016-4470 rhbz 1341716 1346626
+Patch727: KEYS-potential-uninitialized-variable.patch
+
+#rhbz 1338025
+Patch728: hp-wmi-fix-wifi-cannot-be-hard-unblock.patch
+
+#skl_update_other_pipe_wm issue patch-series from drm-next, rhbz 1305038
+Patch801: 0001-drm-i915-Reorganize-WM-structs-unions-in-CRTC-state.patch
+Patch802: 0002-drm-i915-Rename-s-skl_compute_pipe_wm-skl_build_pipe.patch
+Patch803: 0003-drm-i915-gen9-Cache-plane-data-rates-in-CRTC-state.patch
+Patch804: 0004-drm-i915-gen9-Allow-calculation-of-data-rate-for-in-.patch
+Patch805: 0005-drm-i915-gen9-Store-plane-minimum-blocks-in-CRTC-wm-.patch
+Patch806: 0006-drm-i915-Track-whether-an-atomic-transaction-changes.patch
+Patch807: 0007-drm-i915-gen9-Allow-skl_allocate_pipe_ddb-to-operate.patch
+Patch808: 0008-drm-i915-Add-distrust_bios_wm-flag-to-dev_priv-v2.patch
+Patch809: 0009-drm-i915-gen9-Compute-DDB-allocation-at-atomic-check.patch
+Patch810: 0010-drm-i915-gen9-Drop-re-allocation-of-DDB-at-atomic-co.patch
+Patch811: 0011-drm-i915-gen9-Calculate-plane-WM-s-from-state.patch
+Patch812: 0012-drm-i915-gen9-Allow-watermark-calculation-on-in-flig.patch
+Patch813: 0013-drm-i915-gen9-Use-a-bitmask-to-track-dirty-pipe-wate.patch
+Patch814: 0014-drm-i915-gen9-Propagate-watermark-calculation-failur.patch
+Patch815: 0015-drm-i915-gen9-Calculate-watermarks-during-atomic-che.patch
+Patch816: 0016-drm-i915-gen9-Reject-display-updates-that-exceed-wm-.patch
+Patch817: 0017-drm-i915-Remove-wm_config-from-dev_priv-intel_atomic.patch
+
+#other drm/kms fixes (most Cc-ed stable)
+Patch821: 0001-drm-mgag200-Black-screen-fix-for-G200e-rev-4.patch
+Patch822: 0002-drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch
+Patch823: 0003-drm-nouveau-disp-sor-gf119-both-links-use-the-same-t.patch
+Patch824: 0004-drm-nouveau-disp-sor-gm107-training-pattern-register.patch
+Patch825: 0005-i915-fbc-Disable-on-HSW-by-default-for-now.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -2155,6 +2180,29 @@ fi
#
#
%changelog
+* Fri Jun 24 2016 Josh Boyer <jwboyer@fedoraproject.org>
+- Linux v4.6.3
+
+* Tue Jun 21 2016 Peter Robinson <pbrobinson@fedoraproject.org>
+- Update patch from 4.5 with missing bits for bcm238x support
+
+* Mon Jun 20 2016 Hans de Goede <jwrdegoede@fedoraproject.org>
+- Bring in patch-series from drm-next to fix skl_update_other_pipe_wm issues
+ (rhbz 1305038)
+- Cherry pick some other drm / kms fixes from upstream
+
+* Wed Jun 15 2016 Laura Abbott <labbott@fedoraproject.org>
+- hp-wmi: fix wifi cannot be hard-unblock (rhbz 1338025)
+
+* Wed Jun 15 2016 Josh Boyer <jwboyer@fedoraproject.org>
+- CVE-2016-4470 keys: uninitialized variable crash (rhbz 1341716 1346626)
+
+* Tue Jun 14 2016 Peter Robinson <pbrobinson@fedoraproject.org>
+- Enable Infiniband on ARM now we have HW
+
+* Mon Jun 13 2016 Josh Boyer <jwboyer@fedoraproject.org>
+- CVE-2016-1583 stack overflow via ecryptfs and /proc (rhbz 1344721 1344722)
+
* Wed Jun 08 2016 Josh Boyer <jwboyer@fedoraproject.org>
- Linux v4.6.2
diff --git a/netfilter-x_tables-deal-with-bogus-nextoffset-values.patch b/netfilter-x_tables-deal-with-bogus-nextoffset-values.patch
deleted file mode 100644
index ebfe1716f..000000000
--- a/netfilter-x_tables-deal-with-bogus-nextoffset-values.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-Subject: [PATCH nf] netfilter: x_tables: deal with bogus nextoffset values
-From: Florian Westphal <fw () strlen ! de>
-Date: 2016-03-10 0:56:02
-
-Ben Hawkes says:
-
- In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it
- is possible for a user-supplied ipt_entry structure to have a large
- next_offset field. This field is not bounds checked prior to writing a
- counter value at the supplied offset.
-
-Problem is that xt_entry_foreach() macro stops iterating once e->next_offset
-is out of bounds, assuming this is the last entry.
-
-With malformed data thats not necessarily the case so we can
-write outside of allocated area later as we might not have walked the
-entire blob.
-
-Fix this by simplifying mark_source_chains -- it already has to check
-if nextoff is in range to catch invalid jumps, so just do the check
-when we move to a next entry as well.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
----
- net/ipv4/netfilter/arp_tables.c | 16 ++++++++--------
- net/ipv4/netfilter/ip_tables.c | 15 ++++++++-------
- net/ipv6/netfilter/ip6_tables.c | 13 ++++++-------
- 3 files changed, 22 insertions(+), 22 deletions(-)
-
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index b488cac..5a0b591 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -437,6 +437,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
-
- /* Move along one */
- size = e->next_offset;
-+
-+ if (pos + size > newinfo->size - sizeof(*e))
-+ return 0;
-+
- e = (struct arpt_entry *)
- (entry0 + pos + size);
- e->counters.pcnt = pos;
-@@ -447,14 +451,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
- if (strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0 &&
- newpos >= 0) {
-- if (newpos > newinfo->size -
-- sizeof(struct arpt_entry)) {
-- duprintf("mark_source_chains: "
-- "bad verdict (%i)\n",
-- newpos);
-- return 0;
-- }
--
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-@@ -462,6 +458,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
- }
-+
-+ if (newpos > newinfo->size - sizeof(*e))
-+ return 0;
-+
- e = (struct arpt_entry *)
- (entry0 + newpos);
- e->counters.pcnt = pos;
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index b99affa..ceb995f 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -519,6 +519,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
-
- /* Move along one */
- size = e->next_offset;
-+
-+ if (pos + size > newinfo->size - sizeof(*e))
-+ return 0;
-+
- e = (struct ipt_entry *)
- (entry0 + pos + size);
- e->counters.pcnt = pos;
-@@ -529,13 +533,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
- if (strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0 &&
- newpos >= 0) {
-- if (newpos > newinfo->size -
-- sizeof(struct ipt_entry)) {
-- duprintf("mark_source_chains: "
-- "bad verdict (%i)\n",
-- newpos);
-- return 0;
-- }
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-@@ -543,6 +540,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
- }
-+
-+ if (newpos > newinfo->size - sizeof(*e))
-+ return 0;
-+
- e = (struct ipt_entry *)
- (entry0 + newpos);
- e->counters.pcnt = pos;
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 99425cf..d88a794 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -531,6 +531,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
-
- /* Move along one */
- size = e->next_offset;
-+ if (pos + size > newinfo->size - sizeof(*e))
-+ return 0;
- e = (struct ip6t_entry *)
- (entry0 + pos + size);
- e->counters.pcnt = pos;
-@@ -541,13 +543,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
- if (strcmp(t->target.u.user.name,
- XT_STANDARD_TARGET) == 0 &&
- newpos >= 0) {
-- if (newpos > newinfo->size -
-- sizeof(struct ip6t_entry)) {
-- duprintf("mark_source_chains: "
-- "bad verdict (%i)\n",
-- newpos);
-- return 0;
-- }
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-@@ -555,6 +550,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
- }
-+
-+ if (newpos > newinfo->size - sizeof(*e))
-+ return 0;
-+
- e = (struct ip6t_entry *)
- (entry0 + newpos);
- e->counters.pcnt = pos;
---
-2.4.10
diff --git a/sources b/sources
index 97a63ff63..8debc8e12 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
d2927020e24a76da4ab482a8bc3e9ef3 linux-4.6.tar.xz
fd23b14b9d474c3dfacb6e8ee82d3a51 perf-man-4.6.tar.gz
-c064bbe8108b8e5304f3db2130a96845 patch-4.6.2.xz
+0d59cb81eb7c0daf0f5019deda65af90 patch-4.6.3.xz
diff --git a/tipc-check-nl-sock-before-parsing-nested-attributes.patch b/tipc-check-nl-sock-before-parsing-nested-attributes.patch
deleted file mode 100644
index 09bfe1485..000000000
--- a/tipc-check-nl-sock-before-parsing-nested-attributes.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 45e093ae2830cd1264677d47ff9a95a71f5d9f9c Mon Sep 17 00:00:00 2001
-From: Richard Alpe <richard.alpe@ericsson.com>
-Date: Mon, 16 May 2016 11:14:54 +0200
-Subject: [PATCH] tipc: check nl sock before parsing nested attributes
-
-Make sure the socket for which the user is listing publication exists
-before parsing the socket netlink attributes.
-
-Prior to this patch a call without any socket caused a NULL pointer
-dereference in tipc_nl_publ_dump().
-
-Tested-and-reported-by: Baozeng Ding <sploving1@gmail.com>
-Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
-Acked-by: Jon Maloy <jon.maloy@ericsson.cm>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/tipc/socket.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/net/tipc/socket.c b/net/tipc/socket.c
-index 12628890c219..3b7a79991d55 100644
---- a/net/tipc/socket.c
-+++ b/net/tipc/socket.c
-@@ -2853,6 +2853,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
- if (err)
- return err;
-
-+ if (!attrs[TIPC_NLA_SOCK])
-+ return -EINVAL;
-+
- err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
- attrs[TIPC_NLA_SOCK],
- tipc_nl_sock_policy);
---
-2.5.5
-