Subversion Repositories Kolibri OS

Rev

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

Rev 3031 Rev 3192
Line 25... Line 25...
25
 *
25
 *
26
 * Authors:
26
 * Authors:
27
 *      Dave Airlie 
27
 *      Dave Airlie 
28
 *      Jesse Barnes 
28
 *      Jesse Barnes 
29
 */
29
 */
-
 
30
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 
31
 
30
#include 
32
#include 
31
#include 
33
#include 
32
#include 
34
#include 
33
#include 
35
#include 
34
#include 
36
#include 
Line 41... Line 43...
41
MODULE_DESCRIPTION("DRM KMS helper");
43
MODULE_DESCRIPTION("DRM KMS helper");
42
MODULE_LICENSE("GPL and additional rights");
44
MODULE_LICENSE("GPL and additional rights");
Line 43... Line 45...
43
 
45
 
Line -... Line 46...
-
 
46
static LIST_HEAD(kernel_fb_helper_list);
-
 
47
 
-
 
48
/**
-
 
49
 * DOC: fbdev helpers
-
 
50
 *
-
 
51
 * The fb helper functions are useful to provide an fbdev on top of a drm kernel
-
 
52
 * mode setting driver. They can be used mostly independantely from the crtc
-
 
53
 * helper functions used by many drivers to implement the kernel mode setting
-
 
54
 * interfaces.
44
static LIST_HEAD(kernel_fb_helper_list);
55
 */
45
 
56
 
46
/* simple single crtc case helper function */
57
/* simple single crtc case helper function */
47
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
58
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
48
{
59
{
49
	struct drm_device *dev = fb_helper->dev;
60
	struct drm_device *dev = fb_helper->dev;
Line -... Line 61...
-
 
61
	struct drm_connector *connector;
-
 
62
	int i;
50
	struct drm_connector *connector;
63
 
51
	int i;
64
    ENTER();
Line 52... Line 65...
52
 
65
 
53
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
66
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
54
		struct drm_fb_helper_connector *fb_helper_connector;
67
		struct drm_fb_helper_connector *fb_helper_connector;
Line 55... Line 68...
55
 
68
 
56
		fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
69
		fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
57
		if (!fb_helper_connector)
70
		if (!fb_helper_connector)
-
 
71
			goto fail;
58
			goto fail;
72
 
59
 
73
		fb_helper_connector->connector = connector;
60
		fb_helper_connector->connector = connector;
74
		fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
61
		fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
75
	}
62
	}
76
    LEAVE();
63
	return 0;
77
	return 0;
64
fail:
78
fail:
-
 
79
	for (i = 0; i < fb_helper->connector_count; i++) {
65
	for (i = 0; i < fb_helper->connector_count; i++) {
80
		kfree(fb_helper->connector_info[i]);
66
		kfree(fb_helper->connector_info[i]);
81
		fb_helper->connector_info[i] = NULL;
67
		fb_helper->connector_info[i] = NULL;
82
	}
Line 68... Line 83...
68
	}
83
	fb_helper->connector_count = 0;
Line 120... Line 135...
120
 
135
 
121
		/* Walk the connectors & encoders on this fb turning them on/off */
136
		/* Walk the connectors & encoders on this fb turning them on/off */
122
		for (j = 0; j < fb_helper->connector_count; j++) {
137
		for (j = 0; j < fb_helper->connector_count; j++) {
123
			connector = fb_helper->connector_info[j]->connector;
138
			connector = fb_helper->connector_info[j]->connector;
124
			connector->funcs->dpms(connector, dpms_mode);
139
			connector->funcs->dpms(connector, dpms_mode);
125
			drm_connector_property_set_value(connector,
140
			drm_object_property_set_value(&connector->base,
126
				dev->mode_config.dpms_property, dpms_mode);
141
				dev->mode_config.dpms_property, dpms_mode);
127
		}
142
		}
128
	}
143
	}
129
				mutex_unlock(&dev->mode_config.mutex);
