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>
This commit is contained in:
Sinclair Yeh
2017-03-23 13:14:54 -07:00
parent d7721ca711
commit 06ec41909e
5 changed files with 379 additions and 0 deletions

View File

@@ -167,6 +167,7 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv,
if (vfb != ld->fb) {
if (ld->fb && ld->fb->unpin)
ld->fb->unpin(ld->fb);
vmw_svga_enable(vmw_priv);
if (vfb->pin)
vfb->pin(vfb);
ld->fb = vfb;
@@ -190,6 +191,68 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv,
return 0;
}
/**
* vmw_ldu_crtc_mode_set_nofb - Enable svga
*
* @crtc: CRTC associated with the new screen
*
* For LDU, just enable the svga
*/
static void vmw_ldu_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
}
/**
* vmw_ldu_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_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
{
}
/**
* vmw_ldu_crtc_helper_commit - Noop
*
* @crtc: CRTC associated with the new screen
*
* This is called after a mode set has been completed. Here's
* usually a good place to call vmw_ldu_add_active/vmw_ldu_del_active
* but since for LDU the display plane is closely tied to the
* CRTC, it makes more sense to do those at plane update time.
*/
static void vmw_ldu_crtc_helper_commit(struct drm_crtc *crtc)
{
struct vmw_private *dev_priv;
struct vmw_legacy_display_unit *ldu;
struct vmw_framebuffer *vfb;
struct drm_framebuffer *fb;
ldu = vmw_crtc_to_ldu(crtc);
dev_priv = vmw_priv(crtc->dev);
fb = crtc->primary->fb;
vfb = (fb) ? vmw_framebuffer_to_vfb(fb) : NULL;
if (vfb)
vmw_ldu_add_active(dev_priv, ldu, vfb);
else
vmw_ldu_del_active(dev_priv, ldu);
}
/**
* vmw_ldu_crtc_helper_disable - Turns off CRTC
*
* @crtc: CRTC to be turned off
*/
static void vmw_ldu_crtc_helper_disable(struct drm_crtc *crtc)
{
}
static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
{
struct vmw_private *dev_priv;
@@ -346,6 +409,20 @@ static const struct drm_plane_funcs vmw_ldu_cursor_funcs = {
.atomic_destroy_state = vmw_du_plane_destroy_state,
};
/*
* Atomic Helpers
*/
static const struct drm_crtc_helper_funcs vmw_ldu_crtc_helper_funcs = {
.prepare = vmw_ldu_crtc_helper_prepare,
.commit = vmw_ldu_crtc_helper_commit,
.disable = vmw_ldu_crtc_helper_disable,
.mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = vmw_ldu_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_ldu_init(struct vmw_private *dev_priv, unsigned unit)
{
@@ -445,6 +522,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
goto err_free_unregister;
}
drm_crtc_helper_add(crtc, &vmw_ldu_crtc_helper_funcs);
drm_mode_crtc_set_gamma_size(crtc, 256);
drm_object_attach_property(&connector->base,