From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jason Ekstrand Subject: Re: [PATCH v2 9/9] drm/i915: Add render decompression support Date: Tue, 28 Feb 2017 12:18:39 -0800 Message-ID: References: <20170104184232.23048-10-ville.syrjala@linux.intel.com> <20170105151454.12862-1-ville.syrjala@linux.intel.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1312375058==" Return-path: In-Reply-To: <20170105151454.12862-1-ville.syrjala@linux.intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: =?UTF-8?B?VmlsbGUgU3lyasOkbMOk?= Cc: Ben Widawsky , Paulo Zanoni , intel-gfx@lists.freedesktop.org, Maling list - DRI developers , Chad Versace , Vandana Kannan List-Id: dri-devel@lists.freedesktop.org --===============1312375058== Content-Type: multipart/alternative; boundary=001a114cd4e8d4c95905499ce62f --001a114cd4e8d4c95905499ce62f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Thu, Jan 5, 2017 at 7:14 AM, wrote: > From: Ville Syrj=C3=A4l=C3=A4 > > 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 > * Daniel Vetter > * Ben Widawsky > > v2: Deal with display workarounds 0390, 0531, 1125 (Paulo) > > Cc: Paulo Zanoni > Cc: Vandana Kannan > Cc: Daniel Vetter > Cc: Ben Widawsky > Cc: Jason Ekstrand > Signed-off-by: Ville Syrj=C3=A4l=C3=A4 > --- > 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 =3D=3D 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 =3D=3D 1) > + return 64; > I've said it before but reading through Ben's patches again make me want to be peskier about it. I would really like the UABI to treat the CCS as if it's Y-tiled with a tile size of 128B x 32 rows. Why? Because this is what all the docs say it is. From the display docs for "Color Control Surface": "The Color Control Surface (CCS) contains the compression status of the cache-line pairs. The compression state of the cache-line pair is specified by 2 bits in the CCS. Each CCS cache-line represents an area on the main surface of 16 x16 sets of 128 byte Y-tiled cache-line-pairs. CCS is always Y tiled." This contains 95% of the information needed to know the relation between the CCS and the main surface. The other 5% (which is badly documented) is that cache line pairs are horizontally adjacent. This gives a relationship of one cache line in the CCS maps to 32x64 cache lines in the main surface. But it's not actually Y-tiled? Of course not. I've worked out the exact tiling and it looks something like Y but isn't quite the same. However, this isn't unique to CCS. Stencil (W-tiled), HiZ, and gen7-8 single-sampled MCS also each have their own tiling (Haswell MCS is especially exotic) but the docs call all of them Y-tiled and I think the hardware internally treats them as Y-tiled with the cache lines shuffled around a bit. Given the fact that they seem to like to change the MCS/CCS tiling around on every hardware generation, I'm reluctant to base UABI on the fact that the CCS appears to have 64x64 "pixels" per tile with each "pixel" corresponding to 16x8 pixels in the color surface. That's not what we had on any previous gen and may change on gen10 for no aparent reason. I'd much rather base it on Y-tiling and a relationship between cache lines which, even if they change the exact swizzle on gen10, will probably remain the same. (For the gen7-8 analogue of CCS, they changed the tiling every generation but the relationship of one MCS cache line maps to 32x128 color cache lines remained the same). Ok, I've said my peice. If we have to divide by 2 in userspace, we won't die, but I'd like to get the UABI right before we chissel it in stone. --Jason > + /* 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 =3D to_i915(fb->dev); > > /* AUX_DIST needs only 4K alignment */ > - if (fb->format->format =3D=3D DRM_FORMAT_NV12 && plane =3D=3D 1) > + if (plane =3D=3D 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) >=3D 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(uin= t64_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 =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS) &&= i =3D=3D > 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 =3D (x * 16) % (64 * 16); > + ccs_y =3D (y * 8) % (64 * 8); > + main_x =3D intel_fb->normal[0].x % (64 * 16); > + main_y =3D 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 mai= n > surface. > + */ > + if (main_x !=3D ccs_x || main_y !=3D ccs_y) { > + DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d cc= s > %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 =3D plane_state->base.fb; > + int aux_x =3D plane_state->aux.x; > + int aux_y =3D plane_state->aux.y; > + u32 aux_offset =3D plane_state->aux.offset; > + u32 alignment =3D intel_surf_alignment(fb, 1); > + > + while (aux_offset >=3D main_offset && aux_y <=3D main_y) { > + int x, y; > + > + if (aux_x =3D=3D main_x && aux_y =3D=3D main_y) > + break; > + > + if (aux_offset =3D=3D 0) > + break; > + > + x =3D aux_x / 16; > + y =3D aux_y / 8; > + aux_offset =3D intel_adjust_tile_offset(&x, &y, plane_sta= te, > 1, > + aux_offset, > aux_offset - alignment); > + aux_x =3D x * 16 + aux_x % 16; > + aux_y =3D y * 8 + aux_y % 8; > + } > + > + if (aux_x !=3D main_x || aux_y !=3D main_y) > + return false; > + > + plane_state->aux.offset =3D aux_offset; > + plane_state->aux.x =3D aux_x; > + plane_state->aux.y =3D aux_y; > + > + return true; > +} > + > static int skl_check_main_surface(struct intel_plane_state *plane_state) > { > const struct drm_framebuffer *fb =3D 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 =3D=3D 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 =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS) { > + while (!skl_check_main_ccs_coordinates(plane_state, x, y, > offset)) { > + if (offset =3D=3D 0) > + break; > + > + offset =3D intel_adjust_tile_offset(&x, &y, > plane_state, 0, > + offset, offset = - > alignment); > + } > + > + if (x !=3D plane_state->aux.x || y !=3D plane_state->aux.= y) { > + DRM_DEBUG_KMS("Unable to find suitable display > surface offset due to CCS\n"); > + return -EINVAL; > + } > + } > + > plane_state->main.offset =3D offset; > plane_state->main.x =3D x; > plane_state->main.y =3D 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 =3D to_intel_plane(plane_state-> > base.plane); > + struct intel_crtc *crtc =3D to_intel_crtc(plane_state->base.crtc)= ; > + int src_x =3D plane_state->base.src.x1 >> 16; > + int src_y =3D plane_state->base.src.y1 >> 16; > + int x =3D src_x / 16; > + int y =3D 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 =3D=3D 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 =3D intel_compute_tile_offset(&x, &y, plane_state, 1); > + > + plane_state->aux.offset =3D offset; > + plane_state->aux.x =3D x * 16 + src_x % 16; > + plane_state->aux.y =3D y * 8 + src_y % 8; > + > + return 0; > +} > + > int skl_check_plane_surface(struct intel_plane_state *plane_state) > { > const struct drm_framebuffer *fb =3D plane_state->base.fb; > @@ -3002,6 +3142,11 @@ int skl_check_plane_surface(struct > intel_plane_state *plane_state) > ret =3D skl_check_nv12_aux_surface(plane_state); > if (ret) > return ret; > + } else if (fb->modifier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS) { > + ret =3D skl_check_ccs_aux_surface(plane_state); > + if (ret) > + return ret; > } else { > plane_state->aux.offset =3D ~0xfff; > plane_state->aux.x =3D 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 =3D plane_state->base.rotation; > u32 stride =3D skl_plane_stride(fb, 0, rotation); > + u32 aux_stride =3D skl_plane_stride(fb, 1, rotation); > u32 surf_addr =3D plane_state->main.offset; > int scaler_id =3D plane_state->scaler_id; > int src_x =3D 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 >=3D 0) { > uint32_t ps_ctrl =3D 0; > @@ -9807,10 +9961,16 @@ skylake_get_initial_plane_config(struct > intel_crtc *crtc, > fb->modifier =3D I915_FORMAT_MOD_X_TILED; > break; > case PLANE_CTL_TILED_Y: > - fb->modifier =3D I915_FORMAT_MOD_Y_TILED; > + if (val & PLANE_CTL_DECOMPRESSION_ENABLE) > + fb->modifier =3D I915_FORMAT_MOD_Y_TILED_CCS; > + else > + fb->modifier =3D I915_FORMAT_MOD_Y_TILED; > break; > case PLANE_CTL_TILED_YF: > - fb->modifier =3D I915_FORMAT_MOD_Yf_TILED; > + if (val & PLANE_CTL_DECOMPRESSION_ENABLE) > + fb->modifier =3D I915_FORMAT_MOD_Yf_TILED_CCS; > + else > + fb->modifier =3D 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 =3D skl_plane_stride(fb, 0, rotation); > > ctl =3D I915_READ(PLANE_CTL(pipe, 0)); > - ctl &=3D ~PLANE_CTL_TILED_MASK; > + ctl &=3D ~(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 |=3D PLANE_CTL_TILED_Y; > break; > + case I915_FORMAT_MOD_Y_TILED_CCS: > + ctl |=3D PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENAB= LE; > + break; > case I915_FORMAT_MOD_Yf_TILED: > ctl |=3D PLANE_CTL_TILED_YF; > break; > + case I915_FORMAT_MOD_Yf_TILED_CCS: > + ctl |=3D 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 =3D to_i915(dev); > + struct drm_framebuffer *fb =3D &intel_fb->base; > unsigned int tiling =3D 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] !=3D 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 =3D 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 =3D 0; i < fb->format->num_planes; i++) { > + u32 stride_alignment; > + > + if (mode_cmd->handles[i] !=3D mode_cmd->handles[0]) { > + DRM_DEBUG_KMS("bad plane %d handle\n", i); > + return -EINVAL; > + } > + > + stride_alignment =3D 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. > Note to Ben: Userspace needs to know about this too. In this case, I believe "multiple of 4" means "multiple of 4 tiles". You've never hit this because the standard 1920x1080 is 60 tiles wide which is a multiple of 4. > + */ > + if (IS_GEN9(dev_priv) && i =3D=3D 0 && fb->width > 3840 &= & > + (fb->modifier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS)) > + stride_alignment *=3D 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 =3D obj; > > - ret =3D intel_fill_fb_info(dev_priv, &intel_fb->base); > + ret =3D intel_fill_fb_info(dev_priv, fb); > if (ret) > return ret; > > - ret =3D drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_func= s); > + ret =3D 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 !=3D I915_FORMAT_MOD_Y_TILED && > - fb->modifier !=3D I915_FORMAT_MOD_Yf_TILED) > + fb->modifier !=3D I915_FORMAT_MOD_Yf_TILED && > + fb->modifier !=3D I915_FORMAT_MOD_Y_TILED_CCS && > + fb->modifier !=3D I915_FORMAT_MOD_Yf_TILED_CCS) > return 8; > > src_w =3D 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 =3D fb->modifier =3D=3D I915_FORMAT_MOD_Y_TILED || > - fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED; > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED || > + fb->modifier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS; > x_tiled =3D fb->modifier =3D=3D 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 =3D DIV_ROUND_UP(selected_result.val, > plane_blocks_per_line.val); > > + /* Display WA #1125: skl,bxt,kbl,glk */ > + if (level =3D=3D 0 && > + (fb->modifier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS || > + fb->modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS)) > + res_blocks +=3D fixed_16_16_to_u32_round_up(y_tile_minimu= m); > + > + /* Display WA #1126: skl,bxt,kbl,glk */ > if (level >=3D 1 && level <=3D 7) { > if (y_tiled) { > res_blocks +=3D fixed_16_16_to_u32_round_up(y_ > tile_minimum); > 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 =3D plane_state->main.offset; > unsigned int rotation =3D plane_state->base.rotation; > u32 stride =3D skl_plane_stride(fb, 0, rotation); > + u32 aux_stride =3D skl_plane_stride(fb, 1, rotation); > int crtc_x =3D plane_state->base.dst.x1; > int crtc_y =3D plane_state->base.dst.y1; > uint32_t crtc_w =3D 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 >=3D 0) { > -- > 2.10.2 > > --001a114cd4e8d4c95905499ce62f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


