From 06ec41909e31be3347f8679e9667d12ac6f7ee6e Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Thu, 23 Mar 2017 13:14:54 -0700 Subject: drm/vmwgfx: Add and connect CRTC helper functions Atomic mode set requires us to refactor existing vmw_stdu_crtc_set_config code into sections that check the validity of the new mode, and sections that actually program the hardware state. vmw_du_crtc_atomic_check() takes CRTC-related checking code. In a later patch, vmw_du_primary_plane_atomic_check() will take framebuffer-related checking code. These helpers won't be called until we flip on the atomic support flag or set drm_crtc_funcs->set_config to using the atomic helper. v2: * The state->num_connector is actually the total number of potential connectors, not just the one associated with the display unit. The proper one to check is ->connector_mask. * Add the check to only allow plane state to be the same as crtc state (Thanks to mlankhorst) * Make sure to turn on SVGA mode before using VRAM. SVGA mode is disabled in master_drop if dbdev is not running. v3: * Moved dot clock override to crtc_atomic_check Signed-off-by: Sinclair Yeh Signed-off-by: Thomas Hellstrom Reviewed-by: Thomas Hellstrom Acked-by: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 36d42f5656b4..662024c9f351 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -250,6 +250,109 @@ static int vmw_sou_backing_alloc(struct vmw_private *dev_priv, return ret; } +/** + * vmw_sou_crtc_mode_set_nofb - Create new screen + * + * @crtc: CRTC associated with the new screen + * + * This function creates/destroys a screen. This function cannot fail, so if + * somehow we run into a failure, just do the best we can to get out. + */ +static void vmw_sou_crtc_mode_set_nofb(struct drm_crtc *crtc) +{ + struct vmw_private *dev_priv; + struct vmw_screen_object_unit *sou; + struct vmw_framebuffer *vfb; + struct drm_framebuffer *fb; + struct drm_plane_state *ps; + struct vmw_plane_state *vps; + int ret; + + + sou = vmw_crtc_to_sou(crtc); + dev_priv = vmw_priv(crtc->dev); + ps = crtc->primary->state; + fb = ps->fb; + vps = vmw_plane_state_to_vps(ps); + + vfb = (fb) ? vmw_framebuffer_to_vfb(fb) : NULL; + + if (sou->defined) { + ret = vmw_sou_fifo_destroy(dev_priv, sou); + if (ret) { + DRM_ERROR("Failed to destroy Screen Object\n"); + return; + } + } + + if (vfb) { + sou->buffer = vps->dmabuf; + sou->buffer_size = vps->dmabuf_size; + + ret = vmw_sou_fifo_create(dev_priv, sou, crtc->x, crtc->y, + &crtc->mode); + if (ret) + DRM_ERROR("Failed to define Screen Object %dx%d\n", + crtc->x, crtc->y); + + vmw_kms_add_active(dev_priv, &sou->base, vfb); + } else { + sou->buffer = NULL; + sou->buffer_size = 0; + + vmw_kms_del_active(dev_priv, &sou->base); + } +} + +/** + * vmw_sou_crtc_helper_prepare - Noop + * + * @crtc: CRTC associated with the new screen + * + * Prepares the CRTC for a mode set, but we don't need to do anything here. + */ +static void vmw_sou_crtc_helper_prepare(struct drm_crtc *crtc) +{ +} + +/** + * vmw_sou_crtc_helper_commit - Noop + * + * @crtc: CRTC associated with the new screen + * + * This is called after a mode set has been completed. + */ +static void vmw_sou_crtc_helper_commit(struct drm_crtc *crtc) +{ +} + +/** + * vmw_sou_crtc_helper_disable - Turns off CRTC + * + * @crtc: CRTC to be turned off + */ +static void vmw_sou_crtc_helper_disable(struct drm_crtc *crtc) +{ + struct vmw_private *dev_priv; + struct vmw_screen_object_unit *sou; + int ret; + + + if (!crtc) { + DRM_ERROR("CRTC is NULL\n"); + return; + } + + sou = vmw_crtc_to_sou(crtc); + dev_priv = vmw_priv(crtc->dev); + + if (sou->defined) { + ret = vmw_sou_fifo_destroy(dev_priv, sou); + if (ret) + DRM_ERROR("Failed to destroy Screen Object\n"); + } +} + static int vmw_sou_crtc_set_config(struct drm_mode_set *set) { struct vmw_private *dev_priv; @@ -527,6 +630,20 @@ static const struct drm_plane_funcs vmw_sou_cursor_funcs = { .atomic_destroy_state = vmw_du_plane_destroy_state, }; +/* + * Atomic Helpers + */ +static const struct drm_crtc_helper_funcs vmw_sou_crtc_helper_funcs = { + .prepare = vmw_sou_crtc_helper_prepare, + .commit = vmw_sou_crtc_helper_commit, + .disable = vmw_sou_crtc_helper_disable, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_nofb = vmw_sou_crtc_mode_set_nofb, + .atomic_check = vmw_du_crtc_atomic_check, + .atomic_begin = vmw_du_crtc_atomic_begin, + .atomic_flush = vmw_du_crtc_atomic_flush, +}; + static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) { @@ -626,6 +743,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) goto err_free_unregister; } + drm_crtc_helper_add(crtc, &vmw_sou_crtc_helper_funcs); + drm_mode_crtc_set_gamma_size(crtc, 256); drm_object_attach_property(&connector->base, -- cgit v1.2.3