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
to_drm_sysfb_device(struct drm_device * dev)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 *
to_drm_sysfb_plane_state(struct drm_plane_state * base)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 *
to_drm_sysfb_crtc_state(struct drm_crtc_state * base)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