On Sat, Sep 05, 2015 at 01:12:50AM +0530, Vandana Kannan wrote: > This patch includes enabling render decompression after checking all the > requirements (format, tiling, rotation etc.). Along with this, the WAs > mentioned in BSpec Workaround page have been implemented. > > This patch has been implemented on top of Nabendu/Chandra's NV12 patches. > > TODO: > 1. Disable stereo 3D when render decomp is enabled (bit 7:6) > 2. Render decompression must not be used in VTd pass-through mode > 3. Program hashing select CHICKEN_MISC1 bit 15 > 4. For Gen10, add support for RGB 1010102 > > Signed-off-by: Vandana Kannan <vandana.kannan@xxxxxxxxx> > --- > drivers/gpu/drm/drm_atomic.c | 4 + > drivers/gpu/drm/drm_crtc.c | 16 ++++ > drivers/gpu/drm/i915/intel_display.c | 174 +++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_drv.h | 7 ++ > drivers/gpu/drm/i915/intel_sprite.c | 35 +++++++ > include/drm/drm_crtc.h | 11 +++ > 6 files changed, 247 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 940f80b..d9004e8 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -607,6 +607,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, > state->src_h = val; > } else if (property == config->rotation_property) { > state->rotation = val; > + } else if (property == config->compression_property) { > + state->compression = val; Please use a framebuffer modifier instead. Also this needs userspace. -Daniel > } else if (plane->funcs->atomic_set_property) { > return plane->funcs->atomic_set_property(plane, state, > property, val); > @@ -654,6 +656,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, > *val = state->src_h; > } else if (property == config->rotation_property) { > *val = state->rotation; > + } else if (property == config->compression_property) { > + *val = state->compression; > } else if (plane->funcs->atomic_get_property) { > return plane->funcs->atomic_get_property(plane, state, property, val); > } else { > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 474f328..66f817b 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -5778,6 +5778,22 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, > } > EXPORT_SYMBOL(drm_mode_create_rotation_property); > > +struct drm_property *drm_mode_create_compression_property( > + struct drm_device *dev, > + unsigned int comp_caps) > +{ > + static const struct drm_prop_enum_list props[] = { > + { DRM_COMP_NONE, "Not compression capable" }, > + { DRM_COMP_RENDER, "Only render decompression" }, > + }; > + > + return drm_property_create_bitmask(dev, 0, "render compression", > + props, ARRAY_SIZE(props), > + comp_caps); > +} > +EXPORT_SYMBOL(drm_mode_create_compression_property); > + > + > /** > * DOC: Tile group > * > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 59d6736..115736f 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3120,8 +3120,47 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, > > hphase = 0x00010001; /* use trip for both Y and UV */ > vphase = 0x00012000; /* use trip for Y and phase 0.5 for UV */ > + > + /* > + * On SKL-C and BXT-A, > + * when the plane source pixel format is NV12, > + * the CHICKEN_PIPESL_* register bit 22 must be > + * set to 1 > + */ > + if (IS_BROXTON(dev) || (IS_SKYLAKE(dev) && > + INTEL_REVID(dev) == SKL_REVID_C0)) > + I915_WRITE(CHICKEN_PIPESL_1(pipe), > + I915_READ(CHICKEN_PIPESL_1(pipe)) | > + HSW_FBCQ_DIS); > } > } > + > + if (plane->state->compression) { > + /* > + * FIXME: Check if aux_dist ad aux_stride can be taken as it > + * is from userspace. > + */ > + aux_dist = fb->offsets[1]; > + aux_stride = fb->pitches[1]; > + /* > + * For SKL and BXT, > + * When the render compression is enabled with plane > + * width greater than 3840 and horizontal panning, > + * the stride programmed in the PLANE_STRIDE register > + * must be multiple of 4. > + */ > + if (x > 3840 && x_offset != 0) > + stride = stride - (stride % 4); > + if (IS_BROXTON(dev) || (IS_SKYLAKE(dev) && > + INTEL_REVID(dev) == SKL_REVID_C0)) > + I915_WRITE(CHICKEN_PIPESL_1(pipe), > + I915_READ(CHICKEN_PIPESL_1(pipe)) & > + ~HSW_FBCQ_DIS); > + plane_ctl |= PLANE_CTL_DECOMPRESSION_ENABLE; > + } else { > + plane_ctl &= ~PLANE_CTL_DECOMPRESSION_ENABLE; > + } > + > plane_offset = y_offset << 16 | x_offset; > > I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); > @@ -11760,6 +11799,29 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, > plane_state->rotation != BIT(DRM_ROTATE_0)) > intel_crtc->atomic.disable_fbc = true; > > + if (INTEL_INFO(dev)->gen >= 9) { > + if (plane_state->compression) { > + ret = skl_check_compression(dev, > + to_intel_plane(plane), > + to_intel_plane_state(plane_state), > + intel_crtc->pipe); > + if (ret) > + return ret; > + } > + } > + > + /* > + * Disable FBC if render decompression has to be enabled. > + * FIXME: If FBC is disabled here because render decomp > + * has to be enabled, then in update_primary_plane(), if > + * render decomp is disabled for some reason, we need to > + * enable FBC ? > + */ > + if (IS_SKYLAKE(dev) && dev_priv->fbc.crtc == intel_crtc && > + plane_state->compression) { > + intel_crtc->atomic.disable_fbc = true; > + } > + > /* > * BDW signals flip done immediately if the plane > * is disabled, even if the plane enable is already > @@ -11778,6 +11840,16 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, > intel_crtc->atomic.update_sprite_watermarks |= > 1 << i; > } > + if (INTEL_INFO(dev)->gen >= 9) { > + if (plane_state->compression) { > + ret = skl_check_compression(dev, > + to_intel_plane(plane), > + to_intel_plane_state(plane_state), > + intel_crtc->pipe); > + if (ret) > + return ret; > + } > + } > } > return 0; > } > @@ -13495,6 +13567,88 @@ skl_max_scale(struct intel_crtc *intel_crtc, > return max_scale; > } > > +int skl_check_compression(struct drm_device *dev, > + struct intel_plane *intel_plane, > + struct intel_plane_state *plane_state, > + enum pipe pipe) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct drm_rect *src = &plane_state->src; > + struct drm_framebuffer *fb; > + int i; > + > + fb = intel_plane ? plane_state->base.fb : NULL; > + > + /* > + * TODO: > + * 1. Disable stereo 3D when render decomp is enabled (bit 7:6) > + * 2. Render decompression must not be used in VTd pass-through mode > + * 3. Program hashing select CHICKEN_MISC1 bit 15 > + */ > + > + /* > + * On SKL A and SKL B, > + * Do not enable render decompression when the plane > + * width is smaller than 32 pixels or greater than > + * 2048 pixels > + */ > + if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) < SKL_REVID_C0) > + && ((src->x1 >> 16) > 2048)) > + plane_state->base.compression = DRM_COMP_NONE; > + > + if (!plane_state->base.compression) > + return -EINVAL; > + > + /* > + * On SKL:*:C and BXT:*:A, there is a possible hang with NV12 format. > + * WA: When the plane source pixel format is NV12, > + * the CHICKEN_PIPESL_* register bit 22 must be set to 1 and the > + * render decompression must not be enabled on any of the planes in > + * that pipe. > + */ > + if (IS_BROXTON(dev) || (IS_SKYLAKE(dev) && > + INTEL_REVID(dev) == SKL_REVID_C0)) { > + struct drm_plane *drm_plane; > + struct drm_plane_state *state; > + > + for_each_plane(dev_priv, pipe, i) { > + drm_plane = drm_plane_from_index(dev, i); > + if (drm_plane) { > + state = drm_plane->state; > + if (state) { > + if (state->fb && > + state->fb->pixel_format > + == DRM_FORMAT_NV12) { > + plane_state->base.compression = > + DRM_COMP_NONE; > + } > + } > + } > + } > + } > + > + if (!plane_state->base.compression) > + return -EINVAL; > + > + /* > + * Conditions to satisfy before enabling render decomp. > + * SKL+ > + * Pipe A & B, Planes 1 & 2 > + * RGB8888 Tile-Y format > + * 0/180 rotation > + */ > + if ((pipe == PIPE_C) || > + ((fb->pixel_format != DRM_FORMAT_XRGB8888) && > + (fb->pixel_format != DRM_FORMAT_ARGB8888)) || > + intel_rotation_90_or_270(plane_state->base.rotation) || > + ((fb->modifier[0] == DRM_FORMAT_MOD_NONE) || > + (fb->modifier[0] == I915_FORMAT_MOD_X_TILED))) { > + plane_state->base.compression = DRM_COMP_NONE; > + return -EINVAL; > + } > + return 0; > +} > + > static int > intel_check_primary_plane(struct drm_plane *plane, > struct intel_crtc_state *crtc_state, > @@ -13670,11 +13824,31 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, > if (INTEL_INFO(dev)->gen >= 4) > intel_create_rotation_property(dev, primary); > > + intel_create_compression_property(dev, primary); > + > drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); > > return &primary->base; > } > > +void intel_create_compression_property(struct drm_device *dev, > + struct intel_plane *plane) > +{ > + /* Render compression is applicable only for plane 1 & 2 */ > + if (INTEL_INFO(dev)->gen >= 9 && (plane->plane <= 1)) { > + if (!dev->mode_config.compression_property) > + dev->mode_config.compression_property = > + drm_mode_create_compression_property(dev, > + BIT(DRM_COMP_NONE) | > + BIT(DRM_COMP_RENDER)); > + > + if (dev->mode_config.compression_property) > + drm_object_attach_property(&plane->base.base, > + dev->mode_config.compression_property, > + plane->base.state->compression); > + } > +} > + > void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane) > { > if (!dev->mode_config.rotation_property) { > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 6cd6cb0..bae22eb 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1090,6 +1090,13 @@ intel_rotation_90_or_270(unsigned int rotation) > void intel_create_rotation_property(struct drm_device *dev, > struct intel_plane *plane); > > +void intel_create_compression_property(struct drm_device *dev, > + struct intel_plane *plane); > +int skl_check_compression(struct drm_device *dev, > + struct intel_plane *intel_plane, > + struct intel_plane_state *plane_state, > + enum pipe pipe); > + > /* shared dpll functions */ > struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc); > void assert_shared_dpll(struct drm_i915_private *dev_priv, > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index 2f9f856..c6cf4ad 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -275,8 +275,41 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, > > hphase = 0x00010001; /* use trip for both Y and UV */ > vphase = 0x00012000; /* use trip for Y and phase 0.5 for UV */ > + > + if (IS_BROXTON(dev) || (IS_SKYLAKE(dev) && > + INTEL_REVID(dev) == SKL_REVID_C0)) > + I915_WRITE(CHICKEN_PIPESL_1(pipe), > + I915_READ(CHICKEN_PIPESL_1(pipe)) | > + HSW_FBCQ_DIS); > } > } > + > + if (drm_plane->state->compression) { > + /* > + * FIXME: Check if aux_dist ad aux_stride can be taken as it > + * is from userspace. > + */ > + aux_dist = fb->offsets[1]; > + aux_stride = fb->pitches[1]; > + /* > + * For SKL and BXT, > + * When the render compression is enabled with plane > + * width greater than 3840 and horizontal panning, > + * the stride programmed in the PLANE_STRIDE register > + * must be multiple of 4. > + */ > + if (x > 3840 && x_offset != 0) > + stride = stride - (stride % 4); > + if (IS_BROXTON(dev) || (IS_SKYLAKE(dev) && > + INTEL_REVID(dev) == SKL_REVID_C0)) > + I915_WRITE(CHICKEN_PIPESL_1(pipe), > + I915_READ(CHICKEN_PIPESL_1(pipe)) & > + ~HSW_FBCQ_DIS); > + plane_ctl |= PLANE_CTL_DECOMPRESSION_ENABLE; > + } else { > + plane_ctl &= ~PLANE_CTL_DECOMPRESSION_ENABLE; > + } > + > plane_offset = y_offset << 16 | x_offset; > > I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset); > @@ -1217,6 +1250,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) > > intel_create_rotation_property(dev, intel_plane); > > + intel_create_compression_property(dev, intel_plane); > + > drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); > > out: > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 75f49c1..02a9aaa 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -93,6 +93,10 @@ static inline uint64_t I642U64(int64_t val) > #define DRM_REFLECT_X 4 > #define DRM_REFLECT_Y 5 > > +/* render compression property bits */ > +#define DRM_COMP_NONE 0 > +#define DRM_COMP_RENDER 1 > + > enum drm_connector_force { > DRM_FORCE_UNSPECIFIED, > DRM_FORCE_OFF, > @@ -783,6 +787,9 @@ struct drm_plane_state { > /* Plane rotation */ > unsigned int rotation; > > + /* Render compression */ > + unsigned int compression; > + > struct drm_atomic_state *state; > }; > > @@ -1114,6 +1121,7 @@ struct drm_mode_config { > struct drm_property *tile_property; > struct drm_property *plane_type_property; > struct drm_property *rotation_property; > + struct drm_property *compression_property; > struct drm_property *prop_src_x; > struct drm_property *prop_src_y; > struct drm_property *prop_src_w; > @@ -1507,6 +1515,9 @@ extern int drm_format_vert_chroma_subsampling(uint32_t format); > extern const char *drm_get_format_name(uint32_t format); > extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, > unsigned int supported_rotations); > +extern struct drm_property *drm_mode_create_compression_property( > + struct drm_device *dev, > + unsigned int comp_caps); > extern unsigned int drm_rotation_simplify(unsigned int rotation, > unsigned int supported_rotations); > > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx