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