drm/i915: Polish WM_LINETIME register stuff
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 20 Jan 2020 17:47:11 +0000 (19:47 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 31 Jan 2020 13:32:52 +0000 (15:32 +0200)
Let's store the normal and IPS linetime watermarks individually,
and while at it we'll pimp the register definitions as well.

v2: Deal with gvt

Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200120174728.21095-2-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c

index a366f9974fceaa486b59eef7677e6e63afcb3ea0..baca171b74db2173868457bdd8677228e71b6e2f 100644 (file)
@@ -663,7 +663,8 @@ struct intel_crtc_scaler_state {
 
 struct intel_pipe_wm {
        struct intel_wm_level wm[5];
-       u32 linetime;
+       u16 linetime;
+       u16 ips_linetime;
        bool fbc_wm_enabled;
        bool pipe_enabled;
        bool sprites_enabled;
index 21af822a79e04a109107559d7aa68f4cb3bb901f..ab3da6e707348ce252063abc11aa559b1622bdc5 100644 (file)
@@ -2401,9 +2401,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_F(_MMIO(0x7144c), 0xc, 0, 0, 0, D_PRE_SKL, NULL, NULL);
        MMIO_F(_MMIO(0x7244c), 0xc, 0, 0, 0, D_PRE_SKL, NULL, NULL);
 
-       MMIO_D(PIPE_WM_LINETIME(PIPE_A), D_ALL);
-       MMIO_D(PIPE_WM_LINETIME(PIPE_B), D_ALL);
-       MMIO_D(PIPE_WM_LINETIME(PIPE_C), D_ALL);
+       MMIO_D(WM_LINETIME(PIPE_A), D_ALL);
+       MMIO_D(WM_LINETIME(PIPE_B), D_ALL);
+       MMIO_D(WM_LINETIME(PIPE_C), D_ALL);
        MMIO_D(SPLL_CTL, D_ALL);
        MMIO_D(_MMIO(_WRPLL_CTL1), D_ALL);
        MMIO_D(_MMIO(_WRPLL_CTL2), D_ALL);
index 639c3a10cfa34bfbae1c7ffe6a3f1649e272e711..0bd431f6a01127a4d7bc921229b6271179eee381 100644 (file)
@@ -10543,13 +10543,13 @@ enum skl_power_gate {
 #define  D_COMP_COMP_DISABLE           (1 << 0)
 
 /* Pipe WM_LINETIME - watermark line time */
-#define _PIPE_WM_LINETIME_A            0x45270
-#define _PIPE_WM_LINETIME_B            0x45274
-#define PIPE_WM_LINETIME(pipe) _MMIO_PIPE(pipe, _PIPE_WM_LINETIME_A, _PIPE_WM_LINETIME_B)
-#define   PIPE_WM_LINETIME_MASK                        (0x1ff)
-#define   PIPE_WM_LINETIME_TIME(x)             ((x))
-#define   PIPE_WM_LINETIME_IPS_LINETIME_MASK   (0x1ff << 16)
-#define   PIPE_WM_LINETIME_IPS_LINETIME(x)     ((x) << 16)
+#define _WM_LINETIME_A         0x45270
+#define _WM_LINETIME_B         0x45274
+#define WM_LINETIME(pipe) _MMIO_PIPE(pipe, _WM_LINETIME_A, _WM_LINETIME_B)
+#define  HSW_LINETIME_MASK     REG_GENMASK(8, 0)
+#define  HSW_LINETIME(x)       REG_FIELD_PREP(HSW_LINETIME_MASK, (x))
+#define  HSW_IPS_LINETIME_MASK REG_GENMASK(24, 16)
+#define  HSW_IPS_LINETIME(x)   REG_FIELD_PREP(HSW_IPS_LINETIME_MASK, (x))
 
 /* SFUSE_STRAP */
 #define SFUSE_STRAP                    _MMIO(0xc2014)
index 1cf909d8347bb5d5cb1f51b7a5dea95811f7b77a..c4adce6c1540e38bed53e1f40cd85f2d6848cec8 100644 (file)
@@ -2811,31 +2811,31 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
 }
 
 static u32
-hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
+hsw_linetime_wm(const struct intel_crtc_state *crtc_state)
 {
-       const struct intel_atomic_state *intel_state =
-               to_intel_atomic_state(crtc_state->uapi.state);
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
-       u32 linetime, ips_linetime;
 
        if (!crtc_state->hw.active)
                return 0;
-       if (WARN_ON(adjusted_mode->crtc_clock == 0))
-               return 0;
-       if (WARN_ON(intel_state->cdclk.logical.cdclk == 0))
-               return 0;
 
-       /* The WM are computed with base on how long it takes to fill a single
-        * row at the given clock rate, multiplied by 8.
-        * */
-       linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
-                                    adjusted_mode->crtc_clock);
-       ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
-                                        intel_state->cdclk.logical.cdclk);
+       return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+                                adjusted_mode->crtc_clock);
+}
+
+static u32
+hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state)
+{
+       const struct intel_atomic_state *state =
+               to_intel_atomic_state(crtc_state->uapi.state);
+       const struct drm_display_mode *adjusted_mode =
+               &crtc_state->hw.adjusted_mode;
+
+       if (!crtc_state->hw.active)
+               return 0;
 
-       return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
-              PIPE_WM_LINETIME_TIME(linetime);
+       return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+                                state->cdclk.logical.cdclk);
 }
 
 static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
