Subversion Repositories Kolibri OS

Rev

Rev 1179 | Rev 1246 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1179 Rev 1221
Line 38... Line 38...
38
//MODULE_DESCRIPTION("DRM KMS helper");
38
//MODULE_DESCRIPTION("DRM KMS helper");
39
//MODULE_LICENSE("GPL and additional rights");
39
//MODULE_LICENSE("GPL and additional rights");
Line 40... Line 40...
40
 
40
 
Line -... Line 41...
-
 
41
static LIST_HEAD(kernel_fb_helper_list);
-
 
42
 
-
 
43
int drm_fb_helper_add_connector(struct drm_connector *connector)
-
 
44
{
-
 
45
	connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
-
 
46
	if (!connector->fb_helper_private)
-
 
47
		return -ENOMEM;
-
 
48
 
-
 
49
	return 0;
-
 
50
}
41
static LIST_HEAD(kernel_fb_helper_list);
51
EXPORT_SYMBOL(drm_fb_helper_add_connector);
42
 
52
 
43
bool drm_fb_helper_force_kernel_mode(void)
53
bool drm_fb_helper_force_kernel_mode(void)
44
{
54
{
45
	int i = 0;
55
	int i = 0;
Line 228... Line 238...
228
	drm_fb_helper_crtc_free(helper);
238
	drm_fb_helper_crtc_free(helper);
229
	return -ENOMEM;
239
	return -ENOMEM;
230
}
240
}
231
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
241
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
Line -... Line 242...
-
 
242
 
-
 
243
static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
-
 
244
		     u16 blue, u16 regno, struct fb_info *info)
-
 
245
{
-
 
246
	struct drm_fb_helper *fb_helper = info->par;
-
 
247
	struct drm_framebuffer *fb = fb_helper->fb;
-
 
248
	int pindex;
-
 
249
 
-
 
250
	pindex = regno;
-
 
251
 
-
 
252
	if (fb->bits_per_pixel == 16) {
-
 
253
		pindex = regno << 3;
-
 
254
 
-
 
255
		if (fb->depth == 16 && regno > 63)
-
 
256
			return;
-
 
257
		if (fb->depth == 15 && regno > 31)
-
 
258
			return;
-
 
259
 
-
 
260
		if (fb->depth == 16) {
-
 
261
			u16 r, g, b;
-
 
262
			int i;
-
 
263
			if (regno < 32) {
-
 
264
				for (i = 0; i < 8; i++)
-
 
265
					fb_helper->funcs->gamma_set(crtc, red,
-
 
266
						green, blue, pindex + i);
-
 
267
			}
-
 
268
 
-
 
269
			fb_helper->funcs->gamma_get(crtc, &r,
-
 
270
						    &g, &b,
-
 
271
						    pindex >> 1);
-
 
272
 
-
 
273
			for (i = 0; i < 4; i++)
-
 
274
				fb_helper->funcs->gamma_set(crtc, r,
-
 
275
							    green, b,
-
 
276
							    (pindex >> 1) + i);
-
 
277
		}
-
 
278
	}
-
 
279
 
-
 
280
	if (fb->depth != 16)
-
 
281
		fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
-
 
282
 
-
 
283
	if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-
 
284
		((u32 *) fb->pseudo_palette)[regno] =
-
 
285
			(regno << info->var.red.offset) |
-
 
286
			(regno << info->var.green.offset) |
-
 
287
			(regno << info->var.blue.offset);
-
 
288
	}
-
 
289
}
-
 
290
 
-
 
291
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
-
 
