Subversion Repositories Kolibri OS

Rev

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

Rev 5271 Rev 6084
Line 56... Line 56...
56
 */
56
 */
Line 57... Line 57...
57
 
57
 
58
static bool drm_kms_helper_poll = true;
58
static bool drm_kms_helper_poll = true;
Line -... Line 59...
-
 
59
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
59
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
60
 
60
 
61
static enum drm_mode_status
61
static void drm_mode_validate_flag(struct drm_connector *connector,
62
drm_mode_validate_flag(const struct drm_display_mode *mode,
62
				   int flags)
-
 
63
{
-
 
64
	struct drm_display_mode *mode;
-
 
65
 
-
 
66
	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
-
 
67
		      DRM_MODE_FLAG_3D_MASK))
-
 
68
		return;
-
 
69
 
63
		       int flags)
70
	list_for_each_entry(mode, &connector->modes, head) {
64
{
71
		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
65
	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
-
 
66
	    !(flags & DRM_MODE_FLAG_INTERLACE))
72
				!(flags & DRM_MODE_FLAG_INTERLACE))
67
		return MODE_NO_INTERLACE;
73
			mode->status = MODE_NO_INTERLACE;
68
 
74
		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
69
	if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
-
 
70
	    !(flags & DRM_MODE_FLAG_DBLSCAN))
75
				!(flags & DRM_MODE_FLAG_DBLSCAN))
71
		return MODE_NO_DBLESCAN;
76
			mode->status = MODE_NO_DBLESCAN;
72
 
77
		if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
73
	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
-
 
74
	    !(flags & DRM_MODE_FLAG_3D_MASK))
-
 
75
		return MODE_NO_STEREO;
-
 
76
 
-
 
77
	return MODE_OK;
-
 
78
}
-
 
79
 
-
 
80
static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
-
 
81
{
-
 
82
	struct drm_display_mode *mode;
-
 
83
 
-
 
84
	if (!connector->cmdline_mode.specified)
-
 
85
		return 0;
-
 
86
 
-
 
87
	mode = drm_mode_create_from_cmdline_mode(connector->dev,
-
 
88
						 &connector->cmdline_mode);
-
 
89
	if (mode == NULL)
-
 
90
		return 0;
-
 
91
 
78
				!(flags & DRM_MODE_FLAG_3D_MASK))
92
	drm_mode_probed_add(connector, mode);
Line -... Line 93...
-
 
93
	return 1;
-
 
94
}
-
 
95
 
-
 
96
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
-
 
97
/**
-
 
98
 * drm_kms_helper_poll_enable_locked - re-enable output polling.
-
 
99
 * @dev: drm_device
-
 
100
 *
-
 
101
 * This function re-enables the output polling work without
-
 
102
 * locking the mode_config mutex.
-
 
103
 *
-
 
104
 * This is like drm_kms_helper_poll_enable() however it is to be
-
 
105
 * called from a context where the mode_config mutex is locked
-
 
106
 * already.
-
 
107
 */
-
 
108
void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
-
 
109
{
-
 
110
	bool poll = false;
-
 
111
	struct drm_connector *connector;
-
 
112
 
79
			mode->status = MODE_NO_STEREO;
113
	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
-
 
114
 
-
 
115
	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
-
 
116
		return;
-
 
117
 
-
 
118
	drm_for_each_connector(connector, dev) {
-
 
119
		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
-
 
120
					 DRM_CONNECTOR_POLL_DISCONNECT))
80
	}
121
			poll = true;
-
 
122
	}
-
 
123
 
Line 81... Line 124...
81
 
124
}
82
	return;
125
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
83
}
126
 
84
 
127
 
85
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
128
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
86
							      uint32_t maxX, uint32_t maxY, bool merge_type_bits)
129
							      uint32_t maxX, uint32_t maxY, bool merge_type_bits)
87
{
130
{
88
	struct drm_device *dev = connector->dev;
131
	struct drm_device *dev = connector->dev;
89
	struct drm_display_mode *mode;
132
	struct drm_display_mode *mode;
90
	struct drm_connector_helper_funcs *connector_funcs =
133
	const struct drm_connector_helper_funcs *connector_funcs =
-
 
134
		connector->helper_private;
Line 91... Line 135...
91
		connector->helper_private;
135
	int count = 0;
Line 92... Line 136...
92
	int count = 0;
136
	int mode_flags = 0;
93
	int mode_flags = 0;
137
	bool verbose_prune = true;
Line 108... Line 152...
108
		else
152
		else
109
			connector->status = connector_status_disconnected;
153
			connector->status = connector_status_disconnected;
110
		if (connector->funcs->force)
154
		if (connector->funcs->force)
111
			connector->funcs->force(connector);
155
			connector->funcs->force(connector);
112
	} else {
156
	} else {
-
 
157
		old_status = connector->status;
-
 
158
 
113
		connector->status = connector->funcs->detect(connector, true);
159
		connector->status = connector->funcs->detect(connector, true);
114
	}
160
	}
