diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_frontend.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_frontend.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c index e950370792ce..6ede40aab515 100644 --- a/drivers/gpu/drm/sun4i/sun4i_frontend.c +++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c @@ -126,21 +126,64 @@ void sun4i_frontend_update_buffer(struct sun4i_frontend *frontend, { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; + unsigned int strides[3] = {}; + dma_addr_t paddr; bool swap; + if (fb->modifier == DRM_FORMAT_MOD_ALLWINNER_TILED) { + unsigned int width = state->src_w >> 16; + unsigned int offset; + + strides[0] = SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[0]); + + /* + * The X1 offset is the offset to the bottom-right point in the + * end tile, which is the final pixel (at offset width - 1) + * within the end tile (with a 32-byte mask). + */ + offset = (width - 1) & (32 - 1); + + regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF0_REG, + SUN4I_FRONTEND_TB_OFF_X1(offset)); + + if (fb->format->num_planes > 1) { + strides[1] = + SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[1]); + + regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF1_REG, + SUN4I_FRONTEND_TB_OFF_X1(offset)); + } + + if (fb->format->num_planes > 2) { + strides[2] = + SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[2]); + + regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF2_REG, + SUN4I_FRONTEND_TB_OFF_X1(offset)); + } + } else { + strides[0] = fb->pitches[0]; + + if (fb->format->num_planes > 1) + strides[1] = fb->pitches[1]; + + if (fb->format->num_planes > 2) + strides[2] = fb->pitches[2]; + } + /* Set the line width */ DRM_DEBUG_DRIVER("Frontend stride: %d bytes\n", fb->pitches[0]); regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD0_REG, - fb->pitches[0]); + strides[0]); if (fb->format->num_planes > 1) regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD1_REG, - fb->pitches[1]); + strides[1]); if (fb->format->num_planes > 2) regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD2_REG, - fb->pitches[2]); + strides[2]); /* Some planar formats require chroma channel swapping by hand. */ swap = sun4i_frontend_format_chroma_requires_swap(fb->format->format); |