Message ID | 20180725153209.14366-5-boris.brezillon@bootlin.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vc4: Fix negative X/Y positioning of planes | expand |
On Wed, 25 Jul 2018 17:32:08 +0200 Boris Brezillon <boris.brezillon@bootlin.com> wrote: > From: Eric Anholt <eric@anholt.net> > > The offset adjustment depends on the framebuffer modified, so let's ^ modifier > just move this operation in the DRM_FORMAT_MOD_LINEAR case inside > vc4_plane_mode_set(). > > This we'll be able to fix offset calculation for ^ Thanks to this, we'll ... > DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED and DRM_FORMAT_MOD_BROADCOM_SANDXXX. > > Signed-off-by: Eric Anholt <eric@anholt.net> > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > --- > drivers/gpu/drm/vc4/vc4_plane.c | 23 +++++++++++++++-------- > 1 file changed, 15 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c > index 39e1fa3a8466..2b8ba1c412be 100644 > --- a/drivers/gpu/drm/vc4/vc4_plane.c > +++ b/drivers/gpu/drm/vc4/vc4_plane.c > @@ -354,14 +354,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) > vc4_state->y_scaling[1] = VC4_SCALING_NONE; > } > > - /* Adjust the base pointer to the first pixel to be scanned out. */ > - for (i = 0; i < num_planes; i++) { > - vc4_state->offsets[i] += (src_y / (i ? v_subsample : 1)) * > - fb->pitches[i]; > - vc4_state->offsets[i] += (src_x / (i ? h_subsample : 1)) * > - fb->format->cpp[i]; > - } > - > return 0; > } > > @@ -476,6 +468,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, > u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); > int num_planes = drm_format_num_planes(format->drm); > u32 src_x, src_y, crtc_h, crtc_w, src_h, src_w; > + u32 h_subsample, v_subsample; > bool mix_plane_alpha; > bool covers_screen; > u32 scl0, scl1, pitch0; > @@ -527,11 +520,25 @@ static int vc4_plane_mode_set(struct drm_plane *plane, > src_y = state->src.y1 >> 16; > src_w = (state->src.x2 - state->src.x1) >> 16; > src_h = (state->src.y2 - state->src.y1) >> 16; > + h_subsample = drm_format_horz_chroma_subsampling(format->drm); > + v_subsample = drm_format_vert_chroma_subsampling(format->drm); > > switch (base_format_mod) { > case DRM_FORMAT_MOD_LINEAR: > tiling = SCALER_CTL0_TILING_LINEAR; > pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); > + > + /* Adjust the base pointer to the first pixel to be scanned > + * out. > + */ > + for (i = 0; i < num_planes; i++) { > + vc4_state->offsets[i] += src_y / > + (i ? v_subsample : 1) * > + fb->pitches[i]; > + vc4_state->offsets[i] += src_x / > + (i ? h_subsample : 1) * > + fb->format->cpp[i]; > + } > break; > > case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: {
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 39e1fa3a8466..2b8ba1c412be 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -354,14 +354,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) vc4_state->y_scaling[1] = VC4_SCALING_NONE; } - /* Adjust the base pointer to the first pixel to be scanned out. */ - for (i = 0; i < num_planes; i++) { - vc4_state->offsets[i] += (src_y / (i ? v_subsample : 1)) * - fb->pitches[i]; - vc4_state->offsets[i] += (src_x / (i ? h_subsample : 1)) * - fb->format->cpp[i]; - } - return 0; } @@ -476,6 +468,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); int num_planes = drm_format_num_planes(format->drm); u32 src_x, src_y, crtc_h, crtc_w, src_h, src_w; + u32 h_subsample, v_subsample; bool mix_plane_alpha; bool covers_screen; u32 scl0, scl1, pitch0; @@ -527,11 +520,25 @@ static int vc4_plane_mode_set(struct drm_plane *plane, src_y = state->src.y1 >> 16; src_w = (state->src.x2 - state->src.x1) >> 16; src_h = (state->src.y2 - state->src.y1) >> 16; + h_subsample = drm_format_horz_chroma_subsampling(format->drm); + v_subsample = drm_format_vert_chroma_subsampling(format->drm); switch (base_format_mod) { case DRM_FORMAT_MOD_LINEAR: tiling = SCALER_CTL0_TILING_LINEAR; pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); + + /* Adjust the base pointer to the first pixel to be scanned + * out. + */ + for (i = 0; i < num_planes; i++) { + vc4_state->offsets[i] += src_y / + (i ? v_subsample : 1) * + fb->pitches[i]; + vc4_state->offsets[i] += src_x / + (i ? h_subsample : 1) * + fb->format->cpp[i]; + } break; case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: {