@@ -76,6 +76,11 @@ struct vmw_kms_sou_dirty_cmd {
SVGA3dCmdBlitSurfaceToScreen body;
};
+struct vmw_kms_sou_define_gmrfb {
+ uint32_t header;
+ SVGAFifoCmdDefineGMRFB body;
+};
+
/**
* Display unit using screen objects.
*/
@@ -499,6 +504,135 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
return vmw_bo_pin_in_vram(dev_priv, vps->bo, true);
}
+static int vmw_sou_bo_prepare(struct vmw_du_update_plane *update)
+{
+ struct vmw_du_update_plane_buffer *bo_update;
+ struct vmw_framebuffer_bo *vfbbo;
+
+ bo_update = container_of(update, typeof(*bo_update), base);
+ vfbbo = container_of(update->vfb, typeof(*vfbbo), base);
+
+ return vmw_kms_helper_buffer_prepare(update->dev_priv, vfbbo->buffer,
+ true, false, bo_update->cpu_blit);
+}
+
+static uint32_t vmw_sou_bo_fifo_size(struct vmw_du_update_plane *update,
+ uint32_t num_hits)
+{
+ return sizeof(struct vmw_kms_sou_define_gmrfb) +
+ sizeof(struct vmw_kms_sou_bo_blit) * num_hits;
+}
+
+static uint32_t vmw_sou_bo_define_gmrfb(struct vmw_du_update_plane *update,
+ void *cmd)
+{
+ struct vmw_framebuffer_bo *vfbbo =
+ container_of(update->vfb, typeof(*vfbbo), base);
+ struct vmw_kms_sou_define_gmrfb *gmr = cmd;
+ int depth = update->vfb->base.format->depth;
+
+ /* Emulate RGBA support, contrary to svga_reg.h this is not
+ * supported by hosts. This is only a problem if we are reading
+ * this value later and expecting what we uploaded back.
+ */
+ if (depth == 32)
+ depth = 24;
+
+ gmr->header = SVGA_CMD_DEFINE_GMRFB;
+
+ gmr->body.format.bitsPerPixel = update->vfb->base.format->cpp[0] * 8;
+ gmr->body.format.colorDepth = depth;
+ gmr->body.format.reserved = 0;
+ gmr->body.bytesPerLine = update->vfb->base.pitches[0];
+ vmw_bo_get_guest_ptr(&vfbbo->buffer->base, &gmr->body.ptr);
+
+ return sizeof(*gmr);
+}
+
+static uint32_t vmw_sou_bo_populate_clip(struct vmw_du_update_plane *update,
+ void *cmd, struct drm_rect *clip,
+ uint32_t fb_x, uint32_t fb_y)
+{
+ struct vmw_kms_sou_bo_blit *blit = cmd;
+
+ blit->header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN;
+ blit->body.destScreenId = update->du->unit;
+ blit->body.srcOrigin.x = fb_x;
+ blit->body.srcOrigin.y = fb_y;
+ blit->body.destRect.left = clip->x1;
+ blit->body.destRect.top = clip->y1;
+ blit->body.destRect.right = clip->x2;
+ blit->body.destRect.bottom = clip->y2;
+
+ return sizeof(*blit);
+}
+
+static uint32_t vmw_stud_bo_post_clip(struct vmw_du_update_plane *update,
+ void *cmd, struct drm_rect *bb)
+{
+ return 0;
+}
+
+static void vmw_sou_bo_finish(struct vmw_du_update_plane *update)
+{
+ struct vmw_framebuffer_bo *vfbbo =
+ container_of(update->vfb, typeof(*vfbbo), base);
+
+ vmw_kms_helper_buffer_finish(update->dev_priv, NULL, vfbbo->buffer,
+ update->out_fence, NULL);
+}
+
+static void vmw_sou_bo_revert(struct vmw_du_update_plane *update)
+{
+ struct vmw_framebuffer_bo *vfbbo =
+ container_of(update->vfb, typeof(*vfbbo), base);
+
+ vmw_kms_helper_buffer_revert(vfbbo->buffer);
+}
+
+/**
+ * vmw_sou_plane_update_bo - update display unit for bo backed fb
+ * @dev_priv: device private
+ * @plane: plane state
+ * @old_state: old plane state
+ * @vfb: framebuffer which is blitted to display unit
+ * @out_fence: (optional) If non-NULL, will return a ref-counted pointer to a
+ * struct vmw_fence_obj. The returned fence pointer may be NULL in which case
+ * the device has already synchronized.
+ *
+ * RETURNS:
+ *
+ * 0 on success or a negative error code on failure.
+ */
+static int vmw_sou_plane_update_bo(struct vmw_private *dev_priv,
+ struct drm_plane *plane,
+ struct drm_plane_state *old_state,
+ struct vmw_framebuffer *vfb,
+ struct vmw_fence_obj **out_fence)
+{
+ struct vmw_du_update_plane_buffer bo_update;
+
+ memset(&bo_update, 0, sizeof(struct vmw_du_update_plane_buffer));
+ bo_update.base.plane = plane;
+ bo_update.base.old_state = old_state;
+ bo_update.base.dev_priv = dev_priv;
+ bo_update.base.du = vmw_crtc_to_du(plane->state->crtc);
+ bo_update.base.vfb = vfb;
+ bo_update.base.out_fence = out_fence;
+
+ bo_update.cpu_blit = false;
+
+ bo_update.base.prepare = vmw_sou_bo_prepare;
+ bo_update.base.calc_fifo_size = vmw_sou_bo_fifo_size;
+ bo_update.base.post_prepare = vmw_sou_bo_define_gmrfb;
+ bo_update.base.clip = vmw_sou_bo_populate_clip;
+ bo_update.base.post_clip = vmw_stud_bo_post_clip;
+ bo_update.base.finish = vmw_sou_bo_finish;
+ bo_update.base.revert = vmw_sou_bo_revert;
+
+ return vmw_du_helper_plane_update(&bo_update.base);
+}
+
static int vmw_sou_surface_prepare(struct vmw_du_update_plane *update)
{
struct vmw_du_update_plane_surface *srf_update;
Using the new interface implement SOU plane update for BO backed fb. Signed-off-by: Deepak Rawat <drawat@vmware.com> --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 134 +++++++++++++++++++++++++++ 1 file changed, 134 insertions(+)