summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/ipuv3-plane.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/imx/ipuv3-plane.c')
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index fc8f4834ed7b..9a7150ac34a6 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -30,6 +30,11 @@ to_ipu_plane_state(struct drm_plane_state *p)
return container_of(p, struct ipu_plane_state, base);
}
+static unsigned int ipu_src_rect_width(const struct drm_plane_state *state)
+{
+ return ALIGN(drm_rect_width(&state->src) >> 16, 8);
+}
+
static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p)
{
return container_of(p, struct ipu_plane, base);
@@ -440,6 +445,12 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
if (old_fb && fb->pitches[0] != old_fb->pitches[0])
crtc_state->mode_changed = true;
+ if (ALIGN(fb->width, 8) * fb->format->cpp[0] >
+ fb->pitches[0] + fb->offsets[0]) {
+ dev_warn(dev, "pitch is not big enough for 8 pixels alignment");
+ return -EINVAL;
+ }
+
switch (fb->format->format) {
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
@@ -615,7 +626,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
if (ipu_state->use_pre) {
axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
- drm_rect_width(&new_state->src) >> 16,
+ ipu_src_rect_width(new_state),
drm_rect_height(&new_state->src) >> 16,
fb->pitches[0], fb->format->format,
fb->modifier, &eba);
@@ -648,9 +659,9 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
break;
}
- ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
+ ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
- width = drm_rect_width(&new_state->src) >> 16;
+ width = ipu_src_rect_width(new_state);
height = drm_rect_height(&new_state->src) >> 16;
info = drm_format_info(fb->format->format);
ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
@@ -715,7 +726,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_cpmem_zero(ipu_plane->alpha_ch);
ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
- drm_rect_width(&new_state->src) >> 16,
+ ipu_src_rect_width(new_state),
drm_rect_height(&new_state->src) >> 16);
ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);