Subversion Repositories Kolibri OS

Rev

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

Rev 4126 Rev 4560
Line 37... Line 37...
37
#include 
37
#include 
38
#include 
38
#include 
39
#include 
39
#include 
40
#include 
40
#include 
Line -... Line 41...
-
 
41
 
-
 
42
MODULE_AUTHOR("David Airlie, Jesse Barnes");
-
 
43
MODULE_DESCRIPTION("DRM KMS helper");
-
 
44
MODULE_LICENSE("GPL and additional rights");
41
 
45
 
42
/**
46
/**
43
 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
47
 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
44
 * 						connector list
48
 * 						connector list
45
 * @dev: drm device to operate on
49
 * @dev: drm device to operate on
Line 74... Line 78...
74
static void drm_mode_validate_flag(struct drm_connector *connector,
78
static void drm_mode_validate_flag(struct drm_connector *connector,
75
				   int flags)
79
				   int flags)
76
{
80
{
77
	struct drm_display_mode *mode;
81
	struct drm_display_mode *mode;
Line 78... Line 82...
78
 
82
 
-
 
83
	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
79
	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
84
		      DRM_MODE_FLAG_3D_MASK))
Line 80... Line 85...
80
		return;
85
		return;
81
 
86
 
82
	list_for_each_entry(mode, &connector->modes, head) {
87
	list_for_each_entry(mode, &connector->modes, head) {
83
		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
88
		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
84
				!(flags & DRM_MODE_FLAG_INTERLACE))
89
				!(flags & DRM_MODE_FLAG_INTERLACE))
85
			mode->status = MODE_NO_INTERLACE;
90
			mode->status = MODE_NO_INTERLACE;
86
		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
91
		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
-
 
92
				!(flags & DRM_MODE_FLAG_DBLSCAN))
-
 
93
			mode->status = MODE_NO_DBLESCAN;
-
 
94
		if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
87
				!(flags & DRM_MODE_FLAG_DBLSCAN))
95
				!(flags & DRM_MODE_FLAG_3D_MASK))
Line 88... Line 96...
88
			mode->status = MODE_NO_DBLESCAN;
96
			mode->status = MODE_NO_STEREO;
89
	}
97
	}
Line 103... Line 111...
103
 * Based on the helper callbacks implemented by @connector try to detect all
111
 * Based on the helper callbacks implemented by @connector try to detect all
104
 * valid modes.  Modes will first be added to the connector's probed_modes list,
112
 * valid modes.  Modes will first be added to the connector's probed_modes list,
105
 * then culled (based on validity and the @maxX, @maxY parameters) and put into
113
 * then culled (based on validity and the @maxX, @maxY parameters) and put into
106
 * the normal modes list.
114
 * the normal modes list.
107
 *
115
 *
108
 * Intended to be use as a generic implementation of the ->probe() @connector
116
 * Intended to be use as a generic implementation of the ->fill_modes()
109
 * callback for drivers that use the crtc helpers for output mode filtering and
117
 * @connector vfunc for drivers that use the crtc helpers for output mode
110
 * detection.
118
 * filtering and detection.
111
 *
119
 *
112
 * RETURNS:
120
 * RETURNS:
113
 * Number of modes found on @connector.
121
 * Number of modes found on @connector.
114
 */
122
 */
115
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
123
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
Line 173... Line 181...
173
 
181
 
174
	if (connector->interlace_allowed)
182
	if (connector->interlace_allowed)
175
		mode_flags |= DRM_MODE_FLAG_INTERLACE;
183
		mode_flags |= DRM_MODE_FLAG_INTERLACE;
176
	if (connector->doublescan_allowed)
184
	if (connector->doublescan_allowed)
-
 
185
		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
-
 
186
	if (connector->stereo_allowed)
177
		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
187
		mode_flags |= DRM_MODE_FLAG_3D_MASK;
