Subversion Repositories Kolibri OS

Rev

Rev 1221 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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