1 /* 2 * Copyright (C) 2015 Red Hat, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include "virtgpu_drv.h" 27 #include <drm/drm_plane_helper.h> 28 #include <drm/drm_atomic_helper.h> 29 30 static const uint32_t virtio_gpu_formats[] = { 31 DRM_FORMAT_XRGB8888, 32 DRM_FORMAT_ARGB8888, 33 DRM_FORMAT_BGRX8888, 34 DRM_FORMAT_BGRA8888, 35 DRM_FORMAT_RGBX8888, 36 DRM_FORMAT_RGBA8888, 37 DRM_FORMAT_XBGR8888, 38 DRM_FORMAT_ABGR8888, 39 }; 40 41 static void virtio_gpu_plane_destroy(struct drm_plane *plane) 42 { 43 kfree(plane); 44 } 45 46 static const struct drm_plane_funcs virtio_gpu_plane_funcs = { 47 .update_plane = drm_atomic_helper_update_plane, 48 .disable_plane = drm_atomic_helper_disable_plane, 49 .destroy = virtio_gpu_plane_destroy, 50 .reset = drm_atomic_helper_plane_reset, 51 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 52 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 53 }; 54 55 static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, 56 struct drm_plane_state *state) 57 { 58 return 0; 59 } 60 61 static void virtio_gpu_plane_atomic_update(struct drm_plane *plane, 62 struct drm_plane_state *old_state) 63 { 64 struct drm_device *dev = plane->dev; 65 struct virtio_gpu_device *vgdev = dev->dev_private; 66 struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(plane->crtc); 67 struct virtio_gpu_framebuffer *vgfb; 68 struct virtio_gpu_object *bo; 69 uint32_t handle; 70 71 if (plane->state->fb) { 72 vgfb = to_virtio_gpu_framebuffer(plane->state->fb); 73 bo = gem_to_virtio_gpu_obj(vgfb->obj); 74 handle = bo->hw_res_handle; 75 if (bo->dumb) { 76 virtio_gpu_cmd_transfer_to_host_2d 77 (vgdev, handle, 0, 78 cpu_to_le32(plane->state->crtc_w), 79 cpu_to_le32(plane->state->crtc_h), 80 plane->state->crtc_x, plane->state->crtc_y, NULL); 81 } 82 } else { 83 handle = 0; 84 } 85 86 DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d\n", handle, 87 plane->state->crtc_w, plane->state->crtc_h, 88 plane->state->crtc_x, plane->state->crtc_y); 89 virtio_gpu_cmd_set_scanout(vgdev, output->index, handle, 90 plane->state->crtc_w, 91 plane->state->crtc_h, 92 plane->state->crtc_x, 93 plane->state->crtc_y); 94 virtio_gpu_cmd_resource_flush(vgdev, handle, 95 plane->state->crtc_x, 96 plane->state->crtc_y, 97 plane->state->crtc_w, 98 plane->state->crtc_h); 99 } 100 101 102 static const struct drm_plane_helper_funcs virtio_gpu_plane_helper_funcs = { 103 .atomic_check = virtio_gpu_plane_atomic_check, 104 .atomic_update = virtio_gpu_plane_atomic_update, 105 }; 106 107 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, 108 int index) 109 { 110 struct drm_device *dev = vgdev->ddev; 111 struct drm_plane *plane; 112 int ret; 113 114 plane = kzalloc(sizeof(*plane), GFP_KERNEL); 115 if (!plane) 116 return ERR_PTR(-ENOMEM); 117 118 ret = drm_universal_plane_init(dev, plane, 1 << index, 119 &virtio_gpu_plane_funcs, 120 virtio_gpu_formats, 121 ARRAY_SIZE(virtio_gpu_formats), 122 DRM_PLANE_TYPE_PRIMARY, NULL); 123 if (ret) 124 goto err_plane_init; 125 126 drm_plane_helper_add(plane, &virtio_gpu_plane_helper_funcs); 127 return plane; 128 129 err_plane_init: 130 kfree(plane); 131 return ERR_PTR(ret); 132 } 133