@@ -3178,8 +3178,10 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
        ilk_compute_wm_level(dev_priv, intel_crtc, 0, crtc_state,
                             pristate, sprstate, curstate, &pipe_wm->wm[0]);
 
-       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-               pipe_wm->linetime = hsw_compute_linetime_wm(crtc_state);
+       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+               pipe_wm->linetime = hsw_linetime_wm(crtc_state);
+               pipe_wm->ips_linetime = hsw_ips_linetime_wm(crtc_state);
+       }
 
        if (!ilk_validate_pipe_wm(dev_priv, pipe_wm))
                return -EINVAL;
@@ -3426,13 +3428,14 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv,
        /* LP0 register values */
        for_each_intel_crtc(&dev_priv->drm, intel_crtc) {
                enum pipe pipe = intel_crtc->pipe;
-               const struct intel_wm_level *r =
-                       &intel_crtc->wm.active.ilk.wm[0];
+               const struct intel_pipe_wm *pipe_wm = &intel_crtc->wm.active.ilk;
+               const struct intel_wm_level *r = &pipe_wm->wm[0];
 
                if (drm_WARN_ON(&dev_priv->drm, !r->enable))
                        continue;
-
-               results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime;
+               results->wm_linetime[pipe] =
+                       HSW_LINETIME(pipe_wm->linetime) |
+                       HSW_IPS_LINETIME(pipe_wm->ips_linetime);
 
                results->wm_pipe[pipe] =
                        (r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@ -3585,11 +3588,11 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
                I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]);
 
        if (dirty & WM_DIRTY_LINETIME(PIPE_A))
-               I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]);
+               I915_WRITE(WM_LINETIME(PIPE_A), results->wm_linetime[0]);
        if (dirty & WM_DIRTY_LINETIME(PIPE_B))
-               I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]);
+               I915_WRITE(WM_LINETIME(PIPE_B), results->wm_linetime[1]);
        if (dirty & WM_DIRTY_LINETIME(PIPE_C))
-               I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]);
+               I915_WRITE(WM_LINETIME(PIPE_C), results->wm_linetime[2]);
 
        if (dirty & WM_DIRTY_DDB) {
                if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -5571,7 +5574,7 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
        if ((state->wm_results.dirty_pipes & BIT(crtc->pipe)) == 0)
                return;
 
-       I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
+       I915_WRITE(WM_LINETIME(pipe), HSW_LINETIME(pipe_wm->linetime));
 }
 
 static void skl_initial_wm(struct intel_atomic_state *state,
@@ -5716,7 +5719,8 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
        if (!crtc->active)
                return;
 
-       out->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
+       val = I915_READ(WM_LINETIME(pipe));
+       out->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, val);
 }
 
 void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
@@ -5758,7 +5762,7 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc)
 
        hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]);
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-               hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+               hw->wm_linetime[pipe] = I915_READ(WM_LINETIME(pipe));
 
        memset(active, 0, sizeof(*active));
 
@@ -5777,7 +5781,10 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc)
                active->wm[0].pri_val = (tmp & WM0_PIPE_PLANE_MASK) >> WM0_PIPE_PLANE_SHIFT;
                active->wm[0].spr_val = (tmp & WM0_PIPE_SPRITE_MASK) >> WM0_PIPE_SPRITE_SHIFT;
                active->wm[0].cur_val = tmp & WM0_PIPE_CURSOR_MASK;
-               active->linetime = hw->wm_linetime[pipe];
+               active->linetime = REG_FIELD_GET(HSW_LINETIME_MASK,
+                                                hw->wm_linetime[pipe]);
+               active->ips_linetime = REG_FIELD_GET(HSW_IPS_LINETIME_MASK,
+                                                    hw->wm_linetime[pipe]);
        } else {
                int level, max_level = ilk_wm_max_level(dev_priv);