157 lines
4.3 KiB
C
157 lines
4.3 KiB
C
|
/* 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_ */
|