diff options
author | Sinclair Yeh <syeh@vmware.com> | 2017-03-23 21:14:54 +0100 |
---|---|---|
committer | Sinclair Yeh <syeh@vmware.com> | 2017-03-31 22:36:11 +0200 |
commit | 06ec41909e31be3347f8679e9667d12ac6f7ee6e (patch) | |
tree | 8e38f19c07d6ae63aafb371a0d02479582d8f57e /drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |
parent | drm/vmwgfx: Connector atomic state (diff) | |
download | linux-06ec41909e31be3347f8679e9667d12ac6f7ee6e.tar.xz linux-06ec41909e31be3347f8679e9667d12ac6f7ee6e.zip |
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 <syeh@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Acked-by: Daniel Vetter <daniel@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 119 |
1 files changed, 119 insertions, 0 deletions
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, |