144
				mutex_unlock(&dev->mode_config.mutex);
Line 177... Line 192...
177
		       int crtc_count, int max_conn_count)
192
		       int crtc_count, int max_conn_count)
178
{
193
{
179
	struct drm_crtc *crtc;
194
	struct drm_crtc *crtc;
180
	int i;
195
	int i;
Line -... Line 196...
-
 
196
 
-
 
197
    ENTER();
-
 
198
 
-
 
199
    dbgprintf("crtc_count %d max_conn_count %d\n", crtc_count, max_conn_count);
181
 
200
 
Line 182... Line 201...
182
	fb_helper->dev = dev;
201
	fb_helper->dev = dev;
Line 183... Line 202...
183
 
202
 
184
	INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
203
	INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
-
 
204
 
-
 
205
	fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
185
 
206
	if (!fb_helper->crtc_info)
-
 
207
    {
Line 186... Line 208...
186
	fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
208
        FAIL();
187
	if (!fb_helper->crtc_info)
209
		return -ENOMEM;
188
		return -ENOMEM;
210
    };
189
 
211
 
-
 
212
	fb_helper->crtc_count = crtc_count;
190
	fb_helper->crtc_count = crtc_count;
213
	fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
191
	fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
214
	if (!fb_helper->connector_info) {
192
	if (!fb_helper->connector_info) {
215
		kfree(fb_helper->crtc_info);
Line 193... Line 216...
193
		kfree(fb_helper->crtc_info);
216
        FAIL();
Line 210... Line 233...
210
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
233
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
211
		fb_helper->crtc_info[i].mode_set.crtc = crtc;
234
		fb_helper->crtc_info[i].mode_set.crtc = crtc;
212
		i++;
235
		i++;
213
	}
236
	}
Line -... Line 237...
-
 
237
 
214
 
238
    LEAVE();
215
	return 0;
239
	return 0;
216
out_free:
240
out_free:
-
 
241
	drm_fb_helper_crtc_free(fb_helper);
217
	drm_fb_helper_crtc_free(fb_helper);
242
    FAIL();
218
	return -ENOMEM;
243
	return -ENOMEM;
219
}
244
}
Line 220... Line 245...
220
EXPORT_SYMBOL(drm_fb_helper_init);
245
EXPORT_SYMBOL(drm_fb_helper_init);
Line 496... Line 521...
496
	sizes.fb_width = (unsigned)-1;
521
	sizes.fb_width = (unsigned)-1;
497
	sizes.fb_height = (unsigned)-1;
522
	sizes.fb_height = (unsigned)-1;
Line 498... Line 523...
498
 
523
 
499
	/* if driver picks 8 or 16 by default use that
524
	/* if driver picks 8 or 16 by default use that
500
	   for both depth/bpp */
525
	   for both depth/bpp */
501
	if (preferred_bpp != sizes.surface_bpp) {
526
	if (preferred_bpp != sizes.surface_bpp)
502
		sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
527
		sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
503
	}
528
 
