1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
2 
3 /*
4  *  Xen para-virtual DRM device
5  *
6  * Copyright (C) 2016-2018 EPAM Systems Inc.
7  *
8  * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
9  */
10 
11 #ifndef __XEN_DRM_FRONT_H_
12 #define __XEN_DRM_FRONT_H_
13 
14 #include <linux/scatterlist.h>
15 
16 #include <drm/drm_connector.h>
17 #include <drm/drm_simple_kms_helper.h>
18 
19 #include "xen_drm_front_cfg.h"
20 
21 struct drm_device;
22 struct drm_framebuffer;
23 struct drm_gem_object;
24 struct drm_pending_vblank_event;
25 
26 /**
27  * DOC: Driver modes of operation in terms of display buffers used
28  *
29  * Depending on the requirements for the para-virtualized environment, namely
30  * requirements dictated by the accompanying DRM/(v)GPU drivers running in both
31  * host and guest environments, display buffers can be allocated by either
32  * frontend driver or backend.
33  */
34 
35 /**
36  * DOC: Buffers allocated by the frontend driver
37  *
38  * In this mode of operation driver allocates buffers from system memory.
39  *
40  * Note! If used with accompanying DRM/(v)GPU drivers this mode of operation
41  * may require IOMMU support on the platform, so accompanying DRM/vGPU
42  * hardware can still reach display buffer memory while importing PRIME
43  * buffers from the frontend driver.
44  */
45 
46 /**
47  * DOC: Buffers allocated by the backend
48  *
49  * This mode of operation is run-time configured via guest domain configuration
50  * through XenStore entries.
51  *
52  * For systems which do not provide IOMMU support, but having specific
53  * requirements for display buffers it is possible to allocate such buffers
54  * at backend side and share those with the frontend.
55  * For example, if host domain is 1:1 mapped and has DRM/GPU hardware expecting
56  * physically contiguous memory, this allows implementing zero-copying
57  * use-cases.
58  *
59  * Note, while using this scenario the following should be considered:
60  *
61  * #. If guest domain dies then pages/grants received from the backend
62  *    cannot be claimed back
63  *
64  * #. Misbehaving guest may send too many requests to the
65  *    backend exhausting its grant references and memory
66  *    (consider this from security POV)
67  */
68 
69 /**
70  * DOC: Driver limitations
71  *
72  * #. Only primary plane without additional properties is supported.
73  *
74  * #. Only one video mode per connector supported which is configured
75  *    via XenStore.
76  *
77  * #. All CRTCs operate at fixed frequency of 60Hz.
78  */
79 
80 /* timeout in ms to wait for backend to respond */
81 #define XEN_DRM_FRONT_WAIT_BACK_MS	3000
82 
83 #ifndef GRANT_INVALID_REF
84 /*
85  * Note on usage of grant reference 0 as invalid grant reference:
86  * grant reference 0 is valid, but never exposed to a PV driver,
87  * because of the fact it is already in use/reserved by the PV console.
88  */
89 #define GRANT_INVALID_REF	0
90 #endif
91 
92 struct xen_drm_front_info {
93 	struct xenbus_device *xb_dev;
94 	struct xen_drm_front_drm_info *drm_info;
95 
96 	/* to protect data between backend IO code and interrupt handler */
97 	spinlock_t io_lock;
98 
99 	int num_evt_pairs;
100 	struct xen_drm_front_evtchnl_pair *evt_pairs;
101 	struct xen_drm_front_cfg cfg;
102 
103 	/* display buffers */
104 	struct list_head dbuf_list;
105 };
106 
107 struct xen_drm_front_drm_pipeline {
108 	struct xen_drm_front_drm_info *drm_info;
109 
110 	int index;
111 
112 	struct drm_simple_display_pipe pipe;
113 
114 	struct drm_connector conn;
115 	/* These are only for connector mode checking */
116 	int width, height;
117 
118 	struct drm_pending_vblank_event *pending_event;
119 
120 	struct delayed_work pflip_to_worker;
121 
122 	bool conn_connected;
123 };
124 
125 struct xen_drm_front_drm_info {
126 	struct xen_drm_front_info *front_info;
127 	struct drm_device *drm_dev;
128 
129 	struct xen_drm_front_drm_pipeline pipeline[XEN_DRM_FRONT_MAX_CRTCS];
130 };
131 
132 static inline u64 xen_drm_front_fb_to_cookie(struct drm_framebuffer *fb)
133 {
134 	return (uintptr_t)fb;
135 }
136 
137 static inline u64 xen_drm_front_dbuf_to_cookie(struct drm_gem_object *gem_obj)
138 {
139 	return (uintptr_t)gem_obj;
140 }
141 
142 int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline,
143 			   u32 x, u32 y, u32 width, u32 height,
144 			   u32 bpp, u64 fb_cookie);
145 
146 int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info,
147 			      u64 dbuf_cookie, u32 width, u32 height,
148 			      u32 bpp, u64 size, struct page **pages);
149 
150 int xen_drm_front_fb_attach(struct xen_drm_front_info *front_info,
151 			    u64 dbuf_cookie, u64 fb_cookie, u32 width,
152 			    u32 height, u32 pixel_format);
153 
154 int xen_drm_front_fb_detach(struct xen_drm_front_info *front_info,
155 			    u64 fb_cookie);
156 
157 int xen_drm_front_page_flip(struct xen_drm_front_info *front_info,
158 			    int conn_idx, u64 fb_cookie);
159 
160 void xen_drm_front_on_frame_done(struct xen_drm_front_info *front_info,
161 				 int conn_idx, u64 fb_cookie);
162 
163 #endif /* __XEN_DRM_FRONT_H_ */
164