On Tue, Feb 07, 2017 at 05:37:44PM +0200, Imre Deak wrote:
> On Thu, Jan 05, 2017 at 05:14:54PM +0200, ville.syrj...@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrj...@linux.intel.com>
> > 
> > SKL+ display engine can scan out certain kinds of compressed surfaces
> > produced by the render engine. This involved telling the display engine
> > the location of the color control surfae (CCS) which describes
> > which parts of the main surface are compressed and which are not. The
> > location of CCS is provided by userspace as just another plane with its
> > own offset.
> > 
> > Add the required stuff to validate the user provided AUX plane metadata
> > and convert the user provided linear offset into something the hardware
> > can consume.
> > 
> > Due to hardware limitations we require that the main surface and
> > the AUX surface (CCS) be part of the same bo. The hardware also
> > makes life hard by not allowing you to provide separate x/y offsets
> > for the main and AUX surfaces (excpet with NV12), so finding suitable
> > offsets for both requires a bit of work. Assuming we still want keep
> > playing tricks with the offsets. I've just gone with a dumb "search
> > backward for suitable offsets" approach, which is far from optimal,
> > but it works.
> > 
> > Also not all planes will be capable of scanning out compressed surfaces,
> > and eg. 90/270 degree rotation is not supported in combination with
> > decompression either.
> > 
> > This patch may contain work from at least the following people:
> > * Vandana Kannan <vandana.kan...@intel.com>
> > * Daniel Vetter <dan...@ffwll.ch>
> > * Ben Widawsky <b...@bwidawsk.net>
> > 
> > v2: Deal with display workarounds 0390, 0531, 1125 (Paulo)
> > 
> > Cc: Paulo Zanoni <paulo.r.zan...@intel.com>
> > Cc: Vandana Kannan <vandana.kan...@intel.com>
> > Cc: Daniel Vetter <dan...@ffwll.ch>
> > Cc: Ben Widawsky <b...@bwidawsk.net>
> > Cc: Jason Ekstrand <ja...@jlekstrand.net>
> > Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h      |  23 ++++
> >  drivers/gpu/drm/i915/intel_display.c | 234 
> > ++++++++++++++++++++++++++++++++---
> >  drivers/gpu/drm/i915/intel_pm.c      |  29 ++++-
> >  drivers/gpu/drm/i915/intel_sprite.c  |   5 +
> >  4 files changed, 274 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h 
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 00970aa77afa..6849ba93f1d9 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -6209,6 +6209,28 @@ enum {
> >                     _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A),   \
> >                     _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))
> >  
> > +#define PLANE_AUX_DIST_1_A         0x701c0
> > +#define PLANE_AUX_DIST_2_A         0x702c0
> > +#define PLANE_AUX_DIST_1_B         0x711c0
> > +#define PLANE_AUX_DIST_2_B         0x712c0
> > +#define _PLANE_AUX_DIST_1(pipe) \
> > +                   _PIPE(pipe, PLANE_AUX_DIST_1_A, PLANE_AUX_DIST_1_B)
> > +#define _PLANE_AUX_DIST_2(pipe) \
> > +                   _PIPE(pipe, PLANE_AUX_DIST_2_A, PLANE_AUX_DIST_2_B)
> > +#define PLANE_AUX_DIST(pipe, plane)     \
> > +   _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe))
> > +
> > +#define PLANE_AUX_OFFSET_1_A               0x701c4
> > +#define PLANE_AUX_OFFSET_2_A               0x702c4
> > +#define PLANE_AUX_OFFSET_1_B               0x711c4
> > +#define PLANE_AUX_OFFSET_2_B               0x712c4
> > +#define _PLANE_AUX_OFFSET_1(pipe)       \
> > +           _PIPE(pipe, PLANE_AUX_OFFSET_1_A, PLANE_AUX_OFFSET_1_B)
> > +#define _PLANE_AUX_OFFSET_2(pipe)       \
> > +           _PIPE(pipe, PLANE_AUX_OFFSET_2_A, PLANE_AUX_OFFSET_2_B)
> > +#define PLANE_AUX_OFFSET(pipe, plane)   \
> > +   _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
> > +
> >  /* legacy palette */
> >  #define _LGC_PALETTE_A           0x4a000
> >  #define _LGC_PALETTE_B           0x4a800
> > @@ -6433,6 +6455,7 @@ enum {
> >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE            (1 << 2)
> >  
> >  #define CHICKEN_PAR1_1             _MMIO(0x42080)
> > +#define  SKL_RC_HASH_OUTSIDE       (1 << 15)
> >  #define  DPA_MASK_VBLANK_SRD       (1 << 15)
> >  #define  FORCE_ARB_IDLE_PLANES     (1 << 14)
> >  #define  SKL_EDP_PSR_FIX_RDWRAP    (1 << 3)
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 38de9df0ec60..2236abebd8bc 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2064,11 +2064,19 @@ intel_tile_width_bytes(const struct drm_framebuffer 
> > *fb, int plane)
> >                     return 128;
> >             else
> >                     return 512;
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +           if (plane == 1)
> > +                   return 64;
> > +           /* fall through */
> >     case I915_FORMAT_MOD_Y_TILED:
> >             if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
> >                     return 128;
> >             else
> >                     return 512;
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> > +           if (plane == 1)
> > +                   return 64;
> > +           /* fall through */
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             /*
> >              * Bspec seems to suggest that the Yf tile width would
> > @@ -2156,7 +2164,7 @@ static unsigned int intel_surf_alignment(const struct 
> > drm_framebuffer *fb,
> >     struct drm_i915_private *dev_priv = to_i915(fb->dev);
> >  
> >     /* AUX_DIST needs only 4K alignment */
> > -   if (fb->format->format == DRM_FORMAT_NV12 && plane == 1)
> > +   if (plane == 1)
> >             return 4096;
> >  
> >     switch (fb->modifier) {
> > @@ -2166,6 +2174,8 @@ static unsigned int intel_surf_alignment(const struct 
> > drm_framebuffer *fb,
> >             if (INTEL_GEN(dev_priv) >= 9)
> >                     return 256 * 1024;
> >             return 0;
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> >     case I915_FORMAT_MOD_Y_TILED:
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             return 1 * 1024 * 1024;
> > @@ -2472,6 +2482,7 @@ static unsigned int 
> > intel_fb_modifier_to_tiling(uint64_t fb_modifier)
> >     case I915_FORMAT_MOD_X_TILED:
> >             return I915_TILING_X;
> >     case I915_FORMAT_MOD_Y_TILED:
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> >             return I915_TILING_Y;
> >     default:
> >             return I915_TILING_NONE;
> > @@ -2536,6 +2547,35 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
> >  
> >             intel_fb_offset_to_xy(&x, &y, fb, i);
> >  
> > +           if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +                fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == 1) {
> > +                   int main_x, main_y;
> > +                   int ccs_x, ccs_y;
> > +
> > +                   /*
> > +                    * Each byte of CCS corresponds to a 16x8 area of the 
> > main surface, and
> > +                    * each CCS tile is 64x64 bytes.
> > +                    */
> > +                   ccs_x = (x * 16) % (64 * 16);
> > +                   ccs_y = (y * 8) % (64 * 8);
> > +                   main_x = intel_fb->normal[0].x % (64 * 16);
> > +                   main_y = intel_fb->normal[0].y % (64 * 8);
> > +
> > +                   /*
> > +                    * CCS doesn't have its own x/y offset register, so the 
> > intra CCS tile
> > +                    * x/y offsets must match between CCS and the main 
> > surface.
> > +                    */
> > +                   if (main_x != ccs_x || main_y != ccs_y) {
> > +                           DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs 
> > %d,%d) full (main %d,%d ccs %d,%d)\n",
> > +                                         main_x, main_y,
> > +                                         ccs_x, ccs_y,
> > +                                         intel_fb->normal[0].x,
> > +                                         intel_fb->normal[0].y,
> > +                                         x, y);
> > +                           return -EINVAL;
> > +                   }
> > +           }
> > +
> >             /*
> >              * The fence (if used) is aligned to the start of the object
> >              * so having the framebuffer wrap around across the edge of the
> > @@ -2873,6 +2913,9 @@ static int skl_max_plane_width(const struct 
> > drm_framebuffer *fb, int plane,
> >                     break;
> >             }
> >             break;
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> > +           /* FIXME AUX plane? */
> >     case I915_FORMAT_MOD_Y_TILED:
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             switch (cpp) {
> > @@ -2895,6 +2938,42 @@ static int skl_max_plane_width(const struct 
> > drm_framebuffer *fb, int plane,
> >     return 2048;
> >  }
> >  
> > +static bool skl_check_main_ccs_coordinates(struct intel_plane_state 
> > *plane_state,
> > +                                      int main_x, int main_y, u32 
> > main_offset)
> > +{
> > +   const struct drm_framebuffer *fb = plane_state->base.fb;
> > +   int aux_x = plane_state->aux.x;
> > +   int aux_y = plane_state->aux.y;
> > +   u32 aux_offset = plane_state->aux.offset;
> > +   u32 alignment = intel_surf_alignment(fb, 1);
> > +
> > +   while (aux_offset >= main_offset && aux_y <= main_y) {
> > +           int x, y;
> > +
> > +           if (aux_x == main_x && aux_y == main_y)
> > +                   break;
> > +
> > +           if (aux_offset == 0)
> > +                   break;
> > +
> > +           x = aux_x / 16;
> > +           y = aux_y / 8;
> > +           aux_offset = intel_adjust_tile_offset(&x, &y, plane_state, 1,
> > +                                                 aux_offset, aux_offset - 
> > alignment);
> > +           aux_x = x * 16 + aux_x % 16;
> > +           aux_y = y * 8 + aux_y % 8;
> > +   }
> > +
> > +   if (aux_x != main_x || aux_y != main_y)
> > +           return false;
> > +
> > +   plane_state->aux.offset = aux_offset;
> > +   plane_state->aux.x = aux_x;
> > +   plane_state->aux.y = aux_y;
> > +
> > +   return true;
> > +}
> > +
> >  static int skl_check_main_surface(struct intel_plane_state *plane_state)
> >  {
> >     const struct drm_framebuffer *fb = plane_state->base.fb;
> > @@ -2937,7 +3016,7 @@ static int skl_check_main_surface(struct 
> > intel_plane_state *plane_state)
> >  
> >             while ((x + w) * cpp > fb->pitches[0]) {
> >                     if (offset == 0) {
> > -                           DRM_DEBUG_KMS("Unable to find suitable display 
> > surface offset\n");
> > +                           DRM_DEBUG_KMS("Unable to find suitable display 
> > surface offset due to X-tiling\n");
> >                             return -EINVAL;
> >                     }
> >  
> > @@ -2946,6 +3025,26 @@ static int skl_check_main_surface(struct 
> > intel_plane_state *plane_state)
> >             }
> >     }
> >  
> > +   /*
> > +    * CCS AUX surface doesn't have its own x/y offsets, we must make sure
> > +    * they match with the main surface x/y offsets.
> > +    */
> > +   if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +       fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
> > +           while (!skl_check_main_ccs_coordinates(plane_state, x, y, 
> > offset)) {
> > +                   if (offset == 0)
> > +                           break;
> > +
> > +                   offset = intel_adjust_tile_offset(&x, &y, plane_state, 
> > 0,
> > +                                                     offset, offset - 
> > alignment);
> > +           }
> > +
> > +           if (x != plane_state->aux.x || y != plane_state->aux.y) {
> > +                   DRM_DEBUG_KMS("Unable to find suitable display surface 
> > offset due to CCS\n");
> > +                   return -EINVAL;
> > +           }
> > +   }
> > +
> >     plane_state->main.offset = offset;
> >     plane_state->main.x = x;
> >     plane_state->main.y = y;
> > @@ -2982,6 +3081,47 @@ static int skl_check_nv12_aux_surface(struct 
> > intel_plane_state *plane_state)
> >     return 0;
> >  }
> >  
> > +static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
> > +{
> > +   struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
> > +   struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
> > +   int src_x = plane_state->base.src.x1 >> 16;
> > +   int src_y = plane_state->base.src.y1 >> 16;
> > +   int x = src_x / 16;
> > +   int y = src_y / 8;
> > +   u32 offset;
> > +
> > +   switch (plane->id) {
> > +   case PLANE_PRIMARY:
> > +   case PLANE_SPRITE0:
> > +           break;
> > +   default:
> > +           DRM_DEBUG_KMS("RC support only on plane 1 and 2\n");
> > +           return -EINVAL;
> > +   }
> > +
> > +   if (crtc->pipe == PIPE_C) {
> > +           DRM_DEBUG_KMS("No RC support on pipe C\n");
> > +           return -EINVAL;
> > +   }
> > +
> > +   if (plane_state->base.rotation &&
> > +       plane_state->base.rotation & ~(DRM_ROTATE_0 | DRM_ROTATE_180)) {
> > +           DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
> > +                         plane_state->base.rotation);
> > +           return -EINVAL;
> > +   }
> > +
> > +   intel_add_fb_offsets(&x, &y, plane_state, 1);
> > +   offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
> > +
> > +   plane_state->aux.offset = offset;
> > +   plane_state->aux.x = x * 16 + src_x % 16;
> > +   plane_state->aux.y = y * 8 + src_y % 8;
> > +
> > +   return 0;
> > +}
> > +
> >  int skl_check_plane_surface(struct intel_plane_state *plane_state)
> >  {
> >     const struct drm_framebuffer *fb = plane_state->base.fb;
> > @@ -3002,6 +3142,11 @@ int skl_check_plane_surface(struct intel_plane_state 
> > *plane_state)
> >             ret = skl_check_nv12_aux_surface(plane_state);
> >             if (ret)
> >                     return ret;
> > +   } else if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
> > +           ret = skl_check_ccs_aux_surface(plane_state);
> > +           if (ret)
> > +                   return ret;
> >     } else {
> >             plane_state->aux.offset = ~0xfff;
> >             plane_state->aux.x = 0;
> > @@ -3357,8 +3502,12 @@ u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> >             return PLANE_CTL_TILED_X;
> >     case I915_FORMAT_MOD_Y_TILED:
> >             return PLANE_CTL_TILED_Y;
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +           return PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             return PLANE_CTL_TILED_YF;
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> > +           return PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
> >     default:
> >             MISSING_CASE(fb_modifier);
> >     }
> > @@ -3401,6 +3550,7 @@ static void skylake_update_primary_plane(struct 
> > drm_plane *plane,
> >     u32 plane_ctl;
> >     unsigned int rotation = plane_state->base.rotation;
> >     u32 stride = skl_plane_stride(fb, 0, rotation);
> > +   u32 aux_stride = skl_plane_stride(fb, 1, rotation);
> >     u32 surf_addr = plane_state->main.offset;
> >     int scaler_id = plane_state->scaler_id;
> >     int src_x = plane_state->main.x;
> > @@ -3436,6 +3586,10 @@ static void skylake_update_primary_plane(struct 
> > drm_plane *plane,
> >     I915_WRITE(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x);
> >     I915_WRITE(PLANE_STRIDE(pipe, plane_id), stride);
> >     I915_WRITE(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
> > +   I915_WRITE(PLANE_AUX_DIST(pipe, plane_id),
> > +              (plane_state->aux.offset - surf_addr) | aux_stride);
> > +   I915_WRITE(PLANE_AUX_OFFSET(pipe, plane_id),
> > +              (plane_state->aux.y << 16) | plane_state->aux.x);
> >  
> >     if (scaler_id >= 0) {
> >             uint32_t ps_ctrl = 0;
> > @@ -9807,10 +9961,16 @@ skylake_get_initial_plane_config(struct intel_crtc 
> > *crtc,
> >             fb->modifier = I915_FORMAT_MOD_X_TILED;
> >             break;
> >     case PLANE_CTL_TILED_Y:
> > -           fb->modifier = I915_FORMAT_MOD_Y_TILED;
> > +           if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
> > +                   fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
> > +           else
> > +                   fb->modifier = I915_FORMAT_MOD_Y_TILED;
> >             break;
> >     case PLANE_CTL_TILED_YF:
> > -           fb->modifier = I915_FORMAT_MOD_Yf_TILED;
> > +           if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
> > +                   fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
> > +           else
> > +                   fb->modifier = I915_FORMAT_MOD_Yf_TILED;
> >             break;
> >     default:
> >             MISSING_CASE(tiling);
> > @@ -12014,7 +12174,7 @@ static void skl_do_mmio_flip(struct intel_crtc 
> > *intel_crtc,
> >     u32 ctl, stride = skl_plane_stride(fb, 0, rotation);
> >  
> >     ctl = I915_READ(PLANE_CTL(pipe, 0));
> > -   ctl &= ~PLANE_CTL_TILED_MASK;
> > +   ctl &= ~(PLANE_CTL_TILED_MASK | PLANE_CTL_DECOMPRESSION_ENABLE);
> >     switch (fb->modifier) {
> >     case DRM_FORMAT_MOD_NONE:
> >             break;
> > @@ -12024,9 +12184,15 @@ static void skl_do_mmio_flip(struct intel_crtc 
> > *intel_crtc,
> >     case I915_FORMAT_MOD_Y_TILED:
> >             ctl |= PLANE_CTL_TILED_Y;
> >             break;
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +           ctl |= PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
> > +           break;
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             ctl |= PLANE_CTL_TILED_YF;
> >             break;
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> > +           ctl |= PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
> > +           break;
> >     default:
> >             MISSING_CASE(fb->modifier);
> >     }
> > @@ -15925,9 +16091,10 @@ static int intel_framebuffer_init(struct 
> > drm_device *dev,
> >                               struct drm_i915_gem_object *obj)
> >  {
> >     struct drm_i915_private *dev_priv = to_i915(dev);
> > +   struct drm_framebuffer *fb = &intel_fb->base;
> >     unsigned int tiling = i915_gem_object_get_tiling(obj);
> > -   int ret;
> > -   u32 pitch_limit, stride_alignment;
> > +   int ret, i;
> > +   u32 pitch_limit;
> >     struct drm_format_name_buf format_name;
> >  
> >     WARN_ON(!mutex_is_locked(&dev->struct_mutex));
> > @@ -15953,6 +16120,19 @@ static int intel_framebuffer_init(struct 
> > drm_device *dev,
> >  
> >     /* Passed in modifier sanity checking. */
> >     switch (mode_cmd->modifier[0]) {
> > +   case I915_FORMAT_MOD_Y_TILED_CCS:
> > +   case I915_FORMAT_MOD_Yf_TILED_CCS:
> > +           switch (mode_cmd->pixel_format) {
> > +           case DRM_FORMAT_XBGR8888:
> > +           case DRM_FORMAT_ABGR8888:
> > +           case DRM_FORMAT_XRGB8888:
> > +           case DRM_FORMAT_ARGB8888:
> > +                   break;
> > +           default:
> > +                   DRM_DEBUG_KMS("RC supported only with RGB8888 
> > formats\n");
> > +                   return -EINVAL;
> > +           }
> > +           /* fall through */
> >     case I915_FORMAT_MOD_Y_TILED:
> >     case I915_FORMAT_MOD_Yf_TILED:
> >             if (INTEL_GEN(dev_priv) < 9) {
> > @@ -16059,22 +16239,46 @@ static int intel_framebuffer_init(struct 
> > drm_device *dev,
> >     if (mode_cmd->offsets[0] != 0)
> >             return -EINVAL;
> >  
> > -   drm_helper_mode_fill_fb_struct(dev, &intel_fb->base, mode_cmd);
> > +   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
> >  
> > -   stride_alignment = intel_fb_stride_alignment(&intel_fb->base, 0);
> > -   if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
> > -           DRM_DEBUG_KMS("pitch (%d) must be at least %u byte aligned\n",
> > -                         mode_cmd->pitches[0], stride_alignment);
> > -           return -EINVAL;
> > +   for (i = 0; i < fb->format->num_planes; i++) {
> > +           u32 stride_alignment;
> > +
> > +           if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
> > +                   DRM_DEBUG_KMS("bad plane %d handle\n", i);
> > +                   return -EINVAL;
> > +           }
> > +
> > +           stride_alignment = intel_fb_stride_alignment(fb, i);
> > +
> > +           /*
> > +            * Display WA #0531: skl,bxt,kbl,glk
> > +            *
> > +            * Render decompression and plane width > 3840
> > +            * combined with horizontal panning requires the
> > +            * plane stride to be a multiple of 4. We'll just
> > +            * require the entire fb to accommodate that to avoid
> > +            * potential runtime errors at plane configuration time.
> > +            */
> > +           if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 &&
> > +               (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +                fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
> > +                   stride_alignment *= 4;
> > +
> > +           if (fb->pitches[i] & (stride_alignment - 1)) {
> > +                   DRM_DEBUG_KMS("plane %d pitch (%d) must be at least %u 
> > byte aligned\n",
> > +                                 i, fb->pitches[i], stride_alignment);
> > +                   return -EINVAL;
> > +           }
> >     }
> >  
> >     intel_fb->obj = obj;
> >  
> > -   ret = intel_fill_fb_info(dev_priv, &intel_fb->base);
> > +   ret = intel_fill_fb_info(dev_priv, fb);
> >     if (ret)
> >             return ret;
> >  
> > -   ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
> > +   ret = drm_framebuffer_init(dev, fb, &intel_fb_funcs);
> >     if (ret) {
> >             DRM_ERROR("framebuffer init failed %d\n", ret);
> >             return ret;
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c 
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index 249623d45be0..25782cd174c0 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -62,6 +62,20 @@ static void gen9_init_clock_gating(struct 
> > drm_i915_private *dev_priv)
> >     I915_WRITE(CHICKEN_PAR1_1,
> >                I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
> >  
> > +   /*
> > +    * Display WA#0390: skl,bxt,kbl,glk
> > +    *
> > +    * Must match Sampler, Pixel Back End, and Media
> > +    * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27 and 31).
> > +    *
> > +    * Including bits outside the page in the hash would
> > +    * require 2 (or 4?) MiB alignment of resources. Just
> > +    * assume the defaul hashing mode which only uses bits
> > +    * within the page.
> > +    */
> > +   I915_WRITE(CHICKEN_PAR1_1,
> > +              I915_READ(CHICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE);
> > +
> >     I915_WRITE(GEN8_CONFIG0,
> >                I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
> >  
> > @@ -3314,7 +3328,9 @@ skl_ddb_min_alloc(const struct drm_plane_state 
> > *pstate,
> >  
> >     /* For Non Y-tile return 8-blocks */
> >     if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
> > -       fb->modifier != I915_FORMAT_MOD_Yf_TILED)
> > +       fb->modifier != I915_FORMAT_MOD_Yf_TILED &&
> > +       fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS &&
> > +       fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS)
> >             return 8;
> >  
> >     src_w = drm_rect_width(&intel_pstate->base.src) >> 16;
> > @@ -3590,7 +3606,9 @@ static int skl_compute_plane_wm(const struct 
> > drm_i915_private *dev_priv,
> >     }
> >  
> >     y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
> > -             fb->modifier == I915_FORMAT_MOD_Yf_TILED;
> > +             fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
> > +             fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +             fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
> >     x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
> >  
> >     /* Display WA #1141: kbl. */
> > @@ -3675,6 +3693,13 @@ static int skl_compute_plane_wm(const struct 
> > drm_i915_private *dev_priv,
> >     res_lines = DIV_ROUND_UP(selected_result.val,
> >                              plane_blocks_per_line.val);
> >  
> > +   /* Display WA #1125: skl,bxt,kbl,glk */
> > +   if (level == 0 &&
> > +       (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> > +        fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
> > +           res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum);
> 
> This WA also requires adjusting res_lines and making the level 0
> res_blocks and res_lines the minimum for the higher levels.
> The level 0 res_lines won't be used though later and the minimum could
> be guaranteed already by the higher memory latency values for higher
> levels. In any case this check can be added later if needed. The rest
> looks good:
> Reviewed-by: Imre Deak <imre.d...@intel.com>
> 
> > +
> > +   /* Display WA #1126: skl,bxt,kbl,glk */
> >     if (level >= 1 && level <= 7) {
> >             if (y_tiled) {
> >                     res_blocks += 
> > fixed_16_16_to_u32_round_up(y_tile_minimum);

Yeah so this ^ is where we do the same adjustment for level >= 1
regardless of CCS or not, and so assuming the memory latency values
are non-decreasing this should give us the required guarantee already.

> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index 7031bc733d97..063a994815d0 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -210,6 +210,7 @@ skl_update_plane(struct drm_plane *drm_plane,
> >     u32 surf_addr = plane_state->main.offset;
> >     unsigned int rotation = plane_state->base.rotation;
> >     u32 stride = skl_plane_stride(fb, 0, rotation);
> > +   u32 aux_stride = skl_plane_stride(fb, 1, rotation);
> >     int crtc_x = plane_state->base.dst.x1;
> >     int crtc_y = plane_state->base.dst.y1;
> >     uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
> > @@ -248,6 +249,10 @@ skl_update_plane(struct drm_plane *drm_plane,
> >     I915_WRITE(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
> >     I915_WRITE(PLANE_STRIDE(pipe, plane_id), stride);
> >     I915_WRITE(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
> > +   I915_WRITE(PLANE_AUX_DIST(pipe, plane_id),
> > +              (plane_state->aux.offset - surf_addr) | aux_stride);
> > +   I915_WRITE(PLANE_AUX_OFFSET(pipe, plane_id),
> > +              (plane_state->aux.y << 16) | plane_state->aux.x);
> >  
> >     /* program plane scaler */
> >     if (plane_state->scaler_id >= 0) {
> > -- 
> > 2.10.2
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to