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