Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/drm/drm_fb_helper.h
26278 views
1
/*
2
* Copyright (c) 2006-2009 Red Hat Inc.
3
* Copyright (c) 2006-2008 Intel Corporation
4
* Copyright (c) 2007 Dave Airlie <[email protected]>
5
*
6
* DRM framebuffer helper functions
7
*
8
* Permission to use, copy, modify, distribute, and sell this software and its
9
* documentation for any purpose is hereby granted without fee, provided that
10
* the above copyright notice appear in all copies and that both that copyright
11
* notice and this permission notice appear in supporting documentation, and
12
* that the name of the copyright holders not be used in advertising or
13
* publicity pertaining to distribution of the software without specific,
14
* written prior permission. The copyright holders make no representations
15
* about the suitability of this software for any purpose. It is provided "as
16
* is" without express or implied warranty.
17
*
18
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24
* OF THIS SOFTWARE.
25
*
26
* Authors:
27
* Dave Airlie <[email protected]>
28
* Jesse Barnes <[email protected]>
29
*/
30
#ifndef DRM_FB_HELPER_H
31
#define DRM_FB_HELPER_H
32
33
struct drm_clip_rect;
34
struct drm_fb_helper;
35
36
#include <linux/fb.h>
37
38
#include <drm/drm_client.h>
39
40
/**
41
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
42
* @fb_width: fbdev width
43
* @fb_height: fbdev height
44
* @surface_width: scanout buffer width
45
* @surface_height: scanout buffer height
46
* @surface_bpp: scanout buffer bpp
47
* @surface_depth: scanout buffer depth
48
*
49
* Note that the scanout surface width/height may be larger than the fbdev
50
* width/height. In case of multiple displays, the scanout surface is sized
51
* according to the largest width/height (so it is large enough for all CRTCs
52
* to scanout). But the fbdev width/height is sized to the minimum width/
53
* height of all the displays. This ensures that fbcon fits on the smallest
54
* of the attached displays. fb_width/fb_height is used by
55
* drm_fb_helper_fill_info() to fill out the &fb_info.var structure.
56
*/
57
struct drm_fb_helper_surface_size {
58
u32 fb_width;
59
u32 fb_height;
60
u32 surface_width;
61
u32 surface_height;
62
u32 surface_bpp;
63
u32 surface_depth;
64
};
65
66
/**
67
* struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
68
*
69
* Driver callbacks used by the fbdev emulation helper library.
70
*/
71
struct drm_fb_helper_funcs {
72
/**
73
* @fb_dirty:
74
*
75
* Driver callback to update the framebuffer memory. If set, fbdev
76
* emulation will invoke this callback in regular intervals after
77
* the framebuffer has been written.
78
*
79
* This callback is optional.
80
*
81
* Returns:
82
* 0 on success, or an error code otherwise.
83
*/
84
int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip);
85
86
/**
87
* @fb_restore:
88
*
89
* Driver callback to restore internal fbdev state. If set, fbdev
90
* emulation will invoke this callback after restoring the display
91
* mode.
92
*
93
* Only for i915. Do not use in new code.
94
*
95
* TODO: Fix i915 to not require this callback.
96
*/
97
void (*fb_restore)(struct drm_fb_helper *helper);
98
99
/**
100
* @fb_set_suspend:
101
*
102
* Driver callback to suspend or resume, if set, fbdev emulation will
103
* invoke this callback during suspend and resume. Driver should call
104
* fb_set_suspend() from their implementation. If not set, fbdev
105
* emulation will invoke fb_set_suspend() directly.
106
*
107
* Only for i915. Do not use in new code.
108
*
109
* TODO: Fix i915 to not require this callback.
110
*/
111
void (*fb_set_suspend)(struct drm_fb_helper *helper, bool suspend);
112
};
113
114
/**
115
* struct drm_fb_helper - main structure to emulate fbdev on top of KMS
116
* @fb: Scanout framebuffer object
117
* @dev: DRM device
118
* @funcs: driver callbacks for fb helper
119
* @info: emulated fbdev device info struct
120
* @pseudo_palette: fake palette of 16 colors
121
* @damage_clip: clip rectangle used with deferred_io to accumulate damage to
122
* the screen buffer
123
* @damage_lock: spinlock protecting @damage_clip
124
* @damage_work: worker used to flush the framebuffer
125
* @resume_work: worker used during resume if the console lock is already taken
126
*
127
* This is the main structure used by the fbdev helpers. Drivers supporting
128
* fbdev emulation should embedded this into their overall driver structure.
129
* Drivers must also fill out a &struct drm_fb_helper_funcs with a few
130
* operations.
131
*/
132
struct drm_fb_helper {
133
/**
134
* @client:
135
*
136
* DRM client used by the generic fbdev emulation.
137
*/
138
struct drm_client_dev client;
139
140
/**
141
* @buffer:
142
*
143
* Framebuffer used by the generic fbdev emulation.
144
*/
145
struct drm_client_buffer *buffer;
146
147
struct drm_framebuffer *fb;
148
struct drm_device *dev;
149
const struct drm_fb_helper_funcs *funcs;
150
struct fb_info *info;
151
u32 pseudo_palette[17];
152
struct drm_clip_rect damage_clip;
153
spinlock_t damage_lock;
154
struct work_struct damage_work;
155
struct work_struct resume_work;
156
157
/**
158
* @lock:
159
*
160
* Top-level FBDEV helper lock. This protects all internal data
161
* structures and lists, such as @connector_info and @crtc_info.
162
*
163
* FIXME: fbdev emulation locking is a mess and long term we want to
164
* protect all helper internal state with this lock as well as reduce
165
* core KMS locking as much as possible.
166
*/
167
struct mutex lock;
168
169
/**
170
* @kernel_fb_list:
171
*
172
* Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
173
*/
174
struct list_head kernel_fb_list;
175
176
/**
177
* @delayed_hotplug:
178
*
179
* A hotplug was received while fbdev wasn't in control of the DRM
180
* device, i.e. another KMS master was active. The output configuration
181
* needs to be reprobe when fbdev is in control again.
182
*/
183
bool delayed_hotplug;
184
185
/**
186
* @deferred_setup:
187
*
188
* If no outputs are connected (disconnected or unknown) the FB helper
189
* code will defer setup until at least one of the outputs shows up.
190
* This field keeps track of the status so that setup can be retried
191
* at every hotplug event until it succeeds eventually.
192
*
193
* Protected by @lock.
194
*/
195
bool deferred_setup;
196
197
/**
198
* @preferred_bpp:
199
*
200
* Temporary storage for the driver's preferred BPP setting passed to
201
* FB helper initialization. This needs to be tracked so that deferred
202
* FB helper setup can pass this on.
203
*
204
* See also: @deferred_setup
205
*/
206
int preferred_bpp;
207
208
#ifdef CONFIG_FB_DEFERRED_IO
209
/**
210
* @fbdefio:
211
*
212
* Temporary storage for the driver's FB deferred I/O handler. If the
213
* driver uses the DRM fbdev emulation layer, this is set by the core
214
* to a generic deferred I/O handler if a driver is preferring to use
215
* a shadow buffer.
216
*/
217
struct fb_deferred_io fbdefio;
218
#endif
219
};
220
221
static inline struct drm_fb_helper *
222
drm_fb_helper_from_client(struct drm_client_dev *client)
223
{
224
return container_of(client, struct drm_fb_helper, client);
225
}
226
227
/**
228
* define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers
229
*
230
* Helper define to register default implementations of drm_fb_helper
231
* functions. To be used in struct fb_ops of drm drivers.
232
*/
233
#define DRM_FB_HELPER_DEFAULT_OPS \
234
.fb_check_var = drm_fb_helper_check_var, \
235
.fb_set_par = drm_fb_helper_set_par, \
236
.fb_setcmap = drm_fb_helper_setcmap, \
237
.fb_blank = drm_fb_helper_blank, \
238
.fb_pan_display = drm_fb_helper_pan_display, \
239
.fb_debug_enter = drm_fb_helper_debug_enter, \
240
.fb_debug_leave = drm_fb_helper_debug_leave, \
241
.fb_ioctl = drm_fb_helper_ioctl
242
243
#ifdef CONFIG_DRM_FBDEV_EMULATION
244
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
245
unsigned int preferred_bpp,
246
const struct drm_fb_helper_funcs *funcs);
247
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);
248
int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
249
void drm_fb_helper_fini(struct drm_fb_helper *helper);
250
int drm_fb_helper_blank(int blank, struct fb_info *info);
251
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
252
struct fb_info *info);
253
int drm_fb_helper_set_par(struct fb_info *info);
254
int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
255
struct fb_info *info);
256
257
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
258
259
struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper);
260
void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper);
261
void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);
262
void drm_fb_helper_fill_info(struct fb_info *info,
263
struct drm_fb_helper *fb_helper,
264
struct drm_fb_helper_surface_size *sizes);
265
266
void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);
267
void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height);
268
269
#ifdef CONFIG_FB_DEFERRED_IO
270
void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist);
271
#endif
272
273
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
274
void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
275
bool suspend);
276
277
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
278
279
int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
280
unsigned long arg);
281
282
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
283
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
284
int drm_fb_helper_debug_enter(struct fb_info *info);
285
int drm_fb_helper_debug_leave(struct fb_info *info);
286
void drm_fb_helper_lastclose(struct drm_device *dev);
287
#else
288
static inline void drm_fb_helper_prepare(struct drm_device *dev,
289
struct drm_fb_helper *helper,
290
unsigned int preferred_bpp,
291
const struct drm_fb_helper_funcs *funcs)
292
{
293
}
294
295
static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
296
{
297
}
298
299
static inline int drm_fb_helper_init(struct drm_device *dev,
300
struct drm_fb_helper *helper)
301
{
302
/* So drivers can use it to free the struct */
303
helper->dev = dev;
304
dev->fb_helper = helper;
305
306
return 0;
307
}
308
309
static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
310
{
311
if (helper && helper->dev)
312
helper->dev->fb_helper = NULL;
313
}
314
315
static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
316
{
317
return 0;
318
}
319
320
static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
321
struct fb_info *info)
322
{
323
return 0;
324
}
325
326
static inline int drm_fb_helper_set_par(struct fb_info *info)
327
{
328
return 0;
329
}
330
331
static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
332
struct fb_info *info)
333
{
334
return 0;
335
}
336
337
static inline int
338
drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
339
{
340
return 0;
341
}
342
343
static inline struct fb_info *
344
drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
345
{
346
return NULL;
347
}
348
349
static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
350
{
351
}
352
353
static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
354
{
355
}
356
357
static inline void
358
drm_fb_helper_fill_info(struct fb_info *info,
359
struct drm_fb_helper *fb_helper,
360
struct drm_fb_helper_surface_size *sizes)
361
{
362
}
363
364
static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
365
struct fb_info *info)
366
{
367
return 0;
368
}
369
370
static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
371
unsigned long arg)
372
{
373
return 0;
374
}
375
376
#ifdef CONFIG_FB_DEFERRED_IO
377
static inline void drm_fb_helper_deferred_io(struct fb_info *info,
378
struct list_head *pagelist)
379
{
380
}
381
#endif
382
383
static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
384
bool suspend)
385
{
386
}
387
388
static inline void
389
drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
390
{
391
}
392
393
static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
394
{
395
return 0;
396
}
397
398
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
399
{
400
return 0;
401
}
402
403
static inline int drm_fb_helper_debug_enter(struct fb_info *info)
404
{
405
return 0;
406
}
407
408
static inline int drm_fb_helper_debug_leave(struct fb_info *info)
409
{
410
return 0;
411
}
412
413
static inline void drm_fb_helper_lastclose(struct drm_device *dev)
414
{
415
}
416
#endif
417
418
#endif
419
420