diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_plane.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index da18dec21696..fa6809d8b0fe 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -500,8 +500,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, u32 ctl0_offset = vc4_state->dlist_count; const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); int num_planes = drm_format_num_planes(format->drm); - u32 scl0, scl1; - u32 lbm_size; + u32 scl0, scl1, pitch0; + u32 lbm_size, tiling; unsigned long irqflags; int ret, i; @@ -542,11 +542,31 @@ static int vc4_plane_mode_set(struct drm_plane *plane, scl1 = vc4_get_scl_field(state, 0); } + switch (fb->modifier) { + case DRM_FORMAT_MOD_LINEAR: + tiling = SCALER_CTL0_TILING_LINEAR; + pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); + break; + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + tiling = SCALER_CTL0_TILING_256B_OR_T; + + pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET), + VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L), + VC4_SET_FIELD((vc4_state->src_w[0] + 31) >> 5, + SCALER_PITCH0_TILE_WIDTH_R)); + break; + default: + DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx", + (long long)fb->modifier); + return -EINVAL; + } + /* Control word */ vc4_dlist_write(vc4_state, SCALER_CTL0_VALID | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) | + VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) | (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) | VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) | VC4_SET_FIELD(scl1, SCALER_CTL0_SCL1)); @@ -600,8 +620,11 @@ static int vc4_plane_mode_set(struct drm_plane *plane, for (i = 0; i < num_planes; i++) vc4_dlist_write(vc4_state, 0xc0c0c0c0); - /* Pitch word 0/1/2 */ - for (i = 0; i < num_planes; i++) { + /* Pitch word 0 */ + vc4_dlist_write(vc4_state, pitch0); + + /* Pitch word 1/2 */ + for (i = 1; i < num_planes; i++) { vc4_dlist_write(vc4_state, VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH)); } |