Line 178... Line 188...
178
	drm_mode_validate_flag(connector, mode_flags);
188
	drm_mode_validate_flag(connector, mode_flags);
179
 
189
 
180
	list_for_each_entry(mode, &connector->modes, head) {
190
	list_for_each_entry(mode, &connector->modes, head) {
Line 312... Line 322...
312
		}
322
		}
313
	}
323
	}
314
}
324
}
315
EXPORT_SYMBOL(drm_helper_disable_unused_functions);
325
EXPORT_SYMBOL(drm_helper_disable_unused_functions);
Line 316... Line -...
316
 
-
 
317
/**
-
 
318
 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
-
 
319
 * @encoder: encoder to test
-
 
320
 * @crtc: crtc to test
-
 
321
 *
-
 
322
 * Return false if @encoder can't be driven by @crtc, true otherwise.
-
 
323
 */
-
 
324
static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
-
 
325
				struct drm_crtc *crtc)
-
 
326
{
-
 
327
	struct drm_device *dev;
-
 
328
	struct drm_crtc *tmp;
-
 
329
	int crtc_mask = 1;
-
 
330
 
-
 
331
	WARN(!crtc, "checking null crtc?\n");
-
 
332
 
-
 
333
	dev = crtc->dev;
-
 
334
 
-
 
335
	list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
-
 
336
		if (tmp == crtc)
-
 
337
			break;
-
 
338
		crtc_mask <<= 1;
-
 
339
	}
-
 
340
 
-
 
341
	if (encoder->possible_crtcs & crtc_mask)
-
 
342
		return true;
-
 
343
	return false;
-
 
344
}
-
 
345
 
326
 
346
/*
327
/*
347
 * Check the CRTC we're going to map each output to vs. its current
328
 * Check the CRTC we're going to map each output to vs. its current
348
 * CRTC.  If they don't match, we have to disable the output and the CRTC
329
 * CRTC.  If they don't match, we have to disable the output and the CRTC
349
 * since the driver will have to re-route things.
330
 * since the driver will have to re-route things.
Line 393... Line 374...
393
			      struct drm_display_mode *mode,
374
			      struct drm_display_mode *mode,
394
			      int x, int y,
375
			      int x, int y,
395
			      struct drm_framebuffer *old_fb)
376
			      struct drm_framebuffer *old_fb)
396
{
377
{
397
	struct drm_device *dev = crtc->dev;
378
	struct drm_device *dev = crtc->dev;
398
	struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
379
	struct drm_display_mode *adjusted_mode, saved_mode;
399
	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
380
	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
400
	struct drm_encoder_helper_funcs *encoder_funcs;
381
	struct drm_encoder_helper_funcs *encoder_funcs;
401
	int saved_x, saved_y;
382
	int saved_x, saved_y;
-
 
383
	bool saved_enabled;
402
	struct drm_encoder *encoder;
384
	struct drm_encoder *encoder;
403
	bool ret = true;
385
	bool ret = true;
Line -... Line 386...
-
 
386
 
404
 
387
	saved_enabled = crtc->enabled;
405
	crtc->enabled = drm_helper_crtc_in_use(crtc);
388
	crtc->enabled = drm_helper_crtc_in_use(crtc);
406
	if (!crtc->enabled)
389
	if (!crtc->enabled)
Line 407... Line 390...
407
		return true;
390
		return true;
408
 
391
 
-
 
392
	adjusted_mode = drm_mode_duplicate(dev, mode);
409
	adjusted_mode = drm_mode_duplicate(dev, mode);
393
	if (!adjusted_mode) {
-
 
394
		crtc->enabled = saved_enabled;
Line 410... Line -...
410
	if (!adjusted_mode)
-
 
411
		return false;
395
		return false;
412
 
396
	}
413
	saved_hwmode = crtc->hwmode;
397
 
Line 414... Line 398...
414
	saved_mode = crtc->mode;
398
	saved_mode = crtc->mode;
Line 521... Line 505...
521
 
505
 
522
	/* Calculate and store various constants which
506
	/* Calculate and store various constants which
523
	 * are later needed by vblank and swap-completion
507
	 * are later needed by vblank and swap-completion
524
	 * timestamping. They are derived from true hwmode.
508
	 * timestamping. They are derived from true hwmode.
525
	 */
