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