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