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 #include <drm/drm_atomic.h> 12 #include <drm/drm_atomic_helper.h> 13 #include <drm/drm_drv.h> 14 #include <drm/drm_fourcc.h> 15 #include <drm/drm_framebuffer.h> 16 #include <drm/drm_gem.h> 17 #include <drm/drm_gem_atomic_helper.h> 18 #include <drm/drm_gem_framebuffer_helper.h> 19 #include <drm/drm_probe_helper.h> 20 #include <drm/drm_vblank.h> 21 22 #include "xen_drm_front.h" 23 #include "xen_drm_front_conn.h" 24 #include "xen_drm_front_kms.h" 25 26 /* 27 * Timeout in ms to wait for frame done event from the backend: 28 * must be a bit more than IO time-out 29 */ 30 #define FRAME_DONE_TO_MS (XEN_DRM_FRONT_WAIT_BACK_MS + 100) 31 32 static struct xen_drm_front_drm_pipeline * 33 to_xen_drm_pipeline(struct drm_simple_display_pipe *pipe) 34 { 35 return container_of(pipe, struct xen_drm_front_drm_pipeline, pipe); 36 } 37 38 static void fb_destroy(struct drm_framebuffer *fb) 39 { 40 struct xen_drm_front_drm_info *drm_info = fb->dev->dev_private; 41 int idx; 42 43 if (drm_dev_enter(fb->dev, &idx)) { 44 xen_drm_front_fb_detach(drm_info->front_info, 45 xen_drm_front_fb_to_cookie(fb)); 46 drm_dev_exit(idx); 47 } 48 drm_gem_fb_destroy(fb); 49 } 50 51 static const struct drm_framebuffer_funcs fb_funcs = { 52 .destroy = fb_destroy, 53 }; 54 55 static struct drm_framebuffer * 56 fb_create(struct drm_device *dev, struct drm_file *filp, 57 const struct drm_mode_fb_cmd2 *mode_cmd) 58 { 59 struct xen_drm_front_drm_info *drm_info = dev->dev_private; 60 struct drm_framebuffer *fb; 61 struct drm_gem_object *gem_obj; 62 int ret; 63 64 fb = drm_gem_fb_create_with_funcs(dev, filp, mode_cmd, &fb_funcs); 65 if (IS_ERR(fb)) 66 return fb; 67 68 gem_obj = fb->obj[0]; 69 70 ret = xen_drm_front_fb_attach(drm_info->front_info, 71 xen_drm_front_dbuf_to_cookie(gem_obj), 72 xen_drm_front_fb_to_cookie(fb), 73 fb->width, fb->height, 74 fb->format->format); 75 if (ret < 0) { 76 DRM_ERROR("Back failed to attach FB %p: %d\n", fb, ret); 77 goto fail; 78 } 79 80 return fb; 81 82 fail: 83 drm_gem_fb_destroy(fb); 84 return ERR_PTR(ret); 85 } 86 87 static const struct drm_mode_config_funcs mode_config_funcs = { 88 .fb_create = fb_create, 89 .atomic_check = drm_atomic_helper_check, 90 .atomic_commit = drm_atomic_helper_commit, 91 }; 92 93 static void send_pending_event(struct xen_drm_front_drm_pipeline *pipeline) 94 { 95 struct drm_crtc *crtc = &pipeline->pipe.crtc; 96 struct drm_device *dev = crtc->dev; 97 unsigned long flags; 98 99 spin_lock_irqsave(&dev->event_lock, flags); 100 if (pipeline->pending_event) 101 drm_crtc_send_vblank_event(crtc, pipeline->pending_event); 102 pipeline->pending_event = NULL; 103 spin_unlock_irqrestore(&dev->event_lock, flags); 104 } 105 106 static void display_enable(struct drm_simple_display_pipe *pipe, 107 struct drm_crtc_state *crtc_state, 108 struct drm_plane_state *plane_state) 109 { 110 struct xen_drm_front_drm_pipeline *pipeline = 111 to_xen_drm_pipeline(pipe); 112 struct drm_crtc *crtc = &pipe->crtc; 113 struct drm_framebuffer *fb = plane_state->fb; 114 int ret, idx; 115 116 if (!drm_dev_enter(pipe->crtc.dev, &idx)) 117 return; 118 119 ret = xen_drm_front_mode_set(pipeline, crtc->x, crtc->y, 120 fb->width, fb->height, 121 fb->format->cpp[0] * 8, 122 xen_drm_front_fb_to_cookie(fb)); 123 124 if (ret) { 125 DRM_ERROR("Failed to enable display: %d\n", ret); 126 pipeline->conn_connected = false; 127 } 128 129 drm_dev_exit(idx); 130 } 131 132 static void display_disable(struct drm_simple_display_pipe *pipe) 133 { 134 struct xen_drm_front_drm_pipeline *pipeline = 135 to_xen_drm_pipeline(pipe); 136 int ret = 0, idx; 137 138 if (drm_dev_enter(pipe->crtc.dev, &idx)) { 139 ret = xen_drm_front_mode_set(pipeline, 0, 0, 0, 0, 0, 140 xen_drm_front_fb_to_cookie(NULL)); 141 drm_dev_exit(idx); 142 } 143 if (ret) 144 DRM_ERROR("Failed to disable display: %d\n", ret); 145 146 /* Make sure we can restart with enabled connector next time */ 147 pipeline->conn_connected = true; 148 149 /* release stalled event if any */ 150 send_pending_event(pipeline); 151 } 152 153 void xen_drm_front_kms_on_frame_done(struct xen_drm_front_drm_pipeline *pipeline, 154 u64 fb_cookie) 155 { 156 /* 157 * This runs in interrupt context, e.g. under 158 * drm_info->front_info->io_lock, so we cannot call _sync version 159 * to cancel the work 160 */ 161 cancel_delayed_work(&pipeline->pflip_to_worker); 162 163 send_pending_event(pipeline); 164 } 165 166 static void pflip_to_worker(struct work_struct *work) 167 { 168 struct delayed_work *delayed_work = to_delayed_work(work); 169 struct xen_drm_front_drm_pipeline *pipeline = 170 container_of(delayed_work, 171 struct xen_drm_front_drm_pipeline, 172 pflip_to_worker); 173 174 DRM_ERROR("Frame done timed-out, releasing"); 175 send_pending_event(pipeline); 176 } 177 178 static bool display_send_page_flip(struct drm_simple_display_pipe *pipe, 179 struct drm_plane_state *old_plane_state) 180 { 181 struct drm_plane_state *plane_state = 182 drm_atomic_get_new_plane_state(old_plane_state->state, 183 &pipe->plane); 184 185 /* 186 * If old_plane_state->fb is NULL and plane_state->fb is not, 187 * then this is an atomic commit which will enable display. 188 * If old_plane_state->fb is not NULL and plane_state->fb is, 189 * then this is an atomic commit which will disable display. 190 * Ignore these and do not send page flip as this framebuffer will be 191 * sent to the backend as a part of display_set_config call. 192 */ 193 if (old_plane_state->fb && plane_state->fb) { 194 struct xen_drm_front_drm_pipeline *pipeline = 195 to_xen_drm_pipeline(pipe); 196 struct xen_drm_front_drm_info *drm_info = pipeline->drm_info; 197 int ret; 198 199 schedule_delayed_work(&pipeline->pflip_to_worker, 200 msecs_to_jiffies(FRAME_DONE_TO_MS)); 201 202 ret = xen_drm_front_page_flip(drm_info->front_info, 203 pipeline->index, 204 xen_drm_front_fb_to_cookie(plane_state->fb)); 205 if (ret) { 206 DRM_ERROR("Failed to send page flip request to backend: %d\n", ret); 207 208 pipeline->conn_connected = false; 209 /* 210 * Report the flip not handled, so pending event is 211 * sent, unblocking user-space. 212 */ 213 return false; 214 } 215 /* 216 * Signal that page flip was handled, pending event will be sent 217 * on frame done event from the backend. 218 */ 219 return true; 220 } 221 222 return false; 223 } 224 225 static int display_check(struct drm_simple_display_pipe *pipe, 226 struct drm_plane_state *plane_state, 227 struct drm_crtc_state *crtc_state) 228 { 229 /* 230 * Xen doesn't initialize vblanking via drm_vblank_init(), so 231 * DRM helpers assume that it doesn't handle vblanking and start 232 * sending out fake VBLANK events automatically. 233 * 234 * As xen contains it's own logic for sending out VBLANK events 235 * in send_pending_event(), disable no_vblank (i.e., the xen 236 * driver has vblanking support). 237 */ 238 crtc_state->no_vblank = false; 239 240 return 0; 241 } 242 243 static void display_update(struct drm_simple_display_pipe *pipe, 244 struct drm_plane_state *old_plane_state) 245 { 246 struct xen_drm_front_drm_pipeline *pipeline = 247 to_xen_drm_pipeline(pipe); 248 struct drm_crtc *crtc = &pipe->crtc; 249 struct drm_pending_vblank_event *event; 250 int idx; 251 252 event = crtc->state->event; 253 if (event) { 254 struct drm_device *dev = crtc->dev; 255 unsigned long flags; 256 257 WARN_ON(pipeline->pending_event); 258 259 spin_lock_irqsave(&dev->event_lock, flags); 260 crtc->state->event = NULL; 261 262 pipeline->pending_event = event; 263 spin_unlock_irqrestore(&dev->event_lock, flags); 264 } 265 266 if (!drm_dev_enter(pipe->crtc.dev, &idx)) { 267 send_pending_event(pipeline); 268 return; 269 } 270 271 /* 272 * Send page flip request to the backend *after* we have event cached 273 * above, so on page flip done event from the backend we can 274 * deliver it and there is no race condition between this code and 275 * event from the backend. 276 * If this is not a page flip, e.g. no flip done event from the backend 277 * is expected, then send now. 278 */ 279 if (!display_send_page_flip(pipe, old_plane_state)) 280 send_pending_event(pipeline); 281 282 drm_dev_exit(idx); 283 } 284 285 static enum drm_mode_status 286 display_mode_valid(struct drm_simple_display_pipe *pipe, 287 const struct drm_display_mode *mode) 288 { 289 struct xen_drm_front_drm_pipeline *pipeline = 290 container_of(pipe, struct xen_drm_front_drm_pipeline, 291 pipe); 292 293 if (mode->hdisplay != pipeline->width) 294 return MODE_ERROR; 295 296 if (mode->vdisplay != pipeline->height) 297 return MODE_ERROR; 298 299 return MODE_OK; 300 } 301 302 static const struct drm_simple_display_pipe_funcs display_funcs = { 303 .mode_valid = display_mode_valid, 304 .enable = display_enable, 305 .disable = display_disable, 306 .check = display_check, 307 .update = display_update, 308 }; 309 310 static int display_pipe_init(struct xen_drm_front_drm_info *drm_info, 311 int index, struct xen_drm_front_cfg_connector *cfg, 312 struct xen_drm_front_drm_pipeline *pipeline) 313 { 314 struct drm_device *dev = drm_info->drm_dev; 315 const u32 *formats; 316 int format_count; 317 int ret; 318 319 pipeline->drm_info = drm_info; 320 pipeline->index = index; 321 pipeline->height = cfg->height; 322 pipeline->width = cfg->width; 323 324 INIT_DELAYED_WORK(&pipeline->pflip_to_worker, pflip_to_worker); 325 326 ret = xen_drm_front_conn_init(drm_info, &pipeline->conn); 327 if (ret) 328 return ret; 329 330 formats = xen_drm_front_conn_get_formats(&format_count); 331 332 return drm_simple_display_pipe_init(dev, &pipeline->pipe, 333 &display_funcs, formats, 334 format_count, NULL, 335 &pipeline->conn); 336 } 337 338 int xen_drm_front_kms_init(struct xen_drm_front_drm_info *drm_info) 339 { 340 struct drm_device *dev = drm_info->drm_dev; 341 int i, ret; 342 343 drm_mode_config_init(dev); 344 345 dev->mode_config.min_width = 0; 346 dev->mode_config.min_height = 0; 347 dev->mode_config.max_width = 4095; 348 dev->mode_config.max_height = 2047; 349 dev->mode_config.funcs = &mode_config_funcs; 350 351 for (i = 0; i < drm_info->front_info->cfg.num_connectors; i++) { 352 struct xen_drm_front_cfg_connector *cfg = 353 &drm_info->front_info->cfg.connectors[i]; 354 struct xen_drm_front_drm_pipeline *pipeline = 355 &drm_info->pipeline[i]; 356 357 ret = display_pipe_init(drm_info, i, cfg, pipeline); 358 if (ret) { 359 drm_mode_config_cleanup(dev); 360 return ret; 361 } 362 } 363 364 drm_mode_config_reset(dev); 365 drm_kms_helper_poll_init(dev); 366 return 0; 367 } 368 369 void xen_drm_front_kms_fini(struct xen_drm_front_drm_info *drm_info) 370 { 371 int i; 372 373 for (i = 0; i < drm_info->front_info->cfg.num_connectors; i++) { 374 struct xen_drm_front_drm_pipeline *pipeline = 375 &drm_info->pipeline[i]; 376 377 cancel_delayed_work_sync(&pipeline->pflip_to_worker); 378 379 send_pending_event(pipeline); 380 } 381 } 382