Blob Blame History Raw
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