]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915: Have plane->get_hw_state() return the current pipe
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 30 Jan 2018 20:38:03 +0000 (22:38 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 1 Jun 2018 15:40:19 +0000 (18:40 +0300)
Like we do for encoder let's make the plane->get_hw_state() return
the pipe to which the plane is currently attached. We don't currently
allow planes to move between the pipes, but perhaps one day we will.

In either case this makes the code more uniform and perhaps makes
intel_plane_mapping_ok() slightly more clear.

Note that for i965 and g4x planes A and B still have pipe select bits
but they're hardwired to pipe A and B respectively. This means we can
safely interpret those bits just like on gen2/3. This allows the
same readout code work for plane C (which can still be assigned
to eiter pipe on i965) should we ever expose it.

g4x no longer allows moving the cursor planes between the pipes,
but the pipe select bits can still be set in the register. Thus
we have to ignore those bits. OTOH i965 still allows the cursors
to move between pipes thus we have to trust the bits there.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180130203807.13721-3-ville.syrjala@linux.intel.com
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sprite.c

index f238b7b33cd9f350b9b60bd6a3835eadd2d5f7c0..be8a1947275591c9593118248fd28c84faf37f29 100644 (file)
@@ -5936,6 +5936,8 @@ enum {
 #define   CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX)
 #define   CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX)
 #define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_PIPE_SELECT_MASK     (0x3 << 28)
+#define   MCURSOR_PIPE_SELECT_SHIFT    28
 #define   MCURSOR_PIPE_SELECT(pipe)    ((pipe) << 28)
 #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
 #define   CURSOR_ROTATE_180    (1<<15)
index da251ff6aca93a430dda05e3600f70eebe96d71f..136f129f71c4022693ca6671687247d92af228ce 100644 (file)
@@ -1284,7 +1284,10 @@ void assert_pipe(struct drm_i915_private *dev_priv,
 
 static void assert_plane(struct intel_plane *plane, bool state)
 {
-       bool cur_state = plane->get_hw_state(plane);
+       enum pipe pipe;
+       bool cur_state;
+
+       cur_state = plane->get_hw_state(plane, &pipe);
 
        I915_STATE_WARN(cur_state != state,
                        "%s assertion failure (expected %s, current %s)\n",
@@ -3387,24 +3390,33 @@ static void i9xx_disable_plane(struct intel_plane *plane,
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
-static bool i9xx_plane_get_hw_state(struct intel_plane *plane)
+static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
+                                   enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       enum pipe pipe = plane->pipe;
        bool ret;
+       u32 val;
 
        /*
         * Not 100% correct for planes that can move between pipes,
         * but that's only the case for gen2-4 which don't have any
         * display power wells.
         */
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(DSPCNTR(i9xx_plane)) & DISPLAY_PLANE_ENABLE;
+       val = I915_READ(DSPCNTR(i9xx_plane));
+
+       ret = val & DISPLAY_PLANE_ENABLE;
+
+       if (INTEL_GEN(dev_priv) >= 5)
+               *pipe = plane->pipe;
+       else
+               *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
+                       DISPPLANE_SEL_PIPE_SHIFT;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -7647,16 +7659,18 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *plane = to_intel_plane(crtc->base.primary);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       enum pipe pipe = crtc->pipe;
+       enum pipe pipe;
        u32 val, base, offset;
        int fourcc, pixel_format;
        unsigned int aligned_height;
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
-       if (!plane->get_hw_state(plane))
+       if (!plane->get_hw_state(plane, &pipe))
                return;
 
+       WARN_ON(pipe != crtc->pipe);
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -8677,16 +8691,18 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *plane = to_intel_plane(crtc->base.primary);
        enum plane_id plane_id = plane->id;
-       enum pipe pipe = crtc->pipe;
+       enum pipe pipe;
        u32 val, base, offset, stride_mult, tiling, alpha;
        int fourcc, pixel_format;
        unsigned int aligned_height;
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
-       if (!plane->get_hw_state(plane))
+       if (!plane->get_hw_state(plane, &pipe))
                return;
 
+       WARN_ON(pipe != crtc->pipe);
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -9667,7 +9683,8 @@ static void i845_disable_cursor(struct intel_plane *plane,
        i845_update_cursor(plane, NULL, NULL);
 }
 
-static bool i845_cursor_get_hw_state(struct intel_plane *plane)
+static bool i845_cursor_get_hw_state(struct intel_plane *plane,
+                                    enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
@@ -9679,6 +9696,8 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane)
 
        ret = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
 
+       *pipe = PIPE_A;
+
        intel_display_power_put(dev_priv, power_domain);
 
        return ret;
@@ -9880,23 +9899,32 @@ static void i9xx_disable_cursor(struct intel_plane *plane,
        i9xx_update_cursor(plane, NULL, NULL);
 }
 
-static bool i9xx_cursor_get_hw_state(struct intel_plane *plane)
+static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
+                                    enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
-       enum pipe pipe = plane->pipe;
        bool ret;
+       u32 val;
 
        /*
         * Not 100% correct for planes that can move between pipes,
         * but that's only the case for gen2-3 which don't have any
         * display power wells.
         */
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
+       val = I915_READ(CURCNTR(plane->pipe));
+
+       ret = val & CURSOR_MODE;
+
+       if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
+               *pipe = plane->pipe;
+       else
+               *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
+                       MCURSOR_PIPE_SELECT_SHIFT;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -15087,12 +15115,12 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
 static bool intel_plane_mapping_ok(struct intel_crtc *crtc,
                                   struct intel_plane *plane)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       u32 val = I915_READ(DSPCNTR(i9xx_plane));
+       enum pipe pipe;
 
-       return (val & DISPLAY_PLANE_ENABLE) == 0 ||
-               (val & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE(crtc->pipe);
+       if (!plane->get_hw_state(plane, &pipe))
+               return true;
+
+       return pipe == crtc->pipe;
 }
 
 static void
@@ -15294,7 +15322,10 @@ static void readout_plane_state(struct intel_crtc *crtc)
        for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
-               bool visible = plane->get_hw_state(plane);
+               enum pipe pipe;
+               bool visible;
+
+               visible = plane->get_hw_state(plane, &pipe);
 
                intel_set_plane_visible(crtc_state, plane_state, visible);
        }
index fd6256632482ca82135b951dd5d0f37cb7c0c75c..1a4659a2e000a89d2943602ef2d0b374498cb61e 100644 (file)
@@ -970,7 +970,7 @@ struct intel_plane {
                             const struct intel_plane_state *plane_state);
        void (*disable_plane)(struct intel_plane *plane,
                              struct intel_crtc *crtc);
-       bool (*get_hw_state)(struct intel_plane *plane);
+       bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
        int (*check_plane)(struct intel_plane *plane,
                           struct intel_crtc_state *crtc_state,
                           struct intel_plane_state *state);
@@ -2082,7 +2082,7 @@ void skl_update_plane(struct intel_plane *plane,
                      const struct intel_crtc_state *crtc_state,
                      const struct intel_plane_state *plane_state);
 void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc);
-bool skl_plane_get_hw_state(struct intel_plane *plane);
+bool skl_plane_get_hw_state(struct intel_plane *plane, enum pipe *pipe);
 bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
                       enum pipe pipe, enum plane_id plane_id);
 bool intel_format_is_yuv(uint32_t format);
index 1597938d2451f6272a06d2a93db0f96774a60662..fe2b44844e8a238eea9e2802aa71d122514906c1 100644 (file)
@@ -327,19 +327,21 @@ skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 }
 
 bool
-skl_plane_get_hw_state(struct intel_plane *plane)
+skl_plane_get_hw_state(struct intel_plane *plane,
+                      enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
        enum plane_id plane_id = plane->id;
-       enum pipe pipe = plane->pipe;
        bool ret;
 
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(PLANE_CTL(pipe, plane_id)) & PLANE_CTL_ENABLE;
+       ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
+
+       *pipe = plane->pipe;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -588,19 +590,21 @@ vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 }
 
 static bool
-vlv_plane_get_hw_state(struct intel_plane *plane)
+vlv_plane_get_hw_state(struct intel_plane *plane,
+                      enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
        enum plane_id plane_id = plane->id;
-       enum pipe pipe = plane->pipe;
        bool ret;
 
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(SPCNTR(pipe, plane_id)) & SP_ENABLE;
+       ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
+
+       *pipe = plane->pipe;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -754,18 +758,20 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 }
 
 static bool
-ivb_plane_get_hw_state(struct intel_plane *plane)
+ivb_plane_get_hw_state(struct intel_plane *plane,
+                      enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
-       enum pipe pipe = plane->pipe;
        bool ret;
 
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret =  I915_READ(SPRCTL(pipe)) & SPRITE_ENABLE;
+       ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
+
+       *pipe = plane->pipe;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -910,18 +916,20 @@ g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
 }
 
 static bool
-g4x_plane_get_hw_state(struct intel_plane *plane)
+g4x_plane_get_hw_state(struct intel_plane *plane,
+                      enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
-       enum pipe pipe = plane->pipe;
        bool ret;
 
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(DVSCNTR(pipe)) & DVS_ENABLE;
+       ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
+
+       *pipe = plane->pipe;
 
        intel_display_power_put(dev_priv, power_domain);