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 * Display modes 59 */ 60 61 struct drm_display_mode drm_sysfb_mode(unsigned int width, 62 unsigned int height, 63 unsigned int width_mm, 64 unsigned int height_mm); 65 66 /* 67 * Device 68 */ 69 70 struct drm_sysfb_device { 71 struct drm_device dev; 72 73 const u8 *edid; /* can be NULL */ 74 75 /* hardware settings */ 76 struct drm_display_mode fb_mode; 77 const struct drm_format_info *fb_format; 78 unsigned int fb_pitch; 79 unsigned int fb_gamma_lut_size; 80 81 /* hardware-framebuffer kernel address */ 82 struct iosys_map fb_addr; 83 }; 84 85 static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *dev) 86 { 87 return container_of(dev, struct drm_sysfb_device, dev); 88 } 89 90 /* 91 * Plane 92 */ 93 94 struct drm_sysfb_plane_state { 95 struct drm_shadow_plane_state base; 96 97 /* transfers framebuffer data to scanout buffer in CRTC format */ 98 drm_sysfb_blit_func blit_to_crtc; 99 }; 100 101 static inline struct drm_sysfb_plane_state * 102 to_drm_sysfb_plane_state(struct drm_plane_state *base) 103 { 104 return container_of(to_drm_shadow_plane_state(base), struct drm_sysfb_plane_state, base); 105 } 106 107 size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, 108 const u32 *native_fourccs, size_t native_nfourccs, 109 u32 *fourccs_out, size_t nfourccs_out); 110 111 int drm_sysfb_plane_helper_begin_fb_access(struct drm_plane *plane, 112 struct drm_plane_state *plane_state); 113 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, 114 struct drm_atomic_state *new_state); 115 void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane, 116 struct drm_atomic_state *state); 117 void drm_sysfb_plane_helper_atomic_disable(struct drm_plane *plane, 118 struct drm_atomic_state *state); 119 int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane, 120 struct drm_scanout_buffer *sb); 121 122 #define DRM_SYSFB_PLANE_NFORMATS(_num_native) \ 123 ((_num_native) + 1) 124 125 #define DRM_SYSFB_PLANE_FORMAT_MODIFIERS \ 126 DRM_FORMAT_MOD_LINEAR, \ 127 DRM_FORMAT_MOD_INVALID 128 129 #define DRM_SYSFB_PLANE_HELPER_FUNCS \ 130 .begin_fb_access = drm_sysfb_plane_helper_begin_fb_access, \ 131 .end_fb_access = drm_gem_end_shadow_fb_access, \ 132 .atomic_check = drm_sysfb_plane_helper_atomic_check, \ 133 .atomic_update = drm_sysfb_plane_helper_atomic_update, \ 134 .atomic_disable = drm_sysfb_plane_helper_atomic_disable, \ 135 .get_scanout_buffer = drm_sysfb_plane_helper_get_scanout_buffer 136 137 void drm_sysfb_plane_reset(struct drm_plane *plane); 138 struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane *plane); 139 void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane, 140 struct drm_plane_state *plane_state); 141 142 #define DRM_SYSFB_PLANE_FUNCS \ 143 .reset = drm_sysfb_plane_reset, \ 144 .update_plane = drm_atomic_helper_update_plane, \ 145 .disable_plane = drm_atomic_helper_disable_plane, \ 146 .atomic_duplicate_state = drm_sysfb_plane_atomic_duplicate_state, \ 147 .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state 148 149 /* 150 * CRTC 151 */ 152 153 struct drm_sysfb_crtc_state { 154 struct drm_crtc_state base; 155 156 /* CRTC input color format; required for color mgmt. */ 157 const struct drm_format_info *format; 158 }; 159 160 static inline struct drm_sysfb_crtc_state * 161 to_drm_sysfb_crtc_state(struct drm_crtc_state *base) 162 { 163 return container_of(base, struct drm_sysfb_crtc_state, base); 164 } 165 166 enum drm_mode_status drm_sysfb_crtc_helper_mode_valid(struct drm_crtc *crtc, 167 const struct drm_display_mode *mode); 168 int drm_sysfb_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state); 169 170 #define DRM_SYSFB_CRTC_HELPER_FUNCS \ 171 .mode_valid = drm_sysfb_crtc_helper_mode_valid, \ 172 .atomic_check = drm_sysfb_crtc_helper_atomic_check 173 174 void drm_sysfb_crtc_reset(struct drm_crtc *crtc); 175 struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc); 176 void drm_sysfb_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); 177 178 #define DRM_SYSFB_CRTC_FUNCS \ 179 .reset = drm_sysfb_crtc_reset, \ 180 .set_config = drm_atomic_helper_set_config, \ 181 .page_flip = drm_atomic_helper_page_flip, \ 182 .atomic_duplicate_state = drm_sysfb_crtc_atomic_duplicate_state, \ 183 .atomic_destroy_state = drm_sysfb_crtc_atomic_destroy_state 184 185 /* 186 * Connector 187 */ 188 189 int drm_sysfb_connector_helper_get_modes(struct drm_connector *connector); 190 191 #define DRM_SYSFB_CONNECTOR_HELPER_FUNCS \ 192 .get_modes = drm_sysfb_connector_helper_get_modes 193 194 #define DRM_SYSFB_CONNECTOR_FUNCS \ 195 .reset = drm_atomic_helper_connector_reset, \ 196 .fill_modes = drm_helper_probe_single_connector_modes, \ 197 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ 198 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state 199 200 /* 201 * Mode config 202 */ 203 204 #define DRM_SYSFB_MODE_CONFIG_FUNCS \ 205 .fb_create = drm_gem_fb_create_with_dirty, \ 206 .atomic_check = drm_atomic_helper_check, \ 207 .atomic_commit = drm_atomic_helper_commit 208 209 #endif 210