diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 11:52:34 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 11:52:34 +0100 |
commit | 3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c (patch) | |
tree | 79bb02ca5105290ee7a8f440fe34522b846403fe /drivers/gpu/drm/armada/armada_crtc.c | |
parent | 9c41467c9aa5b3916ff559b8c2b3725d6290e5ec (diff) | |
download | kernel_replicant_linux-3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c.tar.gz kernel_replicant_linux-3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c.tar.bz2 kernel_replicant_linux-3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c.zip |
drm/armada: use old_state for update tracking in atomic_update()
Rather than tracking the register state, we can now check the previous
state and decide which registers need updating from that since the old
plane state indicates the previous state which was programmed into the
hardware.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/gpu/drm/armada/armada_crtc.c')
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 116 |
1 files changed, 60 insertions, 56 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 056673911818..14339d5bed14 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -1114,64 +1114,14 @@ int armada_drm_plane_atomic_check(struct drm_plane *plane, return 0; } -static unsigned int armada_drm_primary_update_state( - struct drm_plane_state *state, struct armada_regs *regs) -{ - struct armada_plane *dplane = drm_to_armada_plane(state->plane); - struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc); - struct armada_framebuffer *dfb = drm_fb_to_armada_fb(state->fb); - bool was_disabled; - unsigned int idx = 0; - u32 val; - - val = CFG_GRA_FMT(dfb->fmt) | CFG_GRA_MOD(dfb->mod); - if (dfb->fmt > CFG_420) - val |= CFG_PALETTE_ENA; - if (state->visible) - val |= CFG_GRA_ENA; - if (drm_rect_width(&state->src) >> 16 != drm_rect_width(&state->dst)) - val |= CFG_GRA_HSMOOTH; - if (dcrtc->interlaced) - val |= CFG_GRA_FTOGGLE; - - was_disabled = !(dplane->state.ctrl0 & CFG_GRA_ENA); - if (was_disabled) - armada_reg_queue_mod(regs, idx, - 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1); - - dplane->state.ctrl0 = val; - dplane->state.src_hw = armada_rect_hw_fp(&state->src); - dplane->state.dst_hw = armada_rect_hw(&state->dst); - dplane->state.dst_yx = armada_rect_yx(&state->dst); - - idx += armada_drm_crtc_calc_fb(&dfb->fb, state->src.x1 >> 16, - state->src.y1 >> 16, regs + idx, - dcrtc->interlaced); - armada_reg_queue_set(regs, idx, dplane->state.dst_yx, - LCD_SPU_GRA_OVSA_HPXL_VLN); - armada_reg_queue_set(regs, idx, dplane->state.src_hw, - LCD_SPU_GRA_HPXL_VLN); - armada_reg_queue_set(regs, idx, dplane->state.dst_hw, - LCD_SPU_GZM_HPXL_VLN); - armada_reg_queue_mod(regs, idx, dplane->state.ctrl0, CFG_GRAFORMAT | - CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | - CFG_SWAPYU | CFG_YUV2RGB) | - CFG_PALETTE_ENA | CFG_GRA_FTOGGLE | - CFG_GRA_HSMOOTH | CFG_GRA_ENA, - LCD_SPU_DMA_CTRL0); - - dplane->state.vsync_update = !was_disabled; - dplane->state.changed = true; - - return idx; -} - static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_plane_state *state = plane->state; struct armada_crtc *dcrtc; struct armada_regs *regs; + u32 cfg, cfg_mask, val; + unsigned int idx; DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); @@ -1187,13 +1137,69 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, dcrtc = drm_to_armada_crtc(state->crtc); regs = dcrtc->regs + dcrtc->regs_idx; - dcrtc->regs_idx += armada_drm_primary_update_state(state, regs); + idx = 0; + if (!old_state->visible && state->visible) { + val = CFG_PDWN64x66; + if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) + val |= CFG_PDWN256x24; + armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1); + } + val = armada_rect_hw_fp(&state->src); + if (armada_rect_hw_fp(&old_state->src) != val) + armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN); + val = armada_rect_yx(&state->dst); + if (armada_rect_yx(&old_state->dst) != val) + armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN); + val = armada_rect_hw(&state->dst); + if (armada_rect_hw(&old_state->dst) != val) + armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN); + if (old_state->src.x1 != state->src.x1 || + old_state->src.y1 != state->src.y1 || + old_state->fb != state->fb) { + idx += armada_drm_crtc_calc_fb(state->fb, + state->src.x1 >> 16, + state->src.y1 >> 16, + regs + idx, + dcrtc->interlaced); + } + if (old_state->fb != state->fb) { + cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) | + CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod); + if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) + cfg |= CFG_PALETTE_ENA; + if (state->visible) + cfg |= CFG_GRA_ENA; + if (dcrtc->interlaced) + cfg |= CFG_GRA_FTOGGLE; + cfg_mask = CFG_GRAFORMAT | + CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | + CFG_SWAPYU | CFG_YUV2RGB) | + CFG_PALETTE_ENA | CFG_GRA_FTOGGLE | + CFG_GRA_ENA; + } else if (old_state->visible != state->visible) { + cfg = state->visible ? CFG_GRA_ENA : 0; + cfg_mask = CFG_GRA_ENA; + } else { + cfg = cfg_mask = 0; + } + if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) || + drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) { + cfg_mask |= CFG_GRA_HSMOOTH; + if (drm_rect_width(&state->src) >> 16 != + drm_rect_width(&state->dst)) + cfg |= CFG_GRA_HSMOOTH; + } + + if (cfg_mask) + armada_reg_queue_mod(regs, idx, cfg, cfg_mask, + LCD_SPU_DMA_CTRL0); + + dcrtc->regs_idx += idx; } static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct armada_plane *dplane = drm_to_armada_plane(plane); struct armada_crtc *dcrtc; struct armada_regs *regs; unsigned int idx = 0; @@ -1208,8 +1214,6 @@ static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane, old_state->crtc->base.id, old_state->crtc->name, old_state->fb->base.id); - dplane->state.ctrl0 &= ~CFG_GRA_ENA; - dcrtc = drm_to_armada_crtc(old_state->crtc); regs = dcrtc->regs + dcrtc->regs_idx; |