drm_fb_helper.h revision 1.7 1 /* $NetBSD: drm_fb_helper.h,v 1.7 2018/08/27 04:58:37 riastradh Exp $ */
2
3 /*
4 * Copyright (c) 2006-2009 Red Hat Inc.
5 * Copyright (c) 2006-2008 Intel Corporation
6 * Copyright (c) 2007 Dave Airlie <airlied (at) linux.ie>
7 *
8 * DRM framebuffer helper functions
9 *
10 * Permission to use, copy, modify, distribute, and sell this software and its
11 * documentation for any purpose is hereby granted without fee, provided that
12 * the above copyright notice appear in all copies and that both that copyright
13 * notice and this permission notice appear in supporting documentation, and
14 * that the name of the copyright holders not be used in advertising or
15 * publicity pertaining to distribution of the software without specific,
16 * written prior permission. The copyright holders make no representations
17 * about the suitability of this software for any purpose. It is provided "as
18 * is" without express or implied warranty.
19 *
20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
22 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
24 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
25 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 * OF THIS SOFTWARE.
27 *
28 * Authors:
29 * Dave Airlie <airlied (at) linux.ie>
30 * Jesse Barnes <jesse.barnes (at) intel.com>
31 */
32 #ifndef DRM_FB_HELPER_H
33 #define DRM_FB_HELPER_H
34
35 struct drm_fb_helper;
36
37 #include <linux/kgdb.h>
38
39 #ifdef __NetBSD__
40 #include <sys/device_if.h>
41 #endif
42
43 struct drm_fb_offset {
44 int x, y;
45 };
46
47 struct drm_fb_helper_crtc {
48 struct drm_mode_set mode_set;
49 struct drm_display_mode *desired_mode;
50 int x, y;
51 };
52
53 /**
54 * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
55 * @fb_width: fbdev width
56 * @fb_height: fbdev height
57 * @surface_width: scanout buffer width
58 * @surface_height: scanout buffer height
59 * @surface_bpp: scanout buffer bpp
60 * @surface_depth: scanout buffer depth
61 *
62 * Note that the scanout surface width/height may be larger than the fbdev
63 * width/height. In case of multiple displays, the scanout surface is sized
64 * according to the largest width/height (so it is large enough for all CRTCs
65 * to scanout). But the fbdev width/height is sized to the minimum width/
66 * height of all the displays. This ensures that fbcon fits on the smallest
67 * of the attached displays.
68 *
69 * So what is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
70 * rather than the surface size.
71 */
72 struct drm_fb_helper_surface_size {
73 u32 fb_width;
74 u32 fb_height;
75 u32 surface_width;
76 u32 surface_height;
77 u32 surface_bpp;
78 u32 surface_depth;
79 };
80
81 /**
82 * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
83 * @gamma_set: Set the given gamma lut register on the given crtc.
84 * @gamma_get: Read the given gamma lut register on the given crtc, used to
85 * save the current lut when force-restoring the fbdev for e.g.
86 * kdbg.
87 * @fb_probe: Driver callback to allocate and initialize the fbdev info
88 * structure. Furthermore it also needs to allocate the drm
89 * framebuffer used to back the fbdev.
90 * @initial_config: Setup an initial fbdev display configuration
91 *
92 * Driver callbacks used by the fbdev emulation helper library.
93 */
94 struct drm_fb_helper_funcs {
95 void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
96 u16 blue, int regno);
97 void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
98 u16 *blue, int regno);
99
100 int (*fb_probe)(struct drm_fb_helper *helper,
101 struct drm_fb_helper_surface_size *sizes);
102 bool (*initial_config)(struct drm_fb_helper *fb_helper,
103 struct drm_fb_helper_crtc **crtcs,
104 struct drm_display_mode **modes,
105 struct drm_fb_offset *offsets,
106 bool *enabled, int width, int height);
107 };
108
109 struct drm_fb_helper_connector {
110 struct drm_connector *connector;
111 };
112
113 /**
114 * struct drm_fb_helper - helper to emulate fbdev on top of kms
115 * @fb: Scanout framebuffer object
116 * @dev: DRM device
117 * @crtc_count: number of possible CRTCs
118 * @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
119 * @connector_count: number of connected connectors
120 * @connector_info_alloc_count: size of connector_info
121 * @funcs: driver callbacks for fb helper
122 * @fbdev: emulated fbdev device info struct
123 * @pseudo_palette: fake palette of 16 colors
124 * @kernel_fb_list: list_head in kernel_fb_helper_list
125 * @delayed_hotplug: was there a hotplug while kms master active?
126 */
127 struct drm_fb_helper {
128 struct drm_framebuffer *fb;
129 struct drm_device *dev;
130 int crtc_count;
131 struct drm_fb_helper_crtc *crtc_info;
132 int connector_count;
133 int connector_info_alloc_count;
134 struct drm_fb_helper_connector **connector_info;
135 const struct drm_fb_helper_funcs *funcs;
136 #ifdef __NetBSD__ /* XXX fb info */
137 device_t fbdev;
138 #else
139 struct fb_info *fbdev;
140 #endif
141 u32 pseudo_palette[17];
142 struct list_head kernel_fb_list;
143
144 /* we got a hotplug but fbdev wasn't running the console
145 delay until next set_par */
146 bool delayed_hotplug;
147
148 /**
149 * @atomic:
150 *
151 * Use atomic updates for restore_fbdev_mode(), etc. This defaults to
152 * true if driver has DRIVER_ATOMIC feature flag, but drivers can
153 * override it to true after drm_fb_helper_init() if they support atomic
154 * modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper
155 * does not require ASYNC commits).
156 */
157 bool atomic;
158 };
159
160 #ifdef CONFIG_DRM_FBDEV_EMULATION
161 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
162 const struct drm_fb_helper_funcs *funcs);
163 int drm_fb_helper_init(struct drm_device *dev,
164 struct drm_fb_helper *helper, int crtc_count,
165 int max_conn);
166 void drm_fb_helper_fini(struct drm_fb_helper *helper);
167 #ifdef __NetBSD__ /* XXX fb info */
168 int drm_fb_helper_set_config(struct drm_fb_helper *);
169 #else
170 int drm_fb_helper_blank(int blank, struct fb_info *info);
171 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
172 struct fb_info *info);
173 int drm_fb_helper_set_par(struct fb_info *info);
174 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
175 struct fb_info *info);
176 #endif
177
178 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
179 #ifndef __NetBSD__ /* XXX fb info */
180
181 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
182 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
183 void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper);
184 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
185 uint32_t fb_width, uint32_t fb_height);
186 void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
187 uint32_t depth);
188
189 void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
190
191 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
192 size_t count, loff_t *ppos);
193 ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
194 size_t count, loff_t *ppos);
195
196 void drm_fb_helper_sys_fillrect(struct fb_info *info,
197 const struct fb_fillrect *rect);
198 void drm_fb_helper_sys_copyarea(struct fb_info *info,
199 const struct fb_copyarea *area);
200 void drm_fb_helper_sys_imageblit(struct fb_info *info,
201 const struct fb_image *image);
202
203 void drm_fb_helper_cfb_fillrect(struct fb_info *info,
204 const struct fb_fillrect *rect);
205 void drm_fb_helper_cfb_copyarea(struct fb_info *info,
206 const struct fb_copyarea *area);
207 void drm_fb_helper_cfb_imageblit(struct fb_info *info,
208 const struct fb_image *image);
209 #endif
210
211 void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state);
212
213 #ifndef __NetBSD__ /* XXX fb cmap */
214 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
215 #endif
216
217 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
218 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
219 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
220 #ifndef __NetBSD__ /* XXX fb info */
221 int drm_fb_helper_debug_enter(struct fb_info *info);
222 int drm_fb_helper_debug_leave(struct fb_info *info);
223 #endif
224 int drm_fb_helper_debug_enter_fb(struct drm_fb_helper *fb_helper);
225 int drm_fb_helper_debug_leave_fb(struct drm_fb_helper *fb_helper);
226 struct drm_display_mode *
227 drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
228 int width, int height);
229 struct drm_display_mode *
230 drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
231 int width, int height);
232
233 int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
234 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
235 struct drm_connector *connector);
236 #else
237 static inline void drm_fb_helper_prepare(struct drm_device *dev,
238 struct drm_fb_helper *helper,
239 const struct drm_fb_helper_funcs *funcs)
240 {
241 }
242
243 static inline int drm_fb_helper_init(struct drm_device *dev,
244 struct drm_fb_helper *helper, int crtc_count,
245 int max_conn)
246 {
247 return 0;
248 }
249
250 static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
251 {
252 }
253
254 static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
255 {
256 return 0;
257 }
258
259 static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
260 struct fb_info *info)
261 {
262 return 0;
263 }
264
265 static inline int drm_fb_helper_set_par(struct fb_info *info)
266 {
267 return 0;
268 }
269
270 static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
271 struct fb_info *info)
272 {
273 return 0;
274 }
275
276 static inline int
277 drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
278 {
279 return 0;
280 }
281
282 static inline struct fb_info *
283 drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper)
284 {
285 return NULL;
286 }
287
288 static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
289 {
290 }
291 static inline void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper)
292 {
293 }
294
295 static inline void drm_fb_helper_fill_var(struct fb_info *info,
296 struct drm_fb_helper *fb_helper,
297 uint32_t fb_width, uint32_t fb_height)
298 {
299 }
300
301 static inline void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
302 uint32_t depth)
303 {
304 }
305
306 static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
307 struct fb_info *info)
308 {
309 return 0;
310 }
311
312 static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
313 {
314 }
315
316 static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info,
317 char __user *buf, size_t count,
318 loff_t *ppos)
319 {
320 return -ENODEV;
321 }
322
323 static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info,
324 const char __user *buf,
325 size_t count, loff_t *ppos)
326 {
327 return -ENODEV;
328 }
329
330 static inline void drm_fb_helper_sys_fillrect(struct fb_info *info,
331 const struct fb_fillrect *rect)
332 {
333 }
334
335 static inline void drm_fb_helper_sys_copyarea(struct fb_info *info,
336 const struct fb_copyarea *area)
337 {
338 }
339
340 static inline void drm_fb_helper_sys_imageblit(struct fb_info *info,
341 const struct fb_image *image)
342 {
343 }
344
345 static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info,
346 const struct fb_fillrect *rect)
347 {
348 }
349
350 static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info,
351 const struct fb_copyarea *area)
352 {
353 }
354
355 static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
356 const struct fb_image *image)
357 {
358 }
359
360 static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
361 int state)
362 {
363 }
364
365 static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
366 {
367 return 0;
368 }
369
370 static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
371 int bpp_sel)
372 {
373 return 0;
374 }
375
376 static inline int
377 drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
378 {
379 return 0;
380 }
381
382 static inline int drm_fb_helper_debug_enter(struct fb_info *info)
383 {
384 return 0;
385 }
386
387 static inline int drm_fb_helper_debug_leave(struct fb_info *info)
388 {
389 return 0;
390 }
391
392 static inline struct drm_display_mode *
393 drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
394 int width, int height)
395 {
396 return NULL;
397 }
398
399 static inline struct drm_display_mode *
400 drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
401 int width, int height)
402 {
403 return NULL;
404 }
405
406 static inline int
407 drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
408 struct drm_connector *connector)
409 {
410 return 0;
411 }
412
413 static inline int
414 drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
415 struct drm_connector *connector)
416 {
417 return 0;
418 }
419 #endif
420 #endif
421