On Thu, Jan 5, 2017 at 7:14 AM, <ville.syrjala@linux.inte= l.com> wrote:
From: Ville Syrj= =C3=A4l=C3=A4 <ville.sy= rjala@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 "searc= h
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.ka= nnan@intel.com>
* Daniel Vetter <daniel@ffwll.ch&= gt;
* Ben Widawsky <ben@bwidawsk.net= >

v2: Deal with display workarounds 0390, 0531, 1125 (Paulo)

Cc: Paulo Zanoni <paulo.r.za= noni@intel.com>
Cc: Vandana Kannan <vandana.kannan@intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ben Widawsky <
ben@bwidawsk.net>
Cc: Jason Ekstrand <
jason@jlekst= rand.net>
Signed-off-by: Ville Syrj=C3=A4l=C3=A4 <ville.syrjala@linux.intel.com>
---
=C2=A0drivers/gpu/drm/i915/i915_reg.h=C2=A0 =C2=A0 =C2=A0 |=C2= =A0 23 ++++
=C2=A0drivers/gpu/drm/i915/intel_display.c | 234 +++++++++++++++++++++= +++++++++++---
=C2=A0drivers/gpu/drm/i915/intel_pm.c=C2=A0 =C2=A0 =C2=A0 |=C2=A0 29 += +++-
=C2=A0drivers/gpu/drm/i915/intel_sprite.c=C2=A0 |=C2=A0 =C2=A05 +
=C2=A04 files changed, 274 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i9= 15_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 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A),=C2=A0 =C2=A0\
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))

