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