1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef DRM_SYSFB_HELPER_H 4 #define DRM_SYSFB_HELPER_H 5 6 #include <linux/container_of.h> 7 #include <linux/iosys-map.h> 8 9 #include <video/pixel_format.h> 10 11 #include <drm/drm_crtc.h> 12 #include <drm/drm_device.h> 13 #include <drm/drm_gem_atomic_helper.h> 14 #include <drm/drm_modes.h> 15 #include <drm/drm_panic_helper.h> 16 17 struct drm_format_info; 18 struct drm_scanout_buffer; 19 struct screen_info; 20 21 typedef void (*drm_sysfb_blit_func)(struct iosys_map *, const unsigned int *, 22 const struct iosys_map *, 23 const struct drm_framebuffer *, 24 const struct drm_rect *, 25 struct drm_format_conv_state *); 26 27 /* 28 * Input parsing 29 */ 30 31 struct drm_sysfb_format { 32 struct pixel_format pixel; 33 u32 fourcc; 34 }; 35 36 int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name, 37 u64 value, u32 max); 38 int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name, 39 u64 value, u32 max); 40 const struct drm_format_info *drm_sysfb_get_format(struct drm_device *dev, 41 const struct drm_sysfb_format *formats, 42 size_t nformats, 43 const struct pixel_format *pixel); 44 45 #if defined(CONFIG_SCREEN_INFO) 46 int drm_sysfb_get_width_si(struct drm_device *dev, const struct screen_info *si); 47 int drm_sysfb_get_height_si(struct drm_device *dev, const struct screen_info *si); 48 struct resource *drm_sysfb_get_memory_si(struct drm_device *dev, 49 const struct screen_info *si, 50 struct resource *res); 51 int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info *si, 52 const struct drm_format_info *format, 53 unsigned int width, unsigned int height, u64 size); 54 s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si, 55 unsigned int height, unsigned int stride, u64 size); 56 #endif 57 58 /* 59 * Display modes 60 */ 61 62 struct drm_display_mode drm_sysfb_mode(unsigned int width, 63 unsigned int height, 64 unsigned int width_mm, 65 unsigned int height_mm); 66 67 /* 68 * Device 69 */ 70 71 struct drm_sysfb_device { 72 struct drm_device dev; 73 74 const u8 *edid; /* can be NULL */ 75 76 /* hardware settings */ 77 struct drm_display_mode fb_mode; 78 const struct drm_format_info *fb_format; 79 unsigned int fb_pitch; 80 unsigned int fb_gamma_lut_size; 81 82 /* hardware-framebuffer kernel address */ 83 struct iosys_map fb_addr; 84 }; 85 86 static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *dev) 87 { 88 return container_of(dev, struct drm_sysfb_device, dev); 89 } 90 91 /* 92 * Plane 93 */ 94 95 struct drm_sysfb_plane_state { 96 struct drm_shadow_plane_state base; 97 98 /* transfers framebuffer data to scanout buffer in CRTC format */ 99 drm_sysfb_blit_func blit_to_crtc; 100 }; 101 102 static inline struct drm_sysfb_plane_state * 103 to_drm_sysfb_plane_state(struct drm_plane_state *base) 104 { 105 return container_of(to_drm_shadow_plane_state(base), struct drm_sysfb_plane_state, base); 106 } 107 108 size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, 109 const u32 *native_fourccs, size_t native_nfourccs, 110 u32 *fourccs_out, size_t nfourccs_out); 111 112 int drm_sysfb_plane_helper_begin_fb_access(struct drm_plane *plane, 113 struct drm_plane_state *plane_state); 114 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, 115 struct drm_atomic_commit *new_state); 116 void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane, 117 struct drm_atomic_commit *state); 118 void drm_sysfb_plane_helper_atomic_disable(struct drm_plane *plane, 119 struct drm_atomic_commit *state); 120 int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane, 121 struct drm_scanout_buffer *sb); 122 123 #define DRM_SYSFB_PLANE_NFORMATS(_num_native) \ 124 ((_num_native) + 1) 125 126 #define DRM_SYSFB_PLANE_FORMAT_MODIFIERS \ 127 DRM_FORMAT_MOD_LINEAR, \ 128 DRM_FORMAT_MOD_INVALID 129 130 #define DRM_SYSFB_PLANE_HELPER_FUNCS \ 131 .begin_fb_access = drm_sysfb_plane_helper_begin_fb_access, \ 132 .end_fb_access = drm_gem_end_shadow_fb_access, \ 133 .atomic_check = drm_sysfb_plane_helper_atomic_check, \ 134 .atomic_update = drm_sysfb_plane_helper_atomic_update, \ 135 .atomic_disable = drm_sysfb_plane_helper_atomic_disable, \ 136 .get_scanout_buffer = drm_sysfb_plane_helper_get_scanout_buffer 137 138 struct drm_plane_state *drm_sysfb_plane_atomic_create_state(struct drm_plane *plane); 139 struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane *plane); 140 void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane, 141 struct drm_plane_state *plane_state); 142 143 #define DRM_SYSFB_PLANE_FUNCS \ 144 .update_plane = drm_atomic_helper_update_plane, \ 145 .disable_plane = drm_atomic_helper_disable_plane, \ 146 .atomic_create_state = drm_sysfb_plane_atomic_create_state, \ 147 .atomic_duplicate_state = drm_sysfb_plane_atomic_duplicate_state, \ 148 .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state, \ 149 DRM_PANIC_PLANE_FUNCS 150 151 /* 152 * CRTC 153 */ 154 155 struct drm_sysfb_crtc_state { 156 struct drm_crtc_state base; 157 158 /* CRTC input color format; required for color mgmt. */ 159 const struct drm_format_info *format; 160 }; 161 162 static inline struct drm_sysfb_crtc_state * 163 to_drm_sysfb_crtc_state(struct drm_crtc_state *base) 164 { 165 return container_of(base, struct drm_sysfb_crtc_state, base); 166 } 167 168 enum drm_mode_status drm_sysfb_crtc_helper_mode_valid(struct drm_crtc *crtc, 169 const struct drm_display_mode *mode); 170 int drm_sysfb_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_commit *new_state); 171 172 #define DRM_SYSFB_CRTC_HELPER_FUNCS \ 173 .mode_valid = drm_sysfb_crtc_helper_mode_valid, \ 174 .atomic_check = drm_sysfb_crtc_helper_atomic_check 175 176 struct drm_crtc_state *drm_sysfb_crtc_create_state(struct drm_crtc *crtc); 177 struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc); 178 void drm_sysfb_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); 179 180 #define DRM_SYSFB_CRTC_FUNCS \ 181 .atomic_create_state = drm_sysfb_crtc_create_state, \ 182 .set_config = drm_atomic_helper_set_config, \ 183 .page_flip = drm_atomic_helper_page_flip, \ 184 .atomic_duplicate_state = drm_sysfb_crtc_atomic_duplicate_state, \ 185 .atomic_destroy_state = drm_sysfb_crtc_atomic_destroy_state 186 187 /* 188 * Connector 189 */ 190 191 int drm_sysfb_connector_helper_get_modes(struct drm_connector *connector); 192 193 #define DRM_SYSFB_CONNECTOR_HELPER_FUNCS \ 194 .get_modes = drm_sysfb_connector_helper_get_modes 195 196 #define DRM_SYSFB_CONNECTOR_FUNCS \ 197 .atomic_create_state = drm_atomic_helper_connector_create_state, \ 198 .fill_modes = drm_helper_probe_single_connector_modes, \ 199 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ 200 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state 201 202 /* 203 * Mode config 204 */ 205 206 #define DRM_SYSFB_MODE_CONFIG_FUNCS \ 207 .fb_create = drm_gem_fb_create_with_dirty, \ 208 .atomic_check = drm_atomic_helper_check, \ 209 .atomic_commit = drm_atomic_helper_commit 210 211 #endif 212