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
This commit is contained in:
parent
b983da8fef
commit
93f8d223fc
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
From b87459ac92803eafc8dd9f8a8ccc36190fe427f1 Mon Sep 17 00:00:00 2001
|
||||
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
|
||||
Date: Wed, 4 May 2016 14:38:26 +0200
|
||||
Subject: [PATCH 6/6] drm/core: Do not preserve framebuffer on rmfb, v4.
|
||||
|
||||
Upstream since: 4.7-rc1
|
||||
commit f2d580b9a8149735cbc4b59c4a8df60173658140
|
||||
|
||||
It turns out that preserving framebuffers after the rmfb call breaks
|
||||
vmwgfx userspace. This was originally introduced because it was thought
|
||||
nobody relied on the behavior, but unfortunately it seems there are
|
||||
exceptions.
|
||||
|
||||
drm_framebuffer_remove may fail with -EINTR now, so a straight revert
|
||||
is impossible. There is no way to remove the framebuffer from the lists
|
||||
and active planes without introducing a race because of the different
|
||||
locking requirements. Instead call drm_framebuffer_remove from a
|
||||
workqueue, which is unaffected by signals.
|
||||
|
||||
Changes since v1:
|
||||
- Add comment.
|
||||
Changes since v2:
|
||||
- Add fastpath for refcount = 1. (danvet)
|
||||
Changes since v3:
|
||||
- Rebased.
|
||||
- Restore lastclose framebuffer removal too.
|
||||
|
||||
Cc: stable@vger.kernel.org #v4.4+
|
||||
Fixes: 13803132818c ("drm/core: Preserve the framebuffer after removing it.")
|
||||
Testcase: kms_rmfb_basic
|
||||
References: https://lists.freedesktop.org/archives/dri-devel/2016-March/102876.html
|
||||
Cc: Thomas Hellstrom <thellstrom@vmware.com>
|
||||
Cc: David Herrmann <dh.herrmann@gmail.com>
|
||||
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Tested-by: Thomas Hellstrom <thellstrom@vmware.com> #v3
|
||||
Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
|
||||
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/6c63ca37-0e7e-ac7f-a6d2-c7822e3d611f@linux.intel.com
|
||||
---
|
||||
drivers/gpu/drm/drm_crtc.c | 60 ++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 55 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
|
||||
index e08f962..f30de80 100644
|
||||
--- a/drivers/gpu/drm/drm_crtc.c
|
||||
+++ b/drivers/gpu/drm/drm_crtc.c
|
||||
@@ -3434,6 +3434,24 @@ int drm_mode_addfb2(struct drm_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct drm_mode_rmfb_work {
|
||||
+ struct work_struct work;
|
||||
+ struct list_head fbs;
|
||||
+};
|
||||
+
|
||||
+static void drm_mode_rmfb_work_fn(struct work_struct *w)
|
||||
+{
|
||||
+ struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
|
||||
+
|
||||
+ while (!list_empty(&arg->fbs)) {
|
||||
+ struct drm_framebuffer *fb =
|
||||
+ list_first_entry(&arg->fbs, typeof(*fb), filp_head);
|
||||
+
|
||||
+ list_del_init(&fb->filp_head);
|
||||
+ drm_framebuffer_remove(fb);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* drm_mode_rmfb - remove an FB from the configuration
|
||||
* @dev: drm device for the ioctl
|
||||
@@ -3474,7 +3492,25 @@ int drm_mode_rmfb(struct drm_device *dev,
|
||||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
mutex_unlock(&file_priv->fbs_lock);
|
||||
|
||||
- drm_framebuffer_unreference(fb);
|
||||
+ /*
|
||||
+ * we now own the reference that was stored in the fbs list
|
||||
+ *
|
||||
+ * drm_framebuffer_remove may fail with -EINTR on pending signals,
|
||||
+ * so run this in a separate stack as there's no way to correctly
|
||||
+ * handle this after the fb is already removed from the lookup table.
|
||||
+ */
|
||||
+ if (atomic_read(&fb->refcount.refcount) > 1) {
|
||||
+ struct drm_mode_rmfb_work arg;
|
||||
+
|
||||
+ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
|
||||
+ INIT_LIST_HEAD(&arg.fbs);
|
||||
+ list_add_tail(&fb->filp_head, &arg.fbs);
|
||||
+
|
||||
+ schedule_work(&arg.work);
|
||||
+ flush_work(&arg.work);
|
||||
+ destroy_work_on_stack(&arg.work);
|
||||
+ } else
|
||||
+ drm_framebuffer_unreference(fb);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3627,7 +3663,6 @@ out_err1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
/**
|
||||
* drm_fb_release - remove and free the FBs on this file
|
||||
* @priv: drm file for the ioctl
|
||||
@@ -3642,6 +3677,9 @@ out_err1:
|
||||
void drm_fb_release(struct drm_file *priv)
|
||||
{
|
||||
struct drm_framebuffer *fb, *tfb;
|
||||
+ struct drm_mode_rmfb_work arg;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&arg.fbs);
|
||||
|
||||
/*
|
||||
* When the file gets released that means no one else can access the fb
|
||||
@@ -3654,10 +3692,22 @@ void drm_fb_release(struct drm_file *priv)
|
||||
* at it any more.
|
||||
*/
|
||||
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
|
||||
- list_del_init(&fb->filp_head);
|
||||
+ if (atomic_read(&fb->refcount.refcount) > 1) {
|
||||
+ list_move_tail(&fb->filp_head, &arg.fbs);
|
||||
+ } else {
|
||||
+ list_del_init(&fb->filp_head);
|
||||
|
||||
- /* This drops the fpriv->fbs reference. */
|
||||
- drm_framebuffer_unreference(fb);
|
||||
+ /* This drops the fpriv->fbs reference. */
|
||||
+ drm_framebuffer_unreference(fb);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!list_empty(&arg.fbs)) {
|
||||
+ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
|
||||
+
|
||||
+ schedule_work(&arg.work);
|
||||
+ flush_work(&arg.work);
|
||||
+ destroy_work_on_stack(&arg.work);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
32
kernel.spec
32
kernel.spec
|
@ -639,6 +639,33 @@ 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
|
||||
Patch826: 0006-drm-core-Do-not-preserve-framebuffer-on-rmfb-v4.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
%endif
|
||||
|
@ -2164,6 +2191,11 @@ fi
|
|||
#
|
||||
#
|
||||
%changelog
|
||||
* 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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue