17fd56e02SRodrigo Siqueira /* SPDX-License-Identifier: GPL-2.0+ */ 27fd56e02SRodrigo Siqueira 31c7c5fd9SHaneen Mohammed #ifndef _VKMS_DRV_H_ 41c7c5fd9SHaneen Mohammed #define _VKMS_DRV_H_ 51c7c5fd9SHaneen Mohammed 6ce672a1bSSam Ravnborg #include <linux/hrtimer.h> 7ce672a1bSSam Ravnborg 8854502faSRodrigo Siqueira #include <drm/drm.h> 9720cf96dSVille Syrjälä #include <drm/drm_framebuffer.h> 10559e50fdSRodrigo Siqueira #include <drm/drm_gem.h> 117602d422SThomas Zimmermann #include <drm/drm_gem_atomic_helper.h> 12854502faSRodrigo Siqueira #include <drm/drm_encoder.h> 13dbd9d80cSRodrigo Siqueira #include <drm/drm_writeback.h> 14854502faSRodrigo Siqueira 157b4668e4SAlaa Emad #define XRES_MIN 10 167b4668e4SAlaa Emad #define YRES_MIN 10 17d1648930SRodrigo Siqueira 18d1648930SRodrigo Siqueira #define XRES_DEF 1024 19d1648930SRodrigo Siqueira #define YRES_DEF 768 20d1648930SRodrigo Siqueira 21d1648930SRodrigo Siqueira #define XRES_MAX 8192 22d1648930SRodrigo Siqueira #define YRES_MAX 8192 23d1648930SRodrigo Siqueira 24df2d385cSJosé Expósito #define NUM_OVERLAY_PLANES 8 25df2d385cSJosé Expósito 26db1f254fSArthur Grillo #define VKMS_LUT_SIZE 256 27db1f254fSArthur Grillo 281645e7b9SIgor Torrente struct vkms_frame_info { 292eef1ef6SIgor Torrente struct drm_framebuffer *fb; 30db7f419cSHaneen Mohammed struct drm_rect src, dst; 314a982034SMaíra Canal struct drm_rect rotated; 322a37630dSIgor Torrente struct iosys_map map[DRM_FORMAT_MAX_PLANES]; 334a982034SMaíra Canal unsigned int rotation; 34db7f419cSHaneen Mohammed unsigned int offset; 35db7f419cSHaneen Mohammed unsigned int pitch; 36db7f419cSHaneen Mohammed unsigned int cpp; 376c234fe3SHaneen Mohammed }; 386c234fe3SHaneen Mohammed 39bbdf7b2aSIgor Torrente struct pixel_argb_u16 { 40bbdf7b2aSIgor Torrente u16 a, r, g, b; 41bbdf7b2aSIgor Torrente }; 42bbdf7b2aSIgor Torrente 43bbdf7b2aSIgor Torrente struct line_buffer { 44bbdf7b2aSIgor Torrente size_t n_pixels; 45bbdf7b2aSIgor Torrente struct pixel_argb_u16 *pixels; 46bbdf7b2aSIgor Torrente }; 47bbdf7b2aSIgor Torrente 48bbdf7b2aSIgor Torrente struct vkms_writeback_job { 49bbdf7b2aSIgor Torrente struct iosys_map data[DRM_FORMAT_MAX_PLANES]; 50bbdf7b2aSIgor Torrente struct vkms_frame_info wb_frame_info; 51cc4fd293SMaíra Canal void (*pixel_write)(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel); 52bbdf7b2aSIgor Torrente }; 53bbdf7b2aSIgor Torrente 54dfb9f5caSHaneen Mohammed /** 553e77c4d0SHaneen Mohammed * vkms_plane_state - Driver specific plane state 563e77c4d0SHaneen Mohammed * @base: base plane state 571645e7b9SIgor Torrente * @frame_info: data required for composing computation 583e77c4d0SHaneen Mohammed */ 593e77c4d0SHaneen Mohammed struct vkms_plane_state { 607602d422SThomas Zimmermann struct drm_shadow_plane_state base; 611645e7b9SIgor Torrente struct vkms_frame_info *frame_info; 62322d716aSMaíra Canal void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel); 633e77c4d0SHaneen Mohammed }; 643e77c4d0SHaneen Mohammed 652f56dd8cSMelissa Wen struct vkms_plane { 662f56dd8cSMelissa Wen struct drm_plane base; 672f56dd8cSMelissa Wen }; 682f56dd8cSMelissa Wen 69db1f254fSArthur Grillo struct vkms_color_lut { 70db1f254fSArthur Grillo struct drm_color_lut *base; 71db1f254fSArthur Grillo size_t lut_length; 72db1f254fSArthur Grillo s64 channel_value2index_ratio; 73db1f254fSArthur Grillo }; 74db1f254fSArthur Grillo 753e77c4d0SHaneen Mohammed /** 76dfb9f5caSHaneen Mohammed * vkms_crtc_state - Driver specific CRTC state 77dfb9f5caSHaneen Mohammed * @base: base CRTC state 78a4e7e98eSRodrigo Siqueira * @composer_work: work struct to compose and add CRC entries 790ca33adbSHaneen Mohammed * @n_frame_start: start frame number for computed CRC 800ca33adbSHaneen Mohammed * @n_frame_end: end frame number for computed CRC 81dfb9f5caSHaneen Mohammed */ 82dfb9f5caSHaneen Mohammed struct vkms_crtc_state { 83dfb9f5caSHaneen Mohammed struct drm_crtc_state base; 84a4e7e98eSRodrigo Siqueira struct work_struct composer_work; 8518d0952aSDaniel Vetter 868b186587SDaniel Vetter int num_active_planes; 878b186587SDaniel Vetter /* stack of active planes for crc computation, should be in z order */ 888b186587SDaniel Vetter struct vkms_plane_state **active_planes; 8950fff206SThomas Zimmermann struct vkms_writeback_job *active_writeback; 90db1f254fSArthur Grillo struct vkms_color_lut gamma_lut; 918b186587SDaniel Vetter 92dbd9d80cSRodrigo Siqueira /* below four are protected by vkms_output.composer_lock */ 9318d0952aSDaniel Vetter bool crc_pending; 94dbd9d80cSRodrigo Siqueira bool wb_pending; 950ca33adbSHaneen Mohammed u64 frame_start; 960ca33adbSHaneen Mohammed u64 frame_end; 97dfb9f5caSHaneen Mohammed }; 98dfb9f5caSHaneen Mohammed 99854502faSRodrigo Siqueira struct vkms_output { 100854502faSRodrigo Siqueira struct drm_crtc crtc; 101854502faSRodrigo Siqueira struct drm_encoder encoder; 102854502faSRodrigo Siqueira struct drm_connector connector; 103dbd9d80cSRodrigo Siqueira struct drm_writeback_connector wb_connector; 1043a070992SRodrigo Siqueira struct hrtimer vblank_hrtimer; 1053a070992SRodrigo Siqueira ktime_t period_ns; 1063a070992SRodrigo Siqueira struct drm_pending_vblank_event *event; 107a4e7e98eSRodrigo Siqueira /* ordered wq for composer_work */ 108a4e7e98eSRodrigo Siqueira struct workqueue_struct *composer_workq; 109a4e7e98eSRodrigo Siqueira /* protects concurrent access to composer */ 1106c234fe3SHaneen Mohammed spinlock_t lock; 111fb4155faSDaniel Vetter 112*7908632fSMaíra Canal /* protected by @lock */ 113a4e7e98eSRodrigo Siqueira bool composer_enabled; 114a4e7e98eSRodrigo Siqueira struct vkms_crtc_state *composer_state; 1158b186587SDaniel Vetter 116a4e7e98eSRodrigo Siqueira spinlock_t composer_lock; 117854502faSRodrigo Siqueira }; 1181c7c5fd9SHaneen Mohammed 1192df7af93SSumera Priyadarsini struct vkms_device; 1202df7af93SSumera Priyadarsini 1212df7af93SSumera Priyadarsini struct vkms_config { 1221e85b7d4SSumera Priyadarsini bool writeback; 1232df7af93SSumera Priyadarsini bool cursor; 124310e506cSMelissa Wen bool overlay; 1252df7af93SSumera Priyadarsini /* only set when instantiated */ 1262df7af93SSumera Priyadarsini struct vkms_device *dev; 1272df7af93SSumera Priyadarsini }; 1282df7af93SSumera Priyadarsini 1291c7c5fd9SHaneen Mohammed struct vkms_device { 1301c7c5fd9SHaneen Mohammed struct drm_device drm; 1311c7c5fd9SHaneen Mohammed struct platform_device *platform; 132854502faSRodrigo Siqueira struct vkms_output output; 1332df7af93SSumera Priyadarsini const struct vkms_config *config; 1341c7c5fd9SHaneen Mohammed }; 1351c7c5fd9SHaneen Mohammed 1363a070992SRodrigo Siqueira #define drm_crtc_to_vkms_output(target) \ 1373a070992SRodrigo Siqueira container_of(target, struct vkms_output, crtc) 1383a070992SRodrigo Siqueira 1393a070992SRodrigo Siqueira #define drm_device_to_vkms_device(target) \ 1403a070992SRodrigo Siqueira container_of(target, struct vkms_device, drm) 1413a070992SRodrigo Siqueira 142dfb9f5caSHaneen Mohammed #define to_vkms_crtc_state(target)\ 143dfb9f5caSHaneen Mohammed container_of(target, struct vkms_crtc_state, base) 144dfb9f5caSHaneen Mohammed 1453e77c4d0SHaneen Mohammed #define to_vkms_plane_state(target)\ 1467602d422SThomas Zimmermann container_of(target, struct vkms_plane_state, base.base) 1473e77c4d0SHaneen Mohammed 1483a070992SRodrigo Siqueira /* CRTC */ 149854502faSRodrigo Siqueira int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 150854502faSRodrigo Siqueira struct drm_plane *primary, struct drm_plane *cursor); 151854502faSRodrigo Siqueira 152e9d85f73SRodrigo Siqueira int vkms_output_init(struct vkms_device *vkmsdev, int index); 153854502faSRodrigo Siqueira 1542f56dd8cSMelissa Wen struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, 155e9d85f73SRodrigo Siqueira enum drm_plane_type type, int index); 156854502faSRodrigo Siqueira 1576c234fe3SHaneen Mohammed /* CRC Support */ 158c936843fSOleg Vasilev const char *const *vkms_get_crc_sources(struct drm_crtc *crtc, 159c936843fSOleg Vasilev size_t *count); 160c0811a7dSMahesh Kumar int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name); 161af697933SMahesh Kumar int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, 162af697933SMahesh Kumar size_t *values_cnt); 163a4e7e98eSRodrigo Siqueira 164a4e7e98eSRodrigo Siqueira /* Composer Support */ 165a4e7e98eSRodrigo Siqueira void vkms_composer_worker(struct work_struct *work); 166dbd9d80cSRodrigo Siqueira void vkms_set_composer(struct vkms_output *out, bool enabled); 167322d716aSMaíra Canal void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y); 168cc4fd293SMaíra Canal void vkms_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y); 169dbd9d80cSRodrigo Siqueira 170dbd9d80cSRodrigo Siqueira /* Writeback */ 171dbd9d80cSRodrigo Siqueira int vkms_enable_writeback_connector(struct vkms_device *vkmsdev); 1726c234fe3SHaneen Mohammed 1731c7c5fd9SHaneen Mohammed #endif /* _VKMS_DRV_H_ */ 174