From: Ville Syrj?l? <ville.syrj...@linux.intel.com>

Separate the part that calculates the register values from the part that
writes the registers. This will be useful in the atomic page flip code.

Signed-off-by: Ville Syrj?l? <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    3 +
 drivers/gpu/drm/i915/intel_display.c |  145 ++++++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h     |    1 +
 3 files changed, 100 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 53a35fd..302b6e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -269,6 +269,9 @@ struct drm_i915_display_funcs {
                          struct drm_i915_gem_object *obj);
        int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                            int x, int y);
+       int (*calc_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+                         int x, int y);
+       void (*commit_plane)(struct drm_crtc *crtc);
        /* clock updates for mode set */
        /* cursor updates */
        /* render clock increase/decrease */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ba737b8..0fb1e09 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1940,8 +1940,27 @@ static unsigned long 
gen4_compute_dspaddr_offset_xtiled(int *x, int *y,
        return tile_rows * pitch * 8 + tiles * 4096;
 }

-static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-                            int x, int y)
+static void intel_commit_plane(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int plane = intel_crtc->plane;
+       const struct intel_plane_regs *regs = &intel_crtc->primary_regs;
+
+       I915_WRITE(DSPCNTR(plane), regs->cntr);
+       I915_WRITE(DSPSTRIDE(plane), regs->stride);
+
+       if (INTEL_INFO(dev)->gen >= 4) {
+               I915_WRITE(DSPTILEOFF(plane), regs->tileoff);
+               I915_WRITE(DSPLINOFF(plane), regs->linoff);
+               I915_WRITE(DSPSURF(plane), regs->surf);
+       } else
+               I915_WRITE(DSPADDR(plane), regs->linoff);
+}
+
+static int i9xx_calc_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+                          int x, int y)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1950,9 +1969,8 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
        struct drm_i915_gem_object *obj;
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
-       u32 dspcntr;
-       u32 reg;
        unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+       struct intel_plane_regs *regs = &intel_crtc->primary_regs;

        switch (plane) {
        case 0:
@@ -1966,36 +1984,35 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,
        intel_fb = to_intel_framebuffer(fb);
        obj = intel_fb->obj;

-       reg = DSPCNTR(plane);
-       dspcntr = I915_READ(reg);
+       regs->cntr = I915_READ(DSPCNTR(plane));
        /* Mask out pixel format bits in case we change it */
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+       regs->cntr &= ~DISPPLANE_PIXFORMAT_MASK;
        switch (fb->pixel_format) {
        case DRM_FORMAT_C8:
-               dspcntr |= DISPPLANE_8BPP;
+               regs->cntr |= DISPPLANE_8BPP;
                break;
        case DRM_FORMAT_XRGB1555:
        case DRM_FORMAT_ARGB1555:
-               dspcntr |= DISPPLANE_BGRX555;
+               regs->cntr |= DISPPLANE_BGRX555;
                break;
        case DRM_FORMAT_RGB565:
-               dspcntr |= DISPPLANE_BGRX565;
+               regs->cntr |= DISPPLANE_BGRX565;
                break;
        case DRM_FORMAT_XRGB8888:
        case DRM_FORMAT_ARGB8888:
-               dspcntr |= DISPPLANE_BGRX888;
+               regs->cntr |= DISPPLANE_BGRX888;
                break;
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ABGR8888:
-               dspcntr |= DISPPLANE_RGBX888;
+               regs->cntr |= DISPPLANE_RGBX888;
                break;
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ARGB2101010:
-               dspcntr |= DISPPLANE_BGRX101010;
+               regs->cntr |= DISPPLANE_BGRX101010;
                break;
        case DRM_FORMAT_XBGR2101010:
        case DRM_FORMAT_ABGR2101010:
-               dspcntr |= DISPPLANE_RGBX101010;
+               regs->cntr |= DISPPLANE_RGBX101010;
                break;
        default:
                DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
@@ -2004,13 +2021,11 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,

        if (INTEL_INFO(dev)->gen >= 4) {
                if (obj->tiling_mode != I915_TILING_NONE)
-                       dspcntr |= DISPPLANE_TILED;
+                       regs->cntr |= DISPPLANE_TILED;
                else
-                       dspcntr &= ~DISPPLANE_TILED;
+                       regs->cntr &= ~DISPPLANE_TILED;
        }

-       I915_WRITE(reg, dspcntr);
-
        linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp;

        if (INTEL_INFO(dev)->gen >= 4) {
@@ -2024,21 +2039,37 @@ static int i9xx_update_plane(struct drm_crtc *crtc, 
struct drm_framebuffer *fb,

        DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
                      obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
-       I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
+       regs->stride = fb->pitches[0];
        if (INTEL_INFO(dev)->gen >= 4) {
-               I915_MODIFY_DISPBASE(DSPSURF(plane),
-                                    obj->gtt_offset + 
intel_crtc->dspaddr_offset);
-               I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
-               I915_WRITE(DSPLINOFF(plane), linear_offset);
+               regs->surf = I915_LO_DISPBASE(I915_READ(DSPSURF(plane))) |
+                       (obj->gtt_offset + intel_crtc->dspaddr_offset);
+               regs->tileoff = (y << 16) | x;
+               regs->linoff = linear_offset;
        } else
-               I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset);
-       POSTING_READ(reg);
+               regs->linoff = obj->gtt_offset + linear_offset;

        return 0;
 }

-static int ironlake_update_plane(struct drm_crtc *crtc,
-                                struct drm_framebuffer *fb, int x, int y)
+static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+                            int x, int y)
+{
+       struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+       int ret;
+
+       ret = i9xx_calc_plane(crtc, fb, x, y);
+       if (ret)
+               return ret;
+
+       intel_commit_plane(crtc);
+
+       POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane));
+
+       return 0;
+}
+
+static int ironlake_calc_plane(struct drm_crtc *crtc,
+                              struct drm_framebuffer *fb, int x, int y)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2047,9 +2078,8 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
        struct drm_i915_gem_object *obj;
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
-       u32 dspcntr;
-       u32 reg;
        unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+       struct intel_plane_regs *regs = &intel_crtc->primary_regs;

        switch (plane) {
        case 0:
@@ -2064,32 +2094,31 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
        intel_fb = to_intel_framebuffer(fb);
        obj = intel_fb->obj;

-       reg = DSPCNTR(plane);
-       dspcntr = I915_READ(reg);
+       regs->cntr = I915_READ(DSPCNTR(plane));
        /* Mask out pixel format bits in case we change it */
-       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+       regs->cntr &= ~DISPPLANE_PIXFORMAT_MASK;
        switch (fb->pixel_format) {
        case DRM_FORMAT_C8:
-               dspcntr |= DISPPLANE_8BPP;
+               regs->cntr |= DISPPLANE_8BPP;
                break;
        case DRM_FORMAT_RGB565:
-               dspcntr |= DISPPLANE_BGRX565;
+               regs->cntr |= DISPPLANE_BGRX565;
                break;
        case DRM_FORMAT_XRGB8888:
        case DRM_FORMAT_ARGB8888:
-               dspcntr |= DISPPLANE_BGRX888;
+               regs->cntr |= DISPPLANE_BGRX888;
                break;
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ABGR8888:
-               dspcntr |= DISPPLANE_RGBX888;
+               regs->cntr |= DISPPLANE_RGBX888;
                break;
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ARGB2101010:
-               dspcntr |= DISPPLANE_BGRX101010;
+               regs->cntr |= DISPPLANE_BGRX101010;
                break;
        case DRM_FORMAT_XBGR2101010:
        case DRM_FORMAT_ABGR2101010:
-               dspcntr |= DISPPLANE_RGBX101010;
+               regs->cntr |= DISPPLANE_RGBX101010;
                break;
        default:
                DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
@@ -2097,14 +2126,12 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
        }

        if (obj->tiling_mode != I915_TILING_NONE)
-               dspcntr |= DISPPLANE_TILED;
+               regs->cntr |= DISPPLANE_TILED;
        else
-               dspcntr &= ~DISPPLANE_TILED;
+               regs->cntr &= ~DISPPLANE_TILED;

        /* must disable */
-       dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
-
-       I915_WRITE(reg, dspcntr);
+       regs->cntr |= DISPPLANE_TRICKLE_FEED_DISABLE;

        linear_offset = fb->offsets[0] + y * fb->pitches[0] + x * 
(fb->bits_per_pixel / 8);
        intel_crtc->dspaddr_offset =
@@ -2114,12 +2141,28 @@ static int ironlake_update_plane(struct drm_crtc *crtc,

        DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
                      obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
-       I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
-       I915_MODIFY_DISPBASE(DSPSURF(plane),
-                            obj->gtt_offset + intel_crtc->dspaddr_offset);
-       I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
-       I915_WRITE(DSPLINOFF(plane), linear_offset);
-       POSTING_READ(reg);
+       regs->stride = fb->pitches[0];
+       regs->surf = I915_LO_DISPBASE(I915_READ(DSPSURF(plane))) |
+               (obj->gtt_offset + intel_crtc->dspaddr_offset);
+       regs->tileoff = (y << 16) | x;
+       regs->linoff = linear_offset;
+
+       return 0;
+}
+
+static int ironlake_update_plane(struct drm_crtc *crtc, struct drm_framebuffer 
*fb,
+                                int x, int y)
+{
+       struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+       int ret;
+
+       ret = ironlake_calc_plane(crtc, fb, x, y);
+       if (ret)
+               return ret;
+
+       intel_commit_plane(crtc);
+
+       POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane));

        return 0;
 }
@@ -7928,12 +7971,16 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.crtc_disable = ironlake_crtc_disable;
                dev_priv->display.off = ironlake_crtc_off;
                dev_priv->display.update_plane = ironlake_update_plane;
+               dev_priv->display.calc_plane = ironlake_calc_plane;
+               dev_priv->display.commit_plane = intel_commit_plane;
        } else {
                dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
                dev_priv->display.crtc_enable = i9xx_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
                dev_priv->display.off = i9xx_crtc_off;
                dev_priv->display.update_plane = i9xx_update_plane;
+               dev_priv->display.calc_plane = i9xx_calc_plane;
+               dev_priv->display.commit_plane = intel_commit_plane;
        }

        /* Returns the core display clock speed */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5dab482..1389eeb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -226,6 +226,7 @@ struct intel_crtc {

        /* We can share PLLs across outputs if the timings match */
        struct intel_pch_pll *pch_pll;
+       struct intel_plane_regs primary_regs;
 };

 struct intel_plane_coords {
-- 
1.7.8.6

Reply via email to