From 7d62237da6ec072292c2f738ebffbf10f6a101cf Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Jan 2019 11:14:21 +0000 Subject: [PATCH] drm/armada: move plane address and pitch calculation to atomic_check Move the plane address and pitch calculations to atomic_check rather than the update function, so we don't have to probe the interlace setting for the CRTC while updating the plane. Signed-off-by: Russell King --- drivers/gpu/drm/armada/armada_overlay.c | 23 +++++++++---------- drivers/gpu/drm/armada/armada_plane.c | 30 +++++++++---------------- drivers/gpu/drm/armada/armada_plane.h | 5 +++++ 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index d8d6e4645c1f..a79d6e940435 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -109,27 +109,24 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane, old_state->fb != state->fb || state->crtc->state->mode_changed) { const struct drm_format_info *format; - u16 src_x, pitches[3]; - u32 addrs[2][3]; + u16 src_x; - armada_drm_plane_calc(state, addrs, pitches, dcrtc->interlaced); - - armada_reg_queue_set(regs, idx, addrs[0][0], + armada_reg_queue_set(regs, idx, armada_addr(state, 0, 0), LCD_SPU_DMA_START_ADDR_Y0); - armada_reg_queue_set(regs, idx, addrs[0][1], + armada_reg_queue_set(regs, idx, armada_addr(state, 0, 1), LCD_SPU_DMA_START_ADDR_U0); - armada_reg_queue_set(regs, idx, addrs[0][2], + armada_reg_queue_set(regs, idx, armada_addr(state, 0, 2), LCD_SPU_DMA_START_ADDR_V0); - armada_reg_queue_set(regs, idx, addrs[1][0], + armada_reg_queue_set(regs, idx, armada_addr(state, 1, 0), LCD_SPU_DMA_START_ADDR_Y1); - armada_reg_queue_set(regs, idx, addrs[1][1], + armada_reg_queue_set(regs, idx, armada_addr(state, 1, 1), LCD_SPU_DMA_START_ADDR_U1); - armada_reg_queue_set(regs, idx, addrs[1][2], + armada_reg_queue_set(regs, idx, armada_addr(state, 1, 2), LCD_SPU_DMA_START_ADDR_V1); - val = pitches[0] << 16 | pitches[0]; + val = armada_pitch(state, 0) << 16 | armada_pitch(state, 0); armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_YC); - val = pitches[1] << 16 | pitches[2]; + val = armada_pitch(state, 1) << 16 | armada_pitch(state, 2); armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_UV); cfg = CFG_DMA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) | @@ -147,7 +144,7 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane, src_x = state->src.x1 >> 16; if (format->num_planes == 1 && src_x & (format->hsub - 1)) cfg ^= CFG_DMA_MOD(CFG_SWAPUV); - if (dcrtc->interlaced) + if (to_armada_plane_state(state)->interlace) cfg |= CFG_DMA_FTOGGLE; cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV | diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c index 09218c1d8a4b..45092fc3598e 100644 --- a/drivers/gpu/drm/armada/armada_plane.c +++ b/drivers/gpu/drm/armada/armada_plane.c @@ -79,23 +79,6 @@ void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3], } } -static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state, - struct armada_regs *regs, bool interlaced) -{ - u16 pitches[3]; - u32 addrs[2][3]; - unsigned i = 0; - - armada_drm_plane_calc(state, addrs, pitches, interlaced); - - /* write offset, base, and pitch */ - armada_reg_queue_set(regs, i, addrs[0][0], LCD_CFG_GRA_START_ADDR0); - armada_reg_queue_set(regs, i, addrs[1][0], LCD_CFG_GRA_START_ADDR1); - armada_reg_queue_mod(regs, i, pitches[0], 0xffff, LCD_CFG_GRA_PITCH); - - return i; -} - int armada_drm_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) { @@ -167,6 +150,9 @@ int armada_drm_plane_atomic_check(struct drm_plane *plane, st->dst_hw <<= 16; st->dst_hw |= drm_rect_width(&state->dst) & 0x0000ffff; + armada_drm_plane_calc(state, st->addrs, st->pitches, interlace); + st->interlace = interlace; + return 0; } @@ -213,8 +199,12 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, old_state->src.y1 != state->src.y1 || old_state->fb != state->fb || state->crtc->state->mode_changed) { - idx += armada_drm_crtc_calc_fb(state, regs + idx, - dcrtc->interlaced); + armada_reg_queue_set(regs, idx, armada_addr(state, 0, 0), + LCD_CFG_GRA_START_ADDR0); + armada_reg_queue_set(regs, idx, armada_addr(state, 1, 0), + LCD_CFG_GRA_START_ADDR1); + armada_reg_queue_mod(regs, idx, armada_pitch(state, 0), 0xffff, + LCD_CFG_GRA_PITCH); } if (old_state->fb != state->fb || state->crtc->state->mode_changed) { @@ -224,7 +214,7 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, cfg |= CFG_PALETTE_ENA; if (state->visible) cfg |= CFG_GRA_ENA; - if (dcrtc->interlaced) + if (to_armada_plane_state(state)->interlace) cfg |= CFG_GRA_FTOGGLE; cfg_mask = CFG_GRAFORMAT | CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h index 396c45a4ea5e..2707ec781941 100644 --- a/drivers/gpu/drm/armada/armada_plane.h +++ b/drivers/gpu/drm/armada/armada_plane.h @@ -6,6 +6,9 @@ struct armada_plane_state { u32 src_hw; u32 dst_yx; u32 dst_hw; + u32 addrs[2][3]; + u16 pitches[3]; + bool interlace; }; #define to_armada_plane_state(st) \ @@ -13,6 +16,8 @@ struct armada_plane_state { #define armada_src_hw(state) to_armada_plane_state(state)->src_hw #define armada_dst_yx(state) to_armada_plane_state(state)->dst_yx #define armada_dst_hw(state) to_armada_plane_state(state)->dst_hw +#define armada_addr(state, f, p) to_armada_plane_state(state)->addrs[f][p] +#define armada_pitch(state, n) to_armada_plane_state(state)->pitches[n] void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3], u16 pitches[3], bool interlaced);