1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0+ */ 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun #ifndef _VKMS_DRV_H_ 4*4882a593Smuzhiyun #define _VKMS_DRV_H_ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #include <linux/hrtimer.h> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <drm/drm.h> 9*4882a593Smuzhiyun #include <drm/drm_gem.h> 10*4882a593Smuzhiyun #include <drm/drm_encoder.h> 11*4882a593Smuzhiyun #include <drm/drm_writeback.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #define XRES_MIN 20 14*4882a593Smuzhiyun #define YRES_MIN 20 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #define XRES_DEF 1024 17*4882a593Smuzhiyun #define YRES_DEF 768 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #define XRES_MAX 8192 20*4882a593Smuzhiyun #define YRES_MAX 8192 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun extern bool enable_cursor; 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun struct vkms_composer { 25*4882a593Smuzhiyun struct drm_framebuffer fb; 26*4882a593Smuzhiyun struct drm_rect src, dst; 27*4882a593Smuzhiyun unsigned int offset; 28*4882a593Smuzhiyun unsigned int pitch; 29*4882a593Smuzhiyun unsigned int cpp; 30*4882a593Smuzhiyun }; 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /** 33*4882a593Smuzhiyun * vkms_plane_state - Driver specific plane state 34*4882a593Smuzhiyun * @base: base plane state 35*4882a593Smuzhiyun * @composer: data required for composing computation 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun struct vkms_plane_state { 38*4882a593Smuzhiyun struct drm_plane_state base; 39*4882a593Smuzhiyun struct vkms_composer *composer; 40*4882a593Smuzhiyun }; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /** 43*4882a593Smuzhiyun * vkms_crtc_state - Driver specific CRTC state 44*4882a593Smuzhiyun * @base: base CRTC state 45*4882a593Smuzhiyun * @composer_work: work struct to compose and add CRC entries 46*4882a593Smuzhiyun * @n_frame_start: start frame number for computed CRC 47*4882a593Smuzhiyun * @n_frame_end: end frame number for computed CRC 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun struct vkms_crtc_state { 50*4882a593Smuzhiyun struct drm_crtc_state base; 51*4882a593Smuzhiyun struct work_struct composer_work; 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun int num_active_planes; 54*4882a593Smuzhiyun /* stack of active planes for crc computation, should be in z order */ 55*4882a593Smuzhiyun struct vkms_plane_state **active_planes; 56*4882a593Smuzhiyun void *active_writeback; 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* below four are protected by vkms_output.composer_lock */ 59*4882a593Smuzhiyun bool crc_pending; 60*4882a593Smuzhiyun bool wb_pending; 61*4882a593Smuzhiyun u64 frame_start; 62*4882a593Smuzhiyun u64 frame_end; 63*4882a593Smuzhiyun }; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun struct vkms_output { 66*4882a593Smuzhiyun struct drm_crtc crtc; 67*4882a593Smuzhiyun struct drm_encoder encoder; 68*4882a593Smuzhiyun struct drm_connector connector; 69*4882a593Smuzhiyun struct drm_writeback_connector wb_connector; 70*4882a593Smuzhiyun struct hrtimer vblank_hrtimer; 71*4882a593Smuzhiyun ktime_t period_ns; 72*4882a593Smuzhiyun struct drm_pending_vblank_event *event; 73*4882a593Smuzhiyun /* ordered wq for composer_work */ 74*4882a593Smuzhiyun struct workqueue_struct *composer_workq; 75*4882a593Smuzhiyun /* protects concurrent access to composer */ 76*4882a593Smuzhiyun spinlock_t lock; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun /* protected by @lock */ 79*4882a593Smuzhiyun bool composer_enabled; 80*4882a593Smuzhiyun struct vkms_crtc_state *composer_state; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun spinlock_t composer_lock; 83*4882a593Smuzhiyun }; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun struct vkms_device { 86*4882a593Smuzhiyun struct drm_device drm; 87*4882a593Smuzhiyun struct platform_device *platform; 88*4882a593Smuzhiyun struct vkms_output output; 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun struct vkms_gem_object { 92*4882a593Smuzhiyun struct drm_gem_object gem; 93*4882a593Smuzhiyun struct mutex pages_lock; /* Page lock used in page fault handler */ 94*4882a593Smuzhiyun struct page **pages; 95*4882a593Smuzhiyun unsigned int vmap_count; 96*4882a593Smuzhiyun void *vaddr; 97*4882a593Smuzhiyun }; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun #define drm_crtc_to_vkms_output(target) \ 100*4882a593Smuzhiyun container_of(target, struct vkms_output, crtc) 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun #define drm_device_to_vkms_device(target) \ 103*4882a593Smuzhiyun container_of(target, struct vkms_device, drm) 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun #define drm_gem_to_vkms_gem(target)\ 106*4882a593Smuzhiyun container_of(target, struct vkms_gem_object, gem) 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun #define to_vkms_crtc_state(target)\ 109*4882a593Smuzhiyun container_of(target, struct vkms_crtc_state, base) 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun #define to_vkms_plane_state(target)\ 112*4882a593Smuzhiyun container_of(target, struct vkms_plane_state, base) 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun /* CRTC */ 115*4882a593Smuzhiyun int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 116*4882a593Smuzhiyun struct drm_plane *primary, struct drm_plane *cursor); 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun int vkms_output_init(struct vkms_device *vkmsdev, int index); 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, 121*4882a593Smuzhiyun enum drm_plane_type type, int index); 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /* Gem stuff */ 124*4882a593Smuzhiyun vm_fault_t vkms_gem_fault(struct vm_fault *vmf); 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun int vkms_dumb_create(struct drm_file *file, struct drm_device *dev, 127*4882a593Smuzhiyun struct drm_mode_create_dumb *args); 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun void vkms_gem_free_object(struct drm_gem_object *obj); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun int vkms_gem_vmap(struct drm_gem_object *obj); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun void vkms_gem_vunmap(struct drm_gem_object *obj); 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun /* Prime */ 136*4882a593Smuzhiyun struct drm_gem_object * 137*4882a593Smuzhiyun vkms_prime_import_sg_table(struct drm_device *dev, 138*4882a593Smuzhiyun struct dma_buf_attachment *attach, 139*4882a593Smuzhiyun struct sg_table *sg); 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun /* CRC Support */ 142*4882a593Smuzhiyun const char *const *vkms_get_crc_sources(struct drm_crtc *crtc, 143*4882a593Smuzhiyun size_t *count); 144*4882a593Smuzhiyun int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name); 145*4882a593Smuzhiyun int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, 146*4882a593Smuzhiyun size_t *values_cnt); 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* Composer Support */ 149*4882a593Smuzhiyun void vkms_composer_worker(struct work_struct *work); 150*4882a593Smuzhiyun void vkms_set_composer(struct vkms_output *out, bool enabled); 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun /* Writeback */ 153*4882a593Smuzhiyun int vkms_enable_writeback_connector(struct vkms_device *vkmsdev); 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun #endif /* _VKMS_DRV_H_ */ 156