xref: /linux/drivers/gpu/drm/sysfb/drm_sysfb_helper.h (revision face6a3615a649456eb4549f6d474221d877d604)
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