504
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
529
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
505
	for (i = 0; i < fb_helper->connector_count; i++) {
530
	for (i = 0; i < fb_helper->connector_count; i++) {
506
		struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
531
		struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
Line 566... Line 591...
566
		return new_fb;
591
		return new_fb;
Line 567... Line 592...
567
 
592
 
Line 568... Line 593...
568
	info = fb_helper->fbdev;
593
	info = fb_helper->fbdev;
569
 
594
 
570
	/* set the fb pointer */
595
	/* set the fb pointer */
571
	for (i = 0; i < fb_helper->crtc_count; i++) {
-
 
Line 572... Line 596...
572
		fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
596
	for (i = 0; i < fb_helper->crtc_count; i++)
573
		}
597
		fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
Line 574... Line 598...
574
 
598
 
Line 724... Line 748...
724
 
748
 
725
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
749
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
726
{
750
{
Line 727... Line 751...
727
	bool enable;
751
	bool enable;
728
 
752
 
729
	if (strict) {
753
	if (strict)
730
		enable = connector->status == connector_status_connected;
754
		enable = connector->status == connector_status_connected;
731
	} else {
755
	else
732
		enable = connector->status != connector_status_disconnected;
756
		enable = connector->status != connector_status_disconnected;
733
	}
757
 
Line 734... Line 758...
734
	return enable;
758
	return enable;
735
}
759
}
Line 844... Line 868...
844
	/* select a crtc for this connector and then attempt to configure
868
	/* select a crtc for this connector and then attempt to configure
845
	   remaining connectors */
869
	   remaining connectors */
846
	for (c = 0; c < fb_helper->crtc_count; c++) {
870
	for (c = 0; c < fb_helper->crtc_count; c++) {
847
		crtc = &fb_helper->crtc_info[c];
871
		crtc = &fb_helper->crtc_info[c];
Line 848... Line 872...
848
 
872
 
849
		if ((encoder->possible_crtcs & (1 << c)) == 0) {
873
		if ((encoder->possible_crtcs & (1 << c)) == 0)
850
			continue;
-
 
Line 851... Line 874...
851
		}
874
			continue;
852
 
875
 
853
		for (o = 0; o < n; o++)
876
		for (o = 0; o < n; o++)
Line 899... Line 922...
899
			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
922
			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
900
	modes = kcalloc(dev->mode_config.num_connector,
923
	modes = kcalloc(dev->mode_config.num_connector,
901
			sizeof(struct drm_display_mode *), GFP_KERNEL);
924
			sizeof(struct drm_display_mode *), GFP_KERNEL);
902
	enabled = kcalloc(dev->mode_config.num_connector,
925
	enabled = kcalloc(dev->mode_config.num_connector,
903
			  sizeof(bool), GFP_KERNEL);
926
			  sizeof(bool), GFP_KERNEL);
-
 
927
	if (!crtcs || !modes || !enabled) {
-
 
928
		DRM_ERROR("Memory allocation failed\n");
-
 
929
		goto out;
-
 
930
	}
-
 
931
 
Line 904... Line 932...
904
 
932
 
Line 905... Line 933...
905
	drm_enable_connectors(fb_helper, enabled);
933
	drm_enable_connectors(fb_helper, enabled);
Line 940... Line 968...
940
							   fb_crtc->desired_mode);
968
							   fb_crtc->desired_mode);
941
			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
969
			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
942
		}
970
		}
943
	}
971
	}
Line -... Line 972...
-
 
972
 
944
 
973
out:
945
	kfree(crtcs);
974
	kfree(crtcs);
946
	kfree(modes);
975
	kfree(modes);
947
	kfree(enabled);
976
	kfree(enabled);
Line 948... Line 977...
948
}
977
}
949
 
978
 
950
/**
979
/**
-
 
980
 * drm_helper_initial_config - setup a sane initial connector configuration
951
 * drm_helper_initial_config - setup a sane initial connector configuration
981
 * @fb_helper: fb_helper device struct
952
 * @dev: DRM device
982
 * @bpp_sel: bpp value to use for the framebuffer configuration
-
 
983
 *
953
 *
984
 * LOCKING:
954
 * LOCKING:
985
 * Called at init time by the driver to set up the @fb_helper initial
955
 * Called at init time, must take mode config lock.
986
 * configuration, must take the mode config lock.
956
 *
987
 *
957
 * Scan the CRTCs and connectors and try to put together an initial setup.
988
 * Scans the CRTCs and connectors and tries to put together an initial setup.
958
 * At the moment, this is a cloned configuration across all heads with
989
 * At the moment, this is a cloned configuration across all heads with
959
 * a new framebuffer object as the backing store.
990
 * a new framebuffer object as the backing store.
960
 *
991
 *
961
 * RETURNS:
992
 * RETURNS:
962
 * Zero if everything went ok, nonzero otherwise.
993
 * Zero if everything went ok, nonzero otherwise.
963
 */
