|
@@ -2463,8 +2463,14 @@ u32 intel_compute_tile_offset(int *x, int *y,
|
|
const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
|
|
const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
|
|
const struct drm_framebuffer *fb = state->base.fb;
|
|
const struct drm_framebuffer *fb = state->base.fb;
|
|
unsigned int rotation = state->base.rotation;
|
|
unsigned int rotation = state->base.rotation;
|
|
- u32 alignment = intel_surf_alignment(dev_priv, fb->modifier[plane]);
|
|
|
|
int pitch = intel_fb_pitch(fb, plane, rotation);
|
|
int pitch = intel_fb_pitch(fb, plane, rotation);
|
|
|
|
+ u32 alignment;
|
|
|
|
+
|
|
|
|
+ /* AUX_DIST needs only 4K alignment */
|
|
|
|
+ if (fb->pixel_format == DRM_FORMAT_NV12 && plane == 1)
|
|
|
|
+ alignment = 4096;
|
|
|
|
+ else
|
|
|
|
+ alignment = intel_surf_alignment(dev_priv, fb->modifier[plane]);
|
|
|
|
|
|
return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
|
|
return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
|
|
rotation, alignment);
|
|
rotation, alignment);
|
|
@@ -2895,7 +2901,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
|
|
int h = drm_rect_height(&plane_state->src) >> 16;
|
|
int h = drm_rect_height(&plane_state->src) >> 16;
|
|
int max_width = skl_max_plane_width(fb, 0, rotation);
|
|
int max_width = skl_max_plane_width(fb, 0, rotation);
|
|
int max_height = 4096;
|
|
int max_height = 4096;
|
|
- u32 alignment, offset;
|
|
|
|
|
|
+ u32 alignment, offset, aux_offset = plane_state->aux.offset;
|
|
|
|
|
|
if (w > max_width || h > max_height) {
|
|
if (w > max_width || h > max_height) {
|
|
DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
|
|
DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
|
|
@@ -2908,6 +2914,15 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
|
|
|
|
|
|
alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
|
|
alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * AUX surface offset is specified as the distance from the
|
|
|
|
+ * main surface offset, and it must be non-negative. Make
|
|
|
|
+ * sure that is what we will get.
|
|
|
|
+ */
|
|
|
|
+ if (offset > aux_offset)
|
|
|
|
+ offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
|
|
|
|
+ offset, aux_offset & ~(alignment - 1));
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* When using an X-tiled surface, the plane blows up
|
|
* When using an X-tiled surface, the plane blows up
|
|
* if the x offset + width exceed the stride.
|
|
* if the x offset + width exceed the stride.
|
|
@@ -2935,6 +2950,35 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
|
|
|
|
+{
|
|
|
|
+ const struct drm_framebuffer *fb = plane_state->base.fb;
|
|
|
|
+ unsigned int rotation = plane_state->base.rotation;
|
|
|
|
+ int max_width = skl_max_plane_width(fb, 1, rotation);
|
|
|
|
+ int max_height = 4096;
|
|
|
|
+ int x = plane_state->src.x1 >> 17;
|
|
|
|
+ int y = plane_state->src.y1 >> 17;
|
|
|
|
+ int w = drm_rect_width(&plane_state->src) >> 17;
|
|
|
|
+ int h = drm_rect_height(&plane_state->src) >> 17;
|
|
|
|
+ u32 offset;
|
|
|
|
+
|
|
|
|
+ intel_add_fb_offsets(&x, &y, plane_state, 1);
|
|
|
|
+ offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
|
|
|
|
+
|
|
|
|
+ /* FIXME not quite sure how/if these apply to the chroma plane */
|
|
|
|
+ if (w > max_width || h > max_height) {
|
|
|
|
+ DRM_DEBUG_KMS("CbCr source size %dx%d too big (limit %dx%d)\n",
|
|
|
|
+ w, h, max_width, max_height);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ plane_state->aux.offset = offset;
|
|
|
|
+ plane_state->aux.x = x;
|
|
|
|
+ plane_state->aux.y = y;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
int skl_check_plane_surface(struct intel_plane_state *plane_state)
|
|
int skl_check_plane_surface(struct intel_plane_state *plane_state)
|
|
{
|
|
{
|
|
const struct drm_framebuffer *fb = plane_state->base.fb;
|
|
const struct drm_framebuffer *fb = plane_state->base.fb;
|
|
@@ -2946,6 +2990,20 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
|
|
drm_rect_rotate(&plane_state->src,
|
|
drm_rect_rotate(&plane_state->src,
|
|
fb->width, fb->height, BIT(DRM_ROTATE_270));
|
|
fb->width, fb->height, BIT(DRM_ROTATE_270));
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Handle the AUX surface first since
|
|
|
|
+ * the main surface setup depends on it.
|
|
|
|
+ */
|
|
|
|
+ if (fb->pixel_format == DRM_FORMAT_NV12) {
|
|
|
|
+ ret = skl_check_nv12_aux_surface(plane_state);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
+ } else {
|
|
|
|
+ plane_state->aux.offset = ~0xfff;
|
|
|
|
+ plane_state->aux.x = 0;
|
|
|
|
+ plane_state->aux.y = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
ret = skl_check_main_surface(plane_state);
|
|
ret = skl_check_main_surface(plane_state);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|