509
	 */
Line 526... Line 510...
526
	drm_calc_timestamping_constants(crtc);
510
	drm_calc_timestamping_constants(crtc, &crtc->hwmode);
527
 
511
 
528
	/* FIXME: add subpixel order */
512
	/* FIXME: add subpixel order */
529
done:
513
done:
530
	drm_mode_destroy(dev, adjusted_mode);
514
	drm_mode_destroy(dev, adjusted_mode);
531
	if (!ret) {
515
	if (!ret) {
532
		crtc->hwmode = saved_hwmode;
516
		crtc->enabled = saved_enabled;
533
		crtc->mode = saved_mode;
517
		crtc->mode = saved_mode;
534
		crtc->x = saved_x;
518
		crtc->x = saved_x;
Line 555... Line 539...
555
		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
539
		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
556
			if (connector->encoder != encoder)
540
			if (connector->encoder != encoder)
557
				continue;
541
				continue;
Line 558... Line 542...
558
 
542
 
-
 
543
			connector->encoder = NULL;
-
 
544
 
-
 
545
			/*
-
 
546
			 * drm_helper_disable_unused_functions() ought to be
-
 
547
			 * doing this, but since we've decoupled the encoder
-
 
548
			 * from the connector above, the required connection
-
 
549
			 * between them is henceforth no longer available.
-
 
550
			 */
559
			connector->encoder = NULL;
551
			connector->dpms = DRM_MODE_DPMS_OFF;
560
		}
552
		}
Line 561... Line 553...
561
	}
553
	}
562
 
554
 
Line 581... Line 573...
581
 * Returns 0 on success, -ERRNO on failure.
573
 * Returns 0 on success, -ERRNO on failure.
582
 */
574
 */
583
int drm_crtc_helper_set_config(struct drm_mode_set *set)
575
int drm_crtc_helper_set_config(struct drm_mode_set *set)
584
{
576
{
585
	struct drm_device *dev;
577
	struct drm_device *dev;
586
	struct drm_crtc *save_crtcs, *new_crtc, *crtc;
578
	struct drm_crtc *new_crtc;
587
	struct drm_encoder *save_encoders, *new_encoder, *encoder;
579
	struct drm_encoder *save_encoders, *new_encoder, *encoder;
588
	struct drm_framebuffer *old_fb = NULL;
-
 
589
	bool mode_changed = false; /* if true do a full mode set */
580
	bool mode_changed = false; /* if true do a full mode set */
590
	bool fb_changed = false; /* if true and !mode_changed just do a flip */
581
	bool fb_changed = false; /* if true and !mode_changed just do a flip */
591
	struct drm_connector *save_connectors, *connector;
582
	struct drm_connector *save_connectors, *connector;
592
	int count = 0, ro, fail = 0;
583
	int count = 0, ro, fail = 0;
593
	struct drm_crtc_helper_funcs *crtc_funcs;
584
	struct drm_crtc_helper_funcs *crtc_funcs;
Line 619... Line 610...
619
		return drm_crtc_helper_disable(set->crtc);
610
		return drm_crtc_helper_disable(set->crtc);
620
	}
611
	}
Line 621... Line 612...
621
 
612
 
Line -... Line 613...
-
 
613
	dev = set->crtc->dev;
622
	dev = set->crtc->dev;
614
 
623
 
615
	/*
624
	/* Allocate space for the backup of all (non-pointer) crtc, encoder and
-
 
625
	 * connector data. */
-
 
