drm/kms: move driver specific fb common code to helper functions (v2)
[deliverable/linux.git] / drivers / gpu / drm / drm_fb_helper.c
1 /*
2 * Copyright (c) 2006-2009 Red Hat Inc.
3 * Copyright (c) 2006-2008 Intel Corporation
4 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
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 <airlied@linux.ie>
28 * Jesse Barnes <jesse.barnes@intel.com>
29 */
30 #include <linux/sysrq.h>
31 #include <linux/fb.h>
32 #include "drmP.h"
33 #include "drm_crtc.h"
34 #include "drm_fb_helper.h"
35 #include "drm_crtc_helper.h"
36
37 static LIST_HEAD(kernel_fb_helper_list);
38
39 bool drm_fb_helper_force_kernel_mode(void)
40 {
41 int i = 0;
42 bool ret, error = false;
43 struct drm_fb_helper *helper;
44
45 if (list_empty(&kernel_fb_helper_list))
46 return false;
47
48 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
49 for (i = 0; i < helper->crtc_count; i++) {
50 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
51 ret = drm_crtc_helper_set_config(mode_set);
52 if (ret)
53 error = true;
54 }
55 }
56 return error;
57 }
58
59 int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
60 void *panic_str)
61 {
62 DRM_ERROR("panic occurred, switching back to text console\n");
63 return drm_fb_helper_force_kernel_mode();
64 return 0;
65 }
66 EXPORT_SYMBOL(drm_fb_helper_panic);
67
68 static struct notifier_block paniced = {
69 .notifier_call = drm_fb_helper_panic,
70 };
71
72 /**
73 * drm_fb_helper_restore - restore the framebuffer console (kernel) config
74 *
75 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
76 */
77 void drm_fb_helper_restore(void)
78 {
79 bool ret;
80 ret = drm_fb_helper_force_kernel_mode();
81 if (ret == true)
82 DRM_ERROR("Failed to restore crtc configuration\n");
83 }
84 EXPORT_SYMBOL(drm_fb_helper_restore);
85
86 static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
87 {
88 drm_fb_helper_restore();
89 }
90 static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
91
92 static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3)
93 {
94 schedule_work(&drm_fb_helper_restore_work);
95 }
96
97 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
98 .handler = drm_fb_helper_sysrq,
99 .help_msg = "force-fb(V)",
100 .action_msg = "Restore framebuffer console",
101 };
102
103 static void drm_fb_helper_on(struct fb_info *info)
104 {
105 struct drm_fb_helper *fb_helper = info->par;
106 struct drm_device *dev = fb_helper->dev;
107 struct drm_crtc *crtc;
108 struct drm_encoder *encoder;
109 int i;
110
111 /*
112 * For each CRTC in this fb, turn the crtc on then,
113 * find all associated encoders and turn them on.
114 */
115 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
116 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
117
118 for (i = 0; i < fb_helper->crtc_count; i++) {
119 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
120 break;
121 }
122
123 mutex_lock(&dev->mode_config.mutex);
124 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
125 mutex_unlock(&dev->mode_config.mutex);
126
127 /* Found a CRTC on this fb, now find encoders */
128 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
129 if (encoder->crtc == crtc) {
130 struct drm_encoder_helper_funcs *encoder_funcs;
131
132 encoder_funcs = encoder->helper_private;
133 mutex_lock(&dev->mode_config.mutex);
134 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
135 mutex_unlock(&dev->mode_config.mutex);
136 }
137 }
138 }
139 }
140
141 static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
142 {
143 struct drm_fb_helper *fb_helper = info->par;
144 struct drm_device *dev = fb_helper->dev;
145 struct drm_crtc *crtc;
146 struct drm_encoder *encoder;
147 int i;
148
149 /*
150 * For each CRTC in this fb, find all associated encoders
151 * and turn them off, then turn off the CRTC.
152 */
153 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
154 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
155
156 for (i = 0; i < fb_helper->crtc_count; i++) {
157 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
158 break;
159 }
160
161 /* Found a CRTC on this fb, now find encoders */
162 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
163 if (encoder->crtc == crtc) {
164 struct drm_encoder_helper_funcs *encoder_funcs;
165
166 encoder_funcs = encoder->helper_private;
167 mutex_lock(&dev->mode_config.mutex);
168 encoder_funcs->dpms(encoder, dpms_mode);
169 mutex_unlock(&dev->mode_config.mutex);
170 }
171 }
172 if (dpms_mode == DRM_MODE_DPMS_OFF) {
173 mutex_lock(&dev->mode_config.mutex);
174 crtc_funcs->dpms(crtc, dpms_mode);
175 mutex_unlock(&dev->mode_config.mutex);
176 }
177 }
178 }
179
180 int drm_fb_helper_blank(int blank, struct fb_info *info)
181 {
182 switch (blank) {
183 case FB_BLANK_UNBLANK:
184 drm_fb_helper_on(info);
185 break;
186 case FB_BLANK_NORMAL:
187 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
188 break;
189 case FB_BLANK_HSYNC_SUSPEND:
190 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
191 break;
192 case FB_BLANK_VSYNC_SUSPEND:
193 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
194 break;
195 case FB_BLANK_POWERDOWN:
196 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
197 break;
198 }
199 return 0;
200 }
201 EXPORT_SYMBOL(drm_fb_helper_blank);
202
203 static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
204 {
205 int i;
206
207 for (i = 0; i < helper->crtc_count; i++)
208 kfree(helper->crtc_info[i].mode_set.connectors);
209 kfree(helper->crtc_info);
210 }
211
212 int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn_count)
213 {
214 struct drm_device *dev = helper->dev;
215 struct drm_crtc *crtc;
216 int ret = 0;
217 int i;
218
219 helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
220 if (!helper->crtc_info)
221 return -ENOMEM;
222
223 helper->crtc_count = crtc_count;
224
225 for (i = 0; i < crtc_count; i++) {
226 helper->crtc_info[i].mode_set.connectors =
227 kcalloc(max_conn_count,
228 sizeof(struct drm_connector *),
229 GFP_KERNEL);
230
231 if (!helper->crtc_info[i].mode_set.connectors) {
232 ret = -ENOMEM;
233 goto out_free;
234 }
235 helper->crtc_info[i].mode_set.num_connectors = 0;
236 }
237
238 i = 0;
239 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
240 helper->crtc_info[i].crtc_id = crtc->base.id;
241 helper->crtc_info[i].mode_set.crtc = crtc;
242 i++;
243 }
244 helper->conn_limit = max_conn_count;
245 return 0;
246 out_free:
247 drm_fb_helper_crtc_free(helper);
248 return -ENOMEM;
249 }
250 EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
251
252 int drm_fb_helper_setcolreg(unsigned regno,
253 unsigned red,
254 unsigned green,
255 unsigned blue,
256 unsigned transp,
257 struct fb_info *info)
258 {
259 struct drm_fb_helper *fb_helper = info->par;
260 struct drm_device *dev = fb_helper->dev;
261 struct drm_crtc *crtc;
262 int i;
263
264 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
265 struct drm_framebuffer *fb = fb_helper->fb;
266
267 for (i = 0; i < fb_helper->crtc_count; i++) {
268 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
269 break;
270 }
271 if (i == fb_helper->crtc_count)
272 continue;
273
274 if (regno > 255)
275 return 1;
276
277 if (fb->depth == 8) {
278 fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
279 return 0;
280 }
281
282 if (regno < 16) {
283 switch (fb->depth) {
284 case 15:
285 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
286 ((green & 0xf800) >> 6) |
287 ((blue & 0xf800) >> 11);
288 break;
289 case 16:
290 fb->pseudo_palette[regno] = (red & 0xf800) |
291 ((green & 0xfc00) >> 5) |
292 ((blue & 0xf800) >> 11);
293 break;
294 case 24:
295 case 32:
296 fb->pseudo_palette[regno] =
297 (((red >> 8) & 0xff) << info->var.red.offset) |
298 (((green >> 8) & 0xff) << info->var.green.offset) |
299 (((blue >> 8) & 0xff) << info->var.blue.offset);
300 break;
301 }
302 }
303 }
304 return 0;
305 }
306 EXPORT_SYMBOL(drm_fb_helper_setcolreg);
307
308 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
309 struct fb_info *info)
310 {
311 struct drm_fb_helper *fb_helper = info->par;
312 struct drm_framebuffer *fb = fb_helper->fb;
313 int depth;
314
315 if (var->pixclock == -1 || !var->pixclock)
316 return -EINVAL;
317
318 /* Need to resize the fb object !!! */
319 if (var->xres > fb->width || var->yres > fb->height) {
320 DRM_ERROR("Requested width/height is greater than current fb "
321 "object %dx%d > %dx%d\n", var->xres, var->yres,
322 fb->width, fb->height);
323 DRM_ERROR("Need resizing code.\n");
324 return -EINVAL;
325 }
326
327 switch (var->bits_per_pixel) {
328 case 16:
329 depth = (var->green.length == 6) ? 16 : 15;
330 break;
331 case 32:
332 depth = (var->transp.length > 0) ? 32 : 24;
333 break;
334 default:
335 depth = var->bits_per_pixel;
336 break;
337 }
338
339 switch (depth) {
340 case 8:
341 var->red.offset = 0;
342 var->green.offset = 0;
343 var->blue.offset = 0;
344 var->red.length = 8;
345 var->green.length = 8;
346 var->blue.length = 8;
347 var->transp.length = 0;
348 var->transp.offset = 0;
349 break;
350 case 15:
351 var->red.offset = 10;
352 var->green.offset = 5;
353 var->blue.offset = 0;
354 var->red.length = 5;
355 var->green.length = 5;
356 var->blue.length = 5;
357 var->transp.length = 1;
358 var->transp.offset = 15;
359 break;
360 case 16:
361 var->red.offset = 11;
362 var->green.offset = 5;
363 var->blue.offset = 0;
364 var->red.length = 5;
365 var->green.length = 6;
366 var->blue.length = 5;
367 var->transp.length = 0;
368 var->transp.offset = 0;
369 break;
370 case 24:
371 var->red.offset = 16;
372 var->green.offset = 8;
373 var->blue.offset = 0;
374 var->red.length = 8;
375 var->green.length = 8;
376 var->blue.length = 8;
377 var->transp.length = 0;
378 var->transp.offset = 0;
379 break;
380 case 32:
381 var->red.offset = 16;
382 var->green.offset = 8;
383 var->blue.offset = 0;
384 var->red.length = 8;
385 var->green.length = 8;
386 var->blue.length = 8;
387 var->transp.length = 8;
388 var->transp.offset = 24;
389 break;
390 default:
391 return -EINVAL;
392 }
393 return 0;
394 }
395 EXPORT_SYMBOL(drm_fb_helper_check_var);
396
397 /* this will let fbcon do the mode init */
398 int drm_fb_helper_set_par(struct fb_info *info)
399 {
400 struct drm_fb_helper *fb_helper = info->par;
401 struct drm_device *dev = fb_helper->dev;
402 struct fb_var_screeninfo *var = &info->var;
403 struct drm_crtc *crtc;
404 int ret;
405 int i;
406
407 if (var->pixclock != -1) {
408 DRM_ERROR("PIXEL CLCOK SET\n");
409 return -EINVAL;
410 }
411
412 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
413
414 for (i = 0; i < fb_helper->crtc_count; i++) {
415 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
416 break;
417 }
418 if (i == fb_helper->crtc_count)
419 continue;
420
421 if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
422 mutex_lock(&dev->mode_config.mutex);
423 ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
424 mutex_unlock(&dev->mode_config.mutex);
425 if (ret)
426 return ret;
427 }
428 }
429 return 0;
430 }
431 EXPORT_SYMBOL(drm_fb_helper_set_par);
432
433 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
434 struct fb_info *info)
435 {
436 struct drm_fb_helper *fb_helper = info->par;
437 struct drm_device *dev = fb_helper->dev;
438 struct drm_mode_set *modeset;
439 struct drm_crtc *crtc;
440 int ret = 0;
441 int i;
442
443 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
444 for (i = 0; i < fb_helper->crtc_count; i++) {
445 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
446 break;
447 }
448
449 if (i == fb_helper->crtc_count)
450 continue;
451
452 modeset = &fb_helper->crtc_info[i].mode_set;
453
454 modeset->x = var->xoffset;
455 modeset->y = var->yoffset;
456
457 if (modeset->num_connectors) {
458 mutex_lock(&dev->mode_config.mutex);
459 ret = crtc->funcs->set_config(modeset);
460 mutex_unlock(&dev->mode_config.mutex);
461 if (!ret) {
462 info->var.xoffset = var->xoffset;
463 info->var.yoffset = var->yoffset;
464 }
465 }
466 }
467 return ret;
468 }
469 EXPORT_SYMBOL(drm_fb_helper_pan_display);
470
471 int drm_fb_helper_single_fb_probe(struct drm_device *dev,
472 int (*fb_create)(struct drm_device *dev,
473 uint32_t fb_width,
474 uint32_t fb_height,
475 uint32_t surface_width,
476 uint32_t surface_height,
477 struct drm_framebuffer **fb_ptr))
478 {
479 struct drm_crtc *crtc;
480 struct drm_connector *connector;
481 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
482 unsigned int surface_width = 0, surface_height = 0;
483 int new_fb = 0;
484 int crtc_count = 0;
485 int ret, i, conn_count = 0;
486 struct fb_info *info;
487 struct drm_framebuffer *fb;
488 struct drm_mode_set *modeset = NULL;
489 struct drm_fb_helper *fb_helper;
490
491 /* first up get a count of crtcs now in use and new min/maxes width/heights */
492 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
493 if (drm_helper_crtc_in_use(crtc)) {
494 if (crtc->desired_mode) {
495 if (crtc->desired_mode->hdisplay < fb_width)
496 fb_width = crtc->desired_mode->hdisplay;
497
498 if (crtc->desired_mode->vdisplay < fb_height)
499 fb_height = crtc->desired_mode->vdisplay;
500
501 if (crtc->desired_mode->hdisplay > surface_width)
502 surface_width = crtc->desired_mode->hdisplay;
503
504 if (crtc->desired_mode->vdisplay > surface_height)
505 surface_height = crtc->desired_mode->vdisplay;
506 }
507 crtc_count++;
508 }
509 }
510
511 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
512 /* hmm everyone went away - assume VGA cable just fell out
513 and will come back later. */
514 return 0;
515 }
516
517 /* do we have an fb already? */
518 if (list_empty(&dev->mode_config.fb_kernel_list)) {
519 ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
520 surface_height, &fb);
521 if (ret)
522 return -EINVAL;
523 new_fb = 1;
524 } else {
525 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
526 struct drm_framebuffer, filp_head);
527
528 /* if someone hotplugs something bigger than we have already allocated, we are pwned.
529 As really we can't resize an fbdev that is in the wild currently due to fbdev
530 not really being designed for the lower layers moving stuff around under it.
531 - so in the grand style of things - punt. */
532 if ((fb->width < surface_width) ||
533 (fb->height < surface_height)) {
534 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
535 return -EINVAL;
536 }
537 }
538
539 info = fb->fbdev;
540 fb_helper = info->par;
541
542 crtc_count = 0;
543 /* okay we need to setup new connector sets in the crtcs */
544 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
545 modeset = &fb_helper->crtc_info[crtc_count].mode_set;
546 modeset->fb = fb;
547 conn_count = 0;
548 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
549 if (connector->encoder)
550 if (connector->encoder->crtc == modeset->crtc) {
551 modeset->connectors[conn_count] = connector;
552 conn_count++;
553 if (conn_count > fb_helper->conn_limit)
554 BUG();
555 }
556 }
557
558 for (i = conn_count; i < fb_helper->conn_limit; i++)
559 modeset->connectors[i] = NULL;
560
561 modeset->crtc = crtc;
562 crtc_count++;
563
564 modeset->num_connectors = conn_count;
565 if (modeset->crtc->desired_mode) {
566 if (modeset->mode)
567 drm_mode_destroy(dev, modeset->mode);
568 modeset->mode = drm_mode_duplicate(dev,
569 modeset->crtc->desired_mode);
570 }
571 }
572 fb_helper->crtc_count = crtc_count;
573 fb_helper->fb = fb;
574
575 if (new_fb) {
576 info->var.pixclock = -1;
577 if (register_framebuffer(info) < 0)
578 return -EINVAL;
579 } else {
580 drm_fb_helper_set_par(info);
581 }
582 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
583 info->fix.id);
584
585 /* Switch back to kernel console on panic */
586 /* multi card linked list maybe */
587 if (list_empty(&kernel_fb_helper_list)) {
588 printk(KERN_INFO "registered panic notifier\n");
589 atomic_notifier_chain_register(&panic_notifier_list,
590 &paniced);
591 register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
592 }
593 list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
594 return 0;
595 }
596 EXPORT_SYMBOL(drm_fb_helper_single_fb_probe);
597
598 void drm_fb_helper_free(struct drm_fb_helper *helper)
599 {
600 list_del(&helper->kernel_fb_list);
601 if (list_empty(&kernel_fb_helper_list)) {
602 printk(KERN_INFO "unregistered panic notifier\n");
603 atomic_notifier_chain_unregister(&panic_notifier_list,
604 &paniced);
605 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
606 }
607 drm_fb_helper_crtc_free(helper);
608 }
609 EXPORT_SYMBOL(drm_fb_helper_free);
610
611 void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
612 {
613 info->fix.type = FB_TYPE_PACKED_PIXELS;
614 info->fix.visual = FB_VISUAL_TRUECOLOR;
615 info->fix.type_aux = 0;
616 info->fix.xpanstep = 1; /* doing it in hw */
617 info->fix.ypanstep = 1; /* doing it in hw */
618 info->fix.ywrapstep = 0;
619 info->fix.accel = FB_ACCEL_I830;
620 info->fix.type_aux = 0;
621
622 info->fix.line_length = pitch;
623 return;
624 }
625 EXPORT_SYMBOL(drm_fb_helper_fill_fix);
626
627 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
628 uint32_t fb_width, uint32_t fb_height)
629 {
630 info->pseudo_palette = fb->pseudo_palette;
631 info->var.xres_virtual = fb->width;
632 info->var.yres_virtual = fb->height;
633 info->var.bits_per_pixel = fb->bits_per_pixel;
634 info->var.xoffset = 0;
635 info->var.yoffset = 0;
636 info->var.activate = FB_ACTIVATE_NOW;
637 info->var.height = -1;
638 info->var.width = -1;
639
640 switch (fb->depth) {
641 case 8:
642 info->var.red.offset = 0;
643 info->var.green.offset = 0;
644 info->var.blue.offset = 0;
645 info->var.red.length = 8; /* 8bit DAC */
646 info->var.green.length = 8;
647 info->var.blue.length = 8;
648 info->var.transp.offset = 0;
649 info->var.transp.length = 0;
650 break;
651 case 15:
652 info->var.red.offset = 10;
653 info->var.green.offset = 5;
654 info->var.blue.offset = 0;
655 info->var.red.length = 5;
656 info->var.green.length = 5;
657 info->var.blue.length = 5;
658 info->var.transp.offset = 15;
659 info->var.transp.length = 1;
660 break;
661 case 16:
662 info->var.red.offset = 11;
663 info->var.green.offset = 5;
664 info->var.blue.offset = 0;
665 info->var.red.length = 5;
666 info->var.green.length = 6;
667 info->var.blue.length = 5;
668 info->var.transp.offset = 0;
669 break;
670 case 24:
671 info->var.red.offset = 16;
672 info->var.green.offset = 8;
673 info->var.blue.offset = 0;
674 info->var.red.length = 8;
675 info->var.green.length = 8;
676 info->var.blue.length = 8;
677 info->var.transp.offset = 0;
678 info->var.transp.length = 0;
679 break;
680 case 32:
681 info->var.red.offset = 16;
682 info->var.green.offset = 8;
683 info->var.blue.offset = 0;
684 info->var.red.length = 8;
685 info->var.green.length = 8;
686 info->var.blue.length = 8;
687 info->var.transp.offset = 24;
688 info->var.transp.length = 8;
689 break;
690 default:
691 break;
692 }
693
694 info->var.xres = fb_width;
695 info->var.yres = fb_height;
696 }
697 EXPORT_SYMBOL(drm_fb_helper_fill_var);
This page took 0.062183 seconds and 5 git commands to generate.