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 <linux/errno.h> 12 #include <linux/irq.h> 13 14 #include <drm/drm_print.h> 15 16 #include <xen/xenbus.h> 17 #include <xen/events.h> 18 #include <xen/grant_table.h> 19 20 #include "xen_drm_front.h" 21 #include "xen_drm_front_evtchnl.h" 22 23 static irqreturn_t evtchnl_interrupt_ctrl(int irq, void *dev_id) 24 { 25 struct xen_drm_front_evtchnl *evtchnl = dev_id; 26 struct xen_drm_front_info *front_info = evtchnl->front_info; 27 struct xendispl_resp *resp; 28 RING_IDX i, rp; 29 unsigned long flags; 30 31 if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED)) 32 return IRQ_HANDLED; 33 34 spin_lock_irqsave(&front_info->io_lock, flags); 35 36 again: 37 rp = evtchnl->u.req.ring.sring->rsp_prod; 38 /* ensure we see queued responses up to rp */ 39 virt_rmb(); 40 41 for (i = evtchnl->u.req.ring.rsp_cons; i != rp; i++) { 42 resp = RING_GET_RESPONSE(&evtchnl->u.req.ring, i); 43 if (unlikely(resp->id != evtchnl->evt_id)) 44 continue; 45 46 switch (resp->operation) { 47 case XENDISPL_OP_PG_FLIP: 48 case XENDISPL_OP_FB_ATTACH: 49 case XENDISPL_OP_FB_DETACH: 50 case XENDISPL_OP_DBUF_CREATE: 51 case XENDISPL_OP_DBUF_DESTROY: 52 case XENDISPL_OP_SET_CONFIG: 53 evtchnl->u.req.resp_status = resp->status; 54 complete(&evtchnl->u.req.completion); 55 break; 56 57 default: 58 DRM_ERROR("Operation %d is not supported\n", 59 resp->operation); 60 break; 61 } 62 } 63 64 evtchnl->u.req.ring.rsp_cons = i; 65 66 if (i != evtchnl->u.req.ring.req_prod_pvt) { 67 int more_to_do; 68 69 RING_FINAL_CHECK_FOR_RESPONSES(&evtchnl->u.req.ring, 70 more_to_do); 71 if (more_to_do) 72 goto again; 73 } else { 74 evtchnl->u.req.ring.sring->rsp_event = i + 1; 75 } 76 77 spin_unlock_irqrestore(&front_info->io_lock, flags); 78 return IRQ_HANDLED; 79 } 80 81 static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id) 82 { 83 struct xen_drm_front_evtchnl *evtchnl = dev_id; 84 struct xen_drm_front_info *front_info = evtchnl->front_info; 85 struct xendispl_event_page *page = evtchnl->u.evt.page; 86 u32 cons, prod; 87 unsigned long flags; 88 89 if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED)) 90 return IRQ_HANDLED; 91 92 spin_lock_irqsave(&front_info->io_lock, flags); 93 94 prod = page->in_prod; 95 /* ensure we see ring contents up to prod */ 96 virt_rmb(); 97 if (prod == page->in_cons) 98 goto out; 99 100 for (cons = page->in_cons; cons != prod; cons++) { 101 struct xendispl_evt *event; 102 103 event = &XENDISPL_IN_RING_REF(page, cons); 104 if (unlikely(event->id != evtchnl->evt_id++)) 105 continue; 106 107 switch (event->type) { 108 case XENDISPL_EVT_PG_FLIP: 109 xen_drm_front_on_frame_done(front_info, evtchnl->index, 110 event->op.pg_flip.fb_cookie); 111 break; 112 } 113 } 114 page->in_cons = cons; 115 /* ensure ring contents */ 116 virt_wmb(); 117 118 out: 119 spin_unlock_irqrestore(&front_info->io_lock, flags); 120 return IRQ_HANDLED; 121 } 122 123 static void evtchnl_free(struct xen_drm_front_info *front_info, 124 struct xen_drm_front_evtchnl *evtchnl) 125 { 126 void *page = NULL; 127 128 if (evtchnl->type == EVTCHNL_TYPE_REQ) 129 page = evtchnl->u.req.ring.sring; 130 else if (evtchnl->type == EVTCHNL_TYPE_EVT) 131 page = evtchnl->u.evt.page; 132 if (!page) 133 return; 134 135 evtchnl->state = EVTCHNL_STATE_DISCONNECTED; 136 137 if (evtchnl->type == EVTCHNL_TYPE_REQ) { 138 /* release all who still waits for response if any */ 139 evtchnl->u.req.resp_status = -EIO; 140 complete_all(&evtchnl->u.req.completion); 141 } 142 143 if (evtchnl->irq) 144 unbind_from_irqhandler(evtchnl->irq, evtchnl); 145 146 if (evtchnl->port) 147 xenbus_free_evtchn(front_info->xb_dev, evtchnl->port); 148 149 /* end access and free the page */ 150 xenbus_teardown_ring(&page, 1, &evtchnl->gref); 151 152 memset(evtchnl, 0, sizeof(*evtchnl)); 153 } 154 155 static int evtchnl_alloc(struct xen_drm_front_info *front_info, int index, 156 struct xen_drm_front_evtchnl *evtchnl, 157 enum xen_drm_front_evtchnl_type type) 158 { 159 struct xenbus_device *xb_dev = front_info->xb_dev; 160 void *page; 161 irq_handler_t handler; 162 int ret; 163 164 memset(evtchnl, 0, sizeof(*evtchnl)); 165 evtchnl->type = type; 166 evtchnl->index = index; 167 evtchnl->front_info = front_info; 168 evtchnl->state = EVTCHNL_STATE_DISCONNECTED; 169 170 ret = xenbus_setup_ring(xb_dev, GFP_NOIO | __GFP_HIGH, &page, 171 1, &evtchnl->gref); 172 if (ret) 173 goto fail; 174 175 if (type == EVTCHNL_TYPE_REQ) { 176 struct xen_displif_sring *sring; 177 178 init_completion(&evtchnl->u.req.completion); 179 mutex_init(&evtchnl->u.req.req_io_lock); 180 sring = page; 181 XEN_FRONT_RING_INIT(&evtchnl->u.req.ring, sring, XEN_PAGE_SIZE); 182 183 handler = evtchnl_interrupt_ctrl; 184 } else { 185 evtchnl->u.evt.page = page; 186 handler = evtchnl_interrupt_evt; 187 } 188 189 ret = xenbus_alloc_evtchn(xb_dev, &evtchnl->port); 190 if (ret < 0) 191 goto fail; 192 193 ret = bind_evtchn_to_irqhandler(evtchnl->port, 194 handler, 0, xb_dev->devicetype, 195 evtchnl); 196 if (ret < 0) 197 goto fail; 198 199 evtchnl->irq = ret; 200 return 0; 201 202 fail: 203 DRM_ERROR("Failed to allocate ring: %d\n", ret); 204 return ret; 205 } 206 207 int xen_drm_front_evtchnl_create_all(struct xen_drm_front_info *front_info) 208 { 209 struct xen_drm_front_cfg *cfg; 210 int ret, conn; 211 212 cfg = &front_info->cfg; 213 214 front_info->evt_pairs = 215 kzalloc_objs(struct xen_drm_front_evtchnl_pair, 216 cfg->num_connectors); 217 if (!front_info->evt_pairs) { 218 ret = -ENOMEM; 219 goto fail; 220 } 221 222 for (conn = 0; conn < cfg->num_connectors; conn++) { 223 ret = evtchnl_alloc(front_info, conn, 224 &front_info->evt_pairs[conn].req, 225 EVTCHNL_TYPE_REQ); 226 if (ret < 0) { 227 DRM_ERROR("Error allocating control channel\n"); 228 goto fail; 229 } 230 231 ret = evtchnl_alloc(front_info, conn, 232 &front_info->evt_pairs[conn].evt, 233 EVTCHNL_TYPE_EVT); 234 if (ret < 0) { 235 DRM_ERROR("Error allocating in-event channel\n"); 236 goto fail; 237 } 238 } 239 front_info->num_evt_pairs = cfg->num_connectors; 240 return 0; 241 242 fail: 243 xen_drm_front_evtchnl_free_all(front_info); 244 return ret; 245 } 246 247 static int evtchnl_publish(struct xenbus_transaction xbt, 248 struct xen_drm_front_evtchnl *evtchnl, 249 const char *path, const char *node_ring, 250 const char *node_chnl) 251 { 252 struct xenbus_device *xb_dev = evtchnl->front_info->xb_dev; 253 int ret; 254 255 /* write control channel ring reference */ 256 ret = xenbus_printf(xbt, path, node_ring, "%u", evtchnl->gref); 257 if (ret < 0) { 258 xenbus_dev_error(xb_dev, ret, "writing ring-ref"); 259 return ret; 260 } 261 262 /* write event channel ring reference */ 263 ret = xenbus_printf(xbt, path, node_chnl, "%u", evtchnl->port); 264 if (ret < 0) { 265 xenbus_dev_error(xb_dev, ret, "writing event channel"); 266 return ret; 267 } 268 269 return 0; 270 } 271 272 int xen_drm_front_evtchnl_publish_all(struct xen_drm_front_info *front_info) 273 { 274 struct xenbus_transaction xbt; 275 struct xen_drm_front_cfg *plat_data; 276 int ret, conn; 277 278 plat_data = &front_info->cfg; 279 280 again: 281 ret = xenbus_transaction_start(&xbt); 282 if (ret < 0) { 283 xenbus_dev_fatal(front_info->xb_dev, ret, 284 "starting transaction"); 285 return ret; 286 } 287 288 for (conn = 0; conn < plat_data->num_connectors; conn++) { 289 ret = evtchnl_publish(xbt, &front_info->evt_pairs[conn].req, 290 plat_data->connectors[conn].xenstore_path, 291 XENDISPL_FIELD_REQ_RING_REF, 292 XENDISPL_FIELD_REQ_CHANNEL); 293 if (ret < 0) 294 goto fail; 295 296 ret = evtchnl_publish(xbt, &front_info->evt_pairs[conn].evt, 297 plat_data->connectors[conn].xenstore_path, 298 XENDISPL_FIELD_EVT_RING_REF, 299 XENDISPL_FIELD_EVT_CHANNEL); 300 if (ret < 0) 301 goto fail; 302 } 303 304 ret = xenbus_transaction_end(xbt, 0); 305 if (ret < 0) { 306 if (ret == -EAGAIN) 307 goto again; 308 309 xenbus_dev_fatal(front_info->xb_dev, ret, 310 "completing transaction"); 311 goto fail_to_end; 312 } 313 314 return 0; 315 316 fail: 317 xenbus_transaction_end(xbt, 1); 318 319 fail_to_end: 320 xenbus_dev_fatal(front_info->xb_dev, ret, "writing Xen store"); 321 return ret; 322 } 323 324 void xen_drm_front_evtchnl_flush(struct xen_drm_front_evtchnl *evtchnl) 325 { 326 int notify; 327 328 evtchnl->u.req.ring.req_prod_pvt++; 329 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&evtchnl->u.req.ring, notify); 330 if (notify) 331 notify_remote_via_irq(evtchnl->irq); 332 } 333 334 void xen_drm_front_evtchnl_set_state(struct xen_drm_front_info *front_info, 335 enum xen_drm_front_evtchnl_state state) 336 { 337 unsigned long flags; 338 int i; 339 340 if (!front_info->evt_pairs) 341 return; 342 343 spin_lock_irqsave(&front_info->io_lock, flags); 344 for (i = 0; i < front_info->num_evt_pairs; i++) { 345 front_info->evt_pairs[i].req.state = state; 346 front_info->evt_pairs[i].evt.state = state; 347 } 348 spin_unlock_irqrestore(&front_info->io_lock, flags); 349 } 350 351 void xen_drm_front_evtchnl_free_all(struct xen_drm_front_info *front_info) 352 { 353 int i; 354 355 if (!front_info->evt_pairs) 356 return; 357 358 for (i = 0; i < front_info->num_evt_pairs; i++) { 359 evtchnl_free(front_info, &front_info->evt_pairs[i].req); 360 evtchnl_free(front_info, &front_info->evt_pairs[i].evt); 361 } 362 363 kfree(front_info->evt_pairs); 364 front_info->evt_pairs = NULL; 365 } 366