diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c9f5ddabfb72..18bd8dc46507 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -26,6 +26,8 @@ **************************************************************************/ #include "vmwgfx_kms.h" +#include +#include /* Might need a hrtimer here? */ @@ -388,6 +390,84 @@ void vmw_du_primary_plane_destroy(struct drm_plane *plane) } +/** + * vmw_du_crtc_duplicate_state - duplicate crtc state + * @crtc: DRM crtc + * + * Allocates and returns a copy of the crtc state (both common and + * vmw-specific) for the specified crtc. + * + * Returns: The newly allocated crtc state, or NULL on failure. + */ +struct drm_crtc_state * +vmw_du_crtc_duplicate_state(struct drm_crtc *crtc) +{ + struct drm_crtc_state *state; + struct vmw_crtc_state *vcs; + + if (WARN_ON(!crtc->state)) + return NULL; + + vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL); + + if (!vcs) + return NULL; + + state = &vcs->base; + + __drm_atomic_helper_crtc_duplicate_state(crtc, state); + + return state; +} + + +/** + * vmw_du_crtc_reset - creates a blank vmw crtc state + * @crtc: DRM crtc + * + * Resets the atomic state for @crtc by freeing the state pointer (which + * might be NULL, e.g. at driver load time) and allocating a new empty state + * object. + */ +void vmw_du_crtc_reset(struct drm_crtc *crtc) +{ + struct vmw_crtc_state *vcs; + + + if (crtc->state) { + __drm_atomic_helper_crtc_destroy_state(crtc->state); + + kfree(vmw_crtc_state_to_vcs(crtc->state)); + } + + vcs = kzalloc(sizeof(*vcs), GFP_KERNEL); + + if (!vcs) { + DRM_ERROR("Cannot allocate vmw_crtc_state\n"); + return; + } + + crtc->state = &vcs->base; + crtc->state->crtc = crtc; +} + + +/** + * vmw_du_crtc_destroy_state - destroy crtc state + * @crtc: DRM crtc + * @state: state object to destroy + * + * Destroys the crtc state (both common and vmw-specific) for the + * specified plane. + */ +void +vmw_du_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + drm_atomic_helper_crtc_destroy_state(crtc, state); +} + + /* * Generic framebuffer code */ @@ -1600,6 +1680,7 @@ int vmw_du_connector_set_property(struct drm_connector *connector, } + int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index e400bfb26167..370f75c95f56 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -139,6 +139,19 @@ static const uint32_t vmw_cursor_plane_formats[] = { DRM_FORMAT_ARGB8888, }; + +#define vmw_crtc_state_to_vcs(x) container_of(x, struct vmw_crtc_state, base) + + +/** + * Derived class for crtc state object + * + * @base DRM crtc object + */ +struct vmw_crtc_state { + struct drm_crtc_state base; +}; + /** * Base class display unit. * @@ -205,6 +218,9 @@ int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y); int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); +int vmw_du_connector_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t val); int vmw_du_connector_dpms(struct drm_connector *connector, int mode); void vmw_du_connector_save(struct drm_connector *connector); void vmw_du_connector_restore(struct drm_connector *connector); @@ -212,9 +228,6 @@ enum drm_connector_status vmw_du_connector_detect(struct drm_connector *connector, bool force); int vmw_du_connector_fill_modes(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); -int vmw_du_connector_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val); int vmw_kms_helper_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer *framebuffer, const struct drm_clip_rect *clips, @@ -285,6 +298,10 @@ int vmw_du_cursor_plane_update(struct drm_plane *plane, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h); +void vmw_du_crtc_reset(struct drm_crtc *crtc); +struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc); +void vmw_du_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state); /* * Legacy display unit functions - vmwgfx_ldu.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 3efcbe514472..3ee33f0234e4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -280,6 +280,9 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { .gamma_set = vmw_du_crtc_gamma_set, .destroy = vmw_ldu_crtc_destroy, + .reset = vmw_du_crtc_reset, + .atomic_duplicate_state = vmw_du_crtc_duplicate_state, + .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = vmw_ldu_crtc_set_config, }; @@ -355,6 +358,11 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ldu->base.pref_width = dev_priv->initial_width; ldu->base.pref_height = dev_priv->initial_height; ldu->base.pref_mode = NULL; + + /* + * Remove this after enabling atomic because property values can + * only exist in a state object + */ ldu->base.is_implicit = true; /* Initialize primary plane */ @@ -405,6 +413,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) goto err_free_encoder; } + /* FIXME: Turn on after plane/connector states are implemented. */ + /* vmw_du_crtc_reset(crtc); */ ret = drm_crtc_init_with_planes(dev, crtc, &ldu->base.primary, &ldu->base.cursor, &vmw_legacy_crtc_funcs, NULL); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 8ffccb87cf3a..033e17b966b1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -461,6 +461,9 @@ out_no_fence: static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { .gamma_set = vmw_du_crtc_gamma_set, .destroy = vmw_sou_crtc_destroy, + .reset = vmw_du_crtc_reset, + .atomic_duplicate_state = vmw_du_crtc_duplicate_state, + .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = vmw_sou_crtc_set_config, .page_flip = vmw_sou_crtc_page_flip, }; @@ -535,6 +538,11 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) sou->base.pref_width = dev_priv->initial_width; sou->base.pref_height = dev_priv->initial_height; sou->base.pref_mode = NULL; + + /* + * Remove this after enabling atomic because property values can + * only exist in a state object + */ sou->base.is_implicit = false; /* Initialize primary plane */ @@ -586,6 +594,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) goto err_free_encoder; } + /* FIXME: Turn on after plane/connector states are implemented. */ + /* vmw_du_crtc_reset(crtc); */ ret = drm_crtc_init_with_planes(dev, crtc, &sou->base.primary, &sou->base.cursor, &vmw_screen_object_crtc_funcs, NULL); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 4d9dd1b67b93..3b8fafe1586e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -1017,6 +1017,9 @@ out_finish: static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = { .gamma_set = vmw_du_crtc_gamma_set, .destroy = vmw_stdu_crtc_destroy, + .reset = vmw_du_crtc_reset, + .atomic_duplicate_state = vmw_du_crtc_duplicate_state, + .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = vmw_stdu_crtc_set_config, .page_flip = vmw_stdu_crtc_page_flip, }; @@ -1131,6 +1134,11 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) stdu->base.pref_active = (unit == 0); stdu->base.pref_width = dev_priv->initial_width; stdu->base.pref_height = dev_priv->initial_height; + + /* + * Remove this after enabling atomic because property values can + * only exist in a state object + */ stdu->base.is_implicit = false; /* Initialize primary plane */ @@ -1181,6 +1189,8 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) goto err_free_encoder; } + /* FIXME: Turn on after plane/connector states are implemented. */ + /* vmw_du_crtc_reset(crtc); */ ret = drm_crtc_init_with_planes(dev, crtc, &stdu->base.primary, &stdu->base.cursor, &vmw_stdu_crtc_funcs, NULL);