292
{
-
 
293
	struct drm_fb_helper *fb_helper = info->par;
-
 
294
	struct drm_device *dev = fb_helper->dev;
-
 
295
	u16 *red, *green, *blue, *transp;
-
 
296
	struct drm_crtc *crtc;
-
 
297
	int i, rc = 0;
-
 
298
	int start;
-
 
299
 
-
 
300
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
301
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
 
302
		for (i = 0; i < fb_helper->crtc_count; i++) {
-
 
303
			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
-
 
304
				break;
-
 
305
		}
-
 
306
		if (i == fb_helper->crtc_count)
-
 
307
			continue;
-
 
308
 
-
 
309
		red = cmap->red;
-
 
310
		green = cmap->green;
-
 
311
		blue = cmap->blue;
-
 
312
		transp = cmap->transp;
-
 
313
		start = cmap->start;
-
 
314
 
-
 
315
		for (i = 0; i < cmap->len; i++) {
-
 
316
			u16 hred, hgreen, hblue, htransp = 0xffff;
-
 
317
 
-
 
318
			hred = *red++;
-
 
319
			hgreen = *green++;
-
 
320
			hblue = *blue++;
-
 
321
 
-
 
322
			if (transp)
-
 
323
				htransp = *transp++;
-
 
324
 
-
 
325
			setcolreg(crtc, hred, hgreen, hblue, start++, info);
-
 
326
		}
-
 
327
		crtc_funcs->load_lut(crtc);
-
 
328
	}
-
 
329
	return rc;
-
 
330
}
-
 
331
EXPORT_SYMBOL(drm_fb_helper_setcmap);
232
 
332
 
233
int drm_fb_helper_setcolreg(unsigned regno,
333
int drm_fb_helper_setcolreg(unsigned regno,
234
			    unsigned red,
334
			    unsigned red,
235
			    unsigned green,
335
			    unsigned green,
236
			    unsigned blue,
336
			    unsigned blue,
Line 240... Line 340...
240
	struct drm_fb_helper *fb_helper = info->par;
340
	struct drm_fb_helper *fb_helper = info->par;
241
	struct drm_device *dev = fb_helper->dev;
341
	struct drm_device *dev = fb_helper->dev;
242
	struct drm_crtc *crtc;
342
	struct drm_crtc *crtc;
243
	int i;
343
	int i;
Line 244... Line 344...
244
 
344
 
245
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
345
	if (regno > 255)
Line -... Line 346...
-
 
346
		return 1;
-
 
347
 
246
		struct drm_framebuffer *fb = fb_helper->fb;
348
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
247
 
349
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
248
		for (i = 0; i < fb_helper->crtc_count; i++) {
350
		for (i = 0; i < fb_helper->crtc_count; i++) {
249
			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
351
			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
250
				break;
352
				break;
251
		}
353
		}
Line 252... Line -...
252
		if (i == fb_helper->crtc_count)
-
 
253
			continue;
-
 
254
 
-
 
255
		if (regno > 255)
-
 
256
			return 1;
-
 
257
 
-
 
258
		if (fb->depth == 8) {
-
 
Line 259... Line -...
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) |
354
		if (i == fb_helper->crtc_count)
268
					((blue & 0xf800) >> 11);
-
 
269
				break;
355
			continue;
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);
356
 
281
				break;
357
 
282
			}
358
		setcolreg(crtc, red, green, blue, regno, info);
283
		}
359
		crtc_funcs->load_lut(crtc);
Line 448... Line 524...
448
	return ret;
524
	return ret;
449
}
525
}
450
EXPORT_SYMBOL(drm_fb_helper_pan_display);
526
EXPORT_SYMBOL(drm_fb_helper_pan_display);
Line 451... Line 527...
451
 
527
 
-
 
528
int drm_fb_helper_single_fb_probe(struct drm_device *dev,
452
int drm_fb_helper_single_fb_probe(struct drm_device *dev,
529
				  int preferred_bpp,
453
				  int (*fb_create)(struct drm_device *dev,
530
				  int (*fb_create)(struct drm_device *dev,
454
						   uint32_t fb_width,
531
						   uint32_t fb_width,
455
						   uint32_t fb_height,
532
						   uint32_t fb_height,
456
						   uint32_t surface_width,
533
						   uint32_t surface_width,
-
 
534
						   uint32_t surface_height,
-
 
535
						   uint32_t surface_depth,
457
						   uint32_t surface_height,
536
						   uint32_t surface_bpp,
458
						   struct drm_framebuffer **fb_ptr))
537
						   struct drm_framebuffer **fb_ptr))