Line 115... Line 161...
115
 
161
 
116
	/* Re-enable polling in case the global poll config changed. */
162
	/* Re-enable polling in case the global poll config changed. */
117
	if (drm_kms_helper_poll != dev->mode_config.poll_running)
163
	if (drm_kms_helper_poll != dev->mode_config.poll_running)
Line 118... Line 164...
118
		drm_kms_helper_poll_enable(dev);
164
		drm_kms_helper_poll_enable_locked(dev);
Line 119... Line 165...
119
 
165
 
120
	dev->mode_config.poll_running = drm_kms_helper_poll;
166
	dev->mode_config.poll_running = drm_kms_helper_poll;
Line 134... Line 180...
134
	{
180
	{
135
		if (connector->override_edid) {
181
		if (connector->override_edid) {
136
			struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
182
			struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
Line 137... Line 183...
137
 
183
 
-
 
184
			count = drm_add_edid_modes(connector, edid);
138
			count = drm_add_edid_modes(connector, edid);
185
			drm_edid_to_eld(connector, edid);
139
		} else
186
		} else
140
		count = (*connector_funcs->get_modes)(connector);
187
			count = (*connector_funcs->get_modes)(connector);
Line 141... Line 188...
141
	}
188
	}
Line 145... Line 192...
145
	if (count == 0)
192
	if (count == 0)
146
		goto prune;
193
		goto prune;
Line 147... Line 194...
147
 
194
 
Line 148... Line -...
148
	drm_mode_connector_list_update(connector, merge_type_bits);
-
 
149
 
-
 
150
	if (maxX && maxY)
-
 
151
		drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
195
	drm_mode_connector_list_update(connector, merge_type_bits);
152
 
196
 
153
	if (connector->interlace_allowed)
197
	if (connector->interlace_allowed)
154
		mode_flags |= DRM_MODE_FLAG_INTERLACE;
198
		mode_flags |= DRM_MODE_FLAG_INTERLACE;
155
	if (connector->doublescan_allowed)
199
	if (connector->doublescan_allowed)
156
		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
200
		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
157
	if (connector->stereo_allowed)
-
 
Line 158... Line 201...
158
		mode_flags |= DRM_MODE_FLAG_3D_MASK;
201
	if (connector->stereo_allowed)
-
 
202
		mode_flags |= DRM_MODE_FLAG_3D_MASK;
-
 
203
 
-
 
204
	list_for_each_entry(mode, &connector->modes, head) {
-
 
205
		if (mode->status == MODE_OK)
-
 
206
			mode->status = drm_mode_validate_basic(mode);
-
 
207
 
-
 
208
		if (mode->status == MODE_OK)
-
 
209
			mode->status = drm_mode_validate_size(mode, maxX, maxY);
-
 
210
 
159
	drm_mode_validate_flag(connector, mode_flags);
211
		if (mode->status == MODE_OK)
160
 
212
			mode->status = drm_mode_validate_flag(mode, mode_flags);
161
	list_for_each_entry(mode, &connector->modes, head) {
213
 
162
		if (mode->status == MODE_OK && connector_funcs->mode_valid)
214
		if (mode->status == MODE_OK && connector_funcs->mode_valid)
Line 249... Line 301...
249
//   if (dev->mode_config.funcs->output_poll_changed)
301
//   if (dev->mode_config.funcs->output_poll_changed)
250
//       dev->mode_config.funcs->output_poll_changed(dev);
302
//       dev->mode_config.funcs->output_poll_changed(dev);
251
}
303
}
252
EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
304
EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
Line 253... Line -...
253
 
-
 
254
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
305
 
