2 * Copyright (c) 2006-2009 Red Hat Inc.
3 * Copyright (c) 2006-2008 Intel Corporation
4 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
6 * DRM framebuffer helper functions
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.
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
27 * Dave Airlie <airlied@linux.ie>
28 * Jesse Barnes <jesse.barnes@intel.com>
30 #include <linux/sysrq.h>
34 #include "drm_fb_helper.h"
35 #include "drm_crtc_helper.h"
37 MODULE_AUTHOR("David Airlie, Jesse Barnes");
38 MODULE_DESCRIPTION("DRM KMS helper");
39 MODULE_LICENSE("GPL and additional rights");
41 static LIST_HEAD(kernel_fb_helper_list);
43 int drm_fb_helper_add_connector(struct drm_connector *connector)
45 connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
46 if (!connector->fb_helper_private)
52 EXPORT_SYMBOL(drm_fb_helper_add_connector);
54 static int my_atoi(const char *name)
61 val = 10*val+(*name-'0');
70 * drm_fb_helper_connector_parse_command_line - parse command line for connector
71 * @connector - connector to parse line for
72 * @mode_option - per connector mode option
74 * This parses the connector specific then generic command lines for
75 * modes and options to configure the connector.
77 * This uses the same parameters as the fb modedb.c, except for extra
78 * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
80 * enable/enable Digital/disable bit at the end
82 static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector,
83 const char *mode_option)
87 int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
88 unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
89 int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
91 enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
92 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
93 struct drm_fb_helper_cmdline_mode *cmdline_mode = &fb_help_conn->cmdline_mode;
96 mode_option = fb_mode_option;
99 cmdline_mode->specified = false;
104 namelen = strlen(name);
105 for (i = namelen-1; i >= 0; i--) {
109 if (!refresh_specified && !bpp_specified &&
111 refresh = my_atoi(&name[i+1]);
112 refresh_specified = 1;
120 if (!bpp_specified && !yres_specified) {
121 bpp = my_atoi(&name[i+1]);
129 if (!yres_specified) {
130 yres = my_atoi(&name[i+1]);
153 force = DRM_FORCE_ON;
156 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) ||
157 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
158 force = DRM_FORCE_ON;
160 force = DRM_FORCE_ON_DIGITAL;
163 force = DRM_FORCE_OFF;
169 if (i < 0 && yres_specified) {
170 xres = my_atoi(name);
175 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
176 drm_get_connector_name(connector), xres, yres,
177 (refresh) ? refresh : 60, (rb) ? " reduced blanking" :
178 "", (margins) ? " with margins" : "", (interlace) ?
184 case DRM_FORCE_OFF: s = "OFF"; break;
185 case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
187 case DRM_FORCE_ON: s = "ON"; break;
190 DRM_INFO("forcing %s connector %s\n",
191 drm_get_connector_name(connector), s);
192 connector->force = force;
196 cmdline_mode->specified = true;
197 cmdline_mode->xres = xres;
198 cmdline_mode->yres = yres;
201 if (refresh_specified) {
202 cmdline_mode->refresh_specified = true;
203 cmdline_mode->refresh = refresh;
207 cmdline_mode->bpp_specified = true;
208 cmdline_mode->bpp = bpp;
210 cmdline_mode->rb = rb ? true : false;
211 cmdline_mode->cvt = cvt ? true : false;
212 cmdline_mode->interlace = interlace ? true : false;
217 int drm_fb_helper_parse_command_line(struct drm_device *dev)
219 struct drm_connector *connector;
221 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
224 /* do something on return - turn off connector maybe */
225 if (fb_get_options(drm_get_connector_name(connector), &option))
228 drm_fb_helper_connector_parse_command_line(connector, option);
233 bool drm_fb_helper_force_kernel_mode(void)
236 bool ret, error = false;
237 struct drm_fb_helper *helper;
239 if (list_empty(&kernel_fb_helper_list))
242 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
243 for (i = 0; i < helper->crtc_count; i++) {
244 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
245 ret = drm_crtc_helper_set_config(mode_set);
253 int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
256 DRM_ERROR("panic occurred, switching back to text console\n");
257 return drm_fb_helper_force_kernel_mode();
260 EXPORT_SYMBOL(drm_fb_helper_panic);
262 static struct notifier_block paniced = {
263 .notifier_call = drm_fb_helper_panic,
267 * drm_fb_helper_restore - restore the framebuffer console (kernel) config
269 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
271 void drm_fb_helper_restore(void)
274 ret = drm_fb_helper_force_kernel_mode();
276 DRM_ERROR("Failed to restore crtc configuration\n");
278 EXPORT_SYMBOL(drm_fb_helper_restore);
280 static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
282 drm_fb_helper_restore();
284 static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
286 static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3)
288 schedule_work(&drm_fb_helper_restore_work);
291 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
292 .handler = drm_fb_helper_sysrq,
293 .help_msg = "force-fb(V)",
294 .action_msg = "Restore framebuffer console",
297 static void drm_fb_helper_on(struct fb_info *info)
299 struct drm_fb_helper *fb_helper = info->par;
300 struct drm_device *dev = fb_helper->dev;
301 struct drm_crtc *crtc;
302 struct drm_encoder *encoder;
306 * For each CRTC in this fb, turn the crtc on then,
307 * find all associated encoders and turn them on.
309 for (i = 0; i < fb_helper->crtc_count; i++) {
310 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
311 struct drm_crtc_helper_funcs *crtc_funcs =
312 crtc->helper_private;
314 /* Only mess with CRTCs in this fb */
315 if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
319 mutex_lock(&dev->mode_config.mutex);
320 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
321 mutex_unlock(&dev->mode_config.mutex);
323 /* Found a CRTC on this fb, now find encoders */
324 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
325 if (encoder->crtc == crtc) {
326 struct drm_encoder_helper_funcs *encoder_funcs;
328 encoder_funcs = encoder->helper_private;
329 mutex_lock(&dev->mode_config.mutex);
330 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
331 mutex_unlock(&dev->mode_config.mutex);
338 static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
340 struct drm_fb_helper *fb_helper = info->par;
341 struct drm_device *dev = fb_helper->dev;
342 struct drm_crtc *crtc;
343 struct drm_encoder *encoder;
347 * For each CRTC in this fb, find all associated encoders
348 * and turn them off, then turn off the CRTC.
350 for (i = 0; i < fb_helper->crtc_count; i++) {
351 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
352 struct drm_crtc_helper_funcs *crtc_funcs =
353 crtc->helper_private;
355 /* Only mess with CRTCs in this fb */
356 if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
360 /* Found a CRTC on this fb, now find encoders */
361 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
362 if (encoder->crtc == crtc) {
363 struct drm_encoder_helper_funcs *encoder_funcs;
365 encoder_funcs = encoder->helper_private;
366 mutex_lock(&dev->mode_config.mutex);
367 encoder_funcs->dpms(encoder, dpms_mode);
368 mutex_unlock(&dev->mode_config.mutex);
371 if (dpms_mode == DRM_MODE_DPMS_OFF) {
372 mutex_lock(&dev->mode_config.mutex);
373 crtc_funcs->dpms(crtc, dpms_mode);
374 mutex_unlock(&dev->mode_config.mutex);
380 int drm_fb_helper_blank(int blank, struct fb_info *info)
383 case FB_BLANK_UNBLANK:
384 drm_fb_helper_on(info);
386 case FB_BLANK_NORMAL:
387 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
389 case FB_BLANK_HSYNC_SUSPEND:
390 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
392 case FB_BLANK_VSYNC_SUSPEND:
393 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
395 case FB_BLANK_POWERDOWN:
396 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
401 EXPORT_SYMBOL(drm_fb_helper_blank);
403 static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
407 for (i = 0; i < helper->crtc_count; i++)
408 kfree(helper->crtc_info[i].mode_set.connectors);
409 kfree(helper->crtc_info);
412 int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn_count)
414 struct drm_device *dev = helper->dev;
415 struct drm_crtc *crtc;
419 helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
420 if (!helper->crtc_info)
423 helper->crtc_count = crtc_count;
425 for (i = 0; i < crtc_count; i++) {
426 helper->crtc_info[i].mode_set.connectors =
427 kcalloc(max_conn_count,
428 sizeof(struct drm_connector *),
431 if (!helper->crtc_info[i].mode_set.connectors) {
435 helper->crtc_info[i].mode_set.num_connectors = 0;
439 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
440 helper->crtc_info[i].crtc_id = crtc->base.id;
441 helper->crtc_info[i].mode_set.crtc = crtc;
444 helper->conn_limit = max_conn_count;
447 drm_fb_helper_crtc_free(helper);
450 EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
452 int drm_fb_helper_setcolreg(unsigned regno,
457 struct fb_info *info)
459 struct drm_fb_helper *fb_helper = info->par;
460 struct drm_device *dev = fb_helper->dev;
461 struct drm_crtc *crtc;
464 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
465 struct drm_framebuffer *fb = fb_helper->fb;
467 for (i = 0; i < fb_helper->crtc_count; i++) {
468 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
471 if (i == fb_helper->crtc_count)
477 if (fb->depth == 8) {
478 fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
485 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
486 ((green & 0xf800) >> 6) |
487 ((blue & 0xf800) >> 11);
490 fb->pseudo_palette[regno] = (red & 0xf800) |
491 ((green & 0xfc00) >> 5) |
492 ((blue & 0xf800) >> 11);
496 fb->pseudo_palette[regno] =
497 (((red >> 8) & 0xff) << info->var.red.offset) |
498 (((green >> 8) & 0xff) << info->var.green.offset) |
499 (((blue >> 8) & 0xff) << info->var.blue.offset);
506 EXPORT_SYMBOL(drm_fb_helper_setcolreg);
508 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
509 struct fb_info *info)
511 struct drm_fb_helper *fb_helper = info->par;
512 struct drm_framebuffer *fb = fb_helper->fb;
515 if (var->pixclock == -1 || !var->pixclock)
518 /* Need to resize the fb object !!! */
519 if (var->xres > fb->width || var->yres > fb->height) {
520 DRM_ERROR("Requested width/height is greater than current fb "
521 "object %dx%d > %dx%d\n", var->xres, var->yres,
522 fb->width, fb->height);
523 DRM_ERROR("Need resizing code.\n");
527 switch (var->bits_per_pixel) {
529 depth = (var->green.length == 6) ? 16 : 15;
532 depth = (var->transp.length > 0) ? 32 : 24;
535 depth = var->bits_per_pixel;
542 var->green.offset = 0;
543 var->blue.offset = 0;
545 var->green.length = 8;
546 var->blue.length = 8;
547 var->transp.length = 0;
548 var->transp.offset = 0;
551 var->red.offset = 10;
552 var->green.offset = 5;
553 var->blue.offset = 0;
555 var->green.length = 5;
556 var->blue.length = 5;
557 var->transp.length = 1;
558 var->transp.offset = 15;
561 var->red.offset = 11;
562 var->green.offset = 5;
563 var->blue.offset = 0;
565 var->green.length = 6;
566 var->blue.length = 5;
567 var->transp.length = 0;
568 var->transp.offset = 0;
571 var->red.offset = 16;
572 var->green.offset = 8;
573 var->blue.offset = 0;
575 var->green.length = 8;
576 var->blue.length = 8;
577 var->transp.length = 0;
578 var->transp.offset = 0;
581 var->red.offset = 16;
582 var->green.offset = 8;
583 var->blue.offset = 0;
585 var->green.length = 8;
586 var->blue.length = 8;
587 var->transp.length = 8;
588 var->transp.offset = 24;
595 EXPORT_SYMBOL(drm_fb_helper_check_var);
597 /* this will let fbcon do the mode init */
598 int drm_fb_helper_set_par(struct fb_info *info)
600 struct drm_fb_helper *fb_helper = info->par;
601 struct drm_device *dev = fb_helper->dev;
602 struct fb_var_screeninfo *var = &info->var;
603 struct drm_crtc *crtc;
607 if (var->pixclock != -1) {
608 DRM_ERROR("PIXEL CLCOK SET\n");
612 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
614 for (i = 0; i < fb_helper->crtc_count; i++) {
615 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
618 if (i == fb_helper->crtc_count)
621 if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
622 mutex_lock(&dev->mode_config.mutex);
623 ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
624 mutex_unlock(&dev->mode_config.mutex);
631 EXPORT_SYMBOL(drm_fb_helper_set_par);
633 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
634 struct fb_info *info)
636 struct drm_fb_helper *fb_helper = info->par;
637 struct drm_device *dev = fb_helper->dev;
638 struct drm_mode_set *modeset;
639 struct drm_crtc *crtc;
643 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
644 for (i = 0; i < fb_helper->crtc_count; i++) {
645 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
649 if (i == fb_helper->crtc_count)
652 modeset = &fb_helper->crtc_info[i].mode_set;
654 modeset->x = var->xoffset;
655 modeset->y = var->yoffset;
657 if (modeset->num_connectors) {
658 mutex_lock(&dev->mode_config.mutex);
659 ret = crtc->funcs->set_config(modeset);
660 mutex_unlock(&dev->mode_config.mutex);
662 info->var.xoffset = var->xoffset;
663 info->var.yoffset = var->yoffset;
669 EXPORT_SYMBOL(drm_fb_helper_pan_display);
671 int drm_fb_helper_single_fb_probe(struct drm_device *dev,
672 int (*fb_create)(struct drm_device *dev,
675 uint32_t surface_width,
676 uint32_t surface_height,
677 uint32_t surface_depth,
678 uint32_t surface_bpp,
679 struct drm_framebuffer **fb_ptr))
681 struct drm_crtc *crtc;
682 struct drm_connector *connector;
683 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
684 unsigned int surface_width = 0, surface_height = 0;
687 int ret, i, conn_count = 0;
688 struct fb_info *info;
689 struct drm_framebuffer *fb;
690 struct drm_mode_set *modeset = NULL;
691 struct drm_fb_helper *fb_helper;
692 uint32_t surface_depth = 24, surface_bpp = 32;
694 /* first up get a count of crtcs now in use and new min/maxes width/heights */
695 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
696 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
697 struct drm_fb_helper_cmdline_mode *cmdline_mode = &fb_help_conn->cmdline_mode;
699 if (cmdline_mode->bpp_specified) {
700 switch (cmdline_mode->bpp) {
702 surface_depth = surface_bpp = 8;
709 surface_depth = surface_bpp = 16;
712 surface_depth = surface_bpp = 24;
723 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
724 if (drm_helper_crtc_in_use(crtc)) {
725 if (crtc->desired_mode) {
726 if (crtc->desired_mode->hdisplay < fb_width)
727 fb_width = crtc->desired_mode->hdisplay;
729 if (crtc->desired_mode->vdisplay < fb_height)
730 fb_height = crtc->desired_mode->vdisplay;
732 if (crtc->desired_mode->hdisplay > surface_width)
733 surface_width = crtc->desired_mode->hdisplay;
735 if (crtc->desired_mode->vdisplay > surface_height)
736 surface_height = crtc->desired_mode->vdisplay;
742 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
743 /* hmm everyone went away - assume VGA cable just fell out
744 and will come back later. */
748 /* do we have an fb already? */
749 if (list_empty(&dev->mode_config.fb_kernel_list)) {
750 ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
751 surface_height, surface_depth, surface_bpp,
757 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
758 struct drm_framebuffer, filp_head);
760 /* if someone hotplugs something bigger than we have already allocated, we are pwned.
761 As really we can't resize an fbdev that is in the wild currently due to fbdev
762 not really being designed for the lower layers moving stuff around under it.
763 - so in the grand style of things - punt. */
764 if ((fb->width < surface_width) ||
765 (fb->height < surface_height)) {
766 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
772 fb_helper = info->par;
775 /* okay we need to setup new connector sets in the crtcs */
776 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
777 modeset = &fb_helper->crtc_info[crtc_count].mode_set;
780 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
781 if (connector->encoder)
782 if (connector->encoder->crtc == modeset->crtc) {
783 modeset->connectors[conn_count] = connector;
785 if (conn_count > fb_helper->conn_limit)
790 for (i = conn_count; i < fb_helper->conn_limit; i++)
791 modeset->connectors[i] = NULL;
793 modeset->crtc = crtc;
796 modeset->num_connectors = conn_count;
797 if (modeset->crtc->desired_mode) {
799 drm_mode_destroy(dev, modeset->mode);
800 modeset->mode = drm_mode_duplicate(dev,
801 modeset->crtc->desired_mode);
804 fb_helper->crtc_count = crtc_count;
808 info->var.pixclock = -1;
809 if (register_framebuffer(info) < 0)
812 drm_fb_helper_set_par(info);
814 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
817 /* Switch back to kernel console on panic */
818 /* multi card linked list maybe */
819 if (list_empty(&kernel_fb_helper_list)) {
820 printk(KERN_INFO "registered panic notifier\n");
821 atomic_notifier_chain_register(&panic_notifier_list,
823 register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
825 list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
828 EXPORT_SYMBOL(drm_fb_helper_single_fb_probe);
830 void drm_fb_helper_free(struct drm_fb_helper *helper)
832 list_del(&helper->kernel_fb_list);
833 if (list_empty(&kernel_fb_helper_list)) {
834 printk(KERN_INFO "unregistered panic notifier\n");
835 atomic_notifier_chain_unregister(&panic_notifier_list,
837 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
839 drm_fb_helper_crtc_free(helper);
841 EXPORT_SYMBOL(drm_fb_helper_free);
843 void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
845 info->fix.type = FB_TYPE_PACKED_PIXELS;
846 info->fix.visual = FB_VISUAL_TRUECOLOR;
847 info->fix.type_aux = 0;
848 info->fix.xpanstep = 1; /* doing it in hw */
849 info->fix.ypanstep = 1; /* doing it in hw */
850 info->fix.ywrapstep = 0;
851 info->fix.accel = FB_ACCEL_NONE;
852 info->fix.type_aux = 0;
854 info->fix.line_length = pitch;
857 EXPORT_SYMBOL(drm_fb_helper_fill_fix);
859 void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
860 uint32_t fb_width, uint32_t fb_height)
862 info->pseudo_palette = fb->pseudo_palette;
863 info->var.xres_virtual = fb->width;
864 info->var.yres_virtual = fb->height;
865 info->var.bits_per_pixel = fb->bits_per_pixel;
866 info->var.xoffset = 0;
867 info->var.yoffset = 0;
868 info->var.activate = FB_ACTIVATE_NOW;
869 info->var.height = -1;
870 info->var.width = -1;
874 info->var.red.offset = 0;
875 info->var.green.offset = 0;
876 info->var.blue.offset = 0;
877 info->var.red.length = 8; /* 8bit DAC */
878 info->var.green.length = 8;
879 info->var.blue.length = 8;
880 info->var.transp.offset = 0;
881 info->var.transp.length = 0;
884 info->var.red.offset = 10;
885 info->var.green.offset = 5;
886 info->var.blue.offset = 0;
887 info->var.red.length = 5;
888 info->var.green.length = 5;
889 info->var.blue.length = 5;
890 info->var.transp.offset = 15;
891 info->var.transp.length = 1;
894 info->var.red.offset = 11;
895 info->var.green.offset = 5;
896 info->var.blue.offset = 0;
897 info->var.red.length = 5;
898 info->var.green.length = 6;
899 info->var.blue.length = 5;
900 info->var.transp.offset = 0;
903 info->var.red.offset = 16;
904 info->var.green.offset = 8;
905 info->var.blue.offset = 0;
906 info->var.red.length = 8;
907 info->var.green.length = 8;
908 info->var.blue.length = 8;
909 info->var.transp.offset = 0;
910 info->var.transp.length = 0;
913 info->var.red.offset = 16;
914 info->var.green.offset = 8;
915 info->var.blue.offset = 0;
916 info->var.red.length = 8;
917 info->var.green.length = 8;
918 info->var.blue.length = 8;
919 info->var.transp.offset = 24;
920 info->var.transp.length = 8;
926 info->var.xres = fb_width;
927 info->var.yres = fb_height;
929 EXPORT_SYMBOL(drm_fb_helper_fill_var);