994
 */
964
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
995
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
965
{
996
{
-
 
997
	struct drm_device *dev = fb_helper->dev;
-
 
998
	int count = 0;
-
 
999
    bool ret;
Line 966... Line 1000...
966
	struct drm_device *dev = fb_helper->dev;
1000
 
967
	int count = 0;
1001
    ENTER();
Line 968... Line 1002...
968
 
1002
 
Line 975... Line 1009...
975
						    dev->mode_config.max_width,
1009
						    dev->mode_config.max_width,
976
						    dev->mode_config.max_height);
1010
						    dev->mode_config.max_height);
977
	/*
1011
	/*
978
	 * we shouldn't end up with no modes here.
1012
	 * we shouldn't end up with no modes here.
979
	 */
1013
	 */
980
	if (count == 0) {
1014
	if (count == 0)
981
		printk(KERN_INFO "No connectors reported connected with modes\n");
1015
		dev_info(fb_helper->dev->dev, "No connectors reported connected with modes\n");
-
 
1016
 
-
 
1017
	drm_setup_crtcs(fb_helper);
-
 
1018
 
-
 
1019
    ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
-
 
1020
    LEAVE();
-
 
1021
}
-
 
1022
EXPORT_SYMBOL(drm_fb_helper_initial_config);
-
 
1023
 
-
 
1024
#if 0
-
 
1025
/**
-
 
1026
 * drm_fb_helper_hotplug_event - respond to a hotplug notification by
-
 
1027
 *                               probing all the outputs attached to the fb
-
 
1028
 * @fb_helper: the drm_fb_helper
-
 
1029
 *
-
 
1030
 * LOCKING:
-
 
1031
 * Called at runtime, must take mode config lock.
-
 
1032
 *
-
 
1033
 * Scan the connectors attached to the fb_helper and try to put together a
-
 
1034
 * setup after *notification of a change in output configuration.
-
 
1035
 *
-
 
1036
 * RETURNS:
-
 
1037
 * 0 on success and a non-zero error code otherwise.
-
 
1038
 */
-
 
1039
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
-
 
1040
{
-
 
1041
	struct drm_device *dev = fb_helper->dev;
-
 
1042
	int count = 0;
-
 
1043
	u32 max_width, max_height, bpp_sel;
-
 
1044
	int bound = 0, crtcs_bound = 0;
-
 
1045
	struct drm_crtc *crtc;
-
 
1046
 
-
 
1047
	if (!fb_helper->fb)
-
 
1048
		return 0;
-
 
1049
 
-
 
1050
	mutex_lock(&dev->mode_config.mutex);
-
 
1051
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
1052
		if (crtc->fb)
-
 
1053
			crtcs_bound++;
-
 
1054
		if (crtc->fb == fb_helper->fb)
-
 
1055
			bound++;
982
	}
1056
	}
-
 
1057
 
-
 
1058
	if (bound < crtcs_bound) {
-
 
1059
		fb_helper->delayed_hotplug = true;
-
 
1060
		mutex_unlock(&dev->mode_config.mutex);
-
 
1061
		return 0;
-
 
1062
	}
-
 
1063
	DRM_DEBUG_KMS("\n");
-
 
1064
 
-
 
1065
	max_width = fb_helper->fb->width;
-
 
1066
	max_height = fb_helper->fb->height;
-
 
1067
	bpp_sel = fb_helper->fb->bits_per_pixel;
-
 
1068
 
-
 
1069
	count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
-
 
1070
						    max_height);
983
	drm_setup_crtcs(fb_helper);
1071
	drm_setup_crtcs(fb_helper);
-
 
1072
	mutex_unlock(&dev->mode_config.mutex);
Line 984... Line 1073...
984
 
1073
 
985
	return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
1074
	return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
986
}
1075
}
-
 
1076
EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
-
 
1077
#endif
-
 
1078
-
 
1079