Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/drm/drm_fb_helper.h
49213 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
bool force);
259
260
void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);
261
void drm_fb_helper_fill_info(struct fb_info *info,
262
struct drm_fb_helper *fb_helper,
263
struct drm_fb_helper_surface_size *sizes);
264
265
void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);
266
void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height);
267
268
#ifdef CONFIG_FB_DEFERRED_IO
269
void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist);
270
#endif
271
272
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
273
void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
274
bool suspend);
275
276
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
277
278
int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
279
unsigned long arg);
280
281
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
282
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
283
int drm_fb_helper_debug_enter(struct fb_info *info);
284
int drm_fb_helper_debug_leave(struct fb_info *info);
285
#else
286
static inline void drm_fb_helper_prepare(struct drm_device *dev,
287
struct drm_fb_helper *helper,
288
unsigned int preferred_bpp,
289
const struct drm_fb_helper_funcs *funcs)
290
{
291
}
292
293
static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
294
{
295
}
296
297
static inline int drm_fb_helper_init(struct drm_device *dev,
298
struct drm_fb_helper *helper)
299
{
300
/* So drivers can use it to free the struct */
301
helper->dev = dev;
302
dev->fb_helper = helper;
303
304
return 0;
305
}
306
307
static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
308
{
309
if (helper && helper->dev)
310
helper->dev->fb_helper = NULL;
311
}
312
313
static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
314
{
315
return 0;
316
}
317
318
static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
319
struct fb_info *info)
320
{
321
return 0;
322
}
323
324
static inline int drm_fb_helper_set_par(struct fb_info *info)
325
{
326
return 0;
327
}
328
329
static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
330
struct fb_info *info)
331
{
332
return 0;
333
}
334
335
static inline int
336
drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
337
{
338
return 0;
339
}
340
341
static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
342
{
343
}
344
345
static inline void
346
drm_fb_helper_fill_info(struct fb_info *info,
347
struct drm_fb_helper *fb_helper,
348
struct drm_fb_helper_surface_size *sizes)
349
{
350
}
351
352
static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
353
struct fb_info *info)
354
{
355
return 0;
356
}
357
358
static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
359
unsigned long arg)
360
{
361
return 0;
362
}
363
364
#ifdef CONFIG_FB_DEFERRED_IO
365
static inline void drm_fb_helper_deferred_io(struct fb_info *info,
366
struct list_head *pagelist)
367
{
368
}
369
#endif
370
371
static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
372
bool suspend)
373
{
374
}
375
376
static inline void
377
drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
378
{
379
}
380
381
static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
382
{
383
return 0;
384
}
385
386
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
387
{
388
return 0;
389
}
390
391
static inline int drm_fb_helper_debug_enter(struct fb_info *info)
392
{
393
return 0;
394
}
395
396
static inline int drm_fb_helper_debug_leave(struct fb_info *info)
397
{
398
return 0;
399
}
400
#endif
401
402
#endif
403
404