626
	save_crtcs = kzalloc(dev->mode_config.num_crtc *
-
 
627
			     sizeof(struct drm_crtc), GFP_KERNEL);
-
 
628
	if (!save_crtcs)
616
	 * Allocate space for the backup of all (non-pointer) encoder and
629
		return -ENOMEM;
617
	 * connector data.
630
 
618
	 */
631
	save_encoders = kzalloc(dev->mode_config.num_encoder *
619
	save_encoders = kzalloc(dev->mode_config.num_encoder *
632
				sizeof(struct drm_encoder), GFP_KERNEL);
-
 
633
	if (!save_encoders) {
620
				sizeof(struct drm_encoder), GFP_KERNEL);
634
		kfree(save_crtcs);
-
 
Line 635... Line 621...
635
		return -ENOMEM;
621
	if (!save_encoders)
636
	}
622
		return -ENOMEM;
637
 
623
 
638
	save_connectors = kzalloc(dev->mode_config.num_connector *
-
 
639
				sizeof(struct drm_connector), GFP_KERNEL);
624
	save_connectors = kzalloc(dev->mode_config.num_connector *
640
	if (!save_connectors) {
625
				sizeof(struct drm_connector), GFP_KERNEL);
641
		kfree(save_crtcs);
626
	if (!save_connectors) {
Line -... Line 627...
-
 
627
		kfree(save_encoders);
642
		kfree(save_encoders);
628
		return -ENOMEM;
643
		return -ENOMEM;
629
	}
644
	}
630
 
645
 
631
	/*
646
	/* Copy data. Note that driver private data is not affected.
632
	 * Copy data. Note that driver private data is not affected.
647
	 * Should anything bad happen only the expected state is
-
 
648
	 * restored, not the drivers personal bookkeeping.
-
 
649
	 */
-
 
650
	count = 0;
-
 
651
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
652
		save_crtcs[count++] = *crtc;
633
	 * Should anything bad happen only the expected state is
653
	}
634
	 * restored, not the drivers personal bookkeeping.
654
 
635
	 */
Line 655... Line 636...
655
	count = 0;
636
	count = 0;
Line 773... Line 754...
773
	/* mode_set_base is not a required function */
754
	/* mode_set_base is not a required function */
774
	if (fb_changed && !crtc_funcs->mode_set_base)
755
	if (fb_changed && !crtc_funcs->mode_set_base)
775
		mode_changed = true;
756
		mode_changed = true;
Line 776... Line 757...
776
 
757
 
777
	if (mode_changed) {
758
	if (mode_changed) {
778
		set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
-
 
779
		if (set->crtc->enabled) {
759
		if (drm_helper_crtc_in_use(set->crtc)) {
780
			DRM_DEBUG_KMS("attempting to set mode from"
760
			DRM_DEBUG_KMS("attempting to set mode from"
781
					" userspace\n");
761
					" userspace\n");
782
			drm_mode_debug_printmodeline(set->mode);
-
 
783
			old_fb = set->crtc->fb;
762
			drm_mode_debug_printmodeline(set->mode);
784
			set->crtc->fb = set->fb;
763
			set->crtc->fb = set->fb;
785
			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
764
			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
786
						      set->x, set->y,
765
						      set->x, set->y,
787
						      old_fb)) {
766
						      save_set.fb)) {
788
				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
767
				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
789
					  set->crtc->base.id);
768
					  set->crtc->base.id);
790
				set->crtc->fb = old_fb;
769
				set->crtc->fb = save_set.fb;
791
				ret = -EINVAL;
770
				ret = -EINVAL;
792
				goto fail;
771
				goto fail;
793
			}
772
			}
794
			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
773
			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
Line 800... Line 779...
800
		}
779
		}
801
		drm_helper_disable_unused_functions(dev);
780
		drm_helper_disable_unused_functions(dev);
