aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c50
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt.c56
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c8
-rw-r--r--drivers/gpu/drm/i915/i915_vma_types.h2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c13
7 files changed, 112 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 30a2b9510184..bdb2adb4d748 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -933,7 +933,7 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
int i;
for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
- size += rot_info->plane[i].width * rot_info->plane[i].height;
+ size += rot_info->plane[i].dst_stride * rot_info->plane[i].width;
return size;
}
@@ -944,7 +944,7 @@ unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info
int i;
for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
- size += rem_info->plane[i].width * rem_info->plane[i].height;
+ size += rem_info->plane[i].dst_stride * rem_info->plane[i].height;
return size;
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 8008fd6f489e..e2e707c4dff5 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -128,6 +128,7 @@ struct intel_framebuffer {
/* Params to remap the FB pages and program the plane registers in each view. */
struct intel_fb_view normal_view;
struct intel_fb_view rotated_view;
+ struct intel_fb_view remapped_view;
};
struct intel_fbdev {
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 41ba835fabfb..fca41ac5b8e1 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -486,10 +486,17 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
return true;
}
+static bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb)
+{
+ return false;
+}
+
static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation)
{
if (drm_rotation_90_or_270(rotation))
return fb->rotated_view.color_plane[color_plane].stride;
+ else if (intel_fb_needs_pot_stride_remap(fb))
+ return fb->remapped_view.color_plane[color_plane].stride;
else
return fb->normal_view.color_plane[color_plane].stride;
}
@@ -598,6 +605,16 @@ plane_view_src_stride_tiles(const struct intel_framebuffer *fb, int color_plane,
}
static unsigned int
+plane_view_dst_stride_tiles(const struct intel_framebuffer *fb, int color_plane,
+ unsigned int pitch_tiles)
+{
+ if (intel_fb_needs_pot_stride_remap(fb))
+ return roundup_pow_of_two(pitch_tiles);
+ else
+ return pitch_tiles;
+}
+
+static unsigned int
plane_view_width_tiles(const struct intel_framebuffer *fb, int color_plane,
const struct fb_plane_view_dims *dims,
int x)
@@ -629,8 +646,8 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
unsigned int tile_width = dims->tile_width;
unsigned int tile_height = dims->tile_height;
unsigned int tile_size = intel_tile_size(i915);
- unsigned int pitch_tiles;
struct drm_rect r;
+ u32 size;
assign_chk_ovf(i915, remap_info->offset, obj_offset);
assign_chk_ovf(i915, remap_info->src_stride, plane_view_src_stride_tiles(fb, color_plane, dims));
@@ -640,6 +657,9 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
if (view->gtt.type == I915_GGTT_VIEW_ROTATED) {
check_array_bounds(i915, view->gtt.rotated.plane, color_plane);
+ assign_chk_ovf(i915, remap_info->dst_stride,
+ plane_view_dst_stride_tiles(fb, color_plane, remap_info->height));
+
/* rotate the x/y offsets to match the GTT view */
drm_rect_init(&r, x, y, dims->width, dims->height);
drm_rect_rotate(&r,
@@ -650,8 +670,9 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
color_plane_info->x = r.x1;
color_plane_info->y = r.y1;
- pitch_tiles = remap_info->height;
- color_plane_info->stride = pitch_tiles * tile_height;
+ color_plane_info->stride = remap_info->dst_stride * tile_height;
+
+ size = remap_info->dst_stride * remap_info->width;
/* rotate the tile dimensions to match the GTT view */
swap(tile_width, tile_height);
@@ -660,12 +681,16 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
check_array_bounds(i915, view->gtt.remapped.plane, color_plane);
+ assign_chk_ovf(i915, remap_info->dst_stride,
+ plane_view_dst_stride_tiles(fb, color_plane, remap_info->width));
+
color_plane_info->x = x;
color_plane_info->y = y;
- pitch_tiles = remap_info->width;
- color_plane_info->stride = pitch_tiles * tile_width *
- fb->base.format->cpp[color_plane];
+ color_plane_info->stride = remap_info->dst_stride * tile_width *
+ fb->base.format->cpp[color_plane];
+
+ size = remap_info->dst_stride * remap_info->height;
}
/*
@@ -675,10 +700,10 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
*/
intel_adjust_tile_offset(&color_plane_info->x, &color_plane_info->y,
tile_width, tile_height,
- tile_size, pitch_tiles,
+ tile_size, remap_info->dst_stride,
gtt_offset * tile_size, 0);
- return remap_info->width * remap_info->height;
+ return size;
}
#undef assign_chk_ovf
@@ -723,12 +748,14 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct drm_framebuffer *fb
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
u32 gtt_offset_rotated = 0;
+ u32 gtt_offset_remapped = 0;
unsigned int max_size = 0;
int i, num_planes = fb->format->num_planes;
unsigned int tile_size = intel_tile_size(i915);
intel_fb_view_init(&intel_fb->normal_view, I915_GGTT_VIEW_NORMAL);
intel_fb_view_init(&intel_fb->rotated_view, I915_GGTT_VIEW_ROTATED);
+ intel_fb_view_init(&intel_fb->remapped_view, I915_GGTT_VIEW_REMAPPED);
for (i = 0; i < num_planes; i++) {
struct fb_plane_view_dims view_dims;
@@ -776,6 +803,11 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct drm_framebuffer *fb
offset, gtt_offset_rotated, x, y,
&intel_fb->rotated_view);
+ if (intel_fb_needs_pot_stride_remap(intel_fb))
+ gtt_offset_remapped += calc_plane_remap_info(intel_fb, i, &view_dims,
+ offset, gtt_offset_remapped, x, y,
+ &intel_fb->remapped_view);
+
size = calc_plane_normal_size(intel_fb, i, &view_dims, x, y);
/* how many tiles in total needed in the bo */
max_size = max(max_size, offset + size);
@@ -859,6 +891,8 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio
{
if (drm_rotation_90_or_270(rotation))
*view = fb->rotated_view;
+ else if (intel_fb_needs_pot_stride_remap(fb))
+ *view = fb->remapped_view;
else
*view = fb->normal_view;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index fff750451fef..8a4fa7aef71d 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1247,14 +1247,16 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
static struct scatterlist *
rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
unsigned int width, unsigned int height,
- unsigned int stride,
+ unsigned int src_stride, unsigned int dst_stride,
struct sg_table *st, struct scatterlist *sg)
{
unsigned int column, row;
unsigned int src_idx;
for (column = 0; column < width; column++) {
- src_idx = stride * (height - 1) + column + offset;
+ unsigned int left;
+
+ src_idx = src_stride * (height - 1) + column + offset;
for (row = 0; row < height; row++) {
st->nents++;
/*
@@ -1267,8 +1269,25 @@ rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
i915_gem_object_get_dma_address(obj, src_idx);
sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
sg = sg_next(sg);
- src_idx -= stride;
+ src_idx -= src_stride;
}
+
+ left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
+
+ if (!left)
+ continue;
+
+ st->nents++;
+
+ /*
+ * The DE ignores the PTEs for the padding tiles, the sg entry
+ * here is just a conenience to indicate how many padding PTEs
+ * to insert at this spot.
+ */
+ sg_set_page(sg, NULL, left, 0);
+ sg_dma_address(sg) = 0;
+ sg_dma_len(sg) = left;
+ sg = sg_next(sg);
}
return sg;
@@ -1297,11 +1316,12 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
st->nents = 0;
sg = st->sgl;
- for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
+ for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
sg = rotate_pages(obj, rot_info->plane[i].offset,
rot_info->plane[i].width, rot_info->plane[i].height,
- rot_info->plane[i].src_stride, st, sg);
- }
+ rot_info->plane[i].src_stride,
+ rot_info->plane[i].dst_stride,
+ st, sg);
return st;
@@ -1319,7 +1339,7 @@ err_st_alloc:
static struct scatterlist *
remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
unsigned int width, unsigned int height,
- unsigned int stride,
+ unsigned int src_stride, unsigned int dst_stride,
struct sg_table *st, struct scatterlist *sg)
{
unsigned int row;
@@ -1352,7 +1372,24 @@ remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
left -= length;
}
- offset += stride - width;
+ offset += src_stride - width;
+
+ left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
+
+ if (!left)
+ continue;
+
+ st->nents++;
+
+ /*
+ * The DE ignores the PTEs for the padding tiles, the sg entry
+ * here is just a conenience to indicate how many padding PTEs
+ * to insert at this spot.
+ */
+ sg_set_page(sg, NULL, left, 0);
+ sg_dma_address(sg) = 0;
+ sg_dma_len(sg) = left;
+ sg = sg_next(sg);
}
return sg;
@@ -1384,7 +1421,8 @@ intel_remap_pages(struct intel_remapped_info *rem_info,
for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
sg = remap_pages(obj, rem_info->plane[i].offset,
rem_info->plane[i].width, rem_info->plane[i].height,
- rem_info->plane[i].src_stride, st, sg);
+ rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
+ st, sg);
}
i915_sg_trim(st);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 48032c0288ee..4cf975b7504f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -173,26 +173,30 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
break;
case I915_GGTT_VIEW_ROTATED:
- seq_printf(m, ", rotated [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
+ seq_printf(m, ", rotated [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
vma->ggtt_view.rotated.plane[0].width,
vma->ggtt_view.rotated.plane[0].height,
vma->ggtt_view.rotated.plane[0].src_stride,
+ vma->ggtt_view.rotated.plane[0].dst_stride,
vma->ggtt_view.rotated.plane[0].offset,
vma->ggtt_view.rotated.plane[1].width,
vma->ggtt_view.rotated.plane[1].height,
vma->ggtt_view.rotated.plane[1].src_stride,
+ vma->ggtt_view.rotated.plane[1].dst_stride,
vma->ggtt_view.rotated.plane[1].offset);
break;
case I915_GGTT_VIEW_REMAPPED:
- seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
+ seq_printf(m, ", remapped [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
vma->ggtt_view.remapped.plane[0].width,
vma->ggtt_view.remapped.plane[0].height,
vma->ggtt_view.remapped.plane[0].src_stride,
+ vma->ggtt_view.remapped.plane[0].dst_stride,
vma->ggtt_view.remapped.plane[0].offset,
vma->ggtt_view.remapped.plane[1].width,
vma->ggtt_view.remapped.plane[1].height,
vma->ggtt_view.remapped.plane[1].src_stride,
+ vma->ggtt_view.remapped.plane[1].dst_stride,
vma->ggtt_view.remapped.plane[1].offset);
break;
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index f7f2aa168c9e..6b1bfa230b82 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -101,7 +101,7 @@ struct intel_remapped_plane_info {
u16 width;
u16 height;
u16 src_stride;
- u16 unused_mbz;
+ u16 dst_stride;
} __packed;
struct intel_remapped_info {
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 9aaf7201e242..6aadcd31d75a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -528,6 +528,15 @@ static int igt_vma_rotate_remap(void *arg)
GEM_BUG_ON(max_offset > max_pages);
max_offset = max_pages - max_offset;
+ if (!plane_info[0].dst_stride)
+ plane_info[0].dst_stride = view.type == I915_GGTT_VIEW_ROTATED ?
+ plane_info[0].height :
+ plane_info[0].width;
+ if (!plane_info[1].dst_stride)
+ plane_info[1].dst_stride = view.type == I915_GGTT_VIEW_ROTATED ?
+ plane_info[1].height :
+ plane_info[1].width;
+
for_each_prime_number_from(plane_info[0].offset, 0, max_offset) {
for_each_prime_number_from(plane_info[1].offset, 0, max_offset) {
struct scatterlist *sg;
@@ -902,6 +911,10 @@ static int igt_vma_remapped_gtt(void *arg)
if (err)
goto out;
+ if (!plane_info[0].dst_stride)
+ plane_info[0].dst_stride = *t == I915_GGTT_VIEW_ROTATED ?
+ p->height : p->width;
+
vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);