459
{
538
{
460
	struct drm_crtc *crtc;
539
	struct drm_crtc *crtc;
461
	struct drm_connector *connector;
540
	struct drm_connector *connector;
Line 466... Line 545...
466
	int ret, i, conn_count = 0;
545
	int ret, i, conn_count = 0;
467
	struct fb_info *info;
546
	struct fb_info *info;
468
	struct drm_framebuffer *fb;
547
	struct drm_framebuffer *fb;
469
	struct drm_mode_set *modeset = NULL;
548
	struct drm_mode_set *modeset = NULL;
470
	struct drm_fb_helper *fb_helper;
549
	struct drm_fb_helper *fb_helper;
-
 
550
	uint32_t surface_depth = 24, surface_bpp = 32;
Line -... Line 551...
-
 
551
 
-
 
552
	/* if driver picks 8 or 16 by default use that
-
 
553
	   for both depth/bpp */
-
 
554
	if (preferred_bpp != surface_bpp) {
-
 
555
		surface_depth = surface_bpp = preferred_bpp;
471
 
556
	}
-
 
557
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
-
 
558
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
 
559
		struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
-
 
560
 
-
 
561
		struct drm_fb_helper_cmdline_mode *cmdline_mode;
-
 
562
 
-
 
563
		if (!fb_help_conn)
-
 
564
			continue;
-
 
565
		
-
 
566
		cmdline_mode = &fb_help_conn->cmdline_mode;
-
 
567
 
-
 
568
		if (cmdline_mode->bpp_specified) {
-
 
569
			switch (cmdline_mode->bpp) {
-
 
570
			case 8:
-
 
571
				surface_depth = surface_bpp = 8;
-
 
572
				break;
-
 
573
			case 15:
-
 
574
				surface_depth = 15;
-
 
575
				surface_bpp = 16;
-
 
576
				break;
-
 
577
			case 16:
-
 
578
				surface_depth = surface_bpp = 16;
-
 
579
				break;
-
 
580
			case 24:
-
 
581
				surface_depth = surface_bpp = 24;
-
 
582
				break;
-
 
583
			case 32:
-
 
584
				surface_depth = 24;
-
 
585
				surface_bpp = 32;
-
 
586
				break;
-
 
587
			}
-
 
588
			break;
-
 
589
		}
-
 
590
	}
472
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
591
 
473
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
592
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
474
		if (drm_helper_crtc_in_use(crtc)) {
593
		if (drm_helper_crtc_in_use(crtc)) {
475
			if (crtc->desired_mode) {
594
			if (crtc->desired_mode) {
476
				if (crtc->desired_mode->hdisplay < fb_width)
595
				if (crtc->desired_mode->hdisplay < fb_width)
Line 496... Line 615...
496
	}
615
	}
Line 497... Line 616...
497
 
616
 
498
	/* do we have an fb already? */
617
	/* do we have an fb already? */
499
	if (list_empty(&dev->mode_config.fb_kernel_list)) {
618
	if (list_empty(&dev->mode_config.fb_kernel_list)) {
500
		ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
619
		ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
-
 
620
				   surface_height, surface_depth, surface_bpp,
501
				   surface_height, &fb);
621
				   &fb);
502
		if (ret)
622
		if (ret)
503
			return -EINVAL;
623
			return -EINVAL;
504
		new_fb = 1;
624
		new_fb = 1;
505
	} else {
625
	} else {
Line 575... Line 695...
575
	list_del(&helper->kernel_fb_list);
695
	list_del(&helper->kernel_fb_list);
576
	drm_fb_helper_crtc_free(helper);
696
	drm_fb_helper_crtc_free(helper);
577
}
697
}
578
EXPORT_SYMBOL(drm_fb_helper_free);
698
EXPORT_SYMBOL(drm_fb_helper_free);
Line 579... Line 699...
579
 
699
 
-
 
700
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
580
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
701
			    uint32_t depth)
581
{
702
{
582
	info->fix.type = FB_TYPE_PACKED_PIXELS;
703
	info->fix.type = FB_TYPE_PACKED_PIXELS;
-
 
704
	info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
583
	info->fix.visual = FB_VISUAL_TRUECOLOR;
705
		FB_VISUAL_DIRECTCOLOR;
584
	info->fix.type_aux = 0;
706
	info->fix.type_aux = 0;
585
	info->fix.xpanstep = 1; /* doing it in hw */
707
	info->fix.xpanstep = 1; /* doing it in hw */
586
	info->fix.ypanstep = 1; /* doing it in hw */
708
	info->fix.ypanstep = 1; /* doing it in hw */
587
	info->fix.ywrapstep = 0;
709
	info->fix.ywrapstep = 0;