802
	} else if (fb_changed) {
781
	} else if (fb_changed) {
803
		set->crtc->x = set->x;
782
		set->crtc->x = set->x;
804
		set->crtc->y = set->y;
783
		set->crtc->y = set->y;
805
 
-
 
806
		old_fb = set->crtc->fb;
-
 
807
		if (set->crtc->fb != set->fb)
-
 
808
			set->crtc->fb = set->fb;
784
			set->crtc->fb = set->fb;
809
		ret = crtc_funcs->mode_set_base(set->crtc,
785
		ret = crtc_funcs->mode_set_base(set->crtc,
810
						set->x, set->y, old_fb);
786
						set->x, set->y, save_set.fb);
811
		if (ret != 0) {
787
		if (ret != 0) {
-
 
788
			set->crtc->x = save_set.x;
-
 
789
			set->crtc->y = save_set.y;
812
			set->crtc->fb = old_fb;
790
			set->crtc->fb = save_set.fb;
813
			goto fail;
791
			goto fail;
814
	}
792
	}
815
	}
793
	}
Line 816... Line 794...
816
 
794
 
817
	kfree(save_connectors);
795
	kfree(save_connectors);
818
	kfree(save_encoders);
-
 
819
	kfree(save_crtcs);
796
	kfree(save_encoders);
Line 820... Line 797...
820
	return 0;
797
	return 0;
821
 
798
 
822
fail:
799
fail:
823
	/* Restore all previous data. */
-
 
824
	count = 0;
-
 
825
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
826
		*crtc = save_crtcs[count++];
-
 
827
	}
-
 
828
 
800
	/* Restore all previous data. */
829
	count = 0;
801
	count = 0;
830
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
802
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
Line 831... Line 803...
831
		*encoder = save_encoders[count++];
803
		*encoder = save_encoders[count++];
Line 842... Line 814...
842
				      save_set.y, save_set.fb))
814
				      save_set.y, save_set.fb))
843
		DRM_ERROR("failed to restore config after modeset failure\n");
815
		DRM_ERROR("failed to restore config after modeset failure\n");
Line 844... Line 816...
844
 
816
 
845
	kfree(save_connectors);
817
	kfree(save_connectors);
846
	kfree(save_encoders);
-
 
847
	kfree(save_crtcs);
818
	kfree(save_encoders);
848
	return ret;
819
	return ret;
849
}
820
}
Line 850... Line 821...
850
EXPORT_SYMBOL(drm_crtc_helper_set_config);
821
EXPORT_SYMBOL(drm_crtc_helper_set_config);
Line 1122... Line 1093...
1122
{
1093
{
1123
	drm_kms_helper_poll_disable(dev);
1094
	drm_kms_helper_poll_disable(dev);
1124
}
1095
}
1125
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
1096
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
Line 1126... Line 1097...
1126
 
1097
 
1127
void drm_helper_hpd_irq_event(struct drm_device *dev)
1098
bool drm_helper_hpd_irq_event(struct drm_device *dev)
1128
{
1099
{
1129
	struct drm_connector *connector;
1100
	struct drm_connector *connector;
1130
	enum drm_connector_status old_status;
1101
	enum drm_connector_status old_status;
Line 1131... Line 1102...
1131
	bool changed = false;
1102
	bool changed = false;
1132
 
1103
 
Line 1133... Line 1104...
1133
	if (!dev->mode_config.poll_enabled)
1104
	if (!dev->mode_config.poll_enabled)
1134
		return;
1105
		return false;
Line 1135... Line 1106...
1135
 
1106
 
Line 1154... Line 1125...
1154
 
1125
 
Line 1155... Line 1126...
1155
	mutex_unlock(&dev->mode_config.mutex);
1126
	mutex_unlock(&dev->mode_config.mutex);
1156
 
1127
 
-
 
1128
	if (changed)
-
 
1129
		drm_kms_helper_hotplug_event(dev);
1157
	if (changed)
1130
 
1158
		drm_kms_helper_hotplug_event(dev);
1131
	return changed;