diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 13:52:34 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 13:52:34 +0300 |
commit | d40af7b1ae23da718ba916fcd07f5b064efff921 (patch) | |
tree | fa4c494a51f12550bcd22ab87857dd1a5bb69b2a /drivers/gpu/drm/armada/armada_crtc.c | |
parent | 3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c (diff) | |
download | linux-d40af7b1ae23da718ba916fcd07f5b064efff921.tar.xz |
drm/armada: move primary plane to separate file
Split out the primary plane support; this is now entirely separate from
the CRTC support.
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 | 273 |
1 files changed, 2 insertions, 271 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 14339d5bed14..b9b0a508793d 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -20,6 +20,7 @@ #include "armada_fb.h" #include "armada_gem.h" #include "armada_hw.h" +#include "armada_plane.h" #include "armada_trace.h" enum csc_mode { @@ -30,23 +31,6 @@ enum csc_mode { CSC_RGB_STUDIO = 2, }; -static const uint32_t armada_primary_formats[] = { - DRM_FORMAT_UYVY, - DRM_FORMAT_YUYV, - DRM_FORMAT_VYUY, - DRM_FORMAT_YVYU, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_XRGB8888, - DRM_FORMAT_XBGR8888, - DRM_FORMAT_RGB888, - DRM_FORMAT_BGR888, - DRM_FORMAT_ARGB1555, - DRM_FORMAT_ABGR1555, - DRM_FORMAT_RGB565, - DRM_FORMAT_BGR565, -}; - /* * A note about interlacing. Let's consider HDMI 1920x1080i. * The timing parameters we have from X are: @@ -160,57 +144,6 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc) } } -void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, - int x, int y) -{ - const struct drm_format_info *format = fb->format; - unsigned int num_planes = format->num_planes; - u32 addr = drm_fb_obj(fb)->dev_addr; - int i; - - if (num_planes > 3) - num_planes = 3; - - addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] + - x * format->cpp[0]; - - y /= format->vsub; - x /= format->hsub; - - for (i = 1; i < num_planes; i++) - addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + - x * format->cpp[i]; - for (; i < 3; i++) - addrs[i] = 0; -} - -static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, - int x, int y, struct armada_regs *regs, bool interlaced) -{ - unsigned pitch = fb->pitches[0]; - u32 addrs[3], addr_odd, addr_even; - unsigned i = 0; - - DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", - pitch, x, y, fb->format->cpp[0] * 8); - - armada_drm_plane_calc_addrs(addrs, fb, x, y); - - addr_odd = addr_even = addrs[0]; - - if (interlaced) { - addr_even += pitch; - pitch *= 2; - } - - /* write offset, base, and pitch */ - armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0); - armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1); - armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH); - - return i; -} - static void armada_drm_plane_work_call(struct armada_crtc *dcrtc, struct armada_plane_work *work, void (*fn)(struct armada_crtc *, struct armada_plane_work *)) @@ -1067,194 +1000,6 @@ static const struct drm_crtc_funcs armada_crtc_funcs = { .disable_vblank = armada_drm_crtc_disable_vblank, }; -int armada_drm_plane_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *state) -{ - DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", - plane->base.id, plane->name, - state->fb ? state->fb->base.id : 0); - - /* - * Take a reference on the new framebuffer - we want to - * hold on to it while the hardware is displaying it. - */ - if (state->fb) - drm_framebuffer_get(state->fb); - return 0; -} - -void armada_drm_plane_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", - plane->base.id, plane->name, - old_state->fb ? old_state->fb->base.id : 0); - - if (old_state->fb) - drm_framebuffer_put(old_state->fb); -} - -int armada_drm_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) -{ - if (state->fb && !WARN_ON(!state->crtc)) { - struct drm_crtc *crtc = state->crtc; - struct drm_crtc_state *crtc_state; - - if (state->state) - crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); - else - crtc_state = crtc->state; - return drm_atomic_helper_check_plane_state(state, crtc_state, - 0, INT_MAX, - true, false); - } else { - state->visible = false; - } - return 0; -} - -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); - - if (!state->fb || WARN_ON(!state->crtc)) - return; - - DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n", - plane->base.id, plane->name, - state->crtc->base.id, state->crtc->name, - state->fb->base.id, - old_state->visible, state->visible); - - dcrtc = drm_to_armada_crtc(state->crtc); - regs = dcrtc->regs + dcrtc->regs_idx; - - 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_crtc *dcrtc; - struct armada_regs *regs; - unsigned int idx = 0; - - DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); - - if (!old_state->crtc) - return; - - DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n", - plane->base.id, plane->name, - old_state->crtc->base.id, old_state->crtc->name, - old_state->fb->base.id); - - dcrtc = drm_to_armada_crtc(old_state->crtc); - regs = dcrtc->regs + dcrtc->regs_idx; - - /* Disable plane and power down most RAMs and FIFOs */ - armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0); - armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 | - CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66, - 0, LCD_SPU_SRAM_PARA1); - - dcrtc->regs_idx += idx; -} - -static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = { - .prepare_fb = armada_drm_plane_prepare_fb, - .cleanup_fb = armada_drm_plane_cleanup_fb, - .atomic_check = armada_drm_plane_atomic_check, - .atomic_update = armada_drm_primary_plane_atomic_update, - .atomic_disable = armada_drm_primary_plane_atomic_disable, -}; - -static const struct drm_plane_funcs armada_primary_plane_funcs = { - .update_plane = drm_plane_helper_update, - .disable_plane = drm_plane_helper_disable, - .destroy = drm_primary_helper_destroy, - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, -}; - -int armada_drm_plane_init(struct armada_plane *plane) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(plane->works); i++) - plane->works[i].plane = &plane->base; - - init_waitqueue_head(&plane->frame_wait); - - return 0; -} - static const struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = { { CSC_AUTO, "Auto" }, { CSC_YUV_CCIR601, "CCIR601" }, @@ -1363,21 +1108,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, goto err_crtc; } - ret = armada_drm_plane_init(primary); - if (ret) { - kfree(primary); - goto err_crtc; - } - - drm_plane_helper_add(&primary->base, - &armada_primary_plane_helper_funcs); - - ret = drm_universal_plane_init(drm, &primary->base, 0, - &armada_primary_plane_funcs, - armada_primary_formats, - ARRAY_SIZE(armada_primary_formats), - NULL, - DRM_PLANE_TYPE_PRIMARY, NULL); + ret = armada_drm_primary_plane_init(drm, primary); if (ret) { kfree(primary); goto err_crtc; |