255
static void output_poll_execute(struct work_struct *work)
306
static void output_poll_execute(struct work_struct *work)
256
{
307
{
257
	struct delayed_work *delayed_work = to_delayed_work(work);
308
	struct delayed_work *delayed_work = to_delayed_work(work);
258
	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
309
	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
259
	struct drm_connector *connector;
310
	struct drm_connector *connector;
260
	enum drm_connector_status old_status;
311
	enum drm_connector_status old_status;
-
 
312
	bool repoll = false, changed;
-
 
313
 
-
 
314
	/* Pick up any changes detected by the probe functions. */
-
 
315
	changed = dev->mode_config.delayed_event;
Line 261... Line 316...
261
	bool repoll = false, changed = false;
316
	dev->mode_config.delayed_event = false;
262
 
317
 
Line 263... Line 318...
263
	if (!drm_kms_helper_poll)
318
	if (!drm_kms_helper_poll)
264
		return;
319
		goto out;
Line 265... Line 320...
265
 
320
 
266
	mutex_lock(&dev->mode_config.mutex);
321
	mutex_lock(&dev->mode_config.mutex);
267
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
322
	drm_for_each_connector(connector, dev) {
Line 268... Line 323...
268
 
323
 
269
		/* Ignore forced connectors. */
324
		/* Ignore forced connectors. */
270
		if (connector->force)
325
		if (connector->force)
271
			continue;
326
			continue;
Line 272... Line -...
272
 
-
 
273
		/* Ignore HPD capable connectors and connectors where we don't
-
 
274
		 * want any hotplug detection at all for polling. */
327
 
275
		if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
328
		/* Ignore HPD capable connectors and connectors where we don't
276
			continue;
329
		 * want any hotplug detection at all for polling. */
277
 
330
		if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
278
		repoll = true;
331
			continue;
279
 
332
 
Line -... Line 333...
-
 
333
		old_status = connector->status;
-
 
334
		/* if we are connected and don't want to poll for disconnect
280
		old_status = connector->status;
335
		   skip it */
281
		/* if we are connected and don't want to poll for disconnect
336
		if (old_status == connector_status_connected &&
282
		   skip it */
337
		    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
Line -... Line 338...
-
 
338
			continue;
-
 
339
 
-
 
340
		repoll = true;
-
 
341
 
-
 
342
		connector->status = connector->funcs->detect(connector, false);
-
 
343
		if (old_status != connector->status) {
-
 
344
			const char *old, *new;
-
 
345
 
-
 
346
			/*
-
 
347
			 * The poll work sets force=false when calling detect so
-
 
348
			 * that drivers can avoid to do disruptive tests (e.g.
-
 
349
			 * when load detect cycles could cause flickering on
-
 
350
			 * other, running displays). This bears the risk that we
-
 
351
			 * flip-flop between unknown here in the poll work and
-
 
352
			 * the real state when userspace forces a full detect
-
 
353
			 * call after receiving a hotplug event due to this
-
 
354
			 * change.
-
 
355
			 *
283
		if (old_status == connector_status_connected &&
356
			 * Hence clamp an unknown detect status to the old
284
		    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
357
			 * value.
Line 285... Line 358...
285
			continue;
358
			 */
286
 
359
			if (connector->status == connector_status_unknown) {
Line 301... Line 374...
301
		}
374
		}
302
	}
375
	}
Line 303... Line 376...
303
 
376
 
Line -... Line 377...
-
 
377
	mutex_unlock(&dev->mode_config.mutex);
-
 
378
 
304
	mutex_unlock(&dev->mode_config.mutex);
379
out: ;
305
 
380
 
Line 306... Line 381...
306
//   if (changed)
381
//   if (changed)
307
//       drm_kms_helper_hotplug_event(dev);
382
//       drm_kms_helper_hotplug_event(dev);
Line 338... Line 413...
338
 * an error to call this when the output polling support has not yet been set
413
 * an error to call this when the output polling support has not yet been set
339
 * up.
414
 * up.
340
 */
415
 */
341
void drm_kms_helper_poll_enable(struct drm_device *dev)
416
void drm_kms_helper_poll_enable(struct drm_device *dev)
342
{
417
{
343
	bool poll = false;
-
 
344
	struct drm_connector *connector;
418
	mutex_lock(&dev->mode_config.mutex);
345
 
-
 
346
	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
419
	drm_kms_helper_poll_enable_locked(dev);
347
		return;
-
 
348
 
-
 
349
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
420
	mutex_unlock(&dev->mode_config.mutex);
350
		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
-
 
351
					 DRM_CONNECTOR_POLL_DISCONNECT))
-
 
352
			poll = true;
-
 
353
	}
-
 
354
 
-
 
355
//   if (poll)
-
 
356
//       schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
-
 
357
}
421
}
358
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
422
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
Line 359... Line 423...
359
 
423
 
360
/**
424
/**
Line 426... Line 490...
426
 
490
 
427
	if (!dev->mode_config.poll_enabled)
491
	if (!dev->mode_config.poll_enabled)
Line 428... Line 492...
428
		return false;
492
		return false;
429
 
493
 
Line 430... Line 494...
430
	mutex_lock(&dev->mode_config.mutex);
494
	mutex_lock(&dev->mode_config.mutex);
431
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
495
	drm_for_each_connector(connector, dev) {
432
 
496