/** * Send stop command to hw. * * Returns * -ERESTARTSYS if interrupted by a signal. */ static int vmw_overlay_send_stop(struct vmw_private *dev_priv, uint32_t stream_id, bool interruptible) { struct { struct vmw_escape_header escape; SVGAEscapeVideoSetRegs body; struct vmw_escape_video_flush flush; } *cmds; int ret; for (;;) { cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); if (cmds) break; ret = vmw_fallback_wait(dev_priv, false, true, 0, interruptible, 3*HZ); if (interruptible && ret == -ERESTARTSYS) return ret; else BUG_ON(ret != 0); } fill_escape(&cmds->escape, sizeof(cmds->body)); cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS; cmds->body.header.streamId = stream_id; cmds->body.items[0].registerId = SVGA_VIDEO_ENABLED; cmds->body.items[0].value = false; fill_flush(&cmds->flush, stream_id); vmw_fifo_commit(dev_priv, sizeof(*cmds)); return 0; }
/** * Send put command to hw. * * Returns * -ERESTARTSYS if interrupted by a signal. */ static int vmw_overlay_send_put(struct vmw_private *dev_priv, struct vmw_dma_buffer *buf, struct drm_vmw_control_stream_arg *arg, bool interruptible) { struct vmw_escape_video_flush *flush; size_t fifo_size; bool have_so = dev_priv->sou_priv ? true : false; int i, num_items; SVGAGuestPtr ptr; struct { struct vmw_escape_header escape; struct { uint32_t cmdType; uint32_t streamId; } header; } *cmds; struct { uint32_t registerId; uint32_t value; } *items; /* defines are a index needs + 1 */ if (have_so) num_items = SVGA_VIDEO_DST_SCREEN_ID + 1; else num_items = SVGA_VIDEO_PITCH_3 + 1; fifo_size = sizeof(*cmds) + sizeof(*flush) + sizeof(*items) * num_items; cmds = vmw_fifo_reserve(dev_priv, fifo_size); /* hardware has hung, can't do anything here */ if (!cmds) return -ENOMEM; items = (typeof(items))&cmds[1]; flush = (struct vmw_escape_video_flush *)&items[num_items]; /* the size is header + number of items */ fill_escape(&cmds->escape, sizeof(*items) * (num_items + 1)); cmds->header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS; cmds->header.streamId = arg->stream_id; /* the IDs are neatly numbered */ for (i = 0; i < num_items; i++) items[i].registerId = i; vmw_bo_get_guest_ptr(&buf->base, &ptr); ptr.offset += arg->offset; items[SVGA_VIDEO_ENABLED].value = true; items[SVGA_VIDEO_FLAGS].value = arg->flags; items[SVGA_VIDEO_DATA_OFFSET].value = ptr.offset; items[SVGA_VIDEO_FORMAT].value = arg->format; items[SVGA_VIDEO_COLORKEY].value = arg->color_key; items[SVGA_VIDEO_SIZE].value = arg->size; items[SVGA_VIDEO_WIDTH].value = arg->width; items[SVGA_VIDEO_HEIGHT].value = arg->height; items[SVGA_VIDEO_SRC_X].value = arg->src.x; items[SVGA_VIDEO_SRC_Y].value = arg->src.y; items[SVGA_VIDEO_SRC_WIDTH].value = arg->src.w; items[SVGA_VIDEO_SRC_HEIGHT].value = arg->src.h; items[SVGA_VIDEO_DST_X].value = arg->dst.x; items[SVGA_VIDEO_DST_Y].value = arg->dst.y; items[SVGA_VIDEO_DST_WIDTH].value = arg->dst.w; items[SVGA_VIDEO_DST_HEIGHT].value = arg->dst.h; items[SVGA_VIDEO_PITCH_1].value = arg->pitch[0]; items[SVGA_VIDEO_PITCH_2].value = arg->pitch[1]; items[SVGA_VIDEO_PITCH_3].value = arg->pitch[2]; if (have_so) { items[SVGA_VIDEO_DATA_GMRID].value = ptr.gmrId; items[SVGA_VIDEO_DST_SCREEN_ID].value = SVGA_ID_INVALID; } fill_flush(flush, arg->stream_id); vmw_fifo_commit(dev_priv, fifo_size); return 0; }
/** * Send put command to hw. * * Returns * -ERESTARTSYS if interrupted by a signal. */ static int vmw_overlay_send_put(struct vmw_private *dev_priv, struct vmw_dma_buffer *buf, struct drm_vmw_control_stream_arg *arg, bool interruptible) { struct { struct vmw_escape_header escape; struct { struct { uint32_t cmdType; uint32_t streamId; } header; struct { uint32_t registerId; uint32_t value; } items[SVGA_VIDEO_PITCH_3 + 1]; } body; struct vmw_escape_video_flush flush; } *cmds; uint32_t offset; int i, ret; for (;;) { cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); if (cmds) break; ret = vmw_fallback_wait(dev_priv, false, true, 0, interruptible, 3*HZ); if (interruptible && ret == -ERESTARTSYS) return ret; else BUG_ON(ret != 0); } fill_escape(&cmds->escape, sizeof(cmds->body)); cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS; cmds->body.header.streamId = arg->stream_id; for (i = 0; i <= SVGA_VIDEO_PITCH_3; i++) cmds->body.items[i].registerId = i; offset = buf->base.offset + arg->offset; cmds->body.items[SVGA_VIDEO_ENABLED].value = true; cmds->body.items[SVGA_VIDEO_FLAGS].value = arg->flags; cmds->body.items[SVGA_VIDEO_DATA_OFFSET].value = offset; cmds->body.items[SVGA_VIDEO_FORMAT].value = arg->format; cmds->body.items[SVGA_VIDEO_COLORKEY].value = arg->color_key; cmds->body.items[SVGA_VIDEO_SIZE].value = arg->size; cmds->body.items[SVGA_VIDEO_WIDTH].value = arg->width; cmds->body.items[SVGA_VIDEO_HEIGHT].value = arg->height; cmds->body.items[SVGA_VIDEO_SRC_X].value = arg->src.x; cmds->body.items[SVGA_VIDEO_SRC_Y].value = arg->src.y; cmds->body.items[SVGA_VIDEO_SRC_WIDTH].value = arg->src.w; cmds->body.items[SVGA_VIDEO_SRC_HEIGHT].value = arg->src.h; cmds->body.items[SVGA_VIDEO_DST_X].value = arg->dst.x; cmds->body.items[SVGA_VIDEO_DST_Y].value = arg->dst.y; cmds->body.items[SVGA_VIDEO_DST_WIDTH].value = arg->dst.w; cmds->body.items[SVGA_VIDEO_DST_HEIGHT].value = arg->dst.h; cmds->body.items[SVGA_VIDEO_PITCH_1].value = arg->pitch[0]; cmds->body.items[SVGA_VIDEO_PITCH_2].value = arg->pitch[1]; cmds->body.items[SVGA_VIDEO_PITCH_3].value = arg->pitch[2]; fill_flush(&cmds->flush, arg->stream_id); vmw_fifo_commit(dev_priv, sizeof(*cmds)); return 0; }