| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| #ifndef DRM_SYSFB_HELPER_H | |
| #define DRM_SYSFB_HELPER_H | |
| #include <linux/container_of.h> | |
| #include <linux/iosys-map.h> | |
| #include <video/pixel_format.h> | |
| #include <drm/drm_crtc.h> | |
| #include <drm/drm_device.h> | |
| #include <drm/drm_gem_atomic_helper.h> | |
| #include <drm/drm_modes.h> | |
| struct drm_format_info; | |
| struct drm_scanout_buffer; | |
| struct screen_info; | |
| typedef void (*drm_sysfb_blit_func)(struct iosys_map *, const unsigned int *, | |
| const struct iosys_map *, | |
| const struct drm_framebuffer *, | |
| const struct drm_rect *, | |
| struct drm_format_conv_state *); | |
| /* | |
| * Input parsing | |
| */ | |
| struct drm_sysfb_format { | |
| struct pixel_format pixel; | |
| u32 fourcc; | |
| }; | |
| int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name, | |
| u64 value, u32 max); | |
| int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name, | |
| u64 value, u32 max); | |
| const struct drm_format_info *drm_sysfb_get_format(struct drm_device *dev, | |
| const struct drm_sysfb_format *formats, | |
| size_t nformats, | |
| const struct pixel_format *pixel); | |
| #if defined(CONFIG_SCREEN_INFO) | |
| int drm_sysfb_get_width_si(struct drm_device *dev, const struct screen_info *si); | |
| int drm_sysfb_get_height_si(struct drm_device *dev, const struct screen_info *si); | |
| struct resource *drm_sysfb_get_memory_si(struct drm_device *dev, | |
| const struct screen_info *si, | |
| struct resource *res); | |
| int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info *si, | |
| const struct drm_format_info *format, | |
| unsigned int width, unsigned int height, u64 size); | |
| s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si, | |
| unsigned int height, unsigned int stride, u64 size); | |
| #endif | |
| /* | |
| * Display modes | |
| */ | |
| struct drm_display_mode drm_sysfb_mode(unsigned int width, | |
| unsigned int height, | |
| unsigned int width_mm, | |
| unsigned int height_mm); | |
| /* | |
| * Device | |
| */ | |
| struct drm_sysfb_device { | |
| struct drm_device dev; | |
| const u8 *edid; /* can be NULL */ | |
| /* hardware settings */ | |
| struct drm_display_mode fb_mode; | |
| const struct drm_format_info *fb_format; | |
| unsigned int fb_pitch; | |
| unsigned int fb_gamma_lut_size; | |
| /* hardware-framebuffer kernel address */ | |
| struct iosys_map fb_addr; | |
| }; | |
| static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *dev) | |
| { | |
| return container_of(dev, struct drm_sysfb_device, dev); | |
| } | |
| /* | |
| * Plane | |
| */ | |
| struct drm_sysfb_plane_state { | |
| struct drm_shadow_plane_state base; | |
| /* transfers framebuffer data to scanout buffer in CRTC format */ | |
| drm_sysfb_blit_func blit_to_crtc; | |
| }; | |
| static inline struct drm_sysfb_plane_state * | |
| to_drm_sysfb_plane_state(struct drm_plane_state *base) | |
| { | |
| return container_of(to_drm_shadow_plane_state(base), struct drm_sysfb_plane_state, base); | |
| } | |
| size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, | |
| const u32 *native_fourccs, size_t native_nfourccs, | |
| u32 *fourccs_out, size_t nfourccs_out); | |
| int drm_sysfb_plane_helper_begin_fb_access(struct drm_plane *plane, | |
| struct drm_plane_state *plane_state); | |
| int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, | |
| struct drm_atomic_commit *new_state); | |
| void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane, | |
| struct drm_atomic_commit *state); | |
| void drm_sysfb_plane_helper_atomic_disable(struct drm_plane *plane, | |
| struct drm_atomic_commit *state); | |
| int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane, | |
| struct drm_scanout_buffer *sb); | |
| #define DRM_SYSFB_PLANE_NFORMATS(_num_native) \ | |
| ((_num_native) + 1) | |
| #define DRM_SYSFB_PLANE_FORMAT_MODIFIERS \ | |
| DRM_FORMAT_MOD_LINEAR, \ | |
| DRM_FORMAT_MOD_INVALID | |
| #define DRM_SYSFB_PLANE_HELPER_FUNCS \ | |
| .begin_fb_access = drm_sysfb_plane_helper_begin_fb_access, \ | |
| .end_fb_access = drm_gem_end_shadow_fb_access, \ | |
| .atomic_check = drm_sysfb_plane_helper_atomic_check, \ | |
| .atomic_update = drm_sysfb_plane_helper_atomic_update, \ | |
| .atomic_disable = drm_sysfb_plane_helper_atomic_disable, \ | |
| .get_scanout_buffer = drm_sysfb_plane_helper_get_scanout_buffer | |
| void drm_sysfb_plane_reset(struct drm_plane *plane); | |
| struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane *plane); | |
| void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane, | |
| struct drm_plane_state *plane_state); | |
| #define DRM_SYSFB_PLANE_FUNCS \ | |
| .reset = drm_sysfb_plane_reset, \ | |
| .update_plane = drm_atomic_helper_update_plane, \ | |
| .disable_plane = drm_atomic_helper_disable_plane, \ | |
| .atomic_duplicate_state = drm_sysfb_plane_atomic_duplicate_state, \ | |
| .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state | |
| /* | |
| * CRTC | |
| */ | |
| struct drm_sysfb_crtc_state { | |
| struct drm_crtc_state base; | |
| /* CRTC input color format; required for color mgmt. */ | |
| const struct drm_format_info *format; | |
| }; | |
| static inline struct drm_sysfb_crtc_state * | |
| to_drm_sysfb_crtc_state(struct drm_crtc_state *base) | |
| { | |
| return container_of(base, struct drm_sysfb_crtc_state, base); | |
| } | |
| enum drm_mode_status drm_sysfb_crtc_helper_mode_valid(struct drm_crtc *crtc, | |
| const struct drm_display_mode *mode); | |
| int drm_sysfb_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_commit *new_state); | |
| #define DRM_SYSFB_CRTC_HELPER_FUNCS \ | |
| .mode_valid = drm_sysfb_crtc_helper_mode_valid, \ | |
| .atomic_check = drm_sysfb_crtc_helper_atomic_check | |
| void drm_sysfb_crtc_reset(struct drm_crtc *crtc); | |
| struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc); | |
| void drm_sysfb_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); | |
| #define DRM_SYSFB_CRTC_FUNCS \ | |
| .reset = drm_sysfb_crtc_reset, \ | |
| .set_config = drm_atomic_helper_set_config, \ | |
| .page_flip = drm_atomic_helper_page_flip, \ | |
| .atomic_duplicate_state = drm_sysfb_crtc_atomic_duplicate_state, \ | |
| .atomic_destroy_state = drm_sysfb_crtc_atomic_destroy_state | |
| /* | |
| * Connector | |
| */ | |
| int drm_sysfb_connector_helper_get_modes(struct drm_connector *connector); | |
| #define DRM_SYSFB_CONNECTOR_HELPER_FUNCS \ | |
| .get_modes = drm_sysfb_connector_helper_get_modes | |
| #define DRM_SYSFB_CONNECTOR_FUNCS \ | |
| .reset = drm_atomic_helper_connector_reset, \ | |
| .fill_modes = drm_helper_probe_single_connector_modes, \ | |
| .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ | |
| .atomic_destroy_state = drm_atomic_helper_connector_destroy_state | |
| /* | |
| * Mode config | |
| */ | |
| #define DRM_SYSFB_MODE_CONFIG_FUNCS \ | |
| .fb_create = drm_gem_fb_create_with_dirty, \ | |
| .atomic_check = drm_atomic_helper_check, \ | |
| .atomic_commit = drm_atomic_helper_commit | |
| #endif |