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