+#define PLANE_AUX_DIST_1_A=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= 0x701c0
+#define PLANE_AUX_DIST_2_A=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= 0x702c0
+#define PLANE_AUX_DIST_1_B=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= 0x711c0
+#define PLANE_AUX_DIST_2_B=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= 0x712c0
+#define _PLANE_AUX_DIST_1(pipe) \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0_PIPE(pipe, PLANE_AUX_DIST_1_A, PLANE_AUX_DIST_1_B)
+#define _PLANE_AUX_DIST_2(pipe) \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0_PIPE(pipe, PLANE_AUX_DIST_2_A, PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DIST(pipe, plane)=C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0_MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PL= ANE_AUX_DIST_2(pipe))
+
+#define PLANE_AUX_OFFSET_1_A=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x701= c4
+#define PLANE_AUX_OFFSET_2_A=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x702= c4
+#define PLANE_AUX_OFFSET_1_B=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x711= c4
+#define PLANE_AUX_OFFSET_2_B=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x712= c4
+#define _PLANE_AUX_OFFSET_1(pipe)=C2=A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0_PIPE(pipe, PLANE_A= UX_OFFSET_1_A, PLANE_AUX_OFFSET_1_B)
+#define _PLANE_AUX_OFFSET_2(pipe)=C2=A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0_PIPE(pipe, PLANE_A= UX_OFFSET_2_A, PLANE_AUX_OFFSET_2_B)
+#define PLANE_AUX_OFFSET(pipe, plane)=C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0_MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _= PLANE_AUX_OFFSET_2(pipe))
+
=C2=A0/* legacy palette */
=C2=A0#define _LGC_PALETTE_A=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x4a00= 0
=C2=A0#define _LGC_PALETTE_B=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x4a80= 0
@@ -6433,6 +6455,7 @@ enum {
=C2=A0# define CHICKEN3_DGMG_DONE_FIX_DISABLE=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 2)

=C2=A0#define CHICKEN_PAR1_1=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0_MMIO(0x42080= )
+#define=C2=A0 SKL_RC_HASH_OUTSIDE=C2=A0 =C2=A0(1 << 15)
=C2=A0#define=C2=A0 DPA_MASK_VBLANK_SRD=C2=A0 =C2=A0(1 << 15)
=C2=A0#define=C2=A0 FORCE_ARB_IDLE_PLANES (1 << 14)
=C2=A0#define=C2=A0 SKL_EDP_PSR_FIX_RDWRAP=C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 &l= t;< 3)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i9= 15/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)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return 128;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return 512;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (plane =3D=3D 1)=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return 64;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* fall through */<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (IS_GEN2(dev_pri= v) || HAS_128_BYTE_Y_TILING(dev_priv))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return 128;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return 512;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (plane =3D=3D 1)=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return 64;

I'= ve said it before but reading through Ben's patches again make me want = to be peskier about it.=C2=A0 I would really like the UABI to treat the CCS= as if it's Y-tiled with a tile size of 128B x 32 rows.=C2=A0 Why?=C2= =A0 Because this is what all the docs say it is.=C2=A0 From the display doc= s for "Color Control Surface":

"The Color Control Sur= face (CCS) contains the compression status of the cache-line pairs. The
= compression state of the cache-line pair is specified by 2 bits in the CCS.= Each CCS cache-line represents
an area on the main surface of 16 x16 se= ts of 128 byte Y-tiled cache-line-pairs. CCS is always Y tiled."
This contains 95% of the information needed to know the relati= on between the CCS and the main surface.=C2=A0 The other 5% (which is badly= documented) is that cache line pairs are horizontally adjacent.=C2=A0 This= gives a relationship of one cache line in the CCS maps to 32x64 cache line= s in the main surface.

But it's not actually Y-tiled?= =C2=A0 Of course not.=C2=A0 I've worked out the exact tiling and it loo= ks something like Y but isn't quite the same.=C2=A0 However, this isn&#= 39;t unique to CCS.=C2=A0 Stencil (W-tiled), HiZ, and gen7-8 single-sampled= MCS also each have their own tiling (Haswell MCS is especially exotic) but= the docs call all of them Y-tiled and I think the hardware internally trea= ts them as Y-tiled with the cache lines shuffled around a bit.

Given= the fact that they seem to like to change the MCS/CCS tiling around on eve= ry hardware generation, I'm reluctant to base UABI on the fact that the= CCS appears to have 64x64 "pixels" per tile with each "pixe= l" corresponding to 16x8 pixels in the color surface.=C2=A0 That's= not what we had on any previous gen and may change on gen10 for no aparent= reason.=C2=A0 I'd much rather base it on Y-tiling and a relationship b= etween cache lines which, even if they change the exact swizzle on gen10, w= ill probably remain the same.=C2=A0 (For the gen7-8 analogue of CCS, they c= hanged the tiling every generation but the relationship of one MCS cache li= ne maps to 32x128 color cache lines remained the same).

O= k, I've said my peice.=C2=A0 If we have to divide by 2 in userspace, we= won't die, but I'd like to get the UABI right before we chissel it= in stone.

--Jason
=C2=A0
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* fall through */<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* 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,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct drm_i915_private *dev_priv =3D to_i915(f= b->dev);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* AUX_DIST needs only 4K alignment */
-=C2=A0 =C2=A0 =C2=A0 =C2=A0if (fb->format->format =3D=3D DRM_FORMAT_= NV12 && plane =3D=3D 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (plane =3D=3D 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 4096;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (fb->modifier) {
@@ -2166,6 +2174,8 @@ static unsigned int intel_surf_alignment(const struct= drm_framebuffer *fb,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (INTEL_GEN(dev_p= riv) >=3D 9)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return 256 * 1024;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1 * 1024 * 1= 024;
@@ -2472,6 +2482,7 @@ static unsigned int intel_fb_modifier_to_tiling(= uint64_t fb_modifier)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_X_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return I915_TILING_= X;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return I915_TILING_= Y;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return I915_TILING_= NONE;
@@ -2536,6 +2547,35 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv= ,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 intel_fb_offset_to_= xy(&x, &y, fb, i);

+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((fb->modifie= r =3D=3D I915_FORMAT_MOD_Y_TILED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb-&= gt;modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS) && i =3D=3D 1) { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int main_x, main_y;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int ccs_x, ccs_y;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 * Each byte of CCS corresponds to a 16x8 area of the main surfac= e, and
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 * each CCS tile is 64x64 bytes.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0ccs_x =3D (x * 16) % (64 * 16);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0ccs_y =3D (y * 8) % (64 * 8);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0main_x =3D intel_fb->normal[0].x % (64 * 16);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0main_y =3D intel_fb->normal[0].y % (64 * 8);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 * CCS doesn't have its own x/y offset register, so the intra= CCS tile
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 * x/y offsets must match between CCS and the main surface.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (main_x !=3D ccs_x || main_y !=3D ccs_y) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("Bad CCS x/y (main= %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0main_x, main_y,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0ccs_x, ccs_y,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0intel_fb->normal[0].x,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0intel_fb->normal[0].y,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0x, y);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* The fence (= if used) is aligned to the start of the object
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* so having t= he framebuffer wrap around across the edge of the
@@ -2873,6 +2913,9 @@ static int skl_max_plane_width(const struct drm_frame= buffer *fb, int plane,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* FIXME AUX plane?= */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (cpp) {
@@ -2895,6 +2938,42 @@ static int skl_max_plane_width(const struct drm_fram= ebuffer *fb, int plane,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2048;
=C2=A0}

+static bool skl_check_main_ccs_coordinates(struct intel_plane_state *= plane_state,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 i= nt main_x, int main_y, u32 main_offset)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0const struct drm_framebuffer *fb =3D plane_stat= e->base.fb;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int aux_x =3D plane_state->aux.x;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int aux_y =3D plane_state->aux.y;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 aux_offset =3D plane_state->aux.offset;<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 alignment =3D intel_surf_alignment(fb, 1);<= br> +
+=C2=A0 =C2=A0 =C2=A0 =C2=A0while (aux_offset >=3D main_offset &&= ; aux_y <=3D main_y) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int x, y;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (aux_x =3D=3D ma= in_x && aux_y =3D=3D main_y)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0break;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (aux_offset =3D= =3D 0)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0break;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0x =3D aux_x / 16; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0y =3D aux_y / 8; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0aux_offset =3D inte= l_adjust_tile_offset(&x, &y, plane_state, 1,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0aux_offset, aux_offset - alignment= );
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0aux_x =3D x * 16 + = aux_x % 16;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0aux_y =3D y * 8 + a= ux_y % 8;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (aux_x !=3D main_x || aux_y !=3D main_y)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.offset =3D aux_offset;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.x =3D aux_x;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.y =3D aux_y;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return true;
+}
+
=C2=A0static int skl_check_main_surface(struct intel_plane_state *plane_sta= te)
=C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 const struct drm_framebuffer *fb =3D plane_stat= e->base.fb;
@@ -2937,7 +3016,7 @@ static int skl_check_main_surface(struct intel_plane_= state *plane_state)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 while ((x + w) * cp= p > fb->pitches[0]) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if (offset =3D=3D 0) {
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("Unable to find su= itable display surface offset\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("Unable to find su= itable display surface offset due to X-tiling\n");
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 }

@@ -2946,6 +3025,26 @@ static int skl_check_main_surface(struct intel_plane= _state *plane_state)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

+=C2=A0 =C2=A0 =C2=A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * CCS AUX surface doesn't have its own x/y= offsets, we must make sure
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * they match with the main surface x/y offsets= .
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (fb->modifier =3D=3D I915_FORMAT_MOD_Y_TI= LED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier =3D=3D I915_FORMA= T_MOD_Yf_TILED_CCS) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0while (!skl_check_m= ain_ccs_coordinates(plane_state, x, y, offset)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (offset =3D=3D 0)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0offset =3D intel_adjust_tile_offset(&x, &y, plane_state, = 0,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0offset, offset - ali= gnment);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (x !=3D plane_st= ate->aux.x || y !=3D plane_state->aux.y) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0DRM_DEBUG_KMS("Unable to find suitable display surface offse= t due to CCS\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 plane_state->main.offset =3D offset;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 plane_state->main.x =3D x;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 plane_state->main.y =3D y;
@@ -2982,6 +3081,47 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
=C2=A0}

+static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_= state)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct intel_plane *plane =3D to_intel_plane(pl= ane_state->base.plane);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct intel_crtc *crtc =3D to_intel_crtc(plane= _state->base.crtc);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int src_x =3D plane_state->base.src.x1 >&= gt; 16;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int src_y =3D plane_state->base.src.y1 >&= gt; 16;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int x =3D src_x / 16;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int y =3D src_y / 8;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 offset;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0switch (plane->id) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case PLANE_PRIMARY:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case PLANE_SPRITE0:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("= ;RC support only on plane 1 and 2\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (crtc->pipe =3D=3D PIPE_C) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("= ;No RC support on pipe C\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (plane_st= ate->base.rotation &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->base.rotation &am= p; ~(DRM_ROTATE_0 | DRM_ROTATE_180)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("= ;RC support only with 0/180 degree rotation %x\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->base.rotation);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0intel_add_fb_offsets(&x, &y, plane_stat= e, 1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0offset =3D intel_compute_tile_offset(&x, &a= mp;y, plane_state, 1);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.offset =3D offset;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.x =3D x * 16 + src_x % 16;<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0plane_state->aux.y =3D y * 8 + src_y % 8; +
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
+}
+
=C2=A0int skl_check_plane_surface(struct intel_plane_state *plane_state) =C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 const struct drm_framebuffer *fb =3D plane_stat= e->base.fb;
@@ -3002,6 +3142,11 @@ int skl_check_plane_surface(struct intel_plan= e_state *plane_state)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 ret =3D skl_check_nv12_aux_surface(plane_state);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ret)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return ret;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (fb->modifier =3D=3D I915_FORMAT_M= OD_Y_TILED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb->modi= fier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D skl_check_c= cs_aux_surface(plane_state);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return ret;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 } else {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 plane_state->aux= .offset =3D ~0xfff;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 plane_state->aux= .x =3D 0;
@@ -3357,8 +3502,12 @@ u32 skl_plane_ctl_tiling(uint64_t fb_modifier= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 return PLANE_CTL_TILED_X;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return PLANE_CTL_TI= LED_Y;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return PLANE_CTL_TI= LED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return PLANE_CTL_TI= LED_YF;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return PLANE_CTL_TI= LED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 MISSING_CASE(fb_mod= ifier);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
@@ -3401,6 +3550,7 @@ static void skylake_update_primary_plane(= struct drm_plane *plane,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 plane_ctl;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int rotation =3D plane_state->base.= rotation;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 stride =3D skl_plane_stride(fb, 0, rotation= );
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 aux_stride =3D skl_plane_stride(fb, 1, rota= tion);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 surf_addr =3D plane_state->main.offset;<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int scaler_id =3D plane_state->scaler_id; =C2=A0 =C2=A0 =C2=A0 =C2=A0 int src_x =3D plane_state->main.x;
@@ -3436,6 +3586,10 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_OFFSET(= pipe, plane_id), (src_y << 16) | src_x);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_STRIDE(pipe, plane_id), stride= );
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_SIZE(pipe, plane_id), (src_h &= lt;< 16) | src_w);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0I915_WRITE(PLANE_AUX_DIST(pipe, plane_id),=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (plane_stat= e->aux.offset - surf_addr) | aux_stride);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0I915_WRITE(PLANE_AUX_OFFSET(pipe, plane_id= ),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (plane_stat= e->aux.y << 16) | plane_state->aux.x);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (scaler_id >=3D 0) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t ps_ctrl = =3D 0;
@@ -9807,10 +9961,16 @@ skylake_get_initial_plane_config(struct= intel_crtc *crtc,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 fb->modifier =3D I915_FORMAT_MOD_X_TILED;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case PLANE_CTL_TILED_Y:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier =3D= I915_FORMAT_MOD_Y_TILED;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (val & PLANE= _CTL_DECOMPRESSION_ENABLE)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0fb->modifier =3D I915_FORMAT_MOD_Y_TILED_CCS;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0fb->modifier =3D I915_FORMAT_MOD_Y_TILED;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case PLANE_CTL_TILED_YF:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier =3D= I915_FORMAT_MOD_Yf_TILED;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (val & PLANE= _CTL_DECOMPRESSION_ENABLE)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0fb->modifier =3D I915_FORMAT_MOD_Yf_TILED_CCS;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0fb->modifier =3D I915_FORMAT_MOD_Yf_TILED;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 MISSING_CASE(tiling= );
@@ -12014,7 +12174,7 @@ static void skl_do_mmio_flip(struct intel_cr= tc *intel_crtc,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 ctl, stride =3D skl_= plane_stride(fb, 0, rotation);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 ctl =3D I915_READ(PLANE_CTL(pipe, 0));
-=C2=A0 =C2=A0 =C2=A0 =C2=A0ctl &=3D ~PLANE_CTL_TILED_MASK;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ctl &=3D ~(PLANE_CTL_TILED_MASK | PLANE_CTL= _DECOMPRESSION_ENABLE);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (fb->modifier) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case DRM_FORMAT_MOD_NONE:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
@@ -12024,9 +12184,15 @@ static void skl_do_mmio_flip(struct intel_c= rtc *intel_crtc,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_T= ILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctl |=3D PLANE_CTL_= TILED_Y;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ctl |=3D PLANE_CTL_= TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctl |=3D PLANE_CTL_= TILED_YF;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ctl |=3D PLANE_CTL_= TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 MISSING_CASE(fb->= ;modifier);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
@@ -15925,9 +16091,10 @@ static int intel_framebuffer_init(struct dr= m_device *dev,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct drm_i915_gem_object *o= bj)
=C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct drm_i915_private *dev_priv =3D to_i915(d= ev);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct drm_framebuffer *fb =3D &inte= l_fb->base;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int tiling =3D = i915_gem_object_get_tiling(obj);
-=C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
-=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 pitch_limit, stride_alignment;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int ret, i;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 pitch_limit;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct drm_format_name_buf format_name;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 WARN_ON(!mutex_is_locked(&dev->stru= ct_mutex));
@@ -15953,6 +16120,19 @@ static int intel_framebuffer_init(struct dr= m_device *dev,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Passed in modifier sanity checking. */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (mode_cmd->modifier[0]) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Y_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0case I915_FORMAT_MOD_Yf_TILED_CCS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch (mode_cmd-&g= t;pixel_format) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case DRM_FORMAT_XBG= R8888:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case DRM_FORMAT_ABG= R8888:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case DRM_FORMAT_XRG= B8888:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case DRM_FORMAT_ARG= B8888:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0break;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n"= ;);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* fall through */<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Y_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 case I915_FORMAT_MOD_Yf_TILED:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (INTEL_GEN(dev_p= riv) < 9) {
@@ -16059,22 +16239,46 @@ static int intel_framebuffer_init(struct d= rm_device *dev,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (mode_cmd->offsets[0] !=3D 0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;

-=C2=A0 =C2=A0 =C2=A0 =C2=A0drm_helper_mode_fill_fb_struct(dev, &i= ntel_fb->base, mode_cmd);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0drm_helper_mode_fill_fb_struct(dev, fb, mo= de_cmd);

-=C2=A0 =C2=A0 =C2=A0 =C2=A0stride_alignment =3D intel_fb_stride_alignment(= &intel_fb->base, 0);
-=C2=A0 =C2=A0 =C2=A0 =C2=A0if (mode_cmd->pitches[0] & (stride_align= ment - 1)) {
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("= ;pitch (%d) must be at least %u byte aligned\n",
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mode_cmd->pitches[0], stride_alignment);<= br> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < fb->format->n= um_planes; i++) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0u32 stride_alignment;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (mode_cmd->ha= ndles[i] !=3D mode_cmd->handles[0]) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0DRM_DEBUG_KMS("bad plane %d handle\n", i);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0stride_align= ment =3D intel_fb_stride_alignment(fb, i);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * Display WA #0531= : skl,bxt,kbl,glk
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * Render decompres= sion and plane width > 3840
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * combined with ho= rizontal panning requires the
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * plane stride to = be a multiple of 4. We'll just
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * require the enti= re fb to accommodate that to avoid
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * potential runtim= e errors at plane configuration time.

N= ote to Ben: Userspace needs to know about this too.=C2=A0 In this case, I b= elieve "multiple of 4" means "multiple of 4 tiles".=C2= =A0 You've never hit this because the standard 1920x1080 is 60 tiles wi= de which is a multiple of 4.
=C2=A0
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (IS_GEN9(dev_pri= v) && i =3D=3D 0 && fb->width > 3840 &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fb-&= gt;modifier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb-&= gt;modifier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0stride_alignment *=3D 4;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (fb->pitches[= i] & (stride_alignment - 1)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DRM_DEBUG_KMS("plane %d pitch (%d) m= ust be at least %u byte aligned\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0i, fb->= ;pitches[i], stride_alignment);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 intel_fb->obj =3D obj;

-=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D intel_fill_fb_info(dev_priv, &am= p;intel_fb->base);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D intel_fill_fb_info(dev_priv, fb);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ret)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;

-=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D drm_framebuffer_init(dev, &intel_fb= ->base, &intel_fb_funcs);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D drm_framebuffer_init(dev, fb, &inte= l_fb_funcs);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ret) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DRM_ERROR("fra= mebuffer init failed %d\n", ret);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/in= tel_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_priva= te *dev_priv)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(CHICKEN_PAR1_1,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0I915_R= EAD(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);

+=C2=A0 =C2=A0 =C2=A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * Display WA#0390: skl,bxt,kbl,glk
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 *
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * Must match Sampler, Pixel Back End, and Medi= a
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27= and 31).
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 *
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * Including bits outside the page in the hash = would
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * require 2 (or 4?) MiB alignment of resources= . Just
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * assume the defaul hashing mode which only us= es bits
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * within the page.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0I915_WRITE(CHICKEN_PAR1_1,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_READ(C= HICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE);
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(GEN8_CONFIG0,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0I915_R= EAD(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);

@@ -3314,7 +3328,9 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstat= e,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* For Non Y-tile return 8-blocks */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (fb->modifier !=3D I915_FORMAT_MOD_Y_TILE= D &&
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier !=3D I915_FORMAT_= MOD_Yf_TILED)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier !=3D I915_FORMAT_= MOD_Yf_TILED &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier !=3D I915_FORMAT_= MOD_Y_TILED_CCS &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modifier !=3D I915_FORMAT_= MOD_Yf_TILED_CCS)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 8;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 src_w =3D drm_rect_width(&intel_pstate->= base.src) >> 16;
@@ -3590,7 +3606,9 @@ static int skl_compute_plane_wm(const struct d= rm_i915_private *dev_priv,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 y_tiled =3D fb->modifier =3D=3D I915_FORMAT_= MOD_Y_TILED ||
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modif= ier =3D=3D I915_FORMAT_MOD_Yf_TILED;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modif= ier =3D=3D I915_FORMAT_MOD_Yf_TILED ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modif= ier =3D=3D I915_FORMAT_MOD_Y_TILED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb->modif= ier =3D=3D I915_FORMAT_MOD_Yf_TILED_CCS;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 x_tiled =3D fb->modifier =3D=3D I915_FORMAT_= MOD_X_TILED;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Display WA #1141: kbl. */
@@ -3675,6 +3693,13 @@ static int skl_compute_plane_wm(const struct = drm_i915_private *dev_priv,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 res_lines =3D DIV_ROUND_UP(selected_result.val,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0plane_blocks_per_line.val);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Display WA #1125: skl,bxt,kbl,glk */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (level =3D=3D 0 &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fb->modifier =3D=3D I915_FORM= AT_MOD_Y_TILED_CCS ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fb->modifier =3D=3D I915_FORM= AT_MOD_Yf_TILED_CCS))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0res_blocks +=3D fix= ed_16_16_to_u32_round_up(y_tile_minimum);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Display WA #1126: skl,bxt,kbl,glk */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (level >=3D 1 && level <=3D 7)= {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (y_tiled) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 res_blocks +=3D fixed_16_16_to_u32_round_up(y_tile_minimum)= ;
diff --git a/drivers/gp= u/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,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 surf_addr =3D plane_state->main.offset;<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int rotation =3D plane_state->base.= rotation;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 u32 stride =3D skl_plane_stride(fb, 0, rotation= );
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 aux_stride =3D skl_plane_stride(fb, 1, rota= tion);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int crtc_x =3D plane_state->base.dst.x1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int crtc_y =3D plane_state->base.dst.y1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_t crtc_w =3D drm_rect_width(&plane_s= tate->base.dst);
@@ -248,6 +249,10 @@ skl_update_plane(struct drm_plane *drm_plane,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_OFFSET(pipe, plane_id), (y <= ;< 16) | x);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_STRIDE(pipe, plane_id), stride= );
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I915_WRITE(PLANE_SIZE(pipe, plane_id), (src_h &= lt;< 16) | src_w);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0I915_WRITE(PLANE_AUX_DIST(pipe, plane_id),=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (plane_stat= e->aux.offset - surf_addr) | aux_stride);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0I915_WRITE(PLANE_AUX_OFFSET(pipe, plane_id= ),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (plane_stat= e->aux.y << 16) | plane_state->aux.x);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* program plane scaler */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (plane_state->scaler_id >=3D 0) {
--
2.10.2


--001a114cd4e8d4c95905499ce62f-- --===============1312375058== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KSW50ZWwtZ2Z4 IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlz dHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vaW50ZWwtZ2Z4Cg== --===============1312375058==--